##// END OF EJS Templates
use jslink, jsdlink for frontend link functions
Min RK -
Show More
@@ -1,38 +1,38 b''
1 from .widget import Widget, DOMWidget, CallbackDispatcher, register
1 from .widget import Widget, DOMWidget, CallbackDispatcher, register
2
2
3 from .widget_bool import Checkbox, ToggleButton
3 from .widget_bool import Checkbox, ToggleButton
4 from .widget_button import Button
4 from .widget_button import Button
5 from .widget_box import Box, FlexBox, HBox, VBox
5 from .widget_box import Box, FlexBox, HBox, VBox
6 from .widget_float import FloatText, BoundedFloatText, FloatSlider, FloatProgress, FloatRangeSlider
6 from .widget_float import FloatText, BoundedFloatText, FloatSlider, FloatProgress, FloatRangeSlider
7 from .widget_image import Image
7 from .widget_image import Image
8 from .widget_int import IntText, BoundedIntText, IntSlider, IntProgress, IntRangeSlider
8 from .widget_int import IntText, BoundedIntText, IntSlider, IntProgress, IntRangeSlider
9 from .widget_output import Output
9 from .widget_output import Output
10 from .widget_selection import RadioButtons, ToggleButtons, Dropdown, Select
10 from .widget_selection import RadioButtons, ToggleButtons, Dropdown, Select
11 from .widget_selectioncontainer import Tab, Accordion
11 from .widget_selectioncontainer import Tab, Accordion
12 from .widget_string import HTML, Latex, Text, Textarea
12 from .widget_string import HTML, Latex, Text, Textarea
13 from .interaction import interact, interactive, fixed, interact_manual
13 from .interaction import interact, interactive, fixed, interact_manual
14 from .widget_link import Link, link, DirectionalLink, directional_link, dlink
14 from .widget_link import jslink, jsdlink, Link, DirectionalLink
15
15
16 # Deprecated classes
16 # Deprecated classes
17 from .widget_bool import CheckboxWidget, ToggleButtonWidget
17 from .widget_bool import CheckboxWidget, ToggleButtonWidget
18 from .widget_button import ButtonWidget
18 from .widget_button import ButtonWidget
19 from .widget_box import ContainerWidget
19 from .widget_box import ContainerWidget
20 from .widget_float import FloatTextWidget, BoundedFloatTextWidget, FloatSliderWidget, FloatProgressWidget
20 from .widget_float import FloatTextWidget, BoundedFloatTextWidget, FloatSliderWidget, FloatProgressWidget
21 from .widget_image import ImageWidget
21 from .widget_image import ImageWidget
22 from .widget_int import IntTextWidget, BoundedIntTextWidget, IntSliderWidget, IntProgressWidget
22 from .widget_int import IntTextWidget, BoundedIntTextWidget, IntSliderWidget, IntProgressWidget
23 from .widget_selection import RadioButtonsWidget, ToggleButtonsWidget, DropdownWidget, SelectWidget
23 from .widget_selection import RadioButtonsWidget, ToggleButtonsWidget, DropdownWidget, SelectWidget
24 from .widget_selectioncontainer import TabWidget, AccordionWidget
24 from .widget_selectioncontainer import TabWidget, AccordionWidget
25 from .widget_string import HTMLWidget, LatexWidget, TextWidget, TextareaWidget
25 from .widget_string import HTMLWidget, LatexWidget, TextWidget, TextareaWidget
26
26
27 # We use warn_explicit so we have very brief messages without file or line numbers.
27 # We use warn_explicit so we have very brief messages without file or line numbers.
28 # The concern is that file or line numbers will confuse the interactive user.
28 # The concern is that file or line numbers will confuse the interactive user.
29 # To ignore this warning, do:
29 # To ignore this warning, do:
30 #
30 #
31 # from warnings import filterwarnings
31 # from warnings import filterwarnings
32 # filterwarnings('ignore', module='IPython.html.widgets')
32 # filterwarnings('ignore', module='IPython.html.widgets')
33
33
34 from warnings import warn_explicit
34 from warnings import warn_explicit
35 __warningregistry__ = {}
35 __warningregistry__ = {}
36 warn_explicit("IPython widgets are experimental and may change in the future.",
36 warn_explicit("IPython widgets are experimental and may change in the future.",
37 FutureWarning, '', 0, module = 'IPython.html.widgets',
37 FutureWarning, '', 0, module = 'IPython.html.widgets',
38 registry = __warningregistry__, module_globals = globals)
38 registry = __warningregistry__, module_globals = globals)
@@ -1,39 +1,39 b''
1 # Copyright (c) IPython Development Team.
1 # Copyright (c) IPython Development Team.
2 # Distributed under the terms of the Modified BSD License.
2 # Distributed under the terms of the Modified BSD License.
3
3
4 import nose.tools as nt
4 import nose.tools as nt
5
5
6 from .. import link, dlink, ToggleButton
6 from .. import jslink, jsdlink, ToggleButton
7 from .test_interaction import setup, teardown
7 from .test_interaction import setup, teardown
8
8
9 def test_link_args():
9 def test_jslink_args():
10 with nt.assert_raises(TypeError):
10 with nt.assert_raises(TypeError):
11 link()
11 jslink()
12 w1 = ToggleButton()
12 w1 = ToggleButton()
13 with nt.assert_raises(TypeError):
13 with nt.assert_raises(TypeError):
14 link((w1, 'value'))
14 jslink((w1, 'value'))
15
15
16 w2 = ToggleButton()
16 w2 = ToggleButton()
17 link((w1, 'value'), (w2, 'value'))
17 jslink((w1, 'value'), (w2, 'value'))
18
18
19 with nt.assert_raises(TypeError):
19 with nt.assert_raises(TypeError):
20 link((w1, 'value'), (w2, 'nosuchtrait'))
20 jslink((w1, 'value'), (w2, 'nosuchtrait'))
21
21
22 with nt.assert_raises(TypeError):
22 with nt.assert_raises(TypeError):
23 link((w1, 'value'), (w2, 'traits'))
23 jslink((w1, 'value'), (w2, 'traits'))
24
24
25 def test_dlink_args():
25 def test_jsdlink_args():
26 with nt.assert_raises(TypeError):
26 with nt.assert_raises(TypeError):
27 dlink()
27 jsdlink()
28 w1 = ToggleButton()
28 w1 = ToggleButton()
29 with nt.assert_raises(TypeError):
29 with nt.assert_raises(TypeError):
30 dlink((w1, 'value'))
30 jsdlink((w1, 'value'))
31
31
32 w2 = ToggleButton()
32 w2 = ToggleButton()
33 dlink((w1, 'value'), (w2, 'value'))
33 jsdlink((w1, 'value'), (w2, 'value'))
34
34
35 with nt.assert_raises(TypeError):
35 with nt.assert_raises(TypeError):
36 dlink((w1, 'value'), (w2, 'nosuchtrait'))
36 jsdlink((w1, 'value'), (w2, 'nosuchtrait'))
37
37
38 with nt.assert_raises(TypeError):
38 with nt.assert_raises(TypeError):
39 dlink((w1, 'value'), (w2, 'traits'))
39 jsdlink((w1, 'value'), (w2, 'traits'))
@@ -1,112 +1,111 b''
1 """Link and DirectionalLink classes.
1 """Link and DirectionalLink classes.
2
2
3 Propagate changes between widgets on the javascript side
3 Propagate changes between widgets on the javascript side
4 """
4 """
5
5
6 # Copyright (c) IPython Development Team.
6 # Copyright (c) IPython Development Team.
7 # Distributed under the terms of the Modified BSD License.
7 # Distributed under the terms of the Modified BSD License.
8
8
9 from .widget import Widget
9 from .widget import Widget
10 from IPython.testing.skipdoctest import skip_doctest
10 from IPython.testing.skipdoctest import skip_doctest
11 from IPython.utils.traitlets import Unicode, Tuple, List,Instance, TraitError
11 from IPython.utils.traitlets import Unicode, Tuple, List,Instance, TraitError
12
12
13 class WidgetTraitTuple(Tuple):
13 class WidgetTraitTuple(Tuple):
14 """Traitlet for validating a single (Widget, 'trait_name') pair"""
14 """Traitlet for validating a single (Widget, 'trait_name') pair"""
15
15
16 def __init__(self, **kwargs):
16 def __init__(self, **kwargs):
17 super(WidgetTraitTuple, self).__init__(Instance(Widget), Unicode, **kwargs)
17 super(WidgetTraitTuple, self).__init__(Instance(Widget), Unicode, **kwargs)
18
18
19 def validate_elements(self, obj, value):
19 def validate_elements(self, obj, value):
20 value = super(WidgetTraitTuple, self).validate_elements(obj, value)
20 value = super(WidgetTraitTuple, self).validate_elements(obj, value)
21 widget, trait_name = value
21 widget, trait_name = value
22 trait = widget.traits().get(trait_name)
22 trait = widget.traits().get(trait_name)
23 trait_repr = "%s.%s" % (widget.__class__.__name__, trait_name)
23 trait_repr = "%s.%s" % (widget.__class__.__name__, trait_name)
24 # Can't raise TraitError because the parent will swallow the message
24 # Can't raise TraitError because the parent will swallow the message
25 # and throw it away in a new, less informative TraitError
25 # and throw it away in a new, less informative TraitError
26 if trait is None:
26 if trait is None:
27 raise TypeError("No such trait: %s" % trait_repr)
27 raise TypeError("No such trait: %s" % trait_repr)
28 elif not trait.get_metadata('sync'):
28 elif not trait.get_metadata('sync'):
29 raise TypeError("%s cannot be synced" % trait_repr)
29 raise TypeError("%s cannot be synced" % trait_repr)
30
30
31 return value
31 return value
32
32
33
33
34 class Link(Widget):
34 class Link(Widget):
35 """Link Widget
35 """Link Widget
36
36
37 one trait:
37 one trait:
38 widgets, a list of (widget, 'trait_name') tuples which should be linked in the frontend.
38 widgets, a list of (widget, 'trait_name') tuples which should be linked in the frontend.
39 """
39 """
40 _model_name = Unicode('LinkModel', sync=True)
40 _model_name = Unicode('LinkModel', sync=True)
41 widgets = List(WidgetTraitTuple, sync=True)
41 widgets = List(WidgetTraitTuple, sync=True)
42
42
43 def __init__(self, widgets, **kwargs):
43 def __init__(self, widgets, **kwargs):
44 if len(widgets) < 2:
44 if len(widgets) < 2:
45 raise TypeError("Require at least two widgets to link")
45 raise TypeError("Require at least two widgets to link")
46 kwargs['widgets'] = widgets
46 kwargs['widgets'] = widgets
47 super(Link, self).__init__(**kwargs)
47 super(Link, self).__init__(**kwargs)
48
48
49 # for compatibility with traitlet links
49 # for compatibility with traitlet links
50 def unlink(self):
50 def unlink(self):
51 self.close()
51 self.close()
52
52
53
53
54 @skip_doctest
54 @skip_doctest
55 def link(*args):
55 def jslink(*args):
56 """Link traits from different widgets together on the frontend so they remain in sync.
56 """Link traits from different widgets together on the frontend so they remain in sync.
57
57
58 Parameters
58 Parameters
59 ----------
59 ----------
60 *args : two or more (Widget, 'trait_name') tuples that should be kept in sync.
60 *args : two or more (Widget, 'trait_name') tuples that should be kept in sync.
61
61
62 Examples
62 Examples
63 --------
63 --------
64
64
65 >>> c = link((widget1, 'value'), (widget2, 'value'), (widget3, 'value'))
65 >>> c = link((widget1, 'value'), (widget2, 'value'), (widget3, 'value'))
66 """
66 """
67 return Link(widgets=args)
67 return Link(widgets=args)
68
68
69
69
70 class DirectionalLink(Widget):
70 class DirectionalLink(Widget):
71 """A directional link
71 """A directional link
72
72
73 source: a (Widget, 'trait_name') tuple for the source trait
73 source: a (Widget, 'trait_name') tuple for the source trait
74 targets: one or more (Widget, 'trait_name') tuples that should be updated
74 targets: one or more (Widget, 'trait_name') tuples that should be updated
75 when the source trait changes.
75 when the source trait changes.
76 """
76 """
77 _model_name = Unicode('DirectionalLinkModel', sync=True)
77 _model_name = Unicode('DirectionalLinkModel', sync=True)
78 targets = List(WidgetTraitTuple, sync=True)
78 targets = List(WidgetTraitTuple, sync=True)
79 source = WidgetTraitTuple(sync=True)
79 source = WidgetTraitTuple(sync=True)
80
80
81 # Does not quite behave like other widgets but reproduces
81 # Does not quite behave like other widgets but reproduces
82 # the behavior of IPython.utils.traitlets.directional_link
82 # the behavior of IPython.utils.traitlets.directional_link
83 def __init__(self, source, targets, **kwargs):
83 def __init__(self, source, targets, **kwargs):
84 if len(targets) < 1:
84 if len(targets) < 1:
85 raise TypeError("Require at least two widgets to link")
85 raise TypeError("Require at least two widgets to link")
86
86
87 kwargs['source'] = source
87 kwargs['source'] = source
88 kwargs['targets'] = targets
88 kwargs['targets'] = targets
89 super(DirectionalLink, self).__init__(**kwargs)
89 super(DirectionalLink, self).__init__(**kwargs)
90
90
91 # for compatibility with traitlet links
91 # for compatibility with traitlet links
92 def unlink(self):
92 def unlink(self):
93 self.close()
93 self.close()
94
94
95 @skip_doctest
95 @skip_doctest
96 def directional_link(source, *targets):
96 def jsdlink(source, *targets):
97 """Link the trait of a source widget with traits of target widgets in the frontend.
97 """Link the trait of a source widget with traits of target widgets in the frontend.
98
98
99 Parameters
99 Parameters
100 ----------
100 ----------
101 source : a (Widget, 'trait_name') tuple for the source trait
101 source : a (Widget, 'trait_name') tuple for the source trait
102 *targets : one or more (Widget, 'trait_name') tuples that should be updated
102 *targets : one or more (Widget, 'trait_name') tuples that should be updated
103 when the source trait changes.
103 when the source trait changes.
104
104
105 Examples
105 Examples
106 --------
106 --------
107
107
108 >>> c = dlink((src_widget, 'value'), (tgt_widget1, 'value'), (tgt_widget2, 'value'))
108 >>> c = dlink((src_widget, 'value'), (tgt_widget1, 'value'), (tgt_widget2, 'value'))
109 """
109 """
110 return DirectionalLink(source=source, targets=targets)
110 return DirectionalLink(source=source, targets=targets)
111
111
112 dlink = directional_link
General Comments 0
You need to be logged in to leave comments. Login now