root/dwt/graphics/Color.d

Revision 246:fd9c62a2998e, 10.9 kB (checked in by Frank Benoit <benoit@tionex.de>, 6 months ago)

Updater SWT 3.4M7 to 3.4

Line 
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 dwt.graphics.Color;
14
15 import dwt.DWT;
16 import dwt.DWTException;
17 import dwt.internal.win32.OS;
18
19 import dwt.graphics.Resource;
20 import dwt.graphics.RGB;
21 import dwt.graphics.Device;
22
23 import tango.text.convert.Format;
24 import dwt.dwthelper.utils;
25
26 /**
27  * Instances of this class manage the operating system resources that
28  * implement DWT'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">DWT Example: PaintExample</a>
41  * @see <a href="http://www.eclipse.org/swt/">Sample code and further information</a>
42  */
43
44 public final class Color : Resource {
45
46     alias Resource.init_ init_;
47
48     /**
49      * the handle to the OS color resource
50      * (Warning: This field is platform dependent)
51      * <p>
52      * <b>IMPORTANT:</b> This field is <em>not</em> part of the DWT
53      * public API. It is marked public only so that it can be shared
54      * within the packages provided by DWT. It is not available on all
55      * platforms and should never be accessed from application code.
56      * </p>
57      */
58     public COLORREF handle;
59
60 /**
61  * Prevents uninitialized instances from being created outside the package.
62  */
63 this(Device device) {
64     super(device);
65 }
66
67 /**
68  * Constructs a new instance of this class given a device and the
69  * desired red, green and blue values expressed as ints in the range
70  * 0 to 255 (where 0 is black and 255 is full brightness). On limited
71  * color devices, the color instance created by this call may not have
72  * the same RGB values as the ones specified by the arguments. The
73  * RGB values on the returned instance will be the color values of
74  * the operating system color.
75  * <p>
76  * You must dispose the color when it is no longer required.
77  * </p>
78  *
79  * @param device the device on which to allocate the color
80  * @param red the amount of red in the color
81  * @param green the amount of green in the color
82  * @param blue the amount of blue in the color
83  *
84  * @exception IllegalArgumentException <ul>
85  *    <li>ERROR_NULL_ARGUMENT - if device is null and there is no current device</li>
86  *    <li>ERROR_INVALID_ARGUMENT - if the red, green or blue argument is not between 0 and 255</li>
87  * </ul>
88  *
89  * @see #dispose
90  */
91 public this (Device device, int red, int green, int blue) {
92     super(device);
93     init_(red, green, blue);
94     init_();
95 }
96
97 /**
98  * Constructs a new instance of this class given a device and an
99  * <code>RGB</code> describing the desired red, green and blue values.
100  * On limited color devices, the color instance created by this call
101  * may not have the same RGB values as the ones specified by the
102  * argument. The RGB values on the returned instance will be the color
103  * values of the operating system color.
104  * <p>
105  * You must dispose the color when it is no longer required.
106  * </p>
107  *
108  * @param device the device on which to allocate the color
109  * @param rgb the RGB values of the desired color
110  *
111  * @exception IllegalArgumentException <ul>
112  *    <li>ERROR_NULL_ARGUMENT - if device is null and there is no current device</li>
113  *    <li>ERROR_NULL_ARGUMENT - if the rgb argument is null</li>
114  *    <li>ERROR_INVALID_ARGUMENT - if the red, green or blue components of the argument are not between 0 and 255</li>
115  * </ul>
116  *
117  * @see #dispose
118  */
119 public this (Device device, RGB rgb) {
120     super(device);
121     if (rgb is null) DWT.error(DWT.ERROR_NULL_ARGUMENT);
122     init_(rgb.red, rgb.green, rgb.blue);
123     init_();
124 }
125
126 void destroy() {
127     /*
128      * If this is a palette-based device,
129      * Decrease the reference count for this color.
130      * If the reference count reaches 0, the slot may
131      * be reused when another color is allocated.
132      */
133     auto hPal = device.hPalette;
134     if (hPal !is null) {
135         int index = OS.GetNearestPaletteIndex(hPal, handle);
136         int[] colorRefCount = device.colorRefCount;
137         if (colorRefCount[index] > 0) {
138             colorRefCount[index]--;
139         }
140     }
141     handle = -1;
142 }
143
144 /**
145  * Compares the argument to the receiver, and returns true
146  * if they represent the <em>same</em> object using a class
147  * specific comparison.
148  *
149  * @param object the object to compare with this object
150  * @return <code>true</code> if the object is the same as this object and <code>false</code> otherwise
151  *
152  * @see #hashCode
153  */
154 public bool equals (Object object) {
155     if (object is this) return true;
156     if (!(cast(Color)object)) return false;
157     Color color = cast(Color) object;
158     return device is color.device && (handle & 0xFFFFFF) is (color.handle & 0xFFFFFF);
159 }
160
161 /**
162  * Returns the amount of blue in the color, from 0 to 255.
163  *
164  * @return the blue component of the color
165  *
166  * @exception DWTException <ul>
167  *    <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
168  * </ul>
169  */
170 public int getBlue () {
171     if (isDisposed()) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED);
172     return (handle & 0xFF0000) >> 16;
173 }
174
175 /**
176  * Returns the amount of green in the color, from 0 to 255.
177  *
178  * @return the green component of the color
179  *
180  * @exception DWTException <ul>
181  *    <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
182  * </ul>
183  */
184 public int getGreen () {
185     if (isDisposed()) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED);
186     return (handle & 0xFF00) >> 8 ;
187 }
188
189 /**
190  * Returns the amount of red in the color, from 0 to 255.
191  *
192  * @return the red component of the color
193  *
194  * @exception DWTException <ul>
195  *    <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
196  * </ul>
197  */
198 public int getRed () {
199     if (isDisposed()) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED);
200     return handle & 0xFF;
201 }
202
203 /**
204  * Returns an <code>RGB</code> representing the receiver.
205  *
206  * @return the RGB for the color
207  *
208  * @exception DWTException <ul>
209  *    <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
210  * </ul>
211  */
212 public RGB getRGB () {
213     if (isDisposed()) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED);
214     return new RGB(cast(int)handle & 0xFF,cast(int) (handle & 0xFF00) >> 8,cast(int) (handle & 0xFF0000) >> 16);
215 }
216
217 /**
218  * Returns an integer hash code for the receiver. Any two
219  * objects that return <code>true</code> when passed to
220  * <code>equals</code> must return the same value for this
221  * method.
222  *
223  * @return the receiver's hash
224  *
225  * @see #equals
226  */
227 public int hashCode () {
228     return handle;
229 }
230
231 /**
232  * Allocates the operating system resources associated
233  * with the receiver.
234  *
235  * @param device the device on which to allocate the color
236  * @param red the amount of red in the color
237  * @param green the amount of green in the color
238  * @param blue the amount of blue in the color
239  *
240  * @exception IllegalArgumentException <ul>
241  *    <li>ERROR_INVALID_ARGUMENT - if the red, green or blue argument is not between 0 and 255</li>
242  * </ul>
243  *
244  * @see #dispose
245  */
246 void init_(int red, int green, int blue) {
247     if (red > 255 || red < 0 || green > 255 || green < 0 || blue > 255 || blue < 0) {
248         DWT.error(DWT.ERROR_INVALID_ARGUMENT);
249     }
250     handle = (red & 0xFF) | ((green & 0xFF) << 8) | ((blue & 0xFF) << 16);
251
252     /* If this is not a palette-based device, return */
253     auto hPal = device.hPalette;
254     if (hPal is null) return;
255
256     int[] colorRefCount = device.colorRefCount;
257     /* Add this color to the default palette now */
258     /* First find out if the color already exists */
259     int index = OS.GetNearestPaletteIndex(hPal, handle);
260     /* See if the nearest color actually is the color */
261     PALETTEENTRY entry;
262     OS.GetPaletteEntries(hPal, index, 1, &entry);
263     if ((entry.peRed is cast(byte)red) && (entry.peGreen is cast(byte)green) &&
264         (entry.peBlue is cast(byte)blue)) {
265             /* Found the color. Increment the ref count and return */
266             colorRefCount[index]++;
267             return;
268     }
269     /* Didn't find the color, allocate it now. Find the first free entry */
270     int i = 0;
271     while (i < colorRefCount.length) {
272         if (colorRefCount[i] is 0) {
273             index = i;
274             break;
275         }
276         i++;
277     }
278     if (i is colorRefCount.length) {
279         /* No free entries, use the closest one */
280         /* Remake the handle from the actual rgbs */
281         handle = (entry.peRed & 0xFF) | ((entry.peGreen & 0xFF) << 8) |
282                  ((entry.peBlue & 0xFF) << 16);
283     } else {
284         /* Found a free entry */
285         entry.peRed = cast(BYTE)(red & 0xFF);
286         entry.peGreen = cast(BYTE)(green & 0xFF);
287         entry.peBlue = cast(BYTE)(blue & 0xFF);
288         entry.peFlags = 0;
289         OS.SetPaletteEntries(hPal, index, 1, &entry);
290     }
291     colorRefCount[index]++;
292 }
293
294 /**
295  * Returns <code>true</code> if the color has been disposed,
296  * and <code>false</code> otherwise.
297  * <p>
298  * This method gets the dispose state for the color.
299  * When a color has been disposed, it is an error to
300  * invoke any other method using the color.
301  *
302  * @return <code>true</code> when the color is disposed and <code>false</code> otherwise
303  */
304 override public bool isDisposed() {
305     return handle is -1;
306 }
307
308 /**
309  * Returns a string containing a concise, human-readable
310  * description of the receiver.
311  *
312  * @return a string representation of the receiver
313  */
314 override public String toString () {
315     if (isDisposed()) return "Color {*DISPOSED*}"; //$NON-NLS-1$
316     return Format( "Color {{{}, {}, {}}", getRed(), getGreen(), getBlue()); //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
317 }
318
319 /**
320  * Invokes platform specific functionality to allocate a new color.
321  * <p>
322  * <b>IMPORTANT:</b> This method is <em>not</em> part of the public
323  * API for <code>Color</code>. It is marked public only so that it
324  * can be shared within the packages provided by DWT. It is not
325  * available on all platforms, and should never be called from
326  * application code.
327  * </p>
328  *
329  * @param device the device on which to allocate the color
330  * @param handle the handle for the color
331  * @return a new color object containing the specified device and handle
332  */
333 public static Color win32_new(Device device, int handle) {
334     Color color = new Color(device);
335     color.handle = handle;
336     return color;
337 }
338
339 }
Note: See TracBrowser for help on using the browser.