Changeset 1865


Ignore:
Timestamp:
11/28/06 17:47:55 (13 years ago)
Author:
sorber
Message:

Smoother transitions toggling between erase and draw modes
Enabled saving and loading of OverlayFreeforms

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

Legend:

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

    r1846 r1865  
    258258    boolean ctl = (mods & InputEvent.CTRL_MASK) != 0;  
    259259 
     260    if (ctl && mode == DRAW) { 
     261        freeform.truncateNodeArray(); 
     262        setMode(ERASE); 
     263    } 
     264 
    260265    if (mode == DRAW) { 
     266       
    261267      // compute distance to endpoints of nearby freeforms 
    262268      int index = -1; 
     
    312318      } 
    313319 
    314       if (!ctl) { 
    315         float lastX = freeform.getLastNodeX(); 
    316         float lastY = freeform.getLastNodeY(); 
    317         float dx = x - lastX;  
    318         float dy = y - lastY;  
    319         // compute distance 
    320         double dist = Math.sqrt (dx*dx + dy*dy); 
     320      // delete an end node if you're near enough 
     321      float[] beg = freeform.getNodeCoords (0); 
     322      float[] end = freeform.getNodeCoords (freeform.getNumNodes() - 1); 
     323 
     324      double[] drag = {(double) x, (double) y}; 
     325      double[] begd = {(double) beg[0], (double) beg[1]}; 
     326      double[] endd = {(double) end[0], (double) end[1]}; 
    321327       
    322         if (dist > DRAW_THRESH) { 
    323           freeform.setNextNode(x, y); 
    324           double len = freeform.getCurveLength(); 
    325           freeform.setCurveLength(len + dist); 
    326         } 
    327  
    328         setMode(DRAW); 
    329       } else { 
    330         // delete an end node if you're near enough 
    331         float[] beg = freeform.getNodeCoords (0); 
    332         float[] end = freeform.getNodeCoords (freeform.getNumNodes() - 1); 
    333  
    334         double[] drag = {(double) x, (double) y}; 
    335         double[] begd = {(double) beg[0], (double) beg[1]}; 
    336         double[] endd = {(double) end[0], (double) end[1]}; 
     328      double bdist = MathUtil.getDistance (drag, begd); 
     329      double edist = MathUtil.getDistance (drag, endd); 
     330       
     331      boolean closerToEnd = edist < bdist ? true : false; 
     332      double mdist = closerToEnd ? edist : bdist; 
     333       
     334      if (mdist < DRAW_THRESH) { 
     335        if (!closerToEnd) freeform.reverseNodes(); 
     336        if (ctl) { 
     337          double[] nearest = new double[2], pd = new double[2]; 
     338          float[] p; 
     339          double delta; 
     340          int index; 
     341          if (closerToEnd) nearest = endd; 
     342          else nearest = begd; 
    337343         
    338         double bdist = MathUtil.getDistance (drag, begd); 
    339         double edist = MathUtil.getDistance (drag, endd); 
    340          
    341         boolean closerToEnd = edist < bdist ? true : false; 
    342         double mdist = closerToEnd ? edist : bdist; 
    343          
    344         if (mdist < DRAW_THRESH) { 
    345           double[] nearest; 
    346           int index, offset; 
    347  
    348           if (closerToEnd) { 
    349             index = freeform.getNumNodes()-1; 
    350             offset = -1; 
    351             nearest = endd; 
    352           } else { 
    353             index = 0; 
    354             offset = 1; 
    355             nearest = begd; 
    356           } 
    357344          // adjust curve length 
    358           float[] p = freeform.getNodeCoords(index + offset); 
    359           double[] pd = {(double) p[0], (double) p[1]}; 
    360  
    361           double delta = MathUtil.getDistance (nearest, pd); 
     345          index = freeform.getNumNodes()-1; // last node in freef 
     346          p = freeform.getNodeCoords(index); 
     347          pd[0] = (double) p[0]; 
     348          pd[1] = (double) p[1]; 
     349 
     350          delta = MathUtil.getDistance (nearest, pd); 
    362351          freeform.setCurveLength(freeform.getCurveLength() - delta); 
    363352 
    364           // delete appropriate node 
     353          // delete last node node 
    365354          freeform.deleteNode(index); 
    366355          freeform.updateBoundingBox(); // WARNING this is O(n) expensive.  Maybe remove it and just update at 
    367356                                        // mouseUp? 
     357        } else { 
     358          setMode(DRAW); 
    368359        } 
    369  
    370         if (freeform.getNumNodes() == 0) { 
    371           setMode(CHILL); 
    372         } 
     360        if (freeform.getNumNodes() == 0) setMode(CHILL); 
     361      } else { 
     362        // do nothing if too far from curve 
    373363      } 
    374364    } else if (mode == EDIT) { 
  • trunk/loci/visbio/overlays/OverlayIO.java

    r1796 r1865  
    5757 
    5858    Vector[] loadedOverlays = null; 
     59    Vector loadedFreeforms = new Vector(); 
     60    int nextFreeformToRestore = 0; 
    5961    boolean foundHeader = false; 
    6062    int lineNum = 0; 
     
    112114        } 
    113115        foundHeader = true; 
     116      } else { 
     117        // parse table entry 
     118        String type = st.nextToken().substring(1); // remove initial # 
     119        if (type.indexOf(',') == -1) { // if not a line of freeform nodes  
     120          if (count != lengths.length + 10) { 
     121            System.err.println("Warning: line " + lineNum + 
     122              " has the incorrect number of columns (" + count + 
     123              " instead of " + (lengths.length + 10) + ") and will be ignored."); 
     124            continue; 
     125          } 
     126 
     127          int[] pos = new int[lengths.length]; 
     128          for (int i=0; i<pos.length; i++) { 
     129            try { pos[i] = Integer.parseInt(st.nextToken()); } 
     130            catch (NumberFormatException exc) { 
     131              pos = null; 
     132              break; 
     133            } 
     134          } 
     135          if (pos == null) { 
     136            System.err.println("Warning: line " + lineNum + 
     137              " has an invalid dimensional position and will be ignored."); 
     138            continue; 
     139          } 
     140          String sx1 = st.nextToken(); 
     141          String sy1 = st.nextToken(); 
     142          String sx2 = st.nextToken(); 
     143          String sy2 = st.nextToken(); 
     144          float x1, y1, x2, y2; 
     145          try { 
     146            x1 = sx1.equals(NOT_APPLICABLE) ? Float.NaN : Float.parseFloat(sx1); 
     147            y1 = sy1.equals(NOT_APPLICABLE) ? Float.NaN : Float.parseFloat(sy1); 
     148            x2 = sx2.equals(NOT_APPLICABLE) ? Float.NaN : Float.parseFloat(sx2); 
     149            y2 = sy2.equals(NOT_APPLICABLE) ? Float.NaN : Float.parseFloat(sy2); 
     150          } 
     151          catch (NumberFormatException exc) { 
     152            System.err.println("Warning: line " + lineNum + 
     153              " has invalid coordinate values and will be ignored."); 
     154            continue; 
     155          } 
     156          String text = st.nextToken(); 
     157          Color color = ColorUtil.hexToColor(st.nextToken()); 
     158          if (color == null) { 
     159            System.err.println("Warning: line " + lineNum + 
     160              " has an invalid color value and will be ignored."); 
     161            continue; 
     162          } 
     163          boolean filled = st.nextToken().equalsIgnoreCase("true"); 
     164          String group = st.nextToken(); 
     165          String notes = st.nextToken(); 
     166          notes = notes.substring(0, notes.length() - 1); // remove trailing # 
     167 
     168          String className = "loci.visbio.overlays.Overlay" + type; 
     169          OverlayObject obj = createOverlay(className, trans, lineNum); 
     170          if (obj == null) continue; 
     171           
     172          boolean hasNodes = false; 
     173          if (obj instanceof OverlayFreeform) { 
     174            loadedFreeforms.add(obj); 
     175            hasNodes = true; 
     176          } 
     177 
     178          // assign overlay parameters 
     179          int r = MathUtil.positionToRaster(lengths, pos); 
     180          if (r < 0 || r >= loadedOverlays.length) { 
     181            System.err.println("Warning: could not reconstruct " + type + 
     182              "overlay defined on line " + lineNum + 
     183              ": invalid dimensional position."); 
     184            continue; 
     185          } 
     186           
     187          obj.x1 = x1; 
     188          obj.y1 = y1; 
     189          obj.x2 = x2; 
     190          obj.y2 = y2; 
     191          obj.text = text; 
     192          obj.color = color; 
     193          obj.filled = filled; 
     194          obj.group = group; 
     195          obj.notes = notes; 
     196          obj.hasNodes = hasNodes; // necessary to distinguish freeforms 
     197          obj.drawing = false; 
     198          obj.selected = false; 
     199          obj.computeGridParameters(); 
     200 
     201          // add overlay to list 
     202          loadedOverlays[r].add(obj); 
     203        } else { 
     204          // parse freeform nodes 
     205          String nodeList = type.substring (0, type.indexOf('#')); 
     206          StringTokenizer st2 = new StringTokenizer (nodeList, " "); 
     207          int numNodes = st2.countTokens(); 
     208          float[][] nodes = new float[2][numNodes]; 
     209 
     210          int i = 0; 
     211          while (st2.hasMoreTokens()) { 
     212            String node = st2.nextToken(); 
     213            int comma = node.indexOf(','); 
     214            String x, y; 
     215            try { 
     216              x = node.substring(1, comma); 
     217              y = node.substring(comma + 1, node.length()-1); 
     218              nodes[0][i] = Float.parseFloat(x);         
     219              nodes[1][i] = Float.parseFloat(y); 
     220              i++; 
     221            } catch (StringIndexOutOfBoundsException exc) { // if no comma, extra spaces 
     222              JOptionPane.showMessageDialog(owner, "Invalid overlay file: malformatted Freeform node list.\n"  
     223                  + "Error found near following string: " + node + "", "Cannot load overlays", JOptionPane.ERROR_MESSAGE); 
     224              return null; 
     225            } catch (NumberFormatException exc) { // if parseFloat fails 
     226              JOptionPane.showMessageDialog(owner, "Invalid overlay file: malformatted Freeform node list.\n"  
     227                  + "Error found near following string: " + node + "", "Cannot load overlays", JOptionPane.ERROR_MESSAGE); 
     228              return null; 
     229            } 
     230          } 
     231 
     232          // set nodes of corresponding freeform  
     233          OverlayFreeform f =  (OverlayFreeform) loadedFreeforms.elementAt(nextFreeformToRestore++); 
     234          f.setNodes(nodes); 
     235        } 
    114236      } 
    115       else { 
    116         // parse table entry 
    117         if (count != lengths.length + 10) { 
    118           System.err.println("Warning: line " + lineNum + 
    119             " has the incorrect number of columns (" + count + 
    120             " instead of " + (lengths.length + 10) + ") and will be ignored."); 
    121           continue; 
    122         } 
    123         String type = st.nextToken().substring(1); // remove initial # 
    124         int[] pos = new int[lengths.length]; 
    125         for (int i=0; i<pos.length; i++) { 
    126           try { pos[i] = Integer.parseInt(st.nextToken()); } 
    127           catch (NumberFormatException exc) { 
    128             pos = null; 
    129             break; 
    130           } 
    131         } 
    132         if (pos == null) { 
    133           System.err.println("Warning: line " + lineNum + 
    134             " has an invalid dimensional position and will be ignored."); 
    135           continue; 
    136         } 
    137         String sx1 = st.nextToken(); 
    138         String sy1 = st.nextToken(); 
    139         String sx2 = st.nextToken(); 
    140         String sy2 = st.nextToken(); 
    141         float x1, y1, x2, y2; 
    142         try { 
    143           x1 = sx1.equals(NOT_APPLICABLE) ? Float.NaN : Float.parseFloat(sx1); 
    144           y1 = sy1.equals(NOT_APPLICABLE) ? Float.NaN : Float.parseFloat(sy1); 
    145           x2 = sx2.equals(NOT_APPLICABLE) ? Float.NaN : Float.parseFloat(sx2); 
    146           y2 = sy2.equals(NOT_APPLICABLE) ? Float.NaN : Float.parseFloat(sy2); 
    147         } 
    148         catch (NumberFormatException exc) { 
    149           System.err.println("Warning: line " + lineNum + 
    150             " has invalid coordinate values and will be ignored."); 
    151           continue; 
    152         } 
    153         String text = st.nextToken(); 
    154         Color color = ColorUtil.hexToColor(st.nextToken()); 
    155         if (color == null) { 
    156           System.err.println("Warning: line " + lineNum + 
    157             " has an invalid color value and will be ignored."); 
    158           continue; 
    159         } 
    160         boolean filled = st.nextToken().equalsIgnoreCase("true"); 
    161         String group = st.nextToken(); 
    162         String notes = st.nextToken(); 
    163         notes = notes.substring(0, notes.length() - 1); // remove trailing # 
    164  
    165         String className = "loci.visbio.overlays.Overlay" + type; 
    166         OverlayObject obj = createOverlay(className, trans, lineNum); 
    167         if (obj == null) continue; 
    168  
    169         // assign overlay parameters 
    170         int r = MathUtil.positionToRaster(lengths, pos); 
    171         if (r < 0 || r >= loadedOverlays.length) { 
    172           System.err.println("Warning: could not reconstruct " + type + 
    173             "overlay defined on line " + lineNum + 
    174             ": invalid dimensional position."); 
    175           continue; 
    176         } 
    177         obj.x1 = x1; 
    178         obj.y1 = y1; 
    179         obj.x2 = x2; 
    180         obj.y2 = y2; 
    181         obj.text = text; 
    182         obj.color = color; 
    183         obj.filled = filled; 
    184         obj.group = group; 
    185         obj.notes = notes; 
    186         obj.drawing = false; 
    187         obj.selected = false; 
    188         obj.computeGridParameters(); 
    189  
    190         // add overlay to list 
    191         loadedOverlays[r].add(obj); 
    192       } 
    193     } 
    194  
     237    } 
     238 
     239    if (nextFreeformToRestore < loadedFreeforms.size()) { 
     240      JOptionPane.showMessageDialog(owner, "Invalid overlay file: missing node lists for one or more Freeforms.",  
     241          "Cannot load overlays", JOptionPane.ERROR_MESSAGE); 
     242      return null; 
     243    } 
     244     
    195245    if (loadedOverlays == null) { 
    196246      JOptionPane.showMessageDialog(owner, 
     
    208258    int[] lengths = trans.getLengths(); 
    209259    Vector[] overlays = trans.overlays; 
     260    Vector savedFreeforms = new Vector(); 
    210261 
    211262    // file header 
     
    229280      for (int j=0; j<overlays[i].size(); j++) { 
    230281        OverlayObject obj = (OverlayObject) overlays[i].elementAt(j); 
     282        if (obj instanceof OverlayFreeform) savedFreeforms.add(obj); 
    231283        out.print(obj.toString()); 
    232284        out.print("\t"); 
     
    251303      } 
    252304    } 
     305 
     306    // nodes of freeforms, one freeform per line 
     307    for (int i=0; i<savedFreeforms.size(); i++) { 
     308      OverlayFreeform of = (OverlayFreeform) savedFreeforms.get(i); 
     309      float[][] nodes = of.getNodes(); 
     310      for (int j=0; j<nodes[0].length; j++) { 
     311        out.print("("+nodes[0][j]+","+nodes[1][j]+") "); 
     312      } 
     313      out.println(); 
     314    }  
    253315  } 
    254316 
  • trunk/loci/visbio/overlays/OverlayObject.java

    r1846 r1865  
    299299  } 
    300300 
     301  /** Sets the node array to that provided--for loading from saved */ 
     302  public void setNodes(float[][] nodes) { 
     303    this.nodes = nodes; 
     304    numNodes = nodes[0].length; 
     305    maxNodes = numNodes; 
     306    computeLength(); 
     307    updateBoundingBox(); 
     308    computeGridParameters(); 
     309  } 
     310 
    301311  /** Changes X coordinate of the overlay's second endpoint. */ 
    302312  public void setX2(float x2) { 
     
    404414  /** Computes length of curve */ 
    405415  public void computeLength() { 
    406     truncateNodeArray(); 
     416    if (maxNodes != numNodes) truncateNodeArray(); 
    407417    double length = 0; 
    408418    for (int i=0; i<numNodes-1; i++) { 
Note: See TracChangeset for help on using the changeset viewer.