b715482e21d9508a9de7c973bd5f3cde10a3c7be
[scilab.git] / scilab / modules / gui / src / java / org / scilab / modules / gui / bridge / tab / SwingScilabTab.java
1 /*
2  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  * Copyright (C) 20072008 - INRIA - Vincent Couvert
4  * Copyright (C) 2007 - INRIA - Bruno JOFRET
5  * Copyright (C) 2007 - INRIA - Marouane BEN JELLOUL
6  *
7  * This file must be used under the terms of the CeCILL.
8  * This source file is licensed as described in the file COPYING, which
9  * you should have received as part of this distribution.  The terms
10  * are also available at
11  * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
12  *
13  */
14
15 package org.scilab.modules.gui.bridge.tab;
16
17 import java.awt.Color;
18 import java.awt.Component;
19 import java.awt.Container;
20 import java.awt.Dimension;
21 import java.awt.Graphics;
22 import java.awt.Image;
23 import java.awt.Point;
24 import java.awt.event.FocusEvent;
25 import java.awt.event.FocusListener;
26 import java.lang.reflect.InvocationTargetException;
27 import java.util.Iterator;
28
29 import javax.swing.Action;
30 import javax.swing.ImageIcon;
31 import javax.swing.SwingUtilities;
32
33 import org.flexdock.docking.DockingConstants;
34 import org.flexdock.docking.DockingPort;
35 import org.flexdock.docking.event.DockingEvent;
36 import org.flexdock.docking.activation.ActiveDockableTracker;
37 import org.flexdock.docking.props.PropertyChangeListenerFactory;
38 import org.flexdock.view.View;
39 import org.scilab.modules.gui.bridge.canvas.SwingScilabCanvasImpl;
40 import org.scilab.modules.gui.bridge.checkbox.SwingScilabCheckBox;
41 import org.scilab.modules.gui.bridge.console.SwingScilabConsole;
42 import org.scilab.modules.gui.bridge.editbox.SwingScilabEditBox;
43 import org.scilab.modules.gui.bridge.frame.SwingScilabFrame;
44 import org.scilab.modules.gui.bridge.helpbrowser.SwingScilabHelpBrowser;
45 import org.scilab.modules.gui.bridge.label.SwingScilabLabel;
46 import org.scilab.modules.gui.bridge.listbox.SwingScilabListBox;
47 import org.scilab.modules.gui.bridge.popupmenu.SwingScilabPopupMenu;
48 import org.scilab.modules.gui.bridge.pushbutton.SwingScilabPushButton;
49 import org.scilab.modules.gui.bridge.radiobutton.SwingScilabRadioButton;
50 import org.scilab.modules.gui.bridge.slider.SwingScilabSlider;
51 import org.scilab.modules.gui.bridge.tree.SwingScilabTree;
52 import org.scilab.modules.gui.bridge.window.SwingScilabWindow;
53 import org.scilab.modules.gui.canvas.Canvas;
54 import org.scilab.modules.gui.checkbox.CheckBox;
55 import org.scilab.modules.gui.console.Console;
56 import org.scilab.modules.gui.dockable.Dockable;
57 import org.scilab.modules.gui.editbox.EditBox;
58 import org.scilab.modules.gui.events.callback.CallBack;
59 import org.scilab.modules.gui.frame.Frame;
60 import org.scilab.modules.gui.helpbrowser.HelpBrowser;
61 import org.scilab.modules.gui.label.Label;
62 import org.scilab.modules.gui.listbox.ListBox;
63 import org.scilab.modules.gui.menubar.MenuBar;
64 import org.scilab.modules.gui.popupmenu.PopupMenu;
65 import org.scilab.modules.gui.pushbutton.PushButton;
66 import org.scilab.modules.gui.radiobutton.RadioButton;
67 import org.scilab.modules.gui.slider.Slider;
68 import org.scilab.modules.gui.tab.SimpleTab;
69 import org.scilab.modules.gui.textbox.TextBox;
70 import org.scilab.modules.gui.toolbar.ToolBar;
71 import org.scilab.modules.gui.tree.Tree;
72 import org.scilab.modules.gui.utils.BarUpdater;
73 import org.scilab.modules.gui.utils.Position;
74 import org.scilab.modules.gui.utils.SciUndockingAction;
75 import org.scilab.modules.gui.utils.SciClosingAction;
76 import org.scilab.modules.gui.utils.Size;
77
78 /**
79  * Swing implementation for Scilab tabs in GUIs
80  * This implementation uses FlexDock package
81  * @author Bruno JOFRET
82  * @author Vincent COUVERT
83  * @author Marouane BEN JELLOUL
84  * @author Jean-Baptiste SILVY
85  */
86 public class SwingScilabTab extends View implements SimpleTab, FocusListener {
87
88     private static final Image SCILAB_ICON = new ImageIcon(System.getenv("SCI") + "/modules/gui/images/icons/scilab.png").getImage();
89
90     private static final long serialVersionUID = 1L;
91
92     private static final int VIEWPORT_SIZE = 4;
93
94     private static final String UNDOCK = "undock";
95
96     static {
97         PropertyChangeListenerFactory.addFactory(new BarUpdater.UpdateBarFactory());
98     }
99
100     private int parentWindowId;
101
102     private MenuBar menuBar;
103
104     private ToolBar toolBar;
105
106     private TextBox infoBar;
107
108     /** Contains the canvas and widgets */
109     private SwingScilabAxes contentPane;
110
111     /** Scroll the axes */
112     private ScilabScrollPane scrolling;
113
114     private Image icon;
115
116     /**
117      * Constructor
118      * @param name the name of the tab
119      * @param uuid an uuid to identify the tab
120      */
121     public SwingScilabTab(String name, String uuid) {
122         super(uuid, name, name);
123         //This button is "overloaded" when we add a callback
124         //this.addAction(DockingConstants.CLOSE_ACTION);
125         // Removed because make JOGL crash when "Unpin"
126         //this.addAction(DockingConstants.PIN_ACTION);
127         this.addAction(DockingConstants.ACTIVE_WINDOW);
128
129         // no need for an axes
130         contentPane = null;
131         scrolling = null;
132
133         this.setVisible(true);
134
135         getTitlebar().addFocusListener(this);
136         addFocusListener(this);
137     }
138
139     /**
140      * Constructor
141      * @param name the name of the tab (used to identify it)
142      */
143     public SwingScilabTab(String name) {
144         this(name, name);
145     }
146
147     /**
148      * @param e the FocusEvent
149      */
150     public void focusGained(FocusEvent e) {
151         if (contentPane != null) {
152             contentPane.requestFocus();
153         } else if (getContentPane() != null) {
154             getContentPane().requestFocus();
155         } else {
156             SwingScilabTab.this.requestFocusInWindow();
157         }
158     }
159
160     /**
161      * @return the window icon associated with this tab
162      */
163     public Image getWindowIcon() {
164         if (icon ==null) {
165             return SCILAB_ICON;
166         } else {
167             return icon;
168         }
169     }
170
171     /**
172      * @param the window icon associated with this tab
173      */
174     public void setWindowIcon(Image icon) {
175         this.icon = icon;
176     }
177
178     /**
179      * @param e the FocusEvent
180      */
181     public void focusLost(FocusEvent e) { }
182
183     /**
184      * Create a graphic tab used to display a figure with 3D graphics and/or UIcontrols
185      * @param name name of the tab
186      * @param figureId id of the displayed figure
187      */
188     public SwingScilabTab(String name, int figureId) {
189         super(name, name, name);
190
191         // This button is "overloaded" when we add a callback
192         //this.addAction(DockingConstants.CLOSE_ACTION);
193         // Removed because make JOGL crash when "Unpin"
194         //this.addAction(DockingConstants.PIN_ACTION);
195         this.addAction(DockingConstants.ACTIVE_WINDOW);
196
197         // create the panel in which all the uiobjects will lie.
198         contentPane = new SwingScilabAxes(figureId);
199
200         // add it inside a JSCrollPane
201         scrolling = new SwingScilabScrollPane(contentPane);
202
203         // put in in the back of the tab
204         setContentPane(scrolling.getAsContainer());
205
206         this.setVisible(true);
207
208         getTitlebar().addFocusListener(this);
209         addFocusListener(this);
210     }
211
212     /**
213      * {@inheritDoc}
214      */
215     public void dockingComplete(DockingEvent evt) {
216         super.dockingComplete(evt);
217         DockingPort port = evt.getNewDockingPort();
218         Iterator iter = port.getDockables().iterator();
219
220         if (port.getDockables().size() > 1) {
221             while (iter.hasNext()) {
222                 Object d = iter.next();
223                 if (d instanceof View) {
224                     View view = (View) d;
225                     view.setActionBlocked(DockingConstants.CLOSE_ACTION, false);
226                     view.setActionBlocked(UNDOCK, false);
227                 }
228             }
229         } else {
230             setActionBlocked(UNDOCK, true);
231             setActionBlocked(DockingConstants.CLOSE_ACTION, true);
232         }
233     }
234
235     /**
236      * Sets the Name of a swing Scilab tab
237      * @param newTabName the Name of the tab
238      * @see org.scilab.modules.gui.tab.Tab#setName()
239      */
240     public void setName(String newTabName) {
241         setTitle(newTabName, true);
242
243         getTitlePane().repaint();
244         SwingUtilities.getAncestorOfClass(SwingScilabWindow.class, this).setName(newTabName);
245     }
246
247     /**
248      * Gets the title of a swing Scilab tab
249      * @return the title of the tab
250      * @see org.scilab.modules.gui.tab.Tab#getTitle()
251      */
252     public String getName() {
253         return this.getTitle();
254     }
255
256     /**
257      * Paint immediately this component
258      */
259     public void paintImmediately() {
260         // paint all
261         paintImmediately(0, 0, getWidth(), getHeight());
262     }
263
264     /**
265      * Draws a swing Scilab tab
266      * @see org.scilab.modules.gui.uielement.UIElement#draw()
267      */
268     public void draw() {
269         if (SwingUtilities.isEventDispatchThread()) {
270             setVisible(true);
271             paintImmediately();
272         } else {
273             try {
274                 SwingUtilities.invokeAndWait(new Runnable() {
275                         public void run() {
276                             setVisible(true);
277                             paintImmediately();
278                         }
279                     });
280             } catch (InterruptedException e) {
281                 e.printStackTrace();
282             } catch (InvocationTargetException e) {
283                 e.printStackTrace();
284             }
285         }
286
287     }
288
289     /**
290      * Gets the dimensions (width and height) of a swing Scilab tab
291      * @return the dimensions of the tab
292      * @see org.scilab.modules.gui.uielement.UIElement#getDims()
293      */
294     public Size getDims() {
295         return new Size(this.getSize().width, this.getSize().height);
296     }
297
298     /**
299      * Get the size for the axes
300      * @return size of the axes in pixels
301      */
302     public Size getAxesSize() {
303         return new Size(contentPane.getWidth(), contentPane.getHeight());
304     }
305
306     /**
307      * @param newSize new size to set for the axes
308      */
309     public void setAxesSize(Size newSize) {
310         contentPane.setSize(new Dimension(newSize.getWidth(), newSize.getHeight()));
311     }
312
313     /**
314      * Gets the position (X-coordinate and Y-coordinate) of a swing Scilab tab
315      * @return the position of the tab
316      * @see org.scilab.modules.gui.uielement.UIElement#getPosition()
317      */
318     public Position getPosition() {
319         return new Position(this.getX(), this.getY());
320     }
321
322     /**
323      * Sets the dimensions (width and height) of a swing Scilab tab
324      * @param newSize the dimensions we want to set to the tab
325      * @see org.scilab.modules.gui.uielement.UIElement#setDims(org.scilab.modules.gui.utils.Size)
326      */
327     public void setDims(Size newSize) {
328         this.setSize(newSize.getWidth(), newSize.getHeight());
329     }
330
331     /**
332      * Sets the position (X-coordinate and Y-coordinate) of a swing Scilab tab
333      * @param newPosition the position we want to set to the tab
334      * @see org.scilab.modules.gui.uielement.UIElement#setPosition(org.scilab.modules.gui.utils.Position)
335      */
336     public void setPosition(Position newPosition) {
337         this.setLocation(newPosition.getX(), newPosition.getY());
338     }
339
340     /**
341      * Add a member (dockable element) to container and returns its index
342      * @param member the member to add
343      * @return index of member in ArrayList
344      */
345     public int addMember(Canvas member) {
346         int result;
347
348         if (SwingScilabCanvasImpl.isGLCanvasEnabled()) {
349             int[] currentView = getViewingRegion();
350             final SwingScilabTab thisF = this;
351             try {
352                 SwingUtilities.invokeAndWait(new Runnable() {
353                         public void run() {
354                             scrolling = new AwtScilabScrollPane(contentPane, thisF);
355                             setContentPane(scrolling.getAsContainer());
356                             revalidate();
357
358                         }
359                     });
360             } catch (InterruptedException e) {
361                 e.printStackTrace();
362             } catch (InvocationTargetException e) {
363                 e.getCause().printStackTrace();
364             }
365             // set the canvas after doing every thing
366             result = contentPane.addMember(member);
367             // set the same viewport as before
368             setViewingRegion(currentView[0], currentView[1], currentView[2], currentView[2 + 1]);
369         } else {
370             result = contentPane.addMember(member);
371         }
372         return result;
373     }
374
375     /**
376      * We want to be able to remove directly a Canvas from a Tab.
377      * @param member canvas to remove
378      */
379     public void removeMember(Canvas member) {
380         contentPane.removeMember(member);
381         if (SwingScilabCanvasImpl.isGLCanvasEnabled()) {
382             try {
383                 SwingUtilities.invokeAndWait(new Runnable() {
384                         public void run() {
385                             scrolling = new SwingScilabScrollPane(contentPane);
386                             setContentPane(scrolling.getAsContainer());
387                             revalidate();
388                         }
389                     });
390             } catch (InterruptedException e) {
391                 e.printStackTrace();
392             } catch (InvocationTargetException e) {
393                 e.getCause().printStackTrace();
394             }
395         }
396     }
397
398     /**
399      * Add a member (dockable element) to container and returns its index
400      * @param member the member to add
401      * @return index of member in ArrayList
402      */
403     public int addMember(Console member) {
404         return this.addMember((SwingScilabConsole) member.getAsSimpleConsole());
405     }
406
407     /**
408      * Add a member (dockable element) to container and returns its index
409      * @param member the member to add
410      * @return index of member in ArrayList
411      */
412     private int addMember(SwingScilabConsole member) {
413         // replace the current content pane
414         this.setContentPane(member);
415         return this.getComponentZOrder(member);
416     }
417
418     /**
419      * Add a member (dockable element) to container and returns its index
420      * @param member the member to add
421      * @return index of member in ArrayList
422      */
423     public int addMember(HelpBrowser member) {
424         return this.addMember((SwingScilabHelpBrowser) member.getAsSimpleHelpBrowser());
425     }
426
427     /**
428      * Add a member (dockable element) to container and returns its index
429      * @param member the member to add
430      * @return index of member in ArrayList
431      */
432     private int addMember(SwingScilabHelpBrowser member) {
433         // replace the current content pane
434         this.setContentPane(member);
435         return this.getComponentZOrder(member);
436     }
437
438     /**
439      * Add a member (dockable element) to container and returns its index
440      * @param member the member to add
441      * @return index of member in ArrayList
442      */
443     public int addMember(Frame member) {
444         return this.addMember((SwingScilabFrame) member.getAsSimpleFrame());
445     }
446
447     /**
448      * Add a member (dockable element) to container and returns its index
449      * @param member the member to add
450      * @return index of member in ArrayList
451      */
452     private int addMember(SwingScilabFrame member) {
453         return contentPane.addFrame(member);
454     }
455
456     /**
457      * Remove a Frame from its container
458      * @param member the Frame to remove
459      */
460     public void removeMember(Frame member) {
461         this.removeMember((SwingScilabFrame) member.getAsSimpleFrame());
462     }
463
464     /**
465      * Remove a Frame from its container
466      * @param member the Frame to remove
467      */
468     private void removeMember(SwingScilabFrame member) {
469         contentPane.removeFrame(member);
470     }
471
472     /**
473      * Add a member (dockable element) to container and returns its index
474      * @param member the member to add
475      * @return index of member in ArrayList
476      */
477     public int addMember(PushButton member) {
478         return this.addMember((SwingScilabPushButton) member.getAsSimplePushButton());
479     }
480
481     /**
482      * Add a member (dockable element) to container and returns its index
483      * @param member the member to add
484      * @return index of member in ArrayList
485      */
486     private int addMember(SwingScilabPushButton member) {
487         int res = contentPane.addWidget(member);
488         repaint();
489         return res;
490     }
491
492     /**
493      * Remove a PushButton from its container
494      * @param member the PushButton to remove
495      */
496     public void removeMember(PushButton member) {
497         this.removeMember((SwingScilabPushButton) member.getAsSimplePushButton());
498     }
499
500     /**
501      * Remove a PushButton from its container
502      * @param member the PushButton to remove
503      */
504     private void removeMember(SwingScilabPushButton member) {
505         contentPane.remove(member);
506     }
507
508     /**
509      * Add a member (dockable element) to container and returns its index
510      * @param member the member to add
511      * @return index of member in ArrayList
512      */
513     public int addMember(EditBox member) {
514         return this.addMember((SwingScilabEditBox) member.getAsSimpleEditBox());
515     }
516
517     /**
518      * Add a member (dockable element) to container and returns its index
519      * @param member the member to add
520      * @return index of member in ArrayList
521      */
522     private int addMember(SwingScilabEditBox member) {
523         return contentPane.addWidget(member);
524     }
525
526     /**
527      * Remove an EditBox from its container
528      * @param member the EditBox to remove
529      */
530     public void removeMember(EditBox member) {
531         this.removeMember((SwingScilabEditBox) member.getAsSimpleEditBox());
532     }
533
534     /**
535      * Remove an EditBox from its container
536      * @param member the EditBox to remove
537      */
538     private void removeMember(SwingScilabEditBox member) {
539         contentPane.removeWidget(member);
540     }
541
542     /**
543      * Add a member (dockable element) to container and returns its index
544      * @param member the member to add
545      * @return index of member in ArrayList
546      */
547     public int addMember(Label member) {
548         return this.addMember((SwingScilabLabel) member.getAsSimpleLabel());
549     }
550
551     /**
552      * Add a member (dockable element) to container and returns its index
553      * @param member the member to add
554      * @return index of member in ArrayList
555      */
556     private int addMember(SwingScilabLabel member) {
557         return contentPane.addWidget(member);
558     }
559
560     /**
561      * Remove a Label from its container
562      * @param member the Label to remove
563      */
564     public void removeMember(Label member) {
565         this.removeMember((SwingScilabLabel) member.getAsSimpleLabel());
566     }
567
568     /**
569      * Remove a Label from its container
570      * @param member the Label to remove
571      */
572     private void removeMember(SwingScilabLabel member) {
573         contentPane.removeWidget(member);
574     }
575
576     /**
577      * Add a member (dockable element) to container and returns its index
578      * @param member the member to add
579      * @return index of member in ArrayList
580      */
581     public int addMember(CheckBox member) {
582         return this.addMember((SwingScilabCheckBox) member.getAsSimpleCheckBox());
583     }
584
585     /**
586      * Add a member (dockable element) to container and returns its index
587      * @param member the member to add
588      * @return index of member in ArrayList
589      */
590     private int addMember(SwingScilabCheckBox member) {
591         return contentPane.addWidget(member);
592     }
593
594     /**
595      * Remove a CheckBox from its container
596      * @param member the CheckBox to remove
597      */
598     public void removeMember(CheckBox member) {
599         this.removeMember((SwingScilabCheckBox) member.getAsSimpleCheckBox());
600     }
601
602     /**
603      * Remove a CheckBox from its container
604      * @param member the CheckBox to remove
605      */
606     private void removeMember(SwingScilabCheckBox member) {
607         contentPane.removeWidget(member);
608     }
609
610     /**
611      * Add a member (dockable element) to container and returns its index
612      * @param member the member to add
613      * @return index of member in ArrayList
614      */
615     public int addMember(RadioButton member) {
616         return this.addMember((SwingScilabRadioButton) member.getAsSimpleRadioButton());
617     }
618
619     /**
620      * Add a member (dockable element) to container and returns its index
621      * @param member the member to add
622      * @return index of member in ArrayList
623      */
624     private int addMember(SwingScilabRadioButton member) {
625         return contentPane.addWidget(member);
626     }
627
628     /**
629      * Remove a RadioButton from its container
630      * @param member the RadioButton to remove
631      */
632     public void removeMember(RadioButton member) {
633         this.removeMember((SwingScilabRadioButton) member.getAsSimpleRadioButton());
634     }
635
636     /**
637      * Remove a RadioButton from its container
638      * @param member the RadioButton to remove
639      */
640     private void removeMember(SwingScilabRadioButton member) {
641         contentPane.removeWidget(member);
642     }
643
644     /**
645      * Add a member (dockable element) to container and returns its index
646      * @param member the member to add
647      * @return index of member in ArrayList
648      */
649     public int addMember(Slider member) {
650         return this.addMember((SwingScilabSlider) member.getAsSimpleSlider());
651     }
652
653     /**
654      * Add a member (dockable element) to container and returns its index
655      * @param member the member to add
656      * @return index of member in ArrayList
657      */
658     private int addMember(SwingScilabSlider member) {
659         return contentPane.addWidget(member);
660     }
661
662     /**
663      * Remove a Slider from its container
664      * @param member the Slider to remove
665      */
666     public void removeMember(Slider member) {
667         this.removeMember((SwingScilabSlider) member.getAsSimpleSlider());
668     }
669
670     /**
671      * Remove a Slider from its container
672      * @param member the Slider to remove
673      */
674     private void removeMember(SwingScilabSlider member) {
675         contentPane.removeWidget(member);
676     }
677
678     /**
679      * Add a member (dockable element) to container and returns its index
680      * @param member the member to add
681      * @return index of member in ArrayList
682      */
683     public int addMember(ListBox member) {
684         return this.addMember((SwingScilabListBox) member.getAsSimpleListBox());
685     }
686
687     /**
688      * Add a member (dockable element) to container and returns its index
689      * @param member the member to add
690      * @return index of member in ArrayList
691      */
692     private int addMember(SwingScilabListBox member) {
693         return contentPane.addWidget(member);
694     }
695
696     /**
697      * Remove a ListBox from its container
698      * @param member the ListBox to remove
699      */
700     public void removeMember(ListBox member) {
701         this.removeMember((SwingScilabListBox) member.getAsSimpleListBox());
702     }
703
704     /**
705      * Remove a ListBox from its container
706      * @param member the ListBox to remove
707      */
708     private void removeMember(SwingScilabListBox member) {
709         contentPane.removeWidget(member);
710     }
711
712     /**
713      * Add a member (dockable element) to container and returns its index
714      * @param member the member to add
715      * @return index of member in ArrayList
716      */
717     public int addMember(PopupMenu member) {
718         return this.addMember((SwingScilabPopupMenu) member.getAsSimplePopupMenu());
719     }
720
721     /**
722      * Add a member (dockable element) to container and returns its index
723      * @param member the member to add
724      * @return index of member in ArrayList
725      */
726     private int addMember(SwingScilabPopupMenu member) {
727         return contentPane.addWidget(member);
728     }
729
730     /**
731      * Remove a PopupMenu from its container
732      * @param member the PopupMenu to remove
733      */
734     public void removeMember(PopupMenu member) {
735         this.removeMember((SwingScilabPopupMenu) member.getAsSimplePopupMenu());
736     }
737
738     /**
739      * Remove a PopupMenu from its container
740      * @param member the PopupMenu to remove
741      */
742     private void removeMember(SwingScilabPopupMenu member) {
743         contentPane.removeWidget(member);
744     }
745
746     /**
747      * Add a Tree member (dockable element) to container and returns its index
748      * @param member the member to add
749      * @return index of member in ArrayList
750      */
751     public int addMember(Tree member) {
752         return this.addMember((SwingScilabTree) member.getAsSimpleTree());
753     }
754
755     /**
756      * Add a Tree member (dockable element) to container and returns its index
757      * @param member the member to add
758      * @return index of member in ArrayList
759      */
760     public int addMember(SwingScilabTree member) {
761         return contentPane.addWidget(member.getAsComponent());
762     }
763
764
765     /**
766      * Add a Tree member (dockable element) to container and returns its index
767      * @param member the member to add
768      * @return index of member in ArrayList
769      */
770     public int addTree(SwingScilabTree member) {
771         this.setContentPane(member.getAsComponent());
772         return this.getComponentZOrder(member.getAsComponent());
773     }
774
775     /**
776      * Remove a PopupMenu from its container
777      * @param member the PopupMenu to remove
778      */
779     public void removeMember(Tree member) {
780         this.removeMember((SwingScilabTree) member.getAsSimpleTree());
781     }
782
783     /**
784      * Remove a PopupMenu from its container
785      * @param member the PopupMenu to remove
786      */
787     private void removeMember(SwingScilabTree member) {
788         contentPane.removeTree(member);
789     }
790
791
792
793
794     /**
795      * Add a member (dockable element) to container and returns its index
796      * @param member the member to add
797      * @return index of member in ArrayList
798      */
799     public int addMember(Dockable member) {
800         // TODO Auto-generated method stub
801         return 0;
802     }
803
804     /**
805      * Get the current status of the Tab in its parent
806      * @return true is the tab is the tab currently "on top" in its parent
807      */
808     public boolean isCurrentTab() {
809         // TODO should not always return TRUE
810         return true;
811     }
812
813     /**
814      * Get the parent window id for this tab
815      * @return the id of the parent window
816      */
817     public int getParentWindowId() {
818         return this.parentWindowId;
819     }
820
821     /**
822      * Set the parent window id for this tab
823      * @param id the id of the parent window
824      */
825     public void setParentWindowId(int id) {
826         this.parentWindowId = id;
827     }
828
829     /**
830      * Setter for MenuBar
831      * @param newMenuBar : the MenuBar to set.
832      * @see org.scilab.modules.gui.tab.SimpleTab#setMenuBar(org.scilab.modules.gui.menubar.MenuBar)
833      */
834     public void setMenuBar(MenuBar newMenuBar) {
835         this.menuBar = newMenuBar;
836     }
837
838
839     /**
840      * Getter for MenuBar
841      * @return MenuBar : the MenuBar associated to the Tab.
842      * @see org.scilab.modules.gui.tab.SimpleTab#getMenuBar()
843      */
844     public MenuBar getMenuBar() {
845         return this.menuBar;
846     }
847
848     /**
849      * Setter for ToolBar
850      * @param newToolBar : the ToolBar to set.
851      * @see org.scilab.modules.gui.tab.SimpleTab#setToolBar(org.scilab.modules.gui.toolbar.ToolBar)
852      */
853     public void setToolBar(ToolBar newToolBar) {
854         this.toolBar = newToolBar;
855     }
856
857     /**
858      * Getter for ToolBar
859      * @return ToolBar : the ToolBar associated to the Tab.
860      * @see org.scilab.modules.gui.tab.SimpleTab#getToolBar()
861      */
862     public ToolBar getToolBar() {
863         return this.toolBar;
864     }
865
866     /**
867      * Setter for InfoBar
868      * @param newInfoBar the InfoBar to set.
869      */
870     public void setInfoBar(TextBox newInfoBar) {
871         this.infoBar = newInfoBar;
872     }
873
874     /**
875      * Getter for InfoBar
876      * @return the InfoBar associated to the Tab.
877      */
878     public TextBox getInfoBar() {
879         return this.infoBar;
880     }
881
882     /**
883      * Set the callback of the tab
884      * @param callback the callback to set.
885      */
886     public void setCallback(CallBack callback) {
887         Action action;
888         if (callback != null) {
889             action = new SciClosingAction(this, callback);
890         } else {
891             this.addAction(DockingConstants.CLOSE_ACTION);
892             action = new SciClosingAction(this, this.getTitlebar().getAction(DockingConstants.CLOSE_ACTION));
893         }
894
895         action.putValue(Action.NAME, DockingConstants.CLOSE_ACTION);
896         this.addAction(action);
897
898         /* Undock button */
899         SciUndockingAction undockAction = new SciUndockingAction(this);
900         undockAction.putValue(Action.NAME, UNDOCK);
901         this.addAction(undockAction);
902     }
903
904     /**
905      * Set this tab as the current tab of its parent Window
906      */
907     public void setCurrent() {
908         ActiveDockableTracker.requestDockableActivation(this);
909     }
910
911     /**
912      * Set the background color of the tab.
913      * @param red red channel of the color
914      * @param green green channel
915      * @param blue blue channel
916      */
917     public void setBackground(double red, double green, double blue) {
918         Color newColor = new Color((float) red, (float) green, (float) blue);
919         contentPane.setBackground(red, green, blue);
920         scrolling.setBackground(red, green, blue);
921         setBackground(newColor);
922     }
923
924     /**
925      * Get the part of the axes which is currently viewed
926      * @return [x,y,w,h] array
927      */
928     public int[] getViewingRegion() {
929         return scrolling.getViewingRegion();
930     }
931
932     /**
933      * Specify a new viewport for the axes
934      * For SwingScilabCanvas viewport can not be modified
935      * since it match the parent tab size
936      * @param posX X coordinate of upper left point of the viewport within the axes
937      * @param posY Y coordinate of upper left point of the viewport within the axes
938      * @param width width of the viewport
939      * @param height height of the viewport
940      */
941     public void setViewingRegion(int posX, int posY, int width, int height) {
942         // Check that the canvas can be resized
943         if (!scrolling.getAutoResizeMode()) {
944             // don't set viewport size here it should always fit parent tab size
945             // It seems that we must check the viewport size and positions
946             // to get coherent values, otherwise the setViewPosition hangs...
947             // there are three checks that must be performed for the two dimensions
948             // - be sure that viewport position is greater than 0.
949             // - if the viewport is larger than the canvas, then it can't be moved
950             // - if the viewport is smaller than the canvas, then it should remains
951             //   inside the canvas
952
953             int canvasWidth = contentPane.getWidth();
954             int canvasHeight = contentPane.getHeight();
955             int[] curViewedRegion = getViewingRegion();
956             int viewportPosX = curViewedRegion[0];
957             int viewPortPosY = curViewedRegion[1];
958             int viewportWidth = curViewedRegion[2];
959             int viewportHeight = curViewedRegion[VIEWPORT_SIZE - 1];
960
961             // use previous values as default ones
962             int realPosX = 0;
963             int realPosY = 0;
964
965
966             if (viewportWidth <= canvasWidth) {
967                 // viewport smaller than the canvas
968                 // check that the viewport stays in the canvas
969                 // the left most position is canvasWidth - viewporwidth
970                 realPosX = Math.min(posX, canvasWidth - viewportWidth);
971             } else {
972                 // viewport larger than the canvas
973                 // get previous position (should be 0)
974                 realPosX = viewportPosX;
975             }
976             // last check, greater than 0
977             realPosX = Math.max(0, realPosX);
978
979             if (viewportHeight <= canvasHeight) {
980                 realPosY = Math.min(posY, canvasHeight - viewportHeight);
981             } else {
982                 realPosY = viewPortPosY;
983             }
984             realPosY = Math.max(0, realPosY);
985
986             // must be called on the Swing thread otherwise some JOGL corruption may appear
987             final Point realPos = new Point(realPosX, realPosY);
988             try {
989                 SwingUtilities.invokeAndWait(new Runnable() {
990                         public void run() {
991                             scrolling.setViewPosition(realPos.x, realPos.y);
992                         }
993                     });
994             } catch (InterruptedException e) {
995                 e.printStackTrace();
996             } catch (InvocationTargetException e) {
997                 e.getCause().printStackTrace();
998             }
999
1000
1001         }
1002     }
1003
1004     /**
1005      * Set the event handler of the Canvas
1006      * @param funName the name of the Scilab function to call
1007      */
1008     public void setEventHandler(String funName) {
1009         contentPane.setEventHandler(funName);
1010     }
1011
1012
1013     /**
1014      * Set the status of the event handler of the Canvas
1015      * @param status is true to set the event handler active
1016      */
1017     public void setEventHandlerEnabled(boolean status) {
1018         contentPane.setEventHandlerEnabled(status);
1019     }
1020
1021     /**
1022      * Specify whether the canvas should fit the parent tab size
1023      * (and consequently the scrollpane size) or not
1024      * @param onOrOff true to enable autoresize mode
1025      */
1026     public void setAutoResizeMode(boolean onOrOff) {
1027         scrolling.setAutoResizeMode(onOrOff);
1028     }
1029
1030     /**
1031      * @return whether the resize mode is on or off
1032      */
1033     public boolean getAutoResizeMode() {
1034         return scrolling.getAutoResizeMode();
1035     }
1036
1037     /**
1038      * Get the displacement in pixel that should be used for rotating axes
1039      * @param displacement out parameter, [x,y] array of displacement in pixels
1040      * @return true if the displacement recording continue, false otherwise
1041      */
1042     public boolean getRotationDisplacement(int[] displacement) {
1043         return contentPane.getRotationDisplacement(displacement);
1044     }
1045
1046     /**
1047      * Close the tab and disable it.
1048      */
1049     public void close() {
1050         this.getContentPane().removeAll();
1051         this.setMenuBar(null);
1052         this.setToolBar(null);
1053         this.setInfoBar(null);
1054         this.setTitlebar(null);
1055         this.removeAll();
1056         setActive(false);
1057
1058         scrolling = null;
1059         contentPane = null;
1060
1061         // without this children canvas are not released.
1062         Container dummyContainer = new Container();
1063         this.setContentPane(dummyContainer);
1064     }
1065
1066     /**
1067      * Asynchronous stop of rotation tracking.
1068      */
1069     public void stopRotationRecording() {
1070         contentPane.stopRotationRecording();
1071     }
1072
1073     /**
1074      * Redefine paint children to be sure that AWT components are well painted.
1075      *  @param g a Graphics
1076      */
1077     public void paintChildren(Graphics g) {
1078         Component[] children = getComponents();
1079         for (int i = 0; i < children.length; i++) {
1080             // AWT children don't draw themselves automatically
1081             // so force their draw
1082             if (!children[i].isLightweight()) {
1083                 children[i].paint(g);
1084             }
1085         }
1086         super.paintChildren(g);
1087     }
1088 }