import java.util.List;
import java.util.Stack;
+import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.core.client.Scheduler;
import com.google.gwt.core.client.Scheduler.ScheduledCommand;
+import com.google.gwt.dom.client.NativeEvent;
import com.google.gwt.dom.client.NodeList;
import com.google.gwt.dom.client.Style.Unit;
import com.google.gwt.event.dom.client.FocusEvent;
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.ui.HasHTML;
import com.google.gwt.user.client.ui.PopupPanel;
import com.google.gwt.user.client.ui.RootPanel;
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.VConsole;
import com.vaadin.terminal.gwt.client.VTooltip;
public class VMenuBar extends SimpleFocusablePanel implements Paintable,
// associated
protected static final Command emptyCommand = null;
+ public static final String OPEN_ROOT_MENU_ON_HOWER = "ormoh";
+
/** Widget fields **/
protected boolean subMenu;
protected ArrayList<CustomMenuItem> items;
}
});
+ private boolean openRootOnHover;
+
public VMenuBar() {
// Create an empty horizontal menubar
this(false, null);
if (client.updateComponent(this, uidl, true)) {
return;
}
+
+ openRootOnHover = uidl.getBooleanAttribute(OPEN_ROOT_MENU_ON_HOWER);
+
enabled = !uidl.getBooleanAttribute("disabled");
// For future connections
break;
case Event.ONMOUSEOVER:
+ LazyCloser.cancelClosing();
+
if (isEnabled() && targetItem.isEnabled()) {
itemOver(targetItem);
}
case Event.ONMOUSEOUT:
itemOut(targetItem);
+ LazyCloser.schedule();
break;
}
} else if (subMenu && DOM.eventGetType(e) == Event.ONCLICK && subMenu) {
* @param item
*/
public void itemOver(CustomMenuItem item) {
- if ((subMenu || menuVisible) && !item.isSeparator()) {
+ if ((openRootOnHover || subMenu || menuVisible) && !item.isSeparator()) {
setSelected(item);
+ if (!subMenu && openRootOnHover && !menuVisible) {
+ menuVisible = true; // start opening menus
+ LazyCloser.prepare(this);
+ }
}
if (menuVisible && visibleChildMenu != item.getSubMenu()
}
}
+ /**
+ * Used to autoclose submenus when they the menu is in a mode which opens
+ * root menus on mouse hover.
+ */
+ private static class LazyCloser extends Timer {
+ static LazyCloser INSTANCE;
+ private VMenuBar activeRoot;
+
+ @Override
+ public void run() {
+ activeRoot.hideChildren();
+ activeRoot.setSelected(null);
+ activeRoot.menuVisible = false;
+ activeRoot = null;
+ }
+
+ public static void cancelClosing() {
+ if (INSTANCE != null) {
+ INSTANCE.cancel();
+ }
+ }
+
+ public static void prepare(VMenuBar vMenuBar) {
+ if (INSTANCE == null) {
+ INSTANCE = new LazyCloser();
+ }
+ if (INSTANCE.activeRoot == vMenuBar) {
+ INSTANCE.cancel();
+ } else if (INSTANCE.activeRoot != null) {
+ INSTANCE.cancel();
+ INSTANCE.run();
+ }
+ INSTANCE.activeRoot = vMenuBar;
+ }
+
+ public static void schedule() {
+ if (INSTANCE != null && INSTANCE.activeRoot != null) {
+ INSTANCE.schedule(750);
+ }
+ }
+
+ }
+
/**
* Shows the child menu of an item. The caller must ensure that the item has
* a submenu.
private MenuItem moreItem;
+ private boolean openRootOnHover;
+
/** Paint (serialise) the component for the client. */
@Override
public void paintContent(PaintTarget target) throws PaintException {
// Superclass writes any common attributes in the paint target.
super.paintContent(target);
+ target.addAttribute(VMenuBar.OPEN_ROOT_MENU_ON_HOWER, openRootOnHover);
+
target.startTag("options");
if (submenuIcon != null) {
public MenuItem getMoreMenuItem() {
return moreItem;
}
+
+ /**
+ * Using this method menubar can be put into a special mode where the root
+ * level menu opens without clicking on the menu. In this mode the menu also
+ * closes itself if the mouse is moved out of the opened menu.
+ *
+ * @param b
+ */
+ public void setOpenRootOnHover(boolean b) {
+ if(b != openRootOnHover) {
+ openRootOnHover = b;
+ requestRepaint();
+ }
+ }
+
+ /**
+ * Detects whether the menubar is in a mode where root menus are
+ * automatically opened when the mouse cursor is moved over the menubar.
+ * Normally root menu opens only by clicking on the menu.
+ *
+ * @return true if the root menus open without click
+ */
+ public boolean isOpenRootOnHover() {
+ return openRootOnHover;
+ }
/**
* This interface contains the layer for menu commands of the
private int subLevels = -1;\r
private int subMenuDensity = -1;\r
private Integer subMenuSeparatorDensity = null;\r
+ private Boolean openRootMenuOnHover = false;\r
private int iconInterval = -1;\r
private Integer iconSize;\r
private Integer disabledDensity;\r
createSubMenuDensitySelect(CATEGORY_MENU_ITEMS);\r
createSubMenuSeparatorDensitySelect(CATEGORY_MENU_ITEMS);\r
\r
+ createBooleanAction("OpenRootMenuOnHover", CATEGORY_FEATURES,\r
+ openRootMenuOnHover, setOpenRootOnHover);\r
+\r
createMenuItemIconIntervalSelect(CATEGORY_MENU_ITEM_STATES);\r
createMenuIconsSizeSelect(CATEGORY_MENU_ITEM_STATES);\r
createMenuItemDisabledDensitySelect(CATEGORY_MENU_ITEM_STATES);\r
}\r
};\r
\r
+ private Command<MenuBar, Boolean> setOpenRootOnHover = new Command<MenuBar, Boolean>() {\r
+\r
+ public void execute(MenuBar c, Boolean value, Object data) {\r
+ openRootMenuOnHover = value;\r
+ c.setOpenRootOnHover(value);\r
+ }\r
+\r
+ };\r
+\r
private Command<MenuBar, Integer> selectIcon = new Command<MenuBar, Integer>() {\r
\r
public void execute(MenuBar c, Integer value, Object data) {\r