Updated 2018-10-11 20:03:48 by DDG

dgw::combobox

DDG 2018-10-11: A snidget widget which behaves like a normal ttk::combobox but it does also is able to popup the internal listbox and filters the list items by the input given in the entry. The user just must supply the option -hidehits true.

Installation as Tcl-module

Put the file with the source code somewhere in a directory like /home/username/tcl/dgw/combobox-0.1.tm In your code you would now have to write:
 tcl::tm::path add /home/username/tcl
 package require dgw::combobox

See below for the code and an example usage.

SOURCE
 package require Tk 8.5
 package require tile
 package require snit

 namespace eval ::dgw { }

 snit::widget ::dgw::combobox {
    option -values [list]
    # without -hidenohits true
    # we have a normal
    # ttk combobox
    option -hidenohits false
    variable Values
    delegate option * to combo except [list -values -postcommand]
    delegate method * to combo
    component combo
    constructor {args} {
        $self configurelist $args
        install combo using ttk::combobox $win.combo -values $options(-values) \
              -postcommand [mymethod UpdateValues]
        bind $combo <KeyRelease> [mymethod Post %K]        
        bind $combo <Control-space> [mymethod Post %K]
        pack $combo -side top -fill x -expand false
        set Values $options(-values)
    }
    onconfigure -values {vals} {
        set Values $vals
        set options(-values) $vals
        if {[winfo exists $combo]} {
            $combo configure -values $Values
        }
    }
    method UpdateValues {} {
        set text [string map [list {[} {\[} {]} {\]}] [$combo get]]
        $combo configure -values [lsearch -all -inline $Values $text*]
    }
    method Post {key} {
        #puts $key
        if {$options(-hidenohits)} {
            $self UpdateValues
            # save acces to internal function
            if {[string equal [info commands ::ttk::combobox::Post] ::ttk::combobox::Post]} {
                if {$key eq "Return"} { return }
                ::ttk::combobox::Post $combo
                if {$key ne "Down" && [llength [$combo cget -values]] > 1} {
                    after 100 [list focus $combo]
                } elseif {$key eq "Down"} {
                    set lb $combo.popdown.f.l
                    if {[winfo exists $lb]} {
                        after 100 [list focus $lb]
                    }
                }
            }
        }
    }
 }


 package provide dgw::combobox 0.1

 if {$argv0 eq [info script]} {
    wm title . "DGApp"
    pack [label .l0 -text "standard combobox"]
    ttk::combobox .c1 -values [list  done1 done2 dtwo dthree four five six seven]
    pack .c1 -side top
    
    pack [label .l1 -text "combobox with filtering"]
    dgw::combobox .c2 -values [list done1 done2 dtwo dthree four five six seven] \
          -hidenohits true
    
    pack .c2 -side top 
 }