001: /*
002: * Copyright 2000,2005 wingS development team.
003: *
004: * This file is part of wingS (http://wingsframework.org).
005: *
006: * wingS is free software; you can redistribute it and/or modify
007: * it under the terms of the GNU Lesser General Public License
008: * as published by the Free Software Foundation; either version 2.1
009: * of the License, or (at your option) any later version.
010: *
011: * Please see COPYING for the complete licence.
012: */
013: package org.wings.plaf.css;
014:
015: import org.wings.*;
016: import org.wings.io.Device;
017: import org.wings.plaf.Update;
018:
019: import java.awt.event.ActionListener;
020: import java.io.IOException;
021:
022: public final class MenuCG extends org.wings.plaf.css.MenuItemCG
023: implements org.wings.plaf.MenuCG {
024:
025: private static final long serialVersionUID = 1L;
026: private SResourceIcon arrowIcon = new SResourceIcon(
027: "org/wings/icons/MenuArrowRight.gif");
028: {
029: arrowIcon.getId();
030: }
031: private SResourceIcon arrowIconDisabled = new SResourceIcon(
032: "org/wings/icons/MenuArrowRight_Disabled.gif");
033: {
034: arrowIconDisabled.getId();
035: }
036:
037: public void installCG(final SComponent comp) {
038: super .installCG(comp);
039: }
040:
041: public void uninstallCG(final SComponent comp) {
042: }
043:
044: public void writePopup(final Device device, SMenu menu)
045: throws IOException {
046: if (menu.isEnabled()) {
047: device.print("<ul");
048: writeListAttributes(device, menu);
049: device.print(" class=\"SMenu\">");
050: for (int i = 0; i < menu.getMenuComponentCount(); i++) {
051: SComponent menuItem = menu.getMenuComponent(i);
052:
053: if (menuItem.isVisible()) {
054: device.print("\n <li class=\"");
055: if (menuItem instanceof SMenuItem) {
056: if (menuItem instanceof SMenu) {
057: device.print("SMenu");
058: } else {
059: device.print("SMenuItem");
060: }
061: if (!menuItem.isEnabled()) {
062: device.print("_Disabled");
063: }
064: device.print("\"");
065: printScriptHandlers(device, menuItem,
066: "onmouseover");
067: } else {
068: device.print("SMenuComponent\"");
069: }
070: device.print(">");
071: if (menuItem instanceof SMenuItem) {
072: device.print("<a href=\"#\"");
073: if (menuItem instanceof SMenu) {
074: if (menuItem.isEnabled()) {
075: device.print(" class=\"x sub\"");
076: } else {
077: device.print(" class=\"y sub\"");
078: }
079: }
080: if (menuItem.getListeners(ActionListener.class).length == 0) {
081: // Prevent an unnecessary server roundtrip in case we've
082: // got a menu or menu item with no actions attached to it.
083: if (menuItem instanceof SMenu) {
084: // In case we've got a (sub-) menu we render the same
085: // 'ScriptHandler' as we've already done on 'mouseover'.
086: // Actually this is not mandatory but it makes menues
087: // usable on devices where 'mouseover' isn't working,
088: // e.g. on this fancy e-board in our presentation room.
089: printScriptHandlers(device, menuItem,
090: "onclick");
091: }
092: } else {
093: Utils
094: .printClickability(
095: device,
096: menuItem,
097: ((SMenuItem) menuItem)
098: .getToggleSelectionParameter(),
099: menuItem.isEnabled(),
100: menuItem
101: .getShowAsFormComponent());
102: }
103: device.print(">");
104: }
105: menuItem.write(device);
106: if (menuItem instanceof SMenuItem) {
107: device.print("</a>");
108: }
109: if (menuItem.isEnabled()
110: && menuItem instanceof SMenu) {
111: menuItem.putClientProperty("popup",
112: Boolean.TRUE);
113: menuItem.write(device);
114: menuItem.putClientProperty("popup", null);
115: }
116: device.print("</li>");
117: }
118: }
119: device.print("</ul>");
120: }
121: device.print("\n");
122: }
123:
124: /* (non-Javadoc)
125: * @see org.wings.plaf.css.MenuCG#printScriptHandlers(org.wings.io.Device, org.wings.SComponent)
126: */
127: protected void printScriptHandlers(Device device,
128: SComponent menuItem, String handler) throws IOException {
129: // Print the script handlers if this is a SMenu OR if the parent has both, items and menus as childs.
130: // In the latter case a menu item might need to close an open submenu from a menu on the same level.
131: SMenuItem tMenuItem = (SMenuItem) menuItem;
132: if (!(tMenuItem instanceof SMenu)) {
133: if (tMenuItem.getParentMenu() != null
134: && tMenuItem.getParentMenu() instanceof SMenu) {
135: SMenu tParentMenu = (SMenu) tMenuItem.getParentMenu();
136: boolean tHasMenuChild = false;
137: boolean tHasMenuItemChild = false;
138: for (int tChildIndex = 0; tChildIndex < tParentMenu
139: .getMenuComponentCount(); tChildIndex++) {
140: SComponent tChild = tParentMenu
141: .getChild(tChildIndex);
142: if (tChild instanceof SMenu) {
143: tHasMenuChild = true;
144: } else {
145: tHasMenuItemChild = true;
146: }
147: }
148:
149: // No handler if not both types are present
150: if (!(tHasMenuChild && tHasMenuItemChild)) {
151: return;
152: }
153: }
154: }
155:
156: device.print(" ").print(handler).print(
157: "=\"wpm_openMenu(event, '");
158: device.print(tMenuItem.getName());
159: device.print("_pop','");
160: device.print(tMenuItem.getParentMenu().getName());
161: device.print("_pop');\"");
162: }
163:
164: /* (non-Javadoc)
165: * @see org.wings.plaf.css.MenuCG#writeListAttributes(org.wings.io.Device, org.wings.SMenu)
166: */
167: protected void writeListAttributes(Device device, SMenu menu)
168: throws IOException {
169: // calculate max length of children texts for sizing of layer
170: int maxLength = 0;
171: for (int i = 0; i < menu.getMenuComponentCount(); i++) {
172: if (!(menu.getMenuComponent(i) instanceof SMenuItem))
173: continue;
174: String text = ((SMenuItem) menu.getMenuComponent(i))
175: .getText();
176: if (text != null && text.length() > maxLength) {
177: maxLength = text.length();
178: if (menu.getMenuComponent(i) instanceof SMenu) {
179: maxLength = maxLength + 2; //graphics
180: }
181: }
182: }
183: device.print(" style=\"width:");
184: String stringLength = String.valueOf(maxLength
185: * menu.getWidthScaleFactor());
186: device.print(stringLength.substring(0, stringLength
187: .lastIndexOf('.') + 2));
188: device.print("em;\"");
189: device.print(" id=\"");
190: device.print(menu.getName());
191: device.print("_pop\"");
192: }
193:
194: public void writeInternal(final Device device, final SComponent _c)
195: throws IOException {
196: SMenu menu = (SMenu) _c;
197: if (menu.getClientProperty("popup") == null)
198: writeItemContent(device, menu);
199: else
200: writePopup(device, menu);
201: }
202:
203: public Update getComponentUpdate(SComponent component) {
204: SComponent parentMenu = ((SMenu) component).getParentMenu();
205: if (parentMenu != null)
206: return parentMenu.getCG().getComponentUpdate(parentMenu);
207: else
208: return new ComponentUpdate(this , component);
209: }
210:
211: protected static class ComponentUpdate extends
212: AbstractComponentCG.ComponentUpdate {
213:
214: public ComponentUpdate(AbstractComponentCG cg,
215: SComponent component) {
216: super (cg, component);
217: }
218:
219: @Override
220: public Handler getHandler() {
221: component.putClientProperty("popup", Boolean.TRUE);
222: UpdateHandler handler = (UpdateHandler) super .getHandler();
223: component.putClientProperty("popup", null);
224:
225: handler.setName("componentMenu");
226: handler.setParameter(0, component.getName() + "_pop");
227:
228: return handler;
229: }
230:
231: }
232:
233: }
|