API Reference 0.3.24dart_web_toolkit_uiMenuBar

MenuBar class

A standard menu bar widget. A menu bar can contain any number of menu items, each of which can either fire a {@link com.google.gwt.core.client.Scheduler.ScheduledCommand} or open a cascaded menu bar.

CSS Style Rules

.gwt-MenuBar
the menu bar itself
.gwt-MenuBar-horizontal
dependent style applied to horizontal menu bars
.gwt-MenuBar-vertical
dependent style applied to vertical menu bars
.gwt-MenuBar .gwt-MenuItem
menu items
.gwt-MenuBar .gwt-MenuItem-selected
selected menu items
.gwt-MenuBar .gwt-MenuItemSeparator
section breaks between menu items
.gwt-MenuBar .gwt-MenuItemSeparator .menuSeparatorInner
inner component of section separators
.gwt-MenuBarPopup .menuPopupTopLeft
the top left cell
.gwt-MenuBarPopup .menuPopupTopLeftInner
the inner element of the cell
.gwt-MenuBarPopup .menuPopupTopCenter
the top center cell
.gwt-MenuBarPopup .menuPopupTopCenterInner
the inner element of the cell
.gwt-MenuBarPopup .menuPopupTopRight
the top right cell
.gwt-MenuBarPopup .menuPopupTopRightInner
the inner element of the cell
.gwt-MenuBarPopup .menuPopupMiddleLeft
the middle left cell
.gwt-MenuBarPopup .menuPopupMiddleLeftInner
the inner element of the cell
.gwt-MenuBarPopup .menuPopupMiddleCenter
the middle center cell
.gwt-MenuBarPopup .menuPopupMiddleCenterInner
the inner element of the cell
.gwt-MenuBarPopup .menuPopupMiddleRight
the middle right cell
.gwt-MenuBarPopup .menuPopupMiddleRightInner
the inner element of the cell
.gwt-MenuBarPopup .menuPopupBottomLeft
the bottom left cell
.gwt-MenuBarPopup .menuPopupBottomLeftInner
the inner element of the cell
.gwt-MenuBarPopup .menuPopupBottomCenter
the bottom center cell
.gwt-MenuBarPopup .menuPopupBottomCenterInner
the inner element of the cell
.gwt-MenuBarPopup .menuPopupBottomRight
the bottom right cell
.gwt-MenuBarPopup .menuPopupBottomRightInner
the inner element of the cell

Example

{@example com.google.gwt.examples.MenuBarExample}

Use in UiBinder Templates

MenuBar elements in UiBinder template files can have a vertical bool attribute (which defaults to false), and may have only MenuItem elements as children. MenuItems may contain HTML and MenuBars.

For example:

<g:MenuBar>
  <g:MenuItem>Higgledy
    <g:MenuBar vertical="true">
      <g:MenuItem>able</g:MenuItem>
      <g:MenuItem>baker</g:MenuItem>
      <g:MenuItem>charlie</g:MenuItem>
    </g:MenuBar>
  </g:MenuItem>
  <g:MenuItem>Piggledy
    <g:MenuBar vertical="true">
      <g:MenuItem>foo</g:MenuItem>
      <g:MenuItem>bar</g:MenuItem>
      <g:MenuItem>baz</g:MenuItem>
    </g:MenuBar>
  </g:MenuItem>
  <g:MenuItem><b>Pop!</b>
    <g:MenuBar vertical="true">
      <g:MenuItem>uno</g:MenuItem>
      <g:MenuItem>dos</g:MenuItem>
      <g:MenuItem>tres</g:MenuItem>
    </g:MenuBar>
  </g:MenuItem>
</g:MenuBar>
class MenuBar extends Widget implements HasAnimation, HasCloseHandlers<PopupPanel> {

 static final String _STYLENAME_DEFAULT = "dwt-MenuBar";

 /**
  * List of all {@link MenuItem}s and {@link MenuItemSeparator}s.
  */
 List<UiObject> _allItems = new List<UiObject>();

 /**
  * List of {@link MenuItem}s, not including {@link MenuItemSeparator}s.
  */
 List<MenuItem> _items = new List<MenuItem>();

 dart_html.Element _body;

 AbstractImagePrototype _subMenuIcon = null;
 bool _isAnimationEnabled = false;
 MenuBar _parentMenu;
 PopupPanel _popup;
 MenuItem _selectedItem;
 MenuBar _shownChildMenu;
 bool _vertical = false, _autoOpen = false;
 bool _focusOnHover = true;

 /**
  * Creates an empty menu bar that uses the specified ClientBundle for menu
  * images.
  *
  * @param vertical <code>true</code> to orient the menu bar vertically
  * @param resources a bundle that provides images for this menu
  */
 MenuBar([bool vertical = false, MenuResource resources = null]) {
   if (resources == null) {
     resources = new MenuResources();
   }
   _init(vertical, AbstractImagePrototype.create(resources.menuBarSubMenuIcon()));
 }

 HandlerRegistration addCloseHandler(CloseHandler<PopupPanel> handler) {
   return addHandler(handler, CloseEvent.TYPE);
 }

 /**
  * Adds a menu item to the bar.
  *
  * @param item the item to be added
  * @return the {@link MenuItem} object
  */
 MenuItem addItem(MenuItem item) {
   return insertItem(item, _allItems.length);
 }

 /**
  * Adds a menu item to the bar containing SafeHtml, that will fire the given
  * command when it is selected.
  *
  * @param html the item's html text
  * @param cmd the command to be fired
  * @return the {@link MenuItem} object created
  */
 MenuItem addSafeHtmlItem(SafeHtml html, {MenuBar popup, ScheduledCommand cmd}) {
   return addItem(new MenuItem.fromSafeHtml(html, subMenu:popup, cmd:cmd));
 }

 /**
  * Adds a menu item to the bar, that will fire the given command when it is
  * selected.
  *
  * @param text the item's text
  * @param asHtml <code>true</code> to treat the specified text as html
  * @param cmd the command to be fired
  * @return the {@link MenuItem} object created
  */
 MenuItem addTextItem(String text, bool asHtml, {MenuBar popup, ScheduledCommand cmd}) {
   return addItem(new MenuItem(text, asHtml, subMenu:popup, cmd:cmd));
 }

 /**
  * Adds a thin line to the {@link MenuBar} to separate sections of
  * {@link MenuItem}s.
  *
  * @param separator the {@link MenuItemSeparator} to be added
  * @return the {@link MenuItemSeparator} object
  */
 MenuItemSeparator addSeparator([MenuItemSeparator separator = null]) {
   if (separator == null) {
     separator = new MenuItemSeparator();
   }
   return insertSeparator(_allItems.length, separator);
 }

 /**
  * Removes all menu items from this menu bar.
  */
 void clearItems() {
   // Deselect the current item
   selectItem(null);

   dart_html.Element container = _getItemContainerElement();
   while (Dom.getChildCount(container) > 0) {
     Dom.getChild(container, 0).remove();
   }

   // Set the parent of all items to null
   for (UiObject item in _allItems) {
     _setItemColSpan(item, 1);
     if (item is MenuItemSeparator) {
       (item as MenuItemSeparator).setParentMenu(null);
     } else {
       (item as MenuItem).setParentMenu(null);
     }
   }

   // Clear out all of the items and separators
   _items.clear();
   _allItems.clear();
 }

 /**
  * Closes this menu and all child menu popups.
  *
  * @param pFocus true to move focus to the parent
  */
 void closeAllChildren(bool pFocus) {
   if (_shownChildMenu != null) {
     // Hide any open submenus of this item
     _shownChildMenu._onHide(pFocus);
     _shownChildMenu = null;
     selectItem(null);
   }
   // Close the current popup
   if (_popup != null) {
     _popup.hide();
   }
   // If focus is true, set focus to parentMenu
   if (pFocus && _parentMenu != null) {
     _parentMenu.focus();
   }
 }

 /**
  * Give this MenuBar focus.
  */
 void focus() {
   FocusPanel.impl.focus(getElement());
 }

 /**
  * Gets whether this menu bar's child menus will open when the mouse is moved
  * over it.
  *
  * @return <code>true</code> if child menus will auto-open
  */
 bool getAutoOpen() {
   return _autoOpen;
 }

 /**
  * Get the index of a {@link MenuItem}.
  *
  * @return the index of the item, or -1 if it is not contained by this MenuBar
  */
 int getItemIndex(MenuItem item) {
   return _allItems.indexOf(item);
 }

 /**
  * Get the index of a {@link MenuItemSeparator}.
  *
  * @return the index of the separator, or -1 if it is not contained by this
  *         MenuBar
  */
 int getSeparatorIndex(MenuItemSeparator item) {
   return _allItems.indexOf(item);
 }

 /**
  * Adds a menu item to the bar at a specific index.
  *
  * @param item the item to be inserted
  * @param beforeIndex the index where the item should be inserted
  * @return the {@link MenuItem} object
  * @throws IndexOutOfBoundsException if <code>beforeIndex</code> is out of
  *           range
  */
 MenuItem insertItem(MenuItem item, int beforeIndex) {
   // Check the bounds
   if (beforeIndex < 0 || beforeIndex > _allItems.length) {
     throw new Exception("IndexOutOfBounds");
   }

   // Add to the list of items
//    _allItems.insertRange(beforeIndex, 1, item);
   _allItems.insert(beforeIndex, item);
   int itemsIndex = 0;
   for (int i = 0; i < beforeIndex; i++) {
     if (_allItems[i] is MenuItem) {
       itemsIndex++;
     }
   }
//    _items.insertRange(itemsIndex, 1, item);
   _items.insert(itemsIndex, item);

   // Setup the menu item
   _addItemElement(beforeIndex, item.getElement());
   item.setParentMenu(this);
   item.setSelectionStyle(false);
   updateSubmenuIcon(item);
   return item;
 }

 /**
  * Adds a thin line to the {@link MenuBar} to separate sections of
  * {@link MenuItem}s at the specified index.
  *
  * @param separator the {@link MenuItemSeparator} to be inserted
  * @param beforeIndex the index where the separator should be inserted
  * @return the {@link MenuItemSeparator} object
  * @throws IndexOutOfBoundsException if <code>beforeIndex</code> is out of
  *           range
  */
 MenuItemSeparator insertSeparator(int beforeIndex, [MenuItemSeparator separator = null]) {
   // Check the bounds
   if (beforeIndex < 0 || beforeIndex > _allItems.length) {
     throw new Exception("IndexOutOfBounds");
   }

   if (separator == null) {
     separator = new MenuItemSeparator();
   }

   if (_vertical) {
     _setItemColSpan(separator, 2);
   }
   _addItemElement(beforeIndex, separator.getElement());
   separator.setParentMenu(this);
//    _allItems.insertRange(beforeIndex, 1, separator);
   _allItems.insert(beforeIndex, separator);
   return separator;
 }


 bool isAnimationEnabled() {
   return _isAnimationEnabled;
 }

 /**
  * Check whether or not this widget will steal keyboard focus when the mouse
  * hovers over it.
  *
  * @return true if enabled, false if disabled
  */
 bool isFocusOnHoverEnabled() {
   return _focusOnHover;
 }

 /**
  * Moves the menu selection down to the next item. If there is no selection,
  * selects the first item. If there are no items at all, does nothing.
  */
 void moveSelectionDown() {
   if (_selectFirstItemIfNoneSelected()) {
     return;
   }

   if (_vertical) {
     _selectNextItem();
   } else {
     if (_selectedItem.getSubMenu() != null
         && !_selectedItem.getSubMenu().getItems().isEmpty
         && (_shownChildMenu == null || _shownChildMenu.getSelectedItem() == null)) {
       if (_shownChildMenu == null) {
         doItemAction(_selectedItem, false, true);
       }
       _selectedItem.getSubMenu().focus();
     } else if (_parentMenu != null) {
       if (_parentMenu._vertical) {
         _parentMenu._selectNextItem();
       } else {
         _parentMenu.moveSelectionDown();
       }
     }
   }
 }

 /**
  * Moves the menu selection up to the previous item. If there is no selection,
  * selects the first item. If there are no items at all, does nothing.
  */
 void moveSelectionUp() {
   if (_selectFirstItemIfNoneSelected()) {
     return;
   }

   if ((_shownChildMenu == null) && _vertical) {
     _selectPrevItem();
   } else if ((_parentMenu != null) && _parentMenu._vertical) {
     _parentMenu._selectPrevItem();
   } else {
     _close(true);
   }
 }


 void onBrowserEvent(dart_html.Event event) {
   MenuItem item = _findItem(event.target);
   switch (Dom.eventGetType(event)) {
     case IEvent.ONCLICK:
       FocusPanel.impl.focus(getElement());
       // Fire an item's command when the user clicks on it.
       if (item != null) {
         doItemAction(item, true, true);
       }
       break;

     case IEvent.ONMOUSEOVER:
       if (item != null) {
         itemOver(item, true);
       }
       break;

     case IEvent.ONMOUSEOUT:
       if (item != null) {
         itemOver(null, true);
       }
       break;

     case IEvent.ONFOCUS:
       _selectFirstItemIfNoneSelected();
       break;

     case IEvent.ONKEYDOWN:
       dart_html.KeyboardEvent kEvent = event as dart_html.KeyboardEvent;
       int keyCode = kEvent.keyCode;
       switch (keyCode) {
         case KeyCodes.KEY_LEFT:
           if (LocaleInfo.getCurrentLocale().isRTL()) {
             _moveToNextItem();
           } else {
             _moveToPrevItem();
           }
           _eatEvent(event);
           break;
         case KeyCodes.KEY_RIGHT:
           if (LocaleInfo.getCurrentLocale().isRTL()) {
             _moveToPrevItem();
           } else {
             _moveToNextItem();
           }
           _eatEvent(event);
           break;
         case KeyCodes.KEY_UP:
           moveSelectionUp();
           _eatEvent(event);
           break;
         case KeyCodes.KEY_DOWN:
           moveSelectionDown();
           _eatEvent(event);
           break;
         case KeyCodes.KEY_ESCAPE:
           closeAllParentsAndChildren();
           _eatEvent(event);
           break;
         case KeyCodes.KEY_TAB:
           closeAllParentsAndChildren();
           break;
         case KeyCodes.KEY_ENTER:
           if (!_selectFirstItemIfNoneSelected()) {
             doItemAction(_selectedItem, true, true);
             _eatEvent(event);
           }
           break;
       } // end switch(keyCode)

       break;
   } // end switch (Dom.eventGetType(event))
   super.onBrowserEvent(event);
 }

 /**
  * Closes the menu bar.
  *
  * @deprecated Use {@link #addCloseHandler(CloseHandler)} instead
  */
//
//  @Deprecated
//  void onPopupClosed(PopupPanel sender, bool autoClosed) {
//    // If the menu popup was auto-closed, close all of its parents as well.
//    if (autoClosed) {
//      closeAllParents();
//    }
//
//    // When the menu popup closes, remember that no item is
//    // currently showing a popup menu.
//    onHide(!autoClosed);
//    CloseEvent.fire(MenuBar.this, sender);
//    shownChildMenu = null;
//    popup = null;
//    if (parentMenu != null && parentMenu.popup != null) {
//      parentMenu.popup.setPreviewingAllNativeEvents(true);
//    }
//  }

 /**
  * Removes the specified menu item from the bar.
  *
  * @param item the item to be removed
  */
 void removeItem(MenuItem item) {
   // Unselect if the item is currently selected
   if (_selectedItem == item) {
     selectItem(null);
   }

   if (_removeItemElement(item)) {
     _setItemColSpan(item, 1);
     _items.remove(item);
     item.setParentMenu(null);
   }
 }

 /**
  * Removes the specified {@link MenuItemSeparator} from the bar.
  *
  * @param separator the separator to be removed
  */
 void removeSeparator(MenuItemSeparator separator) {
   if (_removeItemElement(separator)) {
     separator.setParentMenu(null);
   }
 }

 /**
  * Select the given MenuItem, which must be a direct child of this MenuBar.
  *
  * @param item the MenuItem to select, or null to clear selection
  */
 void selectItem(MenuItem item) {
   assert (item == null || item.getParentMenu() == this);

   if (item == _selectedItem) {
     return;
   }

   if (_selectedItem != null) {
     _selectedItem.setSelectionStyle(false);
     // Set the style of the submenu indicator
     if (_vertical) {
       dart_html.Element tr = _selectedItem.getElement().parent;
       if (Dom.getChildCount(tr) == 2) {
         dart_html.Element td = Dom.getChild(tr, 1);
         UiObject.manageElementStyleName(td, "subMenuIcon-selected", false);
       }
     }
   }

   if (item != null) {
     item.setSelectionStyle(true);

     // Set the style of the submenu indicator
     if (_vertical) {
       dart_html.Element tr = item.getElement().parent;
       if (tr.children.length == 2) {
         dart_html.Element td = tr.children[1];
         UiObject.manageElementStyleName(td, "subMenuIcon-selected", true);
       }
     }

//      Roles.getMenubarRole().setAriaActivedescendantProperty(getElement(),
//          IdReference.of(Dom.getElementAttribute(item.getElement(), "id")));
   }

   _selectedItem = item;
 }


 void setAnimationEnabled(bool enable) {
   _isAnimationEnabled = enable;
 }

 /**
  * Sets whether this menu bar's child menus will open when the mouse is moved
  * over it.
  *
  * @param autoOpen <code>true</code> to cause child menus to auto-open
  */
 void setAutoOpen(bool autoOpen) {
   this._autoOpen = autoOpen;
 }

 /**
  * Enable or disable auto focus when the mouse hovers over the MenuBar. This
  * allows the MenuBar to respond to keyboard events without the user having to
  * click on it, but it will steal focus from other elements on the page.
  * Enabled by default.
  *
  * @param enabled true to enable, false to disable
  */
 void setFocusOnHoverEnabled(bool enabled) {
   _focusOnHover = enabled;
 }

 /**
  * Returns a list containing the <code>MenuItem</code> objects in the menu
  * bar. If there are no items in the menu bar, then an empty <code>List</code>
  * object will be returned.
  *
  * @return a list containing the <code>MenuItem</code> objects in the menu bar
  */
 List<MenuItem> getItems() {
   return this._items;
 }

 /**
  * Returns the <code>MenuItem</code> that is currently selected (highlighted)
  * by the user. If none of the items in the menu are currently selected, then
  * <code>null</code> will be returned.
  *
  * @return the <code>MenuItem</code> that is currently selected, or
  *         <code>null</code> if no items are currently selected
  */
 MenuItem getSelectedItem() {
   return this._selectedItem;
 }


 void onDetach() {
   // When the menu is detached, make sure to close all of its children.
   if (_popup != null) {
     _popup.hide();
   }

   super.onDetach();
 }

 /*
  * Closes all parent menu popups.
  */
 void closeAllParents() {
   if (_parentMenu != null) {
     // The parent menu will recursively call closeAllParents.
     _close(false);
   } else {
     // If this is the top most menu, deselect the current item.
     selectItem(null);
   }
 }

 /**
  * Closes all parent and child menu popups.
  */
 void closeAllParentsAndChildren() {
   closeAllParents();
   // Ensure the popup is closed even if it has not been enetered
   // with the mouse or key navigation
   if (_parentMenu == null && _popup != null) {
     _popup.hide();
   }
 }

 /*
  * Performs the action associated with the given menu item. If the item has a
  * popup associated with it, the popup will be shown. If it has a command
  * associated with it, and 'fireCommand' is true, then the command will be
  * fired. Popups associated with other items will be hidden.
  *
  * @param item the item whose popup is to be shown. @param fireCommand
  * <code>true</code> if the item's command should be fired, <code>false</code>
  * otherwise.
  */
 void doItemAction(final MenuItem item, bool fireCommand, bool pFocus) {
   // Should not perform any action if the item is disabled
   if (!item.enabled) {
     return;
   }

   // Ensure that the item is selected.
   selectItem(item);

   // if the command should be fired and the item has one, fire it
   if (fireCommand && item.getScheduledCommand() != null) {
     // Close this menu and all of its parents.
     closeAllParents();

     // Fire the item's command. The command must be fired in the same event
     // loop or popup blockers will prevent popups from opening.
     ScheduledCommand cmd = item.getScheduledCommand();
     Scheduler.get().scheduleDeferred(new _MenuScheduledCommand(cmd));

     // hide any open submenus of this item
     if (_shownChildMenu != null) {
       _shownChildMenu._onHide(pFocus);
       _popup.hide();
       _shownChildMenu = null;
       selectItem(null);
     }
   } else if (item.getSubMenu() != null) {
     if (_shownChildMenu == null) {
       // open this submenu
       _openPopup(item);
     } else if (item.getSubMenu() != _shownChildMenu) {
       // close the other submenu and open this one
       _shownChildMenu._onHide(pFocus);
       _popup.hide();
       _openPopup(item);
     } else if (fireCommand && !_autoOpen) {
       // close this submenu
       _shownChildMenu._onHide(pFocus);
       _popup.hide();
       _shownChildMenu = null;
       selectItem(item);
     }
   } else if (_autoOpen && _shownChildMenu != null) {
     // close submenu
     _shownChildMenu._onHide(pFocus);
     _popup.hide();
     _shownChildMenu = null;
   }
 }

 /**
  * Visible for testing.
  */
 PopupPanel getPopup() {
   return _popup;
 }

 void itemOver(MenuItem item, bool pFocus) {
   if (item == null) {
     // Don't clear selection if the currently selected item's menu is showing.
     if ((_selectedItem != null)
         && (_shownChildMenu == _selectedItem.getSubMenu())) {
       return;
     }
   }

   if (item != null && !item.enabled) {
     return;
   }

   // Style the item selected when the mouse enters.
   selectItem(item);
   if (pFocus && _focusOnHover) {
     focus();
   }

   // If child menus are being shown, or this menu is itself
   // a child menu, automatically show an item's child menu
   // when the mouse enters.
   if (item != null) {
     if ((_shownChildMenu != null) || (_parentMenu != null) || _autoOpen) {
       doItemAction(item, false, _focusOnHover);
     }
   }
 }

//  /**
//   * Set the IDs of the menu items.
//   *
//   * @param baseID the base ID
//   */
//  void setMenuItemDebugIds(String baseID) {
//    int itemCount = 0;
//    for (MenuItem item in _items) {
//      item.ensureDebugId(baseID + "-item" + itemCount);
//      itemCount++;
//    }
//  }

 /**
  * Show or hide the icon used for items with a submenu.
  *
  * @param item the item with or without a submenu
  */
 void updateSubmenuIcon(MenuItem item) {
   // The submenu icon only applies to vertical menus
   if (!_vertical) {
     return;
   }

   // Get the index of the MenuItem
   int idx = _allItems.indexOf(item);
   if (idx == -1) {
     return;
   }

   dart_html.Element container = _getItemContainerElement();
   dart_html.Element tr = Dom.getChild(container, idx);
   int tdCount = Dom.getChildCount(tr);
   MenuBar submenu = item.getSubMenu();
   if (submenu == null) {
     // Remove the submenu indicator
     if (tdCount == 2) {
       //Dom.removeChild(tr, Dom.getChild(tr, 1));
       Dom.getChild(tr, 1).remove();
     }
     _setItemColSpan(item, 2);
   } else if (tdCount == 1) {
     // Show the submenu indicator
     _setItemColSpan(item, 1);
     dart_html.Element td = new dart_html.TableCellElement();
     td.style.verticalAlign = "middle";
     td.append(_subMenuIcon.createElement());
     UiObject.setElementStyleName(td, "subMenuIcon");
     tr.append(td);
   }
 }

 /**
  * Physically add the td element of a {@link MenuItem} or
  * {@link MenuItemSeparator} to this {@link MenuBar}.
  *
  * @param beforeIndex the index where the separator should be inserted
  * @param tdElem the td element to be added
  */
 void _addItemElement(int beforeIndex, dart_html.Element tdElem) {
   if (_vertical) {
     dart_html.Element tr = new dart_html.TableRowElement();
     Dom.insertChild(_body, tr, beforeIndex);
     tr.append(tdElem);
   } else {
     dart_html.Element tr = Dom.getChild(_body, 0);
     Dom.insertChild(tr, tdElem, beforeIndex);
   }
 }

 /**
  * Closes this menu (if it is a popup).
  *
  * @param focus true to move focus to the parent
  */
 void _close(bool focus) {
   if (_parentMenu != null) {
     _parentMenu._popup.hide(!focus);
     if (focus) {
       _parentMenu.focus();
     }
   }
 }

 void _eatEvent(dart_html.Event event) {
//    event.cancelBubble = true;
   event.preventDefault();
 }

 MenuItem _findItem(dart_html.Element hItem) {
   for (MenuItem item in _items) {
     if (Dom.isOrHasChild(item.getElement(), hItem)) {
       return item;
     }
   }
   return null;
 }

 dart_html.Element _getItemContainerElement() {
   if (_vertical) {
     return _body;
   } else {
     return Dom.getChild(_body, 0);
   }
 }

 void _init(bool vertical, AbstractImagePrototype subMenuIcon) {
   this._subMenuIcon = subMenuIcon;

   dart_html.TableElement table = new dart_html.TableElement();
   _body = table.createTBody();
   table.append(_body);

   if (!vertical) {
     dart_html.Element tr = new dart_html.TableRowElement();
     _body.append(tr);
   }

   this._vertical = vertical;

   dart_html.Element outer = FocusPanel.impl.createFocusable();
   outer.append(table);
   setElement(outer);

   //Roles.getMenubarRole().set(getElement());

   sinkEvents(IEvent.ONCLICK | IEvent.ONMOUSEOVER | IEvent.ONMOUSEOUT
       | IEvent.ONFOCUS | IEvent.ONKEYDOWN);

   clearAndSetStyleName(_STYLENAME_DEFAULT);
   if (_vertical) {
     addStyleDependentName("vertical");
   } else {
     addStyleDependentName("horizontal");
   }

   // Hide focus outline in Mozilla/Webkit/Opera
   Dom.setStyleAttribute(getElement(), "outline", "0px");

   // Hide focus outline in IE 6/7
   Dom.setElementAttribute(getElement(), "hideFocus", "true");

   // Deselect items when blurring without a child menu.
   addDomHandler(new BlurHandlerAdapter((BlurEvent evt) {
     if (_shownChildMenu == null) {
       selectItem(null);
     }
   }), BlurEvent.TYPE);
 }

 void _moveToNextItem() {
   if (_selectFirstItemIfNoneSelected()) {
     return;
   }

   if (!_vertical) {
     _selectNextItem();
   } else {
     if (_selectedItem.getSubMenu() != null
         && !_selectedItem.getSubMenu().getItems().isEmpty
         && (_shownChildMenu == null || _shownChildMenu.getSelectedItem() == null)) {
       if (_shownChildMenu == null) {
         doItemAction(_selectedItem, false, true);
       }
       _selectedItem.getSubMenu().focus();
     } else if (_parentMenu != null) {
       if (!_parentMenu._vertical) {
         _parentMenu._selectNextItem();
       } else {
         _parentMenu._moveToNextItem();
       }
     }
   }
 }

 void _moveToPrevItem() {
   if (_selectFirstItemIfNoneSelected()) {
     return;
   }

   if (!_vertical) {
     _selectPrevItem();
   } else {
     if ((_parentMenu != null) && (!_parentMenu._vertical)) {
       _parentMenu._selectPrevItem();
     } else {
       _close(true);
     }
   }
 }

 /*
  * This method is called when a menu bar is hidden, so that it can hide any
  * child popups that are currently being shown.
  */
 void _onHide(bool pFocus) {
   if (_shownChildMenu != null) {
     _shownChildMenu._onHide(pFocus);
     _popup.hide();
     if (pFocus) {
       focus();
     }
   }
 }

 /*
  * This method is called when a menu bar is shown.
  */
 void _onShow() {
   // clear the selection; a keyboard user can cursor down to the first item
   selectItem(null);
 }

 void _openPopup(MenuItem item) {
   // Only the last popup to be opened should preview all event
   if (_parentMenu != null && _parentMenu._popup != null) {
     _parentMenu._popup.setPreviewingAllNativeEvents(false);
   }

   // Create a new popup for this item, and position it next to
   // the item (below if this is a horizontal menu bar, to the
   // right if it's a vertical bar).
   _popup = new _MenuDecoratedPopupPanel(this, item, true, false, "menuPopup");
   _popup.setAnimationType(AnimationType.ONE_WAY_CORNER);
   _popup.setAnimationEnabled(_isAnimationEnabled);
   _popup.clearAndSetStyleName(_STYLENAME_DEFAULT + "Popup");
   String primaryStyleName = getStylePrimaryName();
   if (_STYLENAME_DEFAULT != primaryStyleName) {
     _popup.addStyleName(primaryStyleName + "Popup");
   }
   //_popup.addPopupListener(this);
   // Closes the menu bar.
   _popup.addCloseHandler(new CloseHandlerAdapter((CloseEvent evt){
       // If the menu popup was auto-closed, close all of its parents as well.
       if (evt.autoClosed) {
         closeAllParents();
       }

       // When the menu popup closes, remember that no item is
       // currently showing a popup menu.
       _onHide(!evt.autoClosed);
       CloseEvent.fire(this, evt.target);
       _shownChildMenu = null;
       _popup = null;
       if (_parentMenu != null && _parentMenu._popup != null) {
         _parentMenu._popup.setPreviewingAllNativeEvents(true);
       }
   }));

   _shownChildMenu = item.getSubMenu();
   item.getSubMenu()._parentMenu = this;

   // Show the popup, ensuring that the menubar's event preview remains on top
   // of the popup's.
   _popup.setPopupPositionAndShow(new _PopupPanelPositionCallback(this, item));
 }

 /**
  * Removes the specified item from the {@link MenuBar} and the physical Dom
  * structure.
  *
  * @param item the item to be removed
  * @return true if the item was removed
  */
 bool _removeItemElement(UiObject item) {
   int idx = _allItems.indexOf(item);
   if (idx == -1) {
     return false;
   }

   dart_html.Element container = _getItemContainerElement();
   //Dom.removeChild(container, Dom.getChild(container, idx));
   Dom.getChild(container, idx).remove();
   _allItems.remove(idx);
   return true;
 }

 /**
  * Selects the first item in the menu if no items are currently selected. Has
  * no effect if there are no items.
  *
  * @return true if no item was previously selected, false otherwise
  */
 bool _selectFirstItemIfNoneSelected() {
   if (_selectedItem == null) {
     for (MenuItem nextItem in _items) {
       if (nextItem.enabled) {
         selectItem(nextItem);
         break;
       }
     }
     return true;
   }
   return false;
}

 void _selectNextItem() {
   if (_selectedItem == null) {
     return;
   }

   int index = _items.indexOf(_selectedItem);
   // We know that selectedItem is set to an item that is contained in the
   // items collection.
   // Therefore, we know that index can never be -1.
   assert (index != -1);

   MenuItem itemToBeSelected;

   int firstIndex = index;
   while (true) {
     index = index + 1;
     if (index == _items.length) {
       // we're at the end, loop around to the start
       index = 0;
     }
     if (index == firstIndex) {
       itemToBeSelected = _items[firstIndex];
       break;
     } else {
       itemToBeSelected = _items[index];
       if (itemToBeSelected.enabled) {
         break;
       }
     }
   }

   selectItem(itemToBeSelected);
   if (_shownChildMenu != null) {
     doItemAction(itemToBeSelected, false, true);
   }
 }

 void _selectPrevItem() {
   if (_selectedItem == null) {
     return;
   }

   int index = _items.indexOf(_selectedItem);
   // We know that selectedItem is set to an item that is contained in the
   // items collection.
   // Therefore, we know that index can never be -1.
   assert (index != -1);

   MenuItem itemToBeSelected;

   int firstIndex = index;
   while (true) {
     index = index - 1;
     if (index < 0) {
       // we're at the start, loop around to the end
       index = _items.length - 1;
     }
     if (index == firstIndex) {
       itemToBeSelected = _items[firstIndex];
       break;
     } else {
       itemToBeSelected = _items[index];
       if (itemToBeSelected.enabled) {
         break;
       }
     }
   }

   selectItem(itemToBeSelected);
   if (_shownChildMenu != null) {
     doItemAction(itemToBeSelected, false, true);
   }
 }

 /**
  * Set the colspan of a {@link MenuItem} or {@link MenuItemSeparator}.
  *
  * @param item the {@link MenuItem} or {@link MenuItemSeparator}
  * @param colspan the colspan
  */
 void _setItemColSpan(UiObject item, int colspan) {
   Dom.setElementPropertyInt(item.getElement(), "colSpan", colspan);
 }
}

Extends

UiObject > Widget > MenuBar

Implements

HasCloseHandlers<PopupPanel>, HasAnimation

Constructors

new MenuBar([bool vertical = false, MenuResource resources = null]) #

Creates an empty menu bar that uses the specified ClientBundle for menu images.

@param vertical <code>true</code> to orient the menu bar vertically @param resources a bundle that provides images for this menu

MenuBar([bool vertical = false, MenuResource resources = null]) {
 if (resources == null) {
   resources = new MenuResources();
 }
 _init(vertical, AbstractImagePrototype.create(resources.menuBarSubMenuIcon()));
}

Properties

int eventsToSink #

inherited from Widget

A set og events that should be sunk when the widget is attached to the DOM. (We delay the sinking of events to improve startup performance.) When the widget is attached, this is set is empty

Package protected to allow Composite to see it.

int eventsToSink = 0

String get title #

inherited from UiObject

Gets the title associated with this object. The title is the 'tool-tip' displayed to users when they hover over the object.

@return the object's title

String get title => getElement().title;

void set title(String value) #

inherited from UiObject

Sets the element's title.

void set title(String value) {
 getElement().title = value;
}

bool get visible #

inherited from UiObject

Determines whether or not this object is visible. Note that this does not necessarily take into account whether or not the receiver's parent is visible, or even if it is attached to the Document. The default implementation of this trait in UIObject is based on the value of a dom element's style object's display attribute.

@return <code>true</code> if the object is visible

bool get visible => isVisible(getElement());

void set visible(bool visible) #

inherited from UiObject

Sets whether this object is visible.

@param visible <code>true</code> to show the object, <code>false</code> to

     hide it
void set visible(bool visible) {
 setVisible(getElement(), visible);
}

Methods

HandlerRegistration addAttachHandler(AttachEventHandler handler) #

inherited from Widget

Adds an AttachEvent handler.

@param handler the handler @return the handler registration

HandlerRegistration addAttachHandler(AttachEventHandler handler) {
 return addHandler(handler, AttachEvent.TYPE);
}

HandlerRegistration addBitlessDomHandler(EventHandler handler, DomEventType type) #

inherited from Widget

For <a href= "http://code.google.com/p/google-web-toolkit/wiki/UnderstandingMemoryLeaks"

browsers which do not leak</a>, adds a native event handler to the widget.

Note that, unlike the {@link #addDomHandler(EventHandler, com.google.gwt.event.dom.client.DomEvent.Type)} implementation, there is no need to attach the widget to the DOM in order to cause the event handlers to be attached.

@param <H> the type of handler to add @param type the event key @param handler the handler @return {@link HandlerRegistration} used to remove the handler

HandlerRegistration addBitlessDomHandler(EventHandler handler, DomEventType type) {
 assert (handler != null);; // : "handler must not be null";
 assert (type != null); // : "type must not be null";
 sinkBitlessEvent(type.eventName);
 return ensureHandlers().addHandler(type, handler);
}

HandlerRegistration addCloseHandler(CloseHandler<PopupPanel> handler) #

Adds a {@link CloseEvent} handler.

@param handler the handler @return the registration for the event

docs inherited from HasCloseHandlers<PopupPanel>
HandlerRegistration addCloseHandler(CloseHandler<PopupPanel> handler) {
 return addHandler(handler, CloseEvent.TYPE);
}

HandlerRegistration addDomHandler(EventHandler handler, DomEventType type) #

inherited from Widget

Adds a native event handler to the widget and sinks the corresponding native event. If you do not want to sink the native event, use the generic addHandler method instead.

@param <H> the type of handler to add @param type the event key @param handler the handler @return {@link HandlerRegistration} used to remove the handler

HandlerRegistration addDomHandler(EventHandler handler, DomEventType type) {
 assert (handler != null); // : "handler must not be null";
 assert (type != null); // : "type must not be null";
 int typeInt = IEvent.getTypeInt(type.eventName);
 if (typeInt == -1) {
   sinkBitlessEvent(type.eventName);
 } else {
   sinkEvents(typeInt);
 }
 return ensureHandlers().addHandler(type, handler);
}

HandlerRegistration addHandler(EventHandler handler, EventType<EventHandler> type) #

inherited from Widget

Adds this handler to the widget.

@param <H> the type of handler to add @param type the event type @param handler the handler @return {@link HandlerRegistration} used to remove the handler

HandlerRegistration addHandler(EventHandler handler, EventType<EventHandler> type) {
 return ensureHandlers().addHandler(type, handler);
}

MenuItem addItem(MenuItem item) #

Adds a menu item to the bar.

@param item the item to be added @return the {@link MenuItem} object

MenuItem addItem(MenuItem item) {
 return insertItem(item, _allItems.length);
}

MenuItem addSafeHtmlItem(SafeHtml html, {MenuBar popup, ScheduledCommand cmd}) #

Adds a menu item to the bar containing SafeHtml, that will fire the given command when it is selected.

@param html the item's html text @param cmd the command to be fired @return the {@link MenuItem} object created

MenuItem addSafeHtmlItem(SafeHtml html, {MenuBar popup, ScheduledCommand cmd}) {
 return addItem(new MenuItem.fromSafeHtml(html, subMenu:popup, cmd:cmd));
}

MenuItemSeparator addSeparator([MenuItemSeparator separator = null]) #

Adds a thin line to the {@link MenuBar} to separate sections of {@link MenuItem}s.

@param separator the {@link MenuItemSeparator} to be added @return the {@link MenuItemSeparator} object

MenuItemSeparator addSeparator([MenuItemSeparator separator = null]) {
 if (separator == null) {
   separator = new MenuItemSeparator();
 }
 return insertSeparator(_allItems.length, separator);
}

void addStyleDependentName(String styleSuffix) #

inherited from UiObject

Adds a dependent style name by specifying the style name's suffix. The actual form of the style name that is added is:

getStylePrimaryName() + '-' + styleSuffix

@param styleSuffix the suffix of the dependent style to be added. @see #setStylePrimaryName(String) @see #removeStyleDependentName(String) @see #setStyleDependentName(String, boolean) @see #addStyleName(String)

void addStyleDependentName(String styleSuffix) {
 setStyleDependentName(styleSuffix, true);
}

void addStyleName(String style) #

inherited from UiObject

Adds a secondary or dependent style name to this object. A secondary style name is an additional style name that is, in HTML/CSS terms, included as a space-separated token in the value of the CSS <code>class</code> attribute for this object's root element.

The most important use for this method is to add a special kind of secondary style name called a dependent style name. To add a dependent style name, use {@link #addStyleDependentName(String)}, which will prefix the 'style' argument with the result of {@link #k()} (followed by a '-'). For example, suppose the primary style name is gwt-TextBox. If the following method is called as obj.setReadOnly(true):

public void setReadOnly(boolean readOnly) {
  isReadOnlyMode = readOnly;

// Create a dependent style name. String readOnlyStyle = "readonly";

if (readOnly) {

addStyleDependentName(readOnlyStyle);

} else {

removeStyleDependentName(readOnlyStyle);

} }</pre>

then both of the CSS style rules below will be applied:

// This rule is based on the primary style name and is always active. .gwt-TextBox { font-size: 12pt; }

// This rule is based on a dependent style name that is only active // when the widget has called addStyleName(getStylePrimaryName() + // "-readonly"). .gwt-TextBox-readonly { background-color: lightgrey; border: none; }</pre>

The code can also be simplified with {@link #setStyleDependentName(String, boolean)}:

public void setReadOnly(boolean readOnly) {
  isReadOnlyMode = readOnly;
  setStyleDependentName("readonly", readOnly);
}

Dependent style names are powerful because they are automatically updated whenever the primary style name changes. Continuing with the example above, if the primary style name changed due to the following call:

setStylePrimaryName("my-TextThingy");

then the object would be re-associated with following style rules, removing those that were shown above.

.my-TextThingy {
  font-size: 20pt;
}

.my-TextThingy-readonly { background-color: red; border: 2px solid yellow; }</pre>

Secondary style names that are not dependent style names are not automatically updated when the primary style name changes.

@param style the secondary style name to be added @see UIObject @see #removeStyleName(String)

void addStyleName(String style) {
 setStyleName(style, true);
}

MenuItem addTextItem(String text, bool asHtml, {MenuBar popup, ScheduledCommand cmd}) #

Adds a menu item to the bar, that will fire the given command when it is selected.

@param text the item's text @param asHtml <code>true</code> to treat the specified text as html @param cmd the command to be fired @return the {@link MenuItem} object created

MenuItem addTextItem(String text, bool asHtml, {MenuBar popup, ScheduledCommand cmd}) {
 return addItem(new MenuItem(text, asHtml, subMenu:popup, cmd:cmd));
}

Widget asWidget() #

inherited from Widget

Returns the Widget aspect of the receiver.

Widget asWidget() {
 return this;
}

void clearAndSetStyleName(String style) #

inherited from UiObject

Clears all of the object's style names and sets it to the given style. You should normally use {@link #setStylePrimaryName(String)} unless you wish to explicitly remove all existing styles.

@param style the new style name @see #setStylePrimaryName(String)

void clearAndSetStyleName(String style) {
 setElementStyleName(getStyleElement(), style);
}

void clearItems() #

Removes all menu items from this menu bar.

void clearItems() {
 // Deselect the current item
 selectItem(null);

 dart_html.Element container = _getItemContainerElement();
 while (Dom.getChildCount(container) > 0) {
   Dom.getChild(container, 0).remove();
 }

 // Set the parent of all items to null
 for (UiObject item in _allItems) {
   _setItemColSpan(item, 1);
   if (item is MenuItemSeparator) {
     (item as MenuItemSeparator).setParentMenu(null);
   } else {
     (item as MenuItem).setParentMenu(null);
   }
 }

 // Clear out all of the items and separators
 _items.clear();
 _allItems.clear();
}

void closeAllChildren(bool pFocus) #

Closes this menu and all child menu popups.

@param pFocus true to move focus to the parent

void closeAllChildren(bool pFocus) {
 if (_shownChildMenu != null) {
   // Hide any open submenus of this item
   _shownChildMenu._onHide(pFocus);
   _shownChildMenu = null;
   selectItem(null);
 }
 // Close the current popup
 if (_popup != null) {
   _popup.hide();
 }
 // If focus is true, set focus to parentMenu
 if (pFocus && _parentMenu != null) {
   _parentMenu.focus();
 }
}

void closeAllParents() #

void closeAllParents() {
 if (_parentMenu != null) {
   // The parent menu will recursively call closeAllParents.
   _close(false);
 } else {
   // If this is the top most menu, deselect the current item.
   selectItem(null);
 }
}

void closeAllParentsAndChildren() #

Closes all parent and child menu popups.

void closeAllParentsAndChildren() {
 closeAllParents();
 // Ensure the popup is closed even if it has not been enetered
 // with the mouse or key navigation
 if (_parentMenu == null && _popup != null) {
   _popup.hide();
 }
}

EventBus createEventBus() #

inherited from Widget

Creates the SimpleEventBus used by this Widget. You can override this method to create a custom EventBus.

@return the EventBus you want to use.

EventBus createEventBus() {
 return new SimpleEventBus();
}

void delegateEvent(Widget target, DwtEvent event) #

inherited from Widget

Fires an event on a child widget. Used to delegate the handling of an event from one widget to another.

@param event the event @param target fire the event on the given target

void delegateEvent(Widget target, DwtEvent event) {
 target.fireEvent(event);
}

void doAttachChildren() #

inherited from Widget

If a widget contains one or more child widgets that are not in the logical widget hierarchy (the child is physically connected only on the DOM level), it must override this method and call {@link #onAttach()} for each of its child widgets.

@see #onAttach()

void doAttachChildren() {
}

void doDetachChildren() #

inherited from Widget

If a widget contains one or more child widgets that are not in the logical widget hierarchy (the child is physically connected only on the DOM level), it must override this method and call {@link #onDetach()} for each of its child widgets.

@see #onDetach()

void doDetachChildren() {
}

void doItemAction(MenuItem item, bool fireCommand, bool pFocus) #

void doItemAction(final MenuItem item, bool fireCommand, bool pFocus) {
 // Should not perform any action if the item is disabled
 if (!item.enabled) {
   return;
 }

 // Ensure that the item is selected.
 selectItem(item);

 // if the command should be fired and the item has one, fire it
 if (fireCommand && item.getScheduledCommand() != null) {
   // Close this menu and all of its parents.
   closeAllParents();

   // Fire the item's command. The command must be fired in the same event
   // loop or popup blockers will prevent popups from opening.
   ScheduledCommand cmd = item.getScheduledCommand();
   Scheduler.get().scheduleDeferred(new _MenuScheduledCommand(cmd));

   // hide any open submenus of this item
   if (_shownChildMenu != null) {
     _shownChildMenu._onHide(pFocus);
     _popup.hide();
     _shownChildMenu = null;
     selectItem(null);
   }
 } else if (item.getSubMenu() != null) {
   if (_shownChildMenu == null) {
     // open this submenu
     _openPopup(item);
   } else if (item.getSubMenu() != _shownChildMenu) {
     // close the other submenu and open this one
     _shownChildMenu._onHide(pFocus);
     _popup.hide();
     _openPopup(item);
   } else if (fireCommand && !_autoOpen) {
     // close this submenu
     _shownChildMenu._onHide(pFocus);
     _popup.hide();
     _shownChildMenu = null;
     selectItem(item);
   }
 } else if (_autoOpen && _shownChildMenu != null) {
   // close submenu
   _shownChildMenu._onHide(pFocus);
   _popup.hide();
   _shownChildMenu = null;
 }
}

EventBus ensureHandlers() #

inherited from Widget

Ensures the existence of the event bus.

@return the EventBus.

EventBus ensureHandlers() {
 return _eventBus == null ? _eventBus = createEventBus() : _eventBus;
}

double extractLengthValue(String s) #

inherited from UiObject

Intended to be used to pull the value out of a CSS length. If the value is "auto" or "inherit", 0 will be returned.

@param s The CSS length string to extract @return The leading numeric portion of <code>s</code>, or 0 if "auto" or

    "inherit" are passed in.
double extractLengthValue(String s) {
 if (s == "auto" || s == "inherit" || s == "") {
   return 0.0;
 } else {
   // numberRegex divides the string into a leading numeric portion
   // followed by an arbitrary portion.
   if(numberRegex.hasMatch(s)) {
     // Extract the leading numeric portion of string
     s = numberRegex.firstMatch(s)[0];
   }
   return double.parse(s);
 }
}

void fireEvent(DwtEvent event) #

inherited from Widget

Fires the given event to the handlers listening to the event's type.

Any exceptions thrown by handlers will be bundled into a UmbrellaException and then re-thrown after all handlers have completed. An exception thrown by a handler will not prevent other handlers from executing.

@param event the event

void fireEvent(DwtEvent event) {
//    if (_eventBus != null) {
//      _eventBus.fireEvent(event);
//    }
 if (_eventBus != null) {
   // If it not live we should revive it.
   if (!event.isLive()) {
     event.revive();
   }
   Object oldSource = event.getSource();
   event.overrideSource(getElement());
   try {

     // May throw an UmbrellaException.
     _eventBus.fireEventFromSource(event, getElement());
   } on UmbrellaException catch (e) {
     throw new UmbrellaException(e.causes);
   } finally {
     if (oldSource == null) {
       // This was my event, so I should kill it now that I'm done.
       event.kill();
     } else {
       // Restoring the source for the next handler to use.
       event.overrideSource(oldSource);
     }
   }
 }
}

void focus() #

Give this MenuBar focus.

void focus() {
 FocusPanel.impl.focus(getElement());
}

int getAbsoluteLeft() #

inherited from UiObject

Gets the object's absolute left position in pixels, as measured from the browser window's client area.

@return the object's absolute left position

int getAbsoluteLeft() {
 return Dom.getAbsoluteLeft(getElement());
}

int getAbsoluteTop() #

inherited from UiObject

Gets the object's absolute top position in pixels, as measured from the browser window's client area.

@return the object's absolute top position

int getAbsoluteTop() {
 return Dom.getAbsoluteTop(getElement());
}

bool getAutoOpen() #

Gets whether this menu bar's child menus will open when the mouse is moved over it.

@return <code>true</code> if child menus will auto-open

bool getAutoOpen() {
 return _autoOpen;
}

Element getElement() #

inherited from UiObject

Gets this object's browser element.

dart_html.Element getElement() {
 assert (_element != null); // : MISSING_ELEMENT_ERROR;
 return _element;
}

EventBus getEventBus() #

inherited from Widget

Return EventBus.

EventBus getEventBus() {
 return _eventBus;
}

int getItemIndex(MenuItem item) #

Get the index of a {@link MenuItem}.

@return the index of the item, or -1 if it is not contained by this MenuBar

int getItemIndex(MenuItem item) {
 return _allItems.indexOf(item);
}

List<MenuItem> getItems() #

Returns a list containing the <code>MenuItem</code> objects in the menu bar. If there are no items in the menu bar, then an empty <code>List</code> object will be returned.

@return a list containing the <code>MenuItem</code> objects in the menu bar

List<MenuItem> getItems() {
 return this._items;
}

Object getLayoutData() #

inherited from Widget

Gets the panel-defined layout data associated with this widget.

@return the widget's layout data @see #setLayoutData

Object getLayoutData() {
 return _layoutData;
}

int getOffsetHeight() #

inherited from UiObject

Gets the object's offset height in pixels. This is the total height of the object, including decorations such as border and padding, but not margin.

@return the object's offset height

int getOffsetHeight() {
 return getElement().offset.height; // Dom.getElementPropertyInt(getElement(), "offsetHeight");
}

int getOffsetWidth() #

inherited from UiObject

Gets the object's offset width in pixels. This is the total width of the object, including decorations such as border and padding, but not margin.

@return the object's offset width

int getOffsetWidth() {
 return getElement().offset.width; // Dom.getElementPropertyInt(getElement(), "offsetWidth");
}

Widget getParent() #

inherited from Widget

Gets this widget's parent panel.

@return the widget's parent panel

Widget getParent() {
 return _parent;
}

PopupPanel getPopup() #

Visible for testing.

PopupPanel getPopup() {
 return _popup;
}

MenuItem getSelectedItem() #

Returns the <code>MenuItem</code> that is currently selected (highlighted) by the user. If none of the items in the menu are currently selected, then <code>null</code> will be returned.

@return the <code>MenuItem</code> that is currently selected, or

    <code>null</code> if no items are currently selected
MenuItem getSelectedItem() {
 return this._selectedItem;
}

int getSeparatorIndex(MenuItemSeparator item) #

Get the index of a {@link MenuItemSeparator}.

@return the index of the separator, or -1 if it is not contained by this

    MenuBar
int getSeparatorIndex(MenuItemSeparator item) {
 return _allItems.indexOf(item);
}

Element getStyleElement() #

inherited from UiObject

Template method that returns the element to which style names will be applied. By default it returns the root element, but this method may be overridden to apply styles to a child element.

@return the element to which style names will be applied

dart_html.Element getStyleElement() {
 return getElement();
}

String getStyleName() #

inherited from UiObject

Gets all of the object's style names, as a space-separated list. If you wish to retrieve only the primary style name, call {@link #getStylePrimaryName()}.

@return the objects's space-separated style names @see #getStylePrimaryName()

String getStyleName() {
 return getElementStyleName(getStyleElement());
}

String getStylePrimaryName() #

inherited from UiObject

Gets the primary style name associated with the object.

@return the object's primary style name @see #setStyleName(String) @see #addStyleName(String) @see #removeStyleName(String)

String getStylePrimaryName() {
 return getElementStylePrimaryName(getStyleElement());
}

MenuItem insertItem(MenuItem item, int beforeIndex) #

Adds a menu item to the bar at a specific index.

@param item the item to be inserted @param beforeIndex the index where the item should be inserted @return the {@link MenuItem} object @throws IndexOutOfBoundsException if <code>beforeIndex</code> is out of

      range
MenuItem insertItem(MenuItem item, int beforeIndex) {
 // Check the bounds
 if (beforeIndex < 0 || beforeIndex > _allItems.length) {
   throw new Exception("IndexOutOfBounds");
 }

 // Add to the list of items
//    _allItems.insertRange(beforeIndex, 1, item);
 _allItems.insert(beforeIndex, item);
 int itemsIndex = 0;
 for (int i = 0; i < beforeIndex; i++) {
   if (_allItems[i] is MenuItem) {
     itemsIndex++;
   }
 }
//    _items.insertRange(itemsIndex, 1, item);
 _items.insert(itemsIndex, item);

 // Setup the menu item
 _addItemElement(beforeIndex, item.getElement());
 item.setParentMenu(this);
 item.setSelectionStyle(false);
 updateSubmenuIcon(item);
 return item;
}

MenuItemSeparator insertSeparator(int beforeIndex, [MenuItemSeparator separator = null]) #

Adds a thin line to the {@link MenuBar} to separate sections of {@link MenuItem}s at the specified index.

@param separator the {@link MenuItemSeparator} to be inserted @param beforeIndex the index where the separator should be inserted @return the {@link MenuItemSeparator} object @throws IndexOutOfBoundsException if <code>beforeIndex</code> is out of

      range
MenuItemSeparator insertSeparator(int beforeIndex, [MenuItemSeparator separator = null]) {
 // Check the bounds
 if (beforeIndex < 0 || beforeIndex > _allItems.length) {
   throw new Exception("IndexOutOfBounds");
 }

 if (separator == null) {
   separator = new MenuItemSeparator();
 }

 if (_vertical) {
   _setItemColSpan(separator, 2);
 }
 _addItemElement(beforeIndex, separator.getElement());
 separator.setParentMenu(this);
//    _allItems.insertRange(beforeIndex, 1, separator);
 _allItems.insert(beforeIndex, separator);
 return separator;
}

bool isAnimationEnabled() #

Returns true if animations are enabled, false if not.

docs inherited from HasAnimation
bool isAnimationEnabled() {
 return _isAnimationEnabled;
}

bool isAttached() #

inherited from Widget

Returns whether or not the receiver is attached to the {@link com.google.gwt.dom.client.Document Document}'s {@link com.google.gwt.dom.client.BodyElement BodyElement}.

@return true if attached, false otherwise

bool isAttached() {
 return _attached;
}

bool isFocusOnHoverEnabled() #

Check whether or not this widget will steal keyboard focus when the mouse hovers over it.

@return true if enabled, false if disabled

bool isFocusOnHoverEnabled() {
 return _focusOnHover;
}

bool isOrWasAttached() #

inherited from Widget

Has this widget ever been attached?

@return true if this widget ever been attached to the DOM, false otherwise

bool isOrWasAttached() {
 return eventsToSink == -1;
}

void itemOver(MenuItem item, bool pFocus) #

void itemOver(MenuItem item, bool pFocus) {
 if (item == null) {
   // Don't clear selection if the currently selected item's menu is showing.
   if ((_selectedItem != null)
       && (_shownChildMenu == _selectedItem.getSubMenu())) {
     return;
   }
 }

 if (item != null && !item.enabled) {
   return;
 }

 // Style the item selected when the mouse enters.
 selectItem(item);
 if (pFocus && _focusOnHover) {
   focus();
 }

 // If child menus are being shown, or this menu is itself
 // a child menu, automatically show an item's child menu
 // when the mouse enters.
 if (item != null) {
   if ((_shownChildMenu != null) || (_parentMenu != null) || _autoOpen) {
     doItemAction(item, false, _focusOnHover);
   }
 }
}

void moveSelectionDown() #

Moves the menu selection down to the next item. If there is no selection, selects the first item. If there are no items at all, does nothing.

void moveSelectionDown() {
 if (_selectFirstItemIfNoneSelected()) {
   return;
 }

 if (_vertical) {
   _selectNextItem();
 } else {
   if (_selectedItem.getSubMenu() != null
       && !_selectedItem.getSubMenu().getItems().isEmpty
       && (_shownChildMenu == null || _shownChildMenu.getSelectedItem() == null)) {
     if (_shownChildMenu == null) {
       doItemAction(_selectedItem, false, true);
     }
     _selectedItem.getSubMenu().focus();
   } else if (_parentMenu != null) {
     if (_parentMenu._vertical) {
       _parentMenu._selectNextItem();
     } else {
       _parentMenu.moveSelectionDown();
     }
   }
 }
}

void moveSelectionUp() #

Moves the menu selection up to the previous item. If there is no selection, selects the first item. If there are no items at all, does nothing.

void moveSelectionUp() {
 if (_selectFirstItemIfNoneSelected()) {
   return;
 }

 if ((_shownChildMenu == null) && _vertical) {
   _selectPrevItem();
 } else if ((_parentMenu != null) && _parentMenu._vertical) {
   _parentMenu._selectPrevItem();
 } else {
   _close(true);
 }
}

void onAttach() #

inherited from Widget

This method is called when a widget is attached to the browser's document. To receive notification after a Widget has been added to the document, override the {@link #onLoad} method or use {@link #addAttachHandler}.

It is strongly recommended that you override {@link #onLoad()} or {@link #doAttachChildren()} instead of this method to avoid inconsistencies between logical and physical attachment states.

Subclasses that override this method must call super.onAttach() to ensure that the Widget has been attached to its underlying Element.

@throws IllegalStateException if this widget is already attached @see #onLoad() @see #doAttachChildren()

void onAttach() {
 if (isAttached()) {
   throw new Exception("Should only call onAttach when the widget is detached from the browser's document");
 }

 _attached = true;

 // Event hookup code
 Dom.setEventListener(getElement(), this);
 int bitsToAdd = eventsToSink;
 eventsToSink = -1;
 if (bitsToAdd > 0) {
   sinkEvents(bitsToAdd);
 }
 doAttachChildren();

 // onLoad() gets called only *after* all of the children are attached and
 // the attached flag is set. This allows widgets to be notified when they
 // are fully attached, and panels when all of their children are attached.
 onLoad();
 AttachEvent.fire(this, true);
}

void onBrowserEvent(Event event) #

Fired whenever a browser event is received.

@param event the event received

TODO

docs inherited from Widget
void onBrowserEvent(dart_html.Event event) {
 MenuItem item = _findItem(event.target);
 switch (Dom.eventGetType(event)) {
   case IEvent.ONCLICK:
     FocusPanel.impl.focus(getElement());
     // Fire an item's command when the user clicks on it.
     if (item != null) {
       doItemAction(item, true, true);
     }
     break;

   case IEvent.ONMOUSEOVER:
     if (item != null) {
       itemOver(item, true);
     }
     break;

   case IEvent.ONMOUSEOUT:
     if (item != null) {
       itemOver(null, true);
     }
     break;

   case IEvent.ONFOCUS:
     _selectFirstItemIfNoneSelected();
     break;

   case IEvent.ONKEYDOWN:
     dart_html.KeyboardEvent kEvent = event as dart_html.KeyboardEvent;
     int keyCode = kEvent.keyCode;
     switch (keyCode) {
       case KeyCodes.KEY_LEFT:
         if (LocaleInfo.getCurrentLocale().isRTL()) {
           _moveToNextItem();
         } else {
           _moveToPrevItem();
         }
         _eatEvent(event);
         break;
       case KeyCodes.KEY_RIGHT:
         if (LocaleInfo.getCurrentLocale().isRTL()) {
           _moveToPrevItem();
         } else {
           _moveToNextItem();
         }
         _eatEvent(event);
         break;
       case KeyCodes.KEY_UP:
         moveSelectionUp();
         _eatEvent(event);
         break;
       case KeyCodes.KEY_DOWN:
         moveSelectionDown();
         _eatEvent(event);
         break;
       case KeyCodes.KEY_ESCAPE:
         closeAllParentsAndChildren();
         _eatEvent(event);
         break;
       case KeyCodes.KEY_TAB:
         closeAllParentsAndChildren();
         break;
       case KeyCodes.KEY_ENTER:
         if (!_selectFirstItemIfNoneSelected()) {
           doItemAction(_selectedItem, true, true);
           _eatEvent(event);
         }
         break;
     } // end switch(keyCode)

     break;
 } // end switch (Dom.eventGetType(event))
 super.onBrowserEvent(event);
}

void onDetach() #

This method is called when a widget is detached from the browser's document. To receive notification before a Widget is removed from the document, override the {@link #onUnload} method or use {@link #addAttachHandler}.

It is strongly recommended that you override {@link #onUnload()} or {@link #doDetachChildren()} instead of this method to avoid inconsistencies between logical and physical attachment states.

Subclasses that override this method must call super.onDetach() to ensure that the Widget has been detached from the underlying Element. Failure to do so will result in application memory leaks due to circular references between DOM Elements and JavaScript objects.

@throws IllegalStateException if this widget is already detached @see #onUnload() @see #doDetachChildren()

docs inherited from Widget
void onDetach() {
 // When the menu is detached, make sure to close all of its children.
 if (_popup != null) {
   _popup.hide();
 }

 super.onDetach();
}

void onLoad() #

inherited from Widget

This method is called immediately after a widget becomes attached to the browser's document.

void onLoad() {
}

void onUnload() #

inherited from Widget

This method is called immediately before a widget will be detached from the browser's document.

void onUnload() {
}

void removeFromParent() #

inherited from Widget

Removes this widget from its parent widget, if one exists.

If it has no parent, this method does nothing. If it is a "root" widget (meaning it's been added to the detach list via {@link RootPanel#detachOnWindowClose(Widget)}), it will be removed from the detached immediately. This makes it possible for Composites and Panels to adopt root widgets.

@throws IllegalStateException if this widget's parent does not support

      removal (e.g. {@link Composite})
void removeFromParent() {
 if (_parent == null) {
   // If the widget had no parent, check to see if it was in the detach list
   // and remove it if necessary.
   if (RootPanel.isInDetachList(this)) {
     RootPanel.detachNow(this);
   }
 } else if (_parent is HasWidgets) {
   (_parent as HasWidgets).remove(this);
 } else if (_parent != null) {
   throw new Exception("This widget's parent does not implement HasWidgets");
 }
}

void removeItem(MenuItem item) #

Closes the menu bar.

@deprecated Use {@link #addCloseHandler(CloseHandler)} instead

Removes the specified menu item from the bar.

@param item the item to be removed

void removeItem(MenuItem item) {
 // Unselect if the item is currently selected
 if (_selectedItem == item) {
   selectItem(null);
 }

 if (_removeItemElement(item)) {
   _setItemColSpan(item, 1);
   _items.remove(item);
   item.setParentMenu(null);
 }
}

void removeSeparator(MenuItemSeparator separator) #

Removes the specified {@link MenuItemSeparator} from the bar.

@param separator the separator to be removed

void removeSeparator(MenuItemSeparator separator) {
 if (_removeItemElement(separator)) {
   separator.setParentMenu(null);
 }
}

void removeStyleDependentName(String styleSuffix) #

inherited from UiObject

Removes a dependent style name by specifying the style name's suffix.

@param styleSuffix the suffix of the dependent style to be removed @see #setStylePrimaryName(Element, String) @see #addStyleDependentName(String) @see #setStyleDependentName(String, boolean)

void removeStyleDependentName(String styleSuffix) {
 setStyleDependentName(styleSuffix, false);
}

void removeStyleName(String style) #

inherited from UiObject

Removes a style name. This method is typically used to remove secondary style names, but it can be used to remove primary stylenames as well. That use is not recommended.

@param style the secondary style name to be removed @see #addStyleName(String) @see #setStyleName(String, boolean)

void removeStyleName(String style) {
 setStyleName(style, false);
}

void replaceElement(Element elem) #

inherited from Widget

Replaces this object's browser element.

This method exists only to support a specific use-case in Image, and should not be used by other classes.

@param elem the object's new element

void replaceElement(dart_html.Element elem) {
 if (isAttached()) {
   // Remove old event listener to avoid leaking. onDetach will not do this
   // for us, because it is only called when the widget itself is detached
   // from the document.
   Dom.setEventListener(getElement(), null);
 }

 super.replaceElement(elem);

 if (isAttached()) {
   // Hook the event listener back up on the new element. onAttach will not
   // do this for us, because it is only called when the widget itself is
   // attached to the document.
   Dom.setEventListener(getElement(), this);
 }
}

void selectItem(MenuItem item) #

Select the given MenuItem, which must be a direct child of this MenuBar.

@param item the MenuItem to select, or null to clear selection

void selectItem(MenuItem item) {
 assert (item == null || item.getParentMenu() == this);

 if (item == _selectedItem) {
   return;
 }

 if (_selectedItem != null) {
   _selectedItem.setSelectionStyle(false);
   // Set the style of the submenu indicator
   if (_vertical) {
     dart_html.Element tr = _selectedItem.getElement().parent;
     if (Dom.getChildCount(tr) == 2) {
       dart_html.Element td = Dom.getChild(tr, 1);
       UiObject.manageElementStyleName(td, "subMenuIcon-selected", false);
     }
   }
 }

 if (item != null) {
   item.setSelectionStyle(true);

   // Set the style of the submenu indicator
   if (_vertical) {
     dart_html.Element tr = item.getElement().parent;
     if (tr.children.length == 2) {
       dart_html.Element td = tr.children[1];
       UiObject.manageElementStyleName(td, "subMenuIcon-selected", true);
     }
   }

//      Roles.getMenubarRole().setAriaActivedescendantProperty(getElement(),
//          IdReference.of(Dom.getElementAttribute(item.getElement(), "id")));
 }

 _selectedItem = item;
}

void setAnimationEnabled(bool enable) #

Enable or disable animations.

@param enable true to enable, false to disable

docs inherited from HasAnimation
void setAnimationEnabled(bool enable) {
 _isAnimationEnabled = enable;
}

void setAutoOpen(bool autoOpen) #

Sets whether this menu bar's child menus will open when the mouse is moved over it.

@param autoOpen <code>true</code> to cause child menus to auto-open

void setAutoOpen(bool autoOpen) {
 this._autoOpen = autoOpen;
}

void setElement(Element elem) #

inherited from UiObject

Sets this object's browser element. UIObject subclasses must call this method before attempting to call any other methods, and it may only be called once.

@param elem the object's element

void setElement(dart_html.Element elem) {
 assert (_element == null);
 this._element = elem;
}

void setFocusOnHoverEnabled(bool enabled) #

Enable or disable auto focus when the mouse hovers over the MenuBar. This allows the MenuBar to respond to keyboard events without the user having to click on it, but it will steal focus from other elements on the page. Enabled by default.

@param enabled true to enable, false to disable

void setFocusOnHoverEnabled(bool enabled) {
 _focusOnHover = enabled;
}

void setHeight(String height) #

inherited from UiObject

Sets the object's height. This height does not include decorations such as border, margin, and padding.

@param height the object's new height, in CSS units (e.g. "10px", "1em")

void setHeight(String height) {
 // This exists to deal with an inconsistency in IE's implementation where
 // it won't accept negative numbers in length measurements
 assert (extractLengthValue(height.trim().toLowerCase()) >= 0); // : "CSS heights should not be negative";
 Dom.setStyleAttribute(getElement(), "height", height);
}

void setLayoutData(Object value) #

inherited from Widget

Sets the panel-defined layout data associated with this widget. Only the panel that currently contains a widget should ever set this value. It serves as a place to store layout bookkeeping data associated with a widget.

@param layoutData the widget's layout data

void setLayoutData(Object value) {
 this._layoutData = value;
}

void setParent(Widget parent) #

inherited from Widget

Sets this widget's parent. This method should only be called by {@link Panel} and {@link Composite}.

@param parent the widget's new parent @throws IllegalStateException if <code>parent</code> is non-null and the

      widget already has a parent
void setParent(Widget parent) {
 Widget oldParent = this._parent;
 if (parent == null) {
   try {
     if (oldParent != null && oldParent.isAttached()) {
       onDetach();
       assert (!isAttached()); // : "Failure of " + this.getClass().getName() + " to call super.onDetach()";
     }
   } finally {
     // Put this in a finally in case onDetach throws an exception.
     this._parent = null;
   }
 } else {
   if (oldParent != null) {
     throw new Exception("Cannot set a new parent without first clearing the old parent");
   }
   this._parent = parent;
   if (parent.isAttached()) {
     onAttach();
     assert (isAttached()); // : "Failure of " + this.getClass().getName() + " to call super.onAttach()";
   }
 }
}

void setPixelSize(int width, int height) #

inherited from UiObject

Sets the object's size, in pixels, not including decorations such as border, margin, and padding.

@param width the object's new width, in pixels @param height the object's new height, in pixels

void setPixelSize(int width, int height) {
 if (width >= 0) {
   setWidth(width.toString() + "px");
 }
 if (height >= 0) {
   setHeight(height.toString() + "px");
 }
}

void setSize(String width, String height) #

inherited from UiObject

Sets the object's size. This size does not include decorations such as border, margin, and padding.

@param width the object's new width, in CSS units (e.g. "10px", "1em") @param height the object's new height, in CSS units (e.g. "10px", "1em")

void setSize(String width, String height) {
 setWidth(width);
 setHeight(height);
}

void setStyleDependentName(String styleSuffix, bool add) #

inherited from UiObject

Adds or removes a dependent style name by specifying the style name's suffix. The actual form of the style name that is added is:

getStylePrimaryName() + '-' + styleSuffix

@param styleSuffix the suffix of the dependent style to be added or removed @param add <code>true</code> to add the given style, <code>false</code> to

     remove it

@see #setStylePrimaryName(Element, String) @see #addStyleDependentName(String) @see #setStyleName(String, boolean) @see #removeStyleDependentName(String)

void setStyleDependentName(String styleSuffix, bool add) {
 setStyleName(getStylePrimaryName() + '-' + styleSuffix, add);
}

void setStyleName(String style, bool add) #

inherited from UiObject

Adds or removes a style name. This method is typically used to remove secondary style names, but it can be used to remove primary stylenames as well. That use is not recommended.

@param style the style name to be added or removed @param add <code>true</code> to add the given style, <code>false</code> to

     remove it

@see #addStyleName(String) @see #removeStyleName(String)

void setStyleName(String style, bool add) {
 manageElementStyleName(getStyleElement(), style, add);
}

void setStylePrimaryName(String style) #

inherited from UiObject

Sets the object's primary style name and updates all dependent style names.

@param style the new primary style name @see #addStyleName(String) @see #removeStyleName(String)

void setStylePrimaryName(String style) {
 setElementStylePrimaryName(getStyleElement(), style);
}

void setWidth(String width) #

inherited from UiObject

Sets the object's width. This width does not include decorations such as border, margin, and padding.

@param width the object's new width, in CSS units (e.g. "10px", "1em")

void setWidth(String width) {
 // This exists to deal with an inconsistency in IE's implementation where
 // it won't accept negative numbers in length measurements
 assert (extractLengthValue(width.trim().toLowerCase()) >= 0); // : "CSS widths should not be negative";
 Dom.setStyleAttribute(getElement(), "width", width);
}

void sinkBitlessEvent(String eventTypeName) #

inherited from UiObject

Sinks a named event. Note that only {@link Widget widgets} may actually receive events, but can receive events from all objects contained within them.

@param eventTypeName name of the event to sink on this element @see com.google.gwt.user.client.Event

void sinkBitlessEvent(String eventTypeName) {
 Dom.sinkBitlessEvent(getElement(), eventTypeName);
}

void sinkEvents(int eventBitsToAdd) #

inherited from Widget

Overridden to defer the call to super.sinkEvents until the first time this widget is attached to the dom, as a performance enhancement. Subclasses wishing to customize sinkEvents can preserve this deferred sink behavior by putting their implementation behind a check of <code>isOrWasAttached()</code>:

{@literal @}Override
public void sinkEvents(int eventBitsToAdd) {
  if (isOrWasAttached()) {
    /{@literal *} customized sink code goes here {@literal *}/
  } else {
    super.sinkEvents(eventBitsToAdd);
 }
} 
void sinkEvents(int eventBitsToAdd) {
 if (isOrWasAttached()) {
   super.sinkEvents(eventsToSink);
 } else {
   eventsToSink |= eventBitsToAdd;
 }
}

String toString() #

inherited from UiObject

This method is overridden so that any object can be viewed in the debugger as an HTML snippet.

@return a string representation of the object

String toString() {
 if (_element == null) {
   return "(null handle)";
 }
 return getElement().toString();
}

void unsinkEvents(int eventBitsToRemove) #

inherited from UiObject

Removes a set of events from this object's event list.

@param eventBitsToRemove a bitfield representing the set of events to be

     removed from this element's event set

@see #sinkEvents @see com.google.gwt.user.client.Event

void unsinkEvents(int eventBitsToRemove) {
 Dom.sinkEvents(getElement(), Dom.getEventsSunk(getElement()) & (~eventBitsToRemove));
}

void updateSubmenuIcon(MenuItem item) #

Show or hide the icon used for items with a submenu.

@param item the item with or without a submenu

void updateSubmenuIcon(MenuItem item) {
 // The submenu icon only applies to vertical menus
 if (!_vertical) {
   return;
 }

 // Get the index of the MenuItem
 int idx = _allItems.indexOf(item);
 if (idx == -1) {
   return;
 }

 dart_html.Element container = _getItemContainerElement();
 dart_html.Element tr = Dom.getChild(container, idx);
 int tdCount = Dom.getChildCount(tr);
 MenuBar submenu = item.getSubMenu();
 if (submenu == null) {
   // Remove the submenu indicator
   if (tdCount == 2) {
     //Dom.removeChild(tr, Dom.getChild(tr, 1));
     Dom.getChild(tr, 1).remove();
   }
   _setItemColSpan(item, 2);
 } else if (tdCount == 1) {
   // Show the submenu indicator
   _setItemColSpan(item, 1);
   dart_html.Element td = new dart_html.TableCellElement();
   td.style.verticalAlign = "middle";
   td.append(_subMenuIcon.createElement());
   UiObject.setElementStyleName(td, "subMenuIcon");
   tr.append(td);
 }
}