Show More
@@ -53,7 +53,7 b' define(["widgets/js/widget"], function(WidgetManager){' | |||||
53 | if (options === undefined || options.updated_view != this) { |
|
53 | if (options === undefined || options.updated_view != this) { | |
54 | // JQuery slider option keys. These keys happen to have a |
|
54 | // JQuery slider option keys. These keys happen to have a | |
55 | // one-to-one mapping with the corrosponding keys of the model. |
|
55 | // one-to-one mapping with the corrosponding keys of the model. | |
56 | var jquery_slider_keys = ['step', 'max', 'min', 'disabled']; |
|
56 | var jquery_slider_keys = ['step', 'max', 'min', 'disabled', 'range']; | |
57 | var that = this; |
|
57 | var that = this; | |
58 | _.each(jquery_slider_keys, function(key, i) { |
|
58 | _.each(jquery_slider_keys, function(key, i) { | |
59 | var model_value = that.model.get(key); |
|
59 | var model_value = that.model.get(key); | |
@@ -72,11 +72,21 b' define(["widgets/js/widget"], function(WidgetManager){' | |||||
72 | // consistent. |
|
72 | // consistent. | |
73 | var orientation = this.model.get('orientation'); |
|
73 | var orientation = this.model.get('orientation'); | |
74 | var value = this.model.get('min'); |
|
74 | var value = this.model.get('min'); | |
|
75 | if (this.model.get('range')) { | |||
|
76 | this.$slider.slider('option', 'values', [value, value]); | |||
|
77 | } else { | |||
75 | this.$slider.slider('option', 'value', value); |
|
78 | this.$slider.slider('option', 'value', value); | |
|
79 | } | |||
76 | this.$slider.slider('option', 'orientation', orientation); |
|
80 | this.$slider.slider('option', 'orientation', orientation); | |
77 | value = this.model.get('value'); |
|
81 | value = this.model.get('value'); | |
|
82 | if (this.model.get('range')) { | |||
|
83 | this.$slider.slider('option', 'values', value); | |||
|
84 | this.$readout.text(value.join("-")); | |||
|
85 | } else { | |||
78 | this.$slider.slider('option', 'value', value); |
|
86 | this.$slider.slider('option', 'value', value); | |
79 | this.$readout.text(value); |
|
87 | this.$readout.text(value); | |
|
88 | } | |||
|
89 | ||||
80 |
|
90 | |||
81 | // Use the right CSS classes for vertical & horizontal sliders |
|
91 | // Use the right CSS classes for vertical & horizontal sliders | |
82 | if (orientation=='vertical') { |
|
92 | if (orientation=='vertical') { | |
@@ -137,10 +147,16 b' define(["widgets/js/widget"], function(WidgetManager){' | |||||
137 |
|
147 | |||
138 |
// Calling model.set will trigger all of the other views of the |
|
148 | // Calling model.set will trigger all of the other views of the | |
139 | // model to update. |
|
149 | // model to update. | |
|
150 | if (this.model.get("range")) { | |||
|
151 | var actual_value = ui.values.map(this._validate_slide_value); | |||
|
152 | this.$readout.text(actual_value.join("-")); | |||
|
153 | } else { | |||
140 | var actual_value = this._validate_slide_value(ui.value); |
|
154 | var actual_value = this._validate_slide_value(ui.value); | |
141 | this.model.set('value', actual_value, {updated_view: this}); |
|
|||
142 | this.$readout.text(actual_value); |
|
155 | this.$readout.text(actual_value); | |
|
156 | } | |||
|
157 | this.model.set('value', actual_value, {updated_view: this}); | |||
143 | this.touch(); |
|
158 | this.touch(); | |
|
159 | ||||
144 | }, |
|
160 | }, | |
145 |
|
161 | |||
146 | _validate_slide_value: function(x) { |
|
162 | _validate_slide_value: function(x) { |
@@ -5,7 +5,7 b' from .widget_button import ButtonWidget' | |||||
5 | from .widget_container import ContainerWidget, PopupWidget |
|
5 | from .widget_container import ContainerWidget, PopupWidget | |
6 | from .widget_float import FloatTextWidget, BoundedFloatTextWidget, FloatSliderWidget, FloatProgressWidget |
|
6 | from .widget_float import FloatTextWidget, BoundedFloatTextWidget, FloatSliderWidget, FloatProgressWidget | |
7 | from .widget_image import ImageWidget |
|
7 | from .widget_image import ImageWidget | |
8 | from .widget_int import IntTextWidget, BoundedIntTextWidget, IntSliderWidget, IntProgressWidget |
|
8 | from .widget_int import IntTextWidget, BoundedIntTextWidget, IntSliderWidget, IntProgressWidget, IntRangeSliderWidget | |
9 | from .widget_selection import RadioButtonsWidget, ToggleButtonsWidget, DropdownWidget, SelectWidget |
|
9 | from .widget_selection import RadioButtonsWidget, ToggleButtonsWidget, DropdownWidget, SelectWidget | |
10 | from .widget_selectioncontainer import TabWidget, AccordionWidget |
|
10 | from .widget_selectioncontainer import TabWidget, AccordionWidget | |
11 | from .widget_string import HTMLWidget, LatexWidget, TextWidget, TextareaWidget |
|
11 | from .widget_string import HTMLWidget, LatexWidget, TextWidget, TextareaWidget |
@@ -23,7 +23,7 b' from inspect import getcallargs' | |||||
23 | from IPython.core.getipython import get_ipython |
|
23 | from IPython.core.getipython import get_ipython | |
24 | from IPython.html.widgets import (Widget, TextWidget, |
|
24 | from IPython.html.widgets import (Widget, TextWidget, | |
25 | FloatSliderWidget, IntSliderWidget, CheckboxWidget, DropdownWidget, |
|
25 | FloatSliderWidget, IntSliderWidget, CheckboxWidget, DropdownWidget, | |
26 | ContainerWidget, DOMWidget) |
|
26 | ContainerWidget, DOMWidget, IntRangeSliderWidget) | |
27 | from IPython.display import display, clear_output |
|
27 | from IPython.display import display, clear_output | |
28 | from IPython.utils.py3compat import string_types, unicode_type |
|
28 | from IPython.utils.py3compat import string_types, unicode_type | |
29 | from IPython.utils.traitlets import HasTraits, Any, Unicode |
|
29 | from IPython.utils.traitlets import HasTraits, Any, Unicode | |
@@ -107,6 +107,15 b' def _widget_abbrev(o):' | |||||
107 | else: |
|
107 | else: | |
108 | cls = FloatSliderWidget |
|
108 | cls = FloatSliderWidget | |
109 | return cls(value=value, min=min, max=max, step=step) |
|
109 | return cls(value=value, min=min, max=max, step=step) | |
|
110 | elif _matches(o, [float_or_int]*4): | |||
|
111 | min, low, high, max = o | |||
|
112 | if not min <= low <= high <= max: | |||
|
113 | raise ValueError("Range input expects min <= low <= high <= max, got %r" % o) | |||
|
114 | if all(isinstance(_, int) for _ in o): | |||
|
115 | cls = IntRangeSliderWidget | |||
|
116 | else: | |||
|
117 | cls = FloatRangeSliderWidget | |||
|
118 | return cls(value=(low, high), min=min, max=max) | |||
110 | else: |
|
119 | else: | |
111 | return _widget_abbrev_single_value(o) |
|
120 | return _widget_abbrev_single_value(o) | |
112 |
|
121 |
@@ -14,7 +14,7 b' Represents an unbounded int using a widget.' | |||||
14 | # Imports |
|
14 | # Imports | |
15 | #----------------------------------------------------------------------------- |
|
15 | #----------------------------------------------------------------------------- | |
16 | from .widget import DOMWidget |
|
16 | from .widget import DOMWidget | |
17 | from IPython.utils.traitlets import Unicode, CInt, Bool, Enum |
|
17 | from IPython.utils.traitlets import Unicode, CInt, Bool, Enum, Tuple | |
18 |
|
18 | |||
19 | #----------------------------------------------------------------------------- |
|
19 | #----------------------------------------------------------------------------- | |
20 | # Classes |
|
20 | # Classes | |
@@ -53,8 +53,38 b' class IntSliderWidget(_BoundedIntWidget):' | |||||
53 | _view_name = Unicode('IntSliderView', sync=True) |
|
53 | _view_name = Unicode('IntSliderView', sync=True) | |
54 |
orientation = Enum([u'horizontal', u'vertical'], u'horizontal', |
|
54 | orientation = Enum([u'horizontal', u'vertical'], u'horizontal', | |
55 | help="Vertical or horizontal.", sync=True) |
|
55 | help="Vertical or horizontal.", sync=True) | |
|
56 | range = Bool(False, help="Display a range selector", sync=True) | |||
56 | readout = Bool(True, help="Display the current value of the slider next to it.", sync=True) |
|
57 | readout = Bool(True, help="Display the current value of the slider next to it.", sync=True) | |
57 |
|
58 | |||
58 |
|
59 | |||
59 | class IntProgressWidget(_BoundedIntWidget): |
|
60 | class IntProgressWidget(_BoundedIntWidget): | |
60 | _view_name = Unicode('ProgressView', sync=True) |
|
61 | _view_name = Unicode('ProgressView', sync=True) | |
|
62 | ||||
|
63 | class _IntRangeWidget(_IntWidget): | |||
|
64 | value = Tuple(CInt, CInt, default_value=(0, 1), help="Low and high int values", sync=True) | |||
|
65 | ||||
|
66 | class _BoundedIntRangeWidget(_IntRangeWidget): | |||
|
67 | step = CInt(1, help="Minimum step that the value can take (ignored by some views)", sync=True) | |||
|
68 | max = CInt(100, help="Max value", sync=True) | |||
|
69 | min = CInt(0, help="Min value", sync=True) | |||
|
70 | ||||
|
71 | def __init__(self, *pargs, **kwargs): | |||
|
72 | """Constructor""" | |||
|
73 | DOMWidget.__init__(self, *pargs, **kwargs) | |||
|
74 | self.on_trait_change(self._validate, ['value', 'min', 'max']) | |||
|
75 | ||||
|
76 | def _validate(self, name, old, new): | |||
|
77 | """Validate min <= low <= high <= max""" | |||
|
78 | if name == "value": | |||
|
79 | low, high = new | |||
|
80 | low = max(low, self.min) | |||
|
81 | high = min(high, self.max) | |||
|
82 | self.value = (min(low, high), max(low, high)) | |||
|
83 | ||||
|
84 | ||||
|
85 | class IntRangeSliderWidget(_BoundedIntRangeWidget): | |||
|
86 | _view_name = Unicode('IntSliderView', sync=True) | |||
|
87 | orientation = Enum([u'horizontal', u'vertical'], u'horizontal', | |||
|
88 | help="Vertical or horizontal.", sync=True) | |||
|
89 | range = Bool(True, help="Display a range selector", sync=True) | |||
|
90 | readout = Bool(True, help="Display the current value of the slider next to it.", sync=True) |
General Comments 0
You need to be logged in to leave comments.
Login now