##// END OF EJS Templates
Changed parent/child api widgets
Changed parent/child api widgets

File last commit:

r14278:f58ca8b9
r14280:f8192995
Show More
widget.py
171 lines | 5.0 KiB | text/x-python | PythonLexer
Jonathan Frederic
Added widget.py
r14223 from copy import copy
Jonathan Frederic
Updates to widget.py...
r14232 from glob import glob
Jonathan Frederic
Added widget.py
r14223 import uuid
import sys
Jonathan Frederic
Updates to widget.py...
r14232 import os
Jonathan Frederic
Added widget.py
r14223
Jonathan Frederic
Updates to widget.py...
r14232 import IPython
Jonathan Frederic
Basic display logic...
r14229 from IPython.kernel.comm import Comm
from IPython.config import LoggingConfigurable
Jonathan Frederic
Added system that allows js to be required by widgets.
r14256 from IPython.utils.traitlets import Unicode, Dict, List
Jonathan Frederic
Basic display logic...
r14229 from IPython.display import Javascript, display
Jonathan Frederic
Updates to widget.py...
r14232 from IPython.utils.py3compat import string_types
Jonathan Frederic
Changed js loading,...
r14261 def init_widget_js():
path = os.path.split(os.path.abspath( __file__ ))[0]
for filepath in glob(os.path.join(path, "*.py")):
filename = os.path.split(filepath)[1]
name = filename.rsplit('.', 1)[0]
Jonathan Frederic
Renamed widget python classes to avoid name stomping
r14267 if not (name == 'widget' or name == '__init__') and name.startswith('widget_'):
# Remove 'widget_' from the start of the name before compiling the path.
Jonathan Frederic
LOTS OF WIDGET CHANGES...
r14278 js_path = '../static/notebook/js/widgets/%s.js' % name[7:]
Jonathan Frederic
Changed js loading,...
r14261 display(Javascript(data='$.getScript("%s");' % js_path))
Jonathan Frederic
Updates to widget.py...
r14232
class Widget(LoggingConfigurable):
Jonathan Frederic
Added widget.py
r14223
### Public declarations
target_name = Unicode('widget')
Jonathan Frederic
Updates to widget.py...
r14232 default_view_name = Unicode()
Jonathan Frederic
Added widget.py
r14223
### Private/protected declarations
_keys = []
_property_lock = False
_parent = None
_children = []
_css = Dict()
### Public constructor
def __init__(self, parent=None, **kwargs):
super(Widget, self).__init__(**kwargs)
self._children = []
if parent is not None:
parent._children.append(self)
self._parent = parent
Jonathan Frederic
Updates to widget.py...
r14232 self.comm = None
Jonathan Frederic
Added widget.py
r14223
# Register after init to allow default values to be specified
self.on_trait_change(self._handle_property_changed, self.keys)
def __del__(self):
self.close()
def close(self):
self.comm.close()
del self.comm
### Properties
def _get_parent(self):
return self._parent
parent = property(_get_parent)
def _get_children(self):
return copy(self._children)
children = property(_get_children)
def _get_keys(self):
keys = ['_css']
keys.extend(self._keys)
return keys
keys = property(_get_keys)
def _get_css(self, key, selector=""):
if selector in self._css and key in self._css[selector]:
return self._css[selector][key]
else:
return None
def _set_css(self, value, key, selector=""):
if selector not in self._css:
self._css[selector] = {}
# Only update the property if it has changed.
if not (key in self._css[selector] and value in self._css[selector][key]):
self._css[selector][key] = value
self.send_state() # Send new state to client.
css = property(_get_css, _set_css)
### Event handlers
def _handle_msg(self, msg):
Jonathan Frederic
Add state packet delta compression.
r14273 # Handle backbone sync methods CREATE, PATCH, and UPDATE
Jonathan Frederic
Added widget.py
r14223 sync_method = msg['content']['data']['sync_method']
sync_data = msg['content']['data']['sync_data']
Jonathan Frederic
Add state packet delta compression.
r14273 self._handle_recieve_state(sync_data) # handles all methods
Jonathan Frederic
Added widget.py
r14223
def _handle_recieve_state(self, sync_data):
self._property_lock = True
try:
# Use _keys instead of keys - Don't get retrieve the css from the client side.
for name in self._keys:
if name in sync_data:
setattr(self, name, sync_data[name])
finally:
self._property_lock = False
def _handle_property_changed(self, name, old, new):
Jonathan Frederic
Fixed bug where properties couldn't be set on model till model was shown
r14246 if not self._property_lock and self.comm is not None:
Jonathan Frederic
Added widget.py
r14223 # TODO: Validate properties.
# Send new state to frontend
Jonathan Frederic
Add state packet delta compression.
r14273 self.send_state(key=name)
Jonathan Frederic
Updates to widget.py...
r14232
def _handle_close(self):
self.comm = None
Jonathan Frederic
Added widget.py
r14223
### Public methods
Jonathan Frederic
Updates to widget.py...
r14232 def _repr_widget_(self, view_name=None):
Jonathan Frederic
Added widget.py
r14223 if not view_name:
Jonathan Frederic
Updates to widget.py...
r14232 view_name = self.default_view_name
# Create a comm.
if self.comm is None:
self.comm = Comm(target_name=self.target_name)
self.comm.on_msg(self._handle_msg)
self.comm.on_close(self._handle_close)
Jonathan Frederic
Added widget.py
r14223 # Make sure model is syncronized
self.send_state()
# Show view.
if self.parent is None:
Jonathan Frederic
LOTS OF WIDGET CHANGES...
r14278 self.comm.send({"method": "display", "view_name": view_name})
Jonathan Frederic
Added widget.py
r14223 else:
Jonathan Frederic
LOTS OF WIDGET CHANGES...
r14278 self.comm.send({"method": "display",
Jonathan Frederic
Added widget.py
r14223 "view_name": view_name,
"parent": self.parent.comm.comm_id})
Jonathan Frederic
LOTS OF WIDGET CHANGES...
r14278 # Now display children if any.
Jonathan Frederic
Added widget.py
r14223 for child in self.children:
Jonathan Frederic
Basic display logic...
r14229 child._repr_widget_()
Jonathan Frederic
Updates to widget.py...
r14232 return None
Jonathan Frederic
Add state packet delta compression.
r14273 def send_state(self, key=None):
Jonathan Frederic
Added widget.py
r14223 state = {}
Jonathan Frederic
Add state packet delta compression.
r14273
# If a key is provided, just send the state of that key.
keys = []
if key is None:
keys.extend(self.keys)
else:
keys.append(key)
Jonathan Frederic
Added widget.py
r14223 for key in self.keys:
try:
state[key] = getattr(self, key)
except Exception as e:
pass # Eat errors, nom nom nom
self.comm.send({"method": "update",
Jonathan Frederic
Updates to widget.py...
r14232 "state": state})