widget_box.js
328 lines
| 12.5 KiB
| application/javascript
|
JavascriptLexer
Jonathan Frederic
|
r17198 | // Copyright (c) IPython Development Team. | ||
// Distributed under the terms of the Modified BSD License. | ||||
Jonathan Frederic
|
r14366 | |||
Jonathan Frederic
|
r17198 | define([ | ||
"widgets/js/widget", | ||||
Jonathan Frederic
|
r17216 | "jqueryui", | ||
MinRK
|
r17312 | "bootstrap", | ||
Jonathan Frederic
|
r17215 | ], function(widget, $){ | ||
Jonathan Frederic
|
r14366 | |||
Jonathan Frederic
|
r17637 | var BoxView = widget.DOMWidgetView.extend({ | ||
sylvain.corlay
|
r17349 | initialize: function(){ | ||
// Public constructor | ||||
Jonathan Frederic
|
r17637 | BoxView.__super__.initialize.apply(this, arguments); | ||
Jonathan Frederic
|
r17173 | this.update_children([], this.model.get('children')); | ||
sylvain.corlay
|
r17347 | this.model.on('change:children', function(model, value) { | ||
Jonathan Frederic
|
r17173 | this.update_children(model.previous('children'), value); | ||
Jason Grout
|
r14503 | }, this); | ||
}, | ||||
sylvain.corlay
|
r17349 | |||
render: function(){ | ||||
// Called when view is rendered. | ||||
Jonathan Frederic
|
r17596 | this.$el.addClass('widget-container'); | ||
Jason Grout
|
r14503 | }, | ||
update_children: function(old_list, new_list) { | ||||
Jonathan Frederic
|
r14609 | // Called when the children list changes. | ||
sylvain.corlay
|
r17349 | this.do_diff(old_list, new_list, | ||
Jonathan Frederic
|
r14598 | $.proxy(this.remove_child_model, this), | ||
$.proxy(this.add_child_model, this)); | ||||
}, | ||||
remove_child_model: function(model) { | ||||
Jonathan Frederic
|
r14609 | // Called when a model is removed from the children list. | ||
Jonathan Frederic
|
r17178 | this.pop_child_view(model).remove(); | ||
Jonathan Frederic
|
r14598 | }, | ||
add_child_model: function(model) { | ||||
Jonathan Frederic
|
r14609 | // Called when a model is added to the children list. | ||
Jonathan Frederic
|
r14598 | var view = this.create_child_view(model); | ||
this.$el.append(view.$el); | ||||
Jonathan Frederic
|
r16660 | |||
sylvain.corlay
|
r17353 | // Trigger the displayed event of the child view. | ||
Sylvain Corlay
|
r17329 | this.after_displayed(function() { | ||
Jonathan Frederic
|
r17179 | view.trigger('displayed'); | ||
Sylvain Corlay
|
r17271 | }); | ||
Jonathan Frederic
|
r14263 | }, | ||
}); | ||||
Jonathan Frederic
|
r17596 | |||
Jonathan Frederic
|
r17637 | var FlexBoxView = BoxView.extend({ | ||
Jonathan Frederic
|
r17596 | render: function(){ | ||
Jonathan Frederic
|
r17637 | FlexBoxView.__super__.render.apply(this); | ||
Sylvain Corlay
|
r17600 | this.model.on('change:orientation', this.update_orientation, this); | ||
Jonathan Frederic
|
r17596 | this.model.on('change:flex', this._flex_changed, this); | ||
this.model.on('change:pack', this._pack_changed, this); | ||||
this.model.on('change:align', this._align_changed, this); | ||||
this._flex_changed(); | ||||
this._pack_changed(); | ||||
this._align_changed(); | ||||
Sylvain Corlay
|
r17600 | that.update_orientation(); | ||
}, | ||||
update_orientation: function(){ | ||||
var orientation = this.model.get("orientation"); | ||||
if (orientation == "vertical") { | ||||
this.$el.removeClass("hbox").addClass("vbox"); | ||||
} else { | ||||
this.$el.removeClass("vbox").addClass("hbox"); | ||||
} | ||||
Jonathan Frederic
|
r17596 | }, | ||
_flex_changed: function(){ | ||||
if (this.model.previous('flex')) { | ||||
this.$el.removeClass('box-flex' + this.model.previous('flex')); | ||||
} | ||||
this.$el.addClass('box-flex' + this.model.get('flex')); | ||||
}, | ||||
_pack_changed: function(){ | ||||
if (this.model.previous('pack')) { | ||||
this.$el.removeClass(this.model.previous('pack')); | ||||
} | ||||
this.$el.addClass(this.model.get('pack')); | ||||
}, | ||||
_align_changed: function(){ | ||||
if (this.model.previous('align')) { | ||||
this.$el.removeClass('align-' + this.model.previous('align')); | ||||
} | ||||
this.$el.addClass('align-' + this.model.get('align')); | ||||
}, | ||||
}); | ||||
Jonathan Frederic
|
r17198 | var PopupView = widget.DOMWidgetView.extend({ | ||
Jonathan Frederic
|
r14409 | render: function(){ | ||
Jonathan Frederic
|
r14609 | // Called when view is rendered. | ||
Jonathan Frederic
|
r14409 | var that = this; | ||
Jonathan Frederic
|
r14507 | |||
MinRK
|
r14792 | this.$el.on("remove", function(){ | ||
Jonathan Frederic
|
r16955 | that.$backdrop.remove(); | ||
Jonathan Frederic
|
r14409 | }); | ||
Jonathan Frederic
|
r16955 | this.$backdrop = $('<div />') | ||
Jonathan Frederic
|
r14443 | .appendTo($('#notebook-container')) | ||
Jonathan Frederic
|
r16955 | .addClass('modal-dialog') | ||
.css('position', 'absolute') | ||||
.css('left', '0px') | ||||
.css('top', '0px'); | ||||
this.$window = $('<div />') | ||||
.appendTo(this.$backdrop) | ||||
.addClass('modal-content widget-modal') | ||||
Jonathan Frederic
|
r14443 | .mousedown(function(){ | ||
that.bring_to_front(); | ||||
}); | ||||
Jonathan Frederic
|
r15022 | |||
// Set the elements array since the this.$window element is not child | ||||
// of this.$el and the parent widget manager or other widgets may | ||||
// need to know about all of the top-level widgets. The IPython | ||||
// widget manager uses this to register the elements with the | ||||
// keyboard manager. | ||||
Jonathan Frederic
|
r16660 | this.additional_elements = [this.$window]; | ||
Jonathan Frederic
|
r15022 | |||
Jonathan Frederic
|
r14410 | this.$title_bar = $('<div />') | ||
Jonathan Frederic
|
r14409 | .addClass('popover-title') | ||
Jonathan Frederic
|
r14443 | .appendTo(this.$window) | ||
.mousedown(function(){ | ||||
that.bring_to_front(); | ||||
Jonathan Frederic
|
r14466 | }); | ||
Jonathan Frederic
|
r14443 | this.$close = $('<button />') | ||
Thomas Spura
|
r17413 | .addClass('close fa fa-remove') | ||
Jonathan Frederic
|
r14443 | .css('margin-left', '5px') | ||
Jonathan Frederic
|
r14410 | .appendTo(this.$title_bar) | ||
Jonathan Frederic
|
r14409 | .click(function(){ | ||
that.hide(); | ||||
event.stopPropagation(); | ||||
}); | ||||
Jonathan Frederic
|
r14443 | this.$minimize = $('<button />') | ||
Thomas Spura
|
r17413 | .addClass('close fa fa-arrow-down') | ||
Jonathan Frederic
|
r14443 | .appendTo(this.$title_bar) | ||
.click(function(){ | ||||
that.popped_out = !that.popped_out; | ||||
if (!that.popped_out) { | ||||
that.$minimize | ||||
Thomas Spura
|
r17413 | .removeClass('fa fa-arrow-down') | ||
.addClass('fa fa-arrow-up'); | ||||
Jonathan Frederic
|
r14443 | |||
that.$window | ||||
.draggable('destroy') | ||||
.resizable('destroy') | ||||
Jonathan Frederic
|
r16955 | .removeClass('widget-modal modal-content') | ||
Jonathan Frederic
|
r14443 | .addClass('docked-widget-modal') | ||
.detach() | ||||
.insertBefore(that.$show_button); | ||||
that.$show_button.hide(); | ||||
that.$close.hide(); | ||||
} else { | ||||
that.$minimize | ||||
Thomas Spura
|
r17413 | .addClass('fa fa-arrow-down') | ||
.removeClass('fa fa-arrow-up'); | ||||
Jonathan Frederic
|
r14443 | |||
that.$window | ||||
.removeClass('docked-widget-modal') | ||||
Jonathan Frederic
|
r16955 | .addClass('widget-modal modal-content') | ||
Jonathan Frederic
|
r14443 | .detach() | ||
Jonathan Frederic
|
r16955 | .appendTo(that.$backdrop) | ||
Jonathan Frederic
|
r14443 | .draggable({handle: '.popover-title', snap: '#notebook, .modal', snapMode: 'both'}) | ||
.resizable() | ||||
.children('.ui-resizable-handle').show(); | ||||
that.show(); | ||||
that.$show_button.show(); | ||||
that.$close.show(); | ||||
} | ||||
event.stopPropagation(); | ||||
}); | ||||
Jonathan Frederic
|
r14409 | this.$title = $('<div />') | ||
.addClass('widget-modal-title') | ||||
MinRK
|
r15329 | .html(" ") | ||
Jonathan Frederic
|
r14410 | .appendTo(this.$title_bar); | ||
Jonathan Frederic
|
r14409 | this.$body = $('<div />') | ||
.addClass('modal-body') | ||||
Jonathan Frederic
|
r14411 | .addClass('widget-modal-body') | ||
Jonathan Frederic
|
r14409 | .addClass('widget-container') | ||
Jonathan Frederic
|
r15015 | .addClass('vbox') | ||
Jonathan Frederic
|
r14409 | .appendTo(this.$window); | ||
this.$show_button = $('<button />') | ||||
MinRK
|
r15329 | .html(" ") | ||
Jonathan Frederic
|
r16914 | .addClass('btn btn-info widget-modal-show') | ||
Jonathan Frederic
|
r14409 | .appendTo(this.$el) | ||
.click(function(){ | ||||
that.show(); | ||||
}); | ||||
this.$window.draggable({handle: '.popover-title', snap: '#notebook, .modal', snapMode: 'both'}); | ||||
this.$window.resizable(); | ||||
Jonathan Frederic
|
r14410 | this.$window.on('resize', function(){ | ||
that.$body.outerHeight(that.$window.innerHeight() - that.$title_bar.outerHeight()); | ||||
Jonathan Frederic
|
r14466 | }); | ||
Jonathan Frederic
|
r14410 | |||
Jonathan Frederic
|
r14409 | this._shown_once = false; | ||
Jonathan Frederic
|
r14443 | this.popped_out = true; | ||
Jonathan Frederic
|
r14754 | |||
Jonathan Frederic
|
r17173 | this.update_children([], this.model.get('children')); | ||
sylvain.corlay
|
r17347 | this.model.on('change:children', function(model, value) { | ||
Jonathan Frederic
|
r17173 | this.update_children(model.previous('children'), value); | ||
Jonathan Frederic
|
r14754 | }, this); | ||
Jonathan Frederic
|
r14409 | }, | ||
hide: function() { | ||||
Jonathan Frederic
|
r14609 | // Called when the modal hide button is clicked. | ||
Jonathan Frederic
|
r14409 | this.$window.hide(); | ||
this.$show_button.removeClass('btn-info'); | ||||
}, | ||||
show: function() { | ||||
Jonathan Frederic
|
r14609 | // Called when the modal show button is clicked. | ||
Jonathan Frederic
|
r14409 | this.$show_button.addClass('btn-info'); | ||
Jonathan Frederic
|
r14425 | this.$window.show(); | ||
Jonathan Frederic
|
r14443 | if (this.popped_out) { | ||
Jonathan Frederic
|
r14466 | this.$window.css("positon", "absolute"); | ||
Jonathan Frederic
|
r14443 | this.$window.css("top", "0px"); | ||
this.$window.css("left", Math.max(0, (($('body').outerWidth() - this.$window.outerWidth()) / 2) + | ||||
$(window).scrollLeft()) + "px"); | ||||
this.bring_to_front(); | ||||
} | ||||
}, | ||||
bring_to_front: function() { | ||||
Jonathan Frederic
|
r14609 | // Make the modal top-most, z-ordered about the other modals. | ||
Jonathan Frederic
|
r14443 | var $widget_modals = $(".widget-modal"); | ||
var max_zindex = 0; | ||||
$widget_modals.each(function (index, el){ | ||||
Jonathan Frederic
|
r16955 | var zindex = parseInt($(el).css('z-index')); | ||
if (!isNaN(zindex)) { | ||||
max_zindex = Math.max(max_zindex, zindex); | ||||
} | ||||
Jonathan Frederic
|
r14443 | }); | ||
// Start z-index of widget modals at 2000 | ||||
max_zindex = Math.max(max_zindex, 2000); | ||||
Jonathan Frederic
|
r16955 | |||
Jonathan Frederic
|
r14443 | $widget_modals.each(function (index, el){ | ||
Jonathan Frederic
|
r14466 | $el = $(el); | ||
Jonathan Frederic
|
r14443 | if (max_zindex == parseInt($el.css('z-index'))) { | ||
$el.css('z-index', max_zindex - 1); | ||||
} | ||||
}); | ||||
this.$window.css('z-index', max_zindex); | ||||
Jonathan Frederic
|
r14409 | }, | ||
Jonathan Frederic
|
r14507 | update_children: function(old_list, new_list) { | ||
Jonathan Frederic
|
r14609 | // Called when the children list is modified. | ||
sylvain.corlay
|
r17349 | this.do_diff(old_list, new_list, | ||
Jonathan Frederic
|
r14598 | $.proxy(this.remove_child_model, this), | ||
$.proxy(this.add_child_model, this)); | ||||
}, | ||||
remove_child_model: function(model) { | ||||
Jonathan Frederic
|
r14609 | // Called when a child is removed from children list. | ||
Jonathan Frederic
|
r17178 | this.pop_child_view(model).remove(); | ||
Jonathan Frederic
|
r14598 | }, | ||
add_child_model: function(model) { | ||||
Jonathan Frederic
|
r14609 | // Called when a child is added to children list. | ||
Jonathan Frederic
|
r14598 | var view = this.create_child_view(model); | ||
this.$body.append(view.$el); | ||||
Jonathan Frederic
|
r16660 | |||
sylvain.corlay
|
r17353 | // Trigger the displayed event of the child view. | ||
Sylvain Corlay
|
r17329 | this.after_displayed(function() { | ||
Jonathan Frederic
|
r17179 | view.trigger('displayed'); | ||
Sylvain Corlay
|
r17271 | }); | ||
Jonathan Frederic
|
r14507 | }, | ||
Jonathan Frederic
|
r14409 | update: function(){ | ||
Jonathan Frederic
|
r14568 | // Update the contents of this view | ||
// | ||||
// Called when the model is changed. The model may have been | ||||
// changed by another view or by a state update from the back-end. | ||||
Jonathan Frederic
|
r14409 | var description = this.model.get('description'); | ||
MinRK
|
r15330 | if (description.trim().length === 0) { | ||
MinRK
|
r15329 | this.$title.html(" "); // Preserve title height | ||
Jonathan Frederic
|
r14409 | } else { | ||
Jonathan Frederic
|
r14663 | this.$title.text(description); | ||
Jonathan Frederic
|
r16817 | MathJax.Hub.Queue(["Typeset",MathJax.Hub,this.$title.get(0)]); | ||
Jonathan Frederic
|
r14409 | } | ||
var button_text = this.model.get('button_text'); | ||||
MinRK
|
r15330 | if (button_text.trim().length === 0) { | ||
MinRK
|
r15329 | this.$show_button.html(" "); // Preserve button height | ||
Jonathan Frederic
|
r14409 | } else { | ||
Jonathan Frederic
|
r14663 | this.$show_button.text(button_text); | ||
Jonathan Frederic
|
r14409 | } | ||
if (!this._shown_once) { | ||||
this._shown_once = true; | ||||
this.show(); | ||||
} | ||||
Jonathan Frederic
|
r14676 | return PopupView.__super__.update.apply(this); | ||
Jonathan Frederic
|
r14409 | }, | ||
Jonathan Frederic
|
r14419 | _get_selector_element: function(selector) { | ||
Jonathan Frederic
|
r14609 | // Get an element view a 'special' jquery selector. (see widget.js) | ||
// | ||||
Jonathan Frederic
|
r14419 | // Since the modal actually isn't within the $el in the DOM, we need to extend | ||
// the selector logic to allow the user to set css on the modal if need be. | ||||
// The convention used is: | ||||
// "modal" - select the modal div | ||||
// "modal [selector]" - select element(s) within the modal div. | ||||
// "[selector]" - select elements within $el | ||||
Jason Grout
|
r17420 | // "" - select the $el | ||
Jonathan Frederic
|
r14419 | if (selector.substring(0, 5) == 'modal') { | ||
if (selector == 'modal') { | ||||
return this.$window; | ||||
} else { | ||||
return this.$window.find(selector.substring(6)); | ||||
} | ||||
} else { | ||||
Jonathan Frederic
|
r14676 | return PopupView.__super__._get_selector_element.apply(this, [selector]); | ||
Jonathan Frederic
|
r14419 | } | ||
}, | ||||
Jonathan Frederic
|
r14409 | }); | ||
Jonathan Frederic
|
r17198 | |||
return { | ||||
Jonathan Frederic
|
r17637 | 'BoxView': BoxView, | ||
Jonathan Frederic
|
r17198 | 'PopupView': PopupView, | ||
Jonathan Frederic
|
r17637 | 'FlexBoxView': FlexBoxView, | ||
Jonathan Frederic
|
r17198 | }; | ||
Jonathan Frederic
|
r14409 | }); | ||