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