diff 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
line wrap: on
line diff
--- a/dwtx/jface/window/ToolTip.d	Mon May 19 13:41:06 2008 +0200
+++ b/dwtx/jface/window/ToolTip.d	Thu May 22 01:36:46 2008 +0200
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2006, 2007 IBM Corporation and others.
+ * Copyright (c) 2006, 2008 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -7,6 +7,7 @@
  *
  * Contributors:
  *     Tom Schindl <tom.schindl@bestsolution.at> - initial API and implementation
+ *                                                 bugfix in: 195137, 198089, 225190
  * Port to the D programming language:
  *     Frank Benoit <benoit@tionex.de>
  *******************************************************************************/
@@ -23,6 +24,7 @@
 import dwt.layout.FillLayout;
 import dwt.widgets.Composite;
 import dwt.widgets.Control;
+import dwt.widgets.Display;
 import dwt.widgets.Event;
 import dwt.widgets.Listener;
 import dwt.widgets.Monitor;
@@ -69,6 +71,8 @@
 
     private TooltipHideListener hideListener;
 
+    private Listener shellListener;
+
     private bool hideOnMouseDown = true;
 
     private bool respectDisplayBounds = true;
@@ -79,6 +83,8 @@
 
     private Object currentArea;
 
+    private static final bool IS_OSX = DWT.getPlatform().equals("carbon"); //$NON-NLS-1$
+
     /**
      * Create new instance which add TooltipSupport to the widget
      *
@@ -93,7 +99,7 @@
      * @param control
      *            the control to which the tooltip is bound
      * @param style
-     *            style passed to control tooltip behaviour
+     *            style passed to control tooltip behavior
      *
      * @param manualActivation
      *            <code>true</code> if the activation is done manually using
@@ -108,12 +114,29 @@
         this.control.addDisposeListener(new class DisposeListener {
 
             public void widgetDisposed(DisposeEvent e) {
+                data = null;
                 deactivate();
             }
 
         });
 
         this.listener = new ToolTipOwnerControlListener();
+        this.shellListener = new Listener() {
+            public void handleEvent(final Event event) {
+                if( ToolTip.this.control !is null && ! ToolTip.this.control.isDisposed() ) {
+                    ToolTip.this.control.getDisplay().asyncExec(new Runnable() {
+
+                        public void run() {
+                            // Check if the new active shell is the tooltip itself
+                            if( ToolTip.this.control.getDisplay().getActiveShell() !is CURRENT_TOOLTIP) {
+                                toolTipHide(CURRENT_TOOLTIP, event);
+                            }
+                        }
+                        
+                    });                 
+                }
+            }
+        };
 
         if (!manualActivation) {
             activate();
@@ -296,8 +319,8 @@
      *            the event
      * @return the area responsible for the tooltip creation or
      *         <code>null</code> this could be any object describing the area
-     *         (e.g. the {@link Control}  onto which the tooltip is bound to, a part of
-     *         this area e.g. for {@link ColumnViewer} this could be a
+     *         (e.g. the {@link Control} onto which the tooltip is bound to, a
+     *         part of this area e.g. for {@link ColumnViewer} this could be a
      *         {@link ViewerCell})
      */
     protected Object getToolTipArea(Event event) {
@@ -343,8 +366,18 @@
             }
 
             tip.pack();
-            tip.setLocation(fixupDisplayBounds(tip.getSize(), getLocation(tip
-                    .getSize(), event)));
+            Point size = tip.getSize();
+            Point location = fixupDisplayBounds(size, getLocation(size, event));
+
+            // Need to adjust a bit more if the mouse cursor.y is tip.y and
+            // the cursor.x is inside the tip
+            Point cursorLocation = tip.getDisplay().getCursorLocation();
+
+            if( cursorLocation.y is location.y && location.x < cursorLocation.x && location.x + size.x > cursorLocation.x ) {
+                location.y -= 2;
+            }
+
+            tip.setLocation(location);
             tip.setVisible(true);
         }
     }
@@ -377,12 +410,12 @@
             }
 
             if (!(bounds.contains(location) && bounds.contains(rightBounds))) {
-                if (rightBounds.x > bounds.width) {
-                    location.x -= rightBounds.x - bounds.width;
+                if (rightBounds.x > bounds.x + bounds.width) {
+                    location.x -= rightBounds.x - (bounds.x + bounds.width);
                 }
 
-                if (rightBounds.y > bounds.height) {
-                    location.y -= rightBounds.y - bounds.height;
+                if (rightBounds.y > bounds.y + bounds.height) {
+                    location.y -= rightBounds.y - (bounds.y + bounds.height);
                 }
 
                 if (location.x < bounds.x) {
@@ -414,13 +447,65 @@
 
     private void toolTipHide(Shell tip, Event event) {
         if (tip !is null && !tip.isDisposed() && shouldHideToolTip(event)) {
+            control.getShell().removeListener(DWT.Deactivate, shellListener);
             currentArea = null;
+            passOnEvent(tip,event);
             tip.dispose();
             CURRENT_TOOLTIP = null;
             afterHideToolTip(event);
         }
     }
 
+    private void passOnEvent(Shell tip,Event event) {
+        if ( control !is null && ! control.isDisposed() && event !is null && event.widget !is control && event.type is DWT.MouseDown) {
+            final Display display = control.getDisplay();
+            Point newPt = display.map(tip, null, new Point(event.x, event.y));
+
+            final Event newEvent = new Event();
+            newEvent.button=event.button;
+            newEvent.character=event.character;
+            newEvent.count = event.count;
+            newEvent.data=event.data;
+            newEvent.detail=event.detail;
+            newEvent.display=event.display;
+            newEvent.doit=event.doit;
+            newEvent.end=event.end;
+            newEvent.gc=event.gc;
+            newEvent.height=event.height;
+            newEvent.index=event.index;
+            newEvent.item=event.item;
+            newEvent.keyCode=event.keyCode;
+            newEvent.start=event.start;
+            newEvent.stateMask=event.stateMask;
+            newEvent.text=event.text;
+            newEvent.time=event.time;
+            newEvent.type=event.type;
+            newEvent.widget=event.widget;
+            newEvent.width=event.width;
+            newEvent.x = newPt.x;
+            newEvent.y = newPt.y;
+
+            tip.close();
+            display.asyncExec(new Runnable() {
+                public void run() {
+                    if( IS_OSX ) {
+                        try {
+                            Thread.sleep(300);
+                        } catch (InterruptedException e) {
+
+                        }
+
+                        display.post(newEvent);
+                        newEvent.type = DWT.MouseUp;
+                        display.post(newEvent);
+                    } else {
+                        display.post(newEvent);
+                    }
+                }
+            });
+        }
+    }
+
     private void toolTipOpen(Shell shell, Event event) {
         // Ensure that only one Tooltip is shown in time
         if (CURRENT_TOOLTIP !is null) {
@@ -429,6 +514,8 @@
 
         CURRENT_TOOLTIP = shell;
 
+        control.getShell().addListener(DWT.Deactivate, shellListener);
+
         if (popupDelay > 0) {
             control.getDisplay().timerExec(popupDelay, new class(shell,event) Runnable {
                 Shell shell_;