background-color: #FFE0E0;\r
}
+/**
+ * Custom toolktip
+ */
+ .i-tooltip {
+ background-color: #ffffcc;
+ border: 1px solid #464f52;
+ font-size: 12px;
+ font-family: "Trebuchet MS", geneva, helvetica, arial, tahoma, verdana, sans-serif;
+ color: #464f52;
+ }
+
+.i-tooltip-text {
+ margin: 4px;
+}
+
+ .i-tooltip .i-errormessage {
+ padding: 4px;
+ border-width: 0 0 1px 0;
+ }
+
/**
* Context menu styles
*/
background-color: #FFE0E0;
}
+/**
+ * Custom toolktip
+ */
+ .i-tooltip {
+ background-color: #ffffcc;
+ border: 1px solid #464f52;
+ font-size: 12px;
+ font-family: "Trebuchet MS", geneva, helvetica, arial, tahoma, verdana, sans-serif;
+ color: #464f52;
+ }
+
+ .i-tooltip-text {
+ margin: 4px;
+}
+
+ .i-tooltip .i-errormessage {
+ padding: 4px;
+ border-width: 0 0 1px 0;
+ }
+
+
/**
* Context menu styles
*/
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.DeferredCommand;
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.WindowCloseListener;
private final HashMap paintableToId = new HashMap();
+ /** Contains ExtendedTitleInfo by paintable id */
+ private final HashMap paintableToTitle = new HashMap();
+
private final WidgetSet widgetSet;
private ContextMenu contextMenu = null;
}
public void unregisterPaintable(Paintable p) {
- idToPaintable.remove(paintableToId.get(p));
+ Object id = paintableToId.get(p);
+ idToPaintable.remove(id);
+ paintableToTitle.remove(id);
paintableToId.remove(p);
if (p instanceof HasWidgets) {
styleBuf.append(" ");
styleBuf.append(MODIFIED_CLASSNAME);
}
+
+ TooltipInfo tooltipInfo = getTitleInfo((Paintable) component);
+ if (uidl.hasAttribute("description")) {
+ tooltipInfo.setTitle(uidl.getStringAttribute("description"));
+ }
+
// add error classname to components w/ error
if (uidl.hasAttribute("error")) {
styleBuf.append(" ");
styleBuf.append(primaryName);
styleBuf.append(ERROR_CLASSNAME_EXT);
+
+ tooltipInfo.setErrorUidl(uidl.getErrors());
+ } else {
+ tooltipInfo.setErrorUidl(null);
}
// Styles + disabled & readonly
}
}
+
+ /* Extended title handling */
+
+ /**
+ * Data showed in tooltips are stored centrilized as it may be needed in
+ * varios place: caption, layouts, and in owner components themselves.
+ *
+ * Updating TooltipInfo is done in updateComponent method.
+ *
+ */
+ public TooltipInfo getTitleInfo(Paintable titleOwner) {
+ TooltipInfo info = (TooltipInfo) paintableToTitle.get(titleOwner);
+ if (info == null) {
+ info = new TooltipInfo();
+ paintableToTitle.put(titleOwner, info);
+ }
+ return info;
+ }
+
+ private final Tooltip tooltip = new Tooltip(this);
+
+ /**
+ * Component may want to delegate Tooltip handling to client. Layouts add
+ * Tooltip (description, errors) to caption, but some components may want
+ * them to appear one other elements too.
+ *
+ * Events wanted by this handler are same as in Tooltip.TOOLTIP_EVENTS
+ *
+ * @param event
+ * @param owner
+ */
+ public void handleTooltipEvent(Event event, Paintable owner) {
+ tooltip.handleTooltipEvent(event, owner);
+
+ }
}
private Element captionText;
- private ErrorMessage errorMessage;
-
private final ApplicationConnection client;
/**
if (uidl.hasAttribute("error")) {
isEmpty = false;
- final UIDL errorUidl = uidl.getErrors();
-
if (errorIndicatorElement == null) {
errorIndicatorElement = DOM.createDiv();
if (Util.isIE()) {
"i-errorindicator");
DOM.appendChild(getElement(), errorIndicatorElement);
}
- if (errorMessage == null) {
- errorMessage = new ErrorMessage();
- }
- errorMessage.updateFromUIDL(errorUidl);
-
} else if (errorIndicatorElement != null) {
DOM.removeChild(getElement(), errorIndicatorElement);
errorIndicatorElement = null;
DOM.removeChild(getElement(), icon.getElement());
icon = null;
}
-
}
if (uidl.hasAttribute("caption")) {
if (uidl.hasAttribute("description")) {
if (captionText != null) {
- DOM.setElementProperty(captionText, "title", uidl
- .getStringAttribute("description"));
addStyleDependentName("hasdescription");
} else {
- setTitle(uidl.getStringAttribute("description"));
removeStyleDependentName("hasdescription");
}
}
public void onBrowserEvent(Event event) {
final Element target = DOM.eventGetTarget(event);
- if (errorIndicatorElement != null
- && DOM.compare(target, errorIndicatorElement)) {
- switch (DOM.eventGetType(event)) {
- case Event.ONMOUSEOVER:
- showErrorMessage();
- break;
- case Event.ONMOUSEOUT:
- hideErrorMessage();
- break;
- case Event.ONCLICK:
- ApplicationConnection.getConsole().log(
- DOM.getInnerHTML(errorMessage.getElement()));
- default:
- break;
- }
+ if (client != null && !DOM.compare(target, getElement())) {
+ client.handleTooltipEvent(event, owner);
} else {
super.onBrowserEvent(event);
}
}
- private void hideErrorMessage() {
- if (errorMessage != null) {
- errorMessage.hide();
- }
- }
-
- private void showErrorMessage() {
- if (errorMessage != null) {
- errorMessage.showAt(errorIndicatorElement);
- }
- }
-
public static boolean isNeeded(UIDL uidl) {
if (uidl.getStringAttribute("caption") != null) {
return true;
--- /dev/null
+package com.itmill.toolkit.terminal.gwt.client;
+
+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.itmill.toolkit.terminal.gwt.client.ui.ToolkitOverlay;
+
+/**
+ * TODO open for extension
+ */
+public class Tooltip extends ToolkitOverlay {
+ private static final String CLASSNAME = "i-tooltip";
+ private static final int MARGIN = 4;
+ public static final int TOOLTIP_EVENTS = Event.ONKEYDOWN
+ | Event.ONMOUSEOVER | Event.ONMOUSEOUT | Event.ONMOUSEMOVE
+ | Event.ONCLICK;
+ protected static final int MAX_WIDTH = 280;
+ ErrorMessage em = new ErrorMessage();
+ Element description = DOM.createDiv();
+ private Paintable tooltipOwner;
+ private boolean closing;
+ private boolean opening;
+ private ApplicationConnection ac;
+
+ public Tooltip(ApplicationConnection client) {
+ ac = client;
+ setStyleName(CLASSNAME);
+ FlowPanel layout = new FlowPanel();
+ setWidget(layout);
+ layout.add(em);
+ DOM.setElementProperty(description, "className", CLASSNAME + "-text");
+ DOM.appendChild(layout.getElement(), description);
+ }
+
+ private void show(TooltipInfo info) {
+ boolean hasContent = false;
+ if (info.getErrorUidl() != null) {
+ em.setVisible(true);
+ em.updateFromUIDL(info.getErrorUidl());
+ hasContent = true;
+ } else {
+ em.setVisible(false);
+ }
+ if (info.getTitle() != null && !"".equals(info.getTitle())) {
+ DOM.setInnerHTML(description, info.getTitle());
+ hasContent = true;
+ } else {
+ DOM.setInnerHTML(description, "");
+ }
+ if (hasContent) {
+ setPopupPositionAndShow(new PositionCallback() {
+ public void setPosition(int offsetWidth, int offsetHeight) {
+
+ if (offsetWidth > MAX_WIDTH) {
+ setWidth(MAX_WIDTH + "px");
+ }
+
+ offsetWidth = getOffsetWidth();
+
+ int x = tooltipEventMouseX + 10;
+ int y = tooltipEventMouseY + 10;
+
+ if (x + offsetWidth + MARGIN - Window.getScrollLeft() > Window
+ .getClientWidth()) {
+ x = Window.getClientWidth() - offsetWidth - MARGIN;
+ }
+
+ if (y + offsetHeight + MARGIN - Window.getScrollTop() > Window
+ .getClientHeight()) {
+ y = tooltipEventMouseY - 5 - offsetHeight;
+ }
+
+ setPopupPosition(x, y);
+ }
+ });
+ } else {
+ hide();
+ }
+ }
+
+ public void showTooltip(Paintable owner, Event event) {
+ if (closing && tooltipOwner == owner) {
+ closeTimer.cancel();
+ closing = false;
+ return;
+ }
+ updatePosition(event);
+
+ if (opening) {
+ showTimer.cancel();
+ }
+ tooltipOwner = owner;
+ showTimer.schedule(1000);
+ opening = true;
+
+ }
+
+ private Timer showTimer = new Timer() {
+ public void run() {
+ TooltipInfo info = ac.getTitleInfo(tooltipOwner);
+ show(info);
+ opening = false;
+
+ }
+ };
+
+ private Timer closeTimer = new Timer() {
+ public void run() {
+ hide();
+ closing = false;
+ tooltipOwner = null;
+ setWidth("");
+ }
+ };
+
+ public void hideTooltip() {
+ if (opening) {
+ showTimer.cancel();
+ opening = false;
+ tooltipOwner = null;
+ }
+ if (!isAttached()) {
+ return;
+ }
+ if (closing) {
+ // already about to close
+ return;
+ }
+ closeTimer.schedule(300);
+ }
+
+ private int tooltipEventMouseX;
+ private int tooltipEventMouseY;
+
+ public void updatePosition(Event event) {
+ tooltipEventMouseX = DOM.eventGetClientX(event);
+ tooltipEventMouseY = DOM.eventGetClientY(event);
+
+ }
+
+ public void handleTooltipEvent(Event event, Paintable owner) {
+ final int type = DOM.eventGetType(event);
+ if ((Tooltip.TOOLTIP_EVENTS & type) == type) {
+ if (type == Event.ONMOUSEOVER) {
+ showTooltip(owner, event);
+ } else if (type == Event.ONMOUSEMOVE) {
+ updatePosition(event);
+ } else {
+ hideTooltip();
+ }
+ } else {
+ ApplicationConnection.getConsole().log(
+ "Hiding tooltip on" + DOM.eventGetTypeString(event));
+ hideTooltip();
+ }
+ }
+
+}
--- /dev/null
+package com.itmill.toolkit.terminal.gwt.client;
+
+public class TooltipInfo {
+
+ private String title;
+
+ private UIDL errorUidl;
+
+ public String getTitle() {
+ return title;
+ }
+
+ public void setTitle(String title) {
+ this.title = title;
+ }
+
+ public UIDL getErrorUidl() {
+ return errorUidl;
+ }
+
+ public void setErrorUidl(UIDL errorUidl) {
+ this.errorUidl = errorUidl;
+ }
+
+}
import com.google.gwt.user.client.ui.ClickListener;
import com.google.gwt.user.client.ui.Widget;
import com.itmill.toolkit.terminal.gwt.client.ApplicationConnection;
-import com.itmill.toolkit.terminal.gwt.client.ErrorMessage;
import com.itmill.toolkit.terminal.gwt.client.Paintable;
+import com.itmill.toolkit.terminal.gwt.client.Tooltip;
import com.itmill.toolkit.terminal.gwt.client.UIDL;
public class IButton extends Button implements Paintable {
private final Element captionElement = DOM.createSpan();
- private ErrorMessage errorMessage;
-
private Icon icon;
public IButton() {
client.updateVariable(id, "state", true, true);
}
});
+ sinkEvents(Tooltip.TOOLTIP_EVENTS);
}
public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
// handle error
if (uidl.hasAttribute("error")) {
- final UIDL errorUidl = uidl.getErrors();
if (errorIndicatorElement == null) {
errorIndicatorElement = DOM.createDiv();
DOM.setElementProperty(errorIndicatorElement, "className",
"i-errorindicator");
- DOM.sinkEvents(errorIndicatorElement, Event.MOUSEEVENTS);
- sinkEvents(Event.MOUSEEVENTS);
}
DOM.insertChild(getElement(), errorIndicatorElement, 0);
- if (errorMessage == null) {
- errorMessage = new ErrorMessage();
- }
- errorMessage.updateFromUIDL(errorUidl);
} else if (errorIndicatorElement != null) {
DOM.removeChild(getElement(), errorIndicatorElement);
errorIndicatorElement = null;
}
-
+
if (uidl.hasAttribute("readonly")) {
setEnabled(false);
}
icon = null;
}
}
-
- // handle description
- if (uidl.hasAttribute("description")) {
- setTitle(uidl.getStringAttribute("description"));
- } else {
- setTitle(null);
- }
-
}
public void setText(String text) {
}
public void onBrowserEvent(Event event) {
- final Element target = DOM.eventGetTarget(event);
- if (errorIndicatorElement != null
- && DOM.compare(target, errorIndicatorElement)) {
- switch (DOM.eventGetType(event)) {
- case Event.ONMOUSEOVER:
- showErrorMessage();
- break;
- case Event.ONMOUSEOUT:
- hideErrorMessage();
- break;
- case Event.ONCLICK:
- ApplicationConnection.getConsole().log(
- DOM.getInnerHTML(errorMessage.getElement()));
- return;
- default:
- break;
- }
- }
super.onBrowserEvent(event);
- }
-
- private void hideErrorMessage() {
- errorMessage.hide();
- }
-
- private void showErrorMessage() {
- if (errorMessage != null) {
- errorMessage.showAt(errorIndicatorElement);
+ if (client != null) {
+ client.handleTooltipEvent(event, this);
}
}
import com.google.gwt.user.client.ui.ClickListener;
import com.google.gwt.user.client.ui.Widget;
import com.itmill.toolkit.terminal.gwt.client.ApplicationConnection;
-import com.itmill.toolkit.terminal.gwt.client.ErrorMessage;
import com.itmill.toolkit.terminal.gwt.client.Paintable;
+import com.itmill.toolkit.terminal.gwt.client.Tooltip;
import com.itmill.toolkit.terminal.gwt.client.UIDL;
public class ICheckBox extends com.google.gwt.user.client.ui.CheckBox implements
private Icon icon;
- private ErrorMessage errorMessage;
-
private boolean isBlockMode = false;
public ICheckBox() {
}
});
-
+ sinkEvents(Tooltip.TOOLTIP_EVENTS);
}
public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
}
if (uidl.hasAttribute("error")) {
- final UIDL errorUidl = uidl.getErrors();
-
if (errorIndicatorElement == null) {
errorIndicatorElement = DOM.createDiv();
- DOM.sinkEvents(errorIndicatorElement, Event.MOUSEEVENTS);
DOM.setElementProperty(errorIndicatorElement, "className",
"i-errorindicator");
DOM.appendChild(getElement(), errorIndicatorElement);
}
- if (errorMessage == null) {
- errorMessage = new ErrorMessage();
- }
- errorMessage.updateFromUIDL(errorUidl);
-
} else if (errorIndicatorElement != null) {
DOM.setStyleAttribute(errorIndicatorElement, "display", "none");
}
- if (uidl.hasAttribute("description")) {
- setTitle(uidl.getStringAttribute("description"));
- }
-
if (uidl.hasAttribute("readonly")) {
setEnabled(false);
}
public void onBrowserEvent(Event event) {
super.onBrowserEvent(event);
- final Element target = DOM.eventGetTarget(event);
- if (errorIndicatorElement != null
- && DOM.compare(target, errorIndicatorElement)) {
- switch (DOM.eventGetType(event)) {
- case Event.ONMOUSEOVER:
- errorMessage.showAt(errorIndicatorElement);
- break;
- case Event.ONMOUSEOUT:
- errorMessage.hide();
- break;
- case Event.ONCLICK:
- ApplicationConnection.getConsole().log(
- DOM.getInnerHTML(errorMessage.getElement()));
- default:
- break;
- }
+ if (client != null) {
+ client.handleTooltipEvent(event, this);
}
}
\r
import java.util.Date;\r
\r
+import com.google.gwt.user.client.Event;\r
import com.google.gwt.user.client.ui.FlowPanel;\r
import com.itmill.toolkit.terminal.gwt.client.ApplicationConnection;\r
import com.itmill.toolkit.terminal.gwt.client.DateTimeService;\r
import com.itmill.toolkit.terminal.gwt.client.LocaleNotLoadedException;\r
import com.itmill.toolkit.terminal.gwt.client.Paintable;\r
+import com.itmill.toolkit.terminal.gwt.client.Tooltip;\r
import com.itmill.toolkit.terminal.gwt.client.UIDL;\r
\r
public class IDateField extends FlowPanel implements Paintable, Field {\r
public IDateField() {\r
setStyleName(CLASSNAME);\r
dts = new DateTimeService();\r
+ sinkEvents(Tooltip.TOOLTIP_EVENTS);\r
+ }\r
+\r
+ public void onBrowserEvent(Event event) {\r
+ super.onBrowserEvent(event);\r
+ if (client != null) {\r
+ client.handleTooltipEvent(event, this);\r
+ }\r
}\r
\r
public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {\r
import com.itmill.toolkit.terminal.gwt.client.ApplicationConnection;
import com.itmill.toolkit.terminal.gwt.client.Focusable;
import com.itmill.toolkit.terminal.gwt.client.Paintable;
+import com.itmill.toolkit.terminal.gwt.client.Tooltip;
import com.itmill.toolkit.terminal.gwt.client.UIDL;
import com.itmill.toolkit.terminal.gwt.client.Util;
private final FlowPanel panel = new FlowPanel();
- private final TextBox tb = new TextBox();
+ private final TextBox tb = new TextBox() {
+ public void onBrowserEvent(Event event) {
+ super.onBrowserEvent(event);
+ if (client != null) {
+ client.handleTooltipEvent(event, IFilterSelect.this);
+ }
+ }
+ };
private final SuggestionPopup suggestionPopup = new SuggestionPopup();
public IFilterSelect() {
selectedItemIcon.setVisible(false);
panel.add(selectedItemIcon);
+ tb.sinkEvents(Tooltip.TOOLTIP_EVENTS);
panel.add(tb);
panel.add(popupOpener);
initWidget(panel);
import java.util.Iterator;
import java.util.Vector;
+import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.Widget;
+import com.itmill.toolkit.terminal.gwt.client.Tooltip;
import com.itmill.toolkit.terminal.gwt.client.UIDL;
public class IListSelect extends IOptionGroupBase {
private int lastSelectedIndex = -1;
+ private class MyListBox extends ListBox {
+ MyListBox() {
+ super();
+ sinkEvents(Tooltip.TOOLTIP_EVENTS);
+ }
+
+ public void onBrowserEvent(Event event) {
+ super.onBrowserEvent(event);
+ if (client != null) {
+ client.handleTooltipEvent(event, IListSelect.this);
+ }
+ }
+ }
+
public IListSelect() {
+ // TODO use myListBox to have Tooltips
super(new ListBox(), CLASSNAME);
select = (ListBox) optionsContainer;
select.addChangeListener(this);
\r
public static final String CLASSNAME_OPTION = "i-select-option";\r
\r
- ApplicationConnection client;\r
+ protected ApplicationConnection client;\r
\r
- String id;\r
+ protected String id;\r
\r
protected Set selectedKeys;\r
\r
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.ui.ChangeListener;
import com.google.gwt.user.client.ui.FocusListener;
import com.google.gwt.user.client.ui.TextBoxBase;
import com.google.gwt.user.client.ui.Widget;
import com.itmill.toolkit.terminal.gwt.client.ApplicationConnection;
import com.itmill.toolkit.terminal.gwt.client.Paintable;
+import com.itmill.toolkit.terminal.gwt.client.Tooltip;
import com.itmill.toolkit.terminal.gwt.client.UIDL;
/**
setStyleName(CLASSNAME);
addChangeListener(this);
addFocusListener(this);
+ sinkEvents(Tooltip.TOOLTIP_EVENTS);
+ }
+
+ public void onBrowserEvent(Event event) {
+ super.onBrowserEvent(event);
+ if (client != null) {
+ client.handleTooltipEvent(event, this);
+ }
}
public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {