|
Class: PluggableAdaptor
Object
|
+--Model
|
+--ValueModel
|
+--PluggableAdaptor
|
+--TypeConverter
- Package:
- stx:libview2
- Category:
- Interface-Support-Models
- Version:
- rev:
1.33
date: 2023/07/15 18:32:13
- user: cg
- file: PluggableAdaptor.st directory: libview2
- module: stx stc-classLibrary: libview2
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.
copyrightCOPYRIGHT (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.
instance creation
-
on: anObject
-
create & return a new protocolAdaptor.
Any get/put and updateBlocks are still to be defined
-
on: anObject getter: getterBlock
-
-
on: anObject getter: getterBlock setter: setterBlock
-
-
on: anObject setter: setterBlock
-
accessing
-
getBlock
-
-
putBlock
-
-
setValue: newValue
-
stupid default
-
updateBlock
-
-
value
-
stupid default
-
valueUsingSubject: someObject
-
change & update
-
update: something with: aParameter from: changedObject
-
(comment from inherited method)
dependent is notified of some change -
Default is to try update:with:
initialization & release
-
collectionIndex: idx
-
configure the adaptor to translate #value/#value:-messages into
indexed accesses via #at:/#at:put:, using the supplied index
-
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.
-
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.
-
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.
-
getSelector: getSelector putSelector: putSelector
-
configure the adaptor to translate #value-messages into a send of
getSelector and #value:-messages into sends of putSelector.
-
model
-
get the real model, into which / from which the
real model value is converted
-
model: anObject
-
set the real model, into which / from which the
real model value is converted
-
performAction: aSelector
-
configure the adaptor to send an aSelector-message to the model
whenever a new value is stored via #value:
-
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.
-
selectValue: something
-
configure the adaptor to behave like a boolean value, returning
true whenever the model's value equals something
-
subjectChannel: aValueHolder
-
setup to use aValueHolder as model
testing
-
isPluggableAdaptor
-
utilities
-
getter: getterBlock
-
-
getter: getter setter: setter
-
-
setter: setterBlock
-
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.
|
choose one from alternatives (radioButton-like behavior):
|m v|
m := #foo asValue.
v := HorizontalPanelView new.
v add:(Toggle on:((PluggableAdaptor on:m) selectValue:#foo) label:'foo' ).
v add:(Toggle on:((PluggableAdaptor on:m) selectValue:#bar) label:'bar' ).
v add:(Toggle on:((PluggableAdaptor on:m) selectValue:#baz) label:'baz' ).
v add:(Label label:'Current:' ).
v add:(Label new labelChannel:m ).
v 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.
|
|