summaryrefslogtreecommitdiff
path: root/itcl/iwidgets3.0.0/generic/disjointlistbox.itk
diff options
context:
space:
mode:
Diffstat (limited to 'itcl/iwidgets3.0.0/generic/disjointlistbox.itk')
-rwxr-xr-xitcl/iwidgets3.0.0/generic/disjointlistbox.itk489
1 files changed, 489 insertions, 0 deletions
diff --git a/itcl/iwidgets3.0.0/generic/disjointlistbox.itk b/itcl/iwidgets3.0.0/generic/disjointlistbox.itk
new file mode 100755
index 00000000000..5f40399fa8e
--- /dev/null
+++ b/itcl/iwidgets3.0.0/generic/disjointlistbox.itk
@@ -0,0 +1,489 @@
+#
+# ::iwidgets::Disjointlistbox
+# ----------------------------------------------------------------------
+# Implements a widget which maintains a disjoint relationship between
+# the items displayed by two listboxes. The disjointlistbox is composed
+# of 2 Scrolledlistboxes, 2 Pushbuttons, and 2 labels.
+#
+# The disjoint behavior of this widget exists between the two Listboxes,
+# That is, a given instance of a ::iwidgets::Disjointlistbox will never
+# exist which has Listbox widgets with items in common.
+#
+# Users may transfer items between the two Listbox widgets using the
+# the two Pushbuttons.
+#
+# The options include the ability to configure the "items" displayed by
+# either of the two Listboxes and to control the placement of the insertion
+# and removal buttons.
+#
+# The following depicts the allowable "-buttonplacement" option values
+# and their associated layout:
+#
+# "-buttonplacement" => center
+#
+# --------------------------
+# |listbox| |listbox|
+# | |________| |
+# | (LHS) | button | (RHS) |
+# | |========| |
+# | | button | |
+# |_______|--------|_______|
+# | count | | count |
+# --------------------------
+#
+# "-buttonplacement" => bottom
+#
+# ---------------------
+# | listbox | listbox |
+# | (LHS) | (RHS) |
+# |_________|_________|
+# | button | button |
+# |---------|---------|
+# | count | count |
+# ---------------------
+#
+# ----------------------------------------------------------------------
+# AUTHOR: John A. Tucker EMAIL: jatucker@spd.dsccc.com
+#
+# ======================================================================
+
+#
+# Default resources.
+#
+
+set tk_strictMotif 1
+
+option add *Disjointlistbox.lhsLabelText Available widgetDefault
+option add *Disjointlistbox.rhsLabelText Current widgetDefault
+option add *Disjointlistbox.lhsButtonLabel {Insert >>} widgetDefault
+option add *Disjointlistbox.rhsButtonLabel {<< Remove} widgetDefault
+option add *Disjointlistbox.vscrollMode static widgetDefault
+option add *Disjointlistbox.hscrollMode static widgetDefault
+option add *Disjointlistbox.selectMode multiple widgetDefault
+option add *Disjointlistbox.labelPos nw widgetDefault
+option add *Disjointlistbox.buttonPlacement bottom widgetDefault
+
+
+#
+# Usual options.
+#
+itk::usual Disjointlistbox {
+ keep -background -textbackground -cursor \
+ -foreground -textfont -labelfont
+}
+
+
+# ----------------------------------------------------------------------
+# ::iwidgets::Disjointlistbox
+# ----------------------------------------------------------------------
+class ::iwidgets::Disjointlistbox {
+
+ inherit itk::Widget
+
+ #
+ # options
+ #
+ itk_option define -buttonplacement buttonPlacement ButtonPlacement bottom
+ itk_option define -lhsbuttonlabel lhsButtonLabel LabelText {Insert >>}
+ itk_option define -rhsbuttonlabel rhsButtonLabel LabelText {<< Remove}
+
+ constructor {args} {}
+
+ #
+ # PUBLIC
+ #
+ public {
+ method clear {}
+ method getlhs {{first 0} {last end}}
+ method getrhs {{first 0} {last end}}
+ method lhs {args}
+ method insertlhs {items}
+ method insertrhs {items}
+ method setlhs {items}
+ method setrhs {items}
+ method rhs {args}
+ }
+
+ #
+ # PROTECTED
+ #
+ protected {
+ method insert {theListbox items}
+ method listboxClick {clickSide otherSide}
+ method listboxDblClick {clickSide otherSide}
+ method remove {theListbox items}
+ method showCount {}
+ method transfer {}
+
+ variable sourceListbox {}
+ variable destinationListbox {}
+ }
+}
+
+#
+# Provide a lowercased access method for the ::iwidgets::Disjointlistbox class.
+#
+proc ::iwidgets::disjointlistbox {pathName args} {
+ uplevel ::iwidgets::Disjointlistbox $pathName $args
+}
+
+# ------------------------------------------------------------------
+#
+# Method: Constructor
+#
+# Purpose:
+#
+body ::iwidgets::Disjointlistbox::constructor {args} {
+ #
+ # Create the left-most Listbox
+ #
+ itk_component add lhs {
+ iwidgets::Scrolledlistbox $itk_interior.lhs \
+ -selectioncommand [code $this listboxClick lhs rhs] \
+ -dblclickcommand [code $this listboxDblClick lhs rhs]
+ } {
+ usual
+ keep -selectmode -vscrollmode -hscrollmode
+ rename -labeltext -lhslabeltext lhsLabelText LabelText
+ }
+
+ #
+ # Create the right-most Listbox
+ #
+ itk_component add rhs {
+ iwidgets::Scrolledlistbox $itk_interior.rhs \
+ -selectioncommand [code $this listboxClick rhs lhs] \
+ -dblclickcommand [code $this listboxDblClick rhs lhs]
+ } {
+ usual
+ keep -selectmode -vscrollmode -hscrollmode
+ rename -labeltext -rhslabeltext rhsLabelText LabelText
+ }
+
+ #
+ # Create the left-most item count Label
+ #
+ itk_component add lhsCount {
+ label $itk_interior.lhscount
+ } {
+ usual
+ rename -font -labelfont labelFont Font
+ }
+
+ #
+ # Create the right-most item count Label
+ #
+ itk_component add rhsCount {
+ label $itk_interior.rhscount
+ } {
+ usual
+ rename -font -labelfont labelFont Font
+ }
+
+ set sourceListbox $itk_component(lhs)
+ set destinationListbox $itk_component(rhs)
+
+ #
+ # Bind the "showCount" method to the Map event of one of the labels
+ # to keep the diplayed item count current.
+ #
+ bind $itk_component(lhsCount) <Map> [code $this showCount]
+
+ grid $itk_component(lhs) -row 0 -column 0 -sticky nsew
+ grid $itk_component(rhs) -row 0 -column 2 -sticky nsew
+
+ grid rowconfigure $itk_interior 0 -weight 1
+ grid columnconfigure $itk_interior 0 -weight 1
+ grid columnconfigure $itk_interior 2 -weight 1
+
+ eval itk_initialize $args
+}
+
+# ------------------------------------------------------------------
+# Method: listboxClick
+#
+# Purpose: Evaluate a single click make in the specified Listbox.
+#
+body ::iwidgets::Disjointlistbox::listboxClick {clickSide otherSide} {
+ set button "button"
+ $itk_component($clickSide$button) configure -state active
+ $itk_component($otherSide$button) configure -state disabled
+ set sourceListbox $itk_component($clickSide)
+ set destinationListbox $itk_component($otherSide)
+}
+
+# ------------------------------------------------------------------
+# Method: listboxDblClick
+#
+# Purpose: Evaluate a double click in the specified Listbox.
+#
+body ::iwidgets::Disjointlistbox::listboxDblClick {clickSide otherSide} {
+ listboxClick $clickSide $otherSide
+ transfer
+}
+
+# ------------------------------------------------------------------
+# Method: transfer
+#
+# Purpose: Transfer source Listbox items to destination Listbox
+#
+body ::iwidgets::Disjointlistbox::transfer {} {
+
+ if {[$sourceListbox selecteditemcount] == 0} {
+ return
+ }
+ set selectedindices [lsort -integer -decreasing [$sourceListbox curselection]]
+ set selecteditems [$sourceListbox getcurselection]
+
+ foreach index $selectedindices {
+ $sourceListbox delete $index
+ }
+
+ foreach item $selecteditems {
+ $destinationListbox insert end $item
+ }
+ $destinationListbox sort increasing
+
+ showCount
+}
+
+# ------------------------------------------------------------------
+# Method: getlhs
+#
+# Purpose: Retrieve the items of the left Listbox widget
+#
+body ::iwidgets::Disjointlistbox::getlhs {{first 0} {last end}} {
+ return [lhs get $first $last]
+}
+
+# ------------------------------------------------------------------
+# Method: getrhs
+#
+# Purpose: Retrieve the items of the right Listbox widget
+#
+body ::iwidgets::Disjointlistbox::getrhs {{first 0} {last end}} {
+ return [rhs get $first $last]
+}
+
+# ------------------------------------------------------------------
+# Method: insertrhs
+#
+# Purpose: Insert items into the right Listbox widget
+#
+body ::iwidgets::Disjointlistbox::insertrhs {items} {
+ remove $itk_component(lhs) $items
+ insert $itk_component(rhs) $items
+}
+
+# ------------------------------------------------------------------
+# Method: insertlhs
+#
+# Purpose: Insert items into the left Listbox widget
+#
+body ::iwidgets::Disjointlistbox::insertlhs {items} {
+ remove $itk_component(rhs) $items
+ insert $itk_component(lhs) $items
+}
+
+# ------------------------------------------------------------------
+# Method: clear
+#
+# Purpose: Remove the items from the Listbox widgets and set the item count
+# Labels text to 0
+#
+body ::iwidgets::Disjointlistbox::clear {} {
+ lhs clear
+ rhs clear
+ showCount
+}
+
+# ------------------------------------------------------------------
+# Method: insert
+#
+# Purpose: Insert the input items into the input Listbox widget while
+# maintaining the disjoint property between them.
+#
+body ::iwidgets::Disjointlistbox::insert {theListbox items} {
+
+ set curritems [$theListbox get 0 end]
+
+ foreach item $items {
+ #
+ # if the item is not already present in the Listbox then insert it
+ #
+ if {[lsearch -exact $curritems $item] == -1} {
+ $theListbox insert end $item
+ }
+ }
+ $theListbox sort increasing
+ showCount
+}
+
+# ------------------------------------------------------------------
+# Method: remove
+#
+# Purpose: Remove the input items from the input Listbox widget while
+# maintaining the disjoint property between them.
+#
+body ::iwidgets::Disjointlistbox::remove {theListbox items} {
+
+ set indexes {}
+ set curritems [$theListbox get 0 end]
+
+ foreach item $items {
+ #
+ # if the item is in the listbox then add its index to the index list
+ #
+ if {[set index [lsearch -exact $curritems $item]] != -1} {
+ lappend indexes $index
+ }
+ }
+
+ foreach index [lsort -integer -decreasing $indexes] {
+ $theListbox delete $index
+ }
+ showCount
+}
+
+# ------------------------------------------------------------------
+# Method: showCount
+#
+# Purpose: Set the text of the item count Labels.
+#
+body ::iwidgets::Disjointlistbox::showCount {} {
+ $itk_component(lhsCount) config -text "item count: [lhs size]"
+ $itk_component(rhsCount) config -text "item count: [rhs size]"
+}
+
+# ------------------------------------------------------------------
+# METHOD: setlhs
+#
+# Set the items of the left-most Listbox with the input list
+# option. Remove all (if any) items from the right-most Listbox
+# which exist in the input list option to maintain the disjoint
+# property between the two
+#
+body ::iwidgets::Disjointlistbox::setlhs {items} {
+ lhs clear
+ insertlhs $items
+}
+
+# ------------------------------------------------------------------
+# METHOD: setrhs
+#
+# Set the items of the right-most Listbox with the input list
+# option. Remove all (if any) items from the left-most Listbox
+# which exist in the input list option to maintain the disjoint
+# property between the two
+#
+body ::iwidgets::Disjointlistbox::setrhs {items} {
+ rhs clear
+ insertrhs $items
+}
+
+# ------------------------------------------------------------------
+# Method: lhs
+#
+# Purpose: Evaluates the specified arguments against the lhs Listbox
+#
+body ::iwidgets::Disjointlistbox::lhs {args} {
+ return [eval $itk_component(lhs) $args]
+}
+
+# ------------------------------------------------------------------
+# Method: rhs
+#
+# Purpose: Evaluates the specified arguments against the rhs Listbox
+#
+body ::iwidgets::Disjointlistbox::rhs {args} {
+ return [eval $itk_component(rhs) $args]
+}
+
+# ------------------------------------------------------------------
+# OPTION: buttonplacement
+#
+# Configure the placement of the buttons to be either between or below
+# the two list boxes.
+#
+configbody ::iwidgets::Disjointlistbox::buttonplacement {
+ if {$itk_option(-buttonplacement) != ""} {
+
+ if { [lsearch [component] lhsbutton] != -1 } {
+ eval destroy $itk_component(rhsbutton) $itk_component(lhsbutton)
+ }
+
+ if { [lsearch [component] bbox] != -1 } {
+ destroy $itk_component(bbox)
+ }
+
+ set where $itk_option(-buttonplacement)
+
+ switch $where {
+
+ center {
+ #
+ # Create the button box frame
+ #
+ itk_component add bbox {
+ frame $itk_interior.bbox
+ }
+
+ itk_component add lhsbutton {
+ button $itk_component(bbox).lhsbutton -command [code $this transfer]
+ } {
+ usual
+ rename -text -lhsbuttonlabel lhsButtonLabel LabelText
+ rename -font -labelfont labelFont Font
+ }
+
+ itk_component add rhsbutton {
+ button $itk_component(bbox).rhsbutton -command [code $this transfer]
+ } {
+ usual
+ rename -text -rhsbuttonlabel rhsButtonLabel LabelText
+ rename -font -labelfont labelFont Font
+ }
+
+ grid configure $itk_component(lhsCount) -row 1 -column 0 -sticky ew
+ grid configure $itk_component(rhsCount) -row 1 -column 2 -sticky ew
+
+ grid configure $itk_component(bbox) \
+ -in $itk_interior -row 0 -column 1 -columnspan 1 -sticky nsew
+
+ grid configure $itk_component(rhsbutton) \
+ -in $itk_component(bbox) -row 0 -column 0 -sticky ew
+ grid configure $itk_component(lhsbutton) \
+ -in $itk_component(bbox) -row 1 -column 0 -sticky ew
+ }
+
+ bottom {
+
+ itk_component add lhsbutton {
+ button $itk_interior.lhsbutton -command [code $this transfer]
+ } {
+ usual
+ rename -text -lhsbuttonlabel lhsButtonLabel LabelText
+ rename -font -labelfont labelFont Font
+ }
+
+ itk_component add rhsbutton {
+ button $itk_interior.rhsbutton -command [code $this transfer]
+ } {
+ usual
+ rename -text -rhsbuttonlabel rhsButtonLabel LabelText
+ rename -font -labelfont labelFont Font
+ }
+
+ grid $itk_component(lhsCount) -row 2 -column 0 -sticky ew
+ grid $itk_component(rhsCount) -row 2 -column 2 -sticky ew
+ grid $itk_component(lhsbutton) -row 1 -column 0 -sticky ew
+ grid $itk_component(rhsbutton) -row 1 -column 2 -sticky ew
+ }
+
+ default {
+ error "bad buttonplacement option\"$where\": should be center or bottom"
+ }
+ }
+ }
+}
+