##// END OF EJS Templates
add docstrings, validation to widget links
Min RK -
Show More
@@ -11,7 +11,7 b' from .widget_selection import RadioButtons, ToggleButtons, Dropdown, Select'
11 11 from .widget_selectioncontainer import Tab, Accordion
12 12 from .widget_string import HTML, Latex, Text, Textarea
13 13 from .interaction import interact, interactive, fixed, interact_manual
14 from .widget_link import Link, link, DirectionalLink, dlink
14 from .widget_link import Link, link, DirectionalLink, directional_link, dlink
15 15
16 16 # Deprecated classes
17 17 from .widget_bool import CheckboxWidget, ToggleButtonWidget
@@ -2,31 +2,47 b''
2 2
3 3 Propagate changes between widgets on the javascript side
4 4 """
5 #-----------------------------------------------------------------------------
6 # Copyright (c) 2014, 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 Widget
17 from IPython.utils.traitlets import Unicode, Tuple, Any
10 from IPython.testing.skipdoctest import skip_doctest
11 from IPython.utils.traitlets import Unicode, Tuple, List,Instance, TraitError
18 12
19 #-----------------------------------------------------------------------------
20 # Classes
21 #-----------------------------------------------------------------------------
13 class WidgetTraitTuple(Tuple):
14 """Traitlet for validating a single (Widget, 'trait_name') pair"""
15
16 def __init__(self, **kwargs):
17 super(WidgetTraitTuple, self).__init__(Instance(Widget), Unicode, **kwargs)
18
19 def validate_elements(self, obj, value):
20 value = super(WidgetTraitTuple, self).validate_elements(obj, value)
21 widget, trait_name = value
22 trait = widget.traits().get(trait_name)
23 trait_repr = "%s.%s" % (widget.__class__.__name__, trait_name)
24 # Can't raise TraitError because the parent will swallow the message
25 # and throw it away in a new, less informative TraitError
26 if trait is None:
27 raise TypeError("No such trait: %s" % trait_repr)
28 elif not trait.get_metadata('sync'):
29 raise TypeError("%s cannot be synced" % trait_repr)
30
31 return value
22 32
23 33
24 34 class Link(Widget):
25 """Link Widget"""
35 """Link Widget
36
37 one trait:
38 widgets, a list of (widget, 'trait_name') tuples which should be linked in the frontend.
39 """
26 40 _model_name = Unicode('LinkModel', sync=True)
27 widgets = Tuple(sync=True, allow_none=False)
41 widgets = List(WidgetTraitTuple, sync=True)
28 42
29 def __init__(self, widgets=(), **kwargs):
43 def __init__(self, widgets, **kwargs):
44 if len(widgets) < 2:
45 raise TypeError("Require at least two widgets to link")
30 46 kwargs['widgets'] = widgets
31 47 super(Link, self).__init__(**kwargs)
32 48
@@ -35,19 +51,39 b' class Link(Widget):'
35 51 self.close()
36 52
37 53
54 @skip_doctest
38 55 def link(*args):
56 """Link traits from different widgets together on the frontend so they remain in sync.
57
58 Parameters
59 ----------
60 *args : two or more (Widget, 'trait_name') tuples that should be kept in sync.
61
62 Examples
63 --------
64
65 >>> c = link((widget1, 'value'), (widget2, 'value'), (widget3, 'value'))
66 """
39 67 return Link(widgets=args)
40 68
41 69
42 70 class DirectionalLink(Widget):
43 """Directional Link Widget"""
71 """A directional link
72
73 source: a (Widget, 'trait_name') tuple for the source trait
74 targets: one or more (Widget, 'trait_name') tuples that should be updated
75 when the source trait changes.
76 """
44 77 _model_name = Unicode('DirectionalLinkModel', sync=True)
45 targets = Any(sync=True)
46 source = Tuple(sync=True)
78 targets = List(WidgetTraitTuple, sync=True)
79 source = WidgetTraitTuple(sync=True)
47 80
48 81 # Does not quite behave like other widgets but reproduces
49 82 # the behavior of IPython.utils.traitlets.directional_link
50 def __init__(self, source, targets=(), **kwargs):
83 def __init__(self, source, targets, **kwargs):
84 if len(targets) < 1:
85 raise TypeError("Require at least two widgets to link")
86
51 87 kwargs['source'] = source
52 88 kwargs['targets'] = targets
53 89 super(DirectionalLink, self).__init__(**kwargs)
@@ -56,6 +92,21 b' class DirectionalLink(Widget):'
56 92 def unlink(self):
57 93 self.close()
58 94
95 @skip_doctest
96 def directional_link(source, *targets):
97 """Link the trait of a source widget with traits of target widgets in the frontend.
98
99 Parameters
100 ----------
101 source : a (Widget, 'trait_name') tuple for the source trait
102 *targets : one or more (Widget, 'trait_name') tuples that should be updated
103 when the source trait changes.
104
105 Examples
106 --------
107
108 >>> c = dlink((src_widget, 'value'), (tgt_widget1, 'value'), (tgt_widget2, 'value'))
109 """
110 return DirectionalLink(source=source, targets=targets)
59 111
60 def dlink(source, *targets):
61 return DirectionalLink(source, targets)
112 dlink = directional_link
General Comments 0
You need to be logged in to leave comments. Login now