package org.gwtoolbox.widget.client.menu;
import com.google.gwt.i18n.client.LocaleInfo;
import com.google.gwt.user.client.Command;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.ui.Accessibility;
import com.google.gwt.user.client.ui.HasHTML;
import com.google.gwt.user.client.ui.UIObject;
import com.google.gwt.user.client.ui.impl.FocusImpl;
/**
* @author Uri Boness
*/
public abstract class MenuItemBase extends UIObject implements HasHTML {
private static final String DEPENDENT_STYLENAME_SELECTED_ITEM = "selected";
private static final String STYLE_NAME = "MenuItemBase";
private static final String DISABLED_STYLE_NAME = "MenuItemBase-disabled";
private Command command;
private Menu parentMenu, subMenu;
private Element content;
private Element icon;
private String iconStyleName;
private boolean enabled = true;
private String key;
private String category;
/**
* Constructs a new menu item that fires a command when it is selected.
*
* @param text the item's text
* @param cmd the command to be fired when it is selected
*/
public MenuItemBase(String text, Command cmd) {
this(text, text, false, (Menu) null);
setCommand(cmd);
}
public MenuItemBase(String key, String text, Command cmd) {
this(key, text, false, (Menu) null);
setCommand(cmd);
}
/**
* Constructs a new menu item that fires a 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 when it is selected
*/
public MenuItemBase(String text, boolean asHTML, Command cmd) {
this(text, text, asHTML, (Menu) null);
setCommand(cmd);
}
public MenuItemBase(String key, String text, boolean asHTML, Command cmd) {
this(key, text, asHTML, (Menu) null);
setCommand(cmd);
}
/**
* Constructs a new menu item that cascades to a sub-menu when it is selected.
*
* @param text the item's text
* @param subMenu the sub-menu to be displayed when it is selected
*/
public MenuItemBase(String text, Menu subMenu) {
this(text, text, false, subMenu);
}
/**
* Constructs a new menu item that cascades to a sub-menu when it is selected.
*
* @param text the item's text
* @param asHTML <code>true</code> to treat the specified text as html
* @param subMenu the sub-menu to be displayed when it is selected
*/
public MenuItemBase(String key, String text, boolean asHTML, Menu subMenu) {
setElement(DOM.createTD());
DOM.setStyleAttribute(getElement(), "padding", "0");
markSelected(false);
this.key = key;
icon = DOM.createDiv();
getElement().appendChild(icon);
setStyleName(icon, "Icon");
content = DOM.createDiv();
getElement().appendChild(content);
setStyleName(content, "Content");
if (asHTML) {
setHTML(text);
} else {
setText(text);
}
setStylePrimaryName(STYLE_NAME);
DOM.setElementAttribute(getElement(), "id", DOM.createUniqueId());
// Add a11y role "menuitem"
Accessibility.setRole(getElement(), Accessibility.ROLE_MENUITEM);
if (subMenu != null) {
setSubMenu(subMenu);
}
}
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
/**
* Gets the command associated with this item.
*
* @return this item's command, or <code>null</code> if none exists
*/
public Command getCommand() {
return command;
}
public String getCategory() {
return category;
}
public void setCategory(String category) {
this.category = category;
}
/**
* Sets the command associated with this item.
*
* @param cmd the command to be associated with this item
*/
public void setCommand(Command cmd) {
command = cmd;
}
public String getIconStyleName() {
return iconStyleName;
}
protected void setIconStyleName(String iconStyleName) {
if (this.iconStyleName != null) {
setStyleName(icon, this.iconStyleName, false);
}
this.iconStyleName = iconStyleName;
if (iconStyleName != null) {
setStyleName(icon, iconStyleName, true);
}
}
public String getHTML() {
return DOM.getInnerHTML(content);
}
public void setHTML(String html) {
DOM.setInnerHTML(content, html);
}
public String getText() {
return DOM.getInnerText(content);
}
public void setText(String text) {
DOM.setInnerText(content, text);
}
public boolean isEnabled() {
return enabled;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
if (!enabled) {
setStylePrimaryName(DISABLED_STYLE_NAME);
} else {
setStylePrimaryName(STYLE_NAME);
}
}
/**
* Gets the sub-menu associated with this item.
*
* @return this item's sub-menu, or <code>null</code> if none exists
*/
public Menu getSubMenu() {
return subMenu;
}
/**
* Sets the sub-menu associated with this item.
*
* @param subMenu this item's new sub-menu
*/
public void setSubMenu(Menu subMenu) {
this.subMenu = subMenu;
// Change tab index from 0 to -1, because only the root menu is supposed to
// be in the tab order
FocusImpl.getFocusImplForPanel().setTabIndex(subMenu.getElement(), -1);
// Update a11y role "haspopup"
Accessibility.setState(this.getElement(), Accessibility.STATE_HASPOPUP, "true");
}
/**
* Gets the menu that contains this item.
*
* @return the parent menu, or <code>null</code> if none exists.
*/
public Menu getParentMenu() {
return parentMenu;
}
//================================================ Helper Methods ==================================================
void setParentMenu(Menu parentMenu) {
if (parentMenu == null) {
return;
}
this.parentMenu = parentMenu;
if (!parentMenu.isVertical()) {
setVisible(icon, false);
} else if (subMenu != null) {
Element indicator = DOM.createDiv();
DOM.setStyleAttribute(indicator, "fontSize", "0");
if (LocaleInfo.getCurrentLocale().isRTL()) {
setStyleName(indicator, "SubMenuIndicator-rtl");
getElement().insertBefore(indicator, content);
} else {
setStyleName(indicator, "SubMenuIndicator");
getElement().appendChild(indicator);
}
}
}
void markSelected(boolean selected) {
if (selected) {
addStyleDependentName(DEPENDENT_STYLENAME_SELECTED_ITEM);
} else {
removeStyleDependentName(DEPENDENT_STYLENAME_SELECTED_ITEM);
}
}
/**
* Also sets the Debug IDs of MenuItems in the submenu of this
* {@link MenuItemBase} if a submenu exists.
*
* @see com.google.gwt.user.client.ui.UIObject#onEnsureDebugId(String)
*/
@Override
protected void onEnsureDebugId(String baseID) {
super.onEnsureDebugId(baseID);
if (subMenu != null) {
subMenu.setMenuItemDebugIds(baseID);
}
}
}
|