|
Class: BlockValue
Object
|
+--Model
|
+--ValueModel
|
+--BlockValue
|
+--BooleanBlockValue
- Package:
- stx:libview2
- Category:
- Interface-Support-Models
- Version:
- rev:
1.34
date: 2019/05/01 20:49:36
- user: cg
- file: BlockValue.st directory: libview2
- module: stx stc-classLibrary: libview2
- Author:
- Claus Gittinger
BlockValues depend on one or more other objects (typically valueHolders)
and recompute a value whenever one of them changes.
If the recomputed new value is different, it triggers itself a change to its dependents.
A typical example use is to base an enableChannel's value on multiple other
boolean (or non-boolean) values. (See example for how this is done)
Notice, that a BlockValue can also be created without depending on any other
object (i.e. BlockValue with:aBlock). In this case, a recomputation must be explicitly
triggered by sending #recomputeValue to the blockValue instance.
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.
Warning:
BlockValues only work ine one direction; changing the blockValue's value
does not affect the original model's value.
initialization
-
initialize
-
instance creation
-
block: aBlock arguments: aCollectionOfArguments
-
return a new BlockValue computing aBlock.
Same as #with:arguments: for ST80 compatibility
-
forLogical: arg1 and: arg2
-
return a new BlockValue computing the logical AND of its args
(which are usually other valueHolders)
-
forLogical: arg1 and: arg2 and: arg3
-
return a new BlockValue computing the logical AND of its args
(which are usually other valueHolders)
-
forLogical: arg1 or: arg2
-
return a new BlockValue computing the logical OR of its args
(which are usually other valueHolders)
-
forLogical: arg1 or: arg2 or: arg3
-
return a new BlockValue computing the logical OR of its args
(which are usually other valueHolders)
-
forLogicalAndAll: argArray
-
return a new BlockValue computing the logical AND of all elements
in the passed argArray (which are usually other valueHolders)
-
forLogicalNot: arg
-
return a new BlockValue computing the logical NOT of its arg
(which is usually another valueHolder)
-
forLogicalOrAll: argArray
-
return a new BlockValue computing the logical OR of all elements
in the passed argArray (which are usually other valueHolders)
-
forValue: someValue equalTo: someConstant
-
return a new BlockValue generating a true,
if someValue (usually another holder) contains a value equal to someConstant.
Useful, if the other valueHolder is a radioButton group model,
and you want to automatically enable/disable other items based on the value
(i.e. via the enableChannel)
-
with: aBlock
-
return a new BlockValue computing aBlock
-
with: aBlock argument: anArgument
-
return a new BlockValue computing aBlock
-
with: aBlock argument: anArgument1 argument: anArgument2
-
return a new BlockValue computing aBlock
-
with: aBlock argument: anArgument1 argument: anArgument2 argument: anArgument3
-
return a new BlockValue computing aBlock
-
with: aBlock argument: anArgument1 argument: anArgument2 argument: anArgument3 argument: anArgument4
-
return a new BlockValue computing aBlock
-
with: aBlock arguments: aCollectionOfArguments
-
return a new BlockValue computing aBlock
accessing
-
setArguments: aCollectionOfArguments
-
set the receiver's arguments to be passed to it.
A change in any of the arguments will force reevaluation of the action
block - possibly generating another change from myself
-
setBlock: aBlock
-
set the receiver's action block
-
setBlock: aBlock argumentArray: anArgumentCollection
-
set the receiver's action block, and define an arguments collection
to be passed to it.
A change in any element of the collection will force reevaluation of the
action block (passing the collection as a single argument)
- possibly generating another change from myself
-
setBlock: aBlock arguments: aCollectionOfArguments
-
set the receiver's action block, and define arguments to be passed to it.
A change in any of the arguments will force reevaluation of the action
block - possibly generating another change from myself
-
setValue: newValue
-
physically set my value, without change notifications.
This is a noop here, since my value is computed.
-
value
-
retrieve my value - this does not always evaluate the action block,
since the returned value is cached internally
change & update
-
recomputeValue
-
force reevaluation of my actionBlock,
and possibly send a change notification to my dependents
-
update: something with: aParameter from: someone
-
the one I depend on has changed - reevaluate my actionBlock,
and possibly send a change notification to my dependents
dependents access
-
release
-
release any dependencies upon the arguments
misc
-
computeValue
-
evaluate the receiver's action block
-
dependOn: someObject
-
arrange for the blockValue to be reevaluated, whenever someObject
changes (i.e. sends a change notification)
-
resetValue
-
evaluate the receiver's action block
checkToggle 3 shows the value of toggle1 AND toggle2
|val1 val2 both box|
val1 := false asValue.
val2 := false asValue.
both := BlockValue
with:[:v1 :v2 |
Transcript showCR:'evaluating ...'.
v1 value and:[v2 value]
]
arguments:(Array with:val1 with:val2).
box := Dialog new.
box addCheckBox:'one' on:val1.
box addCheckBox:'two' on:val2.
box addHorizontalLine.
box addCheckBox:'both' on:both.
box addOkButton.
box open
|
the same, using a convenient instance creation message:
|val1 val2 both box|
val1 := false asValue.
val2 := false asValue.
both := BlockValue forLogical:val1 and:val2.
box := Dialog new.
box addCheckBox:'one' on:val1.
box addCheckBox:'two' on:val2.
box addHorizontalLine.
(box addCheckBox:'both' on:both) disable.
box addOkButton.
box open
|
logical or:
|val1 val2 both box|
val1 := false asValue.
val2 := false asValue.
both := BlockValue forLogical:val1 or:val2.
box := Dialog new.
box addCheckBox:'one' on:val1.
box addCheckBox:'two' on:val2.
box addHorizontalLine.
box addCheckBox:'both' on:both.
box addOkButton.
box open
|
example use: enabling an element depending on two others:
|val1 val2 enabler val3 box|
val1 := false asValue.
val2 := false asValue.
val3 := false asValue.
enabler := BlockValue forLogical:val1 and:val2.
box := Dialog new.
box addCheckBox:'one' on:val1.
box addCheckBox:'two' on:val2.
box addHorizontalLine.
(box addCheckBox:'three (both of the above)' on:val3) enableChannel:enabler.
box addOkButton.
box open
|
like above, using a logical-or block:
|val1 val2 enabler val3 box|
val1 := false asValue.
val2 := false asValue.
val3 := false asValue.
enabler := BlockValue forLogical:val1 or:val2.
box := Dialog new.
box addCheckBox:'one' on:val1.
box addCheckBox:'two' on:val2.
box addHorizontalLine.
(box addCheckBox:'three (any of the above)' on:val3) enableChannel:enabler.
box addOkButton.
box open
|
like above, using a bunch of toggles:
|values anyValue box|
values := (1 to:10) collect:[:i | false asValue].
anyValue := BlockValue forLogicalOrAll:values.
anyValue onChangeSend:#value to:[Transcript showCR:'any is true'].
box := Dialog new.
values keysAndValuesDo:[:index :aValueHolder |
box addCheckBox:index printString on:aValueHolder.
].
box addHorizontalLine.
(box addOkButton) enableChannel:anyValue.
box open
| a logical-not block:
|val1 valNot box|
val1 := false asValue.
valNot := BlockValue forLogicalNot:val1.
box := Dialog new.
box addCheckBox:'one' on:val1.
box addHorizontalLine.
(box addCheckBox:'not one' on:valNot) enabled:false
box addOkButton.
box open
|
|