Changeset 2393


Ignore:
Timestamp:
03/06/07 17:52:00 (13 years ago)
Author:
sorber
Message:

Can erase polyline nodes. Add indicator for closed polyline. Polyline checks if tool changed (OverlayTransform). Cleaned up polyline getData method.

Location:
trunk/loci/visbio/overlays
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/loci/visbio/overlays/OverlayNodedObject.java

    r2364 r2393  
    7070  } 
    7171 
    72   /** Highlighting color. */ 
    73   protected static final Color HLT = Color.YELLOW; 
    74  
    7572  /** Alpha value for highlighting */ 
    7673  protected static final float HLT_ALPHA = 0.5f; 
     
    10198  /** Index of the highlighted node */ 
    10299  protected int highlightIndex; 
     100 
     101  /** Color to highlight highlighted node */ 
     102  protected Color highlightColor; 
    103103 
    104104  /** The active display, used by the getData method */ 
     
    158158    TupleType range = overlay.getRangeType(); 
    159159 
    160     boolean circleFilled = false; // can't set to true right now w/o 
    161     // Manifold dimension mismatch occuring, since nodes are of  
    162     // manifold dimension 1. 
    163  
    164     float scale; 
    165     if (display != null) scale = getScalingValue(display); 
    166     else scale = 1f; 
    167  
     160    FlatField field = null; 
     161    Set fieldSet = null; 
     162       
     163    // determine number of samples 
     164    boolean circleFilled = false; // only works if nodes are also filled 
     165    // (all sets in a union set must have same manifold dimension) 
    168166    int arcLen = ARC[0].length; 
    169167    int len = 2 * arcLen; 
    170     float rad = 10.0f * scale; // 10.0 pixels wide per active display 
    171  
    172     float[][] highlightSetSamples = new float[2][0]; 
    173  
     168    int hlen = circleFilled ? len : len + 1; 
     169    int totalSamples = maxNodes; 
     170    if (isHighlightNode()) totalSamples += hlen; 
     171 
     172    float[][] rangeSamples = new float[4][totalSamples]; 
     173 
     174    // ****************************************************************** 
     175    // build nodes set and assign nodes range samples 
     176    // ****************************************************************** 
     177    SampledSet nodesSet = null; 
     178    try { 
     179      nodesSet = new Gridded2DSet(domain, 
     180        nodes, maxNodes, null, null, null, false); 
     181       
     182      // I've written !isDrawing() to prevent a manifold dimension mismatch 
     183      // that occurs when drawing filled polylines 
     184      if (filled && !isDrawing()) {   
     185        Irregular2DSet roiSet = 
     186          DelaunayCustom.fillCheck((Gridded2DSet) nodesSet, false); 
     187        if (roiSet != null)  nodesSet = roiSet; 
     188      } 
     189 
     190      fieldSet = nodesSet; 
     191    } 
     192    catch (VisADException exc) { exc.printStackTrace(); } 
     193     
     194    // fill nodes range samples 
     195    float r = color.getRed() / 255f; 
     196    float g = color.getGreen() / 255f; 
     197    float b = color.getBlue() / 255f; 
     198 
     199    Arrays.fill(rangeSamples[0], 0, maxNodes, r); 
     200    Arrays.fill(rangeSamples[1], 0, maxNodes, g); 
     201    Arrays.fill(rangeSamples[2], 0, maxNodes, b); 
     202    Arrays.fill(rangeSamples[3], 0, maxNodes, 1.0f); 
     203     
     204    // ************************************************************** 
     205    // make highlight set and fill highlight range samples 
     206    // ************************************************************** 
    174207    if (isHighlightNode()) { 
    175       highlightSetSamples = new float[2][circleFilled ? len : len + 1]; 
     208      SampledSet highlightSet = null; 
     209 
     210      // scale cirlce radius 
     211      float scale; 
     212      if (display != null) scale = getScalingValue(display); 
     213      else scale = 1f; 
     214      float rad = 10.0f * scale; // 10.0 pixels wide per active display 
     215 
     216      // assemble highlight set samples 
     217      float[][] highlightSetSamples = new float[2][hlen]; 
    176218      float[] c = getNodeCoords(getHighlightedNodeIndex()); 
    177219 
     
    188230        highlightSetSamples[1][ndx] = c[1] - rad * ARC[1][i]; 
    189231      } 
    190     }  
    191      
    192     FlatField field = null; 
    193     FlatField highlightField = null; 
    194     try { 
    195       //highlight  
    196       SampledSet highlightSet = null; 
    197       if (isHighlightNode()) { 
     232 
     233      try { 
     234        // build highlight set  
    198235        if (circleFilled) { 
    199236          highlightSet = new Gridded2DSet(domain, highlightSetSamples, 
     
    207244        } 
    208245      } 
    209  
    210      // nodes 
    211       SampledSet nodesSet = new Gridded2DSet(domain, 
    212         nodes, maxNodes, null, null, null, false); 
     246      catch (VisADException exc) { exc.printStackTrace(); } 
    213247       
    214       // I've written !isDrawing() to prevent a manifold dimension mismatch 
    215       // that occurs when drawing filled polylines 
    216       if (filled && !isDrawing()) {   
    217         Irregular2DSet roiSet = 
    218           DelaunayCustom.fillCheck((Gridded2DSet) nodesSet, false); 
    219         if (roiSet != null)  nodesSet = roiSet; 
    220       } 
    221  
    222       int hlen = 0; 
    223       int totalSamples = nodesSet.getLength(); 
    224       if (highlightSet != null) { 
    225         hlen = highlightSet.getLength();  
    226         totalSamples += hlen;  
    227       } 
    228  
    229       float r = color.getRed() / 255f; 
    230       float g = color.getGreen() / 255f; 
    231       float b = color.getBlue() / 255f; 
    232  
    233       float hltR = HLT.getRed() / 255f; 
    234       float hltG = HLT.getGreen() / 255f; 
    235       float hltB = HLT.getBlue() / 255f; 
     248      // fill highlight range samples 
     249      float hltR = highlightColor.getRed() / 255f; 
     250      float hltG = highlightColor.getGreen() / 255f; 
     251      float hltB = highlightColor.getBlue() / 255f; 
    236252      float hltA = HLT_ALPHA; 
    237253 
    238       float[][] rangeSamples = new float[4][totalSamples]; 
    239       Arrays.fill(rangeSamples[0], 0, hlen, hltR); 
    240       Arrays.fill(rangeSamples[1], 0, hlen, hltG); 
    241       Arrays.fill(rangeSamples[2], 0, hlen, hltB); 
    242       Arrays.fill(rangeSamples[3], 0, hlen, hltA); 
    243  
    244       Arrays.fill(rangeSamples[0], hlen, totalSamples, r); 
    245       Arrays.fill(rangeSamples[1], hlen, totalSamples, g); 
    246       Arrays.fill(rangeSamples[2], hlen, totalSamples, b); 
    247       Arrays.fill(rangeSamples[3], hlen, totalSamples, 1.0f); 
    248        
    249       // select which sets to include in union set 
    250       SampledSet[] sets; 
    251       if (isHighlightNode()) sets = new SampledSet[]{highlightSet, nodesSet};   
    252       else sets = new SampledSet[]{nodesSet}; 
    253        
    254       UnionSet fieldSet = new UnionSet(domain, sets); 
    255  
     254      Arrays.fill(rangeSamples[0], maxNodes, totalSamples, hltR); 
     255      Arrays.fill(rangeSamples[1], maxNodes, totalSamples, hltG); 
     256      Arrays.fill(rangeSamples[2], maxNodes, totalSamples, hltB); 
     257      Arrays.fill(rangeSamples[3], maxNodes, totalSamples, hltA); 
     258 
     259      try { 
     260        // assemble a UnionSet of nodes and circle 
     261        SampledSet[] sets = new SampledSet[]{nodesSet, highlightSet};   
     262        fieldSet = new UnionSet(domain, sets); 
     263      } 
     264      catch (VisADException exc) { exc.printStackTrace(); } 
     265    } 
     266     
     267    // ********************************************************** 
     268    // assemble ultimate field 
     269    // ********************************************************** 
     270    try { 
    256271      FunctionType fieldType = new FunctionType(domain, range); 
    257272      field = new FlatField(fieldType, fieldSet); 
     
    260275    catch (VisADException exc) { exc.printStackTrace(); } 
    261276    catch (RemoteException exc) { exc.printStackTrace(); } 
    262     return field; // return field; 
     277 
     278    return field;  
    263279  } 
    264280 
     
    352368 
    353369  /** Highlight a node. */  
    354   public void setHighlightNode(int i) { 
     370  public void setHighlightNode(int i, Color c) { 
    355371    highlightNode = true; 
    356372    highlightIndex = i; 
     373    highlightColor = c; 
    357374  } 
    358375 
    359376  /** Turn off node highlighting */ 
    360   public void turnOffHighlighting() { highlightNode = false; } 
     377  public void turnOffHighlighting() {  
     378    highlightNode = false; 
     379    highlightIndex = -1;  
     380    highlightColor = null; 
     381  } 
    361382 
    362383  /** Returns coordinates of node at given index in the node array */ 
  • trunk/loci/visbio/overlays/OverlayTransform.java

    r2332 r2393  
    117117  protected TransientSelectBox selectBox; 
    118118 
     119  /** Type of last tool used */ 
     120  protected String lastToolType; 
     121 
     122  /** Whether last tool has changed */ 
     123  protected boolean toolChanged; 
     124 
    119125  // -- Constructor -- 
    120126 
     
    133139    initState(null); 
    134140    parent.addTransformListener(this); 
     141 
     142    lastToolType = ""; 
     143    toolChanged = false; 
    135144  } 
    136145 
     
    688697    OverlayTool tool = controls.getActiveTool(); 
    689698    DisplayImpl display = (DisplayImpl) e.getDisplay(); 
     699 
     700    if (tool != null) { 
     701      String toolType = tool.getName(); 
     702      if (toolType.equals(lastToolType)) toolChanged = false; 
     703      else toolChanged = true; 
     704      lastToolType = toolType; 
     705    } 
    690706 
    691707    if (id == DisplayEvent.TRANSFORM_DONE) updatePosition(display); 
     
    897913  } 
    898914 
     915  /**  
     916   * Returns whether the current tool has changed 
     917   */ 
     918  public boolean hasToolChanged() { return toolChanged; } 
     919 
    899920} 
  • trunk/loci/visbio/overlays/PolylineTool.java

    r2374 r2393  
    2525 
    2626import java.awt.event.InputEvent; 
     27import java.awt.Color; 
    2728import java.util.Vector; 
    2829import loci.visbio.data.TransformEvent; 
     
    3637 
    3738  // -- Constants -- 
    38  
    39  
     39  protected static final int ERASE = -1; 
     40  protected static final int WAIT = 0; 
     41  protected static final int EXTEND = 1; 
     42  protected static final int ADJUST = 2; 
     43  protected static final int SELECT = 3; 
     44  protected static final int PLACE = 4; 
     45  protected static final int ADJUST_TAIL = 5; 
     46  protected static final int CLOSE_LOOP = 6; 
     47  protected static final int SELECTED_TAIL = 7; 
     48 
     49 
     50  /** Maximum distance (in pixels) mouse can be from a node to be considered 
     51   *  pointing to it. */ 
     52  protected static final double THRESH = 2.0; 
     53 
     54  /** Color for highlighting head or tail node of polyline when 'connecting' 
     55   *  free end to fixed end */ 
     56  protected static final Color CON = Color.GREEN; 
     57 
     58  /** Color for highlighting head or tail node when the mouse is nearby or 
     59   *  when dragging the node. */ 
     60  protected static final Color SEL = Color.YELLOW; 
    4061 
    4162  // -- Fields -- 
     
    4566 
    4667  /** Curve close to the mouse when drawing is not occurring */ 
    47   protected OverlayPolyline near; 
    48  
    49   /** Nearest node on Polyline near */ 
    50   protected int nearNode; 
     68  protected OverlayPolyline selectedPln; 
     69 
     70  /** Nearest node on selected PolyLine */ 
     71  protected int selectedNode; 
    5172 
    5273  /** Whether the active node of the polyline is anchored. */ 
     
    6485   *  last node placed. */ 
    6586  protected boolean departed; 
     87 
     88  /** Has the user entered resume mode */ 
     89  protected boolean resume; 
     90 
     91  protected int mode; 
    6692 
    6793  // -- Constructor -- 
     
    75101    nearHead = false; 
    76102    departed = false; 
    77     unsetMouseOverNode(); 
     103    mode = WAIT; 
     104    unselect(); 
    78105  } 
    79106 
     
    84111    float dx, float dy, int[] pos, int mods) 
    85112  { 
    86     // -- housekeeping 
     113    //System.out.println("down mode = " + mode); 
    87114    boolean ctl = (mods & InputEvent.CTRL_MASK) != 0; 
    88115    DisplayImpl display = (DisplayImpl) e.getDisplay(); 
    89116 
    90     double dpx = (double) px; 
    91     double dpy = (double) py; 
    92  
    93     // -- action! 
    94117    deselectAll();  
    95     
    96     if (line == null) { 
    97       if (!isMouseOverNode()) { 
    98         line =  new OverlayPolyline(overlay, dx, dy, dx, dy); 
    99         configureOverlay(line); 
    100         overlay.addObject(line, pos); 
    101       } 
    102     } 
    103     else { 
    104       line.setActiveDisplay (display); 
    105  
    106       if (nearTail) { 
    107         if (!anchored) line.deleteNode(line.getNumNodes()-1); 
     118 
     119    if (overlay.hasToolChanged()) { 
     120      unselect(); 
     121      mode = WAIT; 
     122    } 
     123    if (mode == WAIT) { 
     124      line =  new OverlayPolyline(overlay, dx, dy, dx, dy); 
     125      configureOverlay(line); 
     126      overlay.addObject(line, pos); 
     127      mode = PLACE; 
     128    } 
     129    else if (mode == PLACE) { 
     130      if (line.getNumNodes() > 1) { 
    108131        releaseLine(); 
    109         //System.out.println("nearTail, ending line"); // TEMP 
    110       } 
    111       else if (nearHead) { 
    112         if (anchored) System.out.println("puzzling case is here"); 
     132      } 
     133      else {  
     134        overlay.removeObject(line); 
     135        line = null; 
     136      } 
     137      mode = WAIT; 
     138    } 
     139    else if (mode == SELECT) { 
     140      if (!ctl) { 
     141        // which node are you near? 
     142        if (selectedNode == line.getNumNodes() - 1) { 
     143          mode = SELECTED_TAIL; 
     144        } 
     145        else if (selectedNode == 0) { 
     146          // you're near the head node 
     147          line.reverseNodes(); 
     148          selectNode(display, line, line.getNumNodes() - 1); 
     149          mode = SELECTED_TAIL; 
     150        } 
    113151        else { 
    114           float[] c = line.getNodeCoords(0); 
    115           line.setLastNode(c[0], c[1]); 
    116           releaseLine();  
    117           //System.out.println("nearHead, ending line"); // TEMP 
     152          mode = ADJUST; 
    118153        } 
    119154      } 
    120155      else { 
    121         nearTail = true; 
    122         if (anchored) { 
    123           line.setNextNode(dx, dy); 
    124         } 
    125         else {  
    126           line.setNodeCoords(line.getNumNodes() - 1, dx, dy); 
    127         } 
    128         line.computeLength(); 
    129       } 
    130     } 
    131  
    132     anchored = true; 
    133     departed = false; 
     156        // if node interior, create two new polylines 
     157        if (selectedNode > 0 && selectedNode < line.getNumNodes() - 1) { 
     158          float[][] nodes = line.getNodes(); 
     159          OverlayPolyline l1, l2; 
     160 
     161          int numNodes = line.getNumNodes(); 
     162 
     163          int numNodes1 = selectedNode; 
     164          int numNodes2 = numNodes - selectedNode - 1; 
     165          // selectedNode is an index into the node array; 
     166          float[][] n1 = new float[2][numNodes1]; 
     167          float[][] n2 = new float[2][numNodes2]; 
     168  
     169          // if non-trivial polyline remains 'left' of deleted node 
     170          if (selectedNode > 1) { 
     171            for (int i=0; i<2; i++)  
     172              System.arraycopy(nodes[i], 0, n1[i], 0, numNodes1); 
     173 
     174            l1 = new OverlayPolyline(overlay, n1); 
     175            configureOverlay(l1); 
     176            overlay.addObject(l1); 
     177            l1.setDrawing(false); 
     178            l1.setSelected(false); 
     179          } 
     180 
     181          // if non-trivial polyline remains 'right' of deleted node 
     182          if (selectedNode < numNodes - 1) { 
     183            for (int i=0; i<2; i++) { 
     184              System.arraycopy(nodes[i], numNodes1 + 1, n2[i], 0,  
     185                numNodes2); 
     186            } 
     187            l2 = new OverlayPolyline(overlay, n2); 
     188            configureOverlay(l2); 
     189            overlay.addObject(l2); 
     190            l2.setDrawing(false); 
     191            l2.setSelected(false); 
     192          } 
     193 
     194          overlay.removeObject(line); 
     195          unselect(); 
     196          mode = WAIT; 
     197        } 
     198        else { 
     199          // else delete node 
     200          line.deleteNode(selectedNode); 
     201          releaseLine(); 
     202          unselect(); // TODO these are redundant  
     203          mode = WAIT; 
     204        } 
     205      } 
     206    } 
     207    else if (mode == EXTEND) { 
     208      line.setLastNode(dx, dy); 
     209      line.computeLength(); 
     210      mode = PLACE; 
     211    } 
    134212 
    135213    overlay.notifyListeners(new TransformEvent(overlay)); 
     
    139217  public void mouseDrag(DisplayEvent e, int px, int py, 
    140218    float dx, float dy, int[] pos, int mods) { 
    141     // System.out.println("mouseDrag"); // TEMP 
    142     if (isMouseOverNode()) { 
    143       near.setNodeCoords(nearNode, dx, dy); 
     219    //System.out.println("mode = " + mode); 
     220    DisplayImpl display = (DisplayImpl) e.getDisplay(); 
     221 
     222    if (overlay.hasToolChanged()) { 
     223      unselect(); 
     224      mode = WAIT; 
     225    } 
     226    if (mode == ADJUST) { 
     227      line.setNodeCoords(selectedNode, dx, dy); 
    144228      overlay.notifyListeners(new TransformEvent(overlay)); 
    145229    }  
    146     else { 
     230    else if (mode == SELECTED_TAIL) { 
     231      mode = ADJUST_TAIL; 
     232      mouseDrag(e, px, py, dx, dy, pos, mods); 
     233    } 
     234    else if (mode == ADJUST_TAIL || mode == CLOSE_LOOP) { 
     235      line.setNodeCoords(selectedNode, dx, dy); 
     236 
     237      int ndx = 0; // index of head 
     238      double[] dPxlDbl = {(double) px, (double) py}; 
     239      float[] nDom = line.getNodeCoords(ndx); 
     240      double[] nDomDbl = {(double) nDom[0], (double) nDom[1]}; 
     241      int[] nPxl = DisplayUtil.domainToPixel(display, nDomDbl); 
     242      double[] nPxlDbl = {(double) nPxl[0], (double) nPxl[1]}; 
     243      double dist = MathUtil.getDistance (nPxlDbl, dPxlDbl); 
     244       
     245      // if near ndx, highlight selected node differently  
     246      if (dist < THRESH) { 
     247        line.setHighlightNode(selectedNode, CON); 
     248        mode = CLOSE_LOOP; 
     249      } 
     250      else { 
     251        line.setHighlightNode(selectedNode, SEL); 
     252        mode = ADJUST_TAIL; 
     253      } 
     254 
     255      overlay.notifyListeners(new TransformEvent(overlay)); 
     256    } 
     257    else if (mode == PLACE || mode == EXTEND) { 
    147258      mouseMoved(e, px, py, dx, dy, pos, mods); 
    148259    } 
     
    152263  public void mouseUp(DisplayEvent e, int px, int py,  
    153264      float dx, float dy, int[] pos, int mods) { 
    154     if (isMouseOverNode()) { 
    155       // System.out.println("mouseUp"); // TEMP 
    156       near.updateBoundingBox(); 
    157       near.computeGridParameters(); 
    158       unsetMouseOverNode(); 
     265    //System.out.println("up mode = " + mode); 
     266    DisplayImpl display = (DisplayImpl) e.getDisplay(); 
     267 
     268    if (overlay.hasToolChanged()) { 
     269      mode = WAIT; 
     270      unselect(); 
     271    } 
     272    if (mode == ADJUST) { 
     273      mode = SELECT; 
     274    } 
     275    else if (mode == ADJUST_TAIL) { 
     276      mode = SELECT; 
     277    } 
     278    else if (mode == SELECTED_TAIL) {  
     279      line.turnOffHighlighting(); 
     280      mode = PLACE; 
     281    } 
     282    else if (mode == CLOSE_LOOP) { 
     283      float[] c = line.getNodeCoords(0); 
     284      line.setLastNode(c[0], c[1]);  
     285      selectNode(display, line, line.getNumNodes() - 1); 
     286      mode = SELECT; 
    159287    } 
    160288  } 
     
    163291  public void mouseMoved(DisplayEvent e, int px, int py,  
    164292      float dx, float dy, int[] pos, int mods) { 
     293    //System.out.println("moved mode = " + mode); 
    165294    DisplayImpl display = (DisplayImpl) e.getDisplay(); 
    166     if (line != null) { 
    167       line.setActiveDisplay(display); 
    168  
    169       nearTail = false; 
    170       nearHead = false; 
    171  
    172       if (anchored) { 
    173         line.setNextNode(dx, dy); 
    174         anchored = false; 
    175         nearTail = true; 
    176       } 
    177       else { 
    178         line.setLastNode(dx, dy); 
    179       } 
    180  
    181       // determine whether to highlight head or tail nodes 
    182       double[] movePxl = {(double) px, (double) py};  
    183       float[] prevDom = line.getNodeCoords(line.getNumNodes() - 2); 
    184       double[] prevDomDbl = {(double) prevDom[0], (double) prevDom[1]};  
    185       int[] prevPxlInt = DisplayUtil.domainToPixel(display, prevDomDbl); 
    186       double[] prevPxl = {(double) prevPxlInt[0], (double) prevPxlInt[1]}; 
    187       double tailDist = MathUtil.getDistance(movePxl, prevPxl); 
    188  
    189       float[] headDom = line.getNodeCoords(0); 
    190       double[] headDomDbl = {(double) headDom[0], (double) headDom[1]}; 
    191       int[] headPxlInt = DisplayUtil.domainToPixel(display, headDomDbl); 
    192       double[] headPxl = {(double) headPxlInt[0], (double) headPxlInt[1]}; 
    193       double headDist = MathUtil.getDistance(movePxl, headPxl); 
    194  
    195       if (tailDist > 10.0) departed = true; 
    196  
    197       if (headDist < 2.0) { 
    198         line.setHighlightNode(0); 
    199         //System.out.println("near head"); // TEMP 
    200         nearHead = true; 
    201       } 
    202       else if (departed && tailDist < 2.0) { 
    203         line.setHighlightNode(line.getNumNodes() - 2); 
    204         //System.out.println("near tail");// TEMP 
    205         nearTail = true; 
    206       } 
    207       else { 
    208         line.turnOffHighlighting(); 
    209       } 
    210     } 
    211     else { 
    212       // find out if you're near a node 
     295    double[] movePxl = {(double) px, (double) py};  
     296 
     297    if (overlay.hasToolChanged()) { 
     298      unselect(); 
     299      mode = WAIT; 
     300    } 
     301    if (mode == WAIT) { 
    213302      OverlayObject[] objects = overlay.getObjects(); 
    214303      double threshold = 2.0; 
    215       int[] objNode =  getNearestNode(display, objects, px, py, threshold); 
    216  
    217       unHighlightAllPolylines(objects); 
    218       if (objNode != null) { 
    219         int obj = objNode[0]; 
    220         int node = objNode[1]; 
     304      int[] ndxNode =  getNearestNode(display, objects, px, py, threshold); 
     305 
     306      if (ndxNode != null) { 
     307        int ndx = ndxNode[0]; 
     308        int node = ndxNode[1]; 
    221309        //System.out.println("near node " + node + " of object " + obj); // TEMP  
    222         OverlayPolyline pln = (OverlayPolyline) objects[obj]; 
    223         pln.setHighlightNode(node); 
    224         setMouseOverNode(pln, node); 
    225       } 
    226       else if (isMouseOverNode()) { 
    227         unsetMouseOverNode(); 
    228       } 
     310        line = (OverlayPolyline) objects[ndx]; 
     311        selectNode(display, line, node); 
     312        mode = SELECT; 
     313      } 
     314    } 
     315    else if (mode == PLACE) { 
     316      line.setNextNode(dx, dy); 
     317      mode = EXTEND; 
     318    } 
     319    else if (mode == EXTEND) { 
     320      line.setLastNode(dx, dy); 
     321      // determine if near head:  
     322      int ndx = 0; // index of head 
     323      double[] dPxlDbl = {(double) px, (double) py}; 
     324      float[] nDom = line.getNodeCoords(ndx); 
     325      double[] nDomDbl = {(double) nDom[0], (double) nDom[1]}; 
     326      int[] nPxl = DisplayUtil.domainToPixel(display, nDomDbl); 
     327      double[] nPxlDbl = {(double) nPxl[0], (double) nPxl[1]}; 
     328      double dist = MathUtil.getDistance (nPxlDbl, dPxlDbl); 
     329       
     330      // if near ndx, highlight selected node differently  
     331      if (dist < THRESH) { 
     332        line.setActiveDisplay(display); 
     333        line.setHighlightNode(line.getNumNodes()-1, CON); 
     334        mode = CLOSE_LOOP; 
     335      } 
     336      // mode remains extend otherwise 
     337    } 
     338    else if (mode == CLOSE_LOOP) { 
     339      line.setLastNode(dx, dy); 
     340      // determine if near head:  
     341      int ndx = 0; // index of head 
     342      double[] dPxlDbl = {(double) px, (double) py}; 
     343      float[] nDom = line.getNodeCoords(ndx); 
     344      double[] nDomDbl = {(double) nDom[0], (double) nDom[1]}; 
     345      int[] nPxl = DisplayUtil.domainToPixel(display, nDomDbl); 
     346      double[] nPxlDbl = {(double) nPxl[0], (double) nPxl[1]}; 
     347      double dist = MathUtil.getDistance (nPxlDbl, dPxlDbl); 
     348       
     349      // if near ndx, highlight selected node differently  
     350      if (dist > THRESH) { 
     351        line.turnOffHighlighting(); 
     352        mode = EXTEND;  
     353      } 
     354    } 
     355    else if (mode == SELECT) { 
     356      float[] nodeFlt = line.getNodeCoords (selectedNode);  
     357      double[] nodeDbl = {(double) nodeFlt[0], (double) nodeFlt[1]}; 
     358      int[] nodePxl = DisplayUtil.domainToPixel(display, nodeDbl);  
     359      double[] nodePxlDbl = {(double) nodePxl[0], (double) nodePxl[1]}; 
     360      double dist = MathUtil.getDistance(movePxl, nodePxlDbl);  
     361 
     362      double threshold = 2.0; 
     363      if (dist > threshold) { 
     364        line.turnOffHighlighting(); 
     365        unselect(); 
     366        mode = WAIT; 
     367      } 
     368    } 
     369    else if (mode == ADJUST) { 
    229370    } 
    230371    overlay.notifyListeners(new TransformEvent(overlay)); 
     
    233374  // -- Helper methods --  
    234375   
    235   private void unsetMouseOverNode() { 
    236     near = null; 
    237     nearNode = -1; 
     376  /** Ends drawing of the current line */ 
     377  private void releaseLine() { 
     378    if (line != null) { 
     379      line.turnOffHighlighting(); 
     380      line.updateBoundingBox(); 
     381      line.computeGridParameters(); 
     382      line.computeLength(); 
     383      line.setDrawing(false); 
     384      line.setSelected(true); 
     385      line = null; 
     386    } 
     387  } 
     388 
     389  private void unselect() { 
     390    line = null; 
     391    selectedNode = -1; 
    238392  } 
    239393   
    240   private void setMouseOverNode(OverlayPolyline pln, int node) { 
    241     near = pln; 
    242     nearNode = node; 
    243   } 
    244  
    245   private boolean isMouseOverNode() { return (near != null); } 
     394  private void selectNode(DisplayImpl display, OverlayPolyline pln, int node) { 
     395    selectedNode = node; 
     396    pln.setHighlightNode(node, SEL); 
     397    pln.setActiveDisplay(display); 
     398  } 
    246399   
    247400  /** Unhighlights all polylines in a list of OverlayObjects */ 
     
    297450 
    298451   
    299   /** Ends drawing of the current line */ 
    300   private void releaseLine() { 
    301     if (line != null) { 
    302       line.turnOffHighlighting(); 
    303       line.updateBoundingBox(); 
    304       line.computeGridParameters(); 
    305       line.computeLength(); 
    306       line.setDrawing(false); 
    307       line.setSelected(false); 
    308       line = null; 
    309     } 
    310   } 
    311  
     452  
    312453  /** Casts an array of floats to doubles */ 
    313454  private double[][] floatsToPixelDoubles(DisplayImpl d, float[][] nodes) { 
Note: See TracChangeset for help on using the changeset viewer.