aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorRisto Yrjänä <risto.yrjana@itmill.com>2008-07-22 05:42:33 +0000
committerRisto Yrjänä <risto.yrjana@itmill.com>2008-07-22 05:42:33 +0000
commit1bec9086a719271baf2129358e02855a1d710c44 (patch)
tree5040f4c2c21320e2f4d7236c184cbf8f8b208667 /src
parent265ee675748e6af11ba7749814ecd34cae26d509 (diff)
downloadvaadin-framework-1bec9086a719271baf2129358e02855a1d710c44.tar.gz
vaadin-framework-1bec9086a719271baf2129358e02855a1d710c44.zip
Adds #1946 collapsing + submenu icons.
svn changeset:5109/svn branch:trunk
Diffstat (limited to 'src')
-rw-r--r--src/com/itmill/toolkit/terminal/gwt/client/ui/IMenuBar.java161
-rw-r--r--src/com/itmill/toolkit/ui/MenuBar.java149
2 files changed, 244 insertions, 66 deletions
diff --git a/src/com/itmill/toolkit/terminal/gwt/client/ui/IMenuBar.java b/src/com/itmill/toolkit/terminal/gwt/client/ui/IMenuBar.java
index 58d6f6fdfc..c943b91ea6 100644
--- a/src/com/itmill/toolkit/terminal/gwt/client/ui/IMenuBar.java
+++ b/src/com/itmill/toolkit/terminal/gwt/client/ui/IMenuBar.java
@@ -1,9 +1,11 @@
package com.itmill.toolkit.terminal.gwt.client.ui;
+import java.util.ArrayList;
import java.util.Iterator;
import java.util.Stack;
import com.google.gwt.user.client.Command;
+import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.ui.MenuBar;
import com.google.gwt.user.client.ui.MenuItem;
import com.itmill.toolkit.terminal.gwt.client.ApplicationConnection;
@@ -15,28 +17,44 @@ public class IMenuBar extends MenuBar implements Paintable {
/** Set the CSS class name to allow styling. */
public static final String CLASSNAME = "i-menubar";
- /** Component identifier in UIDL communications. */
+ /** For server connections **/
protected String uidlId;
-
- /** Reference to the server connection object. */
protected ApplicationConnection client;
- /** A host reference for the Command objects */
protected final IMenuBar hostReference = this;
+ protected static final boolean vertical = true;
+ protected String submenuIcon = null;
+ protected boolean collapseItems = true;
+
+ protected MenuItem moreItem = null;
+
+ // Construct an empty command to be used when the item has no command
+ // associated
+ protected static final Command emptyCommand = null;
/**
* The constructor should first call super() to initialize the component and
* then handle any initialization relevant to IT Mill Toolkit.
*/
public IMenuBar() {
- // The superclass has a lot of relevant initialization
+ // Create an empty horizontal menubar
super();
+ DOM.setStyleAttribute(this.getElement(), "white-space", "nowrap");
// This method call of the Paintable interface sets the component
// style name in DOM tree
setStyleName(CLASSNAME);
}
+ public IMenuBar(boolean vertical) {
+ super(vertical);
+ DOM.setStyleAttribute(this.getElement(), "white-space", "nowrap");
+
+ // This method call of the Paintable interface sets the component
+ // style name in DOM tree
+ setStyleName(CLASSNAME + "_submenu");
+ }
+
/**
* This method must be implemented to update the client-side component from
* UIDL data received from server.
@@ -51,11 +69,8 @@ public class IMenuBar extends MenuBar implements Paintable {
return;
}
- // Save reference to server connection object to be able to send
- // user interaction later
+ // For future connections
this.client = client;
-
- // Save the UIDL identifier for the component
uidlId = uidl.getId();
// Empty the menu every time it receives new information
@@ -63,26 +78,47 @@ public class IMenuBar extends MenuBar implements Paintable {
this.clearItems();
}
- /* Get tree received from server and actualize it in the GWT-MenuBar */
-
+ UIDL options = uidl.getChildUIDL(0);
// For GWT 1.5
- // this.setAnimationEnabled(uidl.getBooleanAttribute("animationEnabled"));
+ //this.setAnimationEnabled(options.getBooleanAttribute("animationEnabled"
+ // ))
+ // ;
+
+ if (options.hasAttribute("submenuIcon")) {
+ submenuIcon = client.translateToolkitUri(uidl.getChildUIDL(0)
+ .getStringAttribute("submenuIcon"));
+ } else {
+ submenuIcon = null;
+ }
+
+ collapseItems = options.getBooleanAttribute("collapseItems");
+
+ if (collapseItems) {
+ UIDL moreItemUIDL = options.getChildUIDL(0);
+ StringBuffer itemHTML = new StringBuffer();
+ itemHTML.append("<p>");
+ if (moreItemUIDL.hasAttribute("icon")) {
+ itemHTML.append("<img src=\""
+ + client.translateToolkitUri(moreItemUIDL
+ .getStringAttribute("icon"))
+ + "\" align=\"left\" />");
+ }
+ itemHTML.append(moreItemUIDL.getStringAttribute("text"));
+ itemHTML.append("</p>");
+ moreItem = new MenuItem(itemHTML.toString(), true, emptyCommand);
+ }
+
UIDL items = uidl.getChildUIDL(1);
Iterator itr = items.getChildIterator();
Stack iteratorStack = new Stack();
Stack menuStack = new Stack();
MenuBar currentMenu = this;
- // Construct an empty command to be used when the item has no command
- // associated
- Command emptyCommand = new Command() {
- public void execute() {
- }
- };
+ // int topLevelWidth = 0;
while (itr.hasNext()) {
UIDL item = (UIDL) itr.next();
- MenuItem menuItem = null; // For receiving the item
+ MenuItem currentItem = null; // For receiving the item
String itemText = item.getStringAttribute("text");
final int itemId = item.getIntAttribute("id");
@@ -90,46 +126,96 @@ public class IMenuBar extends MenuBar implements Paintable {
boolean itemHasCommand = item.getBooleanAttribute("command");
// Construct html from the text and the optional icon
- if (!item.hasAttribute("icon")) {
- itemText = "<p>" + itemText + "</p>";
- } else {
- itemText = "<p>"
- + "<img src=\""
+ StringBuffer itemHTML = new StringBuffer();
+
+ itemHTML.append("<p>");
+
+ if (item.hasAttribute("icon")) {
+ itemHTML.append("<img src=\""
+ client.translateToolkitUri(item
- .getStringAttribute("icon")) + "\"</img>"
- + itemText + "</p>";
+ .getStringAttribute("icon"))
+ + "\" align=\"left\" />");
}
- // Check if we need to attach a command to this item
+ itemHTML.append(itemText);
+
+ if (currentMenu != this && item.getChildCount() > 0
+ && submenuIcon != null) {
+ itemHTML.append("<img src=\"" + submenuIcon
+ + "\" align=\"right\" />");
+ }
+
+ itemHTML.append("</p>");
+
+ Command cmd = null;
+
+ // Check if we need to create a command to this item
if (itemHasCommand) {
// Construct a command that fires onMenuClick(int) with the
// item's id-number
- Command normalCommand = new Command() {
+ cmd = new Command() {
public void execute() {
hostReference.onMenuClick(itemId);
}
};
-
- menuItem = currentMenu.addItem(itemText, true, normalCommand);
-
- } else {
- menuItem = currentMenu.addItem(itemText, true, emptyCommand);
}
+ currentItem = currentMenu.addItem(itemHTML.toString(), true, cmd);
+
if (item.getChildCount() > 0) {
menuStack.push(currentMenu);
iteratorStack.push(itr);
itr = item.getChildIterator();
- currentMenu = new MenuBar(true);
- menuItem.setSubMenu(currentMenu);
+ currentMenu = new IMenuBar(vertical);
+ currentItem.setSubMenu(currentMenu);
}
- if (!itr.hasNext() && !iteratorStack.empty()) {
+ while (!itr.hasNext() && !iteratorStack.empty()) {
itr = (Iterator) iteratorStack.pop();
currentMenu = (MenuBar) menuStack.pop();
}
}// while
+ // we might need to collapse the top-level menu
+ if (collapseItems) {
+ int topLevelWidth = 0;
+
+ int ourWidth = this.getOffsetWidth();
+
+ int i = 0;
+ for (; i < getItems().size() && topLevelWidth < ourWidth; i++) {
+ MenuItem item = (MenuItem) getItems().get(i);
+ topLevelWidth += item.getOffsetWidth();
+ }
+
+ if (topLevelWidth > this.getOffsetWidth()) {
+ ArrayList toBeCollapsed = new ArrayList();
+ MenuBar collapsed = new IMenuBar(vertical);
+ for (int j = i - 2; j < getItems().size(); j++) {
+ toBeCollapsed.add(getItems().get(j));
+ }
+
+ for (int j = 0; j < toBeCollapsed.size(); j++) {
+ MenuItem item = (MenuItem) toBeCollapsed.get(j);
+ removeItem(item);
+
+ // it's ugly, but we have to insert the submenu icon
+ if (item.getSubMenu() != null && submenuIcon != null) {
+ String itemHTML = item.getHTML();
+ StringBuffer itemText = new StringBuffer(itemHTML
+ .substring(0, itemHTML.length() - 4));
+ itemText.append("<img src=\"" + submenuIcon
+ + "\" align=\"right\" /></p>");
+ item.setHTML(itemText.toString());
+ }
+
+ collapsed.addItem(item);
+ }
+
+ moreItem.setSubMenu(collapsed);
+ addItem(moreItem);
+ }
+ }
}// updateFromUIDL
/**
@@ -137,7 +223,7 @@ public class IMenuBar extends MenuBar implements Paintable {
* information to the server
*
* @param clickedItemId
- * id of the item that was clicked
+ * id of the item that was clicked
*/
public void onMenuClick(int clickedItemId) {
// Updating the state to the server can not be done before
@@ -149,4 +235,5 @@ public class IMenuBar extends MenuBar implements Paintable {
client.updateVariable(uidlId, "clickedId", clickedItemId, true);
}
}
+
}// class IMenuBar
diff --git a/src/com/itmill/toolkit/ui/MenuBar.java b/src/com/itmill/toolkit/ui/MenuBar.java
index 6428bcca7e..0b137d7484 100644
--- a/src/com/itmill/toolkit/ui/MenuBar.java
+++ b/src/com/itmill/toolkit/ui/MenuBar.java
@@ -24,6 +24,9 @@ public class MenuBar extends AbstractComponent {
private static int numberOfItems = 0;
private boolean animationEnabled;
+ private boolean collapseItems;
+ private Resource submenuIcon;
+ private MenuItem moreItem;
/** Tag is the UIDL element name for client-server communications. */
public java.lang.String getTag() {
@@ -41,6 +44,22 @@ public class MenuBar extends AbstractComponent {
target.startTag("options");
target.addAttribute("animationEnabled", animationEnabled);
+
+ if (submenuIcon != null) {
+ target.addAttribute("submenuIcon", submenuIcon);
+ }
+
+ target.addAttribute("collapseItems", collapseItems);
+
+ if (collapseItems) {
+ target.startTag("moreItem");
+ target.addAttribute("text", moreItem.getText());
+ if (moreItem.getIcon() != null) {
+ target.addAttribute("icon", moreItem.getIcon());
+ }
+ target.endTag("moreItem");
+ }
+
target.endTag("options");
target.startTag("items");
@@ -77,7 +96,8 @@ public class MenuBar extends AbstractComponent {
target.endTag("item"); // Item had no children, end description
}
- if (!itr.hasNext() && !iteratorStack.empty()) { // The end submenu
+ // The end submenu. More than one submenu may end at once.
+ while (!itr.hasNext() && !iteratorStack.empty()) {
itr = (Iterator) iteratorStack.pop();
target.endTag("item");
}
@@ -114,11 +134,12 @@ public class MenuBar extends AbstractComponent {
}
}
- }
+ }// while
+
// If we got the clicked item, launch the command.
if (found) {
tmpItem.getCommand().menuSelected(tmpItem);
- }// while
+ }
}// if
}// changeVariables
@@ -127,7 +148,9 @@ public class MenuBar extends AbstractComponent {
*/
public MenuBar() {
menuItems = new ArrayList();
- animationEnabled = false;
+ setAnimation(false);
+ setCollapse(true);
+ setMoreMenuItem(null);
}
/**
@@ -135,11 +158,11 @@ public class MenuBar extends AbstractComponent {
* caption must be given.
*
* @param caption
- * the text for the menu item
+ * the text for the menu item
* @param icon
- * the icon for the menu item
+ * the icon for the menu item
* @param command
- * the command for the menu item
+ * the command for the menu item
* @throws IllegalArgumentException
*/
public MenuBar.MenuItem addItem(String caption, Resource icon,
@@ -161,13 +184,13 @@ public class MenuBar extends AbstractComponent {
* caption must be given.
*
* @param caption
- * the text for the menu item
+ * the text for the menu item
* @param icon
- * the icon for the menu item
+ * the icon for the menu item
* @param command
- * the command for the menu item
+ * the command for the menu item
* @param itemToAddBefore
- * the item that will be after the new item
+ * the item that will be after the new item
* @throws IllegalArgumentException
*/
public MenuBar.MenuItem addItemBefore(String caption, Resource icon,
@@ -203,7 +226,7 @@ public class MenuBar extends AbstractComponent {
* Remove first occurrence the specified item from the main menu
*
* @param item
- * The item to be removed
+ * The item to be removed
*/
public void removeItem(MenuBar.MenuItem item) {
if (item != null) {
@@ -231,12 +254,13 @@ public class MenuBar extends AbstractComponent {
/**
* Enable or disable animated menubar appearance. Animation is disabled by
- * default.
+ * default. Currently does nothing.
*
* @param hasAnimation
*/
public void setAnimation(boolean animation) {
animationEnabled = animation;
+ requestRepaint();
}
/**
@@ -251,8 +275,75 @@ public class MenuBar extends AbstractComponent {
}
/**
- * This interface contains the layer for menu commands of the MenuBar class .
- * It's method will fire when the user clicks on the containing MenuItem.
+ * Set the icon to be used if a sub-menu has children. Defaults to null;
+ *
+ * @param icon
+ */
+ public void setSubmenuIcon(Resource icon) {
+ submenuIcon = icon;
+ requestRepaint();
+ }
+
+ /**
+ * Get the icon used for sub-menus. Returns null if no icon is set.
+ *
+ * @return
+ */
+ public Resource getSubmenuIcon() {
+ return submenuIcon;
+ }
+
+ /**
+ * Enable or disable collapsing top-level items. Top-level items will
+ * collapse to if there is not enough room for them. Items that don't fit
+ * will be placed under the "More" menu item.
+ *
+ * Collapsing is enabled by default.
+ *
+ * @param collapse
+ */
+ public void setCollapse(boolean collapse) {
+ collapseItems = collapse;
+ requestRepaint();
+ }
+
+ /**
+ * Collapsing is enabled by default.
+ *
+ * @return true if the top-level items will be collapsed
+ */
+ public boolean getCollapse() {
+ return collapseItems;
+ }
+
+ /**
+ * Set the item that is used when collapsing the top level menu. The item
+ * command will be ignored. If set to null, the default item with the "More"
+ * text will be used.
+ *
+ * @param item
+ */
+ public void setMoreMenuItem(MenuItem item) {
+ if (item != null) {
+ moreItem = item;
+ } else {
+ moreItem = new MenuItem("More", null, null);
+ }
+ requestRepaint();
+ }
+
+ /**
+ * Get the MenuItem used as the collapse menu item.
+ *
+ * @return
+ */
+ public MenuItem getMoreMenuItem() {
+ return moreItem;
+ }
+
+ /**
+ * This interface contains the layer for menu commands of the MenuBar class
+ * . It's method will fire when the user clicks on the containing MenuItem.
* The selected item is given as an argument.
*/
public interface Command {
@@ -280,9 +371,9 @@ public class MenuBar extends AbstractComponent {
* caption must be given.
*
* @param text
- * The text associated with the command
+ * The text associated with the command
* @param command
- * The command to be fired
+ * The command to be fired
* @throws IllegalArgumentException
*/
public MenuItem(String caption, Resource icon, MenuBar.Command command) {
@@ -309,11 +400,11 @@ public class MenuBar extends AbstractComponent {
* command can be null, but a caption must be given.
*
* @param caption
- * the text for the menu item
+ * the text for the menu item
* @param icon
- * the icon for the menu item
+ * the icon for the menu item
* @param command
- * the command for the menu item
+ * the command for the menu item
*/
public MenuBar.MenuItem addItem(String caption, Resource icon,
MenuBar.Command command) {
@@ -342,13 +433,13 @@ public class MenuBar extends AbstractComponent {
* but a caption must be given.
*
* @param caption
- * the text for the menu item
+ * the text for the menu item
* @param icon
- * the icon for the menu item
+ * the icon for the menu item
* @param command
- * the command for the menu item
+ * the command for the menu item
* @param itemToAddBefore
- * the item that will be after the new item
+ * the item that will be after the new item
*
*/
public MenuBar.MenuItem addItemBefore(String caption, Resource icon,
@@ -439,7 +530,7 @@ public class MenuBar extends AbstractComponent {
* Set the command for this item. Set null to remove.
*
* @param command
- * The MenuCommand of this item
+ * The MenuCommand of this item
*/
public void setCommand(MenuBar.Command command) {
itsCommand = command;
@@ -449,7 +540,7 @@ public class MenuBar extends AbstractComponent {
* Sets the icon. Set null to remove.
*
* @param icon
- * The icon for this item
+ * The icon for this item
*/
public void setIcon(Resource icon) {
itsIcon = icon;
@@ -460,7 +551,7 @@ public class MenuBar extends AbstractComponent {
* Set the text of this object.
*
* @param text
- * Text for this object
+ * Text for this object
*/
public void setText(java.lang.String text) {
if (text != null) {
@@ -473,7 +564,7 @@ public class MenuBar extends AbstractComponent {
* Remove the first occurrence of the item.
*
* @param item
- * The item to be removed
+ * The item to be removed
*/
public void removeChild(MenuBar.MenuItem item) {
if (item != null && itsChildren != null) {
@@ -500,7 +591,7 @@ public class MenuBar extends AbstractComponent {
* Set the parent of this item. This is called by the addItem method.
*
* @param parent
- * The parent item
+ * The parent item
*/
protected void setParent(MenuBar.MenuItem parent) {
itsParent = parent;