Mercurial > projects > dwt-addons
annotate dwtx/jface/resource/ImageRegistry.d @ 200:eb3414669eb0 default tip
fix for dmd 1.041 and tango 0.99.8
author | Frank Benoit <benoit@tionex.de> |
---|---|
date | Sat, 28 Mar 2009 03:09:57 +0100 |
parents | 04b47443bb01 |
children |
rev | line source |
---|---|
8 | 1 /******************************************************************************* |
90 | 2 * Copyright (c) 2000, 2008 IBM Corporation and others. |
8 | 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 * Steven Ketcham (sketcham@dsicdi.com) - Bug 42451 | |
11 * [Dialogs] ImageRegistry throws null pointer exception in | |
12 * application with multiple Display's | |
13 * Port to the D programming language: | |
14 * Frank Benoit <benoit@tionex.de> | |
15 *******************************************************************************/ | |
16 module dwtx.jface.resource.ImageRegistry; | |
17 | |
18 import dwtx.jface.resource.ImageDescriptor; | |
19 import dwtx.jface.resource.ResourceManager; | |
20 import dwtx.jface.resource.DeviceResourceException; | |
21 import dwtx.jface.resource.JFaceResources; | |
22 | |
23 | |
24 // import java.util.Iterator; | |
25 // import java.util.Map; | |
26 | |
27 import dwt.DWT; | |
28 import dwt.graphics.Device; | |
29 import dwt.graphics.Image; | |
30 import dwt.graphics.ImageData; | |
31 import dwt.widgets.Display; | |
32 import dwtx.core.runtime.Assert; | |
33 import dwtx.jface.dialogs.Dialog; | |
34 | |
35 import dwt.dwthelper.utils; | |
104
04b47443bb01
Reworked the collection uses to make use of a wrapper collection that is compatible to the Java Collections.
Frank Benoit <benoit@tionex.de>
parents:
90
diff
changeset
|
36 import dwtx.dwtxhelper.Collection; |
8 | 37 import dwt.dwthelper.Runnable; |
38 | |
39 /** | |
40 * An image registry maintains a mapping between symbolic image names | |
41 * and DWT image objects or special image descriptor objects which | |
42 * defer the creation of DWT image objects until they are needed. | |
43 * <p> | |
44 * An image registry owns all of the image objects registered | |
45 * with it, and automatically disposes of them when the DWT Display | |
46 * that creates the images is disposed. Because of this, clients do not | |
47 * need to (indeed, must not attempt to) dispose of these images themselves. | |
48 * </p> | |
49 * <p> | |
50 * Clients may instantiate this class (it was not designed to be subclassed). | |
51 * </p> | |
52 * <p> | |
53 * Unlike the FontRegistry, it is an error to replace images. As a result | |
54 * there are no events that fire when values are changed in the registry | |
55 * </p> | |
90 | 56 * @noextend This class is not intended to be subclassed by clients. |
8 | 57 */ |
58 public class ImageRegistry { | |
59 /** | |
60 * display used when getting images | |
61 */ | |
62 private Display display; | |
63 | |
64 private ResourceManager manager; | |
65 | |
104
04b47443bb01
Reworked the collection uses to make use of a wrapper collection that is compatible to the Java Collections.
Frank Benoit <benoit@tionex.de>
parents:
90
diff
changeset
|
66 private Map table; |
8 | 67 |
68 private Runnable disposeRunnable; | |
69 private void init_disposeRunnable(){ | |
70 disposeRunnable = new class Runnable { | |
71 public void run() { | |
72 dispose(); | |
73 } | |
74 }; | |
75 } | |
76 | |
77 /** | |
78 * Contains the data for an entry in the registry. | |
79 */ | |
80 private static class Entry { | |
81 /** the image */ | |
82 protected Image image; | |
83 | |
84 /** the descriptor */ | |
85 protected ImageDescriptor descriptor; | |
86 } | |
87 | |
88 private static class OriginalImageDescriptor : ImageDescriptor { | |
89 private Image original; | |
90 private int refCount = 0; | |
91 private Device originalDisplay; | |
92 | |
93 /** | |
94 * @param original the original image | |
95 * @param originalDisplay the device the image is part of | |
96 */ | |
97 public this(Image original, Device originalDisplay) { | |
98 this.original = original; | |
99 this.originalDisplay = originalDisplay; | |
100 } | |
101 | |
43
ea8ff534f622
Fix override and super aliases
Frank Benoit <benoit@tionex.de>
parents:
8
diff
changeset
|
102 public override Object createResource(Device device) { |
8 | 103 if (device is originalDisplay) { |
104 refCount++; | |
105 return original; | |
106 } | |
107 return super.createResource(device); | |
108 } | |
109 | |
43
ea8ff534f622
Fix override and super aliases
Frank Benoit <benoit@tionex.de>
parents:
8
diff
changeset
|
110 public override void destroyResource(Object toDispose) { |
8 | 111 if (original is toDispose) { |
112 refCount--; | |
113 if (refCount is 0) { | |
114 original.dispose(); | |
115 original = null; | |
116 } | |
117 } else { | |
118 super.destroyResource(toDispose); | |
119 } | |
120 } | |
121 | |
122 /* (non-Javadoc) | |
123 * @see dwtx.jface.resource.ImageDescriptor#getImageData() | |
124 */ | |
43
ea8ff534f622
Fix override and super aliases
Frank Benoit <benoit@tionex.de>
parents:
8
diff
changeset
|
125 public override ImageData getImageData() { |
8 | 126 return original.getImageData(); |
127 } | |
128 } | |
129 | |
130 /** | |
131 * Creates an empty image registry. | |
132 * <p> | |
133 * There must be an DWT Display created in the current | |
134 * thread before calling this method. | |
135 * </p> | |
136 */ | |
137 public this() { | |
138 this(Display.getCurrent()); | |
139 } | |
140 | |
141 /** | |
142 * Creates an empty image registry using the given resource manager to allocate images. | |
143 * | |
144 * @param manager the resource manager used to allocate images | |
145 * | |
146 * @since 3.1 | |
147 */ | |
148 public this(ResourceManager manager) { | |
149 init_disposeRunnable(); | |
150 Assert.isNotNull(manager); | |
151 Device dev = manager.getDevice(); | |
152 if ( auto disp = cast(Display)dev ) { | |
153 this.display = disp; | |
154 } | |
155 this.manager = manager; | |
156 manager.disposeExec(disposeRunnable); | |
157 } | |
158 | |
159 /** | |
160 * Creates an empty image registry. | |
161 * | |
162 * @param display this <code>Display</code> must not be | |
163 * <code>null</code> and must not be disposed in order | |
164 * to use this registry | |
165 */ | |
166 public this(Display display) { | |
167 this(JFaceResources.getResources(display)); | |
168 } | |
169 | |
170 /** | |
171 * Returns the image associated with the given key in this registry, | |
172 * or <code>null</code> if none. | |
173 * | |
174 * @param key the key | |
175 * @return the image, or <code>null</code> if none | |
176 */ | |
177 public Image get(String key) { | |
178 | |
179 // can be null | |
180 if (key is null) { | |
181 return null; | |
182 } | |
183 | |
184 if (display !is null) { | |
185 /** | |
186 * NOTE, for backwards compatibility the following images are supported | |
187 * here, they should never be disposed, hence we explicitly return them | |
188 * rather then registering images that DWT will dispose. | |
189 * | |
190 * Applications should go direclty to DWT for these icons. | |
191 * | |
192 * @see Display.getSystemIcon(int ID) | |
193 */ | |
194 int swtKey = -1; | |
195 if (key.equals(Dialog.DLG_IMG_INFO)) { | |
196 swtKey = DWT.ICON_INFORMATION; | |
197 } | |
198 if (key.equals(Dialog.DLG_IMG_QUESTION)) { | |
199 swtKey = DWT.ICON_QUESTION; | |
200 } | |
201 if (key.equals(Dialog.DLG_IMG_WARNING)) { | |
202 swtKey = DWT.ICON_WARNING; | |
203 } | |
204 if (key.equals(Dialog.DLG_IMG_ERROR)) { | |
205 swtKey = DWT.ICON_ERROR; | |
206 } | |
207 // if we actually just want to return an DWT image do so without | |
208 // looking in the registry | |
209 if (swtKey !is -1) { | |
210 Image[1] image; | |
211 int id = swtKey; | |
212 display.syncExec(new class Runnable { | |
213 public void run() { | |
214 image[0] = display.getSystemImage(id); | |
215 } | |
216 }); | |
217 return image[0]; | |
218 } | |
219 } | |
220 | |
221 Entry entry = getEntry(key); | |
222 if (entry is null) { | |
223 return null; | |
224 } | |
225 | |
226 if (entry.image is null) { | |
227 entry.image = manager.createImageWithDefault(entry.descriptor); | |
228 } | |
229 | |
230 return entry.image; | |
231 } | |
232 | |
233 /** | |
234 * Returns the descriptor associated with the given key in this registry, | |
235 * or <code>null</code> if none. | |
236 * | |
237 * @param key the key | |
238 * @return the descriptor, or <code>null</code> if none | |
239 * @since 2.1 | |
240 */ | |
241 public ImageDescriptor getDescriptor(String key) { | |
242 Entry entry = getEntry(key); | |
243 if (entry is null) { | |
244 return null; | |
245 } | |
246 | |
247 return entry.descriptor; | |
248 } | |
249 | |
250 /** | |
251 * Adds (or replaces) an image descriptor to this registry. The first time | |
252 * this new entry is retrieved, the image descriptor's image will be computed | |
253 * (via </code>ImageDescriptor.createImage</code>) and remembered. | |
254 * This method replaces an existing image descriptor associated with the | |
255 * given key, but fails if there is a real image associated with it. | |
256 * | |
257 * @param key the key | |
258 * @param descriptor the ImageDescriptor | |
259 * @exception IllegalArgumentException if the key already exists | |
260 */ | |
261 public void put(String key, ImageDescriptor descriptor) { | |
262 Entry entry = getEntry(key); | |
263 if (entry is null) { | |
264 entry = new Entry(); | |
104
04b47443bb01
Reworked the collection uses to make use of a wrapper collection that is compatible to the Java Collections.
Frank Benoit <benoit@tionex.de>
parents:
90
diff
changeset
|
265 getTable().put(stringcast(key), entry); |
8 | 266 } |
267 | |
268 if (entry.image !is null) { | |
269 throw new IllegalArgumentException( | |
270 "ImageRegistry key already in use: " ~ key); //$NON-NLS-1$ | |
271 } | |
272 | |
273 entry.descriptor = descriptor; | |
274 } | |
275 | |
276 /** | |
277 * Adds an image to this registry. This method fails if there | |
278 * is already an image or descriptor for the given key. | |
279 * <p> | |
280 * Note that an image registry owns all of the image objects registered | |
281 * with it, and automatically disposes of them when the DWT Display is disposed. | |
282 * Because of this, clients must not register an image object | |
283 * that is managed by another object. | |
284 * </p> | |
285 * | |
286 * @param key the key | |
287 * @param image the image, should not be <code>null</code> | |
288 * @exception IllegalArgumentException if the key already exists | |
289 */ | |
290 public void put(String key, Image image) { | |
291 Entry entry = getEntry(key); | |
292 | |
293 if (entry is null) { | |
294 entry = new Entry(); | |
295 putEntry(key, entry); | |
296 } | |
297 | |
298 if (entry.image !is null || entry.descriptor !is null) { | |
299 throw new IllegalArgumentException( | |
300 "ImageRegistry key already in use: " ~ key); //$NON-NLS-1$ | |
301 } | |
302 | |
70
46a6e0e6ccd4
Merge with d-fied sources of 3.4M7
Frank Benoit <benoit@tionex.de>
parents:
52
diff
changeset
|
303 // Check for a null image here, otherwise the problem won't appear |
46a6e0e6ccd4
Merge with d-fied sources of 3.4M7
Frank Benoit <benoit@tionex.de>
parents:
52
diff
changeset
|
304 // until dispose. |
8 | 305 // See https://bugs.eclipse.org/bugs/show_bug.cgi?id=130315 |
70
46a6e0e6ccd4
Merge with d-fied sources of 3.4M7
Frank Benoit <benoit@tionex.de>
parents:
52
diff
changeset
|
306 Assert.isNotNull(image, "Cannot register a null image."); //$NON-NLS-1$ |
8 | 307 entry.image = image; |
308 entry.descriptor = new OriginalImageDescriptor(image, manager.getDevice()); | |
309 | |
310 try { | |
311 manager.create(entry.descriptor); | |
312 } catch (DeviceResourceException e) { | |
313 } | |
314 } | |
315 | |
316 /** | |
317 * Removes an image from this registry. | |
318 * If an DWT image was allocated, it is disposed. | |
319 * This method has no effect if there is no image or descriptor for the given key. | |
320 * @param key the key | |
321 */ | |
322 public void remove(String key) { | |
323 ImageDescriptor descriptor = getDescriptor(key); | |
324 if (descriptor !is null) { | |
325 manager.destroy(descriptor); | |
104
04b47443bb01
Reworked the collection uses to make use of a wrapper collection that is compatible to the Java Collections.
Frank Benoit <benoit@tionex.de>
parents:
90
diff
changeset
|
326 getTable().remove(stringcast(key)); |
8 | 327 } |
328 } | |
329 | |
330 private Entry getEntry(String key) { | |
104
04b47443bb01
Reworked the collection uses to make use of a wrapper collection that is compatible to the Java Collections.
Frank Benoit <benoit@tionex.de>
parents:
90
diff
changeset
|
331 return cast(Entry) getTable().get(stringcast(key)); |
8 | 332 } |
333 | |
334 private void putEntry(String key, Entry entry) { | |
104
04b47443bb01
Reworked the collection uses to make use of a wrapper collection that is compatible to the Java Collections.
Frank Benoit <benoit@tionex.de>
parents:
90
diff
changeset
|
335 getTable().put(stringcast(key), entry); |
8 | 336 } |
337 | |
104
04b47443bb01
Reworked the collection uses to make use of a wrapper collection that is compatible to the Java Collections.
Frank Benoit <benoit@tionex.de>
parents:
90
diff
changeset
|
338 private Map getTable() { |
8 | 339 if (table is null) { |
104
04b47443bb01
Reworked the collection uses to make use of a wrapper collection that is compatible to the Java Collections.
Frank Benoit <benoit@tionex.de>
parents:
90
diff
changeset
|
340 table = new HashMap(10); |
8 | 341 } |
342 return table; | |
343 } | |
344 | |
345 /** | |
346 * Disposes this image registry, disposing any images | |
347 * that were allocated for it, and clearing its entries. | |
348 * | |
349 * @since 3.1 | |
350 */ | |
351 public void dispose() { | |
352 manager.cancelDisposeExec(disposeRunnable); | |
353 | |
354 if (table !is null) { | |
104
04b47443bb01
Reworked the collection uses to make use of a wrapper collection that is compatible to the Java Collections.
Frank Benoit <benoit@tionex.de>
parents:
90
diff
changeset
|
355 for (Iterator i = table.values().iterator(); i.hasNext();) { |
04b47443bb01
Reworked the collection uses to make use of a wrapper collection that is compatible to the Java Collections.
Frank Benoit <benoit@tionex.de>
parents:
90
diff
changeset
|
356 Entry entry = cast(Entry) i.next(); |
8 | 357 if (entry.image !is null) { |
358 manager.destroyImage(entry.descriptor); | |
359 } | |
360 } | |
361 table = null; | |
362 } | |
363 display = null; | |
364 } | |
365 } |