Changeset 2697


Ignore:
Timestamp:
04/27/07 12:34:25 (13 years ago)
Author:
sorber
Message:

Selection layers returned by OverlayUtil.getSelectionLayer() are now scaled to the current display.
PointerTool selection threshold is scaled to the current display.
Restored method for computing text bounds to OverlayText (renamed computeTextBounds()).

Location:
trunk/loci/visbio
Files:
4 edited

Legend:

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

    r2667 r2697  
    2525 
    2626import java.awt.Color; 
     27import java.awt.FontMetrics; 
    2728import java.rmi.RemoteException; 
    2829import visad.*; 
     
    4546    x1 = x; 
    4647    y1 = y; 
     48    x2 = x; 
     49    y2 = y; 
    4750    this.text = text; 
     51    computeTextBounds(); 
     52    // System.out.println("New text object created with text [" + text + "]"); 
     53    // System.out.println("text bounds: [" + x1 + "," + y1 + "] [" + x2 + "," + 
     54    //    y2 + "]"); 
    4855  } 
    4956 
     
    5360  public static String[] getStatTypes() {return statTypes;} 
    5461 
     62  // -- OverlayText API methods -- 
     63 
     64  public void computeTextBounds() { 
     65    // Computing the grid for text overlays is difficult because the size of  
     66    // the overlay depends on the font metrics, which are obtained from an AWT  
     67    // component (in this case, window.getDisplay().getComponent() for a  
     68    // display window), but data transforms have no knowledge of which display  
     69    // windows are currently displaying them.  
     70 
     71    // HACK - for now, use this harebrained scheme to estimate the bounds  
     72    int sx = overlay.getScalingValueX();  
     73    int sy = overlay.getScalingValueY();  
     74    float mw = sx / 318f, mh = sy / 640f; // obtained through experimentation  
     75    FontMetrics fm = overlay.getFontMetrics();  
     76    x2 = x1 + mw * fm.stringWidth(text);  
     77    y2 = y1 + mh * fm.getHeight();  
     78  }  
     79  
    5580  // -- OverlayObject API methods -- 
    5681 
  • trunk/loci/visbio/overlays/OverlayTransform.java

    r2667 r2697  
    258258        obj.drawing = false; 
    259259        obj.selected = true; 
     260        if (obj instanceof OverlayText)  
     261          ((OverlayText) obj).computeTextBounds(); 
    260262        overlays[ndx].add(obj); 
    261263      } 
     
    377379        obj.drawing = false; 
    378380        obj.selected = false; 
     381        if (obj instanceof OverlayText)  
     382          ((OverlayText) obj).computeTextBounds(); 
    379383 
    380384        overlays[ndx].add(obj); 
     
    699703    // recompute grid boxes for text overlays 
    700704    // 4/24 removed computeGridParameters method 
     705    for (int j=0; j<overlays.length; j++) { 
     706      for (int i=0; i<overlays[j].size(); i++) { 
     707        OverlayObject obj = (OverlayObject) overlays[j].get(i); 
     708        if (obj instanceof OverlayText)  
     709          ((OverlayText) obj).computeTextBounds(); 
     710      } 
     711    } 
    701712 
    702713    notifyListeners(new TransformEvent(this, TransformEvent.DATA_CHANGED)); 
  • trunk/loci/visbio/overlays/PointerTool.java

    r2524 r2697  
    2828import loci.visbio.data.TransformEvent; 
    2929import loci.visbio.util.MathUtil; 
     30import loci.visbio.util.OverlayUtil; 
    3031import visad.DisplayEvent; 
    3132import visad.DisplayImpl; 
     
    9293    } 
    9394 
    94     double threshold = 0.02 * overlay.getScalingValue(); 
     95    // Factor 8.5 obtained through trail and error. 
     96    double threshold = 8.5f * OverlayUtil.getMultiplier(display); 
    9597 
    9698    if (dist < threshold) { 
  • trunk/loci/visbio/util/OverlayUtil.java

    r2666 r2697  
    2323 
    2424import java.awt.Color; 
    25 import java.awt.FontMetrics; 
    2625import java.rmi.RemoteException; 
    2726import java.util.Arrays; 
     
    2928import loci.visbio.view.TransformLink; 
    3029import visad.*; 
     30import visad.util.CursorUtil; 
    3131 
    3232/** Utility methods for Overlays */ 
     
    3636 
    3737  /** Width of the selection layer beyond the object's boundaries */ 
    38   protected static final float GLOW_WIDTH = 1.0f; 
     38  protected static final float GLOW_WIDTH = 5.0f; // in pixels 
    3939 
    4040  /** Alpha of the selection layer */ 
     
    112112    float y1 = obj.getY(); 
    113113    float y2 = obj.getY2(); 
    114  
    115114    // compute corners of arrow tail 
    116115    float padding = 0.02f * overlay.getScalingValue(); 
     
    137136    c = Math.sqrt(a * a + b * b); 
    138137 
    139     double scl = 1; // for now 
    140     double d = GLOW_WIDTH * scl; 
     138    double d = GLOW_WIDTH * getMultiplier(link); 
    141139 
    142140    // compute four corners of highlighted zone 
     
    188186    TupleType range = overlay.getRangeType(); 
    189187 
    190     float delta = GLOW_WIDTH; 
    191188    float x1 = obj.getX(); 
    192189    float x2 = obj.getX2(); 
    193190    float y1 = obj.getY(); 
    194191    float y2 = obj.getY2(); 
     192 
     193    float delta = GLOW_WIDTH * getMultiplier(link); 
    195194 
    196195    // Determine orientation of (x1, y1) relative to (x2, y2) 
     
    199198    // supposition that the box is oriented like this: 
    200199    // 
    201     // (x1, y1) +--------+ 
     200    //       p1 +--------+ 
    202201    //          |        | 
    203202    //          |        | 
    204     //          +--------+ (x2, y2) 
     203    //          +--------+ p2 
    205204    // 
    206205    // which means x1 is supposed to be _less_ than x2, but inconsistently, 
     
    217216    float[][] setSamples = { 
    218217      {xx1 - delta, xx2 + delta, xx1 - delta, xx2 + delta}, 
    219       {yy1 + delta, yy1 + delta, yy2 - delta, yy2 - delta}}; 
     218      {yy1 + delta, yy1 + delta, yy2 - delta, yy2 - delta} 
     219    }; 
    220220     
    221221    // construct range samples 
     
    255255    float y1 = obj.getY(); 
    256256    float y2 = obj.getY2(); 
    257  
    258     float delta = GLOW_WIDTH; 
     257   
     258    /* 
     259    // method for doing math in pixel coordinates part 1 of 2 
     260    float[] p1 = domainToPixel(link, new float[]{obj.getX(), obj.getY()}); 
     261    float[] p2 = domainToPixel(link, new float[]{obj.getX2(), obj.getY2()}); 
     262 
     263    float x1 = p1[0]; 
     264    float x2 = p2[0]; 
     265    float y1 = p1[1]; 
     266    float y2 = p2[1]; 
     267    */ 
     268 
     269    float delta = GLOW_WIDTH * getMultiplier(link); 
    259270 
    260271    // compute locations of grid points 
     
    270281    float dy2 = ratio * y; 
    271282 
    272     float[] p1 = {x1 - dx1 - dx2, y1 + dy1 - dy2}; 
    273     float[] p2 = {x2 - dx1 + dx2, y2 + dy1 + dy2}; 
    274     float[] p3 = {x1 + dx1 - dx2, y1 - dy1 - dy2}; 
    275     float[] p4 = {x2 + dx1 + dx2, y2 - dy1 + dy2}; 
    276  
    277     float[][] setSamples = {{p1[0], p2[0], p3[0], p4[0]}, 
    278                             {p1[1], p2[1], p3[1], p4[1]}}; 
     283    float[] c1 = {x1 - dx1 - dx2, y1 + dy1 - dy2}; 
     284    float[] c2 = {x2 - dx1 + dx2, y2 + dy1 + dy2}; 
     285    float[] c3 = {x1 + dx1 - dx2, y1 - dy1 - dy2}; 
     286    float[] c4 = {x2 + dx1 + dx2, y2 - dy1 + dy2}; 
     287 
     288    float[][] setSamples = {{c1[0], c2[0], c3[0], c4[0]}, 
     289                            {c1[1], c2[1], c3[1], c4[1]}};  
     290 
     291    /* 
     292    // method for doing math in pixel coordinates part 2 of 2 
     293    float[][] setSamplesPxl = {{c1[0], c2[0], c3[0], c4[0]}, 
     294                            {c1[1], c2[1], c3[1], c4[1]}}; 
     295 
     296    float[][] setSamples = pixelToDomain(link, setSamplesPxl); 
     297    */ 
    279298 
    280299    // construct range samples; 
     
    318337 
    319338    float size = 0.02f * overlay.getScalingValue(); 
    320     float delta = GLOW_WIDTH; 
     339    float delta = GLOW_WIDTH * getMultiplier(link); 
    321340 
    322341    float xx1 = x1 - size - delta; 
     
    438457    OverlayNodedObject nobj = (OverlayNodedObject) obj; 
    439458 
    440     float delta = GLOW_WIDTH; 
     459    float delta = GLOW_WIDTH * getMultiplier(link); 
    441460    float[][] nodes = nobj.getNodes(); 
    442461    int numNodes = nobj.getNumNodes();  
     
    525544    float rry = cy > y1 ? cy - y1 : cy - y2; 
    526545 
    527     float scl = 1; // for now 
     546    float scl = getMultiplier(link); // for now 
    528547    float rx = rrx + GLOW_WIDTH * scl; 
    529548    float ry = rry + GLOW_WIDTH * scl; 
     
    578597    TupleType range = overlay.getRangeType(); 
    579598 
    580     float[][] corners = computeTextOutline((OverlayText) obj, overlay); 
     599    ((OverlayText) obj).computeTextBounds(); 
     600    float[][] corners = computeOutline(obj, link); 
    581601 
    582602    float[][] setSamples = { 
     
    620640    float y2 = obj.getY2(); 
    621641 
    622     float[][] cnrs = computeOutline(obj, overlay); 
     642    float[][] cnrs = computeOutline(obj, link); 
    623643 
    624644    float[][] setSamples = null; 
     
    656676  } 
    657677 
     678  /**  
     679   * Returns a multiplier suitable for scaling distances to pixel coordinates. 
     680   * Useful when the location of an event are unimportant, just the properties 
     681   * of the display.  
     682   */ 
     683  public static float getMultiplier(TransformLink link) { 
     684    DisplayImpl display = link.getHandler().getWindow().getDisplay(); 
     685    return getMultiplier(display); 
     686  } 
     687 
     688  /**  
     689   * Returns a multiplier suitable for scaling distances to pixel coordinates. 
     690   * Useful when the location of an event are unimportant, just the properties 
     691   * of the display.  
     692   */ 
     693  public static float getMultiplier(DisplayImpl display) { 
     694    int[] p1 = {0,0}; 
     695    int[] p2 = {0, 1000}; 
     696    double[] d1 = CursorUtil.pixelToDomain(display, p1[0], p1[1]); 
     697    double[] d2 = CursorUtil.pixelToDomain(display, p2[0], p2[1]); 
     698    int px = p2[0] - p1[0]; 
     699    int py = p2[1] - p1[1]; 
     700    double dx = d2[0] - d1[0]; 
     701    double dy = d2[1] - d1[1]; 
     702    double pp = Math.sqrt(px * px + py * py); 
     703    double dd = Math.sqrt(dx * dx + dy * dy); 
     704    return (float) (dd / pp); 
     705  } 
     706 
    658707  // -- Helper Methods -- 
    659708 
    660   // Note: Both of these methods are basically the old  
     709  // Note: This method is basically the old  
    661710  // OverlayObject.computeGridParameters() 
    662   // methods, the first from OverlayText, the second from OverlayBox. 
    663  
    664   /** Computes the corners of an OverlayText object's outline */ 
    665   private static float[][] computeTextOutline(OverlayText obj,  
    666       OverlayTransform overlay) { 
    667     // Computing the grid for text overlays is difficult because the size of 
    668     // the overlay depends on the font metrics, which are obtained from an AWT 
    669     // component (in this case, window.getDisplay().getComponent() for a 
    670     // display window), but data transforms have no knowledge of which display 
    671     // windows are currently displaying them. 
    672  
     711  // method from OverlayBox. 
     712  /** Computes corners of an OverlayObject's outline */ 
     713  private static float[][] computeOutline(OverlayObject obj, 
     714     TransformLink link) {  
     715    DisplayImpl display = link.getHandler().getWindow().getDisplay(); 
    673716    float x1 = obj.getX(); 
    674717    float x2 = obj.getX2(); 
     
    676719    float y2 = obj.getY2(); 
    677720 
    678     // HACK - for now, use this harebrained scheme to estimate the bounds 
    679     int sx = overlay.getScalingValueX(); 
    680     int sy = overlay.getScalingValueY(); 
    681     float mw = sx / 318f, mh = sy / 640f; // obtained through experimentation 
    682     FontMetrics fm = overlay.getFontMetrics(); 
    683     x2 = x1 + mw * fm.stringWidth(obj.getText()); 
    684     y2 = y1 + mh * fm.getHeight(); 
    685  
    686     float padx = 0.02f * sx; 
    687     float pady = 0.02f * sy; 
    688     float xx1 = x1 - padx; 
    689     float xx2 = x2 + padx; 
    690     float yy1 = y1 - pady; 
    691     float yy2 = y2 + pady; 
    692  
    693     return new float[][]{{xx1, yy1}, {xx2, yy2}}; 
    694   } 
    695  
    696   /** Computes corners of an OverlayObject's outline */ 
    697   private static float[][] computeOutline(OverlayObject obj, 
    698      OverlayTransform overlay) {  
    699     if (obj instanceof OverlayText) return computeTextOutline( 
    700         (OverlayText) obj, overlay); 
    701  
    702     float x1 = obj.getX(); 
    703     float x2 = obj.getX2(); 
    704     float y1 = obj.getY(); 
    705     float y2 = obj.getY2(); 
    706  
    707     float padding = 0.02f * overlay.getScalingValue(); 
     721    float scl = 0; 
     722    if (obj instanceof OverlayText) scl = .25f; 
     723    float padding = GLOW_WIDTH * (scl + getMultiplier(link)); 
    708724    boolean flipX = x2 < x1; 
    709725    float xx1 = flipX ? (x1 + padding) : (x1 - padding); 
     
    713729    float yy2 = flipY ? (y2 - padding) : (y2 + padding); 
    714730 
    715     return new float[][]{{x1, y1}, {x2, y2}}; 
    716   } 
     731    return new float[][]{{xx1, yy1}, {xx2, yy2}}; 
     732  } 
     733 
     734  /** Computes outline of a text object  */ 
     735  private static float[][] computeTextOutline(OverlayObject obj, 
     736      OverlayTransform overlay) { 
     737    if (obj instanceof OverlayText) ((OverlayText) obj).computeTextBounds(); 
     738    float x1 = obj.getX(); 
     739    float x2 = obj.getX2(); 
     740    float y1 = obj.getY(); 
     741    float y2 = obj.getY2(); 
     742 
     743    int sx = overlay.getScalingValueX();  
     744    int sy = overlay.getScalingValueY();  
     745 
     746    float padx = 0.02f * sx;  
     747    float pady = 0.02f * sy;  
     748    float xx1 = x1 - padx;  
     749    float xx2 = x2 + padx;  
     750    float yy1 = y1 - pady;  
     751    float yy2 = y2 + pady;  
     752 
     753    return new float[][]{{xx1, yy1}, {xx2, yy2}}; 
     754  } 
     755 
     756  /** Converts float coordinates to a pixel coordinateis (as floats) */ 
     757  private static float[] domainToPixel(TransformLink link, float[] d) { 
     758    DisplayImpl display = link.getHandler().getWindow().getDisplay(); 
     759    double[] dDbl = new double[d.length]; // domain coordinates as doubles 
     760    for (int i=0; i<d.length; i++) dDbl[i] = (double) d[i]; 
     761    int[] p = CursorUtil.domainToPixel(display, dDbl); 
     762    float[] pfloat = new float[p.length]; // pixel coordinates as floats 
     763    for (int i=0; i<p.length; i++) pfloat[i] = (float) p[i]; 
     764    return pfloat; 
     765  } 
     766 
     767  /** Converts pixel coordinateis (as floats) to domain coordinates */ 
     768  private static float[] pixelToDomain(TransformLink link, float[] p) { 
     769    DisplayImpl display = link.getHandler().getWindow().getDisplay(); 
     770    // pixel coords cast down to ints here: 
     771    double[] d = CursorUtil.pixelToDomain(display, 
     772      (int) (p[0]+ 1), (int) (p[1] + 1)); 
     773    float[] dfloat = new float[d.length]; // domain coordinates as floats 
     774    for (int i=0; i<d.length; i++) dfloat[i] = (float) d[i]; 
     775    return dfloat; 
     776  } 
     777 
     778  /** Converts an array of pixels as floats to domain */ 
     779  private static float[][] pixelToDomain(TransformLink link, 
     780      float[][] pixelSamples) { 
     781    DisplayImpl display = link.getHandler().getWindow().getDisplay(); 
     782    float[][] domainSamples = new 
     783      float[pixelSamples.length][pixelSamples[0].length]; 
     784    for (int i=0; i<pixelSamples[0].length; i++) { 
     785      // cast down to int here 
     786      double[] d = CursorUtil.pixelToDomain(display, 
     787          (int) (pixelSamples[0][i] + 1), (int) (pixelSamples[1][i] + 1)); 
     788      domainSamples[0][i] = (float) d[0]; 
     789      domainSamples[1][i] = (float) d[1]; 
     790    } 
     791    return domainSamples; 
     792  } 
     793 
    717794} 
Note: See TracChangeset for help on using the changeset viewer.