/* * Ext GWT - Ext for GWT * Copyright(c) 2007-2009, Ext JS, LLC. * licensing@extjs.com * * http://extjs.com/license */ package com.extjs.gxt.ui.client.widget.tree; import com.extjs.gxt.ui.client.GXT; import com.extjs.gxt.ui.client.Style.Direction; import com.extjs.gxt.ui.client.aria.FocusFrame; import com.extjs.gxt.ui.client.core.El; import com.extjs.gxt.ui.client.event.ComponentEvent; import com.extjs.gxt.ui.client.event.Events; import com.extjs.gxt.ui.client.event.FxEvent; import com.extjs.gxt.ui.client.event.Listener; import com.extjs.gxt.ui.client.event.TreeEvent; import com.extjs.gxt.ui.client.fx.FxConfig; import com.extjs.gxt.ui.client.widget.tree.Tree.Joint; import com.extjs.gxt.ui.client.widget.treepanel.TreePanel; import com.google.gwt.user.client.DOM; import com.google.gwt.user.client.Element; import com.google.gwt.user.client.Event; import com.google.gwt.user.client.ui.Accessibility; /** * Default <code>TreeItemUI</code> implementation. * * @deprecated see {@link TreePanel} */ public class DefaultTreeItemUI implements TreeItemUI { protected int animDuration = 300; protected Element checkEl, checkDivEl; protected String classTreeClose = "my-tree-close"; protected String classTreeOpen = "my-tree-open"; protected El containerEl; protected Element iconEl, iconDivEl; protected Element itemEl, indentEl; protected TreeItem item; protected Element jointEl, jointDivEl; protected String styleTreeChecked = "my-tree-checked"; protected String styleTreeItem = ""; protected String styleTreeJointOver = "my-tree-joint-over"; protected String styleTreeLoading = "my-tree-loading"; protected String styleTreeNotChecked = "my-tree-notchecked"; protected String styleTreeOver = "my-tree-over"; protected String styleTreeSelected = "my-tree-sel"; protected Element textEl, textSpanEl; protected String textStyle; public void afterRender() { if (item.root) return; itemEl = item.getElement().getFirstChild().cast(); fly(itemEl).addStyleName(styleTreeItem); El el = item.el(); Element td = el.selectNode("td:first-child").dom; indentEl = td.getFirstChildElement().cast(); jointEl = td.getNextSiblingElement().cast(); jointDivEl = jointEl.getFirstChild().cast(); checkEl = jointEl.getNextSiblingElement().getNextSiblingElement().cast(); checkDivEl = checkEl.getFirstChild().cast(); iconEl = checkEl.getNextSibling().cast(); iconDivEl = iconEl.getFirstChild().cast(); textEl = iconEl.getNextSiblingElement().cast(); textSpanEl = textEl.getFirstChildElement().cast(); containerEl = el.getChild(1); containerEl.setVisible(false); containerEl.makePositionable(); if (item.getItemStyleName() != null) { item.el().firstChild().addStyleName(item.getItemStyleName()); } if (checkEl != null) { fly(checkEl).setVisible(item.tree.getCheckable()); } item.updateIconStyle(); item.updateJointStyle(); if (item.getTextStyle() != null) { onTextStyleChange(item.getTextStyle()); } if (item.isChecked()) { onCheckChange(true); } fly(indentEl).setWidth(item.getIndent() - 18); item.disableTextSelection(true); } public void bind(TreeItem item) { this.item = item; } public void collapse() { if (item.root) { return; } item.updateIconStyle(); item.updateJointStyle(); if (item.tree.getAnimate()) { animCollapse(); } else { containerEl.setVisible(false); afterCollapse(); } } public void expand() { if (item.root) { return; } item.updateJointStyle(); if (item.getItemCount() == 0) { return; } item.updateIconStyle(); item.updateJointStyle(); if (item.tree.getAnimate()) { animExpand(); } else { containerEl.setVisible(true); afterExpand(); } } public Element getCheckElement() { return checkEl; } public Element getContainerElement() { return containerEl.dom; } public Element getJointElement() { return jointDivEl; } public native String getTemplate(String id, String text, String icon, int joint, int level) /*-{ return ['<div id=' + id + ' class="my-tree-item x-tree-item" role="treeitem" aria-level="' + (++level) + '">', '<div class=my-treeitem-wrap>', '<table cellpadding=0 cellspacing=0><tbody>', '<tr>', '<td><div class="my-tree-indent"></div></td>', '<td class="my-tree-joint" align="center" valign="middle"><div> </div></td>', '<td class="my-tree-left"><div></div></td>', '<td class="my-tree-check"><div class="my-tree-notchecked"></div></td>', '<td class="my-tree-icon"><div> </div></td>', '<td class="my-tree-item-text"><span>' + text + '</span></td>', '<td class="my-tree-right"><div></div></td>', '</tr>', '</tbody>', '</table>', '</div>', '<div class="my-tree-ct" role="container"></div>', '</div>'].join(""); }-*/; public void handleEvent(TreeEvent te) { int type = te.getEventTypeInt(); Element target = te.getTarget(); switch (type) { case Event.ONCLICK: case Event.ONDBLCLICK: if (checkEl != null && DOM.isOrHasChild(checkEl, target)) { te.stopEvent(); item.setChecked(!item.isChecked()); } else { handleClickEvent(te); } return; case Event.ONMOUSEOVER: case Event.ONMOUSEOUT: if (DOM.isOrHasChild(jointEl, target)) { handleJointEvent(te); } else if (isSelectableTarget(target)) { handleMouseEvent(te); } break; } } public boolean isSelectableTarget(Element target) { if (DOM.isOrHasChild(iconEl, target) || DOM.isOrHasChild(textEl, target) || (checkEl != null && DOM.isOrHasChild(checkEl, target))) { return true; } return false; } public void onCheckChange(boolean checked) { String cls = checked ? styleTreeChecked : styleTreeNotChecked; checkDivEl.setClassName(cls); item.fireEvent(Events.CheckChange, new TreeEvent(item.tree, item)); } public void onDoubleClick(ComponentEvent ce) { item.toggle(); ce.cancelBubble(); } public void onIconStyleChange(String style) { if (style != null) { fly(iconEl).setStyleAttribute("display", ""); fly(iconDivEl).setIconStyle(style); } else { fly(iconEl).setStyleAttribute("display", "none"); } } public void onIndentChange(int level) { fly(indentEl).setWidth(item.getIndent() - 18); Accessibility.setState(item.getElement(), "aria-level", ++level + ""); } public void onJointChange(Joint joint) { switch (joint) { case NONE: jointDivEl.setClassName("none"); break; case EXPANDED: jointDivEl.setClassName("my-tree-open"); break; case COLLAPSED: jointDivEl.setClassName("my-tree-close"); break; } } public void onLoadingChange(boolean loading) { if (loading) { item.addStyleName(styleTreeLoading); } else { item.removeStyleName(styleTreeLoading); } } public void onOverChange(boolean over) { fly(itemEl).setStyleName(styleTreeOver, over); } public void onRemoveChild(TreeItem child) { containerEl.dom.removeChild(child.getElement()); if (item.getItemCount() == 0) { boolean b = item.tree.getAnimate(); item.tree.setAnimate(false); item.setExpanded(false); item.tree.setAnimate(b); } } public void onSelectedChange(boolean selected) { if (item.isRendered()) { fly(itemEl).setStyleName(styleTreeSelected, selected); if (!selected) { onOverChange(false); } else { Accessibility.setState(item.tree.getElement(), "aria-activedescendant", item.getId()); } } } public void onTextChange(String text) { if (!item.root) { textSpanEl.setInnerHTML(text); } } public void onTextStyleChange(String style) { if (textStyle != null) { fly(textSpanEl).removeStyleName(textStyle); } textStyle = style; if (style != null) { fly(textSpanEl).addStyleName(style); } } public void refresh() { onIconStyleChange(null); item.updateJointStyle(); } protected void afterCollapse() { item.tree.disableEvents(false); containerEl.dom.getStyle().setProperty("marginTop", "0"); fly(itemEl).removeStyleName(styleTreeJointOver); if (GXT.isAriaEnabled()) { Accessibility.setState(item.getElement(), "aria-expanded", "false"); FocusFrame.get().sync(item.tree); } item.fireEvent(Events.Collapse, new TreeEvent(item.tree, item)); } protected void afterExpand() { item.tree.disableEvents(false); fly(itemEl).removeStyleName(styleTreeJointOver); if (GXT.isAriaEnabled()) { Accessibility.setState(item.getElement(), "aria-expanded", "true"); FocusFrame.get().sync(item.tree); } item.fireEvent(Events.Expand, new TreeEvent(item.tree, item)); } protected El fly(Element elem) { return El.fly(elem); } protected void handleClickEvent(TreeEvent te) { TreeItem item = te.getItem(); if (te.getEventTypeInt() == Event.ONCLICK) { Element target = te.getTarget(); if (target != null && te.within(item.getUI().getJointElement())) { item.toggle(); } te.cancelBubble(); } else if (te.getEventTypeInt() == Event.ONDBLCLICK) { item.toggle(); } } protected void handleJointEvent(TreeEvent ce) { switch (ce.getEventTypeInt()) { case Event.ONMOUSEOVER: fly(itemEl).addStyleName(styleTreeJointOver); break; case Event.ONMOUSEOUT: fly(itemEl).removeStyleName(styleTreeJointOver); break; } ce.stopEvent(); } protected void handleMouseEvent(TreeEvent ce) { int type = ce.getEventTypeInt(); switch (type) { case Event.ONMOUSEOVER: onOverChange(true); break; case Event.ONMOUSEOUT: onOverChange(false); break; } ce.cancelBubble(); } protected void onClick(TreeEvent te) { Element target = te.getTarget(); if (target != null && isSelectableTarget(target)) { item.toggle(); } te.cancelBubble(); } private void animCollapse() { containerEl.slideOut(Direction.UP, new FxConfig(animDuration, new Listener<FxEvent>() { public void handleEvent(FxEvent fe) { afterCollapse(); } })); item.tree.disableEvents(true); } private void animExpand() { containerEl.slideIn(Direction.DOWN, new FxConfig(animDuration, new Listener<FxEvent>() { public void handleEvent(FxEvent fe) { afterExpand(); } })); item.tree.disableEvents(true); } }