Source code for enaml.widgets.slider

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

from enaml.core.trait_types import Bounded

from .constraints_widget import PolicyEnum
from .control import Control


#: The slider attributes to proxy to clients
_SLIDER_ATTRS = [
    'maximum', 'minimum', 'orientation', 'page_step', 'single_step',
    'tick_interval', 'tick_position', 'tracking', 'value'
]


#: The maximum slider value. Somewhat arbitrary, but the limit in Qt.
MAX_SLIDER_VALUE = (1 << 16) - 1


[docs]class Slider(Control): """ A simple slider widget that can be used to select from a range of integral values. """ #: The minimum value for the slider. To avoid issues where #: :attr:`minimum` is higher than :attr:`maximum`. The value is #: a positive integer capped by the :attr:`maximum`. If the new #: value of :attr:`minimum` make the current position invalid then #: the current position is set to :attr:minimum. Default value is 0. minimum = Property(Int, depends_on ='_minimum') #: The internal minimum storage. _minimum = Int(0) #: The maximum value for the slider. Checks make sure that #: :attr:`maximum` cannot be lower than :attr:`minimum`. If the #: new value of :attr:`maximum` make the current position invalid #: then the current position is set to :attr:maximum. The max value #: is restricted to 65535, while the default is 100. maximum = Property(Int, depends_on ='_maximum') #: The internal maximum storage. _maximum = Int(100) #: The position value of the Slider. The bounds are defined by #: :attr:minimum: and :attr:maximum:. value = Bounded(low='minimum', high='maximum') #: 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() for attr in _SLIDER_ATTRS: snap[attr] = getattr(self, attr) 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() self.publish_attributes(*_SLIDER_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, value): """ The property setter for the 'minimum' attribute. This validates that the value is always smaller than :attr:`maximum`. """ if value > self.maximum: msg = ('The minimum value of the slider should be smaller ' 'than the current maximum ({0}), but a value of {1} ' 'was given') msg = msg.format(self.maximum, value) raise TraitError(msg) else: self._minimum = value def _get_maximum(self): """ The property getter for the slider 'maximum'. """ return self._maximum def _set_maximum(self, value): """ The property setter for the 'maximum' attribute. This validates that the value is always larger than :attr:`minimum`. """ if (value < self.minimum) or (value > MAX_SLIDER_VALUE): msg = ('The maximum value of the slider should be larger ' 'than the current minimum ({0}) and less than the ' 'maximum slider value ({1}), but a value of {2} ' 'was given') msg = msg.format(self.minimum, MAX_SLIDER_VALUE, value) raise TraitError(msg) else: self._maximum = value #-------------------------------------------------------------------------- # Private API #-------------------------------------------------------------------------- @on_trait_change('minimum, maximum') def _adapt_value(self): """ Adapt the value to the min/max boundaries. """ self.value = min(max(self.value, self.minimum), self.maximum)