/*
* JBoss, Home of Professional Open Source
* Copyright 2011 Red Hat Inc. and/or its affiliates and other contributors
* as indicated by the @author tags. All rights reserved.
* See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU Lesser General Public License, v. 2.1.
* This program is distributed in the hope that it will be useful, but WITHOUT A
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
* You should have received a copy of the GNU Lesser General Public License,
* v.2.1 along with this distribution; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*/
package org.jboss.ballroom.client.layout;
import com.google.gwt.core.client.GWT;
import com.google.gwt.core.client.Scheduler;
import com.google.gwt.dom.client.EventTarget;
import com.google.gwt.event.dom.client.KeyCodes;
import com.google.gwt.event.dom.client.KeyDownEvent;
import com.google.gwt.event.dom.client.KeyDownHandler;
import com.google.gwt.event.dom.client.MouseDownEvent;
import com.google.gwt.event.dom.client.MouseDownHandler;
import com.google.gwt.event.logical.shared.CloseEvent;
import com.google.gwt.event.logical.shared.CloseHandler;
import com.google.gwt.event.logical.shared.OpenEvent;
import com.google.gwt.event.logical.shared.OpenHandler;
import com.google.gwt.event.logical.shared.SelectionEvent;
import com.google.gwt.event.logical.shared.SelectionHandler;
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.HTMLPanel;
import com.google.gwt.user.client.ui.Tree;
import com.google.gwt.user.client.ui.TreeItem;
import org.jboss.ballroom.client.spi.Framework;
import org.jboss.ballroom.client.widgets.icons.DefaultTreeResources;
/**
*
* A tree that's used as a navigation element on the left hand side.<br>
* It's driven by a token attribute that's associated with the tree item.
*
* @see LHSNavTreeItem
* @see LHSTreeSection
*
* @author Heiko Braun
* @date 3/24/11
*/
public class LHSNavTree extends Tree implements LHSHighlightEvent.NavItemSelectionHandler {
private static final String TREE_ID_ATTRIBUTE = "treeid";
private static final Framework framework = GWT.create(Framework.class);
private String treeId;
private String category;
private LHSNavTreeItem prevNavItem;
public LHSNavTree(final String category) {
this(DefaultTreeResources.INSTANCE, category);
}
public LHSNavTree(Tree.Resources resources, final String category) {
super(resources);
this.treeId = "lhs-nav-tree_"+HTMLPanel.createUniqueId();
this.category = category;
addStyleName("stack-section");
/**
* actions that reveal content
*/
addKeyDownHandler(new KeyDownHandler() {
public void onKeyDown(KeyDownEvent keyDownEvent) {
if(keyDownEvent.getNativeKeyCode()== KeyCodes.KEY_ENTER)
{
revealContent(false);
}
}
});
addMouseDownHandler(new MouseDownHandler() {
public void onMouseDown(MouseDownEvent mouseDownEvent) {
Scheduler.get().scheduleDeferred(new Scheduler.ScheduledCommand() {
public void execute() {
revealContent(true);
}
});
}
});
Scheduler.get().scheduleEntry(new Scheduler.ScheduledCommand() {
public void execute() {
framework.getEventBus().addHandler(LHSHighlightEvent.TYPE, LHSNavTree.this);
}
});
/*
Allow clicks on lhs titles to open thr tree
*/
addMouseDownHandler(new MouseDownHandler() {
public void onMouseDown(MouseDownEvent event) {
EventTarget target = event.getNativeEvent().getEventTarget();
com.google.gwt.dom.client.Element el = Element.as(target);
final String title = el.getInnerText();
if(el.getTagName().equalsIgnoreCase("div"))
{
applyStateChange(new StateChange()
{
public void applyTo(TreeItem treeItem) {
boolean isMatched = title.equals(treeItem.getText());
if(isMatched)
{
treeItem.setState(!treeItem.getState());
}
}
});
}
}
});
}
/**
* flag the 'active' item and revel content if necessary
*/
private void revealContent(boolean open) {
TreeItem activeItem = getSelectedItem();
if(activeItem instanceof LHSNavTreeItem)
{
((LHSNavTreeItem)activeItem).reveal();
}
}
public String getTreeId() {
return treeId;
}
@Override
public void addItem(TreeItem item) {
item.getElement().setAttribute(TREE_ID_ATTRIBUTE, treeId);
super.addItem(item);
}
public void onSelectedNavTree(final LHSHighlightEvent event) {
if(category.equals(event.getCategory()) || event.getCategory().equals("*"))
{
applyStateChange(new StateChange()
{
public void applyTo(TreeItem treeItem) {
if(!(treeItem instanceof LHSNavTreeItem))
return;
LHSNavTreeItem target = (LHSNavTreeItem) treeItem;
String token = treeItem.getElement().hasAttribute("token") ?
treeItem.getElement().getAttribute("token") : "not-set";
boolean isSelected = event.getItem().equals(treeItem.getText())
|| token.equals(event.getToken());
if(isSelected)
{
if(prevNavItem!=null && !prevNavItem.equals(treeItem))
prevNavItem.setActive(false);
prevNavItem=target;
openParents(treeItem);
target.setActive(true);
}
else
{
target.setActive(false);
}
}
});
}
}
private void openParents(TreeItem treeItem) {
TreeItem parentItem = treeItem.getParentItem();
if(parentItem !=null)
{
parentItem.setState(true);
openParents(parentItem);
}
}
void applyStateChange(StateChange stateChange)
{
for(int i=0; i<getItemCount(); i++)
{
dfsItem(stateChange, getItem(i));
}
}
private void dfsItem(StateChange stateChange, TreeItem item) {
if(null==item) return;
for(int x=0; x<item.getChildCount(); x++)
{
dfsItem(stateChange, item.getChild(x));
}
stateChange.applyTo(item);
}
interface StateChange {
void applyTo(TreeItem item);
}
public void expandTopLevel() {
for(int i=0; i<getItemCount(); i++)
{
TreeItem item = getItem(i);
item.setState(true);
}
}
}