6
6
import ij .plugin .PointToolOptions ;
7
7
import ij .plugin .filter .Analyzer ;
8
8
import ij .plugin .frame .Recorder ;
9
+ import ij .util .Tools ;
9
10
import ij .util .Java2 ;
10
11
import java .awt .*;
11
12
import java .awt .image .*;
@@ -22,6 +23,8 @@ public class PointRoi extends PolygonRoi {
22
23
public static final String [] sizes = {"Tiny" , "Small" , "Medium" , "Large" , "Extra Large" , "XXL" , "XXXL" };
23
24
public static final String [] types = {"Hybrid" , "Cross" , "Dot" , "Circle" };
24
25
public static final int HYBRID =0 , CROSS =1 , CROSSHAIR =1 , DOT =2 , CIRCLE =3 ;
26
+ /** Returned by getPosition if point stack positions are different */
27
+ public static final int POINTWISE_POSITION = -2 ;
25
28
private static final String TYPE_KEY = "point.type" ;
26
29
private static final String SIZE_KEY = "point.size" ;
27
30
private static final String CROSS_COLOR_KEY = "point.cross.color" ;
@@ -215,12 +218,13 @@ public void draw(Graphics g) {
215
218
if (fontSize >9 )
216
219
Java2 .setAntialiasedText (g , true );
217
220
}
218
- int slice = imp !=null &&positions !=null &&imp .getStackSize ()>1 ?imp .getCurrentSlice ():0 ;
221
+ int [] positions = this .positions ; //use a copy to avoid NullPointerException on asynchronous change to null
222
+ int slice = imp !=null && positions !=null && imp .getStackSize ()>1 ?imp .getCurrentSlice ():0 ;
219
223
ImageCanvas ic = imp !=null ?imp .getCanvas ():null ;
220
224
if (ic !=null && overlay && ic .getShowAllList ()!=null && ic .getShowAllList ().contains (this ) && !Prefs .showAllSliceOnly )
221
- slice = 0 ; // draw point irrespective of currently selected slice
225
+ slice = 0 ; // In RoiManager's "show all" mode and not "associate with slice", draw point irrespective of currently selected slice
222
226
if (Prefs .showAllPoints )
223
- slice = 0 ;
227
+ slice = 0 ; // "Show on all slices" in Point tool options
224
228
//IJ.log("draw: "+positions+" "+imp.getCurrentSlice());
225
229
for (int i =0 ; i <nPoints ; i ++) {
226
230
//IJ.log(i+" "+slice+" "+(positions!=null?positions[i]:-1)+" "+getPosition());
@@ -690,6 +694,52 @@ public void updateCounts() {
690
694
counts [(counters ==null || counters [i ]>=counts .length ) ? 0 : counters [i ]] ++;
691
695
}
692
696
697
+ /** Sets the stack position (image number) of all points in this Roi.
698
+ * The points are only displayed when the stack is at the specified position.
699
+ * Set to zero to have the points displayed on all images in the stack.
700
+ * The stack position, when set, determines the visibility of this Roi
701
+ * (i) if it is part of an overlay (normal overlay or the RoiManager's
702
+ * 'Show All' overlay), or
703
+ * (ii) if it is the currently active Roi and Prefs.showAllPoints
704
+ * ('Show an all slices' in the Point Tool Options dialog) is off.
705
+ * Clears any association of this Roi to a hyperstack position.
706
+ *
707
+ * Note that the behavior differs from that of the other Roi types:
708
+ * For the other Roi types, setPosition does not restrict the visibility
709
+ * to stack slice 'n' if that roi is the currently active Roi; it only
710
+ * affects the visibility if that Roi is part of an overlay.
711
+ */
712
+ public void setPosition (int n ) {
713
+ if (n <0 && n !=POINTWISE_POSITION )
714
+ n = 0 ;
715
+ if (n == 0 ) {
716
+ positions = null ;
717
+ } else {
718
+ if (positions == null )
719
+ positions = new int [counters == null ? nPoints *2 : counters .length ];
720
+ if (n != POINTWISE_POSITION )
721
+ Arrays .fill (positions , n );
722
+ }
723
+ hyperstackPosition = false ;
724
+ }
725
+
726
+ /** Returns the stack position (image number) of the points in this Roi, if
727
+ * all points have the same position. Returns 0 if none of the points is
728
+ * associated with a particular stack image, and PointRoi.POINTWISE_POSITION = -2
729
+ * if there are different stack positions for different points.
730
+ */
731
+ public int getPosition () {
732
+ if (positions == null || nPoints < 1 ) {
733
+ return 0 ;
734
+ } else {
735
+ int position = positions [0 ];
736
+ for (int i =1 ; i <nPoints ; i ++)
737
+ if (positions [i ] != position )
738
+ return POINTWISE_POSITION ;
739
+ return position ;
740
+ }
741
+ }
742
+
693
743
/** Returns the stack slice of the point with the given index, or 0 if no slice defined for this point */
694
744
public int getPointPosition (int index ) {
695
745
if (positions !=null && index <nPoints )
@@ -698,6 +748,18 @@ public int getPointPosition(int index) {
698
748
return 0 ;
699
749
}
700
750
751
+ /** Returns whether this Roi contains a point associated to the given stack slice.
752
+ * Returns true for (non-existant) slice 0.
753
+ * Does not care whether points would be shown irrespective of the slice number
754
+ * (as given by the Point Tool options "Show on all slices", Prefs.showAllPoints).
755
+ */
756
+ public boolean hasPointPosition (int slice ) {
757
+ if (slice < 0 ) return false ;
758
+ if (slice == 0 ) return true ;
759
+ if (positions == null ) return true ;
760
+ return Tools .indexOf (positions , slice ) >= 0 ;
761
+ }
762
+
701
763
public void displayCounts () {
702
764
ImagePlus imp = getImage ();
703
765
String firstColumnHdr = "Slice" ;
0 commit comments