dgw::combobox

dgw::combobox

DDG 2018-10-11: A snidget widget which behaves like a normal ttk::combobox but it 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 
 }

img_dgw-combobox