2
# $Id: repeater.tcl 11708 2007-02-12 23:01:19Z shyouhei $
4
# Demonstration of custom classes.
6
# The Tile button doesn't have built-in support for autorepeat.
7
# Instead of adding -repeatdelay and -repeatinterval options,
8
# and all the extra binding scripts required to deal with them,
9
# we create a custom widget class for autorepeating buttons.
12
# ttk::button .b -class Repeater [... other options ...]
15
# Use system settings for repeat interval and initial delay.
18
# Repeater buttons work more like scrollbar arrows than
19
# Tk repeating buttons: they fire once immediately when
20
# first pressed, and $State(delay) specifies the initial
21
# interval before the button starts autorepeating.
24
namespace eval tile::Repeater {
26
set State(timer) {} ;# [after] id of repeat script
27
set State(interval) 100 ;# interval between repetitions
28
set State(delay) 300 ;# delay after initial invocation
34
bind Repeater <Enter> { %W state active }
35
bind Repeater <Leave> { %W state !active }
37
bind Repeater <Key-space> { tile::Repeater::Activate %W }
38
bind Repeater <<Invoke>> { tile::Repeater::Activate %W }
40
bind Repeater <ButtonPress-1> { tile::Repeater::Press %W }
41
bind Repeater <ButtonRelease-1> { tile::Repeater::Release %W }
42
bind Repeater <B1-Leave> { tile::Repeater::Pause %W }
43
bind Repeater <B1-Enter> { tile::Repeater::Resume %W } ;# @@@ see below
45
# @@@ Workaround for metacity-induced bug:
46
bind Repeater <B1-Enter> \
47
{ if {"%d" ne "NotifyUngrab"} { tile::Repeater::Resume %W } }
49
### Binding procedures.
52
## Activate -- Keyboard activation binding.
53
# Simulate clicking the button, and invoke the command once.
55
proc tile::Repeater::Activate {w} {
56
$w instate disabled { return }
57
set oldState [$w state pressed]
58
update idletasks; after 100
60
after idle [list $w invoke]
63
## Press -- ButtonPress-1 binding.
64
# Invoke the command once and start autorepeating after
65
# $State(delay) milliseconds.
67
proc tile::Repeater::Press {w} {
69
$w instate disabled { return }
72
after cancel $State(timer)
73
set State(timer) [after $State(delay) [list tile::Repeater::Repeat $w]]
76
## Release -- ButtonRelease binding.
79
proc tile::Repeater::Release {w} {
82
after cancel $State(timer)
85
## Pause -- B1-Leave binding
86
# Temporarily suspend autorepeat.
88
proc tile::Repeater::Pause {w} {
91
after cancel $State(timer)
94
## Resume -- B1-Enter binding
97
proc tile::Repeater::Resume {w} {
99
$w instate disabled { return }
102
after cancel $State(timer)
103
set State(timer) [after $State(interval) [list tile::Repeater::Repeat $w]]
106
## Repeat -- Timer script
107
# Invoke the command and reschedule another repetition
108
# after $State(interval) milliseconds.
110
proc tile::Repeater::Repeat {w} {
112
$w instate disabled { return }
114
set State(timer) [after $State(interval) [list tile::Repeater::Repeat $w]]