enable/disable a tab children frame, enable/disable tab title to show its state
[scilab.git] / scilab / modules / gui / src / java / org / scilab / modules / gui / bridge / frame / SwingScilabScrollableFrame.java
1 /*
2  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  * Copyright (C) 2007 - INRIA - Vincent Couvert
4  * Copyright (C) 2007 - INRIA - Marouane BEN JELLOUL
5  *
6  * This file must be used under the terms of the CeCILL.
7  * This source file is licensed as described in the file COPYING, which
8  * you should have received as part of this distribution.  The terms
9  * are also available at
10  * http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt
11  *
12  */
13
14 package org.scilab.modules.gui.bridge.frame;
15
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_CHILDREN__;
18 import static org.scilab.modules.graphic_objects.graphicObject.GraphicObjectProperties.__GO_GRID_OPT_GRID__;
19 import static org.scilab.modules.graphic_objects.graphicObject.GraphicObjectProperties.__GO_GRID_OPT_PADDING__;
20 import static org.scilab.modules.graphic_objects.graphicObject.GraphicObjectProperties.__GO_LAYOUT__;
21 import static org.scilab.modules.graphic_objects.graphicObject.GraphicObjectProperties.__GO_TAG__;
22 import static org.scilab.modules.graphic_objects.graphicObject.GraphicObjectProperties.__GO_UI_ENABLE__;
23 import static org.scilab.modules.graphic_objects.graphicObject.GraphicObjectProperties.__GO_UI_FRAME_BORDER__;
24 import static org.scilab.modules.graphic_objects.graphicObject.GraphicObjectProperties.__GO_UI_STRING__;
25 import static org.scilab.modules.graphic_objects.graphicObject.GraphicObjectProperties.__GO_VISIBLE__;
26
27 import java.awt.BorderLayout;
28 import java.awt.Color;
29 import java.awt.Component;
30 import java.awt.Container;
31 import java.awt.Dimension;
32 import java.awt.GridBagConstraints;
33 import java.awt.GridBagLayout;
34 import java.awt.GridLayout;
35 import java.awt.Insets;
36 import java.awt.LayoutManager;
37
38 import javax.swing.JPanel;
39 import javax.swing.JScrollPane;
40 import javax.swing.ScrollPaneLayout;
41 import javax.swing.SwingUtilities;
42 import javax.swing.UIManager;
43 import javax.swing.border.Border;
44
45 import org.scilab.modules.graphic_objects.graphicController.GraphicController;
46 import org.scilab.modules.graphic_objects.graphicModel.GraphicModel;
47 import org.scilab.modules.graphic_objects.uicontrol.Uicontrol;
48 import org.scilab.modules.graphic_objects.utils.LayoutType;
49 import org.scilab.modules.gui.SwingView;
50 import org.scilab.modules.gui.SwingViewObject;
51 import org.scilab.modules.gui.SwingViewWidget;
52 import org.scilab.modules.gui.bridge.tab.SwingScilabPanel;
53 import org.scilab.modules.gui.bridge.tab.SwingScilabTabGroup;
54 import org.scilab.modules.gui.bridge.textbox.SwingScilabTextBox;
55 import org.scilab.modules.gui.bridge.window.SwingScilabWindow;
56 import org.scilab.modules.gui.dockable.Dockable;
57 import org.scilab.modules.gui.events.callback.CommonCallBack;
58 import org.scilab.modules.gui.frame.SimpleFrame;
59 import org.scilab.modules.gui.menubar.MenuBar;
60 import org.scilab.modules.gui.textbox.TextBox;
61 import org.scilab.modules.gui.toolbar.ToolBar;
62 import org.scilab.modules.gui.utils.BorderConvertor;
63 import org.scilab.modules.gui.utils.Position;
64 import org.scilab.modules.gui.utils.PositionConverter;
65 import org.scilab.modules.gui.utils.ScilabRelief;
66 import org.scilab.modules.gui.utils.Size;
67
68 /**
69  * Swing implementation for Scilab frames in GUI
70  * @author Vincent COUVERT
71  * @author Marouane BEN JELLOUL
72  */
73 public class SwingScilabScrollableFrame extends JScrollPane implements SwingViewObject, SimpleFrame {
74
75     private static final long serialVersionUID = -7401084975837285447L;
76
77     private Integer uid;
78     private JPanel panel = new JPanel();
79
80     private Border defaultBorder = null;
81
82     /**
83      * Constructor
84      */
85     public SwingScilabScrollableFrame() {
86         super();
87         setViewportView(panel);
88         panel.setLayout(null);
89         setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
90         setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
91     }
92
93     public JPanel getPanel() {
94         return panel;
95     }
96     /**
97      * Draws a Swing Scilab frame
98      * @see org.scilab.modules.gui.UIElement#draw()
99      */
100     public void draw() {
101         this.setVisible(true);
102         this.doLayout();
103     }
104
105     /**
106      * Gets the dimensions (width and height) of a swing Scilab frame
107      * @return the dimension of the frame
108      * @see org.scilab.modules.gui.UIElement#getDims()
109      */
110     public Size getDims() {
111         return new Size(this.getSize().width, this.getSize().height);
112     }
113
114     /**
115      * Gets the position (X-coordinate and Y-coordinate) of a swing Scilab frame
116      * @return the position of the frame
117      * @see org.scilab.modules.gui.UIElement#getPosition()
118      */
119     public Position getPosition() {
120         return PositionConverter.javaToScilab(getLocation(), getSize(), getParent());
121     }
122
123     /**
124      * Sets the dimensions (width and height) of a swing Scilab frame
125      * @param newSize the size we want to set to the frame
126      * @see org.scilab.modules.gui.UIElement#setDims(org.scilab.modules.gui.utils.Size)
127      */
128     public void setDims(Size newSize) {
129         setSize(newSize.getWidth(), newSize.getHeight());
130     }
131
132     /**
133      * Sets the position (X-coordinate and Y-coordinate) of a swing Scilab frame
134      * @param newPosition the position we want to set to the frame
135      * @see org.scilab.modules.gui.UIElement#setPosition(org.scilab.modules.gui.utils.Position)
136      */
137     public void setPosition(Position newPosition) {
138         Position javaPosition = PositionConverter.scilabToJava(newPosition, getDims(), getParent());
139         setLocation(javaPosition.getX(), javaPosition.getY());
140     }
141
142     /**
143      * Add a SwingViewObject (from SwingView.java) to container and returns its index
144      * @param member the member to add
145      */
146     public void addMember(SwingViewObject member) {
147         Uicontrol uicontrol = (Uicontrol) GraphicModel.getModel().getObjectFromId(member.getId());
148         if (getLayout() instanceof BorderLayout) {
149             switch (uicontrol.getBorderPositionAsEnum()) {
150                 case BOTTOM:
151                     panel.add((Component) member, BorderLayout.SOUTH);
152                     break;
153                 case TOP:
154                     panel.add((Component) member, BorderLayout.NORTH);
155                     break;
156                 case LEFT:
157                     panel.add((Component) member, BorderLayout.WEST);
158                     break;
159                 case RIGHT:
160                     panel.add((Component) member, BorderLayout.EAST);
161                     break;
162                 case CENTER:
163                     panel.add((Component) member, BorderLayout.CENTER);
164                     break;
165                 default:
166                     break;
167             }
168         } else if (getLayout() instanceof GridBagLayout) {
169             GridBagConstraints constraints = new GridBagConstraints();
170
171             // Grid
172             Integer[] grid = uicontrol.getGridBagGrid();
173             constraints.gridx = grid[0];
174             constraints.gridy = grid[1];
175             constraints.gridwidth = grid[2];
176             constraints.gridheight = grid[3];
177
178             // Weight
179             Double[] weight = uicontrol.getGridBagWeight();
180             constraints.weightx = weight[0];
181             constraints.weighty = weight[1];
182
183             // Anchor
184             switch (uicontrol.getGridBagAnchorAsEnum()) {
185                 case LEFT :
186                     constraints.anchor = GridBagConstraints.WEST;
187                     break;
188                 case UPPER :
189                     constraints.anchor = GridBagConstraints.NORTH;
190                     break;
191                 case LOWER:
192                     constraints.anchor = GridBagConstraints.SOUTH;
193                     break;
194                 case LOWER_LEFT:
195                     constraints.anchor = GridBagConstraints.SOUTHWEST;
196                     break;
197                 case LOWER_RIGHT:
198                     constraints.anchor = GridBagConstraints.SOUTHEAST;
199                     break;
200                 case RIGHT:
201                     constraints.anchor = GridBagConstraints.EAST;
202                     break;
203                 case UPPER_LEFT:
204                     constraints.anchor = GridBagConstraints.NORTHWEST;
205                     break;
206                 case UPPER_RIGHT:
207                     constraints.anchor = GridBagConstraints.NORTHEAST;
208                     break;
209                 case CENTER :
210                 default :
211                     constraints.anchor = GridBagConstraints.CENTER;
212                     break;
213             }
214
215             // Fill
216             switch (uicontrol.getGridBagFillAsEnum()) {
217                 case BOTH :
218                     constraints.fill = GridBagConstraints.BOTH;
219                     break;
220                 case HORIZONTAL:
221                     constraints.fill = GridBagConstraints.HORIZONTAL;
222                     break;
223                 case VERTICAL:
224                     constraints.fill = GridBagConstraints.VERTICAL;
225                     break;
226                 case NONE:
227                 default:
228                     constraints.fill = GridBagConstraints.NONE;
229                     break;
230             }
231
232             // Insets
233             Double[] margins = uicontrol.getMargins();
234             constraints.insets = new Insets(
235                 margins[0].intValue(), margins[1].intValue(),
236                 margins[2].intValue(), margins[3].intValue());
237
238             // Padding
239             Integer[] padding = uicontrol.getGridBagPadding();
240             constraints.ipadx = padding[0];
241             constraints.ipady = padding[1];
242
243             Integer[] preferredSize = uicontrol.getGridBagPreferredSize();
244             if (preferredSize[0].equals(-1) == false && preferredSize[1].equals(-1) == false) {
245                 ((Component) member).setPreferredSize(new Dimension(preferredSize[0], preferredSize[1]));
246             }
247
248             panel.add((Component) member, constraints);
249             revalidate();
250         } else if (getLayout() instanceof GridLayout) {
251             this.panel.add((Component) member, 0);
252         } else {
253             panel.add((Component) member);
254         }
255
256         SwingScilabPanel win = (SwingScilabPanel)SwingUtilities.getAncestorOfClass(SwingScilabPanel.class, this);
257         if (win != null) {
258             SwingScilabWindow parentWindow = SwingScilabWindow.allScilabWindows.get(win.getParentWindowId());
259             parentWindow.pack();
260         }
261     }
262
263     /**
264      * Add a member (dockable element) to container and returns its index
265      * @param member the member to add
266      * @return index of member in ArrayList
267      */
268     public int addMember(TextBox member) {
269         return this.addMember((SwingScilabTextBox) member.getAsSimpleTextBox());
270     }
271
272     /**
273      * Add a callback to the Frame
274      * @param callback the callback to set.
275      */
276     public void setCallback(CommonCallBack callback) {
277         // Nothing to do...
278     }
279
280     /**
281      * Setter for MenuBar
282      * @param menuBarToAdd the MenuBar associated to the Frame.
283      */
284     public void addMenuBar(MenuBar menuBarToAdd) {
285         /* Unimplemented for Frames */
286         throw new UnsupportedOperationException();
287     }
288
289     /**
290      * Setter for ToolBar
291      * @param toolBarToAdd the ToolBar associated to the Frame.
292      */
293     public void addToolBar(ToolBar toolBarToAdd) {
294         /* Unimplemented for Frames */
295         throw new UnsupportedOperationException();
296     }
297
298     /**
299      * Getter for MenuBar
300      * @return MenuBar: the MenuBar associated to the Frame.
301      */
302     public MenuBar getMenuBar() {
303         /* Unimplemented for Frames */
304         throw new UnsupportedOperationException();
305     }
306
307     /**
308      * Getter for ToolBar
309      * @return ToolBar: the ToolBar associated to the Frame.
310      */
311     public ToolBar getToolBar() {
312         /* Unimplemented for Frames */
313         throw new UnsupportedOperationException();
314     }
315
316     /**
317      * Get the text of the Frame
318      * @return the text of the frame
319      * @see org.scilab.modules.gui.frame.SimpleFrame#getText()
320      */
321     public String getText() {
322         return this.getName();
323     }
324
325     /**
326      * Set the text of the Frame
327      * @param text the text to set to the frame
328      * @see org.scilab.modules.gui.frame.SimpleFrame#setText()
329      */
330     public void setText(String text) {
331         this.setName(text);
332     }
333
334     /**
335      * Add a dockable element in the Frame (Not available for the moment)
336      * @param member the object we want to add to the Frame
337      * @return the index of the member in the Frame
338      * @see org.scilab.modules.gui.container.Container#addMember(org.scilab.modules.gui.dockable.Dockable)
339      */
340     public int addMember(Dockable member) {
341         /* Unimplemented for Frames */
342         throw new UnsupportedOperationException();
343     }
344
345     /**
346      * Set the Relief of the Frame
347      * @param reliefType the type of the relief to set (See ScilabRelief.java)
348      */
349     public void setRelief(String reliefType) {
350         if (defaultBorder == null) {
351             defaultBorder = getBorder();
352         }
353         setBorder(ScilabRelief.getBorderFromRelief(reliefType, defaultBorder));
354     }
355
356     /**
357      * Destroy the Frame
358      */
359     public void destroy() {
360         getParent().remove(this);
361         this.setVisible(false);
362     }
363
364     /**
365      * Setter for InfoBar
366      * @param infoBarToAdd the InfoBar associated to the Frame.
367      */
368     public void addInfoBar(TextBox infoBarToAdd) {
369         /* Unimplemented for Frames */
370         throw new UnsupportedOperationException();
371     }
372
373     /**
374      * Getter for InfoBar
375      * @return the InfoBar associated to the Frame.
376      */
377     public TextBox getInfoBar() {
378         /* Unimplemented for Frames */
379         throw new UnsupportedOperationException();
380     }
381
382     /**
383      * Set the horizontal alignment for the Slider text
384      * @param alignment the value for the alignment (See ScilabAlignment.java)
385      */
386     public void setHorizontalAlignment(String alignment) {
387         // Nothing to do here
388     }
389
390     /**
391      * Set the vertical alignment for the Slider text
392      * @param alignment the value for the alignment (See ScilabAlignment.java)
393      */
394     public void setVerticalAlignment(String alignment) {
395         // Nothing to do here
396     }
397
398     /**
399      * Set the UID
400      * @param id the UID
401      */
402     public void setId(Integer id) {
403         uid = id;
404     }
405
406     /**
407      * Get the UID
408      * @return the UID
409      */
410     public Integer getId() {
411         return uid;
412     }
413
414     /**
415      * Generic update method
416      * @param property property name
417      * @param value property value
418      */
419     public void update(int property, Object value) {
420         GraphicController controller = GraphicController.getController();
421
422         switch (property) {
423             case __GO_UI_STRING__: {
424                 // Update tab title
425                 Container parent = getParent();
426                 if (parent instanceof SwingScilabTabGroup) {
427                     SwingScilabTabGroup tab = (SwingScilabTabGroup) parent;
428                     int index = tab.indexOfComponent(this);
429                     if (index != -1) {
430                         tab.setTitleAt(index, ((String[]) value)[0]);
431                     }
432                 }
433                 break;
434             }
435             case __GO_UI_FRAME_BORDER__: {
436                 Integer borderId = (Integer) value;
437                 Border border = BorderConvertor.getBorder(borderId);
438                 setBorder(border);
439                 break;
440             }
441             case __GO_LAYOUT__ : {
442                 LayoutType newLayout = LayoutType.intToEnum((Integer) value);
443                 switch (newLayout) {
444                     case BORDER: {
445                         Integer[] padding = (Integer[]) controller.getProperty(getId(), __GO_BORDER_OPT_PADDING__);
446                         setLayout(new BorderLayout(padding[0], padding[1]));
447                         break;
448                     }
449                     case GRIDBAG:
450                         setLayout(new GridBagLayout());
451                         break;
452                     case GRID: {
453                         Integer[] padding = (Integer[]) controller.getProperty(getId(), __GO_GRID_OPT_PADDING__);
454                         Integer[] grid = (Integer[]) controller.getProperty(getId(), __GO_GRID_OPT_GRID__);
455                         if (grid[0] == 0 && grid[1] == 0) {
456                             grid[0] = 1;
457                         }
458                         setLayout(new GridLayout(grid[0], grid[1], padding[0], padding[1]));
459                         break;
460                     }
461                     case NONE:
462                     default: {
463                         setLayout(null);
464                         break;
465                     }
466                 }
467                 break;
468             }
469             case __GO_VISIBLE__ : {
470                 boolean needUpdate = true;
471                 Component parent = getParent();
472                 if (parent instanceof SwingScilabLayer) {
473                     //no no no don't touch visible on layer children !
474                     Boolean visible = (Boolean) value;
475                     SwingScilabLayer layer = (SwingScilabLayer) parent;
476                     Boolean isActive = layer.isLayerActive(this);
477                     if (isActive != visible) {
478                         controller.setProperty(uid, __GO_VISIBLE__, isActive);
479                     }
480
481                     needUpdate = false;
482                 } else if (parent instanceof SwingScilabTabGroup) {
483                     //no no no don't touch visible on layer children !
484                     Boolean visible = (Boolean) value;
485                     SwingScilabTabGroup layer = (SwingScilabTabGroup) parent;
486                     Boolean isActive = layer.isTabActive(this);
487                     if (isActive != visible) {
488                         controller.setProperty(uid, __GO_VISIBLE__, isActive);
489                     }
490
491                     needUpdate = false;
492                 }
493
494                 if (needUpdate) {
495                     setVisible(((Boolean) value).booleanValue());
496                 }
497
498                 break;
499             }
500             case __GO_TAG__ : {
501                 Component parent = getParent();
502                 if (parent instanceof SwingScilabLayer) {
503                     SwingScilabLayer layer = (SwingScilabLayer)parent;
504                     layer.updateModelProperties(null, layer.getActiveLayer());
505                 } else if (parent instanceof SwingScilabTabGroup) {
506                     ((SwingScilabTabGroup)parent).updateModelProperties();
507                 }
508                 break;
509             }
510             default:
511                 SwingViewWidget.update(this, property, value);
512                 break;
513         }
514     }
515
516     /**
517      * Set the enable status of the frame and its children
518      * @param status the status to set
519      */
520     public void setEnabled(boolean status) {
521         if (status) {
522             // Enable the frame
523             super.setEnabled(status);
524             // Enable its children according to their __GO_UI_ENABLE__ property
525             Integer[] children = (Integer[]) GraphicController.getController().getProperty(uid, __GO_CHILDREN__);
526             for (int kChild = 0; kChild < children.length; kChild++) {
527                 Boolean childStatus = (Boolean) GraphicController.getController().getProperty(children[kChild], __GO_UI_ENABLE__);
528                 SwingView.getFromId(children[kChild]).update(__GO_UI_ENABLE__, childStatus);
529             }
530         } else {
531             // Disable the frame
532             super.setEnabled(status);
533             // Disable its children
534             Component[] components = getComponents();
535             for (int compIndex = 0; compIndex < components.length; compIndex++) {
536                 components[compIndex].setEnabled(false);
537             }
538         }
539
540         //if parent is a tab enable/disable children tab
541         Component parent = getParent();
542         if (parent instanceof SwingScilabTabGroup) {
543             SwingScilabTabGroup tab = (SwingScilabTabGroup)parent;
544             Integer index = tab.getIndex(this);
545             if (index != -1) {
546                 tab.setEnabledAt(index, status);
547             }
548         }
549     }
550
551     public void setLayout(LayoutManager layout) {
552         if (layout != null) {
553             if (layout instanceof ScrollPaneLayout) {
554                 super.setLayout(layout);
555             } else if (panel != null) {
556                 panel.setLayout(layout);
557             }
558         }
559     }
560
561     public LayoutManager getLayout() {
562         if (panel != null) {
563             return panel.getLayout();
564         }
565         return null;
566     }
567
568     public void setBorder(Border border) {
569         if (panel != null) {
570             panel.setBorder(border);
571         }
572     }
573
574     public Border getBorder() {
575         if (panel != null) {
576             return panel.getBorder();
577         }
578
579         return null;
580     }
581
582     public void setBackground(Color bg) {
583         if (panel != null) {
584             panel.setBackground(bg);
585         }
586     }
587
588     public void resetBackground() {
589         Color color = (Color)UIManager.getLookAndFeelDefaults().get("ScrollPane.background");
590         if (color != null) {
591             setBackground(color);
592         }
593     }
594
595 }