Browse Source

#6440: mode to open root nodes by mouse over only

svn changeset:18266/svn branch:6.6
tags/6.7.0.beta1
Matti Tahvonen 13 years ago
parent
commit
16aae528a8

+ 62
- 1
src/com/vaadin/terminal/gwt/client/ui/VMenuBar.java View File

@@ -8,8 +8,10 @@ import java.util.Iterator;
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;
@@ -25,6 +27,7 @@ import com.google.gwt.user.client.Command;
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;
@@ -36,6 +39,7 @@ 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.VConsole;
import com.vaadin.terminal.gwt.client.VTooltip;

public class VMenuBar extends SimpleFocusablePanel implements Paintable,
@@ -63,6 +67,8 @@ 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;
@@ -85,6 +91,8 @@ public class VMenuBar extends SimpleFocusablePanel implements Paintable,
}
});

private boolean openRootOnHover;

public VMenuBar() {
// Create an empty horizontal menubar
this(false, null);
@@ -182,6 +190,9 @@ public class VMenuBar extends SimpleFocusablePanel implements Paintable,
if (client.updateComponent(this, uidl, true)) {
return;
}

openRootOnHover = uidl.getBooleanAttribute(OPEN_ROOT_MENU_ON_HOWER);

enabled = !uidl.getBooleanAttribute("disabled");

// For future connections
@@ -478,6 +489,8 @@ public class VMenuBar extends SimpleFocusablePanel implements Paintable,
break;

case Event.ONMOUSEOVER:
LazyCloser.cancelClosing();

if (isEnabled() && targetItem.isEnabled()) {
itemOver(targetItem);
}
@@ -485,6 +498,7 @@ public class VMenuBar extends SimpleFocusablePanel implements Paintable,

case Event.ONMOUSEOUT:
itemOut(targetItem);
LazyCloser.schedule();
break;
}
} else if (subMenu && DOM.eventGetType(e) == Event.ONCLICK && subMenu) {
@@ -542,8 +556,12 @@ public class VMenuBar extends SimpleFocusablePanel implements Paintable,
* @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()
@@ -571,6 +589,49 @@ public class VMenuBar extends SimpleFocusablePanel implements Paintable,
}
}

/**
* 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.

+ 29
- 0
src/com/vaadin/ui/MenuBar.java View File

@@ -49,6 +49,8 @@ public class MenuBar extends AbstractComponent {

private MenuItem moreItem;

private boolean openRootOnHover;

/** Paint (serialise) the component for the client. */
@Override
public void paintContent(PaintTarget target) throws PaintException {
@@ -56,6 +58,8 @@ public class MenuBar extends AbstractComponent {
// 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) {
@@ -364,6 +368,31 @@ public class MenuBar extends AbstractComponent {
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

+ 13
- 0
tests/src/com/vaadin/tests/components/menubar/MenuBarTest.java View File

@@ -19,6 +19,7 @@ public class MenuBarTest extends AbstractComponentTest<MenuBar> {
private int subLevels = -1;
private int subMenuDensity = -1;
private Integer subMenuSeparatorDensity = null;
private Boolean openRootMenuOnHover = false;
private int iconInterval = -1;
private Integer iconSize;
private Integer disabledDensity;
@@ -38,6 +39,9 @@ public class MenuBarTest extends AbstractComponentTest<MenuBar> {
createSubMenuDensitySelect(CATEGORY_MENU_ITEMS);
createSubMenuSeparatorDensitySelect(CATEGORY_MENU_ITEMS);
createBooleanAction("OpenRootMenuOnHover", CATEGORY_FEATURES,
openRootMenuOnHover, setOpenRootOnHover);
createMenuItemIconIntervalSelect(CATEGORY_MENU_ITEM_STATES);
createMenuIconsSizeSelect(CATEGORY_MENU_ITEM_STATES);
createMenuItemDisabledDensitySelect(CATEGORY_MENU_ITEM_STATES);
@@ -185,6 +189,15 @@ public class MenuBarTest extends AbstractComponentTest<MenuBar> {
}
};
private Command<MenuBar, Boolean> setOpenRootOnHover = new Command<MenuBar, Boolean>() {
public void execute(MenuBar c, Boolean value, Object data) {
openRootMenuOnHover = value;
c.setOpenRootOnHover(value);
}
};
private Command<MenuBar, Integer> selectIcon = new Command<MenuBar, Integer>() {
public void execute(MenuBar c, Integer value, Object data) {

Loading…
Cancel
Save