/** Sets the cursor based on the current tool and cursor location. */
 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();
   if (win == null) return;
   if (IJ.spaceBarDown()) {
     setCursor(handCursor);
     return;
   }
   int id = Toolbar.getToolId();
   switch (Toolbar.getToolId()) {
     case Toolbar.MAGNIFIER:
       setCursor(moveCursor);
       break;
     case Toolbar.HAND:
       setCursor(handCursor);
       break;
     default: // selection tool
       if (id == Toolbar.SPARE1 || id >= Toolbar.SPARE2) {
         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 (Prefs.usePointerCursor
           || (roi != null && roi.getState() != roi.CONSTRUCTING && roi.contains(ox, oy)))
         setCursor(defaultCursor);
       else setCursor(crosshairCursor);
   }
 }
 public void mouseMoved(MouseEvent e) {
   // if (ij==null) return;
   int sx = e.getX();
   int sy = e.getY();
   int ox = offScreenX(sx);
   int oy = offScreenY(sy);
   flags = e.getModifiers();
   setCursor(sx, sy, ox, oy);
   IJ.setInputEvent(e);
   Roi roi = imp.getRoi();
   if (roi != null
       && (roi.getType() == Roi.POLYGON
           || roi.getType() == Roi.POLYLINE
           || roi.getType() == Roi.ANGLE)
       && roi.getState() == roi.CONSTRUCTING) {
     PolygonRoi pRoi = (PolygonRoi) roi;
     pRoi.handleMouseMove(ox, oy);
   } else {
     if (ox < imageWidth && oy < imageHeight) {
       ImageWindow win = imp.getWindow();
       // Cursor must move at least 12 pixels before text
       // displayed using IJ.showStatus() is overwritten.
       if ((sx - sx2) * (sx - sx2) + (sy - sy2) * (sy - sy2) > 144) showCursorStatus = true;
       if (win != null && showCursorStatus) win.mouseMoved(ox, oy);
     } else IJ.showStatus("");
   }
 }
 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) {
     imp.setRoi(((PointRoi) roi).addPoint(ox, oy));
     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.killRoi();
       return;
     }
     if (roi.contains(ox, oy)) {
       if (roi.modState == Roi.NO_MODS) roi.handleMouseDown(sx, sy);
       else {
         imp.killRoi();
         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.killRoi();
       return;
     }
   }
   imp.createNewRoi(sx, sy);
 }
 public void mouseReleased(MouseEvent e) {
   flags = e.getModifiers();
   flags &= ~InputEvent.BUTTON1_MASK; // make sure button 1 bit is not set
   flags &= ~InputEvent.BUTTON2_MASK; // make sure button 2 bit is not set
   flags &= ~InputEvent.BUTTON3_MASK; // make sure button 3 bit is not set
   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.killRoi();
     else {
       roi.handleMouseUp(e.getX(), e.getY());
       if (roi.getType() == Roi.LINE && roi.getLength() == 0.0) imp.killRoi();
     }
   }
 }
 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); // simulate double-click to finalize
     roi.handleMouseUp(x, y); // polygon or polyline selection
     return;
   }
   PopupMenu popup = Menus.getPopupMenu();
   if (popup != null) {
     add(popup);
     if (IJ.isMacOSX()) IJ.wait(10);
     popup.show(this, x, y);
   }
 }