/tkabber-0.11.1/ifacetk/buttonbar.tcl
TCL | 610 lines | 409 code | 109 blank | 92 comment | 76 complexity | ef82e69be8ccac605c7a15ddb04ae3f5 MD5 | raw file
Possible License(s): GPL-2.0, BSD-2-Clause
- # ----------------------------------------------------------------------------
- # ButtonBar.tcl
- # ----------------------------------------------------------------------------
- # Index of commands:
- # - ButtonBar::create
- # - ButtonBar::configure
- # - ButtonBar::cget
- # - ButtonBar::insert
- # - ButtonBar::delete
- # - ButtonBar::move
- # - ButtonBar::itemconfigure
- # - ButtonBar::itemcget
- # - ButtonBar::setfocus
- # - ButtonBar::index
- # ----------------------------------------------------------------------------
- namespace eval ButtonBar {
- Widget::define ButtonBar ButtonBar Button
- Widget::declare ButtonBar {
- {-background TkResource "" 0 frame}
- {-orient Enum horizontal 0 {horizontal vertical}}
- {-minwidth Int 0 0 "%d >= 0"}
- {-maxwidth Int 200 0 "%d >= 0"}
- {-padx TkResource "" 0 button}
- {-pady TkResource "" 0 button}
- {-command String "" 0}
- {-bg Synonym -background}
- {-pages String "" 0}
- }
- Widget::addmap ButtonBar "" :cmd {-background {}}
- bind ButtonBar <Destroy> [list [namespace current]::_destroy %W]
- }
- # ----------------------------------------------------------------------------
- # Command ButtonBar::create
- # ----------------------------------------------------------------------------
- proc ButtonBar::create {path args} {
- Widget::init ButtonBar $path $args
- variable $path
- upvar 0 $path data
- eval [list frame $path] [Widget::subcget $path :cmd] \
- [list -class ButtonBar -takefocus 0 -highlightthickness 0]
- # For 8.4+ we don't want to inherit the padding
- catch {$path configure -padx 0 -pady 0}
- frame $path.spacer -width [winfo screenwidth $path]
- bind $path <Configure> [list [namespace current]::_configure %W]
- set data(buttons) [list]
- set data(active) ""
- set data(bindtabs) [list]
- return [Widget::create ButtonBar $path]
- }
- # ----------------------------------------------------------------------------
- # Command ButtonBar::configure
- # ----------------------------------------------------------------------------
- proc ButtonBar::configure {path args} {
- variable $path
- upvar 0 $path data
- set res [Widget::configure $path $args]
- if {[Widget::hasChanged $path -orient val] || \
- [Widget::hasChanged $path -minwidth val] || \
- [Widget::hasChanged $path -maxwidth val]} {
- _redraw $path
- }
- return $res
- }
- # ----------------------------------------------------------------------------
- # Command ButtonBar::cget
- # ----------------------------------------------------------------------------
- proc ButtonBar::cget {path option} {
- return [Widget::cget $path $option]
- }
- # ----------------------------------------------------------------------------
- # Command ButtonBar::_option
- # ----------------------------------------------------------------------------
- proc ButtonBar::_itemoption {path name option} {
- return [lindex [Button::configure [_but $path $name] $option] 4]
- }
- # ----------------------------------------------------------------------------
- # Command ButtonBar::insert
- # ----------------------------------------------------------------------------
- proc ButtonBar::insert {path idx name args} {
- variable $path
- upvar 0 $path data
- set but [_but $path $name]
- set data(buttons) [linsert $data(buttons) $idx $name]
- set newargs {}
- foreach {key val} $args {
- switch -- $key {
- -raisecmd {
- set data(raisecmd,$name) $val
- }
- default { lappend newargs $key $val }
- }
- }
- eval [list Button::create $but \
- -padx [Widget::getoption $path -padx] \
- -pady [Widget::getoption $path -pady] \
- -anchor w \
- -command [list [namespace current]::activate $path $name]] \
- $newargs
- _calc_text $path $name
- bind $but <Configure> [list [namespace current]::_itemconfigure \
- [_escape $path] [_escape $name]]
- foreach {event script} $data(bindtabs) {
- bind $but $event [linsert $script end [_escape $name]]
- }
- DragSite::register $but \
- -draginitcmd [list [namespace current]::_draginitcmd $path $name]
- DropSite::register $but \
- -dropcmd [list [namespace current]::_dropcmd $path $name] \
- -droptypes [list ButtonBar:$path]
- _redraw $path
- if {![string equal [Widget::getoption $path -pages] ""]} {
- set res [[Widget::getoption $path -pages] add $name]
- } else {
- set res $but
- }
- if {[llength $data(buttons)] == 1} {
- activate $path $name -nocmd
- }
- return $res
- }
- proc ButtonBar::_draginitcmd {path name target x y top} {
- activate $path $name
- return [list ButtonBar:$path {move} $name]
- }
- proc ButtonBar::_dropcmd {path tname target source X Y op type name} {
- move $path $name [index $path $tname]
- }
- # ----------------------------------------------------------------------------
- # Command ButtonBar::move
- # ----------------------------------------------------------------------------
- proc ButtonBar::move {path name idx} {
- variable $path
- upvar 0 $path data
- set i [lsearch -exact $data(buttons) $name]
- if {$i >= 0} {
- set data(buttons) [linsert [lreplace $data(buttons) $i $i] $idx $name]
- _redraw $path
- }
- }
- # ----------------------------------------------------------------------------
- # Command ButtonBar::delete
- # ----------------------------------------------------------------------------
- proc ButtonBar::delete {path name {destroyframe 1}} {
- variable $path
- upvar 0 $path data
- set i [lsearch -exact $data(buttons) $name]
- if {$i >= 0} {
- set data(buttons) [lreplace $data(buttons) $i $i]
- destroy [_but $path $name]
- if {![string equal [Widget::getoption $path -pages] ""]} {
- [Widget::getoption $path -pages] delete $name
- }
- if {[llength $data(buttons)] == 0} {
- set data(active) ""
- }
- catch {unset data(raisecmd,$name)}
- catch {unset data(text,$name)}
- catch {unset data(width,$name)}
- catch {unset data(height,$name)}
- _redraw $path
- }
- }
- # ----------------------------------------------------------------------------
- # Command ButtonBar::activate
- # ----------------------------------------------------------------------------
- proc ButtonBar::activate {path name {nocmd ""}} {
- variable $path
- upvar 0 $path data
- set active ""
- foreach n $data(buttons) {
- set but [_but $path $n]
- if {[string equal $n $name]} {
- Button::configure $but -relief sunken -state active
- set active $n
- } else {
- Button::configure $but -relief raised -state normal
- }
- }
- if {![string equal [Widget::getoption $path -pages] ""]} {
- [Widget::getoption $path -pages] raise $active
- }
- if {$nocmd != "-nocmd" && $active != $data(active)} {
- if {[info exists data(raisecmd,$name)]} {
- uplevel #0 $data(raisecmd,$name)
- }
- set cmd [Widget::getoption $path -command]
- if {$cmd != ""} {
- uplevel #0 $cmd [list $active]
- }
- }
- set data(active) $active
- }
- # ----------------------------------------------------------------------------
- # Command ButtonBar::itemconfigure
- # ----------------------------------------------------------------------------
- proc ButtonBar::itemconfigure {path name args} {
- variable $path
- upvar 0 $path data
- set but [_but $path $name]
- set res [eval [list Button::configure $but] $args]
- if {[llength $args] == 1} {
- switch -- [lindex $args 0] {
- -text {
- set res $data(text,$name)
- }
- }
- } else {
- set tf 0
- foreach {key val} $args {
- switch -- $key {
- -text -
- -font {
- set tf 1
- }
- }
- }
- if {$tf} {
- _calc_text $path $name
- _reconfigure_text $path $name
- }
- }
- return $res
- }
- # ----------------------------------------------------------------------------
- # Command ButtonBar::itemcget
- # ----------------------------------------------------------------------------
- proc ButtonBar::itemcget {path name option} {
- variable $path
- upvar 0 $path data
- set res [Button::cget [_but $path $name] $option]
- switch -- $option {
- -text {
- set res $data(text,$name)
- }
- }
- return $res
- }
- # ----------------------------------------------------------------------------
- # Command ButtonBar::setfocus
- # ----------------------------------------------------------------------------
- proc ButtonBar::setfocus {path name} {
- set but [_but $path $name]
- if { [winfo exists $but] } {
- focus $but
- }
- }
- # ----------------------------------------------------------------------------
- # Command ButtonBar::index
- # ----------------------------------------------------------------------------
- proc ButtonBar::index {path name} {
- variable $path
- upvar 0 $path data
- return [lsearch -exact $data(buttons) $name]
- }
- # ----------------------------------------------------------------------------
- # Command ButtonBar::_configure
- # ----------------------------------------------------------------------------
- proc ButtonBar::_configure {path} {
- variable $path
- upvar 0 $path data
- set w [winfo width $path]
- set h [winfo height $path]
- if {![info exists data(width)] || $data(width) != $w || \
- ![info exists data(height)] || $data(height) != $h} {
- set data(width) $w
- set data(height) $h
- _redraw $path
- }
- }
- # ----------------------------------------------------------------------------
- # Command ButtonBar::_redraw
- # ----------------------------------------------------------------------------
- proc ButtonBar::_redraw {path} {
- variable $path
- upvar 0 $path data
- array unset data configured,*
- $path:cmd configure -width 0
- grid forget $path.spacer
- set cols [lindex [grid size $path] 0]
- set rows [lindex [grid size $path] 1]
- for {set c 0} {$c < $cols} {incr c} {
- grid columnconfigure $path $c -weight 0 -minsize 0
- catch {grid columnconfigure $path $c -uniform {}}
- }
- for {set r 0} {$r < $rows} {incr r} {
- grid rowconfigure $path $r -weight 0 -minsize 0
- catch {grid rowconfigure $path $r -uniform {}}
- }
- set num [llength $data(buttons)]
- if {$num == 0} return
- # Change buttons stacking order
- foreach name $data(buttons) {
- ::raise [_but $path $name]
- }
- set min [Widget::getoption $path -minwidth]
- set max [Widget::getoption $path -maxwidth]
- if {$min > $max} {
- set max $min
- }
- if {[string equal [Widget::getoption $path -orient] "horizontal"]} {
- set w [winfo width $path]
- if {$min == 0} {
- set cols $num
- } else {
- set cols [expr {int($w / $min)}]
- if {$cols > $num} {
- set cols $num
- }
- }
- if {[expr {$max * $cols}] < $w} {
- set weight 2
- set minsize $max
- grid $path.spacer -column $cols -row 0
- grid columnconfigure $path $cols -weight 1 -minsize 0
- } else {
- set weight 1
- set minsize $min
- }
- set c 0
- set r 0
- foreach name $data(buttons) {
- grid [_but $path $name] -column $c -row $r -sticky nsew
- grid columnconfigure $path $c -weight $weight -minsize $minsize
- catch {grid columnconfigure $path $c -uniform 1}
- incr c
- if {$c >= $cols} {
- set c 0
- incr r
- }
- }
- } else {
- set h [winfo height $path]
- set c 0
- set r 0
- set th 0
- set num 0
- foreach name $data(buttons) {
- _reconfigure_text $path $name
- }
- foreach name $data(buttons) {
- set but [_but $path $name]
- if {[info exists data(height,$name)]} {
- incr th $data(height,$name)
- } else {
- incr th [winfo reqheight $but]
- }
- if {($c > 0 && $r >= $num) || ($c == 0 && $th > $h)} {
- set r 0
- incr c
- } elseif {$c == 0} {
- incr num
- }
- grid $but -column $c -row $r -sticky nsew
- grid rowconfigure $path $r -weight 0 -minsize 0
- grid columnconfigure $path $c -weight 0 -minsize $max
- incr r
- }
- grid rowconfigure $path $num -weight 10000000 -minsize 0
- }
- }
- # ----------------------------------------------------------------------------
- # Command ButtonBar::_destroy
- # ----------------------------------------------------------------------------
- proc ButtonBar::_destroy {path} {
- variable $path
- upvar 0 $path data
- Widget::destroy $path
- unset data
- }
- # ----------------------------------------------------------------------------
- # Command ButtonBar::_but
- # ----------------------------------------------------------------------------
- proc ButtonBar::_but {path name} {
- return $path.b:$name
- }
- # ----------------------------------------------------------------------------
- # Command ButtonBar::pages
- # ----------------------------------------------------------------------------
- proc ButtonBar::pages {path {first ""} {last ""}} {
- variable $path
- upvar 0 $path data
- if {[string equal $first ""]} {
- return $data(buttons)
- } elseif {[string equal $last ""]} {
- return [lindex $data(buttons) $first]
- } else {
- return [lrange $data(buttons) $first $last]
- }
- }
- # ----------------------------------------------------------------------------
- # Command ButtonBar::raise
- # ----------------------------------------------------------------------------
- proc ButtonBar::raise {path {name ""}} {
- variable $path
- upvar 0 $path data
- if {[string equal $name ""]} {
- return $data(active)
- } else {
- activate $path $name
- }
- }
- # ----------------------------------------------------------------------------
- # Command ButtonBar::getframe
- # ----------------------------------------------------------------------------
- proc ButtonBar::getframe {path name} {
- if {![string equal [Widget::getoption $path -pages] ""]} {
- return [[Widget::getoption $path -pages] getframe $name]
- } else {
- return ""
- }
- }
- # ----------------------------------------------------------------------------
- # Command ButtonBar::bindtabs
- # ----------------------------------------------------------------------------
- proc ButtonBar::bindtabs {path event script} {
- variable $path
- upvar 0 $path data
- lappend data(bindtabs) $event $script
- foreach name $data(buttons) {
- bind [_but $path $name] $event [linsert $script end [_escape $name]]
- }
- }
- # ----------------------------------------------------------------------------
- # Command ButtonBar::see
- # ----------------------------------------------------------------------------
- proc ButtonBar::see {path name} {
- return ""
- }
- # ----------------------------------------------------------------------------
- # Command ButtonBar::_itemconfigure
- # ----------------------------------------------------------------------------
- proc ButtonBar::_itemconfigure {path name} {
- variable $path
- upvar 0 $path data
- if {[info exists data(configured,$name)]} return
- set data(configured,$name) 1
- set but [_but $path $name]
- set w [winfo width $but]
- if {![info exists data(text,$name)] ||
- ![info exists data(width,$name)] || $data(width,$name) != $w} {
- set data(width,$name) $w
- _reconfigure_text $path $name
- }
- set data(height,$name) [winfo height $but]
- }
- # ----------------------------------------------------------------------------
- # Command ButtonBar::_calc_text
- # ----------------------------------------------------------------------------
- proc ButtonBar::_calc_text {path name} {
- variable $path
- upvar 0 $path data
- set text [_itemoption $path $name -text]
- set font [_itemoption $path $name -font]
- set data(text,$name) [list $text [font measure $font $text]]
- set len [string length $text]
- for {set ind 0} {$ind < $len} {incr ind} {
- lappend data(text,$name) \
- [font measure $font [string range $text 0 $ind]\u2026]
- }
- }
- # ----------------------------------------------------------------------------
- # Command ButtonBar::_reconfigure_text
- # ----------------------------------------------------------------------------
- proc ButtonBar::_reconfigure_text {path name} {
- variable $path
- upvar 0 $path data
- if {![info exists data(text,$name)]} return
- set but [_but $path $name]
- set padx [_itemoption $path $name -padx]
- set bd [_itemoption $path $name -bd]
- set hl [_itemoption $path $name -highlightthickness]
- set w [winfo width $but]
- set min [Widget::getoption $path -minwidth]
- set max [Widget::getoption $path -maxwidth]
- if {$min > $max} {
- set max $min
- }
- set tw [expr {$w - 2*($padx + $bd + $hl + 1)}]
- set mw [expr {$max - 2*($padx + $bd + $hl + 1)}]
- set text [lindex $data(text,$name) 0]
- set textw [lindex $data(text,$name) 1]
- Button::configure $but -text $text -helptext ""
- if {$textw <= $tw && $textw <= $mw} {
- return
- }
- set i -1
- foreach textw [lrange $data(text,$name) 2 end] {
- if {$textw > $tw || $textw > $mw} {
- Button::configure $but -text [string range $text 0 $i]\u2026 \
- -helptext $text
- return
- }
- incr i
- }
- }
- # ----------------------------------------------------------------------------
- # Command ButtonBar::_escape
- # ----------------------------------------------------------------------------
- proc ButtonBar::_escape {str} {
- string map {% %%} $str
- }