@@ -29,6 +29,7 @@ import com.google.gwt.user.client.ui.RootPanel; | |||
import com.google.gwt.user.client.ui.Widget; | |||
import com.vaadin.terminal.gwt.client.RenderInformation.FloatSize; | |||
import com.vaadin.terminal.gwt.client.communication.MethodInvocation; | |||
import com.vaadin.terminal.gwt.client.ui.VOverlay; | |||
public class Util { | |||
@@ -642,12 +643,16 @@ public class Util { | |||
*/ | |||
public static ComponentConnector getConnectorForElement( | |||
ApplicationConnection client, Widget parent, Element element) { | |||
Element browseElement = element; | |||
Element rootElement = parent.getElement(); | |||
while (element != null && element != rootElement) { | |||
while (browseElement != null && browseElement != rootElement) { | |||
ComponentConnector connector = ConnectorMap.get(client) | |||
.getConnector(element); | |||
.getConnector(browseElement); | |||
if (connector == null) { | |||
String ownerPid = VCaption.getCaptionOwnerPid(element); | |||
String ownerPid = VCaption.getCaptionOwnerPid(browseElement); | |||
if (ownerPid != null) { | |||
connector = (ComponentConnector) ConnectorMap.get(client) | |||
.getConnector(ownerPid); | |||
@@ -656,17 +661,26 @@ public class Util { | |||
if (connector != null) { | |||
// check that inside the rootElement | |||
while (element != null && element != rootElement) { | |||
element = (Element) element.getParentElement(); | |||
while (browseElement != null && browseElement != rootElement) { | |||
browseElement = (Element) browseElement.getParentElement(); | |||
} | |||
if (element != rootElement) { | |||
if (browseElement != rootElement) { | |||
return null; | |||
} else { | |||
return connector; | |||
} | |||
} | |||
element = (Element) element.getParentElement(); | |||
browseElement = (Element) browseElement.getParentElement(); | |||
} | |||
if (browseElement == null) { | |||
// Element is possibly inside a VOverlay | |||
VOverlay overlay = findWidget(element, VOverlay.class); | |||
if (overlay != null && overlay.getOwner() != null) { | |||
return getConnectorForElement(client, RootPanel.get(), overlay | |||
.getOwner().getElement()); | |||
} | |||
} | |||
return null; |
@@ -14,6 +14,7 @@ import com.google.gwt.user.client.DOM; | |||
import com.google.gwt.user.client.Element; | |||
import com.google.gwt.user.client.ui.PopupPanel; | |||
import com.google.gwt.user.client.ui.RootPanel; | |||
import com.google.gwt.user.client.ui.Widget; | |||
import com.vaadin.terminal.gwt.client.BrowserInfo; | |||
/** | |||
@@ -45,6 +46,12 @@ public class VOverlay extends PopupPanel implements CloseHandler<PopupPanel> { | |||
*/ | |||
private Element shadow; | |||
/* | |||
* Creator of VOverlow (widget that made the instance, not the layout | |||
* parent) | |||
*/ | |||
private Widget owner; | |||
/** | |||
* The HTML snippet that is used to render the actual shadow. In consists of | |||
* nine different DIV-elements with the following class names: | |||
@@ -414,4 +421,25 @@ public class VOverlay extends PopupPanel implements CloseHandler<PopupPanel> { | |||
protected boolean isSinkShadowEvents() { | |||
return sinkShadowEvents; | |||
} | |||
/** | |||
* Get owner (Widget that made this VOverlay, not the layout parent) of | |||
* VOverlay | |||
* | |||
* @return Owner (creator) or null if not defined | |||
*/ | |||
public Widget getOwner() { | |||
return owner; | |||
} | |||
/** | |||
* Set owner (Widget that made this VOverlay, not the layout parent) of | |||
* VOverlay | |||
* | |||
* @param owner | |||
* Owner (creator) of VOverlay | |||
*/ | |||
public void setOwner(Widget owner) { | |||
this.owner = owner; | |||
} | |||
} |
@@ -7,9 +7,11 @@ import java.util.Iterator; | |||
import java.util.Stack; | |||
import com.google.gwt.core.client.GWT; | |||
import com.google.gwt.dom.client.Element; | |||
import com.google.gwt.user.client.Command; | |||
import com.vaadin.terminal.gwt.client.ApplicationConnection; | |||
import com.vaadin.terminal.gwt.client.Paintable; | |||
import com.vaadin.terminal.gwt.client.TooltipInfo; | |||
import com.vaadin.terminal.gwt.client.UIDL; | |||
import com.vaadin.terminal.gwt.client.Util; | |||
import com.vaadin.terminal.gwt.client.ui.AbstractComponentConnector; | |||
@@ -120,6 +122,7 @@ public class MenuBarConnector extends AbstractComponentConnector implements | |||
iteratorStack.push(itr); | |||
itr = item.getChildIterator(); | |||
currentMenu = new VMenuBar(true, currentMenu); | |||
client.getVTooltip().connectHandlersToWidget(currentMenu); | |||
// this is the top-level style that also propagates to items - | |||
// any item specific styles are set above in | |||
// currentItem.updateFromUIDL(item, client) | |||
@@ -160,4 +163,26 @@ public class MenuBarConnector extends AbstractComponentConnector implements | |||
public void layout() { | |||
getWidget().iLayout(); | |||
} | |||
@Override | |||
public TooltipInfo getTooltipInfo(Element element) { | |||
TooltipInfo info = null; | |||
// Check content of widget to find tooltip for element | |||
if (element != getWidget().getElement()) { | |||
CustomMenuItem item = getWidget().getMenuItemWithElement( | |||
(com.google.gwt.user.client.Element) element); | |||
if (item != null) { | |||
info = item.getTooltip(); | |||
} | |||
} | |||
// Use default tooltip if nothing found from DOM three | |||
if (info == null) { | |||
info = super.getTooltipInfo(element); | |||
} | |||
return info; | |||
} | |||
} |
@@ -33,6 +33,7 @@ import com.google.gwt.user.client.ui.Widget; | |||
import com.vaadin.terminal.gwt.client.ApplicationConnection; | |||
import com.vaadin.terminal.gwt.client.BrowserInfo; | |||
import com.vaadin.terminal.gwt.client.LayoutManager; | |||
import com.vaadin.terminal.gwt.client.TooltipInfo; | |||
import com.vaadin.terminal.gwt.client.UIDL; | |||
import com.vaadin.terminal.gwt.client.Util; | |||
import com.vaadin.terminal.gwt.client.ui.Icon; | |||
@@ -87,8 +88,6 @@ public class VMenuBar extends SimpleFocusablePanel implements | |||
boolean enabled = true; | |||
private String width = "notinited"; | |||
private VLazyExecutor iconLoadedExecutioner = new VLazyExecutor(100, | |||
new ScheduledCommand() { | |||
@@ -524,6 +523,22 @@ public class VMenuBar extends SimpleFocusablePanel implements | |||
final int shadowSpace = 10; | |||
popup = new VOverlay(true, false, true); | |||
// Setting owner and handlers to support tooltips. Needed for tooltip | |||
// handling of overlay widgets (will direct queries to parent menu) | |||
if (parentMenu == null) { | |||
popup.setOwner(this); | |||
} else { | |||
VMenuBar parent = parentMenu; | |||
while (parent.getParentMenu() != null) { | |||
parent = parent.getParentMenu(); | |||
} | |||
popup.setOwner(parent); | |||
} | |||
if (client != null) { | |||
client.getVTooltip().connectHandlersToWidget(popup); | |||
} | |||
popup.setStyleName(CLASSNAME + "-popup"); | |||
popup.setWidget(item.getSubMenu()); | |||
popup.addCloseHandler(this); | |||
@@ -707,9 +722,7 @@ public class VMenuBar extends SimpleFocusablePanel implements | |||
* A class to hold information on menu items | |||
* | |||
*/ | |||
protected static class CustomMenuItem extends Widget implements HasHTML { | |||
private ApplicationConnection client; | |||
public static class CustomMenuItem extends Widget implements HasHTML { | |||
protected String html = null; | |||
protected Command command = null; | |||
@@ -719,6 +732,7 @@ public class VMenuBar extends SimpleFocusablePanel implements | |||
protected boolean isSeparator = false; | |||
protected boolean checkable = false; | |||
protected boolean checked = false; | |||
protected String description = null; | |||
/** | |||
* Default menu item {@link Widget} constructor for GWT.create(). | |||
@@ -884,7 +898,6 @@ public class VMenuBar extends SimpleFocusablePanel implements | |||
} | |||
public void updateFromUIDL(UIDL uidl, ApplicationConnection client) { | |||
this.client = client; | |||
setSeparator(uidl.hasAttribute("separator")); | |||
setEnabled(!uidl.hasAttribute(ATTRIBUTE_ITEM_DISABLED)); | |||
@@ -903,17 +916,18 @@ public class VMenuBar extends SimpleFocusablePanel implements | |||
addStyleDependentName(itemStyle); | |||
} | |||
if (uidl.hasAttribute(ATTRIBUTE_ITEM_DESCRIPTION)) { | |||
description = uidl | |||
.getStringAttribute(ATTRIBUTE_ITEM_DESCRIPTION); | |||
} | |||
} | |||
private VMenuBar findRootMenu() { | |||
VMenuBar menubar = getParentMenu(); | |||
// Traverse up until root menu is found | |||
while (menubar.getParentMenu() != null) { | |||
menubar = menubar.getParentMenu(); | |||
public TooltipInfo getTooltip() { | |||
if (description == null) { | |||
return null; | |||
} | |||
return menubar; | |||
return new TooltipInfo(description); | |||
} | |||
/** | |||
@@ -1405,4 +1419,28 @@ public class VMenuBar extends SimpleFocusablePanel implements | |||
return null; | |||
} | |||
/** | |||
* Get menu item with given DOM element | |||
* | |||
* @param element | |||
* Element used in search | |||
* @return Menu item or null if not found | |||
*/ | |||
public CustomMenuItem getMenuItemWithElement(Element element) { | |||
for (int i = 0; i < items.size(); i++) { | |||
CustomMenuItem item = items.get(i); | |||
if (DOM.isOrHasChild(item.getElement(), element)) { | |||
return item; | |||
} | |||
if (item.getSubMenu() != null) { | |||
item = item.getSubMenu().getMenuItemWithElement(element); | |||
if (item != null) { | |||
return item; | |||
} | |||
} | |||
} | |||
return null; | |||
} | |||
} |