##// END OF EJS Templates
Merge pull request #7603 from SylvainCorlay/traitlet_hook...
Merge pull request #7603 from SylvainCorlay/traitlet_hook Early validation hook

File last commit:

r20230:403a37ac
r20762:d532b150 merge
Show More
widget_link.py
111 lines | 3.5 KiB | text/x-python | PythonLexer
Jason Grout
Adding Link widget
r18051 """Link and DirectionalLink classes.
Jason Grout
Add the unlink method to javascript links to maintain compatibility with traitlet links
r19390 Propagate changes between widgets on the javascript side
Jason Grout
Adding Link widget
r18051 """
Min RK
add docstrings, validation to widget links
r20075
# Copyright (c) IPython Development Team.
Jason Grout
Adding Link widget
r18051 # Distributed under the terms of the Modified BSD License.
from .widget import Widget
Min RK
add docstrings, validation to widget links
r20075 from IPython.testing.skipdoctest import skip_doctest
from IPython.utils.traitlets import Unicode, Tuple, List,Instance, TraitError
Jason Grout
Adding Link widget
r18051
Min RK
add docstrings, validation to widget links
r20075 class WidgetTraitTuple(Tuple):
"""Traitlet for validating a single (Widget, 'trait_name') pair"""
def __init__(self, **kwargs):
super(WidgetTraitTuple, self).__init__(Instance(Widget), Unicode, **kwargs)
def validate_elements(self, obj, value):
value = super(WidgetTraitTuple, self).validate_elements(obj, value)
widget, trait_name = value
trait = widget.traits().get(trait_name)
trait_repr = "%s.%s" % (widget.__class__.__name__, trait_name)
# Can't raise TraitError because the parent will swallow the message
# and throw it away in a new, less informative TraitError
if trait is None:
raise TypeError("No such trait: %s" % trait_repr)
elif not trait.get_metadata('sync'):
raise TypeError("%s cannot be synced" % trait_repr)
return value
Jason Grout
Adding Link widget
r18051
class Link(Widget):
Min RK
add docstrings, validation to widget links
r20075 """Link Widget
one trait:
widgets, a list of (widget, 'trait_name') tuples which should be linked in the frontend.
"""
Jason Grout
Adding Link widget
r18051 _model_name = Unicode('LinkModel', sync=True)
Min RK
add docstrings, validation to widget links
r20075 widgets = List(WidgetTraitTuple, sync=True)
Jason Grout
Adding Link widget
r18051
Min RK
add docstrings, validation to widget links
r20075 def __init__(self, widgets, **kwargs):
if len(widgets) < 2:
raise TypeError("Require at least two widgets to link")
Jason Grout
Adding Link widget
r18051 kwargs['widgets'] = widgets
super(Link, self).__init__(**kwargs)
Jason Grout
Add the unlink method to javascript links to maintain compatibility with traitlet links
r19390 # for compatibility with traitlet links
def unlink(self):
self.close()
Sylvain Corlay
Adding directional link widget
r18052
Min RK
add docstrings, validation to widget links
r20075 @skip_doctest
Min RK
use jslink, jsdlink for frontend link functions
r20230 def jslink(*args):
Min RK
add docstrings, validation to widget links
r20075 """Link traits from different widgets together on the frontend so they remain in sync.
Parameters
----------
*args : two or more (Widget, 'trait_name') tuples that should be kept in sync.
Examples
--------
>>> c = link((widget1, 'value'), (widget2, 'value'), (widget3, 'value'))
"""
Jason Grout
Adding Link widget
r18051 return Link(widgets=args)
Sylvain Corlay
Adding directional link widget
r18052
class DirectionalLink(Widget):
Min RK
add docstrings, validation to widget links
r20075 """A directional link
source: a (Widget, 'trait_name') tuple for the source trait
targets: one or more (Widget, 'trait_name') tuples that should be updated
when the source trait changes.
"""
Sylvain Corlay
Adding directional link widget
r18052 _model_name = Unicode('DirectionalLinkModel', sync=True)
Min RK
add docstrings, validation to widget links
r20075 targets = List(WidgetTraitTuple, sync=True)
source = WidgetTraitTuple(sync=True)
Sylvain Corlay
Adding directional link widget
r18052
# Does not quite behave like other widgets but reproduces
# the behavior of IPython.utils.traitlets.directional_link
Min RK
add docstrings, validation to widget links
r20075 def __init__(self, source, targets, **kwargs):
if len(targets) < 1:
raise TypeError("Require at least two widgets to link")
Sylvain Corlay
Adding directional link widget
r18052 kwargs['source'] = source
kwargs['targets'] = targets
super(DirectionalLink, self).__init__(**kwargs)
Jason Grout
Add the unlink method to javascript links to maintain compatibility with traitlet links
r19390 # for compatibility with traitlet links
def unlink(self):
self.close()
Min RK
add docstrings, validation to widget links
r20075 @skip_doctest
Min RK
use jslink, jsdlink for frontend link functions
r20230 def jsdlink(source, *targets):
Min RK
add docstrings, validation to widget links
r20075 """Link the trait of a source widget with traits of target widgets in the frontend.
Parameters
----------
source : a (Widget, 'trait_name') tuple for the source trait
*targets : one or more (Widget, 'trait_name') tuples that should be updated
when the source trait changes.
Examples
--------
>>> c = dlink((src_widget, 'value'), (tgt_widget1, 'value'), (tgt_widget2, 'value'))
"""
return DirectionalLink(source=source, targets=targets)
Sylvain Corlay
Adding directional link widget
r18052