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