code: /*--------------------------------------------------------------*
    Copyright (C) 2006-2015 OpenSim Ltd.
  
    This file is distributed WITHOUT ANY WARRANTY. See the file
    'License' for details on this and other legal matters.
  *--------------------------------------------------------------*/
  
  package org.omnetpp.figures.anchors;
  
  import org.eclipse.draw2d.IFigure;
  import org.eclipse.draw2d.geometry.Point;
  import org.eclipse.draw2d.geometry.Rectangle;
  
  /**
   * Anchor where the reference point can be anything inside the figure and the anchor is placed
   * on the bounding box, or it can be pinned down to any inside point.
   *
   * @author rhornig
   */
  public class PinnableNoncentralChopboxAnchor extends NoncentralChopboxAnchor {
      // fixed location if the anchor is pinned (relative in owner area ie 0.0 - 1.0)
      private double pinnedLocationX = 0.5f;
      private double pinnedLocationY = 0.5f;
  
      // is the anchor pinned down? so it cannot move automatically
      private boolean pinnedDown = false;
  
      /**
       * Create an anchor in unpinned state. (If it gets pinned, default location
       * will be the middle of the owner.)
       */
      public PinnableNoncentralChopboxAnchor(IFigure owner) {
          super(owner);
      }
  
      /**
       * Create an anchor at the given location in pinned-down state.
       * The location x, y parameters are relative to the owner area,
       * i.e. 0.0 means left/top, and 1.0 means right/bottom.
       */
      public PinnableNoncentralChopboxAnchor(IFigure owner, double pinnedLocationX, double pinnedLocationY) {
          super(owner);
          this.pinnedLocationX = pinnedLocationX;
          this.pinnedLocationY = pinnedLocationY;
          this.pinnedDown = true;
      }
  
  
      @Override
      public Point getLocation(Point foreignRef) {
          if (!isPinnedDown())
              return super.getLocation(foreignRef);
  
          // if we are pinned, return the current fixed reference point as the location
          return getReferencePoint();
      }
  
      @Override
      public Point getReferencePoint() {
          if (!isPinnedDown()) return super.getReferencePoint();
  
          Rectangle r = new Rectangle(getBox());
          r.translate(-1, -1);
          r.resize(1, 1);
          getOwner().translateToAbsolute(r);
          double oX = r.x + pinnedLocationX * r.width;
          double oY = r.y + pinnedLocationY * r.height;
          return new Point((int)Math.round(oX), (int)Math.round(oY));
      }
  
      public boolean isPinnedDown() {
          return pinnedDown;
      }
  
      public void setPinnedDown(boolean pinnedDown) {
          if (this.pinnedDown != pinnedDown) {
              this.pinnedDown = pinnedDown;
              // the pinning status has changed, so the anchor point might have moved
              fireAnchorMoved();
          }
      }
  
      public double getPinnedLocationX() {
          return pinnedLocationX;
      }
  
  
      public void setPinnedLocationX(double pinnedLocationX) {
          this.pinnedLocationX = pinnedLocationX;
          fireAnchorMoved();
      }
  
  
      public double getPinnedLocationY() {
          return pinnedLocationY;
      }
  
  
      public void setPinnedLocationY(double pinnedLocationY) {
          this.pinnedLocationY = pinnedLocationY;
          fireAnchorMoved();
      }
  
      public void setPinnedLocation(double pinnedLocationX, double pinnedLocationY) {
          this.pinnedLocationX = pinnedLocationX;
          this.pinnedLocationY = pinnedLocationY;
          fireAnchorMoved();
      }
  }
  