Package ij.gui

Source Code of ij.gui.Toolbar

package ij.gui;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.*;
import java.io.File;
import java.util.*;
import ij.*;
import ij.plugin.frame.Recorder;
import ij.plugin.frame.Editor;
import ij.plugin.MacroInstaller;
import ij.plugin.RectToolOptions;
import ij.macro.Program;

/** The ImageJ toolbar. */
public class Toolbar extends Canvas implements MouseListener, MouseMotionListener, ItemListener, ActionListener {

  public static final int RECTANGLE = 0;
  public static final int OVAL = 1;
  public static final int POLYGON = 2;
  public static final int FREEROI = 3;
  public static final int LINE = 4;
  public static final int POLYLINE = 5;
  public static final int FREELINE = 6;
  public static final int POINT = 7, CROSSHAIR = 7;
  public static final int WAND = 8;
  public static final int TEXT = 9;
  public static final int SPARE1 = 10;
  public static final int MAGNIFIER = 11;
  public static final int HAND = 12;
  public static final int DROPPER = 13;
  public static final int ANGLE = 14;
  public static final int SPARE2 = 15;
  public static final int SPARE3 = 16;
  public static final int SPARE4 = 17;
  public static final int SPARE5 = 18;
  public static final int SPARE6 = 19;
  public static final int SPARE7 = 20;
  public static final int SPARE8 = 21;
  public static final int SPARE9 = 22;
 
  public static final int DOUBLE_CLICK_THRESHOLD = 650;

  public static final int OVAL_ROI=0, ELLIPSE_ROI=1, BRUSH_ROI=2;

  private static final int NUM_TOOLS = 23;
  private static final int NUM_BUTTONS = 21;
  private static final int SIZE = 26;
  private static final int OFFSET = 5;
  private static final String BRUSH_SIZE = "toolbar.brush.size";
  public static final String CORNER_DIAMETER = "toolbar.arc.size";
   
  private Dimension ps = new Dimension(SIZE*NUM_BUTTONS, SIZE);
  private boolean[] down;
  private static int current;
  private int previous;
  private int x,y;
  private int xOffset, yOffset;
  private long mouseDownTime;
  private Graphics g;
  private static Toolbar instance;
  private int mpPrevious = RECTANGLE;
  private String[] names = new String[NUM_TOOLS];
  private String[] icons = new String[NUM_TOOLS];
    private PopupMenu[] menus = new PopupMenu[NUM_TOOLS];
  private int pc;
  private String icon;
  private MacroInstaller macroInstaller;
  private int startupTime;
  private PopupMenu rectPopup, ovalPopup, pointPopup, linePopup, switchPopup;
  private CheckboxMenuItem rectItem, roundRectItem;
  private CheckboxMenuItem ovalItem, ellipseItem, brushItem;
  private CheckboxMenuItem pointItem, multiPointItem;
  private CheckboxMenuItem straightLineItem, polyLineItem, freeLineItem, arrowItem;
  private String currentSet = "Startup Macros";

  private static Color foregroundColor = Prefs.getColor(Prefs.FCOLOR,Color.black);
  private static Color backgroundColor = Prefs.getColor(Prefs.BCOLOR,Color.white);
  private static int ovalType = OVAL_ROI;
  private static boolean multiPointMode = Prefs.multiPointMode;
  private static boolean roundRectMode;
  private static boolean arrowMode;
  private static int brushSize = (int)Prefs.get(BRUSH_SIZE, 15);
  private static int arcSize = (int)Prefs.get(CORNER_DIAMETER, 20);
  private int lineType = LINE;
 
  private Color gray = ImageJ.backgroundColor;
  private Color brighter = gray.brighter();
  private Color darker = new Color(175, 175, 175);
  private Color evenDarker = new Color(110, 110, 110);
  private Color triangleColor = new Color(150, 0, 0);
  private Color toolColor = new Color(0, 25, 45);


  public Toolbar() {
    down = new boolean[NUM_TOOLS];
    resetButtons();
    down[0] = true;
    setForeground(Color.black);
    setBackground(gray);
    addMouseListener(this);
    addMouseMotionListener(this);
    instance = this;
    names[NUM_TOOLS-1] = "Switch to alternate macro tool sets";
    icons[NUM_TOOLS-1] = "C900T1c12>T7c12>"; // ">>"
    addPopupMenus();
    if (IJ.isMacOSX() || IJ.isVista()) Prefs.antialiasedTools = true;
  }

  void addPopupMenus() {
    rectPopup = new PopupMenu();
    if (Menus.getFontSize()!=0)
      rectPopup.setFont(Menus.getFont());
    rectItem = new CheckboxMenuItem("Rectangle Tool", !roundRectMode);
    rectItem.addItemListener(this);
    rectPopup.add(rectItem);
    roundRectItem = new CheckboxMenuItem("Rounded Rectangle Tool", roundRectMode);
    roundRectItem.addItemListener(this);
    rectPopup.add(roundRectItem);
    add(rectPopup);

    ovalPopup = new PopupMenu();
    if (Menus.getFontSize()!=0)
      ovalPopup.setFont(Menus.getFont());
    ovalItem = new CheckboxMenuItem("Oval selections", ovalType==OVAL_ROI);
    ovalItem.addItemListener(this);
    ovalPopup.add(ovalItem);
    ellipseItem = new CheckboxMenuItem("Elliptical selections", ovalType==ELLIPSE_ROI);
    ellipseItem.addItemListener(this);
    ovalPopup.add(ellipseItem);
    brushItem = new CheckboxMenuItem("Selection Brush Tool", ovalType==BRUSH_ROI);
    brushItem.addItemListener(this);
    ovalPopup.add(brushItem);
    add(ovalPopup);

    pointPopup = new PopupMenu();
    if (Menus.getFontSize()!=0)
      pointPopup.setFont(Menus.getFont());
    pointItem = new CheckboxMenuItem("Point Tool", !multiPointMode);
    pointItem.addItemListener(this);
    pointPopup.add(pointItem);
    multiPointItem = new CheckboxMenuItem("Multi-point Tool", multiPointMode);
    multiPointItem.addItemListener(this);
    pointPopup.add(multiPointItem);
    add(pointPopup);

    linePopup = new PopupMenu();
    if (Menus.getFontSize()!=0)
      linePopup.setFont(Menus.getFont());
    straightLineItem = new CheckboxMenuItem("Straight Line", lineType==LINE&&!arrowMode);
    straightLineItem.addItemListener(this);
    linePopup.add(straightLineItem);
    polyLineItem = new CheckboxMenuItem("Segmented Line", lineType==POLYLINE);
    polyLineItem.addItemListener(this);
    linePopup.add(polyLineItem);
    freeLineItem = new CheckboxMenuItem("Freehand Line", lineType==FREELINE);
    freeLineItem.addItemListener(this);
    linePopup.add(freeLineItem);
    arrowItem = new CheckboxMenuItem("Arrow tool", lineType==LINE&&!arrowMode);
    arrowItem.addItemListener(this);
    linePopup.add(arrowItem);
    add(linePopup);

    switchPopup = new PopupMenu();
    if (Menus.getFontSize()!=0)
      switchPopup.setFont(Menus.getFont());
    add(switchPopup);
  }
 
  /** Returns the ID of the current tool (Toolbar.RECTANGLE,
    Toolbar.OVAL, etc.). */
  public static int getToolId() {
    return current;
  }

  /** Returns the ID of the tool whose name (the description displayed in the status bar)
    starts with the specified string, or -1 if the tool is not found. */
  public int getToolId(String name) {
    int tool =  -1;
    for (int i=0; i<=SPARE9; i++) {
      if (names[i]!=null && names[i].startsWith(name)) {
        tool = i;
        break;
      }     
    }
    return tool;
  }

  /** Returns a reference to the ImageJ toolbar. */
  public static Toolbar getInstance() {
    return instance;
  }

  private void drawButtons(Graphics g) {
    if (Prefs.antialiasedTools) {
      Graphics2D g2d = (Graphics2D)g;
      g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
      g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
    }
    for (int i=0; i<LINE; i++)
      drawButton(g, i);
    drawButton(g, lineType);
    for (int i=POINT; i<NUM_TOOLS; i++)
      drawButton(g, i);
  }

  private void fill3DRect(Graphics g, int x, int y, int width, int height, boolean raised) {
    if (null==g) return;
    if (raised)
      g.setColor(gray);
    else
      g.setColor(darker);
    g.fillRect(x+1, y+1, width-2, height-2);
    g.setColor(raised ? brighter : evenDarker);
    g.drawLine(x, y, x, y + height - 1);
    g.drawLine(x + 1, y, x + width - 2, y);
    g.setColor(raised ? evenDarker : brighter);
    g.drawLine(x + 1, y + height - 1, x + width - 1, y + height - 1);
    g.drawLine(x + width - 1, y, x + width - 1, y + height - 2);
  }   

  private void drawButton(Graphics g, int tool) {
    if (g==null) return;
        int index = toolIndex(tool);
        fill3DRect(g, index * SIZE + 1, 1, SIZE, SIZE-1, !down[tool]);
        g.setColor(toolColor);
        int x = index * SIZE + OFFSET;
    int y = OFFSET;
    if (down[tool]) { x++; y++;}
    this.g = g;
    if (tool>=SPARE1 && tool<=SPARE9 && icons[tool]!=null) {
      drawIcon(g, tool, x, y);
      return;
    }
    switch (tool) {
      case RECTANGLE:
        xOffset = x; yOffset = y;
        if (roundRectMode)
          g.drawRoundRect(x+1, y+2, 15, 12, 8, 8);
        else
          g.drawRect(x+1, y+2, 15, 12);
        drawTriangle(15,14);
        return;
      case OVAL:
        xOffset = x; yOffset = y;
        if (ovalType==BRUSH_ROI) {
          m(9,2); d(13,2); d(13,2); d(15,5); d(15,8);
          d(13,10); d(10,10); d(8,13); d(4,13);
          d(2,11);  d(2,7); d(4,5); d(7,5); d(9,2);
        } else if (ovalType==ELLIPSE_ROI) {
          yOffset = y + 1;
          m(11,0); d(13,0); d(14,1); d(15,1); d(16,2); d(17,3); d(17,7);
          d(12,12); d(11,12); d(10,13); d(8,13); d(7,14); d(4,14); d(3,13);
          d(2,13); d(1,12); d(1,11); d(0,10); d(0,9); d(1,8); d(1,7);
          d(6,2); d(7,2); d(8,1); d(10,1); d(11,0);
        } else
          g.drawOval(x+1, y+2, 15, 12);
        drawTriangle(15,14);
        return;
      case POLYGON:
        xOffset = x+1; yOffset = y+3;
        m(4,0); d(14,0); d(14,1); d(10,5); d(10,6);
        d(13,9); d(13,10); d(0,10); d(0,4); d(4,0);
        return;
      case FREEROI:
        xOffset = x+1; yOffset = y+3;
        m(3,0); d(5,0); d(7,2); d(9,2); d(11,0); d(13,0); d(14,1); d(15,2);
        d(15,4); d(14,5); d(14,6); d(12,8); d(11,8); d(10,9); d(9,9); d(8,10);
        d(5,10); d(3,8); d(2,8); d(1,7); d(1,6); d(0,5); d(0,2); d(1,1); d(2,1);
        return;
      case LINE:
        xOffset = x; yOffset = y;
        if (arrowMode) {
          m(1,14); d(14,1); m(6,5); d(14,1); m(10,9); d(14,1); m(6,5); d(10,9);
        } else {
          m(0,12); d(17,3);
        }
        drawTriangle(12,14);
        return;
      case POLYLINE:
        xOffset = x; yOffset = y;
        m(14,6); d(11,3); d(1,3); d(1,4); d(6,9); d(2,13);
        drawTriangle(12,14);
        return;
      case FREELINE:
        xOffset = x; yOffset = y;
        m(16,4); d(14,6); d(12,6); d(9,3); d(8,3); d(6,7); d(2,11); d(1,11);
        drawTriangle(12,14);
        return;
      case POINT:
        xOffset = x; yOffset = y;
        if (multiPointMode) {
          drawPoint(1,3); drawPoint(9,1); drawPoint(15,5);
          drawPoint(10,11); drawPoint(2,12);
        } else {
          m(1,8); d(6,8); d(6,6); d(10,6); d(10,10); d(6,10); d(6,9);
          m(8,1); d(8,5); m(11,8); d(15,8); m(8,11); d(8,15);
          m(8,8); d(8,8);
          g.setColor(Roi.getColor());
          g.fillRect(x+7, y+7, 3, 3);
        }
        drawTriangle(14,14);
        return;
      case WAND:
        xOffset = x+2; yOffset = y+2;
        dot(4,0);  m(2,0); d(3,1); d(4,2);  m(0,0); d(1,1);
        m(0,2); d(1,3); d(2,4);  dot(0,4); m(3,3); d(12,12);
        return;
      case TEXT:
        xOffset = x+2; yOffset = y+1;
        m(0,13); d(3,13);
        m(1,12); d(7,0); d(12,13);
        m(11,13); d(14,13);
        m(3,8); d(10,8);
        return;
      case MAGNIFIER:
        xOffset = x+2; yOffset = y+2;
        m(3,0); d(3,0); d(5,0); d(8,3); d(8,5); d(7,6); d(7,7);
        d(6,7); d(5,8); d(3,8); d(0,5); d(0,3); d(3,0);
        m(8,8); d(9,8); d(13,12); d(13,13); d(12,13); d(8,9); d(8,8);
        return;
      case HAND:
        xOffset = x+1; yOffset = y+1;
        m(5,14); d(2,11); d(2,10); d(0,8); d(0,7); d(1,6); d(2,6); d(4,8);
        d(4,6); d(3,5); d(3,4); d(2,3); d(2,2); d(3,1); d(4,1); d(5,2); d(5,3);
        m(6,5); d(6,1); d(7,0); d(8,0); d(9,1); d(9,5);
        m(9,1); d(11,1); d(12,2); d(12,6);
        m(13,4); d(14,3); d(15,4); d(15,7); d(14,8);
        d(14,10); d(13,11); d(13,12); d(12,13); d(12,14);
        return;
      case DROPPER:
        xOffset = x; yOffset = y;
        g.setColor(foregroundColor);
        //m(0,0); d(17,0); d(17,17); d(0,17); d(0,0);
        m(12,2); d(14,2);
        m(11,3); d(15,3);
        m(11,4); d(15,4);
        m(8,5); d(15,5);
        m(9,6); d(14,6);
        m(10,7); d(12,7); d(12,9);
        m(8,7); d(2,13); d(2,15); d(4,15); d(11,8);
        g.setColor(backgroundColor);
        m(0,0); d(16,0); d(16,16); d(0,16); d(0,0);
        return;
      case ANGLE:
        xOffset = x+1; yOffset = y+2;
        m(0,11); d(11,0); m(0,11); d(15,11);
        m(10,11); d(10,8); m(9,7); d(9,6); dot(8,5);
        return;
    }
  }
 
  void drawTriangle(int x, int y) {
    g.setColor(triangleColor);
    xOffset+=x; yOffset+=y;
    m(0,0); d(4,0); m(1,1); d(3,1); dot(2,2);
  }
 
  void drawPoint(int x, int y) {
    g.setColor(toolColor);
    m(x-2,y); d(x+2,y);
    m(x,y-2); d(x,y+2);
    g.setColor(Roi.getColor());
    dot(x,y);
  }
 
  void drawIcon(Graphics g, int tool, int x, int y) {
    if (null==g) return;
    icon = icons[tool];
    this.icon = icon;
    int length = icon.length();
    int x1, y1, x2, y2;
    pc = 0;
    while (true) {
      char command = icon.charAt(pc++);
      if (pc>=length) break;
      switch (command) {
        case 'B': x+=v(); y+=v(); break// reset base
        case 'R': g.drawRect(x+v(), y+v(), v(), v()); break// rectangle
        case 'F': g.fillRect(x+v(), y+v(), v(), v()); break// filled rectangle
        case 'O': g.drawOval(x+v(), y+v(), v(), v()); break// oval
        case 'o': g.fillOval(x+v(), y+v(), v(), v()); break// filled oval
        case 'C': g.setColor(new Color(v()*16,v()*16,v()*16)); break; // set color
        case 'L': g.drawLine(x+v(), y+v(), x+v(), y+v()); break; // line
        case 'D': g.fillRect(x+v(), y+v(), 1, 1); break; // dot
        case 'P': // polyline
          x1=x+v(); y1=y+v();
          while (true) {
            x2=v(); if (x2==0) break;
            y2=v(); if (y2==0) break;
            x2+=x; y2+=y;
            g.drawLine(x1, y1, x2, y2);
            x1=x2; y1=y2;
          }
          break;
        case 'T': // text (one character)
          x2 = x+v();
          y2 = y+v();
          int size = v()*10+v();
          char[] c = new char[1];
          c[0] = pc<icon.length()?icon.charAt(pc++):'e';
          g.setFont(new Font("SansSerif", Font.BOLD, size));
          g.drawString(new String(c), x2, y2);
          break;
        default: break;
      }
      if (pc>=length) break;
    }
    if (menus[tool]!=null && menus[tool].getItemCount()>0) {
      xOffset = x; yOffset = y;
      drawTriangle(14, 14);
    }
  }
 
  int v() {
    if (pc>=icon.length()) return 0;
    char c = icon.charAt(pc++);
    //IJ.log("v: "+pc+" "+c+" "+toInt(c));
    switch (c) {
      case '0': return 0;
      case '1': return 1;
      case '2': return 2;
      case '3': return 3;
      case '4': return 4;
      case '5': return 5;
      case '6': return 6;
      case '7': return 7;
      case '8': return 8;
      case '9': return 9;
      case 'a': return 10;
      case 'b': return 11;
      case 'c': return 12;
      case 'd': return 13;
      case 'e': return 14;
      case 'f': return 15;
      default: return 0;
    }
  }
 
  private void showMessage(int tool) {
    if (tool>=SPARE1 && tool<=SPARE9 && names[tool]!=null) {
      String name = names[tool];
      int index = name.indexOf("Action Tool");
      if (index!=-1)
        name = name.substring(0, index);
      else {
        index = name.indexOf("Menu Tool");
        if (index!=-1)
          name = name.substring(0, index+4);
      }
      IJ.showStatus(name);
      return;
    }
    String hint = " (right click to switch)";
    switch (tool) {
      case RECTANGLE:
        if (roundRectMode)
          IJ.showStatus("Rectangular or *rounded rectangular* selections"+hint);
        else
          IJ.showStatus("*Rectangular* or rounded rectangular selections"+hint);
        return;
      case OVAL:
        if (ovalType==BRUSH_ROI)
          IJ.showStatus("Oval, elliptical or *brush* selections"+hint);
        else if (ovalType==ELLIPSE_ROI)
          IJ.showStatus("Oval, *elliptical* or brush selections"+hint);
        else
          IJ.showStatus("*Oval*, elliptical or brush selections"+hint);
        return;
      case POLYGON:
        IJ.showStatus("Polygon selections");
        return;
      case FREEROI:
        IJ.showStatus("Freehand selections");
        return;
      case LINE:
        if (arrowMode)
          IJ.showStatus("Straight, segmented or freehand lines, or *arrows*"+hint);
        else
          IJ.showStatus("*Straight*, segmented or freehand lines, or arrows"+hint);
        return;
      case POLYLINE:
        IJ.showStatus("Straight, *segmented* or freehand lines, or arrows"+hint);
        return;
      case FREELINE:
        IJ.showStatus("Straight, segmented or *freehand* lines, or arrows"+hint);
        return;
      case POINT:
        if (multiPointMode)
          IJ.showStatus("Point or *multi-point* selections"+hint);
        else
          IJ.showStatus("*Point* or multi-point selections"+hint);
        return;
      case WAND:
        IJ.showStatus("Wand (tracing) tool");
        return;
      case TEXT:
        IJ.showStatus("Text tool");
        TextRoi.recordSetFont();
        return;
      case MAGNIFIER:
        IJ.showStatus("Magnifying glass (or use \"+\" and \"-\" keys)");
        return;
      case HAND:
        IJ.showStatus("Scrolling tool (or press space bar and drag)");
        return;
      case DROPPER:
        IJ.showStatus("Color picker (" + foregroundColor.getRed() + ","
        + foregroundColor.getGreen() + "," + foregroundColor.getBlue() + ")");
        return;
      case ANGLE:
        IJ.showStatus("Angle tool");
        return;
      default:
        IJ.showStatus("ImageJ "+IJ.getVersion()+" / Java "+System.getProperty("java.version")+(IJ.is64Bit()?" (64-bit)":" (32-bit)"));
        return;
    }
  }

  private void m(int x, int y) {
    this.x = xOffset+x;
    this.y = yOffset+y;
  }

  private void d(int x, int y) {
    x += xOffset;
    y += yOffset;
    g.drawLine(this.x, this.y, x, y);
    this.x = x;
    this.y = y;
  }
 
  private void dot(int x, int y) {
    g.fillRect(x+xOffset, y+yOffset, 1, 1);
  }

  private void resetButtons() {
    for (int i=0; i<NUM_TOOLS; i++)
      down[i] = false;
  }

  public void paint(Graphics g) {
    if (null==g) return;
    drawButtons(g);
  }

  public boolean setTool(String name) {
    name = name.toLowerCase(Locale.US);
    boolean ok = true;
    if (name.indexOf("round")!=-1) {
      roundRectMode = true;
      setTool(RECTANGLE);
    } else if (name.indexOf("rect")!=-1) {
      roundRectMode = false;
      setTool(RECTANGLE);
    } else if (name.indexOf("oval")!=-1) {
      ovalType = OVAL_ROI;
      setTool(OVAL);
    } else if (name.indexOf("ellip")!=-1) {
      ovalType = ELLIPSE_ROI;
      setTool(OVAL);
    } else if (name.indexOf("brush")!=-1) {
      ovalType = BRUSH_ROI;
      setTool(OVAL);
    } else if (name.indexOf("polygon")!=-1)
      setTool(POLYGON);
    else if (name.indexOf("polyline")!=-1)
      setTool(POLYLINE);
    else if (name.indexOf("freeline")!=-1)
      setTool(FREELINE);
    else if (name.indexOf("line")!=-1) {
      arrowMode = false;
      setTool(LINE);
    } else if (name.indexOf("arrow")!=-1) {
      arrowMode = true;
      setTool(LINE);
    } else if (name.indexOf("free")!=-1)
      setTool(FREEROI);
    else if (name.indexOf("multi")!=-1) {
      multiPointMode = true;
      Prefs.multiPointMode = true;
      setTool(POINT);
    } else if (name.indexOf("point")!=-1) {
      multiPointMode = false;
      Prefs.multiPointMode = false;
      setTool(POINT);
    } else if (name.indexOf("wand")!=-1)
      setTool(WAND);
    else if (name.indexOf("text")!=-1)
      setTool(TEXT);
    else if (name.indexOf("hand")!=-1)
      setTool(HAND);
    else if (name.indexOf("zoom")!=-1)
      setTool(MAGNIFIER);
    else if (name.indexOf("dropper")!=-1||name.indexOf("color")!=-1)
      setTool(DROPPER);
    else if (name.indexOf("angle")!=-1)
      setTool(ANGLE);
    else
      ok = false;
    return ok;
  }
 
  /** Returns the name of the current tool. */
  public static String getToolName() {
    String name = instance.getName(current);
    if (current>=SPARE1 && current<=SPARE9 && instance.names[current]!=null)
      name = instance.names[current];
    return name!=null?name:"";
  }

  /** Returns the name of the specified tool. */
  String getName(int id) {
    switch (id) {
      case RECTANGLE: return roundRectMode?"roundrect":"rectangle";
      case OVAL:
        switch (ovalType) {
          case OVAL_ROI: return "oval";
          case ELLIPSE_ROI: return "ellipse";
          case BRUSH_ROI: return "brush";
        }
      case POLYGON: return "polygon";
      case FREEROI: return "freehand";
      case LINE: return arrowMode?"arrow":"line";
      case POLYLINE: return "polyline";
      case FREELINE: return "freeline";
      case ANGLE: return "angle";
      case POINT: return Prefs.multiPointMode?"multipoint":"point";
      case WAND: return "wand";
      case TEXT: return "text";
      case HAND: return "hand";
      case MAGNIFIER: return "zoom";
      case DROPPER: return "dropper";
      default: return null;
    }
   
  }
 
  public void setTool(int tool) {
    if ((tool==current&&!(tool==RECTANGLE||tool==OVAL||tool==POINT)) || tool<0 || tool>=NUM_TOOLS-1)
      return;
    if (tool==SPARE1||(tool>=SPARE2&&tool<=SPARE8)) {
      if (names[tool]==null)
        names[tool] = "Spare tool"; // enable tool
      if (names[tool].indexOf("Action Tool")!=-1)
        return;
    }
    if (isLine(tool)) lineType = tool;
    setTool2(tool);
  }
   
  private void setTool2(int tool) {
    if (!isValidTool(tool)) return;
    String previousName = getToolName();
    current = tool;
    down[current] = true;
    if (current!=previous)
      down[previous] = false;
    Graphics g = this.getGraphics();
    if (Prefs.antialiasedTools) {
      Graphics2D g2d = (Graphics2D)g;
      g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
    }
    drawButton(g, previous);
    drawButton(g, current);
    if (null==g) return;
    g.dispose();
    showMessage(current);
    previous = current;
    if (Recorder.record) {
      String name = getName(current);
      if (name!=null) Recorder.record("setTool", name);
    }
    if (IJ.isMacOSX())
      repaint();
    if (!previousName.equals(getToolName()))
      IJ.notifyEventListeners(IJEventListener.TOOL_CHANGED);
  }
 
  boolean isValidTool(int tool) {
    if (tool<0 || tool>=NUM_TOOLS)
      return false;
    if ((tool==SPARE1||(tool>=SPARE2&&tool<=SPARE9)) && names[tool]==null)
      return false;
    return true;
  }

  /**
  * @deprecated
  * replaced by getForegroundColor()
  */
  public Color getColor() {
    return foregroundColor;
  }

  /**
  * @deprecated
  * replaced by setForegroundColor()
  */
  public void setColor(Color c) {
    if (c!=null) {
      foregroundColor = c;
      drawButton(this.getGraphics(), DROPPER);
    }
  }
 
  public static Color getForegroundColor() {
    return foregroundColor;
  }

  public static void setForegroundColor(Color c) {
    if (c!=null) {
      foregroundColor = c;
      repaintTool(DROPPER);
      if (!IJ.isMacro()) setRoiColor(c);
      IJ.notifyEventListeners(IJEventListener.FOREGROUND_COLOR_CHANGED);
    }
  }

  public static Color getBackgroundColor() {
    return backgroundColor;
  }

  public static void setBackgroundColor(Color c) {
    if (c!=null) {
      backgroundColor = c;
      repaintTool(DROPPER);
      IJ.notifyEventListeners(IJEventListener.BACKGROUND_COLOR_CHANGED);
    }
  }
 
  private static void setRoiColor(Color c) {
    ImagePlus imp = WindowManager.getCurrentImage();
    if (imp==null) return;
    Roi roi = imp.getRoi();
    if (roi!=null && (roi.isDrawingTool())) {
      roi.setStrokeColor(c);
      imp.draw();
    }
  }

  /** Returns the size of the brush tool, or 0 if the brush tool is not enabled. */
  public static int getBrushSize() {
    if (ovalType==BRUSH_ROI)
      return brushSize;
    else
      return 0;
  }

  /** Set the size of the brush tool, which must be greater than 4. */
  public static void setBrushSize(int size) {
    brushSize = size;
    if (brushSize<5) brushSize = 5;
    Prefs.set(BRUSH_SIZE, brushSize);
  }
   
  /** Returns the rounded rectangle arc size, or 0 if the rounded rectangle tool is not enabled. */
  public static int getRoundRectArcSize() {
    if (!roundRectMode)
      return 0;
    else
      return arcSize;
  }

  /** Sets the rounded rectangle corner diameter (pixels). */
  public static void setRoundRectArcSize(int size) {
    if (size<=0)
      roundRectMode = false;
    else {
      arcSize = size;
      Prefs.set(CORNER_DIAMETER, arcSize);
    }
    repaintTool(RECTANGLE);
    ImagePlus imp = WindowManager.getCurrentImage();
    Roi roi = imp!=null?imp.getRoi():null;
    if (roi!=null && roi.getType()==Roi.RECTANGLE)
      roi.setCornerDiameter(roundRectMode?arcSize:0);
  }

  /** Returns 'true' if the multi-point tool is enabled. */
  public static boolean getMultiPointMode() {
    return multiPointMode;
  }

  /** Returns the oval tool type (OVAL_ROI, ELLIPSE_ROI or BRUSH_ROI). */
  public static int getOvalToolType() {
    return ovalType;
  }

  public static int getButtonSize() {
    return SIZE;
  }
 
  static void repaintTool(int tool) {
    if (IJ.getInstance()!=null) {
      Toolbar tb = getInstance();
      Graphics g = tb.getGraphics();
      if (g==null) return;
      if (Prefs.antialiasedTools)
        ((Graphics2D)g).setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
      tb.drawButton(g, tool);
      if (g!=null) g.dispose();
    }
    //Toolbar tb = getInstance();
    //tb.repaint(tool * SIZE , 0, SIZE, SIZE);
  }
 
  // Returns the toolbar position index of the specified tool
    int toolIndex(int tool) {
      switch (tool) {
      case RECTANGLE: return 0;
      case OVAL: return 1;
      case POLYGON: return 2;
      case FREEROI: return 3;
      case LINE: return 4;
      case POLYLINE: return 4;
      case FREELINE: return 4;
      case POINT: return 6;
      case WAND: return 7;
      case TEXT: return 8;
      case MAGNIFIER: return 9;
      case HAND: return 10;
      case DROPPER: return 11;
      case ANGLE: return 5;
      case SPARE1: return 12;
      default: return tool - 2;
    }
    }

  // Returns the tool corresponding to the specified tool position index
    int toolID(int index) {
      switch (index) {
      case 0: return RECTANGLE;
      case 1: return OVAL;
      case 2: return POLYGON;
      case 3: return FREEROI;
      case 4: return lineType;
      case 5: return ANGLE;
      case 6: return POINT;
      case 7: return WAND;
      case 8: return TEXT;
      case 9: return MAGNIFIER;
      case 10: return HAND;
      case 11: return DROPPER;
      case 12: return SPARE1;
      default: return index + 2;
    }
    }

  public void mousePressed(MouseEvent e) {
    int x = e.getX();
     int newTool = 0;
    for (int i=0; i<NUM_BUTTONS; i++) {
      if (x>i*SIZE && x<i*SIZE+SIZE)
        newTool = toolID(i);
    }
    if (newTool==SPARE9) {
      showSwitchPopupMenu(e);
      return;
    }
    if (!isValidTool(newTool)) return;
    if (menus[newTool]!=null && menus[newTool].getItemCount()>0) {
            menus[newTool].show(e.getComponent(), e.getX(), e.getY());
      return;
    }
    boolean doubleClick = newTool==current && (System.currentTimeMillis()-mouseDownTime)<=DOUBLE_CLICK_THRESHOLD;
     mouseDownTime = System.currentTimeMillis();
    if (!doubleClick) {
      mpPrevious = current;
      if (isMacroTool(newTool)) {
        String name = names[newTool];
        if (name.indexOf("Unused Tool")!=-1)
          return;
        if (name.indexOf("Action Tool")!=-1) {
          if (e.isPopupTrigger()||e.isMetaDown()) {
            name = name.endsWith(" ")?name:name+" ";
            macroInstaller.runMacroTool(name+"Options");
          } else {
            drawTool(newTool, true);
            IJ.wait(50);
            drawTool(newTool, false);
            runMacroTool(newTool);
          }
          return;
        } else
          name = name.endsWith(" ")?name:name+" ";
          macroInstaller.runMacroTool(name+"Selected");
        }
      }
      setTool2(newTool);
      boolean isRightClick = e.isPopupTrigger()||e.isMetaDown();
      if (current==RECTANGLE && isRightClick) {
        rectItem.setState(!roundRectMode);
        roundRectItem.setState(roundRectMode);
        if (IJ.isMacOSX()) IJ.wait(10);
        rectPopup.show(e.getComponent(),x,y);
        mouseDownTime = 0L;
      }
      if (current==OVAL && isRightClick) {
        ovalItem.setState(ovalType==OVAL_ROI);
        ellipseItem.setState(ovalType==ELLIPSE_ROI);
        brushItem.setState(ovalType==BRUSH_ROI);
        if (IJ.isMacOSX()) IJ.wait(10);
        ovalPopup.show(e.getComponent(),x,y);
        mouseDownTime = 0L;
      }
      if (current==POINT && isRightClick) {
        pointItem.setState(!multiPointMode);
        multiPointItem.setState(multiPointMode);
        if (IJ.isMacOSX()) IJ.wait(10);
        pointPopup.show(e.getComponent(),x,y);
        mouseDownTime = 0L;
      }
      if (isLine(current) && isRightClick) {
        straightLineItem.setState(lineType==LINE&&!arrowMode);
        polyLineItem.setState(lineType==POLYLINE);
        freeLineItem.setState(lineType==FREELINE);
        arrowItem.setState(lineType==LINE&&arrowMode);
        if (IJ.isMacOSX()) IJ.wait(10);
        linePopup.show(e.getComponent(),x,y);
        mouseDownTime = 0L;
      }
      if (isMacroTool(current) && isRightClick) {
        String name = names[current].endsWith(" ")?names[current]:names[current]+" ";
        macroInstaller.runMacroTool(name+"Options");
      }
    } else {
      if (isMacroTool(current)) {
        String name = names[current].endsWith(" ")?names[current]:names[current]+" ";
        macroInstaller.runMacroTool(name+"Options");
        return;
      }
      ImagePlus imp = WindowManager.getCurrentImage();
      switch (current) {
        case RECTANGLE:
          if (roundRectMode)
            IJ.doCommand("Rounded Rect Tool...");
          break;
        case OVAL:
          showBrushDialog();
          break;
        case MAGNIFIER:
          if (imp!=null) {
            ImageCanvas ic = imp.getCanvas();
            if (ic!=null) ic.unzoom();
          }
          break;
        case LINE: case POLYLINE: case FREELINE:
          if (current==LINE && arrowMode) {
            IJ.doCommand("Arrow Tool...");
          } else
            IJ.runPlugIn("ij.plugin.frame.LineWidthAdjuster", "");
          break;
        case ANGLE:
          showAngleDialog();
          break;
        case POINT:
          if (multiPointMode) {
            if (imp!=null && imp.getRoi()!=null)
              IJ.doCommand("Add Selection...");
          } else
            IJ.doCommand("Point Tool...");
          break;
        case WAND:
          IJ.doCommand("Wand Tool...");
          break;
        case TEXT:
          IJ.doCommand("Fonts...");
          break;
        case DROPPER:
          IJ.doCommand("Color Picker...");
          setTool2(mpPrevious);
          break;
        default:
      }
    }
  }
 
  void showSwitchPopupMenu(MouseEvent e) {
    String path = IJ.getDirectory("macros")+"toolsets/";
    if (path==null) {
      return;
    }
    boolean applet = IJ.getApplet()!=null;
    File f = new File(path);
    String[] list;
    if (!applet && f.exists() && f.isDirectory()) {
      list = f.list();
      if (list==null) return;
    } else
      list = new String[0];
        boolean stackTools = false;
    for (int i=0; i<list.length; i++) {
            if (list[i].equals("Stack Tools.txt")) {
                stackTools = true;
                break;
            }
    }
    switchPopup.removeAll();
        path = IJ.getDirectory("macros") + "StartupMacros.txt";
    f = new File(path);
    if (!applet && f.exists())
            addItem("Startup Macros");
        else
            addItem("StartupMacros*");
    if (!stackTools) addItem("Stack Tools*");
     for (int i=0; i<list.length; i++) {
      String name = list[i];
      if (name.endsWith(".txt")) {
        name = name.substring(0, name.length()-4);
                addItem(name);
      } else if (name.endsWith(".ijm")) {
        name = name.substring(0, name.length()-4) + " ";
                addItem(name);
      }
    }
    addItem("Help...");
    add(ovalPopup);
    if (IJ.isMacOSX()) IJ.wait(10);
    switchPopup.show(e.getComponent(), e.getX(), e.getY());
  }
   
    void addItem(String name) {
    CheckboxMenuItem item = new CheckboxMenuItem(name, name.equals(currentSet));
    item.addItemListener(this);
    switchPopup.add(item);
    }

  void drawTool(int tool, boolean drawDown) {
    down[tool] = drawDown;
    Graphics g = this.getGraphics();
    if (!drawDown && Prefs.antialiasedTools) {
      Graphics2D g2d = (Graphics2D)g;
      g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
    }
    drawButton(g, tool);
    if (null==g) return;
    g.dispose();
  }

  boolean isLine(int tool) {
    return tool==LINE || tool==POLYLINE || tool==FREELINE;
  }
 
  public void restorePreviousTool() {
    setTool2(mpPrevious);
  }
 
  boolean isMacroTool(int tool) {
    return tool>=SPARE1 && tool<=SPARE9 && names[tool]!=null && macroInstaller!=null;
  }
 
  public void mouseReleased(MouseEvent e) {}
  public void mouseExited(MouseEvent e) {}
  public void mouseClicked(MouseEvent e) {}
  public void mouseEntered(MouseEvent e) {}
    public void mouseDragged(MouseEvent e) {}
 
  public void itemStateChanged(ItemEvent e) {
    CheckboxMenuItem item = (CheckboxMenuItem)e.getSource();
    String previousName = getToolName();
    if (item==rectItem || item==roundRectItem) {
      roundRectMode = item==roundRectItem;
      repaintTool(RECTANGLE);
      showMessage(RECTANGLE);
      ImagePlus imp = WindowManager.getCurrentImage();
      Roi roi = imp!=null?imp.getRoi():null;
      if (roi!=null && roi.getType()==Roi.RECTANGLE)
        roi.setCornerDiameter(roundRectMode?arcSize:0);
      if (!previousName.equals(getToolName()))
        IJ.notifyEventListeners(IJEventListener.TOOL_CHANGED);
    } else if (item==ovalItem || item==ellipseItem || item==brushItem) {
      if (item==brushItem)
        ovalType = BRUSH_ROI;
      else if (item==ellipseItem)
        ovalType = ELLIPSE_ROI;
      else
        ovalType = OVAL_ROI;
      repaintTool(OVAL);
      showMessage(OVAL);
      if (!previousName.equals(getToolName()))
        IJ.notifyEventListeners(IJEventListener.TOOL_CHANGED);
    } else if (item==pointItem || item==multiPointItem) {
      multiPointMode = item==multiPointItem;
      Prefs.multiPointMode = multiPointMode;
      repaintTool(POINT);
      showMessage(POINT);
      if (!previousName.equals(getToolName()))
        IJ.notifyEventListeners(IJEventListener.TOOL_CHANGED);
    } else if (item==straightLineItem) {
      lineType = LINE;
      arrowMode = false;
      setTool2(LINE);
      showMessage(LINE);
    } else if (item==polyLineItem) {
      lineType = POLYLINE;
      setTool2(POLYLINE);
      showMessage(POLYLINE);
    } else if (item==freeLineItem) {
      lineType = FREELINE;
      setTool2(FREELINE);
      showMessage(FREELINE);
    } else if (item==arrowItem) {
      lineType = LINE;
      arrowMode = true;
      setTool2(LINE);
      showMessage(LINE);
    } else {
      String label = item.getActionCommand();
      if (!label.equals("Help...")) currentSet = label;
      String path;
      if (label.equals("Help...")) {
        IJ.showMessage("Tool Switcher",
          "Use this drop down menu to switch to macro tool\n"+
          "sets located in the ImageJ/macros/toolsets folder,\n"+
          "or to revert to the ImageJ/macros/StartupMacros\n"+
          "set. The default tool sets, which have names\n"+
          "ending in '*', are loaded from ij.jar.\n"+
          " \n"+
          "Hold the shift key down while selecting a tool\n"+
          "set to view its source code.\n"+
          " \n"+
          "Several example tool sets are available at\n"+
          "<"+IJ.URL+"/macros/toolsets/>."
          );
        return;
      } else if (label.endsWith("*")) {
                // load from ij.jar
                MacroInstaller mi = new MacroInstaller();
                label = label.substring(0, label.length()-1) + ".txt";
                path = "/macros/"+label;
        if (IJ.shiftKeyDown()) {
          String macros = mi.openFromIJJar(path);
                    Editor ed = new Editor();
                    ed.setSize(350, 300);
                    ed.create(label, macros);
                  IJ.setKeyUp(KeyEvent.VK_SHIFT);
        } else
          mi.installFromIJJar(path);
            } else {
                // load from ImageJ/macros/toolsets
                if (label.equals("Startup Macros"))
                    path = IJ.getDirectory("macros")+"StartupMacros.txt";
                else if (label.endsWith(" "))
                    path = IJ.getDirectory("macros")+"toolsets/"+label.substring(0, label.length()-1)+".ijm";
                else
                    path = IJ.getDirectory("macros")+"toolsets/"+label+".txt";
                try {
                    if (IJ.shiftKeyDown()) {
                        IJ.open(path);
                    IJ.setKeyUp(KeyEvent.VK_SHIFT);
                    } else
                        new MacroInstaller().run(path);
                }
                catch(Exception ex) {}
            }
    }
  }

  public void actionPerformed(ActionEvent e) {
    MenuItem item = (MenuItem)e.getSource();
    String cmd = e.getActionCommand();
    PopupMenu popup = (PopupMenu)item.getParent();
    int tool = -1;
    for (int i=SPARE1; i<NUM_TOOLS; i++) {
      if (popup==menus[i]) {
        tool = i;
        break;
      }
    }
    if (tool==-1) return;
    if (macroInstaller!=null)
      macroInstaller.runMenuTool(names[tool], cmd);
    }

  public Dimension getPreferredSize(){
    return ps;
  }

  public Dimension getMinimumSize(){
    return ps;
  }
 
  public void mouseMoved(MouseEvent e) {
    int x = e.getX();
    x=toolID(x/SIZE);
    showMessage(x);
  }

  /** Adds a tool to the toolbar. The 'toolTip' string is displayed in the status bar
     when the mouse is over the tool icon. The 'toolTip' string may include icon
    (http://imagej.nih.gov/ij/developer/macro/macros.html#tools).
    Returns the tool ID, or -1 if all tools are in use. */
  public int addTool(String toolTip) {
    int index = toolTip.indexOf('-');
    boolean hasIcon = index>=0 && (toolTip.length()-index)>4;
    int tool =-1;
    if (names[SPARE1]==null)
      tool = SPARE1;
    if (tool==-1) {
      for (int i=SPARE2; i<=SPARE8; i++) {
        if (names[i]==null) {
          tool = i;
          break;
        }     
      }
    }
    if (tool==-1) return -1;
    if (hasIcon) {
      icons[tool] = toolTip.substring(index+1);
      if (index>0 && toolTip.charAt(index-1)==' ')
        names[tool] = toolTip.substring(0, index-1);
      else
        names[tool] = toolTip.substring(0, index);
    } else {
      if (toolTip.endsWith("-"))
        toolTip = toolTip.substring(0, toolTip.length()-1);
      else if (toolTip.endsWith("- "))
        toolTip = toolTip.substring(0, toolTip.length()-2);
      names[tool] = toolTip;
    }
        if (tool==current && (names[tool].indexOf("Action Tool")!=-1||names[tool].indexOf("Unused Tool")!=-1))
          setTool(RECTANGLE);
        if (names[tool].endsWith(" Menu Tool"))
            installMenu(tool);
    return tool;
  }
   
    void installMenu(int tool) {
        Program pgm = macroInstaller.getProgram();
        Hashtable h = pgm.getMenus();
        if (h==null) return;
        String[] commands = (String[])h.get(names[tool]);
        if (commands==null) return;
    if (menus[tool]==null) {
      menus[tool] = new PopupMenu("");
      if (Menus.getFontSize()!=0)
        menus[tool].setFont(Menus.getFont());
      add(menus[tool] );
    } else
      menus[tool].removeAll();
        for (int i=0; i<commands.length; i++) {
      if (commands[i].equals("-"))
        menus[tool].addSeparator();
      else {
        MenuItem mi = new MenuItem(commands[i]);
        mi.addActionListener(this);
        menus[tool].add(mi);
      }
        }
        if (tool==current) setTool(RECTANGLE);
    }
   
  /** Used by the MacroInstaller class to install macro tools. */
  public void addMacroTool(String name, MacroInstaller macroInstaller, int id) {
      if (id==0) {
      for (int i=SPARE1; i<NUM_TOOLS-1; i++) {
        names[i] = null;
        icons[i] = null;
        if (menus[i]!=null) menus[i].removeAll();
      }
      }
    this.macroInstaller = macroInstaller;
        addTool(name);
  }
     
  void runMacroTool(int id) {
    if (macroInstaller!=null)
      macroInstaller.runMacroTool(names[id]);
  }
 
  void showBrushDialog() {
    GenericDialog gd = new GenericDialog("Selection Brush");
    gd.addCheckbox("Enable selection brush", ovalType==BRUSH_ROI);
    gd.addNumericField("           Size:", brushSize, 0, 4, "pixels");
    gd.showDialog();
    if (gd.wasCanceled()) return;
    if (gd.getNextBoolean())
      ovalType = BRUSH_ROI;
    brushSize = (int)gd.getNextNumber();
    repaintTool(OVAL);
    ImagePlus img = WindowManager.getCurrentImage();
    Roi roi = img!=null?img.getRoi():null;
    if (roi!=null && roi.getType()==Roi.OVAL && ovalType==BRUSH_ROI)
      img.killRoi();
    Prefs.set(BRUSH_SIZE, brushSize);
  }

  void showAngleDialog() {
    GenericDialog gd = new GenericDialog("Angle Tool");
    gd.addCheckbox("Measure reflex angle", Prefs.reflexAngle);
    gd.showDialog();
    if (!gd.wasCanceled())
      Prefs.reflexAngle = gd.getNextBoolean();
  }

}
TOP

Related Classes of ij.gui.Toolbar

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.