de.swm.commons.mobile.client.widgets.tree.TreePanel Maven / Gradle / Ivy
/*
* Copyright 2011 SWM Services GmbH.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package de.swm.commons.mobile.client.widgets.tree;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.uibinder.client.UiConstructor;
import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.EventListener;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.Widget;
import de.swm.commons.mobile.client.SWMMobile;
import de.swm.commons.mobile.client.base.PanelBase;
import de.swm.commons.mobile.client.event.*;
import de.swm.commons.mobile.client.theme.components.TreePanelCss;
import de.swm.commons.mobile.client.utils.Utils;
import de.swm.commons.mobile.client.widgets.*;
import de.swm.commons.mobile.client.widgets.scroll.ScrollPanelWithScrollbar;
import de.swm.commons.mobile.client.widgets.tree.TreeChangedEvent.EventType;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class TreePanel extends PanelBase implements SwipeEventsHandler {
private static final String BREADCRUMB_DELIMITER = ">";
private final TreePanelCss css;
private final boolean hasBreadcrumb;
private Label breadcrumbLabel;
private ScrollPanelWithScrollbar leftScrollPanel;
private ScrollPanelWithScrollbar middleScrollPanel;
private ScrollPanelWithScrollbar rightScrollPanel;
private ITree selectedTree;
private HandlerRegistration selectionHandlerRegistration;
private final SelectionChangedHandler selectionHandler;
private final Map itemMap = new HashMap();
public TreePanel() {
this(false);
}
@UiConstructor
public TreePanel(boolean hasBreadcrumb) {
this.hasBreadcrumb = hasBreadcrumb;
css = SWMMobile.getTheme().getMGWTCssBundle().getTreePanelCss();
addStyleName(css.getTreePanel());
if (hasBreadcrumb) {
HorizontalPanel breadcrumbPanel = new HorizontalPanel();
breadcrumbPanel.addStyleName(css.getTreeBreadcrumbPanel());
ImageHighlightButton backButton = new ImageHighlightButton(SWMMobile.getTheme().getMGWTImageBundle().arrowleft(), new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
navigateBack();
}
});
backButton.addStyleName(css.getTreeBreadcrumbButton());
breadcrumbPanel.add(backButton);
breadcrumbLabel = new Label("-");
breadcrumbLabel.addStyleName(css.getTreeBreadcrumbLabel());
breadcrumbPanel.add(breadcrumbLabel);
add(breadcrumbPanel);
}
HorizontalPanel container = new HorizontalPanel();
container.addStyleName(css.getTreeContainer());
add(container);
leftScrollPanel = new ScrollPanelWithScrollbar();
leftScrollPanel.addStyleName(css.getTreeList());
leftScrollPanel.addStyleName(css.getTreeLeftList());
leftScrollPanel.add(new ListPanel());
container.add(leftScrollPanel);
rightScrollPanel = new ScrollPanelWithScrollbar();
rightScrollPanel.addStyleName(css.getTreeList());
rightScrollPanel.addStyleName(css.getTreeRightList());
rightScrollPanel.add(new ListPanel());
container.add(rightScrollPanel);
middleScrollPanel = new ScrollPanelWithScrollbar();
middleScrollPanel.addStyleName(css.getTreeList());
middleScrollPanel.addStyleName(css.getTreeMiddleList());
middleScrollPanel.add(new ListPanel());
container.add(middleScrollPanel);
selectionHandler = new SelectionChangedHandler() {
@Override
public void onSelectionChanged(SelectionChangedEvent e) {
int selectedIdex = e.getSelection();
ListPanel list = (ListPanel) middleScrollPanel.getWidget();
ListItem selectedItem = list.getItem(selectedIdex);
ITree tree = itemMap.get(selectedItem);
if (hasDetails(tree)) {
shiftRight(tree);
selectedTree = tree;
}
if (tree != null) {
TreeChangedEvent event = new TreeChangedEvent(tree, EventType.CHILD_SELECTED);
fireEvent(event);
}
}
};
ListPanel list = (ListPanel) middleScrollPanel.getWidget();
selectionHandlerRegistration = list.addSelectionChangedHandler(selectionHandler);
}
private boolean hasDetails(ITree tree) {
if (tree != null) {
if (!tree.getChildren().isEmpty()) {
return true;
} else {
ITreeNode node = tree.getNode();
if (node != null && node.getDisplay() != null) {
return true;
}
}
}
return false;
}
public void setTree(ITree tree) {
ListPanel list = (ListPanel) middleScrollPanel.getWidget();
populateList(list, tree);
selectedTree = tree;
if (hasBreadcrumb) {
breadcrumbLabel.setText(tree.getNode().getHeader());
}
TreeChangedEvent event = new TreeChangedEvent(selectedTree, EventType.INIT_COMPLETE);
this.fireEvent(event);
}
/**
* Adds a tree changed handler.
*
* @param handler
* tree changed handler
* @return handle to remove this handler.
*/
public HandlerRegistration addTreeChangedHandler(TreeChangedHandler handler) {
return this.addHandler(handler, TreeChangedEvent.TYPE);
}
@Override
public void onLoad() {
super.onLoad();
DragController.get().addSwipeEventsHandler(this);
}
@Override
protected void onUnload() {
DragController.get().removeSwipeEventHandler(this);
super.onUnload();
}
@Override
public void onSwipeHorizontal(SwipeEvent e) {
e.stopPropagation();
if (e.getSpeed() > 0) {
navigateBack();
}
}
@Override
public void onSwipeVertical(SwipeEvent e) {
// Do nothing.
}
private void shiftRight(ITree tree) {
if (hasBreadcrumb) {
breadcrumbLabel.setText(breadcrumbLabel.getText() + " " + BREADCRUMB_DELIMITER + " " + tree.getNode().getHeader());
}
if (tree.getChildren().isEmpty() && tree.getNode().getDisplay() != null) {
// use custom display for leaf of tree
rightScrollPanel.clear();
rightScrollPanel.add(tree.getNode().getDisplay().asWidget());
tree.getNode().getDisplay().setNode(tree.getNode());
} else {
// use standard list to display children of tree
ListPanel list = (ListPanel) rightScrollPanel.getWidget();
populateList(list, tree);
}
middleScrollPanel.addStyleName(css.getSlide());
rightScrollPanel.addStyleName(css.getSlide());
middleScrollPanel.addStyleName(css.getLeft());
rightScrollPanel.addStyleName(css.getLeft());
Utils.addEventListenerOnce(rightScrollPanel.getElement(), Utils.getTransitionEventName(rightScrollPanel.getElement()), false, new EventListener() {
@Override
public void onBrowserEvent(Event event) {
selectionHandlerRegistration.removeHandler();
middleScrollPanel.removeStyleName(css.getSlide());
rightScrollPanel.removeStyleName(css.getSlide());
middleScrollPanel.removeStyleName(css.getLeft());
rightScrollPanel.removeStyleName(css.getLeft());
leftScrollPanel.removeStyleName(css.getTreeLeftList());
middleScrollPanel.removeStyleName(css.getTreeMiddleList());
rightScrollPanel.removeStyleName(css.getTreeRightList());
// shift panels
ScrollPanelWithScrollbar tmp = leftScrollPanel;
leftScrollPanel = middleScrollPanel;
middleScrollPanel = rightScrollPanel;
rightScrollPanel = tmp;
leftScrollPanel.addStyleName(css.getTreeLeftList());
middleScrollPanel.addStyleName(css.getTreeMiddleList());
rightScrollPanel.addStyleName(css.getTreeRightList());
Widget content = middleScrollPanel.getWidget();
if (content instanceof ListPanel) {
ListPanel list = (ListPanel) content;
selectionHandlerRegistration = list.addSelectionChangedHandler(selectionHandler);
}
}
});
}
private void shiftLeft(final ITree tree) {
if (hasBreadcrumb) {
String breadcrumb = breadcrumbLabel.getText();
int pos = breadcrumb.lastIndexOf(BREADCRUMB_DELIMITER);
if (pos > 1) {
breadcrumbLabel.setText(breadcrumb.substring(0, pos - 1));
}
}
final ListPanel list = (ListPanel) leftScrollPanel.getWidget();
populateList(list, tree.getParent());
middleScrollPanel.addStyleName(css.getSlide());
leftScrollPanel.addStyleName(css.getSlide());
middleScrollPanel.addStyleName(css.getRight());
leftScrollPanel.addStyleName(css.getRight());
Utils.addEventListenerOnce(middleScrollPanel.getElement(), Utils.getTransitionEventName(middleScrollPanel.getElement()), false, new EventListener() {
@Override
public void onBrowserEvent(Event event) {
if (!tree.getChildren().isEmpty() || (tree.getNode().getDisplay() == null)) {
// current tree node is no leaf or has no custom display -> there was a standard selection listener which must be removed
selectionHandlerRegistration.removeHandler();
}
middleScrollPanel.removeStyleName(css.getSlide());
leftScrollPanel.removeStyleName(css.getSlide());
middleScrollPanel.removeStyleName(css.getRight());
leftScrollPanel.removeStyleName(css.getRight());
leftScrollPanel.removeStyleName(css.getTreeLeftList());
middleScrollPanel.removeStyleName(css.getTreeMiddleList());
rightScrollPanel.removeStyleName(css.getTreeRightList());
// shift panels
ScrollPanelWithScrollbar tmp = rightScrollPanel;
rightScrollPanel = middleScrollPanel;
middleScrollPanel = leftScrollPanel;
leftScrollPanel = tmp;
leftScrollPanel.addStyleName(css.getTreeLeftList());
middleScrollPanel.addStyleName(css.getTreeMiddleList());
rightScrollPanel.addStyleName(css.getTreeRightList());
if (tree.getChildren().isEmpty() && (tree.getNode().getDisplay() != null)) {
// current tree node uses a custom display -> recreate list for new right scroll panel
rightScrollPanel.clear();
rightScrollPanel.add(new ListPanel());
}
selectionHandlerRegistration = list.addSelectionChangedHandler(selectionHandler);
}
});
}
private void populateList(ListPanel list, ITree tree) {
itemMap.clear();
list.clear();
List children = tree.getChildren();
for (ITree child : children) {
ITreeNode node = child.getNode();
ListItem item = null;
if (node.getIcon() != null) {
item = new DecoratedListItem(node.getIcon(), node.getHeader(), null);
} else {
item = new ListItem();
item.add(new Label(node.getHeader()));
}
item.setShowArrow(!child.getChildren().isEmpty());
if (node.getStyleName() != null) {
item.addStyleName(node.getStyleName());
}
list.add(item);
itemMap.put(item, child);
}
}
@Override
public void setHeight(String height) {
super.setHeight(height);
leftScrollPanel.setHeight(height);
rightScrollPanel.setHeight(height);
middleScrollPanel.setHeight(height);
}
private void navigateBack() {
if (selectedTree.getParent() != null) {
shiftLeft(selectedTree);
selectedTree = selectedTree.getParent();
TreeChangedEvent backEvent = new TreeChangedEvent(selectedTree, EventType.BACK_EVENT);
fireEvent(backEvent);
}
}
}