Generalizations.

This commit is contained in:
Guido van Rossum 1990-10-25 18:50:27 +00:00
parent f49ef1cad0
commit ceae528b9f
2 changed files with 188 additions and 198 deletions

View file

@ -1,8 +1,4 @@
# Module 'Buttons' -- see README # Module 'Buttons'
#
# Module functionality is now split in two parts:
# - 'appearance' defines what it looks like
# - 'reactivity' defines how it acts to mouse events
# Import module 'rect' renamed as '_rect' # Import module 'rect' renamed as '_rect'
@ -20,32 +16,42 @@ _BUTTON = 2
_MASK = 3 _MASK = 3
# BaseAppearance provides defaults for all appearance methods. # LabelAppearance provides defaults for all appearance methods.
# In fact it looks like a label. # selected state not visible
# disabled --> crossed out
# hilited --> inverted
# #
class BaseAppearance(): class LabelAppearance():
# #
# Initialization # Initialization
# #
def init_appearance(self, (win, bounds)): def init_appearance(self, (win, bounds)):
win.change(bounds)
self.win = win self.win = win
self.bounds = bounds self.bounds = bounds
self.enabled = 1 self.enabled = 1
self.hilited = 0 self.hilited = 0
self.selected = 0 self.selected = 0
self.text = '' self.text = ''
self.limbo = 1
self.recalc()
self.win.change(self.bounds)
# While the limbo flag is set, redraw calls are ignored.
# It is cleared by the first draw event.
# This is intended to avoid duplicate drawing during
# initialization.
# #
# Changing the parameters # Changing the parameters
# #
def settext(self, text): def settext(self, text):
self.text = text self.text = text
self.recalctextpos()
self.redraw() self.redraw()
# #
def setbounds(self, bounds): def setbounds(self, bounds):
# This elays drawing until after all buttons are moved # This delays drawing until after all buttons are moved
self.win.change(self.bounds) self.win.change(self.bounds)
self.bounds = bounds self.bounds = bounds
self.recalc()
self.win.change(bounds) self.win.change(bounds)
# #
# Changing the state bits # Changing the state bits
@ -53,25 +59,54 @@ class BaseAppearance():
def enable(self, flag): def enable(self, flag):
if flag <> self.enabled: if flag <> self.enabled:
self.enabled = flag self.enabled = flag
self.flipenable(self.win.begindrawing()) if not self.limbo:
self.flipenable(self.win.begindrawing())
# #
def hilite(self, flag): def hilite(self, flag):
if flag <> self.hilited: if flag <> self.hilited:
self.hilited = flag self.hilited = flag
self.fliphilite(self.win.begindrawing()) if not self.limbo:
self.fliphilite(self.win.begindrawing())
# #
def select(self, flag): def select(self, flag):
if flag <> self.selected: if flag <> self.selected:
self.selected = flag self.selected = flag
self.redraw() self.redraw()
# #
# Recalculate the box bounds and text position.
# This can be overridden by buttons that draw different boxes
# or want their text in a different position.
#
def recalc(self):
self.recalcbounds()
self.recalctextpos()
#
def recalcbounds(self):
self.hilitebounds = _rect.inset(self.bounds, (3, 3))
self.crossbounds = self.bounds
#
def recalctextpos(self):
(left, top), (right, bottom) = self.bounds
d = self.win.begindrawing()
h = (left + right - d.textwidth(self.text)) / 2
v = (top + bottom - d.lineheight()) / 2
self.textpos = h, v
#
# Resize method.
# Override for widgets that take over window geomtry management.
#
def resize(self):
pass
#
# Generic drawing mechanism. # Generic drawing mechanism.
# There should be no reason to override redraw() or draw() methods. # Do not override redraw() or draw() methods; override drawit() c.s.
# #
def redraw(self): def redraw(self):
self.draw(self.win.begindrawing(), self.bounds) if not self.limbo:
self.draw(self.win.begindrawing(), self.bounds)
# #
def draw(self, (d, area)): def draw(self, (d, area)):
self.limbo = 0
area = _rect.intersect(area, self.bounds) area = _rect.intersect(area, self.bounds)
if area = _rect.empty: if area = _rect.empty:
return return
@ -83,10 +118,9 @@ class BaseAppearance():
# The drawit() method is fairly generic but may be overridden. # The drawit() method is fairly generic but may be overridden.
# #
def drawit(self, d): def drawit(self, d):
self.drawpict(d) # Box, circle etc.; also 'selected' self.drawpict(d)
if self.text: if self.text:
hv = self.textpos(d) d.text(self.textpos, self.text)
d.text(hv, self.text)
if not self.enabled: if not self.enabled:
self.flipenable(d) self.flipenable(d)
if self.hilited: if self.hilited:
@ -95,52 +129,15 @@ class BaseAppearance():
# Default drawing detail functions. # Default drawing detail functions.
# Overriding these is normally sufficient to get different # Overriding these is normally sufficient to get different
# appearances. # appearances.
# No picture; centered text; enable crosses out; hilite inverts.
# #
def drawpict(self, d): def drawpict(self, d):
pass pass
# #
def textpos(self, d):
# XXX shouldn't this be done once by init/settext()?
(left, top), (right, bottom) = self.bounds
h = (left + right - d.textwidth(self.text)) / 2
v = (top + bottom - d.lineheight()) / 2
return h, v
#
def flipenable(self, d): def flipenable(self, d):
_xorcross(d, self.bounds) _xorcross(d, self.crossbounds)
# #
def fliphilite(self, d): def fliphilite(self, d):
d.invert(_rect.inset(self.bounds, (3, 3))) d.invert(self.hilitebounds)
# Subroutine to cross out a rectangle.
#
def _xorcross(d, bounds):
((left, top), (right, bottom)) = bounds
left = left + 2
right = right - 2
top = top + 2
bottom = bottom - 3
d.xorline(((left, top), (right, bottom)))
d.xorline((left, bottom), (right, top))
# LabelAppearance displays a centered string.
# selected --> underlined
# disabled --> crossed out
# hilited --> inverted
#
class LabelAppearance() = BaseAppearance():
#
def drawpict(self, d):
if self.selected:
# Underline it
d.line((left+1, bottom-1), (right-1, bottom-1))
#
if not self.enabled: self._crossout(d)
if self.hilited: self._invert(d)
#
# ButtonAppearance displays a centered string in a box. # ButtonAppearance displays a centered string in a box.
@ -148,7 +145,7 @@ class LabelAppearance() = BaseAppearance():
# disabled --> crossed out # disabled --> crossed out
# hilited --> inverted # hilited --> inverted
# #
class ButtonAppearance() = BaseAppearance(): class ButtonAppearance() = LabelAppearance():
# #
def drawpict(self, d): def drawpict(self, d):
d.box(_rect.inset(self.bounds, (1, 1))) d.box(_rect.inset(self.bounds, (1, 1)))
@ -165,27 +162,25 @@ class ButtonAppearance() = BaseAppearance():
# disabled --> whole button crossed out # disabled --> whole button crossed out
# hilited --> box is inverted # hilited --> box is inverted
# #
class CheckAppearance() = BaseAppearance(): class CheckAppearance() = LabelAppearance():
# #
def drawpict(self, d): def drawpict(self, d):
(left, top), (right, bottom) = self.bounds d.box(self.boxbounds)
size = bottom - top if self.selected: _xorcross(d, self.boxbounds)
boxbounds = (left, top), (left+size, bottom)
d.box(boxbounds)
if self.selected: _xorcross(d, boxbounds)
# #
def textpos(self, d): def recalcbounds(self):
LabelAppearance.recalcbounds(self)
(left, top), (right, bottom) = self.bounds (left, top), (right, bottom) = self.bounds
size = bottom - top self.size = bottom - top - 4
h = left + size + d.textwidth(' ') self.boxbounds = (left+2, top+2), (left+2+self.size, bottom-2)
v = top + (size - d.lineheight()) / 2 self.hilitebounds = self.boxbounds
return h, v
# #
def fliphilite(self, d): def recalctextpos(self):
(left, top), (right, bottom) = self.bounds d = self.win.begindrawing()
size = bottom - top (left, top), (right, bottom) = self.boxbounds
boxbounds = (left, top), (left+size, bottom) h = right + d.textwidth(' ')
d.invert(boxbounds) v = top + (self.size - d.lineheight()) / 2
self.textpos = h, v
# #
@ -194,37 +189,24 @@ class CheckAppearance() = BaseAppearance():
# disabled --> whole button crossed out # disabled --> whole button crossed out
# hilited --> indicator is inverted # hilited --> indicator is inverted
# #
class RadioAppearance() = BaseAppearance(): class RadioAppearance() = CheckAppearance():
# #
def drawpict(self, d): def drawpict(self, d):
(left, top), (right, bottom) = self.bounds (left, top), (right, bottom) = self.boxbounds
size = bottom - top radius = self.size / 2
radius = size / 2
h, v = left + radius, top + radius h, v = left + radius, top + radius
d.circle((h, v), radius - 1) d.circle((h, v), radius)
if self.selected: if self.selected:
some = radius/3 some = radius/3
d.paint((h-some, v-some), (h+some, v+some)) d.paint((h-some, v-some), (h+some, v+some))
# #
def textpos(self, d):
(left, top), (right, bottom) = self.bounds
size = bottom - top
h = left + size + d.textwidth(' ')
v = top + (size - d.lineheight()) / 2
return h, v
#
def fliphilite(self, d):
(left, top), (right, bottom) = self.bounds
size = bottom - top
d.invert((left, top), (left + size, bottom))
#
# NoReactivity ignores mouse and timer events. # NoReactivity ignores mouse and timer events.
# The trigger methods call the corresponding hooks set by the user. # The trigger methods call the corresponding hooks set by the user.
# Hooks (and triggers) mean the following: # Hooks (and triggers) mean the following:
# down_hook called on some mouse-down events # down_hook called on some mouse-down events
# active_hook called on some mouse-move events # move_hook called on some mouse-move events
# up_hook called on mouse-up events # up_hook called on mouse-up events
# on_hook called for buttons with on/off state, when it goes on # on_hook called for buttons with on/off state, when it goes on
# timer_hook called on timer events # timer_hook called on timer events
@ -235,7 +217,7 @@ class RadioAppearance() = BaseAppearance():
class NoReactivity(): class NoReactivity():
# #
def init_reactivity(self): def init_reactivity(self):
self.down_hook = self.active_hook = self.up_hook = \ self.down_hook = self.move_hook = self.up_hook = \
self.on_hook = self.off_hook = self.timer_hook = \ self.on_hook = self.off_hook = self.timer_hook = \
self.hook = self.active = 0 self.hook = self.active = 0
# #
@ -257,8 +239,8 @@ class NoReactivity():
def down_trigger(self): def down_trigger(self):
if self.down_hook: self.down_hook(self) if self.down_hook: self.down_hook(self)
# #
def active_trigger(self): def move_trigger(self):
if self.active_hook: self.active_hook(self) if self.move_hook: self.move_hook(self)
# #
def up_trigger(self): def up_trigger(self):
if self.up_hook: self.up_hook(self) if self.up_hook: self.up_hook(self)
@ -290,7 +272,7 @@ class ToggleReactivity() = NoReactivity():
# #
def mouse_move(self, detail): def mouse_move(self, detail):
if self.active: if self.active:
self.active_trigger() self.move_trigger()
# #
def mouse_up(self, detail): def mouse_up(self, detail):
if self.active: if self.active:
@ -325,7 +307,7 @@ class TriggerReactivity() = NoReactivity():
if self.active: if self.active:
self.hilite(self.mousetest(detail[_HV])) self.hilite(self.mousetest(detail[_HV]))
if self.hilited: if self.hilited:
self.active_trigger() self.move_trigger()
# #
def mouse_up(self, detail): def mouse_up(self, detail):
if self.active: if self.active:
@ -338,7 +320,7 @@ class TriggerReactivity() = NoReactivity():
# #
def timer(self): def timer(self):
if self.active and self.hilited: if self.active and self.hilited:
self.active_trigger() self.timer_trigger()
# #
@ -382,14 +364,27 @@ class Define():
# #
def define(self, (win, bounds, text)): def define(self, (win, bounds, text)):
self.init_appearance(win, bounds) self.init_appearance(win, bounds)
self.text = text
self.init_reactivity() self.init_reactivity()
self.settext(text)
return self return self
# Subroutine to cross out a rectangle.
#
def _xorcross(d, bounds):
((left, top), (right, bottom)) = bounds
# This is s bit funny to make it look better
left = left + 2
right = right - 2
top = top + 2
bottom = bottom - 3
d.xorline(((left, top), (right, bottom)))
d.xorline((left, bottom), (right, top))
# Ready-made button classes # Ready-made button classes
# #
class BaseButton() = NoReactivity(), BaseAppearance(), Define(): pass class BaseButton() = NoReactivity(), LabelAppearance(), Define(): pass
class Label() = NoReactivity(), LabelAppearance(), Define(): pass class Label() = NoReactivity(), LabelAppearance(), Define(): pass
class ClassicButton() = TriggerReactivity(), ButtonAppearance(), Define(): pass class ClassicButton() = TriggerReactivity(), ButtonAppearance(), Define(): pass
class CheckButton() = CheckReactivity(), CheckAppearance(), Define(): pass class CheckButton() = CheckReactivity(), CheckAppearance(), Define(): pass

View file

@ -1,8 +1,4 @@
# Module 'Buttons' -- see README # Module 'Buttons'
#
# Module functionality is now split in two parts:
# - 'appearance' defines what it looks like
# - 'reactivity' defines how it acts to mouse events
# Import module 'rect' renamed as '_rect' # Import module 'rect' renamed as '_rect'
@ -20,32 +16,42 @@ _BUTTON = 2
_MASK = 3 _MASK = 3
# BaseAppearance provides defaults for all appearance methods. # LabelAppearance provides defaults for all appearance methods.
# In fact it looks like a label. # selected state not visible
# disabled --> crossed out
# hilited --> inverted
# #
class BaseAppearance(): class LabelAppearance():
# #
# Initialization # Initialization
# #
def init_appearance(self, (win, bounds)): def init_appearance(self, (win, bounds)):
win.change(bounds)
self.win = win self.win = win
self.bounds = bounds self.bounds = bounds
self.enabled = 1 self.enabled = 1
self.hilited = 0 self.hilited = 0
self.selected = 0 self.selected = 0
self.text = '' self.text = ''
self.limbo = 1
self.recalc()
self.win.change(self.bounds)
# While the limbo flag is set, redraw calls are ignored.
# It is cleared by the first draw event.
# This is intended to avoid duplicate drawing during
# initialization.
# #
# Changing the parameters # Changing the parameters
# #
def settext(self, text): def settext(self, text):
self.text = text self.text = text
self.recalctextpos()
self.redraw() self.redraw()
# #
def setbounds(self, bounds): def setbounds(self, bounds):
# This elays drawing until after all buttons are moved # This delays drawing until after all buttons are moved
self.win.change(self.bounds) self.win.change(self.bounds)
self.bounds = bounds self.bounds = bounds
self.recalc()
self.win.change(bounds) self.win.change(bounds)
# #
# Changing the state bits # Changing the state bits
@ -53,25 +59,54 @@ class BaseAppearance():
def enable(self, flag): def enable(self, flag):
if flag <> self.enabled: if flag <> self.enabled:
self.enabled = flag self.enabled = flag
self.flipenable(self.win.begindrawing()) if not self.limbo:
self.flipenable(self.win.begindrawing())
# #
def hilite(self, flag): def hilite(self, flag):
if flag <> self.hilited: if flag <> self.hilited:
self.hilited = flag self.hilited = flag
self.fliphilite(self.win.begindrawing()) if not self.limbo:
self.fliphilite(self.win.begindrawing())
# #
def select(self, flag): def select(self, flag):
if flag <> self.selected: if flag <> self.selected:
self.selected = flag self.selected = flag
self.redraw() self.redraw()
# #
# Recalculate the box bounds and text position.
# This can be overridden by buttons that draw different boxes
# or want their text in a different position.
#
def recalc(self):
self.recalcbounds()
self.recalctextpos()
#
def recalcbounds(self):
self.hilitebounds = _rect.inset(self.bounds, (3, 3))
self.crossbounds = self.bounds
#
def recalctextpos(self):
(left, top), (right, bottom) = self.bounds
d = self.win.begindrawing()
h = (left + right - d.textwidth(self.text)) / 2
v = (top + bottom - d.lineheight()) / 2
self.textpos = h, v
#
# Resize method.
# Override for widgets that take over window geomtry management.
#
def resize(self):
pass
#
# Generic drawing mechanism. # Generic drawing mechanism.
# There should be no reason to override redraw() or draw() methods. # Do not override redraw() or draw() methods; override drawit() c.s.
# #
def redraw(self): def redraw(self):
self.draw(self.win.begindrawing(), self.bounds) if not self.limbo:
self.draw(self.win.begindrawing(), self.bounds)
# #
def draw(self, (d, area)): def draw(self, (d, area)):
self.limbo = 0
area = _rect.intersect(area, self.bounds) area = _rect.intersect(area, self.bounds)
if area = _rect.empty: if area = _rect.empty:
return return
@ -83,10 +118,9 @@ class BaseAppearance():
# The drawit() method is fairly generic but may be overridden. # The drawit() method is fairly generic but may be overridden.
# #
def drawit(self, d): def drawit(self, d):
self.drawpict(d) # Box, circle etc.; also 'selected' self.drawpict(d)
if self.text: if self.text:
hv = self.textpos(d) d.text(self.textpos, self.text)
d.text(hv, self.text)
if not self.enabled: if not self.enabled:
self.flipenable(d) self.flipenable(d)
if self.hilited: if self.hilited:
@ -95,52 +129,15 @@ class BaseAppearance():
# Default drawing detail functions. # Default drawing detail functions.
# Overriding these is normally sufficient to get different # Overriding these is normally sufficient to get different
# appearances. # appearances.
# No picture; centered text; enable crosses out; hilite inverts.
# #
def drawpict(self, d): def drawpict(self, d):
pass pass
# #
def textpos(self, d):
# XXX shouldn't this be done once by init/settext()?
(left, top), (right, bottom) = self.bounds
h = (left + right - d.textwidth(self.text)) / 2
v = (top + bottom - d.lineheight()) / 2
return h, v
#
def flipenable(self, d): def flipenable(self, d):
_xorcross(d, self.bounds) _xorcross(d, self.crossbounds)
# #
def fliphilite(self, d): def fliphilite(self, d):
d.invert(_rect.inset(self.bounds, (3, 3))) d.invert(self.hilitebounds)
# Subroutine to cross out a rectangle.
#
def _xorcross(d, bounds):
((left, top), (right, bottom)) = bounds
left = left + 2
right = right - 2
top = top + 2
bottom = bottom - 3
d.xorline(((left, top), (right, bottom)))
d.xorline((left, bottom), (right, top))
# LabelAppearance displays a centered string.
# selected --> underlined
# disabled --> crossed out
# hilited --> inverted
#
class LabelAppearance() = BaseAppearance():
#
def drawpict(self, d):
if self.selected:
# Underline it
d.line((left+1, bottom-1), (right-1, bottom-1))
#
if not self.enabled: self._crossout(d)
if self.hilited: self._invert(d)
#
# ButtonAppearance displays a centered string in a box. # ButtonAppearance displays a centered string in a box.
@ -148,7 +145,7 @@ class LabelAppearance() = BaseAppearance():
# disabled --> crossed out # disabled --> crossed out
# hilited --> inverted # hilited --> inverted
# #
class ButtonAppearance() = BaseAppearance(): class ButtonAppearance() = LabelAppearance():
# #
def drawpict(self, d): def drawpict(self, d):
d.box(_rect.inset(self.bounds, (1, 1))) d.box(_rect.inset(self.bounds, (1, 1)))
@ -165,27 +162,25 @@ class ButtonAppearance() = BaseAppearance():
# disabled --> whole button crossed out # disabled --> whole button crossed out
# hilited --> box is inverted # hilited --> box is inverted
# #
class CheckAppearance() = BaseAppearance(): class CheckAppearance() = LabelAppearance():
# #
def drawpict(self, d): def drawpict(self, d):
(left, top), (right, bottom) = self.bounds d.box(self.boxbounds)
size = bottom - top if self.selected: _xorcross(d, self.boxbounds)
boxbounds = (left, top), (left+size, bottom)
d.box(boxbounds)
if self.selected: _xorcross(d, boxbounds)
# #
def textpos(self, d): def recalcbounds(self):
LabelAppearance.recalcbounds(self)
(left, top), (right, bottom) = self.bounds (left, top), (right, bottom) = self.bounds
size = bottom - top self.size = bottom - top - 4
h = left + size + d.textwidth(' ') self.boxbounds = (left+2, top+2), (left+2+self.size, bottom-2)
v = top + (size - d.lineheight()) / 2 self.hilitebounds = self.boxbounds
return h, v
# #
def fliphilite(self, d): def recalctextpos(self):
(left, top), (right, bottom) = self.bounds d = self.win.begindrawing()
size = bottom - top (left, top), (right, bottom) = self.boxbounds
boxbounds = (left, top), (left+size, bottom) h = right + d.textwidth(' ')
d.invert(boxbounds) v = top + (self.size - d.lineheight()) / 2
self.textpos = h, v
# #
@ -194,37 +189,24 @@ class CheckAppearance() = BaseAppearance():
# disabled --> whole button crossed out # disabled --> whole button crossed out
# hilited --> indicator is inverted # hilited --> indicator is inverted
# #
class RadioAppearance() = BaseAppearance(): class RadioAppearance() = CheckAppearance():
# #
def drawpict(self, d): def drawpict(self, d):
(left, top), (right, bottom) = self.bounds (left, top), (right, bottom) = self.boxbounds
size = bottom - top radius = self.size / 2
radius = size / 2
h, v = left + radius, top + radius h, v = left + radius, top + radius
d.circle((h, v), radius - 1) d.circle((h, v), radius)
if self.selected: if self.selected:
some = radius/3 some = radius/3
d.paint((h-some, v-some), (h+some, v+some)) d.paint((h-some, v-some), (h+some, v+some))
# #
def textpos(self, d):
(left, top), (right, bottom) = self.bounds
size = bottom - top
h = left + size + d.textwidth(' ')
v = top + (size - d.lineheight()) / 2
return h, v
#
def fliphilite(self, d):
(left, top), (right, bottom) = self.bounds
size = bottom - top
d.invert((left, top), (left + size, bottom))
#
# NoReactivity ignores mouse and timer events. # NoReactivity ignores mouse and timer events.
# The trigger methods call the corresponding hooks set by the user. # The trigger methods call the corresponding hooks set by the user.
# Hooks (and triggers) mean the following: # Hooks (and triggers) mean the following:
# down_hook called on some mouse-down events # down_hook called on some mouse-down events
# active_hook called on some mouse-move events # move_hook called on some mouse-move events
# up_hook called on mouse-up events # up_hook called on mouse-up events
# on_hook called for buttons with on/off state, when it goes on # on_hook called for buttons with on/off state, when it goes on
# timer_hook called on timer events # timer_hook called on timer events
@ -235,7 +217,7 @@ class RadioAppearance() = BaseAppearance():
class NoReactivity(): class NoReactivity():
# #
def init_reactivity(self): def init_reactivity(self):
self.down_hook = self.active_hook = self.up_hook = \ self.down_hook = self.move_hook = self.up_hook = \
self.on_hook = self.off_hook = self.timer_hook = \ self.on_hook = self.off_hook = self.timer_hook = \
self.hook = self.active = 0 self.hook = self.active = 0
# #
@ -257,8 +239,8 @@ class NoReactivity():
def down_trigger(self): def down_trigger(self):
if self.down_hook: self.down_hook(self) if self.down_hook: self.down_hook(self)
# #
def active_trigger(self): def move_trigger(self):
if self.active_hook: self.active_hook(self) if self.move_hook: self.move_hook(self)
# #
def up_trigger(self): def up_trigger(self):
if self.up_hook: self.up_hook(self) if self.up_hook: self.up_hook(self)
@ -290,7 +272,7 @@ class ToggleReactivity() = NoReactivity():
# #
def mouse_move(self, detail): def mouse_move(self, detail):
if self.active: if self.active:
self.active_trigger() self.move_trigger()
# #
def mouse_up(self, detail): def mouse_up(self, detail):
if self.active: if self.active:
@ -325,7 +307,7 @@ class TriggerReactivity() = NoReactivity():
if self.active: if self.active:
self.hilite(self.mousetest(detail[_HV])) self.hilite(self.mousetest(detail[_HV]))
if self.hilited: if self.hilited:
self.active_trigger() self.move_trigger()
# #
def mouse_up(self, detail): def mouse_up(self, detail):
if self.active: if self.active:
@ -338,7 +320,7 @@ class TriggerReactivity() = NoReactivity():
# #
def timer(self): def timer(self):
if self.active and self.hilited: if self.active and self.hilited:
self.active_trigger() self.timer_trigger()
# #
@ -382,14 +364,27 @@ class Define():
# #
def define(self, (win, bounds, text)): def define(self, (win, bounds, text)):
self.init_appearance(win, bounds) self.init_appearance(win, bounds)
self.text = text
self.init_reactivity() self.init_reactivity()
self.settext(text)
return self return self
# Subroutine to cross out a rectangle.
#
def _xorcross(d, bounds):
((left, top), (right, bottom)) = bounds
# This is s bit funny to make it look better
left = left + 2
right = right - 2
top = top + 2
bottom = bottom - 3
d.xorline(((left, top), (right, bottom)))
d.xorline((left, bottom), (right, top))
# Ready-made button classes # Ready-made button classes
# #
class BaseButton() = NoReactivity(), BaseAppearance(), Define(): pass class BaseButton() = NoReactivity(), LabelAppearance(), Define(): pass
class Label() = NoReactivity(), LabelAppearance(), Define(): pass class Label() = NoReactivity(), LabelAppearance(), Define(): pass
class ClassicButton() = TriggerReactivity(), ButtonAppearance(), Define(): pass class ClassicButton() = TriggerReactivity(), ButtonAppearance(), Define(): pass
class CheckButton() = CheckReactivity(), CheckAppearance(), Define(): pass class CheckButton() = CheckReactivity(), CheckAppearance(), Define(): pass