1 /******************************************************************************* 2 * Copyright (c) 2000, 2008 IBM Corporation and others. 3 * All rights reserved. This program and the accompanying materials 4 * are made available under the terms of the Eclipse Public License v1.0 5 * which accompanies this distribution, and is available at 6 * http://www.eclipse.org/legal/epl-v10.html 7 * 8 * Contributors: 9 * IBM Corporation - initial API and implementation 10 * Port to the D programming language: 11 * Frank Benoit <benoit@tionex.de> 12 *******************************************************************************/ 13 module org.eclipse.swt.graphics.Color; 14 15 import java.lang.all; 16 17 18 import org.eclipse.swt.SWT; 19 import org.eclipse.swt.internal.gtk.OS; 20 import org.eclipse.swt.graphics.Resource; 21 import org.eclipse.swt.graphics.RGB; 22 import org.eclipse.swt.graphics.Device; 23 24 25 26 /** 27 * Instances of this class manage the operating system resources that 28 * implement SWT's RGB color model. To create a color you can either 29 * specify the individual color components as integers in the range 30 * 0 to 255 or provide an instance of an <code>RGB</code>. 31 * <p> 32 * Application code must explicitly invoke the <code>Color.dispose()</code> 33 * method to release the operating system resources managed by each instance 34 * when those instances are no longer required. 35 * </p> 36 * 37 * @see RGB 38 * @see Device#getSystemColor 39 * @see <a href="http://www.eclipse.org/swt/snippets/#color">Color and RGB snippets</a> 40 * @see <a href="http://www.eclipse.org/swt/examples.php">SWT Example: PaintExample</a> 41 * @see <a href="http://www.eclipse.org/swt/">Sample code and further information</a> 42 */ 43 public final class Color : Resource { 44 alias Resource.init_ init_; 45 /** 46 * the handle to the OS color resource 47 * (Warning: This field is platform dependent) 48 * <p> 49 * <b>IMPORTANT:</b> This field is <em>not</em> part of the SWT 50 * public API. It is marked public only so that it can be shared 51 * within the packages provided by SWT. It is not available on all 52 * platforms and should never be accessed from application code. 53 * </p> 54 */ 55 public GdkColor* handle; 56 57 this(Device device) { 58 super(device); 59 } 60 61 /** 62 * Constructs a new instance of this class given a device and the 63 * desired red, green and blue values expressed as ints in the range 64 * 0 to 255 (where 0 is black and 255 is full brightness). On limited 65 * color devices, the color instance created by this call may not have 66 * the same RGB values as the ones specified by the arguments. The 67 * RGB values on the returned instance will be the color values of 68 * the operating system color. 69 * <p> 70 * You must dispose the color when it is no longer required. 71 * </p> 72 * 73 * @param device the device on which to allocate the color 74 * @param red the amount of red in the color 75 * @param green the amount of green in the color 76 * @param blue the amount of blue in the color 77 * 78 * @exception IllegalArgumentException <ul> 79 * <li>ERROR_NULL_ARGUMENT - if device is null and there is no current device</li> 80 * <li>ERROR_INVALID_ARGUMENT - if the red, green or blue argument is not between 0 and 255</li> 81 * </ul> 82 * 83 * @see #dispose 84 */ 85 public this(Device device, int red, int green, int blue) { 86 super(device); 87 init_(red, green, blue); 88 init_(); 89 } 90 91 /** 92 * Constructs a new instance of this class given a device and an 93 * <code>RGB</code> describing the desired red, green and blue values. 94 * On limited color devices, the color instance created by this call 95 * may not have the same RGB values as the ones specified by the 96 * argument. The RGB values on the returned instance will be the color 97 * values of the operating system color. 98 * <p> 99 * You must dispose the color when it is no longer required. 100 * </p> 101 * 102 * @param device the device on which to allocate the color 103 * @param rgb the RGB values of the desired color 104 * 105 * @exception IllegalArgumentException <ul> 106 * <li>ERROR_NULL_ARGUMENT - if device is null and there is no current device</li> 107 * <li>ERROR_NULL_ARGUMENT - if the rgb argument is null</li> 108 * <li>ERROR_INVALID_ARGUMENT - if the red, green or blue components of the argument are not between 0 and 255</li> 109 * </ul> 110 * 111 * @see #dispose 112 */ 113 public this(Device device, in RGB rgb) { 114 super(device); 115 if (rgb is null) SWT.error(SWT.ERROR_NULL_ARGUMENT); 116 init_(rgb.red, rgb.green, rgb.blue); 117 init_(); 118 } 119 120 override 121 void destroy() { 122 int pixel = handle.pixel; 123 if (device.colorRefCount !is null) { 124 /* If this was the last reference, remove the color from the list */ 125 if (--device.colorRefCount[pixel] is 0) { 126 device.gdkColors[pixel] = null; 127 } 128 } 129 auto colormap = OS.gdk_colormap_get_system(); 130 OS.gdk_colormap_free_colors(colormap, handle, 1); 131 handle = null; 132 } 133 134 /** 135 * Compares the argument to the receiver, and returns true 136 * if they represent the <em>same</em> object using a class 137 * specific comparison. 138 * 139 * @param object the object to compare with this object 140 * @return <code>true</code> if the object is the same as this object and <code>false</code> otherwise 141 * 142 * @see #hashCode 143 */ 144 public override equals_t opEquals(Object object) { 145 if (object is this) return true; 146 if ( auto color = cast(Color)object ){ 147 GdkColor* gdkColor = color.handle; 148 if (handle is gdkColor) return true; 149 return device is color.device && handle.red is gdkColor.red && 150 handle.green is gdkColor.green && handle.blue is gdkColor.blue; 151 } 152 return false; 153 } 154 155 /** 156 * Returns the amount of blue in the color, from 0 to 255. 157 * 158 * @return the blue component of the color 159 * 160 * @exception SWTException <ul> 161 * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> 162 * </ul> 163 */ 164 public int getBlue() { 165 if (isDisposed()) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); 166 return (handle.blue >> 8) & 0xFF; 167 } 168 169 /** 170 * Returns the amount of green in the color, from 0 to 255. 171 * 172 * @return the green component of the color 173 * 174 * @exception SWTException <ul> 175 * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> 176 * </ul> 177 */ 178 public int getGreen() { 179 if (isDisposed()) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); 180 return (handle.green >> 8) & 0xFF; 181 } 182 183 /** 184 * Returns the amount of red in the color, from 0 to 255. 185 * 186 * @return the red component of the color 187 * 188 * @exception SWTException <ul> 189 * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> 190 * </ul> 191 */ 192 public int getRed() { 193 if (isDisposed()) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); 194 return (handle.red >> 8) & 0xFF; 195 } 196 197 /** 198 * Returns an integer hash code for the receiver. Any two 199 * objects that return <code>true</code> when passed to 200 * <code>equals</code> must return the same value for this 201 * method. 202 * 203 * @return the receiver's hash 204 * 205 * @see #equals 206 */ 207 public override hash_t toHash() { 208 if (handle is null) return 0; 209 return handle.red ^ handle.green ^ handle.blue; 210 } 211 212 /** 213 * Returns an <code>RGB</code> representing the receiver. 214 * 215 * @return the RGB for the color 216 * 217 * @exception SWTException <ul> 218 * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> 219 * </ul> 220 */ 221 public RGB getRGB () { 222 if (isDisposed()) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); 223 return new RGB(getRed(), getGreen(), getBlue()); 224 } 225 226 /** 227 * Invokes platform specific functionality to allocate a new color. 228 * <p> 229 * <b>IMPORTANT:</b> This method is <em>not</em> part of the public 230 * API for <code>Color</code>. It is marked public only so that it 231 * can be shared within the packages provided by SWT. It is not 232 * available on all platforms, and should never be called from 233 * application code. 234 * </p> 235 * 236 * @param device the device on which to allocate the color 237 * @param handle the handle for the color 238 * 239 * @private 240 */ 241 public static Color gtk_new(Device device, GdkColor* gdkColor) { 242 Color color = new Color(device); 243 color.handle = gdkColor; 244 return color; 245 } 246 247 void init_(int red, int green, int blue) { 248 if ((red > 255) || (red < 0) || 249 (green > 255) || (green < 0) || 250 (blue > 255) || (blue < 0)) { 251 SWT.error(SWT.ERROR_INVALID_ARGUMENT); 252 } 253 GdkColor* gdkColor = new GdkColor(); 254 gdkColor.red = cast(short)((red & 0xFF) | ((red & 0xFF) << 8)); 255 gdkColor.green = cast(short)((green & 0xFF) | ((green & 0xFF) << 8)); 256 gdkColor.blue = cast(short)((blue & 0xFF) | ((blue & 0xFF) << 8)); 257 auto colormap = OS.gdk_colormap_get_system(); 258 if (!OS.gdk_colormap_alloc_color(colormap, gdkColor, true, true)) { 259 /* Allocate black. */ 260 gdkColor = new GdkColor(); 261 OS.gdk_colormap_alloc_color(colormap, gdkColor, true, true); 262 } 263 handle = gdkColor; 264 if (device.colorRefCount !is null) { 265 /* Make a copy of the color to put in the colors array */ 266 GdkColor* colorCopy = new GdkColor(); 267 colorCopy.red = handle.red; 268 colorCopy.green = handle.green; 269 colorCopy.blue = handle.blue; 270 colorCopy.pixel = handle.pixel; 271 device.gdkColors[colorCopy.pixel] = colorCopy; 272 device.colorRefCount[colorCopy.pixel]++; 273 } 274 } 275 276 /** 277 * Returns <code>true</code> if the color has been disposed, 278 * and <code>false</code> otherwise. 279 * <p> 280 * This method gets the dispose state for the color. 281 * When a color has been disposed, it is an error to 282 * invoke any other method using the color. 283 * 284 * @return <code>true</code> when the color is disposed and <code>false</code> otherwise 285 */ 286 public override bool isDisposed() { 287 return handle is null; 288 } 289 290 /** 291 * Returns a string containing a concise, human-readable 292 * description of the receiver. 293 * 294 * @return a string representation of the receiver 295 */ 296 public override String toString () { 297 if (isDisposed()) return "Color {*DISPOSED*}"; 298 return Format( "Color {{{}, {}, {}}", getRed(), getGreen(), getBlue()); 299 } 300 301 }