AspctAdptr.st
author claus
Tue, 09 May 1995 02:23:22 +0200
changeset 69 225a9efd50f5
child 71 5b34cd877517
permissions -rw-r--r--
.

ProtocolAdaptor subclass:#AspectAdaptor 
	 instanceVariableNames:'myAspect getMsg putMsg'
	 classVariableNames:''
	 poolDictionaries:''
	 category:'Interface-Support'
!

!AspectAdaptor 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/Attic/AspctAdptr.st,v 1.1 1995-05-09 00:20:52 claus Exp $
"
!

documentation
"
    an AspectAdaptor forwards updates and change messages
    from/to a complex model.

    Consider the case where editFields are required for the
    elements (instance variables) of a more complex model.
    Without an aspect adaptor, you needed to copy the individual
    values out-of and into multiple valueHolders.
    An aspectAdaptor makes this easier, by playing model with
    vale/value: symbols towards the editField, and forwarding changes and
    updates to/from the complex model using different aspect symbols.

    Notice: this class was implemented using protocol information
    from alpha testers and PD code - 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
"
    a dialog on a points x/y coordinates:

	|dialog data f|

	data := 0@0.

	dialog := DialogBox new.
	dialog addTextLabel:'x:'.
	f := dialog addInputFieldOn:(AspectAdaptor new
					subject:data; 
					accessWith:#x 
					assignWith:#x:).
	f converter:(PrintConverter new initForNumber).

	dialog addTextLabel:'y:'.
	f := dialog addInputFieldOn:(AspectAdaptor new
					subject:data; 
					forAspect:#y).
	f converter:(PrintConverter new initForNumber).

	dialog addOkButton.
	data inspect.
	dialog open.

	dialog accepted ifTrue:[
	    Transcript showCr:'data now: ' , data printString
	]


    a dialog on a four-field complex model:


	|dialog data dataModel|

	data := #('hello' 'one' 'two' 'three').
	dataModel := Plug new.
	dataModel respondTo:#field1 with:[data at:1].
	dataModel respondTo:#field2 with:[data at:2].
	dataModel respondTo:#field3 with:[data at:3].
	dataModel respondTo:#field4 with:[data at:4].
	dataModel respondTo:#field1: with:[:arg | data at:1 put:arg].
	dataModel respondTo:#field2: with:[:arg | data at:2 put:arg].
	dataModel respondTo:#field3: with:[:arg | data at:3 put:arg].
	dataModel respondTo:#field4: with:[:arg | data at:4 put:arg].

	dialog := DialogBox new.
	dialog addTextLabel:'1:'.
	dialog addInputFieldOn:(AspectAdaptor new
					subject:dataModel; 
					accessWith:#field1
					assignWith:#field1:). 
	dialog addTextLabel:'2:'.
	dialog addInputFieldOn:(AspectAdaptor new
					subject:dataModel; 
					forAspect:#field2).
	dialog addTextLabel:'3:'.
	dialog addInputFieldOn:(AspectAdaptor new
					subject:dataModel; 
					accessWith:#field3
					assignWith:#field3:
					aspect:#field3). 
	dialog addTextLabel:'4:'.
	dialog addInputFieldOn:(AspectAdaptor new
					subject:dataModel; 
					forAspect:#field4).
	dialog addOkButton.
	dataModel inspect.
	dialog open.
	dialog accepted ifTrue:[
	    Transcript showCr:'data now: ' , data printString
	]
"
! !

!AspectAdaptor class methodsFor:'instance creation'!

accessWith:getSelector assignWith:putSelector 
    ^ (self new) accessWith:getSelector assignWith:putSelector
! !

!AspectAdaptor methodsFor:'change & update'!

update:something with:aParameter from:changedObject
    "translate an update from the model into a #value-change
     via my depenedents ..."

    ((changedObject == subject)
    or:[changedObject == subjectChannel]) ifTrue:[
	something == self forAspect ifTrue:[
	    self changed:#value
	].
	^ self
    ].
! !

!AspectAdaptor methodsFor:'accessing-value'!

value
    "translate a query for my value from my user
     into an aspect access towards my subject"

    |target|

    target := super value.
    ^ target perform:getMsg
!

setValue:newValue
    |target oldValue|

    target := super value.
    oldValue := target perform:getMsg.
    oldValue ~~ newValue ifTrue:[
	target perform:putMsg with:newValue.
    ]
!

value:newValue
    |target oldValue|

    target := super value.
    oldValue := target perform:getMsg.
    oldValue ~~ newValue ifTrue:[
	target perform:putMsg with:newValue.
	subjectSendsUpdates ifFalse:[
	    self changed:#value
	]
    ]
! !
        
!AspectAdaptor methodsFor:'accessing-spec'!

forAspect
    myAspect isNil ifTrue:[
	^ getMsg
    ].
    ^ myAspect
!

forAspect:aSelector
    getMsg := myAspect := aSelector.
    putMsg := (aSelector , ':') asSymbol.
!

accessWith:getSelector assignWith:putSelector
    getMsg := getSelector.
    putMsg := putSelector
!

accessWith:getSelector assignWith:putSelector aspect:aspectSymbol
    getMsg := getSelector.
    putMsg := putSelector.
    myAspect := aspectSymbol
! !