AspctAdptr.st
changeset 69 225a9efd50f5
child 71 5b34cd877517
equal deleted inserted replaced
68:43b867285d01 69:225a9efd50f5
       
     1 ProtocolAdaptor subclass:#AspectAdaptor 
       
     2 	 instanceVariableNames:'myAspect getMsg putMsg'
       
     3 	 classVariableNames:''
       
     4 	 poolDictionaries:''
       
     5 	 category:'Interface-Support'
       
     6 !
       
     7 
       
     8 !AspectAdaptor class methodsFor:'documentation'!
       
     9 
       
    10 copyright
       
    11 "
       
    12  COPYRIGHT (c) 1995 by Claus Gittinger
       
    13               All Rights Reserved
       
    14 
       
    15  This software is furnished under a license and may be used
       
    16  only in accordance with the terms of that license and with the
       
    17  inclusion of the above copyright notice.   This software may not
       
    18  be provided or otherwise made available to, or used by, any
       
    19  other person.  No title to or ownership of the software is
       
    20  hereby transferred.
       
    21 "
       
    22 !
       
    23 
       
    24 version
       
    25 "
       
    26 $Header: /cvs/stx/stx/libview2/Attic/AspctAdptr.st,v 1.1 1995-05-09 00:20:52 claus Exp $
       
    27 "
       
    28 !
       
    29 
       
    30 documentation
       
    31 "
       
    32     an AspectAdaptor forwards updates and change messages
       
    33     from/to a complex model.
       
    34 
       
    35     Consider the case where editFields are required for the
       
    36     elements (instance variables) of a more complex model.
       
    37     Without an aspect adaptor, you needed to copy the individual
       
    38     values out-of and into multiple valueHolders.
       
    39     An aspectAdaptor makes this easier, by playing model with
       
    40     vale/value: symbols towards the editField, and forwarding changes and
       
    41     updates to/from the complex model using different aspect symbols.
       
    42 
       
    43     Notice: this class was implemented using protocol information
       
    44     from alpha testers and PD code - it may not be complete or compatible to
       
    45     the corresponding ST-80 class. If you encounter any incompatibilities,
       
    46     please forward a note to the ST/X team.
       
    47 "
       
    48 !
       
    49 
       
    50 examples
       
    51 "
       
    52     a dialog on a points x/y coordinates:
       
    53 
       
    54 	|dialog data f|
       
    55 
       
    56 	data := 0@0.
       
    57 
       
    58 	dialog := DialogBox new.
       
    59 	dialog addTextLabel:'x:'.
       
    60 	f := dialog addInputFieldOn:(AspectAdaptor new
       
    61 					subject:data; 
       
    62 					accessWith:#x 
       
    63 					assignWith:#x:).
       
    64 	f converter:(PrintConverter new initForNumber).
       
    65 
       
    66 	dialog addTextLabel:'y:'.
       
    67 	f := dialog addInputFieldOn:(AspectAdaptor new
       
    68 					subject:data; 
       
    69 					forAspect:#y).
       
    70 	f converter:(PrintConverter new initForNumber).
       
    71 
       
    72 	dialog addOkButton.
       
    73 	data inspect.
       
    74 	dialog open.
       
    75 
       
    76 	dialog accepted ifTrue:[
       
    77 	    Transcript showCr:'data now: ' , data printString
       
    78 	]
       
    79 
       
    80 
       
    81     a dialog on a four-field complex model:
       
    82 
       
    83 
       
    84 	|dialog data dataModel|
       
    85 
       
    86 	data := #('hello' 'one' 'two' 'three').
       
    87 	dataModel := Plug new.
       
    88 	dataModel respondTo:#field1 with:[data at:1].
       
    89 	dataModel respondTo:#field2 with:[data at:2].
       
    90 	dataModel respondTo:#field3 with:[data at:3].
       
    91 	dataModel respondTo:#field4 with:[data at:4].
       
    92 	dataModel respondTo:#field1: with:[:arg | data at:1 put:arg].
       
    93 	dataModel respondTo:#field2: with:[:arg | data at:2 put:arg].
       
    94 	dataModel respondTo:#field3: with:[:arg | data at:3 put:arg].
       
    95 	dataModel respondTo:#field4: with:[:arg | data at:4 put:arg].
       
    96 
       
    97 	dialog := DialogBox new.
       
    98 	dialog addTextLabel:'1:'.
       
    99 	dialog addInputFieldOn:(AspectAdaptor new
       
   100 					subject:dataModel; 
       
   101 					accessWith:#field1
       
   102 					assignWith:#field1:). 
       
   103 	dialog addTextLabel:'2:'.
       
   104 	dialog addInputFieldOn:(AspectAdaptor new
       
   105 					subject:dataModel; 
       
   106 					forAspect:#field2).
       
   107 	dialog addTextLabel:'3:'.
       
   108 	dialog addInputFieldOn:(AspectAdaptor new
       
   109 					subject:dataModel; 
       
   110 					accessWith:#field3
       
   111 					assignWith:#field3:
       
   112 					aspect:#field3). 
       
   113 	dialog addTextLabel:'4:'.
       
   114 	dialog addInputFieldOn:(AspectAdaptor new
       
   115 					subject:dataModel; 
       
   116 					forAspect:#field4).
       
   117 	dialog addOkButton.
       
   118 	dataModel inspect.
       
   119 	dialog open.
       
   120 	dialog accepted ifTrue:[
       
   121 	    Transcript showCr:'data now: ' , data printString
       
   122 	]
       
   123 "
       
   124 ! !
       
   125 
       
   126 !AspectAdaptor class methodsFor:'instance creation'!
       
   127 
       
   128 accessWith:getSelector assignWith:putSelector 
       
   129     ^ (self new) accessWith:getSelector assignWith:putSelector
       
   130 ! !
       
   131 
       
   132 !AspectAdaptor methodsFor:'change & update'!
       
   133 
       
   134 update:something with:aParameter from:changedObject
       
   135     "translate an update from the model into a #value-change
       
   136      via my depenedents ..."
       
   137 
       
   138     ((changedObject == subject)
       
   139     or:[changedObject == subjectChannel]) ifTrue:[
       
   140 	something == self forAspect ifTrue:[
       
   141 	    self changed:#value
       
   142 	].
       
   143 	^ self
       
   144     ].
       
   145 ! !
       
   146 
       
   147 !AspectAdaptor methodsFor:'accessing-value'!
       
   148 
       
   149 value
       
   150     "translate a query for my value from my user
       
   151      into an aspect access towards my subject"
       
   152 
       
   153     |target|
       
   154 
       
   155     target := super value.
       
   156     ^ target perform:getMsg
       
   157 !
       
   158 
       
   159 setValue:newValue
       
   160     |target oldValue|
       
   161 
       
   162     target := super value.
       
   163     oldValue := target perform:getMsg.
       
   164     oldValue ~~ newValue ifTrue:[
       
   165 	target perform:putMsg with:newValue.
       
   166     ]
       
   167 !
       
   168 
       
   169 value:newValue
       
   170     |target oldValue|
       
   171 
       
   172     target := super value.
       
   173     oldValue := target perform:getMsg.
       
   174     oldValue ~~ newValue ifTrue:[
       
   175 	target perform:putMsg with:newValue.
       
   176 	subjectSendsUpdates ifFalse:[
       
   177 	    self changed:#value
       
   178 	]
       
   179     ]
       
   180 ! !
       
   181         
       
   182 !AspectAdaptor methodsFor:'accessing-spec'!
       
   183 
       
   184 forAspect
       
   185     myAspect isNil ifTrue:[
       
   186 	^ getMsg
       
   187     ].
       
   188     ^ myAspect
       
   189 !
       
   190 
       
   191 forAspect:aSelector
       
   192     getMsg := myAspect := aSelector.
       
   193     putMsg := (aSelector , ':') asSymbol.
       
   194 !
       
   195 
       
   196 accessWith:getSelector assignWith:putSelector
       
   197     getMsg := getSelector.
       
   198     putMsg := putSelector
       
   199 !
       
   200 
       
   201 accessWith:getSelector assignWith:putSelector aspect:aspectSymbol
       
   202     getMsg := getSelector.
       
   203     putMsg := putSelector.
       
   204     myAspect := aspectSymbol
       
   205 ! !