##// END OF EJS Templates
Add docstring for IntRangeSlider...
Thomas Kluyver -
Show More
@@ -1,201 +1,202 b''
1 """Int class.
1 """Int class.
2
2
3 Represents an unbounded int using a widget.
3 Represents an unbounded int using a widget.
4 """
4 """
5 #-----------------------------------------------------------------------------
5 #-----------------------------------------------------------------------------
6 # Copyright (c) 2013, the IPython Development Team.
6 # Copyright (c) 2013, the IPython Development Team.
7 #
7 #
8 # Distributed under the terms of the Modified BSD License.
8 # Distributed under the terms of the Modified BSD License.
9 #
9 #
10 # The full license is in the file COPYING.txt, distributed with this software.
10 # The full license is in the file COPYING.txt, distributed with this software.
11 #-----------------------------------------------------------------------------
11 #-----------------------------------------------------------------------------
12
12
13 #-----------------------------------------------------------------------------
13 #-----------------------------------------------------------------------------
14 # Imports
14 # Imports
15 #-----------------------------------------------------------------------------
15 #-----------------------------------------------------------------------------
16 from .widget import DOMWidget, register
16 from .widget import DOMWidget, register
17 from IPython.utils.traitlets import Unicode, CInt, Bool, CaselessStrEnum, Tuple
17 from IPython.utils.traitlets import Unicode, CInt, Bool, CaselessStrEnum, Tuple
18 from IPython.utils.warn import DeprecatedClass
18 from IPython.utils.warn import DeprecatedClass
19
19
20 #-----------------------------------------------------------------------------
20 #-----------------------------------------------------------------------------
21 # Classes
21 # Classes
22 #-----------------------------------------------------------------------------
22 #-----------------------------------------------------------------------------
23 class _Int(DOMWidget):
23 class _Int(DOMWidget):
24 """Base class used to create widgets that represent an int."""
24 """Base class used to create widgets that represent an int."""
25 value = CInt(0, help="Int value", sync=True)
25 value = CInt(0, help="Int value", sync=True)
26 disabled = Bool(False, help="Enable or disable user changes", sync=True)
26 disabled = Bool(False, help="Enable or disable user changes", sync=True)
27 description = Unicode(help="Description of the value this widget represents", sync=True)
27 description = Unicode(help="Description of the value this widget represents", sync=True)
28
28
29 def __init__(self, value=None, **kwargs):
29 def __init__(self, value=None, **kwargs):
30 if value is not None:
30 if value is not None:
31 kwargs['value'] = value
31 kwargs['value'] = value
32 super(_Int, self).__init__(**kwargs)
32 super(_Int, self).__init__(**kwargs)
33
33
34 class _BoundedInt(_Int):
34 class _BoundedInt(_Int):
35 """Base class used to create widgets that represent a int that is bounded
35 """Base class used to create widgets that represent a int that is bounded
36 by a minium and maximum."""
36 by a minium and maximum."""
37 step = CInt(1, help="Minimum step that the value can take (ignored by some views)", sync=True)
37 step = CInt(1, help="Minimum step that the value can take (ignored by some views)", sync=True)
38 max = CInt(100, help="Max value", sync=True)
38 max = CInt(100, help="Max value", sync=True)
39 min = CInt(0, help="Min value", sync=True)
39 min = CInt(0, help="Min value", sync=True)
40
40
41 def __init__(self, *pargs, **kwargs):
41 def __init__(self, *pargs, **kwargs):
42 """Constructor"""
42 """Constructor"""
43 super(_BoundedInt, self).__init__(*pargs, **kwargs)
43 super(_BoundedInt, self).__init__(*pargs, **kwargs)
44 self.on_trait_change(self._validate_value, ['value'])
44 self.on_trait_change(self._validate_value, ['value'])
45 self.on_trait_change(self._handle_max_changed, ['max'])
45 self.on_trait_change(self._handle_max_changed, ['max'])
46 self.on_trait_change(self._handle_min_changed, ['min'])
46 self.on_trait_change(self._handle_min_changed, ['min'])
47
47
48 def _validate_value(self, name, old, new):
48 def _validate_value(self, name, old, new):
49 """Validate value."""
49 """Validate value."""
50 if self.min > new or new > self.max:
50 if self.min > new or new > self.max:
51 self.value = min(max(new, self.min), self.max)
51 self.value = min(max(new, self.min), self.max)
52
52
53 def _handle_max_changed(self, name, old, new):
53 def _handle_max_changed(self, name, old, new):
54 """Make sure the min is always <= the max."""
54 """Make sure the min is always <= the max."""
55 if new < self.min:
55 if new < self.min:
56 raise ValueError("setting max < min")
56 raise ValueError("setting max < min")
57
57
58 def _handle_min_changed(self, name, old, new):
58 def _handle_min_changed(self, name, old, new):
59 """Make sure the max is always >= the min."""
59 """Make sure the max is always >= the min."""
60 if new > self.max:
60 if new > self.max:
61 raise ValueError("setting min > max")
61 raise ValueError("setting min > max")
62
62
63 @register('IPython.IntText')
63 @register('IPython.IntText')
64 class IntText(_Int):
64 class IntText(_Int):
65 """Textbox widget that represents a int."""
65 """Textbox widget that represents a int."""
66 _view_name = Unicode('IntTextView', sync=True)
66 _view_name = Unicode('IntTextView', sync=True)
67
67
68
68
69 @register('IPython.BoundedIntText')
69 @register('IPython.BoundedIntText')
70 class BoundedIntText(_BoundedInt):
70 class BoundedIntText(_BoundedInt):
71 """Textbox widget that represents a int bounded by a minimum and maximum value."""
71 """Textbox widget that represents a int bounded by a minimum and maximum value."""
72 _view_name = Unicode('IntTextView', sync=True)
72 _view_name = Unicode('IntTextView', sync=True)
73
73
74
74
75 @register('IPython.IntSlider')
75 @register('IPython.IntSlider')
76 class IntSlider(_BoundedInt):
76 class IntSlider(_BoundedInt):
77 """Slider widget that represents a int bounded by a minimum and maximum value."""
77 """Slider widget that represents a int bounded by a minimum and maximum value."""
78 _view_name = Unicode('IntSliderView', sync=True)
78 _view_name = Unicode('IntSliderView', sync=True)
79 orientation = CaselessStrEnum(values=['horizontal', 'vertical'],
79 orientation = CaselessStrEnum(values=['horizontal', 'vertical'],
80 default_value='horizontal', allow_none=False,
80 default_value='horizontal', allow_none=False,
81 help="Vertical or horizontal.", sync=True)
81 help="Vertical or horizontal.", sync=True)
82 _range = Bool(False, help="Display a range selector", sync=True)
82 _range = Bool(False, help="Display a range selector", sync=True)
83 readout = Bool(True, help="Display the current value of the slider next to it.", sync=True)
83 readout = Bool(True, help="Display the current value of the slider next to it.", sync=True)
84 slider_color = Unicode(sync=True)
84 slider_color = Unicode(sync=True)
85
85
86
86
87 @register('IPython.IntProgress')
87 @register('IPython.IntProgress')
88 class IntProgress(_BoundedInt):
88 class IntProgress(_BoundedInt):
89 """Progress bar that represents a int bounded by a minimum and maximum value."""
89 """Progress bar that represents a int bounded by a minimum and maximum value."""
90 _view_name = Unicode('ProgressView', sync=True)
90 _view_name = Unicode('ProgressView', sync=True)
91
91
92 bar_style = CaselessStrEnum(
92 bar_style = CaselessStrEnum(
93 values=['success', 'info', 'warning', 'danger', ''],
93 values=['success', 'info', 'warning', 'danger', ''],
94 default_value='', allow_none=True, sync=True, help="""Use a
94 default_value='', allow_none=True, sync=True, help="""Use a
95 predefined styling for the progess bar.""")
95 predefined styling for the progess bar.""")
96
96
97 class _IntRange(_Int):
97 class _IntRange(_Int):
98 value = Tuple(CInt, CInt, default_value=(0, 1), help="Tuple of (lower, upper) bounds", sync=True)
98 value = Tuple(CInt, CInt, default_value=(0, 1), help="Tuple of (lower, upper) bounds", sync=True)
99 lower = CInt(0, help="Lower bound", sync=False)
99 lower = CInt(0, help="Lower bound", sync=False)
100 upper = CInt(1, help="Upper bound", sync=False)
100 upper = CInt(1, help="Upper bound", sync=False)
101
101
102 def __init__(self, *pargs, **kwargs):
102 def __init__(self, *pargs, **kwargs):
103 value_given = 'value' in kwargs
103 value_given = 'value' in kwargs
104 lower_given = 'lower' in kwargs
104 lower_given = 'lower' in kwargs
105 upper_given = 'upper' in kwargs
105 upper_given = 'upper' in kwargs
106 if value_given and (lower_given or upper_given):
106 if value_given and (lower_given or upper_given):
107 raise ValueError("Cannot specify both 'value' and 'lower'/'upper' for range widget")
107 raise ValueError("Cannot specify both 'value' and 'lower'/'upper' for range widget")
108 if lower_given != upper_given:
108 if lower_given != upper_given:
109 raise ValueError("Must specify both 'lower' and 'upper' for range widget")
109 raise ValueError("Must specify both 'lower' and 'upper' for range widget")
110
110
111 super(_IntRange, self).__init__(*pargs, **kwargs)
111 super(_IntRange, self).__init__(*pargs, **kwargs)
112
112
113 # ensure the traits match, preferring whichever (if any) was given in kwargs
113 # ensure the traits match, preferring whichever (if any) was given in kwargs
114 if value_given:
114 if value_given:
115 self.lower, self.upper = self.value
115 self.lower, self.upper = self.value
116 else:
116 else:
117 self.value = (self.lower, self.upper)
117 self.value = (self.lower, self.upper)
118
118
119 self.on_trait_change(self._validate, ['value', 'upper', 'lower'])
119 self.on_trait_change(self._validate, ['value', 'upper', 'lower'])
120
120
121 def _validate(self, name, old, new):
121 def _validate(self, name, old, new):
122 if name == 'value':
122 if name == 'value':
123 self.lower, self.upper = min(new), max(new)
123 self.lower, self.upper = min(new), max(new)
124 elif name == 'lower':
124 elif name == 'lower':
125 self.value = (new, self.value[1])
125 self.value = (new, self.value[1])
126 elif name == 'upper':
126 elif name == 'upper':
127 self.value = (self.value[0], new)
127 self.value = (self.value[0], new)
128
128
129 class _BoundedIntRange(_IntRange):
129 class _BoundedIntRange(_IntRange):
130 step = CInt(1, help="Minimum step that the value can take (ignored by some views)", sync=True)
130 step = CInt(1, help="Minimum step that the value can take (ignored by some views)", sync=True)
131 max = CInt(100, help="Max value", sync=True)
131 max = CInt(100, help="Max value", sync=True)
132 min = CInt(0, help="Min value", sync=True)
132 min = CInt(0, help="Min value", sync=True)
133
133
134 def __init__(self, *pargs, **kwargs):
134 def __init__(self, *pargs, **kwargs):
135 any_value_given = 'value' in kwargs or 'upper' in kwargs or 'lower' in kwargs
135 any_value_given = 'value' in kwargs or 'upper' in kwargs or 'lower' in kwargs
136 _IntRange.__init__(self, *pargs, **kwargs)
136 _IntRange.__init__(self, *pargs, **kwargs)
137
137
138 # ensure a minimal amount of sanity
138 # ensure a minimal amount of sanity
139 if self.min > self.max:
139 if self.min > self.max:
140 raise ValueError("min must be <= max")
140 raise ValueError("min must be <= max")
141
141
142 if any_value_given:
142 if any_value_given:
143 # if a value was given, clamp it within (min, max)
143 # if a value was given, clamp it within (min, max)
144 self._validate("value", None, self.value)
144 self._validate("value", None, self.value)
145 else:
145 else:
146 # otherwise, set it to 25-75% to avoid the handles overlapping
146 # otherwise, set it to 25-75% to avoid the handles overlapping
147 self.value = (0.75*self.min + 0.25*self.max,
147 self.value = (0.75*self.min + 0.25*self.max,
148 0.25*self.min + 0.75*self.max)
148 0.25*self.min + 0.75*self.max)
149 # callback already set for 'value', 'lower', 'upper'
149 # callback already set for 'value', 'lower', 'upper'
150 self.on_trait_change(self._validate, ['min', 'max'])
150 self.on_trait_change(self._validate, ['min', 'max'])
151
151
152 def _validate(self, name, old, new):
152 def _validate(self, name, old, new):
153 if name == "min":
153 if name == "min":
154 if new > self.max:
154 if new > self.max:
155 raise ValueError("setting min > max")
155 raise ValueError("setting min > max")
156 elif name == "max":
156 elif name == "max":
157 if new < self.min:
157 if new < self.min:
158 raise ValueError("setting max < min")
158 raise ValueError("setting max < min")
159
159
160 low, high = self.value
160 low, high = self.value
161 if name == "value":
161 if name == "value":
162 low, high = min(new), max(new)
162 low, high = min(new), max(new)
163 elif name == "upper":
163 elif name == "upper":
164 if new < self.lower:
164 if new < self.lower:
165 raise ValueError("setting upper < lower")
165 raise ValueError("setting upper < lower")
166 high = new
166 high = new
167 elif name == "lower":
167 elif name == "lower":
168 if new > self.upper:
168 if new > self.upper:
169 raise ValueError("setting lower > upper")
169 raise ValueError("setting lower > upper")
170 low = new
170 low = new
171
171
172 low = max(self.min, min(low, self.max))
172 low = max(self.min, min(low, self.max))
173 high = min(self.max, max(high, self.min))
173 high = min(self.max, max(high, self.min))
174
174
175 # determine the order in which we should update the
175 # determine the order in which we should update the
176 # lower, upper traits to avoid a temporary inverted overlap
176 # lower, upper traits to avoid a temporary inverted overlap
177 lower_first = high < self.lower
177 lower_first = high < self.lower
178
178
179 self.value = (low, high)
179 self.value = (low, high)
180 if lower_first:
180 if lower_first:
181 self.lower = low
181 self.lower = low
182 self.upper = high
182 self.upper = high
183 else:
183 else:
184 self.upper = high
184 self.upper = high
185 self.lower = low
185 self.lower = low
186
186
187 @register('IPython.IntRangeSlider')
187 @register('IPython.IntRangeSlider')
188 class IntRangeSlider(_BoundedIntRange):
188 class IntRangeSlider(_BoundedIntRange):
189 """Slider widget that represents a pair of ints between a minimum and maximum value."""
189 _view_name = Unicode('IntSliderView', sync=True)
190 _view_name = Unicode('IntSliderView', sync=True)
190 orientation = CaselessStrEnum(values=['horizontal', 'vertical'],
191 orientation = CaselessStrEnum(values=['horizontal', 'vertical'],
191 default_value='horizontal', allow_none=False,
192 default_value='horizontal', allow_none=False,
192 help="Vertical or horizontal.", sync=True)
193 help="Vertical or horizontal.", sync=True)
193 _range = Bool(True, help="Display a range selector", sync=True)
194 _range = Bool(True, help="Display a range selector", sync=True)
194 readout = Bool(True, help="Display the current value of the slider next to it.", sync=True)
195 readout = Bool(True, help="Display the current value of the slider next to it.", sync=True)
195 slider_color = Unicode(sync=True)
196 slider_color = Unicode(sync=True)
196
197
197 # Remove in IPython 4.0
198 # Remove in IPython 4.0
198 IntTextWidget = DeprecatedClass(IntText, 'IntTextWidget')
199 IntTextWidget = DeprecatedClass(IntText, 'IntTextWidget')
199 BoundedIntTextWidget = DeprecatedClass(BoundedIntText, 'BoundedIntTextWidget')
200 BoundedIntTextWidget = DeprecatedClass(BoundedIntText, 'BoundedIntTextWidget')
200 IntSliderWidget = DeprecatedClass(IntSlider, 'IntSliderWidget')
201 IntSliderWidget = DeprecatedClass(IntSlider, 'IntSliderWidget')
201 IntProgressWidget = DeprecatedClass(IntProgress, 'IntProgressWidget')
202 IntProgressWidget = DeprecatedClass(IntProgress, 'IntProgressWidget')
General Comments 0
You need to be logged in to leave comments. Login now