[Richard Suchenwirth] 2002-08-17 - The [BWidget] package is a set of powerful megawidgets written in pure Tcl. Examination of the source code shows that it is easy to add functionality which can be called in Tk's object-oriented way: if you provide a proc ''Class::command'', where ''class'' is one of BWidget's widget classes, calls to a widget of that class with that command will be dispatched to your "method", e.g. proc Foo::grill {w ...} {...} Foo .bar .bar grill args ;# calls Foo::grill .bar args I employ this simple protocol to extend ComboBoxes for two typical use cases (to appear in [starDOM]): * a "history", where previous inputs are recorded in the list of values used as a stack - the last input is on top (just below a blank field for new random input); * a "chooser" where you can only select one of the pre-defined alternatives (basically just a reconfiguration). } package require BWidget namespace eval ComboBox {#needed to extend BWidget functionality} proc ComboBox::enable {w what args} { switch -- $what { history { $w configure -values {{}} ;# always keep a blank on top foreach evt { } { $w bind $evt {+ ComboBox::_add %W [%W cget -text]} } } chooser { set values [$w cget -values] set width 0 foreach i $values { set sl [string length $i] if {$sl > $width} {set width $sl} } set bg [[label .dummy] cget -bg] destroy .dummy $w setvalue first $w configure -width [expr {$width+1}] $w configure -editable 0 -relief flat -entrybg $bg ;# (1) } } if {$args != ""} {eval [list $w configure] $args} } # This "internal" function is underscore-prefixed: proc ComboBox::_add {w item} { set w [winfo parent $w] ;# binding comes from entry set values [$w cget -values] if {[lsearch -exact $values $item] < 0} { $w configure -values [linsert $values 1 $item] } } #------------------------------------------- Test and demo code: if {[file tail [info script]]==[file tail $argv0]} { ComboBox .c -label "Search " -textvariable query .c bind {puts [list search -$mode $query]} .c enable history ComboBox .m -values {case nocase regexp XPath} -textvariable mode .m enable chooser pack .c .m -side left bind . {exec wish $argv0 &; exit} bind . ? {console show} } #(1) I first had "grey" there which looks ok on Win 95, but not on Win2k. The better way is to read the default background from another widget (".dummy" above), which is only used to cget its setting, and immediately destroyed. ---- [TR] - a method of enhancing [BWidget]s look and feel for different platforms is the usage of customized bindings and the [option] database. Making the BWidget combobox behave more Windows-like, the selected element in the dropdown listbox should follow the mouse and the active element drawn with a dotbox around it. Here's how: option add *Listbox.activeStyle dotbox startupFile bind Listbox { %W selection clear 0 end %W selection set @%x,%y %W activate @%x,%y } This applies to all listboxes in the application though ... --- [FW]: It looks like the follow feature has since been added to the package, so now you can skip all but the first line of that and just use ''-hottrack 1'' in your combobox declaration.