diff --git a/IPython/html/static/widgets/js/widget_container.js b/IPython/html/static/widgets/js/widget_container.js index e56873304..45f0cc1f5 100644 --- a/IPython/html/static/widgets/js/widget_container.js +++ b/IPython/html/static/widgets/js/widget_container.js @@ -19,7 +19,7 @@ define([ render: function(){ // Called when view is rendered. - this.$el.addClass('widget-container').addClass('vbox'); + this.$el.addClass('widget-container'); }, update_children: function(old_list, new_list) { @@ -45,6 +45,56 @@ define([ }); }, }); + + + var FlexContainerView = ContainerView.extend({ + render: function(){ + FlexContainerView.__super__.render.apply(this); + 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(); + }, + + _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')); + }, + }); + + + var VBoxContainerView = FlexContainerView.extend({ + render: function(){ + this.$el.addClass('vbox'); + FlexContainerView.__super__.render.apply(this); + }, + }); + + + var HBoxContainerView = FlexContainerView.extend({ + render: function(){ + this.$el.addClass('hbox'); + FlexContainerView.__super__.render.apply(this); + }, + }); var PopupView = widget.DOMWidgetView.extend({ @@ -279,5 +329,8 @@ define([ return { 'ContainerView': ContainerView, 'PopupView': PopupView, + 'FlexContainerView': FlexContainerView, + 'VBoxContainerView': VBoxContainerView, + 'HBoxContainerView': HBoxContainerView, }; }); diff --git a/IPython/html/widgets/__init__.py b/IPython/html/widgets/__init__.py index 7b6d0a836..42fe52215 100644 --- a/IPython/html/widgets/__init__.py +++ b/IPython/html/widgets/__init__.py @@ -2,7 +2,7 @@ from .widget import Widget, DOMWidget, CallbackDispatcher from .widget_bool import CheckboxWidget, ToggleButtonWidget from .widget_button import ButtonWidget -from .widget_container import ContainerWidget, PopupWidget +from .widget_container import ContainerWidget, PopupWidget, FlexContainerWidget, HBoxContainerWidget, VBoxContainerWidget from .widget_float import FloatTextWidget, BoundedFloatTextWidget, FloatSliderWidget, FloatProgressWidget from .widget_image import ImageWidget from .widget_int import IntTextWidget, BoundedIntTextWidget, IntSliderWidget, IntProgressWidget diff --git a/IPython/html/widgets/widget_container.py b/IPython/html/widgets/widget_container.py index 6ba8206a0..bbafdd695 100644 --- a/IPython/html/widgets/widget_container.py +++ b/IPython/html/widgets/widget_container.py @@ -7,7 +7,7 @@ Represents a container that can be used to group other widgets. # Distributed under the terms of the Modified BSD License. from .widget import DOMWidget -from IPython.utils.traitlets import Unicode, Tuple, TraitError +from IPython.utils.traitlets import Unicode, Tuple, TraitError, Int, CaselessStrEnum class ContainerWidget(DOMWidget): _view_name = Unicode('ContainerView', sync=True) @@ -32,3 +32,24 @@ class PopupWidget(ContainerWidget): description = Unicode(sync=True) button_text = Unicode(sync=True) + + +class FlexContainerWidget(ContainerWidget): + _view_name = Unicode('FlexContainerView', sync=True) + flex = Int(0, sync=True, help="""Specify the flexible-ness of the model.""") + def _flex_changed(self, name, old, new): + new = min(max(0, new), 2) + if self.flex != new: + self.flex = new + + _locations = ['start', 'center', 'end'] + pack = CaselessStrEnum(values=_locations, default_value='start', allow_none=False, sync=True) + align = CaselessStrEnum(values=_locations, default_value='start', allow_none=False, sync=True) + + +class VBoxContainerWidget(FlexContainerWidget): + _view_name = Unicode('VBoxContainerView', sync=True) + + +class HBoxContainerWidget(FlexContainerWidget): + _view_name = Unicode('HBoxContainerView', sync=True)