Package org.geomajas.gwt.client.controller.editing

Source Code of org.geomajas.gwt.client.controller.editing.EditController$GeometricInfoLabel

/*
* 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.gwt.client.controller.editing;

import org.geomajas.gwt.client.controller.AbstractSnappingController;
import org.geomajas.gwt.client.gfx.paintable.GfxGeometry;
import org.geomajas.gwt.client.gfx.style.ShapeStyle;
import org.geomajas.gwt.client.i18n.I18nProvider;
import org.geomajas.gwt.client.map.feature.FeatureTransaction;
import org.geomajas.gwt.client.map.feature.TransactionGeomIndex;
import org.geomajas.gwt.client.map.layer.VectorLayer;
import org.geomajas.gwt.client.spatial.Bbox;
import org.geomajas.gwt.client.spatial.geometry.Geometry;
import org.geomajas.gwt.client.spatial.geometry.GeometryFactory;
import org.geomajas.gwt.client.spatial.geometry.LinearRing;
import org.geomajas.gwt.client.spatial.geometry.Polygon;
import org.geomajas.gwt.client.util.DistanceFormat;
import org.geomajas.gwt.client.widget.MapWidget;
import org.geomajas.gwt.client.widget.MapWidget.RenderGroup;
import org.geomajas.gwt.client.widget.MapWidget.RenderStatus;

import com.smartgwt.client.types.VerticalAlignment;
import com.smartgwt.client.widgets.Label;
import com.smartgwt.client.widgets.events.ClickEvent;
import com.smartgwt.client.widgets.events.ClickHandler;
import com.smartgwt.client.widgets.menu.Menu;

/**
* Basic template for a controller that handles the editing of certain types of geometries.
*
* @author Pieter De Graef
*/
public abstract class EditController extends AbstractSnappingController {

  /**
   * When editing geometries, 2 editing modes exist: one in which you constantly add new points to the geometry
   * (INSERT_MODE), and one where you are free to move points, add or remove points etc (DRAG_MODE). This is the
   * definition of both modes.
   */
  public static enum EditMode {
    DRAG_MODE, INSERT_MODE
  }

  /**
   * Reference to a parent editing controller. Editing controllers support a hierarchical structure where a parent
   * delegates to the correct child EditController, depending on the circumstances.
   */
  protected EditController parent;

  /** The currently active editing modus. */
  private EditMode editMode;

  /** The current active context menu on the map. */
  protected Menu menu;

  /** Definition of the label that displays geometric information of the geometry that's currently being edited. */
  protected GeometricInfoLabel infoLabel;

  /** Option to show the maximum bounds wherein editing is allowed. */
  private boolean maxBoundsDisplayed;

  /** Paintable for the maximum bounds wherein editing is allowed. */
  private GfxGeometry maxExtent;

  // -------------------------------------------------------------------------
  // Constructor
  // -------------------------------------------------------------------------

  /**
   * Protected and only constructor. Extending classes must use this constructor.
   *
   * @param mapWidget
   *            Reference to the map widget on which editing is in progress.
   * @param parent
   *            The parent editing controller, or null if there is none.
   */
  protected EditController(MapWidget mapWidget, EditController parent) {
    super(mapWidget);
    this.parent = parent;
  }

  // -------------------------------------------------------------------------
  // Class specific functions:
  // -------------------------------------------------------------------------

  /**
   * Return a context menu specific for this editing controller instance.
   */
  public abstract Menu getContextMenu();

  /**
   * When creating a new feature, the controller must specify through a <code>TransactionGeomIndex</code> object,
   * where to begin adding coordinates in the geometry. The contents of this index will depend on the type of
   * geometric object the edit controller supports.
   *
   * @return
   */
  public abstract TransactionGeomIndex getGeometryIndex();

  /**
   * Set a new index at which inserting of points should happen.
   *
   * @param geometryIndex
   */
  public abstract void setGeometryIndex(TransactionGeomIndex geometryIndex);

  /**
   * Clean up all graphical stuff.
   */
  public abstract void cleanup();

  /**
   * True if this controller is busy. A busy controller should receive all subsequent mouse events until this method
   * returns false.
   *
   * @return true if busy
   */
  public abstract boolean isBusy();
 
  /**
   * Show an overview of geometric attributes of the geometry that's being edited.
   */
  public void showGeometricInfo() {
    FeatureTransaction ft = getFeatureTransaction();
    if (infoLabel == null && ft != null && ft.getNewFeatures() != null && ft.getNewFeatures().length > 0) {
      infoLabel = new GeometricInfoLabel();
      infoLabel.addClickHandler(new DestroyLabelInfoOnClick());
      infoLabel.setGeometry(ft.getNewFeatures()[0].getGeometry());
      infoLabel.animateMove(mapWidget.getWidth() - 155, 10);
    }
  }

  /**
   * Update the overview of geometric attributes of the geometry that's being edited.
   */
  public void updateGeometricInfo() {
    FeatureTransaction ft = getFeatureTransaction();
    if (infoLabel != null && ft != null && ft.getNewFeatures() != null && ft.getNewFeatures().length > 0) {
      infoLabel.setGeometry(ft.getNewFeatures()[0].getGeometry());
    }
  }

  /**
   * Hide the overview of geometric attributes.
   */
  public void hideGeometricInfo() {
    if (infoLabel != null) {
      infoLabel.destroy();
      infoLabel = null;
    }
  }

  // -------------------------------------------------------------------------
  // Getters and setters:
  // -------------------------------------------------------------------------

  /**
   * Reference to a parent editing controller. Editing controllers support a hierarchical structure where a parent
   * delegates to the correct child EditController, depending on the circumstances.
   */
  public EditController getParent() {
    return parent;
  }

  /** The currently active editing modus. */
  public EditMode getEditMode() {
    return editMode;
  }

  public void setEditMode(EditMode editMode) {
    this.editMode = editMode;
  }

  public GeometricInfoLabel getInfoLabel() {
    return infoLabel;
  }

  /** Should the maximum bounds wherein editing is allowed be rendered on the map or not? */
  public boolean isMaxBoundsDisplayed() {
    return maxBoundsDisplayed;
  }

  /**
   * Determine whether or not the maximum bounds wherein editing is allowed be rendered on the map.
   *
   * @param maxBoundsDisplayed
   *            The new value.
   */
  public void setMaxBoundsDisplayed(boolean maxBoundsDisplayed) {
    this.maxBoundsDisplayed = maxBoundsDisplayed;
  }

  // -------------------------------------------------------------------------
  // GraphicsController implementation:
  // -------------------------------------------------------------------------

  public void onActivate() {
    menu = getContextMenu();
    mapWidget.setContextMenu(menu);

    if (maxBoundsDisplayed) {
      VectorLayer layer = getFeatureTransaction().getLayer();
      GeometryFactory factory = mapWidget.getMapModel().getGeometryFactory();
      LinearRing hole = factory.createLinearRing(new Bbox(layer.getLayerInfo().getMaxExtent()));
      LinearRing shell = factory.createLinearRing(mapWidget.getMapModel().getMapView().getMaxBounds());
      Polygon polygon = factory.createPolygon(shell, new LinearRing[] { hole });

      maxExtent = new GfxGeometry("maxExtent");
      maxExtent.setGeometry(polygon);
      maxExtent.setStyle(new ShapeStyle("#000000", .6f, "#990000", 1, 2));
      mapWidget.registerWorldPaintable(maxExtent);
    }
  }

  public void onDeactivate() {
    if (maxExtent != null) {
      mapWidget.unregisterWorldPaintable(maxExtent);
    }
    if (getFeatureTransaction() != null) {
      mapWidget.render(getFeatureTransaction(), RenderGroup.VECTOR, RenderStatus.DELETE);
      mapWidget.getMapModel().getFeatureEditor().stopEditing();
    }
    if (menu != null) {
      menu.destroy();
      menu = null;
      mapWidget.setContextMenu(null);
    }
    hideGeometricInfo();
    cleanup();
  }

  // -------------------------------------------------------------------------
  // Protected helper methods:
  // -------------------------------------------------------------------------

  /**
   * Helper method to the FeatureTransaction.
   */
  protected FeatureTransaction getFeatureTransaction() {
    return mapWidget.getMapModel().getFeatureEditor().getFeatureTransaction();
  }

  // -------------------------------------------------------------------------
  // Private inner classes:
  // -------------------------------------------------------------------------

  /**
   * Label that displays some basic geometric information, such as length and area.
   *
   * @author Pieter De Graef
   */
  private class GeometricInfoLabel extends Label {

    private Geometry geometry;

    // Constructors:

    protected GeometricInfoLabel() {
      setParentElement(mapWidget);
      setValign(VerticalAlignment.TOP);
      setShowEdges(true);
      setWidth(145);
      setPadding(3);
      setLeft(mapWidget.getWidth() - 155);
      setTop(-80);
      setBackgroundColor("#FFFFFF");
      setAnimateTime(500);
    }

    // Getters and setters:

    public void setGeometry(Geometry geometry) {
      this.geometry = geometry;
      updateContents();
    }

    // Private methods:

    private void updateContents() {
      String contents = I18nProvider.getMenu().editGeometricInfoLabelTitle();
      if (geometry == null) {
        setContents(contents + I18nProvider.getMenu().editGeometricInfoLabelNoGeometry());
      } else {
        String area = DistanceFormat.asMapArea(mapWidget, geometry.getArea());
        String length = DistanceFormat.asMapLength(mapWidget, geometry.getLength());
        setContents(contents
            + I18nProvider.getMenu().editGeometricInfoLabelInfo(area, length, geometry.getNumPoints()));
      }
    }
  }

  /**
   * @author Pieter De Graef
   */
  private class DestroyLabelInfoOnClick implements ClickHandler {

    public void onClick(ClickEvent event) {
      infoLabel.destroy();
      infoLabel = null;
    }
  }
}
TOP

Related Classes of org.geomajas.gwt.client.controller.editing.EditController$GeometricInfoLabel

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.