Package org.geomajas.widget.advancedviews.client.widget

Source Code of org.geomajas.widget.advancedviews.client.widget.LayerTreeWithLegend$LayerTreeModalButton

/*
* This is part of Geomajas, a GIS framework, http://www.geomajas.org/.
*
* Copyright 2008-2011 Geosparc nv, http://www.geosparc.com/, Belgium.
*
* The program is available in open source according to the GNU Affero
* General Public License. All contributions in this program are covered
* by the Geomajas Contributors License Agreement. For full licensing
* details, see LICENSE.txt in the project root.
*/

package org.geomajas.widget.advancedviews.client.widget;

import java.util.ArrayList;
import java.util.List;

import org.geomajas.configuration.FeatureStyleInfo;
import org.geomajas.configuration.NamedStyleInfo;
import org.geomajas.configuration.client.ClientLayerInfo;
import org.geomajas.configuration.client.ClientLayerTreeInfo;
import org.geomajas.configuration.client.ClientLayerTreeNodeInfo;
import org.geomajas.configuration.client.ClientToolInfo;
import org.geomajas.global.Api;
import org.geomajas.gwt.client.action.ToolbarBaseAction;
import org.geomajas.gwt.client.action.layertree.LayerTreeAction;
import org.geomajas.gwt.client.action.layertree.LayerTreeModalAction;
import org.geomajas.gwt.client.action.layertree.LayerTreeRegistry;
import org.geomajas.gwt.client.map.event.LayerChangedHandler;
import org.geomajas.gwt.client.map.event.LayerFilteredEvent;
import org.geomajas.gwt.client.map.event.LayerFilteredHandler;
import org.geomajas.gwt.client.map.event.LayerLabeledEvent;
import org.geomajas.gwt.client.map.event.LayerShownEvent;
import org.geomajas.gwt.client.map.event.LayerStyleChangeEvent;
import org.geomajas.gwt.client.map.event.LayerStyleChangedHandler;
import org.geomajas.gwt.client.map.layer.Layer;
import org.geomajas.gwt.client.map.layer.RasterLayer;
import org.geomajas.gwt.client.map.layer.VectorLayer;
import org.geomajas.gwt.client.widget.MapWidget;
import org.geomajas.widget.advancedviews.client.AdvancedViewsMessages;
import org.geomajas.widget.advancedviews.client.util.LayerIconHelper;
import org.geomajas.widget.advancedviews.client.util.UrlBuilder;
import org.geomajas.widget.advancedviews.client.util.WidgetInfoHelper;
import org.geomajas.widget.advancedviews.configuration.client.LayerTreeWithLegendInfo;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.shared.HandlerRegistration;
import com.smartgwt.client.types.Alignment;
import com.smartgwt.client.types.SelectionType;
import com.smartgwt.client.widgets.Canvas;
import com.smartgwt.client.widgets.IButton;
import com.smartgwt.client.widgets.ImgButton;
import com.smartgwt.client.widgets.events.ClickEvent;
import com.smartgwt.client.widgets.events.ClickHandler;
import com.smartgwt.client.widgets.grid.ListGridRecord;
import com.smartgwt.client.widgets.layout.HLayout;
import com.smartgwt.client.widgets.layout.LayoutSpacer;
import com.smartgwt.client.widgets.tree.TreeGrid;
import com.smartgwt.client.widgets.tree.TreeNode;
import com.smartgwt.client.widgets.tree.events.LeafClickEvent;

/**
* A layertree widget with combined legend per layer.
*
* @author Kristof Heirwegh
* @since 1.0.0
*/
@Api
public class LayerTreeWithLegend extends LayerTreeBase {

  private static final String LEGEND_ICONS_PATH = "d/legendIcons";

  private static final String SHOW_LAYERINFO_ICON = "[ISOMORPHIC]/geomajas/silk/cog.png";

  private AdvancedViewsMessages messages = GWT.create(AdvancedViewsMessages.class);

  private static final String EXPANDED_ATTR = "isExpanded";

  private final MapWidget mapWidget;

  private final List<HandlerRegistration> registrations = new ArrayList<HandlerRegistration>();

  protected LayerTreeTreeNode rollOverLayerTreeNode;

  public LayerTreeWithLegend(final MapWidget mapWidget) {
    super(mapWidget);
    this.mapWidget = mapWidget;
    treeGrid.setShowRollOverCanvas(true);
  }

  public int getIconSize() {
    return treeGrid.getImageSize();
  }

  public void setIconSize(int iconSize) {
    treeGrid.setIconSize(iconSize);
  }

  /**
   * Processes a treeNode (add it to the TreeGrid).
   *
   * @param treeNode
   *            The treeNode to process
   * @param nodeRoot
   *            The root node to which the treeNode has to be added
   * @param refresh
   *            True if the tree is refreshed (causing it to keep its expanded
   *            state)
   */
  protected void processNode(final ClientLayerTreeNodeInfo treeNode, final TreeNode nodeRoot, final boolean refresh) {
    if (null != treeNode) {
      String treeNodeLabel = treeNode.getLabel();
      final TreeNode node = new TreeNode(treeNodeLabel);
      node.setAttribute(EXPANDED_ATTR, treeNode.isExpanded());
      tree.add(node, nodeRoot);

      // (final leafs)
      for (ClientLayerInfo info : treeNode.getLayers()) {
        Layer<?> layer = mapModel.getLayer(info.getId());
        LayerTreeLegendNode ltln = new LayerTreeLegendNode(this.tree, layer);
        tree.add(ltln, node);
        ltln.init();
      }

      // treeNodes
      List<ClientLayerTreeNodeInfo> childs = treeNode.getTreeNodes();
      for (ClientLayerTreeNodeInfo newNode : childs) {
        processNode(newNode, node, refresh);
      }
    }
  }

  /**
   * When a legendItem is selected, select the layer instead.
   */
  public void onLeafClick(LeafClickEvent event) {
    LayerTreeTreeNode layerTreeNode;
    if (event.getLeaf() instanceof LayerTreeLegendItemNode) {
      layerTreeNode = ((LayerTreeLegendItemNode) event.getLeaf()).parent;
      treeGrid.deselectRecord(event.getLeaf());
      treeGrid.selectRecord(layerTreeNode);
    } else {
      layerTreeNode = (LayerTreeTreeNode) event.getLeaf();
    }

    // -- update model
    mapModel.selectLayer(layerTreeNode.getLayer());
  }

  // ----------------------------------------------------------

  /**
   * Node with legend for LayerNode.
   */
  public class LayerTreeLegendNode extends LayerTreeTreeNode {

    public LayerTreeLegendNode(RefreshableTree tree, Layer<?> layer) {
      super(tree, layer);
    }

    public void init() {
      if (layer instanceof VectorLayer) {
        VectorLayer vl = (VectorLayer) layer;
        NamedStyleInfo nsi = vl.getLayerInfo().getNamedStyleInfo();
        for (FeatureStyleInfo fsi : nsi.getFeatureStyles()) {
          LayerTreeLegendItemNode tn = new LayerTreeLegendItemNode(this, vl.getServerLayerId(),
              nsi.getName(), fsi);
          tree.add(tn, this);
        }
      } else {
        RasterLayer rl = (RasterLayer) layer;
        LayerTreeLegendItemNode tn = new LayerTreeLegendItemNode(this, rl.getServerLayerId(),
            LayerIconHelper.getSmallLayerIconUrl(rl));
        tree.add(tn, this);
      }
    }
  }

  /**
   * Node which displays a legend icon + description.
   */
  public class LayerTreeLegendItemNode extends LayerTreeTreeNode {
    private LayerTreeLegendNode parent;
    private UrlBuilder url = new UrlBuilder(GWT.getHostPageBaseURL());

    // rasterlayer
    public LayerTreeLegendItemNode(LayerTreeLegendNode parent, String layerId, String rasterIconUrl) {
      super(parent.tree, parent.layer);
      this.parent = parent;
      setTitle(layer.getLabel());
      setName(parent.getAttribute("id") + "_legend");
      url.addPath(LEGEND_ICONS_PATH);
      url.addParameter("widgetId", LayerTreeWithLegend.this.getID());
      if (rasterIconUrl != null) {
        url.addParameter("styleName", rasterIconUrl);
      }
      url.addParameter("layerId", layerId);
      setIcon(url.toString());
    }

    // vectorlayer
    public LayerTreeLegendItemNode(LayerTreeLegendNode parent, String layerId, String styleName,
        FeatureStyleInfo fsi) {
      super(parent.tree, parent.layer);
      this.parent = parent;
      setName(fsi.getName());
      url.addPath(LEGEND_ICONS_PATH);
      url.addParameter("widgetId", LayerTreeWithLegend.this.getID());
      url.addParameter("layerId", layerId);
      url.addParameter("styleName", styleName);
      url.addParameter("featureStyleId", fsi.getStyleId());
      setIcon(url.toString());
    }

    @Override
    public void updateIcon() {
      // leave my icons alone!
    }

    public LayerTreeLegendNode getParent() {
      return parent;
    }

    public void setParent(LayerTreeLegendNode parent) {
      this.parent = parent;
    }
  }

  @Override
  protected void syncNodeState(boolean layersOnly) {
    for (TreeNode childnode : tree.getAllNodes(tree.getRoot())) {
      if (childnode instanceof LayerTreeLegendNode) {
        if (((LayerTreeLegendNode) childnode).layer.isShowing()) {
          tree.openFolder(childnode);
        } else {
          tree.closeFolder(childnode);
        }
      } else if (!layersOnly && !(childnode instanceof LayerTreeLegendItemNode)) {
        if (childnode.getAttributeAsBoolean(EXPANDED_ATTR)) {
          tree.openFolder(childnode);
        } else {
          tree.closeFolder(childnode);
        }
      }
    }
  }

  @Override
  protected TreeGrid createTreeGrid() {
    return createTreeGridInfoWindowRollover();
  }

  @Override
  protected void onIconClick(TreeNode node) {
    if (node instanceof LayerTreeLegendNode) {
      super.onIconClick(node);
    } else if (node instanceof TreeNode) {
      // TODO -- show/hide all layers in folder
      GWT.log("TODO");
    }
  }

  protected TreeGrid createTreeGridInfoWindowRollover() {
    return new TreeGrid() {
      private HLayout rollOverTools;
      private HLayout emptyRollOver;

      @Override
      protected Canvas getRollOverCanvas(Integer rowNum, Integer colNum) {
        if (rollOverTools == null) {
          rollOverTools = new HLayout();
          rollOverTools.setSnapTo("TR");
          rollOverTools.setWidth(25);
          rollOverTools.setHeight(LAYERTREEBUTTON_SIZE);
          emptyRollOver = new HLayout();
          emptyRollOver.setWidth(1);
          emptyRollOver.setHeight(LAYERTREEBUTTON_SIZE);

          ImgButton showInfo = new ImgButton();
          showInfo.setShowDown(false);
          showInfo.setShowRollOver(false);
          showInfo.setLayoutAlign(Alignment.CENTER);
          showInfo.setSrc(SHOW_LAYERINFO_ICON);
          showInfo.setPrompt(messages.layerTreeWithLegendLayerActionsToolTip());
          showInfo.setHeight(16);
          showInfo.setWidth(16);
          showInfo.addClickHandler(new ClickHandler() {
            public void onClick(ClickEvent event) {
              LayerActions la = new LayerActions(rollOverLayerTreeNode.getLayer());
              la.draw();
            }
          });
          rollOverTools.addMember(showInfo);
        }

        ListGridRecord lgr = this.getRecord(rowNum);
        if (lgr instanceof LayerTreeLegendItemNode) {
          rollOverLayerTreeNode = ((LayerTreeLegendItemNode) lgr).parent;
        } else if (lgr instanceof LayerTreeLegendNode) {
          rollOverLayerTreeNode = (LayerTreeTreeNode) lgr;
        } else {
          rollOverLayerTreeNode = null;
          rollOverTools.setVisible(false);
          return emptyRollOver;
        }

        rollOverTools.setVisible(true);
        return rollOverTools;
      }
    };
  }

  protected TreeGrid createTreeGridFullRollover() {
    return new TreeGrid() {
      private HLayout rollOverTools;
      private HLayout emptyRollOver;
      private Canvas[] toolButtons;

      @Override
      protected Canvas getRollOverCanvas(Integer rowNum, Integer colNum) {
        if (rollOverTools == null) {
          rollOverTools = new HLayout();
          rollOverTools.setSnapTo("TR");
          rollOverTools.setWidth(50);
          rollOverTools.setHeight(LAYERTREEBUTTON_SIZE);
          emptyRollOver = new HLayout();
          emptyRollOver.setWidth(1);
          emptyRollOver.setHeight(LAYERTREEBUTTON_SIZE);

          ClientLayerTreeInfo layerTreeInfo = mapModel.getMapInfo().getLayerTree();
          if (layerTreeInfo != null) {
            for (ClientToolInfo tool : layerTreeInfo.getTools()) {
              String id = tool.getId();
              IButton button = null;
              ToolbarBaseAction action = LayerTreeRegistry.getToolbarAction(id, mapWidget);
              if (action instanceof LayerTreeAction) {
                button = new LayerTreeButton(LayerTreeWithLegend.this, (LayerTreeAction) action);
              } else if (action instanceof LayerTreeModalAction) {
                button = new LayerTreeModalButton(LayerTreeWithLegend.this,
                    (LayerTreeModalAction) action);
              }
              if (button != null) {
                rollOverTools.addMember(button);
                LayoutSpacer spacer = new LayoutSpacer();
                spacer.setWidth(2);
                rollOverTools.addMember(spacer);
              }
            }
          }
          toolButtons = rollOverTools.getMembers();
        }

        ListGridRecord lgr = this.getRecord(rowNum);
        if (lgr instanceof LayerTreeLegendItemNode) {
          rollOverLayerTreeNode = ((LayerTreeLegendItemNode) lgr).parent;
        } else if (lgr instanceof LayerTreeLegendNode) {
          rollOverLayerTreeNode = (LayerTreeTreeNode) lgr;
        } else {
          rollOverLayerTreeNode = null;
          rollOverTools.setVisible(false);
          return emptyRollOver;
        }

        rollOverTools.setVisible(true);
        updateButtonIconsAndStates();
        return rollOverTools;
      }

      /**
       * Updates the icons and the state of the buttons in the toolbar
       * based upon the current layer
       *
       * @param toolStripMembers
       *            data for the toolbar
       */
      private void updateButtonIconsAndStates() {
        for (Canvas toolButton : toolButtons) {
          if (toolButton instanceof LayerTreeModalButton) {
            ((LayerTreeModalButton) toolButton).update();
          } else if (toolButton instanceof LayerTreeButton) {
            ((LayerTreeButton) toolButton).update();
          }
        }
      }
    };
  }

  /**
   * General definition of an action button for the layer tree.
   *
   * @author Frank Wynants
   * @author Pieter De Graef
   */
  private class LayerTreeButton extends IButton {

    private LayerTreeWithLegend tree;

    private LayerTreeAction action;

    public LayerTreeButton(final LayerTreeWithLegend tree, final LayerTreeAction action) {
      this.tree = tree;
      this.action = action;
      setWidth(LAYERTREEBUTTON_SIZE);
      setHeight(LAYERTREEBUTTON_SIZE);
      setIconSize(LAYERTREEBUTTON_SIZE - 8);
      setIcon(action.getIcon());
      setTooltip(action.getTooltip());
      setActionType(SelectionType.BUTTON);
      setShowDisabledIcon(false);
      addClickHandler(new ClickHandler() {
        public void onClick(ClickEvent event) {
          try {
            action.onClick(tree.rollOverLayerTreeNode.getLayer());
            update();
          } catch (Throwable t) {
            GWT.log("LayerTreeButton onClick error", t);
          }
        }
      });
    }

    public void update() {
      LayerTreeTreeNode selected = tree.rollOverLayerTreeNode;
      if (selected != null && action.isEnabled(selected.getLayer())) {
        setDisabled(false);
        setIcon(action.getIcon());
        setTooltip(action.getTooltip());
      } else {
        setDisabled(true);
        GWT.log("LayerTreeButton" + action.getDisabledIcon());
        setIcon(action.getDisabledIcon());
        setTooltip("");
      }
    }
  }

  /**
   * General definition of a modal button for the layer tree.
   *
   * @author Frank Wynants
   * @author Pieter De Graef
   */
  private class LayerTreeModalButton extends IButton {

    private LayerTreeWithLegend tree;

    private LayerTreeModalAction modalAction;

    /**
     * Constructor
     *
     * @param tree
     *            The currently selected layer
     * @param modalAction
     *            The action coupled to this button
     */
    public LayerTreeModalButton(final LayerTreeWithLegend tree, final LayerTreeModalAction modalAction) {
      this.tree = tree;
      this.modalAction = modalAction;
      setWidth(LAYERTREEBUTTON_SIZE);
      setHeight(LAYERTREEBUTTON_SIZE);
      setIconSize(LAYERTREEBUTTON_SIZE - 8);
      setIcon(modalAction.getDeselectedIcon());
      setActionType(SelectionType.CHECKBOX);
      setTooltip(modalAction.getDeselectedTooltip());
      setShowDisabledIcon(false);

      this.addClickHandler(new ClickHandler() {
        public void onClick(ClickEvent event) {
          LayerTreeTreeNode selectedLayerNode = tree.rollOverLayerTreeNode;
          if (LayerTreeModalButton.this.isSelected()) {
            modalAction.onSelect(selectedLayerNode.getLayer());
          } else {
            modalAction.onDeselect(selectedLayerNode.getLayer());
          }
          selectedLayerNode.updateIcon();
          update();
        }
      });
    }

    public void update() {
      LayerTreeTreeNode selected = tree.rollOverLayerTreeNode;
      if (selected != null && modalAction.isEnabled(selected.getLayer())) {
        setDisabled(false);
      } else {
        setSelected(false);
        setDisabled(true);
        GWT.log("LayerTreeModalButton" + modalAction.getDisabledIcon());
        setIcon(modalAction.getDisabledIcon());
        setTooltip("");
      }
      if (selected != null && modalAction.isSelected(selected.getLayer())) {
        setIcon(modalAction.getSelectedIcon());
        setTooltip(modalAction.getSelectedTooltip());
        select();
      } else if (selected != null) {
        setIcon(modalAction.getDeselectedIcon());
        setTooltip(modalAction.getDeselectedTooltip());
        deselect();
      }
    }
  }

  // -- part of legend

  @Override
  protected void initialize() {
    super.initialize();
    LayerTreeWithLegendInfo ltwli = WidgetInfoHelper.getClientWidgetInfo(LayerTreeWithLegendInfo.IDENTIFIER,
        mapWidget);
    setIconSize(ltwli == null ? DEFAULT_ICONSIZE : ltwli.getIconSize());

    for (Layer<?> layer : mapModel.getLayers()) {
      registrations.add(layer.addLayerChangedHandler(new LayerChangedHandler() {
        public void onLabelChange(LayerLabeledEvent event) {
          GWT.log("Legend: onLabelChange() - " + event.getLayer().getLabel());
          // find the node & update the icon
          for (TreeNode node : tree.getAllNodes()) {
            if (node.getName().equals(event.getLayer().getLabel())) {
              if (node instanceof LayerTreeTreeNode) {
                ((LayerTreeTreeNode) node).updateIcon();
              }
            }
          }
        }

        public void onVisibleChange(LayerShownEvent event) {
          GWT.log("Legend: onVisibleChange() - " + event.getLayer().getLabel());
          // find the node & update the icon
          for (TreeNode node : tree.getAllNodes()) {
            if (node.getName().equals(event.getLayer().getLabel())) {
              if (node instanceof LayerTreeTreeNode) {
                ((LayerTreeTreeNode) node).updateIcon();
              }
            }
          }
        }
      }));
      registrations.add(layer.addLayerStyleChangedHandler(new LayerStyleChangedHandler() {
        public void onLayerStyleChange(LayerStyleChangeEvent event) {
          GWT.log("Legend: onLayerStyleChange()");
          // TODO update layerstyles
        }
      }));
     
      if (layer instanceof VectorLayer) {
        VectorLayer vl = (VectorLayer) layer;
        registrations.add(vl.addLayerFilteredHandler(new LayerFilteredHandler() {
          public void onFilterChange(LayerFilteredEvent event) {
            GWT.log("Legend: onLayerFilterChange() - " + event.getLayer().getLabel());
            // find the node & update the icon
            for (TreeNode node : tree.getAllNodes()) {
              if (node.getName().equals(event.getLayer().getLabel())) {
                if (node instanceof LayerTreeTreeNode) {
                  ((LayerTreeTreeNode) node).updateIcon();
                }
              }
            }
          }
        }));
      }
    }
  }

  /** Remove all handlers on unload. */
  protected void onUnload() {
    if (registrations != null) {
      for (HandlerRegistration registration : registrations) {
        registration.removeHandler();
      }
    }
    super.onUnload();
  }
}
TOP

Related Classes of org.geomajas.widget.advancedviews.client.widget.LayerTreeWithLegend$LayerTreeModalButton

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.