##// END OF EJS Templates
s/default_view_name/view_name
Jonathan Frederic -
Show More
@@ -1,433 +1,433
1 1 """Base Widget class. Allows user to create widgets in the backend that render
2 2 in the IPython notebook frontend.
3 3 """
4 4 #-----------------------------------------------------------------------------
5 5 # Copyright (c) 2013, the IPython Development Team.
6 6 #
7 7 # Distributed under the terms of the Modified BSD License.
8 8 #
9 9 # The full license is in the file COPYING.txt, distributed with this software.
10 10 #-----------------------------------------------------------------------------
11 11
12 12 #-----------------------------------------------------------------------------
13 13 # Imports
14 14 #-----------------------------------------------------------------------------
15 15 from copy import copy
16 16 from glob import glob
17 17 import uuid
18 18 import sys
19 19 import os
20 20 import inspect
21 21 import types
22 22
23 23 import IPython
24 24 from IPython.kernel.comm import Comm
25 25 from IPython.config import LoggingConfigurable
26 26 from IPython.utils.traitlets import Unicode, Dict, List, Instance, Bool
27 27 from IPython.display import Javascript, display
28 28 from IPython.utils.py3compat import string_types
29 29
30 30 #-----------------------------------------------------------------------------
31 31 # Classes
32 32 #-----------------------------------------------------------------------------
33 33
34 34 class Widget(LoggingConfigurable):
35 35
36 36 # Shared declarations (Class level)
37 37 widget_construction_callback = None
38 38
39 keys = ['default_view_name']
39 keys = ['view_name']
40 40
41 41 def on_widget_constructed(callback):
42 42 """Class method, registers a callback to be called when a widget is
43 43 constructed. The callback must have the following signature:
44 44 callback(widget)"""
45 45 Widget.widget_construction_callback = callback
46 46
47 47 def _handle_widget_constructed(widget):
48 48 """Class method, called when a widget is constructed."""
49 49 if Widget.widget_construction_callback is not None and callable(Widget.widget_construction_callback):
50 50 Widget.widget_construction_callback(widget)
51 51
52 52
53 53
54 54 # Public declarations (Instance level)
55 55 target_name = Unicode('widget', help="""Name of the backbone model
56 56 registered in the frontend to create and sync this widget with.""")
57 default_view_name = Unicode(help="""Default view registered in the frontend
57 view_name = Unicode(help="""Default view registered in the frontend
58 58 to use to represent the widget.""")
59 59
60 60 # Private/protected declarations
61 61 # todo: change this to a context manager
62 62 _property_lock = (None, None) # Last updated (key, value) from the front-end. Prevents echo.
63 63 _displayed = False
64 64 _comm = Instance('IPython.kernel.comm.Comm')
65 65
66 66 def __init__(self, **kwargs):
67 67 """Public constructor
68 68 """
69 69 self._display_callbacks = []
70 70 self._msg_callbacks = []
71 71 super(Widget, self).__init__(**kwargs)
72 72
73 73 self.on_trait_change(self._handle_property_changed, self.keys)
74 74 Widget._handle_widget_constructed(self)
75 75
76 76 def __del__(self):
77 77 """Object disposal"""
78 78 self.close()
79 79
80 80
81 81 def close(self):
82 82 """Close method. Closes the widget which closes the underlying comm.
83 83 When the comm is closed, all of the widget views are automatically
84 84 removed from the frontend."""
85 85 self._close_communication()
86 86
87 87 @property
88 88 def comm(self):
89 89 if self._comm is None:
90 90 self._open_communication()
91 91 return self._comm
92 92
93 93 @property
94 94 def model_id(self):
95 95 return self.comm.comm_id
96 96
97 97 # Event handlers
98 98 def _handle_msg(self, msg):
99 99 """Called when a msg is recieved from the frontend"""
100 100 data = msg['content']['data']
101 101 method = data['method']
102 102
103 103 # Handle backbone sync methods CREATE, PATCH, and UPDATE all in one.
104 104 if method == 'backbone' and 'sync_data' in data:
105 105 sync_data = data['sync_data']
106 106 self._handle_recieve_state(sync_data) # handles all methods
107 107
108 108 # Handle a custom msg from the front-end
109 109 elif method == 'custom':
110 110 if 'custom_content' in data:
111 111 self._handle_custom_msg(data['custom_content'])
112 112
113 113 def _handle_custom_msg(self, content):
114 114 """Called when a custom msg is recieved."""
115 115 for handler in self._msg_callbacks:
116 116 if callable(handler):
117 117 argspec = inspect.getargspec(handler)
118 118 nargs = len(argspec[0])
119 119
120 120 # Bound methods have an additional 'self' argument
121 121 if isinstance(handler, types.MethodType):
122 122 nargs -= 1
123 123
124 124 # Call the callback
125 125 if nargs == 1:
126 126 handler(content)
127 127 elif nargs == 2:
128 128 handler(self, content)
129 129 else:
130 130 raise TypeError('Widget msg callback must ' \
131 131 'accept 1 or 2 arguments, not %d.' % nargs)
132 132
133 133
134 134 def _handle_recieve_state(self, sync_data):
135 135 """Called when a state is recieved from the frontend."""
136 136 for name in self.keys:
137 137 if name in sync_data:
138 138 try:
139 139 self._property_lock = (name, sync_data[name])
140 140 setattr(self, name, sync_data[name])
141 141 finally:
142 142 self._property_lock = (None, None)
143 143
144 144
145 145 def _handle_property_changed(self, name, old, new):
146 146 """Called when a property has been changed."""
147 147 # Make sure this isn't information that the front-end just sent us.
148 148 if self._property_lock[0] != name and self._property_lock[1] != new:
149 149 # Send new state to frontend
150 150 self.send_state(key=name)
151 151
152 152 def _handle_displayed(self, **kwargs):
153 153 """Called when a view has been displayed for this widget instance
154 154
155 155 Parameters
156 156 ----------
157 157 [view_name]: unicode (optional kwarg)
158 158 Name of the view that was displayed."""
159 159 for handler in self._display_callbacks:
160 160 if callable(handler):
161 161 argspec = inspect.getargspec(handler)
162 162 nargs = len(argspec[0])
163 163
164 164 # Bound methods have an additional 'self' argument
165 165 if isinstance(handler, types.MethodType):
166 166 nargs -= 1
167 167
168 168 # Call the callback
169 169 if nargs == 0:
170 170 handler()
171 171 elif nargs == 1:
172 172 handler(self)
173 173 elif nargs == 2:
174 174 handler(self, kwargs.get('view_name', None))
175 175 else:
176 176 handler(self, **kwargs)
177 177
178 178 # Public methods
179 179 def send_state(self, key=None):
180 180 """Sends the widget state, or a piece of it, to the frontend.
181 181
182 182 Parameters
183 183 ----------
184 184 key : unicode (optional)
185 185 A single property's name to sync with the frontend.
186 186 """
187 187 self._send({"method": "update",
188 188 "state": self.get_state()})
189 189
190 190 def get_state(self, key=None):
191 191 """Gets the widget state, or a piece of it.
192 192
193 193 Parameters
194 194 ----------
195 195 key : unicode (optional)
196 196 A single property's name to get.
197 197 """
198 198 state = {}
199 199
200 200 # If a key is provided, just send the state of that key.
201 201 if key is None:
202 202 keys = self.keys[:]
203 203 else:
204 204 keys = [key]
205 205 for k in keys:
206 206 value = getattr(self, k)
207 207
208 208 # a more elegant solution to encoding Widgets would be
209 209 # to tap into the JSON encoder and teach it how to deal
210 210 # with Widget objects, or maybe just teach the JSON
211 211 # encoder to look for a _repr_json property before giving
212 212 # up encoding
213 213 if isinstance(value, Widget):
214 214 value = value.model_id
215 215 elif isinstance(value, list) and len(value)>0 and isinstance(value[0], Widget):
216 216 # assume all elements of the list are widgets
217 217 value = [i.model_id for i in value]
218 218 state[k] = value
219 219 return state
220 220
221 221
222 222 def send(self, content):
223 223 """Sends a custom msg to the widget model in the front-end.
224 224
225 225 Parameters
226 226 ----------
227 227 content : dict
228 228 Content of the message to send.
229 229 """
230 230 self._send({"method": "custom",
231 231 "custom_content": content})
232 232
233 233
234 234 def on_msg(self, callback, remove=False):
235 235 """Register a callback for when a custom msg is recieved from the front-end
236 236
237 237 Parameters
238 238 ----------
239 239 callback: method handler
240 240 Can have a signature of:
241 241 - callback(content)
242 242 - callback(sender, content)
243 243 remove: bool
244 244 True if the callback should be unregistered."""
245 245 if remove and callback in self._msg_callbacks:
246 246 self._msg_callbacks.remove(callback)
247 247 elif not remove and not callback in self._msg_callbacks:
248 248 self._msg_callbacks.append(callback)
249 249
250 250
251 251 def on_displayed(self, callback, remove=False):
252 252 """Register a callback to be called when the widget has been displayed
253 253
254 254 Parameters
255 255 ----------
256 256 callback: method handler
257 257 Can have a signature of:
258 258 - callback()
259 259 - callback(sender)
260 260 - callback(sender, view_name)
261 261 - callback(sender, **kwargs)
262 262 kwargs from display call passed through without modification.
263 263 remove: bool
264 264 True if the callback should be unregistered."""
265 265 if remove and callback in self._display_callbacks:
266 266 self._display_callbacks.remove(callback)
267 267 elif not remove and not callback in self._display_callbacks:
268 268 self._display_callbacks.append(callback)
269 269
270 270
271 271 # Support methods
272 272 def _repr_widget_(self, **kwargs):
273 273 """Function that is called when `IPython.display.display` is called on
274 274 the widget.
275 275
276 276 Parameters
277 277 ----------
278 278 view_name: unicode (optional)
279 View to display in the frontend. Overrides default_view_name."""
280 view_name = kwargs.get('view_name', self.default_view_name)
279 View to display in the frontend. Overrides view_name."""
280 view_name = kwargs.get('view_name', self.view_name)
281 281
282 282 # Create a communication.
283 283 self._open_communication()
284 284
285 285 # Make sure model is syncronized
286 286 self.send_state()
287 287
288 288 # Show view.
289 289 self._send({"method": "display", "view_name": view_name})
290 290 self._displayed = True
291 291 self._handle_displayed(**kwargs)
292 292
293 293
294 294 def _open_communication(self):
295 295 """Opens a communication with the front-end."""
296 296 # Create a comm.
297 297 if self._comm is None:
298 298 self._comm = Comm(target_name=self.target_name)
299 299 self._comm.on_msg(self._handle_msg)
300 300 self._comm.on_close(self._close_communication)
301 301
302 302 # first update
303 303 self.send_state()
304 304
305 305
306 306 def _close_communication(self):
307 307 """Closes a communication with the front-end."""
308 308 if self._comm is not None:
309 309 try:
310 310 self._comm.close()
311 311 finally:
312 312 self._comm = None
313 313
314 314
315 315 def _send(self, msg):
316 316 """Sends a message to the model in the front-end"""
317 317 if self._comm is not None:
318 318 self._comm.send(msg)
319 319 return True
320 320 else:
321 321 return False
322 322
323 323
324 324 class DOMWidget(Widget):
325 325 visible = Bool(True, help="Whether or not the widget is visible.")
326 326
327 327 # Private/protected declarations
328 328 _css = Dict() # Internal CSS property dict
329 329
330 330 keys = ['visible', '_css'] + Widget.keys
331 331
332 332 def get_css(self, key, selector=""):
333 333 """Get a CSS property of the widget. Note, this function does not
334 334 actually request the CSS from the front-end; Only properties that have
335 335 been set with set_css can be read.
336 336
337 337 Parameters
338 338 ----------
339 339 key: unicode
340 340 CSS key
341 341 selector: unicode (optional)
342 342 JQuery selector used when the CSS key/value was set.
343 343 """
344 344 if selector in self._css and key in self._css[selector]:
345 345 return self._css[selector][key]
346 346 else:
347 347 return None
348 348
349 349
350 350 def set_css(self, *args, **kwargs):
351 351 """Set one or more CSS properties of the widget (shared among all of the
352 352 views). This function has two signatures:
353 353 - set_css(css_dict, [selector=''])
354 354 - set_css(key, value, [selector=''])
355 355
356 356 Parameters
357 357 ----------
358 358 css_dict : dict
359 359 CSS key/value pairs to apply
360 360 key: unicode
361 361 CSS key
362 362 value
363 363 CSS value
364 364 selector: unicode (optional)
365 365 JQuery selector to use to apply the CSS key/value.
366 366 """
367 367 selector = kwargs.get('selector', '')
368 368
369 369 # Signature 1: set_css(css_dict, [selector=''])
370 370 if len(args) == 1:
371 371 if isinstance(args[0], dict):
372 372 for (key, value) in args[0].items():
373 373 self.set_css(key, value, selector=selector)
374 374 else:
375 375 raise Exception('css_dict must be a dict.')
376 376
377 377 # Signature 2: set_css(key, value, [selector=''])
378 378 elif len(args) == 2 or len(args) == 3:
379 379
380 380 # Selector can be a positional arg if it's the 3rd value
381 381 if len(args) == 3:
382 382 selector = args[2]
383 383 if selector not in self._css:
384 384 self._css[selector] = {}
385 385
386 386 # Only update the property if it has changed.
387 387 key = args[0]
388 388 value = args[1]
389 389 if not (key in self._css[selector] and value in self._css[selector][key]):
390 390 self._css[selector][key] = value
391 391 self.send_state('_css') # Send new state to client.
392 392 else:
393 393 raise Exception('set_css only accepts 1-3 arguments')
394 394
395 395
396 396 def add_class(self, class_names, selector=""):
397 397 """Add class[es] to a DOM element
398 398
399 399 Parameters
400 400 ----------
401 401 class_names: unicode or list
402 402 Class name(s) to add to the DOM element(s).
403 403 selector: unicode (optional)
404 404 JQuery selector to select the DOM element(s) that the class(es) will
405 405 be added to.
406 406 """
407 407 class_list = class_names
408 408 if isinstance(list, class_list):
409 409 class_list = ' '.join(class_list)
410 410
411 411 self.send({"msg_type": "add_class",
412 412 "class_list": class_list,
413 413 "selector": selector})
414 414
415 415
416 416 def remove_class(self, class_names, selector=""):
417 417 """Remove class[es] from a DOM element
418 418
419 419 Parameters
420 420 ----------
421 421 class_names: unicode or list
422 422 Class name(s) to remove from the DOM element(s).
423 423 selector: unicode (optional)
424 424 JQuery selector to select the DOM element(s) that the class(es) will
425 425 be removed from.
426 426 """
427 427 class_list = class_names
428 428 if isinstance(list, class_list):
429 429 class_list = ' '.join(class_list)
430 430
431 431 self.send({"msg_type": "remove_class",
432 432 "class_list": class_list,
433 433 "selector": selector})
@@ -1,31 +1,31
1 1 """BoolWidget class.
2 2
3 3 Represents a boolean using a widget.
4 4 """
5 5 #-----------------------------------------------------------------------------
6 6 # Copyright (c) 2013, the IPython Development Team.
7 7 #
8 8 # Distributed under the terms of the Modified BSD License.
9 9 #
10 10 # The full license is in the file COPYING.txt, distributed with this software.
11 11 #-----------------------------------------------------------------------------
12 12
13 13 #-----------------------------------------------------------------------------
14 14 # Imports
15 15 #-----------------------------------------------------------------------------
16 16 from .widget import DOMWidget
17 17 from IPython.utils.traitlets import Unicode, Bool, List
18 18
19 19 #-----------------------------------------------------------------------------
20 20 # Classes
21 21 #-----------------------------------------------------------------------------
22 22 class BoolWidget(DOMWidget):
23 23 target_name = Unicode('BoolWidgetModel')
24 default_view_name = Unicode('CheckboxView')
24 view_name = Unicode('CheckboxView')
25 25
26 26 # Model Keys
27 27 keys = ['value', 'description', 'disabled'] + DOMWidget.keys
28 28 value = Bool(False, help="Bool value")
29 29 description = Unicode('', help="Description of the boolean (label).")
30 30 disabled = Bool(False, help="Enable or disable user changes.")
31 31 No newline at end of file
@@ -1,93 +1,93
1 1 """ButtonWidget 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 6 #-----------------------------------------------------------------------------
7 7 # Copyright (c) 2013, the IPython Development Team.
8 8 #
9 9 # Distributed under the terms of the Modified BSD License.
10 10 #
11 11 # The full license is in the file COPYING.txt, distributed with this software.
12 12 #-----------------------------------------------------------------------------
13 13
14 14 #-----------------------------------------------------------------------------
15 15 # Imports
16 16 #-----------------------------------------------------------------------------
17 17 import inspect
18 18 import types
19 19
20 20 from .widget import DOMWidget
21 21 from IPython.utils.traitlets import Unicode, Bool, Int
22 22
23 23 #-----------------------------------------------------------------------------
24 24 # Classes
25 25 #-----------------------------------------------------------------------------
26 26 class ButtonWidget(DOMWidget):
27 27 target_name = Unicode('ButtonWidgetModel')
28 default_view_name = Unicode('ButtonView')
28 view_name = Unicode('ButtonView')
29 29
30 30 # Keys
31 31 keys = ['description', 'disabled'] + DOMWidget.keys
32 32 description = Unicode('', help="Description of the button (label).")
33 33 disabled = Bool(False, help="Enable or disable user changes.")
34 34
35 35
36 36 def __init__(self, **kwargs):
37 37 super(ButtonWidget, self).__init__(**kwargs)
38 38
39 39 self._click_handlers = []
40 40 self.on_msg(self._handle_button_msg)
41 41
42 42
43 43 def on_click(self, callback, remove=False):
44 44 """Register a callback to execute when the button is clicked. The
45 45 callback can either accept no parameters or one sender parameter:
46 46 - callback()
47 47 - callback(sender)
48 48 If the callback has a sender parameter, the ButtonWidget instance that
49 49 called the callback will be passed into the method as the sender.
50 50
51 51 Parameters
52 52 ----------
53 53 remove : bool (optional)
54 54 Set to true to remove the callback from the list of callbacks."""
55 55 if remove:
56 56 self._click_handlers.remove(callback)
57 57 elif not callback in self._click_handlers:
58 58 self._click_handlers.append(callback)
59 59
60 60
61 61 def _handle_button_msg(self, content):
62 62 """Handle a msg from the front-end
63 63
64 64 Parameters
65 65 ----------
66 66 content: dict
67 67 Content of the msg."""
68 68 if 'event' in content and content['event'] == 'click':
69 69 self._handle_click()
70 70
71 71
72 72 def _handle_click(self):
73 73 """Handles when the button has been clicked. Fires on_click
74 74 callbacks when appropriate."""
75 75
76 76 for handler in self._click_handlers:
77 77 if callable(handler):
78 78 argspec = inspect.getargspec(handler)
79 79 nargs = len(argspec[0])
80 80
81 81 # Bound methods have an additional 'self' argument
82 82 if isinstance(handler, types.MethodType):
83 83 nargs -= 1
84 84
85 85 # Call the callback
86 86 if nargs == 0:
87 87 handler()
88 88 elif nargs == 1:
89 89 handler(self)
90 90 else:
91 91 raise TypeError('ButtonWidget click callback must ' \
92 92 'accept 0 or 1 arguments.')
93 93
@@ -1,203 +1,203
1 1 """ContainerWidget class.
2 2
3 3 Represents a container that can be used to group other widgets.
4 4 """
5 5 #-----------------------------------------------------------------------------
6 6 # Copyright (c) 2013, the IPython Development Team.
7 7 #
8 8 # Distributed under the terms of the Modified BSD License.
9 9 #
10 10 # The full license is in the file COPYING.txt, distributed with this software.
11 11 #-----------------------------------------------------------------------------
12 12
13 13 #-----------------------------------------------------------------------------
14 14 # Imports
15 15 #-----------------------------------------------------------------------------
16 16 from .widget import DOMWidget
17 17 from IPython.utils.traitlets import Unicode, Bool, List, Instance
18 18
19 19 #-----------------------------------------------------------------------------
20 20 # Classes
21 21 #-----------------------------------------------------------------------------
22 22 class ContainerWidget(DOMWidget):
23 23 target_name = Unicode('ContainerWidgetModel')
24 default_view_name = Unicode('ContainerView')
24 view_name = Unicode('ContainerView')
25 25
26 26 # Keys, all private and managed by helper methods. Flexible box model
27 27 # classes...
28 28 keys = ['_vbox', '_hbox', '_align_start', '_align_end', '_align_center',
29 29 '_pack_start', '_pack_end', '_pack_center', '_flex0', '_flex1',
30 30 '_flex2', 'description', 'button_text',
31 31 'children'] + DOMWidget.keys
32 32 children = List(Instance(DOMWidget))
33 33
34 34 description = Unicode()
35 35 button_text = Unicode()
36 36 _hbox = Bool(False)
37 37 _vbox = Bool(False)
38 38 _align_start = Bool(False)
39 39 _align_end = Bool(False)
40 40 _align_center = Bool(False)
41 41 _pack_start = Bool(False)
42 42 _pack_end = Bool(False)
43 43 _pack_center = Bool(False)
44 44 _flex0 = Bool(False)
45 45 _flex1 = Bool(False)
46 46 _flex2 = Bool(False)
47 47
48 48 def hbox(self, enabled=True):
49 49 """Make this container an hbox. Automatically disables conflicting
50 50 features.
51 51
52 52 Parameters
53 53 ----------
54 54 enabled: bool (optional)
55 55 Enabled or disable the hbox feature of the container, defaults to
56 56 True."""
57 57 self._hbox = enabled
58 58 if enabled:
59 59 self._vbox = False
60 60
61 61 def vbox(self, enabled=True):
62 62 """Make this container an vbox. Automatically disables conflicting
63 63 features.
64 64
65 65 Parameters
66 66 ----------
67 67 enabled: bool (optional)
68 68 Enabled or disable the vbox feature of the container, defaults to
69 69 True."""
70 70 self._vbox = enabled
71 71 if enabled:
72 72 self._hbox = False
73 73
74 74 def align_start(self, enabled=True):
75 75 """Make the contents of this container align to the start of the axis.
76 76 Automatically disables conflicting alignments.
77 77
78 78 Parameters
79 79 ----------
80 80 enabled: bool (optional)
81 81 Enabled or disable the start alignment of the container, defaults to
82 82 True."""
83 83 self._align_start = enabled
84 84 if enabled:
85 85 self._align_end = False
86 86 self._align_center = False
87 87
88 88 def align_end(self, enabled=True):
89 89 """Make the contents of this container align to the end of the axis.
90 90 Automatically disables conflicting alignments.
91 91
92 92 Parameters
93 93 ----------
94 94 enabled: bool (optional)
95 95 Enabled or disable the end alignment of the container, defaults to
96 96 True."""
97 97 self._align_end = enabled
98 98 if enabled:
99 99 self._align_start = False
100 100 self._align_center = False
101 101
102 102 def align_center(self, enabled=True):
103 103 """Make the contents of this container align to the center of the axis.
104 104 Automatically disables conflicting alignments.
105 105
106 106 Parameters
107 107 ----------
108 108 enabled: bool (optional)
109 109 Enabled or disable the center alignment of the container, defaults to
110 110 True."""
111 111 self._align_center = enabled
112 112 if enabled:
113 113 self._align_start = False
114 114 self._align_end = False
115 115
116 116
117 117 def pack_start(self, enabled=True):
118 118 """Make the contents of this container pack to the start of the axis.
119 119 Automatically disables conflicting packings.
120 120
121 121 Parameters
122 122 ----------
123 123 enabled: bool (optional)
124 124 Enabled or disable the start packing of the container, defaults to
125 125 True."""
126 126 self._pack_start = enabled
127 127 if enabled:
128 128 self._pack_end = False
129 129 self._pack_center = False
130 130
131 131 def pack_end(self, enabled=True):
132 132 """Make the contents of this container pack to the end of the axis.
133 133 Automatically disables conflicting packings.
134 134
135 135 Parameters
136 136 ----------
137 137 enabled: bool (optional)
138 138 Enabled or disable the end packing of the container, defaults to
139 139 True."""
140 140 self._pack_end = enabled
141 141 if enabled:
142 142 self._pack_start = False
143 143 self._pack_center = False
144 144
145 145 def pack_center(self, enabled=True):
146 146 """Make the contents of this container pack to the center of the axis.
147 147 Automatically disables conflicting packings.
148 148
149 149 Parameters
150 150 ----------
151 151 enabled: bool (optional)
152 152 Enabled or disable the center packing of the container, defaults to
153 153 True."""
154 154 self._pack_center = enabled
155 155 if enabled:
156 156 self._pack_start = False
157 157 self._pack_end = False
158 158
159 159
160 160 def flex0(self, enabled=True):
161 161 """Put this container in flex0 mode. Automatically disables conflicting
162 162 flex modes. See the widget tutorial part 5 example notebook for more
163 163 information.
164 164
165 165 Parameters
166 166 ----------
167 167 enabled: bool (optional)
168 168 Enabled or disable the flex0 attribute of the container, defaults to
169 169 True."""
170 170 self._flex0 = enabled
171 171 if enabled:
172 172 self._flex1 = False
173 173 self._flex2 = False
174 174
175 175 def flex1(self, enabled=True):
176 176 """Put this container in flex1 mode. Automatically disables conflicting
177 177 flex modes. See the widget tutorial part 5 example notebook for more
178 178 information.
179 179
180 180 Parameters
181 181 ----------
182 182 enabled: bool (optional)
183 183 Enabled or disable the flex1 attribute of the container, defaults to
184 184 True."""
185 185 self._flex1 = enabled
186 186 if enabled:
187 187 self._flex0 = False
188 188 self._flex2 = False
189 189
190 190 def flex2(self, enabled=True):
191 191 """Put this container in flex2 mode. Automatically disables conflicting
192 192 flex modes. See the widget tutorial part 5 example notebook for more
193 193 information.
194 194
195 195 Parameters
196 196 ----------
197 197 enabled: bool (optional)
198 198 Enabled or disable the flex2 attribute of the container, defaults to
199 199 True."""
200 200 self._flex2 = enabled
201 201 if enabled:
202 202 self._flex0 = False
203 203 self._flex1 = False
@@ -1,30 +1,30
1 1 """FloatWidget class.
2 2
3 3 Represents an unbounded float using a widget.
4 4 """
5 5 #-----------------------------------------------------------------------------
6 6 # Copyright (c) 2013, the IPython Development Team.
7 7 #
8 8 # Distributed under the terms of the Modified BSD License.
9 9 #
10 10 # The full license is in the file COPYING.txt, distributed with this software.
11 11 #-----------------------------------------------------------------------------
12 12
13 13 #-----------------------------------------------------------------------------
14 14 # Imports
15 15 #-----------------------------------------------------------------------------
16 16 from .widget import DOMWidget
17 17 from IPython.utils.traitlets import Unicode, Float, Bool, List
18 18
19 19 #-----------------------------------------------------------------------------
20 20 # Classes
21 21 #-----------------------------------------------------------------------------
22 22 class FloatWidget(DOMWidget):
23 23 target_name = Unicode('FloatWidgetModel')
24 default_view_name = Unicode('FloatTextView')
24 view_name = Unicode('FloatTextView')
25 25
26 26 # Keys
27 27 keys = ['value', 'disabled', 'description'] + DOMWidget.keys
28 28 value = Float(0.0, help="Float value")
29 29 disabled = Bool(False, help="Enable or disable user changes")
30 30 description = Unicode(help="Description of the value this widget represents")
@@ -1,34 +1,34
1 1 """FloatRangeWidget class.
2 2
3 3 Represents a bounded float using a widget.
4 4 """
5 5 #-----------------------------------------------------------------------------
6 6 # Copyright (c) 2013, the IPython Development Team.
7 7 #
8 8 # Distributed under the terms of the Modified BSD License.
9 9 #
10 10 # The full license is in the file COPYING.txt, distributed with this software.
11 11 #-----------------------------------------------------------------------------
12 12
13 13 #-----------------------------------------------------------------------------
14 14 # Imports
15 15 #-----------------------------------------------------------------------------
16 16 from .widget import DOMWidget
17 17 from IPython.utils.traitlets import Unicode, Float, Bool, List
18 18
19 19 #-----------------------------------------------------------------------------
20 20 # Classes
21 21 #-----------------------------------------------------------------------------
22 22 class FloatRangeWidget(DOMWidget):
23 23 target_name = Unicode('FloatRangeWidgetModel')
24 default_view_name = Unicode('FloatSliderView')
24 view_name = Unicode('FloatSliderView')
25 25
26 26 # Keys
27 27 keys = ['value', 'step', 'max', 'min', 'disabled', 'orientation', 'description'] + DOMWidget.keys
28 28 value = Float(0.0, help="Flaot value")
29 29 max = Float(100.0, help="Max value")
30 30 min = Float(0.0, help="Min value")
31 31 disabled = Bool(False, help="Enable or disable user changes")
32 32 step = Float(0.1, help="Minimum step that the value can take (ignored by some views)")
33 33 orientation = Unicode(u'horizontal', help="Vertical or horizontal (ignored by some views)")
34 34 description = Unicode(help="Description of the value this widget represents")
@@ -1,38 +1,38
1 1 """ButtonWidget 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 6 #-----------------------------------------------------------------------------
7 7 # Copyright (c) 2013, the IPython Development Team.
8 8 #
9 9 # Distributed under the terms of the Modified BSD License.
10 10 #
11 11 # The full license is in the file COPYING.txt, distributed with this software.
12 12 #-----------------------------------------------------------------------------
13 13
14 14 #-----------------------------------------------------------------------------
15 15 # Imports
16 16 #-----------------------------------------------------------------------------
17 17 import base64
18 18
19 19 from .widget import DOMWidget
20 20 from IPython.utils.traitlets import Unicode, Bytes
21 21
22 22 #-----------------------------------------------------------------------------
23 23 # Classes
24 24 #-----------------------------------------------------------------------------
25 25 class ImageWidget(DOMWidget):
26 26 target_name = Unicode('ImageWidgetModel')
27 default_view_name = Unicode('ImageView')
27 view_name = Unicode('ImageView')
28 28
29 29 # Define the custom state properties to sync with the front-end
30 30 keys = ['image_format', 'width', 'height', '_b64value'] + DOMWidget.keys
31 31 image_format = Unicode('png')
32 32 width = Unicode()
33 33 height = Unicode()
34 34 _b64value = Unicode()
35 35
36 36 value = Bytes()
37 37 def _value_changed(self, name, old, new):
38 38 self._b64value = base64.b64encode(new) No newline at end of file
@@ -1,30 +1,30
1 1 """IntWidget class.
2 2
3 3 Represents an unbounded int using a widget.
4 4 """
5 5 #-----------------------------------------------------------------------------
6 6 # Copyright (c) 2013, the IPython Development Team.
7 7 #
8 8 # Distributed under the terms of the Modified BSD License.
9 9 #
10 10 # The full license is in the file COPYING.txt, distributed with this software.
11 11 #-----------------------------------------------------------------------------
12 12
13 13 #-----------------------------------------------------------------------------
14 14 # Imports
15 15 #-----------------------------------------------------------------------------
16 16 from .widget import DOMWidget
17 17 from IPython.utils.traitlets import Unicode, Int, Bool, List
18 18
19 19 #-----------------------------------------------------------------------------
20 20 # Classes
21 21 #-----------------------------------------------------------------------------
22 22 class IntWidget(DOMWidget):
23 23 target_name = Unicode('IntWidgetModel')
24 default_view_name = Unicode('IntTextView')
24 view_name = Unicode('IntTextView')
25 25
26 26 # Keys
27 27 keys = ['value', 'disabled', 'description'] + DOMWidget.keys
28 28 value = Int(0, help="Int value")
29 29 disabled = Bool(False, help="Enable or disable user changes")
30 30 description = Unicode(help="Description of the value this widget represents")
@@ -1,34 +1,34
1 1 """IntRangeWidget class.
2 2
3 3 Represents a bounded int using a widget.
4 4 """
5 5 #-----------------------------------------------------------------------------
6 6 # Copyright (c) 2013, the IPython Development Team.
7 7 #
8 8 # Distributed under the terms of the Modified BSD License.
9 9 #
10 10 # The full license is in the file COPYING.txt, distributed with this software.
11 11 #-----------------------------------------------------------------------------
12 12
13 13 #-----------------------------------------------------------------------------
14 14 # Imports
15 15 #-----------------------------------------------------------------------------
16 16 from .widget import DOMWidget
17 17 from IPython.utils.traitlets import Unicode, Int, Bool, List
18 18
19 19 #-----------------------------------------------------------------------------
20 20 # Classes
21 21 #-----------------------------------------------------------------------------
22 22 class IntRangeWidget(DOMWidget):
23 23 target_name = Unicode('IntRangeWidgetModel')
24 default_view_name = Unicode('IntSliderView')
24 view_name = Unicode('IntSliderView')
25 25
26 26 # Keys
27 27 keys = ['value', 'step', 'max', 'min', 'disabled', 'orientation', 'description'] + DOMWidget.keys
28 28 value = Int(0, help="Int value")
29 29 max = Int(100, help="Max value")
30 30 min = Int(0, help="Min value")
31 31 disabled = Bool(False, help="Enable or disable user changes")
32 32 step = Int(1, help="Minimum step that the value can take (ignored by some views)")
33 33 orientation = Unicode(u'horizontal', help="Vertical or horizontal (ignored by some views)")
34 34 description = Unicode(help="Description of the value this widget represents")
@@ -1,58 +1,58
1 1 """MulticontainerWidget class.
2 2
3 3 Represents a multipage container that can be used to group other widgets into
4 4 pages.
5 5 """
6 6 #-----------------------------------------------------------------------------
7 7 # Copyright (c) 2013, the IPython Development Team.
8 8 #
9 9 # Distributed under the terms of the Modified BSD License.
10 10 #
11 11 # The full license is in the file COPYING.txt, distributed with this software.
12 12 #-----------------------------------------------------------------------------
13 13
14 14 #-----------------------------------------------------------------------------
15 15 # Imports
16 16 #-----------------------------------------------------------------------------
17 17 from .widget import DOMWidget
18 18 from IPython.utils.traitlets import Unicode, Dict, Int, List, Instance
19 19
20 20 #-----------------------------------------------------------------------------
21 21 # Classes
22 22 #-----------------------------------------------------------------------------
23 23 class MulticontainerWidget(DOMWidget):
24 24 target_name = Unicode('MulticontainerWidgetModel')
25 default_view_name = Unicode('TabView')
25 view_name = Unicode('TabView')
26 26
27 27 # Keys
28 28 keys = ['_titles', 'selected_index', 'children'] + DOMWidget.keys
29 29 _titles = Dict(help="Titles of the pages")
30 30 selected_index = Int(0)
31 31
32 32 children = List(Instance(DOMWidget))
33 33
34 34 # Public methods
35 35 def set_title(self, index, title):
36 36 """Sets the title of a container page
37 37
38 38 Parameters
39 39 ----------
40 40 index : int
41 41 Index of the container page
42 42 title : unicode
43 43 New title"""
44 44 self._titles[index] = title
45 45 self.send_state('_titles')
46 46
47 47
48 48 def get_title(self, index):
49 49 """Gets the title of a container pages
50 50
51 51 Parameters
52 52 ----------
53 53 index : int
54 54 Index of the container page"""
55 55 if index in self._titles:
56 56 return self._titles[index]
57 57 else:
58 58 return None
@@ -1,32 +1,32
1 1 """SelectionWidget class.
2 2
3 3 Represents an enumeration using a widget.
4 4 """
5 5 #-----------------------------------------------------------------------------
6 6 # Copyright (c) 2013, the IPython Development Team.
7 7 #
8 8 # Distributed under the terms of the Modified BSD License.
9 9 #
10 10 # The full license is in the file COPYING.txt, distributed with this software.
11 11 #-----------------------------------------------------------------------------
12 12
13 13 #-----------------------------------------------------------------------------
14 14 # Imports
15 15 #-----------------------------------------------------------------------------
16 16 from .widget import DOMWidget
17 17 from IPython.utils.traitlets import Unicode, List, Bool
18 18
19 19 #-----------------------------------------------------------------------------
20 20 # SelectionWidget
21 21 #-----------------------------------------------------------------------------
22 22 class SelectionWidget(DOMWidget):
23 23 target_name = Unicode('SelectionWidgetModel')
24 default_view_name = Unicode('DropdownView')
24 view_name = Unicode('DropdownView')
25 25
26 26 # Keys
27 27 keys = ['value', 'values', 'disabled', 'description'] + DOMWidget.keys
28 28 value = Unicode(help="Selected value")
29 29 values = List(help="List of values the user can select")
30 30 disabled = Bool(False, help="Enable or disable user changes")
31 31 description = Unicode(help="Description of the value this widget represents")
32 32 No newline at end of file
@@ -1,93 +1,93
1 1 """StringWidget class.
2 2
3 3 Represents a unicode string using a widget.
4 4 """
5 5 #-----------------------------------------------------------------------------
6 6 # Copyright (c) 2013, the IPython Development Team.
7 7 #
8 8 # Distributed under the terms of the Modified BSD License.
9 9 #
10 10 # The full license is in the file COPYING.txt, distributed with this software.
11 11 #-----------------------------------------------------------------------------
12 12
13 13 #-----------------------------------------------------------------------------
14 14 # Imports
15 15 #-----------------------------------------------------------------------------
16 16 import inspect
17 17 import types
18 18
19 19 from .widget import DOMWidget
20 20 from IPython.utils.traitlets import Unicode, Bool, List, Int
21 21
22 22 #-----------------------------------------------------------------------------
23 23 # Classes
24 24 #-----------------------------------------------------------------------------
25 25 class StringWidget(DOMWidget):
26 26 target_name = Unicode('StringWidgetModel')
27 default_view_name = Unicode('TextBoxView')
27 view_name = Unicode('TextBoxView')
28 28
29 29 # Keys
30 30 keys = ['value', 'disabled', 'description'] + DOMWidget.keys
31 31 value = Unicode(help="String value")
32 32 disabled = Bool(False, help="Enable or disable user changes")
33 33 description = Unicode(help="Description of the value this widget represents")
34 34
35 35
36 36 def __init__(self, **kwargs):
37 37 super(StringWidget, self).__init__(**kwargs)
38 38 self._submission_callbacks = []
39 39 self.on_msg(self._handle_string_msg)
40 40
41 41
42 42 def scroll_to_bottom(self):
43 43 self.send({"method": "scroll_to_bottom"})
44 44
45 45
46 46 def _handle_string_msg(self, content):
47 47 """Handle a msg from the front-end
48 48
49 49 Parameters
50 50 ----------
51 51 content: dict
52 52 Content of the msg."""
53 53 if 'event' in content and content['event'] == 'submit':
54 54 self._handle_submit()
55 55
56 56
57 57 def on_submit(self, callback, remove=False):
58 58 """Register a callback to handle text submission (triggered when the
59 59 user clicks enter).
60 60
61 61 Parameters
62 62 callback: Method handle
63 63 Function to be called when the text has been submitted. Function
64 64 can have two possible signatures:
65 65 callback()
66 66 callback(sender)
67 67 remove: bool (optional)
68 68 Whether or not to unregister the callback"""
69 69 if remove and callback in self._submission_callbacks:
70 70 self._submission_callbacks.remove(callback)
71 71 elif not remove and not callback in self._submission_callbacks:
72 72 self._submission_callbacks.append(callback)
73 73
74 74
75 75 def _handle_submit(self):
76 76 """Handles when a string widget view is submitted."""
77 77 for handler in self._submission_callbacks:
78 78 if callable(handler):
79 79 argspec = inspect.getargspec(handler)
80 80 nargs = len(argspec[0])
81 81
82 82 # Bound methods have an additional 'self' argument
83 83 if isinstance(handler, types.MethodType):
84 84 nargs -= 1
85 85
86 86 # Call the callback
87 87 if nargs == 0:
88 88 handler()
89 89 elif nargs == 1:
90 90 handler(self)
91 91 else:
92 92 raise TypeError('StringWidget submit callback must ' \
93 93 'accept 0 or 1 arguments.')
General Comments 0
You need to be logged in to leave comments. Login now