| /* |
| * Copyright 2008 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. |
| */ |
| package com.google.gwt.user.client.ui; |
| |
| import com.google.gwt.aria.client.Roles; |
| import com.google.gwt.core.client.Scheduler.ScheduledCommand; |
| import com.google.gwt.safehtml.client.HasSafeHtml; |
| import com.google.gwt.safehtml.shared.SafeHtml; |
| import com.google.gwt.safehtml.shared.annotations.IsSafeHtml; |
| import com.google.gwt.safehtml.shared.annotations.SuppressIsSafeHtmlCastCheck; |
| import com.google.gwt.user.client.Command; |
| import com.google.gwt.user.client.DOM; |
| |
| /** |
| * An entry in a |
| * {@link com.google.gwt.user.client.ui.MenuBar}. Menu items can either fire a |
| * {@link com.google.gwt.core.client.Scheduler.ScheduledCommand} when they are clicked, or open a |
| * cascading sub-menu. |
| * |
| * Each menu item is assigned a unique DOM id in order to support ARIA. See |
| * {@link com.google.gwt.user.client.ui.Accessibility} for more information. |
| */ |
| public class MenuItem extends UIObject implements HasHTML, HasEnabled, HasSafeHtml { |
| |
| private static final String DEPENDENT_STYLENAME_SELECTED_ITEM = "selected"; |
| private static final String DEPENDENT_STYLENAME_DISABLED_ITEM = "disabled"; |
| |
| private ScheduledCommand command; |
| private MenuBar parentMenu, subMenu; |
| private boolean enabled = true; |
| |
| /** |
| * Constructs a new menu item that fires a command when it is selected. |
| * |
| * @param html the item's html text |
| */ |
| public MenuItem(SafeHtml html) { |
| this(html.asString(), true); |
| } |
| |
| /** |
| * Constructs a new menu item that fires a command when it is selected. |
| * |
| * @param html the item's text |
| * @param cmd the command to be fired when it is selected |
| */ |
| public MenuItem(SafeHtml html, ScheduledCommand cmd) { |
| this(html.asString(), true, cmd); |
| } |
| |
| /** |
| * Constructs a new menu item that cascades to a sub-menu when it is selected. |
| * |
| * @param html the item's text |
| * @param subMenu the sub-menu to be displayed when it is selected |
| */ |
| public MenuItem(SafeHtml html, MenuBar subMenu) { |
| this(html.asString(), true, subMenu); |
| } |
| |
| /** |
| * 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 MenuItem(@IsSafeHtml String text, boolean asHTML, ScheduledCommand cmd) { |
| this(text, asHTML); |
| setScheduledCommand(cmd); |
| } |
| |
| /** |
| * 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 MenuItem(@IsSafeHtml String text, boolean asHTML, MenuBar subMenu) { |
| this(text, asHTML); |
| setSubMenu(subMenu); |
| } |
| |
| /** |
| * 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 |
| */ |
| @SuppressIsSafeHtmlCastCheck |
| public MenuItem(String text, ScheduledCommand cmd) { |
| this(text, false); |
| setScheduledCommand(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 |
| */ |
| @SuppressIsSafeHtmlCastCheck |
| public MenuItem(String text, MenuBar subMenu) { |
| this(text, false); |
| setSubMenu(subMenu); |
| } |
| |
| MenuItem(@IsSafeHtml String text, boolean asHTML) { |
| setElement(DOM.createTD()); |
| setSelectionStyle(false); |
| |
| if (asHTML) { |
| setHTML(text); |
| } else { |
| setText(text); |
| } |
| setStyleName("gwt-MenuItem"); |
| |
| getElement().setAttribute("id", DOM.createUniqueId()); |
| // Add a11y role "menuitem" |
| Roles.getMenuitemRole().set(getElement()); |
| } |
| |
| /** |
| * Gets the command associated with this item. If a scheduled command |
| * is associated with this item a command that can be used to execute the |
| * scheduled command will be returned. |
| * |
| * @return the command |
| * @deprecated use {@link #getScheduledCommand()} instead |
| */ |
| @Deprecated |
| public Command getCommand() { |
| Command rtnVal; |
| |
| if (command == null) { |
| rtnVal = null; |
| } else if (command instanceof Command) { |
| rtnVal = (Command) command; |
| } else { |
| rtnVal = new Command() { |
| @Override |
| public void execute() { |
| if (command != null) { |
| command.execute(); |
| } |
| } |
| }; |
| } |
| |
| return rtnVal; |
| } |
| |
| @Override |
| public String getHTML() { |
| return getElement().getInnerHTML(); |
| } |
| |
| /** |
| * Gets the menu that contains this item. |
| * |
| * @return the parent menu, or <code>null</code> if none exists. |
| */ |
| public MenuBar getParentMenu() { |
| return parentMenu; |
| } |
| |
| /** |
| * Gets the scheduled command associated with this item. |
| * |
| * @return this item's scheduled command, or <code>null</code> if none exists |
| */ |
| public ScheduledCommand getScheduledCommand() { |
| return command; |
| } |
| |
| /** |
| * Gets the sub-menu associated with this item. |
| * |
| * @return this item's sub-menu, or <code>null</code> if none exists |
| */ |
| public MenuBar getSubMenu() { |
| return subMenu; |
| } |
| |
| @Override |
| public String getText() { |
| return getElement().getInnerText(); |
| } |
| |
| @Override |
| public boolean isEnabled() { |
| return enabled; |
| } |
| |
| /** |
| * Sets the command associated with this item. |
| * |
| * @param cmd the command to be associated with this item |
| * @deprecated use {@link #setScheduledCommand(ScheduledCommand)} instead |
| */ |
| @Deprecated |
| public void setCommand(Command cmd) { |
| command = cmd; |
| } |
| |
| @Override |
| public void setEnabled(boolean enabled) { |
| if (enabled) { |
| removeStyleDependentName(DEPENDENT_STYLENAME_DISABLED_ITEM); |
| } else { |
| addStyleDependentName(DEPENDENT_STYLENAME_DISABLED_ITEM); |
| } |
| this.enabled = enabled; |
| } |
| |
| @Override |
| public void setHTML(SafeHtml html) { |
| setHTML(html.asString()); |
| } |
| |
| @Override |
| public void setHTML(@IsSafeHtml String html) { |
| getElement().setInnerHTML(html); |
| } |
| |
| /** |
| * Sets the scheduled command associated with this item. |
| * |
| * @param cmd the scheduled command to be associated with this item |
| */ |
| public void setScheduledCommand(ScheduledCommand cmd) { |
| command = cmd; |
| } |
| |
| /** |
| * Sets the sub-menu associated with this item. |
| * |
| * @param subMenu this item's new sub-menu |
| */ |
| public void setSubMenu(MenuBar subMenu) { |
| this.subMenu = subMenu; |
| if (this.parentMenu != null) { |
| this.parentMenu.updateSubmenuIcon(this); |
| } |
| |
| if (subMenu != null) { |
| // Change tab index from 0 to -1, because only the root menu is supposed |
| // to be in the tab order |
| FocusPanel.impl.setTabIndex(subMenu.getElement(), -1); |
| |
| // Update a11y role "haspopup" |
| Roles.getMenuitemRole().setAriaHaspopupProperty(getElement(), true); |
| } else { |
| // Update a11y role "haspopup" |
| Roles.getMenuitemRole().setAriaHaspopupProperty(getElement(), false); |
| } |
| } |
| |
| @Override |
| public void setText(String text) { |
| getElement().setInnerText(text); |
| } |
| |
| /** |
| * Also sets the Debug IDs of MenuItems in the submenu of this |
| * {@link MenuItem} if a submenu exists. |
| * |
| * @see UIObject#onEnsureDebugId(String) |
| */ |
| @Override |
| protected void onEnsureDebugId(String baseID) { |
| super.onEnsureDebugId(baseID); |
| if (subMenu != null) { |
| subMenu.setMenuItemDebugIds(baseID); |
| } |
| } |
| |
| protected void setSelectionStyle(boolean selected) { |
| if (selected) { |
| addStyleDependentName(DEPENDENT_STYLENAME_SELECTED_ITEM); |
| } else { |
| removeStyleDependentName(DEPENDENT_STYLENAME_SELECTED_ITEM); |
| } |
| } |
| |
| void setParentMenu(MenuBar parentMenu) { |
| this.parentMenu = parentMenu; |
| } |
| } |