# gui/implementation/ListBox.tcl

    @implementation ListBox {
      - init {} {
          $super init
          $self hideBorder
          set bg [$frame cget -bg]
          $frame configure -relief sunken -bd 1
          set listbox [listbox $frame.listbox -exportselection no -bd 1 \
            -relief flat]
          set xscroll [scrollbar $frame.xscroll -orient horizontal \
            -command "$listbox xview"]
          set yscroll [scrollbar $frame.yscroll -orient vertical \
            -command "$listbox yview"]

          $listbox configure -xscrollcommand "$xscroll set" \
            -yscrollcommand "$yscroll set"
          grid rowconfigure $frame 0 -weight 1
          grid columnconfigure $frame 0 -weight 1
          grid $listbox $frame.yscroll -sticky snew -padx 0 -pady 0
          grid $frame.xscroll -sticky snew -padx 0 -pady 0
          set font [$listbox cget -font]
          if {[set index [lsearch -exact $font bold]] != -1} {
            $listbox configure -font [lreplace $font $index $index]
          }
          bind $listbox <ButtonRelease-1> "$self selectionChange"
          set callbacks(Selection) {}
        }

      - list {} {
          return [$listbox get 0 end]
        }

      - list: aList {
          foreach item $aList {
            $listbox insert end $item
          }
        }

      - add: anItem {
          $listbox insert end $anItem
          $self update
        }
      - remove: anItem {
          if {[set i [lsearch -exact [$listbox get 0 end] $anItem]] == -1} {
            return
          }
          $listbox delete $i
          $self update
        }
      - removeIndex: anIndex {
          catch {$listbox delete $anIndex}
        }
      - contains: anItem {
          set aList [$listbox get 0 end]
          return [aList contains: $anItem]
        }

      - selection {} {
          if {![string length [set i [$self indexOfSelection]]]} { return }
          return [$listbox get $i]
        }
      - selection: anItem {
          if {[set i [lsearch -exact [$listbox get 0 end] $anItem]] == -1} {
            return
          }
          $listbox selection set $i
        }
      - clearSelection {} {
          $listbox selection clear 0 end
        }

      - indexOfSelection {} {
          return [$listbox curselection]
        }
      - indexOfSelection: anIndex {
          $listbox selection set $anIndex
        }

      - onSelection: aCallback {
          set callbacks(Selection) $aCallback
        }
      - onSelection {} {
          return $callbacks(Selection)
        }
      - selectionChange {} {
          catch {eval $callbacks(Selection)}
        }

      - clear {} {
          $listbox delete 0 end
        }
      - sort {} {
          set myList [$self list]
          myList sort
          $self list: $myList
        }

      - width: width {
          $listbox configure -width $width
        }
      - width {} {
          return [$listbox cget -width]
        }
      - height: height {
          $listbox configure -height $height
        }
      - height {} {
          return [$listbox cget -height]
        }

      - listbox {} {
          return $listbox
        }

      - loadFromFile: aFile {
          if [catch {set f [open $aFile r]} err] {
            return [error "$self loadFromFile: $aFile ($err)"]
          }
          while {[eof $f] == 0} {
            gets $f line
            $self add: $line
          }
          close $f
          $self update
        }

      - dealloc {} {
          catch {destroy $listbox}
          return [$super dealloc]
        }

      - update {} {
          eval [bind $listbox <Configure>]
        }
    }