001: /*
002: * MyGWT Widget Library
003: * Copyright(c) 2007, MyGWT.
004: * licensing@mygwt.net
005: *
006: * http://mygwt.net/license
007: */
008: package net.mygwt.ui.client.widget;
009:
010: import java.util.ArrayList;
011: import java.util.HashMap;
012: import java.util.List;
013: import java.util.Map;
014:
015: import net.mygwt.ui.client.Events;
016: import net.mygwt.ui.client.MyDOM;
017: import net.mygwt.ui.client.event.BaseEvent;
018: import net.mygwt.ui.client.util.Format;
019: import net.mygwt.ui.client.util.Markup;
020: import net.mygwt.ui.client.util.Rectangle;
021:
022: import com.google.gwt.user.client.Command;
023: import com.google.gwt.user.client.DOM;
024: import com.google.gwt.user.client.DeferredCommand;
025: import com.google.gwt.user.client.Element;
026: import com.google.gwt.user.client.Event;
027: import com.google.gwt.user.client.ui.HasText;
028: import com.google.gwt.user.client.ui.HorizontalPanel;
029: import com.google.gwt.user.client.ui.Widget;
030: import com.google.gwt.user.client.ui.WidgetHelper;
031:
032: /**
033: * A horizontal component with 5 regions - left, mid left, center, mid right,
034: * and right. Provides support for a icon in the 2nd region, text in the 3rd,
035: * and widgets in the 4th. The first and last regions are used for styling such
036: * as the rounded corners of a tab item.
037: */
038: public class Item extends Component implements HasText {
039:
040: private static final Map elementCache = new HashMap();
041:
042: private static native Element clone(Element e, boolean deep) /*-{
043: return e.cloneNode(deep);
044: }-*/;
045:
046: // allow subclasses to overwrite if this component should sinkEvents
047: protected boolean sinkEvents = true;
048:
049: protected boolean overStyleEnabled = true;
050: protected String baseStyle, iconStyle;
051: protected Element midleftElem, midRightElem;
052: protected IconButton iconBtn;
053: protected List widgets;
054: protected HorizontalPanel widgetPanel;
055: protected String markup;
056: protected Element centerElem, textElem;
057:
058: private String text;
059: private boolean hovering;
060: private boolean selected;
061: private int spacing;
062:
063: /**
064: * Creates a new item.
065: */
066: public Item() {
067:
068: }
069:
070: /**
071: * Creates a new item.
072: *
073: * @param style the style information
074: * @param baseStyle the base style
075: */
076: public Item(int style, String baseStyle) {
077: super (style);
078: this .baseStyle = baseStyle;
079: }
080:
081: /**
082: * Creates a new item.
083: *
084: * @param baseStyle the base style
085: */
086: public Item(String baseStyle) {
087: this .baseStyle = baseStyle;
088: }
089:
090: /**
091: * Adds a widget to region 4.
092: *
093: * @param widget the widget to add
094: */
095: public void addWidget(Widget widget) {
096: if (widgets == null) {
097: widgets = new ArrayList();
098: }
099: widgets.add(widget);
100: if (rendered) {
101: if (widgetPanel == null) {
102: widgetPanel = new HorizontalPanel();
103: DOM.appendChild(midRightElem, widgetPanel.getElement());
104: if (isAttached()) {
105: WidgetHelper.doAttach(widgetPanel);
106: }
107: }
108: widgetPanel.add(widget);
109: }
110: }
111:
112: /**
113: * Returns the item's icon style.
114: *
115: * @return the icon style
116: */
117: public String getIconStyle() {
118: return iconStyle;
119: }
120:
121: /**
122: * Returns the item's text.
123: *
124: * @return the text
125: */
126: public String getText() {
127: return text;
128: }
129:
130: /**
131: * Returns a widget from region 4.
132: *
133: * @param index the index
134: * @return the widget
135: */
136: public Widget getWidget(int index) {
137: if (widgets != null) {
138: widgets.remove(index);
139: if (rendered) {
140: return widgetPanel.getWidget(index);
141: }
142: }
143: return null;
144: }
145:
146: /**
147: * Inserts a widget into region 4.
148: *
149: * @param widget the widget to insert
150: * @param index the insert index
151: */
152: public void insertWidget(Widget widget, int index) {
153: if (widgets == null) {
154: widgets = new ArrayList();
155: }
156: widgets.add(index, widget);
157: if (rendered) {
158: if (widgetPanel == null) {
159: widgetPanel = new HorizontalPanel();
160: DOM.appendChild(midRightElem, widgetPanel.getElement());
161: if (isAttached()) {
162: WidgetHelper.doAttach(widgetPanel);
163: }
164: }
165: widgetPanel.insert(widget, index);
166: }
167: }
168:
169: public void onBaseEvent(BaseEvent be) {
170: Rectangle rect = MyDOM.getBounds(getElement());
171: if (rect.contains(be.getClientX(), be.getClientY())) {
172: if (!hovering) {
173: hovering = true;
174: onMouseOver(be);
175: }
176: } else {
177: hovering = false;
178: onMouseOut(be);
179: }
180:
181: switch (be.type) {
182: case Event.ONMOUSEDOWN:
183: onMouseDown(be);
184: break;
185: case Event.ONMOUSEUP:
186: onMouseUp(be);
187: break;
188: case Event.ONCLICK:
189: onClick(be);
190: break;
191: }
192:
193: }
194:
195: /**
196: * Removes a widget from region 4.
197: *
198: * @param widget the widget to remove
199: */
200: public void removeWidget(Widget widget) {
201: if (widgets != null) {
202: widgets.remove(widget);
203: if (rendered) {
204: widgetPanel.remove(widget);
205: }
206: }
207: }
208:
209: /**
210: * A CSS style which sets a background image to be used as the icon.
211: *
212: * @param iconStyle the CSS class name
213: */
214: public void setIconStyle(String iconStyle) {
215: this .iconStyle = iconStyle;
216: if (rendered) {
217: if (iconBtn == null) {
218: iconBtn = new IconButton(iconStyle);
219: DOM.appendChild(midleftElem, iconBtn.getElement());
220: iconBtn.removeStyleName("my-nodrag");
221: }
222: iconBtn.changeStyle(iconStyle);
223: }
224: }
225:
226: /**
227: * Sets the item's text.
228: *
229: * @param text the new text
230: */
231: public void setText(String text) {
232: this .text = text;
233: if (rendered) {
234: MyDOM.setInnerHTML(textElem, text);
235: }
236: }
237:
238: /**
239: * Sets the amount of spacing around the widgets in the "tool" area.
240: *
241: * @param spacing the spacing in pixels
242: */
243: public void setWidgetSpacing(int spacing) {
244: this .spacing = spacing;
245: if (rendered) {
246: widgetPanel.setSpacing(spacing);
247: }
248: }
249:
250: protected void doAttachChildren() {
251: if (widgetPanel != null) {
252: WidgetHelper.doAttach(widgetPanel);
253: }
254: }
255:
256: protected void doDetachChildren() {
257: if (widgetPanel != null) {
258: WidgetHelper.doDetach(widgetPanel);
259: }
260: }
261:
262: protected boolean isSelected() {
263: return selected;
264: }
265:
266: protected void onClick(final BaseEvent be) {
267: be.stopEvent();
268: hovering = false;
269: DeferredCommand.addCommand(new Command() {
270: public void execute() {
271: onMouseOut(be);
272: fireEvent(Events.MouseOut, be);
273: }
274: });
275: }
276:
277: protected void onDisable() {
278: super .onDisable();
279: if (overStyleEnabled) {
280: removeStyleName(baseStyle + "-over");
281: removeStyleName(baseStyle + "-down");
282: }
283: if (iconBtn != null) {
284: iconBtn.setEnabled(false);
285: }
286: }
287:
288: protected void onEnable() {
289: super .onEnable();
290: if (iconBtn != null) {
291: iconBtn.setEnabled(true);
292: }
293: }
294:
295: protected void onMouseDown(BaseEvent be) {
296: addStyleName(baseStyle + "-down");
297: }
298:
299: protected void onMouseOut(BaseEvent be) {
300: if (overStyleEnabled) {
301: removeStyleName(baseStyle + "-over");
302: removeStyleName(baseStyle + "-down");
303: }
304: }
305:
306: protected void onMouseOver(BaseEvent be) {
307: if (overStyleEnabled) {
308: addStyleName(baseStyle + "-over");
309: }
310: }
311:
312: protected void onMouseUp(BaseEvent be) {
313: removeStyleName(baseStyle + "-down");
314: }
315:
316: protected void onRender() {
317: if (markup == null) {
318: markup = Markup.ITEM;
319: }
320:
321: String cacheKey = baseStyle + ":" + markup;
322: Element element = (Element) elementCache.get(cacheKey);
323: if (element == null) {
324: element = MyDOM
325: .create(Format.substitute(markup, baseStyle));
326: elementCache.put(cacheKey, element);
327: }
328: setElement(clone(element, true));
329:
330: midleftElem = MyDOM.findChild(baseStyle + "-ml", getElement());
331: centerElem = DOM.getNextSibling(midleftElem);
332: textElem = DOM.getFirstChild(centerElem);
333: midRightElem = DOM.getNextSibling(centerElem);
334:
335: if (text != null) {
336: setText(text);
337: }
338:
339: if (iconStyle != null) {
340: setIconStyle(iconStyle);
341: }
342:
343: if (widgets != null) {
344: widgetPanel = new HorizontalPanel();
345: for (int i = 0; i < widgets.size(); i++) {
346: widgetPanel.add((Widget) widgets.get(i));
347: }
348: DOM.appendChild(midRightElem, widgetPanel.getElement());
349: }
350:
351: if (spacing > 0) {
352: setWidgetSpacing(spacing);
353: }
354:
355: disableTextSelection(true);
356:
357: if (sinkEvents) {
358: sinkEvents(Event.ONCLICK | Event.ONDBLCLICK
359: | Event.MOUSEEVENTS);
360: }
361:
362: }
363:
364: protected void setSelected(boolean select) {
365: selected = select;
366: if (selected) {
367: removeStyleName(baseStyle + "-over");
368: addStyleName(baseStyle + "-sel");
369: } else {
370: removeStyleName(baseStyle + "-sel");
371: }
372: }
373: }
|