bll 2017-10-4: A megawidget button with a display image indicating the status.
-variable : a boolean variable to track
-imageon : the image to display when true (from [image create photo])
-imageoff : the image to display when false
#!/usr/bin/tclsh # # Copyright 2017 Brad Lanam Walnut Creek CA # package require Tcl 8.5- package require Tk # -variable : boolean variable to track # -imageon : image to display when -variable is true # (from [image create photo]) # -imageoff : image to display when -variable is false proc ::buttontoggle { nm args } { btntoggle new $nm {*}$args return $nm } proc ::buttontoggleHandler { cbox args } { $cbox {*}$args } ::oo::class create ::btntoggle { constructor { nm args } { my variable vars set vars(state) off set vars(widget) [ttk::button ${nm}] set vars(btn) ${nm}_buttontoggle rename $vars(widget) ::$vars(btn) interp alias {} $vars(widget) {} ::buttontoggleHandler [self] uplevel 2 [list $vars(widget) configure {*}$args] bind $vars(widget) <Destroy> [list [self] destruct] } method destruct { } { my variable vars trace remove variable $vars(-variable) write [list [self] settrace] interp alias {} $vars(widget) {} [self] destroy } method unknown { args } { my variable vars set nm $vars(btn) return [uplevel 2 [list $nm {*}$args]] } method _getfqvname { v } { set fqv {} if { [string match {::*} $v] } { set fqv $v } if { $fqv eq {} } { set fqv [uplevel 3 [list namespace which -variable $v]] if { $fqv eq {} } { set ns [uplevel 3 [list namespace current]] set fqv $ns$v if { [string match ::::* $fqv] } { set fqv [string range $fqv 2 end] } } } return $fqv } method _setimage { } { variable vars set k -variable if { [info exists vars($k)] && [info exists $vars($k)] && [set $vars($k)] ne {} && [set $vars($k)] } { $vars(btn) configure -image [set $vars(-imageon)] -compound right } else { $vars(btn) configure -image [set $vars(-imageoff)] -compound right } } method settrace { args } { my variable vars my _setimage } method cget { key } { my variable vars set rv {} if { $key eq "-variable" || $key eq "-imageon" || $key eq "-imageoff" } { if { [info exists vars($key)] } { set rv $vars($key) } } else { set rv [$vars(btn) cget $key] } return $rv } method configure { args } { my variable vars foreach {k v} $args { if { $k eq "-imageon" } { set fqv [my _getfqvname $v] set vars($k) $fqv if { ! [info exists $vars($k)] } { set vars($k) {} } } elseif { $k eq "-imageoff" } { set fqv [my _getfqvname $v] set vars($k) $fqv if { ! [info exists $vars($k)] } { set vars($k) {} } } elseif { $k eq "-variable" } { set fqv [my _getfqvname $v] if { [info exists vars($k)] && [info exists $vars($k)] && $vars($k) ne $fqv } { trace remove variable $vars($k) write [list [self] settrace] } set vars($k) $fqv if { ! [info exists $vars($k)] } { set $vars($k) {} } } else { set nm $vars(btn) uplevel 2 [list $nm configure $k $v] } } set k -variable if { [info exists vars($k)] && [info exists $vars($k)] } { trace add variable $vars($k) write [list [self] settrace] } my _setimage return -code ok } } package provide buttontoggle 1.0