summaryrefslogtreecommitdiffstats
path: root/src/com/vaadin/terminal/gwt/client/VTooltip.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/com/vaadin/terminal/gwt/client/VTooltip.java')
-rw-r--r--src/com/vaadin/terminal/gwt/client/VTooltip.java214
1 files changed, 155 insertions, 59 deletions
diff --git a/src/com/vaadin/terminal/gwt/client/VTooltip.java b/src/com/vaadin/terminal/gwt/client/VTooltip.java
index 70f4a0de0a..7fd3a3238b 100644
--- a/src/com/vaadin/terminal/gwt/client/VTooltip.java
+++ b/src/com/vaadin/terminal/gwt/client/VTooltip.java
@@ -3,12 +3,19 @@
*/
package com.vaadin.terminal.gwt.client;
+import com.google.gwt.event.dom.client.ClickEvent;
+import com.google.gwt.event.dom.client.ClickHandler;
+import com.google.gwt.event.dom.client.KeyDownEvent;
+import com.google.gwt.event.dom.client.KeyDownHandler;
+import com.google.gwt.event.dom.client.MouseMoveEvent;
+import com.google.gwt.event.dom.client.MouseMoveHandler;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.FlowPanel;
+import com.google.gwt.user.client.ui.Widget;
import com.vaadin.terminal.gwt.client.ui.VOverlay;
/**
@@ -27,15 +34,12 @@ public class VTooltip extends VOverlay {
private static final int QUICK_OPEN_DELAY = 100;
VErrorMessage em = new VErrorMessage();
Element description = DOM.createDiv();
- private ComponentConnector tooltipOwner;
private boolean closing = false;
private boolean opening = false;
private ApplicationConnection ac;
// Open next tooltip faster. Disabled after 2 sec of showTooltip-silence.
private boolean justClosed = false;
- // If this is "additional" tooltip, this field contains the key for it
- private Object tooltipKey;
public VTooltip(ApplicationConnection client) {
super(false, false, true);
@@ -115,51 +119,30 @@ public class VTooltip extends VOverlay {
}
}
- public void showTooltip(ComponentConnector owner, Event event, Object key) {
- if (closing && tooltipOwner == owner && tooltipKey == key) {
- // return to same tooltip, cancel closing
- closeTimer.cancel();
- closing = false;
- justClosedTimer.cancel();
- justClosed = false;
- return;
- }
+ private void showTooltip() {
- if (closing) {
+ // Close current tooltip
+ if (isShowing()) {
closeNow();
}
- updatePosition(event);
-
- if (opening) {
- showTimer.cancel();
- }
- tooltipOwner = owner;
- tooltipKey = key;
-
// Schedule timer for showing the tooltip according to if it was
// recently closed or not.
- if (justClosed) {
- showTimer.schedule(QUICK_OPEN_DELAY);
- } else {
- showTimer.schedule(OPEN_DELAY);
- }
+ int timeout = justClosed ? QUICK_OPEN_DELAY : OPEN_DELAY;
+ showTimer.schedule(timeout);
opening = true;
}
private void closeNow() {
- if (closing) {
- hide();
- tooltipOwner = null;
- setWidth("");
- closing = false;
- }
+ hide();
+ setWidth("");
+ closing = false;
}
private Timer showTimer = new Timer() {
@Override
public void run() {
- TooltipInfo info = ac.getTooltipTitleInfo(tooltipOwner, tooltipKey);
+ TooltipInfo info = tooltipEventHandler.getTooltipInfo();
if (null != info) {
show(info);
}
@@ -187,7 +170,6 @@ public class VTooltip extends VOverlay {
if (opening) {
showTimer.cancel();
opening = false;
- tooltipOwner = null;
}
if (!isAttached()) {
return;
@@ -209,24 +191,6 @@ public class VTooltip extends VOverlay {
public void updatePosition(Event event) {
tooltipEventMouseX = DOM.eventGetClientX(event);
tooltipEventMouseY = DOM.eventGetClientY(event);
-
- }
-
- public void handleTooltipEvent(Event event, ComponentConnector owner,
- Object key) {
- final int type = DOM.eventGetType(event);
- if ((VTooltip.TOOLTIP_EVENTS & type) == type) {
- if (type == Event.ONMOUSEOVER) {
- showTooltip(owner, event, key);
- } else if (type == Event.ONMOUSEMOVE) {
- updatePosition(event);
- } else {
- hideTooltip();
- }
- } else {
- // non-tooltip event, hide tooltip
- hideTooltip();
- }
}
@Override
@@ -235,17 +199,149 @@ public class VTooltip extends VOverlay {
// cancel closing event if tooltip is mouseovered; the user might want
// to scroll of cut&paste
- switch (type) {
- case Event.ONMOUSEOVER:
+ if (type == Event.ONMOUSEOVER) {
+ // Cancel closing so tooltip stays open and user can copy paste the
+ // tooltip
closeTimer.cancel();
closing = false;
- break;
- case Event.ONMOUSEOUT:
+ }
+ }
+
+ /**
+ * Replace current open tooltip with new content
+ */
+ public void replaceCurrentTooltip() {
+ if (closing) {
+ closeTimer.cancel();
+ closeNow();
+ }
+
+ TooltipInfo info = tooltipEventHandler.getTooltipInfo();
+ if (null != info) {
+ show(info);
+ }
+ opening = false;
+ }
+
+ private class TooltipEventHandler implements MouseMoveHandler,
+ ClickHandler, KeyDownHandler {
+
+ /**
+ * Current element hovered
+ */
+ private com.google.gwt.dom.client.Element currentElement = null;
+
+ /**
+ * Current tooltip active
+ */
+ private TooltipInfo currentTooltipInfo = null;
+
+ /**
+ * Get current active tooltip information
+ *
+ * @return Current active tooltip information or null
+ */
+ public TooltipInfo getTooltipInfo() {
+ return currentTooltipInfo;
+ }
+
+ /**
+ * Locate connector and it's tooltip for given element
+ *
+ * @param element
+ * Element used in search
+ * @return true if connector and tooltip found
+ */
+ private boolean resolveConnector(Element element) {
+
+ ComponentConnector connector = Util.getConnectorForElement(ac, ac
+ .getRootConnector().getWidget(), element);
+
+ // Try to find first connector with proper tooltip info
+ TooltipInfo info = null;
+ while (connector != null) {
+
+ info = connector.getTooltipInfo(element);
+
+ if (info != null && info.hasMessage()) {
+ break;
+ }
+
+ if (!(connector.getParent() instanceof ComponentConnector)) {
+ connector = null;
+ info = null;
+ break;
+ }
+ connector = (ComponentConnector) connector.getParent();
+ }
+
+ if (connector != null && info != null) {
+ currentTooltipInfo = info;
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * Handle hide event
+ *
+ * @param event
+ * Event causing hide
+ */
+ private void handleHideEvent() {
hideTooltip();
- break;
- default:
- // NOP
+ currentTooltipInfo = null;
+ }
+
+ public void onMouseMove(MouseMoveEvent mme) {
+ Event event = Event.as(mme.getNativeEvent());
+ com.google.gwt.dom.client.Element element = Element.as(event
+ .getEventTarget());
+
+ // We can ignore move event if it's handled by move or over already
+ if (currentElement == element) {
+ return;
+ }
+ currentElement = element;
+
+ boolean connectorAndTooltipFound = resolveConnector((com.google.gwt.user.client.Element) element);
+ if (!connectorAndTooltipFound) {
+ if (isShowing()) {
+ handleHideEvent();
+ } else {
+ currentTooltipInfo = null;
+ }
+ } else {
+ updatePosition(event);
+ if (isShowing()) {
+ replaceCurrentTooltip();
+ } else {
+ showTooltip();
+ }
+ }
+ }
+
+ public void onClick(ClickEvent event) {
+ handleHideEvent();
+ }
+
+ public void onKeyDown(KeyDownEvent event) {
+ handleHideEvent();
}
}
+ private final TooltipEventHandler tooltipEventHandler = new TooltipEventHandler();
+
+ /**
+ * Connects DOM handlers to widget that are needed for tooltip presentation.
+ *
+ * @param widget
+ * Widget which DOM handlers are connected
+ */
+ public void connectHandlersToWidget(Widget widget) {
+ widget.addDomHandler(tooltipEventHandler, MouseMoveEvent.getType());
+ widget.addDomHandler(tooltipEventHandler, ClickEvent.getType());
+ widget.addDomHandler(tooltipEventHandler, KeyDownEvent.getType());
+ }
}