package ij.gui;
import ij.*;
import java.awt.*;
class RoiBrush implements Runnable {
static int ADD=0, SUBTRACT=1;
static int leftClick=16, alt=9, shift=1;
private Polygon poly;
private Point previousP;
private int mode = ADD;
RoiBrush() {
Thread thread = new Thread(this, "RoiBrush");
thread.start();
}
public void run() {
int size = Toolbar.getBrushSize();
ImagePlus img = WindowManager.getCurrentImage();
if (img==null) return;
ImageCanvas ic = img.getCanvas();
if (ic==null) return;
Roi roi = img.getRoi();
if (roi!=null && !roi.isArea())
img.deleteRoi();
Point p = ic.getCursorLoc();
if (roi!=null && !roi.contains(p.x, p.y))
mode = SUBTRACT;
int flags;
while (true) {
p = ic.getCursorLoc();
if (p.equals(previousP))
{IJ.wait(1); continue;}
previousP = p;
flags = ic.getModifiers();
if ((flags&leftClick)==0) return;
if ((flags&shift)!=0)
mode = ADD;
else if ((flags&alt)!=0)
mode = SUBTRACT;
if (mode==ADD)
addCircle(img, p.x, p.y, size);
else
subtractCircle(img, p.x, p.y, size);
}
}
void addCircle(ImagePlus img, int x, int y, int width) {
Roi roi = img.getRoi();
Roi roi2 = roi;
if (roi2!=null) {
if (!(roi2 instanceof ShapeRoi))
roi2 = new ShapeRoi(roi2);
((ShapeRoi)roi2).or(getCircularRoi(x, y, width));
roi2.copyAttributes(roi);
} else
roi2 = new OvalRoi(x-width/2, y-width/2, width, width);
img.setRoi(roi2);
}
void subtractCircle(ImagePlus img, int x, int y, int width) {
Roi roi = img.getRoi();
Roi roi2 = roi;
if (roi2!=null) {
if (!(roi2 instanceof ShapeRoi))
roi2 = new ShapeRoi(roi2);
((ShapeRoi)roi2).not(getCircularRoi(x, y, width));
roi2.copyAttributes(roi);
img.setRoi(roi2);
}
}
ShapeRoi getCircularRoi(int x, int y, int width) {
if (poly==null) {
Roi roi = new OvalRoi(x-width/2, y-width/2, width, width);
poly = roi.getPolygon();
for (int i=0; i<poly.npoints; i++) {
poly.xpoints[i] -= x;
poly.ypoints[i] -= y;
}
}
return new ShapeRoi(x, y, poly);
}
}