You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

166 lines
4.6 KiB

# $Id: selector.tcl,v 2.8 2006/01/27 19:05:52 andreas_kupries Exp $
package require Tk 8.3-
package require stooop
# implements generic selection on a list of unique identifiers
::stooop::class selector {
proc selector {this args} switched {$args} {
::set ($this,order) 0
switched::complete $this
}
proc ~selector {this} {
variable ${this}selected
variable ${this}order
catch {::unset ${this}selected ${this}order}
}
proc options {this} {
return [::list\
[::list -selectcommand {} {}]\
]
}
# nothing to do as value is stored at the switched level
proc set-selectcommand {this value} {}
proc set {this indices selected} {
variable ${this}selected
variable ${this}order
::set select {}
::set deselect {}
foreach index $indices {
if {\
[info exists ${this}selected($index)] &&\
($selected == [::set ${this}selected($index)])\
} continue ;# no change
if {$selected} {
lappend select $index
::set ${this}selected($index) 1
} else {
lappend deselect $index
::set ${this}selected($index) 0
}
# keep track of action order
::set ${this}order($index) $($this,order)
incr ($this,order)
}
update $this $select $deselect
}
proc update {this selected deselected} {
if {[string length $switched::($this,-selectcommand)] == 0} return
if {[llength $selected] > 0} {
uplevel #0 $switched::($this,-selectcommand) [::list $selected] 1
}
if {[llength $deselected] > 0} {
uplevel #0 $switched::($this,-selectcommand) [::list $deselected] 0
}
}
proc unset {this indices} {
variable ${this}selected
variable ${this}order
foreach index $indices {
::unset ${this}selected($index) ${this}order($index)
}
}
proc ordered {this index1 index2} {
# used for sorting with lsort command according to order
variable ${this}order
return [expr {\
[::set ${this}order($index1)] - [::set ${this}order($index2)]\
}]
}
### public procedures follow:
proc add {this indices} {
set $this $indices 0
}
proc remove {this indices} {
unset $this $indices
}
proc select {this indices} {
clear $this
set $this $indices 1
# keep track of last selected object for extension
::set ($this,lastSelected) [lindex $indices end]
}
proc deselect {this indices} {
set $this $indices 0
}
proc toggle {this indices} {
variable ${this}selected
variable ${this}order
::set select {}
::set deselect {}
foreach index $indices {
if {[::set ${this}selected($index)]} {
lappend deselect $index
::set ${this}selected($index) 0
if {\
[info exists ($this,lastSelected)] &&\
($index == $($this,lastSelected))\
} {
# too complicated to find out what was selected last
::unset ($this,lastSelected)
}
} else {
lappend select $index
::set ${this}selected($index) 1
# keep track of last selected object for extension
::set ($this,lastSelected) $index
}
# keep track of action order
::set ${this}order($index) $($this,order)
incr ($this,order)
}
update $this $select $deselect
}
::stooop::virtual proc extend {this index} {}
proc clear {this} {
variable ${this}selected
set $this [array names ${this}selected] 0
}
::stooop::virtual proc selected {this} {
# derived class may want to do some additional processing,
# such as sorting, ...
variable ${this}selected
::set list {}
foreach {index value} [array get ${this}selected] {
if {$value} {
lappend list $index
}
}
return [lsort -command "ordered $this" $list] ;# ordered
}
::stooop::virtual proc list {this} {
# derived class may want to do some additional processing,
# such as sorting, ...
variable ${this}selected
# ordered:
return [lsort -command "ordered $this" [array names ${this}selected]]
}
}