home *** CD-ROM | disk | FTP | other *** search
- # SpecTcl, by S. A. Uhler
- # Copyright (c) 1994-1995 Sun Microsystems, Inc.
- #
- # See the file "license.txt" for information on usage and redistribution
- # of this file, and for a DISCLAIMER OF ALL WARRANTIES.
- #
- # generic fill in the form mega-widget (not done yet) 11/94
- # build a data entry form in a frame, inside a scrollable canvas
- # The form consists of keyword - value pairs represented as an array.
-
- # build_form win form <match>
- # win: The name of the frame to put this in - it will be created if needed
- # form: The name of the array to fill out the form with
- # height: How many entries
- # side effects:
- # The bind tags "validate" and "entry" are provided for each entry field
- # various options are processed by looking at the Widget_data array
- # ignore:<name> not placed in the form
- # infilter:<name> processed through an input filter first
- # outfilter:<name> processed through an out filter
- # rename:<name> the option is re-named as its label
-
- # [This needs a re-do]
-
- set Advanced 1
- proc form_build {win form {option Widget_data} {height 10}} {
- global Advanced
- upvar #0 $form data ;# name of array with data
- upvar #0 $option config ;# name of array with configuration stuff
- catch "frame $win"
- if {$win == "."} {set base ""} {set base $win}
- catch "destroy $base.can $base.scroll $base.buttons"
- debug "Building form $form on $win, (base $base)"
-
- # create the canvas, scollbar, and scrolling frame in the canvas
-
- canvas $base.can -yscrollcommand "$base.scroll set"
- scrollbar $base.scroll -orient vertical -command "$base.can yview"
- frame $base.buttons -bg red -bd 1
- set parent $base.can.f
- frame $parent -highlightthickness 0
-
- blt_table $win $base.can 0,1 -fill both
- blt_table $win $base.scroll 0,0 -fill y
- blt_table $win $base.buttons 1,0 -fill x -columnspan 2
- blt_table column $win configure 0 -resize none
- blt_table column $win configure 1 -resize both
- blt_table row $win configure 0 -resize both
- blt_table row $win configure 1 -resize none
- $base.can create window 0 0 -anchor nw -window $parent
- bind $base.can <Configure> {%W itemconfigure all -width %w}
-
-
- # make some buttons
-
- checkbutton $base.buttons.advanced -text "obscure\noptions" \
- -variable Advanced -command "
- form_build $win $form $option $height
- "
- button $base.buttons.quit -text dismiss -command "
- set Geometry([winfo name [winfo toplevel $win]]) \[wm geometry [winfo toplevel $win]\]
- destroy [winfo toplevel $win]
- "
- frame $base.buttons.extra
-
- set col -1
- blt_table $base.buttons $base.buttons.advanced 0,[incr col] -fill y
- blt_table $base.buttons $base.buttons.quit 0,[incr col] -fill y
- blt_table $base.buttons $base.buttons.extra 0,[incr col] -fill both
- blt_table column $base.buttons configure {0 1} -resize none
- # update ;#?
-
- set row 0
- set prev ""
- set first "" ;# temp
- foreach item [lsort [array names data]] {
-
- if {!$Advanced && [info exists config(advanced:$item)]} {
- continue
- }
-
- if {[info exists config(ignore:$item)]} {
- continue
- }
-
- if {[info exists config(rename:$item)]} {
- set text $config(rename:$item)
- } else {
- set text $item
- }
-
- # get the value and run the input filter (if any)
-
- set value $data($item)
- if {[info exists config(infilter:$item)]} {
- $config(infilter:$item) value
- }
-
- set label $parent.$form,$item,label ;# pick something we can parse
- set entry $parent.$form,$item,entry
- label $label -text $text
- entry $entry -bd 3 -relief ridge -width 30
- $entry insert 0 $value
- bindtags $entry "First validate [bindtags $entry]"
- blt_table $parent $label $row,0 -fill none -anchor e
- blt_table $parent $entry $row,1 -fill x -anchor w
- blt_table column $parent configure 0 -resize none
-
- # set tab groupings
- if {$prev != ""} {
- form_bind $base.can $parent $prev $entry
- } else {
- set first $entry
- }
- set prev $entry
- incr row
- }
- form_bind $base.can $parent $prev $first
- foreach i {Return Tab Shift-Tab} {
- bind validate <$i> "check_field %W"
- }
-
- # set the field to "non validated" when the 1st key is pressed
-
- bind validate <FocusIn> "
- set ${form}(focus) %W
- bind validate <KeyPress> {
- %W configure -fg red
- set Current(dirty) 1
- bind validate <KeyPress> {}
- }
- "
-
- # set the canvas parameters nicely
-
- update idletasks
- set incr [blt_table row $parent sizes 0]
- $base.can configure -yscrollincrement $incr \
- -height [expr $height * $incr] \
- -width [winfo reqwidth $parent]
- # eval "$base.can configure -scrollregion \{[$base.can bbox all]\}"
- $base.can yview moveto 0
- scrollregion_update $parent
-
- # this is a kludge to work around a focus bug in this version of TK
-
- if {[info exists data(focus)] && [winfo exists $data(focus)]} {
- # after 300 focus $data(focus)
- focus $data(focus)
- } else {
- # after 300 focus $first
- focus $first
- }
- # after 300 "raise [winfo toplevel $win]"
- return $win
- }
-
- # set the key bindings for tabbing through entry fields
-
- proc form_bind {canvas frame prev next} {
- bind $prev <Tab> "focus $next"
- bind $next <Shift-Tab> "focus $prev"
- bind $next <FocusIn> "form_focus $canvas $frame $next"
- }
-
- # focus and make visible (by scrolling canvas as needed)
-
- proc form_focus {canvas frame item} {
- $item selection range 0 end
- dputs $item
- set below [expr [winfo y $item] + [winfo y $frame]]
- if {$below <= 0 } {
- $canvas yview scroll \
- [expr $below/[$canvas cget -yscrollincrement]] units
- return -1
- }
- set above [expr [winfo y $item] + [winfo y $frame] - \
- ([winfo height $canvas] - [winfo height $item])]
- if {$above > 0} {
- $canvas yview scroll \
- [expr $above/[$canvas cget -yscrollincrement]+1] units
- return 1
- }
- return 0
- }
-
- # validate a field entry - this is done any time the field is "left"
- # This is called from "bind" and causes the remaining bindings to be
- # skipped if the validation fails
- # errors (if any) are placed in the "error" entry of the array, which is displayed on the form
- # win: the name of the entry window, from which re can derive the widget info
-
- proc check_field {win} {
- regexp {.*\.([^,]+),([^,]+),} $win dummy name item
- set value [$win get]
- dputs $name: $item<-$value
- upvar #0 $name data
- set data(error) [validate_field $name $item $value]
- if {$data(error) != {}} {
- focus $win
- return -code break
- } else {
- $win configure -fg black
- return
- }
- }
-