Version 0 of snitfinddialog

Updated 2003-11-20 08:47:48

DDG: Tired of writing again and again those clumsy find dialogs. I wrapped all into a snit toplevel widget.

 # NAME snitfinddialog
 #    snitfindialog path ?args?
 #   snitfilendialog provides a standard find dialog layout
 #   all buttons and the entries are accessable via the componnet subcommand
 #   the components are: find, next (standard tk buttons), entry (standard tk entry)
 #   delegated is -textvariable to the entry component
 #   all other options must be send via the component subcommand
 #   -findcmd The command to invoke if "Find" is pressed.
 #   -findnextcmd The command to invoke if "Find Next" is pressed.
 #   -case Case sensitivity of search either true or false. Defaults to false.
 #   -word Matches whole words only true or false. Defaults to false.
 #   -forward Forward (true) or backward (false) searches. Defaults to true.
 #   pathName component componentname ?args?
 #      without args it returns the component path to be saved inside a variable
 #      with args it evaluates args in the context of the component 
 #      if the first argument of args is bind a binding for the component is created 
 #    Dr. Detlef Groth [email protected]
 #    20/11/2003 Version 0.1 initial release

--- And here is the actual code about 60 lines:

 snit::widget snitfinddialog {
    hulltype toplevel
    delegate option -findcmd to component(find) as -command
    delegate option -findnextcmd to component(next) as -command
    delegate option -textvariable to component(entry)
    option -case 0
    option -word 0
    option -forward yes
    variable component
    constructor {args} {
        wm resizable $win false false
        pack [frame $win.left] -side left -padx 5 -pady 5 -ipadx 5 -ipady 5 \
                  -expand yes -fill both
        pack [frame $win.right] -side left -padx 5 -pady 5 -ipadx 5 -ipady 5 \
                  -expand yes -fill both
        pack [button $ -text " Find " -width 15] -side top \
                  -padx 5 -pady 8
        set component(find) $
        pack [button $win.right.searchnext -text " Find Next " -width 15] \
                  -side top -padx 5 -pady 12
        set component(next) $win.right.searchnext
        pack [entry $win.left.entry] -side top -padx 5 -pady 5 -expand yes -fill x
        set component(entry) $win.left.entry
        pack [frame $win.left.bottom] -side top
        pack [frame $win.left.bottom.left] -side left
        pack [checkbutton $win.left.bottom.left.words -text "Whole Words ?  " \
              -variable [varname options(-word)]] -side top -padx 5 -pady 5 -anchor w
        set component(wholewords) $win.left.bottom.left.words
        pack [checkbutton $win.left.bottom.left.uclc -text  "Case sensitive ?" \
              -variable [varname options(-case)]]  -side top -padx 5 -pady 5 -anchor w
        set component(casesensitive) $win.left.bottom.left.uclc
        pack [labelframe $win.left.bottom.right -text " Direction "] -side left \
                  -expand yes -fill both
        pack [radiobutton $win.left.bottom.right.forward -text "Forward " \
              -variable [varname options(-forward)] -value yes] -side top -anchor w -padx 5
        set component(forward) $win.left.bottom.right.forward
        pack [radiobutton $win.left.bottom.right.backward -text "Backward" \
              -variable [varname options(-forward)] -value no] -side top -anchor w  -padx 5
        set component(backward) $win.left.bottom.right.backward
        $self configurelist $args
    method component {w args} {
        if {[llength $args] == 0} {
            if {[info exists component($w)]} {
                return $component($w)
            } else {
                error "Component does not exist! Components are: [array names component]!"
        } else {
            if {[info exists component($w)]} {
                if {[lindex $args 0] eq "bind"} {
                    if {[llength $args] == 3} {
                        eval { bind $component($w) } [lrange $args 1 end]
                    } else {
                        error "Wrong number of arguments: Usage pathName component componentname bind event script"
                } else {
                    eval { $component($w) } $args
            } else {
                error "Component does not exist! Components are: [array names component]!"


And here is an example of usage:

 proc Test_Find {} {
    global textvar
    # testing mFind
    proc Next {} {
        global textvar
        puts "Next $textvar"
    proc Find {} {
        global textvar
        puts "Find $textvar"

    set textvar test
    snitfinddialog .s -case 1 -findnextcmd Next -findcmd Find -textvariable textvar
    wm title .s "Search "
    # demonstrating the component subcommand
    .s component find configure -bg red
    set btn [.s component find]
    $btn configure -bg blue
    .s component find bind <Enter> {puts "Yeah Here Find, I am entered!"}
    .s component next bind <Enter> {puts "Yeah Here Next, I am entered!"} 


DDG: Any suggestions, improvements ? Welcome!