📄 buttonbox.tcl
字号:
# ----------------------------------------------------------------------------# buttonbox.tcl# This file is part of Unifix BWidget Toolkit# ----------------------------------------------------------------------------# Index of commands:# - ButtonBox::create# - ButtonBox::configure# - ButtonBox::cget# - ButtonBox::add# - ButtonBox::itemconfigure# - ButtonBox::itemcget# - ButtonBox::setfocus# - ButtonBox::invoke# - ButtonBox::index# - ButtonBox::_destroy# ----------------------------------------------------------------------------namespace eval ButtonBox { Widget::define ButtonBox buttonbox Button Widget::declare ButtonBox { {-background TkResource "" 0 frame} {-orient Enum horizontal 1 {horizontal vertical}} {-state Enum "normal" 0 {normal disabled}} {-homogeneous Boolean 1 1} {-spacing Int 10 0 "%d >= 0"} {-padx TkResource "" 0 button} {-pady TkResource "" 0 button} {-default Int -1 0 "%d >= -1"} {-bg Synonym -background} } Widget::addmap ButtonBox "" :cmd {-background {}} bind ButtonBox <Destroy> [list ButtonBox::_destroy %W]}# ----------------------------------------------------------------------------# Command ButtonBox::create# ----------------------------------------------------------------------------proc ButtonBox::create { path args } { Widget::init ButtonBox $path $args variable $path upvar 0 $path data eval [list frame $path] [Widget::subcget $path :cmd] \ [list -class ButtonBox -takefocus 0 -highlightthickness 0] # For 8.4+ we don't want to inherit the padding catch {$path configure -padx 0 -pady 0} set data(max) 0 set data(nbuttons) 0 set data(buttons) [list] set data(default) [Widget::getoption $path -default] return [Widget::create ButtonBox $path]}# ----------------------------------------------------------------------------# Command ButtonBox::configure# ----------------------------------------------------------------------------proc ButtonBox::configure { path args } { variable $path upvar 0 $path data set res [Widget::configure $path $args] if { [Widget::hasChanged $path -default val] } { if { $data(default) != -1 && $val != -1 } { set but $path.b$data(default) if { [winfo exists $but] } { $but configure -default normal } set but $path.b$val if { [winfo exists $but] } { $but configure -default active } set data(default) $val } else { Widget::setoption $path -default $data(default) } } if {[Widget::hasChanged $path -state val]} { foreach i $data(buttons) { $path.b$i configure -state $val } } return $res}# ----------------------------------------------------------------------------# Command ButtonBox::cget# ----------------------------------------------------------------------------proc ButtonBox::cget { path option } { return [Widget::cget $path $option]}# ----------------------------------------------------------------------------# Command ButtonBox::add# ----------------------------------------------------------------------------proc ButtonBox::add { path args } { return [eval insert $path end $args]}proc ButtonBox::insert { path idx args } { variable $path upvar 0 $path data set but $path.b$data(nbuttons) set spacing [Widget::getoption $path -spacing] ## Save the current spacing setting for this button. Buttons ## appended to the end of the box have their spacing applied ## to their left while all other have their spacing applied ## to their right. if {$idx == "end"} { set data(spacing,$data(nbuttons)) [list left $spacing] lappend data(buttons) $data(nbuttons) } else { set data(spacing,$data(nbuttons)) [list right $spacing] set data(buttons) [linsert $data(buttons) $idx $data(nbuttons)] } if { $data(nbuttons) == $data(default) } { set style active } elseif { $data(default) == -1 } { set style disabled } else { set style normal } array set flags $args set tags "" if { [info exists flags(-tags)] } { set tags $flags(-tags) unset flags(-tags) set args [array get flags] } eval [list Button::create $but \ -background [Widget::getoption $path -background]\ -padx [Widget::getoption $path -padx] \ -pady [Widget::getoption $path -pady]] \ $args [list -default $style] # ericm@scriptics.com: set up tags, just like the menu items foreach tag $tags { lappend data(tags,$tag) $but if { ![info exists data(tagstate,$tag)] } { set data(tagstate,$tag) 0 } } set data(buttontags,$but) $tags # ericm@scriptics.com _redraw $path incr data(nbuttons) return $but}proc ButtonBox::delete { path idx } { variable $path upvar 0 $path data set i [lindex $data(buttons) $idx] set data(buttons) [lreplace $data(buttons) $idx $idx] destroy $path.b$i}# ButtonBox::setbuttonstate --## Set the state of a given button tag. If this makes any buttons# enable-able (ie, all of their tags are TRUE), enable them.## Arguments:# path the button box widget name# tag the tag to modify# state the new state of $tag (0 or 1)## Results:# None.proc ButtonBox::setbuttonstate {path tag state} { variable $path upvar 0 $path data # First see if this is a real tag if { [info exists data(tagstate,$tag)] } { set data(tagstate,$tag) $state foreach but $data(tags,$tag) { set expression "1" foreach buttontag $data(buttontags,$but) { append expression " && $data(tagstate,$buttontag)" } if { [expr $expression] } { set state normal } else { set state disabled } $but configure -state $state } } return}# ButtonBox::getbuttonstate --## Retrieve the state of a given button tag.## Arguments:# path the button box widget name# tag the tag to modify## Results:# None.proc ButtonBox::getbuttonstate {path tag} { variable $path upvar 0 $path data # First see if this is a real tag if { [info exists data(tagstate,$tag)] } { return $data(tagstate,$tag) } else { error "unknown tag $tag" }}# ----------------------------------------------------------------------------# Command ButtonBox::itemconfigure# ----------------------------------------------------------------------------proc ButtonBox::itemconfigure { path index args } { if { [set idx [lsearch $args -default]] != -1 } { set args [lreplace $args $idx [expr {$idx+1}]] } return [eval [list Button::configure $path.b[index $path $index]] $args]}# ----------------------------------------------------------------------------# Command ButtonBox::itemcget# ----------------------------------------------------------------------------proc ButtonBox::itemcget { path index option } { return [Button::cget $path.b[index $path $index] $option]}# ----------------------------------------------------------------------------# Command ButtonBox::setfocus# ----------------------------------------------------------------------------proc ButtonBox::setfocus { path index } { set but $path.b[index $path $index] if { [winfo exists $but] } { focus $but }}# ----------------------------------------------------------------------------# Command ButtonBox::invoke# ----------------------------------------------------------------------------proc ButtonBox::invoke { path index } { set but $path.b[index $path $index] if { [winfo exists $but] } { Button::invoke $but }}# ----------------------------------------------------------------------------# Command ButtonBox::index# ----------------------------------------------------------------------------proc ButtonBox::index { path index } { variable $path upvar 0 $path data set n [expr {$data(nbuttons) - 1}] if {[string equal $index "default"]} { set res [Widget::getoption $path -default] } elseif {$index == "end" || $index == "last"} { set res $n } elseif {![string is integer $index]} { ## It's not an integer. Search the text of each button ## in the box and return the index that matches. foreach i $data(buttons) { set w $path.b$i lappend text [$w cget -text] lappend names [$w cget -name] } set res [lsearch -exact [concat $names $text] $index] } else { set res $index if {$index > $n} { set res $n } } return $res}# ButtonBox::gettags --## Return a list of all the tags on all the buttons in a buttonbox.## Arguments:# path the buttonbox to query.## Results:# taglist a list of tags on the buttons in the buttonboxproc ButtonBox::gettags {path} { upvar ::ButtonBox::$path data set taglist {} foreach tag [array names data "tags,*"] { lappend taglist [string range $tag 5 end] } return $taglist}# ----------------------------------------------------------------------------# Command ButtonBox::_redraw# ----------------------------------------------------------------------------proc ButtonBox::_redraw { path } { variable $path upvar 0 $path data Widget::getVariable $path buttons ## We re-grid the buttons from left-to-right. As we go through ## each button, we check its spacing and which direction the ## spacing applies to. Once spacing has been applied to an index, ## it is not changed. This means spacing takes precedence from ## left-to-right. set idx 0 set idxs [list] foreach i $data(buttons) { set dir [lindex $data(spacing,$i) 0] set spacing [lindex $data(spacing,$i) 1] set but $path.b$i if {[string equal [Widget::getoption $path -orient] "horizontal"]} { grid $but -column $idx -row 0 -sticky nsew if { [Widget::getoption $path -homogeneous] } { set req [winfo reqwidth $but] if { $req > $data(max) } { grid columnconfigure $path [expr {2*$i}] -minsize $req set data(max) $req } grid columnconfigure $path $idx -minsize $data(max) -weight 1 } else { grid columnconfigure $path $idx -weight 0 } set col [expr {$idx - 1}] if {[string equal $dir "right"]} { set col [expr {$idx + 1}] } if {$col > 0 && [lsearch $idxs $col] < 0} { lappend idxs $col grid columnconfigure $path $col -minsize $spacing } } else { grid $but -column 0 -row $idx -sticky nsew grid rowconfigure $path $idx -weight 0 set row [expr {$idx - 1}] if {[string equal $dir "right"]} { set row [expr {$idx + 1}] } if {$row > 0 && [lsearch $idxs $row] < 0} { lappend idxs $row grid rowconfigure $path $row -minsize $spacing } } incr idx 2 }}# ----------------------------------------------------------------------------# Command ButtonBox::_destroy# ----------------------------------------------------------------------------proc ButtonBox::_destroy { path } { variable $path upvar 0 $path data Widget::destroy $path unset data}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -