001: /*******************************************************************************
002: * Copyright (c) 2007 MyGWT.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * Darrell Meyer <darrell@mygwt.net> - initial API and implementation
010: *******************************************************************************/package net.mygwt.ui.client.viewer;
011:
012: import java.util.ArrayList;
013: import java.util.HashMap;
014: import java.util.List;
015: import java.util.Map;
016:
017: import net.mygwt.ui.client.Events;
018: import net.mygwt.ui.client.MyDOM;
019: import net.mygwt.ui.client.event.BaseEvent;
020: import net.mygwt.ui.client.widget.Component;
021:
022: import com.google.gwt.user.client.DOM;
023: import com.google.gwt.user.client.Element;
024: import com.google.gwt.user.client.Event;
025: import com.google.gwt.user.client.ui.KeyboardListener;
026: import com.google.gwt.user.client.ui.Widget;
027:
028: /**
029: * A <code>Viewer</code> that renders its layout using HTML fragments provided
030: * by the label provider.
031: *
032: * @see TemplateLabelProvider
033: */
034: public class TemplateViewer extends Viewer {
035:
036: private Component container;
037: private Object selected;
038: private Element selectedEl;
039: private TemplateLabelProvider lp;
040: private Element containerEl;
041: private Map idToElementMap;
042: private Map elementToIdMap;
043: private boolean selectOnOver;
044: private boolean focusOnSelect = true;
045:
046: /**
047: * Creates a new template viewer instance.
048: */
049: public TemplateViewer() {
050: idToElementMap = new HashMap();
051: elementToIdMap = new HashMap();
052: }
053:
054: public Widget findItem(Object elem) {
055: return null;
056: }
057:
058: /**
059: * Returns <code>true</code> if focus on select is enabled.
060: *
061: * @return the focus on selec state
062: */
063: public boolean getFocusOnSelect() {
064: return focusOnSelect;
065: }
066:
067: /**
068: * Returns <code>true</code> if elements are selected when the cursor is
069: * over their location.
070: *
071: * @return the selecte on over state
072: */
073: public boolean getSelectOnOver() {
074: return selectOnOver;
075: }
076:
077: public Widget getWidget() {
078: return container;
079: }
080:
081: /**
082: * Moves the current selection down.
083: */
084: public void moveSelectionDown() {
085: if (selectedEl != null) {
086: int index = DOM.getChildIndex(containerEl, selectedEl);
087: if (index < elements.length - 1) {
088: Element el = DOM.getChild(containerEl, index + 1);
089: Object elem = findModel(el);
090: selectItem(elem, el);
091: }
092: } else if (elements.length > 0) {
093: setSelection(new DefaultSelection(elements[0]));
094: }
095: }
096:
097: /**
098: * Moves the current selection up.
099: */
100: public void moveSelectionUp() {
101: if (selectedEl != null) {
102: int index = DOM.getChildIndex(containerEl, selectedEl);
103: if (index > 0) {
104: Element el = DOM.getChild(containerEl, index - 1);
105: Object elem = findModel(el);
106: selectItem(elem, el);
107: }
108: }
109: }
110:
111: public void remove(Object elem) {
112: String id = (String) elementToIdMap.get(elem);
113: if (id != null) {
114: Element el = DOM.getElementById(id);
115: DOM.removeChild(containerEl, el);
116: unregister(id, elem);
117: }
118: }
119:
120: /**
121: * Sets whether the component should receive focus when selected. Default
122: * value is <code>true</code>.
123: *
124: * @param focusOnSelect <code>true</code> to focus on select
125: */
126: public void setFocusOnSelect(boolean focusOnSelect) {
127: this .focusOnSelect = focusOnSelect;
128: }
129:
130: public void setLabelProvider(IBaseLabelProvider labelProvider) {
131: super .setLabelProvider(labelProvider);
132: lp = (TemplateLabelProvider) labelProvider;
133: }
134:
135: public void setSelection(ISelection selection, boolean reveal) {
136: Object elem = selection.getFirstElement();
137: if (elem != null) {
138: String id = (String) elementToIdMap.get(elem);
139: Element el = DOM.getElementById(id);
140: selectItem(elem, el);
141: } else {
142: selectItem(null, null);
143: }
144:
145: }
146:
147: /**
148: * Sets whether elements are selected when the cursor is over their location.
149: * Default value is <code>fals</code>.
150: *
151: * @param selectOnOver the select on over state
152: */
153: public void setSelectOnOver(boolean selectOnOver) {
154: this .selectOnOver = selectOnOver;
155: }
156:
157: public void update() {
158:
159: }
160:
161: public void update(Object elem) {
162:
163: }
164:
165: protected void add(Object elem) {
166: renderItem(elem, elements.length);
167: }
168:
169: protected Component createWidget() {
170: Component c = new Component() {
171: {
172: setBorders(true);
173: }
174:
175: public void onBaseEvent(BaseEvent be) {
176: Element el = findItemElement(be.getTarget());
177: Object elem = findModel(el);
178: switch (be.type) {
179: case Events.MouseOver:
180: if (elem != null) {
181: onMouseOver(elem, el, be);
182: }
183: break;
184: case Events.MouseOut:
185: if (elem != null) {
186: onMouseOut(elem, el, be);
187: }
188: break;
189: case Events.Click:
190: if (elem != null) {
191: onClick(elem, el, be);
192: }
193: break;
194: case Events.KeyUp:
195: onKeyPress(be);
196:
197: break;
198: }
199: be.stopEvent();
200: }
201:
202: protected void onRender() {
203: setElement(MyDOM.create(lp.render()));
204: sinkEvents(Event.ONCLICK | Event.MOUSEEVENTS
205: | Event.KEYEVENTS);
206: }
207: };
208: return c;
209: }
210:
211: protected Element findItemElement(Element elem) {
212: return MyDOM.findParentWithId(elem, 5);
213: }
214:
215: protected Object findModel(Element item) {
216: String id = MyDOM.getId(item);
217: return idToElementMap.get(id);
218: }
219:
220: protected List getSelectedFromWidget() {
221: ArrayList list = new ArrayList();
222: if (selected != null) {
223: list.add(selected);
224: }
225: return list;
226: }
227:
228: protected void insert(Object elem, int index) {
229: renderItem(elem, index);
230: }
231:
232: protected void onClick(Object elem, Element el, BaseEvent be) {
233: selectItem(elem, el);
234: }
235:
236: protected void onHightlight(Object elem, Element el,
237: boolean highlight) {
238: MyDOM.setStyleName(el, lp.getOverStyle(), highlight);
239: }
240:
241: protected void onInputReceived(Object input) {
242: render();
243: }
244:
245: protected void onKeyPress(BaseEvent be) {
246: switch (be.getKeyCode()) {
247: case KeyboardListener.KEY_UP: {
248: moveSelectionUp();
249: }
250: case KeyboardListener.KEY_DOWN: {
251: moveSelectionDown();
252: }
253: }
254: }
255:
256: protected void onMouseOut(Object elem, Element el, BaseEvent be) {
257: onHightlight(elem, el, false);
258: }
259:
260: protected void onMouseOver(Object elem, Element el, BaseEvent be) {
261: if (selectOnOver) {
262: selectItem(elem, el);
263: } else {
264: onHightlight(elem, el, true);
265: }
266: }
267:
268: protected void onSelect(Object elem, Element el, boolean select) {
269: MyDOM.setStyleName(el, lp.getSelectStyle(), select);
270: }
271:
272: private void register(String id, Object elem) {
273: idToElementMap.put(id, elem);
274: elementToIdMap.put(elem, id);
275: }
276:
277: private void render() {
278: if (container == null) {
279: container = createWidget();
280: selected = null;
281: }
282: if (containerEl != null) {
283: MyDOM.setInnerHTML(containerEl, "");
284: }
285:
286: containerEl = MyDOM.findChild("my-container", container
287: .getElement());
288: if (containerEl == null) {
289: containerEl = container.getElement();
290: }
291: TemplateLabelProvider lp = (TemplateLabelProvider) getLabelProvider();
292:
293: Object[] elems = filter(elements);
294: elems = sortElements(elems);
295:
296: StringBuffer sb = new StringBuffer();
297: for (int i = 0; i < elems.length; i++) {
298: sb.append(lp.renderElement(elems[i]));
299: }
300: MyDOM.setInnerHTML(containerEl, sb.toString());
301:
302: int cout = DOM.getChildCount(containerEl);
303: Element[] items = new Element[cout];
304: for (int i = 0; i < cout; i++) {
305: items[i] = DOM.getChild(containerEl, i);
306: String id = MyDOM.getId(items[i]);
307: register(id, elems[i]);
308: }
309:
310: }
311:
312: private void renderItem(Object elem, int position) {
313: TemplateLabelProvider lp = (TemplateLabelProvider) getLabelProvider();
314: Element el = MyDOM.create(lp.renderElement(elem));
315: DOM.insertChild(containerEl, el, position);
316: register(MyDOM.getId(el), elem);
317: }
318:
319: private void selectItem(Object elem, Element el) {
320: if (selected != null && selected == elem)
321: return;
322: if (selected != null) {
323: onSelect(selected, selectedEl, false);
324: }
325: if (elem != null) {
326: onSelect(elem, el, true);
327: System.out.println("dddd");
328: MyDOM.scrollIntoView(el, containerEl, false);
329: if (focusOnSelect) {
330: MyDOM.setFocus(containerEl, true);
331: }
332: }
333: this .selected = elem;
334: this .selectedEl = el;
335:
336: SelectionChangedEvent se = new SelectionChangedEvent(this ,
337: getSelection());
338: fireSelectionChanged(se);
339: }
340:
341: private void unregister(String id, Object elem) {
342: idToElementMap.remove(id);
343: elementToIdMap.remove(elem);
344: }
345:
346: }
|