##// END OF EJS Templates
Allow a widget to be displayed more than once within a parent widget.
Jonathan Frederic -
Show More
@@ -283,7 +283,8 b' function(WidgetManager, _, Backbone){'
283 // Public constructor.
283 // Public constructor.
284 this.model.on('change',this.update,this);
284 this.model.on('change',this.update,this);
285 this.options = parameters.options;
285 this.options = parameters.options;
286 this.child_views = [];
286 this.child_model_views = {};
287 this.child_views = {};
287 this.model.views.push(this);
288 this.model.views.push(this);
288 },
289 },
289
290
@@ -303,17 +304,34 b' function(WidgetManager, _, Backbone){'
303 // it would be great to have the widget manager add the cell metadata
304 // it would be great to have the widget manager add the cell metadata
304 // to the subview without having to add it here.
305 // to the subview without having to add it here.
305 var child_view = this.model.widget_manager.create_view(child_model, options || {}, this);
306 var child_view = this.model.widget_manager.create_view(child_model, options || {}, this);
306 this.child_views[child_model.id] = child_view;
307
308 // Associate the view id with the model id.
309 if (this.child_model_views[child_model.id] === undefined) {
310 this.child_model_views[child_model.id] = [];
311 }
312 this.child_model_views[child_model.id].push(child_view.id);
313
314 // Remember the view by id.
315 this.child_views[child_view.id] = child_view;
307 return child_view;
316 return child_view;
308 },
317 },
309
318
310 delete_child_view: function(child_model, options) {
319 delete_child_view: function(child_model, options) {
311 // Delete a child view that was previously created using create_child_view.
320 // Delete a child view that was previously created using create_child_view.
312 var view = this.child_views[child_model.id];
321 var view_ids = this.child_model_views[child_model.id];
313 if (view !== undefined) {
322 if (view_ids !== undefined) {
314 delete this.child_views[child_model.id];
323
315 view.remove();
324 // Remove every view associate with the model id.
316 child_model.views.pop(view);
325 for (var i =0; i < view_ids.length; i++) {
326 var view_id = view_ids[i];
327 var view = this.child_views[view_id];
328 views.remove();
329 delete this.child_views[view_id];
330 child_model.views.pop(view);
331 }
332
333 // Remove the view list specific to this model.
334 delete this.child_model_views[child_model.id];
317 }
335 }
318 },
336 },
319
337
@@ -332,16 +350,38 b' function(WidgetManager, _, Backbone){'
332
350
333
351
334 // removed items
352 // removed items
335 _.each(_.difference(old_list, new_list), function(item, index, list) {
353 _.each(this.difference(old_list, new_list), function(item, index, list) {
336 removed_callback(item);
354 removed_callback(item);
337 }, this);
355 }, this);
338
356
339 // added items
357 // added items
340 _.each(_.difference(new_list, old_list), function(item, index, list) {
358 _.each(this.difference(new_list, old_list), function(item, index, list) {
341 added_callback(item);
359 added_callback(item);
342 }, this);
360 }, this);
343 },
361 },
344
362
363 difference: function(a, b) {
364 // Calculate the difference of two lists by contents.
365 //
366 // This function is like the underscore difference function
367 // except it will not fail when given a list with duplicates.
368 // i.e.:
369 // diff([1, 2, 2, 3], [3, 2])
370 // Underscores results:
371 // [1]
372 // This method:
373 // [1, 2]
374 var contents = a.slice(0);
375 var found_index;
376 for (var i = 0; i < b.length; i++) {
377 found_index = _.indexOf(contents, b[i]);
378 if (found_index >= 0) {
379 contents.splice(found_index, 1);
380 }
381 }
382 return contents;
383 },
384
345 callbacks: function(){
385 callbacks: function(){
346 // Create msg callbacks for a comm msg.
386 // Create msg callbacks for a comm msg.
347 return this.model.callbacks(this);
387 return this.model.callbacks(this);
@@ -411,16 +451,16 b' function(WidgetManager, _, Backbone){'
411
451
412 var css = this.model.get('_css');
452 var css = this.model.get('_css');
413 if (css === undefined) {return;}
453 if (css === undefined) {return;}
414 for (var i = 0; i < css.length; i++) {
454 var that = this;
455 _.each(css, function(css_traits, selector){
415 // Apply the css traits to all elements that match the selector.
456 // Apply the css traits to all elements that match the selector.
416 var selector = css[i][0];
457 var elements = that._get_selector_element(selector);
417 var elements = this._get_selector_element(selector);
418 if (elements.length > 0) {
458 if (elements.length > 0) {
419 var trait_key = css[i][1];
459 _.each(css_traits, function(css_value, css_key){
420 var trait_value = css[i][2];
460 elements.css(css_key, css_value);
421 elements.css(trait_key ,trait_value);
461 });
422 }
462 }
423 }
463 });
424 },
464 },
425
465
426 _get_selector_element: function (selector) {
466 _get_selector_element: function (selector) {
@@ -2,24 +2,13 b''
2
2
3 Represents a container that can be used to group other widgets.
3 Represents a container that can be used to group other widgets.
4 """
4 """
5 #-----------------------------------------------------------------------------
5
6 # Copyright (c) 2013, the IPython Development Team.
6 # Copyright (c) IPython Development Team.
7 #
8 # Distributed under the terms of the Modified BSD License.
7 # Distributed under the terms of the Modified BSD License.
9 #
10 # The full license is in the file COPYING.txt, distributed with this software.
11 #-----------------------------------------------------------------------------
12
8
13 #-----------------------------------------------------------------------------
14 # Imports
15 #-----------------------------------------------------------------------------
16 from .widget import DOMWidget
9 from .widget import DOMWidget
17 from IPython.utils.traitlets import Unicode, Tuple, TraitError
10 from IPython.utils.traitlets import Unicode, Tuple, TraitError
18
11
19 #-----------------------------------------------------------------------------
20 # Classes
21 #-----------------------------------------------------------------------------
22
23 class ContainerWidget(DOMWidget):
12 class ContainerWidget(DOMWidget):
24 _view_name = Unicode('ContainerView', sync=True)
13 _view_name = Unicode('ContainerView', sync=True)
25
14
@@ -38,22 +27,6 b' class ContainerWidget(DOMWidget):'
38 for child in self._children:
27 for child in self._children:
39 child._handle_displayed()
28 child._handle_displayed()
40
29
41 def _children_changed(self, name, old, new):
42 """Validate children list.
43
44 Makes sure only one instance of any given model can exist in the
45 children list.
46 An excellent post on uniqifiers is available at
47 http://www.peterbe.com/plog/uniqifiers-benchmark
48 which provides the inspiration for using this implementation. Below
49 I've implemented the `f5` algorithm using Python comprehensions."""
50 if new is not None:
51 seen = {}
52 def add_item(i):
53 seen[i.model_id] = True
54 return i
55 self._children = [add_item(i) for i in new if not i.model_id in seen]
56
57
30
58 class PopupWidget(ContainerWidget):
31 class PopupWidget(ContainerWidget):
59 _view_name = Unicode('PopupView', sync=True)
32 _view_name = Unicode('PopupView', sync=True)
General Comments 0
You need to be logged in to leave comments. Login now