jpayne@69: # jpayne@69: # itclWidget.tcl jpayne@69: # ---------------------------------------------------------------------- jpayne@69: # Invoked automatically upon startup to customize the interpreter jpayne@69: # for [incr Tcl] when one of ::itcl::widget or ::itcl::widgetadaptor is called. jpayne@69: # ---------------------------------------------------------------------- jpayne@69: # AUTHOR: Arnulf P. Wiedemann jpayne@69: # jpayne@69: # ---------------------------------------------------------------------- jpayne@69: # Copyright (c) 2008 Arnulf P. Wiedemann jpayne@69: # ====================================================================== jpayne@69: # See the file "license.terms" for information on usage and jpayne@69: # redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES. jpayne@69: jpayne@69: package require Tk 8.6 jpayne@69: # package require itclwidget [set ::itcl::version] jpayne@69: jpayne@69: namespace eval ::itcl { jpayne@69: jpayne@69: proc widget {name args} { jpayne@69: set result [uplevel 1 ::itcl::internal::commands::genericclass widget $name $args] jpayne@69: # we handle create by owerselfs !! allow classunknown to handle that jpayne@69: oo::objdefine $result unexport create jpayne@69: return $result jpayne@69: } jpayne@69: jpayne@69: proc widgetadaptor {name args} { jpayne@69: set result [uplevel 1 ::itcl::internal::commands::genericclass widgetadaptor $name $args] jpayne@69: # we handle create by owerselfs !! allow classunknown to handle that jpayne@69: oo::objdefine $result unexport create jpayne@69: return $result jpayne@69: } jpayne@69: jpayne@69: } ; # end ::itcl jpayne@69: jpayne@69: jpayne@69: namespace eval ::itcl::internal::commands { jpayne@69: jpayne@69: proc initWidgetOptions {varNsName widgetName className} { jpayne@69: set myDict [set ::itcl::internal::dicts::classOptions] jpayne@69: if {$myDict eq ""} { jpayne@69: return jpayne@69: } jpayne@69: if {![dict exists $myDict $className]} { jpayne@69: return jpayne@69: } jpayne@69: set myDict [dict get $myDict $className] jpayne@69: foreach option [dict keys $myDict] { jpayne@69: set infos [dict get $myDict $option] jpayne@69: set resource [dict get $infos -resource] jpayne@69: set class [dict get $infos -class] jpayne@69: set value [::option get $widgetName $resource $class] jpayne@69: if {$value eq ""} { jpayne@69: if {[dict exists $infos -default]} { jpayne@69: set defaultValue [dict get $infos -default] jpayne@69: uplevel 1 set ${varNsName}::itcl_options($option) $defaultValue jpayne@69: } jpayne@69: } else { jpayne@69: uplevel 1 set ${varNsName}::itcl_options($option) $value jpayne@69: } jpayne@69: } jpayne@69: } jpayne@69: jpayne@69: proc initWidgetDelegatedOptions {varNsName widgetName className args} { jpayne@69: set myDict [set ::itcl::internal::dicts::classDelegatedOptions] jpayne@69: if {$myDict eq ""} { jpayne@69: return jpayne@69: } jpayne@69: if {![dict exists $myDict $className]} { jpayne@69: return jpayne@69: } jpayne@69: set myDict [dict get $myDict $className] jpayne@69: foreach option [dict keys $myDict] { jpayne@69: set infos [dict get $myDict $option] jpayne@69: if {![dict exists $infos -resource]} { jpayne@69: # this is the case when delegating "*" jpayne@69: continue jpayne@69: } jpayne@69: if {![dict exists $infos -component]} { jpayne@69: # nothing to do jpayne@69: continue jpayne@69: } jpayne@69: # check if not in the command line options jpayne@69: # these have higher priority jpayne@69: set myOption $option jpayne@69: if {[dict exists $infos -as]} { jpayne@69: set myOption [dict get $infos -as] jpayne@69: } jpayne@69: set noOptionSet 0 jpayne@69: foreach {optName optVal} $args { jpayne@69: if {$optName eq $myOption} { jpayne@69: set noOptionSet 1 jpayne@69: break jpayne@69: } jpayne@69: } jpayne@69: if {$noOptionSet} { jpayne@69: continue jpayne@69: } jpayne@69: set resource [dict get $infos -resource] jpayne@69: set class [dict get $infos -class] jpayne@69: set component [dict get $infos -component] jpayne@69: set value [::option get $widgetName $resource $class] jpayne@69: if {$component ne ""} { jpayne@69: if {$value ne ""} { jpayne@69: set compVar [namespace eval ${varNsName}${className} "set $component"] jpayne@69: if {$compVar ne ""} { jpayne@69: uplevel 1 $compVar configure $myOption $value jpayne@69: } jpayne@69: } jpayne@69: } jpayne@69: } jpayne@69: } jpayne@69: jpayne@69: proc widgetinitobjectoptions {varNsName widgetName className} { jpayne@69: #puts stderr "initWidgetObjectOptions!$varNsName!$widgetName!$className!" jpayne@69: } jpayne@69: jpayne@69: proc deletehull {newName oldName what} { jpayne@69: if {$what eq "delete"} { jpayne@69: set name [namespace tail $newName] jpayne@69: regsub {hull[0-9]+} $name {} name jpayne@69: rename $name {} jpayne@69: } jpayne@69: if {$what eq "rename"} { jpayne@69: set name [namespace tail $newName] jpayne@69: regsub {hull[0-9]+} $name {} name jpayne@69: rename $name {} jpayne@69: } jpayne@69: } jpayne@69: jpayne@69: proc hullandoptionsinstall {objectName className widgetClass hulltype args} { jpayne@69: if {$hulltype eq ""} { jpayne@69: set hulltype frame jpayne@69: } jpayne@69: set idx 0 jpayne@69: set found 0 jpayne@69: foreach {optName optValue} $args { jpayne@69: if {$optName eq "-class"} { jpayne@69: set found 1 jpayne@69: set widgetClass $optValue jpayne@69: break jpayne@69: } jpayne@69: incr idx jpayne@69: } jpayne@69: if {$found} { jpayne@69: set args [lreplace $args $idx [expr {$idx + 1}]] jpayne@69: } jpayne@69: if {$widgetClass eq ""} { jpayne@69: set widgetClass $className jpayne@69: set widgetClass [string totitle $widgetClass] jpayne@69: } jpayne@69: set cmd "set win $objectName; ::itcl::builtin::installhull using $hulltype -class $widgetClass $args" jpayne@69: uplevel 2 $cmd jpayne@69: } jpayne@69: jpayne@69: } ; # end ::itcl::internal::commands jpayne@69: jpayne@69: namespace eval ::itcl::builtin { jpayne@69: jpayne@69: proc installhull {args} { jpayne@69: set cmdPath ::itcl::internal::commands jpayne@69: set className [uplevel 1 info class] jpayne@69: jpayne@69: set replace 0 jpayne@69: switch -- [llength $args] { jpayne@69: 0 { jpayne@69: return -code error\ jpayne@69: "wrong # args: should be \"[lindex [info level 0] 0]\ jpayne@69: name|using ?arg ...?\"" jpayne@69: } jpayne@69: 1 { jpayne@69: set widgetName [lindex $args 0] jpayne@69: set varNsName $::itcl::internal::varNsName($widgetName) jpayne@69: } jpayne@69: default { jpayne@69: upvar win win jpayne@69: set widgetName $win jpayne@69: jpayne@69: set varNsName $::itcl::internal::varNsName($widgetName) jpayne@69: set widgetType [lindex $args 1] jpayne@69: incr replace jpayne@69: if {[llength $args] > 3 && [lindex $args 2] eq "-class"} { jpayne@69: set classNam [lindex $args 3] jpayne@69: incr replace 2 jpayne@69: } else { jpayne@69: set classNam [string totitle $widgetType] jpayne@69: } jpayne@69: uplevel 1 [lreplace $args 0 $replace $widgetType $widgetName -class $classNam] jpayne@69: uplevel 1 [list ${cmdPath}::initWidgetOptions $varNsName $widgetName $className] jpayne@69: } jpayne@69: } jpayne@69: jpayne@69: # initialize the itcl_hull variable jpayne@69: set i 0 jpayne@69: set nam ::itcl::internal::widgets::hull jpayne@69: while {1} { jpayne@69: incr i jpayne@69: set hullNam ${nam}${i}$widgetName jpayne@69: if {[::info command $hullNam] eq ""} { jpayne@69: break jpayne@69: } jpayne@69: } jpayne@69: uplevel 1 [list ${cmdPath}::sethullwindowname $widgetName] jpayne@69: uplevel 1 [list ::rename $widgetName $hullNam] jpayne@69: uplevel 1 [list ::trace add command $hullNam {delete rename} ::itcl::internal::commands::deletehull] jpayne@69: catch {${cmdPath}::checksetitclhull [list] 0} jpayne@69: namespace eval ${varNsName}${className} "set itcl_hull $hullNam" jpayne@69: catch {${cmdPath}::checksetitclhull [list] 2} jpayne@69: uplevel 1 [lreplace $args 0 $replace ${cmdPath}::initWidgetDelegatedOptions $varNsName $widgetName $className] jpayne@69: } jpayne@69: jpayne@69: proc installcomponent {args} { jpayne@69: upvar win win jpayne@69: jpayne@69: set className [uplevel 1 info class] jpayne@69: set myType [${className}::info types [namespace tail $className]] jpayne@69: set isType 0 jpayne@69: if {$myType ne ""} { jpayne@69: set isType 1 jpayne@69: } jpayne@69: set numArgs [llength $args] jpayne@69: set usage "usage: installcomponent using ?-option value ...?" jpayne@69: if {$numArgs < 4} { jpayne@69: error $usage jpayne@69: } jpayne@69: foreach {componentName using widgetType widgetPath} $args break jpayne@69: set opts [lrange $args 4 end] jpayne@69: if {$using ne "using"} { jpayne@69: error $usage jpayne@69: } jpayne@69: if {!$isType} { jpayne@69: set hullExists [uplevel 1 ::info exists itcl_hull] jpayne@69: if {!$hullExists} { jpayne@69: error "cannot install \"$componentName\" before \"itcl_hull\" exists" jpayne@69: } jpayne@69: set hullVal [uplevel 1 set itcl_hull] jpayne@69: if {$hullVal eq ""} { jpayne@69: error "cannot install \"$componentName\" before \"itcl_hull\" exists" jpayne@69: } jpayne@69: } jpayne@69: # check for delegated option and ask the option database for the values jpayne@69: # first check for number of delegated options jpayne@69: set numOpts 0 jpayne@69: set starOption 0 jpayne@69: set myDict [set ::itcl::internal::dicts::classDelegatedOptions] jpayne@69: if {[dict exists $myDict $className]} { jpayne@69: set myDict [dict get $myDict $className] jpayne@69: foreach option [dict keys $myDict] { jpayne@69: if {$option eq "*"} { jpayne@69: set starOption 1 jpayne@69: } jpayne@69: incr numOpts jpayne@69: } jpayne@69: } jpayne@69: set myOptionDict [set ::itcl::internal::dicts::classOptions] jpayne@69: if {[dict exists $myOptionDict $className]} { jpayne@69: set myOptionDict [dict get $myOptionDict $className] jpayne@69: } jpayne@69: set cmd [list $widgetPath configure] jpayne@69: set cmd1 "set $componentName \[$widgetType $widgetPath\]" jpayne@69: uplevel 1 $cmd1 jpayne@69: if {$starOption} { jpayne@69: upvar $componentName compName jpayne@69: set cmd1 [list $compName configure] jpayne@69: set configInfos [uplevel 1 $cmd1] jpayne@69: foreach entry $configInfos { jpayne@69: if {[llength $entry] > 2} { jpayne@69: foreach {optName resource class defaultValue} $entry break jpayne@69: set val "" jpayne@69: catch { jpayne@69: set val [::option get $win $resource $class] jpayne@69: } jpayne@69: if {$val ne ""} { jpayne@69: set addOpt 1 jpayne@69: if {[dict exists $myDict $$optName]} { jpayne@69: set addOpt 0 jpayne@69: } else { jpayne@69: set starDict [dict get $myDict "*"] jpayne@69: if {[dict exists $starDict -except]} { jpayne@69: set exceptions [dict get $starDict -except] jpayne@69: if {[lsearch $exceptions $optName] >= 0} { jpayne@69: set addOpt 0 jpayne@69: } jpayne@69: jpayne@69: } jpayne@69: if {[dict exists $myOptionDict $optName]} { jpayne@69: set addOpt 0 jpayne@69: } jpayne@69: } jpayne@69: if {$addOpt} { jpayne@69: lappend cmd $optName $val jpayne@69: } jpayne@69: jpayne@69: } jpayne@69: jpayne@69: } jpayne@69: } jpayne@69: } else { jpayne@69: foreach optName [dict keys $myDict] { jpayne@69: set optInfos [dict get $myDict $optName] jpayne@69: set resource [dict get $optInfos -resource] jpayne@69: set class [namespace tail $className] jpayne@69: set class [string totitle $class] jpayne@69: set val "" jpayne@69: catch { jpayne@69: set val [::option get $win $resource $class] jpayne@69: } jpayne@69: if {$val ne ""} { jpayne@69: if {[dict exists $optInfos -as] } { jpayne@69: set optName [dict get $optInfos -as] jpayne@69: } jpayne@69: lappend cmd $optName $val jpayne@69: } jpayne@69: } jpayne@69: } jpayne@69: lappend cmd {*}$opts jpayne@69: uplevel 1 $cmd jpayne@69: } jpayne@69: jpayne@69: } ; # end ::itcl::builtin jpayne@69: jpayne@69: set ::itcl::internal::dicts::hullTypes [list \ jpayne@69: frame \ jpayne@69: toplevel \ jpayne@69: labelframe \ jpayne@69: ttk:frame \ jpayne@69: ttk:toplevel \ jpayne@69: ttk:labelframe \ jpayne@69: ] jpayne@69: jpayne@69: namespace eval ::itcl::builtin::Info { jpayne@69: jpayne@69: proc hulltypes {args} { jpayne@69: namespace upvar ::itcl::internal::dicts hullTypes hullTypes jpayne@69: jpayne@69: set numArgs [llength $args] jpayne@69: if {$numArgs > 1} { jpayne@69: error "wrong # args should be: info hulltypes ??" jpayne@69: } jpayne@69: set pattern "" jpayne@69: if {$numArgs > 0} { jpayne@69: set pattern [lindex $args 0] jpayne@69: } jpayne@69: if {$pattern ne ""} { jpayne@69: return [lsearch -all -inline -glob $hullTypes $pattern] jpayne@69: } jpayne@69: return $hullTypes jpayne@69: jpayne@69: } jpayne@69: jpayne@69: proc widgetclasses {args} { jpayne@69: set numArgs [llength $args] jpayne@69: if {$numArgs > 1} { jpayne@69: error "wrong # args should be: info widgetclasses ??" jpayne@69: } jpayne@69: set pattern "" jpayne@69: if {$numArgs > 0} { jpayne@69: set pattern [lindex $args 0] jpayne@69: } jpayne@69: set myDict [set ::itcl::internal::dicts::classes] jpayne@69: if {![dict exists $myDict widget]} { jpayne@69: return [list] jpayne@69: } jpayne@69: set myDict [dict get $myDict widget] jpayne@69: set result [list] jpayne@69: if {$pattern ne ""} { jpayne@69: foreach key [dict keys $myDict] { jpayne@69: set myInfo [dict get $myDict $key] jpayne@69: set value [dict get $myInfo -widget] jpayne@69: if {[string match $pattern $value]} { jpayne@69: lappend result $value jpayne@69: } jpayne@69: } jpayne@69: } else { jpayne@69: foreach key [dict keys $myDict] { jpayne@69: set myInfo [dict get $myDict $key] jpayne@69: lappend result [dict get $myInfo -widget] jpayne@69: } jpayne@69: } jpayne@69: return $result jpayne@69: } jpayne@69: jpayne@69: proc widgets {args} { jpayne@69: set numArgs [llength $args] jpayne@69: if {$numArgs > 1} { jpayne@69: error "wrong # args should be: info widgets ??" jpayne@69: } jpayne@69: set pattern "" jpayne@69: if {$numArgs > 0} { jpayne@69: set pattern [lindex $args 0] jpayne@69: } jpayne@69: set myDict [set ::itcl::internal::dicts::classes] jpayne@69: if {![dict exists $myDict widget]} { jpayne@69: return [list] jpayne@69: } jpayne@69: set myDict [dict get $myDict widget] jpayne@69: set result [list] jpayne@69: if {$pattern ne ""} { jpayne@69: foreach key [dict keys $myDict] { jpayne@69: set myInfo [dict get $myDict $key] jpayne@69: set value [dict get $myInfo -name] jpayne@69: if {[string match $pattern $value]} { jpayne@69: lappend result $value jpayne@69: } jpayne@69: } jpayne@69: } else { jpayne@69: foreach key [dict keys $myDict] { jpayne@69: set myInfo [dict get $myDict $key] jpayne@69: lappend result [dict get $myInfo -name] jpayne@69: } jpayne@69: } jpayne@69: return $result jpayne@69: } jpayne@69: jpayne@69: proc widgetadaptors {args} { jpayne@69: set numArgs [llength $args] jpayne@69: if {$numArgs > 1} { jpayne@69: error "wrong # args should be: info widgetadaptors ??" jpayne@69: } jpayne@69: set pattern "" jpayne@69: if {$numArgs > 0} { jpayne@69: set pattern [lindex $args 0] jpayne@69: } jpayne@69: set myDict [set ::itcl::internal::dicts::classes] jpayne@69: if {![dict exists $myDict widgetadaptor]} { jpayne@69: return [list] jpayne@69: } jpayne@69: set myDict [dict get $myDict widgetadaptor] jpayne@69: set result [list] jpayne@69: if {$pattern ne ""} { jpayne@69: foreach key [dict keys $myDict] { jpayne@69: set myInfo [dict get $myDict $key] jpayne@69: set value [dict get $myInfo -name] jpayne@69: if {[string match $pattern $value]} { jpayne@69: lappend result $value jpayne@69: } jpayne@69: } jpayne@69: } else { jpayne@69: foreach key [dict keys $myDict] { jpayne@69: set myInfo [dict get $myDict $key] jpayne@69: lappend result [dict get $myInfo -name] jpayne@69: } jpayne@69: } jpayne@69: return $result jpayne@69: } jpayne@69: jpayne@69: } ; # end ::itcl::builtin::Info