Mercurial > projects > dwt-addons
annotate dwtx/ui/forms/widgets/AbstractHyperlink.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 | c3583c6ec027 |
children |
rev | line source |
---|---|
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 * Port to the D programming language: | |
11 * Frank Benoit <benoit@tionex.de> | |
12 *******************************************************************************/ | |
13 module dwtx.ui.forms.widgets.AbstractHyperlink; | |
14 | |
15 | |
16 import dwt.DWT; | |
17 import dwt.accessibility.ACC; | |
18 import dwt.events.PaintEvent; | |
19 import dwt.events.PaintListener; | |
20 import dwt.graphics.GC; | |
21 import dwt.graphics.Point; | |
22 import dwt.graphics.Rectangle; | |
23 import dwt.widgets.Canvas; | |
24 import dwt.widgets.Composite; | |
25 import dwt.widgets.Event; | |
26 import dwt.widgets.Listener; | |
27 import dwtx.core.runtime.ListenerList; | |
28 import dwtx.ui.forms.events.HyperlinkEvent; | |
29 import dwtx.ui.forms.events.IHyperlinkListener; | |
30 import dwtx.ui.internal.forms.widgets.FormsResources; | |
31 | |
32 import dwt.dwthelper.utils; | |
33 | |
34 /** | |
35 * This is the base class for custom hyperlink widget. It is responsible for | |
36 * processing mouse and keyboard events, and converting them into unified | |
37 * hyperlink events. Subclasses are responsible for rendering the hyperlink in | |
38 * the client area. | |
39 * | |
40 * @since 3.0 | |
41 */ | |
42 public abstract class AbstractHyperlink : Canvas { | |
43 private bool hasFocus; | |
44 bool paintFocus=true; | |
45 | |
46 /* | |
47 * Armed link is one that will activate on a mouse up event, i.e. | |
48 * it has received a mouse down and mouse still on top of it. | |
49 */ | |
50 private bool armed; | |
51 | |
52 private ListenerList listeners; | |
53 | |
54 /** | |
55 * Amount of the margin width around the hyperlink (default is 1). | |
56 */ | |
57 protected int marginWidth = 1; | |
58 | |
59 /** | |
60 * Amount of the margin height around the hyperlink (default is 1). | |
61 */ | |
62 protected int marginHeight = 1; | |
63 | |
64 /** | |
65 * Creates a new hyperlink in the provided parent. | |
66 * | |
67 * @param parent | |
68 * the control parent | |
69 * @param style | |
70 * the widget style | |
71 */ | |
72 public this(Composite parent, int style) { | |
73 super(parent, style); | |
74 addListener(DWT.KeyDown, new class Listener { | |
75 public void handleEvent(Event e) { | |
76 if (e.character is '\r') { | |
77 handleActivate(e); | |
78 } | |
79 } | |
80 }); | |
81 addPaintListener(new class PaintListener { | |
82 public void paintControl(PaintEvent e) { | |
83 paint(e); | |
84 } | |
85 }); | |
86 addListener(DWT.Traverse, new class Listener { | |
87 public void handleEvent(Event e) { | |
88 switch (e.detail) { | |
89 case DWT.TRAVERSE_PAGE_NEXT: | |
90 case DWT.TRAVERSE_PAGE_PREVIOUS: | |
91 case DWT.TRAVERSE_ARROW_NEXT: | |
92 case DWT.TRAVERSE_ARROW_PREVIOUS: | |
93 case DWT.TRAVERSE_RETURN: | |
94 e.doit = false; | |
95 return; | |
192
c3583c6ec027
Added missing default cases for switch statements
Frank Benoit <benoit@tionex.de>
parents:
75
diff
changeset
|
96 default: |
75 | 97 } |
98 e.doit = true; | |
99 } | |
100 }); | |
101 Listener listener = new class Listener { | |
102 public void handleEvent(Event e) { | |
103 switch (e.type) { | |
104 case DWT.FocusIn: | |
105 hasFocus = true; | |
106 handleEnter(e); | |
107 break; | |
108 case DWT.FocusOut: | |
109 hasFocus = false; | |
110 handleExit(e); | |
111 break; | |
112 case DWT.DefaultSelection: | |
113 handleActivate(e); | |
114 break; | |
115 case DWT.MouseEnter: | |
116 handleEnter(e); | |
117 break; | |
118 case DWT.MouseExit: | |
119 handleExit(e); | |
120 break; | |
121 case DWT.MouseDown: | |
122 handleMouseDown(e); | |
123 break; | |
124 case DWT.MouseUp: | |
125 handleMouseUp(e); | |
126 break; | |
127 case DWT.MouseMove: | |
128 handleMouseMove(e); | |
129 break; | |
192
c3583c6ec027
Added missing default cases for switch statements
Frank Benoit <benoit@tionex.de>
parents:
75
diff
changeset
|
130 default: |
75 | 131 } |
132 } | |
133 }; | |
134 addListener(DWT.MouseEnter, listener); | |
135 addListener(DWT.MouseExit, listener); | |
136 addListener(DWT.MouseDown, listener); | |
137 addListener(DWT.MouseUp, listener); | |
138 addListener(DWT.MouseMove, listener); | |
139 addListener(DWT.FocusIn, listener); | |
140 addListener(DWT.FocusOut, listener); | |
141 setCursor(FormsResources.getHandCursor()); | |
142 } | |
143 | |
144 /** | |
145 * Adds the event listener to this hyperlink. | |
146 * | |
147 * @param listener | |
148 * the event listener to add | |
149 */ | |
150 public void addHyperlinkListener(IHyperlinkListener listener) { | |
151 if (listeners is null) | |
152 listeners = new ListenerList(); | |
153 listeners.add(cast(Object)listener); | |
154 } | |
155 | |
156 /** | |
157 * Removes the event listener from this hyperlink. | |
158 * | |
159 * @param listener | |
160 * the event listener to remove | |
161 */ | |
162 public void removeHyperlinkListener(IHyperlinkListener listener) { | |
163 if (listeners is null) | |
164 return; | |
165 listeners.remove(cast(Object)listener); | |
166 } | |
167 | |
168 /** | |
169 * Returns the selection state of the control. When focus is gained, the | |
170 * state will be <samp>true </samp>; it will switch to <samp>false </samp> | |
171 * when the control looses focus. | |
172 * | |
173 * @return <code>true</code> if the widget has focus, <code>false</code> | |
174 * otherwise. | |
175 */ | |
176 public bool getSelection() { | |
177 return hasFocus; | |
178 } | |
179 | |
180 /** | |
181 * Called when hyperlink is entered. Subclasses that override this method | |
182 * must call 'super'. | |
183 */ | |
184 protected void handleEnter(Event e) { | |
185 redraw(); | |
186 if (listeners is null) | |
187 return; | |
188 int size = listeners.size(); | |
189 HyperlinkEvent he = new HyperlinkEvent(this, getHref(), getText(), | |
190 e.stateMask); | |
191 Object[] listenerList = listeners.getListeners(); | |
192 for (int i = 0; i < size; i++) { | |
193 IHyperlinkListener listener = cast(IHyperlinkListener) listenerList[i]; | |
194 listener.linkEntered(he); | |
195 } | |
196 } | |
197 | |
198 /** | |
199 * Called when hyperlink is exited. Subclasses that override this method | |
200 * must call 'super'. | |
201 */ | |
202 protected void handleExit(Event e) { | |
203 // disarm the link; won't activate on mouseup | |
204 armed = false; | |
205 redraw(); | |
206 if (listeners is null) | |
207 return; | |
208 int size = listeners.size(); | |
209 HyperlinkEvent he = new HyperlinkEvent(this, getHref(), getText(), | |
210 e.stateMask); | |
211 Object[] listenerList = listeners.getListeners(); | |
212 for (int i = 0; i < size; i++) { | |
213 IHyperlinkListener listener = cast(IHyperlinkListener) listenerList[i]; | |
214 listener.linkExited(he); | |
215 } | |
216 } | |
217 | |
218 /** | |
219 * Called when hyperlink has been activated. Subclasses that override this | |
220 * method must call 'super'. | |
221 */ | |
222 protected void handleActivate(Event e) { | |
223 // disarm link, back to normal state | |
224 armed = false; | |
225 getAccessible().setFocus(ACC.CHILDID_SELF); | |
226 if (listeners is null) | |
227 return; | |
228 int size = listeners.size(); | |
229 setCursor(FormsResources.getBusyCursor()); | |
230 HyperlinkEvent he = new HyperlinkEvent(this, getHref(), getText(), | |
231 e.stateMask); | |
232 Object[] listenerList = listeners.getListeners(); | |
233 for (int i = 0; i < size; i++) { | |
234 IHyperlinkListener listener = cast(IHyperlinkListener) listenerList[i]; | |
235 listener.linkActivated(he); | |
236 } | |
237 if (!isDisposed()) | |
238 setCursor(FormsResources.getHandCursor()); | |
239 } | |
240 | |
241 /** | |
242 * Sets the object associated with this hyperlink. Concrete implementation | |
243 * of this class can use if to store text, URLs or model objects that need | |
244 * to be processed on hyperlink events. | |
245 * | |
246 * @param href | |
247 * the hyperlink object reference | |
248 */ | |
249 public void setHref(Object href) { | |
250 setData("href", href); //$NON-NLS-1$ | |
251 } | |
252 | |
253 /** | |
254 * Returns the object associated with this hyperlink. | |
255 * | |
256 * @see #setHref | |
257 * @return the hyperlink object reference | |
258 */ | |
259 public Object getHref() { | |
260 return getData("href"); //$NON-NLS-1$ | |
261 } | |
262 | |
263 /** | |
264 * Returns the textual representation of this hyperlink suitable for showing | |
265 * in tool tips or on the status line. | |
266 * | |
267 * @return the hyperlink text | |
268 */ | |
269 public String getText() { | |
270 return getToolTipText(); | |
271 } | |
272 | |
273 /** | |
274 * Paints the hyperlink as a reaction to the provided paint event. | |
275 * | |
276 * @param gc | |
277 * graphic context | |
278 */ | |
279 protected abstract void paintHyperlink(GC gc); | |
280 | |
281 /** | |
282 * Paints the control as a reaction to the provided paint event. | |
283 * | |
284 * @param e | |
285 * the paint event | |
286 */ | |
287 protected void paint(PaintEvent e) { | |
288 GC gc = e.gc; | |
289 Rectangle clientArea = getClientArea(); | |
290 if (clientArea.width is 0 || clientArea.height is 0) | |
291 return; | |
292 paintHyperlink(gc); | |
293 if (paintFocus && hasFocus) { | |
294 Rectangle carea = getClientArea(); | |
295 gc.setForeground(getForeground()); | |
296 gc.drawFocus(0, 0, carea.width, carea.height); | |
297 } | |
298 } | |
299 | |
300 private void handleMouseDown(Event e) { | |
301 if (e.button !is 1) | |
302 return; | |
303 // armed and ready to activate on mouseup | |
304 armed = true; | |
305 } | |
306 | |
307 private void handleMouseUp(Event e) { | |
308 if (!armed || e.button !is 1) | |
309 return; | |
310 Point size = getSize(); | |
311 // Filter out mouse up events outside | |
312 // the link. This can happen when mouse is | |
313 // clicked, dragged outside the link, then | |
314 // released. | |
315 if (e.x < 0) | |
316 return; | |
317 if (e.y < 0) | |
318 return; | |
319 if (e.x >= size.x) | |
320 return; | |
321 if (e.y >= size.y) | |
322 return; | |
323 handleActivate(e); | |
324 } | |
325 | |
326 private void handleMouseMove(Event e) { | |
327 // disarm link if we move out of bounds | |
328 if (armed) { | |
329 Point size = getSize(); | |
330 armed = (e.x >= 0 && e.y >= 0 && e.x < size.x && e.y < size.y); | |
331 } | |
332 } | |
333 | |
334 /* | |
335 * (non-Javadoc) | |
336 * @see dwt.widgets.Control#setEnabled(bool) | |
337 */ | |
338 | |
339 public void setEnabled (bool enabled) { | |
340 super.setEnabled(enabled); | |
341 redraw(); | |
342 } | |
343 } |