##// END OF EJS Templates
Merge pull request #5010 from jdfreder/widget-ff...
Thomas Kluyver -
r15020:12bac7bd merge
parent child Browse files
Show More
@@ -1,272 +1,274 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 // ContainerWidget
10 10 //============================================================================
11 11
12 12 /**
13 13 * @module IPython
14 14 * @namespace IPython
15 15 **/
16 16
17 17 define(["notebook/js/widgets/widget"], function(WidgetManager) {
18 18
19 19 var ContainerView = IPython.DOMWidgetView.extend({
20 20 render: function(){
21 21 // Called when view is rendered.
22 this.$el.addClass('widget-container');
22 this.$el.addClass('widget-container')
23 .addClass('vbox');
23 24 this.children={};
24 25 this.update_children([], this.model.get('_children'));
25 26 this.model.on('change:_children', function(model, value, options) {
26 27 this.update_children(model.previous('_children'), value);
27 28 }, this);
28 29 this.update();
29 30 },
30 31
31 32 update_children: function(old_list, new_list) {
32 33 // Called when the children list changes.
33 34 this.do_diff(old_list,
34 35 new_list,
35 36 $.proxy(this.remove_child_model, this),
36 37 $.proxy(this.add_child_model, this));
37 38 },
38 39
39 40 remove_child_model: function(model) {
40 41 // Called when a model is removed from the children list.
41 42 this.child_views[model.id].remove();
42 43 this.delete_child_view(model);
43 44 },
44 45
45 46 add_child_model: function(model) {
46 47 // Called when a model is added to the children list.
47 48 var view = this.create_child_view(model);
48 49 this.$el.append(view.$el);
49 50 },
50 51
51 52 update: function(){
52 53 // Update the contents of this view
53 54 //
54 55 // Called when the model is changed. The model may have been
55 56 // changed by another view or by a state update from the back-end.
56 57 return ContainerView.__super__.update.apply(this);
57 58 },
58 59 });
59 60
60 61 WidgetManager.register_widget_view('ContainerView', ContainerView);
61 62
62 63 var PopupView = IPython.DOMWidgetView.extend({
63 64 render: function(){
64 65 // Called when view is rendered.
65 66 var that = this;
66 67 this.children={};
67 68
68 69 this.$el.on("remove", function(){
69 70 that.$window.remove();
70 71 });
71 72 this.$window = $('<div />')
72 73 .addClass('modal widget-modal')
73 74 .appendTo($('#notebook-container'))
74 75 .mousedown(function(){
75 76 that.bring_to_front();
76 77 });
77 78 this.$title_bar = $('<div />')
78 79 .addClass('popover-title')
79 80 .appendTo(this.$window)
80 81 .mousedown(function(){
81 82 that.bring_to_front();
82 83 });
83 84 this.$close = $('<button />')
84 85 .addClass('close icon-remove')
85 86 .css('margin-left', '5px')
86 87 .appendTo(this.$title_bar)
87 88 .click(function(){
88 89 that.hide();
89 90 event.stopPropagation();
90 91 });
91 92 this.$minimize = $('<button />')
92 93 .addClass('close icon-arrow-down')
93 94 .appendTo(this.$title_bar)
94 95 .click(function(){
95 96 that.popped_out = !that.popped_out;
96 97 if (!that.popped_out) {
97 98 that.$minimize
98 99 .removeClass('icon-arrow-down')
99 100 .addClass('icon-arrow-up');
100 101
101 102 that.$window
102 103 .draggable('destroy')
103 104 .resizable('destroy')
104 105 .removeClass('widget-modal modal')
105 106 .addClass('docked-widget-modal')
106 107 .detach()
107 108 .insertBefore(that.$show_button);
108 109 that.$show_button.hide();
109 110 that.$close.hide();
110 111 } else {
111 112 that.$minimize
112 113 .addClass('icon-arrow-down')
113 114 .removeClass('icon-arrow-up');
114 115
115 116 that.$window
116 117 .removeClass('docked-widget-modal')
117 118 .addClass('widget-modal modal')
118 119 .detach()
119 120 .appendTo($('#notebook-container'))
120 121 .draggable({handle: '.popover-title', snap: '#notebook, .modal', snapMode: 'both'})
121 122 .resizable()
122 123 .children('.ui-resizable-handle').show();
123 124 that.show();
124 125 that.$show_button.show();
125 126 that.$close.show();
126 127 }
127 128 event.stopPropagation();
128 129 });
129 130 this.$title = $('<div />')
130 131 .addClass('widget-modal-title')
131 132 .text(' ')
132 133 .appendTo(this.$title_bar);
133 134 this.$body = $('<div />')
134 135 .addClass('modal-body')
135 136 .addClass('widget-modal-body')
136 137 .addClass('widget-container')
138 .addClass('vbox')
137 139 .appendTo(this.$window);
138 140
139 141 this.$show_button = $('<button />')
140 142 .text(' ')
141 143 .addClass('btn btn-info widget-modal-show')
142 144 .appendTo(this.$el)
143 145 .click(function(){
144 146 that.show();
145 147 });
146 148
147 149 this.$window.draggable({handle: '.popover-title', snap: '#notebook, .modal', snapMode: 'both'});
148 150 this.$window.resizable();
149 151 this.$window.on('resize', function(){
150 152 that.$body.outerHeight(that.$window.innerHeight() - that.$title_bar.outerHeight());
151 153 });
152 154
153 155 this.$el_to_style = this.$body;
154 156 this._shown_once = false;
155 157 this.popped_out = true;
156 158
157 159 this.update_children([], this.model.get('_children'));
158 160 this.model.on('change:_children', function(model, value, options) {
159 161 this.update_children(model.previous('_children'), value);
160 162 }, this);
161 163 this.update();
162 164 },
163 165
164 166 hide: function() {
165 167 // Called when the modal hide button is clicked.
166 168 this.$window.hide();
167 169 this.$show_button.removeClass('btn-info');
168 170 },
169 171
170 172 show: function() {
171 173 // Called when the modal show button is clicked.
172 174 this.$show_button.addClass('btn-info');
173 175 this.$window.show();
174 176 if (this.popped_out) {
175 177 this.$window.css("positon", "absolute");
176 178 this.$window.css("top", "0px");
177 179 this.$window.css("left", Math.max(0, (($('body').outerWidth() - this.$window.outerWidth()) / 2) +
178 180 $(window).scrollLeft()) + "px");
179 181 this.bring_to_front();
180 182 }
181 183 },
182 184
183 185 bring_to_front: function() {
184 186 // Make the modal top-most, z-ordered about the other modals.
185 187 var $widget_modals = $(".widget-modal");
186 188 var max_zindex = 0;
187 189 $widget_modals.each(function (index, el){
188 190 max_zindex = Math.max(max_zindex, parseInt($(el).css('z-index')));
189 191 });
190 192
191 193 // Start z-index of widget modals at 2000
192 194 max_zindex = Math.max(max_zindex, 2000);
193 195
194 196 $widget_modals.each(function (index, el){
195 197 $el = $(el);
196 198 if (max_zindex == parseInt($el.css('z-index'))) {
197 199 $el.css('z-index', max_zindex - 1);
198 200 }
199 201 });
200 202 this.$window.css('z-index', max_zindex);
201 203 },
202 204
203 205 update_children: function(old_list, new_list) {
204 206 // Called when the children list is modified.
205 207 this.do_diff(old_list,
206 208 new_list,
207 209 $.proxy(this.remove_child_model, this),
208 210 $.proxy(this.add_child_model, this));
209 211 },
210 212
211 213 remove_child_model: function(model) {
212 214 // Called when a child is removed from children list.
213 215 this.child_views[model.id].remove();
214 216 this.delete_child_view(model);
215 217 },
216 218
217 219 add_child_model: function(model) {
218 220 // Called when a child is added to children list.
219 221 var view = this.create_child_view(model);
220 222 this.$body.append(view.$el);
221 223 },
222 224
223 225 update: function(){
224 226 // Update the contents of this view
225 227 //
226 228 // Called when the model is changed. The model may have been
227 229 // changed by another view or by a state update from the back-end.
228 230 var description = this.model.get('description');
229 231 if (description.length === 0) {
230 232 this.$title.text(' '); // Preserve title height
231 233 } else {
232 234 this.$title.text(description);
233 235 }
234 236
235 237 var button_text = this.model.get('button_text');
236 238 if (button_text.length === 0) {
237 239 this.$show_button.text(' '); // Preserve button height
238 240 } else {
239 241 this.$show_button.text(button_text);
240 242 }
241 243
242 244 if (!this._shown_once) {
243 245 this._shown_once = true;
244 246 this.show();
245 247 }
246 248
247 249 return PopupView.__super__.update.apply(this);
248 250 },
249 251
250 252 _get_selector_element: function(selector) {
251 253 // Get an element view a 'special' jquery selector. (see widget.js)
252 254 //
253 255 // Since the modal actually isn't within the $el in the DOM, we need to extend
254 256 // the selector logic to allow the user to set css on the modal if need be.
255 257 // The convention used is:
256 258 // "modal" - select the modal div
257 259 // "modal [selector]" - select element(s) within the modal div.
258 260 // "[selector]" - select elements within $el
259 261 // "" - select the $el_to_style
260 262 if (selector.substring(0, 5) == 'modal') {
261 263 if (selector == 'modal') {
262 264 return this.$window;
263 265 } else {
264 266 return this.$window.find(selector.substring(6));
265 267 }
266 268 } else {
267 269 return PopupView.__super__._get_selector_element.apply(this, [selector]);
268 270 }
269 271 },
270 272 });
271 273 WidgetManager.register_widget_view('PopupView', PopupView);
272 274 });
General Comments 0
You need to be logged in to leave comments. Login now