comparison dwtx/jface/window/ToolTip.d @ 70:46a6e0e6ccd4

Merge with d-fied sources of 3.4M7
author Frank Benoit <benoit@tionex.de>
date Thu, 22 May 2008 01:36:46 +0200
parents 644f1334b451
children 4878bef4a38e
comparison
equal deleted inserted replaced
69:07b9d96fd764 70:46a6e0e6ccd4
1 /******************************************************************************* 1 /*******************************************************************************
2 * Copyright (c) 2006, 2007 IBM Corporation and others. 2 * Copyright (c) 2006, 2008 IBM Corporation and others.
3 * All rights reserved. This program and the accompanying materials 3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0 4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at 5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/epl-v10.html 6 * http://www.eclipse.org/legal/epl-v10.html
7 * 7 *
8 * Contributors: 8 * Contributors:
9 * Tom Schindl <tom.schindl@bestsolution.at> - initial API and implementation 9 * Tom Schindl <tom.schindl@bestsolution.at> - initial API and implementation
10 * bugfix in: 195137, 198089, 225190
10 * Port to the D programming language: 11 * Port to the D programming language:
11 * Frank Benoit <benoit@tionex.de> 12 * Frank Benoit <benoit@tionex.de>
12 *******************************************************************************/ 13 *******************************************************************************/
13 14
14 module dwtx.jface.window.ToolTip; 15 module dwtx.jface.window.ToolTip;
21 import dwt.graphics.Point; 22 import dwt.graphics.Point;
22 import dwt.graphics.Rectangle; 23 import dwt.graphics.Rectangle;
23 import dwt.layout.FillLayout; 24 import dwt.layout.FillLayout;
24 import dwt.widgets.Composite; 25 import dwt.widgets.Composite;
25 import dwt.widgets.Control; 26 import dwt.widgets.Control;
27 import dwt.widgets.Display;
26 import dwt.widgets.Event; 28 import dwt.widgets.Event;
27 import dwt.widgets.Listener; 29 import dwt.widgets.Listener;
28 import dwt.widgets.Monitor; 30 import dwt.widgets.Monitor;
29 import dwt.widgets.Shell; 31 import dwt.widgets.Shell;
30 // import dwtx.jface.viewers.ColumnViewer; 32 // import dwtx.jface.viewers.ColumnViewer;
67 */ 69 */
68 public static const int NO_RECREATE = 1 << 1; 70 public static const int NO_RECREATE = 1 << 1;
69 71
70 private TooltipHideListener hideListener; 72 private TooltipHideListener hideListener;
71 73
74 private Listener shellListener;
75
72 private bool hideOnMouseDown = true; 76 private bool hideOnMouseDown = true;
73 77
74 private bool respectDisplayBounds = true; 78 private bool respectDisplayBounds = true;
75 79
76 private bool respectMonitorBounds = true; 80 private bool respectMonitorBounds = true;
77 81
78 private int style; 82 private int style;
79 83
80 private Object currentArea; 84 private Object currentArea;
85
86 private static final bool IS_OSX = DWT.getPlatform().equals("carbon"); //$NON-NLS-1$
81 87
82 /** 88 /**
83 * Create new instance which add TooltipSupport to the widget 89 * Create new instance which add TooltipSupport to the widget
84 * 90 *
85 * @param control 91 * @param control
91 97
92 /** 98 /**
93 * @param control 99 * @param control
94 * the control to which the tooltip is bound 100 * the control to which the tooltip is bound
95 * @param style 101 * @param style
96 * style passed to control tooltip behaviour 102 * style passed to control tooltip behavior
97 * 103 *
98 * @param manualActivation 104 * @param manualActivation
99 * <code>true</code> if the activation is done manually using 105 * <code>true</code> if the activation is done manually using
100 * {@link #show(Point)} 106 * {@link #show(Point)}
101 * @see #RECREATE 107 * @see #RECREATE
106 this.style = style; 112 this.style = style;
107 this.hideListener = new TooltipHideListener(); 113 this.hideListener = new TooltipHideListener();
108 this.control.addDisposeListener(new class DisposeListener { 114 this.control.addDisposeListener(new class DisposeListener {
109 115
110 public void widgetDisposed(DisposeEvent e) { 116 public void widgetDisposed(DisposeEvent e) {
117 data = null;
111 deactivate(); 118 deactivate();
112 } 119 }
113 120
114 }); 121 });
115 122
116 this.listener = new ToolTipOwnerControlListener(); 123 this.listener = new ToolTipOwnerControlListener();
124 this.shellListener = new Listener() {
125 public void handleEvent(final Event event) {
126 if( ToolTip.this.control !is null && ! ToolTip.this.control.isDisposed() ) {
127 ToolTip.this.control.getDisplay().asyncExec(new Runnable() {
128
129 public void run() {
130 // Check if the new active shell is the tooltip itself
131 if( ToolTip.this.control.getDisplay().getActiveShell() !is CURRENT_TOOLTIP) {
132 toolTipHide(CURRENT_TOOLTIP, event);
133 }
134 }
135
136 });
137 }
138 }
139 };
117 140
118 if (!manualActivation) { 141 if (!manualActivation) {
119 activate(); 142 activate();
120 } 143 }
121 } 144 }
294 * 317 *
295 * @param event 318 * @param event
296 * the event 319 * the event
297 * @return the area responsible for the tooltip creation or 320 * @return the area responsible for the tooltip creation or
298 * <code>null</code> this could be any object describing the area 321 * <code>null</code> this could be any object describing the area
299 * (e.g. the {@link Control} onto which the tooltip is bound to, a part of 322 * (e.g. the {@link Control} onto which the tooltip is bound to, a
300 * this area e.g. for {@link ColumnViewer} this could be a 323 * part of this area e.g. for {@link ColumnViewer} this could be a
301 * {@link ViewerCell}) 324 * {@link ViewerCell})
302 */ 325 */
303 protected Object getToolTipArea(Event event) { 326 protected Object getToolTipArea(Event event) {
304 return control; 327 return control;
305 } 328 }
341 } else { 364 } else {
342 toolTipHookByTypeRecursively(tip, true, DWT.MouseExit); 365 toolTipHookByTypeRecursively(tip, true, DWT.MouseExit);
343 } 366 }
344 367
345 tip.pack(); 368 tip.pack();
346 tip.setLocation(fixupDisplayBounds(tip.getSize(), getLocation(tip 369 Point size = tip.getSize();
347 .getSize(), event))); 370 Point location = fixupDisplayBounds(size, getLocation(size, event));
371
372 // Need to adjust a bit more if the mouse cursor.y is tip.y and
373 // the cursor.x is inside the tip
374 Point cursorLocation = tip.getDisplay().getCursorLocation();
375
376 if( cursorLocation.y is location.y && location.x < cursorLocation.x && location.x + size.x > cursorLocation.x ) {
377 location.y -= 2;
378 }
379
380 tip.setLocation(location);
348 tip.setVisible(true); 381 tip.setVisible(true);
349 } 382 }
350 } 383 }
351 384
352 private Point fixupDisplayBounds(Point tipSize, Point location) { 385 private Point fixupDisplayBounds(Point tipSize, Point location) {
375 } else { 408 } else {
376 bounds = control.getDisplay().getBounds(); 409 bounds = control.getDisplay().getBounds();
377 } 410 }
378 411
379 if (!(bounds.contains(location) && bounds.contains(rightBounds))) { 412 if (!(bounds.contains(location) && bounds.contains(rightBounds))) {
380 if (rightBounds.x > bounds.width) { 413 if (rightBounds.x > bounds.x + bounds.width) {
381 location.x -= rightBounds.x - bounds.width; 414 location.x -= rightBounds.x - (bounds.x + bounds.width);
382 } 415 }
383 416
384 if (rightBounds.y > bounds.height) { 417 if (rightBounds.y > bounds.y + bounds.height) {
385 location.y -= rightBounds.y - bounds.height; 418 location.y -= rightBounds.y - (bounds.y + bounds.height);
386 } 419 }
387 420
388 if (location.x < bounds.x) { 421 if (location.x < bounds.x) {
389 location.x = bounds.x; 422 location.x = bounds.x;
390 } 423 }
412 return control.toDisplay(event.x + xShift, event.y + yShift); 445 return control.toDisplay(event.x + xShift, event.y + yShift);
413 } 446 }
414 447
415 private void toolTipHide(Shell tip, Event event) { 448 private void toolTipHide(Shell tip, Event event) {
416 if (tip !is null && !tip.isDisposed() && shouldHideToolTip(event)) { 449 if (tip !is null && !tip.isDisposed() && shouldHideToolTip(event)) {
450 control.getShell().removeListener(DWT.Deactivate, shellListener);
417 currentArea = null; 451 currentArea = null;
452 passOnEvent(tip,event);
418 tip.dispose(); 453 tip.dispose();
419 CURRENT_TOOLTIP = null; 454 CURRENT_TOOLTIP = null;
420 afterHideToolTip(event); 455 afterHideToolTip(event);
456 }
457 }
458
459 private void passOnEvent(Shell tip,Event event) {
460 if ( control !is null && ! control.isDisposed() && event !is null && event.widget !is control && event.type is DWT.MouseDown) {
461 final Display display = control.getDisplay();
462 Point newPt = display.map(tip, null, new Point(event.x, event.y));
463
464 final Event newEvent = new Event();
465 newEvent.button=event.button;
466 newEvent.character=event.character;
467 newEvent.count = event.count;
468 newEvent.data=event.data;
469 newEvent.detail=event.detail;
470 newEvent.display=event.display;
471 newEvent.doit=event.doit;
472 newEvent.end=event.end;
473 newEvent.gc=event.gc;
474 newEvent.height=event.height;
475 newEvent.index=event.index;
476 newEvent.item=event.item;
477 newEvent.keyCode=event.keyCode;
478 newEvent.start=event.start;
479 newEvent.stateMask=event.stateMask;
480 newEvent.text=event.text;
481 newEvent.time=event.time;
482 newEvent.type=event.type;
483 newEvent.widget=event.widget;
484 newEvent.width=event.width;
485 newEvent.x = newPt.x;
486 newEvent.y = newPt.y;
487
488 tip.close();
489 display.asyncExec(new Runnable() {
490 public void run() {
491 if( IS_OSX ) {
492 try {
493 Thread.sleep(300);
494 } catch (InterruptedException e) {
495
496 }
497
498 display.post(newEvent);
499 newEvent.type = DWT.MouseUp;
500 display.post(newEvent);
501 } else {
502 display.post(newEvent);
503 }
504 }
505 });
421 } 506 }
422 } 507 }
423 508
424 private void toolTipOpen(Shell shell, Event event) { 509 private void toolTipOpen(Shell shell, Event event) {
425 // Ensure that only one Tooltip is shown in time 510 // Ensure that only one Tooltip is shown in time
426 if (CURRENT_TOOLTIP !is null) { 511 if (CURRENT_TOOLTIP !is null) {
427 toolTipHide(CURRENT_TOOLTIP, null); 512 toolTipHide(CURRENT_TOOLTIP, null);
428 } 513 }
429 514
430 CURRENT_TOOLTIP = shell; 515 CURRENT_TOOLTIP = shell;
516
517 control.getShell().addListener(DWT.Deactivate, shellListener);
431 518
432 if (popupDelay > 0) { 519 if (popupDelay > 0) {
433 control.getDisplay().timerExec(popupDelay, new class(shell,event) Runnable { 520 control.getDisplay().timerExec(popupDelay, new class(shell,event) Runnable {
434 Shell shell_; 521 Shell shell_;
435 Event event_; 522 Event event_;