Browse Source

Made MenuBar item tooltips work again (#8425)

tags/7.0.0.alpha3
Sami Viitanen 12 years ago
parent
commit
6dec84ebe9

+ 21
- 7
src/com/vaadin/terminal/gwt/client/Util.java View File

import com.google.gwt.user.client.ui.Widget; import com.google.gwt.user.client.ui.Widget;
import com.vaadin.terminal.gwt.client.RenderInformation.FloatSize; import com.vaadin.terminal.gwt.client.RenderInformation.FloatSize;
import com.vaadin.terminal.gwt.client.communication.MethodInvocation; import com.vaadin.terminal.gwt.client.communication.MethodInvocation;
import com.vaadin.terminal.gwt.client.ui.VOverlay;


public class Util { public class Util {


*/ */
public static ComponentConnector getConnectorForElement( public static ComponentConnector getConnectorForElement(
ApplicationConnection client, Widget parent, Element element) { ApplicationConnection client, Widget parent, Element element) {

Element browseElement = element;
Element rootElement = parent.getElement(); Element rootElement = parent.getElement();
while (element != null && element != rootElement) {

while (browseElement != null && browseElement != rootElement) {
ComponentConnector connector = ConnectorMap.get(client) ComponentConnector connector = ConnectorMap.get(client)
.getConnector(element);
.getConnector(browseElement);

if (connector == null) { if (connector == null) {
String ownerPid = VCaption.getCaptionOwnerPid(element);
String ownerPid = VCaption.getCaptionOwnerPid(browseElement);
if (ownerPid != null) { if (ownerPid != null) {
connector = (ComponentConnector) ConnectorMap.get(client) connector = (ComponentConnector) ConnectorMap.get(client)
.getConnector(ownerPid); .getConnector(ownerPid);


if (connector != null) { if (connector != null) {
// check that inside the rootElement // 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; return null;
} else { } else {
return connector; 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; return null;

+ 28
- 0
src/com/vaadin/terminal/gwt/client/ui/VOverlay.java View File

import com.google.gwt.user.client.Element; import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.ui.PopupPanel; import com.google.gwt.user.client.ui.PopupPanel;
import com.google.gwt.user.client.ui.RootPanel; import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.Widget;
import com.vaadin.terminal.gwt.client.BrowserInfo; import com.vaadin.terminal.gwt.client.BrowserInfo;


/** /**
*/ */
private Element shadow; 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 * The HTML snippet that is used to render the actual shadow. In consists of
* nine different DIV-elements with the following class names: * nine different DIV-elements with the following class names:
protected boolean isSinkShadowEvents() { protected boolean isSinkShadowEvents() {
return sinkShadowEvents; 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;
}
} }

+ 25
- 0
src/com/vaadin/terminal/gwt/client/ui/menubar/MenuBarConnector.java View File

import java.util.Stack; import java.util.Stack;


import com.google.gwt.core.client.GWT; import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.Element;
import com.google.gwt.user.client.Command; import com.google.gwt.user.client.Command;
import com.vaadin.terminal.gwt.client.ApplicationConnection; import com.vaadin.terminal.gwt.client.ApplicationConnection;
import com.vaadin.terminal.gwt.client.Paintable; 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.UIDL;
import com.vaadin.terminal.gwt.client.Util; import com.vaadin.terminal.gwt.client.Util;
import com.vaadin.terminal.gwt.client.ui.AbstractComponentConnector; import com.vaadin.terminal.gwt.client.ui.AbstractComponentConnector;
iteratorStack.push(itr); iteratorStack.push(itr);
itr = item.getChildIterator(); itr = item.getChildIterator();
currentMenu = new VMenuBar(true, currentMenu); currentMenu = new VMenuBar(true, currentMenu);
client.getVTooltip().connectHandlersToWidget(currentMenu);
// this is the top-level style that also propagates to items - // this is the top-level style that also propagates to items -
// any item specific styles are set above in // any item specific styles are set above in
// currentItem.updateFromUIDL(item, client) // currentItem.updateFromUIDL(item, client)
public void layout() { public void layout() {
getWidget().iLayout(); 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;
}
} }

+ 51
- 13
src/com/vaadin/terminal/gwt/client/ui/menubar/VMenuBar.java View File

import com.vaadin.terminal.gwt.client.ApplicationConnection; import com.vaadin.terminal.gwt.client.ApplicationConnection;
import com.vaadin.terminal.gwt.client.BrowserInfo; import com.vaadin.terminal.gwt.client.BrowserInfo;
import com.vaadin.terminal.gwt.client.LayoutManager; 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.UIDL;
import com.vaadin.terminal.gwt.client.Util; import com.vaadin.terminal.gwt.client.Util;
import com.vaadin.terminal.gwt.client.ui.Icon; import com.vaadin.terminal.gwt.client.ui.Icon;


boolean enabled = true; boolean enabled = true;


private String width = "notinited";

private VLazyExecutor iconLoadedExecutioner = new VLazyExecutor(100, private VLazyExecutor iconLoadedExecutioner = new VLazyExecutor(100,
new ScheduledCommand() { new ScheduledCommand() {


final int shadowSpace = 10; final int shadowSpace = 10;


popup = new VOverlay(true, false, true); 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.setStyleName(CLASSNAME + "-popup");
popup.setWidget(item.getSubMenu()); popup.setWidget(item.getSubMenu());
popup.addCloseHandler(this); popup.addCloseHandler(this);
* A class to hold information on menu items * 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 String html = null;
protected Command command = null; protected Command command = null;
protected boolean isSeparator = false; protected boolean isSeparator = false;
protected boolean checkable = false; protected boolean checkable = false;
protected boolean checked = false; protected boolean checked = false;
protected String description = null;


/** /**
* Default menu item {@link Widget} constructor for GWT.create(). * Default menu item {@link Widget} constructor for GWT.create().
} }


public void updateFromUIDL(UIDL uidl, ApplicationConnection client) { public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
this.client = client;
setSeparator(uidl.hasAttribute("separator")); setSeparator(uidl.hasAttribute("separator"));
setEnabled(!uidl.hasAttribute(ATTRIBUTE_ITEM_DISABLED)); setEnabled(!uidl.hasAttribute(ATTRIBUTE_ITEM_DISABLED));


addStyleDependentName(itemStyle); 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);
} }


/** /**
return null; 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;
}
} }

Loading…
Cancel
Save