##// END OF EJS Templates
move DeprecatedClass to widgets, where it's used...
Min RK -
Show More
@@ -0,0 +1,22 b''
1 """Decorator for warning about deprecated widget classes"""
2
3 # Copyright (c) IPython Development Team.
4 # Distributed under the terms of the Modified BSD License.
5
6 from warnings import warn
7
8
9 def DeprecatedClass(base, class_name):
10 """Warn about a deprecated class on instantiation"""
11 # Hook the init method of the base class.
12 def init_hook(self, *pargs, **kwargs):
13 base.__init__(self, *pargs, **kwargs)
14
15 # Warn once per class.
16 if base not in DeprecatedClass._warned_classes:
17 DeprecatedClass._warned_classes.append(base)
18 warn('"{}" is deprecated, please use "{}" instead.'.format(
19 class_name, base.__name__))
20 return type(class_name, (base,), {'__init__': init_hook})
21
22 DeprecatedClass._warned_classes = []
@@ -1,89 +1,80 b''
1 """Bool class.
1 """Bool class.
2 2
3 3 Represents a boolean using a widget.
4 4 """
5 #-----------------------------------------------------------------------------
6 # Copyright (c) 2013, the IPython Development Team.
7 #
5
6 # Copyright (c) IPython Development Team.
8 7 # Distributed under the terms of the Modified BSD License.
9 #
10 # The full license is in the file COPYING.txt, distributed with this software.
11 #-----------------------------------------------------------------------------
12 8
13 #-----------------------------------------------------------------------------
14 # Imports
15 #-----------------------------------------------------------------------------
16 9 from .widget import DOMWidget, register
17 10 from IPython.utils.traitlets import Unicode, Bool, CaselessStrEnum
18 from IPython.utils.warn import DeprecatedClass
11 from .deprecated import DeprecatedClass
12
19 13
20 #-----------------------------------------------------------------------------
21 # Classes
22 #-----------------------------------------------------------------------------
23 14 class _Bool(DOMWidget):
24 15 """A base class for creating widgets that represent booleans."""
25 16 value = Bool(False, help="Bool value", sync=True)
26 17 description = Unicode('', help="Description of the boolean (label).", sync=True)
27 18 disabled = Bool(False, help="Enable or disable user changes.", sync=True)
28 19
29 20 def __init__(self, value=None, **kwargs):
30 21 if value is not None:
31 22 kwargs['value'] = value
32 23 super(_Bool, self).__init__(**kwargs)
33 24
34 25 @register('IPython.Checkbox')
35 26 class Checkbox(_Bool):
36 27 """Displays a boolean `value` in the form of a checkbox.
37 28
38 29 Parameters
39 30 ----------
40 31 value : {True,False}
41 32 value of the checkbox: True-checked, False-unchecked
42 33 description : str
43 34 description displayed next to the checkbox
44 35 """
45 36 _view_name = Unicode('CheckboxView', sync=True)
46 37
47 38
48 39 @register('IPython.ToggleButton')
49 40 class ToggleButton(_Bool):
50 41 """Displays a boolean `value` in the form of a toggle button.
51 42
52 43 Parameters
53 44 ----------
54 45 value : {True,False}
55 46 value of the toggle button: True-pressed, False-unpressed
56 47 description : str
57 48 description displayed next to the button
58 49 tooltip: str
59 50 tooltip caption of the toggle button
60 51 icon: str
61 52 font-awesome icon name
62 53 """
63 54 _view_name = Unicode('ToggleButtonView', sync=True)
64 55 tooltip = Unicode(help="Tooltip caption of the toggle button.", sync=True)
65 56 icon = Unicode('', help= "Font-awesome icon.", sync=True)
66 57
67 58 button_style = CaselessStrEnum(
68 59 values=['primary', 'success', 'info', 'warning', 'danger', ''],
69 60 default_value='', allow_none=True, sync=True, help="""Use a
70 61 predefined styling for the button.""")
71 62
72 63
73 64 @register('IPython.Valid')
74 65 class Valid(_Bool):
75 66
76 67 """Displays a boolean `value` in the form of a green check (True / valid)
77 68 or a red cross (False / invalid).
78 69
79 70 Parameters
80 71 ----------
81 72 value: {True,False}
82 73 value of the Valid widget
83 74 """
84 75 readout = Unicode(help="Message displayed when the value is False", sync=True)
85 76 _view_name = Unicode('ValidView', sync=True)
86 77
87 78 # Remove in IPython 4.0
88 79 CheckboxWidget = DeprecatedClass(Checkbox, 'CheckboxWidget')
89 80 ToggleButtonWidget = DeprecatedClass(ToggleButton, 'ToggleButtonWidget')
@@ -1,107 +1,107 b''
1 1 """Box class.
2 2
3 3 Represents a container that can be used to group other widgets.
4 4 """
5 5
6 6 # Copyright (c) IPython Development Team.
7 7 # Distributed under the terms of the Modified BSD License.
8 8
9 9 from .widget import DOMWidget, Widget, register
10 10 from IPython.utils.traitlets import Unicode, Tuple, TraitError, Int, CaselessStrEnum
11 from IPython.utils.warn import DeprecatedClass
11 from .deprecated import DeprecatedClass
12 12
13 13 def _widget_to_json(x):
14 14 if isinstance(x, dict):
15 15 return {k: _widget_to_json(v) for k, v in x.items()}
16 16 elif isinstance(x, (list, tuple)):
17 17 return [_widget_to_json(v) for v in x]
18 18 elif isinstance(x, Widget):
19 19 return "IPY_MODEL_" + x.model_id
20 20 else:
21 21 return x
22 22
23 23 def _json_to_widget(x):
24 24 if isinstance(x, dict):
25 25 return {k: _json_to_widget(v) for k, v in x.items()}
26 26 elif isinstance(x, (list, tuple)):
27 27 return [_json_to_widget(v) for v in x]
28 28 elif isinstance(x, string_types) and x.startswith('IPY_MODEL_') and x[10:] in Widget.widgets:
29 29 return Widget.widgets[x[10:]]
30 30 else:
31 31 return x
32 32
33 33 widget_serialization = {
34 34 'from_json': _json_to_widget,
35 35 'to_json': _widget_to_json
36 36 }
37 37
38 38
39 39 @register('IPython.Box')
40 40 class Box(DOMWidget):
41 41 """Displays multiple widgets in a group."""
42 42 _model_name = Unicode('BoxModel', sync=True)
43 43 _view_name = Unicode('BoxView', sync=True)
44 44
45 45 # Child widgets in the container.
46 46 # Using a tuple here to force reassignment to update the list.
47 47 # When a proper notifying-list trait exists, that is what should be used here.
48 48 children = Tuple(sync=True, **widget_serialization)
49 49
50 50 _overflow_values = ['visible', 'hidden', 'scroll', 'auto', 'initial', 'inherit', '']
51 51 overflow_x = CaselessStrEnum(
52 52 values=_overflow_values,
53 53 default_value='', sync=True, help="""Specifies what
54 54 happens to content that is too large for the rendered region.""")
55 55 overflow_y = CaselessStrEnum(
56 56 values=_overflow_values,
57 57 default_value='', sync=True, help="""Specifies what
58 58 happens to content that is too large for the rendered region.""")
59 59
60 60 box_style = CaselessStrEnum(
61 61 values=['success', 'info', 'warning', 'danger', ''],
62 62 default_value='', allow_none=True, sync=True, help="""Use a
63 63 predefined styling for the box.""")
64 64
65 65 def __init__(self, children = (), **kwargs):
66 66 kwargs['children'] = children
67 67 super(Box, self).__init__(**kwargs)
68 68 self.on_displayed(Box._fire_children_displayed)
69 69
70 70 def _fire_children_displayed(self):
71 71 for child in self.children:
72 72 child._handle_displayed()
73 73
74 74
75 75 @register('IPython.FlexBox')
76 76 class FlexBox(Box):
77 77 """Displays multiple widgets using the flexible box model."""
78 78 _view_name = Unicode('FlexBoxView', sync=True)
79 79 orientation = CaselessStrEnum(values=['vertical', 'horizontal'], default_value='vertical', sync=True)
80 80 flex = Int(0, sync=True, help="""Specify the flexible-ness of the model.""")
81 81 def _flex_changed(self, name, old, new):
82 82 new = min(max(0, new), 2)
83 83 if self.flex != new:
84 84 self.flex = new
85 85
86 86 _locations = ['start', 'center', 'end', 'baseline', 'stretch']
87 87 pack = CaselessStrEnum(
88 88 values=_locations,
89 89 default_value='start', sync=True)
90 90 align = CaselessStrEnum(
91 91 values=_locations,
92 92 default_value='start', sync=True)
93 93
94 94
95 95 def VBox(*pargs, **kwargs):
96 96 """Displays multiple widgets vertically using the flexible box model."""
97 97 kwargs['orientation'] = 'vertical'
98 98 return FlexBox(*pargs, **kwargs)
99 99
100 100 def HBox(*pargs, **kwargs):
101 101 """Displays multiple widgets horizontally using the flexible box model."""
102 102 kwargs['orientation'] = 'horizontal'
103 103 return FlexBox(*pargs, **kwargs)
104 104
105 105
106 106 # Remove in IPython 4.0
107 107 ContainerWidget = DeprecatedClass(Box, 'ContainerWidget')
@@ -1,82 +1,73 b''
1 """Button class.
1 """Button class.
2 2
3 3 Represents a button in the frontend using a widget. Allows user to listen for
4 4 click events on the button and trigger backend code when the clicks are fired.
5 5 """
6 #-----------------------------------------------------------------------------
7 # Copyright (c) 2013, the IPython Development Team.
8 #
6
7 # Copyright (c) IPython Development Team.
9 8 # Distributed under the terms of the Modified BSD License.
10 #
11 # The full license is in the file COPYING.txt, distributed with this software.
12 #-----------------------------------------------------------------------------
13 9
14 #-----------------------------------------------------------------------------
15 # Imports
16 #-----------------------------------------------------------------------------
17 10 from .widget import DOMWidget, CallbackDispatcher, register
18 11 from IPython.utils.traitlets import Unicode, Bool, CaselessStrEnum
19 from IPython.utils.warn import DeprecatedClass
12 from .deprecated import DeprecatedClass
13
20 14
21 #-----------------------------------------------------------------------------
22 # Classes
23 #-----------------------------------------------------------------------------
24 15 @register('IPython.Button')
25 16 class Button(DOMWidget):
26 17 """Button widget.
27 18 This widget has an `on_click` method that allows you to listen for the
28 19 user clicking on the button. The click event itself is stateless.
29 20
30 21 Parameters
31 22 ----------
32 23 description : str
33 24 description displayed next to the button
34 25 tooltip: str
35 26 tooltip caption of the toggle button
36 27 icon: str
37 28 font-awesome icon name
38 29 """
39 30 _view_name = Unicode('ButtonView', sync=True)
40 31
41 32 # Keys
42 33 description = Unicode('', help="Button label.", sync=True)
43 34 tooltip = Unicode(help="Tooltip caption of the button.", sync=True)
44 35 disabled = Bool(False, help="Enable or disable user changes.", sync=True)
45 36 icon = Unicode('', help= "Font-awesome icon.", sync=True)
46 37
47 38 button_style = CaselessStrEnum(
48 39 values=['primary', 'success', 'info', 'warning', 'danger', ''],
49 40 default_value='', allow_none=True, sync=True, help="""Use a
50 41 predefined styling for the button.""")
51 42
52 43 def __init__(self, **kwargs):
53 44 """Constructor"""
54 45 super(Button, self).__init__(**kwargs)
55 46 self._click_handlers = CallbackDispatcher()
56 47 self.on_msg(self._handle_button_msg)
57 48
58 49 def on_click(self, callback, remove=False):
59 50 """Register a callback to execute when the button is clicked.
60 51
61 52 The callback will be called with one argument,
62 53 the clicked button widget instance.
63 54
64 55 Parameters
65 56 ----------
66 57 remove : bool (optional)
67 58 Set to true to remove the callback from the list of callbacks."""
68 59 self._click_handlers.register_callback(callback, remove=remove)
69 60
70 61 def _handle_button_msg(self, _, content, buffers):
71 62 """Handle a msg from the front-end.
72 63
73 64 Parameters
74 65 ----------
75 66 content: dict
76 67 Content of the msg."""
77 68 if content.get('event', '') == 'click':
78 69 self._click_handlers(self)
79 70
80 71
81 72 # Remove in IPython 4.0
82 73 ButtonWidget = DeprecatedClass(Button, 'ButtonWidget')
@@ -1,296 +1,287 b''
1 1 """Float class.
2 2
3 3 Represents an unbounded float using a widget.
4 4 """
5 #-----------------------------------------------------------------------------
6 # Copyright (c) 2013, the IPython Development Team.
7 #
5
6 # Copyright (c) IPython Development Team.
8 7 # Distributed under the terms of the Modified BSD License.
9 #
10 # The full license is in the file COPYING.txt, distributed with this software.
11 #-----------------------------------------------------------------------------
12 8
13 #-----------------------------------------------------------------------------
14 # Imports
15 #-----------------------------------------------------------------------------
16 9 from .widget import DOMWidget, register
17 10 from .trait_types import Color
18 11 from IPython.utils.traitlets import (Unicode, CFloat, Bool, CaselessStrEnum,
19 12 Tuple, TraitError)
20 from IPython.utils.warn import DeprecatedClass
13 from .deprecated import DeprecatedClass
14
21 15
22 #-----------------------------------------------------------------------------
23 # Classes
24 #-----------------------------------------------------------------------------
25 16 class _Float(DOMWidget):
26 17 value = CFloat(0.0, help="Float value", sync=True)
27 18 disabled = Bool(False, help="Enable or disable user changes", sync=True)
28 19 description = Unicode(help="Description of the value this widget represents", sync=True)
29 20
30 21 def __init__(self, value=None, **kwargs):
31 22 if value is not None:
32 23 kwargs['value'] = value
33 24 super(_Float, self).__init__(**kwargs)
34 25
35 26
36 27 class _BoundedFloat(_Float):
37 28 max = CFloat(100.0, help="Max value", sync=True)
38 29 min = CFloat(0.0, help="Min value", sync=True)
39 30 step = CFloat(0.1, help="Minimum step to increment the value (ignored by some views)", sync=True)
40 31
41 32 def __init__(self, *pargs, **kwargs):
42 33 """Constructor"""
43 34 super(_BoundedFloat, self).__init__(*pargs, **kwargs)
44 35
45 36 def _value_validate(self, value, trait):
46 37 """Cap and floor value"""
47 38 if self.min > value or self.max < value:
48 39 value = min(max(value, self.min), self.max)
49 40 return value
50 41
51 42 def _min_validate(self, min, trait):
52 43 """Enforce min <= value <= max"""
53 44 if min > self.max:
54 45 raise TraitError("Setting min > max")
55 46 if min > self.value:
56 47 self.value = min
57 48 return min
58 49
59 50 def _max_validate(self, max, trait):
60 51 """Enforce min <= value <= max"""
61 52 if max < self.min:
62 53 raise TraitError("setting max < min")
63 54 if max < self.value:
64 55 self.value = max
65 56 return max
66 57
67 58
68 59 @register('IPython.FloatText')
69 60 class FloatText(_Float):
70 61 """ Displays a float value within a textbox. For a textbox in
71 62 which the value must be within a specific range, use BoundedFloatText.
72 63
73 64 Parameters
74 65 ----------
75 66 value : float
76 67 value displayed
77 68 description : str
78 69 description displayed next to the text box
79 70 color : str Unicode color code (eg. '#C13535'), optional
80 71 color of the value displayed
81 72 """
82 73 _view_name = Unicode('FloatTextView', sync=True)
83 74
84 75
85 76 @register('IPython.BoundedFloatText')
86 77 class BoundedFloatText(_BoundedFloat):
87 78 """ Displays a float value within a textbox. Value must be within the range specified.
88 79 For a textbox in which the value doesn't need to be within a specific range, use FloatText.
89 80
90 81 Parameters
91 82 ----------
92 83 value : float
93 84 value displayed
94 85 min : float
95 86 minimal value of the range of possible values displayed
96 87 max : float
97 88 maximal value of the range of possible values displayed
98 89 description : str
99 90 description displayed next to the textbox
100 91 color : str Unicode color code (eg. '#C13535'), optional
101 92 color of the value displayed
102 93 """
103 94 _view_name = Unicode('FloatTextView', sync=True)
104 95
105 96
106 97 @register('IPython.FloatSlider')
107 98 class FloatSlider(_BoundedFloat):
108 99 """ Slider/trackbar of floating values with the specified range.
109 100
110 101 Parameters
111 102 ----------
112 103 value : float
113 104 position of the slider
114 105 min : float
115 106 minimal position of the slider
116 107 max : float
117 108 maximal position of the slider
118 109 step : float
119 110 step of the trackbar
120 111 description : str
121 112 name of the slider
122 113 orientation : {'vertical', 'horizontal}, optional
123 114 default is horizontal
124 115 readout : {True, False}, optional
125 116 default is True, display the current value of the slider next to it
126 117 slider_color : str Unicode color code (eg. '#C13535'), optional
127 118 color of the slider
128 119 color : str Unicode color code (eg. '#C13535'), optional
129 120 color of the value displayed (if readout == True)
130 121 """
131 122 _view_name = Unicode('FloatSliderView', sync=True)
132 123 orientation = CaselessStrEnum(values=['horizontal', 'vertical'],
133 124 default_value='horizontal', help="Vertical or horizontal.", sync=True)
134 125 _range = Bool(False, help="Display a range selector", sync=True)
135 126 readout = Bool(True, help="Display the current value of the slider next to it.", sync=True)
136 127 slider_color = Color(None, allow_none=True, sync=True)
137 128
138 129
139 130 @register('IPython.FloatProgress')
140 131 class FloatProgress(_BoundedFloat):
141 132 """ Displays a progress bar.
142 133
143 134 Parameters
144 135 -----------
145 136 value : float
146 137 position within the range of the progress bar
147 138 min : float
148 139 minimal position of the slider
149 140 max : float
150 141 maximal position of the slider
151 142 step : float
152 143 step of the progress bar
153 144 description : str
154 145 name of the progress bar
155 146 bar_style: {'success', 'info', 'warning', 'danger', ''}, optional
156 147 color of the progress bar, default is '' (blue)
157 148 colors are: 'success'-green, 'info'-light blue, 'warning'-orange, 'danger'-red
158 149 """
159 150 _view_name = Unicode('ProgressView', sync=True)
160 151
161 152 bar_style = CaselessStrEnum(
162 153 values=['success', 'info', 'warning', 'danger', ''],
163 154 default_value='', allow_none=True, sync=True, help="""Use a
164 155 predefined styling for the progess bar.""")
165 156
166 157 class _FloatRange(_Float):
167 158 value = Tuple(CFloat, CFloat, default_value=(0.0, 1.0), help="Tuple of (lower, upper) bounds", sync=True)
168 159 lower = CFloat(0.0, help="Lower bound", sync=False)
169 160 upper = CFloat(1.0, help="Upper bound", sync=False)
170 161
171 162 def __init__(self, *pargs, **kwargs):
172 163 value_given = 'value' in kwargs
173 164 lower_given = 'lower' in kwargs
174 165 upper_given = 'upper' in kwargs
175 166 if value_given and (lower_given or upper_given):
176 167 raise ValueError("Cannot specify both 'value' and 'lower'/'upper' for range widget")
177 168 if lower_given != upper_given:
178 169 raise ValueError("Must specify both 'lower' and 'upper' for range widget")
179 170
180 171 DOMWidget.__init__(self, *pargs, **kwargs)
181 172
182 173 # ensure the traits match, preferring whichever (if any) was given in kwargs
183 174 if value_given:
184 175 self.lower, self.upper = self.value
185 176 else:
186 177 self.value = (self.lower, self.upper)
187 178
188 179 self.on_trait_change(self._validate, ['value', 'upper', 'lower'])
189 180
190 181 def _validate(self, name, old, new):
191 182 if name == 'value':
192 183 self.lower, self.upper = min(new), max(new)
193 184 elif name == 'lower':
194 185 self.value = (new, self.value[1])
195 186 elif name == 'upper':
196 187 self.value = (self.value[0], new)
197 188
198 189 class _BoundedFloatRange(_FloatRange):
199 190 step = CFloat(1.0, help="Minimum step that the value can take (ignored by some views)", sync=True)
200 191 max = CFloat(100.0, help="Max value", sync=True)
201 192 min = CFloat(0.0, help="Min value", sync=True)
202 193
203 194 def __init__(self, *pargs, **kwargs):
204 195 any_value_given = 'value' in kwargs or 'upper' in kwargs or 'lower' in kwargs
205 196 _FloatRange.__init__(self, *pargs, **kwargs)
206 197
207 198 # ensure a minimal amount of sanity
208 199 if self.min > self.max:
209 200 raise ValueError("min must be <= max")
210 201
211 202 if any_value_given:
212 203 # if a value was given, clamp it within (min, max)
213 204 self._validate("value", None, self.value)
214 205 else:
215 206 # otherwise, set it to 25-75% to avoid the handles overlapping
216 207 self.value = (0.75*self.min + 0.25*self.max,
217 208 0.25*self.min + 0.75*self.max)
218 209 # callback already set for 'value', 'lower', 'upper'
219 210 self.on_trait_change(self._validate, ['min', 'max'])
220 211
221 212
222 213 def _validate(self, name, old, new):
223 214 if name == "min":
224 215 if new > self.max:
225 216 raise ValueError("setting min > max")
226 217 self.min = new
227 218 elif name == "max":
228 219 if new < self.min:
229 220 raise ValueError("setting max < min")
230 221 self.max = new
231 222
232 223 low, high = self.value
233 224 if name == "value":
234 225 low, high = min(new), max(new)
235 226 elif name == "upper":
236 227 if new < self.lower:
237 228 raise ValueError("setting upper < lower")
238 229 high = new
239 230 elif name == "lower":
240 231 if new > self.upper:
241 232 raise ValueError("setting lower > upper")
242 233 low = new
243 234
244 235 low = max(self.min, min(low, self.max))
245 236 high = min(self.max, max(high, self.min))
246 237
247 238 # determine the order in which we should update the
248 239 # lower, upper traits to avoid a temporary inverted overlap
249 240 lower_first = high < self.lower
250 241
251 242 self.value = (low, high)
252 243 if lower_first:
253 244 self.lower = low
254 245 self.upper = high
255 246 else:
256 247 self.upper = high
257 248 self.lower = low
258 249
259 250
260 251 @register('IPython.FloatRangeSlider')
261 252 class FloatRangeSlider(_BoundedFloatRange):
262 253 """ Slider/trackbar for displaying a floating value range (within the specified range of values).
263 254
264 255 Parameters
265 256 ----------
266 257 value : float tuple
267 258 range of the slider displayed
268 259 min : float
269 260 minimal position of the slider
270 261 max : float
271 262 maximal position of the slider
272 263 step : float
273 264 step of the trackbar
274 265 description : str
275 266 name of the slider
276 267 orientation : {'vertical', 'horizontal}, optional
277 268 default is horizontal
278 269 readout : {True, False}, optional
279 270 default is True, display the current value of the slider next to it
280 271 slider_color : str Unicode color code (eg. '#C13535'), optional
281 272 color of the slider
282 273 color : str Unicode color code (eg. '#C13535'), optional
283 274 color of the value displayed (if readout == True)
284 275 """
285 276 _view_name = Unicode('FloatSliderView', sync=True)
286 277 orientation = CaselessStrEnum(values=['horizontal', 'vertical'],
287 278 default_value='horizontal', help="Vertical or horizontal.", sync=True)
288 279 _range = Bool(True, help="Display a range selector", sync=True)
289 280 readout = Bool(True, help="Display the current value of the slider next to it.", sync=True)
290 281 slider_color = Color(None, allow_none=True, sync=True)
291 282
292 283 # Remove in IPython 4.0
293 284 FloatTextWidget = DeprecatedClass(FloatText, 'FloatTextWidget')
294 285 BoundedFloatTextWidget = DeprecatedClass(BoundedFloatText, 'BoundedFloatTextWidget')
295 286 FloatSliderWidget = DeprecatedClass(FloatSlider, 'FloatSliderWidget')
296 287 FloatProgressWidget = DeprecatedClass(FloatProgress, 'FloatProgressWidget')
@@ -1,47 +1,37 b''
1 """Image class.
1 """Image class.
2 2
3 3 Represents an image in the frontend using a widget.
4 4 """
5 #-----------------------------------------------------------------------------
6 # Copyright (c) 2013, the IPython Development Team.
7 #
5
6 # Copyright (c) IPython Development Team.
8 7 # Distributed under the terms of the Modified BSD License.
9 #
10 # The full license is in the file COPYING.txt, distributed with this software.
11 #-----------------------------------------------------------------------------
12 8
13 #-----------------------------------------------------------------------------
14 # Imports
15 #-----------------------------------------------------------------------------
16 9 import base64
17 10
18 11 from .widget import DOMWidget, register
19 12 from IPython.utils.traitlets import Unicode, CUnicode, Bytes
20 from IPython.utils.warn import DeprecatedClass
13 from .deprecated import DeprecatedClass
21 14
22 #-----------------------------------------------------------------------------
23 # Classes
24 #-----------------------------------------------------------------------------
25 15 @register('IPython.Image')
26 16 class Image(DOMWidget):
27 17 """Displays an image as a widget.
28 18
29 19 The `value` of this widget accepts a byte string. The byte string is the raw
30 20 image data that you want the browser to display. You can explicitly define
31 21 the format of the byte string using the `format` trait (which defaults to
32 22 "png")."""
33 23 _view_name = Unicode('ImageView', sync=True)
34 24
35 25 # Define the custom state properties to sync with the front-end
36 26 format = Unicode('png', sync=True)
37 27 width = CUnicode(sync=True)
38 28 height = CUnicode(sync=True)
39 29 _b64value = Unicode(sync=True)
40 30
41 31 value = Bytes()
42 32 def _value_changed(self, name, old, new):
43 33 self._b64value = base64.b64encode(new)
44 34
45 35
46 36 # Remove in IPython 4.0
47 37 ImageWidget = DeprecatedClass(Image, 'ImageWidget')
@@ -1,207 +1,198 b''
1 1 """Int class.
2 2
3 3 Represents an unbounded int using a widget.
4 4 """
5 #-----------------------------------------------------------------------------
6 # Copyright (c) 2013, the IPython Development Team.
7 #
5
6 # Copyright (c) IPython Development Team.
8 7 # Distributed under the terms of the Modified BSD License.
9 #
10 # The full license is in the file COPYING.txt, distributed with this software.
11 #-----------------------------------------------------------------------------
12 8
13 #-----------------------------------------------------------------------------
14 # Imports
15 #-----------------------------------------------------------------------------
16 9 from .widget import DOMWidget, register
17 10 from .trait_types import Color
18 11 from IPython.utils.traitlets import (Unicode, CInt, Bool, CaselessStrEnum,
19 12 Tuple, TraitError)
20 from IPython.utils.warn import DeprecatedClass
13 from .deprecated import DeprecatedClass
14
21 15
22 #-----------------------------------------------------------------------------
23 # Classes
24 #-----------------------------------------------------------------------------
25 16 class _Int(DOMWidget):
26 17 """Base class used to create widgets that represent an int."""
27 18 value = CInt(0, help="Int value", sync=True)
28 19 disabled = Bool(False, help="Enable or disable user changes", sync=True)
29 20 description = Unicode(help="Description of the value this widget represents", sync=True)
30 21
31 22 def __init__(self, value=None, **kwargs):
32 23 if value is not None:
33 24 kwargs['value'] = value
34 25 super(_Int, self).__init__(**kwargs)
35 26
36 27
37 28 class _BoundedInt(_Int):
38 29 """Base class used to create widgets that represent a int that is bounded
39 30 by a minium and maximum."""
40 31 step = CInt(1, help="Minimum step to increment the value (ignored by some views)", sync=True)
41 32 max = CInt(100, help="Max value", sync=True)
42 33 min = CInt(0, help="Min value", sync=True)
43 34
44 35 def __init__(self, *pargs, **kwargs):
45 36 """Constructor"""
46 37 super(_BoundedInt, self).__init__(*pargs, **kwargs)
47 38
48 39 def _value_validate(self, value, trait):
49 40 """Cap and floor value"""
50 41 if self.min > value or self.max < value:
51 42 value = min(max(value, self.min), self.max)
52 43 return value
53 44
54 45 def _min_validate(self, min, trait):
55 46 """Enforce min <= value <= max"""
56 47 if min > self.max:
57 48 raise TraitError("Setting min > max")
58 49 if min > self.value:
59 50 self.value = min
60 51 return min
61 52
62 53 def _max_validate(self, max, trait):
63 54 """Enforce min <= value <= max"""
64 55 if max < self.min:
65 56 raise TraitError("setting max < min")
66 57 if max < self.value:
67 58 self.value = max
68 59 return max
69 60
70 61 @register('IPython.IntText')
71 62 class IntText(_Int):
72 63 """Textbox widget that represents a int."""
73 64 _view_name = Unicode('IntTextView', sync=True)
74 65
75 66
76 67 @register('IPython.BoundedIntText')
77 68 class BoundedIntText(_BoundedInt):
78 69 """Textbox widget that represents a int bounded by a minimum and maximum value."""
79 70 _view_name = Unicode('IntTextView', sync=True)
80 71
81 72
82 73 @register('IPython.IntSlider')
83 74 class IntSlider(_BoundedInt):
84 75 """Slider widget that represents a int bounded by a minimum and maximum value."""
85 76 _view_name = Unicode('IntSliderView', sync=True)
86 77 orientation = CaselessStrEnum(values=['horizontal', 'vertical'],
87 78 default_value='horizontal', help="Vertical or horizontal.", sync=True)
88 79 _range = Bool(False, help="Display a range selector", sync=True)
89 80 readout = Bool(True, help="Display the current value of the slider next to it.", sync=True)
90 81 slider_color = Color(None, allow_none=True, sync=True)
91 82
92 83
93 84 @register('IPython.IntProgress')
94 85 class IntProgress(_BoundedInt):
95 86 """Progress bar that represents a int bounded by a minimum and maximum value."""
96 87 _view_name = Unicode('ProgressView', sync=True)
97 88
98 89 bar_style = CaselessStrEnum(
99 90 values=['success', 'info', 'warning', 'danger', ''],
100 91 default_value='', allow_none=True, sync=True, help="""Use a
101 92 predefined styling for the progess bar.""")
102 93
103 94 class _IntRange(_Int):
104 95 value = Tuple(CInt, CInt, default_value=(0, 1), help="Tuple of (lower, upper) bounds", sync=True)
105 96 lower = CInt(0, help="Lower bound", sync=False)
106 97 upper = CInt(1, help="Upper bound", sync=False)
107 98
108 99 def __init__(self, *pargs, **kwargs):
109 100 value_given = 'value' in kwargs
110 101 lower_given = 'lower' in kwargs
111 102 upper_given = 'upper' in kwargs
112 103 if value_given and (lower_given or upper_given):
113 104 raise ValueError("Cannot specify both 'value' and 'lower'/'upper' for range widget")
114 105 if lower_given != upper_given:
115 106 raise ValueError("Must specify both 'lower' and 'upper' for range widget")
116 107
117 108 super(_IntRange, self).__init__(*pargs, **kwargs)
118 109
119 110 # ensure the traits match, preferring whichever (if any) was given in kwargs
120 111 if value_given:
121 112 self.lower, self.upper = self.value
122 113 else:
123 114 self.value = (self.lower, self.upper)
124 115
125 116 self.on_trait_change(self._validate, ['value', 'upper', 'lower'])
126 117
127 118 def _validate(self, name, old, new):
128 119 if name == 'value':
129 120 self.lower, self.upper = min(new), max(new)
130 121 elif name == 'lower':
131 122 self.value = (new, self.value[1])
132 123 elif name == 'upper':
133 124 self.value = (self.value[0], new)
134 125
135 126 class _BoundedIntRange(_IntRange):
136 127 step = CInt(1, help="Minimum step that the value can take (ignored by some views)", sync=True)
137 128 max = CInt(100, help="Max value", sync=True)
138 129 min = CInt(0, help="Min value", sync=True)
139 130
140 131 def __init__(self, *pargs, **kwargs):
141 132 any_value_given = 'value' in kwargs or 'upper' in kwargs or 'lower' in kwargs
142 133 _IntRange.__init__(self, *pargs, **kwargs)
143 134
144 135 # ensure a minimal amount of sanity
145 136 if self.min > self.max:
146 137 raise ValueError("min must be <= max")
147 138
148 139 if any_value_given:
149 140 # if a value was given, clamp it within (min, max)
150 141 self._validate("value", None, self.value)
151 142 else:
152 143 # otherwise, set it to 25-75% to avoid the handles overlapping
153 144 self.value = (0.75*self.min + 0.25*self.max,
154 145 0.25*self.min + 0.75*self.max)
155 146 # callback already set for 'value', 'lower', 'upper'
156 147 self.on_trait_change(self._validate, ['min', 'max'])
157 148
158 149 def _validate(self, name, old, new):
159 150 if name == "min":
160 151 if new > self.max:
161 152 raise ValueError("setting min > max")
162 153 elif name == "max":
163 154 if new < self.min:
164 155 raise ValueError("setting max < min")
165 156
166 157 low, high = self.value
167 158 if name == "value":
168 159 low, high = min(new), max(new)
169 160 elif name == "upper":
170 161 if new < self.lower:
171 162 raise ValueError("setting upper < lower")
172 163 high = new
173 164 elif name == "lower":
174 165 if new > self.upper:
175 166 raise ValueError("setting lower > upper")
176 167 low = new
177 168
178 169 low = max(self.min, min(low, self.max))
179 170 high = min(self.max, max(high, self.min))
180 171
181 172 # determine the order in which we should update the
182 173 # lower, upper traits to avoid a temporary inverted overlap
183 174 lower_first = high < self.lower
184 175
185 176 self.value = (low, high)
186 177 if lower_first:
187 178 self.lower = low
188 179 self.upper = high
189 180 else:
190 181 self.upper = high
191 182 self.lower = low
192 183
193 184 @register('IPython.IntRangeSlider')
194 185 class IntRangeSlider(_BoundedIntRange):
195 186 """Slider widget that represents a pair of ints between a minimum and maximum value."""
196 187 _view_name = Unicode('IntSliderView', sync=True)
197 188 orientation = CaselessStrEnum(values=['horizontal', 'vertical'],
198 189 default_value='horizontal', help="Vertical or horizontal.", sync=True)
199 190 _range = Bool(True, help="Display a range selector", sync=True)
200 191 readout = Bool(True, help="Display the current value of the slider next to it.", sync=True)
201 192 slider_color = Color(None, allow_none=True, sync=True)
202 193
203 194 # Remove in IPython 4.0
204 195 IntTextWidget = DeprecatedClass(IntText, 'IntTextWidget')
205 196 BoundedIntTextWidget = DeprecatedClass(BoundedIntText, 'BoundedIntTextWidget')
206 197 IntSliderWidget = DeprecatedClass(IntSlider, 'IntSliderWidget')
207 198 IntProgressWidget = DeprecatedClass(IntProgress, 'IntProgressWidget')
@@ -1,248 +1,238 b''
1 1 """Selection classes.
2 2
3 3 Represents an enumeration using a widget.
4 4 """
5 #-----------------------------------------------------------------------------
6 # Copyright (c) 2013, the IPython Development Team.
7 #
8 # Distributed under the terms of the Modified BSD License.
9 #
10 # The full license is in the file COPYING.txt, distributed with this software.
11 #-----------------------------------------------------------------------------
12 5
13 #-----------------------------------------------------------------------------
14 # Imports
15 #-----------------------------------------------------------------------------
6 # Copyright (c) IPython Development Team.
7 # Distributed under the terms of the Modified BSD License.
16 8
17 9 from collections import OrderedDict
18 10 from threading import Lock
19 11
20 12 from .widget import DOMWidget, register
21 13 from IPython.utils.traitlets import (
22 14 Unicode, Bool, Any, Dict, TraitError, CaselessStrEnum, Tuple, List
23 15 )
24 16 from IPython.utils.py3compat import unicode_type
25 from IPython.utils.warn import DeprecatedClass
17 from .deprecated import DeprecatedClass
18
26 19
27 #-----------------------------------------------------------------------------
28 # SelectionWidget
29 #-----------------------------------------------------------------------------
30 20 class _Selection(DOMWidget):
31 21 """Base class for Selection widgets
32 22
33 23 ``options`` can be specified as a list or dict. If given as a list,
34 24 it will be transformed to a dict of the form ``{str(value):value}``.
35 25
36 26 When programmatically setting the value, a reverse lookup is performed
37 27 among the options to set the value of ``selected_label`` accordingly. The
38 28 reverse lookup uses the equality operator by default, but an other
39 29 predicate may be provided via the ``equals`` argument. For example, when
40 30 dealing with numpy arrays, one may set equals=np.array_equal.
41 31 """
42 32
43 33 value = Any(help="Selected value")
44 34 selected_label = Unicode(help="The label of the selected value", sync=True)
45 35 options = Any(help="""List of (key, value) tuples or dict of values that the
46 36 user can select.
47 37
48 38 The keys of this list are the strings that will be displayed in the UI,
49 39 representing the actual Python choices.
50 40
51 41 The keys of this list are also available as _options_labels.
52 42 """)
53 43
54 44 _options_dict = Dict()
55 45 _options_labels = Tuple(sync=True)
56 46 _options_values = Tuple()
57 47
58 48 disabled = Bool(False, help="Enable or disable user changes", sync=True)
59 49 description = Unicode(help="Description of the value this widget represents", sync=True)
60 50
61 51 def __init__(self, *args, **kwargs):
62 52 self.value_lock = Lock()
63 53 self.options_lock = Lock()
64 54 self.equals = kwargs.pop('equals', lambda x, y: x == y)
65 55 self.on_trait_change(self._options_readonly_changed, ['_options_dict', '_options_labels', '_options_values', '_options'])
66 56 if 'options' in kwargs:
67 57 self.options = kwargs.pop('options')
68 58 DOMWidget.__init__(self, *args, **kwargs)
69 59 self._value_in_options()
70 60
71 61 def _make_options(self, x):
72 62 # If x is a dict, convert it to list format.
73 63 if isinstance(x, (OrderedDict, dict)):
74 64 return [(k, v) for k, v in x.items()]
75 65
76 66 # Make sure x is a list or tuple.
77 67 if not isinstance(x, (list, tuple)):
78 68 raise ValueError('x')
79 69
80 70 # If x is an ordinary list, use the option values as names.
81 71 for y in x:
82 72 if not isinstance(y, (list, tuple)) or len(y) < 2:
83 73 return [(i, i) for i in x]
84 74
85 75 # Value is already in the correct format.
86 76 return x
87 77
88 78 def _options_changed(self, name, old, new):
89 79 """Handles when the options tuple has been changed.
90 80
91 81 Setting options implies setting option labels from the keys of the dict.
92 82 """
93 83 if self.options_lock.acquire(False):
94 84 try:
95 85 self.options = new
96 86
97 87 options = self._make_options(new)
98 88 self._options_dict = {i[0]: i[1] for i in options}
99 89 self._options_labels = [i[0] for i in options]
100 90 self._options_values = [i[1] for i in options]
101 91 self._value_in_options()
102 92 finally:
103 93 self.options_lock.release()
104 94
105 95 def _value_in_options(self):
106 96 # ensure that the chosen value is one of the choices
107 97
108 98 if self._options_values:
109 99 if self.value not in self._options_values:
110 100 self.value = next(iter(self._options_values))
111 101
112 102 def _options_readonly_changed(self, name, old, new):
113 103 if not self.options_lock.locked():
114 104 raise TraitError("`.%s` is a read-only trait. Use the `.options` tuple instead." % name)
115 105
116 106 def _value_changed(self, name, old, new):
117 107 """Called when value has been changed"""
118 108 if self.value_lock.acquire(False):
119 109 try:
120 110 # Reverse dictionary lookup for the value name
121 111 for k, v in self._options_dict.items():
122 112 if self.equals(new, v):
123 113 # set the selected value name
124 114 self.selected_label = k
125 115 return
126 116 # undo the change, and raise KeyError
127 117 self.value = old
128 118 raise KeyError(new)
129 119 finally:
130 120 self.value_lock.release()
131 121
132 122 def _selected_label_changed(self, name, old, new):
133 123 """Called when the value name has been changed (typically by the frontend)."""
134 124 if self.value_lock.acquire(False):
135 125 try:
136 126 self.value = self._options_dict[new]
137 127 finally:
138 128 self.value_lock.release()
139 129
140 130
141 131 class _MultipleSelection(_Selection):
142 132 """Base class for MultipleSelection widgets.
143 133
144 134 As with ``_Selection``, ``options`` can be specified as a list or dict. If
145 135 given as a list, it will be transformed to a dict of the form
146 136 ``{str(value): value}``.
147 137
148 138 Despite their names, ``value`` (and ``selected_label``) will be tuples, even
149 139 if only a single option is selected.
150 140 """
151 141
152 142 value = Tuple(help="Selected values")
153 143 selected_labels = Tuple(help="The labels of the selected options",
154 144 sync=True)
155 145
156 146 @property
157 147 def selected_label(self):
158 148 raise AttributeError(
159 149 "Does not support selected_label, use selected_labels")
160 150
161 151 def _value_in_options(self):
162 152 # ensure that the chosen value is one of the choices
163 153 if self.options:
164 154 old_value = self.value or []
165 155 new_value = []
166 156 for value in old_value:
167 157 if value in self._options_dict.values():
168 158 new_value.append(value)
169 159 if new_value:
170 160 self.value = new_value
171 161 else:
172 162 self.value = [next(iter(self._options_dict.values()))]
173 163
174 164 def _value_changed(self, name, old, new):
175 165 """Called when value has been changed"""
176 166 if self.value_lock.acquire(False):
177 167 try:
178 168 self.selected_labels = [
179 169 self._options_labels[self._options_values.index(v)]
180 170 for v in new
181 171 ]
182 172 except:
183 173 self.value = old
184 174 raise KeyError(new)
185 175 finally:
186 176 self.value_lock.release()
187 177
188 178 def _selected_labels_changed(self, name, old, new):
189 179 """Called when the selected label has been changed (typically by the
190 180 frontend)."""
191 181 if self.value_lock.acquire(False):
192 182 try:
193 183 self.value = [self._options_dict[name] for name in new]
194 184 finally:
195 185 self.value_lock.release()
196 186
197 187
198 188 @register('IPython.ToggleButtons')
199 189 class ToggleButtons(_Selection):
200 190 """Group of toggle buttons that represent an enumeration. Only one toggle
201 191 button can be toggled at any point in time."""
202 192 _view_name = Unicode('ToggleButtonsView', sync=True)
203 193 tooltips = List(Unicode(), sync=True)
204 194 icons = List(Unicode(), sync=True)
205 195
206 196 button_style = CaselessStrEnum(
207 197 values=['primary', 'success', 'info', 'warning', 'danger', ''],
208 198 default_value='', allow_none=True, sync=True, help="""Use a
209 199 predefined styling for the buttons.""")
210 200
211 201 @register('IPython.Dropdown')
212 202 class Dropdown(_Selection):
213 203 """Allows you to select a single item from a dropdown."""
214 204 _view_name = Unicode('DropdownView', sync=True)
215 205
216 206 button_style = CaselessStrEnum(
217 207 values=['primary', 'success', 'info', 'warning', 'danger', ''],
218 208 default_value='', allow_none=True, sync=True, help="""Use a
219 209 predefined styling for the buttons.""")
220 210
221 211 @register('IPython.RadioButtons')
222 212 class RadioButtons(_Selection):
223 213 """Group of radio buttons that represent an enumeration. Only one radio
224 214 button can be toggled at any point in time."""
225 215 _view_name = Unicode('RadioButtonsView', sync=True)
226 216
227 217
228 218
229 219 @register('IPython.Select')
230 220 class Select(_Selection):
231 221 """Listbox that only allows one item to be selected at any given time."""
232 222 _view_name = Unicode('SelectView', sync=True)
233 223
234 224
235 225 @register('IPython.SelectMultiple')
236 226 class SelectMultiple(_MultipleSelection):
237 227 """Listbox that allows many items to be selected at any given time.
238 228 Despite their names, inherited from ``_Selection``, the currently chosen
239 229 option values, ``value``, or their labels, ``selected_labels`` must both be
240 230 updated with a list-like object."""
241 231 _view_name = Unicode('SelectMultipleView', sync=True)
242 232
243 233
244 234 # Remove in IPython 4.0
245 235 ToggleButtonsWidget = DeprecatedClass(ToggleButtons, 'ToggleButtonsWidget')
246 236 DropdownWidget = DeprecatedClass(Dropdown, 'DropdownWidget')
247 237 RadioButtonsWidget = DeprecatedClass(RadioButtons, 'RadioButtonsWidget')
248 238 SelectWidget = DeprecatedClass(Select, 'SelectWidget')
@@ -1,68 +1,58 b''
1 1 """SelectionContainer class.
2 2
3 3 Represents a multipage container that can be used to group other widgets into
4 4 pages.
5 5 """
6 #-----------------------------------------------------------------------------
7 # Copyright (c) 2013, the IPython Development Team.
8 #
6
7 # Copyright (c) IPython Development Team.
9 8 # Distributed under the terms of the Modified BSD License.
10 #
11 # The full license is in the file COPYING.txt, distributed with this software.
12 #-----------------------------------------------------------------------------
13 9
14 #-----------------------------------------------------------------------------
15 # Imports
16 #-----------------------------------------------------------------------------
17 10 from .widget_box import Box, register
18 11 from IPython.utils.traitlets import Unicode, Dict, CInt
19 from IPython.utils.warn import DeprecatedClass
12 from .deprecated import DeprecatedClass
20 13
21 #-----------------------------------------------------------------------------
22 # Classes
23 #-----------------------------------------------------------------------------
24 14 class _SelectionContainer(Box):
25 15 """Base class used to display multiple child widgets."""
26 16 _titles = Dict(help="Titles of the pages", sync=True)
27 17 selected_index = CInt(0, sync=True)
28 18
29 19 # Public methods
30 20 def set_title(self, index, title):
31 21 """Sets the title of a container page.
32 22
33 23 Parameters
34 24 ----------
35 25 index : int
36 26 Index of the container page
37 27 title : unicode
38 28 New title"""
39 29 self._titles[index] = title
40 30 self.send_state('_titles')
41 31
42 32 def get_title(self, index):
43 33 """Gets the title of a container pages.
44 34
45 35 Parameters
46 36 ----------
47 37 index : int
48 38 Index of the container page"""
49 39 if index in self._titles:
50 40 return self._titles[index]
51 41 else:
52 42 return None
53 43
54 44 @register('IPython.Accordion')
55 45 class Accordion(_SelectionContainer):
56 46 """Displays children each on a separate accordion page."""
57 47 _view_name = Unicode('AccordionView', sync=True)
58 48
59 49
60 50 @register('IPython.Tab')
61 51 class Tab(_SelectionContainer):
62 52 """Displays children each on a separate accordion tab."""
63 53 _view_name = Unicode('TabView', sync=True)
64 54
65 55
66 56 # Remove in IPython 4.0
67 57 AccordionWidget = DeprecatedClass(Accordion, 'AccordionWidget')
68 58 TabWidget = DeprecatedClass(Tab, 'TabWidget')
@@ -1,95 +1,86 b''
1 """String class.
1 """String class.
2 2
3 3 Represents a unicode string using a widget.
4 4 """
5 #-----------------------------------------------------------------------------
6 # Copyright (c) 2013, the IPython Development Team.
7 #
5
6 # Copyright (c) IPython Development Team.
8 7 # Distributed under the terms of the Modified BSD License.
9 #
10 # The full license is in the file COPYING.txt, distributed with this software.
11 #-----------------------------------------------------------------------------
12 8
13 #-----------------------------------------------------------------------------
14 # Imports
15 #-----------------------------------------------------------------------------
16 9 from .widget import DOMWidget, CallbackDispatcher, register
17 10 from IPython.utils.traitlets import Unicode, Bool
18 from IPython.utils.warn import DeprecatedClass
11 from .deprecated import DeprecatedClass
12
19 13
20 #-----------------------------------------------------------------------------
21 # Classes
22 #-----------------------------------------------------------------------------
23 14 class _String(DOMWidget):
24 15 """Base class used to create widgets that represent a string."""
25 16 value = Unicode(help="String value", sync=True)
26 17 disabled = Bool(False, help="Enable or disable user changes", sync=True)
27 18 description = Unicode(help="Description of the value this widget represents", sync=True)
28 19 placeholder = Unicode("", help="Placeholder text to display when nothing has been typed", sync=True)
29 20
30 21 def __init__(self, value=None, **kwargs):
31 22 if value is not None:
32 23 kwargs['value'] = value
33 24 super(_String, self).__init__(**kwargs)
34 25
35 26 @register('IPython.HTML')
36 27 class HTML(_String):
37 28 """Renders the string `value` as HTML."""
38 29 _view_name = Unicode('HTMLView', sync=True)
39 30
40 31
41 32 @register('IPython.Latex')
42 33 class Latex(_String):
43 34 """Renders math inside the string `value` as Latex (requires $ $ or $$ $$
44 35 and similar latex tags)."""
45 36 _view_name = Unicode('LatexView', sync=True)
46 37
47 38
48 39 @register('IPython.Textarea')
49 40 class Textarea(_String):
50 41 """Multiline text area widget."""
51 42 _view_name = Unicode('TextareaView', sync=True)
52 43
53 44 def scroll_to_bottom(self):
54 45 self.send({"method": "scroll_to_bottom"})
55 46
56 47
57 48 @register('IPython.Text')
58 49 class Text(_String):
59 50 """Single line textbox widget."""
60 51 _view_name = Unicode('TextView', sync=True)
61 52
62 53 def __init__(self, *args, **kwargs):
63 54 super(Text, self).__init__(*args, **kwargs)
64 55 self._submission_callbacks = CallbackDispatcher()
65 56 self.on_msg(self._handle_string_msg)
66 57
67 58 def _handle_string_msg(self, _, content):
68 59 """Handle a msg from the front-end.
69 60
70 61 Parameters
71 62 ----------
72 63 content: dict
73 64 Content of the msg."""
74 65 if content.get('event', '') == 'submit':
75 66 self._submission_callbacks(self)
76 67
77 68 def on_submit(self, callback, remove=False):
78 69 """(Un)Register a callback to handle text submission.
79 70
80 71 Triggered when the user clicks enter.
81 72
82 73 Parameters
83 74 ----------
84 75 callback: callable
85 76 Will be called with exactly one argument: the Widget instance
86 77 remove: bool (optional)
87 78 Whether to unregister the callback"""
88 79 self._submission_callbacks.register_callback(callback, remove=remove)
89 80
90 81
91 82 # Remove in IPython 4.0
92 83 HTMLWidget = DeprecatedClass(HTML, 'HTMLWidget')
93 84 LatexWidget = DeprecatedClass(Latex, 'LatexWidget')
94 85 TextareaWidget = DeprecatedClass(Textarea, 'TextareaWidget')
95 86 TextWidget = DeprecatedClass(Text, 'TextWidget')
@@ -1,81 +1,57 b''
1 1 # encoding: utf-8
2 2 """
3 3 Utilities for warnings. Shoudn't we just use the built in warnings module.
4 4 """
5 5
6 #-----------------------------------------------------------------------------
7 # Copyright (C) 2008-2011 The IPython Development Team
8 #
9 # Distributed under the terms of the BSD License. The full license is in
10 # the file COPYING, distributed as part of this software.
11 #-----------------------------------------------------------------------------
12
13 #-----------------------------------------------------------------------------
14 # Imports
15 #-----------------------------------------------------------------------------
6 # Copyright (c) IPython Development Team.
7 # Distributed under the terms of the Modified BSD License.
8
16 9 from __future__ import print_function
17 10
18 11 import sys
19 import warnings
20 12
21 13 from IPython.utils import io
22 14
23 #-----------------------------------------------------------------------------
24 # Code
25 #-----------------------------------------------------------------------------
26 15
27 16 def warn(msg,level=2,exit_val=1):
28 17 """Standard warning printer. Gives formatting consistency.
29 18
30 19 Output is sent to io.stderr (sys.stderr by default).
31 20
32 21 Options:
33 22
34 23 -level(2): allows finer control:
35 24 0 -> Do nothing, dummy function.
36 25 1 -> Print message.
37 26 2 -> Print 'WARNING:' + message. (Default level).
38 27 3 -> Print 'ERROR:' + message.
39 28 4 -> Print 'FATAL ERROR:' + message and trigger a sys.exit(exit_val).
40 29
41 30 -exit_val (1): exit value returned by sys.exit() for a level 4
42 31 warning. Ignored for all other levels."""
43 32
44 33 if level>0:
45 34 header = ['','','WARNING: ','ERROR: ','FATAL ERROR: ']
46 35 print(header[level], msg, sep='', file=io.stderr)
47 36 if level == 4:
48 37 print('Exiting.\n', file=io.stderr)
49 38 sys.exit(exit_val)
50 39
51 40
52 41 def info(msg):
53 42 """Equivalent to warn(msg,level=1)."""
54 43
55 44 warn(msg,level=1)
56 45
57 46
58 47 def error(msg):
59 48 """Equivalent to warn(msg,level=3)."""
60 49
61 50 warn(msg,level=3)
62 51
63 52
64 53 def fatal(msg,exit_val=1):
65 54 """Equivalent to warn(msg,exit_val=exit_val,level=4)."""
66 55
67 56 warn(msg,exit_val=exit_val,level=4)
68 57
69
70 def DeprecatedClass(base, class_name):
71 # Hook the init method of the base class.
72 def init_hook(self, *pargs, **kwargs):
73 base.__init__(self, *pargs, **kwargs)
74
75 # Warn once per class.
76 if base not in DeprecatedClass._warned_classes:
77 DeprecatedClass._warned_classes.append(base)
78 warn('"{}" is deprecated, please use "{}" instead.'.format(
79 class_name, base.__name__))
80 return type(class_name, (base,), {'__init__': init_hook})
81 DeprecatedClass._warned_classes = []
General Comments 0
You need to be logged in to leave comments. Login now