combobox.wgt
来自「一个跨平台的TCL/TK可视开发环境类似VC. TCL/TK是一个跨平台的脚本」· WGT 代码 · 共 2,104 行 · 第 1/5 页
WGT
2,104 行
#
# NB: because of the sloppy way we are doing this,
# we'll also let the user enter our secret command
# directly (eg: listinsert, listdelete), but we
# won't document that fact
set command "list-[lindex $args 0]"
set args [lrange $args 1 end]
}
set result ""
# many of these commands are just synonyms for specific
# commands in one of the subwidgets. We'll get them out
# of the way first, then do the custom commands.
switch $command {
bbox -
delete -
get -
icursor -
index -
insert -
scan -
selection -
xview {
set result [eval $doWidgetCommand entry $command $args]
}
list-get {set result [eval $doWidgetCommand listbox get $args]}
list-index {set result [eval $doWidgetCommand listbox index $args]}
list-size {set result [eval $doWidgetCommand listbox size $args]}
select {
if {[llength $args] == 1} {
set index [lindex $args 0]
set result [Select $widgets(this) $index]
} else {
error "usage: $w select index"
}
}
subwidget {
set knownWidgets [list button entry listbox popup vsb]
if {[llength $args] == 0} {
return $knownWidgets
}
set name [lindex $args 0]
if {[lsearch $knownWidgets $name] != -1} {
set result $widgets($name)
} else {
error "unknown subwidget $name"
}
}
curselection {
set result [eval $doWidgetCommand listbox curselection]
}
list-insert {
eval $doWidgetCommand listbox insert $args
set result [HandleScrollbar $w "grow"]
}
list-delete {
eval $doWidgetCommand listbox delete $args
set result [HandleScrollbar $w "shrink"]
}
toggle {
# ignore this command if the widget is disabled...
if {$options(-state) == "disabled"} return
# pops down the list if it is not, hides it
# if it is...
if {[winfo ismapped $widgets(popup)]} {
set result [$widgets(this) close]
} else {
set result [$widgets(this) open]
}
}
open {
# if this is an editable combobox2, the focus should
# be set to the entry widget
if {$options(-editable)} {
focus $widgets(entry)
$widgets(entry) select range 0 end
$widgets(entry) icur end
}
# if we are disabled, we won't allow this to happen
if {$options(-state) == "disabled"} {
return 0
}
# compute the geometry of the window to pop up, and set
# it, and force the window manager to take notice
# (even if it is not presently visible).
#
# this isn't strictly necessary if the window is already
# mapped, but we'll go ahead and set the geometry here
# since its harmless and *may* actually reset the geometry
# to something better in some weird case.
set geometry [::combobox2::ComputeGeometry $widgets(this)]
wm geometry $widgets(popup) $geometry
update idletasks
# if we are already open, there's nothing else to do
if {[winfo ismapped $widgets(popup)]} {
return 0
}
# save the widget that currently has the focus; we'll restore
# the focus there when we're done
set oldFocus [focus]
# ok, tweak the visual appearance of things and
# make the list pop up
$widgets(button) configure -relief sunken
raise $widgets(popup) [winfo parent $widgets(this)]
wm deiconify $widgets(popup)
# force focus to the entry widget so we can handle keypress
# events for traversal
focus -force $widgets(entry)
# select something by default, but only if its an
# exact match...
::combobox2::Find $widgets(this) 1
# save the current grab state for the display containing
# this widget. We'll restore it when we close the dropdown
# list
set status "none"
set grab [grab current $widgets(this)]
if {$grab != ""} {set status [grab status $grab]}
set oldGrab [list $grab $status]
unset grab status
# *gasp* do a global grab!!! Mom always told not to
# do things like this, but these are desparate times.
grab -global $widgets(this)
# fake the listbox into thinking it has focus. This is
# necessary to get scanning initialized properly in the
# listbox.
event generate $widgets(listbox) <B1-Enter>
return 1
}
close {
# if we are already closed, don't do anything...
if {![winfo ismapped $widgets(popup)]} {
return 0
}
# restore the focus and grab, but ignore any errors...
# we're going to be paranoid and release the grab before
# trying to set any other grab because we really really
# really want to make sure the grab is released.
catch {focus $oldFocus} result
catch {grab release $widgets(this)}
catch {
set status [lindex $oldGrab 1]
if {$status == "global"} {
grab -global [lindex $oldGrab 0]
} elseif {$status == "local"} {
grab [lindex $oldGrab 0]
}
unset status
}
# hides the listbox
$widgets(button) configure -relief raised
wm withdraw $widgets(popup)
# select the data in the entry widget. Not sure
# why, other than observation seems to suggest that's
# what windows widgets do.
set editable [::combobox2::GetBoolean $options(-editable)]
if {$editable} {
$widgets(entry) selection range 0 end
$widgets(button) configure -relief raised
}
# magic tcl stuff (see tk.tcl in the distribution
# lib directory)
tkCancelRepeat
return 1
}
cget {
if {[llength $args] != 1} {
error "wrong # args: should be $w cget option"
}
set opt [::combobox2::Canonize $w option [lindex $args 0]]
if {$opt == "-value"} {
set result [$widget(entry) get]
} else {
set result $options($opt)
}
}
configure {
set result [eval ::combobox2::Configure {$w} $args]
}
default {
error "bad option \"$command\""
}
}
return $result
}
# ::combobox2::Configure --
#
# Implements the "configure" widget subcommand
#
# Arguments:
#
# w widget pathname
# args zero or more option/value pairs (or a single option)
#
# Results:
#
# Performs typcial "configure" type requests on the widget
proc ::combobox2::Configure {w args} {
variable widgetOptions
variable defaultEntryCursor
upvar ::combobox2::${w}::widgets widgets
upvar ::combobox2::${w}::options options
if {[llength $args] == 0} {
# hmmm. User must be wanting all configuration information
# note that if the value of an array element is of length
# one it is an alias, which needs to be handled slightly
# differently
set results {}
foreach opt [lsort [array names widgetOptions]] {
if {[llength $widgetOptions($opt)] == 1} {
set alias $widgetOptions($opt)
set optName $widgetOptions($alias)
lappend results [list $opt $optName]
} else {
# modif by Christian Gavin 08/02/2000
# if an option has been removed from the list
# (e.g. -value), don't try to access it
if [info exists options($opt)] {
set optName [lindex $widgetOptions($opt) 0]
set optClass [lindex $widgetOptions($opt) 1]
set default [option get $w $optName $optClass]
lappend results [list $opt $optName $optClass \
$default $options($opt)]
}
}
}
return $results
}
# one argument means we are looking for configuration
# information on a single option
if {[llength $args] == 1} {
set opt [::combobox2::Canonize $w option [lindex $args 0]]
set optName [lindex $widgetOptions($opt) 0]
set optClass [lindex $widgetOptions($opt) 1]
set default [option get $w $optName $optClass]
set results [list $opt $optName $optClass \
$default $options($opt)]
return $results
}
# if we have an odd number of values, bail.
if {[expr {[llength $args]%2}] == 1} {
# hmmm. An odd number of elements in args
error "value for \"[lindex $args end]\" missing"
}
# Great. An even number of options. Let's make sure they
# are all valid before we do anything. Note that Canonize
# will generate an error if it finds a bogus option; otherwise
# it returns the canonical option name
foreach {name value} $args {
set name [::combobox2::Canonize $w option $name]
set opts($name) $value
}
# process all of the configuration options
# some (actually, most) options require us to
# do something, like change the attributes of
# a widget or two. Here's where we do that...
foreach option [array names opts] {
set newValue $opts($option)
if {[info exists options($option)]} {
set oldValue $options($option)
}
switch -- $option {
-background {
$widgets(frame) configure -background $newValue
$widgets(entry) configure -background $newValue
$widgets(listbox) configure -background $newValue
# let's keep the scrollbar good-looking
# $widgets(vsb) configure -background $newValue
# $widgets(vsb) configure -troughcolor $newValue
set options($option) $newValue
}
-borderwidth {
$widgets(frame) configure -borderwidth $newValue
set options($option) $newValue
}
-command {
# nothing else to do...
set options($option) $newValue
}
-commandstate {
# do some value checking...
if {$newValue != "normal" && $newValue != "disabled"} {
set options($option) $oldValue
set message "bad state value \"$newValue\";"
append message " must be normal or disabled"
error $message
}
set options($option) $newValue
}
-cursor {
$widgets(frame) configure -cursor $newValue
$widgets(entry) configure -cursor $newValue
$widgets(listbox) configure -cursor $newValue
set options($option) $newValue
}
-editable {
if {$newValue} {
# it's editable...
$widgets(entry) configure \
-state normal \
-cursor $defaultEntryCursor
} else {
$widgets(entry) configure \
-state disabled \
-cursor $options(-cursor)
}
set options($option) $newValue
}
-font {
$widgets(entry) configure -font $newValue
$widgets(listbox) configure -font $newValue
set options($option) $newValue
}
-foreground {
$widgets(entry) configure -foreground $newValue
$widgets(button) configure -foreground $newValue
$widgets(listbox) configure -foreground $newValue
set options($option) $newValue
}
-height {
$widgets(listbox) configure -height $newValue
HandleScrollbar $w
set options($option) $newValue
}
-highlightbackground {
$widgets(frame) configure -highlightbackground $newValue
set options($option) $newValue
}
-highlightcolor {
$widgets(frame) configure -highlightcolor $newValue
set options($option) $newValue
}
-highlightthickness {
$widgets(frame) configure -highlightthickness $newValue
set options($option) $newValue
}
-image {
if {[string length $newValue] > 0} {
$widgets(button) configure -image $newValue
} else {
$widgets(button) configure -image ::combobox2::bimage
}
set options($option) $newValue
}
-maxheight {
# ComputeGeometry may dork with the actual height
# of the listbox, so let's undork it
$widgets(listbox) configure -height $options(-height)
HandleScrollbar $w
set options($option) $newValue
}
-relief {
$widgets(frame) configure -relief $newValue
set options($option) $newValue
}
-selectbackground {
$widgets(entry) configure -selectbackground $newValue
$widgets(listbox) configure -selectbackground $newValue
set options($option) $newValue
}
-selectborderwidth {
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?