slider : set value to [] => 0
[scilab.git] / scilab / modules / gui / src / java / org / scilab / modules / gui / bridge / slider / SwingScilabSlider.java
1 /*
2  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  * Copyright (C) 2014 - Scilab Enterprises - Antoine ELIAS
4  *
5  * This file must be used under the terms of the CeCILL.
6  * This source file is licensed as described in the file COPYING, which
7  * you should have received as part of this distribution.  The terms
8  * are also available at
9  * http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt
10  *
11  */
12
13 package org.scilab.modules.gui.bridge.slider;
14
15 import static org.scilab.modules.graphic_objects.graphicObject.GraphicObjectProperties.__GO_POSITION__;
16 import static org.scilab.modules.graphic_objects.graphicObject.GraphicObjectProperties.__GO_UI_MAX__;
17 import static org.scilab.modules.graphic_objects.graphicObject.GraphicObjectProperties.__GO_UI_MIN__;
18 import static org.scilab.modules.graphic_objects.graphicObject.GraphicObjectProperties.__GO_UI_SLIDERSTEP__;
19 import static org.scilab.modules.graphic_objects.graphicObject.GraphicObjectProperties.__GO_UI_VALUE__;
20
21 import java.awt.Color;
22 import java.awt.event.ActionEvent;
23
24 import javax.swing.AbstractAction;
25 import javax.swing.JScrollBar;
26 import javax.swing.JSlider;
27 import javax.swing.KeyStroke;
28 import javax.swing.UIManager;
29 import javax.swing.border.Border;
30 import javax.swing.event.ChangeEvent;
31 import javax.swing.event.ChangeListener;
32
33 import org.scilab.modules.commons.OS;
34 import org.scilab.modules.graphic_objects.graphicController.GraphicController;
35 import org.scilab.modules.gui.SwingViewObject;
36 import org.scilab.modules.gui.SwingViewWidget;
37 import org.scilab.modules.gui.events.callback.CommonCallBack;
38 import org.scilab.modules.gui.menubar.MenuBar;
39 import org.scilab.modules.gui.slider.SimpleSlider;
40 import org.scilab.modules.gui.textbox.TextBox;
41 import org.scilab.modules.gui.toolbar.ToolBar;
42 import org.scilab.modules.gui.utils.Position;
43 import org.scilab.modules.gui.utils.PositionConverter;
44 import org.scilab.modules.gui.utils.ScilabRelief;
45 import org.scilab.modules.gui.utils.ScilabSwingUtilities;
46 import org.scilab.modules.gui.utils.Size;
47
48 /**
49  * Swing implementation for Scilab Slider in GUIs
50  * @author Antoine ELIAS
51  */
52 public class SwingScilabSlider extends JSlider implements SwingViewObject, SimpleSlider {
53
54     private static final long serialVersionUID = -4262320156090829309L;
55
56     private static final int MINIMUM_VALUE = 0;
57     private static final int MAXIMUM_VALUE = 10000;
58
59     private Integer uid;
60
61     private CommonCallBack callback;
62
63     private ChangeListener changeListener;
64
65     private Border defaultBorder = null;
66
67     static {
68         if (OS.get() == OS.UNIX) {
69             // Force Slider on Unix not to display value upon
70             UIManager.put("Slider.paintValue", false);
71         }
72     }
73
74     class CtrlLeftAction extends AbstractAction {
75         private static final long serialVersionUID = -3289281207742516486L;
76
77         public void actionPerformed(ActionEvent arg0) {
78             double userMin = (Double) GraphicController.getController().getProperty(uid, __GO_UI_MIN__);
79             double userMax = (Double) GraphicController.getController().getProperty(uid, __GO_UI_MAX__);
80             Double[] step = (Double[]) GraphicController.getController().getProperty(uid, __GO_UI_SLIDERSTEP__);
81             int value = SwingScilabSlider.this.getValue();
82
83             double ratio = (MAXIMUM_VALUE - MINIMUM_VALUE) / (userMax - userMin);
84             int newValue = Math.max(MINIMUM_VALUE, value - (int)(step[1] * ratio));
85             setValue(newValue);
86         }
87     }
88
89     class LeftAction extends AbstractAction {
90         private static final long serialVersionUID = 2099826485447918397L;
91
92         public void actionPerformed(ActionEvent arg0) {
93             double userMin = (Double) GraphicController.getController().getProperty(uid, __GO_UI_MIN__);
94             double userMax = (Double) GraphicController.getController().getProperty(uid, __GO_UI_MAX__);
95             Double[] step = (Double[]) GraphicController.getController().getProperty(uid, __GO_UI_SLIDERSTEP__);
96             int value = SwingScilabSlider.this.getValue();
97
98             double ratio = (MAXIMUM_VALUE - MINIMUM_VALUE) / (userMax - userMin);
99             int newValue = Math.max(MINIMUM_VALUE, value - (int)(step[0] * ratio));
100             setValue(newValue);
101         }
102     }
103
104     class RightAction extends AbstractAction {
105         private static final long serialVersionUID = 8666161246122371904L;
106
107         public void actionPerformed(ActionEvent arg0) {
108             double userMin = (Double) GraphicController.getController().getProperty(uid, __GO_UI_MIN__);
109             double userMax = (Double) GraphicController.getController().getProperty(uid, __GO_UI_MAX__);
110             Double[] step = (Double[]) GraphicController.getController().getProperty(uid, __GO_UI_SLIDERSTEP__);
111             int value = SwingScilabSlider.this.getValue();
112
113             double ratio = (MAXIMUM_VALUE - MINIMUM_VALUE) / (userMax - userMin);
114             int newValue = Math.min(MAXIMUM_VALUE, value + (int)(step[0] * ratio));
115             setValue(newValue);
116         }
117     }
118
119     class CtrlRightAction extends AbstractAction {
120         private static final long serialVersionUID = -1364255463511656338L;
121
122         public void actionPerformed(ActionEvent arg0) {
123             double userMin = (Double) GraphicController.getController().getProperty(uid, __GO_UI_MIN__);
124             double userMax = (Double) GraphicController.getController().getProperty(uid, __GO_UI_MAX__);
125             Double[] step = (Double[]) GraphicController.getController().getProperty(uid, __GO_UI_SLIDERSTEP__);
126             int value = SwingScilabSlider.this.getValue();
127
128             double ratio = (MAXIMUM_VALUE - MINIMUM_VALUE) / (userMax - userMin);
129             int newValue = Math.min(MAXIMUM_VALUE, value + (int)(step[1] * ratio));
130             setValue(newValue);
131         }
132     }
133
134     /**
135      * Constructor
136      */
137     public SwingScilabSlider() {
138         super();
139         // needed to have slider working with GLCanvas
140         setOpaque(true);
141         setMinimum(MINIMUM_VALUE);
142         setMaximum(MAXIMUM_VALUE);
143         setValue(0);
144
145         /* some keys binding */
146         getInputMap().put(KeyStroke.getKeyStroke("DOWN"), "LeftAction");
147         getInputMap().put(KeyStroke.getKeyStroke("LEFT"), "LeftAction");
148         getActionMap().put("LeftAction", new LeftAction());
149         getInputMap().put(KeyStroke.getKeyStroke("UP"), "RightAction");
150         getInputMap().put(KeyStroke.getKeyStroke("RIGHT"), "RightAction");
151         getActionMap().put("RightAction", new RightAction());
152         getInputMap().put(KeyStroke.getKeyStroke("control UP"), "CtrlRightAction");
153         getInputMap().put(KeyStroke.getKeyStroke("control RIGHT"), "CtrlRightAction");
154         getActionMap().put("CtrlRightAction", new CtrlRightAction());
155         getInputMap().put(KeyStroke.getKeyStroke("control DOWN"), "CtrlLeftAction");
156         getInputMap().put(KeyStroke.getKeyStroke("control LEFT"), "CtrlLeftAction");
157         getActionMap().put("CtrlLeftAction", new CtrlLeftAction());
158
159
160         changeListener = new ChangeListener() {
161             public void stateChanged(ChangeEvent arg0) {
162                 updateModel();
163                 if (callback != null) {
164                     callback.actionPerformed(null);
165                 }
166             }
167         };
168         addChangeListener(changeListener);
169     }
170
171     /**
172      * Draws a swing Scilab Slider
173      * @see org.scilab.modules.gui.UIElement#draw()
174      */
175     public void draw() {
176         this.setVisible(true);
177         this.doLayout();
178     }
179
180     /**
181      * Gets the dimensions (width and height) of a swing Scilab Slider
182      * @return the dimensions of the Slider
183      * @see org.scilab.modules.gui.uielement.UIElement#getDims()
184      */
185     public Size getDims() {
186         return new Size(super.getSize().width, super.getSize().height);
187     }
188
189     /**
190      * Gets the position (X-coordinate and Y-coordinate) of a swing Scilab Slider
191      * @return the position of the Slider
192      * @see org.scilab.modules.gui.uielement.UIElement#getPosition()
193      */
194     public Position getPosition() {
195         return PositionConverter.javaToScilab(getLocation(), getSize(), getParent());
196     }
197
198     /**
199      * Sets the dimensions (width and height) of a swing Scilab Slider
200      * @param newSize the dimensions to set to the Slider
201      * @see org.scilab.modules.gui.uielement.UIElement#setDims(org.scilab.modules.gui.utils.Size)
202      */
203     public void setDims(Size newSize) {
204         super.setSize(newSize.getWidth(), newSize.getHeight());
205         super.doLayout(); // Usefull in case of resize
206     }
207
208     /**
209      * Sets the position (X-coordinate and Y-coordinate) of a swing Scilab Slider
210      * @param newPosition the position to set to the Slider
211      * @see org.scilab.modules.gui.uielement.UIElement#setPosition(org.scilab.modules.gui.utils.Position)
212      */
213     public void setPosition(Position newPosition) {
214         Position javaPosition = PositionConverter.scilabToJava(newPosition, getDims(), getParent());
215         setLocation(javaPosition.getX(), javaPosition.getY());
216     }
217
218     /**
219      * Add a callback to the Slider
220      * @param cb the callback to set.
221      */
222     public void setCallback(CommonCallBack cb) {
223         /* Create a callback */
224         callback = cb;
225     }
226
227     /**
228      * Setter for MenuBar
229      * @param menuBarToAdd the MenuBar associated to the Tab.
230      */
231     public void addMenuBar(MenuBar menuBarToAdd) {
232         /* Unimplemented for CheckBoxes */
233         throw new UnsupportedOperationException();
234     }
235
236     /**
237      * Setter for ToolBar
238      * @param toolBarToAdd the ToolBar associated to the Tab.
239      */
240     public void addToolBar(ToolBar toolBarToAdd) {
241         /* Unimplemented for CheckBoxes */
242         throw new UnsupportedOperationException();
243     }
244
245     /**
246      * Getter for MenuBar
247      * @return MenuBar: the MenuBar associated to the Tab.
248      */
249     public MenuBar getMenuBar() {
250         /* Unimplemented for CheckBoxes */
251         throw new UnsupportedOperationException();
252     }
253
254     /**
255      * Getter for ToolBar
256      * @return ToolBar: the ToolBar associated to the Tab.
257      */
258     public ToolBar getToolBar() {
259         /* Unimplemented for CheckBoxes */
260         throw new UnsupportedOperationException();
261     }
262
263     /**
264      * Get the text of the Slider
265      * @return the text
266      * @see org.scilab.modules.gui.widget.Widget#getText()
267      */
268     public String getText() {
269         return this.getName();
270     }
271
272     /**
273      * Set the text of the Slider
274      * @param text the text to set to the Slider
275      * @see org.scilab.modules.gui.widget.Widget#setText(java.lang.String)
276      */
277     public void setText(String text) {
278         this.setName(text);
279     }
280
281     public void setEmptyText() {
282         this.setName(null);
283     }
284     /**
285      * Set the horizontal alignment for the Slider text
286      * @param alignment the value for the alignment (See ScilabAlignment.java)
287      */
288     public void setHorizontalAlignment(String alignment) {
289         // Nothing to do here
290     }
291
292     /**
293      * Set the vertical alignment for the Slider text
294      * @param alignment the value for the alignment (See ScilabAlignment.java)
295      */
296     public void setVerticalAlignment(String alignment) {
297         // Nothing to do here
298     }
299
300     /**
301      * Set the minimum value of a Slider
302      * @param value the minimum value
303      */
304     public void setMinimumValue(double value) {
305         updateModel(); /* Update the model according to the knob position */
306     }
307
308     /**
309      * Set the maximum value of a Slider
310      * @param value the maximum value
311      */
312     public void setMaximumValue(double value) {
313         updateModel(); /* Update the model according to the knob position */
314     }
315
316     /**
317      * Set the Relief of the Slider
318      * @param reliefType the type of the relief to set (See ScilabRelief.java)
319      */
320     public void setRelief(String reliefType) {
321         if (defaultBorder == null) {
322             defaultBorder = getBorder();
323         }
324         setBorder(ScilabRelief.getBorderFromRelief(reliefType, defaultBorder));
325     }
326
327     /**
328      * Set the major tick spacing for a Slider
329      * @param space the increment value
330      */
331     public void setMajorTickSpacing(double space) {
332         double userMin = (Double) GraphicController.getController().getProperty(uid, __GO_UI_MIN__);
333         double userMax = (Double) GraphicController.getController().getProperty(uid, __GO_UI_MAX__);
334
335         double ratio = (MAXIMUM_VALUE - MINIMUM_VALUE) / (userMax - userMin);
336         int newspace = (int)(space * ratio);
337         super.setMajorTickSpacing(newspace);
338     }
339
340     /**
341      * Set the minor tick spacing for a Slider
342      * @param space the increment value
343      */
344     public void setMinorTickSpacing(double space) {
345         double userMin = (Double) GraphicController.getController().getProperty(uid, __GO_UI_MIN__);
346         double userMax = (Double) GraphicController.getController().getProperty(uid, __GO_UI_MAX__);
347
348         double ratio = (MAXIMUM_VALUE - MINIMUM_VALUE) / (userMax - userMin);
349         int newspace = (int)(space * ratio);
350         super.setMinorTickSpacing(newspace);
351     }
352
353     /**
354      * Set the slider orientation to vertical
355      */
356     public void setVertical() {
357         setOrientation(JScrollBar.VERTICAL);
358     }
359
360     /**
361      * Set the slider orientation to horizontal
362      */
363     public void setHorizontal() {
364         setOrientation(JScrollBar.HORIZONTAL);
365     }
366
367     /**
368      * Destroy the Slider
369      */
370     public void destroy() {
371         ScilabSwingUtilities.removeFromParent(this);
372     }
373
374     /**
375      * Setter for InfoBar
376      * @param infoBarToAdd the InfoBar associated to the Slider.
377      */
378     public void addInfoBar(TextBox infoBarToAdd) {
379         /* Unimplemented for Sliders */
380         throw new UnsupportedOperationException();
381     }
382
383     /**
384      * Getter for InfoBar
385      * @return the InfoBar associated to the Slider.
386      */
387     public TextBox getInfoBar() {
388         /* Unimplemented for Sliders */
389         throw new UnsupportedOperationException();
390     }
391
392     /**
393      * Set the current value of the Slider
394      * @param value the new value
395      */
396     public void setUserValue(double value) {
397         /* Remove the listener to avoid the callback to be executed */
398         removeChangeListener(changeListener);
399
400         double userMin = (Double) GraphicController.getController().getProperty(uid, __GO_UI_MIN__);
401         double userMax = (Double) GraphicController.getController().getProperty(uid, __GO_UI_MAX__);
402         setValue(MINIMUM_VALUE + (int) ((value - userMin) * (MAXIMUM_VALUE - MINIMUM_VALUE) / (userMax - userMin)));
403
404         /* Put back the listener */
405         addChangeListener(changeListener);
406     }
407
408     /**
409      * Set the UID
410      * @param id the UID
411      */
412     public void setId(Integer id) {
413         uid = id;
414     }
415
416     /**
417      * Get the UID
418      * @return the UID
419      */
420     public Integer getId() {
421         return uid;
422     }
423
424     /**
425      * Generic update method
426      * @param property property name
427      * @param value property value
428      */
429     public void update(int property, Object value) {
430         GraphicController controller = GraphicController.getController();
431
432         switch (property) {
433             case __GO_UI_MAX__: {
434                 Double maxValue = (Double) value;
435                 // Update the slider properties
436                 Double minValue = (Double) controller.getProperty(uid, __GO_UI_MIN__);
437                 setMaximumValue(maxValue);
438                 Double[] sliderStep = ((Double[]) controller.getProperty(uid, __GO_UI_SLIDERSTEP__));
439                 double minorSliderStep = sliderStep[0].doubleValue();
440                 double majorSliderStep = sliderStep[1].doubleValue();
441                 if (minValue <= maxValue) {
442                     setMinorTickSpacing(minorSliderStep);
443                     setMajorTickSpacing(majorSliderStep);
444                 }
445                 break;
446             }
447             case __GO_UI_MIN__ : {
448                 Double minValue = (Double)value;
449                 // Update the slider properties
450                 Double maxValue = (Double) controller.getProperty(uid, __GO_UI_MAX__);
451                 setMinimumValue(minValue);
452                 Double[] sliderStep = ((Double[]) controller.getProperty(uid, __GO_UI_SLIDERSTEP__));
453                 double minorSliderStep = sliderStep[0].doubleValue();
454                 double majorSliderStep = sliderStep[1].doubleValue();
455                 if (minValue <= maxValue) {
456                     setMinorTickSpacing(minorSliderStep);
457                     setMajorTickSpacing(majorSliderStep);
458                 }
459                 break;
460             }
461             case __GO_POSITION__ : {
462                 Double[] dblValues = SwingViewWidget.updatePosition(this, uid, value);
463                 if (dblValues[2].intValue() > dblValues[3].intValue()) {
464                     setHorizontal();
465                 } else {
466                     setVertical();
467                 }
468                 break;
469             }
470             case __GO_UI_SLIDERSTEP__ : {
471                 Double[] sliderStep = ((Double[]) value);
472                 double minorSliderStep = sliderStep[0].doubleValue();
473                 double majorSliderStep = sliderStep[1].doubleValue();
474                 setMinorTickSpacing(minorSliderStep);
475                 setMajorTickSpacing(majorSliderStep);
476                 break;
477             }
478             case __GO_UI_VALUE__ : {
479                 Double[] doubleValue = ((Double[]) value);
480                 if (doubleValue.length != 0) {
481                     setUserValue(doubleValue[0]);
482                 } else {
483                     Double minValue = (Double) controller.getProperty(uid, __GO_UI_MIN__);
484                     setUserValue(minValue);
485                 }
486                 break;
487             }
488             default: {
489                 SwingViewWidget.update(this, property, value);
490                 break;
491             }
492         }
493     }
494
495     /**
496      * Update values in the model when needed
497      */
498     private void updateModel() {
499         Double[] value = new Double[1];
500         double userMin = (Double) GraphicController.getController().getProperty(uid, __GO_UI_MIN__);
501         double userMax = (Double) GraphicController.getController().getProperty(uid, __GO_UI_MAX__);
502         value[0] = userMin + ((getValue() - MINIMUM_VALUE) * (userMax - userMin) / (MAXIMUM_VALUE - MINIMUM_VALUE));
503         GraphicController.getController().setProperty(uid, __GO_UI_VALUE__, value);
504     }
505
506     public void resetBackground() {
507         Color color = (Color)UIManager.getLookAndFeelDefaults().get("Slider.background");
508         if (color != null) {
509             setBackground(color);
510         }
511     }
512
513     public void resetForeground() {
514         Color color = (Color)UIManager.getLookAndFeelDefaults().get("Slider.foreground");
515         if (color != null) {
516             setForeground(color);
517         }
518     }
519 }