--- a/PrintConv.st Sun Jul 23 04:25:16 1995 +0200
+++ b/PrintConv.st Sun Jul 23 04:29:14 1995 +0200
@@ -35,17 +35,19 @@
version
"
-$Header: /cvs/stx/stx/libview2/Attic/PrintConv.st,v 1.5 1995-07-02 16:16:59 claus Exp $
+$Header: /cvs/stx/stx/libview2/Attic/PrintConv.st,v 1.6 1995-07-23 02:28:06 claus Exp $
"
!
documentation
"
- printConverters are used with editFields to convert an object
- to/from some printed representation.
+ printConverters can be used with labels and editFields to convert
+ an object to/from some printed representation.
Conversion is done via two blocks which can be set at instance
creation time - either as custom blocks ot to one of the
- standard conversions.
+ standard conversions. There are a number of standard setups, for
+ common conversions; if none of them fits your needs, create a custom
+ converter, by defining its two conversion blocks.
Notice: this class was implemented using protocol information
from alpha testers - it may not be complete or compatible to
@@ -56,7 +58,9 @@
examples
"
- stupid examples:
+ stupid examples:
+ convert date <-> string:
+
|conv|
conv := (PrintConverter new)
@@ -66,6 +70,8 @@
(conv readValueFrom:(Date today printString)) inspect
+ convert number <-> string:
+
|conv|
conv := (PrintConverter new) initForNumber.
@@ -73,6 +79,8 @@
(conv readValueFrom:'12345') inspect
+ convert boolean <-> string:
+
|conv|
conv := (PrintConverter new) initForYesNo.
@@ -84,7 +92,8 @@
(conv readValueFrom:'ja').
(conv readValueFrom:'nein')
- concrete example: convert in an inputField:
+ concrete examples:
+ convert in an inputField:
|dialog field|
@@ -100,6 +109,100 @@
Transcript showCr:field editValue
]
+ convert a models value for a label:
+
+ |top v1 v2 l1 l2|
+
+ v1 := 0 asValue.
+ v2 := Date today asValue.
+
+ top := StandardSystemView new.
+ top extent:200@200.
+
+ l1 := Label origin:0.0@0.0 corner:1.0@0.5 in:top.
+ l1 converter:(PrintConverter new initForInteger).
+ l1 model:v1; labelMessage:#value; aspect:#value.
+ l1 level:-1; inset:10.
+
+ l2 := Label origin:0.0@0.5 corner:1.0@1.0 in:top.
+ l2 converter:(PrintConverter new initForDate).
+ l2 model:v2; labelMessage:#value; aspect:#value.
+ l2 level:-1; inset:10.
+
+ top open.
+
+ 'now, change the values ...'.
+ [
+ 1 to:50 do:[:i|
+ v1 value:(v1 value + 1).
+ v2 value:(v2 value addDays:1).
+ (Delay forSeconds:0.5) wait
+ ]
+ ] fork
+
+ convert a models value for a label with limited precision
+ float conversion:
+
+ |top v l1 l2|
+
+ v := 0.0 asValue.
+
+ top := StandardSystemView new.
+ top extent:200@200.
+
+ l1 := Label origin:0.0@0.0 corner:1.0@0.5 in:top.
+ l1 converter:(PrintConverter new initForFloat).
+ l1 model:v; labelMessage:#value; aspect:#value.
+ l1 level:-1; inset:10.
+
+ l2 := Label origin:0.0@0.5 corner:1.0@1.0 in:top.
+ l2 converter:(PrintConverter new initForFloatWithPrecision:2).
+ l2 model:v; labelMessage:#value; aspect:#value.
+ l2 level:-1; inset:10.
+
+ top open.
+
+ 'now, change the values ...'.
+ [
+ 1 to:100 do:[:i|
+ v value:(v value + 0.005).
+ (Delay forSeconds:0.5) wait
+ ]
+ ] fork
+
+ a custom converter, converting a number to either 'odd'
+ or 'even' strings (we only need a one-way converter for labels):
+
+ |top v l1 l2|
+
+ v := 0 asValue.
+
+ top := StandardSystemView new.
+ top extent:200@200.
+
+ l1 := Label origin:0.0@0.0 corner:1.0@0.5 in:top.
+ l1 converter:(PrintConverter new initForInteger).
+ l1 model:v; labelMessage:#value; aspect:#value.
+ l1 level:-1; inset:10.
+
+ l2 := Label origin:0.0@0.5 corner:1.0@1.0 in:top.
+ l2 converter:(PrintConverter
+ new
+ toPrint:[:num | num even ifTrue:['even']
+ ifFalse:['odd']]
+ toRead:[:string | ]).
+ l2 model:v; labelMessage:#value; aspect:#value.
+ l2 level:-1; inset:10.
+
+ top open.
+
+ 'now, change the values ...'.
+ [
+ 1 to:100 do:[:i|
+ v value:(v value + 1).
+ (Delay forSeconds:0.5) wait
+ ]
+ ] fork
see more examples in the EditField examples.
"
@@ -113,10 +216,54 @@
toRead:[:string | string]
! !
+!PrintConverter class methodsFor:'utilities'!
+
+print:aNumber formattedBy:formatString
+ "take the digits of aNumbers printString, and squash them
+ into formatString, where #-characters are replaced by
+ successive characters from the printString.
+ Warning: use with care - it does not check for decimal points etc.
+ the printString of aNumber must have enough digits for all
+ #-characters to be replaced.
+ Therefore, precheck the numbers value and use appropriate format
+ strings then.
+ For number formatting, see also: printfPrintString: implementations."
+
+ |pS fS out|
+
+ pS := ReadStream on:aNumber printString.
+ fS := ReadStream on:formatString.
+ out := WriteStream on:String new.
+ [fS atEnd] whileFalse:[
+ |c|
+
+ c := fS next.
+ c == $# ifTrue:[
+ c := pS next
+ ].
+ out nextPut:c
+ ].
+ ^ out contents
+
+ "
+ PrintConverter print:'123456789' formattedBy:'US$ ###,###.##'
+
+ fails for:
+ PrintConverter print:'1234' formattedBy:'US$ ###,###.##'
+
+ invalid string for:
+ PrintConverter print:'123456789' formattedBy:'US$ ###'
+ "
+! !
+
!PrintConverter methodsFor:'initialization'!
toPrint:printBlock toRead:readBlock
- "initialize to convert using two custom blocks"
+ "initialize to convert using two custom blocks.
+ printBlock is supposed to get the objects value as argument,
+ and to return a string.
+ readBlock is supposed to get a string as argument, and return
+ the corresponding object."
valueToStringBlock := printBlock.
stringToValueBlock := readBlock.
@@ -126,7 +273,7 @@
"initialize to convert to/from an integer
- if the string is empty or invalid, convert to 0"
- valueToStringBlock := [:num | num printString].
+ valueToStringBlock := [:num | num truncated printString].
stringToValueBlock := [:string | Integer readFromString:string onError:0]
!
@@ -141,6 +288,26 @@
Integer readFromString:string onError:nil]
!
+initForFloat
+ "initialize to convert to/from an float
+ - if the string is empty or invalid, convert to 0"
+
+ valueToStringBlock := [:num | num asFloat printString].
+ stringToValueBlock := [:string | Float readFromString:string onError:0]
+!
+
+initForFloatWithPrecision:nDigits
+ "initialize to convert to/from an float with nDigits after the decimal point
+ (truncating remaining digits).
+ - if the string is empty or invalid, convert to 0"
+
+ |conv|
+
+ conv := '%.' , nDigits printString , 'f'.
+ valueToStringBlock := [:num | num asFloat printfPrintString:conv].
+ stringToValueBlock := [:string | Float readFromString:string onError:0]
+!
+
initForNumber
"initialize to convert to/from a number
- if the string is empty or invalid, convert to 0"