1 11 package org.eclipse.jface.util; 12 13 import org.eclipse.core.runtime.ListenerList; 14 import org.eclipse.swt.SWT; 15 import org.eclipse.swt.custom.TableTree; 16 import org.eclipse.swt.custom.TableTreeItem; 17 import org.eclipse.swt.events.SelectionEvent; 18 import org.eclipse.swt.events.SelectionListener; 19 import org.eclipse.swt.graphics.Point; 20 import org.eclipse.swt.widgets.Control; 21 import org.eclipse.swt.widgets.Display; 22 import org.eclipse.swt.widgets.Event; 23 import org.eclipse.swt.widgets.Listener; 24 import org.eclipse.swt.widgets.Table; 25 import org.eclipse.swt.widgets.TableItem; 26 import org.eclipse.swt.widgets.Tree; 27 import org.eclipse.swt.widgets.TreeItem; 28 import org.eclipse.swt.widgets.Widget; 29 30 44 public class OpenStrategy { 45 48 public static final int DOUBLE_CLICK = 0; 49 50 53 public static final int SINGLE_CLICK = 1; 54 55 58 public static final int SELECT_ON_HOVER = 1 << 1; 59 60 63 public static final int ARROW_KEYS_OPEN = 1 << 2; 64 65 70 public static final int NO_TIMER = SINGLE_CLICK; 71 72 78 public static final int FILE_EXPLORER = SINGLE_CLICK | ARROW_KEYS_OPEN; 79 80 85 public static final int ACTIVE_DESKTOP = SINGLE_CLICK | SELECT_ON_HOVER; 86 87 private static final int TIME = 500; 89 90 93 private static int CURRENT_METHOD = DOUBLE_CLICK; 94 95 private Listener eventHandler; 96 97 private ListenerList openEventListeners = new ListenerList(); 98 99 private ListenerList selectionEventListeners = new ListenerList(); 100 101 private ListenerList postSelectionEventListeners = new ListenerList(); 102 103 106 public OpenStrategy(Control control) { 107 initializeHandler(control.getDisplay()); 108 addListener(control); 109 } 110 111 115 public void addOpenListener(IOpenEventListener listener) { 116 openEventListeners.add(listener); 117 } 118 119 123 public void removeOpenListener(IOpenEventListener listener) { 124 openEventListeners.remove(listener); 125 } 126 127 131 public void addSelectionListener(SelectionListener listener) { 132 selectionEventListeners.add(listener); 133 } 134 135 139 public void removeSelectionListener(SelectionListener listener) { 140 selectionEventListeners.remove(listener); 141 } 142 143 147 public void addPostSelectionListener(SelectionListener listener) { 148 postSelectionEventListeners.add(listener); 149 } 150 151 155 public void removePostSelectionListener(SelectionListener listener) { 156 postSelectionEventListeners.remove(listener); 157 } 158 159 165 public static int getOpenMethod() { 166 return CURRENT_METHOD; 167 } 168 169 180 public static void setOpenMethod(int method) { 181 if (method == DOUBLE_CLICK) { 182 CURRENT_METHOD = method; 183 return; 184 } 185 if ((method & SINGLE_CLICK) == 0) { 186 throw new IllegalArgumentException ("Invalid open mode"); } 188 if ((method & (SINGLE_CLICK | SELECT_ON_HOVER | ARROW_KEYS_OPEN)) == 0) { 189 throw new IllegalArgumentException ("Invalid open mode"); } 191 CURRENT_METHOD = method; 192 } 193 194 197 public static boolean activateOnOpen() { 198 return getOpenMethod() == DOUBLE_CLICK; 199 } 200 201 205 private void addListener(Control c) { 206 c.addListener(SWT.MouseEnter, eventHandler); 207 c.addListener(SWT.MouseExit, eventHandler); 208 c.addListener(SWT.MouseMove, eventHandler); 209 c.addListener(SWT.MouseDown, eventHandler); 210 c.addListener(SWT.MouseUp, eventHandler); 211 c.addListener(SWT.KeyDown, eventHandler); 212 c.addListener(SWT.Selection, eventHandler); 213 c.addListener(SWT.DefaultSelection, eventHandler); 214 c.addListener(SWT.Collapse, eventHandler); 215 c.addListener(SWT.Expand, eventHandler); 216 } 217 218 221 private void fireSelectionEvent(SelectionEvent e) { 222 if (e.item != null && e.item.isDisposed()) { 223 return; 224 } 225 Object l[] = selectionEventListeners.getListeners(); 226 for (int i = 0; i < l.length; i++) { 227 ((SelectionListener) l[i]).widgetSelected(e); 228 } 229 } 230 231 234 private void fireDefaultSelectionEvent(SelectionEvent e) { 235 Object l[] = selectionEventListeners.getListeners(); 236 for (int i = 0; i < l.length; i++) { 237 ((SelectionListener) l[i]).widgetDefaultSelected(e); 238 } 239 } 240 241 244 private void firePostSelectionEvent(SelectionEvent e) { 245 if (e.item != null && e.item.isDisposed()) { 246 return; 247 } 248 Object l[] = postSelectionEventListeners.getListeners(); 249 for (int i = 0; i < l.length; i++) { 250 ((SelectionListener) l[i]).widgetSelected(e); 251 } 252 } 253 254 257 private void fireOpenEvent(SelectionEvent e) { 258 if (e.item != null && e.item.isDisposed()) { 259 return; 260 } 261 Object l[] = openEventListeners.getListeners(); 262 for (int i = 0; i < l.length; i++) { 263 ((IOpenEventListener) l[i]).handleOpen(e); 264 } 265 } 266 267 private void initializeHandler(final Display display) { 269 eventHandler = new Listener() { 270 boolean timerStarted = false; 271 272 Event mouseUpEvent = null; 273 274 Event mouseMoveEvent = null; 275 276 SelectionEvent selectionPendent = null; 277 278 boolean enterKeyDown = false; 279 280 SelectionEvent defaultSelectionPendent = null; 281 282 boolean arrowKeyDown = false; 283 284 final int[] count = new int[1]; 285 286 long startTime = System.currentTimeMillis(); 287 288 boolean collapseOccurred = false; 289 290 boolean expandOccurred = false; 291 292 public void handleEvent(final Event e) { 293 if (e.type == SWT.DefaultSelection) { 294 SelectionEvent event = new SelectionEvent(e); 295 fireDefaultSelectionEvent(event); 296 if (CURRENT_METHOD == DOUBLE_CLICK) { 297 fireOpenEvent(event); 298 } else { 299 if (enterKeyDown) { 300 fireOpenEvent(event); 301 enterKeyDown = false; 302 defaultSelectionPendent = null; 303 } else { 304 defaultSelectionPendent = event; 305 } 306 } 307 return; 308 } 309 310 switch (e.type) { 311 case SWT.MouseEnter: 312 case SWT.MouseExit: 313 mouseUpEvent = null; 314 mouseMoveEvent = null; 315 selectionPendent = null; 316 break; 317 case SWT.MouseMove: 318 if ((CURRENT_METHOD & SELECT_ON_HOVER) == 0) { 319 return; 320 } 321 if (e.stateMask != 0) { 322 return; 323 } 324 if (e.widget.getDisplay().getFocusControl() != e.widget) { 325 return; 326 } 327 mouseMoveEvent = e; 328 final Runnable runnable[] = new Runnable [1]; 329 runnable[0] = new Runnable () { 330 public void run() { 331 long time = System.currentTimeMillis(); 332 int diff = (int) (time - startTime); 333 if (diff <= TIME) { 334 display.timerExec(diff * 2 / 3, runnable[0]); 335 } else { 336 timerStarted = false; 337 setSelection(mouseMoveEvent); 338 } 339 } 340 }; 341 startTime = System.currentTimeMillis(); 342 if (!timerStarted) { 343 timerStarted = true; 344 display.timerExec(TIME * 2 / 3, runnable[0]); 345 } 346 break; 347 case SWT.MouseDown: 348 mouseUpEvent = null; 349 arrowKeyDown = false; 350 break; 351 case SWT.Expand: 352 expandOccurred = true; 353 break; 354 case SWT.Collapse: 355 collapseOccurred = true; 356 break; 357 case SWT.MouseUp: 358 mouseMoveEvent = null; 359 if ((e.button != 1) || ((e.stateMask & ~SWT.BUTTON1) != 0)) { 360 return; 361 } 362 if (selectionPendent != null 363 && !(collapseOccurred || expandOccurred)) { 364 mouseSelectItem(selectionPendent); 365 } else { 366 mouseUpEvent = e; 367 collapseOccurred = false; 368 expandOccurred = false; 369 } 370 break; 371 case SWT.KeyDown: 372 mouseMoveEvent = null; 373 mouseUpEvent = null; 374 arrowKeyDown = ((e.keyCode == SWT.ARROW_UP) || (e.keyCode == SWT.ARROW_DOWN)) 375 && e.stateMask == 0; 376 if (e.character == SWT.CR) { 377 if (defaultSelectionPendent != null) { 378 fireOpenEvent(new SelectionEvent(e)); 379 enterKeyDown = false; 380 defaultSelectionPendent = null; 381 } else { 382 enterKeyDown = true; 383 } 384 } 385 break; 386 case SWT.Selection: 387 SelectionEvent event = new SelectionEvent(e); 388 fireSelectionEvent(event); 389 mouseMoveEvent = null; 390 if (mouseUpEvent != null) { 391 mouseSelectItem(event); 392 } else { 393 selectionPendent = event; 394 } 395 count[0]++; 396 final int id = count[0]; 397 display.asyncExec(new Runnable () { 402 public void run() { 403 if (arrowKeyDown) { 404 display.timerExec(TIME, new Runnable () { 405 406 public void run() { 407 if (id == count[0]) { 408 firePostSelectionEvent(new SelectionEvent( 409 e)); 410 if ((CURRENT_METHOD & ARROW_KEYS_OPEN) != 0) { 411 fireOpenEvent(new SelectionEvent( 412 e)); 413 } 414 } 415 } 416 }); 417 } else { 418 firePostSelectionEvent(new SelectionEvent(e)); 419 } 420 } 421 }); 422 break; 423 } 424 } 425 426 void mouseSelectItem(SelectionEvent e) { 427 if ((CURRENT_METHOD & SINGLE_CLICK) != 0) { 428 fireOpenEvent(e); 429 } 430 mouseUpEvent = null; 431 selectionPendent = null; 432 } 433 434 void setSelection(Event e) { 435 if (e == null) { 436 return; 437 } 438 Widget w = e.widget; 439 if (w.isDisposed()) { 440 return; 441 } 442 443 SelectionEvent selEvent = new SelectionEvent(e); 444 445 448 if (w instanceof Tree) { 449 Tree tree = (Tree) w; 450 TreeItem item = tree.getItem(new Point(e.x, e.y)); 451 if (item != null) { 452 tree.setSelection(new TreeItem[] { item }); 453 } 454 selEvent.item = item; 455 } else if (w instanceof Table) { 456 Table table = (Table) w; 457 TableItem item = table.getItem(new Point(e.x, e.y)); 458 if (item != null) { 459 table.setSelection(new TableItem[] { item }); 460 } 461 selEvent.item = item; 462 } else if (w instanceof TableTree) { 463 TableTree table = (TableTree) w; 464 TableTreeItem item = table.getItem(new Point(e.x, e.y)); 465 if (item != null) { 466 table.setSelection(new TableTreeItem[] { item }); 467 } 468 selEvent.item = item; 469 } else { 470 return; 471 } 472 if (selEvent.item == null) { 473 return; 474 } 475 fireSelectionEvent(selEvent); 476 firePostSelectionEvent(selEvent); 477 } 478 }; 479 } 480 } 481 | Popular Tags |