margin-right: 0;
margin-top: -2px;
}
+.v-ie7 .v-menubar-submenu .v-menubar-submenu-indicator {
+ position: relative;
+ margin-left: 0;
+}
.v-menubar-menuitem-disabled {
color: #999;
}
.v-menubar-more-menuitem {
/* Arial has the most coverage for geometric entity characters */
font-family: arial, helvetica, sans-serif;
+}
+.v-menubar-separator span {
+ display: block;
+ text-indent: -9999px;
+ height: 1px;
+ margin: 3px 0;
+ overflow: hidden;
+ background: #ddd;
}
\ No newline at end of file
margin-right: 0;
margin-top: -2px;
}
+.v-ie7 .v-menubar-submenu .v-menubar-submenu-indicator {
+ position: relative;
+ margin-left: 0;
+}
.v-menubar-menuitem-disabled {
color: #999;
}
/* Arial has the most coverage for geometric entity characters */
font-family: arial, helvetica, sans-serif;
}
+.v-menubar-separator span {
+ display: block;
+ text-indent: -9999px;
+ height: 1px;
+ margin: 3px 0;
+ overflow: hidden;
+ background: #ddd;
+}
.v-Notification {
background: #999;
background-image: url(img/menu-sel-bg.png); /** sprite-ref: verticals; sprite-alignment: repeat */
}
.v-menubar-submenu .v-menubar-submenu-indicator {
- background: transparent url(img/submenu-icon.png) no-repeat right bottom;
+ background: transparent url(img/submenu-icon.png) no-repeat right 70%;
width: 16px;
margin: 0 -20px 0 5px;
text-indent: -999px;
vertical-align: middle;
}
+.v-ie7 .v-menubar-submenu .v-menubar-submenu-indicator {
+ margin: 0 -20px 0 0;
+ position: relative;
+ right: -4px;
+}
.v-menubar-submenu .v-menubar-menuitem-selected .v-menubar-submenu-indicator {
background-image: url(img/submenu-icon-hover.png);
}
\ No newline at end of file
margin-right: 0;
margin-top: -2px;
}
+.v-ie7 .v-menubar-submenu .v-menubar-submenu-indicator {
+ position: relative;
+ margin-left: 0;
+}
.v-menubar-menuitem-disabled {
color: #999;
}
/* Arial has the most coverage for geometric entity characters */
font-family: arial, helvetica, sans-serif;
}
+.v-menubar-separator span {
+ display: block;
+ text-indent: -9999px;
+ height: 1px;
+ margin: 3px 0;
+ overflow: hidden;
+ background: #ddd;
+}
.v-Notification {
background: #999;
background-position: left -423px;
}
.v-menubar-submenu .v-menubar-submenu-indicator {
- background: transparent url(menubar/img/submenu-icon.png) no-repeat right bottom;
+ background: transparent url(menubar/img/submenu-icon.png) no-repeat right 70%;
width: 16px;
margin: 0 -20px 0 5px;
text-indent: -999px;
vertical-align: middle;
}
+.v-ie7 .v-menubar-submenu .v-menubar-submenu-indicator {
+ margin: 0 -20px 0 0;
+ position: relative;
+ right: -4px;
+}
.v-menubar-submenu .v-menubar-menuitem-selected .v-menubar-submenu-indicator {
background-image: url(menubar/img/submenu-icon-hover.png);
}
border-left: 1px solid #d0d4d5;
}
.v-menubar-submenu .v-menubar-menuitem {
- padding: 2px 10px;
+ padding: 2px 16px 2px 10px;
}
.v-menubar-submenu .v-menubar-menuitem-selected {
color: #fff;
background: #5daee8;
}
.v-menubar-submenu .v-menubar-submenu-indicator {
- margin-right: -3px;
+ margin-right: -12px;
+ height: 14px;
+}
+.v-ie7 .v-menubar-submenu .v-menubar-submenu-indicator {
+ margin-right: -12px;
+ right: -3px;
}
\ No newline at end of file
margin-right: 0;
margin-top: -2px;
}
+.v-ie7 .v-menubar-submenu .v-menubar-submenu-indicator {
+ position: relative;
+ margin-left: 0;
+}
.v-menubar-menuitem-disabled {
color: #999;
}
/* Arial has the most coverage for geometric entity characters */
font-family: arial, helvetica, sans-serif;
}
+.v-menubar-separator span {
+ display: block;
+ text-indent: -9999px;
+ height: 1px;
+ margin: 3px 0;
+ overflow: hidden;
+ background: #ddd;
+}
.v-Notification {
background: #999;
border-left: 1px solid #d0d4d5;
}
.v-menubar-submenu .v-menubar-menuitem {
- padding: 2px 10px;
+ padding: 2px 16px 2px 10px;
}
.v-menubar-submenu .v-menubar-menuitem-selected {
color: #fff;
background: #5daee8;
}
.v-menubar-submenu .v-menubar-submenu-indicator {
- margin-right: -3px;
+ margin-right: -12px;
+ height: 14px;
+}
+.v-ie7 .v-menubar-submenu .v-menubar-submenu-indicator {
+ margin-right: -12px;
+ right: -3px;
}
.v-Notification {
import com.vaadin.terminal.gwt.client.ContainerResizedListener;
import com.vaadin.terminal.gwt.client.Paintable;
import com.vaadin.terminal.gwt.client.UIDL;
+import com.vaadin.terminal.gwt.client.Util;
public class VMenuBar extends Widget implements Paintable,
CloseHandler<PopupPanel>, ContainerResizedListener {
String itemText = item.getStringAttribute("text");
final int itemId = item.getIntAttribute("id");
- boolean itemHasCommand = item.getBooleanAttribute("command");
+ boolean itemHasCommand = item.hasAttribute("command");
// Construct html from the text and the optional icon
StringBuffer itemHTML = new StringBuffer();
+ Command cmd = null;
- // Add submenu indicator
- if (item.getChildCount() > 0) {
- // FIXME For compatibility reasons: remove in version 7
- String bgStyle = "";
- if (submenuIcon != null) {
- bgStyle = " style=\"background-image: url(" + submenuIcon
- + "); text-indent: -999px; width: 1em;\"";
+ if (item.hasAttribute("separator")) {
+ itemHTML.append("<span>---</span>");
+ } else {
+ // Add submenu indicator
+ if (item.getChildCount() > 0) {
+ // FIXME For compatibility reasons: remove in version 7
+ String bgStyle = "";
+ if (submenuIcon != null) {
+ bgStyle = " style=\"background-image: url("
+ + submenuIcon
+ + "); text-indent: -999px; width: 1em;\"";
+ }
+ itemHTML.append("<span class=\"" + CLASSNAME
+ + "-submenu-indicator\"" + bgStyle
+ + ">►</span>");
}
- itemHTML
- .append("<span class=\"" + CLASSNAME
- + "-submenu-indicator\"" + bgStyle
- + ">►</span>");
- }
- if (item.hasAttribute("icon")) {
- itemHTML.append("<img src=\""
- + client.translateVaadinUri(item
- .getStringAttribute("icon")) + "\" class=\""
- + Icon.CLASSNAME + "\" alt=\"\" />");
- }
-
- itemHTML.append(itemText);
+ if (item.hasAttribute("icon")) {
+ itemHTML
+ .append("<img src=\""
+ + client.translateVaadinUri(item
+ .getStringAttribute("icon"))
+ + "\" class=\"" + Icon.CLASSNAME
+ + "\" alt=\"\" />");
+ }
- Command cmd = null;
+ itemHTML.append(Util.escapeHTML(itemText));
- if (itemHasCommand) {
- // Construct a command that fires onMenuClick(int) with the
- // item's id-number
- cmd = new Command() {
- public void execute() {
- hostReference.onMenuClick(itemId);
- }
- };
+ if (itemHasCommand) {
+ // Construct a command that fires onMenuClick(int) with the
+ // item's id-number
+ cmd = new Command() {
+ public void execute() {
+ hostReference.onMenuClick(itemId);
+ }
+ };
+ }
}
currentItem = currentMenu.addItem(itemHTML.toString(), cmd);
+ currentItem.setSeparator(item.hasAttribute("separator"));
currentItem.setEnabled(!item.hasAttribute("disabled"));
if (item.getChildCount() > 0) {
* @param item
*/
public void itemOver(CustomMenuItem item) {
- if (subMenu || menuVisible) {
+ if ((subMenu || menuVisible) && !item.isSeparator()) {
setSelected(item);
}
* @param item
*/
public void showChildMenu(CustomMenuItem item) {
+ final int shadowSpace = 10;
+
popup = new VOverlay(true, false, true);
popup.setWidget(item.getSubMenu());
popup.addCloseHandler(this);
popup.show();
if (left + popup.getOffsetWidth() >= RootPanel.getBodyElement()
- .getOffsetWidth()) {
+ .getOffsetWidth()
+ - shadowSpace) {
if (subMenu) {
left = item.getParentMenu().getAbsoluteLeft()
- - popup.getOffsetWidth();
+ - popup.getOffsetWidth() - shadowSpace;
} else {
left = RootPanel.getBodyElement().getOffsetWidth()
- - popup.getOffsetWidth();
- ApplicationConnection.getConsole().log("" + left);
+ - popup.getOffsetWidth() - shadowSpace;
+ }
+ // Accommodate space for shadow
+ if (left < shadowSpace) {
+ left = shadowSpace;
}
popup.setPopupPosition(left, top);
}
protected VMenuBar subMenu = null;
protected VMenuBar parentMenu = null;
protected boolean enabled = true;
+ protected boolean isSeparator = false;
public CustomMenuItem(String html, Command cmd) {
setElement(DOM.createTD());
}
public void setSelected(boolean selected) {
- if (selected) {
+ if (selected && !isSeparator) {
addStyleDependentName("selected");
} else {
removeStyleDependentName("selected");
public boolean isEnabled() {
return enabled;
}
+
+ private void setSeparator(boolean separator) {
+ isSeparator = separator;
+ if (separator) {
+ setStyleName(CLASSNAME + "-separator");
+ } else {
+ setStyleName(CLASSNAME + "-menuitem");
+ setEnabled(enabled);
+ }
+ }
+
+ public boolean isSeparator() {
+ return isSeparator;
+ }
}
/**
while (itr.hasNext()) {
MenuItem item = itr.next();
-
target.startTag("item");
-
- target.addAttribute("text", item.getText());
target.addAttribute("id", item.getId());
- Command command = item.getCommand();
- if (command != null) {
- target.addAttribute("command", true);
+ if (item.isSeparator()) {
+ target.addAttribute("separator", true);
+ target.endTag("item");
} else {
- target.addAttribute("command", false);
- }
+ target.addAttribute("text", item.getText());
- Resource icon = item.getIcon();
- if (icon != null) {
- target.addAttribute("icon", icon);
- }
+ Command command = item.getCommand();
+ if (command != null) {
+ target.addAttribute("command", true);
+ }
- if (!item.isEnabled()) {
- target.addAttribute("disabled", true);
- }
+ Resource icon = item.getIcon();
+ if (icon != null) {
+ target.addAttribute("icon", icon);
+ }
- if (item.hasChildren()) {
- iteratorStack.push(itr); // For later use
+ if (!item.isEnabled()) {
+ target.addAttribute("disabled", true);
+ }
+
+ if (item.hasChildren()) {
+ iteratorStack.push(itr); // For later use
+
+ // Go through the children
+ itr = item.getChildren().iterator();
+ } else {
+ target.endTag("item"); // Item had no children, end
+ // description
+ }
- // Go through the children
- itr = item.getChildren().iterator();
- } else {
- target.endTag("item"); // Item had no children, end description
}
// The end submenu. More than one submenu may end at once.
itr = iteratorStack.pop();
target.endTag("item");
}
-
}
target.endTag("items");
private Resource itsIcon;
private MenuItem itsParent;
private boolean enabled = true;
+ private boolean isSeparator = false;
/**
* Constructs a new menu item that can optionally have an icon and a
* @return True if this item has children
*/
public boolean hasChildren() {
- return itsChildren != null;
+ return !isSeparator() && itsChildren != null;
+ }
+
+ /**
+ * Adds a separator to this menu. A separator is a way to visually group
+ * items in a menu, to make it easier for users to find what they are
+ * looking for in the menu.
+ *
+ * @author Jouni Koivuviita / IT Mill Ltd.
+ * @since 6.2.0
+ */
+ public MenuBar.MenuItem addSeparator() {
+ MenuItem item = addItem("", null, null);
+ item.setSeparator(true);
+ return item;
+ }
+
+ public MenuBar.MenuItem addSeparatorBefore(MenuItem itemToAddBefore) {
+ MenuItem item = addItemBefore("", null, null, itemToAddBefore);
+ item.setSeparator(true);
+ return item;
}
/**
*/
public MenuBar.MenuItem addItem(String caption, Resource icon,
MenuBar.Command command) {
+ if (isSeparator()) {
+ throw new UnsupportedOperationException(
+ "Cannot add items to a separator");
+ }
if (caption == null) {
- throw new IllegalArgumentException("caption cannot be null");
+ throw new IllegalArgumentException("Caption cannot be null");
}
if (itsChildren == null) {
newItem = new MenuItem(caption, icon, command);
newItem.setParent(this);
itsChildren.add(index, newItem);
-
} else {
newItem = addItem(caption, icon, command);
}
* @return The number of child items
*/
public int getSize() {
- return itsChildren.size();
+ if (itsChildren != null) {
+ return itsChildren.size();
+ }
+ return -1;
}
/**
if (itsChildren.isEmpty()) {
itsChildren = null;
}
+ requestRepaint();
}
- requestRepaint();
}
/**
if (itsChildren != null) {
itsChildren.clear();
itsChildren = null;
+ requestRepaint();
}
- requestRepaint();
}
/**
return enabled;
}
+ private void setSeparator(boolean isSeparator) {
+ this.isSeparator = isSeparator;
+ requestRepaint();
+ }
+
+ public boolean isSeparator() {
+ return isSeparator;
+ }
+
}// class MenuItem
}// class MenuBar