From 75759dad387efb5eb7d44dcc71633cb77d735102 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Leif=20=C3=85strand?= Date: Wed, 31 Aug 2011 10:50:22 +0000 Subject: [PATCH] Added option to sink the same events on the overlay shadow to avoid flickering tooltip if mouse pointer is over the shadow (#7097) svn changeset:20770/svn branch:6.7 --- .../vaadin/terminal/gwt/client/VTooltip.java | 1 + .../terminal/gwt/client/ui/VOverlay.java | 60 ++++++++++++++++++- 2 files changed, 59 insertions(+), 2 deletions(-) diff --git a/src/com/vaadin/terminal/gwt/client/VTooltip.java b/src/com/vaadin/terminal/gwt/client/VTooltip.java index 725c89a204..1f2ee809ed 100644 --- a/src/com/vaadin/terminal/gwt/client/VTooltip.java +++ b/src/com/vaadin/terminal/gwt/client/VTooltip.java @@ -46,6 +46,7 @@ public class VTooltip extends VOverlay { layout.add(em); DOM.setElementProperty(description, "className", CLASSNAME + "-text"); DOM.appendChild(layout.getElement(), description); + setSinkShadowEvents(true); } /** diff --git a/src/com/vaadin/terminal/gwt/client/ui/VOverlay.java b/src/com/vaadin/terminal/gwt/client/ui/VOverlay.java index a277b4c42d..27b8840823 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VOverlay.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VOverlay.java @@ -67,6 +67,8 @@ public class VOverlay extends PopupPanel implements CloseHandler { */ private static final String SHADOW_HTML = "
"; + private boolean sinkShadowEvents = false; + public VOverlay() { super(); adjustZIndex(); @@ -116,11 +118,18 @@ public class VOverlay extends PopupPanel implements CloseHandler { } private void removeShadowIfPresent() { - if (isShadowEnabled() && shadow.getParentElement() != null) { + if (isShadowAttached()) { shadow.getParentElement().removeChild(shadow); + + // Remove event listener from the shadow + unsinkShadowEvents(); } } + private boolean isShadowAttached() { + return isShadowEnabled() && shadow.getParentElement() != null; + } + private void adjustZIndex() { setZIndex(Z_INDEX); } @@ -366,8 +375,9 @@ public class VOverlay extends PopupPanel implements CloseHandler { } // Attach to dom if not there already - if (shadow.getParentElement() == null) { + if (!isShadowAttached()) { RootPanel.get().getElement().insertBefore(shadow, getElement()); + sinkShadowEvents(); } } @@ -382,4 +392,50 @@ public class VOverlay extends PopupPanel implements CloseHandler { public void onClose(CloseEvent event) { removeShadowIfPresent(); } + + @Override + public void sinkEvents(int eventBitsToAdd) { + super.sinkEvents(eventBitsToAdd); + // Also sink events on the shadow if present + sinkShadowEvents(); + } + + private void sinkShadowEvents() { + if (isSinkShadowEvents() && isShadowAttached()) { + // Sink the same events as the actual overlay has sunk + DOM.sinkEvents(shadow, DOM.getEventsSunk(getElement())); + // Send events to VOverlay.onBrowserEvent + DOM.setEventListener(shadow, this); + } + } + + private void unsinkShadowEvents() { + if (isShadowAttached()) { + DOM.setEventListener(shadow, null); + DOM.sinkEvents(shadow, 0); + } + } + + /** + * Enables or disables sinking the events of the shadow to the same + * onBrowserEvent as events to the actual overlay goes. + * + * Please note, that if you enable this, you can't assume that e.g. + * event.getEventTarget returns an element inside the DOM structure of the + * overlay + * + * @param sinkShadowEvents + */ + protected void setSinkShadowEvents(boolean sinkShadowEvents) { + this.sinkShadowEvents = sinkShadowEvents; + if (sinkShadowEvents) { + sinkShadowEvents(); + } else { + unsinkShadowEvents(); + } + } + + protected boolean isSinkShadowEvents() { + return sinkShadowEvents; + } } -- 2.39.5