Package org.geoforge.worldwind.builder

Source Code of org.geoforge.worldwind.builder.GfrBldObjDrgShpSct$RegionShape

/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package org.geoforge.worldwind.builder;

import gov.nasa.worldwind.Movable;
import gov.nasa.worldwind.View;
import gov.nasa.worldwind.avlist.AVKey;
import gov.nasa.worldwind.awt.WorldWindowGLCanvas;
import gov.nasa.worldwind.event.*;
import gov.nasa.worldwind.geom.*;
import gov.nasa.worldwind.globes.EllipsoidalGlobe;
import gov.nasa.worldwind.layers.LayerList;
import gov.nasa.worldwind.layers.RenderableLayer;
import gov.nasa.worldwind.pick.PickedObject;
import gov.nasa.worldwind.pick.PickedObjectList;
import gov.nasa.worldwind.render.*;
import gov.nasa.worldwind.util.Logging;
import java.awt.Color;
import java.awt.Component;
import java.awt.Cursor;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import java.awt.geom.Point2D;
import java.beans.PropertyChangeListener;
import java.util.ArrayList;

/**
*
* @author bantchao@gmail.com
*
* based on wwdw's SectorSelector.java
*/
public class GfrBldObjDrgShpSct extends GfrBldObjAbs implements
        SelectListener,
        MouseMotionListener,
        RenderingListener
{
   
   final static public String STR_SECTOR_PROPERTY = "gov.nasa.worldwind.SectorSelector";

    final static private int _INT_NONE_ = 0;

    final static private int _INT_MOVING_ = 1;
    final static private int _INT_SIZING_ = 2;

    final static private int _INT_NORTH_ = 1;
    final static private int _INT_SOUTH_ = 2;
    final static private int _INT_EAST_ = 4;
    final static private int _INT_WEST_ = 8;
    final static private int _INT_NORTHWEST_ = _INT_NORTH_ + _INT_WEST_;
    final static private int _INT_NORTHEAST_ = _INT_NORTH_ + _INT_EAST_;
    final static private int _INT_SOUTHWEST_ = _INT_SOUTH_ + _INT_WEST_;
    final static private int _INT_SOUTHEAST_ = _INT_SOUTH_ + _INT_EAST_;
   
   
    static private double _s_getValueAbslute_(double a)
    {
        return a >= 0 ? a : -a;
    }
   
   
    // ---
  
    private /*final*/ RegionShape _rgeShape_ = null;

    private double _dblEdgeFactor_ = 0.10;

    // state tracking fields
    private boolean _blnIsArmed_ = false;
    private int _intOperation_ = _INT_NONE_;
    private int _intSide_ = _INT_NONE_;
    private Position _posPrevious_ = null;
    private Sector previousSector = null;
   
   
    @Override
   public void setReady(boolean bln)
   {
      if (bln)
         _enable_();
      else
         _disable_();
   }
   
    @Override
   public Object getValue()
   {
      Sector sec = this._getSector_();
     
      if (sec == null)
         return (ArrayList<Point2D.Double>) null;
     
      Angle angMinLat = sec.getMinLatitude();
      Angle angMinLon = sec.getMinLongitude();
      Angle angMaxLat = sec.getMaxLatitude();
      Angle angMaxLon = sec.getMaxLongitude();
     
      LatLon llnMin = new LatLon(angMinLat, angMinLon);
      LatLon llnMax = new LatLon(angMaxLat, angMaxLon);
     
      ArrayList<LatLon> lstSecMinMax = new ArrayList<LatLon>();
      lstSecMinMax.add(llnMin);
      lstSecMinMax.add(llnMax);
     
      return lstSecMinMax;
   }
   
   
  
   public GfrBldObjDrgShpSct(
           WorldWindowGLCanvas glcWwd,
           PropertyChangeListener lstPropertyChange
           )
   {
      super(glcWwd);
     
  

      // ---
      this._rgeShape_ = new RegionShape();
     
     
      ((RenderableLayer) this._rlr).addRenderable(this._rgeShape_);
     
      if (lstPropertyChange != null)
          super.addPropertyChangeListener(lstPropertyChange);
   }
  
   @Override
   public boolean init()
   {
      return true;
   }
  
   //
    // Selection events are used to resize and move the region
    //
    @Override
    public void selected(SelectEvent evtSelect)
    {
        if (evtSelect == null)
        {
            String msg = Logging.getMessage("nullValue.EventIsNull");
            Logging.logger().log(java.util.logging.Level.FINE, msg);
            throw new IllegalArgumentException(msg);
        }

        if (this._intOperation_ == _INT_NONE_ &&
            evtSelect.getTopObject() != null &&
            !(evtSelect.getTopPickedObject().getParentLayer() == this._rlr)
                )
        {
            this._setCursor_(null);
            return;
        }

        if (evtSelect.getEventAction().equals(SelectEvent.LEFT_PRESS))
        {
            this._posPrevious_ = super._glcWwd.getCurrentPosition();
        }
       
        else if (evtSelect.getEventAction().equals(SelectEvent.DRAG))
        {
            DragSelectEvent dragEvent = (DragSelectEvent) evtSelect;
            Object topObject = dragEvent.getTopObject();
            if (topObject == null)
                return;

            RegionShape dragObject = this._rgeShape_;

            if (this._intOperation_ == _INT_SIZING_)
            {
                Sector newSector = this._resizeShape_(dragObject, this._intSide_);
               
                if (newSector != null)
                    dragObject.setSector(newSector);
               
                evtSelect.consume();
            }
            else
            {
                this._intSide_ = this._determineAdjustmentSide_(dragObject, this._dblEdgeFactor_);

                if (this._intSide_ == _INT_NONE_ || this._intOperation_ == _INT_MOVING_)
                {
                    this._intOperation_ = _INT_MOVING_;
                    this._dragWholeShape_(dragEvent, dragObject);
                }
                else
                {
                    Sector newSector = this._resizeShape_(dragObject, this._intSide_);
                   
                    if (newSector != null)
                        dragObject.setSector(newSector);
                   
                    this._intOperation_ = _INT_SIZING_;
                }
                evtSelect.consume();
            }

            this._posPrevious_ = super._glcWwd.getCurrentPosition();
            this._notifySectorChanged_();
        }
       
        else if (evtSelect.getEventAction().equals(SelectEvent.DRAG_END))
        {
            this._intOperation_ = _INT_NONE_;
            this._posPrevious_ = null;
        }
       
        else if (evtSelect.getEventAction().equals(SelectEvent.ROLLOVER) && this._intOperation_ == _INT_NONE_)
        {
            if (!(super._glcWwd instanceof Component))
                return;

            if (evtSelect.getTopObject() == null || evtSelect.getTopPickedObject().isTerrain())
            {
                this._setCursor_(null);
                return;
            }

            if (!(evtSelect.getTopObject() instanceof Movable))
                return;

            this._setCursor_(this._determineAdjustmentSide_((Movable) evtSelect.getTopObject(), this._dblEdgeFactor_));
        }
    }

  

   @Override
   public void mousePressed(MouseEvent evtMouse)
   {
      if (MouseEvent.BUTTON1_DOWN_MASK != evtMouse.getModifiersEx())
            return;

        if (! this._blnIsArmed_)
            return;

        this._rgeShape_.setResizeable(true);
        this._rgeShape_.setStartPosition(null);

        this._blnIsArmed_ = false;

        evtMouse.consume();
   }

   @Override
   public void mouseReleased(MouseEvent evtMouse)
   {
      if (MouseEvent.BUTTON1 != evtMouse.getButton())
            return;

        if (this._rgeShape_.isResizeable())
            this._setCursor_(null);

        this._rgeShape_.setResizeable(false);

        evtMouse.consume(); // prevent view operations

        this.firePropertyChange(STR_SECTOR_PROPERTY, this.previousSector, null);
   }

 

   @Override
   public void mouseDragged(MouseEvent evtMouse)
   {
      if (MouseEvent.BUTTON1_DOWN_MASK != evtMouse.getModifiersEx())
            return;

        if (this._rgeShape_.isResizeable())
            evtMouse.consume(); // prevent view operations
   }

   @Override
   public void mouseMoved(MouseEvent e) {}

   @Override
   public void stageChanged(RenderingEvent evtRendering)
   {
      if (!evtRendering.getStage().equals(RenderingEvent.AFTER_BUFFER_SWAP))
            return;

        // We notify of changes during this rendering stage because the sector is updated within the region shape's
        // render method.

        this._notifySectorChanged_();
   }
  
   private void _setCursor_(Cursor cursor)
    {
        ((Component) super._glcWwd).setCursor(cursor != null ? cursor : Cursor.getDefaultCursor());
    }
  
   private Sector _getSector_()
    {
        return this._rgeShape_.hasSelection() ? this._rgeShape_.getSector() : null;
        // TODO: Determine how to handle date-line spanning sectors.
    }
  
   private void _enable_()
    {
        this._rgeShape_.setStartPosition(null);

        LayerList layers = super._glcWwd.getModel().getLayers();

        if (!layers.contains(super._rlr))
            layers.add(super._rlr);

        if (! super._rlr.isEnabled())
            super._rlr.setEnabled(true);

   
        this._blnIsArmed_ = true;

        super._glcWwd.addRenderingListener(this);
        super._glcWwd.addSelectListener(this);
        super._glcWwd.getInputHandler().addMouseListener(this);
        super._glcWwd.getInputHandler().addMouseMotionListener(this);

        this._setCursor_(Cursor.getPredefinedCursor(Cursor.CROSSHAIR_CURSOR));
    }

    private void _disable_()
    {
        super._glcWwd.removeRenderingListener(this);
        super._glcWwd.removeSelectListener(this);
        super._glcWwd.getInputHandler().removeMouseListener(this);
        super._glcWwd.getInputHandler().removeMouseMotionListener(this);

        super._glcWwd.getModel().getLayers().remove(super._rlr);

        this._rgeShape_.clear();
    }
  
   private Sector _resizeShape_(Movable dragObject, int side)
    {
        if (dragObject instanceof SurfaceSector)
        {
            SurfaceSector quad = (SurfaceSector) dragObject;
            Sector s = quad.getSector(); // TODO: go over all sectors
            Position p = super._glcWwd.getCurrentPosition();

            if (p == null || this._posPrevious_ == null)
            {
                return null;
            }

            Angle dLat = p.getLatitude().subtract(this._posPrevious_.getLatitude());
            Angle dLon = p.getLongitude().subtract(this._posPrevious_.getLongitude());

            Angle newMinLat = s.getMinLatitude();
            Angle newMinLon = s.getMinLongitude();
            Angle newMaxLat = s.getMaxLatitude();
            Angle newMaxLon = s.getMaxLongitude();

            if (side == _INT_NORTH_)
            {
                newMaxLat = s.getMaxLatitude().add(dLat);
            }
            else if (side == _INT_SOUTH_)
            {
                newMinLat = s.getMinLatitude().add(dLat);
            }
            else if (side == _INT_EAST_)
            {
                newMaxLon = s.getMaxLongitude().add(dLon);
            }
            else if (side == _INT_WEST_)
            {
                newMinLon = s.getMinLongitude().add(dLon);
            }
            else if (side == _INT_NORTHWEST_)
            {
                newMaxLat = s.getMaxLatitude().add(dLat);
                newMinLon = s.getMinLongitude().add(dLon);
            }
            else if (side == _INT_NORTHEAST_)
            {
                newMaxLat = s.getMaxLatitude().add(dLat);
                newMaxLon = s.getMaxLongitude().add(dLon);
            }
            else if (side == _INT_SOUTHWEST_)
            {
                newMinLat = s.getMinLatitude().add(dLat);
                newMinLon = s.getMinLongitude().add(dLon);
            }
            else if (side == _INT_SOUTHEAST_)
            {
                newMinLat = s.getMinLatitude().add(dLat);
                newMaxLon = s.getMaxLongitude().add(dLon);
            }

            return new Sector(newMinLat, newMaxLat, newMinLon, newMaxLon);
        }

        return null;
    }

  

  
   private int _determineAdjustmentSide_(Movable dragObject, double factor)
    {
        if (dragObject instanceof SurfaceSector)
        {
            SurfaceSector quad = (SurfaceSector) dragObject;
            Sector s = quad.getSector(); // TODO: go over all sectors
            Position p = super._glcWwd.getCurrentPosition();

            if (p == null)
            {
                return _INT_NONE_;
            }

            double dN = _s_getValueAbslute_(s.getMaxLatitude().subtract(p.getLatitude()).degrees);
            double dS = _s_getValueAbslute_(s.getMinLatitude().subtract(p.getLatitude()).degrees);
            double dW = _s_getValueAbslute_(s.getMinLongitude().subtract(p.getLongitude()).degrees);
            double dE = _s_getValueAbslute_(s.getMaxLongitude().subtract(p.getLongitude()).degrees);

            double sLat = factor * s.getDeltaLatDegrees();
            double sLon = factor * s.getDeltaLonDegrees();

            if (dN < sLat && dW < sLon)
                return _INT_NORTHWEST_;
            if (dN < sLat && dE < sLon)
                return _INT_NORTHEAST_;
            if (dS < sLat && dW < sLon)
                return _INT_SOUTHWEST_;
            if (dS < sLat && dE < sLon)
                return _INT_SOUTHEAST_;
            if (dN < sLat)
                return _INT_NORTH_;
            if (dS < sLat)
                return _INT_SOUTH_;
            if (dW < sLon)
                return _INT_WEST_;
            if (dE < sLon)
                return _INT_EAST_;
        }

        return _INT_NONE_;
    }
  
   private void _dragWholeShape_(DragSelectEvent dragEvent, Movable dragObject)
    {
        View view = super._glcWwd.getView();
        EllipsoidalGlobe globe = (EllipsoidalGlobe) super._glcWwd.getModel().getGlobe();

        // Compute ref-point position in screen coordinates.
        Position refPos = dragObject.getReferencePosition();
        if (refPos == null)
            return;

        Vec4 refPoint = globe.computePointFromPosition(refPos);
        Vec4 screenRefPoint = view.project(refPoint);

        // Compute screen-coord delta since last event.
        int dx = dragEvent.getPickPoint().x - dragEvent.getPreviousPickPoint().x;
        int dy = dragEvent.getPickPoint().y - dragEvent.getPreviousPickPoint().y;

        // Find intersection of screen coord ref-point with globe.
        double x = screenRefPoint.x + dx;
        double y = dragEvent.getMouseEvent().getComponent().getSize().height - screenRefPoint.y + dy - 1;
        Line ray = view.computeRayFromScreenPoint(x, y);
        Intersection inters[] = globe.intersect(ray, refPos.getElevation());

        if (inters != null)
        {
            // Intersection with globe. Move reference point to the intersection point.
            Position p = globe.computePositionFromPoint(inters[0].getIntersectionPoint());
            dragObject.moveTo(p);
        }
    }

   private void _setCursor_(int sideName)
    {
        Cursor cursor = null;

        switch (sideName)
        {
            case _INT_NONE_:
                cursor = Cursor.getPredefinedCursor(Cursor.HAND_CURSOR);
                break;
            case _INT_NORTH_:
                cursor = Cursor.getPredefinedCursor(Cursor.N_RESIZE_CURSOR);
                break;
            case _INT_SOUTH_:
                cursor = Cursor.getPredefinedCursor(Cursor.S_RESIZE_CURSOR);
                break;
            case _INT_EAST_:
                cursor = Cursor.getPredefinedCursor(Cursor.E_RESIZE_CURSOR);
                break;
            case _INT_WEST_:
                cursor = Cursor.getPredefinedCursor(Cursor.W_RESIZE_CURSOR);
                break;
            case _INT_NORTHWEST_:
                cursor = Cursor.getPredefinedCursor(Cursor.NW_RESIZE_CURSOR);
                break;
            case _INT_NORTHEAST_:
                cursor = Cursor.getPredefinedCursor(Cursor.NE_RESIZE_CURSOR);
                break;
            case _INT_SOUTHWEST_:
                cursor = Cursor.getPredefinedCursor(Cursor.SW_RESIZE_CURSOR);
                break;
            case _INT_SOUTHEAST_:
                cursor = Cursor.getPredefinedCursor(Cursor.SE_RESIZE_CURSOR);
                break;
        }

        this._setCursor_(cursor);
    }
  
  
  
   private void _notifySectorChanged_()
    {
        if (this._rgeShape_.hasSelection() &&
            this._getSector_() != null &&
            !this._getSector_().equals(this.previousSector))
        {
            this.firePropertyChange(STR_SECTOR_PROPERTY, this.previousSector, this._rgeShape_.getSector());
            this.previousSector = this._getSector_();
        }
    }

  

  
  
  
  
   // beg inner-class
  
   protected static class RegionShape extends SurfaceSector
    {
        private boolean resizeable = false;
        private Position startPosition;
        private Position endPosition;
        private SurfaceSector borderShape;

        protected RegionShape()
        {
            super(Sector.EMPTY_SECTOR);
           
            // Create the default border shape.
            this.setBorder(new SurfaceSector(sector));

            // The edges of the region shape should be constant lines of latitude and longitude.
            this.setPathType(AVKey.LINEAR);
            this.getBorder().setPathType(AVKey.LINEAR);

            // Setup default interior rendering attributes. Note that the interior rendering attributes are
            // configured so only the SurfaceSector's interior is rendered.
            ShapeAttributes interiorAttrs = new BasicShapeAttributes();
            interiorAttrs.setDrawOutline(false);
            interiorAttrs.setInteriorMaterial(new Material(Color.WHITE));
            interiorAttrs.setInteriorOpacity(0.1);
            this.setAttributes(interiorAttrs);
            this.setHighlightAttributes(interiorAttrs);

            // Setup default border rendering attributes. Note that the border rendering attributes are configured
            // so that only the SurfaceSector's outline is rendered.
            ShapeAttributes borderAttrs = new BasicShapeAttributes();
            borderAttrs.setDrawInterior(false);
            borderAttrs.setOutlineMaterial(new Material(Color.RED));
            borderAttrs.setOutlineOpacity(0.7);
            borderAttrs.setOutlineWidth(3);
            this.getBorder().setAttributes(borderAttrs);
            this.getBorder().setHighlightAttributes(borderAttrs);
           
            // ---
            Color colSInteriorShape = new Color(1f, 1f, 1f, 0.1f);
            setInteriorColor(colSInteriorShape);
            Color colBorderShape = new Color(1f, 0f, 0f, 0.5f);
            setBorderColor(colBorderShape);
            double dblWidthShape = 3d;
            setBorderWidth(dblWidthShape);
        }

        public Color getInteriorColor()
        {
            return this.getAttributes().getInteriorMaterial().getDiffuse();
        }

        public void setInteriorColor(Color color)
        {
            ShapeAttributes attr = this.getAttributes();
            attr.setInteriorMaterial(new Material(color));
            this.setAttributes(attr);
        }

        public Color getBorderColor()
        {
            return this.getBorder().getAttributes().getOutlineMaterial().getDiffuse();
        }

        public void setBorderColor(Color color)
        {
            ShapeAttributes attr = this.getBorder().getAttributes();
            attr.setOutlineMaterial(new Material(color));
            this.getBorder().setAttributes(attr);
        }

        public double getInteriorOpacity()
        {
            return this.getAttributes().getInteriorOpacity();
        }

        public void setInteriorOpacity(double opacity)
        {
            ShapeAttributes attr = this.getAttributes();
            attr.setInteriorOpacity(opacity);
            this.setAttributes(attr);
        }

        public double getBorderOpacity()
        {
            return this.getBorder().getAttributes().getOutlineOpacity();
        }

        public void setBorderOpacity(double opacity)
        {
            ShapeAttributes attr = this.getBorder().getAttributes();
            attr.setOutlineOpacity(opacity);
            this.getBorder().setAttributes(attr);
        }

        public double getBorderWidth()
        {
            return this.getBorder().getAttributes().getOutlineWidth();
        }

        public void setBorderWidth(double width)
        {
            ShapeAttributes attr = this.getBorder().getAttributes();
            attr.setOutlineWidth(width);
            this.getBorder().setAttributes(attr);
        }

      @Override
        public void setSector(Sector secNew)
        {
            super.setSector(secNew);
            this.getBorder().setSector(secNew);
        }

        protected boolean isResizeable()
        {
            return resizeable;
        }

        protected void setResizeable(boolean resizeable)
        {
            this.resizeable = resizeable;
        }

        protected Position getStartPosition()
        {
            return startPosition;
        }

        protected void setStartPosition(Position startPosition)
        {
            this.startPosition = startPosition;
        }

        protected Position getEndPosition()
        {
            return endPosition;
        }

        protected void setEndPosition(Position endPosition)
        {
            this.endPosition = endPosition;
        }

        protected SurfaceSector getBorder()
        {
            return borderShape;
        }

        protected void setBorder(SurfaceSector shape)
        {
            if (shape == null)
            {
                String message = Logging.getMessage("nullValue.Shape");
                Logging.logger().severe(message);
                throw new IllegalArgumentException(message);
            }

            this.borderShape = shape;
        }

        protected boolean hasSelection()
        {
            return getStartPosition() != null && getEndPosition() != null;
        }

        protected void clear()
        {
            this.setStartPosition(null);
            this.setEndPosition(null);
            this.setSector(Sector.EMPTY_SECTOR);
        }

      @Override
        public void preRender(DrawContext dc)
        {
            // This is called twice: once during normal rendering, then again during ordered surface rendering. During
            // normal renering we pre-render both the interior and border shapes. During ordered surface rendering, both
            // shapes are already added to the DrawContext and both will be individually processed. Therefore we just
            // call our superclass behavior
            if (dc.isOrderedRenderingMode())
            {
                super.preRender(dc);
                return;
            }

            this.doPreRender(dc);
        }

        @Override
        public void render(DrawContext dc)
        {
            if (dc.isPickingMode() && this.isResizeable())
                return;

            // This is called twice: once during normal rendering, then again during ordered surface rendering. During
            // normal renering we render both the interior and border shapes. During ordered surface rendering, both
            // shapes are already added to the DrawContext and both will be individually processed. Therefore we just
            // call our superclass behavior
            if (dc.isOrderedRenderingMode())
            {
                super.render(dc);
                return;
            }

            if (!this.isResizeable())
            {
                if (this.hasSelection())
                {
                    this.doRender(dc);
                }
                return;
            }

            PickedObjectList pos = dc.getPickedObjects();
            PickedObject terrainObject = pos != null ? pos.getTerrainObject() : null;

            if (terrainObject == null)
                return;

            if (this.getStartPosition() != null)
            {
                Position end = terrainObject.getPosition();
               
                if (!this.getStartPosition().equals(end))
                {
                    this.setEndPosition(end);
                    this.setSector(Sector.boundingSector(this.getStartPosition(), this.getEndPosition()));
                    this.doRender(dc);
                }
            }
            else
            {
                this.setStartPosition(pos.getTerrainObject().getPosition());
            }
        }

        protected void doPreRender(DrawContext dc)
        {
            this.doPreRenderInterior(dc);
            this.doPreRenderBorder(dc);
        }

        protected void doPreRenderInterior(DrawContext dc)
        {
            super.preRender(dc);
        }

        protected void doPreRenderBorder(DrawContext dc)
        {
            this.getBorder().preRender(dc);
        }

        protected void doRender(DrawContext dc)
        {
            this.doRenderInterior(dc);
            this.doRenderBorder(dc);
        }

        protected void doRenderInterior(DrawContext dc)
        {
            super.render(dc);
        }

        protected void doRenderBorder(DrawContext dc)
        {
            this.getBorder().render(dc);
        }
    }
  
   // end inner-class
}
TOP

Related Classes of org.geoforge.worldwind.builder.GfrBldObjDrgShpSct$RegionShape

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.