eXept Software AG Logo

Smalltalk/X Webserver

Documentation of class 'AspectAdaptor':

Home

Documentation
www.exept.de
Everywhere
for:
[back]

Class: AspectAdaptor


Inheritance:

   Object
   |
   +--Model
      |
      +--ValueModel
         |
         +--ProtocolAdaptor
            |
            +--AspectAdaptor
               |
               +--AspectAdaptorWithDefault
               |
               +--BufferedAspectAdaptor

Package:
stx:libview2
Category:
Interface-Support-Models
Version:
rev: 1.31 date: 2023/07/15 18:33:43
user: cg
file: AspectAdaptor.st directory: libview2
module: stx stc-classLibrary: libview2

Description:


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 compound object:
- without an aspect adaptor, you needed to copy the individual
  values out-of the object and move these into multiple valueHolders.
  Then, let the editFields modify the valueHolders contents and
  finally, fetch the values and put them back into the compound object.

An aspectAdaptor makes this easier, by playing model with
value/value: symbols towards the editField, and forwarding changes and
updates to/from the compound object using different aspect symbols
and access messages.

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 
    describing the incompatibility verbal (i.e. no code) to the ST/X team.

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.

Class protocol:

instance creation
o  accessWith: getSelector assignWith: putSelector
create and return an adaptor which uses getSelector to fetch a value
from the subject and setSelector to change it.
The returned object can be used in place of a ValueHolder

o  forAspect: anAspect
create and return a new adaptor, which forwards requests
to the subject, using anAspect as get-selector and anAspect-colon as putSelector
for access.
The returned object can be used in place of a ValueHolder

o  forAspect: anAspect subject: anObject
create and return a new adaptor, which forwards requests
to anObject, using anAspect as get-selector and anAspect-colon as putSelector
for access.
The returned object can be used in place of a ValueHolder

o  forAspect: anAspect subjectChannel: aSubjectProvider
create and return a new adaptor, which forwards requests
to the object provided by aSubjectProvider,
accessing the subject via #value from aSubjectProvider.
using anAspect as get-selector and anAspect-colon as putSelector for access.
The returned object can be used in place of a ValueHolder

o  subject: anObject sendsUpdates: aBoolean accessWith: getSel assignWith: putSel aspect: aspect
create and return a new adaptor, which forwards requests
to anObject, using getSel/putSel for access.
The returned object can be used in place of a ValueHolder


Instance protocol:

accessing-spec
o  accessWith: getSelector assignWith: putSelector
setup the receiver to use getSelector to fetch a value
and putSelector to change it.

o  accessWith: getSelector assignWith: putSelector aspect: aspectSymbol
setup the receiver to use getSelector to fetch a value
and putSelector to change it.

o  aspect: aSelector
set the adaptor's change aspect - this is the aspect of the update message,
on which the adaptor reacts

o  forAspect
get the adaptor's aspect - if none was defined, the getMsg is returned

o  forAspect: aSelector
set the adaptor's aspect - this sets both the get- and put-Messages
(the putMessage is the aspect with a colon)

accessing-value
o  defaultValueIfNoSubject
if there is no subject (taget to provide the value),
this value is returned.

o  setValue: newValue
set the value - this forwards a putMessage to the target

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

o  value: newValue
set the value - this forwards a putMessage to the target
and sends out a changeNotification if the value did really change.

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

printing
o  displayOn: aStreamOrGC
(comment from inherited method)
Compatibility
append a printed desription on some stream (Dolphin, Squeak)
OR:
display the receiver in a graphicsContext at 0@0 (ST80).
This method allows for any object to be displayed in some view
(although the fallBack is to display its printString ...)

Notice: displayString and displayOn: are for developers, debugging and inspectors,
whereas printString and printOn: are for the program to print data.


Examples:


a dialog on a point's 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
    ]
a dialog on elements of a dictionary: (notice: the dicationary elements change as soon as a field of the dialog is left - i.e. I write immediately to the model)
    |dialog data|

    data := JSONObject new
                at:'Name' put:'Fritz';
                at:'Tel' put:'1234567';
                at:'City' put:'Stuttgart';
                yourself.

    dialog := DialogBox new.
    dialog addTextLabel:'Name:'.
    dialog addInputFieldOn:(AspectAdaptor new
                                    subject:data; 
                                    accessWith:#Name
                                    assignWith:#Name:). 
    dialog addTextLabel:'Tel:'.
    dialog addInputFieldOn:(AspectAdaptor new
                                    subject:data; 
                                    forAspect:#Tel).
    dialog addTextLabel:'City:'.
    dialog addInputFieldOn:(AspectAdaptor new
                                    subject:data; 
                                    forAspect:#City).
    dialog addOkButton.
    data inspect.
    dialog open.
    dialog accepted ifTrue:[
        Transcript showCR:'data now: ' , data printString
    ]


ST/X 7.7.0.0; WebServer 1.702 at 20f6060372b9.unknown:8081; Sun, 16 Jun 2024 03:50:28 GMT