SelList.st
author Claus Gittinger <cg@exept.de>
Wed, 17 Jan 1996 12:18:40 +0100
changeset 291 71f4a66b3281
parent 204 2da6481de6d4
child 359 dec35d4fbc35
permissions -rw-r--r--
*** empty log message ***

"
 COPYRIGHT (c) 1994 by Claus Gittinger
	      All Rights Reserved

 This software is furnished under a license and may be used
 only in accordance with the terms of that license and with the
 inclusion of the above copyright notice.   This software may not
 be provided or otherwise made available to, or used by, any
 other person.  No title to or ownership of the software is
 hereby transferred.
"

ValueHolder subclass:#SelectionInList
	 instanceVariableNames:'listHolder selectionIndexHolder'
	 classVariableNames:''
	 poolDictionaries:''
	 category:'Interface-Support-Models'
!

!SelectionInList class methodsFor:'documentation'!

copyright
"
 COPYRIGHT (c) 1994 by Claus Gittinger
	      All Rights Reserved

 This software is furnished under a license and may be used
 only in accordance with the terms of that license and with the
 inclusion of the above copyright notice.   This software may not
 be provided or otherwise made available to, or used by, any
 other person.  No title to or ownership of the software is
 hereby transferred.
"
!

documentation
"
    Instances of SelectionInList can be used as model for
    a SelectionInListView or a PopUpList. 
    They keep two values: a list value and a selection value; 
    both are referred to via valueHolders.

    If  any changes, the selectionInList notifies its dependents via a 
    self changed: notification, 
    using #list or #selectionIndex as aspect respectively.
    A popupList also knows how to deal with a slectionInList model;
    this makes it possible to have popupLists be somewhat exchangable
    with selectionInListViews.
"
!

examples
"
  basic setup:

    |m v|

    m := SelectionInList new.
    m list:#('one' 'two' 'three' 'four').
    m selectionIndex:2.

    v := SelectionInListView on:m.
    v open


  two views on the same selectionInList:
  and a button, which adds an item to the list.

    |m v1 v2 b numItems|

    numItems := 4.

    m := SelectionInList new.
    m list:((1 to:numItems) collect:[:i | i printString]).
    m selectionIndex:2.

    v1 := ScrollableView forView:(SelectionInListView on:m).
    v1 open.

    v2 := ScrollableView forView:(SelectionInListView on:m).
    v2 open.

    b := Button label:'add item'.
    b action:[numItems := numItems + 1.
	      m list:((1 to:numItems) collect:[:i | i printString]).
	     ].
    b open
"
! !

!SelectionInList class methodsFor:'instance creation'!

new
    ^ super new initialize
!

with:aList 
    ^ self new listHolder:(ValueHolder with:aList)
! !

!SelectionInList methodsFor:'accessing-holders'!

listHolder
    "return the one holding the list"

    ^ listHolder
!

listHolder:aValueHolder
    "set the one holding the list.
     Q: should we forward a change-notification ?"

    listHolder notNil ifTrue:[
	listHolder removeDependent:self
    ].
    listHolder := aValueHolder.
    listHolder addDependent:self
!

selectionHolder
    "return someone holding on the selection itself
     (not the index). Since we have no one, we need an adapter,
     to get up-to-date values."

    ^ AspectAdaptor 
	subject:self sendsUpdates:true
	accessWith:#selection assignWith:#'selection:' aspect:#selectionIndex
!

selectionIndexHolder
    "return the one holding the index"

    ^ selectionIndexHolder
!

selectionIndexHolder:aValueHolder
    "set the one holding the index.
     Q: should we forward a change-notification ?"

    selectionIndexHolder notNil ifTrue:[
	selectionIndexHolder removeDependent:self
    ].
    selectionIndexHolder := aValueHolder.
    selectionIndexHolder addDependent:self
! !

!SelectionInList methodsFor:'accessing-values'!

list
    ^ listHolder value
!

list:aCollection
    listHolder value:aCollection.
!

selection
    "return the selections value (i.e. the entry in the list"

    |idx|

    idx := self selectionIndex.
    (idx isNil or:[idx == 0]) ifTrue:[^ nil].
    ^ self list at:idx
!

selection:anObject 
    "set the selection to be anObject.
     If anObject is not in the list, the selection is cleared"

    ^ self selectionIndex:(self list indexOf:anObject ifAbsent:0)
!

selectionIndex 
    ^ selectionIndexHolder value
!

selectionIndex:newIndex 
    selectionIndexHolder value ~= newIndex ifTrue:[
	selectionIndexHolder value:newIndex
    ]
! !

!SelectionInList methodsFor:'change & update'!

update:something with:aParameter from:changedObject
    "whenever one of my holders value changes,
     tell my dependents about this"

    changedObject == selectionIndexHolder ifTrue:[
"/        self notifyChange:#selectionIndex
	self changed:#selectionIndex
    ] ifFalse:[
	changedObject == listHolder ifTrue:[
	    something == #value ifTrue:[
		selectionIndexHolder setValue:0.
"/                self notifyChange:#list.
"/                selectionIndexHolder notifyChange:#value
		self changed:#list.
		selectionIndexHolder changed:#value
	    ]
	]
    ]
! !

!SelectionInList methodsFor:'initialization'!

initialize
    self listHolder:(nil asValue).      "/ could also use an empty collection here
    self selectionIndexHolder:(nil asValue).
! !

!SelectionInList methodsFor:'obsolete backward compatibility'!

index
    "OBSOLETE interface"

    self obsoleteMethodWarning:'use #selectionIndex'.
    ^ self selectionIndex
!

index:newIndex
    "OBSOLETE interface"

    self obsoleteMethodWarning:'use #selectionIndex:'.
    ^ self selectionIndex:newIndex
!

indexHolder
    "OBSOLETE interface"

    self obsoleteMethodWarning:'use #selectionIndexHolder'.
    ^ self selectionIndexHolder
!

indexHolder:aValueHolder
    "OBSOLETE interface"

    self obsoleteMethodWarning:'use #selectionIndexHolder:'.
    ^ self selectionIndexHolder:aValueHolder
! !

!SelectionInList class methodsFor:'documentation'!

version
    ^ '$Header: /cvs/stx/stx/libwidg/Attic/SelList.st,v 1.7 1995-11-23 17:48:50 cg Exp $'
! !