##// END OF EJS Templates
Updates to widget.py...
Updates to widget.py Added global init js function Moved init comm logic to show function

File last commit:

r14232:c0cac1e8
r14232:c0cac1e8
Show More
widget.py
164 lines | 4.6 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
from IPython.utils.traitlets import Unicode, Dict
from IPython.display import Javascript, display
Jonathan Frederic
Updates to widget.py...
r14232 from IPython.utils.py3compat import string_types
from IPython.utils.javascript import display_all_js
def init_widget_js(cls):
path = os.path.split(os.path.abspath( __file__ ))[0]
display_all_js(path)
for root, dirs, files in os.walk(path):
for sub_directory in dirs:
display_all_js(os.path.join(path, sub_directory))
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):
# Handle backbone sync methods
sync_method = msg['content']['data']['sync_method']
sync_data = msg['content']['data']['sync_data']
if sync_method.lower() in ['create', 'update']:
self._handle_recieve_state(sync_data)
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):
if not self._property_lock:
# TODO: Validate properties.
# Send new state to frontend
self.send_state()
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:
self.comm.send({"method": "show", "view_name": view_name})
else:
self.comm.send({"method": "show",
"view_name": view_name,
"parent": self.parent.comm.comm_id})
# Now show children if any.
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
Added widget.py
r14223 def send_state(self):
state = {}
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})