Major cleanup of Utils class.
[trakem2.git] / ini / trakem2 / utils / ProjectToolbar.java
blobe5f25857af09c390eaf6e3b9577294c7890714f4
1 /**
3 TrakEM2 plugin for ImageJ(C).
4 Copyright (C) 2005,2006 Albert Cardona and Rodney Douglas.
6 This program is free software; you can redistribute it and/or
7 modify it under the terms of the GNU General Public License
8 as published by the Free Software Foundation (http://www.gnu.org/licenses/gpl.txt )
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 You may contact Albert Cardona at acardona at ini.phys.ethz.ch
20 Institute of Neuroinformatics, University of Zurich / ETH, Switzerland.
21 **/
23 package ini.trakem2.utils;
25 import ij.ImageJ;
26 import ij.IJ;
27 import ij.gui.Toolbar;
28 import ij.plugin.MacroInstaller;
30 import java.awt.event.MouseListener;
31 import java.awt.event.MouseEvent;
32 import java.awt.event.KeyEvent;
33 import java.io.File;
35 import java.lang.reflect.Field;
36 import java.awt.PopupMenu;
37 import java.awt.MenuItem;
38 import java.awt.ItemSelectable;
39 import java.awt.event.ItemEvent;
41 import ini.trakem2.display.Display;
43 public class ProjectToolbar implements MouseListener {
45 /**A tool to select and move Displayable objects (black arrow).*/
46 public static final int SELECT = Toolbar.SPARE1;
47 /**A tool to draw freehand and then autoconvert to Bezier curves.*/
48 public static final int PENCIL = Toolbar.SPARE2;
49 /**A tool to draw/edit.*/
50 public static final int PEN = Toolbar.SPARE3;
51 /**A tool to align objects from two different layers.*/
52 public static final int ALIGN = Toolbar.SPARE4;
54 static private String startup_macros = null;
56 static private ProjectToolbar instance = null;
58 private ProjectToolbar() {}
60 /** Set macro buttons for TrakEM2 in ImageJ's toolbar */
61 static public void setProjectToolbar() {
62 if (null == instance) instance = new ProjectToolbar();
63 // check if macros are installed already
64 MacroInstaller installer = new MacroInstaller();
65 boolean toolbar_present = false;
66 try {
67 java.awt.event.ActionListener[] al = ij.Menus.getMacrosMenu().getActionListeners();
68 MacroInstaller minst = null;
69 for (int j=al.length -1; j>-1; j--) {
70 if (al[j] instanceof MacroInstaller) {
71 minst = (MacroInstaller)al[j];
72 break;
75 if (null != minst) {
76 java.lang.reflect.Field f_macroNames = MacroInstaller.class.getDeclaredField("macroNames");
77 f_macroNames.setAccessible(true);
78 Object ob = f_macroNames.get(minst);
79 if (null != ob) {
80 String[] macroNames = (String[])ob;
81 if (null == macroNames) return;
82 if (macroNames.length > 3
83 && null != macroNames[0] && 0 == macroNames[0].indexOf("Select and Transform")
84 && null != macroNames[1] && 0 == macroNames[1].indexOf("Freehand")
85 && null != macroNames[2] && 0 == macroNames[2].indexOf("Pen")
86 && null != macroNames[3] && 0 == macroNames[3].indexOf("Align")
87 ) {
88 toolbar_present = true;
92 } catch (Exception e) {
93 // the above is not thread safe, will fail many times because the Display being show is also trying to set the toolbar
94 Utils.log2("Can't check if toolbar is in place.");
95 //IJError.print(e);
96 // if it fails, toolbar_present still is false and thus will result in the macros being installed again.
99 // sort of a constructor: an embedded macro set
100 if (!toolbar_present) {
101 int tool = Toolbar.getToolId();
102 StringBuffer sb_tools = new StringBuffer();
103 sb_tools.append("macro 'Select and Transform Tool-C000L2242L2363L3494L35b5L46c6L4797L48a8L49b9L5a6aL8acaL5b6bL9bdbL5c5cLacdcLbdcd' {\ncall('ini.trakem2.utils.ProjectToolbar.toolChanged', 'SELECT');\n}\n")
104 .append("macro 'Freehand Tool-C000Lb0c0La1d1L92e2L83f3L74f4L65e5L56d6L47c7L38b8L29a9L2a2aL4a9aL1b2bL5b8bL1c1cL6c7cL0d1dL5d6dL0e0eL3e5eL0f3f' {\ncall('ini.trakem2.utils.ProjectToolbar.toolChanged', 'PENCIL');\n}\n")
105 .append("macro 'Pen Tool-C000L8080L7191L7292L6363L8383La3a3L6464L8484Lb4b4L5555L8585Lb5b5L4646L8686Lc6c6L4747Lc7c7L3838Ld8d8L4949Lc9c9L4a4aLcacaL5b5bLbbbbL5c5cLbcbcL4dcdL5e5eLbebeL5fbf' {\ncall('ini.trakem2.utils.ProjectToolbar.toolChanged', 'PEN');\n}\n")
106 .append("macro 'Align Tool-C000L50f0L4141Lf1f1L3232Le2e2L3333Le3e3L2424Ld4d4L2525Ld5d5L1616Lc6c6L0707Lb7f7L08b8Lf8f8L4949Le9e9L3a3aLeaeaL2b2bLdbdbL2c2cLdcdcL1d1dLcdcdL0e0eLbebeL0fbf' {\ncall('ini.trakem2.utils.ProjectToolbar.toolChanged', 'ALIGN');\n}\n")
109 installer.install(sb_tools.toString()); // another call to install erases the previous, so it needs all at the same time
110 Toolbar.getInstance().setTool(tool);
114 /** Called by macro tools. */ // TODO doesn't work, no clue
115 static public void toolChanged(String tool_name) {
116 //Display.toolChanged(tool_name);
119 /** Restore ImageJ's toolbar. */
120 static public void setImageJToolbar() {
121 // remove mouse listener
122 MouseListener[] ml = Toolbar.getInstance().getMouseListeners();
123 for (int i=0; i<ml.length; i++) {
124 if (ml[i].equals(instance)) {
125 Toolbar.getInstance().removeMouseListener(instance);
126 break;
129 // try to fetch the macros folder
130 // The code below does the same as:
131 // IJ.run("Install...", "install="+IJ.getDirectory("macros")+"StartupMacros.txt");
132 // but checking whether the startupmacros.txt file exists
133 if (null == startup_macros) {
134 String macros_path = ij.Menus.getMacrosPath();
135 if (null != macros_path) {
136 File f = new File(macros_path);
137 if (f.isDirectory()) {
138 String[] mf = f.list();
139 for (int i=0; i<mf.length; i++) {
140 if (mf[i].toLowerCase().equals("startupmacros.txt")) {
141 startup_macros = Utils.openTextFile(macros_path + "/" + mf[i]);
142 break;
148 // else, try to run
149 if (null == startup_macros && ImageJ.VERSION.compareTo("1.38a") >= 0) {
150 try {
151 /* // works locally, but won't on registered applets or java web start
152 Toolbar tb = Toolbar.getInstance();
153 Field f_sp = Toolbar.class.getDeclaredField("switchPopup");
154 f_sp.setAccessible(true);
155 PopupMenu popup = (PopupMenu)f_sp.get(tb);
156 MenuItem item = null;
157 for (int i=popup.getItemCount() -1; i>-1; i--) {
158 item = popup.getItem(i);
159 if (item.getLabel().equals("StartupMacros*")) {
160 break;
163 // simulate click
164 ItemEvent event = new ItemEvent((ItemSelectable)item,(int)System.currentTimeMillis(),item,1);
165 tb.itemStateChanged(event);
167 // Wayne Rasband's solution:
168 MacroInstaller mi = new MacroInstaller();
169 String path = "/macros/StartupMacros.txt";
170 //mi.installFromIJJar(path); // fails absurdly on IJ < 1.38a despite the 'if' clause
171 java.lang.reflect.Method m = MacroInstaller.class.getDeclaredMethod("installFromIJJar", new Class[]{});
172 m.invoke(mi, new Object[]{path});
173 return;
174 } catch (Exception e) {
175 //e.printStackTrace();
176 if (null != IJ.getInstance() && IJ.getInstance().quitting()) {
177 Utils.log("Failed to restore ImageJ toolbar");
181 if (null != startup_macros) {
182 new MacroInstaller().install(startup_macros);
186 static public void destroy() {
187 if (null != IJ.getInstance() && !IJ.getInstance().quitting()) {
188 setImageJToolbar();
192 static public void setTool(int t) {
193 Toolbar.getInstance().setTool(t);
196 static public int getToolId() {
197 return Toolbar.getToolId();
200 public void mousePressed(MouseEvent me) {
201 int ij_tool = Toolbar.getToolId();
202 Utils.log2("Tool: " + ij_tool);
204 public void mouseReleased(MouseEvent me) {}
205 public void mouseClicked(MouseEvent me) {}
206 public void mouseEntered(MouseEvent me) {}
207 public void mouseExited(MouseEvent me) {}
209 /** Hacks on the ij.gui.Toolbar to get the proper value, and defaults to 15 if the value is absurd. */
210 static public int getBrushSize() {
211 int brushSize = 15;
212 try {
213 java.lang.reflect.Field f = Toolbar.class.getDeclaredField("brushSize");
214 f.setAccessible(true);
215 brushSize = ((Integer)f.get(Toolbar.getInstance())).intValue();
216 if (brushSize < 1) brushSize = 15;
217 } catch (Exception e) {}
218 return brushSize;
221 /** Change the brush size by the given length increment (in pixel units). A lower limit of 1 pixel is preserved. Returns the value finally accepted for brush size.*/
222 static public int setBrushSize(int inc) {
223 int brushSize = 15;
224 try {
225 java.lang.reflect.Field f = Toolbar.class.getDeclaredField("brushSize");
226 f.setAccessible(true);
227 brushSize = ((Integer)f.get(Toolbar.getInstance())).intValue();
228 if (brushSize + inc < 1) brushSize = 1;
229 else brushSize += inc;
230 f.setInt(Toolbar.getInstance(), brushSize);
231 } catch (Exception e) {}
232 return brushSize;
235 static public void keyPressed(KeyEvent ke) {
236 switch (ke.getKeyCode()) {
237 case KeyEvent.VK_F1:
238 setTool(Toolbar.RECTANGLE);
239 break;
240 case KeyEvent.VK_F2:
241 setTool(Toolbar.POLYGON);
242 break;
243 case KeyEvent.VK_F3:
244 setTool(Toolbar.FREEROI);
245 break;
246 case KeyEvent.VK_F4:
247 setTool(Toolbar.TEXT);
248 break;
249 case KeyEvent.VK_F5:
250 setTool(Toolbar.MAGNIFIER);
251 break;
252 case KeyEvent.VK_F6:
253 setTool(Toolbar.HAND);
254 break;
255 case KeyEvent.VK_F7:
256 break;
257 case KeyEvent.VK_F8:
258 break;
259 case KeyEvent.VK_F9:
260 setTool(SELECT);
261 break;
262 case KeyEvent.VK_F10:
263 setTool(PENCIL);
264 break;
265 case KeyEvent.VK_F11:
266 setTool(PEN);
267 break;
268 case KeyEvent.VK_F12:
269 setTool(ALIGN);
270 break;