##// END OF EJS Templates
Register init_widget_js...
Jonathan Frederic -
Show More
@@ -1,7 +1,7 b''
1 from widget import Widget
1 from widget import Widget, init_widget_js
2 2
3 3 from container import ContainerWidget
4 4 from float_range import FloatRangeWidget
5 5 from int_range import IntRangeWidget
6 6 from selection import SelectionWidget
7 7 from string import StringWidget
@@ -1,165 +1,165 b''
1 1
2 2 from copy import copy
3 3 from glob import glob
4 4 import uuid
5 5 import sys
6 6 import os
7 7
8 8 import IPython
9 9 from IPython.kernel.comm import Comm
10 10 from IPython.config import LoggingConfigurable
11 11 from IPython.utils.traitlets import Unicode, Dict
12 12 from IPython.display import Javascript, display
13 13 from IPython.utils.py3compat import string_types
14 14 from IPython.utils.javascript import display_all_js
15 15
16 def init_widget_js(cls):
16 def init_widget_js():
17 17 path = os.path.split(os.path.abspath( __file__ ))[0]
18 18 display_all_js(path)
19 19 for root, dirs, files in os.walk(path):
20 20 for sub_directory in dirs:
21 21 display_all_js(os.path.join(path, sub_directory))
22 22
23 23
24 24 class Widget(LoggingConfigurable):
25 25
26 26 ### Public declarations
27 27 target_name = Unicode('widget')
28 28 default_view_name = Unicode()
29 29
30 30
31 31 ### Private/protected declarations
32 32 _keys = []
33 33 _property_lock = False
34 34 _parent = None
35 35 _children = []
36 36 _css = Dict()
37 37
38 38
39 39 ### Public constructor
40 40 def __init__(self, parent=None, **kwargs):
41 41 super(Widget, self).__init__(**kwargs)
42 42
43 43 self._children = []
44 44 if parent is not None:
45 45 parent._children.append(self)
46 46 self._parent = parent
47 47 self.comm = None
48 48
49 49 # Register after init to allow default values to be specified
50 50 self.on_trait_change(self._handle_property_changed, self.keys)
51 51
52 52
53 53 def __del__(self):
54 54 self.close()
55 55
56 56 def close(self):
57 57 self.comm.close()
58 58 del self.comm
59 59
60 60
61 61 ### Properties
62 62 def _get_parent(self):
63 63 return self._parent
64 64 parent = property(_get_parent)
65 65
66 66
67 67 def _get_children(self):
68 68 return copy(self._children)
69 69 children = property(_get_children)
70 70
71 71
72 72 def _get_keys(self):
73 73 keys = ['_css']
74 74 keys.extend(self._keys)
75 75 return keys
76 76 keys = property(_get_keys)
77 77
78 78 def _get_css(self, key, selector=""):
79 79 if selector in self._css and key in self._css[selector]:
80 80 return self._css[selector][key]
81 81 else:
82 82 return None
83 83 def _set_css(self, value, key, selector=""):
84 84 if selector not in self._css:
85 85 self._css[selector] = {}
86 86
87 87 # Only update the property if it has changed.
88 88 if not (key in self._css[selector] and value in self._css[selector][key]):
89 89 self._css[selector][key] = value
90 90 self.send_state() # Send new state to client.
91 91
92 92 css = property(_get_css, _set_css)
93 93
94 94
95 95 ### Event handlers
96 96 def _handle_msg(self, msg):
97 97
98 98 # Handle backbone sync methods
99 99 sync_method = msg['content']['data']['sync_method']
100 100 sync_data = msg['content']['data']['sync_data']
101 101 if sync_method.lower() in ['create', 'update']:
102 102 self._handle_recieve_state(sync_data)
103 103
104 104
105 105 def _handle_recieve_state(self, sync_data):
106 106 self._property_lock = True
107 107 try:
108 108
109 109 # Use _keys instead of keys - Don't get retrieve the css from the client side.
110 110 for name in self._keys:
111 111 if name in sync_data:
112 112 setattr(self, name, sync_data[name])
113 113 finally:
114 114 self._property_lock = False
115 115
116 116
117 117 def _handle_property_changed(self, name, old, new):
118 118 if not self._property_lock:
119 119 # TODO: Validate properties.
120 120 # Send new state to frontend
121 121 self.send_state()
122 122
123 123
124 124 def _handle_close(self):
125 125 self.comm = None
126 126
127 127
128 128 ### Public methods
129 129 def _repr_widget_(self, view_name=None):
130 130 if not view_name:
131 131 view_name = self.default_view_name
132 132
133 133 # Create a comm.
134 134 if self.comm is None:
135 135 self.comm = Comm(target_name=self.target_name)
136 136 self.comm.on_msg(self._handle_msg)
137 137 self.comm.on_close(self._handle_close)
138 138
139 139 # Make sure model is syncronized
140 140 self.send_state()
141 141
142 142 # Show view.
143 143 if self.parent is None:
144 144 self.comm.send({"method": "show", "view_name": view_name})
145 145 else:
146 146 self.comm.send({"method": "show",
147 147 "view_name": view_name,
148 148 "parent": self.parent.comm.comm_id})
149 149
150 150 # Now show children if any.
151 151 for child in self.children:
152 152 child._repr_widget_()
153 153 return None
154 154
155 155
156 156 def send_state(self):
157 157 state = {}
158 158 for key in self.keys:
159 159 try:
160 160 state[key] = getattr(self, key)
161 161 except Exception as e:
162 162 pass # Eat errors, nom nom nom
163 163 self.comm.send({"method": "update",
164 164 "state": state})
165 165 No newline at end of file
General Comments 0
You need to be logged in to leave comments. Login now