##// END OF EJS Templates
Attempt 1, HBox and VBox implementation.
Jonathan Frederic -
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 .append($("<div />").append(widget_view.$el))
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.html('');
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 .slider({})
14 .addClass('slider');
13 .slider({})
14 .addClass('slider');
15 15
16 16 // Put the slider in a container
17 17 this.$slider_container = $('<div />')
18 .css('padding-top', '4px')
19 .css('padding-bottom', '4px')
20 .append(this.$slider);
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.html('');
9 this.$el
10 .html('')
10 11 this.$slider = $('<div />')
11 .slider({})
12 .addClass('slider');
12 .slider({})
13 .addClass('slider');
13 14
14 15 // Put the slider in a container
15 16 this.$slider_container = $('<div />')
16 .css('padding-top', '4px')
17 .css('padding-bottom', '4px')
18 .addClass(this.model.comm.comm_id)
19 .append(this.$slider);
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 .html('');
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.$label.html(this.model.get('value'));
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