BufferedValueHolder.st
author claus
Tue, 16 May 1995 19:12:27 +0200
changeset 74 4f786ce84f51
parent 72 ba662a33428d
child 90 59d4413a8c39
permissions -rw-r--r--
.

"
 COPYRIGHT (c) 1995 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:#BufferedValueHolder 
	 instanceVariableNames:'subject triggerChannel bufferedValue'
	 classVariableNames:'NotYetAssigned'
	 poolDictionaries:''
	 category:'Interface-Support-Models'
!

!BufferedValueHolder class methodsFor:'documentation'!

copyright
"
 COPYRIGHT (c) 1995 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.
"
!

version
"
$Header: /cvs/stx/stx/libview2/BufferedValueHolder.st,v 1.3 1995-05-16 17:12:27 claus Exp $
"
!

documentation
"
    a bufferedValueHolder keeps atemporary copy of the realHolders value,
    and only does a real store of the value when triggered.
    Triggering is done by depending on a trigger objects value, which is
    typically a ValueHolder for a boolean, which is set by an ok-button.

    Notice: this class was implemented using protocol information
    from alpha testers - it may not be complete or compatible to
    the corresponding ST-80 class. If you encounter any incompatibilities,
    please forward a note to the ST/X team.
"
!

examples 
"
    unbuffered (values are changed, even if not accepted,
    iff a field is left with Return or accept is done in a field):

	|firstName lastName dialog|

	firstName :=  'foo' asValue.
	lastName := 'bar' asValue.

	dialog := Dialog new.
	(dialog addTextLabel:'Name:') layout:#left.
	dialog addInputFieldOn:firstName.
	dialog addVerticalSpace.
	(dialog addTextLabel:'Address:') layout:#left.
	dialog addInputFieldOn:lastName.

	dialog addAbortButton; addOkButton.

	dialog open.

	Transcript show:firstName value; show:' '; showCr:lastName value


    buffered (values are only stored when accepted; undo reloads old values)
    (use an instance of TriggerValue. If a ValueHolder was used, we had
     to temporarily set its value back to nil, to have the change really be
     forwarded to its dependends)

	|firstName lastName trigger dialog|

	firstName :=  'foo' asValue.
	lastName := 'bar' asValue.
	trigger := TriggerValue new.

	dialog := Dialog new.
	(dialog addTextLabel:'Name:') layout:#left.
	dialog addInputFieldOn:(BufferedValueHolder
				    subject:firstName
				    triggerChannel:trigger).
	dialog addVerticalSpace.
	(dialog addTextLabel:'Address:') layout:#left.
	dialog addInputFieldOn:(BufferedValueHolder
				    subject:lastName
				    triggerChannel:trigger).

	dialog addAbortButton; 
	       addButton:(Button new 
				label:'undo'; 
				action:[trigger value:false]);
	       addOkButton.

	dialog open.
	dialog accepted ifTrue:[
	    trigger value:true
	].

	Transcript show:firstName value; show:' '; showCr:lastName value
"
! !

!BufferedValueHolder class methodsFor:'initialization'!

intialize
    NotYetAssigned := Object new
! !

!BufferedValueHolder class methodsFor:'instance creation'!

subject:someModel triggerChannel:aTrigger
    "return a new BufferedValueHolder offering a buffered copy of someModels
     value - only updating this value, when aTrigger changes to true."

    ^ self new subject:someModel; triggerChannel:aTrigger
! !

!BufferedValueHolder methodsFor:'initialization'!

initialize
    super initialize.
    bufferedValue := NotYetAssigned
! !
    
!BufferedValueHolder methodsFor:'change & update'!

update:something with:aParameter from:changedObject
    changedObject == triggerChannel ifTrue:[
	triggerChannel value == true ifTrue:[
	    "
	     now, store the buffered value into the subject
	    "
	    subject value:bufferedValue.
	    ^ self
	].
	triggerChannel value == false ifTrue:[
	    "
	     cancel: flush my buffered value
	    "
	    bufferedValue := NotYetAssigned.
	].
	self notifyChange:#value. 
	^ self
    ].
    changedObject == subject ifTrue:[
	bufferedValue := NotYetAssigned.
	self notifyChange:#value.
	^ self
    ].
! !

!BufferedValueHolder methodsFor:'accessing'!

subject:someModel
    subject notNil ifTrue:[
	subject removeDependent:self
    ].
    subject := someModel.
    subject notNil ifTrue:[
	subject addDependent:self
    ]
!

triggerChannel:aTrigger
    triggerChannel notNil ifTrue:[
	triggerChannel removeDependent:self
    ].
    triggerChannel := aTrigger.
    triggerChannel notNil ifTrue:[
	triggerChannel addDependent:self
    ]
!

setValue:anObject
    "set my value without notification."

    bufferedValue := anObject.
!

value
    "return my value"

    bufferedValue == NotYetAssigned ifTrue:[
	bufferedValue := subject value
    ].
    ^ bufferedValue
! !