/*
* MyGWT Widget Library
* Copyright(c) 2007, MyGWT.
* licensing@mygwt.net
*
* http://mygwt.net/license
*/
package net.mygwt.ui.client.widget.tree;
import net.mygwt.ui.client.Events;
import net.mygwt.ui.client.MyDOM;
import net.mygwt.ui.client.Style;
import net.mygwt.ui.client.event.BaseEvent;
import net.mygwt.ui.client.event.Listener;
import net.mygwt.ui.client.fx.FXStyle;
import net.mygwt.ui.client.util.Markup;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Element;
public class TreeItemUI {
private static Listener clickListener = new Listener() {
public void handleEvent(BaseEvent be) {
if (be.type == Events.Click) {
TreeItem item = (TreeItem) be.widget;
Element target = be.getTarget();
if (target != null && be.within(item.ui.jointEl)) {
item.toggle();
}
be.cancelBubble();
} else if (be.type == Events.DoubleClick) {
TreeItem item = (TreeItem) be.widget;
item.toggle();
}
}
};
private static Listener mouseListener = new Listener() {
public void handleEvent(BaseEvent be) {
int type = be.type;
TreeItem item = (TreeItem) be.widget;
switch (type) {
case Events.MouseOver:
MyDOM.setStyleName(item.ui.itemEl, "my-tree-over", true);
break;
case Events.MouseOut:
MyDOM.setStyleName(item.ui.itemEl, "my-tree-over", false);
break;
}
be.cancelBubble();
}
};
private static Listener jointListener = new Listener() {
public void handleEvent(BaseEvent be) {
int type = be.type;
TreeItem item = (TreeItem) be.widget;
switch (type) {
case Events.MouseOver:
MyDOM.setStyleName(item.ui.itemEl, "my-tree-joint-over", true);
break;
case Events.MouseOut:
MyDOM.setStyleName(item.ui.itemEl, "my-tree-joint-over", false);
break;
}
be.stopEvent();
}
};
protected Element containerEl;
protected Element jointEl, jointDivEl;
private TreeItem item;
private Element itemEl, indentEl;
private Element checkEl, checkDivEl;
private Element iconEl, iconDivEl;
private Element textEl, textSpanEl;
public TreeItemUI(TreeItem item) {
this.item = item;
render();
}
public void collapse() {
if (item.root) {
return;
}
updateJoint();
onIconStyleChange(null);
if (item.tree.animate) {
animCollapse();
} else {
MyDOM.setVisible(containerEl, false);
afterCollapse();
}
}
public void expand() {
if (item.root) {
return;
}
updateJoint();
if (item.getItemCount() == 0) {
return;
}
onIconStyleChange(null);
if (item.tree.animate) {
animExpand();
} else {
MyDOM.setVisible(containerEl, true);
afterExpand();
}
}
public Element getJointEl() {
return jointEl;
}
public void onCheckChange(boolean checked) {
String cls = checked ? "my-tree-checked" : "my-tree-notchecked";
MyDOM.setStyleName(checkDivEl, cls);
}
public void onClick(BaseEvent be) {
Element target = be.getTarget();
if (target != null && be.within(jointEl)) {
item.toggle();
}
be.cancelBubble();
}
public void onDoubleClick(BaseEvent be) {
item.toggle();
be.cancelBubble();
}
public void onLoadingChange(boolean loading) {
if (loading) {
item.addStyleName("my-tree-loading");
} else {
item.removeStyleName("my-tree-loading");
}
}
public void onIconStyleChange(String style) {
if (item.iconStyle != null) {
MyDOM.setVisible(iconEl, true);
MyDOM.setStyleName(iconDivEl, item.iconStyle);
return;
}
if (!item.leaf) {
String s = "";
if (item.expanded && item.tree.openNodeImageStyle != null) {
s = item.tree.openNodeImageStyle;
} else if (item.expanded && item.tree.nodeImageStyle != null) {
s = item.tree.nodeImageStyle;
} else if (!item.expanded) {
s = item.tree.nodeImageStyle;
}
MyDOM.setVisible(iconEl, true);
MyDOM.setStyleName(iconDivEl, s);
} else {
MyDOM.setVisible(iconEl, true);
MyDOM.setStyleName(iconDivEl, item.tree.itemImageStyle);
return;
}
}
public void onSelectedChange(boolean selected) {
if (item.isRendered()) {
MyDOM.setStyleName(itemEl, "my-tree-sel", selected);
MyDOM.setFocus(itemEl, selected);
}
}
public void removeItem(TreeItem child) {
DOM.removeChild(containerEl, child.getElement());
}
protected void afterCollapse() {
item.enable();
item.tree.enable();
MyDOM.setStyleName(itemEl, "my-tree-joint-over", false);
item.fireEvent(Events.Collapse);
}
protected void afterExpand() {
item.enable();
item.tree.enable();
MyDOM.setStyleName(itemEl, "my-tree-joint-over", false);
item.fireEvent(Events.Expand);
}
protected void initEvents() {
item.addListener(Events.Click, clickListener);
item.addListener(Events.DoubleClick, clickListener);
// checkbox
item.addListener(Events.Click, checkEl, new Listener() {
public void handleEvent(BaseEvent be) {
be.stopEvent();
item.setChecked(!item.isChecked());
}
});
// joint events
item.addListener(Events.MouseOver, jointEl, jointListener);
item.addListener(Events.MouseOut, jointEl, jointListener);
// node events
item.addListener(Events.MouseOver, iconEl, mouseListener);
item.addListener(Events.MouseOver, textEl, mouseListener);
item.addListener(Events.MouseOver, checkEl, mouseListener);
item.addListener(Events.MouseOut, iconEl, mouseListener);
item.addListener(Events.MouseOut, textEl, mouseListener);
item.addListener(Events.MouseOut, checkEl, mouseListener);
}
protected void onTextChange(String text) {
DOM.setInnerHTML(textSpanEl, text);
}
protected void render() {
if (item.root == true) {
return;
}
item.setElement(DOM.createDiv());
item.setStyleName("my-treeitem");
DOM.appendChild(item.parentItem.ui.containerEl, item.getElement());
DOM.setInnerHTML(item.getElement(), Markup.TREE_ITEM);
itemEl = DOM.getFirstChild(item.getElement());
Element td = MyDOM.getSubChild(itemEl, 3);
indentEl = DOM.getFirstChild(td);
jointEl = DOM.getNextSibling(td);
jointDivEl = DOM.getFirstChild(jointEl);
checkEl = DOM.getNextSibling(DOM.getNextSibling(jointEl));
checkDivEl = DOM.getFirstChild(checkEl);
iconEl = DOM.getNextSibling(checkEl);
iconDivEl = DOM.getFirstChild(iconEl);
textEl = DOM.getNextSibling(iconEl);
textSpanEl = DOM.getFirstChild(textEl);
Element tbl = DOM.getFirstChild(item.getElement());
containerEl = DOM.getNextSibling(tbl);
int style = item.tree.getStyle();
if ((style & Style.CHECK) != 0) {
MyDOM.setVisible(checkEl, true);
} else {
MyDOM.setVisible(checkEl, false);
}
onTextChange(item.getText());
onIconStyleChange(item.getIconStyle());
MyDOM.setWidth(indentEl, getIndent());
initEvents();
updateJoint();
MyDOM.disableTextSelection(item.getElement());
}
void animCollapse() {
FXStyle fx = new FXStyle(containerEl);
fx.duration = 300;
fx.addListener(Events.EffectComplete, new Listener() {
public void handleEvent(BaseEvent be) {
afterCollapse();
}
});
item.disable();
item.tree.disable();
fx.slideOut(Style.NORTH);
}
void animExpand() {
FXStyle fx = new FXStyle(containerEl);
fx.duration = 300;
fx.addListener(Events.EffectComplete, new Listener() {
public void handleEvent(BaseEvent be) {
afterExpand();
}
});
item.disable();
item.tree.disable();
fx.slideIn(Style.SOUTH);
}
public void updateJoint() {
if (item.root) {
return;
}
if (!item.leaf) {
String cls = item.isExpanded() ? "my-tree-open" : "my-tree-close";
MyDOM.setStyleName(jointDivEl, cls);
} else {
MyDOM.setStyleName(jointDivEl, "none");
}
}
private int getIndent() {
return (item.getDepth() - 1) * 18;
}
}