Show More
@@ -1,261 +1,267 b'' | |||
|
1 | 1 | //---------------------------------------------------------------------------- |
|
2 | 2 | // Copyright (C) 2013 The IPython Development Team |
|
3 | 3 | // |
|
4 | 4 | // Distributed under the terms of the BSD License. The full license is in |
|
5 | 5 | // the file COPYING, distributed as part of this software. |
|
6 | 6 | //---------------------------------------------------------------------------- |
|
7 | 7 | |
|
8 | 8 | //============================================================================ |
|
9 | 9 | // WidgetModel, WidgetView, and WidgetManager |
|
10 | 10 | //============================================================================ |
|
11 | 11 | /** |
|
12 | 12 | * Base Widget classes |
|
13 | 13 | * @module IPython |
|
14 | 14 | * @namespace IPython |
|
15 | 15 | * @submodule widget |
|
16 | 16 | */ |
|
17 | 17 | |
|
18 | 18 | "use strict"; |
|
19 | 19 | |
|
20 | 20 | // Use require.js 'define' method so that require.js is intelligent enough to |
|
21 | 21 | // syncronously load everything within this file when it is being 'required' |
|
22 | 22 | // elsewhere. |
|
23 | 23 | define(["static/components/underscore/underscore-min.js", |
|
24 | 24 | "static/components/backbone/backbone-min.js", |
|
25 | 25 | ], function(){ |
|
26 | 26 | |
|
27 | 27 | // Only run once on a notebook. |
|
28 | 28 | if (IPython.notebook.widget_manager == undefined) { |
|
29 | 29 | |
|
30 | 30 | //-------------------------------------------------------------------- |
|
31 | 31 | // WidgetModel class |
|
32 | 32 | //-------------------------------------------------------------------- |
|
33 | 33 | var WidgetModel = Backbone.Model.extend({ |
|
34 | 34 | apply: function(sender) { |
|
35 | 35 | this.save(); |
|
36 | 36 | |
|
37 | 37 | for (var index in this.views) { |
|
38 | 38 | var view = this.views[index]; |
|
39 | 39 | if (view !== sender) { |
|
40 | 40 | view.refresh(); |
|
41 | 41 | } |
|
42 | 42 | } |
|
43 | 43 | } |
|
44 | 44 | }); |
|
45 | 45 | |
|
46 | 46 | |
|
47 | 47 | //-------------------------------------------------------------------- |
|
48 | 48 | // WidgetView class |
|
49 | 49 | //-------------------------------------------------------------------- |
|
50 | 50 | var WidgetView = Backbone.View.extend({ |
|
51 | 51 | |
|
52 | 52 | initialize: function() { |
|
53 | 53 | this.model.on('change',this.refresh,this); |
|
54 | 54 | }, |
|
55 | 55 | |
|
56 | 56 | refresh: function() { |
|
57 | 57 | this.update(); |
|
58 | 58 | |
|
59 | 59 | if (this.model.css != undefined) { |
|
60 | 60 | for (var selector in this.model.css) { |
|
61 | 61 | if (this.model.css.hasOwnProperty(selector)) { |
|
62 | 62 | |
|
63 | 63 | // Get the elements via the css selector. If the selector is |
|
64 | 64 | // blank, assume the current element is the target. |
|
65 | 65 | var elements = this.$el.find(selector); |
|
66 | 66 | if (selector=='') { |
|
67 | 67 | elements = this.$el; |
|
68 | 68 | } |
|
69 | 69 | |
|
70 | 70 | // Apply the css traits to all elements that match the selector. |
|
71 | 71 | if (elements.length>0){ |
|
72 | 72 | var css_traits = this.model.css[selector]; |
|
73 | 73 | for (var css_key in css_traits) { |
|
74 | 74 | if (css_traits.hasOwnProperty(css_key)) { |
|
75 | 75 | elements.css(css_key, css_traits[css_key]); |
|
76 | 76 | } |
|
77 | 77 | } |
|
78 | 78 | } |
|
79 | 79 | } |
|
80 | 80 | } |
|
81 | 81 | } |
|
82 | 82 | }, |
|
83 | 83 | }); |
|
84 | 84 | |
|
85 | 85 | |
|
86 | 86 | //-------------------------------------------------------------------- |
|
87 | 87 | // WidgetManager class |
|
88 | 88 | //-------------------------------------------------------------------- |
|
89 | 89 | // Public constructor |
|
90 | 90 | var WidgetManager = function(comm_manager){ |
|
91 | 91 | this.comm_manager = comm_manager; |
|
92 | 92 | this.widget_model_types = {}; |
|
93 | 93 | this.widget_view_types = {}; |
|
94 | 94 | this.model_widget_views = {}; |
|
95 | 95 | |
|
96 | 96 | var that = this; |
|
97 | 97 | Backbone.sync = function(method, model, options, error) { |
|
98 | 98 | var result = that.send_sync(method, model); |
|
99 | 99 | if (options.success) { |
|
100 | 100 | options.success(result); |
|
101 | 101 | } |
|
102 | 102 | }; |
|
103 | 103 | } |
|
104 | 104 | |
|
105 | 105 | // Register a widget model type. |
|
106 | 106 | WidgetManager.prototype.register_widget_model = function (widget_model_name, widget_model_type) { |
|
107 | 107 | |
|
108 | 108 | // Register the widget with the comm manager. Make sure to pass this object's context |
|
109 | 109 | // in so `this` works in the call back. |
|
110 | 110 | this.comm_manager.register_target(widget_model_name, $.proxy(this.handle_com_open, this)); |
|
111 | 111 | |
|
112 | 112 | // Register the types of the model and view correspong to this widget type. Later |
|
113 | 113 | // the widget manager will initialize these when the comm is opened. |
|
114 | 114 | this.widget_model_types[widget_model_name] = widget_model_type; |
|
115 | 115 | } |
|
116 | 116 | |
|
117 | 117 | // Register a widget view type. |
|
118 | 118 | WidgetManager.prototype.register_widget_view = function (widget_view_name, widget_view_type) { |
|
119 | 119 | this.widget_view_types[widget_view_name] = widget_view_type; |
|
120 | 120 | } |
|
121 | 121 | |
|
122 | 122 | // Handle when a comm is opened. |
|
123 | 123 | WidgetManager.prototype.handle_com_open = function (comm, msg) { |
|
124 | 124 | var widget_type_name = msg.content.target_name; |
|
125 | 125 | |
|
126 | 126 | // Create the corresponding widget model. |
|
127 | 127 | var widget_model = new this.widget_model_types[widget_type_name]; |
|
128 | 128 | |
|
129 | 129 | // Remember comm associated with the model. |
|
130 | 130 | widget_model.comm = comm; |
|
131 | 131 | comm.model = widget_model; |
|
132 | 132 | |
|
133 | 133 | // Create an array to remember the views associated with the model. |
|
134 | 134 | widget_model.views = []; |
|
135 | 135 | |
|
136 | 136 | // Add a handle to delete the control when the comm is closed. |
|
137 | 137 | var that = this; |
|
138 | 138 | var handle_close = function(msg) { |
|
139 | 139 | that.handle_comm_closed(comm, msg); |
|
140 | 140 | } |
|
141 | 141 | comm.on_close(handle_close); |
|
142 | 142 | |
|
143 | 143 | // Handle incomming messages. |
|
144 | 144 | var handle_msg = function(msg) { |
|
145 | 145 | that.handle_comm_msg(comm, msg); |
|
146 | 146 | } |
|
147 | 147 | comm.on_msg(handle_msg); |
|
148 | 148 | } |
|
149 | 149 | |
|
150 | 150 | // Create view that represents the model. |
|
151 | 151 | WidgetManager.prototype.show_view = function (widget_area, widget_model, widget_view_name) { |
|
152 | 152 | var widget_view = new this.widget_view_types[widget_view_name]({model: widget_model}); |
|
153 | 153 | widget_view.render(); |
|
154 | 154 | widget_model.views.push(widget_view); |
|
155 | 155 | |
|
156 | 156 | // Handle when the view element is remove from the page. |
|
157 | 157 | widget_view.$el.on("remove", function(){ |
|
158 | 158 | var index = widget_model.views.indexOf(widget_view); |
|
159 | 159 | if (index > -1) { |
|
160 | 160 | widget_model.views.splice(index, 1); |
|
161 | 161 | } |
|
162 | 162 | widget_view.remove(); // Clean-up view |
|
163 | 163 | |
|
164 | 164 | // Close the comm if there are no views left. |
|
165 | 165 | if (widget_model.views.length()==0) { |
|
166 | 166 | widget_model.comm.close(); |
|
167 | 167 | } |
|
168 | 168 | }); |
|
169 | 169 | |
|
170 | 170 | // Add the view's element to cell's widget div. |
|
171 | 171 | widget_area |
|
172 |
|
|
|
172 | .append(widget_view.$el) | |
|
173 | 173 | .parent().show(); // Show the widget_area (parent of widget_subarea) |
|
174 | 174 | |
|
175 | 175 | // Update the view based on the model contents. |
|
176 | 176 | widget_view.refresh(); |
|
177 | 177 | } |
|
178 | 178 | |
|
179 | 179 | // Handle incomming comm msg. |
|
180 | 180 | WidgetManager.prototype.handle_comm_msg = function (comm, msg) { |
|
181 | 181 | // Different logic for different methods. |
|
182 | 182 | var method = msg.content.data.method; |
|
183 | 183 | switch (method){ |
|
184 | 184 | case 'show': |
|
185 | 185 | |
|
186 | 186 | // TODO: Get cell from registered output handler. |
|
187 | 187 | var cell = IPython.notebook.get_cell(IPython.notebook.get_selected_index()-1); |
|
188 | 188 | var widget_subarea = cell.element.find('.widget_area').find('.widget_subarea'); |
|
189 | 189 | |
|
190 | 190 | if (msg.content.data.parent != undefined) { |
|
191 | 191 | var find_results = widget_subarea.find("." + msg.content.data.parent); |
|
192 | 192 | if (find_results.length > 0) { |
|
193 | 193 | widget_subarea = find_results; |
|
194 | 194 | } |
|
195 | 195 | } |
|
196 | 196 | |
|
197 | 197 | this.show_view(widget_subarea, comm.model, msg.content.data.view_name); |
|
198 | 198 | break; |
|
199 | 199 | case 'update': |
|
200 | 200 | this.handle_update(comm, msg.content.data.state); |
|
201 | 201 | break; |
|
202 | 202 | } |
|
203 | 203 | } |
|
204 | 204 | |
|
205 | 205 | // Handle when a widget is updated via the python side. |
|
206 | 206 | WidgetManager.prototype.handle_update = function (comm, state) { |
|
207 | this.updating = true; | |
|
207 | 208 | for (var key in state) { |
|
208 | 209 | if (state.hasOwnProperty(key)) { |
|
209 | 210 | if (key=="_css"){ |
|
210 | 211 | comm.model.css = state[key]; |
|
211 | 212 | } else { |
|
212 | 213 | comm.model.set(key, state[key]); |
|
213 | 214 | } |
|
214 | 215 | } |
|
215 | 216 | } |
|
216 | 217 | comm.model.save(); |
|
218 | this.updating = false; | |
|
217 | 219 | } |
|
218 | 220 | |
|
219 | 221 | // Handle when a widget is closed. |
|
220 | 222 | WidgetManager.prototype.handle_comm_closed = function (comm, msg) { |
|
221 | 223 | for (var view_index in comm.model.views) { |
|
222 | 224 | var view = comm.model.views[view_index]; |
|
223 | 225 | view.remove(); |
|
224 | 226 | } |
|
225 | 227 | } |
|
226 | 228 | |
|
227 | 229 | // Get the cell output area corresponding to the comm. |
|
228 | 230 | WidgetManager.prototype._get_comm_outputarea = function (comm) { |
|
229 | 231 | // TODO: get element from comm instead of guessing |
|
230 | 232 | var cell = IPython.notebook.get_cell(IPython.notebook.get_selected_index()) |
|
231 | 233 | return cell.output_area; |
|
232 | 234 | } |
|
233 | 235 | |
|
234 | 236 | // Send widget state to python backend. |
|
235 | 237 | WidgetManager.prototype.send_sync = function (method, model) { |
|
236 | ||
|
237 | // Create a callback for the output if the widget has an output area associate with it. | |
|
238 | var callbacks = {}; | |
|
239 | var comm = model.comm; | |
|
240 | var outputarea = this._get_comm_outputarea(comm); | |
|
241 | if (outputarea != null) { | |
|
242 | callbacks = { | |
|
243 | iopub : { | |
|
244 | output : $.proxy(outputarea.handle_output, outputarea), | |
|
245 | clear_output : $.proxy(outputarea.handle_clear_output, outputarea)} | |
|
246 | }; | |
|
247 | }; | |
|
248 | 238 | var model_json = model.toJSON(); |
|
249 | var data = {sync_method: method, sync_data: model_json}; | |
|
250 | comm.send(data, callbacks); | |
|
239 | ||
|
240 | // Only send updated state if the state hasn't been changed during an update. | |
|
241 | if (!this.updating) { | |
|
242 | // Create a callback for the output if the widget has an output area associate with it. | |
|
243 | var callbacks = {}; | |
|
244 | var comm = model.comm; | |
|
245 | var outputarea = this._get_comm_outputarea(comm); | |
|
246 | if (outputarea != null) { | |
|
247 | callbacks = { | |
|
248 | iopub : { | |
|
249 | output : $.proxy(outputarea.handle_output, outputarea), | |
|
250 | clear_output : $.proxy(outputarea.handle_clear_output, outputarea)} | |
|
251 | }; | |
|
252 | }; | |
|
253 | var data = {sync_method: method, sync_data: model_json}; | |
|
254 | comm.send(data, callbacks); | |
|
255 | } | |
|
256 | ||
|
251 | 257 | return model_json; |
|
252 | 258 | } |
|
253 | 259 | |
|
254 | 260 | IPython.WidgetManager = WidgetManager; |
|
255 | 261 | IPython.WidgetModel = WidgetModel; |
|
256 | 262 | IPython.WidgetView = WidgetView; |
|
257 | 263 | |
|
258 | 264 | IPython.notebook.widget_manager = new WidgetManager(IPython.notebook.kernel.comm_manager); |
|
259 | 265 | |
|
260 | 266 | }; |
|
261 | 267 | }); |
@@ -1,92 +1,94 b'' | |||
|
1 | 1 | |
|
2 | 2 | require(["notebook/js/widget"], function(){ |
|
3 | 3 | |
|
4 | 4 | var BoolWidgetModel = IPython.WidgetModel.extend({}); |
|
5 | 5 | IPython.notebook.widget_manager.register_widget_model('BoolWidgetModel', BoolWidgetModel); |
|
6 | 6 | |
|
7 | 7 | var CheckboxView = IPython.WidgetView.extend({ |
|
8 | 8 | |
|
9 | 9 | // Called when view is rendered. |
|
10 | 10 | render : function(){ |
|
11 | 11 | this.$el |
|
12 | 12 | .html('') |
|
13 | .addClass('widget_item') | |
|
13 | 14 | .addClass(this.model.comm.comm_id); |
|
14 | 15 | |
|
15 | 16 | var $label = $('<label />') |
|
16 | 17 | .addClass('checkbox') |
|
17 | 18 | .appendTo(this.$el); |
|
18 | 19 | this.$checkbox = $('<input />') |
|
19 | 20 | .attr('type', 'checkbox') |
|
20 | 21 | .appendTo($label); |
|
21 | 22 | this.$checkbox_label = $('<div />') |
|
23 | .addClass('widget_item') | |
|
22 | 24 | .appendTo($label); |
|
23 | 25 | |
|
24 | 26 | this.update(); // Set defaults. |
|
25 | 27 | }, |
|
26 | 28 | |
|
27 | 29 | // Handles: Backend -> Frontend Sync |
|
28 | 30 | // Frontent -> Frontend Sync |
|
29 | 31 | update : function(){ |
|
30 | 32 | if (!this.user_invoked_update) { |
|
31 | 33 | this.$checkbox.prop('checked', this.model.get('value')); |
|
32 | 34 | this.$checkbox_label.html(this.model.get('description')); |
|
33 | 35 | } |
|
34 | 36 | }, |
|
35 | 37 | |
|
36 | 38 | events: {"change input" : "handleChanged"}, |
|
37 | 39 | |
|
38 | 40 | // Handles and validates user input. |
|
39 | 41 | handleChanged: function(e) { |
|
40 | 42 | this.user_invoked_update = true; |
|
41 | 43 | this.model.set('value', $(e.target).prop('checked')); |
|
42 | 44 | this.model.apply(this); |
|
43 | 45 | this.user_invoked_update = false; |
|
44 | 46 | }, |
|
45 | 47 | }); |
|
46 | 48 | |
|
47 | 49 | IPython.notebook.widget_manager.register_widget_view('CheckboxView', CheckboxView); |
|
48 | 50 | |
|
49 | 51 | var ToggleButtonView = IPython.WidgetView.extend({ |
|
50 | 52 | |
|
51 | 53 | // Called when view is rendered. |
|
52 | 54 | render : function(){ |
|
53 | 55 | this.$el |
|
54 | 56 | .html('') |
|
55 | 57 | .addClass(this.model.comm.comm_id); |
|
56 | 58 | |
|
57 | 59 | this.$button = $('<button />') |
|
58 | 60 | .addClass('btn') |
|
59 | 61 | .attr('type', 'button') |
|
60 | 62 | .attr('data-toggle', 'button') |
|
61 | 63 | .appendTo(this.$el); |
|
62 | 64 | |
|
63 | 65 | this.update(); // Set defaults. |
|
64 | 66 | }, |
|
65 | 67 | |
|
66 | 68 | // Handles: Backend -> Frontend Sync |
|
67 | 69 | // Frontent -> Frontend Sync |
|
68 | 70 | update : function(){ |
|
69 | 71 | if (!this.user_invoked_update) { |
|
70 | 72 | if (this.model.get('value')) { |
|
71 | 73 | this.$button.addClass('active'); |
|
72 | 74 | } else { |
|
73 | 75 | this.$button.removeClass('active'); |
|
74 | 76 | } |
|
75 | 77 | this.$button.html(this.model.get('description')); |
|
76 | 78 | } |
|
77 | 79 | }, |
|
78 | 80 | |
|
79 | 81 | events: {"click button" : "handleClick"}, |
|
80 | 82 | |
|
81 | 83 | // Handles and validates user input. |
|
82 | 84 | handleClick: function(e) { |
|
83 | 85 | this.user_invoked_update = true; |
|
84 | 86 | this.model.set('value', ! $(e.target).hasClass('active')); |
|
85 | 87 | this.model.apply(this); |
|
86 | 88 | this.user_invoked_update = false; |
|
87 | 89 | }, |
|
88 | 90 | }); |
|
89 | 91 | |
|
90 | 92 | IPython.notebook.widget_manager.register_widget_view('ToggleButtonView', ToggleButtonView); |
|
91 | 93 | |
|
92 | 94 | }); |
@@ -1,19 +1,28 b'' | |||
|
1 | 1 | require(["notebook/js/widget"], function(){ |
|
2 | 2 | var ContainerModel = IPython.WidgetModel.extend({}); |
|
3 | 3 | IPython.notebook.widget_manager.register_widget_model('container_widget', ContainerModel); |
|
4 | 4 | |
|
5 | 5 | var ContainerView = IPython.WidgetView.extend({ |
|
6 | 6 | |
|
7 | 7 | render : function(){ |
|
8 |
this.$el |
|
|
9 | this.$container = $('<div />') | |
|
10 | .addClass('container') | |
|
8 | this.$el = $('<div />') | |
|
11 | 9 | .addClass(this.model.comm.comm_id); |
|
12 | this.$el.append(this.$container); | |
|
13 | 10 | }, |
|
14 | 11 | |
|
15 |
update : function(){ |
|
|
12 | update : function(){ | |
|
13 | if (this.model.get('vbox')) { | |
|
14 | this.$el.addClass('vbox'); | |
|
15 | } else { | |
|
16 | this.$el.removeClass('vbox'); | |
|
17 | } | |
|
18 | ||
|
19 | if (this.model.get('hbox')) { | |
|
20 | this.$el.addClass('hbox'); | |
|
21 | } else { | |
|
22 | this.$el.removeClass('hbox'); | |
|
23 | } | |
|
24 | }, | |
|
16 | 25 | }); |
|
17 | 26 | |
|
18 | 27 | IPython.notebook.widget_manager.register_widget_view('ContainerView', ContainerView); |
|
19 | 28 | }); No newline at end of file |
@@ -1,125 +1,126 b'' | |||
|
1 | 1 | require(["notebook/js/widget"], function(){ |
|
2 | 2 | var FloatRangeWidgetModel = IPython.WidgetModel.extend({}); |
|
3 | 3 | IPython.notebook.widget_manager.register_widget_model('FloatRangeWidgetModel', FloatRangeWidgetModel); |
|
4 | 4 | |
|
5 | 5 | var FloatSliderView = IPython.WidgetView.extend({ |
|
6 | 6 | |
|
7 | 7 | // Called when view is rendered. |
|
8 | 8 | render : function(){ |
|
9 | 9 | this.$el |
|
10 | 10 | .html('') |
|
11 | 11 | .addClass(this.model.comm.comm_id); |
|
12 | 12 | this.$slider = $('<div />') |
|
13 |
|
|
|
14 |
|
|
|
13 | .slider({}) | |
|
14 | .addClass('slider'); | |
|
15 | 15 | |
|
16 | 16 | // Put the slider in a container |
|
17 | 17 | this.$slider_container = $('<div />') |
|
18 |
|
|
|
19 |
|
|
|
20 |
|
|
|
18 | .css('padding-top', '4px') | |
|
19 | .css('padding-bottom', '4px') | |
|
20 | .append(this.$slider); | |
|
21 | 21 | this.$el.append(this.$slider_container); |
|
22 | 22 | |
|
23 | 23 | // Set defaults. |
|
24 | 24 | this.update(); |
|
25 | 25 | }, |
|
26 | 26 | |
|
27 | 27 | // Handles: Backend -> Frontend Sync |
|
28 | 28 | // Frontent -> Frontend Sync |
|
29 | 29 | update : function(){ |
|
30 | 30 | // Slider related keys. |
|
31 | 31 | var _keys = ['value', 'step', 'max', 'min', 'disabled', 'orientation']; |
|
32 | 32 | for (var index in _keys) { |
|
33 | 33 | var key = _keys[index]; |
|
34 | 34 | if (this.model.get(key) != undefined) { |
|
35 | 35 | this.$slider.slider("option", key, this.model.get(key)); |
|
36 | 36 | } |
|
37 | 37 | } |
|
38 | 38 | }, |
|
39 | 39 | |
|
40 | 40 | // Handles: User input |
|
41 | 41 | events: { "slide" : "handleSliderChange" }, |
|
42 | 42 | handleSliderChange: function(e, ui) { |
|
43 | 43 | this.model.set('value', ui.value); |
|
44 | 44 | this.model.apply(this); |
|
45 | 45 | }, |
|
46 | 46 | }); |
|
47 | 47 | |
|
48 | 48 | IPython.notebook.widget_manager.register_widget_view('FloatSliderView', FloatSliderView); |
|
49 | 49 | |
|
50 | 50 | |
|
51 | 51 | var FloatTextView = IPython.WidgetView.extend({ |
|
52 | 52 | |
|
53 | 53 | // Called when view is rendered. |
|
54 | 54 | render : function(){ |
|
55 | 55 | this.$el |
|
56 | 56 | .html('') |
|
57 | .addClass('widget_item') | |
|
57 | 58 | .addClass(this.model.comm.comm_id); |
|
58 | 59 | this.$textbox = $('<input type="text" />') |
|
59 | 60 | .addClass('input') |
|
60 | 61 | .appendTo(this.$el); |
|
61 | 62 | this.update(); // Set defaults. |
|
62 | 63 | }, |
|
63 | 64 | |
|
64 | 65 | // Handles: Backend -> Frontend Sync |
|
65 | 66 | // Frontent -> Frontend Sync |
|
66 | 67 | update : function(){ |
|
67 | 68 | var value = this.model.get('value'); |
|
68 | 69 | if (!this.changing && parseFloat(this.$textbox.val()) != value) { |
|
69 | 70 | this.$textbox.val(value); |
|
70 | 71 | } |
|
71 | 72 | |
|
72 | 73 | if (this.model.get('disabled')) { |
|
73 | 74 | this.$textbox.attr('disabled','disabled'); |
|
74 | 75 | } else { |
|
75 | 76 | this.$textbox.removeAttr('disabled'); |
|
76 | 77 | } |
|
77 | 78 | }, |
|
78 | 79 | |
|
79 | 80 | |
|
80 | 81 | events: {"keyup input" : "handleChanging", |
|
81 | 82 | "paste input" : "handleChanging", |
|
82 | 83 | "cut input" : "handleChanging", |
|
83 | 84 | "change input" : "handleChanged"}, // Fires only when control is validated or looses focus. |
|
84 | 85 | |
|
85 | 86 | // Handles and validates user input. |
|
86 | 87 | handleChanging: function(e) { |
|
87 | 88 | |
|
88 | 89 | // Try to parse value as a float. |
|
89 | 90 | var numericalValue = 0.0; |
|
90 | 91 | if (e.target.value != '') { |
|
91 | 92 | numericalValue = parseFloat(e.target.value); |
|
92 | 93 | } |
|
93 | 94 | |
|
94 | 95 | // If parse failed, reset value to value stored in model. |
|
95 | 96 | if (isNaN(numericalValue)) { |
|
96 | 97 | e.target.value = this.model.get('value'); |
|
97 | 98 | } else if (!isNaN(numericalValue)) { |
|
98 | 99 | if (this.model.get('max') != undefined) { |
|
99 | 100 | numericalValue = Math.min(this.model.get('max'), numericalValue); |
|
100 | 101 | } |
|
101 | 102 | if (this.model.get('min') != undefined) { |
|
102 | 103 | numericalValue = Math.max(this.model.get('min'), numericalValue); |
|
103 | 104 | } |
|
104 | 105 | |
|
105 | 106 | // Apply the value if it has changed. |
|
106 | 107 | if (numericalValue != this.model.get('value')) { |
|
107 | 108 | this.changing = true; |
|
108 | 109 | this.model.set('value', numericalValue); |
|
109 | 110 | this.model.apply(this); |
|
110 | 111 | this.changing = false; |
|
111 | 112 | } |
|
112 | 113 | } |
|
113 | 114 | }, |
|
114 | 115 | |
|
115 | 116 | // Applies validated input. |
|
116 | 117 | handleChanged: function(e) { |
|
117 | 118 | // Update the textbox |
|
118 | 119 | if (this.model.get('value') != e.target.value) { |
|
119 | 120 | e.target.value = this.model.get('value'); |
|
120 | 121 | } |
|
121 | 122 | } |
|
122 | 123 | }); |
|
123 | 124 | |
|
124 | 125 | IPython.notebook.widget_manager.register_widget_view('FloatTextView', FloatTextView); |
|
125 | 126 | }); |
@@ -1,123 +1,125 b'' | |||
|
1 | 1 | require(["notebook/js/widget"], function(){ |
|
2 | 2 | var IntRangeWidgetModel = IPython.WidgetModel.extend({}); |
|
3 | 3 | IPython.notebook.widget_manager.register_widget_model('IntRangeWidgetModel', IntRangeWidgetModel); |
|
4 | 4 | |
|
5 | 5 | var IntSliderView = IPython.WidgetView.extend({ |
|
6 | 6 | |
|
7 | 7 | // Called when view is rendered. |
|
8 | 8 | render : function(){ |
|
9 |
this.$el |
|
|
9 | this.$el | |
|
10 | .html('') | |
|
10 | 11 | this.$slider = $('<div />') |
|
11 |
|
|
|
12 |
|
|
|
12 | .slider({}) | |
|
13 | .addClass('slider'); | |
|
13 | 14 | |
|
14 | 15 | // Put the slider in a container |
|
15 | 16 | this.$slider_container = $('<div />') |
|
16 |
|
|
|
17 |
|
|
|
18 |
|
|
|
19 |
|
|
|
17 | .css('padding-top', '4px') | |
|
18 | .css('padding-bottom', '4px') | |
|
19 | .addClass(this.model.comm.comm_id) | |
|
20 | .append(this.$slider); | |
|
20 | 21 | this.$el.append(this.$slider_container); |
|
21 | 22 | |
|
22 | 23 | // Set defaults. |
|
23 | 24 | this.update(); |
|
24 | 25 | }, |
|
25 | 26 | |
|
26 | 27 | // Handles: Backend -> Frontend Sync |
|
27 | 28 | // Frontent -> Frontend Sync |
|
28 | 29 | update : function(){ |
|
29 | 30 | // Slider related keys. |
|
30 | 31 | var _keys = ['value', 'step', 'max', 'min', 'disabled', 'orientation']; |
|
31 | 32 | for (var index in _keys) { |
|
32 | 33 | var key = _keys[index]; |
|
33 | 34 | if (this.model.get(key) != undefined) { |
|
34 | 35 | this.$slider.slider("option", key, this.model.get(key)); |
|
35 | 36 | } |
|
36 | 37 | } |
|
37 | 38 | }, |
|
38 | 39 | |
|
39 | 40 | // Handles: User input |
|
40 | 41 | events: { "slide" : "handleSliderChange" }, |
|
41 | 42 | handleSliderChange: function(e, ui) { |
|
42 | 43 | this.model.set('value', ~~ui.value); // Double bit-wise not to truncate decimel |
|
43 | 44 | this.model.apply(this); |
|
44 | 45 | }, |
|
45 | 46 | }); |
|
46 | 47 | |
|
47 | 48 | IPython.notebook.widget_manager.register_widget_view('IntSliderView', IntSliderView); |
|
48 | 49 | |
|
49 | 50 | var IntTextView = IPython.WidgetView.extend({ |
|
50 | 51 | |
|
51 | 52 | // Called when view is rendered. |
|
52 | 53 | render : function(){ |
|
53 | 54 | this.$el |
|
54 | 55 | .html('') |
|
56 | .addClass('widget_item') | |
|
55 | 57 | .addClass(this.model.comm.comm_id); |
|
56 | 58 | this.$textbox = $('<input type="text" />') |
|
57 | 59 | .addClass('input') |
|
58 | 60 | .appendTo(this.$el); |
|
59 | 61 | this.update(); // Set defaults. |
|
60 | 62 | }, |
|
61 | 63 | |
|
62 | 64 | // Handles: Backend -> Frontend Sync |
|
63 | 65 | // Frontent -> Frontend Sync |
|
64 | 66 | update : function(){ |
|
65 | 67 | var value = this.model.get('value'); |
|
66 | 68 | if (!this.changing && parseInt(this.$textbox.val()) != value) { |
|
67 | 69 | this.$textbox.val(value); |
|
68 | 70 | } |
|
69 | 71 | |
|
70 | 72 | if (this.model.get('disabled')) { |
|
71 | 73 | this.$textbox.attr('disabled','disabled'); |
|
72 | 74 | } else { |
|
73 | 75 | this.$textbox.removeAttr('disabled'); |
|
74 | 76 | } |
|
75 | 77 | }, |
|
76 | 78 | |
|
77 | 79 | |
|
78 | 80 | events: {"keyup input" : "handleChanging", |
|
79 | 81 | "paste input" : "handleChanging", |
|
80 | 82 | "cut input" : "handleChanging", |
|
81 | 83 | "change input" : "handleChanged"}, // Fires only when control is validated or looses focus. |
|
82 | 84 | |
|
83 | 85 | // Handles and validates user input. |
|
84 | 86 | handleChanging: function(e) { |
|
85 | 87 | |
|
86 | 88 | // Try to parse value as a float. |
|
87 | 89 | var numericalValue = 0; |
|
88 | 90 | if (e.target.value != '') { |
|
89 | 91 | numericalValue = parseInt(e.target.value); |
|
90 | 92 | } |
|
91 | 93 | |
|
92 | 94 | // If parse failed, reset value to value stored in model. |
|
93 | 95 | if (isNaN(numericalValue)) { |
|
94 | 96 | e.target.value = this.model.get('value'); |
|
95 | 97 | } else if (!isNaN(numericalValue)) { |
|
96 | 98 | if (this.model.get('max') != undefined) { |
|
97 | 99 | numericalValue = Math.min(this.model.get('max'), numericalValue); |
|
98 | 100 | } |
|
99 | 101 | if (this.model.get('min') != undefined) { |
|
100 | 102 | numericalValue = Math.max(this.model.get('min'), numericalValue); |
|
101 | 103 | } |
|
102 | 104 | |
|
103 | 105 | // Apply the value if it has changed. |
|
104 | 106 | if (numericalValue != this.model.get('value')) { |
|
105 | 107 | this.changing = true; |
|
106 | 108 | this.model.set('value', numericalValue); |
|
107 | 109 | this.model.apply(this); |
|
108 | 110 | this.changing = false; |
|
109 | 111 | } |
|
110 | 112 | } |
|
111 | 113 | }, |
|
112 | 114 | |
|
113 | 115 | // Applies validated input. |
|
114 | 116 | handleChanged: function(e) { |
|
115 | 117 | // Update the textbox |
|
116 | 118 | if (this.model.get('value') != e.target.value) { |
|
117 | 119 | e.target.value = this.model.get('value'); |
|
118 | 120 | } |
|
119 | 121 | } |
|
120 | 122 | }); |
|
121 | 123 | |
|
122 | 124 | IPython.notebook.widget_manager.register_widget_view('IntTextView', IntTextView); |
|
123 | 125 | }); |
@@ -1,196 +1,202 b'' | |||
|
1 | 1 | require(["notebook/js/widget"], function(){ |
|
2 | 2 | var SelectionWidgetModel = IPython.WidgetModel.extend({}); |
|
3 | 3 | IPython.notebook.widget_manager.register_widget_model('SelectionWidgetModel', SelectionWidgetModel); |
|
4 | 4 | |
|
5 | 5 | var DropdownView = IPython.WidgetView.extend({ |
|
6 | 6 | |
|
7 | 7 | // Called when view is rendered. |
|
8 | 8 | render : function(){ |
|
9 | 9 | |
|
10 | 10 | this.$el |
|
11 | 11 | .html('') |
|
12 | .addClass('widget_item') | |
|
12 | 13 | .addClass(this.model.comm.comm_id); |
|
13 | 14 | this.$buttongroup = $('<div />') |
|
15 | .addClass('widget_item') | |
|
14 | 16 | .addClass('btn-group') |
|
15 | 17 | .appendTo(this.$el); |
|
16 | 18 | this.$droplabel = $('<button />') |
|
17 | 19 | .addClass('btn') |
|
18 | 20 | .appendTo(this.$buttongroup); |
|
19 | 21 | this.$dropbutton = $('<button />') |
|
20 | 22 | .addClass('btn') |
|
21 | 23 | .addClass('dropdown-toggle') |
|
22 | 24 | .attr('data-toggle', 'dropdown') |
|
23 | 25 | .html('<span class="caret"></span>') |
|
24 | 26 | .appendTo(this.$buttongroup); |
|
25 | 27 | this.$droplist = $('<ul />') |
|
26 | 28 | .addClass('dropdown-menu') |
|
27 | 29 | .appendTo(this.$buttongroup); |
|
28 | 30 | |
|
29 | 31 | // Set defaults. |
|
30 | 32 | this.update(); |
|
31 | 33 | }, |
|
32 | 34 | |
|
33 | 35 | // Handles: Backend -> Frontend Sync |
|
34 | 36 | // Frontent -> Frontend Sync |
|
35 | 37 | update : function(){ |
|
36 | 38 | this.$droplabel.html(this.model.get('value')); |
|
37 | 39 | |
|
38 | 40 | var items = this.model.get('values'); |
|
39 | 41 | this.$droplist.html(''); |
|
40 | 42 | for (var index in items) { |
|
41 | 43 | var that = this; |
|
42 | 44 | var item_button = $('<a href="#"/>') |
|
43 | 45 | .html(items[index]) |
|
44 | 46 | .on('click', function(e){ |
|
45 | 47 | that.model.set('value', $(e.target).html(), this ); |
|
48 | that.model.apply(that); | |
|
46 | 49 | }) |
|
47 | 50 | |
|
48 | 51 | this.$droplist.append($('<li />').append(item_button)) |
|
49 | 52 | } |
|
50 | 53 | |
|
51 | 54 | if (this.model.get('disabled')) { |
|
52 | 55 | this.$buttongroup.attr('disabled','disabled'); |
|
53 | 56 | this.$droplabel.attr('disabled','disabled'); |
|
54 | 57 | this.$dropbutton.attr('disabled','disabled'); |
|
55 | 58 | this.$droplist.attr('disabled','disabled'); |
|
56 | 59 | } else { |
|
57 | 60 | this.$buttongroup.removeAttr('disabled'); |
|
58 | 61 | this.$droplabel.removeAttr('disabled'); |
|
59 | 62 | this.$dropbutton.removeAttr('disabled'); |
|
60 | 63 | this.$droplist.removeAttr('disabled'); |
|
61 | 64 | } |
|
62 | 65 | }, |
|
63 | 66 | |
|
64 | 67 | }); |
|
65 | 68 | |
|
66 | 69 | IPython.notebook.widget_manager.register_widget_view('DropdownView', DropdownView); |
|
67 | 70 | |
|
68 | 71 | var RadioButtonsView = IPython.WidgetView.extend({ |
|
69 | 72 | |
|
70 | 73 | // Called when view is rendered. |
|
71 | 74 | render : function(){ |
|
72 | 75 | this.$el |
|
73 | 76 | .html('') |
|
77 | .addClass('widget_item') | |
|
74 | 78 | .addClass(this.model.comm.comm_id); |
|
75 | 79 | this.update(); |
|
76 | 80 | }, |
|
77 | 81 | |
|
78 | 82 | // Handles: Backend -> Frontend Sync |
|
79 | 83 | // Frontent -> Frontend Sync |
|
80 | 84 | update : function(){ |
|
81 | 85 | |
|
82 | 86 | // Add missing items to the DOM. |
|
83 | 87 | var items = this.model.get('values'); |
|
84 | 88 | for (var index in items) { |
|
85 | 89 | var item_query = ' :input[value="' + items[index] + '"]'; |
|
86 | 90 | if (this.$el.find(item_query).length == 0) { |
|
87 | 91 | var $label = $('<label />') |
|
88 | 92 | .addClass('radio') |
|
89 | 93 | .html(items[index]) |
|
90 | 94 | .appendTo(this.$el); |
|
91 | 95 | |
|
92 | 96 | var that = this; |
|
93 | 97 | $('<input />') |
|
94 | 98 | .attr('type', 'radio') |
|
95 | 99 | .addClass(this.model) |
|
96 | 100 | .val(items[index]) |
|
97 | 101 | .prependTo($label) |
|
98 | 102 | .on('click', function(e){ |
|
99 | 103 | that.model.set('value', $(e.target).val(), this); |
|
100 | 104 | that.model.apply(); |
|
101 | 105 | }); |
|
102 | 106 | } |
|
103 | 107 | |
|
104 | 108 | if (this.model.get('value') == items[index]) { |
|
105 | 109 | this.$el.find(item_query).prop('checked', true); |
|
106 | 110 | } else { |
|
107 | 111 | this.$el.find(item_query).prop('checked', false); |
|
108 | 112 | } |
|
109 | 113 | } |
|
110 | 114 | |
|
111 | 115 | // Remove items that no longer exist. |
|
112 | 116 | this.$el.find('input').each(function(i, obj) { |
|
113 | 117 | var value = $(obj).val(); |
|
114 | 118 | var found = false; |
|
115 | 119 | for (var index in items) { |
|
116 | 120 | if (items[index] == value) { |
|
117 | 121 | found = true; |
|
118 | 122 | break; |
|
119 | 123 | } |
|
120 | 124 | } |
|
121 | 125 | |
|
122 | 126 | if (!found) { |
|
123 | 127 | $(obj).parent().remove(); |
|
124 | 128 | } |
|
125 | 129 | }); |
|
126 | 130 | }, |
|
127 | 131 | |
|
128 | 132 | }); |
|
129 | 133 | |
|
130 | 134 | IPython.notebook.widget_manager.register_widget_view('RadioButtonsView', RadioButtonsView); |
|
131 | 135 | |
|
132 | 136 | |
|
133 | 137 | var ToggleButtonsView = IPython.WidgetView.extend({ |
|
134 | 138 | |
|
135 | 139 | // Called when view is rendered. |
|
136 | 140 | render : function(){ |
|
137 | 141 | this.$el |
|
138 | 142 | .html('') |
|
143 | .addClass('widget_item') | |
|
139 | 144 | .addClass(this.model.comm.comm_id); |
|
140 | 145 | this.$buttongroup = $('<div />') |
|
146 | .addClass('widget_item') | |
|
141 | 147 | .addClass('btn-group') |
|
142 | 148 | .attr('data-toggle', 'buttons-radio') |
|
143 | 149 | .appendTo(this.$el); |
|
144 | 150 | this.update(); |
|
145 | 151 | }, |
|
146 | 152 | |
|
147 | 153 | // Handles: Backend -> Frontend Sync |
|
148 | 154 | // Frontent -> Frontend Sync |
|
149 | 155 | update : function(){ |
|
150 | 156 | |
|
151 | 157 | // Add missing items to the DOM. |
|
152 | 158 | var items = this.model.get('values'); |
|
153 | 159 | for (var index in items) { |
|
154 | 160 | var item_query = ' :contains("' + items[index] + '")'; |
|
155 | 161 | if (this.$buttongroup.find(item_query).length == 0) { |
|
156 | 162 | |
|
157 | 163 | var that = this; |
|
158 | 164 | $('<button />') |
|
159 | 165 | .attr('type', 'button') |
|
160 | 166 | .addClass('btn') |
|
161 | 167 | .html(items[index]) |
|
162 | 168 | .appendTo(this.$buttongroup) |
|
163 | 169 | .on('click', function(e){ |
|
164 | 170 | that.model.set('value', $(e.target).html(), this); |
|
165 | 171 | that.model.apply(); |
|
166 | 172 | }); |
|
167 | 173 | } |
|
168 | 174 | |
|
169 | 175 | if (this.model.get('value') == items[index]) { |
|
170 | 176 | this.$buttongroup.find(item_query).addClass('active'); |
|
171 | 177 | } else { |
|
172 | 178 | this.$buttongroup.find(item_query).removeClass('active'); |
|
173 | 179 | } |
|
174 | 180 | } |
|
175 | 181 | |
|
176 | 182 | // Remove items that no longer exist. |
|
177 | 183 | this.$buttongroup.find('button').each(function(i, obj) { |
|
178 | 184 | var value = $(obj).html(); |
|
179 | 185 | var found = false; |
|
180 | 186 | for (var index in items) { |
|
181 | 187 | if (items[index] == value) { |
|
182 | 188 | found = true; |
|
183 | 189 | break; |
|
184 | 190 | } |
|
185 | 191 | } |
|
186 | 192 | |
|
187 | 193 | if (!found) { |
|
188 | 194 | $(obj).remove(); |
|
189 | 195 | } |
|
190 | 196 | }); |
|
191 | 197 | }, |
|
192 | 198 | |
|
193 | 199 | }); |
|
194 | 200 | |
|
195 | 201 | IPython.notebook.widget_manager.register_widget_view('ToggleButtonsView', ToggleButtonsView); |
|
196 | 202 | }); |
@@ -1,98 +1,98 b'' | |||
|
1 | 1 | require(["notebook/js/widget"], function(){ |
|
2 | 2 | var StringWidgetModel = IPython.WidgetModel.extend({}); |
|
3 | 3 | IPython.notebook.widget_manager.register_widget_model('StringWidgetModel', StringWidgetModel); |
|
4 | 4 | |
|
5 | 5 | var LabelView = IPython.WidgetView.extend({ |
|
6 | 6 | |
|
7 | 7 | // Called when view is rendered. |
|
8 | 8 | render : function(){ |
|
9 | this.$el | |
|
10 |
. |
|
|
11 | this.$label = $('<div />') | |
|
12 | .addClass(this.model.comm.comm_id) | |
|
13 | .appendTo(this.$el); | |
|
9 | this.$el = $('<div />') | |
|
10 | .addClass('widget_item') | |
|
11 | .addClass(this.model.comm.comm_id); | |
|
14 | 12 | this.update(); // Set defaults. |
|
15 | 13 | }, |
|
16 | 14 | |
|
17 | 15 | // Handles: Backend -> Frontend Sync |
|
18 | 16 | // Frontent -> Frontend Sync |
|
19 | 17 | update : function(){ |
|
20 |
this.$ |
|
|
18 | this.$el.html(this.model.get('value')); | |
|
21 | 19 | }, |
|
22 | 20 | |
|
23 | 21 | }); |
|
24 | 22 | |
|
25 | 23 | IPython.notebook.widget_manager.register_widget_view('LabelView', LabelView); |
|
26 | 24 | |
|
27 | 25 | var TextareaView = IPython.WidgetView.extend({ |
|
28 | 26 | |
|
29 | 27 | // Called when view is rendered. |
|
30 | 28 | render : function(){ |
|
31 | 29 | this.$el |
|
32 | 30 | .html('') |
|
31 | .addClass('widget_item') | |
|
33 | 32 | .addClass(this.model.comm.comm_id); |
|
34 | 33 | this.$textbox = $('<textarea />') |
|
35 | 34 | .attr('rows', 5) |
|
36 | 35 | .appendTo(this.$el); |
|
37 | 36 | this.update(); // Set defaults. |
|
38 | 37 | }, |
|
39 | 38 | |
|
40 | 39 | // Handles: Backend -> Frontend Sync |
|
41 | 40 | // Frontent -> Frontend Sync |
|
42 | 41 | update : function(){ |
|
43 | 42 | if (!this.user_invoked_update) { |
|
44 | 43 | this.$textbox.val(this.model.get('value')); |
|
45 | 44 | } |
|
46 | 45 | }, |
|
47 | 46 | |
|
48 | 47 | events: {"keyup textarea" : "handleChanging", |
|
49 | 48 | "paste textarea" : "handleChanging", |
|
50 | 49 | "cut textarea" : "handleChanging"}, |
|
51 | 50 | |
|
52 | 51 | // Handles and validates user input. |
|
53 | 52 | handleChanging: function(e) { |
|
54 | 53 | this.user_invoked_update = true; |
|
55 | 54 | this.model.set('value', e.target.value); |
|
56 | 55 | this.model.apply(this); |
|
57 | 56 | this.user_invoked_update = false; |
|
58 | 57 | }, |
|
59 | 58 | }); |
|
60 | 59 | |
|
61 | 60 | IPython.notebook.widget_manager.register_widget_view('TextareaView', TextareaView); |
|
62 | 61 | |
|
63 | 62 | var TextboxView = IPython.WidgetView.extend({ |
|
64 | 63 | |
|
65 | 64 | // Called when view is rendered. |
|
66 | 65 | render : function(){ |
|
67 | 66 | this.$el |
|
68 | 67 | .html('') |
|
68 | .addClass('widget_item') | |
|
69 | 69 | .addClass(this.model.comm.comm_id); |
|
70 | 70 | this.$textbox = $('<input type="text" />') |
|
71 | 71 | .addClass('input') |
|
72 | 72 | .appendTo(this.$el); |
|
73 | 73 | this.update(); // Set defaults. |
|
74 | 74 | }, |
|
75 | 75 | |
|
76 | 76 | // Handles: Backend -> Frontend Sync |
|
77 | 77 | // Frontent -> Frontend Sync |
|
78 | 78 | update : function(){ |
|
79 | 79 | if (!this.user_invoked_update) { |
|
80 | 80 | this.$textbox.val(this.model.get('value')); |
|
81 | 81 | } |
|
82 | 82 | }, |
|
83 | 83 | |
|
84 | 84 | events: {"keyup input" : "handleChanging", |
|
85 | 85 | "paste input" : "handleChanging", |
|
86 | 86 | "cut input" : "handleChanging"}, |
|
87 | 87 | |
|
88 | 88 | // Handles and validates user input. |
|
89 | 89 | handleChanging: function(e) { |
|
90 | 90 | this.user_invoked_update = true; |
|
91 | 91 | this.model.set('value', e.target.value); |
|
92 | 92 | this.model.apply(this); |
|
93 | 93 | this.user_invoked_update = false; |
|
94 | 94 | }, |
|
95 | 95 | }); |
|
96 | 96 | |
|
97 | 97 | IPython.notebook.widget_manager.register_widget_view('TextboxView', TextboxView); |
|
98 | 98 | }); |
@@ -1,12 +1,25 b'' | |||
|
1 | ||
|
1 | 2 | div.widget_area { |
|
2 | 3 | page-break-inside: avoid; |
|
4 | .vbox(); | |
|
5 | } | |
|
6 | ||
|
7 | div.widget_hbox { | |
|
3 | 8 | .hbox(); |
|
4 | 9 | } |
|
5 | 10 | |
|
11 | div.widget_vbox { | |
|
12 | .vbox(); | |
|
13 | } | |
|
14 | ||
|
15 | div.widget_item { | |
|
16 | display: inline-block; | |
|
17 | } | |
|
18 | ||
|
6 | 19 | /* This class is for the widget subarea inside the widget_area and after |
|
7 | 20 | the prompt div. */ |
|
8 | 21 | div.widget_subarea { |
|
9 | 22 | padding: 0.44em 0.4em 0.4em 1px; |
|
10 | 23 | margin-left: 6px; |
|
11 | 24 | .box-flex1(); |
|
12 | 25 | } |
@@ -1,154 +1,169 b'' | |||
|
1 | 1 | .clearfix{*zoom:1;}.clearfix:before,.clearfix:after{display:table;content:"";line-height:0;} |
|
2 | 2 | .clearfix:after{clear:both;} |
|
3 | 3 | .hide-text{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0;} |
|
4 | 4 | .input-block-level{display:block;width:100%;min-height:30px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;} |
|
5 | 5 | .border-box-sizing{box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;} |
|
6 | 6 | .corner-all{border-radius:4px;} |
|
7 | 7 | .hbox{display:-webkit-box;-webkit-box-orient:horizontal;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:horizontal;-moz-box-align:stretch;display:box;box-orient:horizontal;box-align:stretch;} |
|
8 | 8 | .hbox>*{-webkit-box-flex:0;-moz-box-flex:0;box-flex:0;} |
|
9 | 9 | .vbox{display:-webkit-box;-webkit-box-orient:vertical;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:vertical;-moz-box-align:stretch;display:box;box-orient:vertical;box-align:stretch;width:100%;} |
|
10 | 10 | .vbox>*{-webkit-box-flex:0;-moz-box-flex:0;box-flex:0;} |
|
11 | 11 | .reverse{-webkit-box-direction:reverse;-moz-box-direction:reverse;box-direction:reverse;} |
|
12 | 12 | .box-flex0{-webkit-box-flex:0;-moz-box-flex:0;box-flex:0;} |
|
13 | 13 | .box-flex1{-webkit-box-flex:1;-moz-box-flex:1;box-flex:1;} |
|
14 | 14 | .box-flex{-webkit-box-flex:1;-moz-box-flex:1;box-flex:1;} |
|
15 | 15 | .box-flex2{-webkit-box-flex:2;-moz-box-flex:2;box-flex:2;} |
|
16 | 16 | .box-group1{-webkit-box-flex-group:1;-moz-box-flex-group:1;box-flex-group:1;} |
|
17 | 17 | .box-group2{-webkit-box-flex-group:2;-moz-box-flex-group:2;box-flex-group:2;} |
|
18 | 18 | .start{-webkit-box-pack:start;-moz-box-pack:start;box-pack:start;} |
|
19 | 19 | .end{-webkit-box-pack:end;-moz-box-pack:end;box-pack:end;} |
|
20 | 20 | .center{-webkit-box-pack:center;-moz-box-pack:center;box-pack:center;} |
|
21 | 21 | div.error{margin:2em;text-align:center;} |
|
22 | 22 | div.error>h1{font-size:500%;line-height:normal;} |
|
23 | 23 | div.error>p{font-size:200%;line-height:normal;} |
|
24 | 24 | div.traceback-wrapper{text-align:left;max-width:800px;margin:auto;} |
|
25 | 25 | .center-nav{display:inline-block;margin-bottom:-4px;} |
|
26 | 26 | .alternate_upload{background-color:none;display:inline;} |
|
27 | 27 | .alternate_upload.form{padding:0;margin:0;} |
|
28 | 28 | .alternate_upload input.fileinput{background-color:red;position:relative;opacity:0;z-index:2;width:295px;margin-left:163px;cursor:pointer;} |
|
29 | 29 | .list_toolbar{padding:5px;height:25px;line-height:25px;} |
|
30 | 30 | .toolbar_info{float:left;} |
|
31 | 31 | .toolbar_buttons{float:right;} |
|
32 | 32 | .list_header{font-weight:bold;} |
|
33 | 33 | .list_container{margin-top:16px;margin-bottom:16px;border:1px solid #ababab;border-radius:4px;} |
|
34 | 34 | .list_container>div{border-bottom:1px solid #ababab;}.list_container>div:hover .list-item{background-color:red;} |
|
35 | 35 | .list_container>div:last-child{border:none;} |
|
36 | 36 | .list_item:hover .list_item{background-color:#ddd;} |
|
37 | 37 | .item_name{line-height:24px;} |
|
38 | 38 | .list_container>div>span,.list_container>div>div{padding:8px;} |
|
39 | 39 | .list_item a{text-decoration:none;} |
|
40 | 40 | input.nbname_input{height:15px;} |
|
41 | 41 | .highlight_text{color:blue;} |
|
42 | 42 | #project_name>.breadcrumb{padding:0px;margin-bottom:0px;background-color:transparent;font-weight:bold;} |
|
43 | 43 | input.engine_num_input{height:20px;margin-bottom:2px;padding-top:0;padding-bottom:0;width:60px;} |
|
44 | 44 | .ansibold{font-weight:bold;} |
|
45 | 45 | .ansiblack{color:black;} |
|
46 | 46 | .ansired{color:darkred;} |
|
47 | 47 | .ansigreen{color:darkgreen;} |
|
48 | 48 | .ansiyellow{color:brown;} |
|
49 | 49 | .ansiblue{color:darkblue;} |
|
50 | 50 | .ansipurple{color:darkviolet;} |
|
51 | 51 | .ansicyan{color:steelblue;} |
|
52 | 52 | .ansigray{color:gray;} |
|
53 | 53 | .ansibgblack{background-color:black;} |
|
54 | 54 | .ansibgred{background-color:red;} |
|
55 | 55 | .ansibggreen{background-color:green;} |
|
56 | 56 | .ansibgyellow{background-color:yellow;} |
|
57 | 57 | .ansibgblue{background-color:blue;} |
|
58 | 58 | .ansibgpurple{background-color:magenta;} |
|
59 | 59 | .ansibgcyan{background-color:cyan;} |
|
60 | 60 | .ansibggray{background-color:gray;} |
|
61 | 61 | div.cell{border:1px solid transparent;display:-webkit-box;-webkit-box-orient:vertical;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:vertical;-moz-box-align:stretch;display:box;box-orient:vertical;box-align:stretch;width:100%;}div.cell.selected{border-radius:4px;border:thin #ababab solid;} |
|
62 | 62 | div.cell.edit_mode{border-radius:4px;border:thin green solid;} |
|
63 | 63 | div.cell{width:100%;padding:5px 5px 5px 0px;margin:0px;outline:none;} |
|
64 | 64 | div.prompt{min-width:11ex;padding:0.4em;margin:0px;font-family:monospace;text-align:right;line-height:1.231em;} |
|
65 | 65 | div.inner_cell{display:-webkit-box;-webkit-box-orient:vertical;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:vertical;-moz-box-align:stretch;display:box;box-orient:vertical;box-align:stretch;width:100%;-webkit-box-flex:1;-moz-box-flex:1;box-flex:1;} |
|
66 | 66 | div.prompt:empty{padding-top:0;padding-bottom:0;} |
|
67 | 67 | div.input{page-break-inside:avoid;display:-webkit-box;-webkit-box-orient:horizontal;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:horizontal;-moz-box-align:stretch;display:box;box-orient:horizontal;box-align:stretch;} |
|
68 | 68 | div.input_area{border:1px solid #cfcfcf;border-radius:4px;background:#f7f7f7;} |
|
69 | 69 | div.input_prompt{color:navy;border-top:1px solid transparent;} |
|
70 | 70 | .CodeMirror{line-height:1.231em;height:auto;background:none;} |
|
71 | 71 | .CodeMirror-scroll{overflow-y:hidden;overflow-x:auto;} |
|
72 | 72 | @-moz-document url-prefix(){.CodeMirror-scroll{overflow-x:hidden;}}.CodeMirror-lines{padding:0.4em;} |
|
73 | 73 | .CodeMirror-linenumber{padding:0 8px 0 4px;} |
|
74 | 74 | .CodeMirror-gutters{border-bottom-left-radius:4px;border-top-left-radius:4px;} |
|
75 | 75 | .CodeMirror pre{padding:0;border:0;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;} |
|
76 | 76 | pre code{display:block;padding:0.5em;} |
|
77 | 77 | .highlight-base,pre code,pre .subst,pre .tag .title,pre .lisp .title,pre .clojure .built_in,pre .nginx .title{color:black;} |
|
78 | 78 | .highlight-string,pre .string,pre .constant,pre .parent,pre .tag .value,pre .rules .value,pre .rules .value .number,pre .preprocessor,pre .ruby .symbol,pre .ruby .symbol .string,pre .aggregate,pre .template_tag,pre .django .variable,pre .smalltalk .class,pre .addition,pre .flow,pre .stream,pre .bash .variable,pre .apache .tag,pre .apache .cbracket,pre .tex .command,pre .tex .special,pre .erlang_repl .function_or_atom,pre .markdown .header{color:#BA2121;} |
|
79 | 79 | .highlight-comment,pre .comment,pre .annotation,pre .template_comment,pre .diff .header,pre .chunk,pre .markdown .blockquote{color:#408080;font-style:italic;} |
|
80 | 80 | .highlight-number,pre .number,pre .date,pre .regexp,pre .literal,pre .smalltalk .symbol,pre .smalltalk .char,pre .go .constant,pre .change,pre .markdown .bullet,pre .markdown .link_url{color:#080;} |
|
81 | 81 | pre .label,pre .javadoc,pre .ruby .string,pre .decorator,pre .filter .argument,pre .localvars,pre .array,pre .attr_selector,pre .important,pre .pseudo,pre .pi,pre .doctype,pre .deletion,pre .envvar,pre .shebang,pre .apache .sqbracket,pre .nginx .built_in,pre .tex .formula,pre .erlang_repl .reserved,pre .prompt,pre .markdown .link_label,pre .vhdl .attribute,pre .clojure .attribute,pre .coffeescript .property{color:#8888ff;} |
|
82 | 82 | .highlight-keyword,pre .keyword,pre .id,pre .phpdoc,pre .aggregate,pre .css .tag,pre .javadoctag,pre .phpdoc,pre .yardoctag,pre .smalltalk .class,pre .winutils,pre .bash .variable,pre .apache .tag,pre .go .typename,pre .tex .command,pre .markdown .strong,pre .request,pre .status{color:#008000;font-weight:bold;} |
|
83 | 83 | .highlight-builtin,pre .built_in{color:#008000;} |
|
84 | 84 | pre .markdown .emphasis{font-style:italic;} |
|
85 | 85 | pre .nginx .built_in{font-weight:normal;} |
|
86 | 86 | pre .coffeescript .javascript,pre .javascript .xml,pre .tex .formula,pre .xml .javascript,pre .xml .vbscript,pre .xml .css,pre .xml .cdata{opacity:0.5;} |
|
87 | 87 | .cm-s-ipython span.cm-variable{color:black;} |
|
88 | 88 | .cm-s-ipython span.cm-keyword{color:#008000;font-weight:bold;} |
|
89 | 89 | .cm-s-ipython span.cm-number{color:#080;} |
|
90 | 90 | .cm-s-ipython span.cm-comment{color:#408080;font-style:italic;} |
|
91 | 91 | .cm-s-ipython span.cm-string{color:#BA2121;} |
|
92 | 92 | .cm-s-ipython span.cm-builtin{color:#008000;} |
|
93 | 93 | .cm-s-ipython span.cm-error{color:#f00;} |
|
94 | 94 | .cm-s-ipython span.cm-operator{color:#AA22FF;font-weight:bold;} |
|
95 | 95 | .cm-s-ipython span.cm-meta{color:#AA22FF;} |
|
96 | 96 | .cm-s-ipython span.cm-tab{background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAMCAYAAAAkuj5RAAAAAXNSR0IArs4c6QAAAGFJREFUSMft1LsRQFAQheHPowAKoACx3IgEKtaEHujDjORSgWTH/ZOdnZOcM/sgk/kFFWY0qV8foQwS4MKBCS3qR6ixBJvElOobYAtivseIE120FaowJPN75GMu8j/LfMwNjh4HUpwg4LUAAAAASUVORK5CYII=);background-position:right;background-repeat:no-repeat;} |
|
97 | 97 | div.output_wrapper{position:relative;display:-webkit-box;-webkit-box-orient:vertical;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:vertical;-moz-box-align:stretch;display:box;box-orient:vertical;box-align:stretch;width:100%;} |
|
98 | 98 | div.output_scroll{height:24em;width:100%;overflow:auto;border-radius:4px;-webkit-box-shadow:inset 0 2px 8px rgba(0, 0, 0, 0.8);-moz-box-shadow:inset 0 2px 8px rgba(0, 0, 0, 0.8);box-shadow:inset 0 2px 8px rgba(0, 0, 0, 0.8);} |
|
99 | 99 | div.output_collapsed{margin:0px;padding:0px;display:-webkit-box;-webkit-box-orient:vertical;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:vertical;-moz-box-align:stretch;display:box;box-orient:vertical;box-align:stretch;width:100%;} |
|
100 | 100 | div.out_prompt_overlay{height:100%;padding:0px 0.4em;position:absolute;border-radius:4px;} |
|
101 | 101 | div.out_prompt_overlay:hover{-webkit-box-shadow:inset 0 0 1px #000000;-moz-box-shadow:inset 0 0 1px #000000;box-shadow:inset 0 0 1px #000000;background:rgba(240, 240, 240, 0.5);} |
|
102 | 102 | div.output_prompt{color:darkred;} |
|
103 | 103 | div.output_area{padding:0px;page-break-inside:avoid;display:-webkit-box;-webkit-box-orient:horizontal;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:horizontal;-moz-box-align:stretch;display:box;box-orient:horizontal;box-align:stretch;}div.output_area .MathJax_Display{text-align:left !important;} |
|
104 | 104 | div.output_area .rendered_html table{margin-left:0;margin-right:0;} |
|
105 | 105 | div.output_area .rendered_html img{margin-left:0;margin-right:0;} |
|
106 | 106 | .output{display:-webkit-box;-webkit-box-orient:vertical;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:vertical;-moz-box-align:stretch;display:box;box-orient:vertical;box-align:stretch;width:100%;} |
|
107 | 107 | div.output_area pre{font-family:monospace;margin:0;padding:0;border:0;font-size:100%;vertical-align:baseline;color:black;background-color:transparent;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;line-height:inherit;} |
|
108 | 108 | div.output_subarea{padding:0.4em 0.4em 0em 0.4em;-webkit-box-flex:1;-moz-box-flex:1;box-flex:1;} |
|
109 | 109 | div.output_text{text-align:left;color:#000000;font-family:monospace;line-height:1.231em;} |
|
110 | 110 | div.output_stderr{background:#fdd;} |
|
111 | 111 | div.output_latex{text-align:left;} |
|
112 | 112 | div.output_javascript:empty{padding:0;} |
|
113 | 113 | .js-error{color:darkred;} |
|
114 | 114 | div.raw_input{padding-top:0px;padding-bottom:0px;height:1em;line-height:1em;font-family:monospace;} |
|
115 | 115 | span.input_prompt{font-family:inherit;} |
|
116 | 116 | input.raw_input{font-family:inherit;font-size:inherit;color:inherit;width:auto;margin:-2px 0px 0px 1px;padding-left:1px;padding-top:2px;height:1em;} |
|
117 | 117 | p.p-space{margin-bottom:10px;} |
|
118 | 118 | .rendered_html{color:black;}.rendered_html em{font-style:italic;} |
|
119 | 119 | .rendered_html strong{font-weight:bold;} |
|
120 | 120 | .rendered_html u{text-decoration:underline;} |
|
121 | 121 | .rendered_html :link{text-decoration:underline;} |
|
122 | 122 | .rendered_html :visited{text-decoration:underline;} |
|
123 | 123 | .rendered_html h1{font-size:197%;margin:.65em 0;font-weight:bold;} |
|
124 | 124 | .rendered_html h2{font-size:153.9%;margin:.75em 0;font-weight:bold;} |
|
125 | 125 | .rendered_html h3{font-size:123.1%;margin:.85em 0;font-weight:bold;} |
|
126 | 126 | .rendered_html h4{font-size:100%;margin:0.95em 0;font-weight:bold;} |
|
127 | 127 | .rendered_html h5{font-size:85%;margin:1.5em 0;font-weight:bold;} |
|
128 | 128 | .rendered_html h6{font-size:77%;margin:1.65em 0;font-weight:bold;} |
|
129 | 129 | .rendered_html ul{list-style:disc;margin:1em 2em;} |
|
130 | 130 | .rendered_html ul ul{list-style:square;margin:0em 2em;} |
|
131 | 131 | .rendered_html ul ul ul{list-style:circle;margin:0em 2em;} |
|
132 | 132 | .rendered_html ol{list-style:decimal;margin:1em 2em;} |
|
133 | 133 | .rendered_html ol ol{list-style:upper-alpha;margin:0em 2em;} |
|
134 | 134 | .rendered_html ol ol ol{list-style:lower-alpha;margin:0em 2em;} |
|
135 | 135 | .rendered_html ol ol ol ol{list-style:lower-roman;margin:0em 2em;} |
|
136 | 136 | .rendered_html ol ol ol ol ol{list-style:decimal;margin:0em 2em;} |
|
137 | 137 | .rendered_html hr{color:black;background-color:black;} |
|
138 | 138 | .rendered_html pre{margin:1em 2em;} |
|
139 | 139 | .rendered_html pre,.rendered_html code{border:0;background-color:#ffffff;color:#000000;font-size:100%;padding:0px;} |
|
140 | 140 | .rendered_html blockquote{margin:1em 2em;} |
|
141 | 141 | .rendered_html table{margin-left:auto;margin-right:auto;border:1px solid black;border-collapse:collapse;} |
|
142 | 142 | .rendered_html tr,.rendered_html th,.rendered_html td{border:1px solid black;border-collapse:collapse;margin:1em 2em;} |
|
143 | 143 | .rendered_html td,.rendered_html th{text-align:left;vertical-align:middle;padding:4px;} |
|
144 | 144 | .rendered_html th{font-weight:bold;} |
|
145 | 145 | .rendered_html p{text-align:justify;} |
|
146 | 146 | .rendered_html img{display:block;margin-left:auto;margin-right:auto;} |
|
147 | 147 | .rendered_html *+p{margin-top:1em;} |
|
148 | 148 | .rendered_html *+table{margin-top:1em;} |
|
149 | 149 | .rendered_html *+img{margin-top:1em;} |
|
150 | 150 | div.text_cell{padding:5px 5px 5px 0px;display:-webkit-box;-webkit-box-orient:horizontal;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:horizontal;-moz-box-align:stretch;display:box;box-orient:horizontal;box-align:stretch;} |
|
151 | 151 | div.text_cell_input{color:#000000;border:1px solid #cfcfcf;border-radius:4px;background:#f7f7f7;} |
|
152 | 152 | div.text_cell_render{outline:none;resize:none;width:inherit;border-style:none;padding:5px;color:#000000;} |
|
153 | 153 | a.anchor-link:link{text-decoration:none;padding:0px 20px;visibility:hidden;} |
|
154 | 154 | h1:hover .anchor-link,h2:hover .anchor-link,h3:hover .anchor-link,h4:hover .anchor-link,h5:hover .anchor-link,h6:hover .anchor-link{visibility:visible;} |
|
155 | .toolbar{padding:0px 10px;margin-top:-5px;}.toolbar select,.toolbar label{width:auto;height:26px;vertical-align:middle;margin-right:2px;margin-bottom:0px;display:inline;font-size:92%;margin-left:0.3em;margin-right:0.3em;padding:0px;padding-top:3px;} | |
|
156 | .toolbar .btn{padding:2px 8px;} | |
|
157 | .toolbar .btn-group{margin-top:0px;} | |
|
158 | .toolbar-inner{border:none !important;-webkit-box-shadow:none !important;-moz-box-shadow:none !important;box-shadow:none !important;} | |
|
159 | #maintoolbar{margin-bottom:0px;} | |
|
160 | @-moz-keyframes fadeOut{from{opacity:1;} to{opacity:0;}}@-webkit-keyframes fadeOut{from{opacity:1;} to{opacity:0;}}@-moz-keyframes fadeIn{from{opacity:0;} to{opacity:1;}}@-webkit-keyframes fadeIn{from{opacity:0;} to{opacity:1;}}.bigtooltip{overflow:auto;height:200px;-webkit-transition-property:height;-webkit-transition-duration:500ms;-moz-transition-property:height;-moz-transition-duration:500ms;transition-property:height;transition-duration:500ms;} | |
|
161 | .smalltooltip{-webkit-transition-property:height;-webkit-transition-duration:500ms;-moz-transition-property:height;-moz-transition-duration:500ms;transition-property:height;transition-duration:500ms;text-overflow:ellipsis;overflow:hidden;height:80px;} | |
|
162 | .tooltipbuttons{position:absolute;padding-right:15px;top:0px;right:0px;} | |
|
163 | .tooltiptext{padding-right:30px;} | |
|
164 | .ipython_tooltip{max-width:700px;-webkit-animation:fadeOut 400ms;-moz-animation:fadeOut 400ms;animation:fadeOut 400ms;-webkit-animation:fadeIn 400ms;-moz-animation:fadeIn 400ms;animation:fadeIn 400ms;vertical-align:middle;background-color:#f7f7f7;overflow:visible;border:#ababab 1px solid;outline:none;padding:3px;margin:0px;padding-left:7px;font-family:monospace;min-height:50px;-moz-box-shadow:0px 6px 10px -1px #adadad;-webkit-box-shadow:0px 6px 10px -1px #adadad;box-shadow:0px 6px 10px -1px #adadad;border-radius:4px;position:absolute;z-index:2;}.ipython_tooltip a{float:right;} | |
|
165 | .ipython_tooltip .tooltiptext pre{border:0;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;font-size:100%;background-color:#f7f7f7;} | |
|
166 | .pretooltiparrow{left:0px;margin:0px;top:-16px;width:40px;height:16px;overflow:hidden;position:absolute;} | |
|
167 | .pretooltiparrow:before{background-color:#f7f7f7;border:1px #ababab solid;z-index:11;content:"";position:absolute;left:15px;top:10px;width:25px;height:25px;-webkit-transform:rotate(45deg);-moz-transform:rotate(45deg);-ms-transform:rotate(45deg);-o-transform:rotate(45deg);} | |
|
168 | div.widget_area{page-break-inside:avoid;display:-webkit-box;-webkit-box-orient:horizontal;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:horizontal;-moz-box-align:stretch;display:box;box-orient:horizontal;box-align:stretch;} | |
|
169 | div.widget_subarea{padding:0.44em 0.4em 0.4em 1px;margin-left:6px;-webkit-box-flex:1;-moz-box-flex:1;box-flex:1;} |
@@ -1,7 +1,10 b'' | |||
|
1 | 1 | from base import Widget |
|
2 | from IPython.utils.traitlets import Unicode | |
|
2 | from IPython.utils.traitlets import Unicode, Bool | |
|
3 | 3 | |
|
4 | 4 | class ContainerWidget(Widget): |
|
5 | 5 | target_name = Unicode('container_widget') |
|
6 | 6 | default_view_name = Unicode('ContainerView') |
|
7 | No newline at end of file | |
|
7 | _keys = ['vbox', 'hbox'] | |
|
8 | ||
|
9 | hbox = Bool(True) | |
|
10 | vbox = Bool(False) No newline at end of file |
General Comments 0
You need to be logged in to leave comments.
Login now