add scrollable property in ui_frame
[scilab.git] / scilab / modules / gui / src / java / org / scilab / modules / gui / bridge / tab / SwingScilabCommonPanel.java
1 /*
2  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  * Copyright (C) 2014 - Scilab Enterprises - Bruno JOFRET
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.1-en.txt
10  *
11  */
12 package org.scilab.modules.gui.bridge.tab;
13
14 import static org.scilab.modules.graphic_objects.graphicObject.GraphicObjectProperties.__GO_AUTORESIZE__;
15 import static org.scilab.modules.graphic_objects.graphicObject.GraphicObjectProperties.__GO_AXES_SIZE__;
16 import static org.scilab.modules.graphic_objects.graphicObject.GraphicObjectProperties.__GO_BORDER_OPT_PADDING__;
17 import static org.scilab.modules.graphic_objects.graphicObject.GraphicObjectProperties.__GO_CALLBACK__;
18 import static org.scilab.modules.graphic_objects.graphicObject.GraphicObjectProperties.__GO_CHILDREN__;
19 import static org.scilab.modules.graphic_objects.graphicObject.GraphicObjectProperties.__GO_EVENTHANDLER_ENABLE__;
20 import static org.scilab.modules.graphic_objects.graphicObject.GraphicObjectProperties.__GO_EVENTHANDLER_NAME__;
21 import static org.scilab.modules.graphic_objects.graphicObject.GraphicObjectProperties.__GO_GRID_OPT_GRID__;
22 import static org.scilab.modules.graphic_objects.graphicObject.GraphicObjectProperties.__GO_GRID_OPT_PADDING__;
23 import static org.scilab.modules.graphic_objects.graphicObject.GraphicObjectProperties.__GO_ID__;
24 import static org.scilab.modules.graphic_objects.graphicObject.GraphicObjectProperties.__GO_INFOBAR_VISIBLE__;
25 import static org.scilab.modules.graphic_objects.graphicObject.GraphicObjectProperties.__GO_INFO_MESSAGE__;
26 import static org.scilab.modules.graphic_objects.graphicObject.GraphicObjectProperties.__GO_LAYOUT__;
27 import static org.scilab.modules.graphic_objects.graphicObject.GraphicObjectProperties.__GO_MENUBAR_VISIBLE__;
28 import static org.scilab.modules.graphic_objects.graphicObject.GraphicObjectProperties.__GO_NAME__;
29 import static org.scilab.modules.graphic_objects.graphicObject.GraphicObjectProperties.__GO_POSITION__;
30 import static org.scilab.modules.graphic_objects.graphicObject.GraphicObjectProperties.__GO_RESIZE__;
31 import static org.scilab.modules.graphic_objects.graphicObject.GraphicObjectProperties.__GO_SIZE__;
32 import static org.scilab.modules.graphic_objects.graphicObject.GraphicObjectProperties.__GO_TOOLBAR_VISIBLE__;
33 import static org.scilab.modules.graphic_objects.graphicObject.GraphicObjectProperties.__GO_TYPE__;
34 import static org.scilab.modules.graphic_objects.graphicObject.GraphicObjectProperties.__GO_UICHECKEDMENU__;
35 import static org.scilab.modules.graphic_objects.graphicObject.GraphicObjectProperties.__GO_UICHILDMENU__;
36 import static org.scilab.modules.graphic_objects.graphicObject.GraphicObjectProperties.__GO_UIMENU__;
37 import static org.scilab.modules.graphic_objects.graphicObject.GraphicObjectProperties.__GO_UIPARENTMENU__;
38 import static org.scilab.modules.graphic_objects.graphicObject.GraphicObjectProperties.__GO_VISIBLE__;
39
40 import java.awt.BorderLayout;
41 import java.awt.Component;
42 import java.awt.Dimension;
43 import java.awt.GridBagConstraints;
44 import java.awt.GridBagLayout;
45 import java.awt.GridLayout;
46
47 import javax.swing.JLayeredPane;
48
49 import org.scilab.modules.graphic_objects.figure.Figure;
50 import org.scilab.modules.graphic_objects.figure.Figure.BarType;
51 import org.scilab.modules.graphic_objects.graphicController.GraphicController;
52 import org.scilab.modules.graphic_objects.graphicModel.GraphicModel;
53 import org.scilab.modules.graphic_objects.uicontrol.Uicontrol;
54 import org.scilab.modules.graphic_objects.utils.LayoutType;
55 import org.scilab.modules.gui.SwingView;
56 import org.scilab.modules.gui.SwingViewObject;
57 import org.scilab.modules.gui.bridge.frame.SwingScilabFrame;
58 import org.scilab.modules.gui.bridge.frame.SwingScilabScrollableFrame;
59 import org.scilab.modules.gui.bridge.window.SwingScilabWindow;
60 import org.scilab.modules.gui.events.callback.ScilabCloseCallBack;
61 import org.scilab.modules.gui.toolbar.ToolBar;
62 import org.scilab.modules.gui.utils.Position;
63 import org.scilab.modules.gui.utils.Size;
64 import org.scilab.modules.gui.utils.ToolBarBuilder;
65
66 public class SwingScilabCommonPanel {
67
68     public static final String GRAPHICS_TOOLBAR_DESCRIPTOR = System.getenv("SCI") + "/modules/gui/etc/graphics_toolbar.xml";
69
70     /**
71      * Update the tab after a modification of its properties
72      * @param property the property name
73      * @param value the property value
74      * @see org.scilab.modules.gui.SwingViewObject#update(java.lang.String, java.lang.Object)
75      */
76     protected static void update(SwingScilabPanel component, int property, Object value) {
77         String name;
78         Integer figureId;
79         switch (property) {
80             case  __GO_NAME__ :
81                 name = ((String) value);
82                 figureId = (Integer) GraphicController.getController().getProperty(component.getId(), __GO_ID__);
83                 updateTitle(component, name, figureId);
84                 break;
85             case __GO_ID__ :
86                 /* Update title */
87                 figureId = ((Integer) value);
88                 Figure localFigure = (Figure) GraphicController.getController().getObjectFromId(component.getId());
89                 name = localFigure.getName();
90                 updateTitle(component, name, figureId);
91
92                 /** Update tool bar */
93                 if (localFigure.getToolbarAsEnum() == BarType.FIGURE) {
94                     SwingScilabWindow parentWindow = SwingScilabWindow.allScilabWindows.get(component.getParentWindowId());
95                     ToolBar toolbar = ToolBarBuilder.buildToolBar(GRAPHICS_TOOLBAR_DESCRIPTOR, figureId);
96                     toolbar.setVisible(localFigure.getToolbarVisible());
97                     component.setToolBar(toolbar);
98                     parentWindow.addToolBar(toolbar);
99                 }
100
101                 /* Update callback */
102                 String closingCommand =
103                     "if (get_figure_handle(" + figureId + ") <> []) then"
104                     +      "  if (get(get_figure_handle(" + figureId + "), 'event_handler_enable') == 'on') then"
105                     +      "    execstr(get(get_figure_handle(" + figureId + "), 'event_handler')+'(" + figureId + ", -1, -1, -1000)', 'errcatch', 'm');"
106                     +      "  end;"
107                     +      "  delete(get_figure_handle(" + figureId + "));"
108                     +      "end;";
109                 component.setCallback(null);
110                 component.setCallback(ScilabCloseCallBack.create(component.getId(), closingCommand));
111                 /* Update menus callback */
112                 Integer[] children = (Integer[]) GraphicController.getController().getProperty(component.getId(), __GO_CHILDREN__);
113                 updateChildrenCallbacks(children, figureId);
114                 break;
115             case __GO_SIZE__ :
116                 Integer[] size = (Integer[]) value;
117                 SwingScilabWindow figure = SwingScilabWindow.allScilabWindows.get(component.getParentWindowId());
118                 Size oldFigureSize = figure.getDims();
119                 figure.setDims(new Size(size[0], size[1]));
120                 int deltaFigureX = size[0] - oldFigureSize.getWidth();
121                 int deltaFigureY = size[1] - oldFigureSize.getHeight();
122                 if ( oldFigureSize.getWidth() != 0 && oldFigureSize.getHeight() != 0
123                         && ((oldFigureSize.getWidth() != size[0]) || (oldFigureSize.getHeight() != size[1]))
124                         && ((Boolean) GraphicController.getController().getProperty(component.getId(), __GO_AUTORESIZE__))
125                    ) {
126                     Integer[] axesSize = (Integer[]) GraphicController.getController().getProperty(component.getId(), __GO_AXES_SIZE__);
127                     Integer[] newAxesSize = {axesSize[0] + deltaFigureX, axesSize[1] + deltaFigureY};
128                     GraphicController.getController().setProperty(component.getId(), __GO_AXES_SIZE__, newAxesSize);
129                 }
130                 break;
131             case __GO_POSITION__ :
132                 Integer[] position = (Integer[]) value;
133                 SwingScilabWindow.allScilabWindows.get(component.getParentWindowId()).setPosition(new Position(position[0], position[1]));
134                 break;
135             case __GO_AXES_SIZE__ :
136                 Integer[] axesSize = (Integer[]) value;
137                 Dimension oldAxesSize = component.getContentPane().getSize();
138                 if ( oldAxesSize.getWidth() != 0 && oldAxesSize.getHeight() != 0
139                         && ((oldAxesSize.getWidth() != axesSize[0]) || (oldAxesSize.getHeight() != axesSize[1]))
140                         && ((Boolean) GraphicController.getController().getProperty(component.getId(), __GO_AUTORESIZE__))
141                    ) {
142                     // TODO manage tabs when there are docked (do not change the window size if more than one tab docked)
143                     int deltaX = axesSize[0] - (int) oldAxesSize.getWidth();
144                     int deltaY = axesSize[1] - (int) oldAxesSize.getHeight();
145                     Size parentWindowSize = SwingScilabWindow.allScilabWindows.get(component.getParentWindowId()).getDims();
146                     SwingScilabWindow.allScilabWindows.get(component.getParentWindowId()).setDims(
147                         new Size(parentWindowSize.getWidth() + deltaX, parentWindowSize.getHeight() + deltaY));
148                     Integer figureSize[] = {parentWindowSize.getWidth() + deltaX, parentWindowSize.getHeight() + deltaY};
149                     GraphicController.getController().setProperty(component.getId(), __GO_SIZE__, figureSize);
150                 }
151                 break;
152             case __GO_INFO_MESSAGE__ :
153                 if (component.getInfoBar() != null) {
154                     component.getInfoBar().setText((String) value);
155                 }
156                 break;
157             case __GO_EVENTHANDLER_ENABLE__ :
158                 Boolean enabled = (Boolean) GraphicController.getController().getProperty(component.getId(), __GO_EVENTHANDLER_ENABLE__);
159                 component. setEventHandlerEnabled(enabled);
160                 break;
161             case __GO_EVENTHANDLER_NAME__ :
162                 String eventHandlerName = (String) GraphicController.getController().getProperty(component.getId(), __GO_EVENTHANDLER_NAME__);
163                 component.setEventHandler(eventHandlerName);
164                 break;
165             case __GO_VISIBLE__ :
166                 component.getContentPane().setVisible((Boolean) value);
167                 if (component.getParentWindow().getNbDockedObjects() == 1) {
168                     component.getParentWindow().setVisible((Boolean) value);
169                 }
170                 break;
171             case __GO_INFOBAR_VISIBLE__ :
172                 component.getInfoBar().setVisible((Boolean) value);
173                 break;
174             case __GO_TOOLBAR_VISIBLE__ :
175                 component.getToolBar().setVisible((Boolean) value);
176                 break;
177             case __GO_MENUBAR_VISIBLE__ :
178                 component.getMenuBar().setVisible((Boolean) value);
179                 break;
180             case __GO_RESIZE__ :
181                 component.getParentWindow().setResizable((Boolean) value);
182                 break;
183             case __GO_LAYOUT__ :
184                 LayoutType newLayout = LayoutType.intToEnum((Integer) value);
185                 switch (newLayout) {
186                     case BORDER : {
187                         Integer[] padding = (Integer[]) GraphicController.getController().getProperty(component.getId(), __GO_BORDER_OPT_PADDING__);
188                         component.getWidgetPane().setLayout(new BorderLayout(padding[0], padding[1]));
189                         component.getWidgetPane().setLayout(new BorderLayout());
190                         break;
191                     }
192                     case GRIDBAG : {
193                         component.getWidgetPane().setLayout(new GridBagLayout());
194                         break;
195                     }
196                     case GRID : {
197                         Integer[] padding = (Integer[]) GraphicController.getController().getProperty(component.getId(), __GO_GRID_OPT_PADDING__);
198                         Integer[] grid = (Integer[]) GraphicController.getController().getProperty(component.getId(), __GO_GRID_OPT_GRID__);
199                         if (grid[0] == 0 && grid[1] == 0) {
200                             grid[0] = 1;
201                         }
202                         component.getWidgetPane().setLayout(new GridLayout(grid[0], grid[1], padding[0], padding[1]));
203                         break;
204                     }
205                     case NONE :
206                     default:
207                         component.getWidgetPane().setLayout(null);
208                         break;
209                 }
210                 break;
211             case __GO_GRID_OPT_PADDING__ :
212             case __GO_GRID_OPT_GRID__ : {
213                 Integer layout = (Integer) GraphicController.getController().getProperty(component.getId(), __GO_LAYOUT__);
214                 LayoutType layoutType = LayoutType.intToEnum(layout);
215
216                 if (layoutType != LayoutType.GRID) {
217                     break;
218                 }
219
220                 Integer[] padding = (Integer[]) GraphicController.getController().getProperty(component.getId(), __GO_GRID_OPT_PADDING__);
221                 Integer[] grid = (Integer[]) GraphicController.getController().getProperty(component.getId(), __GO_GRID_OPT_GRID__);
222                 if (grid[0] == 0 && grid[1] == 0) {
223                     grid[0] = 1;
224                 }
225                 component.getWidgetPane().setLayout(new GridLayout(grid[0], grid[1], padding[0], padding[1]));
226                 break;
227             }
228             case __GO_BORDER_OPT_PADDING__ : {
229                 Integer layout = (Integer) GraphicController.getController().getProperty(component.getId(), __GO_LAYOUT__);
230                 LayoutType layoutType = LayoutType.intToEnum(layout);
231
232                 if (layoutType != LayoutType.BORDER) {
233                     break;
234                 }
235
236                 Integer[] padding = (Integer[]) GraphicController.getController().getProperty(component.getId(), __GO_BORDER_OPT_PADDING__);
237                 component.getWidgetPane().setLayout(new BorderLayout(padding[0], padding[1]));
238                 component.getWidgetPane().setLayout(new BorderLayout());
239             }
240         }
241     }
242
243     /**
244      * Update the title of the Tab
245      * @param figureName figure_name property
246      * @param figureId figure_id property
247      */
248     private static void updateTitle(SwingScilabPanel component, String figureName, Integer figureId) {
249         if ((figureName != null) && (figureId != null)) {
250             String figureTitle = figureName.replaceFirst("%d", figureId.toString());
251             component.setName(figureTitle);
252         }
253     }
254
255     /**
256      * Update the menus callbacks when they are linked to the figure ID
257      * @param children the children UID
258      * @param parentFigureId the figure ID
259      */
260     private static void updateChildrenCallbacks(Integer[] children, int parentFigureId) {
261         for (int kChild = 0; kChild < children.length; kChild++) {
262             Integer childType = (Integer) GraphicController.getController().getProperty(children[kChild], __GO_TYPE__);
263             if (childType != null && (
264                         childType == __GO_UIMENU__
265                         || childType == __GO_UIPARENTMENU__
266                         || childType == __GO_UICHILDMENU__
267                         || childType == __GO_UICHECKEDMENU__)) {
268                 String cb = (String) GraphicController.getController().getProperty(children[kChild], __GO_CALLBACK__);
269                 SwingView.getFromId(children[kChild]).update(__GO_CALLBACK__, replaceFigureID(cb, parentFigureId));
270                 Integer[] menuChildren = (Integer[]) GraphicController.getController().getProperty(children[kChild], __GO_CHILDREN__);
271                 updateChildrenCallbacks(menuChildren, parentFigureId);
272             }
273         }
274     }
275
276     /**
277      * Replace pattern [SCILAB_FIGURE_ID] by the figure index
278      * @param initialString string read in XML file
279      * @param parentFigureId the figure ID
280      * @return callback string
281      */
282     private static String replaceFigureID(String initialString, Integer parentFigureId) {
283         return initialString.replaceAll("\\[SCILAB_FIGURE_ID\\]", Integer.toString(parentFigureId));
284     }
285
286     /**
287      * Add a SwingViewObject (from SwingView.java) to container and returns its index
288      * @param member the member to add
289      */
290     protected static void addMember(SwingScilabPanel component, SwingViewObject member) {
291         //member.get
292         Uicontrol uicontrol = (Uicontrol) GraphicModel.getModel().getObjectFromId(member.getId());
293         if (component.getWidgetPane().getLayout() instanceof BorderLayout) {
294             switch (uicontrol.getBorderPositionAsEnum()) {
295                 case BOTTOM:
296                     component.getWidgetPane().add((Component) member, BorderLayout.SOUTH);
297                     break;
298                 case TOP:
299                     component.getWidgetPane().add((Component) member, BorderLayout.NORTH);
300                     break;
301                 case LEFT:
302                     component.getWidgetPane().add((Component) member, BorderLayout.WEST);
303                     break;
304                 case RIGHT:
305                     component.getWidgetPane().add((Component) member, BorderLayout.EAST);
306                     break;
307                 case CENTER:
308                     component.getWidgetPane().add((Component) member, BorderLayout.CENTER);
309                     break;
310                 default:
311                     break;
312             }
313         } else if (component.getWidgetPane().getLayout() instanceof GridBagLayout) {
314             GridBagConstraints constraints = new GridBagConstraints();
315
316             // Grid
317             Integer[] grid = uicontrol.getGridBagGrid();
318             constraints.gridx = grid[0];
319             constraints.gridy = grid[1];
320             constraints.gridwidth = grid[2];
321             constraints.gridheight = grid[3];
322
323             // Weight
324             Double[] weight = uicontrol.getGridBagWeight();
325             constraints.weightx = weight[0];
326             constraints.weighty = weight[1];
327
328             // Anchor
329             switch (uicontrol.getGridBagAnchorAsEnum()) {
330                 case LEFT :
331                     constraints.anchor = GridBagConstraints.EAST;
332                     break;
333                 case UPPER :
334                     constraints.anchor = GridBagConstraints.NORTH;
335                     break;
336                 case LOWER:
337                     constraints.anchor = GridBagConstraints.SOUTH;
338                     break;
339                 case LOWER_LEFT:
340                     constraints.anchor = GridBagConstraints.SOUTHEAST;
341                     break;
342                 case LOWER_RIGHT:
343                     constraints.anchor = GridBagConstraints.SOUTHWEST;
344                     break;
345                 case RIGHT:
346                     constraints.anchor = GridBagConstraints.WEST;
347                     break;
348                 case UPPER_LEFT:
349                     constraints.anchor = GridBagConstraints.NORTHEAST;
350                     break;
351                 case UPPER_RIGHT:
352                     constraints.anchor = GridBagConstraints.NORTHWEST;
353                     break;
354                 case CENTER :
355                 default :
356                     constraints.anchor = GridBagConstraints.CENTER;
357                     break;
358             }
359
360             // Fill
361             switch (uicontrol.getGridBagFillAsEnum()) {
362                 case BOTH :
363                     constraints.fill = GridBagConstraints.BOTH;
364                     break;
365                 case HORIZONTAL:
366                     constraints.fill = GridBagConstraints.HORIZONTAL;
367                     break;
368                 case VERTICAL:
369                     constraints.fill = GridBagConstraints.VERTICAL;
370                     break;
371                 case NONE:
372                 default:
373                     constraints.fill = GridBagConstraints.NONE;
374                     break;
375             }
376
377             // Insets
378             // TODO : add Insets
379
380             // Padding
381             Integer[] padding = uicontrol.getGridBagPadding();
382             constraints.ipadx = padding[0];
383             constraints.ipady = padding[1];
384
385             component.getWidgetPane().add((Component) member, constraints);
386             component.getWidgetPane().revalidate();
387         } else {
388             if (member instanceof SwingScilabScrollableFrame || member instanceof SwingScilabFrame) {
389                 component.getWidgetPane().add((Component) member, JLayeredPane.FRAME_CONTENT_LAYER);
390             } else {
391                 component.getWidgetPane().add((Component) member, JLayeredPane.DEFAULT_LAYER + 1);
392             }
393         }
394     }
395
396     protected static void  removeMember(SwingScilabPanel component, SwingViewObject member) {
397         component.getWidgetPane().remove((Component) member);
398     }
399 }