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