Skip to content

Instantly share code, notes, and snippets.

@chronitis
Created July 9, 2014 16:19
Show Gist options
  • Save chronitis/c142d900242b803ffe87 to your computer and use it in GitHub Desktop.
Save chronitis/c142d900242b803ffe87 to your computer and use it in GitHub Desktop.
IntRangeWidget with tuple and scalar traits
"""IntWidget class.
Represents an unbounded int using a widget.
"""
#-----------------------------------------------------------------------------
# Copyright (c) 2013, the IPython Development Team.
#
# Distributed under the terms of the Modified BSD License.
#
# The full license is in the file COPYING.txt, distributed with this software.
#-----------------------------------------------------------------------------
#-----------------------------------------------------------------------------
# Imports
#-----------------------------------------------------------------------------
from .widget import DOMWidget
from IPython.utils.traitlets import Unicode, CInt, Bool, Enum, Tuple, link
#-----------------------------------------------------------------------------
# Classes
#-----------------------------------------------------------------------------
class _IntWidget(DOMWidget):
value = CInt(0, help="Int value", sync=True)
disabled = Bool(False, help="Enable or disable user changes", sync=True)
description = Unicode(help="Description of the value this widget represents", sync=True)
class _BoundedIntWidget(_IntWidget):
step = CInt(1, help="Minimum step that the value can take (ignored by some views)", sync=True)
max = CInt(100, help="Max value", sync=True)
min = CInt(0, help="Min value", sync=True)
def __init__(self, *pargs, **kwargs):
"""Constructor"""
DOMWidget.__init__(self, *pargs, **kwargs)
self.on_trait_change(self._validate, ['value', 'min', 'max'])
def _validate(self, name, old, new):
"""Validate value, max, min."""
if self.min > new or new > self.max:
self.value = min(max(new, self.min), self.max)
class IntTextWidget(_IntWidget):
_view_name = Unicode('IntTextView', sync=True)
class BoundedIntTextWidget(_BoundedIntWidget):
_view_name = Unicode('IntTextView', sync=True)
class IntSliderWidget(_BoundedIntWidget):
_view_name = Unicode('IntSliderView', sync=True)
orientation = Enum([u'horizontal', u'vertical'], u'horizontal',
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)
class IntProgressWidget(_BoundedIntWidget):
_view_name = Unicode('ProgressView', sync=True)
class _IntRangeWidget(_IntWidget):
value = Tuple(CInt, CInt, default_value=(0, 1), help="Low and high int values", sync=True)
lower = CInt(0, help="Lower bound")
upper = CInt(1, help="Upper bound")
def __init__(self, *pargs, **kwargs):
if set(['value', 'lower']) <= set(kwargs) or set(['value', 'upper']) <= set(kwargs):
raise ValueError("Cannot specify both value and (lower, upper) for IntRange")
DOMWidget.__init__(self, *pargs, **kwargs)
def make_closure(targetobj, targetattr, src_pos=None, dest_pos=None):
def update(name, old, new):
if src_pos is None:
value = new
else:
value = new[src_pos]
if dest_pos is None:
setattr(targetobj, targetattr, value)
else:
targetvalue = list(getattr(targetobj, targetattr))
targetvalue[dest_pos] = value
setattr(targetobj, targetattr, tuple(targetvalue))
return update
if 'value' in kwargs:
self.lower, self.upper = self.value
elif 'lower' in kwargs or 'upper' in kwargs:
self.value = self.lower, self.upper
self.on_trait_change(make_closure(self, 'value', dest_pos=0), 'lower')
self.on_trait_change(make_closure(self, 'value', dest_pos=1), 'upper')
self.on_trait_change(make_closure(self, 'lower', src_pos=0), 'value')
self.on_trait_change(make_closure(self, 'upper', src_pos=1), 'value')
class _BoundedIntRangeWidget(_IntRangeWidget):
step = CInt(1, help="Minimum step that the value can take (ignored by some views)", sync=True)
max = CInt(100, help="Max value", sync=True)
min = CInt(0, help="Min value", sync=True)
def __init__(self, *pargs, **kwargs):
"""Constructor"""
_IntRangeWidget.__init__(self, *pargs, **kwargs)
self.on_trait_change(self._validate, ['value', 'min', 'max'])
def _validate(self, name, old, new):
"""Validate min <= low <= high <= max"""
if name == "value":
low, high = new
else:
low, high = self.value
low = max(low, self.min)
high = min(high, self.max)
self.value = (min(low, high), max(low, high))
class IntRangeSliderWidget(_BoundedIntRangeWidget):
_view_name = Unicode('IntSliderView', sync=True)
orientation = Enum([u'horizontal', u'vertical'], u'horizontal',
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)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment