Source code for enaml.widgets.slider

#------------------------------------------------------------------------------
#  Copyright (c) 2013, Enthought, Inc.
#  All rights reserved.
#------------------------------------------------------------------------------
from traits.api import Bool, Enum, Property, Int, Either, Range

from .constraints_widget import PolicyEnum
from .control import Control


[docs]class Slider(Control): """ A simple slider widget that can be used to select from a range of integral values. A `SliderTransform` can be used to transform the integer range of the slider into another data space. For more details, see `enaml.stdlib.slider_transform`. """ #: The minimum slider value. If the minimum value is changed such #: that it becomes greater than the current value or the maximum #: value, then those values will be adjusted. The default is 0. minimum = Property(Int) #: The internal minimum value storage. _minimum = Int(0) #: The maximum slider value. If the maximum value is changed such #: that it becomes smaller than the current value or the minimum #: value, then those values will be adjusted. The default is 100. maximum = Property(Int) #: The internal maximum storage. _maximum = Int(100) #: The position value of the Slider. The value will be clipped to #: always fall between the minimum and maximum. value = Property(Int) #: The internal value storage. _value = Int(0) #: Defines the number of steps that the slider will move when the #: user presses the arrow keys. The default is 1. An upper limit #: may be imposed according the limits of the client widget. single_step = Range(low=1) #: Defines the number of steps that the slider will move when the #: user presses the page_up/page_down keys. The Default is 10. An #: upper limit may be imposed on this value according to the limits #: of the client widget. page_step = Range(low=1, value=10) #: A TickPosition enum value indicating how to display the tick #: marks. Note that the orientation takes precedence over the tick #: mark position and an incompatible tick position will be adapted #: according to the current orientation. The default tick position #: is 'bottom'. tick_position = Enum( 'bottom', ('no_ticks', 'left', 'right', 'top', 'bottom', 'both'), ) #: The interval to place between slider tick marks in units of #: value (as opposed to pixels). The minimum value is 0, which #: indicates that the choice is left up to the client. tick_interval = Range(low=0) #: The orientation of the slider. The default orientation is #: horizontal. When the orientation is flipped the tick positions #: (if set) also adapt to reflect the changes (e.g. the LEFT #: becomes TOP when the orientation becomes horizontal). orientation = Enum('horizontal', 'vertical') #: If True, the value is updated while sliding. Otherwise, it is #: only updated when the slider is released. Defaults to True. tracking = Bool(True) #: Hug width is redefined as a property to be computed based on the #: orientation of the slider unless overridden by the user. hug_width = Property(PolicyEnum, depends_on=['_hug_width', 'orientation']) #: Hug height is redefined as a property to be computed based on the #: orientation of the slider unless overridden by the user. hug_height = Property(PolicyEnum, depends_on=['_hug_height', 'orientation']) #: An internal override trait for hug_width _hug_width = Either(None, PolicyEnum, default=None) #: An internal override trait for hug_height _hug_height = Either(None, PolicyEnum, default=None) #-------------------------------------------------------------------------- # Initialization #--------------------------------------------------------------------------
[docs] def snapshot(self): """ Return a dictionary which contains all the state necessary to initialize a client widget. """ snap = super(Slider, self).snapshot() snap['minimum'] = self.minimum snap['maximum'] = self.maximum snap['value'] = self.value snap['single_step'] = self.single_step snap['page_step'] = self.page_step snap['tick_position'] = self.tick_position snap['tick_interval'] = self.tick_interval snap['orientation'] = self.orientation snap['tracking'] = self.tracking return snap
[docs] def bind(self): """ A method called after initialization which allows the widget to bind any event handlers necessary. """ super(Slider, self).bind() attrs = ( 'minimum', 'maximum', 'value', 'single_step', 'page_step', 'tick_position', 'tick_interval', 'orientation', 'tracking', ) self.publish_attributes(*attrs) #-------------------------------------------------------------------------- # Message Handling #--------------------------------------------------------------------------
[docs] def on_action_value_changed(self, content): """ Handle the 'value_changed' action from the client widget. The content will contain the 'value' of the slider. """ self.set_guarded(value=content['value']) #-------------------------------------------------------------------------- # Property Methods #--------------------------------------------------------------------------
def _get_hug_width(self): """ The property getter for 'hug_width'. Returns a computed hug value unless overridden by the user. """ res = self._hug_width if res is None: if self.orientation == 'horizontal': res = 'ignore' else: res = 'strong' return res def _get_hug_height(self): """ The proper getter for 'hug_height'. Returns a computed hug value unless overridden by the user. """ res = self._hug_height if res is None: if self.orientation == 'vertical': res = 'ignore' else: res = 'strong' return res def _set_hug_width(self, value): """ The property setter for 'hug_width'. Overrides the computed value. """ self._hug_width = value def _set_hug_height(self, value): """ The property setter for 'hug_height'. Overrides the computed value. """ self._hug_height = value def _get_minimum(self): """ The property getter for the slider 'minimum'. """ return self._minimum def _set_minimum(self, minimum): """ The property setter for the 'minimum' attribute. """ # Manually fire the trait change notifications to avoid the # need for property depends_on; this saves memory overhead. # All data is accessed using the private attributes to avoid # inadvertantly triggering the evaluation of a bound Enaml # attribute, which could fool with the state by setting the # value too soon. old_max = self._maximum if minimum > old_max: self._maximum = minimum self.trait_property_changed('maximum', old_max, minimum) old_val = self._value if minimum > old_val: self._value = minimum self.trait_property_changed('value', old_val, minimum) old_min = self._minimum if minimum != old_min: self._minimum = minimum self.trait_property_changed('minimum', old_min, minimum) def _get_maximum(self): """ The property getter for the slider 'maximum'. """ return self._maximum def _set_maximum(self, maximum): """ The property setter for the 'maximum' attribute. """ # Manually fire the trait change notifications to avoid the # need for property depends_on; this saves memory overhead. # All data is accessed using the private attributes to avoid # inadvertantly triggering the evaluation of a bound Enaml # attribute, which could fool with the state by setting the # value too soon. old_min = self._minimum if maximum < old_min: self._minimum = maximum self.trait_property_changed('minimum', old_min, maximum) old_val = self._value if maximum < old_val: self._value = maximum self.trait_property_changed('value', old_val, maximum) old_max = self._maximum if maximum != old_max: self._maximum = maximum self.trait_property_changed('maximum', old_max, maximum) def _get_value(self): """ The property getter for the slider 'value'. """ return self._value def _set_value(self, value): """ The property setter for the 'value' attribute. """ # Manually fire the trait change notifications to avoid the # need for property depends_on; this saves memory overhead. # The minimum and maximum values are explicity accessed through # their property so that any bound Enaml attributes can provide # the proper default value. This ensures that the min and max # are alway up-to-date before potentially clipping the value. old_val = self._value new_val = max(self.minimum, min(self.maximum, value)) if old_val != new_val: self._value = new_val self.trait_property_changed('value', old_val, new_val)