Squiz Matrix  4.12.2
 All Data Structures Namespaces Functions Variables Pages
Toolbar.java
1 package ij.gui;
2 
3 import java.awt.*;
4 import java.awt.event.KeyEvent;
5 import java.awt.event.*;
6 import ij.*;
7 import ij.plugin.frame.Recorder;
8 import javax.swing.*;
9 
11 public class Toolbar extends JPanel implements MouseListener, MouseMotionListener {
12 
13  public static final int RECTANGLE = 0;
14  public static final int OVAL = 1;
15  public static final int POLYGON = 2;
16  public static final int FREEROI = 3;
17  public static final int LINE = 4;
18  public static final int POLYLINE = 5;
19  public static final int FREELINE = 6;
20  public static final int WAND = 7;
21  public static final int TEXT = 8;
22  public static final int MAGNIFIER = 9;
23  public static final int HAND = 10;
24  public static final int DROPPER = 11;
25 
26  public static final int FIRST_SELECT_TOOL = 0;
27  public static final int LAST_SELECT_TOOL = 8;
28 
29  // deprecated
30  public static final int ANGLE = 999;
31  public static final int CROSSHAIR = 999;
32 
33 
34  public static final int NUM_TOOLS = 14;
35 
36  public static final int DIVIDER = 100;
37  public static final int SPARE = 101;
38 
39  public static final int[] BUTTON_SEQUENCE = {
40  RECTANGLE,
41  OVAL,
42  POLYGON,
43  FREEROI,
44  LINE,
45  POLYLINE,
46  FREELINE,
47  WAND,
48  DIVIDER,
49  TEXT,
50  DIVIDER,
51  DROPPER,
52  DIVIDER,
53  MAGNIFIER
54  };
55 
56  private static final int SIZE = 22;
57  private static final int OFFSET = 3;
58 
59  private Dimension ps = new Dimension(SIZE*BUTTON_SEQUENCE.length, SIZE);
60  private boolean[] down;
61  private static int current;
62  private int previous;
63  private int x,y;
64  private int xOffset, yOffset;
65  private long mouseDownTime;
66  private Graphics g;
67  private static Toolbar instance;
68  private int mpPrevious = RECTANGLE;
69  private String[] names = new String[NUM_TOOLS];
70  private String[] icons = new String[NUM_TOOLS];
71  private int pc;
72  private String icon;
73 
74  private static Color foregroundColor = Prefs.getColor(Prefs.FCOLOR,Color.black);
75  private static Color backgroundColor = Prefs.getColor(Prefs.BCOLOR,Color.white);
76 
77  private Color gray = ImageJ.backgroundColor;
78  private Color brighter = gray.brighter();
79  private Color darker = gray.darker();
80  private Color evenDarker = darker.darker();
81 
82 
83  public Toolbar() {
84  down = new boolean[NUM_TOOLS];
85  resetButtons();
86  down[0] = true;
87  setForeground(foregroundColor);
88  setBackground(gray);
89  addMouseListener(this);
90  addMouseMotionListener(this);
91  instance = this;
92  }
93 
96  public static int getToolId() {
97  return current;
98  }
99 
101  public static Toolbar getInstance() {
102  return instance;
103  }
104 
105  private void drawButtons(Graphics g) {
106  int currentOffset = 1;
107  for (int i=0; i<BUTTON_SEQUENCE.length; i++) {
108  drawButton(g, BUTTON_SEQUENCE[i], currentOffset);
109  currentOffset += getButtonWidth(BUTTON_SEQUENCE[i]);
110  }
111  }
112 
113  private int getButtonWidth(int tool) {
114  if (tool == DIVIDER) {
115  return 11;
116  } else {
117  return 22;
118  }
119  }
120 
121  private void fill3DRect(Graphics g, int x, int y, int width, int height, boolean raised) {
122  if (raised)
123  g.setColor(gray);
124  else
125  g.setColor(darker);
126  g.fillRect(x+1, y+1, width-2, height-2);
127  g.setColor(raised ? brighter : evenDarker);
128  g.drawLine(x, y, x, y + height - 1);
129  g.drawLine(x + 1, y, x + width - 2, y);
130  g.setColor(raised ? evenDarker : brighter);
131  g.drawLine(x + 1, y + height - 1, x + width - 1, y + height - 1);
132  g.drawLine(x + width - 1, y, x + width - 1, y + height - 2);
133  }
134 
135  private void drawButton(Graphics g, int tool) {
136  int i=0;
137  int offset = 0;
138  while ((i < BUTTON_SEQUENCE.length) && (BUTTON_SEQUENCE[i] != tool)) {
139  offset += getButtonWidth(BUTTON_SEQUENCE[i]);
140  i++;
141  }
142  drawButton(g, tool, offset);
143  }
144 
145 
146  private void drawButton(Graphics g, int tool, int currentOffset) {
147  if (tool == DIVIDER) return;
148  int index = tool;
149  fill3DRect(g, currentOffset, 1, 22, 21, !down[tool]);
150  g.setColor(Color.black);
151  int x = currentOffset + 2;
152  int y = OFFSET;
153  if (down[tool]) { x++; y++;}
154  this.g = g;
155  if (icons[tool]!=null) {
156  drawIcon(g, icons[tool], x, y);
157  return;
158  }
159  switch (tool) {
160  case RECTANGLE:
161  g.drawRect(x+1, y+2, 14, 11);
162  return;
163  case OVAL:
164  g.drawOval(x+1, y+3, 14, 11);
165  return;
166  case POLYGON:
167  xOffset = x+1; yOffset = y+3;
168  m(4,0); d(14,0); d(14,1); d(10,5); d(10,6);
169  d(13,9); d(13,10); d(0,10); d(0,4); d(4,0);
170  return;
171  case FREEROI:
172  xOffset = x+1; yOffset = y+3;
173  m(3,0); d(5,0); d(7,2); d(9,2); d(11,0); d(13,0); d(14,1); d(15,2);
174  d(15,4); d(14,5); d(14,6); d(12,8); d(11,8); d(10,9); d(9,9); d(8,10);
175  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);
176  return;
177  case LINE:
178  xOffset = x; yOffset = y+5;
179  m(0,0); d(16,6);
180  return;
181  case POLYLINE:
182  xOffset = x+1; yOffset = y+3;
183  m(0,3); d(3,0); d(13,0); d(13,1); d(8,6); d(12,10);
184  return;
185  case FREELINE:
186  xOffset = x+1; yOffset = y+4;
187  m(0,1); d(2,3); d(4,3); d(7,0); d(8,0); d(10,4); d(14,8); d(15,8);
188  return;
189  case CROSSHAIR:
190  xOffset = x; yOffset = y;
191  m(1,8); d(6,8); d(6,6); d(10,6); d(10,10); d(6,10); d(6,9);
192  m(8,1); d(8,5); m(11,8); d(15,8); m(8,11); d(8,15);
193  m(8,8); d(8,8);
194  return;
195  case WAND:
196  xOffset = x+2; yOffset = y+2;
197  m(4,0); d(4,0); m(2,0); d(3,1); d(4,2); m(0,0); d(1,1);
198  m(0,2); d(1,3); d(2,4); m(0,4); d(0,4); m(3,3); d(12,12);
199  return;
200  case TEXT:
201  xOffset = x+2; yOffset = y+1;
202  m(0,13); d(3,13);
203  m(1,12); d(7,0); d(12,13);
204  m(11,13); d(14,13);
205  m(3,8); d(10,8);
206  return;
207  case MAGNIFIER:
208  xOffset = x+2; yOffset = y+2;
209  m(3,0); d(3,0); d(5,0); d(8,3); d(8,5); d(7,6); d(7,7);
210  d(6,7); d(5,8); d(3,8); d(0,5); d(0,3); d(3,0);
211  m(8,8); d(9,8); d(13,12); d(13,13); d(12,13); d(8,9); d(8,8);
212  return;
213 
214  case HAND:
215  xOffset = x+1; yOffset = y+1;
216  m(5,14); d(2,11); d(2,10); d(0,8); d(0,7); d(1,6); d(2,6); d(4,8);
217  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);
218  m(6,5); d(6,1); d(7,0); d(8,0); d(9,1); d(9,5);
219  m(9,1); d(11,1); d(12,2); d(12,6);
220  m(13,4); d(14,3); d(15,4); d(15,7); d(14,8);
221  d(14,10); d(13,11); d(13,12); d(12,13); d(12,14);
222  return;
223  case DROPPER:
224  xOffset = x; yOffset = y;
225  g.setColor(foregroundColor);
226  //m(0,0); d(17,0); d(17,17); d(0,17); d(0,0);
227  m(12,2); d(14,2);
228  m(11,3); d(15,3);
229  m(11,4); d(15,4);
230  m(8,5); d(15,5);
231  m(9,6); d(14,6);
232  m(10,7); d(12,7); d(12,9);
233  m(8,7); d(2,13); d(2,15); d(4,15); d(11,8);
234  g.setColor(backgroundColor);
235  m(0,0); d(16,0); d(16,16); d(0,16); d(0,0);
236  g.setColor(Color.black);
237  return;
238  }
239  }
240 
241  void drawIcon(Graphics g, String icon, int x, int y) {
242  //IJ.log("drawIcon: "+icon);
243  this.icon = icon;
244  int length = icon.length();
245  int x1, y1, x2, y2;
246  pc = 0;
247  while (true) {
248  char command = icon.charAt(pc++);
249  if (pc>=length) break;
250  switch (command) {
251  case 'B': x+=v(); y+=v(); break; // reset base
252  case 'R': g.drawRect(x+v(), y+v(), v(), v()); break; // rectangle
253  case 'F': g.fillRect(x+v(), y+v(), v(), v()); break; // filled rectangle
254  case 'O': g.drawOval(x+v(), y+v(), v(), v()); break; // oval
255  case 'o': g.fillOval(x+v(), y+v(), v(), v()); break; // filled oval
256  case 'C': g.setColor(new Color(v()*16,v()*16,v()*16)); break; // set color
257  case 'L': g.drawLine(x+v(), y+v(), x+v(), y+v()); break; // line
258  case 'D': g.drawLine(x1=x+v(), x2=y+v(), x1, x2); break; // dot
259  case 'P': // polyline
260  x1=x+v(); y1=y+v();
261  while (true) {
262  x2=v(); if (x2==0) break;
263  y2=v(); if (y2==0) break;
264  x2+=x; y2+=y;
265  g.drawLine(x1, y1, x2, y2);
266  x1=x2; y1=y2;
267  }
268  break;
269  case 'T': // text (one character)
270  x2 = x+v();
271  y2 = y+v();
272  int size = v()*10+v();
273  char[] c = new char[1];
274  c[0] = pc<icon.length()?icon.charAt(pc++):'e';
275  g.setFont(new Font("SansSerif", Font.BOLD, size));
276  g.drawString(new String(c), x2, y2);
277  break;
278  default: break;
279  }
280  if (pc>=length) break;
281  }
282  g.setColor(Color.black);
283  }
284 
285  int v() {
286  if (pc>=icon.length()) return 0;
287  char c = icon.charAt(pc++);
288  //IJ.log("v: "+pc+" "+c+" "+toInt(c));
289  switch (c) {
290  case '0': return 0;
291  case '1': return 1;
292  case '2': return 2;
293  case '3': return 3;
294  case '4': return 4;
295  case '5': return 5;
296  case '6': return 6;
297  case '7': return 7;
298  case '8': return 8;
299  case '9': return 9;
300  case 'a': return 10;
301  case 'b': return 11;
302  case 'c': return 12;
303  case 'd': return 13;
304  case 'e': return 14;
305  case 'f': return 15;
306  default: return 0;
307  }
308  }
309 
310  private void showMessage(int tool) {
311  if (tool == -1) return;
312  if ((tool < names.length) && (tool >= 0) && (names[tool]!=null)) {
313  IJ.showStatus(names[tool]);
314  return;
315  }
316  switch (tool) {
317  case RECTANGLE:
318  IJ.showStatus("Rectangular selection tool");
319  return;
320  case OVAL:
321  IJ.showStatus("Oval selection tool");
322  return;
323  case POLYGON:
324  IJ.showStatus("Polygon selection tool");
325  return;
326  case FREEROI:
327  IJ.showStatus("Freehand selection tool");
328  return;
329  case LINE:
330  IJ.showStatus("Straight line selection tool");
331  return;
332  case POLYLINE:
333  IJ.showStatus("Segmented line selection tool");
334  return;
335  case FREELINE:
336  IJ.showStatus("Freehand line selection tool");
337  return;
338  case CROSSHAIR:
339  IJ.showStatus("Crosshair (mark and count) tool");
340  return;
341  case WAND:
342  IJ.showStatus("Wand (tracing) tool: click an object to select it");
343  return;
344  case TEXT:
345  IJ.showStatus("Text tool: click and drag to create a text box");
346  return;
347  case MAGNIFIER:
348  IJ.showStatus("Zoom Tool: left-click to zoom in, right-click to zoom out");
349  return;
350  case HAND:
351  IJ.showStatus("Scrolling tool");
352  return;
353  case DROPPER:
354  IJ.showStatus("Color picker (" + foregroundColor.getRed() + ","
355  + foregroundColor.getGreen() + "," + foregroundColor.getBlue() + ")");
356  return;
357  default:
358  IJ.showStatus("");
359  return;
360  }
361  }
362 
363  private void m(int x, int y) {
364  this.x = xOffset+x;
365  this.y = yOffset+y;
366  }
367 
368  private void d(int x, int y) {
369  x += xOffset;
370  y += yOffset;
371  g.drawLine(this.x, this.y, x, y);
372  this.x = x;
373  this.y = y;
374  }
375 
376  private void resetButtons() {
377  for (int i=0; i<NUM_TOOLS; i++)
378  down[i] = false;
379  }
380 
381  public void paint(Graphics g) {
382  drawButtons(g);
383  }
384 
385  public void setTool(int tool) {
386  if (tool==current || tool<0 || tool>=NUM_TOOLS) {
387  return;
388  }
389  if ((FIRST_SELECT_TOOL <= tool) && (LAST_SELECT_TOOL >= tool)) {
390  IJ.getInstance().getImagePlus().killRoi();
391  }
392  current = tool;
393  down[current] = true;
394  down[previous] = false;
395  Graphics g = this.getGraphics();
396  drawButton(g, previous);
397  drawButton(g, current);
398  g.dispose();
399  showMessage(current);
400  previous = current;
401  if (IJ.isMacOSX())
402  repaint();
403  }
404 
405  public static Color getForegroundColor() {
406  return foregroundColor;
407  }
408 
409  public static void setForegroundColor(Color c) {
410  if (c!=null) {
411  foregroundColor = c;
412  updateColors();
413  }
414  }
415 
416  public static Color getBackgroundColor() {
417  return backgroundColor;
418  }
419 
420  public static void setBackgroundColor(Color c) {
421  if (c!=null) {
422  backgroundColor = c;
423  updateColors();
424  }
425  }
426 
427  static void updateColors() {
428  Toolbar tb = getInstance();
429  Graphics g = tb.getGraphics();
430  tb.drawButton(g, DROPPER);
431  g.dispose();
432  }
433 
434  public void mousePressed(MouseEvent e) {
435  int x = e.getX();
436  int newTool = getToolFromCoord(x);
437  if (newTool == -1) return;
438 
439  boolean doubleClick = newTool==current && (System.currentTimeMillis()-mouseDownTime)<=500;
440  mouseDownTime = System.currentTimeMillis();
441  if (!doubleClick) {
442  mpPrevious = current;
443  setTool(newTool);
444  } else {
445  ImagePlus imp = IJ.getInstance().getImagePlus();
446  switch (current) {
447  case FREEROI:
448  IJ.doCommand("Set Measurements...");
449  setTool(mpPrevious);
450  break;
451  case MAGNIFIER:
452  if (imp!=null) imp.getCanvas().unzoom();
453  break;
454  case POLYGON:
455  if (imp!=null) IJ.doCommand("Calibrate...");
456  setTool(mpPrevious);
457  break;
458  case LINE: case POLYLINE: case FREELINE:
459  IJ.doCommand("Line Width...");
460  break;
461  case CROSSHAIR:
462  IJ.doCommand("Crosshair...");
463  break;
464  case TEXT:
465  IJ.doCommand("Fonts...");
466  break;
467  case DROPPER:
468  IJ.doCommand("Color Picker...");
469  setTool(mpPrevious);
470  break;
471  default:
472  }
473  }
474  }
475 
476  public void mouseReleased(MouseEvent e) {}
477  public void mouseExited(MouseEvent e) { IJ.showStatus(""); }
478  public void mouseClicked(MouseEvent e) {}
479  public void mouseEntered(MouseEvent e) {}
480  public void mouseDragged(MouseEvent e) {}
481 
482  public Dimension getPreferredSize(){
483  return ps;
484  }
485 
486  public Dimension getMinimumSize(){
487  return ps;
488  }
489 
490  public void mouseMoved(MouseEvent e) {
491  int x = e.getX();
492  showMessage(getToolFromCoord(x));
493  }
494 
495  private int getToolFromCoord(int x) {
496  int offset = 0;
497  int i=0;
498  while ((i != BUTTON_SEQUENCE.length) && (offset < x)) {
499  offset += getButtonWidth(BUTTON_SEQUENCE[i]);
500  i++;
501  }
502  return BUTTON_SEQUENCE[i-1];
503  }
504 
505 
506 
507 }