123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510 |
- /*
- @ITMillApache2LicenseForJavaFiles@
- */
-
- package com.itmill.toolkit.terminal.gwt.client.ui;
-
- /*
- * Copyright 2007 Google Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not
- * use this file except in compliance with the License. You may obtain a copy of
- * the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-
- // COPIED HERE DUE package privates in GWT
- import java.util.ArrayList;
- import java.util.List;
-
- import com.google.gwt.user.client.Command;
- import com.google.gwt.user.client.DOM;
- import com.google.gwt.user.client.DeferredCommand;
- import com.google.gwt.user.client.Element;
- import com.google.gwt.user.client.Event;
- import com.google.gwt.user.client.ui.PopupListener;
- import com.google.gwt.user.client.ui.PopupPanel;
- import com.google.gwt.user.client.ui.Widget;
-
- /**
- * 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.user.client.Command} or
- * open a cascaded menu bar.
- *
- * <p>
- * <img class='gallery' src='MenuBar.png'/>
- * </p>
- *
- * <h3>CSS Style Rules</h3> <ul class='css'> <li>.gwt-MenuBar { the menu bar
- * itself }</li> <li>.gwt-MenuBar .gwt-MenuItem { menu items }</li> <li>
- * .gwt-MenuBar .gwt-MenuItem-selected { selected menu items }</li> </ul>
- *
- * <p>
- * <h3>Example</h3>
- * {@example com.google.gwt.examples.MenuBarExample}
- * </p>
- *
- * @deprecated
- */
- public class MenuBar extends Widget implements PopupListener {
-
- private final Element body;
- private final ArrayList items = new ArrayList();
- private MenuBar parentMenu;
- private PopupPanel popup;
- private MenuItem selectedItem;
- private MenuBar shownChildMenu;
- private final boolean vertical;
- private boolean autoOpen;
-
- /**
- * Creates an empty horizontal menu bar.
- */
- public MenuBar() {
- this(false);
- }
-
- /**
- * Creates an empty menu bar.
- *
- * @param vertical
- * <code>true</code> to orient the menu bar vertically
- */
- public MenuBar(boolean vertical) {
- super();
-
- final Element table = DOM.createTable();
- body = DOM.createTBody();
- DOM.appendChild(table, body);
-
- if (!vertical) {
- final Element tr = DOM.createTR();
- DOM.appendChild(body, tr);
- }
-
- this.vertical = vertical;
-
- final Element outer = DOM.createDiv();
- DOM.appendChild(outer, table);
- setElement(outer);
-
- sinkEvents(Event.ONCLICK | Event.ONMOUSEOVER | Event.ONMOUSEOUT);
- setStyleName("gwt-MenuBar");
- }
-
- /**
- * Adds a menu item to the bar.
- *
- * @param item
- * the item to be added
- */
- public void addItem(MenuItem item) {
- Element tr;
- if (vertical) {
- tr = DOM.createTR();
- DOM.appendChild(body, tr);
- } else {
- tr = DOM.getChild(body, 0);
- }
-
- DOM.appendChild(tr, item.getElement());
-
- item.setParentMenu(this);
- item.setSelectionStyle(false);
- items.add(item);
- }
-
- /**
- * 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
- */
- public MenuItem addItem(String text, boolean asHTML, Command cmd) {
- final MenuItem item = new MenuItem(text, asHTML, cmd);
- addItem(item);
- return item;
- }
-
- /**
- * Adds a menu item to the bar, that will open the specified menu when it is
- * selected.
- *
- * @param text
- * the item's text
- * @param asHTML
- * <code>true</code> to treat the specified text as html
- * @param popup
- * the menu to be cascaded from it
- * @return the {@link MenuItem} object created
- */
- public MenuItem addItem(String text, boolean asHTML, MenuBar popup) {
- final MenuItem item = new MenuItem(text, asHTML, popup);
- addItem(item);
- return item;
- }
-
- /**
- * Adds a menu item to the bar, that will fire the given command when it is
- * selected.
- *
- * @param text
- * the item's text
- * @param cmd
- * the command to be fired
- * @return the {@link MenuItem} object created
- */
- public MenuItem addItem(String text, Command cmd) {
- final MenuItem item = new MenuItem(text, cmd);
- addItem(item);
- return item;
- }
-
- /**
- * Adds a menu item to the bar, that will open the specified menu when it is
- * selected.
- *
- * @param text
- * the item's text
- * @param popup
- * the menu to be cascaded from it
- * @return the {@link MenuItem} object created
- */
- public MenuItem addItem(String text, MenuBar popup) {
- final MenuItem item = new MenuItem(text, popup);
- addItem(item);
- return item;
- }
-
- /**
- * Removes all menu items from this menu bar.
- */
- public void clearItems() {
- final Element container = getItemContainerElement();
- while (DOM.getChildCount(container) > 0) {
- DOM.removeChild(container, DOM.getChild(container, 0));
- }
- items.clear();
- }
-
- /**
- * 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
- */
- public boolean getAutoOpen() {
- return autoOpen;
- }
-
- public void onBrowserEvent(Event event) {
- super.onBrowserEvent(event);
-
- final MenuItem item = findItem(DOM.eventGetTarget(event));
- switch (DOM.eventGetType(event)) {
- case Event.ONCLICK: {
- // Fire an item's command when the user clicks on it.
- if (item != null) {
- doItemAction(item, true);
- }
- break;
- }
-
- case Event.ONMOUSEOVER: {
- if (item != null) {
- itemOver(item);
- }
- break;
- }
-
- case Event.ONMOUSEOUT: {
- if (item != null) {
- itemOver(null);
- }
- break;
- }
- }
- }
-
- public void onPopupClosed(PopupPanel sender, boolean 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();
- shownChildMenu = null;
- popup = null;
- }
-
- /**
- * Removes the specified menu item from the bar.
- *
- * @param item
- * the item to be removed
- */
- public void removeItem(MenuItem item) {
- final int idx = items.indexOf(item);
- if (idx == -1) {
- return;
- }
-
- final Element container = getItemContainerElement();
- DOM.removeChild(container, DOM.getChild(container, idx));
- items.remove(idx);
- }
-
- /**
- * 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
- */
- public void setAutoOpen(boolean autoOpen) {
- this.autoOpen = autoOpen;
- }
-
- /**
- * 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
- */
- protected List getItems() {
- return 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
- */
- protected MenuItem getSelectedItem() {
- return selectedItem;
- }
-
- protected 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() {
- MenuBar curMenu = this;
- while (curMenu != null) {
- curMenu.close();
-
- if ((curMenu.parentMenu == null) && (curMenu.selectedItem != null)) {
- curMenu.selectedItem.setSelectionStyle(false);
- curMenu.selectedItem = null;
- }
-
- curMenu = curMenu.parentMenu;
- }
- }
-
- /*
- * 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, boolean fireCommand) {
- // If the given item is already showing its menu, we're done.
- if ((shownChildMenu != null) && (item.getSubMenu() == shownChildMenu)) {
- return;
- }
-
- // If another item is showing its menu, then hide it.
- if (shownChildMenu != null) {
- shownChildMenu.onHide();
- popup.hide();
- }
-
- // If the item has no popup, optionally fire its command.
- if (item.getSubMenu() == null) {
- if (fireCommand) {
- // Close this menu and all of its parents.
- closeAllParents();
-
- // Fire the item's command.
- final Command cmd = item.getCommand();
- if (cmd != null) {
- DeferredCommand.addCommand(cmd);
- }
- }
- return;
- }
-
- // Ensure that the item is selected.
- selectItem(item);
-
- // 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 IToolkitOverlay(true) {
- {
- setWidget(item.getSubMenu());
- item.getSubMenu().onShow();
- }
-
- public boolean onEventPreview(Event event) {
- // Hook the popup panel's event preview. We use this to keep it
- // from
- // auto-hiding when the parent menu is clicked.
- switch (DOM.eventGetType(event)) {
- case Event.ONCLICK:
- // If the event target is part of the parent menu, suppress
- // the
- // event altogether.
- final Element target = DOM.eventGetTarget(event);
- final Element parentMenuElement = item.getParentMenu()
- .getElement();
- if (DOM.isOrHasChild(parentMenuElement, target)) {
- return false;
- }
- break;
- }
-
- return super.onEventPreview(event);
- }
- };
- popup.addPopupListener(this);
-
- if (vertical) {
- popup.setPopupPosition(item.getAbsoluteLeft()
- + item.getOffsetWidth(), item.getAbsoluteTop());
- } else {
- popup.setPopupPosition(item.getAbsoluteLeft(), item
- .getAbsoluteTop()
- + item.getOffsetHeight());
- }
-
- 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.show();
- }
-
- void itemOver(MenuItem item) {
- if (item == null) {
- // Don't clear selection if the currently selected item's menu is
- // showing.
- if ((selectedItem != null)
- && (shownChildMenu == selectedItem.getSubMenu())) {
- return;
- }
- }
-
- // Style the item selected when the mouse enters.
- selectItem(item);
-
- // 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);
- }
- }
- }
-
- void selectItem(MenuItem item) {
- if (item == selectedItem) {
- return;
- }
-
- if (selectedItem != null) {
- selectedItem.setSelectionStyle(false);
- }
-
- if (item != null) {
- item.setSelectionStyle(true);
- }
-
- selectedItem = item;
- }
-
- /**
- * Closes this menu (if it is a popup).
- */
- private void close() {
- if (parentMenu != null) {
- parentMenu.popup.hide();
- }
- }
-
- private MenuItem findItem(Element hItem) {
- for (int i = 0; i < items.size(); ++i) {
- final MenuItem item = (MenuItem) items.get(i);
- if (DOM.isOrHasChild(item.getElement(), hItem)) {
- return item;
- }
- }
-
- return null;
- }
-
- private Element getItemContainerElement() {
- if (vertical) {
- return body;
- } else {
- return DOM.getChild(body, 0);
- }
- }
-
- /*
- * This method is called when a menu bar is hidden, so that it can hide any
- * child popups that are currently being shown.
- */
- private void onHide() {
- if (shownChildMenu != null) {
- shownChildMenu.onHide();
- popup.hide();
- }
- }
-
- /*
- * This method is called when a menu bar is shown.
- */
- private void onShow() {
- // Select the first item when a menu is shown.
- if (items.size() > 0) {
- selectItem((MenuItem) items.get(0));
- }
- }
- }
|