
de.swm.commons.mobile.client.widgets.tree.WideTreePanel Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of swm-mobile Show documentation
Show all versions of swm-mobile Show documentation
GWT Bibliothek fuer Mobile Plattformen der SWM
/*
* 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.HTML;
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.ScrollPanel;
import de.swm.commons.mobile.client.widgets.tree.TreeChangedEvent.EventType;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class WideTreePanel extends PanelBase implements SwipeEventsHandler {
private static final String BREADCRUMB_DELIMITER = ">";
private final TreePanelCss css;
private final boolean hasBreadcrumb;
private Label breadcrumbLabel;
private ScrollPanel scrollPanel0;
private ScrollPanel scrollPanel1;
private ScrollPanel scrollPanel2;
private ScrollPanel scrollPanel3;
private HandlerRegistration handlerRegistration1;
private HandlerRegistration handlerRegistration2;
private final SelectionChangedHandler selectionHandler1;
private final SelectionChangedHandler selectionHandler2;
private ITree selectedTree;
private final Map itemMap = new HashMap();
public WideTreePanel() {
this(false);
}
@UiConstructor
public WideTreePanel(final 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.getWideTreeContainer());
add(container);
scrollPanel0 = new ScrollPanel();
scrollPanel0.addStyleName(css.getWideTreeList());
scrollPanel0.addStyleName(css.getWideTreeList0());
scrollPanel0.add(new ListPanel());
container.add(scrollPanel0);
scrollPanel1 = new ScrollPanel();
scrollPanel1.addStyleName(css.getWideTreeList());
scrollPanel1.addStyleName(css.getWideTreeList1());
scrollPanel1.add(new ListPanel());
container.add(scrollPanel1);
scrollPanel2 = new ScrollPanel();
scrollPanel2.addStyleName(css.getWideTreeList());
scrollPanel2.addStyleName(css.getWideTreeList2());
scrollPanel2.add(new ListPanel());
container.add(scrollPanel2);
scrollPanel3 = new ScrollPanel();
scrollPanel3.addStyleName(css.getWideTreeList());
scrollPanel3.addStyleName(css.getWideTreeList3());
scrollPanel3.add(new ListPanel());
container.add(scrollPanel3);
selectionHandler1 = new SelectionChangedHandler() {
@Override
public void onSelectionChanged(SelectionChangedEvent e) {
int selectedIdex = e.getSelection();
ListPanel list1 = (ListPanel) scrollPanel1.getWidget();
ListItem selectedItem = list1.getItem(selectedIdex);
ITree tree = itemMap.get(selectedItem);
if (tree != null) {
if (tree.getChildren().isEmpty() && tree.getNode().getDisplay() != null) {
// use custom display for leaf of tree
scrollPanel2.clear();
scrollPanel2.add(tree.getNode().getDisplay().asWidget());
tree.getNode().getDisplay().setNode(tree.getNode());
} else {
// use standard list to display children of left tree
ListPanel rightList = (ListPanel) scrollPanel2.getWidget();
populateList(rightList, tree);
}
selectedTree = tree;
clearSelectionState(list1);
selectedItem.addStyleName(css.getSelectedItem());
// set selected icon if specified by node
if ((selectedTree.getNode().getSelectedIcon() != null) && (selectedItem instanceof DecoratedListItem)) {
((DecoratedListItem) selectedItem).setImage(selectedTree.getNode().getSelectedIcon());
}
if (hasBreadcrumb) {
shortenBreadcrumb();
breadcrumbLabel.setText(breadcrumbLabel.getText() + " " + BREADCRUMB_DELIMITER + " " + tree.getNode().getHeader());
}
TreeChangedEvent event = new TreeChangedEvent(tree, EventType.CHILD_SELECTED);
fireEvent(event);
}
}
};
ListPanel list1 = (ListPanel) scrollPanel1.getWidget();
handlerRegistration1 = list1.addSelectionChangedHandler(selectionHandler1);
selectionHandler2 = new SelectionChangedHandler() {
@Override
public void onSelectionChanged(SelectionChangedEvent e) {
int selectedIdex = e.getSelection();
ListPanel list = (ListPanel) scrollPanel2.getWidget();
ListItem selectedItem = list.getItem(selectedIdex);
ITree tree = itemMap.get(selectedItem);
if (hasDetails(tree)) {
shiftRight(tree);
selectedTree = tree;
selectedItem.addStyleName(css.getSelectedItem());
// set selected icon if specified by node
if ((selectedTree.getNode().getSelectedIcon() != null) && (selectedItem instanceof DecoratedListItem)) {
((DecoratedListItem) selectedItem).setImage(selectedTree.getNode().getSelectedIcon());
}
}
if (tree != null) {
TreeChangedEvent event = new TreeChangedEvent(tree, EventType.CHILD_SELECTED);
fireEvent(event);
}
}
};
ListPanel list2 = (ListPanel) scrollPanel2.getWidget();
handlerRegistration2 = list2.addSelectionChangedHandler(selectionHandler2);
}
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) {
selectedTree = tree;
if (hasBreadcrumb) {
breadcrumbLabel.setText(tree.getNode().getHeader());
}
ListPanel list = (ListPanel) scrollPanel1.getWidget();
populateList(list, tree);
list = (ListPanel) scrollPanel2.getWidget();
clearListEntries(list, tree.getChildren().size(), getIconHeight(tree));
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
scrollPanel3.clear();
scrollPanel3.add(tree.getNode().getDisplay().asWidget());
tree.getNode().getDisplay().setNode(tree.getNode());
} else {
// use standard list to display children of tree
ListPanel rightList = (ListPanel) scrollPanel3.getWidget();
populateList(rightList, tree);
}
ListPanel leftList = (ListPanel) scrollPanel1.getWidget();
removeItemsFromMap(leftList);
scrollPanel3.addStyleName(css.getSlide());
scrollPanel2.addStyleName(css.getSlide());
scrollPanel1.addStyleName(css.getSlide());
scrollPanel3.addStyleName(css.getLeft());
scrollPanel2.addStyleName(css.getWideLeft());
scrollPanel1.addStyleName(css.getLeft());
Utils.addEventListenerOnce(scrollPanel3.getElement(), Utils.getTransitionEventName(scrollPanel3.getElement()), false, new EventListener() {
@Override
public void onBrowserEvent(Event event) {
handlerRegistration1.removeHandler();
handlerRegistration2.removeHandler();
scrollPanel3.removeStyleName(css.getSlide());
scrollPanel2.removeStyleName(css.getSlide());
scrollPanel1.removeStyleName(css.getSlide());
scrollPanel3.removeStyleName(css.getLeft());
scrollPanel2.removeStyleName(css.getWideLeft());
scrollPanel1.removeStyleName(css.getLeft());
scrollPanel0.removeStyleName(css.getWideTreeList0());
scrollPanel1.removeStyleName(css.getWideTreeList1());
scrollPanel2.removeStyleName(css.getWideTreeList2());
scrollPanel3.removeStyleName(css.getWideTreeList3());
// shift panels
ScrollPanel tmp = scrollPanel0;
scrollPanel0 = scrollPanel1;
scrollPanel1 = scrollPanel2;
scrollPanel2 = scrollPanel3;
scrollPanel3 = tmp;
scrollPanel0.addStyleName(css.getWideTreeList0());
scrollPanel1.addStyleName(css.getWideTreeList1());
scrollPanel2.addStyleName(css.getWideTreeList2());
scrollPanel3.addStyleName(css.getWideTreeList3());
ListPanel list1 = (ListPanel) scrollPanel1.getWidget();
handlerRegistration1 = list1.addSelectionChangedHandler(selectionHandler1);
Widget rightContent = scrollPanel2.getWidget();
if (rightContent instanceof ListPanel) {
ListPanel list = (ListPanel) rightContent;
handlerRegistration2 = list.addSelectionChangedHandler(selectionHandler2);
}
}
});
}
private void shiftLeft(final ITree tree, final ITree rightTree) {
shortenBreadcrumb();
ListPanel parentList = (ListPanel) scrollPanel0.getWidget();
populateList(parentList, tree.getParent());
updateSelectionState(parentList);
ListPanel childList = (ListPanel) scrollPanel1.getWidget();
clearSelectionState(childList);
if (!rightTree.getChildren().isEmpty() || (rightTree.getNode().getDisplay() == null)) {
// current child tree node is no leaf or has no custom display -> remove standard list items from map
ListPanel grandchildrenList = (ListPanel) scrollPanel2.getWidget();
removeItemsFromMap(grandchildrenList);
}
scrollPanel0.addStyleName(css.getSlide());
scrollPanel1.addStyleName(css.getSlide());
scrollPanel2.addStyleName(css.getSlide());
scrollPanel0.addStyleName(css.getRight());
scrollPanel1.addStyleName(css.getWideRight());
scrollPanel2.addStyleName(css.getRight());
Utils.addEventListenerOnce(scrollPanel1.getElement(), Utils.getTransitionEventName(scrollPanel1.getElement()), false, new EventListener() {
@Override
public void onBrowserEvent(Event event) {
handlerRegistration1.removeHandler();
if (!rightTree.getChildren().isEmpty() || (rightTree.getNode().getDisplay() == null)) {
// current child tree node is no leaf or has no custom display -> there was a standard selection listener which must be removed
handlerRegistration2.removeHandler();
}
scrollPanel0.removeStyleName(css.getSlide());
scrollPanel1.removeStyleName(css.getSlide());
scrollPanel2.removeStyleName(css.getSlide());
scrollPanel0.removeStyleName(css.getRight());
scrollPanel1.removeStyleName(css.getWideRight());
scrollPanel2.removeStyleName(css.getRight());
scrollPanel0.removeStyleName(css.getWideTreeList0());
scrollPanel1.removeStyleName(css.getWideTreeList1());
scrollPanel2.removeStyleName(css.getWideTreeList2());
scrollPanel3.removeStyleName(css.getWideTreeList3());
// shift panels
ScrollPanel tmp = scrollPanel3;
scrollPanel3 = scrollPanel2;
scrollPanel2 = scrollPanel1;
scrollPanel1 = scrollPanel0;
scrollPanel0 = tmp;
scrollPanel0.addStyleName(css.getWideTreeList0());
scrollPanel1.addStyleName(css.getWideTreeList1());
scrollPanel2.addStyleName(css.getWideTreeList2());
scrollPanel3.addStyleName(css.getWideTreeList3());
ListPanel list1 = (ListPanel) scrollPanel1.getWidget();
handlerRegistration1 = list1.addSelectionChangedHandler(selectionHandler1);
ListPanel list2 = (ListPanel) scrollPanel2.getWidget();
handlerRegistration2 = list2.addSelectionChangedHandler(selectionHandler2);
if (rightTree.getChildren().isEmpty() && (rightTree.getNode().getDisplay() != null)) {
// current tree child node uses a custom display -> recreate list for new far right scroll panel
scrollPanel3.clear();
scrollPanel3.add(new ListPanel());
}
}
});
}
private void shortenBreadcrumb() {
if (hasBreadcrumb) {
String breadcrumb = breadcrumbLabel.getText();
int pos = breadcrumb.lastIndexOf(BREADCRUMB_DELIMITER);
if (pos > 1) {
breadcrumbLabel.setText(breadcrumb.substring(0, pos - 1));
}
}
}
private void updateSelectionState(ListPanel list) {
if (selectedTree != null) {
String selectedHeader = selectedTree.getNode().getHeader();
for (int i = 0; i < list.getWidgetCount(); i++) {
ListItem item = list.getItem(i);
ITree t = itemMap.get(item);
if (t != null) {
if (selectedHeader.equals(t.getNode().getHeader())) {
item.addStyleName(css.getSelectedItem());
// set selected icon if specified by node
if ((t.getNode().getSelectedIcon() != null) && (item instanceof DecoratedListItem)) {
DecoratedListItem decoratedItem = (DecoratedListItem) item;
decoratedItem.setImage(t.getNode().getSelectedIcon());
}
}
}
}
}
}
private void clearSelectionState(ListPanel list) {
for (int i = 0; i < list.getWidgetCount(); i++) {
ListItem item = list.getItem(i);
item.removeStyleName(css.getSelectedItem());
// set normal icon if specified by node
ITree t = itemMap.get(item);
if ((t != null) && (t.getNode().getIcon() != null) && (item instanceof DecoratedListItem)) {
DecoratedListItem decoratedItem = (DecoratedListItem) item;
decoratedItem.setImage(t.getNode().getIcon());
}
}
}
private void populateList(ListPanel list, ITree tree) {
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);
}
}
private void clearListEntries(ListPanel list, int num, int iconHeight) {
list.clear();
for (int i = 0; i < num; i++) {
ListItem item = null;
if (iconHeight > 0) {
item = new DecoratedListItem();
item.setTitle(" ");
((DecoratedListItem) item).getImage().setPixelSize(0, iconHeight);
} else {
item = new ListItem();
item.add(new HTML(" "));
}
item.setShowArrow(false);
list.add(item);
}
}
private void removeItemsFromMap(ListPanel list) {
for (int i = 0; i < list.getWidgetCount(); i++) {
ListItem item = list.getItem(i);
if (item != null) {
itemMap.remove(item);
}
}
}
private int getIconHeight(ITree tree) {
List children = tree.getChildren();
for (ITree child : children) {
ITreeNode node = child.getNode();
if (node.getIcon() != null) {
return node.getIcon().getHeight();
}
}
return -1;
}
private void navigateBack() {
if (selectedTree.getParent() != null) {
ITree child = selectedTree;
selectedTree = selectedTree.getParent();
if (selectedTree.getParent() != null) { // another back step possible
shiftLeft(selectedTree, child);
} else { // next step is root of tree
shortenBreadcrumb();
ListPanel list = (ListPanel) scrollPanel1.getWidget();
clearSelectionState(list);
list = (ListPanel) scrollPanel2.getWidget();
clearListEntries(list, selectedTree.getChildren().size(), getIconHeight(selectedTree));
}
TreeChangedEvent backEvent = new TreeChangedEvent(selectedTree, EventType.BACK_EVENT);
fireEvent(backEvent);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy