Added methods to insert MenuItems and MenuItemSeparators into MenuBars. Also fixed a MenuBar bug where the visible submenu of the previous MenuItem would remain open if the user highlights a MenuItem that does not have a visible submenu.
Patch by: jlabanca
Review by: jgw
Issue: 2301
git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@3624 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/user/src/com/google/gwt/user/client/ui/MenuBar.java b/user/src/com/google/gwt/user/client/ui/MenuBar.java
index 6f6957d..929fb47 100644
--- a/user/src/com/google/gwt/user/client/ui/MenuBar.java
+++ b/user/src/com/google/gwt/user/client/ui/MenuBar.java
@@ -185,13 +185,7 @@
* @return the {@link MenuItem} object
*/
public MenuItem addItem(MenuItem item) {
- addItemElement(item.getElement());
- item.setParentMenu(this);
- item.setSelectionStyle(false);
- items.add(item);
- allItems.add(item);
- updateSubmenuIcon(item);
- return item;
+ return insertItem(item, allItems.size());
}
/**
@@ -262,13 +256,7 @@
* @return the {@link MenuItemSeparator} object
*/
public MenuItemSeparator addSeparator(MenuItemSeparator separator) {
- if (vertical) {
- setItemColSpan(separator, 2);
- }
- addItemElement(separator.getElement());
- separator.setParentMenu(this);
- allItems.add(separator);
- return separator;
+ return insertSeparator(separator, allItems.size());
}
/**
@@ -308,6 +296,98 @@
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
+ */
+ public int getItemIndex(MenuItem item) {
+ return allItems.indexOf(item);
+ }
+
+ /**
+ * Get the index of a {@link MenuItemSerpator}.
+ *
+ * @return the index of the separator, or -1 if it is not contained by this
+ * MenuBar
+ */
+ public 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
+ */
+ public MenuItem insertItem(MenuItem item, int beforeIndex)
+ throws IndexOutOfBoundsException {
+ // Check the bounds
+ if (beforeIndex < 0 || beforeIndex > allItems.size()) {
+ throw new IndexOutOfBoundsException();
+ }
+
+ // Add to the list of items
+ allItems.add(beforeIndex, item);
+ int itemsIndex = 0;
+ for (int i = 0; i < beforeIndex; i++) {
+ if (allItems.get(i) instanceof MenuItem) {
+ itemsIndex++;
+ }
+ }
+ items.add(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 beforeIndex the index where the seperator should be inserted
+ * @return the {@link MenuItemSeparator} object
+ * @throws IndexOutOfBoundsException if <code>beforeIndex</code> is out of
+ * range
+ */
+ public MenuItemSeparator insertSeparator(int beforeIndex) {
+ return insertSeparator(new MenuItemSeparator(), beforeIndex);
+ }
+
+ /**
+ * 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 seperator should be inserted
+ * @return the {@link MenuItemSeparator} object
+ * @throws IndexOutOfBoundsException if <code>beforeIndex</code> is out of
+ * range
+ */
+ public MenuItemSeparator insertSeparator(MenuItemSeparator separator,
+ int beforeIndex) throws IndexOutOfBoundsException {
+ // Check the bounds
+ if (beforeIndex < 0 || beforeIndex > allItems.size()) {
+ throw new IndexOutOfBoundsException();
+ }
+
+ if (vertical) {
+ setItemColSpan(separator, 2);
+ }
+ addItemElement(beforeIndex, separator.getElement());
+ separator.setParentMenu(this);
+ allItems.add(beforeIndex, separator);
+ return separator;
+ }
+
public boolean isAnimationEnabled() {
return isAnimationEnabled;
}
@@ -551,6 +631,11 @@
shownChildMenu = null;
selectItem(null);
}
+ } else if (autoOpen && shownChildMenu != null) {
+ // close submenu
+ shownChildMenu.onHide();
+ popup.hide();
+ shownChildMenu = null;
}
}
}
@@ -671,17 +756,18 @@
* Physically add the td element of a {@link MenuItem} or
* {@link MenuItemSeparator} to this {@link MenuBar}.
*
+ * @param beforeIndex the index where the seperator should be inserted
* @param tdElem the td element to be added
*/
- private void addItemElement(Element tdElem) {
- Element tr;
+ private void addItemElement(int beforeIndex, Element tdElem) {
if (vertical) {
- tr = DOM.createTR();
- DOM.appendChild(body, tr);
+ Element tr = DOM.createTR();
+ DOM.insertChild(body, tr, beforeIndex);
+ DOM.appendChild(tr, tdElem);
} else {
- tr = DOM.getChild(body, 0);
+ Element tr = DOM.getChild(body, 0);
+ DOM.insertChild(tr, tdElem, beforeIndex);
}
- DOM.appendChild(tr, tdElem);
}
/**
diff --git a/user/test/com/google/gwt/user/client/ui/MenuBarTest.java b/user/test/com/google/gwt/user/client/ui/MenuBarTest.java
index ac9601a..21beb5b 100644
--- a/user/test/com/google/gwt/user/client/ui/MenuBarTest.java
+++ b/user/test/com/google/gwt/user/client/ui/MenuBarTest.java
@@ -92,6 +92,96 @@
assertNull(separator3.getParentMenu());
}
+ /**
+ * Test inserting {@link MenuItem}s and {@link MenuItemSeparator}s into the
+ * menu.
+ */
+ public void testInsertItems() {
+ // Create a menu bar
+ MenuBar bar = new MenuBar(true);
+
+ // Create a blank command
+ Command blankCommand = new Command() {
+ public void execute() {
+ }
+ };
+
+ // Insert first item
+ MenuItem item0 = bar.insertItem(new MenuItem("test", blankCommand), 0);
+ assertEquals(bar.getItemIndex(item0), 0);
+
+ // Insert item at 0
+ MenuItem item1 = bar.insertItem(new MenuItem("test", blankCommand), 0);
+ assertEquals(bar.getItemIndex(item1), 0);
+ assertEquals(bar.getItemIndex(item0), 1);
+
+ // Insert item at end
+ MenuItem item2 = bar.insertItem(new MenuItem("test", blankCommand), 2);
+ assertEquals(bar.getItemIndex(item1), 0);
+ assertEquals(bar.getItemIndex(item0), 1);
+ assertEquals(bar.getItemIndex(item2), 2);
+
+ // Insert a separator at 0
+ MenuItemSeparator separator0 = bar.insertSeparator(0);
+ assertEquals(bar.getSeparatorIndex(separator0), 0);
+ assertEquals(bar.getItemIndex(item1), 1);
+ assertEquals(bar.getItemIndex(item0), 2);
+ assertEquals(bar.getItemIndex(item2), 3);
+
+ // Insert a separator at end
+ MenuItemSeparator separator1 = bar.insertSeparator(4);
+ assertEquals(bar.getSeparatorIndex(separator0), 0);
+ assertEquals(bar.getItemIndex(item1), 1);
+ assertEquals(bar.getItemIndex(item0), 2);
+ assertEquals(bar.getItemIndex(item2), 3);
+ assertEquals(bar.getSeparatorIndex(separator1), 4);
+
+ // Insert a separator at middle
+ MenuItemSeparator separator2 = bar.insertSeparator(2);
+ assertEquals(bar.getSeparatorIndex(separator0), 0);
+ assertEquals(bar.getItemIndex(item1), 1);
+ assertEquals(bar.getSeparatorIndex(separator2), 2);
+ assertEquals(bar.getItemIndex(item0), 3);
+ assertEquals(bar.getItemIndex(item2), 4);
+ assertEquals(bar.getSeparatorIndex(separator1), 5);
+ }
+
+ /**
+ * Test inserting {@link MenuItem}s and {@link MenuItemSeparator}s into the
+ * menu at indexes that are out of bounds.
+ */
+ public void testInsertItemsOutOfBounds() {
+ // Create a menu bar
+ MenuBar bar = new MenuBar(true);
+
+ // Create a blank command
+ Command blankCommand = new Command() {
+ public void execute() {
+ }
+ };
+
+ // Add some items to the menu
+ for (int i = 0; i < 3; i++) {
+ bar.addItem("item", blankCommand);
+ }
+
+ // Add an item at a negative index
+ try {
+ bar.insertItem(new MenuItem("test", blankCommand), -1);
+ fail("Expected IndexOutOfBoundsException");
+ } catch (IndexOutOfBoundsException e) {
+ // Expected exception
+ }
+
+ // Add an item at a high index
+ try {
+ bar.insertItem(new MenuItem("test", blankCommand), 4);
+ fail("Expected IndexOutOfBoundsException");
+ } catch (IndexOutOfBoundsException e) {
+ // Expected exception
+ }
+ }
+
public void testDebugId() {
Command emptyCommand = new Command() {
public void execute() {
@@ -149,11 +239,9 @@
};
// Add some items
- MenuItem item0 = bar.addItem("item0", blankCommand);
MenuItem item1 = bar.addItem("item1", blankCommand);
MenuItem item2 = bar.addItem("item2", blankCommand);
MenuItem item3 = bar.addItem("item3", blankCommand);
- MenuItem item4 = bar.addItem("item4", blankCommand);
// Test setting the selected item
assertNull(bar.getSelectedItem());