
gxt-2.1.1-sources.com.extjs.gxt.ui.client.widget.menu.Menu Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of gxt Show documentation
Show all versions of gxt Show documentation
Rich Internet Application Framework for GWT
/*
* Ext GWT - Ext for GWT
* Copyright(c) 2007-2009, Ext JS, LLC.
* [email protected]
*
* http://extjs.com/license
*/
package com.extjs.gxt.ui.client.widget.menu;
import com.extjs.gxt.ui.client.GXT;
import com.extjs.gxt.ui.client.Style;
import com.extjs.gxt.ui.client.aria.FocusFrame;
import com.extjs.gxt.ui.client.core.El;
import com.extjs.gxt.ui.client.core.XDOM;
import com.extjs.gxt.ui.client.event.BaseEvent;
import com.extjs.gxt.ui.client.event.ClickRepeaterEvent;
import com.extjs.gxt.ui.client.event.ComponentEvent;
import com.extjs.gxt.ui.client.event.ContainerEvent;
import com.extjs.gxt.ui.client.event.Events;
import com.extjs.gxt.ui.client.event.Listener;
import com.extjs.gxt.ui.client.event.MenuEvent;
import com.extjs.gxt.ui.client.event.PreviewEvent;
import com.extjs.gxt.ui.client.util.BaseEventPreview;
import com.extjs.gxt.ui.client.util.ClickRepeater;
import com.extjs.gxt.ui.client.util.KeyNav;
import com.extjs.gxt.ui.client.util.Point;
import com.extjs.gxt.ui.client.widget.Component;
import com.extjs.gxt.ui.client.widget.Container;
import com.extjs.gxt.ui.client.widget.Layout;
import com.extjs.gxt.ui.client.widget.layout.MenuLayout;
import com.google.gwt.dom.client.NodeList;
import com.google.gwt.event.dom.client.KeyCodes;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.ui.Accessibility;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.Widget;
/**
* A menu component.
*
*
* - Events:
*
* - BeforeShow : MenuEvent(container)
* Fires before this menu is displayed. Listeners can cancel the action by
* calling {@link BaseEvent#setCancelled(boolean)}.
*
* - container : this
*
*
*
* - Show : MenuEvent(container)
* Fires after this menu is displayed.
*
* - container : this
*
*
*
* - BeforeHide : MenuEvent(container)
* Fired before the menu is hidden. Listeners can cancel the action by
* calling {@link BaseEvent#setCancelled(boolean)}.
*
* - container : this
*
*
*
* - Hide : MenuEvent(container)
* Fires after this menu is hidden.
*
* - container : this
*
*
*
* - BeforeAdd : MenuEvent(container, item, index)
* Fires before a item is added or inserted. Listeners can cancel the
* action by calling {@link BaseEvent#setCancelled(boolean)}.
*
* - container : this
* - item : the item being added
* - index : the index at which the item will be added
*
*
*
* - BeforeRemove : MenuEvent(container, item)
* Fires before a item is removed. Listeners can cancel the action by
* calling {@link BaseEvent#setCancelled(boolean)}.
*
* - container : this
* - item : the item being removed
*
*
*
* - Add : MenuEvent(container, item, index)
* Fires after a item has been added or inserted.
*
* - container : this
* - item : the item that was added
* - index : the index at which the item will be added
*
*
*
* - Remove : MenuEvent(container, item)
* Fires after a item has been removed.
*
* - container : this
* - item : the item being removed
*
*
*
*
*
* - Inherited Events:
* - BoxComponent Move
* - BoxComponent Resize
* - Component Enable
* - Component Disable
* - Component BeforeHide
* - Component Hide
* - Component BeforeShow
* - Component Show
* - Component Attach
* - Component Detach
* - Component BeforeRender
* - Component Render
* - Component BrowserEvent
* - Component BeforeStateRestore
* - Component StateRestore
* - Component BeforeStateSave
* - Component SaveState
*
*/
public class Menu extends Container {
protected KeyNav keyNav;
protected Item parentItem;
protected BaseEventPreview eventPreview;
protected boolean plain;
protected boolean showSeparator = true;
protected El ul;
private String subMenuAlign = "tl-tr?";
private String defaultAlign = "tl-bl?";
private int minWidth = 120;
private Item activeItem;
private boolean showing;
private boolean constrainViewport = true;
private boolean focusOnShow = true;
private int maxHeight = Style.DEFAULT;
private boolean enableScrolling = true;
private int scrollIncrement = 24;
private int scrollerHeight = 8;
private int activeMax;
/**
* Creates a new menu.
*/
public Menu() {
baseStyle = "x-menu";
shim = true;
monitorWindowResize = true;
setShadow(true);
setLayoutOnChange(true);
enableLayout = true;
setLayout(new MenuLayout());
eventPreview = new BaseEventPreview() {
@Override
protected boolean onAutoHide(PreviewEvent pe) {
return Menu.this.onAutoHide(pe);
}
@Override
protected void onPreviewKeyPress(PreviewEvent pe) {
super.onPreviewKeyPress(pe);
if (pe.getKeyCode() == KeyCodes.KEY_ESCAPE) {
hide(true);
}
}
};
}
/**
* Adds a item to the menu.
*
* @param item the new item
*/
@Override
public boolean add(Component item) {
return super.add(item);
}
/**
* Returns the default alignment.
*
* @return the default align
*/
public String getDefaultAlign() {
return defaultAlign;
}
@Override
public El getLayoutTarget() {
return ul;
}
public int getMaxHeight() {
return maxHeight;
}
/**
* Returns the menu's minimum width.
*
* @return the width
*/
public int getMinWidth() {
return minWidth;
}
/**
* Returns the menu's parent item.
*
* @return the parent item
*/
public Item getParentItem() {
return parentItem;
}
/**
* Returns the sub menu alignment.
*
* @return the alignment
*/
public String getSubMenuAlign() {
return subMenuAlign;
}
/**
* Hides the menu.
*/
public void hide() {
hide(false);
}
/**
* Hides this menu and optionally all parent menus
*
* @param deep true to close all parent menus
* @return this
*/
public Menu hide(boolean deep) {
if (showing) {
MenuEvent me = new MenuEvent(this);
if (fireEvent(Events.BeforeHide, me)) {
if (activeItem != null) {
activeItem.deactivate();
activeItem = null;
}
onHide();
RootPanel.get().remove(this);
eventPreview.remove();
showing = false;
hidden = true;
fireEvent(Events.Hide, me);
}
if (deep && parentItem != null) {
parentItem.parentMenu.hide(true);
}
}
return this;
}
/**
* Inserts an item into the menu.
*
* @param item the item to insert
* @param index the insert location
*/
@Override
public boolean insert(Component item, int index) {
if (item instanceof Item) {
((Item) item).parentMenu = this;
}
return super.insert(item, index);
}
/**
* Returns true if constrain to viewport is enabled.
*
* @return the constrain to viewport state
*/
public boolean isConstrainViewport() {
return constrainViewport;
}
public boolean isEnableScrolling() {
return enableScrolling;
}
public boolean isFocusOnShow() {
return focusOnShow;
}
@Override
public boolean isVisible() {
return showing;
}
@Override
public void onComponentEvent(ComponentEvent ce) {
super.onComponentEvent(ce);
switch (ce.getEventTypeInt()) {
case Event.ONCLICK:
onClick(ce);
break;
case Event.ONMOUSEOVER:
onMouseOver(ce);
break;
case Event.ONMOUSEOUT:
onMouseOut(ce);
break;
case Event.ONMOUSEWHEEL:
if (enableScrolling) {
scrollMenu(ce.getEvent().getMouseWheelVelocityY() < 0);
}
}
El t = ce.getTargetEl();
if (enableScrolling && t.is(".x-menu-scroller")) {
switch (ce.getEventTypeInt()) {
case Event.ONMOUSEOVER:
deactiveActiveItem();
onScrollerIn(t);
break;
case Event.ONMOUSEOUT:
onScrollerOut(t);
break;
}
}
}
/**
* Removes a item from the menu.
*
* @param item the menu to remove
*/
@Override
public boolean remove(Component item) {
return super.remove(item);
}
/**
* Sets the active item. The component must be of type Item
to be
* activated. All other types are ignored.
*
* @param c the component to set active
* @param autoExpand true to auto expand the item
*/
public void setActiveItem(Component c, boolean autoExpand) {
if (c instanceof Item) {
Item item = (Item) c;
if (item != activeItem) {
deactiveActiveItem();
this.activeItem = item;
item.activate(autoExpand);
item.el().scrollIntoView(ul.dom, false);
focus();
if (GXT.isAriaEnabled()) {
FocusFrame.get().frame(item);
Accessibility.setState(getElement(), "aria-activedescendant", item.getId());
}
} else if (autoExpand) {
item.expandMenu(autoExpand);
}
}
}
/**
* Sets whether the menu should be constrained to the viewport when shown.
* Only applies when using {@link #showAt(int, int)}.
*
* @param constrainViewport true to contrain
*/
public void setConstrainViewport(boolean constrainViewport) {
this.constrainViewport = constrainViewport;
}
/**
* Sets the default {@link El#alignTo} anchor position value for this menu
* relative to its element of origin (defaults to "tl-bl?").
*
* @param defaultAlign the default align
*/
public void setDefaultAlign(String defaultAlign) {
this.defaultAlign = defaultAlign;
}
public void setEnableScrolling(boolean enableScrolling) {
this.enableScrolling = enableScrolling;
}
public void setFocusOnShow(boolean focusOnShow) {
this.focusOnShow = focusOnShow;
}
public void setMaxHeight(int maxHeight) {
this.maxHeight = maxHeight;
}
/**
* Sets he minimum width of the menu in pixels (defaults to 120).
*
* @param minWidth the min width
*/
public void setMinWidth(int minWidth) {
this.minWidth = minWidth;
}
/**
* The {@link El#alignTo} anchor position value to use for submenus of this
* menu (defaults to "tl-tr-?").
*
* @param subMenuAlign the sub alignment
*/
public void setSubMenuAlign(String subMenuAlign) {
this.subMenuAlign = subMenuAlign;
}
/**
* Displays this menu relative to another element.
*
* @param elem the element to align to
* @param pos the {@link El#alignTo} anchor position to use in aligning to the
* element (defaults to defaultAlign)
*/
public void show(Element elem, String pos) {
show(elem, pos, new int[] {0, 0});
}
/**
* Displays this menu relative to another element.
*
* @param elem the element to align to
* @param pos the {@link El#alignTo} anchor position to use in aligning to the
* element (defaults to defaultAlign)
* @param offsets the menu align offsets
*/
public void show(Element elem, String pos, int[] offsets) {
MenuEvent me = new MenuEvent(this);
if (fireEvent(Events.BeforeShow, me)) {
RootPanel.get().add(this);
showing = true;
el().makePositionable(true);
onShow();
el().updateZIndex(0);
doAutoSize();
el().alignTo(elem, pos, offsets);
if (enableScrolling) {
constrainScroll(el().getY());
}
el().show();
eventPreview.add();
if (focusOnShow) {
focus();
}
fireEvent(Events.Show, me);
}
}
/**
* Displays this menu relative to the widget using the default alignment.
*
* @param widget the align widget
*/
public void show(Widget widget) {
show(widget.getElement(), defaultAlign);
}
/**
* Displays this menu at a specific xy position.
*
* @param x the x coordinate
* @param y the y coordinate
*/
public void showAt(int x, int y) {
MenuEvent me = new MenuEvent(this);
if (fireEvent(Events.BeforeShow, me)) {
RootPanel.get().add(this);
showing = true;
el().makePositionable(true);
onShow();
el().updateZIndex(0);
doAutoSize();
if (constrainViewport) {
Point p = el().adjustForConstraints(new Point(x, y));
x = p.x;
y = p.y;
}
setPagePosition(x + XDOM.getBodyScrollLeft(), y + XDOM.getBodyScrollTop());
if (enableScrolling) {
constrainScroll(y);
}
el().show();
eventPreview.add();
if (focusOnShow) {
focus();
}
fireEvent(Events.Show, me);
}
}
protected void constrainScroll(int y) {
int full = ul.setHeight("auto").getHeight();
int max = maxHeight != Style.DEFAULT ? maxHeight : (XDOM.getViewHeight(false) - y);
if (full > max && max > 0) {
activeMax = max - 10 - scrollerHeight * 2;
ul.setHeight(activeMax, true);
createScrollers();
} else {
ul.setHeight(full, true);
NodeList nodes = el().select(".x-menu-scroller");
for (int i = 0; i < nodes.getLength(); i++) {
fly(nodes.getItem(i)).hide();
}
}
ul.setScrollTop(0);
}
@Override
protected ComponentEvent createComponentEvent(Event event) {
return new MenuEvent(this);
}
@Override
protected ContainerEvent
© 2015 - 2025 Weber Informatics LLC | Privacy Policy