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
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]] |
|
} |
|
|
|
}
|
|
|