package ij.gui;
import java.awt.*;
import java.util.Properties;
import java.awt.image.*;
import ij.process.*;
import ij.measure.*;
import ij.plugin.WandToolOptions;
import ij.plugin.frame.Recorder;
import ij.plugin.frame.RoiManager;
import ij.plugin.tool.PlugInTool;
import ij.macro.*;
import ij.*;
import ij.util.*;
import java.awt.event.*;
import java.util.*;
import java.awt.geom.*;
import java.util.concurrent.atomic.AtomicBoolean;
public class ImageCanvas extends Canvas implements MouseListener, MouseMotionListener, Cloneable {
protected static Cursor defaultCursor = new Cursor(Cursor.DEFAULT_CURSOR);
protected static Cursor handCursor = new Cursor(Cursor.HAND_CURSOR);
protected static Cursor moveCursor = new Cursor(Cursor.MOVE_CURSOR);
protected static Cursor crosshairCursor = new Cursor(Cursor.CROSSHAIR_CURSOR);
public static boolean usePointer = Prefs.usePointerCursor;
protected ImagePlus imp;
protected boolean imageUpdated;
protected Rectangle srcRect;
protected int imageWidth, imageHeight;
protected int xMouse; protected int yMouse;
private boolean showCursorStatus = true;
private int sx2, sy2;
private boolean disablePopupMenu;
private static Color zoomIndicatorColor;
private static Font smallFont, largeFont;
private Font font;
private Rectangle[] labelRects;
private boolean maxBoundsReset;
private Overlay overlay, showAllOverlay;
private static final int LIST_OFFSET = 100000;
private static Color showAllColor = Prefs.getColor(Prefs.SHOW_ALL_COLOR, new Color(0, 255, 255));
private Color defaultColor = showAllColor;
private static Color labelColor, bgColor;
private int resetMaxBoundsCount;
private Roi currentRoi;
private int mousePressedX, mousePressedY;
private long mousePressedTime;
private boolean overOverlayLabel;
protected final static int MAX_MOUSEMOVE_ZOOM = 10;
protected int lastZoomSX = -9999999;
protected int lastZoomSY = -9999999;
protected int zoomTargetOX = -1;
protected int zoomTargetOY;
protected ImageJ ij;
protected double magnification;
protected int dstWidth, dstHeight;
protected int xMouseStart;
protected int yMouseStart;
protected int xSrcStart;
protected int ySrcStart;
protected int flags;
private Image offScreenImage;
private int offScreenWidth = 0;
private int offScreenHeight = 0;
private boolean mouseExited = true;
private boolean customRoi;
private boolean drawNames;
private AtomicBoolean paintPending;
private boolean scaleToFit;
private boolean painted;
private boolean hideZoomIndicator;
public ImageCanvas(ImagePlus imp) {
this.imp = imp;
paintPending = new AtomicBoolean(false);
ij = IJ.getInstance();
int width = imp.getWidth();
int height = imp.getHeight();
imageWidth = width;
imageHeight = height;
srcRect = new Rectangle(0, 0, imageWidth, imageHeight);
setSize(imageWidth, imageHeight);
magnification = 1.0;
addMouseListener(this);
addMouseMotionListener(this);
addKeyListener(ij); setFocusTraversalKeysEnabled(false);
}
void updateImage(ImagePlus imp) {
this.imp = imp;
int width = imp.getWidth();
int height = imp.getHeight();
imageWidth = width;
imageHeight = height;
srcRect = new Rectangle(0, 0, imageWidth, imageHeight);
setSize(imageWidth, imageHeight);
magnification = 1.0;
}
void update(ImageCanvas ic) {
if (ic==null || ic==this || ic.imp==null)
return;
if (ic.imp.getWidth()!=imageWidth || ic.imp.getHeight()!=imageHeight)
return;
srcRect = new Rectangle(ic.srcRect.x, ic.srcRect.y, ic.srcRect.width, ic.srcRect.height);
setMagnification(ic.magnification);
setSize(ic.dstWidth, ic.dstHeight);
}
public void setSourceRect(Rectangle r) {
if (r==null)
return;
r = new Rectangle(r.x, r.y, r.width, r.height);
imageWidth = imp.getWidth();
imageHeight = imp.getHeight();
if (r.x<0) r.x = 0;
if (r.y<0) r.y = 0;
if (r.width<1)
r.width = 1;
if (r.height<1)
r.height = 1;
if (r.width>imageWidth)
r.width = imageWidth;
if (r.height>imageHeight)
r.height = imageHeight;
if (r.x+r.width>imageWidth)
r.x = imageWidth-r.width;
if (r.y+r.height>imageHeight)
r.y = imageHeight-r.height;
if (srcRect==null)
srcRect = r;
else {
srcRect.x = r.x;
srcRect.y = r.y;
srcRect.width = r.width;
srcRect.height = r.height;
}
if (dstWidth==0) {
Dimension size = getSize();
dstWidth = size.width;
dstHeight = size.height;
}
magnification = (double)dstWidth/srcRect.width;
imp.setTitle(imp.getTitle());
if (IJ.debugMode) IJ.log("setSourceRect: "+magnification+" "+(int)(srcRect.height*magnification+0.5)+" "+dstHeight+" "+srcRect);
}
void setSrcRect(Rectangle srcRect) {
setSourceRect(srcRect);
}
public Rectangle getSrcRect() {
return srcRect;
}
public void setDrawingSize(int width, int height) {
dstWidth = width;
dstHeight = height;
setSize(dstWidth, dstHeight);
}
public void setSize(int width, int height) {
super.setSize(width, height);
dstWidth = width;
dstHeight = height;
}
public void setImageUpdated() {
imageUpdated = true;
}
public void setPaintPending(boolean state) {
paintPending.set(state);
}
public boolean getPaintPending() {
return paintPending.get();
}
public void update(Graphics g) {
paint(g);
}
public void paint(Graphics g) {
if (IJ.debugMode) IJ.log("ImageCanvas.paint: "+imp);
painted = true;
Roi roi = imp.getRoi();
if (roi!=null || overlay!=null || showAllOverlay!=null || Prefs.paintDoubleBuffered) {
if (roi!=null)
roi.updatePaste();
if (!IJ.isMacOSX() && imageWidth!=0) {
paintDoubleBuffered(g);
setPaintPending(false);
return;
}
}
try {
if (imageUpdated) {
imageUpdated = false;
imp.updateImage();
}
setInterpolation(g, Prefs.interpolateScaledImages);
Image img = imp.getImage();
if (img!=null)
g.drawImage(img, 0, 0, (int)(srcRect.width*magnification+0.5), (int)(srcRect.height*magnification+0.5),
srcRect.x, srcRect.y, srcRect.x+srcRect.width, srcRect.y+srcRect.height, null);
if (overlay!=null)
drawOverlay(overlay, g);
if (showAllOverlay!=null)
drawOverlay(showAllOverlay, g);
if (roi!=null) drawRoi(roi, g);
if (srcRect.width<imageWidth || srcRect.height<imageHeight)
drawZoomIndicator(g);
if (IJ.debugMode) showFrameRate(g);
}
catch(OutOfMemoryError e) {IJ.outOfMemory("Paint");}
setPaintPending(false);
}
private void setInterpolation(Graphics g, boolean interpolate) {
if (magnification==1)
return;
else if (magnification<1.0 || interpolate) {
Object value = RenderingHints.VALUE_RENDER_QUALITY;
((Graphics2D)g).setRenderingHint(RenderingHints.KEY_RENDERING, value);
} else if (magnification>1.0) {
Object value = RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR;
((Graphics2D)g).setRenderingHint(RenderingHints.KEY_INTERPOLATION, value);
}
}
private void drawRoi(Roi roi, Graphics g) {
if (roi==currentRoi) {
Color lineColor = roi.getStrokeColor();
Color fillColor = roi.getFillColor();
float lineWidth = roi.getStrokeWidth();
roi.setStrokeColor(null);
roi.setFillColor(null);
boolean strokeSet = roi.getStroke()!=null;
if (strokeSet)
roi.setStrokeWidth(1);
roi.draw(g);
roi.setStrokeColor(lineColor);
if (strokeSet)
roi.setStrokeWidth(lineWidth);
roi.setFillColor(fillColor);
currentRoi = null;
} else
roi.draw(g);
}
public int getSliceNumber(String label) {
if (label==null) return 0;
int slice = 0;
if (label.length()>=14 && label.charAt(4)=='-' && label.charAt(9)=='-')
slice = (int)Tools.parseDouble(label.substring(0,4),0);
else if (label.length()>=17 && label.charAt(5)=='-' && label.charAt(11)=='-')
slice = (int)Tools.parseDouble(label.substring(0,5),0);
else if (label.length()>=20 && label.charAt(6)=='-' && label.charAt(13)=='-')
slice = (int)Tools.parseDouble(label.substring(0,6),0);
return slice;
}
private void drawOverlay(Overlay overlay, Graphics g) {
if (imp!=null && imp.getHideOverlay() && overlay!=showAllOverlay)
return;
if (imp!=null && showAllOverlay!=null && overlay!=showAllOverlay)
overlay.drawLabels(false);
Color labelColor = overlay.getLabelColor();
if (labelColor==null) labelColor = Color.white;
initGraphics(overlay, g, labelColor, Roi.getColor());
int n = overlay.size();
if (IJ.debugMode) IJ.log("drawOverlay: "+n);
int currentImage = imp!=null?imp.getCurrentSlice():-1;
int stackSize = imp.getStackSize();
if (stackSize==1)
currentImage = -1;
int channel=0, slice=0, frame=0;
boolean hyperstack = imp.isHyperStack();
if (hyperstack) {
channel = imp.getChannel();
slice = imp.getSlice();
frame = imp.getFrame();
}
drawNames = overlay.getDrawNames() && overlay.getDrawLabels();
boolean drawLabels = drawNames || overlay.getDrawLabels();
if (drawLabels)
labelRects = new Rectangle[n];
else
labelRects = null;
font = overlay.getLabelFont();
Roi activeRoi = imp.getRoi();
boolean roiManagerShowAllMode = overlay==showAllOverlay && !Prefs.showAllSliceOnly;
for (int i=0; i<n; i++) {
if (overlay==null) break;
Roi roi = overlay.get(i);
if (roi==null) break;
if (hyperstack) {
int c = roi.getCPosition();
int z = roi.getZPosition();
int t = roi.getTPosition();
int position = roi.getPosition();
if (position>0) {
if (z==0 && imp.getNSlices()>1)
z = position;
else if (t==0)
t = position;
}
if (((c==0||c==channel) && (z==0||z==slice) && (t==0||t==frame)) || roiManagerShowAllMode)
drawRoi(g, roi, drawLabels?i+LIST_OFFSET:-1);
} else {
int position = stackSize>1?roi.getPosition():0;
if (position==0 && stackSize>1)
position = getSliceNumber(roi.getName());
if (position>0 && imp.getCompositeMode()==IJ.COMPOSITE)
position = 0;
if (position==0 || position==currentImage || roiManagerShowAllMode)
drawRoi(g, roi, drawLabels?i+LIST_OFFSET:-1);
}
}
((Graphics2D)g).setStroke(Roi.onePixelWide);
drawNames = false;
font = null;
}
void drawOverlay(Graphics g) {
drawOverlay(overlay, g);
}
private void initGraphics(Overlay overlay, Graphics g, Color textColor, Color defaultColor) {
if (smallFont==null) {
smallFont = new Font("SansSerif", Font.PLAIN, 9);
largeFont = ImageJ.SansSerif12;
}
if (textColor!=null) {
labelColor = textColor;
if (overlay!=null && overlay.getDrawBackgrounds())
bgColor = new Color(255-labelColor.getRed(), 255-labelColor.getGreen(), 255-labelColor.getBlue());
else
bgColor = null;
} else {
int red = defaultColor.getRed();
int green = defaultColor.getGreen();
int blue = defaultColor.getBlue();
if ((red+green+blue)/3<128)
labelColor = Color.white;
else
labelColor = Color.black;
bgColor = defaultColor;
}
this.defaultColor = defaultColor;
g.setColor(defaultColor);
}
void drawRoi(Graphics g, Roi roi, int index) {
ImagePlus imp2 = roi.getImage();
roi.setImage(imp);
Color saveColor = roi.getStrokeColor();
if (saveColor==null)
roi.setStrokeColor(defaultColor);
if (roi.getStroke()==null)
((Graphics2D)g).setStroke(Roi.onePixelWide);
if (roi instanceof TextRoi)
((TextRoi)roi).drawText(g);
else
roi.drawOverlay(g);
roi.setStrokeColor(saveColor);
if (index>=0) {
if (roi==currentRoi)
g.setColor(Roi.getColor());
else
g.setColor(defaultColor);
drawRoiLabel(g, index, roi);
}
if (imp2!=null)
roi.setImage(imp2);
else
roi.setImage(null);
}
void drawRoiLabel(Graphics g, int index, Roi roi) {
if (roi.isCursor())
return;
boolean pointRoi = roi instanceof PointRoi;
Rectangle r = roi.getBounds();
int x = screenX(r.x);
int y = screenY(r.y);
double mag = getMagnification();
int width = (int)(r.width*mag);
int height = (int)(r.height*mag);
int size = width>40 || height>40?12:9;
int pointSize = 0;
int crossSize = 0;
if (pointRoi) {
pointSize = ((PointRoi)roi).getSize();
switch (pointSize) {
case 0: case 1: size=9; break;
case 2: case 3: size=10; break;
case 4: size=12; break;
}
crossSize = pointSize + 10 + 2*pointSize;
}
if (font!=null) {
g.setFont(font);
size = font.getSize();
} else if (size==12)
g.setFont(largeFont);
else
g.setFont(smallFont);
boolean drawingList = index >= LIST_OFFSET;
if (drawingList) index -= LIST_OFFSET;
String label = "" + (index+1);
if (drawNames)
label = roi.getName();
if (label==null)
return;
FontMetrics metrics = g.getFontMetrics();
int w = metrics.stringWidth(label);
x = x + width/2 - w/2;
y = y + height/2 + Math.max(size/2,6);
int h = metrics.getAscent() + metrics.getDescent();
int xoffset=0, yoffset=0;
if (pointRoi) {
xoffset = 6 + pointSize;
yoffset = h - 6 + pointSize;
}
if (bgColor!=null) {
g.setColor(bgColor);
g.fillRoundRect(x-1+xoffset, y-h+2+yoffset, w+1, h-3, 5, 5);
}
if (labelRects!=null && index<labelRects.length) {
if (pointRoi) {
int x2 = screenX(r.x);
int y2 = screenY(r.y);
int crossSize2 = crossSize/2;
labelRects[index] = new Rectangle(x2-crossSize2, y2-crossSize2, crossSize, crossSize);
} else
labelRects[index] = new Rectangle(x-3, y-h+1, w+4, h);
}
g.setColor(labelColor);
g.drawString(label, x+xoffset, y-2+yoffset);
g.setColor(defaultColor);
}
void drawZoomIndicator(Graphics g) {
if (hideZoomIndicator)
return;
int x1 = 10;
int y1 = 10;
double aspectRatio = (double)imageHeight/imageWidth;
int w1 = 64;
if (aspectRatio>1.0)
w1 = (int)(w1/aspectRatio);
int h1 = (int)(w1*aspectRatio);
if (w1<4) w1 = 4;
if (h1<4) h1 = 4;
int w2 = (int)(w1*((double)srcRect.width/imageWidth));
int h2 = (int)(h1*((double)srcRect.height/imageHeight));
if (w2<1) w2 = 1;
if (h2<1) h2 = 1;
int x2 = (int)(w1*((double)srcRect.x/imageWidth));
int y2 = (int)(h1*((double)srcRect.y/imageHeight));
if (zoomIndicatorColor==null)
zoomIndicatorColor = new Color(128, 128, 255);
g.setColor(zoomIndicatorColor);
((Graphics2D)g).setStroke(Roi.onePixelWide);
g.drawRect(x1, y1, w1, h1);
if (w2*h2<=200 || w2<10 || h2<10)
g.fillRect(x1+x2, y1+y2, w2, h2);
else
g.drawRect(x1+x2, y1+y2, w2, h2);
}
void paintDoubleBuffered(Graphics g) {
final int srcRectWidthMag = (int)(srcRect.width*magnification+0.5);
final int srcRectHeightMag = (int)(srcRect.height*magnification+0.5);
if (offScreenImage==null || offScreenWidth!=srcRectWidthMag || offScreenHeight!=srcRectHeightMag) {
offScreenImage = createImage(srcRectWidthMag, srcRectHeightMag);
offScreenWidth = srcRectWidthMag;
offScreenHeight = srcRectHeightMag;
}
Roi roi = imp.getRoi();
try {
if (imageUpdated) {
imageUpdated = false;
imp.updateImage();
}
Graphics offScreenGraphics = offScreenImage.getGraphics();
setInterpolation(offScreenGraphics, Prefs.interpolateScaledImages);
Image img = imp.getImage();
if (img!=null)
offScreenGraphics.drawImage(img, 0, 0, srcRectWidthMag, srcRectHeightMag,
srcRect.x, srcRect.y, srcRect.x+srcRect.width, srcRect.y+srcRect.height, null);
if (overlay!=null)
drawOverlay(overlay, offScreenGraphics);
if (showAllOverlay!=null)
drawOverlay(showAllOverlay, offScreenGraphics);
if (roi!=null)
drawRoi(roi, offScreenGraphics);
if (srcRect.width<imageWidth || srcRect.height<imageHeight)
drawZoomIndicator(offScreenGraphics);
if (IJ.debugMode) showFrameRate(offScreenGraphics);
g.drawImage(offScreenImage, 0, 0, null);
}
catch(OutOfMemoryError e) {IJ.outOfMemory("Paint");}
}
public void resetDoubleBuffer() {
offScreenImage = null;
}
long firstFrame;
int frames, fps;
void showFrameRate(Graphics g) {
frames++;
if (System.currentTimeMillis()>firstFrame+1000) {
firstFrame=System.currentTimeMillis();
fps = frames;
frames=0;
}
g.setColor(Color.white);
g.fillRect(10, 12, 50, 15);
g.setColor(Color.black);
g.drawString((int)(fps+0.5) + " fps", 10, 25);
}
public Dimension getPreferredSize() {
return new Dimension(dstWidth, dstHeight);
}
public Point getCursorLoc() {
return new Point(xMouse, yMouse);
}
public boolean cursorOverImage() {
return !mouseExited;
}
public int getModifiers() {
return flags;
}
public ImagePlus getImage() {
return imp;
}
public void setCursor(int sx, int sy, int ox, int oy) {
xMouse = ox;
yMouse = oy;
mouseExited = false;
Roi roi = imp.getRoi();
ImageWindow win = imp.getWindow();
overOverlayLabel = false;
if (win==null)
return;
if (IJ.spaceBarDown()) {
setCursor(handCursor);
return;
}
int id = Toolbar.getToolId();
switch (id) {
case Toolbar.MAGNIFIER:
setCursor(moveCursor);
break;
case Toolbar.HAND:
setCursor(handCursor);
break;
default: PlugInTool tool = Toolbar.getPlugInTool();
boolean arrowTool = roi!=null && (roi instanceof Arrow) && tool!=null && "Arrow Tool".equals(tool.getToolName());
if ((id>=Toolbar.CUSTOM1) && !arrowTool) {
if (Prefs.usePointerCursor)
setCursor(defaultCursor);
else
setCursor(crosshairCursor);
} else if (roi!=null && roi.getState()!=roi.CONSTRUCTING && roi.isHandle(sx, sy)>=0) {
setCursor(handCursor);
} else if ((overlay!=null||showAllOverlay!=null) && overOverlayLabel(sx,sy,ox,oy)) {
overOverlayLabel = true;
setCursor(handCursor);
} else if (Prefs.usePointerCursor || (roi!=null && roi.getState()!=roi.CONSTRUCTING && roi.contains(ox, oy)))
setCursor(defaultCursor);
else
setCursor(crosshairCursor);
}
}
private boolean overOverlayLabel(int sx, int sy, int ox, int oy) {
Overlay o = showAllOverlay;
if (o==null)
o = overlay;
if (o==null || !o.getDrawLabels() || labelRects==null)
return false;
for (int i=o.size()-1; i>=0; i--) {
if (labelRects!=null&&labelRects[i]!=null&&labelRects[i].contains(sx,sy)) {
Roi roi = imp.getRoi();
if (roi==null || !roi.contains(ox,oy))
return true;
else
return false;
}
}
return false;
}
public int offScreenX(int sx) {
return srcRect.x + (int)(sx/magnification);
}
public int offScreenY(int sy) {
return srcRect.y + (int)(sy/magnification);
}
public double offScreenXD(int sx) {
return srcRect.x + sx/magnification;
}
public double offScreenYD(int sy) {
return srcRect.y + sy/magnification;
}
public int screenX(int ox) {
return (int)((ox-srcRect.x)*magnification);
}
public int screenY(int oy) {
return (int)((oy-srcRect.y)*magnification);
}
public int screenXD(double ox) {
return (int)((ox-srcRect.x)*magnification);
}
public int screenYD(double oy) {
return (int)((oy-srcRect.y)*magnification);
}
public double getMagnification() {
return magnification;
}
public void setMagnification(double magnification) {
setMagnification2(magnification);
}
void setMagnification2(double magnification) {
if (magnification>32.0)
magnification = 32.0;
if (magnification<zoomLevels[0])
magnification = zoomLevels[0];
this.magnification = magnification;
imp.setTitle(imp.getTitle());
}
void resizeCanvas(int width, int height) {
ImageWindow win = imp.getWindow();
if (!maxBoundsReset&& (width>dstWidth||height>dstHeight)&&win!=null&&win.maxBounds!=null&&width!=win.maxBounds.width-10) {
if (resetMaxBoundsCount!=0)
resetMaxBounds(); resetMaxBoundsCount++;
}
if (scaleToFit || IJ.altKeyDown())
{fitToWindow(); return;}
if (width>imageWidth*magnification)
width = (int)(imageWidth*magnification);
if (height>imageHeight*magnification)
height = (int)(imageHeight*magnification);
Dimension size = getSize();
if (srcRect.width<imageWidth || srcRect.height<imageHeight || (painted&&(width!=size.width||height!=size.height))) {
setSize(width, height);
srcRect.width = (int)(dstWidth/magnification);
srcRect.height = (int)(dstHeight/magnification);
if ((srcRect.x+srcRect.width)>imageWidth)
srcRect.x = imageWidth-srcRect.width;
if ((srcRect.y+srcRect.height)>imageHeight)
srcRect.y = imageHeight-srcRect.height;
repaint();
}
}
public void fitToWindow() {
ImageWindow win = imp.getWindow();
if (win==null) return;
Rectangle bounds = win.getBounds();
Insets insets = win.getInsets();
int sliderHeight = win.getSliderHeight();
double xmag = (double)(bounds.width-(insets.left+insets.right+ImageWindow.HGAP*2))/srcRect.width;
double ymag = (double)(bounds.height-(ImageWindow.VGAP*2+insets.top+insets.bottom+sliderHeight))/srcRect.height;
setMagnification(Math.min(xmag, ymag));
int width=(int)(imageWidth*magnification);
int height=(int)(imageHeight*magnification);
if (width==dstWidth&&height==dstHeight) return;
srcRect=new Rectangle(0,0,imageWidth, imageHeight);
setSize(width, height);
getParent().doLayout();
}
void setMaxBounds() {
if (maxBoundsReset) {
maxBoundsReset = false;
ImageWindow win = imp.getWindow();
if (win!=null && !IJ.isLinux() && win.maxBounds!=null) {
win.setMaximizedBounds(win.maxBounds);
win.setMaxBoundsTime = System.currentTimeMillis();
}
}
}
void resetMaxBounds() {
ImageWindow win = imp.getWindow();
if (win!=null && (System.currentTimeMillis()-win.setMaxBoundsTime)>500L) {
win.setMaximizedBounds(win.maxWindowBounds);
maxBoundsReset = true;
}
}
private static final double[] zoomLevels = {
1/72.0, 1/48.0, 1/32.0, 1/24.0, 1/16.0, 1/12.0,
1/8.0, 1/6.0, 1/4.0, 1/3.0, 1/2.0, 0.75, 1.0, 1.5,
2.0, 3.0, 4.0, 6.0, 8.0, 12.0, 16.0, 24.0, 32.0 };
public static double getLowerZoomLevel(double currentMag) {
double newMag = zoomLevels[0];
for (int i=0; i<zoomLevels.length; i++) {
if (zoomLevels[i] < currentMag)
newMag = zoomLevels[i];
else
break;
}
return newMag;
}
public static double getHigherZoomLevel(double currentMag) {
double newMag = 32.0;
for (int i=zoomLevels.length-1; i>=0; i--) {
if (zoomLevels[i]>currentMag)
newMag = zoomLevels[i];
else
break;
}
return newMag;
}
public void zoomIn(int sx, int sy) {
if (magnification>=32) return;
boolean mouseMoved = sqr(sx-lastZoomSX) + sqr(sy-lastZoomSY) > MAX_MOUSEMOVE_ZOOM*MAX_MOUSEMOVE_ZOOM;
lastZoomSX = sx;
lastZoomSY = sy;
if (mouseMoved || zoomTargetOX<0) {
boolean cursorInside = sx >= 0 && sy >= 0 && sx < dstWidth && sy < dstHeight;
zoomTargetOX = offScreenX(cursorInside ? sx : dstWidth/2); zoomTargetOY = offScreenY(cursorInside ? sy : dstHeight/2);
}
double newMag = getHigherZoomLevel(magnification);
int newWidth = (int)(imageWidth*newMag);
int newHeight = (int)(imageHeight*newMag);
Dimension newSize = canEnlarge(newWidth, newHeight);
if (newSize!=null) {
setSize(newSize.width, newSize.height);
if (newSize.width!=newWidth || newSize.height!=newHeight)
adjustSourceRect(newMag, zoomTargetOX, zoomTargetOY);
else
setMagnification(newMag);
imp.getWindow().pack();
} else adjustSourceRect(newMag, zoomTargetOX, zoomTargetOY);
repaint();
if (srcRect.width<imageWidth || srcRect.height<imageHeight)
resetMaxBounds();
}
void adjustSourceRect(double newMag, int x, int y) {
int w = (int)Math.round(dstWidth/newMag);
if (w*newMag<dstWidth) w++;
int h = (int)Math.round(dstHeight/newMag);
if (h*newMag<dstHeight) h++;
Rectangle r = new Rectangle(x-w/2, y-h/2, w, h);
if (r.x<0) r.x = 0;
if (r.y<0) r.y = 0;
if (r.x+w>imageWidth) r.x = imageWidth-w;
if (r.y+h>imageHeight) r.y = imageHeight-h;
srcRect = r;
setMagnification(newMag);
}
protected Dimension canEnlarge(int newWidth, int newHeight) {
if (IJ.altKeyDown())
return null;
ImageWindow win = imp.getWindow();
if (win==null) return null;
Rectangle r1 = win.getBounds();
Insets insets = win.getInsets();
Point loc = getLocation();
if (loc.x>insets.left+5 || loc.y>insets.top+5) {
r1.width = newWidth+insets.left+insets.right+ImageWindow.HGAP*2;
r1.height = newHeight+insets.top+insets.bottom+ImageWindow.VGAP*2+win.getSliderHeight();
} else {
r1.width = r1.width - dstWidth + newWidth;
r1.height = r1.height - dstHeight + newHeight;
}
Rectangle max = win.getMaxWindow(r1.x, r1.y);
boolean fitsHorizontally = r1.x+r1.width<max.x+max.width;
boolean fitsVertically = r1.y+r1.height<max.y+max.height;
if (fitsHorizontally && fitsVertically)
return new Dimension(newWidth, newHeight);
else if (fitsVertically && newHeight<dstWidth)
return new Dimension(dstWidth, newHeight);
else if (fitsHorizontally && newWidth<dstHeight)
return new Dimension(newWidth, dstHeight);
else
return null;
}
public void zoomOut(int sx, int sy) {
if (magnification<=zoomLevels[0])
return;
boolean mouseMoved = sqr(sx-lastZoomSX) + sqr(sy-lastZoomSY) > MAX_MOUSEMOVE_ZOOM*MAX_MOUSEMOVE_ZOOM;
lastZoomSX = sx;
lastZoomSY = sy;
if (mouseMoved || zoomTargetOX<0) {
boolean cursorInside = sx >= 0 && sy >= 0 && sx < dstWidth && sy < dstHeight;
zoomTargetOX = offScreenX(cursorInside ? sx : dstWidth/2); zoomTargetOY = offScreenY(cursorInside ? sy : dstHeight/2);
}
double oldMag = magnification;
double newMag = getLowerZoomLevel(magnification);
double srcRatio = (double)srcRect.width/srcRect.height;
double imageRatio = (double)imageWidth/imageHeight;
double initialMag = imp.getWindow().getInitialMagnification();
if (Math.abs(srcRatio-imageRatio)>0.05) {
double scale = oldMag/newMag;
int newSrcWidth = (int)Math.round(srcRect.width*scale);
int newSrcHeight = (int)Math.round(srcRect.height*scale);
if (newSrcWidth>imageWidth) newSrcWidth=imageWidth;
if (newSrcHeight>imageHeight) newSrcHeight=imageHeight;
int newSrcX = srcRect.x - (newSrcWidth - srcRect.width)/2;
int newSrcY = srcRect.y - (newSrcHeight - srcRect.height)/2;
if (newSrcX + newSrcWidth > imageWidth) newSrcX = imageWidth - newSrcWidth;
if (newSrcY + newSrcHeight > imageHeight) newSrcY = imageHeight - newSrcHeight;
if (newSrcX<0) newSrcX = 0;
if (newSrcY<0) newSrcY = 0;
srcRect = new Rectangle(newSrcX, newSrcY, newSrcWidth, newSrcHeight);
int newDstWidth = (int)(srcRect.width*newMag);
int newDstHeight = (int)(srcRect.height*newMag);
setMagnification(newMag);
setMaxBounds();
if (newDstWidth<dstWidth || newDstHeight<dstHeight) {
setSize(newDstWidth, newDstHeight);
imp.getWindow().pack();
} else
repaint();
return;
}
if (imageWidth*newMag>dstWidth) {
int w = (int)Math.round(dstWidth/newMag);
if (w*newMag<dstWidth) w++;
int h = (int)Math.round(dstHeight/newMag);
if (h*newMag<dstHeight) h++;
Rectangle r = new Rectangle(zoomTargetOX-w/2, zoomTargetOY-h/2, w, h);
if (r.x<0) r.x = 0;
if (r.y<0) r.y = 0;
if (r.x+w>imageWidth) r.x = imageWidth-w;
if (r.y+h>imageHeight) r.y = imageHeight-h;
srcRect = r;
setMagnification(newMag);
} else {
srcRect = new Rectangle(0, 0, imageWidth, imageHeight);
setSize((int)(imageWidth*newMag), (int)(imageHeight*newMag));
setMagnification(newMag);
imp.getWindow().pack();
}
setMaxBounds();
repaint();
}
int sqr(int x) {
return x*x;
}
public void unzoom() {
double imag = imp.getWindow().getInitialMagnification();
if (magnification==imag)
return;
srcRect = new Rectangle(0, 0, imageWidth, imageHeight);
ImageWindow win = imp.getWindow();
setSize((int)(imageWidth*imag), (int)(imageHeight*imag));
setMagnification(imag);
setMaxBounds();
win.pack();
setMaxBounds();
repaint();
}
public void zoom100Percent() {
if (magnification==1.0)
return;
double imag = imp.getWindow().getInitialMagnification();
if (magnification!=imag)
unzoom();
if (magnification==1.0)
return;
if (magnification<1.0) {
while (magnification<1.0)
zoomIn(imageWidth/2, imageHeight/2);
} else if (magnification>1.0) {
while (magnification>1.0)
zoomOut(imageWidth/2, imageHeight/2);
} else
return;
int x=xMouse, y=yMouse;
if (mouseExited) {
x = imageWidth/2;
y = imageHeight/2;
}
int sx = screenX(x);
int sy = screenY(y);
adjustSourceRect(1.0, sx, sy);
repaint();
}
protected void scroll(int sx, int sy) {
int ox = xSrcStart + (int)(sx/magnification); int oy = ySrcStart + (int)(sy/magnification);
int newx = xSrcStart + (xMouseStart-ox);
int newy = ySrcStart + (yMouseStart-oy);
if (newx<0) newx = 0;
if (newy<0) newy = 0;
if ((newx+srcRect.width)>imageWidth) newx = imageWidth-srcRect.width;
if ((newy+srcRect.height)>imageHeight) newy = imageHeight-srcRect.height;
srcRect.x = newx;
srcRect.y = newy;
imp.draw();
Thread.yield();
}
Color getColor(int index){
IndexColorModel cm = (IndexColorModel)imp.getProcessor().getColorModel();
return new Color(cm.getRGB(index));
}
public void setDrawingColor(int ox, int oy, boolean setBackground) {
int type = imp.getType();
int[] v = imp.getPixel(ox, oy);
switch (type) {
case ImagePlus.GRAY8: {
if (setBackground)
setBackgroundColor(getColor(v[0]));
else
setForegroundColor(getColor(v[0]));
break;
}
case ImagePlus.GRAY16: case ImagePlus.GRAY32: {
double min = imp.getProcessor().getMin();
double max = imp.getProcessor().getMax();
double value = (type==ImagePlus.GRAY32)?Float.intBitsToFloat(v[0]):v[0];
int index = (int)(255.0*((value-min)/(max-min)));
if (index<0) index = 0;
if (index>255) index = 255;
if (setBackground)
setBackgroundColor(getColor(index));
else
setForegroundColor(getColor(index));
break;
}
case ImagePlus.COLOR_RGB: case ImagePlus.COLOR_256: {
Color c = new Color(v[0], v[1], v[2]);
if (setBackground)
setBackgroundColor(c);
else
setForegroundColor(c);
break;
}
}
Color c;
if (setBackground)
c = Toolbar.getBackgroundColor();
else {
c = Toolbar.getForegroundColor();
imp.setColor(c);
}
IJ.showStatus("("+c.getRed()+", "+c.getGreen()+", "+c.getBlue()+")");
}
private void setForegroundColor(Color c) {
Toolbar.setForegroundColor(c);
if (Recorder.record)
Recorder.record("setForegroundColor", c.getRed(), c.getGreen(), c.getBlue());
}
private void setBackgroundColor(Color c) {
Toolbar.setBackgroundColor(c);
if (Recorder.record)
Recorder.record("setBackgroundColor", c.getRed(), c.getGreen(), c.getBlue());
}
public void mousePressed(MouseEvent e) {
showCursorStatus = true;
int toolID = Toolbar.getToolId();
ImageWindow win = imp.getWindow();
if (win!=null && win.running2 && toolID!=Toolbar.MAGNIFIER) {
if (win instanceof StackWindow)
((StackWindow)win).setAnimate(false);
else
win.running2 = false;
return;
}
int x = e.getX();
int y = e.getY();
flags = e.getModifiers();
if (toolID!=Toolbar.MAGNIFIER && (e.isPopupTrigger()||(!IJ.isMacintosh()&&(flags&Event.META_MASK)!=0))) {
handlePopupMenu(e);
return;
}
int ox = offScreenX(x);
int oy = offScreenY(y);
xMouse = ox; yMouse = oy;
if (IJ.spaceBarDown()) {
setupScroll(ox, oy);
return;
}
if (overOverlayLabel && (overlay!=null||showAllOverlay!=null)) {
if (activateOverlayRoi(ox, oy))
return;
}
mousePressedX = ox;
mousePressedY = oy;
mousePressedTime = System.currentTimeMillis();
PlugInTool tool = Toolbar.getPlugInTool();
if (tool!=null) {
tool.mousePressed(imp, e);
if (e.isConsumed()) return;
}
if (customRoi && overlay!=null)
return;
if (toolID>=Toolbar.CUSTOM1) {
if (tool!=null && "Arrow Tool".equals(tool.getToolName()))
handleRoiMouseDown(e);
else
Toolbar.getInstance().runMacroTool(toolID);
return;
}
switch (toolID) {
case Toolbar.MAGNIFIER:
if (IJ.shiftKeyDown())
zoomToSelection(ox, oy);
else if ((flags & (Event.ALT_MASK|Event.META_MASK|Event.CTRL_MASK))!=0) {
zoomOut(x, y);
if (getMagnification()<1.0)
imp.repaintWindow();
} else {
zoomIn(x, y);
if (getMagnification()<=1.0)
imp.repaintWindow();
}
break;
case Toolbar.HAND:
setupScroll(ox, oy);
break;
case Toolbar.DROPPER:
setDrawingColor(ox, oy, IJ.altKeyDown());
break;
case Toolbar.WAND:
Roi roi = imp.getRoi();
double tolerance = WandToolOptions.getTolerance();
if (roi!=null && (tolerance==0.0||imp.isThreshold()) && roi.contains(ox, oy)) {
Rectangle r = roi.getBounds();
if (r.width==imageWidth && r.height==imageHeight)
imp.deleteRoi();
else if (!e.isAltDown()) {
handleRoiMouseDown(e);
return;
}
}
if (roi!=null) {
int handle = roi.isHandle(x, y);
if (handle>=0) {
roi.mouseDownInHandle(handle, x, y);
return;
}
}
setRoiModState(e, roi, -1);
String mode = WandToolOptions.getMode();
int npoints = IJ.doWand(ox, oy, tolerance, mode);
if (Recorder.record && npoints>0) {
if (Recorder.scriptMode())
Recorder.recordCall("IJ.doWand(imp, "+ox+", "+oy+", "+tolerance+", \""+mode+"\");");
else {
if (tolerance==0.0 && mode.equals("Legacy"))
Recorder.record("doWand", ox, oy);
else
Recorder.recordString("doWand("+ox+", "+oy+", "+tolerance+", \""+mode+"\");\n");
}
}
break;
case Toolbar.OVAL:
if (Toolbar.getBrushSize()>0)
new RoiBrush();
else
handleRoiMouseDown(e);
break;
default: handleRoiMouseDown(e);
}
}
private boolean drawingTool() {
return Toolbar.getToolName().equals("Paintbrush Tool") || Toolbar.getToolName().equals("Pencil Tool");
}
void zoomToSelection(int x, int y) {
IJ.setKeyUp(IJ.ALL_KEYS);
String macro =
"args = split(getArgument);\n"+
"x1=parseInt(args[0]); y1=parseInt(args[1]); flags=20;\n"+
"while (flags&20!=0) {\n"+
"getCursorLoc(x2, y2, z, flags);\n"+
"if (x2>=x1) x=x1; else x=x2;\n"+
"if (y2>=y1) y=y1; else y=y2;\n"+
"makeRectangle(x, y, abs(x2-x1), abs(y2-y1));\n"+
"wait(10);\n"+
"}\n"+
"run('To Selection');\n";
new MacroRunner(macro, x+" "+y);
}
protected void setupScroll(int ox, int oy) {
xMouseStart = ox;
yMouseStart = oy;
xSrcStart = srcRect.x;
ySrcStart = srcRect.y;
}
protected void handlePopupMenu(MouseEvent e) {
if (disablePopupMenu) return;
if (IJ.debugMode) IJ.log("show popup: " + (e.isPopupTrigger()?"true":"false"));
int x = e.getX();
int y = e.getY();
Roi roi = imp.getRoi();
if (roi!=null && (roi.getType()==Roi.POLYGON || roi.getType()==Roi.POLYLINE || roi.getType()==Roi.ANGLE)
&& roi.getState()==roi.CONSTRUCTING) {
roi.handleMouseUp(x, y); roi.handleMouseUp(x, y); return;
}
PopupMenu popup = Menus.getPopupMenu();
if (popup!=null) {
add(popup);
if (IJ.isMacOSX()) IJ.wait(10);
popup.show(this, x, y);
}
}
public void mouseExited(MouseEvent e) {
PlugInTool tool = Toolbar.getPlugInTool();
if (tool!=null) {
tool.mouseExited(imp, e);
if (e.isConsumed()) return;
}
ImageWindow win = imp.getWindow();
if (win!=null)
setCursor(defaultCursor);
IJ.showStatus("");
mouseExited = true;
}
public void mouseDragged(MouseEvent e) {
int x = e.getX();
int y = e.getY();
xMouse = offScreenX(x);
yMouse = offScreenY(y);
flags = e.getModifiers();
mousePressedX = mousePressedY = -1;
if (flags==0) flags = InputEvent.BUTTON1_MASK;
if (Toolbar.getToolId()==Toolbar.HAND || IJ.spaceBarDown())
scroll(x, y);
else {
PlugInTool tool = Toolbar.getPlugInTool();
if (tool!=null) {
tool.mouseDragged(imp, e);
if (e.isConsumed()) return;
}
IJ.setInputEvent(e);
Roi roi = imp.getRoi();
if (roi != null)
roi.handleMouseDrag(x, y, flags);
}
}
protected void handleRoiMouseDown(MouseEvent e) {
int sx = e.getX();
int sy = e.getY();
int ox = offScreenX(sx);
int oy = offScreenY(sy);
Roi roi = imp.getRoi();
int handle = roi!=null?roi.isHandle(sx, sy):-1;
boolean multiPointMode = roi!=null && (roi instanceof PointRoi) && handle==-1
&& Toolbar.getToolId()==Toolbar.POINT && Toolbar.getMultiPointMode();
if (multiPointMode) {
double oxd = offScreenXD(sx);
double oyd = offScreenYD(sy);
if (e.isShiftDown()) {
FloatPolygon points = roi.getFloatPolygon();
if (points.npoints>0) {
double x0 = points.xpoints[0];
double y0 = points.ypoints[0];
double slope = Math.abs((oxd-x0)/(oyd-y0));
if (slope>=1.0)
oyd = points.ypoints[0];
else
oxd = points.xpoints[0];
}
}
((PointRoi)roi).addPoint(imp, oxd, oyd);
imp.setRoi(roi);
return;
}
setRoiModState(e, roi, handle);
if (roi!=null) {
if (handle>=0) {
roi.mouseDownInHandle(handle, sx, sy);
return;
}
Rectangle r = roi.getBounds();
int type = roi.getType();
if (type==Roi.RECTANGLE && r.width==imp.getWidth() && r.height==imp.getHeight()
&& roi.getPasteMode()==Roi.NOT_PASTING && !(roi instanceof ImageRoi)) {
imp.deleteRoi();
return;
}
if (roi.contains(ox, oy)) {
if (roi.modState==Roi.NO_MODS)
roi.handleMouseDown(sx, sy);
else {
imp.deleteRoi();
imp.createNewRoi(sx,sy);
}
return;
}
if ((type==Roi.POLYGON || type==Roi.POLYLINE || type==Roi.ANGLE)
&& roi.getState()==roi.CONSTRUCTING)
return;
int tool = Toolbar.getToolId();
if ((tool==Toolbar.POLYGON||tool==Toolbar.POLYLINE||tool==Toolbar.ANGLE)&& !(IJ.shiftKeyDown()||IJ.altKeyDown())) {
imp.deleteRoi();
return;
}
}
imp.createNewRoi(sx,sy);
}
void setRoiModState(MouseEvent e, Roi roi, int handle) {
if (roi==null || (handle>=0 && roi.modState==Roi.NO_MODS))
return;
if (roi.state==Roi.CONSTRUCTING)
return;
int tool = Toolbar.getToolId();
if (tool>Toolbar.FREEROI && tool!=Toolbar.WAND && tool!=Toolbar.POINT)
{roi.modState = Roi.NO_MODS; return;}
if (e.isShiftDown())
roi.modState = Roi.ADD_TO_ROI;
else if (e.isAltDown())
roi.modState = Roi.SUBTRACT_FROM_ROI;
else
roi.modState = Roi.NO_MODS;
}
public void disablePopupMenu(boolean status) {
disablePopupMenu = status;
}
public void setShowAllList(Overlay showAllList) {
this.showAllOverlay = showAllList;
labelRects = null;
}
public Overlay getShowAllList() {
return showAllOverlay;
}
public void setShowAllROIs(boolean showAllROIs) {
RoiManager rm = RoiManager.getInstance();
if (rm!=null)
rm.runCommand(showAllROIs?"show all":"show none");
}
public boolean getShowAllROIs() {
return getShowAllList()!=null;
}
public static Color getShowAllColor() {
if (showAllColor!=null && showAllColor.getRGB()==0xff80ffff)
showAllColor = Color.cyan;
return showAllColor;
}
public static void setShowAllColor(Color c) {
if (c==null) return;
showAllColor = c;
labelColor = null;
}
public static void setCursor(Cursor cursor, int type) {
crosshairCursor = cursor;
}
public void setOverlay(Overlay overlay) {
this.overlay = overlay;
labelRects = null;
repaint();
}
public Overlay getOverlay() {
return overlay;
}
public void setDisplayList(Vector list) {
if (list!=null) {
Overlay list2 = new Overlay();
list2.setVector(list);
setOverlay(list2);
} else
setOverlay(null);
if (overlay!=null)
overlay.drawLabels(overlay.size()>0&&overlay.get(0).getStrokeColor()==null);
else
customRoi = false;
repaint();
}
public void setDisplayList(Shape shape, Color color, BasicStroke stroke) {
if (shape==null)
{setOverlay(null); return;}
Roi roi = new ShapeRoi(shape);
roi.setStrokeColor(color);
roi.setStroke(stroke);
Overlay list = new Overlay();
list.add(roi);
setOverlay(list);
}
public void setDisplayList(Roi roi, Color color) {
roi.setStrokeColor(color);
Overlay list = new Overlay();
list.add(roi);
setOverlay(list);
}
public Vector getDisplayList() {
if (overlay==null) return null;
Vector displayList = new Vector();
for (int i=0; i<overlay.size(); i++)
displayList.add(overlay.get(i));
return displayList;
}
public void setCustomRoi(boolean customRoi) {
this.customRoi = customRoi;
}
public boolean getCustomRoi() {
return customRoi;
}
public void setShowCursorStatus(boolean status) {
showCursorStatus = status;
if (status==true)
sx2 = sy2 = -1000;
else {
sx2 = screenX(xMouse);
sy2 = screenY(yMouse);
}
}
public void mouseReleased(MouseEvent e) {
int ox = offScreenX(e.getX());
int oy = offScreenY(e.getY());
if ((overlay!=null||showAllOverlay!=null) && ox==mousePressedX && oy==mousePressedY) {
boolean cmdDown = IJ.isMacOSX() && e.isMetaDown();
Roi roi = imp.getRoi();
if (roi!=null && roi.getBounds().width==0)
roi=null;
if ((e.isAltDown()||e.isControlDown()||cmdDown) && roi==null) {
if (activateOverlayRoi(ox, oy))
return;
} else if ((System.currentTimeMillis()-mousePressedTime)>250L && !drawingTool()) {
if (activateOverlayRoi(ox,oy))
return;
}
}
PlugInTool tool = Toolbar.getPlugInTool();
if (tool!=null) {
tool.mouseReleased(imp, e);
if (e.isConsumed()) return;
}
flags = e.getModifiers();
flags &= ~InputEvent.BUTTON1_MASK; flags &= ~InputEvent.BUTTON2_MASK; flags &= ~InputEvent.BUTTON3_MASK; Roi roi = imp.getRoi();
if (roi != null) {
Rectangle r = roi.getBounds();
int type = roi.getType();
if ((r.width==0 || r.height==0)
&& !(type==Roi.POLYGON||type==Roi.POLYLINE||type==Roi.ANGLE||type==Roi.LINE)
&& !(roi instanceof TextRoi)
&& roi.getState()==roi.CONSTRUCTING
&& type!=roi.POINT)
imp.deleteRoi();
else
roi.handleMouseUp(e.getX(), e.getY());
}
}
private boolean activateOverlayRoi(int ox, int oy) {
int currentImage = -1;
int stackSize = imp.getStackSize();
if (stackSize>1)
currentImage = imp.getCurrentSlice();
int channel=0, slice=0, frame=0;
boolean hyperstack = imp.isHyperStack();
if (hyperstack) {
channel = imp.getChannel();
slice = imp.getSlice();
frame = imp.getFrame();
}
Overlay o = showAllOverlay;
if (o==null)
o = overlay;
if (o==null)
return false;
boolean roiManagerShowAllMode = o==showAllOverlay && !Prefs.showAllSliceOnly;
boolean labels = o.getDrawLabels();
int sx = screenX(ox);
int sy = screenY(oy);
for (int i=o.size()-1; i>=0; i--) {
Roi roi = o.get(i);
if (roi.contains(ox, oy) || (labels&&labelRects!=null&&labelRects[i]!=null&&labelRects[i].contains(sx,sy))) {
if (hyperstack && roi.getPosition()==0) {
int c = roi.getCPosition();
int z = roi.getZPosition();
int t = roi.getTPosition();
if (!((c==0||c==channel)&&(z==0||z==slice)&&(t==0||t==frame) || roiManagerShowAllMode))
continue;
} else {
int position = stackSize>1?roi.getPosition():0;
if (!(position==0||position==currentImage||roiManagerShowAllMode))
continue;
}
if (!IJ.altKeyDown() && roi.getType()==Roi.COMPOSITE
&& roi.getBounds().width==imp.getWidth() && roi.getBounds().height==imp.getHeight())
return false;
if (Toolbar.getToolId()==Toolbar.OVAL && Toolbar.getBrushSize()>0)
Toolbar.getInstance().setTool(Toolbar.RECTANGLE);
roi.setImage(null);
imp.setRoi(roi);
roi.handleMouseDown(sx, sy);
roiManagerSelect(roi, false);
return true;
}
}
return false;
}
public boolean roiManagerSelect(Roi roi, boolean delete) {
RoiManager rm=RoiManager.getInstance();
if (rm==null)
return false;
int index = rm.getRoiIndex(roi);
if (index<0)
return false;
if (delete) {
rm.select(imp, index);
rm.runCommand("delete");
} else
rm.selectAndMakeVisible(imp, index);
return true;
}
public void mouseMoved(MouseEvent e) {
int sx = e.getX();
int sy = e.getY();
int ox = offScreenX(sx);
int oy = offScreenY(sy);
flags = e.getModifiers();
setCursor(sx, sy, ox, oy);
mousePressedX = mousePressedY = -1;
IJ.setInputEvent(e);
PlugInTool tool = Toolbar.getPlugInTool();
if (tool!=null) {
tool.mouseMoved(imp, e);
if (e.isConsumed()) return;
}
Roi roi = imp.getRoi();
int type = roi!=null?roi.getType():-1;
if (type>0 && (type==Roi.POLYGON||type==Roi.POLYLINE||type==Roi.ANGLE||type==Roi.LINE)
&& roi.getState()==roi.CONSTRUCTING)
roi.mouseMoved(e);
else {
if (ox<imageWidth && oy<imageHeight) {
ImageWindow win = imp.getWindow();
if ((sx-sx2)*(sx-sx2)+(sy-sy2)*(sy-sy2)>144)
showCursorStatus = true;
if (win!=null&&showCursorStatus) win.mouseMoved(ox, oy);
} else
IJ.showStatus("");
}
}
public void mouseEntered(MouseEvent e) {
PlugInTool tool = Toolbar.getPlugInTool();
if (tool!=null)
tool.mouseEntered(imp, e);
}
public void mouseClicked(MouseEvent e) {
PlugInTool tool = Toolbar.getPlugInTool();
if (tool!=null)
tool.mouseClicked(imp, e);
}
public void setScaleToFit(boolean scaleToFit) {
this.scaleToFit = scaleToFit;
}
public boolean getScaleToFit() {
return scaleToFit;
}
public boolean hideZoomIndicator(boolean hide) {
boolean hidden = this.hideZoomIndicator;
if (!(srcRect.width<imageWidth||srcRect.height<imageHeight))
return hidden;
this.hideZoomIndicator = hide;
setPaintPending(true);
repaint();
long t0 = System.currentTimeMillis();
while(getPaintPending() && (System.currentTimeMillis()-t0)<500L)
IJ.wait(10);
return hidden;
}
}