# ----------------------------------------------------------------------
# ListboxQuickSelect --
#
# This command implements quick positioning inside a listbox
# with key press. Each key pressed are buffered for the search.
#
# Typical usage is through binding:
# bind $listbox <KeyPress> "ListboxQuickSelect %W %A"
#
# ----------------------------------------------------------------------
proc ListboxQuickSelect {listbox key} {
upvar 0 ::ListboxQuickSelect:$listbox data
if {[string equal $key ""]} {
# %A substitute non unicode character by empty string
return
}
set sel [$listbox curselection]
if {[llength $sel] > 1} {
# Listbox has more than one selected item
return
}
# Initialize index where search begin
if {[llength $sel] == 1} {
set startIndex [lindex $sel 0]
} else {
set startIndex 0
}
if {[info exists data(searchPrefix)]} {
set searchPrefix $data(searchPrefix)
} else {
set searchPrefix ""
}
if {[string equal -nocase $searchPrefix $key]} {
# User presses twice the same key for the first char.
# Search the next item which begin with that char (handled below).
} else {
append searchPrefix $key
}
# Skip current selected item if searchPrefix is one char
# and selected item starts with this char.
if {[llength $sel] == 1 &&
[string length $searchPrefix] == 1 &&
[string match -nocase "$searchPrefix*" \
[$listbox get $startIndex]]} {
incr startIndex
}
# Now search for searchPrefix after current item,
# and wrap if not found.
foreach {start end} [list $startIndex end 0 $startIndex] {
set index $start
foreach item [$listbox get $start $end] {
if {[string match -nocase "$searchPrefix*" $item]} {
set newSelectedIndex $index
break
}
incr index
}
if {[info exists newSelectedIndex]} {
# We have found a new item, select it and stop search
$listbox selection clear 0 end
$listbox selection set $newSelectedIndex
$listbox see $newSelectedIndex
break
}
}
# Bufferize searchPrefix. Discard it in a small delay
if {[info exists data(afterId)]} {
after cancel $data(afterId)
}
set data(searchPrefix) $searchPrefix
set data(afterId) [after 1000 "unset ::ListboxQuickSelect:$listbox"]
}
# --- Test code ---
package require Tk
set listbox [listbox .listbox]
eval $listbox insert end [lsort [glob -nocomplain -directory / -tail *]]
bind $listbox <KeyPress> {
ListboxQuickSelect %W %A
}
focus $listbox
pack $listboxulis, 2003-05-21: Hugecombo has this functionality implemented. And has also a search-by-pattern implemented.Hugecombo: http://perso.wanadoo.fr/maurice.ulis/tcl/Hugecombo
404 Broken LinkTS - Searching list box entries via entry box (ActiveState Cookbook)
. This code allows users to search the entries in a list box while typing them in an entry box. Easily changeable to search through different indexes of the list entries.MHo - See Listbox navigation by keyboard
