Mercurial > projects > dwt-addons
annotate dwtx/jface/util/OpenStrategy.d @ 192:c3583c6ec027
Added missing default cases for switch statements
author | Frank Benoit <benoit@tionex.de> |
---|---|
date | Mon, 03 Nov 2008 22:52:26 +0100 |
parents | 644f1334b451 |
children |
rev | line source |
---|---|
4 | 1 /******************************************************************************* |
2 * Copyright (c) 2000, 2006 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.jface.util.OpenStrategy; | |
14 | |
15 import dwtx.jface.util.IOpenEventListener; | |
16 | |
17 import dwt.DWT; | |
18 import dwt.custom.TableTree; | |
19 import dwt.custom.TableTreeItem; | |
20 import dwt.events.SelectionEvent; | |
21 import dwt.events.SelectionListener; | |
22 import dwt.graphics.Point; | |
23 import dwt.widgets.Control; | |
24 import dwt.widgets.Display; | |
25 import dwt.widgets.Event; | |
26 import dwt.widgets.Listener; | |
27 import dwt.widgets.Table; | |
28 import dwt.widgets.TableItem; | |
29 import dwt.widgets.Tree; | |
30 import dwt.widgets.TreeItem; | |
31 import dwt.widgets.Widget; | |
32 import dwtx.core.runtime.ListenerList; | |
33 | |
34 import dwt.dwthelper.utils; | |
35 import dwt.dwthelper.Runnable; | |
36 | |
37 /** | |
38 * Implementation of single-click and double-click strategies. | |
39 * <p> | |
40 * Usage: | |
41 * <pre> | |
42 * OpenStrategy handler = new OpenStrategy(control); | |
43 * handler.addOpenListener(new IOpenEventListener() { | |
44 * public void handleOpen(SelectionEvent e) { | |
45 * ... // code to handle the open event. | |
46 * } | |
47 * }); | |
48 * </pre> | |
49 * </p> | |
50 */ | |
51 public class OpenStrategy { | |
52 /** | |
53 * Default behavior. Double click to open the item. | |
54 */ | |
55 public static const int DOUBLE_CLICK = 0; | |
56 | |
57 /** | |
58 * Single click will open the item. | |
59 */ | |
60 public static const int SINGLE_CLICK = 1; | |
61 | |
62 /** | |
63 * Hover will select the item. | |
64 */ | |
65 public static const int SELECT_ON_HOVER = 1 << 1; | |
66 | |
67 /** | |
68 * Open item when using arrow keys | |
69 */ | |
70 public static const int ARROW_KEYS_OPEN = 1 << 2; | |
71 | |
72 /** A single click will generate | |
73 * an open event but key arrows will not do anything. | |
74 * | |
75 * @deprecated | |
76 */ | |
77 public static const int NO_TIMER = SINGLE_CLICK; | |
78 | |
79 /** A single click will generate an open | |
80 * event and key arrows will generate an open event after a | |
81 * small time. | |
82 * | |
83 * @deprecated | |
84 */ | |
85 public static const int FILE_EXPLORER = SINGLE_CLICK | ARROW_KEYS_OPEN; | |
86 | |
87 /** Pointing to an item will change the selection | |
88 * and a single click will gererate an open event | |
89 * | |
90 * @deprecated | |
91 */ | |
92 public static const int ACTIVE_DESKTOP = SINGLE_CLICK | SELECT_ON_HOVER; | |
93 | |
94 // Time used in FILE_EXPLORER and ACTIVE_DESKTOP | |
95 private static const int TIME = 500; | |
96 | |
97 /* SINGLE_CLICK or DOUBLE_CLICK; | |
98 * In case of SINGLE_CLICK, the bits SELECT_ON_HOVER and ARROW_KEYS_OPEN | |
99 * my be set as well. */ | |
100 private static int CURRENT_METHOD = DOUBLE_CLICK; | |
101 | |
102 private Listener eventHandler; | |
103 | |
104 private ListenerList openEventListeners; | |
105 | |
106 private ListenerList selectionEventListeners; | |
107 | |
108 private ListenerList postSelectionEventListeners; | |
109 | |
110 /** | |
111 * @param control the control the strategy is applied to | |
112 */ | |
113 public this(Control control) { | |
114 openEventListeners = new ListenerList(); | |
115 selectionEventListeners = new ListenerList(); | |
116 postSelectionEventListeners = new ListenerList(); | |
117 initializeHandler(control.getDisplay()); | |
118 addListener(control); | |
119 } | |
120 | |
121 /** | |
122 * Adds an IOpenEventListener to the collection of openEventListeners | |
123 * @param listener the listener to add | |
124 */ | |
125 public void addOpenListener(IOpenEventListener listener) { | |
126 openEventListeners.add(cast(Object)listener); | |
127 } | |
128 | |
129 /** | |
130 * Removes an IOpenEventListener to the collection of openEventListeners | |
131 * @param listener the listener to remove | |
132 */ | |
133 public void removeOpenListener(IOpenEventListener listener) { | |
134 openEventListeners.remove(cast(Object)listener); | |
135 } | |
136 | |
137 /** | |
138 * Adds an SelectionListener to the collection of selectionEventListeners | |
139 * @param listener the listener to add | |
140 */ | |
141 public void addSelectionListener(SelectionListener listener) { | |
142 selectionEventListeners.add(cast(Object)listener); | |
143 } | |
144 | |
145 /** | |
146 * Removes an SelectionListener to the collection of selectionEventListeners | |
147 * @param listener the listener to remove | |
148 */ | |
149 public void removeSelectionListener(SelectionListener listener) { | |
150 selectionEventListeners.remove(cast(Object)listener); | |
151 } | |
152 | |
153 /** | |
154 * Adds an SelectionListener to the collection of selectionEventListeners | |
155 * @param listener the listener to add | |
156 */ | |
157 public void addPostSelectionListener(SelectionListener listener) { | |
158 postSelectionEventListeners.add(cast(Object)listener); | |
159 } | |
160 | |
161 /** | |
162 * Removes an SelectionListener to the collection of selectionEventListeners | |
163 * @param listener the listener to remove | |
164 */ | |
165 public void removePostSelectionListener(SelectionListener listener) { | |
166 postSelectionEventListeners.remove(cast(Object)listener); | |
167 } | |
168 | |
169 /** | |
170 * This method is internal to the framework; it should not be implemented outside | |
171 * the framework. | |
172 * @return the current used single/double-click method | |
173 * | |
174 */ | |
175 public static int getOpenMethod() { | |
176 return CURRENT_METHOD; | |
177 } | |
178 | |
179 /** | |
180 * Set the current used single/double-click method. | |
181 * | |
182 * This method is internal to the framework; it should not be implemented outside | |
183 * the framework. | |
184 * @param method the method to be used | |
185 * @see OpenStrategy#DOUBLE_CLICK | |
186 * @see OpenStrategy#SINGLE_CLICK | |
187 * @see OpenStrategy#SELECT_ON_HOVER | |
188 * @see OpenStrategy#ARROW_KEYS_OPEN | |
189 */ | |
190 public static void setOpenMethod(int method) { | |
191 if (method is DOUBLE_CLICK) { | |
192 CURRENT_METHOD = method; | |
193 return; | |
194 } | |
195 if ((method & SINGLE_CLICK) is 0) { | |
196 throw new IllegalArgumentException("Invalid open mode"); //$NON-NLS-1$ | |
197 } | |
198 if ((method & (SINGLE_CLICK | SELECT_ON_HOVER | ARROW_KEYS_OPEN)) is 0) { | |
199 throw new IllegalArgumentException("Invalid open mode"); //$NON-NLS-1$ | |
200 } | |
201 CURRENT_METHOD = method; | |
202 } | |
203 | |
204 /** | |
205 * @return true if editors should be activated when opened. | |
206 */ | |
207 public static bool activateOnOpen() { | |
208 return getOpenMethod() is DOUBLE_CLICK; | |
209 } | |
210 | |
211 /* | |
212 * Adds all needed listener to the control in order to implement | |
213 * single-click/double-click strategies. | |
214 */ | |
215 private void addListener(Control c) { | |
216 c.addListener(DWT.MouseEnter, eventHandler); | |
217 c.addListener(DWT.MouseExit, eventHandler); | |
218 c.addListener(DWT.MouseMove, eventHandler); | |
219 c.addListener(DWT.MouseDown, eventHandler); | |
220 c.addListener(DWT.MouseUp, eventHandler); | |
221 c.addListener(DWT.KeyDown, eventHandler); | |
222 c.addListener(DWT.Selection, eventHandler); | |
223 c.addListener(DWT.DefaultSelection, eventHandler); | |
224 c.addListener(DWT.Collapse, eventHandler); | |
225 c.addListener(DWT.Expand, eventHandler); | |
226 } | |
227 | |
228 /* | |
229 * Fire the selection event to all selectionEventListeners | |
230 */ | |
231 private void fireSelectionEvent(SelectionEvent e) { | |
232 if (e.item !is null && e.item.isDisposed()) { | |
233 return; | |
234 } | |
235 Object l[] = selectionEventListeners.getListeners(); | |
236 for (int i = 0; i < l.length; i++) { | |
237 (cast(SelectionListener) l[i]).widgetSelected(e); | |
238 } | |
239 } | |
240 | |
241 /* | |
242 * Fire the default selection event to all selectionEventListeners | |
243 */ | |
244 private void fireDefaultSelectionEvent(SelectionEvent e) { | |
245 Object l[] = selectionEventListeners.getListeners(); | |
246 for (int i = 0; i < l.length; i++) { | |
247 (cast(SelectionListener) l[i]).widgetDefaultSelected(e); | |
248 } | |
249 } | |
250 | |
251 /* | |
252 * Fire the post selection event to all postSelectionEventListeners | |
253 */ | |
254 private void firePostSelectionEvent(SelectionEvent e) { | |
255 if (e.item !is null && e.item.isDisposed()) { | |
256 return; | |
257 } | |
258 Object l[] = postSelectionEventListeners.getListeners(); | |
259 for (int i = 0; i < l.length; i++) { | |
260 (cast(SelectionListener) l[i]).widgetSelected(e); | |
261 } | |
262 } | |
263 | |
264 /* | |
265 * Fire the open event to all openEventListeners | |
266 */ | |
267 private void fireOpenEvent(SelectionEvent e) { | |
268 if (e.item !is null && e.item.isDisposed()) { | |
269 return; | |
270 } | |
271 Object l[] = openEventListeners.getListeners(); | |
272 for (int i = 0; i < l.length; i++) { | |
273 (cast(IOpenEventListener) l[i]).handleOpen(e); | |
274 } | |
275 } | |
276 | |
277 //Initialize event handler. | |
278 private void initializeHandler( Display display_) { | |
39 | 279 eventHandler = new class(display_) Listener { |
4 | 280 Display display; |
281 bool timerStarted = false; | |
282 | |
283 Event mouseUpEvent = null; | |
284 | |
285 Event mouseMoveEvent = null; | |
286 | |
287 SelectionEvent selectionPendent = null; | |
288 | |
289 bool enterKeyDown = false; | |
290 | |
291 SelectionEvent defaultSelectionPendent = null; | |
292 | |
293 bool arrowKeyDown = false; | |
294 | |
39 | 295 int[1] count; |
4 | 296 |
297 long startTime; | |
298 | |
299 bool collapseOccurred = false; | |
300 | |
301 bool expandOccurred = false; | |
302 | |
39 | 303 this(Display a){ |
304 display = a; | |
4 | 305 startTime = System.currentTimeMillis(); |
306 } | |
307 | |
308 public void handleEvent( Event e) { | |
309 if (e.type is DWT.DefaultSelection) { | |
310 SelectionEvent event = new SelectionEvent(e); | |
311 fireDefaultSelectionEvent(event); | |
312 if (CURRENT_METHOD is DOUBLE_CLICK) { | |
313 fireOpenEvent(event); | |
314 } else { | |
315 if (enterKeyDown) { | |
316 fireOpenEvent(event); | |
317 enterKeyDown = false; | |
318 defaultSelectionPendent = null; | |
319 } else { | |
320 defaultSelectionPendent = event; | |
321 } | |
322 } | |
323 return; | |
324 } | |
325 | |
326 switch (e.type) { | |
327 case DWT.MouseEnter: | |
328 case DWT.MouseExit: | |
329 mouseUpEvent = null; | |
330 mouseMoveEvent = null; | |
331 selectionPendent = null; | |
332 break; | |
333 case DWT.MouseMove: | |
334 if ((CURRENT_METHOD & SELECT_ON_HOVER) is 0) { | |
335 return; | |
336 } | |
337 if (e.stateMask !is 0) { | |
338 return; | |
339 } | |
340 if (e.widget.getDisplay().getFocusControl() !is e.widget) { | |
341 return; | |
342 } | |
343 mouseMoveEvent = e; | |
344 Runnable runnable = new class() Runnable { | |
345 public void run() { | |
346 long time = System.currentTimeMillis(); | |
347 int diff = cast(int) (time - startTime); | |
348 if (diff <= TIME) { | |
349 display.timerExec(diff * 2 / 3, this ); | |
350 } else { | |
351 timerStarted = false; | |
352 setSelection(mouseMoveEvent); | |
353 } | |
354 } | |
355 }; | |
356 startTime = System.currentTimeMillis(); | |
357 if (!timerStarted) { | |
358 timerStarted = true; | |
359 display.timerExec(TIME * 2 / 3, runnable ); | |
360 } | |
361 break; | |
362 case DWT.MouseDown: | |
363 mouseUpEvent = null; | |
364 arrowKeyDown = false; | |
365 break; | |
366 case DWT.Expand: | |
367 expandOccurred = true; | |
368 break; | |
369 case DWT.Collapse: | |
370 collapseOccurred = true; | |
371 break; | |
372 case DWT.MouseUp: | |
373 mouseMoveEvent = null; | |
374 if ((e.button !is 1) || ((e.stateMask & ~DWT.BUTTON1) !is 0)) { | |
375 return; | |
376 } | |
377 if (selectionPendent !is null | |
378 && !(collapseOccurred || expandOccurred)) { | |
379 mouseSelectItem(selectionPendent); | |
380 } else { | |
381 mouseUpEvent = e; | |
382 collapseOccurred = false; | |
383 expandOccurred = false; | |
384 } | |
385 break; | |
386 case DWT.KeyDown: | |
387 mouseMoveEvent = null; | |
388 mouseUpEvent = null; | |
389 arrowKeyDown = ((e.keyCode is DWT.ARROW_UP) || (e.keyCode is DWT.ARROW_DOWN)) | |
390 && e.stateMask is 0; | |
391 if (e.character is DWT.CR) { | |
392 if (defaultSelectionPendent !is null) { | |
393 fireOpenEvent(new SelectionEvent(e)); | |
394 enterKeyDown = false; | |
395 defaultSelectionPendent = null; | |
396 } else { | |
397 enterKeyDown = true; | |
398 } | |
399 } | |
400 break; | |
401 case DWT.Selection: | |
402 SelectionEvent event = new SelectionEvent(e); | |
403 fireSelectionEvent(event); | |
404 mouseMoveEvent = null; | |
405 if (mouseUpEvent !is null) { | |
406 mouseSelectItem(event); | |
407 } else { | |
408 selectionPendent = event; | |
409 } | |
410 count[0]++; | |
411 // In the case of arrowUp/arrowDown when in the arrowKeysOpen mode, we | |
412 // want to delay any selection until the last arrowDown/Up occurs. This | |
413 // handles the case where the user presses arrowDown/Up successively. | |
414 // We only want to open an editor for the last selected item. | |
39 | 415 display.asyncExec(new class( count, e) Runnable { |
416 int id_; | |
417 int[] count_; | |
418 Event e_; | |
419 this( int[] a, Event b){ | |
420 count_ = a; | |
421 e_ = b; | |
422 id_ = count_[0]; | |
423 } | |
4 | 424 public void run() { |
425 if (arrowKeyDown) { | |
39 | 426 display.timerExec(TIME, new class(id_,count_,e_) Runnable { |
427 int id__; | |
428 Event e__; | |
429 int[] count__; | |
430 this(int a, int[] b, Event c){ | |
431 id__ = a; | |
432 count__ = b; | |
433 e__ = c; | |
434 } | |
4 | 435 public void run() { |
39 | 436 if (id__ is count__[0]) { |
437 firePostSelectionEvent(new SelectionEvent(e__)); | |
4 | 438 if ((CURRENT_METHOD & ARROW_KEYS_OPEN) !is 0) { |
39 | 439 fireOpenEvent(new SelectionEvent(e__)); |
4 | 440 } |
441 } | |
442 } | |
443 }); | |
444 } else { | |
39 | 445 firePostSelectionEvent(new SelectionEvent(e_)); |
4 | 446 } |
447 } | |
448 }); | |
449 break; | |
192
c3583c6ec027
Added missing default cases for switch statements
Frank Benoit <benoit@tionex.de>
parents:
39
diff
changeset
|
450 default: |
4 | 451 } |
452 } | |
453 | |
454 void mouseSelectItem(SelectionEvent e) { | |
455 if ((CURRENT_METHOD & SINGLE_CLICK) !is 0) { | |
456 fireOpenEvent(e); | |
457 } | |
458 mouseUpEvent = null; | |
459 selectionPendent = null; | |
460 } | |
461 | |
462 void setSelection(Event e) { | |
463 if (e is null) { | |
464 return; | |
465 } | |
466 Widget w = e.widget; | |
467 if (w.isDisposed()) { | |
468 return; | |
469 } | |
470 | |
471 SelectionEvent selEvent = new SelectionEvent(e); | |
472 | |
473 /*ISSUE: May have to create a interface with method: | |
474 setSelection(Point p) so that user's custom widgets | |
475 can use this class. If we keep this option. */ | |
476 if ( auto tree = cast(Tree)w) { | |
477 TreeItem item = tree.getItem(new Point(e.x, e.y)); | |
478 if (item !is null) { | |
479 tree.setSelection([ item ]); | |
480 } | |
481 selEvent.item = item; | |
482 } else if ( auto table = cast(Table)w) { | |
483 TableItem item = table.getItem(new Point(e.x, e.y)); | |
484 if (item !is null) { | |
485 table.setSelection([ item ]); | |
486 } | |
487 selEvent.item = item; | |
488 } else if ( auto table = cast(TableTree)w) { | |
489 TableTreeItem item = table.getItem(new Point(e.x, e.y)); | |
490 if (item !is null) { | |
491 table.setSelection([ item ]); | |
492 } | |
493 selEvent.item = item; | |
494 } else { | |
495 return; | |
496 } | |
497 if (selEvent.item is null) { | |
498 return; | |
499 } | |
500 fireSelectionEvent(selEvent); | |
501 firePostSelectionEvent(selEvent); | |
502 } | |
503 }; | |
504 } | |
505 } |