eXept Software AG Logo

Smalltalk/X Webserver

Documentation of class 'PluggableAdaptor':

Home

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

Class: PluggableAdaptor


Inheritance:

   Object
   |
   +--Model
      |
      +--ValueModel
         |
         +--PluggableAdaptor
            |
            +--TypeConverter

Package:
stx:libview2
Category:
Interface-Support-Models
Version:
rev: 1.28 date: 2016/08/25 21:14:11
user: cg
file: PluggableAdaptor.st directory: libview2
module: stx stc-classLibrary: libview2
Author:
Claus Gittinger

Description:


Allows forwarding of value/value:/change messages via blocks.
Kind of what ST/X always did ....

PluggableAdaptor is the most general of the adaptor models -
any other adapter can be simulated. However, they incur certain
overhead and complexity.
Therefore, in many situations, an AspectAdaptor is the better choice.

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.


Class protocol:

instance creation
o  on: anObject
create & return a new protocolAdaptor.
Any get/put and updateBlocks are still to be defined

o  on: anObject getter: getterBlock

o  on: anObject getter: getterBlock setter: setterBlock

o  on: anObject setter: setterBlock


Instance protocol:

accessing
o  getBlock

o  putBlock

o  setValue: newValue
stupid default

o  updateBlock

o  value
stupid default

o  valueUsingSubject: someObject

change & update
o  update: something with: aParameter from: changedObject
(comment from inherited method)
dependent is notified of some change -
Default is to try update:with:

initialization & release
o  collectionIndex: idx
configure the adaptor to translate #value/#value:-messages into
indexed accesses via #at:/#at:put:, using the supplied index

o  getBlock: newGetBlock
configure the adaptor to translate #value-messages into
evaluation of the corresponding block.
The getBlock argument block1 is called with one argument, the model, and is
supposed to extract & return a value from that model.

o  getBlock: newGetBlock putBlock: newPutBlock
configure the adaptor to translate #value/#value:-messages into
evaluation of the corresponding block1/block2.
The getBlock argument block1 is called with one argument, the model, and is
supposed to extract & return a value from that model.
The putBlock argument, block2 is called with 2 arguments, the model
and the new value, and is supposed to store the new value.

o  getBlock: newGetBlock putBlock: newPutBlock updateBlock: newUpdateBlock
configure the adaptor to translate #value/#value:-messages into
evaluation of the corresponding block1/block2.
The getBlock argument block1 is called with one argument, the model, and is
supposed to extract & return a value from that model.
The putBlock argument, block2 is called with 2 arguments, the model
and the new value, and is supposed to store the new value.
The updateBlock argument, block3 is called with 3 arguments, the model,
the aspect as changed in the model and the change parameter. It
is called when the adaptor receives an update message from the model,
and should return true if a new value should be fetched from the model.

o  getSelector: getSelector putSelector: putSelector
configure the adaptor to translate #value-messages into a send of
getSelector and #value:-messages into sends of putSelector.

o  model
get the real model, into which / from which the
real model value is converted

o  model: anObject
set the real model, into which / from which the
real model value is converted

o  performAction: aSelector
configure the adaptor to send an aSelector-message to the model
whenever a new value is stored via #value:

o  putBlock: newPutBlock
configure the adaptor to translate#value:-messages into
evaluation of the corresponding block2.
The putBlock argument, block2 is called with 2 arguments, the model
and the new value, and is supposed to store the new value.

o  selectValue: something
configure the adaptor to behave like a boolean value, returning
true whenever the models value equals something

o  subjectChannel: aValueHolder
setup to use aValueHolder as model

utilities
o  getter: getterBlock

o  getter: getter setter: setter

o  setter: setterBlock


Examples:


an adaptor for the variable x:
    |m x t|

    m := (PluggableAdaptor new)
            getBlock:[:m | x]
            putBlock:[:m :newValue | x := newValue. Transcript showCR:x]
            updateBlock:[:m :aspect :param | Transcript showCR:'changed'].
    t := Toggle new.
    t model:m.
    t label:'toggle me'.
    t open.
an adaptor to send #destroy:
    |m t|

    m := (PluggableAdaptor new)
            getBlock:[:m | false]
            putBlock:[:m :newValue | t destroy]
            updateBlock:[:m :aspect :param | ].
    t := Button new.
    t model:m.
    t label:'close me'.
    t open.
as above, more convenient setup:
    |m t|

    t := Button new.

    m := (PluggableAdaptor on:t) performAction:#destroy.
    t model:m.
    t label:'close me'.
    t open.
extract values from a complex model:
    |model dialog  name pId|

    model := Plug new.
    model respondTo:#name with:[name].
    model respondTo:#name: with:[:newValue | name := newValue].
    model respondTo:#passportId with:[pId].
    model respondTo:#passportId: with:[:newValue | pId := newValue].
    name := 'John Smith'.
    pId := 56785432.

    dialog := Dialog new.

    dialog addInputFieldOn:((PluggableAdaptor on:model)
                                getBlock:[:m | m name]
                                putBlock:[:m :v | m name:v]
                                updateBlock:[:m :a :p | false]).

    dialog addVerticalSpace.

    dialog addInputFieldOn:((PluggableAdaptor on:model)
                                getBlock:[:m | m passportId printString]
                                putBlock:[:m :v | m passportId:v asNumber]
                                updateBlock:[:m :a :p | false]).
    dialog addAbortButton; addOkButton.
    dialog width:200; sizeFixed:true.
    dialog open.

    dialog accept value ifTrue:[
        Transcript showCR:'accepted.'.
    ].
    Transcript showCR:'  Name: ' , model name.
    Transcript showCR:'  ID  : ' , model passportId printString.
extract values from an association into different labels:
    |assoc t l|

    assoc := 'hello' -> 'world'.

    t := HorizontalPanelView new.
    t extent:200@50.
    t horizontalLayout:#fitSpace.

    l := Label in:t.
    l model:((PluggableAdaptor on:assoc) getSelector:#key putSelector:#key:);
      labelMessage:#value; aspect:#value;
      level:-1.
    l := Label in:t.
    l model:((PluggableAdaptor on:assoc) getSelector:#value putSelector:#value:);
      labelMessage:#value; aspect:#value;
      level:-1.
    t open.

    (Delay forSeconds:3) wait.
    assoc key:'goodbye'.
    assoc changed.
extract values from an array into different labels:
    |a t l|

    a := #('one' 'two' 'three').

    t := HorizontalPanelView new.
    t extent:200@50.
    t horizontalLayout:#fitSpace.

    l := Label in:t.
    l model:((PluggableAdaptor on:a) collectionIndex:1);
      labelMessage:#value; aspect:#value;
      level:-1;
      sizeFixed:true.
    l := Label in:t.
    l model:((PluggableAdaptor on:a) collectionIndex:2);
      labelMessage:#value; aspect:#value;
      level:-1;
      sizeFixed:true.
    l := Label in:t.
    l model:((PluggableAdaptor on:a) collectionIndex:3);
      labelMessage:#value; aspect:#value;
      level:-1;
      sizeFixed:true.
    t open.

    (Delay forSeconds:3) wait.
    a at:1 put:'1'.
    a changed.


ST/X 7.1.0.0; WebServer 1.663 at exept.de:8081; Wed, 12 Dec 2018 22:12:24 GMT