DDG: Tired of writing again and again those clumsy find dialogs I wrapped all into a Snit's Not Incr Tcl toplevel widget.
# NAME snitfinddialog # SYNOPSIS # snitfindialog path ?args? # DESCRIPTION # snitfilendialog provides a standard find dialog layout # all buttons and the entries are accessable via the componet subcommand # the components are: find, next (standard tk buttons), entry (standard tk entry) # STANDARD OPTIONS # delegated is -textvariable to the entry component # all other options must be send via the component subcommand # WIDGET OPTIONS # -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. # WIDGET COMMAND # 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 # AUTHOR # Dr. Detlef Groth [email protected] # HISTORY # 20/11/2003 Version 0.1 initial release
---
And here is the actual code about 60 lines:
package require snit 0.9 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 $win.right.search -text " Find " -width 15] -side top \ -padx 5 -pady 8 set component(find) $win.right.search 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!"} } Test_Find
---
DDG: Any suggestions, improvements ? Welcome!
escargo 20 Nov 2003 - Just a couple of things. I have a Windows XP laptop with ActiveState ActiveTcl 8.4.4 installed. That includes tcllib1.5. Apparently the package require snit 0.9 is satisfied with the 0.82 version included in tcllib. You might want to change the require to package require -exact snit 0.9 to avoid that problem (which, admittedly causes a different problem in the future).
Second, since I'm running on Windows, the puts in Test_find have nowhere to go. I changed the bindings on the find and next buttons to change color on enter and leave events instead. You might consider putting some Windows-toleration code in there for people running without consoles.
Re. 0.9 vs. 0.82, note that 9 < 82. If snit was at 0.81 at some point, then a new release should have been bumped to 0.90, not 0.9. The issue could be resolved by releasing 0.91 and never ever using "package require snit 0.9" anywhere -jcw
Mea culpa. I've got some changes to make anyway. -- WHD
DDG: If running on windows why not simply run a wish. Copy the code into the console and see what it's putting! That's the way I Test_Find! ---
See also Snit's Not Incr Tcl, snitbrowser.