diff options
Diffstat (limited to 'Lib/lib-stdwin/Sliders.py')
-rw-r--r-- | Lib/lib-stdwin/Sliders.py | 215 |
1 files changed, 106 insertions, 109 deletions
diff --git a/Lib/lib-stdwin/Sliders.py b/Lib/lib-stdwin/Sliders.py index b142ef4..f655e77 100644 --- a/Lib/lib-stdwin/Sliders.py +++ b/Lib/lib-stdwin/Sliders.py @@ -1,13 +1,11 @@ # Module 'Sliders' -# -# XXX Should split caller interface, appearance and reactivity better import stdwin from stdwinevents import * import rect from Buttons import * -from Resize import * +from HVSplit import HSplit # Field indices in event detail @@ -18,11 +16,13 @@ _BUTTON = 2 _MASK = 3 -# A dragslider is the simplest possible slider. +# DragSlider is the simplest possible slider. # It looks like a button but dragging the mouse left or right # changes the controlled value. +# It does not support any of the triggers or hooks defined by Buttons, +# but defines its own setval_trigger and setval_hook. # -class DragSliderReactivity() = NoReactivity(): +class DragSliderReactivity() = BaseReactivity(): # def mouse_down(self, detail): h, v = hv = detail[_HV] @@ -43,136 +43,133 @@ class DragSliderReactivity() = NoReactivity(): self.active = 0 # -class DragSliderAppearance() = NoResize(), ButtonAppearance(): - # - def define(self, (win, bounds)): - self.min = 0 - self.val = -1 # Changed by next setval call - self.max = 100 - self.setval_hook = 0 - self.pretext = self.postext = '' - self = ClassicButton.define(self, (win, bounds, '')) - self.setval(50) - return self +class DragSliderAppearance() = ButtonAppearance(): # # INVARIANTS maintained by the setval method: # # self.min <= self.val <= self.max # self.text = self.pretext + `self.val` + self.postext # - # (Notice that unlike in Python ranges, the end point belongs + # (Notice that unlike Python ranges, the end point belongs # to the range.) # + def init_appearance(self): + ButtonAppearance.init_appearance(self) + self.min = 0 + self.val = 0 + self.max = 100 + self.hook = 0 + self.pretext = self.postext = '' + self.recalctext() + # + # The 'get*' and 'set*' methods belong to the generic slider interface + # + def getval(self): return self.val + # + def sethook(self, hook): + self.hook = hook + # + def setminvalmax(self, (min, val, max)): + self.min = min + self.max = max + self.setval(val) + # + def settexts(self, (pretext, postext)): + self.pretext = pretext + self.postext = postext + self.recalctext() + # def setval(self, val): val = min(self.max, max(self.min, val)) if val <> self.val: self.val = val - self.setval_trigger() - # (The trigger may change val, pretext and postext) - self.settext(self.pretext + `self.val` + self.postext) + self.recalctext() + self.trigger() + # + def trigger(self): + if self.hook: + self.hook(self) # - def setval_trigger(self): - if self.setval_hook: - self.setval_hook(self) + def recalctext(self): + self.settext(self.pretext + `self.val` + self.postext) # -class DragSlider() = DragSliderReactivity(), DragSliderAppearance(): pass +class DragSlider() = DragSliderReactivity(), DragSliderAppearance(), Define(): + def definetext(self, (parent, text)): + raise RuntimeError, 'DragSlider.definetext() not supported' -# Auxiliary class for DragSlider incorporated in ComplexSlider +# Auxiliary class for PushButton incorporated in ComplexSlider # -class _SubDragSlider() = DragSlider(): - def define(self, (win, bounds, parent)): - self.parent = parent - return DragSlider.define(self, (win, bounds)) - def setval_trigger(self): - self.parent.val = self.val - self.parent.setval_trigger() - -# Auxiliary class for ClassicButton incorporated in ComplexSlider -# -class _SubClassicButton() = ClassicButton(): - def define(self, (win, bounds, text, step, parent)): - self.parent = parent +class _StepButton() = PushButton(): + def define(self, parent): + self = PushButton.define(self, parent) + self.step = 0 + return self + def setstep(self, step): self.step = step - return ClassicButton.define(self, (win, bounds, text)) + def definetextstep(self, (parent, text, step)): + self = self.definetext(parent, text) + self.setstep(step) + return self + def init_reactivity(self): + PushButton.init_reactivity(self) + self.parent.need_timer(self) + def step_trigger(self): + self.parent.setval(self.parent.getval() + self.step) def down_trigger(self): - self.parent.setval(self.parent.val + self.step) - self.delay = 5 - self.win.settimer(self.delay) - def move_trigger(self): - self.win.settimer(self.delay) - def timer_trigger(self): - self.delay = 1 - self.parent.setval(self.parent.val + self.step) - self.win.settimer(self.delay) + self.step_trigger() + self.parent.settimer(5) + def timer(self): + if self.hilited: + self.step_trigger() + if self.active: + self.parent.settimer(1) -# A complex slider is a wrapper around three buttons: -# One to step down, a dragslider, and one to step up. + +# A complex slider is an HSplit initialized to three buttons: +# one to step down, a dragslider, and one to step up. # -class ComplexSlider() = NoResize(), LabelAppearance(), NoReactivity(): +class ComplexSlider() = HSplit(): # - def define(self, (win, bounds)): - # - self.win = win - self.bounds = bounds - self.setval_hook = 0 - # - (left, top), (right, bottom) = bounds - size = bottom - top - # - downbox = (left, top), (left+size, bottom) - sliderbox = (left+size, top), (right-size, bottom) - upbox = (right-size, top), (right, bottom) - # - self.downbutton = \ - _SubClassicButton().define(win, downbox, '-', -1, self) - # - self.sliderbutton = \ - _SubDragSlider().define(win, sliderbox, self) - # - self.upbutton = \ - _SubClassicButton().define(win, upbox, '+', 1, self) - # - self.min = self.sliderbutton.min - self.val = self.sliderbutton.val - self.max = self.sliderbutton.max - self.pretext = self.sliderbutton.pretext - self.postext = self.sliderbutton.postext + # Override Slider define() method + # + def define(self, parent): + self = self.create(parent) # HSplit # - self.children = \ - [self.downbutton, self.sliderbutton, self.upbutton] + self.downbutton = _StepButton().definetextstep(self, '-', -1) + self.dragbutton = DragSlider().define(self) + self.upbutton = _StepButton().definetextstep(self, '+', 1) # return self # - def mouse_down(self, detail): - for b in self.children: - b.mouse_down(detail) + # Override HSplit methods # - def mouse_move(self, detail): - for b in self.children: - b.mouse_move(detail) - # - def mouse_up(self, detail): - for b in self.children: - b.mouse_up(detail) - # - def timer(self): - for b in self.children: - b.timer() - # - def draw(self, area): - for b in self.children: - b.draw(area) - # - def setval(self, val): - self.sliderbutton.min = self.min - self.sliderbutton.max = self.max - self.sliderbutton.pretext = self.pretext - self.sliderbutton.postext = self.postext - self.sliderbutton.setval(val) - # - def setval_trigger(self): - if self.setval_hook: - self.setval_hook(self) + def minsize(self, m): + w1, h1 = self.downbutton.minsize(m) + w2, h2 = self.dragbutton.minsize(m) + w3, h3 = self.upbutton.minsize(m) + height = max(h1, h2, h3) + w1 = max(w1, height) + w3 = max(w3, height) + return w1+w2+w3, height # + def setbounds(self, bounds): + (left, top), (right, bottom) = self.bounds = bounds + size = bottom - top + self.downbutton.setbounds((left, top), (left+size, bottom)) + self.dragbutton.setbounds((left+size, top), \ + (right-size, bottom)) + self.upbutton.setbounds((right-size, top), (right, bottom)) + # + # Pass other Slider methods on to dragbutton + # + def getval(self): return self.dragbutton.getval() + def sethook(self, hook): self.dragbutton.sethook(hook) + def setminvalmax(self, args): self.dragbutton.setminvalmax(args) + def settexts(self, args): self.dragbutton.settexts(args) + def setval(self, val): self.dragbutton.setval(val) + def enable(self, flag): + self.downbutton.enable(flag) + self.dragbutton.enable(flag) + self.upbutton.enable(flag) |