diff --git a/IPython/html/static/style/ipython.min.css b/IPython/html/static/style/ipython.min.css
index aa541e8..af4b463 100644
--- a/IPython/html/static/style/ipython.min.css
+++ b/IPython/html/static/style/ipython.min.css
@@ -1277,32 +1277,6 @@ div.cell.text_cell.rendered {
}
/* THE CLASSES BELOW CAN APPEAR ANYWHERE IN THE DOM (POSSIBLEY OUTSIDE OF
THE WIDGET AREA). */
-.widget-hlabel {
- /* Horizontal Label */
- min-width: 10ex;
- padding-right: 8px;
- padding-top: 5px;
- text-align: right;
- vertical-align: text-top;
-}
-.widget-vlabel {
- /* Vertical Label */
- padding-bottom: 5px;
- text-align: center;
- vertical-align: text-bottom;
-}
-.widget-hreadout {
- padding-left: 8px;
- padding-top: 5px;
- text-align: left;
- vertical-align: text-top;
-}
-.widget-vreadout {
- /* Vertical Label */
- padding-top: 5px;
- text-align: center;
- vertical-align: text-top;
-}
.slide-track {
/* Slider Track */
border: 1px solid #CCCCCC;
@@ -1522,69 +1496,11 @@ div.cell.text_cell.rendered {
/* ComboBox Main Button */
min-width: 125px;
}
-.widget-box {
- /* The following section sets the style for the invisible div that
- hold widgets and their accompanying labels.
-
- Looks like this:
- +-----------------------------+
- | widget-box (or similar) |
- | +-------+---------------+ |
- | | Label | Actual Widget | |
- | +-------+---------------+ |
- +-----------------------------+
- */
- margin: 5px;
- /* Old browsers */
- -webkit-box-pack: start;
- -moz-box-pack: start;
- box-pack: start;
- /* Modern browsers */
- justify-content: flex-start;
- /* Box */
- box-sizing: border-box;
- -moz-box-sizing: border-box;
- -webkit-box-sizing: border-box;
- /* Old browsers */
- -webkit-box-align: start;
- -moz-box-align: start;
- box-align: start;
- /* Modern browsers */
- align-items: flex-start;
+.widget_item .dropdown-menu li a {
+ color: inherit;
}
.widget-hbox {
/* Horizontal widgets */
- /* The following section sets the style for the invisible div that
- hold widgets and their accompanying labels.
-
- Looks like this:
- +-----------------------------+
- | widget-box (or similar) |
- | +-------+---------------+ |
- | | Label | Actual Widget | |
- | +-------+---------------+ |
- +-----------------------------+
- */
- margin: 5px;
- /* Old browsers */
- -webkit-box-pack: start;
- -moz-box-pack: start;
- box-pack: start;
- /* Modern browsers */
- justify-content: flex-start;
- /* Box */
- /* Old browsers */
- /* Modern browsers */
- /* Box */
- box-sizing: border-box;
- -moz-box-sizing: border-box;
- -webkit-box-sizing: border-box;
- /* Old browsers */
- -webkit-box-align: start;
- -moz-box-align: start;
- box-align: start;
- /* Modern browsers */
- align-items: flex-start;
/* Old browsers */
display: -webkit-box;
-webkit-box-orient: horizontal;
@@ -1605,99 +1521,27 @@ div.cell.text_cell.rendered {
box-flex: 0;
/* Modern browsers */
flex: none;
-}
-.widget-hbox-single {
- /* Single line horizontal widgets */
- /* Horizontal widgets */
- /* The following section sets the style for the invisible div that
- hold widgets and their accompanying labels.
-
- Looks like this:
- +-----------------------------+
- | widget-box (or similar) |
- | +-------+---------------+ |
- | | Label | Actual Widget | |
- | +-------+---------------+ |
- +-----------------------------+
- */
margin: 5px;
- /* Old browsers */
- -webkit-box-pack: start;
- -moz-box-pack: start;
- box-pack: start;
- /* Modern browsers */
- justify-content: flex-start;
- /* Box */
- /* Old browsers */
- /* Modern browsers */
- /* Box */
- box-sizing: border-box;
- -moz-box-sizing: border-box;
- -webkit-box-sizing: border-box;
- /* Old browsers */
- -webkit-box-align: start;
- -moz-box-align: start;
- box-align: start;
- /* Modern browsers */
- align-items: flex-start;
- /* Old browsers */
- display: -webkit-box;
- -webkit-box-orient: horizontal;
- -webkit-box-align: stretch;
- display: -moz-box;
- -moz-box-orient: horizontal;
- -moz-box-align: stretch;
- display: box;
- box-orient: horizontal;
- box-align: stretch;
- /* Modern browsers */
- display: flex;
- flex-direction: row;
- align-items: stretch;
- /* Old browsers */
- -webkit-box-flex: 0;
- -moz-box-flex: 0;
- box-flex: 0;
- /* Modern browsers */
- flex: none;
- height: 30px;
}
-.widget-hbox-single input[type="checkbox"] {
+.widget-hbox input[type="checkbox"] {
margin-top: 9px;
}
+.widget-hbox .widget-label {
+ /* Horizontal Label */
+ min-width: 10ex;
+ padding-right: 8px;
+ padding-top: 5px;
+ text-align: right;
+ vertical-align: text-top;
+}
+.widget-hbox .widget-readout {
+ padding-left: 8px;
+ padding-top: 5px;
+ text-align: left;
+ vertical-align: text-top;
+}
.widget-vbox {
/* Vertical widgets */
- /* The following section sets the style for the invisible div that
- hold widgets and their accompanying labels.
-
- Looks like this:
- +-----------------------------+
- | widget-box (or similar) |
- | +-------+---------------+ |
- | | Label | Actual Widget | |
- | +-------+---------------+ |
- +-----------------------------+
- */
- margin: 5px;
- /* Old browsers */
- -webkit-box-pack: start;
- -moz-box-pack: start;
- box-pack: start;
- /* Modern browsers */
- justify-content: flex-start;
- /* Box */
- /* Old browsers */
- /* Modern browsers */
- /* Box */
- box-sizing: border-box;
- -moz-box-sizing: border-box;
- -webkit-box-sizing: border-box;
- /* Old browsers */
- -webkit-box-align: start;
- -moz-box-align: start;
- box-align: start;
- /* Modern browsers */
- align-items: flex-start;
/* Old browsers */
display: -webkit-box;
-webkit-box-orient: vertical;
@@ -1719,61 +1563,17 @@ div.cell.text_cell.rendered {
/* Modern browsers */
flex: none;
}
-.widget-vbox-single {
- /* For vertical slides */
- /* Vertical widgets */
- /* The following section sets the style for the invisible div that
- hold widgets and their accompanying labels.
-
- Looks like this:
- +-----------------------------+
- | widget-box (or similar) |
- | +-------+---------------+ |
- | | Label | Actual Widget | |
- | +-------+---------------+ |
- +-----------------------------+
- */
- margin: 5px;
- /* Old browsers */
- -webkit-box-pack: start;
- -moz-box-pack: start;
- box-pack: start;
- /* Modern browsers */
- justify-content: flex-start;
- /* Box */
- /* Old browsers */
- /* Modern browsers */
- /* Box */
- box-sizing: border-box;
- -moz-box-sizing: border-box;
- -webkit-box-sizing: border-box;
- /* Old browsers */
- -webkit-box-align: start;
- -moz-box-align: start;
- box-align: start;
- /* Modern browsers */
- align-items: flex-start;
- /* Old browsers */
- display: -webkit-box;
- -webkit-box-orient: vertical;
- -webkit-box-align: stretch;
- display: -moz-box;
- -moz-box-orient: vertical;
- -moz-box-align: stretch;
- display: box;
- box-orient: vertical;
- box-align: stretch;
- /* Modern browsers */
- display: flex;
- flex-direction: column;
- align-items: stretch;
- /* Old browsers */
- -webkit-box-flex: 0;
- -moz-box-flex: 0;
- box-flex: 0;
- /* Modern browsers */
- flex: none;
- width: 30px;
+.widget-vbox .widget-label {
+ /* Vertical Label */
+ padding-bottom: 5px;
+ text-align: center;
+ vertical-align: text-bottom;
+}
+.widget-vbox .widget-readout {
+ /* Vertical Label */
+ padding-top: 5px;
+ text-align: center;
+ vertical-align: text-top;
}
.widget-modal {
/* Box - ModalView */
diff --git a/IPython/html/static/style/style.min.css b/IPython/html/static/style/style.min.css
index 41b21ce..73170c5 100644
--- a/IPython/html/static/style/style.min.css
+++ b/IPython/html/static/style/style.min.css
@@ -9049,32 +9049,6 @@ div.cell.text_cell.rendered {
}
/* THE CLASSES BELOW CAN APPEAR ANYWHERE IN THE DOM (POSSIBLEY OUTSIDE OF
THE WIDGET AREA). */
-.widget-hlabel {
- /* Horizontal Label */
- min-width: 10ex;
- padding-right: 8px;
- padding-top: 5px;
- text-align: right;
- vertical-align: text-top;
-}
-.widget-vlabel {
- /* Vertical Label */
- padding-bottom: 5px;
- text-align: center;
- vertical-align: text-bottom;
-}
-.widget-hreadout {
- padding-left: 8px;
- padding-top: 5px;
- text-align: left;
- vertical-align: text-top;
-}
-.widget-vreadout {
- /* Vertical Label */
- padding-top: 5px;
- text-align: center;
- vertical-align: text-top;
-}
.slide-track {
/* Slider Track */
border: 1px solid #CCCCCC;
@@ -9294,69 +9268,11 @@ div.cell.text_cell.rendered {
/* ComboBox Main Button */
min-width: 125px;
}
-.widget-box {
- /* The following section sets the style for the invisible div that
- hold widgets and their accompanying labels.
-
- Looks like this:
- +-----------------------------+
- | widget-box (or similar) |
- | +-------+---------------+ |
- | | Label | Actual Widget | |
- | +-------+---------------+ |
- +-----------------------------+
- */
- margin: 5px;
- /* Old browsers */
- -webkit-box-pack: start;
- -moz-box-pack: start;
- box-pack: start;
- /* Modern browsers */
- justify-content: flex-start;
- /* Box */
- box-sizing: border-box;
- -moz-box-sizing: border-box;
- -webkit-box-sizing: border-box;
- /* Old browsers */
- -webkit-box-align: start;
- -moz-box-align: start;
- box-align: start;
- /* Modern browsers */
- align-items: flex-start;
+.widget_item .dropdown-menu li a {
+ color: inherit;
}
.widget-hbox {
/* Horizontal widgets */
- /* The following section sets the style for the invisible div that
- hold widgets and their accompanying labels.
-
- Looks like this:
- +-----------------------------+
- | widget-box (or similar) |
- | +-------+---------------+ |
- | | Label | Actual Widget | |
- | +-------+---------------+ |
- +-----------------------------+
- */
- margin: 5px;
- /* Old browsers */
- -webkit-box-pack: start;
- -moz-box-pack: start;
- box-pack: start;
- /* Modern browsers */
- justify-content: flex-start;
- /* Box */
- /* Old browsers */
- /* Modern browsers */
- /* Box */
- box-sizing: border-box;
- -moz-box-sizing: border-box;
- -webkit-box-sizing: border-box;
- /* Old browsers */
- -webkit-box-align: start;
- -moz-box-align: start;
- box-align: start;
- /* Modern browsers */
- align-items: flex-start;
/* Old browsers */
display: -webkit-box;
-webkit-box-orient: horizontal;
@@ -9377,99 +9293,27 @@ div.cell.text_cell.rendered {
box-flex: 0;
/* Modern browsers */
flex: none;
-}
-.widget-hbox-single {
- /* Single line horizontal widgets */
- /* Horizontal widgets */
- /* The following section sets the style for the invisible div that
- hold widgets and their accompanying labels.
-
- Looks like this:
- +-----------------------------+
- | widget-box (or similar) |
- | +-------+---------------+ |
- | | Label | Actual Widget | |
- | +-------+---------------+ |
- +-----------------------------+
- */
margin: 5px;
- /* Old browsers */
- -webkit-box-pack: start;
- -moz-box-pack: start;
- box-pack: start;
- /* Modern browsers */
- justify-content: flex-start;
- /* Box */
- /* Old browsers */
- /* Modern browsers */
- /* Box */
- box-sizing: border-box;
- -moz-box-sizing: border-box;
- -webkit-box-sizing: border-box;
- /* Old browsers */
- -webkit-box-align: start;
- -moz-box-align: start;
- box-align: start;
- /* Modern browsers */
- align-items: flex-start;
- /* Old browsers */
- display: -webkit-box;
- -webkit-box-orient: horizontal;
- -webkit-box-align: stretch;
- display: -moz-box;
- -moz-box-orient: horizontal;
- -moz-box-align: stretch;
- display: box;
- box-orient: horizontal;
- box-align: stretch;
- /* Modern browsers */
- display: flex;
- flex-direction: row;
- align-items: stretch;
- /* Old browsers */
- -webkit-box-flex: 0;
- -moz-box-flex: 0;
- box-flex: 0;
- /* Modern browsers */
- flex: none;
- height: 30px;
}
-.widget-hbox-single input[type="checkbox"] {
+.widget-hbox input[type="checkbox"] {
margin-top: 9px;
}
+.widget-hbox .widget-label {
+ /* Horizontal Label */
+ min-width: 10ex;
+ padding-right: 8px;
+ padding-top: 5px;
+ text-align: right;
+ vertical-align: text-top;
+}
+.widget-hbox .widget-readout {
+ padding-left: 8px;
+ padding-top: 5px;
+ text-align: left;
+ vertical-align: text-top;
+}
.widget-vbox {
/* Vertical widgets */
- /* The following section sets the style for the invisible div that
- hold widgets and their accompanying labels.
-
- Looks like this:
- +-----------------------------+
- | widget-box (or similar) |
- | +-------+---------------+ |
- | | Label | Actual Widget | |
- | +-------+---------------+ |
- +-----------------------------+
- */
- margin: 5px;
- /* Old browsers */
- -webkit-box-pack: start;
- -moz-box-pack: start;
- box-pack: start;
- /* Modern browsers */
- justify-content: flex-start;
- /* Box */
- /* Old browsers */
- /* Modern browsers */
- /* Box */
- box-sizing: border-box;
- -moz-box-sizing: border-box;
- -webkit-box-sizing: border-box;
- /* Old browsers */
- -webkit-box-align: start;
- -moz-box-align: start;
- box-align: start;
- /* Modern browsers */
- align-items: flex-start;
/* Old browsers */
display: -webkit-box;
-webkit-box-orient: vertical;
@@ -9491,61 +9335,17 @@ div.cell.text_cell.rendered {
/* Modern browsers */
flex: none;
}
-.widget-vbox-single {
- /* For vertical slides */
- /* Vertical widgets */
- /* The following section sets the style for the invisible div that
- hold widgets and their accompanying labels.
-
- Looks like this:
- +-----------------------------+
- | widget-box (or similar) |
- | +-------+---------------+ |
- | | Label | Actual Widget | |
- | +-------+---------------+ |
- +-----------------------------+
- */
- margin: 5px;
- /* Old browsers */
- -webkit-box-pack: start;
- -moz-box-pack: start;
- box-pack: start;
- /* Modern browsers */
- justify-content: flex-start;
- /* Box */
- /* Old browsers */
- /* Modern browsers */
- /* Box */
- box-sizing: border-box;
- -moz-box-sizing: border-box;
- -webkit-box-sizing: border-box;
- /* Old browsers */
- -webkit-box-align: start;
- -moz-box-align: start;
- box-align: start;
- /* Modern browsers */
- align-items: flex-start;
- /* Old browsers */
- display: -webkit-box;
- -webkit-box-orient: vertical;
- -webkit-box-align: stretch;
- display: -moz-box;
- -moz-box-orient: vertical;
- -moz-box-align: stretch;
- display: box;
- box-orient: vertical;
- box-align: stretch;
- /* Modern browsers */
- display: flex;
- flex-direction: column;
- align-items: stretch;
- /* Old browsers */
- -webkit-box-flex: 0;
- -moz-box-flex: 0;
- box-flex: 0;
- /* Modern browsers */
- flex: none;
- width: 30px;
+.widget-vbox .widget-label {
+ /* Vertical Label */
+ padding-bottom: 5px;
+ text-align: center;
+ vertical-align: text-bottom;
+}
+.widget-vbox .widget-readout {
+ /* Vertical Label */
+ padding-top: 5px;
+ text-align: center;
+ vertical-align: text-top;
}
.widget-modal {
/* Box - ModalView */
diff --git a/IPython/html/static/widgets/js/widget.js b/IPython/html/static/widgets/js/widget.js
index 4aff9d5..eac8101 100644
--- a/IPython/html/static/widgets/js/widget.js
+++ b/IPython/html/static/widgets/js/widget.js
@@ -258,12 +258,12 @@ define(["widgets/js/manager",
return unpacked;
} else if (typeof value === 'string' && value.slice(0,10) === "IPY_MODEL_") {
- var model = this.widget_manager.get_model(value.slice(10, value.length));
- if (model) {
- return model;
- } else {
- return value;
- }
+ var model = this.widget_manager.get_model(value.slice(10, value.length));
+ if (model) {
+ return model;
+ } else {
+ return value;
+ }
} else {
return value;
}
@@ -427,35 +427,89 @@ define(["widgets/js/manager",
// Public constructor
DOMWidgetView.__super__.initialize.apply(this, [parameters]);
this.on('displayed', this.show, this);
+ this.model.on('change:visible', this.update_visible, this);
+ this.model.on('change:_css', this.update_css, this);
+
+ this.model.on('change:_dom_classes', function(model, new_classes) {
+ var old_classes = model.previous('_dom_classes');
+ this.update_classes(old_classes, new_classes);
+ }, this);
+
+ this.model.on('change:color', function (model, value) {
+ this.update_attr('color', value); }, this);
+
+ this.model.on('change:background_color', function (model, value) {
+ this.update_attr('background', value); }, this);
+
+ this.model.on('change:width', function (model, value) {
+ this.update_attr('width', value); }, this);
+
+ this.model.on('change:height', function (model, value) {
+ this.update_attr('height', value); }, this);
+
+ this.model.on('change:border_color', function (model, value) {
+ this.update_attr('border-color', value); }, this);
+
+ this.model.on('change:border_width', function (model, value) {
+ this.update_attr('border-width', value); }, this);
+
+ this.model.on('change:border_style', function (model, value) {
+ this.update_attr('border-style', value); }, this);
+
+ this.model.on('change:font_style', function (model, value) {
+ this.update_attr('font-style', value); }, this);
+
+ this.model.on('change:font_weight', function (model, value) {
+ this.update_attr('font-weight', value); }, this);
+
+ this.model.on('change:font_size', function (model, value) {
+ this.update_attr('font-size', this._default_px(value)); }, this);
+
+ this.model.on('change:font_family', function (model, value) {
+ this.update_attr('font-family', value); }, this);
+
+ this.model.on('change:padding', function (model, value) {
+ this.update_attr('padding', value); }, this);
+
+ this.model.on('change:margin', function (model, value) {
+ this.update_attr('margin', this._default_px(value)); }, this);
+
+ this.model.on('change:border_radius', function (model, value) {
+ this.update_attr('border-radius', this._default_px(value)); }, this);
+
this.after_displayed(function() {
this.update_visible(this.model, this.model.get("visible"));
this.update_css(this.model, this.model.get("_css"));
+
+ this.update_classes([], this.model.get('_dom_classes'));
+ this.update_attr('color', this.model.get('color'));
+ this.update_attr('background', this.model.get('background_color'));
+ this.update_attr('width', this.model.get('width'));
+ this.update_attr('height', this.model.get('height'));
+ this.update_attr('border-color', this.model.get('border_color'));
+ this.update_attr('border-width', this.model.get('border_width'));
+ this.update_attr('border-style', this.model.get('border_style'));
+ this.update_attr('font-style', this.model.get('font_style'));
+ this.update_attr('font-weight', this.model.get('font_weight'));
+ this.update_attr('font-size', this.model.get('font_size'));
+ this.update_attr('font-family', this.model.get('font_family'));
+ this.update_attr('padding', this.model.get('padding'));
+ this.update_attr('margin', this.model.get('margin'));
+ this.update_attr('border-radius', this.model.get('border_radius'));
}, this);
- this.model.on('msg:custom', this.on_msg, this);
- this.model.on('change:visible', this.update_visible, this);
- this.model.on('change:_css', this.update_css, this);
},
- on_msg: function(msg) {
- // Handle DOM specific msgs.
- switch(msg.msg_type) {
- case 'add_class':
- this.add_class(msg.selector, msg.class_list);
- break;
- case 'remove_class':
- this.remove_class(msg.selector, msg.class_list);
- break;
+ _default_px: function(value) {
+ // Makes browser interpret a numerical string as a pixel value.
+ if (/^\d+\.?(\d+)?$/.test(value.trim())) {
+ return value.trim() + 'px';
}
+ return value;
},
- add_class: function (selector, class_list) {
- // Add a DOM class to an element.
- this._get_selector_element(selector).addClass(class_list);
- },
-
- remove_class: function (selector, class_list) {
- // Remove a DOM class from an element.
- this._get_selector_element(selector).removeClass(class_list);
+ update_attr: function(name, value) {
+ // Set a css attr of the widget view.
+ this.$el.css(name, value);
},
update_visible: function(model, value) {
@@ -479,6 +533,54 @@ define(["widgets/js/manager",
}
},
+ update_classes: function (old_classes, new_classes, $el) {
+ // Update the DOM classes applied to an element, default to this.$el.
+ if ($el===undefined) {
+ $el = this.$el;
+ }
+ this.do_diff(old_classes, new_classes, function(removed) {
+ $el.removeClass(removed);
+ }, function(added) {
+ $el.addClass(added);
+ });
+ },
+
+ update_mapped_classes: function(class_map, trait_name, previous_trait_value, $el) {
+ // Update the DOM classes applied to the widget based on a single
+ // trait's value.
+ //
+ // Given a trait value classes map, this function automatically
+ // handles applying the appropriate classes to the widget element
+ // and removing classes that are no longer valid.
+ //
+ // Parameters
+ // ----------
+ // class_map: dictionary
+ // Dictionary of trait values to class lists.
+ // Example:
+ // {
+ // success: ['alert', 'alert-success'],
+ // info: ['alert', 'alert-info'],
+ // warning: ['alert', 'alert-warning'],
+ // danger: ['alert', 'alert-danger']
+ // };
+ // trait_name: string
+ // Name of the trait to check the value of.
+ // previous_trait_value: optional string, default ''
+ // Last trait value
+ // $el: optional jQuery element handle, defaults to this.$el
+ // Element that the classes are applied to.
+ var key = previous_trait_value;
+ if (key === undefined) {
+ key = this.model.previous(trait_name);
+ }
+ var old_classes = class_map[key] ? class_map[key] : [];
+ key = this.model.get(trait_name);
+ var new_classes = class_map[key] ? class_map[key] : [];
+
+ this.update_classes(old_classes, new_classes, $el || this.$el);
+ },
+
_get_selector_element: function (selector) {
// Get the elements via the css selector.
var elements;
diff --git a/IPython/html/static/widgets/js/widget_bool.js b/IPython/html/static/widgets/js/widget_bool.js
index 83af9d4..e9cbb2d 100644
--- a/IPython/html/static/widgets/js/widget_bool.js
+++ b/IPython/html/static/widgets/js/widget_bool.js
@@ -11,9 +11,9 @@ define([
render : function(){
// Called when view is rendered.
this.$el
- .addClass('widget-hbox-single');
+ .addClass('widget-hbox');
this.$label = $('
')
- .addClass('widget-hlabel')
+ .addClass('widget-label')
.appendTo(this.$el)
.hide();
this.$checkbox = $(' ')
@@ -24,6 +24,11 @@ define([
this.update(); // Set defaults.
},
+ update_attr: function(name, value) {
+ // Set a css attr of the widget view.
+ this.$checkbox.css(name, value);
+ },
+
handle_click: function() {
// Handles when the checkbox is clicked.
@@ -72,8 +77,24 @@ define([
that.handle_click();
}));
+ this.model.on('change:button_style', function(model, value) {
+ this.update_button_style();
+ }, this);
+ this.update_button_style('');
+
this.update(); // Set defaults.
},
+
+ update_button_style: function(previous_trait_value) {
+ var class_map = {
+ primary: ['btn-primary'],
+ success: ['btn-success'],
+ info: ['btn-info'],
+ warning: ['btn-warning'],
+ danger: ['btn-danger']
+ };
+ this.update_mapped_classes(class_map, 'button_style', previous_trait_value);
+ },
update : function(options){
// Update the contents of this view
diff --git a/IPython/html/static/widgets/js/widget_box.js b/IPython/html/static/widgets/js/widget_box.js
index a1e97fe..be54fab 100644
--- a/IPython/html/static/widgets/js/widget_box.js
+++ b/IPython/html/static/widgets/js/widget_box.js
@@ -14,6 +14,20 @@ define([
this.model.on('change:children', function(model, value) {
this.update_children(model.previous('children'), value);
}, this);
+ this.model.on('change:overflow_x', function(model, value) {
+ this.update_overflow_x();
+ }, this);
+ this.model.on('change:overflow_y', function(model, value) {
+ this.update_overflow_y();
+ }, this);
+ this.model.on('change:box_style', function(model, value) {
+ this.update_box_style();
+ }, this);
+ },
+
+ update_attr: function(name, value) {
+ // Set a css attr of the widget view.
+ this.$box.css(name, value);
},
render: function(){
@@ -21,6 +35,29 @@ define([
this.$box = this.$el;
this.$box.addClass('widget-box');
this.update_children([], this.model.get('children'));
+ this.update_overflow_x();
+ this.update_overflow_y();
+ this.update_box_style('');
+ },
+
+ update_overflow_x: function() {
+ // Called when the x-axis overflow setting is changed.
+ this.$box.css('overflow-x', this.model.get('overflow_x'));
+ },
+
+ update_overflow_y: function() {
+ // Called when the y-axis overflow setting is changed.
+ this.$box.css('overflow-y', this.model.get('overflow_y'));
+ },
+
+ update_box_style: function(previous_trait_value) {
+ var class_map = {
+ success: ['alert', 'alert-success'],
+ info: ['alert', 'alert-info'],
+ warning: ['alert', 'alert-warning'],
+ danger: ['alert', 'alert-danger']
+ };
+ this.update_mapped_classes(class_map, 'box_style', previous_trait_value, this.$box);
},
update_children: function(old_list, new_list) {
@@ -142,8 +179,8 @@ define([
that.popped_out = !that.popped_out;
if (!that.popped_out) {
that.$minimize
- .removeClass('fa fa-arrow-down')
- .addClass('fa fa-arrow-up');
+ .removeClass('fa-arrow-down')
+ .addClass('fa-arrow-up');
that.$window
.draggable('destroy')
@@ -156,8 +193,8 @@ define([
that.$close.hide();
} else {
that.$minimize
- .addClass('fa fa-arrow-down')
- .removeClass('fa fa-arrow-up');
+ .addClass('fa-arrow-down')
+ .removeClass('fa-arrow-up');
that.$window
.removeClass('docked-widget-modal')
diff --git a/IPython/html/static/widgets/js/widget_button.js b/IPython/html/static/widgets/js/widget_button.js
index 3ff7c23..ddae4d8 100644
--- a/IPython/html/static/widgets/js/widget_button.js
+++ b/IPython/html/static/widgets/js/widget_button.js
@@ -13,6 +13,11 @@ define([
this.setElement($(" ")
.addClass('btn btn-default'));
+ this.model.on('change:button_style', function(model, value) {
+ this.update_button_style();
+ }, this);
+ this.update_button_style('');
+
this.update(); // Set defaults.
},
@@ -37,6 +42,17 @@ define([
return ButtonView.__super__.update.apply(this);
},
+ update_button_style: function(previous_trait_value) {
+ var class_map = {
+ primary: ['btn-primary'],
+ success: ['btn-success'],
+ info: ['btn-info'],
+ warning: ['btn-warning'],
+ danger: ['btn-danger']
+ };
+ this.update_mapped_classes(class_map, 'button_style', previous_trait_value);
+ },
+
events: {
// Dictionary of events and their handlers.
'click': '_handle_click',
diff --git a/IPython/html/static/widgets/js/widget_int.js b/IPython/html/static/widgets/js/widget_int.js
index c8a736b..48566c5 100644
--- a/IPython/html/static/widgets/js/widget_int.js
+++ b/IPython/html/static/widgets/js/widget_int.js
@@ -11,10 +11,10 @@ define([
render : function(){
// Called when view is rendered.
this.$el
- .addClass('widget-hbox-single');
+ .addClass('widget-hbox');
this.$label = $('
')
.appendTo(this.$el)
- .addClass('widget-hlabel')
+ .addClass('widget-label')
.hide();
this.$slider = $('
')
@@ -28,12 +28,33 @@ define([
this.$readout = $('
')
.appendTo(this.$el)
- .addClass('widget-hreadout')
+ .addClass('widget-readout')
.hide();
+
+ this.model.on('change:slider_color', function(sender, value) {
+ this.$slider.find('a').css('background', value);
+ }, this);
+ this.$slider.find('a').css('background', this.model.get('slider_color'));
// Set defaults.
this.update();
},
+
+ update_attr: function(name, value) {
+ // Set a css attr of the widget view.
+ if (name == 'color') {
+ this.$readout.css(name, value);
+ } else if (name.substring(0, 4) == 'font') {
+ this.$readout.css(name, value);
+ } else if (name.substring(0, 6) == 'border') {
+ this.$slider.find('a').css(name, value);
+ this.$slider_container.css(name, value);
+ } else if (name == 'width' || name == 'height' || name == 'background') {
+ this.$slider_container.css(name, value);
+ } else {
+ this.$slider.css(name, value);
+ }
+ },
update : function(options){
// Update the contents of this view
@@ -102,28 +123,16 @@ define([
.removeClass('widget-hslider')
.addClass('widget-vslider');
this.$el
- .removeClass('widget-hbox-single')
- .addClass('widget-vbox-single');
- this.$label
- .removeClass('widget-hlabel')
- .addClass('widget-vlabel');
- this.$readout
- .removeClass('widget-hreadout')
- .addClass('widget-vreadout');
+ .removeClass('widget-hbox')
+ .addClass('widget-vbox');
} else {
this.$slider_container
.removeClass('widget-vslider')
.addClass('widget-hslider');
this.$el
- .removeClass('widget-vbox-single')
- .addClass('widget-hbox-single');
- this.$label
- .removeClass('widget-vlabel')
- .addClass('widget-hlabel');
- this.$readout
- .removeClass('widget-vreadout')
- .addClass('widget-hreadout');
+ .removeClass('widget-vbox')
+ .addClass('widget-hbox');
}
var description = this.model.get('description');
@@ -180,10 +189,10 @@ define([
render : function(){
// Called when view is rendered.
this.$el
- .addClass('widget-hbox-single');
+ .addClass('widget-hbox');
this.$label = $('
')
.appendTo(this.$el)
- .addClass('widget-hlabel')
+ .addClass('widget-label')
.hide();
this.$textbox = $(' ')
.addClass('form-control')
@@ -221,6 +230,11 @@ define([
return IntTextView.__super__.update.apply(this);
},
+ update_attr: function(name, value) {
+ // Set a css attr of the widget view.
+ this.$textbox.css(name, value);
+ },
+
events: {
// Dictionary of events and their handlers.
"keyup input" : "handleChanging",
@@ -283,10 +297,10 @@ define([
render : function(){
// Called when view is rendered.
this.$el
- .addClass('widget-hbox-single');
+ .addClass('widget-hbox');
this.$label = $('
')
.appendTo(this.$el)
- .addClass('widget-hlabel')
+ .addClass('widget-label')
.hide();
this.$progress = $('
')
.addClass('progress')
@@ -297,6 +311,11 @@ define([
.css('width', '50%')
.appendTo(this.$progress);
this.update(); // Set defaults.
+
+ this.model.on('change:bar_style', function(model, value) {
+ this.update_bar_style();
+ }, this);
+ this.update_bar_style('');
},
update : function(){
@@ -320,6 +339,30 @@ define([
}
return ProgressView.__super__.update.apply(this);
},
+
+ update_bar_style: function(previous_trait_value) {
+ var class_map = {
+ success: ['progress-bar-success'],
+ info: ['progress-bar-info'],
+ warning: ['progress-bar-warning'],
+ danger: ['progress-bar-danger']
+ };
+ this.update_mapped_classes(class_map, 'bar_style', previous_trait_value, this.$bar);
+ },
+
+ update_attr: function(name, value) {
+ // Set a css attr of the widget view.
+ if (name.substring(0, 6) == 'border' || name == 'width' ||
+ name == 'height' || name == 'background' || name == 'margin' ||
+ name == 'padding') {
+
+ this.$progress.css(name, value);
+ } else if (name == 'color') {
+ this.$bar.css('background', value);
+ } else {
+ this.$bar.css(name, value);
+ }
+ },
});
return {
diff --git a/IPython/html/static/widgets/js/widget_selection.js b/IPython/html/static/widgets/js/widget_selection.js
index 3922dc9..cf32ac2 100644
--- a/IPython/html/static/widgets/js/widget_selection.js
+++ b/IPython/html/static/widgets/js/widget_selection.js
@@ -12,10 +12,10 @@ define([
render : function(){
// Called when view is rendered.
this.$el
- .addClass('widget-hbox-single');
+ .addClass('widget-hbox');
this.$label = $('
')
.appendTo(this.$el)
- .addClass('widget-hlabel')
+ .addClass('widget-label')
.hide();
this.$buttongroup = $('
')
.addClass('widget_item')
@@ -36,6 +36,11 @@ define([
this.$droplist = $('')
.addClass('dropdown-menu')
.appendTo(this.$buttongroup);
+
+ this.model.on('change:button_style', function(model, value) {
+ this.update_button_style();
+ }, this);
+ this.update_button_style('');
// Set defaults.
this.update();
@@ -58,6 +63,8 @@ define([
var items = this.model.get('value_names');
var $replace_droplist = $('')
.addClass('dropdown-menu');
+ // Copy the style
+ $replace_droplist.attr('style', this.$droplist.attr('style'));
var that = this;
_.each(items, function(item, i) {
var item_button = $(' ')
@@ -94,6 +101,41 @@ define([
return DropdownView.__super__.update.apply(this);
},
+ update_button_style: function(previous_trait_value) {
+ var class_map = {
+ primary: ['btn-primary'],
+ success: ['btn-success'],
+ info: ['btn-info'],
+ warning: ['btn-warning'],
+ danger: ['btn-danger']
+ };
+ this.update_mapped_classes(class_map, 'button_style', previous_trait_value, this.$droplabel);
+ this.update_mapped_classes(class_map, 'button_style', previous_trait_value, this.$dropbutton);
+ },
+
+ update_attr: function(name, value) {
+ // Set a css attr of the widget view.
+ if (name.substring(0, 6) == 'border' || name == 'background' || name == 'color') {
+ this.$droplabel.css(name, value);
+ this.$dropbutton.css(name, value);
+ this.$droplist.css(name, value);
+ } else if (name == 'width') {
+ this.$droplist.css(name, value);
+ this.$droplabel.css(name, value);
+ } else if (name == 'padding') {
+ this.$droplist.css(name, value);
+ this.$buttongroup.css(name, value);
+ } else if (name == 'margin') {
+ this.$buttongroup.css(name, value);
+ } else if (name == 'height') {
+ this.$droplabel.css(name, value);
+ this.$dropbutton.css(name, value);
+ } else {
+ this.$droplist.css(name, value);
+ this.$droplabel.css(name, value);
+ }
+ },
+
handle_click: function (e) {
// Handle when a value is clicked.
@@ -113,7 +155,7 @@ define([
.addClass('widget-hbox');
this.$label = $('
')
.appendTo(this.$el)
- .addClass('widget-hlabel')
+ .addClass('widget-label')
.hide();
this.$container = $('
')
.appendTo(this.$el)
@@ -184,6 +226,11 @@ define([
return RadioButtonsView.__super__.update.apply(this);
},
+ update_attr: function(name, value) {
+ // Set a css attr of the widget view.
+ this.$container.css(name, value);
+ },
+
handle_click: function (e) {
// Handle when a value is clicked.
@@ -196,18 +243,28 @@ define([
var ToggleButtonsView = widget.DOMWidgetView.extend({
- render : function(){
+ initialize: function() {
+ this._css_state = {};
+ ToggleButtonsView.__super__.initialize.apply(this, arguments);
+ },
+
+ render: function() {
// Called when view is rendered.
this.$el
- .addClass('widget-hbox-single');
+ .addClass('widget-hbox');
this.$label = $('
')
.appendTo(this.$el)
- .addClass('widget-hlabel')
+ .addClass('widget-label')
.hide();
this.$buttongroup = $('
')
.addClass('btn-group')
.attr('data-toggle', 'buttons-radio')
.appendTo(this.$el);
+
+ this.model.on('change:button_style', function(model, value) {
+ this.update_button_style();
+ }, this);
+ this.update_button_style('');
this.update();
},
@@ -238,6 +295,7 @@ define([
.appendTo(that.$buttongroup)
.attr('data-value', item)
.on('click', $.proxy(that.handle_click, that));
+ that.update_style_traits($item_element);
}
if (that.model.get('value_name') == item) {
$item_element.addClass('active');
@@ -275,6 +333,39 @@ define([
return ToggleButtonsView.__super__.update.apply(this);
},
+ update_attr: function(name, value) {
+ // Set a css attr of the widget view.
+ this._css_state[name] = value;
+ this.update_style_traits();
+ },
+
+ update_style_traits: function(button) {
+ for (var name in this._css_state) {
+ if (this._css_state.hasOwnProperty(name)) {
+ if (name == 'margin') {
+ this.$buttongroup.css(name, this._css_state[name]);
+ } else if (name != 'width') {
+ if (button) {
+ button.css(name, this._css_state[name]);
+ } else {
+ this.$buttongroup.find('button').css(name, this._css_state[name]);
+ }
+ }
+ }
+ }
+ },
+
+ update_button_style: function(previous_trait_value) {
+ var class_map = {
+ primary: ['btn-primary'],
+ success: ['btn-success'],
+ info: ['btn-info'],
+ warning: ['btn-warning'],
+ danger: ['btn-danger']
+ };
+ this.update_mapped_classes(class_map, 'button_style', previous_trait_value, this.$buttongroup.find('button'));
+ },
+
handle_click: function (e) {
// Handle when a value is clicked.
@@ -293,7 +384,7 @@ define([
.addClass('widget-hbox');
this.$label = $('
')
.appendTo(this.$el)
- .addClass('widget-hlabel')
+ .addClass('widget-label')
.hide();
this.$listbox = $(' ')
.addClass('widget-listbox form-control')
@@ -357,6 +448,11 @@ define([
return SelectView.__super__.update.apply(this);
},
+ update_attr: function(name, value) {
+ // Set a css attr of the widget view.
+ this.$listbox.css(name, value);
+ },
+
handle_click: function (e) {
// Handle when a value is clicked.
diff --git a/IPython/html/static/widgets/js/widget_selectioncontainer.js b/IPython/html/static/widgets/js/widget_selectioncontainer.js
index ed6bfe2..4ed19c2 100644
--- a/IPython/html/static/widgets/js/widget_selectioncontainer.js
+++ b/IPython/html/static/widgets/js/widget_selectioncontainer.js
@@ -152,6 +152,11 @@ define([
}, this);
},
+ update_attr: function(name, value) {
+ // Set a css attr of the widget view.
+ this.$tabs.css(name, value);
+ },
+
update_children: function(old_list, new_list) {
// Called when the children list is modified.
this.do_diff(old_list,
diff --git a/IPython/html/static/widgets/js/widget_string.js b/IPython/html/static/widgets/js/widget_string.js
index 037d3be..b571552 100644
--- a/IPython/html/static/widgets/js/widget_string.js
+++ b/IPython/html/static/widgets/js/widget_string.js
@@ -50,7 +50,7 @@ define([
.addClass('widget-hbox');
this.$label = $('
')
.appendTo(this.$el)
- .addClass('widget-hlabel')
+ .addClass('widget-label')
.hide();
this.$textbox = $('')
.attr('rows', 5)
@@ -107,6 +107,11 @@ define([
}
return TextareaView.__super__.update.apply(this);
},
+
+ update_attr: function(name, value) {
+ // Set a css attr of the widget view.
+ this.$textbox.css(name, value);
+ },
events: {
// Dictionary of events and their handlers.
@@ -130,9 +135,9 @@ define([
render: function(){
// Called when view is rendered.
this.$el
- .addClass('widget-hbox-single');
+ .addClass('widget-hbox');
this.$label = $('
')
- .addClass('widget-hlabel')
+ .addClass('widget-label')
.appendTo(this.$el)
.hide();
this.$textbox = $(' ')
@@ -178,6 +183,11 @@ define([
}
return TextView.__super__.update.apply(this);
},
+
+ update_attr: function(name, value) {
+ // Set a css attr of the widget view.
+ this.$textbox.css(name, value);
+ },
events: {
// Dictionary of events and their handlers.
diff --git a/IPython/html/static/widgets/less/widgets.less b/IPython/html/static/widgets/less/widgets.less
index c26aa27..5a49516 100644
--- a/IPython/html/static/widgets/less/widgets.less
+++ b/IPython/html/static/widgets/less/widgets.less
@@ -31,36 +31,6 @@
/* THE CLASSES BELOW CAN APPEAR ANYWHERE IN THE DOM (POSSIBLEY OUTSIDE OF
THE WIDGET AREA). */
-.widget-hlabel {
- /* Horizontal Label */
- min-width : 10ex;
- padding-right : 8px;
- padding-top : 5px;
- text-align : right;
- vertical-align : text-top;
-}
-
-.widget-vlabel {
- /* Vertical Label */
- padding-bottom : 5px;
- text-align : center;
- vertical-align : text-bottom;
-}
-
-.widget-hreadout {
- padding-left : 8px;
- padding-top : 5px;
- text-align : left;
- vertical-align : text-top;
-}
-
-.widget-vreadout {
- /* Vertical Label */
- padding-top : 5px;
- text-align : center;
- vertical-align : text-top;
-}
-
.slide-track {
/* Slider Track */
border : 1px solid #CCCCCC;
@@ -211,50 +181,55 @@
min-width : 125px;
}
-.widget-box {
- /* The following section sets the style for the invisible div that
- hold widgets and their accompanying labels.
-
- Looks like this:
- +-----------------------------+
- | widget-box (or similar) |
- | +-------+---------------+ |
- | | Label | Actual Widget | |
- | +-------+---------------+ |
- +-----------------------------+
- */
- margin : 5px;
-
- .start();
- .widget-box();
+.widget_item .dropdown-menu li a {
+ color: inherit;
}
.widget-hbox {
/* Horizontal widgets */
- .widget-box();
.hbox();
-}
-
-.widget-hbox-single {
- /* Single line horizontal widgets */
- .widget-hbox();
- height : 30px;
+ margin: 5px;
input[type="checkbox"] {
margin-top: 9px;
}
+
+ .widget-label {
+ /* Horizontal Label */
+ min-width : 10ex;
+ padding-right : 8px;
+ padding-top : 5px;
+ text-align : right;
+ vertical-align : text-top;
+ }
+
+ .widget-readout {
+ padding-left : 8px;
+ padding-top : 5px;
+ text-align : left;
+ vertical-align : text-top;
+ }
}
.widget-vbox {
/* Vertical widgets */
- .widget-box();
.vbox();
-}
-.widget-vbox-single {
- /* For vertical slides */
- .widget-vbox();
- width : 30px;
+
+ .widget-label {
+ /* Vertical Label */
+ padding-bottom : 5px;
+ text-align : center;
+ vertical-align : text-bottom;
+ }
+
+ .widget-readout {
+ /* Vertical Label */
+ padding-top : 5px;
+ text-align : center;
+ vertical-align : text-top;
+ }
+
}
.widget-modal {
@@ -296,4 +271,4 @@
top: 0px !important;
left: 0px !important;
margin-left: 0px !important;
-}
\ No newline at end of file
+}
diff --git a/IPython/html/tests/widgets/widget.js b/IPython/html/tests/widgets/widget.js
index 005d75e..9364f03 100644
--- a/IPython/html/tests/widgets/widget.js
+++ b/IPython/html/tests/widgets/widget.js
@@ -149,7 +149,7 @@ casper.notebook_test(function () {
'import time\n' +
'textbox = widgets.Text()\n' +
'display(textbox)\n' +
- 'textbox.add_class("my-throttle-textbox", selector="input")\n' +
+ 'textbox._dom_classes = ["my-throttle-textbox"]\n' +
'def handle_change(name, old, new):\n' +
' display(len(new))\n' +
' time.sleep(0.5)\n' +
@@ -166,7 +166,7 @@ casper.notebook_test(function () {
'.my-throttle-textbox'), 'Textbox exists.');
// Send 20 characters
- this.sendKeys('.my-throttle-textbox', '....................');
+ this.sendKeys('.my-throttle-textbox input', '....................');
});
this.wait_for_widget(textbox);
diff --git a/IPython/html/tests/widgets/widget_bool.js b/IPython/html/tests/widgets/widget_bool.js
index 0fe80b9..35e755b 100644
--- a/IPython/html/tests/widgets/widget_bool.js
+++ b/IPython/html/tests/widgets/widget_bool.js
@@ -22,19 +22,19 @@ casper.notebook_test(function () {
'Widget subarea exists.');
this.test.assert(this.cell_element_exists(index,
- '.widget-area .widget-subarea .widget-hbox-single input'),
+ '.widget-area .widget-subarea .widget-hbox input'),
'Checkbox exists.');
this.test.assert(this.cell_element_function(index,
- '.widget-area .widget-subarea .widget-hbox-single input', 'prop', ['checked']),
+ '.widget-area .widget-subarea .widget-hbox input', 'prop', ['checked']),
'Checkbox is checked.');
this.test.assert(this.cell_element_exists(index,
- '.widget-area .widget-subarea .widget-hbox-single .widget-hlabel'),
+ '.widget-area .widget-subarea .widget-hbox .widget-label'),
'Checkbox label exists.');
this.test.assert(this.cell_element_function(index,
- '.widget-area .widget-subarea .widget-hbox-single .widget-hlabel', 'html')=="Title",
+ '.widget-area .widget-subarea .widget-hbox .widget-label', 'html')=="Title",
'Checkbox labeled correctly.');
this.test.assert(this.cell_element_exists(index,
@@ -61,7 +61,7 @@ casper.notebook_test(function () {
'Change bool widget value cell executed with correct output.');
this.test.assert(! this.cell_element_function(bool_index,
- '.widget-area .widget-subarea .widget-hbox-single input', 'prop', ['checked']),
+ '.widget-area .widget-subarea .widget-hbox input', 'prop', ['checked']),
'Checkbox is not checked. (1)');
this.test.assert(! this.cell_element_function(bool_index,
@@ -69,10 +69,10 @@ casper.notebook_test(function () {
'Toggle button is not toggled. (1)');
// Try toggling the bool by clicking on the checkbox.
- this.cell_element_function(bool_index, '.widget-area .widget-subarea .widget-hbox-single input', 'click');
+ this.cell_element_function(bool_index, '.widget-area .widget-subarea .widget-hbox input', 'click');
this.test.assert(this.cell_element_function(bool_index,
- '.widget-area .widget-subarea .widget-hbox-single input', 'prop', ['checked']),
+ '.widget-area .widget-subarea .widget-hbox input', 'prop', ['checked']),
'Checkbox is checked. (2)');
// Try toggling the bool by clicking on the toggle button.
diff --git a/IPython/html/tests/widgets/widget_box.js b/IPython/html/tests/widgets/widget_box.js
index c1b422a..6e1f242 100644
--- a/IPython/html/tests/widgets/widget_box.js
+++ b/IPython/html/tests/widgets/widget_box.js
@@ -11,7 +11,7 @@ casper.notebook_test(function () {
'button = widgets.Button()\n'+
'container.children = [button]\n'+
'display(container)\n'+
- 'container.add_class("my-test-class")\n'+
+ 'container._dom_classes = ["my-test-class"]\n'+
'print("Success")\n');
this.execute_cell_then(container_index, function(index){
@@ -28,7 +28,7 @@ casper.notebook_test(function () {
this.test.assert(this.cell_element_exists(index,
'.widget-area .widget-subarea .my-test-class'),
- 'add_class works.');
+ '_dom_classes works.');
this.test.assert(this.cell_element_exists(index,
'.widget-area .widget-subarea .my-test-class button'),
@@ -36,20 +36,20 @@ casper.notebook_test(function () {
});
index = this.append_cell(
- 'container.set_css("float", "right")\n'+
+ 'container.box_style = "success"\n'+
'print("Success")\n');
this.execute_cell_then(index, function(index){
this.test.assertEquals(this.get_output_cell(index).text, 'Success\n',
- 'Set container class CSS cell executed with correct output.');
-
- this.test.assert(this.cell_element_function(container_index,
- '.widget-area .widget-subarea .my-test-class', 'css', ['float'])=='right',
- 'set_css works.');
+ 'Set box_style cell executed with correct output.');
+
+ this.test.assert(this.cell_element_exists(container_index,
+ '.widget-box.alert-success'),
+ 'Set box_style works.');
});
index = this.append_cell(
- 'container.remove_class("my-test-class")\n'+
+ 'container._dom_classes = []\n'+
'print("Success")\n');
this.execute_cell_then(index, function(index){
@@ -58,7 +58,7 @@ casper.notebook_test(function () {
this.test.assert(! this.cell_element_exists(container_index,
'.widget-area .widget-subarea .my-test-class'),
- 'remove_class works.');
+ '_dom_classes can be used to remove a class.');
});
index = this.append_cell(
diff --git a/IPython/html/tests/widgets/widget_float.js b/IPython/html/tests/widgets/widget_float.js
index a2f4e74..291efb3 100644
--- a/IPython/html/tests/widgets/widget_float.js
+++ b/IPython/html/tests/widgets/widget_float.js
@@ -7,11 +7,11 @@ casper.notebook_test(function () {
this.execute_cell_then(index);
var float_text = {};
- float_text.query = '.widget-area .widget-subarea .widget-hbox-single .my-second-float-text';
+ float_text.query = '.widget-area .widget-subarea .my-second-float-text input';
float_text.index = this.append_cell(
'float_widget = widgets.FloatText()\n' +
'display(float_widget)\n' +
- 'float_widget.add_class("my-second-float-text", selector="input")\n' +
+ 'float_widget._dom_classes = ["my-second-float-text"]\n' +
'print(float_widget.model_id)\n');
this.execute_cell_then(float_text.index, function(index){
float_text.model_id = this.get_output_cell(index).text.trim();
@@ -55,9 +55,9 @@ casper.notebook_test(function () {
'Invald float textbox value caught and filtered.');
});
- var float_text_query = '.widget-area .widget-subarea .widget-hbox-single .widget-numeric-text';
+ var float_text_query = '.widget-area .widget-subarea .widget-numeric-text';
var slider = {};
- slider.query = '.widget-area .widget-subarea .widget-hbox-single .slider';
+ slider.query = '.widget-area .widget-subarea .slider';
slider.index = this.append_cell(
'floatrange = [widgets.BoundedFloatText(), \n' +
' widgets.FloatSlider()]\n' +
diff --git a/IPython/html/tests/widgets/widget_image.js b/IPython/html/tests/widgets/widget_image.js
index c858c68..ba10d35 100644
--- a/IPython/html/tests/widgets/widget_image.js
+++ b/IPython/html/tests/widgets/widget_image.js
@@ -23,11 +23,7 @@ casper.notebook_test(function () {
'image.value = data\n' +
'image.width = "50px"\n' +
'image.height = "50px"\n' +
- // Set css that will make the image render within the PhantomJS visible
- // window. If we don't do this, the captured image will be black.
- 'image.set_css({"background": "blue", "z-index": "9999", "position": "fixed", "top": "0px", "left": "0px"})\n' +
'display(image)\n' +
- 'image.add_class("my-test-image")\n' +
'print("Success")\n');
this.execute_cell_then(image_index, function(index){
diff --git a/IPython/html/tests/widgets/widget_int.js b/IPython/html/tests/widgets/widget_int.js
index a9bc43d..409dfb6 100644
--- a/IPython/html/tests/widgets/widget_int.js
+++ b/IPython/html/tests/widgets/widget_int.js
@@ -7,11 +7,11 @@ casper.notebook_test(function () {
this.execute_cell_then(index);
var int_text = {};
- int_text.query = '.widget-area .widget-subarea .widget-hbox-single .my-second-int-text';
+ int_text.query = '.widget-area .widget-subarea .my-second-int-text input';
int_text.index = this.append_cell(
'int_widget = widgets.IntText()\n' +
'display(int_widget)\n' +
- 'int_widget.add_class("my-second-int-text", selector="input")\n' +
+ 'int_widget._dom_classes = ["my-second-int-text"]\n' +
'print(int_widget.model_id)\n');
this.execute_cell_then(int_text.index, function(index){
int_text.model_id = this.get_output_cell(index).text.trim();
@@ -62,14 +62,14 @@ casper.notebook_test(function () {
this.execute_cell_then(index);
- var slider_query = '.widget-area .widget-subarea .widget-hbox-single .slider';
+ var slider_query = '.widget-area .widget-subarea .slider';
var int_text2 = {};
- int_text2.query = '.widget-area .widget-subarea .widget-hbox-single .my-second-num-test-text';
+ int_text2.query = '.widget-area .widget-subarea .my-second-num-test-text input';
int_text2.index = this.append_cell(
'intrange = [widgets.BoundedIntTextWidget(),\n' +
' widgets.IntSliderWidget()]\n' +
'[display(intrange[i]) for i in range(2)]\n' +
- 'intrange[0].add_class("my-second-num-test-text", selector="input")\n' +
+ 'intrange[0]._dom_classes = ["my-second-num-test-text"]\n' +
'print(intrange[0].model_id)\n');
this.execute_cell_then(int_text2.index, function(index){
int_text2.model_id = this.get_output_cell(index).text.trim();
diff --git a/IPython/html/tests/widgets/widget_selection.js b/IPython/html/tests/widgets/widget_selection.js
index dac47e0..e4e4524 100644
--- a/IPython/html/tests/widgets/widget_selection.js
+++ b/IPython/html/tests/widgets/widget_selection.js
@@ -6,8 +6,8 @@ casper.notebook_test(function () {
'print("Success")');
this.execute_cell_then(index);
- var combo_selector = '.widget-area .widget-subarea .widget-hbox-single .btn-group .widget-combo-btn';
- var multibtn_selector = '.widget-area .widget-subarea .widget-hbox-single .btn-group[data-toggle="buttons-radio"]';
+ var combo_selector = '.widget-area .widget-subarea .widget-hbox .btn-group .widget-combo-btn';
+ var multibtn_selector = '.widget-area .widget-subarea .widget-hbox .btn-group[data-toggle="buttons-radio"]';
var radio_selector = '.widget-area .widget-subarea .widget-hbox .widget-radio-box';
var list_selector = '.widget-area .widget-subarea .widget-hbox .widget-listbox';
@@ -115,7 +115,7 @@ casper.notebook_test(function () {
this.test.assert(verify_selection(this, 3), 'Multibutton selection updated view states correctly.');
// Verify that selecting a combobox option updates all of the others.
- this.cell_element_function(selection_index, '.widget-area .widget-subarea .widget-hbox-single .btn-group ul.dropdown-menu li:nth-child(3) a', 'click');
+ this.cell_element_function(selection_index, '.widget-area .widget-subarea .widget-hbox .btn-group ul.dropdown-menu li:nth-child(3) a', 'click');
});
this.wait_for_idle();
this.then(function () {
diff --git a/IPython/html/tests/widgets/widget_string.js b/IPython/html/tests/widgets/widget_string.js
index 8e9acee..54e669d 100644
--- a/IPython/html/tests/widgets/widget_string.js
+++ b/IPython/html/tests/widgets/widget_string.js
@@ -23,7 +23,7 @@ casper.notebook_test(function () {
'Widget subarea exists.');
this.test.assert(this.cell_element_exists(index,
- '.widget-area .widget-subarea .widget-hbox-single input[type=text]'),
+ '.widget-area .widget-subarea .widget-hbox input[type=text]'),
'Textbox exists.');
this.test.assert(this.cell_element_exists(index,
@@ -35,7 +35,7 @@ casper.notebook_test(function () {
'Python set textarea value.');
this.test.assert(this.cell_element_function(index,
- '.widget-area .widget-subarea .widget-hbox-single input[type=text]', 'val')=='xyz',
+ '.widget-area .widget-subarea .widget-hbox input[type=text]', 'val')=='xyz',
'Python set textbox value.');
this.test.assert(this.cell_element_exists(string_index,
@@ -47,7 +47,7 @@ casper.notebook_test(function () {
'Python set textarea placeholder.');
this.test.assert(this.cell_element_function(index,
- '.widget-area .widget-subarea .widget-hbox-single input[type=text]', 'attr', ['placeholder'])=='abc',
+ '.widget-area .widget-subarea .widget-hbox input[type=text]', 'attr', ['placeholder'])=='abc',
'Python set textbox placehoder.');
});
});
diff --git a/IPython/html/widgets/widget.py b/IPython/html/widgets/widget.py
index e2f2a6e..a97ec62 100644
--- a/IPython/html/widgets/widget.py
+++ b/IPython/html/widgets/widget.py
@@ -18,7 +18,8 @@ import collections
from IPython.core.getipython import get_ipython
from IPython.kernel.comm import Comm
from IPython.config import LoggingConfigurable
-from IPython.utils.traitlets import Unicode, Dict, Instance, Bool, List, Tuple, Int, Set
+from IPython.utils.traitlets import Unicode, Dict, Instance, Bool, List, \
+ CaselessStrEnum, Tuple, CUnicode, Int, Set
from IPython.utils.py3compat import string_types
#-----------------------------------------------------------------------------
@@ -379,100 +380,60 @@ class Widget(LoggingConfigurable):
class DOMWidget(Widget):
visible = Bool(True, help="Whether the widget is visible.", sync=True)
- _css = List(sync=True) # Internal CSS property list: (selector, key, value)
-
- def get_css(self, key, selector=""):
- """Get a CSS property of the widget.
-
- Note: This function does not actually request the CSS from the
- front-end; Only properties that have been set with set_css can be read.
-
- Parameters
- ----------
- key: unicode
- CSS key
- selector: unicode (optional)
- JQuery selector used when the CSS key/value was set.
- """
- if selector in self._css and key in self._css[selector]:
- return self._css[selector][key]
- else:
- return None
-
- def set_css(self, dict_or_key, value=None, selector=''):
- """Set one or more CSS properties of the widget.
-
- This function has two signatures:
- - set_css(css_dict, selector='')
- - set_css(key, value, selector='')
-
- Parameters
- ----------
- css_dict : dict
- CSS key/value pairs to apply
- key: unicode
- CSS key
- value:
- CSS value
- selector: unicode (optional, kwarg only)
- JQuery selector to use to apply the CSS key/value. If no selector
- is provided, an empty selector is used. An empty selector makes the
- front-end try to apply the css to a default element. The default
- element is an attribute unique to each view, which is a DOM element
- of the view that should be styled with common CSS (see
- `$el_to_style` in the Javascript code).
- """
- if value is None:
- css_dict = dict_or_key
- else:
- css_dict = {dict_or_key: value}
-
- for (key, value) in css_dict.items():
- # First remove the selector/key pair from the css list if it exists.
- # Then add the selector/key pair and new value to the bottom of the
- # list.
- self._css = [x for x in self._css if not (x[0]==selector and x[1]==key)]
- self._css += [(selector, key, value)]
- self.send_state('_css')
-
- def add_class(self, class_names, selector=""):
- """Add class[es] to a DOM element.
-
- Parameters
- ----------
- class_names: unicode or list
- Class name(s) to add to the DOM element(s).
- selector: unicode (optional)
- JQuery selector to select the DOM element(s) that the class(es) will
- be added to.
- """
- class_list = class_names
- if isinstance(class_list, (list, tuple)):
- class_list = ' '.join(class_list)
-
- self.send({
- "msg_type" : "add_class",
- "class_list" : class_list,
- "selector" : selector
- })
-
- def remove_class(self, class_names, selector=""):
- """Remove class[es] from a DOM element.
-
- Parameters
- ----------
- class_names: unicode or list
- Class name(s) to remove from the DOM element(s).
- selector: unicode (optional)
- JQuery selector to select the DOM element(s) that the class(es) will
- be removed from.
- """
- class_list = class_names
- if isinstance(class_list, (list, tuple)):
- class_list = ' '.join(class_list)
-
- self.send({
- "msg_type" : "remove_class",
- "class_list" : class_list,
- "selector" : selector,
- })
+ _css = Tuple(sync=True, help="CSS property list: (selector, key, value)")
+ _dom_classes = Tuple(sync=True, help="DOM classes applied to widget.$el.")
+
+ width = CUnicode(sync=True)
+ height = CUnicode(sync=True)
+ padding = CUnicode(sync=True)
+ margin = CUnicode(sync=True)
+
+ color = Unicode(sync=True)
+ background_color = Unicode(sync=True)
+ border_color = Unicode(sync=True)
+
+ border_width = CUnicode(sync=True)
+ border_radius = CUnicode(sync=True)
+ border_style = CaselessStrEnum(values=[ # http://www.w3schools.com/cssref/pr_border-style.asp
+ 'none',
+ 'hidden',
+ 'dotted',
+ 'dashed',
+ 'solid',
+ 'double',
+ 'groove',
+ 'ridge',
+ 'inset',
+ 'outset',
+ 'initial',
+ 'inherit', ''],
+ default_value='', sync=True)
+
+ font_style = CaselessStrEnum(values=[ # http://www.w3schools.com/cssref/pr_font_font-style.asp
+ 'normal',
+ 'italic',
+ 'oblique',
+ 'initial',
+ 'inherit', ''],
+ default_value='', sync=True)
+ font_weight = CaselessStrEnum(values=[ # http://www.w3schools.com/cssref/pr_font_weight.asp
+ 'normal',
+ 'bold',
+ 'bolder',
+ 'lighter',
+ 'initial',
+ 'inherit', ''] + [str(100 * (i+1)) for i in range(9)],
+ default_value='', sync=True)
+ font_size = CUnicode(sync=True)
+ font_family = Unicode(sync=True)
+
+ def __init__(self, *pargs, **kwargs):
+ super(DOMWidget, self).__init__(*pargs, **kwargs)
+
+ def _validate_border(name, old, new):
+ if new is not None and new != '':
+ if name != 'border_width' and not self.border_width:
+ self.border_width = 1
+ if name != 'border_style' and self.border_style == '':
+ self.border_style = 'solid'
+ self.on_trait_change(_validate_border, ['border_width', 'border_style', 'border_color'])
diff --git a/IPython/html/widgets/widget_bool.py b/IPython/html/widgets/widget_bool.py
index b7bbb1d..57a78d0 100644
--- a/IPython/html/widgets/widget_bool.py
+++ b/IPython/html/widgets/widget_bool.py
@@ -14,7 +14,7 @@ Represents a boolean using a widget.
# Imports
#-----------------------------------------------------------------------------
from .widget import DOMWidget
-from IPython.utils.traitlets import Unicode, Bool
+from IPython.utils.traitlets import Unicode, Bool, CaselessStrEnum
from IPython.utils.warn import DeprecatedClass
#-----------------------------------------------------------------------------
@@ -37,6 +37,11 @@ class ToggleButton(_Bool):
_view_name = Unicode('ToggleButtonView', sync=True)
+ button_style = CaselessStrEnum(
+ values=['primary', 'success', 'info', 'warning', 'danger', ''],
+ default_value='', allow_none=True, sync=True, help="""Use a
+ predefined styling for the button.""")
+
# Remove in IPython 4.0
CheckboxWidget = DeprecatedClass(Checkbox, 'CheckboxWidget')
diff --git a/IPython/html/widgets/widget_box.py b/IPython/html/widgets/widget_box.py
index bd204bd..e2bf081 100644
--- a/IPython/html/widgets/widget_box.py
+++ b/IPython/html/widgets/widget_box.py
@@ -18,6 +18,21 @@ class Box(DOMWidget):
# Using a tuple here to force reassignment to update the list.
# When a proper notifying-list trait exists, that is what should be used here.
children = Tuple(sync=True, allow_none=False)
+
+ _overflow_values = ['visible', 'hidden', 'scroll', 'auto', 'initial', 'inherit', '']
+ overflow_x = CaselessStrEnum(
+ values=_overflow_values,
+ default_value='', allow_none=False, sync=True, help="""Specifies what
+ happens to content that is too large for the rendered region.""")
+ overflow_y = CaselessStrEnum(
+ values=_overflow_values,
+ default_value='', allow_none=False, sync=True, help="""Specifies what
+ happens to content that is too large for the rendered region.""")
+
+ box_style = CaselessStrEnum(
+ values=['success', 'info', 'warning', 'danger', ''],
+ default_value='', allow_none=True, sync=True, help="""Use a
+ predefined styling for the box.""")
def __init__(self, children = (), **kwargs):
kwargs['children'] = children
diff --git a/IPython/html/widgets/widget_button.py b/IPython/html/widgets/widget_button.py
index 17774cc..7ba0ad1 100644
--- a/IPython/html/widgets/widget_button.py
+++ b/IPython/html/widgets/widget_button.py
@@ -15,7 +15,7 @@ click events on the button and trigger backend code when the clicks are fired.
# Imports
#-----------------------------------------------------------------------------
from .widget import DOMWidget, CallbackDispatcher
-from IPython.utils.traitlets import Unicode, Bool
+from IPython.utils.traitlets import Unicode, Bool, CaselessStrEnum
from IPython.utils.warn import DeprecatedClass
#-----------------------------------------------------------------------------
@@ -31,6 +31,11 @@ class Button(DOMWidget):
# Keys
description = Unicode('', help="Description of the button (label).", sync=True)
disabled = Bool(False, help="Enable or disable user changes.", sync=True)
+
+ button_style = CaselessStrEnum(
+ values=['primary', 'success', 'info', 'warning', 'danger', ''],
+ default_value='', allow_none=True, sync=True, help="""Use a
+ predefined styling for the button.""")
def __init__(self, **kwargs):
"""Constructor"""
diff --git a/IPython/html/widgets/widget_float.py b/IPython/html/widgets/widget_float.py
index dc08afd..923acff 100644
--- a/IPython/html/widgets/widget_float.py
+++ b/IPython/html/widgets/widget_float.py
@@ -14,7 +14,7 @@ Represents an unbounded float using a widget.
# Imports
#-----------------------------------------------------------------------------
from .widget import DOMWidget
-from IPython.utils.traitlets import Unicode, CFloat, Bool, Enum, Tuple
+from IPython.utils.traitlets import Unicode, CFloat, Bool, CaselessStrEnum, Tuple
from IPython.utils.warn import DeprecatedClass
#-----------------------------------------------------------------------------
@@ -53,15 +53,22 @@ class BoundedFloatText(_BoundedFloat):
class FloatSlider(_BoundedFloat):
_view_name = Unicode('FloatSliderView', sync=True)
- orientation = Enum([u'horizontal', u'vertical'], u'horizontal',
- help="Vertical or horizontal.", sync=True)
+ orientation = CaselessStrEnum(values=['horizontal', 'vertical'],
+ default_value='horizontal',
+ help="Vertical or horizontal.", allow_none=False, sync=True)
_range = Bool(False, help="Display a range selector", sync=True)
readout = Bool(True, help="Display the current value of the slider next to it.", sync=True)
+ slider_color = Unicode(sync=True)
class FloatProgress(_BoundedFloat):
_view_name = Unicode('ProgressView', sync=True)
+ bar_style = CaselessStrEnum(
+ values=['success', 'info', 'warning', 'danger', ''],
+ default_value='', allow_none=True, sync=True, help="""Use a
+ predefined styling for the progess bar.""")
+
class _FloatRange(_Float):
value = Tuple(CFloat, CFloat, default_value=(0.0, 1.0), help="Tuple of (lower, upper) bounds", sync=True)
lower = CFloat(0.0, help="Lower bound", sync=False)
@@ -158,10 +165,12 @@ class _BoundedFloatRange(_FloatRange):
class FloatRangeSlider(_BoundedFloatRange):
_view_name = Unicode('FloatSliderView', sync=True)
- orientation = Enum([u'horizontal', u'vertical'], u'horizontal',
+ orientation = CaselessStrEnum(values=['horizontal', 'vertical'],
+ default_value='horizontal', allow_none=False,
help="Vertical or horizontal.", sync=True)
_range = Bool(True, help="Display a range selector", sync=True)
readout = Bool(True, help="Display the current value of the slider next to it.", sync=True)
+ slider_color = Unicode(sync=True)
# Remove in IPython 4.0
FloatTextWidget = DeprecatedClass(FloatText, 'FloatTextWidget')
diff --git a/IPython/html/widgets/widget_int.py b/IPython/html/widgets/widget_int.py
index 5777287..123a3a3 100644
--- a/IPython/html/widgets/widget_int.py
+++ b/IPython/html/widgets/widget_int.py
@@ -14,7 +14,7 @@ Represents an unbounded int using a widget.
# Imports
#-----------------------------------------------------------------------------
from .widget import DOMWidget
-from IPython.utils.traitlets import Unicode, CInt, Bool, Enum, Tuple
+from IPython.utils.traitlets import Unicode, CInt, Bool, CaselessStrEnum, Tuple
from IPython.utils.warn import DeprecatedClass
#-----------------------------------------------------------------------------
@@ -58,16 +58,23 @@ class BoundedIntText(_BoundedInt):
class IntSlider(_BoundedInt):
"""Slider widget that represents a int bounded by a minimum and maximum value."""
_view_name = Unicode('IntSliderView', sync=True)
- orientation = Enum([u'horizontal', u'vertical'], u'horizontal',
+ orientation = CaselessStrEnum(values=['horizontal', 'vertical'],
+ default_value='horizontal', allow_none=False,
help="Vertical or horizontal.", sync=True)
_range = Bool(False, help="Display a range selector", sync=True)
readout = Bool(True, help="Display the current value of the slider next to it.", sync=True)
+ slider_color = Unicode(sync=True)
class IntProgress(_BoundedInt):
"""Progress bar that represents a int bounded by a minimum and maximum value."""
_view_name = Unicode('ProgressView', sync=True)
+ bar_style = CaselessStrEnum(
+ values=['success', 'info', 'warning', 'danger', ''],
+ default_value='', allow_none=True, sync=True, help="""Use a
+ predefined styling for the progess bar.""")
+
class _IntRange(_Int):
value = Tuple(CInt, CInt, default_value=(0, 1), help="Tuple of (lower, upper) bounds", sync=True)
lower = CInt(0, help="Lower bound", sync=False)
@@ -162,10 +169,12 @@ class _BoundedIntRange(_IntRange):
class IntRangeSlider(_BoundedIntRange):
_view_name = Unicode('IntSliderView', sync=True)
- orientation = Enum([u'horizontal', u'vertical'], u'horizontal',
+ orientation = CaselessStrEnum(values=['horizontal', 'vertical'],
+ default_value='horizontal', allow_none=False,
help="Vertical or horizontal.", sync=True)
_range = Bool(True, help="Display a range selector", sync=True)
readout = Bool(True, help="Display the current value of the slider next to it.", sync=True)
+ slider_color = Unicode(sync=True)
# Remove in IPython 4.0
IntTextWidget = DeprecatedClass(IntText, 'IntTextWidget')
diff --git a/IPython/html/widgets/widget_selection.py b/IPython/html/widgets/widget_selection.py
index 7c4f2f1..d463049 100644
--- a/IPython/html/widgets/widget_selection.py
+++ b/IPython/html/widgets/widget_selection.py
@@ -18,7 +18,7 @@ from collections import OrderedDict
from threading import Lock
from .widget import DOMWidget
-from IPython.utils.traitlets import Unicode, List, Bool, Any, Dict, TraitError
+from IPython.utils.traitlets import Unicode, List, Bool, Any, Dict, TraitError, CaselessStrEnum
from IPython.utils.py3compat import unicode_type
from IPython.utils.warn import DeprecatedClass
@@ -115,11 +115,21 @@ class ToggleButtons(_Selection):
button can be toggled at any point in time."""
_view_name = Unicode('ToggleButtonsView', sync=True)
+ button_style = CaselessStrEnum(
+ values=['primary', 'success', 'info', 'warning', 'danger', ''],
+ default_value='', allow_none=True, sync=True, help="""Use a
+ predefined styling for the buttons.""")
+
class Dropdown(_Selection):
"""Allows you to select a single item from a dropdown."""
_view_name = Unicode('DropdownView', sync=True)
+ button_style = CaselessStrEnum(
+ values=['primary', 'success', 'info', 'warning', 'danger', ''],
+ default_value='', allow_none=True, sync=True, help="""Use a
+ predefined styling for the buttons.""")
+
class RadioButtons(_Selection):
"""Group of radio buttons that represent an enumeration. Only one radio
diff --git a/examples/Interactive Widgets/Custom Widget - Hello World.ipynb b/examples/Interactive Widgets/Custom Widget - Hello World.ipynb
index 183460b..e647171 100644
--- a/examples/Interactive Widgets/Custom Widget - Hello World.ipynb
+++ b/examples/Interactive Widgets/Custom Widget - Hello World.ipynb
@@ -1,8 +1,16 @@
{
"metadata": {
- "celltoolbar": "Slideshow",
+ "kernelspec": {
+ "codemirror_mode": {
+ "name": "python",
+ "version": 2
+ },
+ "display_name": "Python 2",
+ "language": "python",
+ "name": "python2"
+ },
"name": "",
- "signature": "sha256:32ada55b57f8674a38435bae581b0f53caefd829dca5c5a7931ab3d04a7d86bb"
+ "signature": "sha256:608e0df06fe91ef1c013fd236dda33f7ae11019453f72ae446e8ce15bce82eb2"
},
"nbformat": 3,
"nbformat_minor": 0,
@@ -240,7 +248,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
- "You first need to **import the WidgetManager**. You will use it later to register your view by name (the same name you used in the back-end). To import the widget manager, use the `require` method of [require.js](http://requirejs.org/) (as seen below)."
+ "You first need to **import the `widget` and `manager` modules**. You will use it later to register your view by name (the same name you used in the back-end). To import the modules, use the `require` method of [require.js](http://requirejs.org/) (as seen below)."
]
},
{
@@ -248,8 +256,7 @@
"collapsed": false,
"input": [
"%%javascript\n",
- "\n",
- "require([\"widgets/js/widget\"], function(WidgetManager){\n",
+ "require([\"widgets/js/widget\", \"widgets/js/manager\"], function(widget, manager){\n",
" \n",
"});"
],
@@ -281,16 +288,15 @@
"collapsed": false,
"input": [
"%%javascript\n",
- "\n",
- "require([\"widgets/js/widget\"], function(WidgetManager){\n",
+ "require([\"widgets/js/widget\", \"widgets/js/manager\"], function(widget, manager){\n",
" \n",
" // Define the HelloView\n",
- " var HelloView = IPython.DOMWidgetView.extend({\n",
+ " var HelloView = widget.DOMWidgetView.extend({\n",
" \n",
" });\n",
" \n",
" // Register the HelloView with the widget manager.\n",
- " WidgetManager.register_widget_view('HelloView', HelloView);\n",
+ " manager.WidgetManager.register_widget_view('HelloView', HelloView);\n",
"});"
],
"language": "python",
@@ -321,10 +327,9 @@
"collapsed": false,
"input": [
"%%javascript\n",
- "\n",
- "require([\"widgets/js/widget\"], function(WidgetManager){ \n",
+ "require([\"widgets/js/widget\", \"widgets/js/manager\"], function(widget, manager){\n",
" \n",
- " var HelloView = IPython.DOMWidgetView.extend({\n",
+ " var HelloView = widget.DOMWidgetView.extend({\n",
" \n",
" // Render the view.\n",
" render: function(){ \n",
@@ -332,7 +337,7 @@
" },\n",
" });\n",
" \n",
- " WidgetManager.register_widget_view('HelloView', HelloView);\n",
+ " manager.WidgetManager.register_widget_view('HelloView', HelloView);\n",
"});"
],
"language": "python",
@@ -442,17 +447,16 @@
"collapsed": false,
"input": [
"%%javascript\n",
- "\n",
- "require([\"widgets/js/widget\"], function(WidgetManager){ \n",
+ "require([\"widgets/js/widget\", \"widgets/js/manager\"], function(widget, manager){\n",
" \n",
- " var HelloView = IPython.DOMWidgetView.extend({\n",
+ " var HelloView = widget.DOMWidgetView.extend({\n",
" \n",
" render: function(){ \n",
" this.$el.text(this.model.get('value')); \n",
" },\n",
" });\n",
" \n",
- " WidgetManager.register_widget_view('HelloView', HelloView);\n",
+ " manager.WidgetManager.register_widget_view('HelloView', HelloView);\n",
"});"
],
"language": "python",
@@ -483,11 +487,9 @@
"collapsed": false,
"input": [
"%%javascript\n",
- "\n",
- "require([\"widgets/js/widget\"], function(WidgetManager){ \n",
+ "require([\"widgets/js/widget\", \"widgets/js/manager\"], function(widget, manager){\n",
" \n",
- " var HelloView = IPython.DOMWidgetView.extend({\n",
- " \n",
+ " var HelloView = widget.DOMWidgetView.extend({\n",
" \n",
" render: function(){ \n",
" this.value_changed();\n",
@@ -499,7 +501,7 @@
" },\n",
" });\n",
" \n",
- " WidgetManager.register_widget_view('HelloView', HelloView);\n",
+ " manager.WidgetManager.register_widget_view('HelloView', HelloView);\n",
"});"
],
"language": "python",
@@ -622,10 +624,9 @@
"collapsed": false,
"input": [
"%%javascript\n",
- "\n",
- "require([\"widgets/js/widget\"], function(WidgetManager){ \n",
+ "require([\"widgets/js/widget\", \"widgets/js/manager\"], function(widget, manager){\n",
" \n",
- " var SpinnerView = IPython.DOMWidgetView.extend({\n",
+ " var SpinnerView = widget.DOMWidgetView.extend({\n",
" \n",
" render: function(){ \n",
" \n",
@@ -645,7 +646,7 @@
" },\n",
" });\n",
" \n",
- " WidgetManager.register_widget_view('SpinnerView', SpinnerView);\n",
+ " manager.WidgetManager.register_widget_view('SpinnerView', SpinnerView);\n",
"});"
],
"language": "python",
@@ -676,10 +677,9 @@
"collapsed": false,
"input": [
"%%javascript\n",
- "\n",
- "require([\"widgets/js/widget\"], function(WidgetManager){ \n",
+ "require([\"widgets/js/widget\", \"widgets/js/manager\"], function(widget, manager){\n",
" \n",
- " var SpinnerView = IPython.DOMWidgetView.extend({\n",
+ " var SpinnerView = widget.DOMWidgetView.extend({\n",
" \n",
" render: function(){ \n",
"\n",
@@ -709,7 +709,7 @@
" },\n",
" });\n",
" \n",
- " WidgetManager.register_widget_view('SpinnerView', SpinnerView);\n",
+ " manager.WidgetManager.register_widget_view('SpinnerView', SpinnerView);\n",
"});"
],
"language": "python",
@@ -772,7 +772,7 @@
"input": [
"from IPython.display import display\n",
"w1 = SpinnerWidget(value=0)\n",
- "w2 = widgets.IntSliderWidget()\n",
+ "w2 = widgets.IntSlider()\n",
"display(w1,w2)\n",
"\n",
"from IPython.utils.traitlets import link\n",
diff --git a/examples/Interactive Widgets/Export As (nbconvert).html b/examples/Interactive Widgets/Export As (nbconvert).html
new file mode 100644
index 0000000..ed88f41
--- /dev/null
+++ b/examples/Interactive Widgets/Export As (nbconvert).html
@@ -0,0 +1,10970 @@
+
+
+
+
+
+Notebook
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Create a text Widget without displaying it. The widget will be used to store the notebook's name which is otherwise only available in the front-end.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
WARNING: "TextWidget" is deprecated, please use "Text" instead.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Get the current notebook's name by pushing JavaScript to the browser that sets the notebook name in a string widget.
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Out[4]:
+
+
+
+
u'Export As (nbconvert).ipynb'
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Create the widget that will allow the user to Export the current notebook.
+
+
+
+
+
+
+
+
+
+
+
Export the notebook when the export button is clicked.
+
+
+
+
+
+
+
+
+
+
+
Display the controls.
+
+
+
+
+
+
+
+
+
diff --git a/examples/Interactive Widgets/Export As (nbconvert).ipynb b/examples/Interactive Widgets/Export As (nbconvert).ipynb
index 9c6e758..cf8340b 100644
--- a/examples/Interactive Widgets/Export As (nbconvert).ipynb
+++ b/examples/Interactive Widgets/Export As (nbconvert).ipynb
@@ -1,6 +1,16 @@
{
"metadata": {
- "name": ""
+ "kernelspec": {
+ "codemirror_mode": {
+ "name": "python",
+ "version": 2
+ },
+ "display_name": "Python 2",
+ "language": "python",
+ "name": "python2"
+ },
+ "name": "",
+ "signature": "sha256:dc519f61f8a484b3a8f0b05ad1891fad701324c837325b12d31cce4f31647c2f"
},
"nbformat": 3,
"nbformat_minor": 0,
@@ -24,8 +34,7 @@
],
"language": "python",
"metadata": {},
- "outputs": [],
- "prompt_number": 1
+ "outputs": []
},
{
"cell_type": "markdown",
@@ -38,12 +47,11 @@
"cell_type": "code",
"collapsed": false,
"input": [
- "notebook_name = widgets.TextWidget()"
+ "notebook_name = widgets.Text()"
],
"language": "python",
"metadata": {},
- "outputs": [],
- "prompt_number": 2
+ "outputs": []
},
{
"cell_type": "markdown",
@@ -63,21 +71,7 @@
],
"language": "python",
"metadata": {},
- "outputs": [
- {
- "javascript": [
- "var model = IPython.notebook.kernel.widget_manager.get_model('8c6583524eb3422c99491730a3e1ce6c');\n",
- "model.set('value', IPython.notebook.notebook_name);\n",
- "model.save();"
- ],
- "metadata": {},
- "output_type": "display_data",
- "text": [
- ""
- ]
- }
- ],
- "prompt_number": 3
+ "outputs": []
},
{
"cell_type": "code",
@@ -88,17 +82,7 @@
],
"language": "python",
"metadata": {},
- "outputs": [
- {
- "metadata": {},
- "output_type": "pyout",
- "prompt_number": 4,
- "text": [
- "u'Export As (nbconvert).ipynb'"
- ]
- }
- ],
- "prompt_number": 4
+ "outputs": []
},
{
"cell_type": "markdown",
@@ -111,14 +95,13 @@
"cell_type": "code",
"collapsed": false,
"input": [
- "exporter_names = widgets.DropdownWidget(values=get_export_names(), value='html')\n",
- "export_button = widgets.ButtonWidget(description=\"Export\")\n",
- "download_link = widgets.HTMLWidget(visible=False)"
+ "exporter_names = widgets.Dropdown(values=get_export_names(), value='html')\n",
+ "export_button = widgets.Button(description=\"Export\")\n",
+ "download_link = widgets.HTML(visible=False)"
],
"language": "python",
"metadata": {},
- "outputs": [],
- "prompt_number": 5
+ "outputs": []
},
{
"cell_type": "markdown",
@@ -159,8 +142,7 @@
],
"language": "python",
"metadata": {},
- "outputs": [],
- "prompt_number": 6
+ "outputs": []
},
{
"cell_type": "markdown",
@@ -177,11 +159,10 @@
],
"language": "python",
"metadata": {},
- "outputs": [],
- "prompt_number": 7
+ "outputs": []
}
],
"metadata": {}
}
]
-}
+}
\ No newline at end of file
diff --git a/examples/Interactive Widgets/File Upload Widget.ipynb b/examples/Interactive Widgets/File Upload Widget.ipynb
index 8f7e796..004da18 100644
--- a/examples/Interactive Widgets/File Upload Widget.ipynb
+++ b/examples/Interactive Widgets/File Upload Widget.ipynb
@@ -6,7 +6,17 @@
null
]
],
- "name": ""
+ "kernelspec": {
+ "codemirror_mode": {
+ "name": "python",
+ "version": 2
+ },
+ "display_name": "Python 2",
+ "language": "python",
+ "name": "python2"
+ },
+ "name": "",
+ "signature": "sha256:25c43e4f530e049319d587a7e47734cab5b4b4f608f71aa234e821f43076afe8"
},
"nbformat": 3,
"nbformat_minor": 0,
@@ -24,8 +34,7 @@
],
"language": "python",
"metadata": {},
- "outputs": [],
- "prompt_number": 1
+ "outputs": []
},
{
"cell_type": "markdown",
@@ -69,8 +78,7 @@
],
"language": "python",
"metadata": {},
- "outputs": [],
- "prompt_number": 2
+ "outputs": []
},
{
"cell_type": "code",
@@ -78,9 +86,9 @@
"input": [
"%%javascript\n",
"\n",
- "require([\"widgets/js/widget\"], function(WidgetManager){\n",
+ "require([\"widgets/js/widget\", \"widgets/js/manager\"], function(widget, manager){\n",
"\n",
- " var FilePickerView = IPython.WidgetView.extend({\n",
+ " var FilePickerView = widget.DOMWidgetView.extend({\n",
" render: function(){\n",
" // Render the view.\n",
" this.setElement($(' ')\n",
@@ -121,69 +129,12 @@
" });\n",
" \n",
" // Register the DatePickerView with the widget manager.\n",
- " WidgetManager.register_widget_view('FilePickerView', FilePickerView);\n",
+ " manager.WidgetManager.register_widget_view('FilePickerView', FilePickerView);\n",
"});"
],
"language": "python",
"metadata": {},
- "outputs": [
- {
- "javascript": [
- "\n",
- "require([\"widgets/js/widget\"], function(WidgetManager){\n",
- "\n",
- " var FilePickerView = IPython.WidgetView.extend({\n",
- " render: function(){\n",
- " // Render the view.\n",
- " this.setElement($(' ')\n",
- " .attr('type', 'file'));\n",
- " },\n",
- " \n",
- " events: {\n",
- " // List of events and their handlers.\n",
- " 'change': 'handle_file_change',\n",
- " },\n",
- " \n",
- " handle_file_change: function(evt) { \n",
- " // Handle when the user has changed the file.\n",
- " \n",
- " // Retrieve the first (and only!) File from the FileList object\n",
- " var file = evt.target.files[0];\n",
- " if (file) {\n",
- "\n",
- " // Read the file's textual content and set value to those contents.\n",
- " var that = this;\n",
- " var file_reader = new FileReader();\n",
- " file_reader.onload = function(e) {\n",
- " that.model.set('value', e.target.result);\n",
- " that.touch();\n",
- " }\n",
- " file_reader.readAsText(file);\n",
- " } else {\n",
- "\n",
- " // The file couldn't be opened. Send an error msg to the\n",
- " // back-end.\n",
- " this.send({ 'event': 'error' });\n",
- " }\n",
- "\n",
- " // Set the filename of the file.\n",
- " this.model.set('filename', file.name);\n",
- " this.touch();\n",
- " },\n",
- " });\n",
- " \n",
- " // Register the DatePickerView with the widget manager.\n",
- " WidgetManager.register_widget_view('FilePickerView', FilePickerView);\n",
- "});"
- ],
- "metadata": {},
- "output_type": "display_data",
- "text": [
- ""
- ]
- }
- ],
- "prompt_number": 3
+ "outputs": []
},
{
"cell_type": "markdown",
@@ -222,27 +173,10 @@
],
"language": "python",
"metadata": {},
- "outputs": [
- {
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "Loading test.txt\n"
- ]
- },
- {
- "output_type": "stream",
- "stream": "stdout",
- "text": [
- "Loaded, file contents: Hello World!\n",
- "\n"
- ]
- }
- ],
- "prompt_number": 4
+ "outputs": []
}
],
"metadata": {}
}
]
-}
+}
\ No newline at end of file
diff --git a/examples/Interactive Widgets/Index.ipynb b/examples/Interactive Widgets/Index.ipynb
index 43e9412..741af72 100644
--- a/examples/Interactive Widgets/Index.ipynb
+++ b/examples/Interactive Widgets/Index.ipynb
@@ -1,7 +1,16 @@
{
"metadata": {
+ "kernelspec": {
+ "codemirror_mode": {
+ "name": "python",
+ "version": 2
+ },
+ "display_name": "Python 2",
+ "language": "python",
+ "name": "python2"
+ },
"name": "",
- "signature": "sha256:6873fce87f9a4123795746d3857404b83e1bb099cc5a968aa85100dade070c41"
+ "signature": "sha256:8e469f292b096d750dc8eeb71caa8c08b26bc722708314a26a7684c380ccd20f"
},
"nbformat": 3,
"nbformat_minor": 0,
@@ -53,9 +62,8 @@
"- [Widget Basics](Widget Basics.ipynb) \n",
"- [Widget Events](Widget Events.ipynb) \n",
"- [Widget Placement](Widget Placement.ipynb) \n",
- "- [Widget Styles](Widget Styles.ipynb) \n",
- "- [Widget Alignment](Widget Alignment.ipynb) \n",
- "- [Custom Widgets](Custom Widgets.ipynb)"
+ "- [Widget Styling](Widget Styling.ipynb) \n",
+ "- [Custom Widget](Custom Widget - Hello World.ipynb)"
]
},
{
diff --git a/examples/Interactive Widgets/Nonblocking Console.ipynb b/examples/Interactive Widgets/Nonblocking Console.ipynb
index 444b66d..84b3ef5 100644
--- a/examples/Interactive Widgets/Nonblocking Console.ipynb
+++ b/examples/Interactive Widgets/Nonblocking Console.ipynb
@@ -1,6 +1,16 @@
{
"metadata": {
- "name": ""
+ "kernelspec": {
+ "codemirror_mode": {
+ "name": "python",
+ "version": 2
+ },
+ "display_name": "Python 2",
+ "language": "python",
+ "name": "python2"
+ },
+ "name": "",
+ "signature": "sha256:3dfbc0dcb1fefc9ef028022760916b0300e14f71bf8e27589e61800841d5839c"
},
"nbformat": 3,
"nbformat_minor": 0,
@@ -13,7 +23,6 @@
"input": [
"# Console related imports.\n",
"from subprocess import Popen, PIPE\n",
- "import fcntl\n",
"import os\n",
"from IPython.utils.py3compat import bytes_to_str, string_types\n",
"\n",
@@ -23,8 +32,7 @@
],
"language": "python",
"metadata": {},
- "outputs": [],
- "prompt_number": 1
+ "outputs": []
},
{
"cell_type": "markdown",
@@ -65,9 +73,12 @@
"\n",
"def set_pipe_nonblocking(pipe):\n",
" \"\"\"Set a pipe as non-blocking\"\"\"\n",
- " fl = fcntl.fcntl(pipe, fcntl.F_GETFL)\n",
- " fcntl.fcntl(pipe, fcntl.F_SETFL, fl | os.O_NONBLOCK)\n",
- "\n",
+ " try:\n",
+ " import fcntl\n",
+ " fl = fcntl.fcntl(pipe, fcntl.F_GETFL)\n",
+ " fcntl.fcntl(pipe, fcntl.F_SETFL, fl | os.O_NONBLOCK)\n",
+ " except:\n",
+ " pass\n",
"\n",
"kernel = get_ipython().kernel\n",
"def run_command(command, append_output, has_user_exited=None):\n",
@@ -112,8 +123,7 @@
],
"language": "python",
"metadata": {},
- "outputs": [],
- "prompt_number": 2
+ "outputs": []
},
{
"cell_type": "markdown",
@@ -126,29 +136,27 @@
"cell_type": "code",
"collapsed": false,
"input": [
- "console_container = widgets.ContainerWidget(visible=False)\n",
- "console_container.set_css('padding', '10px')\n",
- "\n",
- "console_style = {\n",
- " 'font-family': 'monospace',\n",
- " 'color': '#AAAAAA',\n",
- " 'background': 'black',\n",
- " 'width': '800px',\n",
- "}\n",
+ "console_container = widgets.VBox(visible=False)\n",
+ "console_container.padding = '10px'\n",
"\n",
- "output_box = widgets.TextareaWidget()\n",
- "output_box.set_css(console_style)\n",
- "output_box.set_css('height', '400px')\n",
+ "output_box = widgets.Textarea()\n",
+ "output_box.height = '400px'\n",
+ "output_box.font_family = 'monospace'\n",
+ "output_box.color = '#AAAAAA'\n",
+ "output_box.background_color = 'black'\n",
+ "output_box.width = '800px'\n",
"\n",
- "input_box = widgets.TextWidget()\n",
- "input_box.set_css(console_style)\n",
+ "input_box = widgets.Text()\n",
+ "input_box.font_family = 'monospace'\n",
+ "input_box.color = '#AAAAAA'\n",
+ "input_box.background_color = 'black'\n",
+ "input_box.width = '800px'\n",
"\n",
"console_container.children = [output_box, input_box]"
],
"language": "python",
"metadata": {},
- "outputs": [],
- "prompt_number": 3
+ "outputs": []
},
{
"cell_type": "markdown",
@@ -188,8 +196,7 @@
],
"language": "python",
"metadata": {},
- "outputs": [],
- "prompt_number": 4
+ "outputs": []
},
{
"cell_type": "markdown",
@@ -202,7 +209,7 @@
"cell_type": "code",
"collapsed": false,
"input": [
- "toggle_button = widgets.ButtonWidget(description=\"Start Console\")\n",
+ "toggle_button = widgets.Button(description=\"Start Console\")\n",
"def toggle_console(sender):\n",
" console_container.visible = not console_container.visible\n",
" if console_container.visible:\n",
@@ -217,8 +224,7 @@
],
"language": "python",
"metadata": {},
- "outputs": [],
- "prompt_number": 5
+ "outputs": []
}
],
"metadata": {}
diff --git a/examples/Interactive Widgets/Variable Inspector.ipynb b/examples/Interactive Widgets/Variable Inspector.ipynb
index 7413c21..844d1be 100644
--- a/examples/Interactive Widgets/Variable Inspector.ipynb
+++ b/examples/Interactive Widgets/Variable Inspector.ipynb
@@ -1,7 +1,16 @@
{
"metadata": {
+ "kernelspec": {
+ "codemirror_mode": {
+ "name": "python",
+ "version": 2
+ },
+ "display_name": "Python 2",
+ "language": "python",
+ "name": "python2"
+ },
"name": "",
- "signature": "sha256:7b872a09743460a3ce0358e9010c3b4baf5136b79a2a075964dea2c2fd85c82e"
+ "signature": "sha256:474731659fb14b86672d1dafb2b497fa280082ab40a8a82fe2cde1b6d9b88a6e"
},
"nbformat": 3,
"nbformat_minor": 0,
@@ -44,8 +53,7 @@
],
"language": "python",
"metadata": {},
- "outputs": [],
- "prompt_number": 1
+ "outputs": []
},
{
"cell_type": "code",
@@ -67,14 +75,14 @@
" self.namespace = NamespaceMagics()\n",
" self.namespace.shell = ipython.kernel.shell\n",
" \n",
- " self._popout = widgets.PopupWidget()\n",
+ " self._popout = widgets.Popup()\n",
" self._popout.description = \"Variable Inspector\"\n",
" self._popout.button_text = self._popout.description\n",
"\n",
- " self._modal_body = widgets.ContainerWidget()\n",
- " self._modal_body.set_css('overflow-y', 'scroll')\n",
+ " self._modal_body = widgets.VBox()\n",
+ " self._modal_body.overflow_y = 'scroll'\n",
"\n",
- " self._modal_body_label = widgets.HTMLWidget(value = 'Not hooked')\n",
+ " self._modal_body_label = widgets.HTML(value = 'Not hooked')\n",
" self._modal_body.children = [self._modal_body_label]\n",
"\n",
" self._popout.children = [\n",
@@ -82,12 +90,12 @@
" ]\n",
" \n",
" self._ipython = ipython\n",
- " self._ipython.register_post_execute(self._fill)\n",
- "\n",
+ " self._ipython.events.register('post_run_cell', self._fill)\n",
+ " \n",
" def close(self):\n",
" \"\"\"Close and remove hooks.\"\"\"\n",
" if not self.closed:\n",
- " del self._ipython._post_execute[self._fill]\n",
+ " self._ipython.events.unregister('post_run_cell', self._fill)\n",
" self._popout.close()\n",
" self.closed = True\n",
" VariableInspectorWindow.instance = None\n",
@@ -102,14 +110,11 @@
" def _ipython_display_(self):\n",
" \"\"\"Called when display() or pyout is used to display the Variable \n",
" Inspector.\"\"\"\n",
- " self._popout._ipython_display_()\n",
- " self._popout.add_class('vbox')\n",
- " self._modal_body.add_class('box-flex1')\n"
+ " self._popout._ipython_display_()\n"
],
"language": "python",
"metadata": {},
- "outputs": [],
- "prompt_number": 2
+ "outputs": []
},
{
"cell_type": "code",
@@ -120,8 +125,7 @@
],
"language": "python",
"metadata": {},
- "outputs": [],
- "prompt_number": 3
+ "outputs": []
},
{
"cell_type": "heading",
@@ -139,8 +143,7 @@
],
"language": "python",
"metadata": {},
- "outputs": [],
- "prompt_number": 4
+ "outputs": []
},
{
"cell_type": "code",
@@ -150,8 +153,7 @@
],
"language": "python",
"metadata": {},
- "outputs": [],
- "prompt_number": 5
+ "outputs": []
},
{
"cell_type": "code",
@@ -161,8 +163,7 @@
],
"language": "python",
"metadata": {},
- "outputs": [],
- "prompt_number": 6
+ "outputs": []
},
{
"cell_type": "code",
@@ -172,8 +173,7 @@
],
"language": "python",
"metadata": {},
- "outputs": [],
- "prompt_number": 7
+ "outputs": []
},
{
"cell_type": "code",
@@ -183,8 +183,17 @@
],
"language": "python",
"metadata": {},
- "outputs": [],
- "prompt_number": 8
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [
+ "inspector.close()"
+ ],
+ "language": "python",
+ "metadata": {},
+ "outputs": []
}
],
"metadata": {}
diff --git a/examples/Interactive Widgets/Widget Basics.ipynb b/examples/Interactive Widgets/Widget Basics.ipynb
index e54d181..8aea4f1 100644
--- a/examples/Interactive Widgets/Widget Basics.ipynb
+++ b/examples/Interactive Widgets/Widget Basics.ipynb
@@ -1,8 +1,16 @@
{
"metadata": {
- "celltoolbar": "Slideshow",
+ "kernelspec": {
+ "codemirror_mode": {
+ "name": "python",
+ "version": 2
+ },
+ "display_name": "Python 2",
+ "language": "python",
+ "name": "python2"
+ },
"name": "",
- "signature": "sha256:916b80c91b959f78d7e5a9d5c9c7d371d3aa2b4476fdb19a7cb5cf9666d68d5b"
+ "signature": "sha256:c8af7f5d30b29ee52fe6a79cf0d573c9c2d5b2f522b04731249e3208671741d3"
},
"nbformat": 3,
"nbformat_minor": 0,
@@ -110,14 +118,14 @@
"cell_type": "markdown",
"metadata": {},
"source": [
- "Widgets have their own display `repr` which allows them to be displayed using IPython's display framework. Constructing and returning an `IntSliderWidget` automatically displays the widget (as seen below). Widgets are **displayed inside the `widget area`**, which sits between the code cell and output. **You can hide all of the widgets** in the `widget area` by clicking the grey *x* in the margin."
+ "Widgets have their own display `repr` which allows them to be displayed using IPython's display framework. Constructing and returning an `IntSlider` automatically displays the widget (as seen below). Widgets are **displayed inside the `widget area`**, which sits between the code cell and output. **You can hide all of the widgets** in the `widget area` by clicking the grey *x* in the margin."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
- "IntSliderWidget()"
+ "IntSlider()"
],
"language": "python",
"metadata": {},
@@ -147,7 +155,7 @@
"collapsed": false,
"input": [
"from IPython.display import display\n",
- "w = IntSliderWidget()\n",
+ "w = IntSlider()\n",
"display(w)"
],
"language": "python",
@@ -266,7 +274,7 @@
"cell_type": "code",
"collapsed": false,
"input": [
- "w = IntSliderWidget()\n",
+ "w = IntSlider()\n",
"display(w)"
],
"language": "python",
@@ -352,7 +360,7 @@
"cell_type": "code",
"collapsed": false,
"input": [
- "TextWidget(value='Hello World!', disabled=True)"
+ "Text(value='Hello World!', disabled=True)"
],
"language": "python",
"metadata": {},
@@ -382,9 +390,9 @@
"collapsed": false,
"input": [
"from IPython.utils.traitlets import link\n",
- "a = FloatTextWidget()\n",
- "b = FloatSliderWidget()\n",
- "c = FloatProgressWidget()\n",
+ "a = FloatText()\n",
+ "b = FloatSlider()\n",
+ "c = FloatProgress()\n",
"display(a,b,c)\n",
"\n",
"\n",
diff --git a/examples/Interactive Widgets/Widget Events.ipynb b/examples/Interactive Widgets/Widget Events.ipynb
index 9a0888c..45ce1fa 100644
--- a/examples/Interactive Widgets/Widget Events.ipynb
+++ b/examples/Interactive Widgets/Widget Events.ipynb
@@ -6,9 +6,17 @@
null
]
],
- "celltoolbar": "Slideshow",
+ "kernelspec": {
+ "codemirror_mode": {
+ "name": "python",
+ "version": 2
+ },
+ "display_name": "Python 2",
+ "language": "python",
+ "name": "python2"
+ },
"name": "",
- "signature": "sha256:43e4910dd01111e1206f4f7940a201d6d5e69485df79de96e0ad927eb0046226"
+ "signature": "sha256:05a3e92089b37f68e3134587ffef6ef73830e5f8b3c515ba24640d7c803820c3"
},
"nbformat": 3,
"nbformat_minor": 0,
@@ -56,7 +64,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
- "The `ButtonWidget` is not used to represent a data type. Instead the button widget is used to **handle mouse clicks**. The **`on_click` method** of the `ButtonWidget` can be used to register function to be called when the button is clicked. The doc string of the `on_click` can be seen below."
+ "The `Button` is not used to represent a data type. Instead the button widget is used to **handle mouse clicks**. The **`on_click` method** of the `Button` can be used to register function to be called when the button is clicked. The doc string of the `on_click` can be seen below."
]
},
{
@@ -64,7 +72,7 @@
"collapsed": false,
"input": [
"from IPython.html import widgets\n",
- "print(widgets.ButtonWidget.on_click.__doc__)"
+ "print(widgets.Button.on_click.__doc__)"
],
"language": "python",
"metadata": {},
@@ -94,7 +102,7 @@
"collapsed": false,
"input": [
"from IPython.display import display\n",
- "button = widgets.ButtonWidget(description=\"Click Me!\")\n",
+ "button = widgets.Button(description=\"Click Me!\")\n",
"display(button)\n",
"\n",
"def on_button_clicked(b):\n",
@@ -122,14 +130,14 @@
"cell_type": "markdown",
"metadata": {},
"source": [
- "The **`TextWidget`** also has a special **`on_submit` event**. The `on_submit` event **fires when the user hits return**."
+ "The **`Text`** also has a special **`on_submit` event**. The `on_submit` event **fires when the user hits return**."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
- "text = widgets.TextWidget()\n",
+ "text = widgets.Text()\n",
"display(text)\n",
"\n",
"def handle_submit(sender):\n",
@@ -193,14 +201,14 @@
"- callback(trait_name, new_value)\n",
"- callback(trait_name, old_value, new_value)\n",
"\n",
- "Using this method, an example of how to output an IntSliderWiget's value as it is changed can be seen below."
+ "Using this method, an example of how to output an `IntSlider`'s value as it is changed can be seen below."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
- "int_range = widgets.IntSliderWidget()\n",
+ "int_range = widgets.IntSlider()\n",
"display(int_range)\n",
"\n",
"def on_value_change(name, value):\n",
diff --git a/examples/Interactive Widgets/Widget List.ipynb b/examples/Interactive Widgets/Widget List.ipynb
index 0d5ff91..6fbfd0a 100644
--- a/examples/Interactive Widgets/Widget List.ipynb
+++ b/examples/Interactive Widgets/Widget List.ipynb
@@ -1,8 +1,16 @@
{
"metadata": {
- "celltoolbar": "Slideshow",
+ "kernelspec": {
+ "codemirror_mode": {
+ "name": "python",
+ "version": 2
+ },
+ "display_name": "Python 2",
+ "language": "python",
+ "name": "python2"
+ },
"name": "",
- "signature": "sha256:f8284581eb29fde72c434a9a414fcb60837302177ebaa4af6ff219dd2b726381"
+ "signature": "sha256:83b39d018a7a6ae0a324b9f3d38debafbfb2ed0a114e4bbd357fb318f8f23438"
},
"nbformat": 3,
"nbformat_minor": 0,
@@ -40,7 +48,7 @@
}
},
"source": [
- "For a complete list of the widgets available to you, you can list the classes in the widget namespace (as seen below). Classes with the suffix `Widget` are widgets. `Widget` and `DOMWidget` are base classes."
+ "For a complete list of the widgets available to you, you can list the classes in the widget namespace (as seen below). `Widget` and `DOMWidget`, not listed below, are base classes."
]
},
{
@@ -48,7 +56,7 @@
"collapsed": false,
"input": [
"from IPython.html import widgets\n",
- "[w for w in dir(widgets) if w.endswith('Widget')]"
+ "[n for n in dir(widgets) if not n.endswith('Widget') and n[0] == n[0].upper() and not n[0] == '_']"
],
"language": "python",
"metadata": {},
@@ -82,14 +90,14 @@
}
},
"source": [
- "FloatSliderWidget"
+ "FloatSlider"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
- "widgets.FloatSliderWidget(\n",
+ "widgets.FloatSlider(\n",
" value=7.5,\n",
" min=5.0,\n",
" max=10.0,\n",
@@ -112,7 +120,7 @@
"cell_type": "code",
"collapsed": false,
"input": [
- "widgets.FloatSliderWidget(\n",
+ "widgets.FloatSlider(\n",
" value=7.5,\n",
" min=5.0,\n",
" max=10.0,\n",
@@ -134,14 +142,14 @@
}
},
"source": [
- "FloatProgressWidget"
+ "FloatProgress"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
- "widgets.FloatProgressWidget(\n",
+ "widgets.FloatProgress(\n",
" value=7.5,\n",
" min=5.0,\n",
" max=10.0,\n",
@@ -162,14 +170,14 @@
}
},
"source": [
- "BoundedFloatTextWidget"
+ "BoundedFloatText"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
- "widgets.BoundedFloatTextWidget(\n",
+ "widgets.BoundedFloatText(\n",
" value=7.5,\n",
" min=5.0,\n",
" max=10.0,\n",
@@ -189,14 +197,14 @@
}
},
"source": [
- "FloatTextWidget"
+ "FloatText"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
- "widgets.FloatTextWidget(\n",
+ "widgets.FloatText(\n",
" value=7.5,\n",
" description='Any:',\n",
")"
@@ -229,14 +237,14 @@
"level": 3,
"metadata": {},
"source": [
- "ToggleButtonWidget"
+ "ToggleButton"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
- "widgets.ToggleButtonWidget(\n",
+ "widgets.ToggleButton(\n",
" description='Click me',\n",
" value=False,\n",
")"
@@ -254,14 +262,14 @@
}
},
"source": [
- "CheckboxWidget"
+ "Checkbox"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
- "widgets.CheckboxWidget(\n",
+ "widgets.Checkbox(\n",
" description='Check me',\n",
" value=True,\n",
")"
@@ -298,7 +306,7 @@
}
},
"source": [
- "DropdownWidget"
+ "Dropdown"
]
},
{
@@ -306,7 +314,7 @@
"collapsed": false,
"input": [
"from IPython.display import display\n",
- "w = widgets.DropdownWidget(\n",
+ "w = widgets.Dropdown(\n",
" values=[1, 2, 3],\n",
" value=2,\n",
" description='Number:',\n",
@@ -338,7 +346,7 @@
"cell_type": "code",
"collapsed": false,
"input": [
- "w = widgets.DropdownWidget(\n",
+ "w = widgets.Dropdown(\n",
" values={'One': 1, 'Two': 2, 'Three': 3},\n",
" value=2,\n",
" description='Number:',\n",
@@ -368,14 +376,14 @@
}
},
"source": [
- "RadioButtonsWidget"
+ "RadioButtons"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
- "widgets.RadioButtonsWidget(\n",
+ "widgets.RadioButtons(\n",
" description='Pizza topping:',\n",
" values=['pepperoni', 'pineapple', 'anchovies'],\n",
")"
@@ -393,14 +401,14 @@
}
},
"source": [
- "SelectWidget"
+ "Select"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
- "widgets.SelectWidget(\n",
+ "widgets.Select(\n",
" description='OS:',\n",
" values=['Linux', 'Windows', 'OSX'],\n",
")"
@@ -418,14 +426,14 @@
}
},
"source": [
- "ToggleButtonsWidget"
+ "ToggleButtons"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
- "widgets.ToggleButtonsWidget(\n",
+ "widgets.ToggleButtons(\n",
" description='Speed:',\n",
" values=['Slow', 'Regular', 'Fast'],\n",
")"
@@ -450,7 +458,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
- "There are 4 widgets that can be used to display a string value. Of those, the **`TextWidget` and `TextareaWidget` accept input**. The **`LatexWidget` and `HTMLWidget` display the string** as either Latex or HTML respectively, but **do not accept input**."
+ "There are 4 widgets that can be used to display a string value. Of those, the **`Text` and `Textarea` widgets accept input**. The **`Latex` and `HTML` widgets display the string** as either Latex or HTML respectively, but **do not accept input**."
]
},
{
@@ -462,14 +470,14 @@
}
},
"source": [
- "TextWidget"
+ "Text"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
- "widgets.TextWidget(\n",
+ "widgets.Text(\n",
" description='String:',\n",
" value='Hello World',\n",
")"
@@ -483,14 +491,14 @@
"level": 3,
"metadata": {},
"source": [
- "TextareaWidget"
+ "Textarea"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
- "widgets.TextareaWidget(\n",
+ "widgets.Textarea(\n",
" description='String:',\n",
" value='Hello World',\n",
")"
@@ -508,14 +516,14 @@
}
},
"source": [
- "LatexWidget"
+ "Latex"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
- "widgets.LatexWidget(\n",
+ "widgets.Latex(\n",
" value=\"$$\\\\frac{n!}{k!(n-k)!} = \\\\binom{n}{k}$$\",\n",
")"
],
@@ -528,14 +536,14 @@
"level": 3,
"metadata": {},
"source": [
- "HTMLWidget"
+ "HTML"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
- "widgets.HTMLWidget(\n",
+ "widgets.HTML(\n",
" value=\"Hello World \"\n",
")"
],
@@ -552,14 +560,14 @@
}
},
"source": [
- "ButtonWidget"
+ "Button"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
- "widgets.ButtonWidget(description='Click me')"
+ "widgets.Button(description='Click me')"
],
"language": "python",
"metadata": {},
diff --git a/examples/Interactive Widgets/Widget Styling.ipynb b/examples/Interactive Widgets/Widget Styling.ipynb
index a7036a7..2924a30 100644
--- a/examples/Interactive Widgets/Widget Styling.ipynb
+++ b/examples/Interactive Widgets/Widget Styling.ipynb
@@ -6,9 +6,17 @@
null
]
],
- "celltoolbar": "Slideshow",
+ "kernelspec": {
+ "codemirror_mode": {
+ "name": "python",
+ "version": 2
+ },
+ "display_name": "Python 2",
+ "language": "python",
+ "name": "python2"
+ },
"name": "",
- "signature": "sha256:b5501a34b2148c57201625da06989ae31e2d22f429b786170c96fb703e08bc58"
+ "signature": "sha256:8bb091be85fd5e7f76082b1b4b98cddec92a856334935ac2c702fe5ec03f6eff"
},
"nbformat": 3,
"nbformat_minor": 0,
@@ -40,69 +48,11 @@
"outputs": []
},
{
- "cell_type": "heading",
- "level": 1,
- "metadata": {
- "slideshow": {
- "slide_type": "slide"
- }
- },
- "source": [
- "Widget Styling"
- ]
- },
- {
- "cell_type": "heading",
- "level": 2,
- "metadata": {},
- "source": [
- "CSS"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "Since the representation of the widget you see is a **browser element**, **Cascading Style Sheets (CSS)** are used for styling. Widgets have a **`set_css` method** that allows you to **add and remove CSS properties** from your elements. The following example shows had `set_css` **can be used to set the background color** of a `TextWidget`."
- ]
- },
- {
"cell_type": "code",
"collapsed": false,
"input": [
"from IPython.html import widgets\n",
- "text = widgets.TextWidget(value=\"Hello World!\")\n",
- "text.set_css('background', 'lime')\n",
- "text "
- ],
- "language": "python",
- "metadata": {},
- "outputs": []
- },
- {
- "cell_type": "heading",
- "level": 3,
- "metadata": {
- "slideshow": {
- "slide_type": "slide"
- }
- },
- "source": [
- "Color codes"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "In the example above, **the color `lime` is specified by name**. CSS also supports specifying colors by a **3 byte hexadecimal string**. The first byte is red, second green, and third blue (**RGB**). The following example sets the `TextWidget`'s background to blue."
- ]
- },
- {
- "cell_type": "code",
- "collapsed": false,
- "input": [
- "text.set_css('background', '#0000FF')"
+ "from IPython.display import display"
],
"language": "python",
"metadata": {},
@@ -110,105 +60,63 @@
},
{
"cell_type": "heading",
- "level": 3,
+ "level": 1,
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
- "Forecolor"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "In CSS the **font color is `color`.**"
+ "Widget Styling"
]
},
{
- "cell_type": "code",
- "collapsed": false,
- "input": [
- "text.set_css('color', '#FFFFFF')"
- ],
- "language": "python",
- "metadata": {},
- "outputs": []
- },
- {
"cell_type": "heading",
- "level": 3,
- "metadata": {
- "slideshow": {
- "slide_type": "slide"
- }
- },
- "source": [
- "Size"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "CSS is also used to set the **height and width** of controls. The `set_css` method also **can accept a single dictionary with multiple CSS properties** (as seen below)."
- ]
- },
- {
- "cell_type": "code",
- "collapsed": false,
- "input": [
- "btn = widgets.ButtonWidget()\n",
- "btn.set_css({\n",
- " 'width': '100px',\n",
- " 'height': '100px',\n",
- " 'background': 'red',\n",
- "})\n",
- "btn"
- ],
- "language": "python",
+ "level": 2,
"metadata": {},
- "outputs": []
- },
- {
- "cell_type": "heading",
- "level": 3,
- "metadata": {
- "slideshow": {
- "slide_type": "slide"
- }
- },
"source": [
- "Removing"
+ "Basic styling"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
- "To remove the styling, you can call `set_css` again, but use an empty string instead of a color value."
+ "The widgets distributed with IPython can be styled by setting the following traits:\n",
+ "\n",
+ "- width \n",
+ "- height \n",
+ "- fore_color \n",
+ "- back_color \n",
+ "- border_color \n",
+ "- border_width \n",
+ "- border_style \n",
+ "- font_style \n",
+ "- font_weight \n",
+ "- font_size \n",
+ "- font_family \n",
+ "\n",
+ "The example below shows how a `Button` widget can be styled:"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
- "btn.set_css('background', '')"
+ "button = widgets.Button(\n",
+ " description='Hello World!',\n",
+ " width=100, # Integers are interpreted as pixel measurements.\n",
+ " height='2em', # em is valid HTML unit of measurement.\n",
+ " color='lime', # Colors can be set by name,\n",
+ " background_color='#0022FF', # and also by color code.\n",
+ " border_color='red')\n",
+ "display(button)"
],
"language": "python",
"metadata": {},
"outputs": []
},
{
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "For more information about what can be done with CSS, please refer to the [Mozilla Developer Network's series on it](https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Getting_started).\n"
- ]
- },
- {
"cell_type": "heading",
"level": 2,
"metadata": {
@@ -224,9 +132,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
- "To display widget A inside widget B, widget A must be a child of widget B. **Only one instance of any particular widget can be child of another (this limitation will be removed in IPython 3.0).** In other words, *widget A* cannot have *widget B* listed twice in it's list of children.\n",
- "\n",
- "Widgets that can contain other widgets have a **`children` attribute**. This attribute can be **set via a keyword argument** in the widget's constructor **or after construction**. Calling display on an **object with children automatically displays those children**, too."
+ "To display widget A inside widget B, widget A must be a child of widget B. Widgets that can contain other widgets have a **`children` attribute**. This attribute can be **set via a keyword argument** in the widget's constructor **or after construction**. Calling display on an **object with children automatically displays those children**, too."
]
},
{
@@ -235,11 +141,13 @@
"input": [
"from IPython.display import display\n",
"\n",
- "float_range = widgets.FloatSliderWidget()\n",
- "string = widgets.TextWidget(value='hi')\n",
- "container = widgets.ContainerWidget(children=[float_range, string])\n",
+ "float_range = widgets.FloatSlider()\n",
+ "string = widgets.Text(value='hi')\n",
+ "container = widgets.Box(children=[float_range, string])\n",
"\n",
- "container.set_css('border', '3px dotted red')\n",
+ "container.border_color = 'red'\n",
+ "container.border_style = 'dotted'\n",
+ "container.border_width = 3\n",
"display(container) # Displays the `container` and all of it's children."
],
"language": "python",
@@ -269,11 +177,13 @@
"cell_type": "code",
"collapsed": false,
"input": [
- "container = widgets.ContainerWidget()\n",
- "container.set_css('border', '3px dotted red')\n",
+ "container = widgets.Box()\n",
+ "container.border_color = 'red'\n",
+ "container.border_style = 'dotted'\n",
+ "container.border_width = 3\n",
"display(container)\n",
"\n",
- "int_range = widgets.IntSliderWidget()\n",
+ "int_range = widgets.IntSlider()\n",
"container.children=[int_range]"
],
"language": "python",
@@ -289,14 +199,14 @@
}
},
"source": [
- "Fancy containers"
+ "Fancy boxes"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
- "If you need to display a more complicated set of widgets, there are **specialized containers** that you can use. To display **multiple sets of widgets**, you can use an **`AccordionWidget` or a `TabWidget` in combination with one `ContainerWidget` per set of widgets** (as seen below). The \"pages\" of these widgets are their children. To set the titles of the pages, one must **call `set_title` after the widget has been displayed**."
+ "If you need to display a more complicated set of widgets, there are **specialized containers** that you can use. To display **multiple sets of widgets**, you can use an **`Accordion` or a `Tab` in combination with one `Box` per set of widgets** (as seen below). The \"pages\" of these widgets are their children. To set the titles of the pages, one must **call `set_title` after the widget has been displayed**."
]
},
{
@@ -304,22 +214,22 @@
"level": 3,
"metadata": {},
"source": [
- "AccordionWidget"
+ "Accordion"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
- "name1 = widgets.TextWidget(description='Location:')\n",
- "zip1 = widgets.BoundedIntTextWidget(description='Zip:', min=0, max=99999)\n",
- "page1 = widgets.ContainerWidget(children=[name1, zip1])\n",
+ "name1 = widgets.Text(description='Location:')\n",
+ "zip1 = widgets.BoundedIntText(description='Zip:', min=0, max=99999)\n",
+ "page1 = widgets.Box(children=[name1, zip1])\n",
"\n",
- "name2 = widgets.TextWidget(description='Location:')\n",
- "zip2 = widgets.BoundedIntTextWidget(description='Zip:', min=0, max=99999)\n",
- "page2 = widgets.ContainerWidget(children=[name2, zip2])\n",
+ "name2 = widgets.Text(description='Location:')\n",
+ "zip2 = widgets.BoundedIntText(description='Zip:', min=0, max=99999)\n",
+ "page2 = widgets.Box(children=[name2, zip2])\n",
"\n",
- "accord = widgets.AccordionWidget(children=[page1, page2])\n",
+ "accord = widgets.Accordion(children=[page1, page2])\n",
"display(accord)\n",
"\n",
"accord.set_title(0, 'From')\n",
@@ -345,15 +255,15 @@
"cell_type": "code",
"collapsed": false,
"input": [
- "name = widgets.TextWidget(description='Name:')\n",
- "color = widgets.DropdownWidget(description='Color:', values=['red', 'orange', 'yellow', 'green', 'blue', 'indigo', 'violet'])\n",
- "page1 = widgets.ContainerWidget(children=[name, color])\n",
+ "name = widgets.Text(description='Name:')\n",
+ "color = widgets.Dropdown(description='Color:', values=['red', 'orange', 'yellow', 'green', 'blue', 'indigo', 'violet'])\n",
+ "page1 = widgets.Box(children=[name, color])\n",
"\n",
- "age = widgets.IntSliderWidget(description='Age:', min=0, max=120, value=50)\n",
- "gender = widgets.RadioButtonsWidget(description='Gender:', values=['male', 'female'])\n",
- "page2 = widgets.ContainerWidget(children=[age, gender])\n",
+ "age = widgets.IntSlider(description='Age:', min=0, max=120, value=50)\n",
+ "gender = widgets.RadioButtons(description='Gender:', values=['male', 'female'])\n",
+ "page2 = widgets.Box(children=[age, gender])\n",
"\n",
- "tabs = widgets.TabWidget(children=[page1, page2])\n",
+ "tabs = widgets.Tab(children=[page1, page2])\n",
"display(tabs)\n",
"\n",
"tabs.set_title(0, 'Name')\n",
@@ -372,22 +282,22 @@
}
},
"source": [
- "PopupWidget"
+ "Popup"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
- "Unlike the other two special containers, the `PopupWidget` is only **designed to display one set of widgets**. The `PopupWidget` can be used to **display widgets outside of the widget area**. "
+ "Unlike the other two special containers, the `Popup` is only **designed to display one set of widgets**. The `Popup` can be used to **display widgets outside of the widget area**. "
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
- "counter = widgets.IntTextWidget(description='Counter:')\n",
- "popup = widgets.PopupWidget(children=[counter], description='Popup Demo', button_text='Popup Button')\n",
+ "counter = widgets.IntText(description='Counter:')\n",
+ "popup = widgets.Popup(children=[counter], description='Popup Demo', button_text='Popup Button')\n",
"display(popup)"
],
"language": "python",
@@ -561,9 +471,9 @@
"cell_type": "code",
"collapsed": false,
"input": [
- "display(widgets.TextWidget(description=\"a:\"))\n",
- "display(widgets.TextWidget(description=\"aa:\"))\n",
- "display(widgets.TextWidget(description=\"aaa:\"))"
+ "display(widgets.Text(description=\"a:\"))\n",
+ "display(widgets.Text(description=\"aa:\"))\n",
+ "display(widgets.Text(description=\"aaa:\"))"
],
"language": "python",
"metadata": {},
@@ -584,10 +494,10 @@
"cell_type": "code",
"collapsed": false,
"input": [
- "display(widgets.TextWidget(description=\"a:\"))\n",
- "display(widgets.TextWidget(description=\"aa:\"))\n",
- "display(widgets.TextWidget(description=\"aaa:\"))\n",
- "display(widgets.TextWidget(description=\"aaaaaaaaaaaaaaaaaa:\"))"
+ "display(widgets.Text(description=\"a:\"))\n",
+ "display(widgets.Text(description=\"aa:\"))\n",
+ "display(widgets.Text(description=\"aaa:\"))\n",
+ "display(widgets.Text(description=\"aaaaaaaaaaaaaaaaaa:\"))"
],
"language": "python",
"metadata": {},
@@ -608,107 +518,10 @@
"cell_type": "code",
"collapsed": false,
"input": [
- "display(widgets.TextWidget(description=\"a:\"))\n",
- "display(widgets.TextWidget(description=\"aa:\"))\n",
- "display(widgets.TextWidget(description=\"aaa:\"))\n",
- "display(widgets.TextWidget())"
- ],
- "language": "python",
- "metadata": {},
- "outputs": []
- },
- {
- "cell_type": "heading",
- "level": 1,
- "metadata": {
- "slideshow": {
- "slide_type": "slide"
- }
- },
- "source": [
- "DOM Classes"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "IPython defines a large number of **DOM (document object model) classes** that you can apply to your widgets. Applying a DOM class causes all of the **CSS associated with that class** to be applied to the element. Classes can be applied and removed using the **`add_class` and `remove_class`** methods **after a widget has been displayed**. The majority of DOM classes defined by IPython are actually **Bootstrap classes**. For more information on Bootstrap classes and CSS, please refer to [Bootstrap's website](http://getbootstrap.com/2.3.2/)."
- ]
- },
- {
- "cell_type": "heading",
- "level": 2,
- "metadata": {
- "slideshow": {
- "slide_type": "slide"
- }
- },
- "source": [
- "Path dependent"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "Both `add_class` and `remove_class` allow you to use **CSS selectors** to pick which sub elements of your widget get styled. Because of this, the `add_class` and `remove_class` methods are **path dependent (order specific)**. The following example shows the **same three calls** made in three **different orders** and the resulting output. **All three differ.**"
- ]
- },
- {
- "cell_type": "code",
- "collapsed": false,
- "input": [
- "%%html\n",
- ""
- ],
- "language": "python",
- "metadata": {},
- "outputs": []
- },
- {
- "cell_type": "code",
- "collapsed": false,
- "input": [
- "from IPython.html import widgets\n",
- "from IPython.display import display\n",
- "html = ' '.join([''.join(['x
' for i in range(8)]) for j in range(8)])\n",
- "widget = [widgets.HTMLWidget(value=html) for i in range(3)]\n",
- "\n",
- "display(widget[0])\n",
- "widget[0].add_class('red', 'div.cube:nth-child(even)')\n",
- "widget[0].remove_class('red', 'div.red:nth-child(7n+1)')\n",
- "widget[0].add_class('blue', 'div.red:nth-child(3n+1)')"
- ],
- "language": "python",
- "metadata": {},
- "outputs": []
- },
- {
- "cell_type": "code",
- "collapsed": false,
- "input": [
- "display(widget[1])\n",
- "widget[1].remove_class('red', 'div.red:nth-child(7n+1)')\n",
- "widget[1].add_class('blue', 'div.red:nth-child(3n+1)')\n",
- "widget[1].add_class('red', 'div.cube:nth-child(even)')"
- ],
- "language": "python",
- "metadata": {},
- "outputs": []
- },
- {
- "cell_type": "code",
- "collapsed": false,
- "input": [
- "display(widget[2])\n",
- "widget[2].add_class('red', 'div.cube:nth-child(even)')\n",
- "widget[2].add_class('blue', 'div.red:nth-child(3n+1)')\n",
- "widget[2].remove_class('red', 'div.red:nth-child(7n+1)')"
+ "display(widgets.Text(description=\"a:\"))\n",
+ "display(widgets.Text(description=\"aa:\"))\n",
+ "display(widgets.Text(description=\"aaa:\"))\n",
+ "display(widgets.Text())"
],
"language": "python",
"metadata": {},
@@ -723,346 +536,14 @@
}
},
"source": [
- "Alignment classes"
+ "Flex boxes"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
- "Widgets can be aligned using IPython **alignment classes**. These classes should work with most widgets, but were **designed to be applied to `ContainerWidget`s**. Examples of these classes follow:"
- ]
- },
- {
- "cell_type": "heading",
- "level": 3,
- "metadata": {},
- "source": [
- "Orientation classes"
- ]
- },
- {
- "cell_type": "heading",
- "level": 4,
- "metadata": {},
- "source": [
- "\"vbox\""
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "Widget containers default to this orientation.\n",
- "\n",
- "
A
\n",
- "
B
\n",
- "
C
\n",
- "
"
- ]
- },
- {
- "cell_type": "heading",
- "level": 4,
- "metadata": {},
- "source": [
- "\"hbox\""
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "\n",
- "
A
\n",
- "
B
\n",
- "
C
\n",
- "
"
- ]
- },
- {
- "cell_type": "heading",
- "level": 3,
- "metadata": {},
- "source": [
- "Packing classes"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "These examples use the **hbox layout** to show packing. Packing is the alignment of the widgets along the the **axis that they are displayed on**."
- ]
- },
- {
- "cell_type": "heading",
- "level": 4,
- "metadata": {},
- "source": [
- "\"start\""
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "\n",
- "
A
\n",
- "
B
\n",
- "
C
\n",
- "
"
- ]
- },
- {
- "cell_type": "heading",
- "level": 4,
- "metadata": {},
- "source": [
- "\"center\""
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "\n",
- "
A
\n",
- "
B
\n",
- "
C
\n",
- "
"
- ]
- },
- {
- "cell_type": "heading",
- "level": 4,
- "metadata": {},
- "source": [
- "\"end\""
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "slideshow": {
- "slide_type": "slide"
- }
- },
- "source": [
- "\n",
- "
A
\n",
- "
B
\n",
- "
C
\n",
- "
"
- ]
- },
- {
- "cell_type": "heading",
- "level": 3,
- "metadata": {},
- "source": [
- "Aligning classes"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "These examples use the **hbox layout** to show alignment. Packing is the alignment of the widgets along the the **axis perpendicular to the one that they are displayed on**."
- ]
- },
- {
- "cell_type": "heading",
- "level": 4,
- "metadata": {},
- "source": [
- "\"align-start\""
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "\n",
- "
A
\n",
- "
B
\n",
- "
C
\n",
- "
"
- ]
- },
- {
- "cell_type": "heading",
- "level": 4,
- "metadata": {},
- "source": [
- "\"align-center\""
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "\n",
- "
A
\n",
- "
B
\n",
- "
C
\n",
- "
"
- ]
- },
- {
- "cell_type": "heading",
- "level": 4,
- "metadata": {},
- "source": [
- "\"align-end\""
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "slideshow": {
- "slide_type": "slide"
- }
- },
- "source": [
- "\n",
- "
A
\n",
- "
B
\n",
- "
C
\n",
- "
"
- ]
- },
- {
- "cell_type": "heading",
- "level": 3,
- "metadata": {},
- "source": [
- "Flex classes"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "To specify **how \"greedy\" a container is** when filling in the remaining space of its parent, the **`box-flexN`** classes are used (where N is 0, 1, or 2). The **higher the value of N, the more greedy** the child is. **`box-flex0` is the default behavior**, which is to not fill the parent."
- ]
- },
- {
- "cell_type": "heading",
- "level": 4,
- "metadata": {},
- "source": [
- "Example 1"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "\n",
- "
box-flex0
\n",
- "
box-flex0
\n",
- "
box-flex0
\n",
- "
"
- ]
- },
- {
- "cell_type": "heading",
- "level": 4,
- "metadata": {},
- "source": [
- "Example 2"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "\n",
- "
box-flex0
\n",
- "
box-flex1
\n",
- "
box-flex0
\n",
- "
"
- ]
- },
- {
- "cell_type": "heading",
- "level": 4,
- "metadata": {},
- "source": [
- "Example 3"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "\n",
- "
box-flex0
\n",
- "
box-flex1
\n",
- "
box-flex1
\n",
- "
"
- ]
- },
- {
- "cell_type": "heading",
- "level": 4,
- "metadata": {},
- "source": [
- "Example 4"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "\n",
- "
box-flex1
\n",
- "
box-flex1
\n",
- "
box-flex1
\n",
- "
"
- ]
- },
- {
- "cell_type": "heading",
- "level": 4,
- "metadata": {},
- "source": [
- "Example 5"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "\n",
- "
box-flex2
\n",
- "
box-flex1
\n",
- "
box-flex1
\n",
- "
"
- ]
- },
- {
- "cell_type": "heading",
- "level": 4,
- "metadata": {},
- "source": [
- "Example 6"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "slideshow": {
- "slide_type": "slide"
- }
- },
- "source": [
- "\n",
- "
box-flex0
\n",
- "
box-flex1
\n",
- "
box-flex2
\n",
- "
"
+ "Widgets can be aligned using the `FlexBox`, `HBox`, and `VBox` widgets."
]
},
{
@@ -1081,17 +562,15 @@
"cell_type": "markdown",
"metadata": {},
"source": [
- "Widget containers **default to vbox** alignment."
+ "Widgets display vertically by default:"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
- "buttons = [widgets.ButtonWidget(description=str(i)) for i in range(3)]\n",
- "\n",
- "container = widgets.ContainerWidget(children=buttons)\n",
- "display(container)"
+ "buttons = [widgets.Button(description=str(i)) for i in range(3)]\n",
+ "display(*buttons)"
],
"language": "python",
"metadata": {},
@@ -1113,17 +592,15 @@
"cell_type": "markdown",
"metadata": {},
"source": [
- "To make a widget container display its widgets horizontally, you need to **remove the `vbox` class** from the container and **add the `hbox` class** in its place."
+ "To make widgets display horizontally, you need to **child them to a `HBox` widget**."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
- "container = widgets.ContainerWidget(children=buttons)\n",
- "display(container)\n",
- "container.remove_class('vbox')\n",
- "container.add_class('hbox')"
+ "container = widgets.HBox(children=buttons)\n",
+ "display(container)"
],
"language": "python",
"metadata": {},
@@ -1133,142 +610,15 @@
"cell_type": "markdown",
"metadata": {},
"source": [
- "By setting the width of the container to 100% and adding the `center` class to it, you can center the buttons."
- ]
- },
- {
- "cell_type": "code",
- "collapsed": false,
- "input": [
- "container.set_css('width', '100%')\n",
- "container.add_class('center')"
- ],
- "language": "python",
- "metadata": {},
- "outputs": []
- },
- {
- "cell_type": "heading",
- "level": 2,
- "metadata": {
- "slideshow": {
- "slide_type": "slide"
- }
- },
- "source": [
- "Style classes"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "In addition to alignment classes, the classes defined by Bootstrap can also be used. This tutorial will only cover a few of the most common classes. For a full list of Bootstrap classes, please refer to [Bootstrap's website](http://getbootstrap.com/2.3.2/)."
- ]
- },
- {
- "cell_type": "heading",
- "level": 3,
- "metadata": {},
- "source": [
- "ButtonWidgets"
- ]
- },
- {
- "cell_type": "code",
- "collapsed": false,
- "input": [
- "# List of the bootstrap button styles\n",
- "classes = [\n",
- " 'btn', \n",
- " 'btn-primary', \n",
- " 'btn-info', \n",
- " 'btn-success', \n",
- " 'btn-warning', \n",
- " 'btn-danger', \n",
- " 'btn-inverse', \n",
- " 'btn-link'\n",
- "]\n",
- "\n",
- "# Display the buttons in a hbox\n",
- "container = widgets.ContainerWidget(children=[widgets.ButtonWidget(description=c) for c in classes])\n",
- "display(container)\n",
- "\n",
- "# Apply classes after display\n",
- "container.remove_class('vbox')\n",
- "container.add_class('hbox')\n",
- "ret = [container.children[i].add_class(c) for i, c in enumerate(classes)]"
- ],
- "language": "python",
- "metadata": {},
- "outputs": []
- },
- {
- "cell_type": "heading",
- "level": 3,
- "metadata": {
- "slideshow": {
- "slide_type": "slide"
- }
- },
- "source": [
- "ContainerWidgets"
- ]
- },
- {
- "cell_type": "code",
- "collapsed": false,
- "input": [
- "def create_label(cls):\n",
- " class_name = widgets.HTMLWidget(value=cls)\n",
- " container = widgets.ContainerWidget(children=[class_name])\n",
- " display(container)\n",
- " container.add_class(cls)\n",
- "\n",
- "ret = [create_label(c) for c in [\n",
- " 'alert', \n",
- " 'alert alert-error', \n",
- " 'alert alert-success', \n",
- " 'alert alert-info'\n",
- "]]"
- ],
- "language": "python",
- "metadata": {},
- "outputs": []
- },
- {
- "cell_type": "heading",
- "level": 3,
- "metadata": {
- "slideshow": {
- "slide_type": "slide"
- }
- },
- "source": [
- "ProgressWidgets"
+ "By setting the width of the container to 100% and its `pack` to `center`, you can center the buttons."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
- "classes = [\n",
- " 'progress-info', \n",
- " 'progress-success', \n",
- " 'progress-warning', \n",
- " 'progress-danger',\n",
- " 'progress-info progress-striped', \n",
- " 'progress-success progress-striped', \n",
- " 'progress-warning progress-striped', \n",
- " 'progress-danger progress-striped',\n",
- " 'active progress-info progress-striped', \n",
- " 'active progress-success progress-striped', \n",
- " 'active progress-warning progress-striped', \n",
- " 'active progress-danger progress-striped',\n",
- "]\n",
- "ws = [widgets.IntProgressWidget(value=50, description=c) for c in classes]\n",
- "ret = [display(w) for w in ws]\n",
- "ret = [ws[i].add_class(c) for i, cs in enumerate(classes) for c in cs.split(' ')]"
+ "container.width = '100%'\n",
+ "container.pack = 'center'"
],
"language": "python",
"metadata": {},
@@ -1298,7 +648,7 @@
"cell_type": "code",
"collapsed": false,
"input": [
- "string = widgets.LatexWidget(value=\"Hello World!\")\n",
+ "string = widgets.Latex(value=\"Hello World!\")\n",
"display(string) "
],
"language": "python",
@@ -1348,17 +698,17 @@
"cell_type": "code",
"collapsed": false,
"input": [
- "form = widgets.ContainerWidget()\n",
- "first = widgets.TextWidget(description=\"First Name:\")\n",
- "last = widgets.TextWidget(description=\"Last Name:\")\n",
+ "form = widgets.VBox()\n",
+ "first = widgets.Text(description=\"First Name:\")\n",
+ "last = widgets.Text(description=\"Last Name:\")\n",
"\n",
- "student = widgets.CheckboxWidget(description=\"Student:\", value=False)\n",
- "school_info = widgets.ContainerWidget(visible=False, children=[\n",
- " widgets.TextWidget(description=\"School:\"),\n",
- " widgets.IntTextWidget(description=\"Grade:\", min=0, max=12)\n",
+ "student = widgets.Checkbox(description=\"Student:\", value=False)\n",
+ "school_info = widgets.VBox(visible=False, children=[\n",
+ " widgets.Text(description=\"School:\"),\n",
+ " widgets.IntText(description=\"Grade:\", min=0, max=12)\n",
" ])\n",
"\n",
- "pet = widgets.TextWidget(description=\"Pet's Name:\")\n",
+ "pet = widgets.Text(description=\"Pet's Name:\")\n",
"form.children = [first, last, student, school_info, pet]\n",
"display(form)\n",
"\n",