75
|
1 /*******************************************************************************
|
|
2 * Copyright (c) 2000, 2007 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 * Chriss Gross (schtoo@schtoo.com) - fix for 61670
|
|
11 * Port to the D programming language:
|
|
12 * Frank Benoit <benoit@tionex.de>
|
|
13 *******************************************************************************/
|
|
14 module dwtx.ui.forms.widgets.ImageHyperlink;
|
|
15
|
|
16 import dwtx.ui.forms.widgets.Hyperlink;
|
|
17
|
|
18 import dwt.DWT;
|
|
19 import dwt.graphics.GC;
|
|
20 import dwt.graphics.Image;
|
|
21 import dwt.graphics.Point;
|
|
22 import dwt.graphics.Rectangle;
|
|
23 import dwt.widgets.Composite;
|
|
24 import dwt.widgets.Event;
|
|
25
|
|
26 import dwt.dwthelper.utils;
|
|
27
|
|
28 /**
|
|
29 * This class extends hyperlink widget by adding the capability to render an
|
|
30 * image relative to the text. If no text has been set, only image will be
|
|
31 * shown. Images for hover and active states can be set in addition to the
|
|
32 * normal state image.
|
|
33 * <p>
|
|
34 * When image is taller than the text, additional style can be provided to
|
|
35 * control vertical alignment (supported values are DWT.TOP, DWT.BOTTOM and
|
|
36 * DWT.CENTER).
|
|
37 * <p>
|
|
38 * The class does not need to be sublassed but it is allowed to do so if some
|
|
39 * aspect of the image hyperlink needs to be modified.
|
|
40 *
|
|
41 * @since 3.0
|
|
42 */
|
|
43 public class ImageHyperlink : Hyperlink {
|
|
44 /**
|
|
45 * Amount of pixels between the image and the text (default is 5).
|
|
46 */
|
|
47 public int textSpacing = 5;
|
|
48
|
|
49 private Image image;
|
|
50
|
|
51 private Image hoverImage;
|
|
52
|
|
53 private Image activeImage;
|
|
54
|
|
55 private int state;
|
|
56
|
|
57 private static const int HOVER = 1 << 1;
|
|
58
|
|
59 private static const int ACTIVE = 1 << 2;
|
|
60
|
|
61 private int verticalAlignment = DWT.CENTER;
|
|
62
|
|
63 private int horizontalAlignment = DWT.LEFT;
|
|
64
|
|
65 /**
|
|
66 * Creates the image hyperlink instance.
|
|
67 *
|
|
68 * @param parent
|
|
69 * the control parent
|
|
70 * @param style
|
|
71 * the control style (DWT.WRAP, BOTTOM, TOP, MIDDLE, LEFT, RIGHT)
|
|
72 */
|
|
73 public this(Composite parent, int style) {
|
|
74 super(parent, removeAlignment(style));
|
|
75 extractAlignment(style);
|
|
76 }
|
|
77
|
|
78 /*
|
|
79 * (non-Javadoc)
|
|
80 *
|
|
81 * @see dwtx.ui.forms.widgets.AbstractHyperlink#paintHyperlink(dwt.events.PaintEvent)
|
|
82 */
|
|
83 protected void paintHyperlink(GC gc) {
|
|
84 paintHyperlink(gc, getClientArea());
|
|
85 }
|
|
86
|
|
87 protected void paintHyperlink(GC gc, Rectangle bounds) {
|
|
88 Image image = null;
|
|
89 if ((state & ACTIVE) !is 0)
|
|
90 image = activeImage;
|
|
91 else if ((state & HOVER) !is 0)
|
|
92 image = hoverImage;
|
|
93 if (image is null)
|
|
94 image = this.image;
|
|
95 Rectangle ibounds = image !is null ? image.getBounds() : new Rectangle(0, 0, 0, 0);
|
|
96 Point maxsize = computeMaxImageSize();
|
|
97 int spacing = image !is null?textSpacing:0;
|
|
98 int textWidth = bounds.width - maxsize.x - spacing
|
|
99 - marginWidth - marginWidth;
|
|
100 int y = bounds.y+marginHeight + maxsize.y / 2 - ibounds.height / 2;
|
|
101
|
|
102 if (horizontalAlignment is DWT.LEFT) {
|
|
103 int x = bounds.x+marginWidth + maxsize.x / 2 - ibounds.width / 2;
|
|
104 int textX = bounds.x + marginWidth + maxsize.x + spacing;
|
|
105 if (image !is null)
|
|
106 gc.drawImage(image, x, y);
|
|
107 if (getText() !is null)
|
|
108 drawText(gc, bounds, textX, textWidth);
|
|
109 } else if (horizontalAlignment is DWT.RIGHT) {
|
|
110 int x = bounds.x+marginWidth;
|
|
111 if (getText() !is null) {
|
|
112 x += drawText(gc, bounds, x, textWidth);
|
|
113 }
|
|
114 x += maxsize.x / 2 - ibounds.width / 2 + spacing;
|
|
115 if (image !is null)
|
|
116 gc.drawImage(image, x, y);
|
|
117 }
|
|
118 }
|
|
119
|
|
120 private int drawText(GC gc, Rectangle clientArea, int textX, int textWidth) {
|
|
121 Point textSize = computeTextSize(textWidth, DWT.DEFAULT);
|
|
122 int slotHeight = clientArea.height - marginHeight - marginHeight;
|
|
123 int textY;
|
|
124 textWidth = textSize.x;
|
|
125 int textHeight = textSize.y;
|
|
126 if (verticalAlignment is DWT.BOTTOM) {
|
|
127 textY = marginHeight + slotHeight - textHeight;
|
|
128 } else if (verticalAlignment is DWT.CENTER) {
|
|
129 textY = marginHeight + slotHeight / 2 - textHeight / 2;
|
|
130 } else {
|
|
131 textY = marginHeight;
|
|
132 }
|
|
133 paintText(gc, new Rectangle(textX, textY, textWidth, textHeight));
|
|
134 return textWidth;
|
|
135 }
|
|
136
|
|
137 /**
|
|
138 * Computes the control size by reserving space for images in addition to
|
|
139 * text.
|
|
140 *
|
|
141 * @param wHint
|
|
142 * width hint
|
|
143 * @param hHint
|
|
144 * height hint
|
|
145 * @param changed
|
|
146 * if <code>true</code>, any cached layout data should be
|
|
147 * computed anew
|
|
148 */
|
|
149 public Point computeSize(int wHint, int hHint, bool changed) {
|
|
150 checkWidget();
|
|
151 Point isize = computeMaxImageSize();
|
|
152 int spacing = isize.x>0?textSpacing:0;
|
|
153 Point textSize = null;
|
|
154 if (getText() !is null) {
|
|
155 int innerWHint = wHint;
|
|
156 if (wHint !is DWT.DEFAULT) {
|
|
157 innerWHint = wHint - 2 * marginWidth - isize.x - spacing;
|
|
158 }
|
|
159 textSize = super.computeSize(innerWHint, hHint, changed);
|
|
160 }
|
|
161 int width = isize.x;
|
|
162 int height = isize.y;
|
|
163 if (textSize !is null) {
|
|
164 width += spacing;
|
|
165 width += textSize.x;
|
|
166 height = Math.max(height, textSize.y);
|
|
167 }
|
|
168 width += 2 * marginWidth;
|
|
169 height += 2 * marginHeight;
|
|
170 return new Point(width, height);
|
|
171 }
|
|
172
|
|
173 protected void handleEnter(Event e) {
|
|
174 state = HOVER;
|
|
175 super.handleEnter(e);
|
|
176 }
|
|
177
|
|
178 protected void handleExit(Event e) {
|
|
179 state = 0;
|
|
180 super.handleExit(e);
|
|
181 }
|
|
182
|
|
183 protected void handleActivate(Event e) {
|
|
184 state &= ACTIVE;
|
|
185 redraw();
|
|
186 super.handleActivate(e);
|
|
187 state &= ~ACTIVE;
|
|
188 if (!isDisposed())
|
|
189 redraw();
|
|
190 }
|
|
191
|
|
192 /**
|
|
193 * Returns active image.
|
|
194 *
|
|
195 * @return active image or <code>null</code> if not set.
|
|
196 */
|
|
197 public Image getActiveImage() {
|
|
198 return activeImage;
|
|
199 }
|
|
200
|
|
201 /**
|
|
202 * Sets the image to show when link is activated.
|
|
203 *
|
|
204 * @param activeImage
|
|
205 *
|
|
206 */
|
|
207 public void setActiveImage(Image activeImage) {
|
|
208 this.activeImage = activeImage;
|
|
209 }
|
|
210
|
|
211 /**
|
|
212 * Returns the hover image.
|
|
213 *
|
|
214 * @return hover image or <code>null</code> if not set.
|
|
215 */
|
|
216 public Image getHoverImage() {
|
|
217 return hoverImage;
|
|
218 }
|
|
219
|
|
220 /**
|
|
221 * Sets the image to show when link is hover state (on mouse over).
|
|
222 *
|
|
223 * @param hoverImage
|
|
224 */
|
|
225 public void setHoverImage(Image hoverImage) {
|
|
226 this.hoverImage = hoverImage;
|
|
227 }
|
|
228
|
|
229 /**
|
|
230 * Returns the image to show in the normal state.
|
|
231 *
|
|
232 * @return normal image or <code>null</code> if not set.
|
|
233 */
|
|
234 public Image getImage() {
|
|
235 return image;
|
|
236 }
|
|
237
|
|
238 /**
|
|
239 * Sets the image to show when link is in the normal state.
|
|
240 *
|
|
241 * @param image
|
|
242 */
|
|
243 public void setImage(Image image) {
|
|
244 this.image = image;
|
|
245 }
|
|
246
|
|
247 private Point computeMaxImageSize() {
|
|
248 int x = 0;
|
|
249 int y = 0;
|
|
250 if (image !is null) {
|
|
251 x = Math.max(image.getBounds().width, x);
|
|
252 y = Math.max(image.getBounds().height, y);
|
|
253 }
|
|
254 if (hoverImage !is null) {
|
|
255 x = Math.max(hoverImage.getBounds().width, x);
|
|
256 y = Math.max(hoverImage.getBounds().height, y);
|
|
257 }
|
|
258 if (activeImage !is null) {
|
|
259 x = Math.max(activeImage.getBounds().width, x);
|
|
260 y = Math.max(activeImage.getBounds().height, y);
|
|
261 }
|
|
262 return new Point(x, y);
|
|
263 }
|
|
264
|
|
265 private static int removeAlignment(int style) {
|
|
266 int resultStyle = style;
|
|
267 if ((style & DWT.CENTER) !is 0) {
|
|
268 resultStyle &= (~DWT.CENTER);
|
|
269 }
|
|
270 if ((style & DWT.TOP) !is 0) {
|
|
271 resultStyle &= (~DWT.TOP);
|
|
272 }
|
|
273 if ((style & DWT.BOTTOM) !is 0) {
|
|
274 resultStyle &= (~DWT.BOTTOM);
|
|
275 }
|
|
276 if ((style & DWT.LEFT) !is 0) {
|
|
277 resultStyle &= (~DWT.LEFT);
|
|
278 }
|
|
279 if ((style & DWT.RIGHT) !is 0) {
|
|
280 resultStyle &= (~DWT.RIGHT);
|
|
281 }
|
|
282 return resultStyle;
|
|
283 }
|
|
284
|
|
285 private void extractAlignment(int style) {
|
|
286 if ((style & DWT.CENTER) !is 0) {
|
|
287 verticalAlignment = DWT.CENTER;
|
|
288 } else if ((style & DWT.TOP) !is 0) {
|
|
289 verticalAlignment = DWT.TOP;
|
|
290 } else if ((style & DWT.BOTTOM) !is 0) {
|
|
291 verticalAlignment = DWT.BOTTOM;
|
|
292 }
|
|
293 if ((style & DWT.LEFT) !is 0) {
|
|
294 horizontalAlignment = DWT.LEFT;
|
|
295 } else if ((style & DWT.RIGHT) !is 0) {
|
|
296 horizontalAlignment = DWT.RIGHT;
|
|
297 }
|
|
298 }
|
|
299 }
|