package ij.gui;
import ij.*;
import ij.plugin.Colors;
import ij.io.RoiDecoder;
import java.awt.*;
import java.util.*;
/** Displays a dialog that allows the user to specify ROI properties such as color and line width. */
public class RoiProperties {
private Roi roi;
private String title;
private boolean showName = true;
private boolean addToOverlay;
private boolean overlayOptions;
private boolean existingOverlay;
private boolean setPositions;
private static final String[] justNames = {"Left", "Center", "Right"};
/** Constructs a ColorChooser using the specified title and initial color. */
public RoiProperties(String title, Roi roi) {
if (roi==null)
throw new IllegalArgumentException("ROI is null");
this.title = title;
showName = title.startsWith("Prop");
addToOverlay = title.equals("Add to Overlay");
overlayOptions = title.equals("Overlay Options");
ImagePlus imp = WindowManager.getCurrentImage();
if (overlayOptions) {
Overlay overlay = imp!=null?imp.getOverlay():null;
setPositions = roi.getPosition()!=0;
if (overlay!=null)
existingOverlay = true;
}
this.roi = roi;
}
private String decodeColor(Color color, Color defaultColor) {
if (color==null)
color = defaultColor;
String str = "#"+Integer.toHexString(color.getRGB());
if (str.length()==9 && str.startsWith("#ff"))
str = "#"+str.substring(3);
String lc = Colors.hexToColor(str);
if (lc!=null) str = lc;
return str;
}
/** Displays the dialog box and returns 'false' if the user cancels it. */
public boolean showDialog() {
Color strokeColor = null;
Color fillColor = null;
double strokeWidth = 1.0;
String name= roi.getName();
boolean isRange = name!=null && name.startsWith("range: ");
String nameLabel = isRange?"Range:":"Name:";
if (isRange) name = name.substring(7);
if (name==null) name = "";
if (!isRange && (roi instanceof ImageRoi))
return showImageDialog(name);
if (roi.getStrokeColor()!=null) strokeColor = roi.getStrokeColor();
if (strokeColor==null) strokeColor = Roi.getColor();
if (roi.getFillColor()!=null) fillColor = roi.getFillColor();
double width = roi.getStrokeWidth();
if (width>1.0) strokeWidth = width;
boolean isText = roi instanceof TextRoi;
boolean isLine = roi.isLine();
int justification = TextRoi.LEFT;
if (isText) {
TextRoi troi = (TextRoi)roi;
Font font = troi.getCurrentFont();
strokeWidth = font.getSize();
justification = troi.getJustification();
}
String linec = strokeColor!=null?"#"+Integer.toHexString(strokeColor.getRGB()):"none";
if (linec.length()==9 && linec.startsWith("#ff"))
linec = "#"+linec.substring(3);
String lc = Colors.hexToColor(linec);
if (lc!=null) linec = lc;
String fillc = fillColor!=null?"#"+Integer.toHexString(fillColor.getRGB()):"none";
if (IJ.isMacro()) fillc = "none";
int digits = (int)strokeWidth==strokeWidth?0:1;
GenericDialog gd = new GenericDialog(title);
if (showName)
gd.addStringField(nameLabel, name, 15);
gd.addStringField("Stroke color: ", linec);
if (isText) {
gd.addNumericField("Font size:", strokeWidth, digits);
gd.addChoice("Justification:", justNames, justNames[justification]);
} else
gd.addNumericField("Width:", strokeWidth, digits);
if (!isLine) {
gd.addMessage("");
gd.addStringField("Fill color: ", fillc);
}
if (addToOverlay)
gd.addCheckbox("New overlay", false);
if (overlayOptions) {
if (existingOverlay) {
gd.addCheckbox("Apply to current overlay", false);
}
gd.addCheckbox("Set stack positions", setPositions);
}
gd.showDialog();
if (gd.wasCanceled()) return false;
if (showName) {
name = gd.getNextString();
if (!isRange) roi.setName(name.length()>0?name:null);
}
linec = gd.getNextString();
strokeWidth = gd.getNextNumber();
if (isText)
justification = gd.getNextChoiceIndex();
if (!isLine)
fillc = gd.getNextString();
boolean applyToOverlay = false;
boolean newOverlay = addToOverlay?gd.getNextBoolean():false;
if (overlayOptions) {
if (existingOverlay)
applyToOverlay = gd.getNextBoolean();
setPositions = gd.getNextBoolean();
roi.setPosition(setPositions?1:0);
}
strokeColor = Colors.decode(linec, Roi.getColor());
fillColor = Colors.decode(fillc, null);
if (isText) {
TextRoi troi = (TextRoi)roi;
Font font = troi.getCurrentFont();
if ((int)strokeWidth!=font.getSize()) {
font = new Font(font.getName(), font.getStyle(), (int)strokeWidth);
troi.setCurrentFont(font);
}
if (justification!=troi.getJustification())
troi.setJustification(justification);
} else if (strokeWidth!=1.0 || roi.getStroke()!=null)
roi.setStrokeWidth((float)strokeWidth);
roi.setStrokeColor(strokeColor);
roi.setFillColor(fillColor);
if (newOverlay) roi.setName("new-overlay");
if (applyToOverlay) {
ImagePlus imp = WindowManager.getCurrentImage();
if (imp==null)
return true;
Overlay overlay = imp.getOverlay();
if (overlay==null)
return true;
Roi[] rois = overlay.toArray();
for (int i=0; i<rois.length; i++) {
rois[i].setStrokeColor(strokeColor);
rois[i].setStrokeWidth((float)strokeWidth);
rois[i].setFillColor(fillColor);
}
imp.draw();
}
//if (strokeWidth>1.0 && !roi.isDrawingTool())
// Line.setWidth(1);
return true;
}
public boolean showImageDialog(String name) {
GenericDialog gd = new GenericDialog(title);
gd.addStringField("Name:", name, 15);
gd.addNumericField("Opacity (0-100%):", ((ImageRoi)roi).getOpacity()*100.0, 0);
if (addToOverlay)
gd.addCheckbox("New Overlay", false);
gd.showDialog();
if (gd.wasCanceled()) return false;
name = gd.getNextString();
roi.setName(name.length()>0?name:null);
double opacity = gd.getNextNumber()/100.0;
((ImageRoi)roi).setOpacity(opacity);
boolean newOverlay = addToOverlay?gd.getNextBoolean():false;
if (newOverlay) roi.setName("new-overlay");
return true;
}
}