You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

VMenuBarPaintable.java 6.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. /*
  2. @VaadinApache2LicenseForJavaFiles@
  3. */
  4. package com.vaadin.terminal.gwt.client.ui;
  5. import java.util.Iterator;
  6. import java.util.Stack;
  7. import com.google.gwt.core.client.GWT;
  8. import com.google.gwt.user.client.Command;
  9. import com.google.gwt.user.client.ui.Widget;
  10. import com.vaadin.terminal.gwt.client.ApplicationConnection;
  11. import com.vaadin.terminal.gwt.client.ComponentState;
  12. import com.vaadin.terminal.gwt.client.UIDL;
  13. import com.vaadin.terminal.gwt.client.Util;
  14. import com.vaadin.terminal.gwt.client.ui.VMenuBar.CustomMenuItem;
  15. public class VMenuBarPaintable extends VAbstractPaintableWidget {
  16. /**
  17. * This method must be implemented to update the client-side component from
  18. * UIDL data received from server.
  19. *
  20. * This method is called when the page is loaded for the first time, and
  21. * every time UI changes in the component are received from the server.
  22. */
  23. @Override
  24. public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
  25. // This call should be made first. Ensure correct implementation,
  26. // and let the containing layout manage caption, etc.
  27. super.updateFromUIDL(uidl, client);
  28. if (!isRealUpdate(uidl)) {
  29. return;
  30. }
  31. getWidgetForPaintable().htmlContentAllowed = uidl
  32. .hasAttribute(VMenuBar.HTML_CONTENT_ALLOWED);
  33. getWidgetForPaintable().openRootOnHover = uidl
  34. .getBooleanAttribute(VMenuBar.OPEN_ROOT_MENU_ON_HOWER);
  35. getWidgetForPaintable().enabled = !uidl.getBooleanAttribute("disabled");
  36. // For future connections
  37. getWidgetForPaintable().client = client;
  38. getWidgetForPaintable().uidlId = uidl.getId();
  39. // Empty the menu every time it receives new information
  40. if (!getWidgetForPaintable().getItems().isEmpty()) {
  41. getWidgetForPaintable().clearItems();
  42. }
  43. UIDL options = uidl.getChildUIDL(0);
  44. if (null != getState()
  45. && getState().getState()
  46. .containsKey(ComponentState.STATE_WIDTH)) {
  47. UIDL moreItemUIDL = options.getChildUIDL(0);
  48. StringBuffer itemHTML = new StringBuffer();
  49. if (moreItemUIDL.hasAttribute("icon")) {
  50. itemHTML.append("<img src=\""
  51. + Util.escapeAttribute(client
  52. .translateVaadinUri(moreItemUIDL
  53. .getStringAttribute("icon")))
  54. + "\" class=\"" + Icon.CLASSNAME + "\" alt=\"\" />");
  55. }
  56. String moreItemText = moreItemUIDL.getStringAttribute("text");
  57. if ("".equals(moreItemText)) {
  58. moreItemText = "&#x25BA;";
  59. }
  60. itemHTML.append(moreItemText);
  61. getWidgetForPaintable().moreItem = GWT.create(CustomMenuItem.class);
  62. getWidgetForPaintable().moreItem.setHTML(itemHTML.toString());
  63. getWidgetForPaintable().moreItem.setCommand(VMenuBar.emptyCommand);
  64. getWidgetForPaintable().collapsedRootItems = new VMenuBar(true,
  65. getWidgetForPaintable());
  66. getWidgetForPaintable().moreItem
  67. .setSubMenu(getWidgetForPaintable().collapsedRootItems);
  68. getWidgetForPaintable().moreItem.addStyleName(VMenuBar.CLASSNAME
  69. + "-more-menuitem");
  70. }
  71. UIDL uidlItems = uidl.getChildUIDL(1);
  72. Iterator<Object> itr = uidlItems.getChildIterator();
  73. Stack<Iterator<Object>> iteratorStack = new Stack<Iterator<Object>>();
  74. Stack<VMenuBar> menuStack = new Stack<VMenuBar>();
  75. VMenuBar currentMenu = getWidgetForPaintable();
  76. while (itr.hasNext()) {
  77. UIDL item = (UIDL) itr.next();
  78. CustomMenuItem currentItem = null;
  79. final int itemId = item.getIntAttribute("id");
  80. boolean itemHasCommand = item.hasAttribute("command");
  81. boolean itemIsCheckable = item
  82. .hasAttribute(VMenuBar.ATTRIBUTE_CHECKED);
  83. String itemHTML = getWidgetForPaintable().buildItemHTML(item);
  84. Command cmd = null;
  85. if (!item.hasAttribute("separator")) {
  86. if (itemHasCommand || itemIsCheckable) {
  87. // Construct a command that fires onMenuClick(int) with the
  88. // item's id-number
  89. cmd = new Command() {
  90. public void execute() {
  91. getWidgetForPaintable().hostReference
  92. .onMenuClick(itemId);
  93. }
  94. };
  95. }
  96. }
  97. currentItem = currentMenu.addItem(itemHTML.toString(), cmd);
  98. currentItem.updateFromUIDL(item, client);
  99. if (item.getChildCount() > 0) {
  100. menuStack.push(currentMenu);
  101. iteratorStack.push(itr);
  102. itr = item.getChildIterator();
  103. currentMenu = new VMenuBar(true, currentMenu);
  104. if (uidl.hasAttribute("style")) {
  105. for (String style : uidl.getStringAttribute("style").split(
  106. " ")) {
  107. currentMenu.addStyleDependentName(style);
  108. }
  109. }
  110. currentItem.setSubMenu(currentMenu);
  111. }
  112. while (!itr.hasNext() && !iteratorStack.empty()) {
  113. boolean hasCheckableItem = false;
  114. for (CustomMenuItem menuItem : currentMenu.getItems()) {
  115. hasCheckableItem = hasCheckableItem
  116. || menuItem.isCheckable();
  117. }
  118. if (hasCheckableItem) {
  119. currentMenu.addStyleDependentName("check-column");
  120. } else {
  121. currentMenu.removeStyleDependentName("check-column");
  122. }
  123. itr = iteratorStack.pop();
  124. currentMenu = menuStack.pop();
  125. }
  126. }// while
  127. getWidgetForPaintable().iLayout(false);
  128. }// updateFromUIDL
  129. @Override
  130. protected Widget createWidget() {
  131. return GWT.create(VMenuBar.class);
  132. }
  133. @Override
  134. public VMenuBar getWidgetForPaintable() {
  135. return (VMenuBar) super.getWidgetForPaintable();
  136. }
  137. }