1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202
|
#------------------------------------------------------------------------------
# Copyright (c) 2013-2025, Nucleic Development Team.
#
# Distributed under the terms of the Modified BSD License.
#
# The full license is in the file LICENSE, distributed with this software.
#------------------------------------------------------------------------------
from atom.api import Bool, Enum, Int, Range, Typed, ForwardTyped
from enaml.core.declarative import d_, observe
from .control import Control, ProxyControl
#: The base tick position enum definition.
TickPosition = Enum('no_ticks', 'left', 'right', 'top', 'bottom', 'both')
class ProxySlider(ProxyControl):
""" The abstract definition of a proxy Slider object.
"""
#: A reference to the Slider declaration.
declaration = ForwardTyped(lambda: Slider)
def set_minimum(self, minimum):
raise NotImplementedError
def set_maximum(self, maximum):
raise NotImplementedError
def set_value(self, value):
raise NotImplementedError
def set_single_step(self, step):
raise NotImplementedError
def set_page_step(self, step):
raise NotImplementedError
def set_tick_position(self, position):
raise NotImplementedError
def set_tick_interval(self, interval):
raise NotImplementedError
def set_orientation(self, orientation):
raise NotImplementedError
def set_tracking(self, tracking):
raise NotImplementedError
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 = d_(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 = d_(Int(100))
#: The position value of the Slider. The value will be clipped to
#: always fall between the minimum and maximum.
value = d_(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 = d_(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 = d_(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 = d_(TickPosition('bottom'))
#: 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 = d_(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 = d_(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 = d_(Bool(True))
#: Whether or not to automatically adjust the 'hug_width' and
#: 'hug_height' values based on the value of 'orientation'.
auto_hug = d_(Bool(True))
#: A reference to the ProxySlider object.
proxy = Typed(ProxySlider)
#--------------------------------------------------------------------------
# Observers
#--------------------------------------------------------------------------
@observe('minimum', 'maximum', 'value', 'single_step', 'page_step',
'tick_position', 'tick_interval', 'orientation', 'tracking')
def _update_proxy(self, change):
""" An observer which sends state change to the proxy.
"""
# The superclass handler implementation is sufficient.
super(Slider, self)._update_proxy(change)
#--------------------------------------------------------------------------
# DefaultValue Handlers
#--------------------------------------------------------------------------
def _default_hug_width(self):
""" Get the default hug width for the separator.
The default hug width is computed based on the orientation.
"""
if self.orientation == 'horizontal':
return 'ignore'
return 'strong'
def _default_hug_height(self):
""" Get the default hug height for the separator.
The default hug height is computed based on the orientation.
"""
if self.orientation == 'vertical':
return 'ignore'
return 'strong'
#--------------------------------------------------------------------------
# PostSetAttr Handlers
#--------------------------------------------------------------------------
def _post_setattr_orientation(self, old, new):
""" Post setattr the orientation for the tool bar.
If auto hug is enabled, the hug values will be updated.
"""
if self.auto_hug:
if new == 'vertical':
self.hug_width = 'strong'
self.hug_height = 'ignore'
else:
self.hug_width = 'ignore'
self.hug_height = 'strong'
def _post_setattr_minimum(self, old, new):
""" Post setattr the minimum value for the slider.
If the new minimum is greater than the current value or maximum,
those values are adjusted up.
"""
if new > self.maximum:
self.maximum = new
if new > self.value:
self.value = new
def _post_setattr_maximum(self, old, new):
""" Post setattr the maximum value for the slider.
If the new maximum is less than the current value or the minimum,
those values are adjusted down.
"""
if new < self.minimum:
self.minimum = new
if new < self.value:
self.value = new
#--------------------------------------------------------------------------
# Post Validation Handlers
#--------------------------------------------------------------------------
def _post_validate_value(self, old, new):
""" Post validate the value for the slider.
The value is clipped to minimum and maximum bounds.
"""
return max(self.minimum, min(new, self.maximum))
|