comparison org.eclipse.jface/src/org/eclipse/jface/resource/ImageRegistry.d @ 12:bc29606a740c

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