Richard Suchenwirth 2000-12-21: This was originally part of my not-yet wikified sandbox, then isolated out into
Turtleshell, but since it is a pretty self-contained thingy, here it comes by itself: a history mechanism for
entry widgets, now in its own namespace.
Description edit
On creating an entry, you just prepend the word(s)
history::for:
history::for entry .e -textvar foo
Your entry will be created with all its args, and in addition you get the following key bindings:
- Cursor up: move one item up in history, display
- Cursor down: move one item down, display (empty after last)
- Page down: move immediately to end of history (i.e. empty)
- Return: append entry content to end of history, if not empty or identical with last
NB: When the user adds another binding (e.g. for <Return>), he
must start it with a + sign, otherwise the history binding gets lost. But I wanted to concentrate all in the
history::for command, which does the creation and the bindings, so user-defined bindings come after history's. Each entry's history is kept in a separate variable
history::$widgetname, so you can have more than one around.
namespace eval history {
proc add? {w} {
variable $w
variable n$w
upvar 0 $w hist
set s [set ::[$w cget -textvariable]]
if {$s == ""} return
if [string compare $s [lindex $hist end]] {
lappend hist $s
set n$w [llength $hist]
}
}
proc move {w where} {
variable $w
variable n$w
upvar 0 $w hist
incr n$w $where
if {[set n$w]<0} {set n$w 0}
if {[set n$w]>=[llength $hist]+1} {
set n$w [llength $hist]
}
set ::[$w cget -textvar] [lindex $hist [set n$w]]
}
proc for {type name args} {
switch -- $type {
entry {
uplevel $type $name $args
bind $name <Up> {history::move %W -1}
bind $name <Down> {history::move %W 1}
bind $name <Next> {history::move %W 99999}
bind $name <Return> {history::add? %W}
variable $name {}
variable n$name 0
}
default {error "usage: history::for entry <w> <args>"}
}
}
}
Test and demo code:
history::for entry .1 -textvar foo
history::for entry .2 -textvar bar
pack .1 .2
bind .1 <Return> {+ puts [string tolower $foo];set foo ""}
bind .2 <Return> {+ puts [string toupper $bar]; set bar ""}
Also see
GWM Undo and Redo undoable widgets for a general method of adding a history and undo/redo functionality to all widgets (not just entry widgets but tbuttons, menus...).