001: /*
002: * uDig - User Friendly Desktop Internet GIS client
003: * http://udig.refractions.net
004: * (C) 2004, Refractions Research Inc.
005: *
006: * This library is free software; you can redistribute it and/or
007: * modify it under the terms of the GNU Lesser General Public
008: * License as published by the Free Software Foundation;
009: * version 2.1 of the License.
010: *
011: * This library is distributed in the hope that it will be useful,
012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * Lesser General Public License for more details.
015: *
016: */
017: package net.refractions.udig.ui;
018:
019: import java.util.Arrays;
020:
021: import org.eclipse.jface.resource.CompositeImageDescriptor;
022: import org.eclipse.jface.resource.ImageDescriptor;
023: import org.eclipse.swt.graphics.Image;
024: import org.eclipse.swt.graphics.ImageData;
025: import org.eclipse.swt.graphics.Point;
026: import org.eclipse.swt.graphics.Rectangle;
027:
028: /**
029: * An DecoratorOverlayIcon consists of a main icon and several adornments.
030: * <p>
031: * Eclipse has many implementations of this class - all of them are internal.
032: * This one is based on org.eclipse.ui.internal.decorators.DecoratorOverlayIcon
033: * and has the advantage of having an equals and hashcode impemenation. This
034: * allows the use of the resulting ImageDescriptors to be cached using weak
035: * references.
036: * </p>
037: * <p>
038: * Overlays are of course 7x8 icons with a white keyline around them.
039: * <p>
040: * Example use:<pre><code>
041: * new DecoratorOverlayIcon(base,
042: * new ImageDescriptor[][]={
043: * null, // TOP_LEFT unsure if we will use this
044: * modified, // TOP_RIGHT indicate content modified (w/ *)
045: * status, // BOTTOM_LEFT called the auxiliary overlay warn, error, success
046: * cached, // BOTTOM_RIGHT not yet defined, recommened cache status...
047: * null, // UNDERLAY not sure if we will use this
048: * }
049: * );
050: * </code></pre>
051: * </p>
052: */
053: public class DecoratorOverlayIcon extends CompositeImageDescriptor {
054: static final Point DEFAULT_SIZE = new Point(22, 16);
055:
056: // the base image
057: private Image base;
058:
059: // the overlay images
060: private ImageDescriptor[] overlays;
061:
062: // the size
063: private Point size;
064:
065: public static final int TOP_LEFT = 0;
066:
067: public static final int TOP_RIGHT = 1;
068:
069: public static final int BOTTOM_LEFT = 2;
070:
071: public static final int BOTTOM_RIGHT = 3;
072:
073: public static final int UNDERLAY = 4;
074:
075: /**
076: * OverlayIcon constructor defaults to size of base image.
077: * <p>
078: * Overlays are of course 7x8 icons with a white keyline around them.
079: * </p>
080: * <p>
081: * Example use:<pre><code>
082: * new DecoratorOverlayIcon(base,
083: * new ImageDescriptor[][]={
084: * null, // TOP_LEFT unsure if we will use this
085: * modified, // TOP_RIGHT indicate content modified (w/ *)
086: * status, // BOTTOM_LEFT called the auxiliary overlay warn, error, success
087: * cached, // BOTTOM_RIGHT not yet defined, recommened cache status...
088: * null, // UNDERLAY not sure if we will use this
089: * }
090: * );
091: * </code></pre>
092: * </p>
093: * @param base the base image
094: * @param overlays the overlay images
095: */
096: public DecoratorOverlayIcon(Image baseImage,
097: ImageDescriptor[] overlaysArray) {
098: this .base = baseImage;
099: this .overlays = new ImageDescriptor[overlaysArray.length];
100: int i = overlaysArray.length;
101: this .overlays = new ImageDescriptor[i];
102:
103: System.arraycopy(overlaysArray, 0, overlays, 0, i);
104: Rectangle bounds = baseImage.getBounds();
105: this .size = new Point(bounds.width, bounds.height);
106: }
107:
108: /**
109: * OverlayIcon constructor allowing explicit size.
110: * <p>
111: * Overlays are of course 7x8 icons with a white keyline around them.
112: * </p>
113: * <p>
114: * Example use:<pre><code>
115: * new DecoratorOverlayIcon(base,
116: * new ImageDescriptor[][]={
117: * null, // TOP_LEFT unsure if we will use this
118: * modified, // TOP_RIGHT indicate content modified (w/ *)
119: * status, // BOTTOM_LEFT called the auxiliary overlay warn, error, success
120: * cached, // BOTTOM_RIGHT not yet defined, recommened cache status...
121: * null, // UNDERLAY not sure if we will use this
122: * },
123: * new Point(22,16)
124: * );
125: * </code></pre>
126: * </p>
127: * @param base the base image
128: * @param overlays the overlay images
129: * @param size the size, 22x16 if null
130: */
131: public DecoratorOverlayIcon(Image baseImage,
132: ImageDescriptor[] overlaysArray, Point sizeValue) {
133: this .base = baseImage;
134: int i = 0;
135: if (overlaysArray != null)
136: i = overlaysArray.length;
137: this .overlays = new ImageDescriptor[i];
138:
139: System.arraycopy(overlaysArray, 0, overlays, 0, i);
140: this .size = sizeValue;
141: }
142:
143: /**
144: * Draw the overlays for the reciever.
145: */
146: protected void drawOverlays(ImageDescriptor[] overlaysArray) {
147:
148: for (int i = 0; i < overlays.length; i++) {
149: ImageDescriptor overlay = overlaysArray[i];
150: if (overlay == null)
151: continue;
152:
153: ImageData overlayData = overlay.getImageData();
154: //Use the missing descriptor if it is not there.
155: if (overlayData == null)
156: overlayData = ImageDescriptor
157: .getMissingImageDescriptor().getImageData();
158: switch (i) {
159: case TOP_LEFT:
160: drawImage(overlayData, 0, 0);
161: break;
162: case TOP_RIGHT:
163: drawImage(overlayData, size.x - overlayData.width, 0);
164: break;
165: case BOTTOM_LEFT:
166: drawImage(overlayData, 0, size.y - overlayData.height);
167: break;
168: case BOTTOM_RIGHT:
169: drawImage(overlayData, size.x - overlayData.width,
170: size.y - overlayData.height);
171: break;
172: }
173: }
174: }
175:
176: /** Note this can only be equal to another DecoratorOverlayIcon. */
177: public boolean equals(Object o) {
178: if (!(o instanceof DecoratorOverlayIcon))
179: return false;
180: DecoratorOverlayIcon other = (DecoratorOverlayIcon) o;
181: return base.equals(other.base)
182: && Arrays.equals(overlays, other.overlays);
183: }
184:
185: /** Hascode for a base with no overlays will be the same as for a base. */
186: public int hashCode() {
187: int code = base.hashCode();
188: for (int i = 0; i < overlays.length; i++) {
189: if (overlays[i] != null)
190: code ^= overlays[i].hashCode();
191: }
192: return code;
193: }
194:
195: protected void drawCompositeImage(int width, int height) {
196: ImageDescriptor underlay = overlays[UNDERLAY];
197: if (underlay != null)
198: drawImage(underlay.getImageData(), 0, 0);
199: drawImage(base.getImageData(), 0, 0);
200: drawOverlays(overlays);
201: }
202:
203: protected Point getSize() {
204: return size;
205: }
206: }
|