combobox.wgt
来自「一个跨平台的TCL/TK可视开发环境类似VC. TCL/TK是一个跨平台的脚本」· WGT 代码 · 共 2,104 行 · 第 1/5 页
WGT
2,104 行
$widgets(entry) configure -selectborderwidth $newValue
$widgets(listbox) configure -selectborderwidth $newValue
set options($option) $newValue
}
-selectforeground {
$widgets(entry) configure -selectforeground $newValue
$widgets(listbox) configure -selectforeground $newValue
set options($option) $newValue
}
-state {
if {$newValue == "normal"} {
# it's enabled
set editable [::combobox2::GetBoolean \
$options(-editable)]
if {$editable} {
$widgets(entry) configure -state normal
$widgets(entry) configure -takefocus 1
}
} elseif {$newValue == "disabled"} {
# it's disabled
$widgets(entry) configure -state disabled
$widgets(entry) configure -takefocus 0
} else {
set options($option) $oldValue
set message "bad state value \"$newValue\";"
append message " must be normal or disabled"
error $message
}
set options($option) $newValue
}
-takefocus {
$widgets(entry) configure -takefocus $newValue
set options($option) $newValue
}
-textvariable {
$widgets(entry) configure -textvariable $newValue
set options($option) $newValue
}
-value {
::combobox2::SetValue $widgets(this) $newValue
set options($option) $newValue
}
-width {
$widgets(frame) configure -width $newValue
$widgets(listbox) configure -width $newValue
set options($option) $newValue
}
-xscrollcommand {
$widgets(entry) configure -xscrollcommand $newValue
set options($option) $newValue
}
}
}
}
# ::combobox2::VTrace --
#
# this proc is called whenever the user changes the value of
# the -textvariable associated with a widget
#
# Arguments:
#
# w widget pathname
# args standard stuff from a variable trace
#
# Returns:
#
# Empty String
proc ::combobox2::VTrace {w args} {
upvar ::combobox2::${w}::widgets widgets
upvar ::combobox2::${w}::options options
upvar ::combobox2::${w}::ignoreTrace ignoreTrace
if {[info exists ignoreTrace]} return
::combobox2::SetValue $widgets(this) [set ::$options(-textvariable)]
return ""
}
# ::combobox2::SetValue --
#
# sets the value of the combobox2 and calls the -command,
# if defined
#
# Arguments:
#
# w widget pathname
# newValue the new value of the combobox2
#
# Returns
#
# Empty string
proc ::combobox2::SetValue {w newValue} {
upvar ::combobox2::${w}::widgets widgets
upvar ::combobox2::${w}::options options
upvar ::combobox2::${w}::ignoreTrace ignoreTrace
upvar ::combobox2::${w}::oldValue oldValue
if {[info exists options(-textvariable)] \
&& [string length $options(-textvariable)] > 0} {
set variable ::$options(-textvariable)
set $variable $newValue
} else {
set oldstate [$widgets(entry) cget -state]
$widgets(entry) configure -state normal
$widgets(entry) delete 0 end
$widgets(entry) insert 0 $newValue
$widgets(entry) configure -state $oldstate
}
# set our internal textvariable; this will cause any public
# textvariable (ie: defined by the user) to be updated as
# well
# set ::combobox2::${w}::entryTextVariable $newValue
# redefine our concept of the "old value". Do it before running
# any associated command so we can be sure it happens even
# if the command somehow fails.
set oldValue $newValue
# call the associated command. The proc will handle whether or
# not to actually call it, and with what args
CallCommand $w $newValue
return ""
}
# ::combobox2::CallCommand --
#
# calls the associated command, if any, appending the new
# value to the command to be called.
#
# Arguments:
#
# w widget pathname
# newValue the new value of the combobox2
#
# Returns
#
# empty string
proc ::combobox2::CallCommand {w newValue} {
upvar ::combobox2::${w}::widgets widgets
upvar ::combobox2::${w}::options options
# call the associated command, if defined and -commandstate is
# set to "normal"
if {$options(-commandstate) == "normal" && \
[string length $options(-command)] > 0} {
set args [list $widgets(this) $newValue]
uplevel \#0 $options(-command) $args
}
}
# ::combobox2::GetBoolean --
#
# returns the value of a (presumably) boolean string (ie: it should
# do the right thing if the string is "yes", "no", "true", 1, etc
#
# Arguments:
#
# value value to be converted
# errorValue a default value to be returned in case of an error
#
# Returns:
#
# a 1 or zero, or the value of errorValue if the string isn't
# a proper boolean value
proc ::combobox2::GetBoolean {value {errorValue 1}} {
if {[catch {expr {([string trim $value])?1:0}} res]} {
return $errorValue
} else {
return $res
}
}
# ::combobox2::convert --
#
# public routine to convert %x, %y and %W binding substitutions.
# Given an x, y and or %W value relative to a given widget, this
# routine will convert the values to be relative to the combobox2
# widget. For example, it could be used in a binding like this:
#
# bind .combobox2 <blah> {doSomething [::combobox2::convert %W -x %x]}
#
# Note that this procedure is *not* exported, but is indented for
# public use. It is not exported because the name could easily
# clash with existing commands.
#
# Arguments:
#
# w a widget path; typically the actual result of a %W
# substitution in a binding. It should be either a
# combobox2 widget or one of its subwidgets
#
# args should one or more of the following arguments or
# pairs of arguments:
#
# -x <x> will convert the value <x>; typically <x> will
# be the result of a %x substitution
# -y <y> will convert the value <y>; typically <y> will
# be the result of a %y substitution
# -W (or -w) will return the name of the combobox2 widget
# which is the parent of $w
#
# Returns:
#
# a list of the requested values. For example, a single -w will
# result in a list of one items, the name of the combobox2 widget.
# Supplying "-x 10 -y 20 -W" (in any order) will return a list of
# three values: the converted x and y values, and the name of
# the combobox2 widget.
proc ::combobox2::convert {w args} {
set result {}
if {![winfo exists $w]} {
error "window \"$w\" doesn't exist"
}
while {[llength $args] > 0} {
set option [lindex $args 0]
set args [lrange $args 1 end]
switch -exact -- $option {
-x {
set value [lindex $args 0]
set args [lrange $args 1 end]
set win $w
while {[winfo class $win] != "Combobox2"} {
incr value [winfo x $win]
set win [winfo parent $win]
if {$win == "."} break
}
lappend result $value
}
-y {
set value [lindex $args 0]
set args [lrange $args 1 end]
set win $w
while {[winfo class $win] != "Combobox2"} {
incr value [winfo y $win]
set win [winfo parent $win]
if {$win == "."} break
}
lappend result $value
}
-w -
-W {
set win $w
while {[winfo class $win] != "Combobox2"} {
set win [winfo parent $win]
if {$win == "."} break;
}
lappend result $win
}
}
}
return $result
}
# ::combobox2::Canonize --
#
# takes a (possibly abbreviated) option or command name and either
# returns the canonical name or an error
#
# Arguments:
#
# w widget pathname
# object type of object to canonize; must be one of "command",
# "option", "scan command" or "list command"
# opt the option (or command) to be canonized
#
# Returns:
#
# Returns either the canonical form of an option or command,
# or raises an error if the option or command is unknown or
# ambiguous.
proc ::combobox2::Canonize {w object opt} {
variable widgetOptions
variable columnOptions
variable widgetCommands
variable listCommands
variable scanCommands
switch $object {
command {
if {[lsearch -exact $widgetCommands $opt] >= 0} {
return $opt
}
# command names aren't stored in an array, and there
# isn't a way to get all the matches in a list, so
# we'll stuff the commands in a temporary array so
# we can use [array names]
set list $widgetCommands
foreach element $list {
set tmp($element) ""
}
set matches [array names tmp ${opt}*]
}
{list command} {
if {[lsearch -exact $listCommands $opt] >= 0} {
return $opt
}
# command names aren't stored in an array, and there
# isn't a way to get all the matches in a list, so
# we'll stuff the commands in a temporary array so
# we can use [array names]
set list $listCommands
foreach element $list {
set tmp($element) ""
}
set matches [array names tmp ${opt}*]
}
{scan command} {
if {[lsearch -exact $scanCommands $opt] >= 0} {
return $opt
}
# command names aren't stored in an array, and there
# isn't a way to get all the matches in a list, so
# we'll stuff the commands in a temporary array so
# we can use [array names]
set list $scanCommands
foreach element $list {
set tmp($element) ""
}
set matches [array names tmp ${opt}*]
}
option {
if {[info exists widgetOptions($opt)] \
&& [llength $widgetOptions($opt)] == 2} {
return $opt
}
set list [array names widgetOptions]
set matches [array names widgetOptions ${opt}*]
}
}
if {[llength $matches] == 0} {
set choices [HumanizeList $list]
error "unknown $object \"$opt\"; must be one of $choices"
} elseif {[llength $matches] == 1} {
set opt [lindex $matches 0]
# deal with option aliases
switch $object {
option {
set opt [lindex $matches 0]
if {[llength $widgetOptions($opt)] == 1} {
set opt $widgetOptions($opt)
}
}
}
return $opt
} else {
set choices [HumanizeList $list]
error "ambiguous $object \"$opt\"; must be one of $choices"
}
}
# ::combobox2::HumanizeList --
#
# Returns a human-readable form of a list by separating items
# by columns, but separating the last two elements with "or"
# (eg: foo, bar or baz)
#
# Arguments:
#
# list a valid tcl list
#
# Results:
#
# A string which as all of the elements joined with ", " or
# the word " or "
proc ::combobox2::HumanizeList {list} {
if {[llength $list] == 1} {
return [lindex $list 0]
} else {
set list [lsort $list]
set secondToLast [expr {[llength $list] -2}]
set most [lrange $list 0 $secondToLast]
set last [lindex $list end]
return "[join $most {, }] or $last"
}
}
# end of combobox.tcl
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?