##// END OF EJS Templates
Float widget views now inherit from int counterparts
Jonathan Frederic -
Show More
@@ -14,255 +14,29 b''
14 * @namespace IPython
14 * @namespace IPython
15 **/
15 **/
16
16
17 define(["notebook/js/widgets/widget"], function(WidgetManager){
17 define(["notebook/js/widgets/widget",
18 "notebook/js/widgets/widget_int"],
19 function(WidgetManager, int_widgets){
18
20
19 var FloatSliderView = IPython.DOMWidgetView.extend({
21 var IntSliderView = int_widgets[0];
20 render : function(){
22 var IntTextView = int_widgets[1];
21 // Called when view is rendered.
22 this.$el
23 .addClass('widget-hbox-single');
24 this.$label = $('<div />')
25 .appendTo(this.$el)
26 .addClass('widget-hlabel')
27 .hide();
28 this.$slider = $('<div />')
29 .slider({})
30 .addClass('slider');
31
32 // Put the slider in a container
33 this.$slider_container = $('<div />')
34 .addClass('widget-hslider')
35 .append(this.$slider);
36 this.$el_to_style = this.$slider_container; // Set default element to style
37 this.$el.append(this.$slider_container);
38
39 // Set defaults.
40 this.update();
41 },
42
43 update : function(options){
44 // Update the contents of this view
45 //
46 // Called when the model is changed. The model may have been
47 // changed by another view or by a state update from the back-end.
48
49 if (options === undefined || options.updated_view != this) {
50 // JQuery slider option keys. These keys happen to have a
51 // one-to-one mapping with the corrosponding keys of the model.
52 var jquery_slider_keys = ['step', 'max', 'min', 'disabled'];
53 var that = this;
54 _.each(jquery_slider_keys, function(key, i) {
55 var model_value = that.model.get(key);
56 if (model_value !== undefined) {
57 that.$slider.slider("option", key, model_value);
58 }
59 });
60
61 // WORKAROUND FOR JQUERY SLIDER BUG.
62 // The horizontal position of the slider handle
63 // depends on the value of the slider at the time
64 // of orientation change. Before applying the new
65 // workaround, we set the value to the minimum to
66 // make sure that the horizontal placement of the
67 // handle in the vertical slider is always
68 // consistent.
69 var orientation = this.model.get('orientation');
70 var value = this.model.get('min');
71 this.$slider.slider('option', 'value', value);
72 this.$slider.slider('option', 'orientation', orientation);
73 value = this.model.get('value');
74 this.$slider.slider('option', 'value', value);
75
76 // Use the right CSS classes for vertical & horizontal sliders
77 if (orientation=='vertical') {
78 this.$slider_container
79 .removeClass('widget-hslider')
80 .addClass('widget-vslider');
81 this.$el
82 .removeClass('widget-hbox-single')
83 .addClass('widget-vbox-single');
84 this.$label
85 .removeClass('widget-hlabel')
86 .addClass('widget-vlabel');
87
88 } else {
89 this.$slider_container
90 .removeClass('widget-vslider')
91 .addClass('widget-hslider');
92 this.$el
93 .removeClass('widget-vbox-single')
94 .addClass('widget-hbox-single');
95 this.$label
96 .removeClass('widget-vlabel')
97 .addClass('widget-hlabel');
98 }
99
23
100 var description = this.model.get('description');
101 if (description.length === 0) {
102 this.$label.hide();
103 } else {
104 this.$label.text(description);
105 this.$label.show();
106 }
107 }
108 return FloatSliderView.__super__.update.apply(this);
109 },
110
111 events: {
112 // Dictionary of events and their handlers.
113 "slide" : "handleSliderChange"
114 },
115
116 handleSliderChange: function(e, ui) {
117 // Handle when the slider value is changed.
118
24
119 // Calling model.set will trigger all of the other views of the
25 var FloatSliderView = IntSliderView.extend({
120 // model to update.
26 _validate_slide_value: function(x) {
121 this.model.set('value', ui.value, {updated_view: this});
27 // Validate the value of the slider before sending it to the back-end
122 this.touch();
28 // and applying it to the other views on the page.
29 return x;
123 },
30 },
124 });
31 });
125 WidgetManager.register_widget_view('FloatSliderView', FloatSliderView);
32 WidgetManager.register_widget_view('FloatSliderView', FloatSliderView);
126
33
127
34
128 var FloatTextView = IPython.DOMWidgetView.extend({
35 var FloatTextView = IntTextView.extend({
129 render : function(){
36 _parse_value: function(value) {
130 // Called when view is rendered.
37 // Parse the value stored in a string.
131 this.$el
38 return parseFloat(value);
132 .addClass('widget-hbox-single');
133 this.$label = $('<div />')
134 .appendTo(this.$el)
135 .addClass('widget-hlabel')
136 .hide();
137 this.$textbox = $('<input type="text" />')
138 .addClass('input')
139 .addClass('widget-numeric-text')
140 .appendTo(this.$el);
141 this.$el_to_style = this.$textbox; // Set default element to style
142 this.update(); // Set defaults.
143 },
144
145 update : function(options){
146 // Update the contents of this view
147 //
148 // Called when the model is changed. The model may have been
149 // changed by another view or by a state update from the back-end.
150 if (options === undefined || options.updated_view != this) {
151 var value = this.model.get('value');
152 if (parseFloat(this.$textbox.val()) != value) {
153 this.$textbox.val(value);
154 }
155
156 if (this.model.get('disabled')) {
157 this.$textbox.attr('disabled','disabled');
158 } else {
159 this.$textbox.removeAttr('disabled');
160 }
161
162 var description = this.model.get('description');
163 if (description.length === 0) {
164 this.$label.hide();
165 } else {
166 this.$label.text(description);
167 this.$label.show();
168 }
169 }
170 return FloatTextView.__super__.update.apply(this);
171 },
172
173 events: {
174 // Dictionary of events and their handlers.
175
176 "keyup input" : "handleChanging",
177 "paste input" : "handleChanging",
178 "cut input" : "handleChanging",
179
180 // Fires only when control is validated or looses focus.
181 "change input" : "handleChanged"
182 },
183
184 handleChanging: function(e) {
185 // Handles and validates user input.
186
187 // Try to parse value as a float.
188 var numericalValue = 0.0;
189 if (e.target.value !== '') {
190 numericalValue = parseFloat(e.target.value);
191 }
192
193 // If parse failed, reset value to value stored in model.
194 if (isNaN(numericalValue)) {
195 e.target.value = this.model.get('value');
196 } else if (!isNaN(numericalValue)) {
197 if (this.model.get('max') !== undefined) {
198 numericalValue = Math.min(this.model.get('max'), numericalValue);
199 }
200 if (this.model.get('min') !== undefined) {
201 numericalValue = Math.max(this.model.get('min'), numericalValue);
202 }
203
204 // Apply the value if it has changed.
205 if (numericalValue != this.model.get('value')) {
206
207 // Calling model.set will trigger all of the other views of the
208 // model to update.
209 this.model.set('value', numericalValue, {updated_view: this});
210 this.touch();
211 }
212 }
213 },
39 },
214
215 handleChanged: function(e) {
216 // Applies validated input.
217 if (this.model.get('value') != e.target.value) {
218 e.target.value = this.model.get('value');
219 }
220 }
221 });
40 });
222 WidgetManager.register_widget_view('FloatTextView', FloatTextView);
41 WidgetManager.register_widget_view('FloatTextView', FloatTextView);
223
224
225 var ProgressView = IPython.DOMWidgetView.extend({
226 render : function(){
227 // Called when view is rendered.
228 this.$el
229 .addClass('widget-hbox-single');
230 this.$label = $('<div />')
231 .appendTo(this.$el)
232 .addClass('widget-hlabel')
233 .hide();
234 this.$progress = $('<div />')
235 .addClass('progress')
236 .addClass('widget-progress')
237 .appendTo(this.$el);
238 this.$el_to_style = this.$progress; // Set default element to style
239 this.$bar = $('<div />')
240 .addClass('bar')
241 .css('width', '50%')
242 .appendTo(this.$progress);
243 this.update(); // Set defaults.
244 },
245
246 update : function(){
247 // Update the contents of this view
248 //
249 // Called when the model is changed. The model may have been
250 // changed by another view or by a state update from the back-end.
251 var value = this.model.get('value');
252 var max = this.model.get('max');
253 var min = this.model.get('min');
254 var percent = 100.0 * (value - min) / (max - min);
255 this.$bar.css('width', percent + '%');
256
257 var description = this.model.get('description');
258 if (description.length === 0) {
259 this.$label.hide();
260 } else {
261 this.$label.text(description);
262 this.$label.show();
263 }
264 return ProgressView.__super__.update.apply(this);
265 },
266 });
267 WidgetManager.register_widget_view('ProgressView', ProgressView);
268 });
42 });
@@ -117,9 +117,17 b' define(["notebook/js/widgets/widget"], function(WidgetManager){'
117
117
118 // Calling model.set will trigger all of the other views of the
118 // Calling model.set will trigger all of the other views of the
119 // model to update.
119 // model to update.
120 this.model.set('value', ~~ui.value, {updated_view: this}); // Double bit-wise not to truncate decimel
120 this.model.set('value', this._validate_slide_value(ui.value), {updated_view: this});
121 this.touch();
121 this.touch();
122 },
122 },
123
124 _validate_slide_value: function(x) {
125 // Validate the value of the slider before sending it to the back-end
126 // and applying it to the other views on the page.
127
128 // Double bit-wise not truncates the decimel (int cast).
129 return ~~x;
130 },
123 });
131 });
124 WidgetManager.register_widget_view('IntSliderView', IntSliderView);
132 WidgetManager.register_widget_view('IntSliderView', IntSliderView);
125
133
@@ -148,7 +156,7 b' define(["notebook/js/widgets/widget"], function(WidgetManager){'
148 // changed by another view or by a state update from the back-end.
156 // changed by another view or by a state update from the back-end.
149 if (options === undefined || options.updated_view != this) {
157 if (options === undefined || options.updated_view != this) {
150 var value = this.model.get('value');
158 var value = this.model.get('value');
151 if (parseInt(this.$textbox.val()) != value) {
159 if (this._parse_value(this.$textbox.val()) != value) {
152 this.$textbox.val(value);
160 this.$textbox.val(value);
153 }
161 }
154
162
@@ -182,10 +190,10 b' define(["notebook/js/widgets/widget"], function(WidgetManager){'
182 handleChanging: function(e) {
190 handleChanging: function(e) {
183 // Handles and validates user input.
191 // Handles and validates user input.
184
192
185 // Try to parse value as a float.
193 // Try to parse value as a int.
186 var numericalValue = 0;
194 var numericalValue = 0;
187 if (e.target.value !== '') {
195 if (e.target.value !== '') {
188 numericalValue = parseInt(e.target.value);
196 numericalValue = this._parse_value(e.target.value);
189 }
197 }
190
198
191 // If parse failed, reset value to value stored in model.
199 // If parse failed, reset value to value stored in model.
@@ -215,7 +223,62 b' define(["notebook/js/widgets/widget"], function(WidgetManager){'
215 if (this.model.get('value') != e.target.value) {
223 if (this.model.get('value') != e.target.value) {
216 e.target.value = this.model.get('value');
224 e.target.value = this.model.get('value');
217 }
225 }
218 }
226 },
227
228 _parse_value: function(value) {
229 // Parse the value stored in a string.
230 return parseInt(value);
231 },
219 });
232 });
220 WidgetManager.register_widget_view('IntTextView', IntTextView);
233 WidgetManager.register_widget_view('IntTextView', IntTextView);
234
235
236 var ProgressView = IPython.DOMWidgetView.extend({
237 render : function(){
238 // Called when view is rendered.
239 this.$el
240 .addClass('widget-hbox-single');
241 this.$label = $('<div />')
242 .appendTo(this.$el)
243 .addClass('widget-hlabel')
244 .hide();
245 this.$progress = $('<div />')
246 .addClass('progress')
247 .addClass('widget-progress')
248 .appendTo(this.$el);
249 this.$el_to_style = this.$progress; // Set default element to style
250 this.$bar = $('<div />')
251 .addClass('bar')
252 .css('width', '50%')
253 .appendTo(this.$progress);
254 this.update(); // Set defaults.
255 },
256
257 update : function(){
258 // Update the contents of this view
259 //
260 // Called when the model is changed. The model may have been
261 // changed by another view or by a state update from the back-end.
262 var value = this.model.get('value');
263 var max = this.model.get('max');
264 var min = this.model.get('min');
265 var percent = 100.0 * (value - min) / (max - min);
266 this.$bar.css('width', percent + '%');
267
268 var description = this.model.get('description');
269 if (description.length === 0) {
270 this.$label.hide();
271 } else {
272 this.$label.text(description);
273 this.$label.show();
274 }
275 return ProgressView.__super__.update.apply(this);
276 },
277 });
278 WidgetManager.register_widget_view('ProgressView', ProgressView);
279
280
281 // Return the slider and text views so they can be inheritted to create the
282 // float versions.
283 return [IntSliderView, IntTextView];
221 });
284 });
General Comments 0
You need to be logged in to leave comments. Login now