gui/implementation/SwitchBox.tcl


@implementation SwitchBox {
  - init {} {
      $super init
      $self hideBorder
      set imageOff [@imageCopy switchOff]
      set imageOn [@imageCopy switchOn]
      set callbacks(Change) {}
    }

  - items {} {
      return [fieldValueList fields]      
    }
  - items: anItemsList {
      $self clear
      foreach item $anItemsList {
        $self add: $item
      }
    }

  - values {} {
      return [fieldValueList values]      
    }
  - values: aValuesList {
      foreach value $aValuesList field [$self items] {
        $self valueOf: $field to: $value
      }
    }

  - list {} {
      return $fieldValueList
    }
  - list: aFieldValueList {
      foreach {field value} $aFieldValueList {
        $self add: $field withValue: $value
      }
    }

  - valueOf: anItem {
      return [fieldValueList get: $anItem]
    }
  - valueOf:to: {anItem boolean} {
      switch $boolean {
        0 { set img $imageOff }
        1 { set img $imageOn }
        default { return -code error "unknown boolean ($boolean)" }
      }
      fieldValueList set: $anItem to: $boolean
      "$frame.i$anItem" configure -image $img
      $self onChange
    }

  - switchOn: anItem {
      $self valueOf: $anItem to: 1
    }
  - switchOff: anItem {
      $self valueOf: $anItem to: 0
    }

  - toggle: anItem {
      if [fieldValueList get: $anItem] {
        $self switchOff: $anItem
      } else {
        $self switchOn: $anItem
      }
    }

  - add: anItem {
      $self add: $anItem withValue: 0
    }
  - add:withValue: {anItem boolean} {
      if [$self contains: $anItem] { return $self }
      fieldValueList add: [list $anItem 0]
      grid [label "$frame.l$anItem" -text $anItem -anchor e] \
        [label "$frame.i$anItem" -image $imageOff -bd 1 -relief raised] \
        -sticky ew
      bind "$frame.l$anItem" <ButtonPress-1> "$self toggle: \"$anItem\""
      bind "$frame.i$anItem" <ButtonPress-1> "$self toggle: \"$anItem\""
      bind "$frame.l$anItem" <ButtonRelease-1> "$self valueChangeFor: \"$anItem\""
      bind "$frame.i$anItem" <ButtonRelease-1> "$self valueChangeFor: \"$anItem\""
      eval bind \"$frame.l$anItem\" [@removeBindingsOnDestroyEvent]
      eval bind \"$frame.i$anItem\" [@removeBindingsOnDestroyEvent]
      $self valueOf: $anItem to: $boolean
    }
  - remove: anItem {
      if {![$self contains: $anItem]} { return $self }
      fieldValueList remove: $anItem
      catch {destroy "$frame.l$anItem" "$frame.i$anItem"}
    }
  - contains: anItem {
      return [fieldValueList contains: $anItem]
    }

  - onChange: aCallback {
      set callbacks(Change) $aCallback
    }
  - onChange {} {
      return $callbacks(Change)
    }
  - valueChangeFor: selection {
      if [string length $callbacks(Change)] {
        catch {eval $callbacks(Change)}
      }
    }

  - clear {} {
      foreach {field value} $fieldValueList {
        $self remove: $field
      }
    }
  - sort {} {
      foreach field [set fields [$self items]] {
        grid forget "$frame.l$field" "$frame.i$field"
      }
      fieldValueList sortByField
      foreach {field value} $fieldValueList {
        grid "$frame.l$field" "$frame.i$field" -sticky ew
      }
    }

  - loadFromFile: aFile {
      if [catch {set f [open $aFile r]} err] {
        return -code error "$self loadFromFile: $aFile ($err)"
      }
      while {[eof $f] == 0} {
        gets $f line
        if [string length $line] {
          if [regexp "," $line] {
            set field [lindex [split $line ,] 0]
            set value [lindex [split $line ,] 1]
            $self add: $field withValue: $value
          } else {
            $self add: $line 
          }
        }
      }
      close $f
    }

  - dealloc {} {
      foreach {field value} $fieldValueList {
        catch {destroy "$frame.l$field" "$frame.i$field"}
      }
      return [$super dealloc]
    }
}