##// END OF EJS Templates
Add initial implementation of 2-handle range sliders for integers.
Gordon Ball -
Show More
@@ -53,7 +53,7 b' define(["widgets/js/widget"], function(WidgetManager){'
53 53 if (options === undefined || options.updated_view != this) {
54 54 // JQuery slider option keys. These keys happen to have a
55 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 57 var that = this;
58 58 _.each(jquery_slider_keys, function(key, i) {
59 59 var model_value = that.model.get(key);
@@ -72,11 +72,21 b' define(["widgets/js/widget"], function(WidgetManager){'
72 72 // consistent.
73 73 var orientation = this.model.get('orientation');
74 74 var value = this.model.get('min');
75 if (this.model.get('range')) {
76 this.$slider.slider('option', 'values', [value, value]);
77 } else {
75 78 this.$slider.slider('option', 'value', value);
79 }
76 80 this.$slider.slider('option', 'orientation', orientation);
77 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 86 this.$slider.slider('option', 'value', value);
79 87 this.$readout.text(value);
88 }
89
80 90
81 91 // Use the right CSS classes for vertical & horizontal sliders
82 92 if (orientation=='vertical') {
@@ -137,10 +147,16 b' define(["widgets/js/widget"], function(WidgetManager){'
137 147
138 148 // Calling model.set will trigger all of the other views of the
139 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 154 var actual_value = this._validate_slide_value(ui.value);
141 this.model.set('value', actual_value, {updated_view: this});
142 155 this.$readout.text(actual_value);
156 }
157 this.model.set('value', actual_value, {updated_view: this});
143 158 this.touch();
159
144 160 },
145 161
146 162 _validate_slide_value: function(x) {
@@ -5,7 +5,7 b' from .widget_button import ButtonWidget'
5 5 from .widget_container import ContainerWidget, PopupWidget
6 6 from .widget_float import FloatTextWidget, BoundedFloatTextWidget, FloatSliderWidget, FloatProgressWidget
7 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 9 from .widget_selection import RadioButtonsWidget, ToggleButtonsWidget, DropdownWidget, SelectWidget
10 10 from .widget_selectioncontainer import TabWidget, AccordionWidget
11 11 from .widget_string import HTMLWidget, LatexWidget, TextWidget, TextareaWidget
@@ -23,7 +23,7 b' from inspect import getcallargs'
23 23 from IPython.core.getipython import get_ipython
24 24 from IPython.html.widgets import (Widget, TextWidget,
25 25 FloatSliderWidget, IntSliderWidget, CheckboxWidget, DropdownWidget,
26 ContainerWidget, DOMWidget)
26 ContainerWidget, DOMWidget, IntRangeSliderWidget)
27 27 from IPython.display import display, clear_output
28 28 from IPython.utils.py3compat import string_types, unicode_type
29 29 from IPython.utils.traitlets import HasTraits, Any, Unicode
@@ -107,6 +107,15 b' def _widget_abbrev(o):'
107 107 else:
108 108 cls = FloatSliderWidget
109 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 119 else:
111 120 return _widget_abbrev_single_value(o)
112 121
@@ -14,7 +14,7 b' Represents an unbounded int using a widget.'
14 14 # Imports
15 15 #-----------------------------------------------------------------------------
16 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 20 # Classes
@@ -53,8 +53,38 b' class IntSliderWidget(_BoundedIntWidget):'
53 53 _view_name = Unicode('IntSliderView', sync=True)
54 54 orientation = Enum([u'horizontal', u'vertical'], u'horizontal',
55 55 help="Vertical or horizontal.", sync=True)
56 range = Bool(False, help="Display a range selector", sync=True)
56 57 readout = Bool(True, help="Display the current value of the slider next to it.", sync=True)
57 58
58 59
59 60 class IntProgressWidget(_BoundedIntWidget):
60 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