236cd95cadf6e463e662f2708ee2cefa32a415eb
[scilab.git] / scilab / modules / xcos / src / java / org / scilab / modules / xcos / palette / XcosPaletteManager.java
1 /*
2  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  * Copyright (C) 2009 - DIGITEO - Antoine ELIAS
4  *
5  * This file must be used under the terms of the CeCILL.
6  * This source file is licensed as described in the file COPYING, which
7  * you should have received as part of this distribution.  The terms
8  * are also available at
9  * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
10  *
11  */
12
13 package org.scilab.modules.xcos.palette;
14
15 import java.awt.Dimension;
16 import java.io.File;
17 import java.util.HashMap;
18 import java.util.Map;
19
20 import javax.swing.ImageIcon;
21 import javax.swing.JScrollPane;
22 import javax.swing.JSplitPane;
23 import javax.swing.JTree;
24 import javax.swing.event.TreeSelectionEvent;
25 import javax.swing.event.TreeSelectionListener;
26 import javax.swing.tree.DefaultMutableTreeNode;
27 import javax.swing.tree.DefaultTreeModel;
28 import javax.swing.tree.TreeModel;
29 import javax.swing.tree.TreeSelectionModel;
30
31 import org.scilab.modules.gui.bridge.tab.SwingScilabTab;
32 import org.scilab.modules.gui.menu.Menu;
33 import org.scilab.modules.gui.menu.ScilabMenu;
34 import org.scilab.modules.gui.menubar.MenuBar;
35 import org.scilab.modules.gui.menubar.ScilabMenuBar;
36 import org.scilab.modules.gui.tab.ScilabTab;
37 import org.scilab.modules.gui.tab.Tab;
38 import org.scilab.modules.gui.textbox.ScilabTextBox;
39 import org.scilab.modules.gui.toolbar.ScilabToolBar;
40 import org.scilab.modules.gui.toolbar.ToolBar;
41 import org.scilab.modules.gui.utils.Size;
42 import org.scilab.modules.gui.window.ScilabWindow;
43 import org.scilab.modules.gui.window.Window;
44 import org.scilab.modules.xcos.actions.ClosePalettesAction;
45 import org.scilab.modules.xcos.actions.NewDiagramAction;
46 import org.scilab.modules.xcos.actions.OpenAction;
47 import org.scilab.modules.xcos.block.BasicBlock;
48 import org.scilab.modules.xcos.block.TextBlock;
49 import org.scilab.modules.xcos.io.BlockReader;
50 import org.scilab.modules.xcos.utils.XcosMessages;
51
52 /**
53  * Manage all the Block Palettes.
54  */
55 public final class XcosPaletteManager {
56
57     private static Thread paletteThread;
58     private static boolean paletteLoadStarted;
59     private static Tab palettes;
60
61     /**
62      * Instantiate all the known names (default configuration)
63      */
64     private static final PaletteStringDescriptor[] allPalettesStringDescriptor = {
65             /** COMMONLY USED BLOCKS palette */
66             new PaletteStringDescriptor(XcosMessages.COMMONUSED_PAL,
67                     new String[] { "ANDBLK", "BIGSOM_f", "CMSCOPE", "CONST_m",
68                             "CONVERT", "CSCOPXY", "DEMUX", "DOLLAR_f",
69                             "INTEGRAL_f", "IN_f", "LOGICAL_OP", "MUX",
70                             "NRMSOM_f", "OUT_f", "PRODUCT", "RELATIONALOP",
71                             "SATURATION", "SWITCH2_m", "TEXT_f" }),
72
73             /** CONTINUOUS palette */
74             new PaletteStringDescriptor(XcosMessages.CONTINUOUS_PAL,
75                     new String[] { "CLINDUMMY_f", "CLR", "CLSS", "DERIV",
76                             "INTEGRAL_f", "INTEGRAL_m", "PID", "TCLSS",
77                             "TIME_DELAY", "VARIABLE_DELAY", "PDE" }),
78
79             /** DISCONTINUOUS palette */
80             new PaletteStringDescriptor(XcosMessages.DISCONTINUOUS_PAL,
81                     new String[] { "BACKLASH", "DEADBAND", "DELAYV_f",
82                             "HYSTHERESIS", "RATELIMITER", "QUANT_f",
83                             "SATURATION" }),
84
85             /** DISCRETE palette */
86             new PaletteStringDescriptor(XcosMessages.DISCRETE_PAL,
87                     new String[] { "AUTOMAT", "DELAYV_f", "DELAY_f", "DLR",
88                             "DLRADAPT_f", "DLSS", "DOLLAR_f", "SAMPHOLD_m",
89                             "TCLSS" }),
90
91             /** LOOKUP TABLES palette */
92             new PaletteStringDescriptor(XcosMessages.LOOKUPTABLES_PAL,
93                     new String[] { "INTRP2BLK_f", "INTRPLBLK_f", "LOOKUP_f" }),
94
95             /** EVENTS palette */
96             new PaletteStringDescriptor(XcosMessages.EVENTS_PAL, new String[] {
97                     "ANDBLK", "ANDLOG_f", "CEVENTSCOPE", "CLKFROM", "CLKGOTO",
98                     "CLKGotoTagVisibility", "CLKOUTV_f", "CLKSOMV_f",
99                     "CLOCK_c", "EDGE_TRIGGER", "ENDBLK", "END_c", "ESELECT_f",
100                     "EVTDLY_c", "EVTGEN_f", "EVTVARDLY", "Extract_Activation",
101                     "HALT_f", "IFTHEL_f", "M_freq", "MCLOCK_f", "MFCLCK_f",
102                     "REGISTER", "SampleCLK", "freq_div" }),
103
104             /** MATH OPERATIONS palette */
105             new PaletteStringDescriptor(XcosMessages.MATHSOPS_PAL,
106                     new String[] { "ABS_VALUE", "BIGSOM_f", "COSBLK_f",
107                             "EXPBLK_m", "GAINBLK_f", "INVBLK", "LOGBLK_f",
108                             "MATMAGPHI", "MATZREIM", "MAXMIN", "MAX_f",
109                             "MIN_f", "POWBLK_f", "PRODUCT", "PROD_f", "SIGNUM",
110                             "SINBLK_f", "SQRT", "SUMMATION", "SUM_f",
111                             "TANBLK_f", "TrigFun" }),
112
113             /** MATRIX palette */
114             new PaletteStringDescriptor(XcosMessages.MATRIX_PAL, new String[] {
115                     "CUMSUM", "EXTRACT", "EXTTRI", "MATBKSL", "MATCATH",
116                     "MATCATV", "MATDET", "MATDIAG", "MATDIV", "MATEIG",
117                     "MATEXPM", "MATINV", "MATLU", "MATMAGPHI", "MATMUL",
118                     "MATPINV", "MATRESH", "MATSING", "MATSUM", "MATTRAN",
119                     "MATZCONJ", "MATZREIM", "RICC", "ROOTCOEF", "SQRT",
120                     "SUBMAT" }),
121
122             /** ELECTRICAL palette */
123             new PaletteStringDescriptor(XcosMessages.ELECTRICAL_PAL,
124                     new String[] { "CCS", "CVS", "Capacitor",
125                             "ConstantVoltage", "CurrentSensor", "Diode",
126                             "Ground", "Gyrator", "IdealTransformer",
127                             "Inductor", "NMOS", "NPN", "OpAmp", "PMOS", "PNP",
128                             "PotentialSensor", "Resistor", "SineVoltage",
129                             "Switch", "VVsourceAC", "VariableResistor",
130                             "VoltageSensor", "VsourceAC" }),
131
132             /** INTEGER palette */
133             new PaletteStringDescriptor(XcosMessages.INTEGER_PAL, new String[] {
134                     "BITCLEAR", "BITSET", "CONVERT", "DFLIPFLOP", "DLATCH",
135                     "EXTRACTBITS", "INTMUL", "JKFLIPFLOP", "LOGIC", "SHIFT",
136                     "SRFLIPFLOP" }),
137
138             /** PORT ACTION palette */
139             new PaletteStringDescriptor(XcosMessages.PORTACTION_PAL,
140                     new String[] { "CLKINV_f", "CLKOUTV_f", "IN_f", "INIMPL_f",
141                             "OUTIMPL_f", "OUT_f", "SUPER_f" }),
142
143             /** THRESHOLD palette */
144             new PaletteStringDescriptor(XcosMessages.THRESHOLD_PAL,
145                     new String[] { "GENERAL_f", "NEGTOPOS_f", "POSTONEG_f",
146                             "ZCROSS_f" }),
147
148             /** Signal Routing palette */
149             new PaletteStringDescriptor(XcosMessages.SIGNALROUTING_PAL,
150                     new String[] { "DEMUX", "EXTRACTOR", "FROM", "FROMMO",
151                             "GOTO", "GOTOMO", "GotoTagVisibility",
152                             "GotoTagVisibilityMO", "ISELECT_m", "MUX",
153                             "M_SWITCH", "NRMSOM_f", "RELAY_f", "SELECT_m",
154                             "SWITCH2_m", "SWITCH_f" }),
155
156             /** SIGNAL PROCESSING palette */
157             new PaletteStringDescriptor(XcosMessages.SIGNALPROCESSING_PAL,
158                     new String[] { "QUANT_f", "SAMPHOLD_m" }),
159
160             /** IMPLICIT palette */
161             new PaletteStringDescriptor(XcosMessages.IMPLICIT_PAL,
162                     new String[] { "CONSTRAINT_f", "DIFF_f" }),
163
164             /** ANNOTATIONS palette */
165             new PaletteStringDescriptor(XcosMessages.ANNOTATIONS_PAL,
166                     new String[] { "TEXT_f" }),
167
168             /** SINKS palette */
169             new PaletteStringDescriptor(XcosMessages.SINKS_PAL, new String[] {
170                     "AFFICH_m", "CANIMXY", "CANIMXY3D", "CFSCOPE", "CLKOUTV_f",
171                     "CMAT3D", "CMATVIEW", "CMSCOPE", "CSCOPE", "CSCOPXY",
172                     "CSCOPXY3D", "ENDBLK", "END_c", "HALT_f", "OUTIMPL_f",
173                     "OUT_f", "TOWS_c", "TRASH_f", "WFILE_f", "WRITEAU_f",
174                     "WRITEC_f" }),
175
176             /** SOURCES palette */
177             new PaletteStringDescriptor(XcosMessages.SOURCES_PAL, new String[] {
178                     "CLKINV_f", "CLOCK_c", "CONST_m", "CURV_f", "Counter",
179                     "FROMWSB", "GENSIN_f", "GENSQR_f", "INIMPL_f", "IN_f",
180                     "Modulo_Count", "RAMP", "RAND_m", "READAU_f", "READC_f",
181                     "RFILE_f", "SAWTOOTH_f", "STEP_FUNCTION", "SampleCLK",
182                     "Sigbuilder", "TIME_f", "TKSCALE" }),
183
184             /** THERMO-HYDRAULICS palette */
185             new PaletteStringDescriptor(XcosMessages.THERMOHYDRAULICS_PAL,
186                     new String[] { "Bache", "PerteDP", "PuitsP", "SourceP",
187                             "VanneReglante" }),
188
189             /** DEMO-BLOCKS palette */
190             new PaletteStringDescriptor(XcosMessages.DEMOBLOCKS_PAL,
191                     new String[] { "BOUNCE", "BOUNCEXY", "BPLATFORM" }),
192
193             /** USER-DEFINED FUNCTIONS palette */
194             new PaletteStringDescriptor(XcosMessages.USERDEFINEDFUNCTIONS_PAL,
195                     new String[] { "CBLOCK", "EXPRESSION", "MBLOCK", "PDE",
196                             "SUPER_f", "c_block", "fortran_block",
197                             "generic_block3", "scifunc_block_m" }) };
198
199     /**
200      * Represent a palette configuration values
201      */
202     private static class PaletteStringDescriptor {
203         public String Name;
204         public String[] Components;
205
206         public PaletteStringDescriptor(String name, String[] components) {
207             Name = name;
208             Components = components;
209         }
210     }
211
212     /**
213      * Represent the instanciation of the configurations values
214      */
215     private static class PaletteDescriptor {
216         public String Name;
217         public PaletteData[] Components;
218
219         public PaletteDescriptor(String name, PaletteData[] components) {
220             Name = name;
221             Components = components;
222         }
223
224         public String toString() {
225             return Name;
226         }
227     }
228
229     /**
230      * Represent any block data
231      */
232     private static class PaletteData {
233         public String Name;
234         public ImageIcon Icon;
235
236         /**
237          * Any PaletteBlock data (arguments of the
238          * org.scilab.modules.xcos.palette.XcosPalette#addTemplate)
239          * 
240          * @param name
241          *            The name of the block
242          * @param icon
243          *            The icon of the block
244          * @param block
245          *            Extracted from PATH/BlockName.hf5
246          */
247         public PaletteData(String name, ImageIcon icon) {
248             Name = name;
249             Icon = icon;
250         }
251     }
252
253     /** Palette creation */
254     static {
255         paletteThread = new Thread() {
256             public void run() {
257
258                 final JSplitPane allpalettes = new JSplitPane(
259                         JSplitPane.HORIZONTAL_SPLIT);
260                 final XcosPalette rootPalette = new XcosPalette(
261                         XcosMessages.PALETTES);
262                 DefaultMutableTreeNode rootNode = new DefaultMutableTreeNode(
263                         rootPalette);
264                 TreeModel paletteTreeModel = new DefaultTreeModel(rootNode);
265                 final JTree paletteTree = new JTree(paletteTreeModel);
266
267                 allpalettes.setRightComponent(rootPalette);
268                 allpalettes.setLeftComponent(new JScrollPane(paletteTree));
269
270                 paletteTree.getSelectionModel().setSelectionMode(
271                         TreeSelectionModel.SINGLE_TREE_SELECTION);
272                 paletteTree
273                         .addTreeSelectionListener(new TreeSelectionListener() {
274
275                             public void valueChanged(TreeSelectionEvent tree) {
276                                 DefaultMutableTreeNode node = (DefaultMutableTreeNode) paletteTree
277                                         .getLastSelectedPathComponent();
278
279                                 if (node == null)
280                                     // Nothing is selected.
281                                     return;
282
283                                 Dimension size = allpalettes.getLeftComponent()
284                                         .getSize();
285                                 allpalettes.getLeftComponent()
286                                         .setPreferredSize(size);
287                                 XcosPalette nodeInfo = (XcosPalette) node
288                                         .getUserObject();
289                                 allpalettes.setRightComponent(nodeInfo);
290                             }
291
292                         });
293                 // Add a default Java bloc in HashMap
294                 ((SwingScilabTab) palettes.getAsSimpleTab())
295                         .setContentPane(allpalettes);
296
297                 allpalettes.setVisible(false);
298                 palettes.setVisible(true);
299
300                 for (PaletteStringDescriptor paletteStringDescriptor : allPalettesStringDescriptor) {
301                     /* Doesn't perform UI update */
302                     PaletteDescriptor currentDescriptor = new PaletteDescriptor(
303                             paletteStringDescriptor.Name,
304                             createPaletteData(paletteStringDescriptor.Components));
305
306                     /* Perform UI update */
307                     XcosPalette xcosPalette = new XcosPalette(
308                             paletteStringDescriptor.Name);
309                     for (PaletteData iter : currentDescriptor.Components) {
310                         xcosPalette.addTemplate(iter.Name, iter.Icon);
311                     }
312                     rootNode.add(new DefaultMutableTreeNode(xcosPalette));
313                 }
314
315                 paletteLoadStarted = true;
316                 palettes.getAsSimpleTab().getInfoBar().setText(
317                         XcosMessages.EMPTY_INFO);
318
319                 /* UI Layout specific operations */
320                 paletteTree.expandRow(0);
321                 allpalettes.getLeftComponent().setMinimumSize(
322                         paletteTree.getPreferredSize());
323                 paletteTree.setSelectionRow(1);
324                 paletteTree.setRootVisible(false);
325                 allpalettes.setContinuousLayout(true);
326                 allpalettes.setVisible(true);
327             }
328         };
329     }
330
331     private XcosPaletteManager() {
332     }
333
334     public static Tab loadPalette() {
335         synchronized (paletteThread) {
336             paletteThread.notifyAll();
337         }
338         if (paletteLoadStarted == false) {
339             createPaletteWindow();
340             palettes.getAsSimpleTab().getInfoBar().setText(
341                     XcosMessages.LOADING_PALETTES);
342             paletteThread.start();
343         }
344         return palettes;
345     }
346
347     private static PaletteData[] createPaletteData(String[] blocksNames) {
348
349         PaletteData[] xcosPalette = new PaletteData[blocksNames.length];
350
351         final String palImagesPath = System.getenv("SCI")
352                 + "/modules/xcos/images/palettes/";
353
354         // BasicBlock theBloc = null;
355
356         for (int kBlock = 0; kBlock < blocksNames.length; kBlock++) {
357             xcosPalette[kBlock] = new PaletteData(blocksNames[kBlock],
358                     new ImageIcon(palImagesPath + blocksNames[kBlock] + ".jpg"));
359
360         }
361
362         return xcosPalette;
363     }
364
365     public static Tab getPalettes() {
366         return palettes;
367     }
368
369     private static void createPaletteWindow() {
370         paletteLoadStarted = false;
371         // Add a default Java bloc in HashMap
372         // Xcos.getAllBlocks().put("TEXT_f", new TextBlock("TEXT_f"));
373
374         Window palWin = ScilabWindow.createWindow();
375         palWin.setDims(new Size(700, 600));
376         palWin.setVisible(true);
377         palettes = ScilabTab.createTab(XcosMessages.PALETTE_BROWSER);
378
379         palettes.setCallback(new ClosePalettesAction(null));
380
381         /** Create the menubar */
382         MenuBar palMenuBar = ScilabMenuBar.createMenuBar();
383         palettes.addMenuBar(palMenuBar);
384
385         Menu palMenu = ScilabMenu.createMenu();
386         palMenu.setText(XcosMessages.PALETTES);
387         palMenu.setMnemonic('P');
388         palMenuBar.add(palMenu);
389
390         palMenu.add(ClosePalettesAction.createMenu(null));
391
392         /** Create the toolbar */
393         ToolBar palToolbar = ScilabToolBar.createToolBar();
394         palettes.addToolBar(palToolbar);
395         palToolbar.add(NewDiagramAction.createButton(null));
396         palToolbar.add(OpenAction.createButton(null));
397
398         /** Create the infobar */
399         palettes.getAsSimpleTab().setInfoBar(ScilabTextBox.createTextBox());
400
401         palWin.addTab(palettes);
402     }
403
404     public static boolean isVisible() {
405         if (palettes != null && palettes.isVisible() == true) {
406             return true;
407         }
408         return false;
409     }
410 }