Label.st
changeset 118 3ee5ea99d0e2
parent 113 fdd18cfff57e
child 125 3ffa271732f7
--- a/Label.st	Sun Apr 30 15:40:03 1995 +0200
+++ b/Label.st	Wed May 03 02:30:14 1995 +0200
@@ -14,7 +14,7 @@
 
 View subclass:#Label
 	 instanceVariableNames:'logo labelWidth labelHeight labelOriginX labelOriginY adjust
-		hSpace vSpace bgColor fgColor fixSize'
+		hSpace vSpace bgColor fgColor fixSize labelMsg'
 	 classVariableNames:'DefaultFont DefaultForegroundColor DefaultBackgroundColor'
 	 poolDictionaries:''
 	 category:'Views-Layout'
@@ -24,7 +24,7 @@
 COPYRIGHT (c) 1989 by Claus Gittinger
 	      All Rights Reserved
 
-$Header: /cvs/stx/stx/libwidg/Label.st,v 1.20 1995-03-31 03:02:16 claus Exp $
+$Header: /cvs/stx/stx/libwidg/Label.st,v 1.21 1995-05-03 00:29:53 claus Exp $
 '!
 
 !Label class methodsFor:'documentation'!
@@ -45,7 +45,7 @@
 
 version
 "
-$Header: /cvs/stx/stx/libwidg/Label.st,v 1.20 1995-03-31 03:02:16 claus Exp $
+$Header: /cvs/stx/stx/libwidg/Label.st,v 1.21 1995-05-03 00:29:53 claus Exp $
 "
 !
 
@@ -54,7 +54,7 @@
     This class implements labels, which are views to display a string or image.
     The Label will try to do its best to make its contents fit into the
     view. The contents can be a String, a collection of Strings (i.e.
-    Text) or a Form/Image. 
+    a StringCollection) or a Form/Image. 
 
     The contents is drawn in fgColor/bgColor, which can be changed using:
 
@@ -69,7 +69,9 @@
 
     This can be used, if resizing of the label is not wanted.
     However, in this case you have to make certain that the size is big enough
-    to hold changed logos later.
+    to hold any changed logos later. (usually, you create the label first with
+    the longest string first to have it compute its size, then set the fixSize 
+    attribute to avoid resizing later).
 
     The placement of the contents within the label is controlled by
     the adjust attribute, it can be set with:
@@ -79,6 +81,34 @@
     where how is one of the symbols left, #right, #center, #centerLeft or
     #centerRight (see the comment in Label>>adjust:). The default is #center.
 
+    model-less operation:
+      if no model is set, the labels contents is set with:
+
+	aLabel label:aStringOrImage
+
+      and stays constant unless changed by new calls to #label:.
+
+
+    model operation:
+      labels with a model, aspectMsg and labelMsg react to 
+      changes of the aspect, and send a labelMsg-message 
+      to the model in order to aquire a new labelString or image.
+      The model should send 'self changed:aspectMsg' if it thinks the label 
+      should change and return a string or image from the labelMsg-message.
+
+	label model:aModel.
+	label aspect:aspectSymbol.
+	label labelMessage:labelSymbol.
+
+	model sends #changed:aspectSymbol
+	---> label will redraw its label from value of model perform:labelSymbol
+
+      Having a labelSymbol different from the aspectSymbol allows for two labels
+      to react on the same aspect-change, but use different messages when asking
+      the model for a new label contents. By default, the labelMsg is nil,
+      so the label does NOT update its shown contents.
+      The aspectMsg defaults to #value.
+
     Instance variables:
 
 	logo                <Object>        the logo, can be a Form, String or Text
@@ -99,17 +129,15 @@
 					    resize the label; otherwise, its size is adjusted.
 					    default:false.
 
-    Model-View interaction:
-      labels with a model and an aspectSymbol react to changes of this
-      aspect, and perform this message on the model to aquire a new labelString.
-      The model is should send 'self changed:<aspect>' if it changes and return
-      a string from the <aspect> message.
+	labelMsg            <Symbol>        if non-nil, this is sent to the model to
+					    aquire the labelString or labelImage.
+					    If nil, the label stays as is
 
-	label model:aModel.
-	label aspect:aspectSymbol.
+    styleSheet parameters:
 
-	model sends #changed:aspectSymbol
-	---> label will redraw its label from value of model>>aspectSymbol
+      labelForegroundColor    <Color>         color to draw foreground pixels (i.e. the string)
+      labelBackgroundColor    <Color>         color to draw background pixels
+      labelFont               <Font>          font to use for textual labels
 "
 !
 
@@ -183,6 +211,23 @@
 	top open
 
 
+    colors & font:    
+	|top l|
+
+	top := StandardSystemView new.
+	top extent:(200 @ 200).
+
+	l := Label in:top.
+	l level:-1.
+	l font:(Font family:'Times' size:18).
+	l foregroundColor:Color yellow.
+	l backgroundColor:Color red.
+	l label:'hello world'.
+	l origin:50@100.
+
+	top open
+
+
     border & colors:    
 	|top l|
 
@@ -210,13 +255,20 @@
 	l := Label in:top.
 	l borderWidth:1.
 	l label:'default - centered'.
-	l origin:0.0@70.
+	l origin:0.0@40.
 	l width:1.0.
 
 	l := Label in:top.
 	l borderWidth:1.
 	l adjust:#left.
 	l label:'left adjust'.
+	l origin:0.0@70.
+	l width:1.0.
+
+	l := Label in:top.
+	l borderWidth:1.
+	l adjust:#centerLeft.
+	l label:'centerLeft adjust and a bit too long'.
 	l origin:0.0@100.
 	l width:1.0.
 
@@ -227,11 +279,19 @@
 	l origin:0.0@130.
 	l width:1.0.
 
+	l := Label in:top.
+	l borderWidth:1.
+	l adjust:#centerRight.
+	l label:'centerRight adjust and a bit too long'.
+	l origin:0.0@160.
+	l width:1.0.
+
 	top open
 
 
     just a reminder, that instead of doing placement manually
     as in ...:    
+
 	|top l|
 
 	top := StandardSystemView new.
@@ -302,7 +362,7 @@
 
 	l := Label in:top.
 	l level:-1.
-	l form:((Image fromFile:'bitmaps/garfield.gif') magnifyBy:0.2 @ 0.2).
+	l label:((Image fromFile:'bitmaps/garfield.gif') magnifyBy:0.2 @ 0.2).
 	l origin:50@100.
 
 	top open
@@ -310,7 +370,7 @@
 
      MVC operation (model provides the label):
      (have to use a plug to simulate a model which responds to
-      the #getLabel message):
+      the #someAspect message):
 
 	|top l model|
 
@@ -321,41 +381,97 @@
 	top extent:(200 @ 200).
 
 	l := Label in:top.
-	l model:model; aspect:#someAspect.
+	l model:model; labelMessage:#someAspect.
 
 	top open
+	...
+
+	model changed:#someAspect
+	...
 
 
-     MVC operation (model  changes aspect after a while):
+    concrete example (track a counters value):
+    (here, the default aspect #value is used both to notify the label about
+    changes and to aquire a new value from the model).
 
 	|top l model|
 
-	model := Plug new.
-	model respondTo:#someAspect with:['models labelString'].
+	model := ValueHolder new.
+	model value:0.
+	[
+	    1 to:20 do:[:i |
+		(Delay forSeconds:1) wait.
+		model value:i
+	    ].
+	    top destroy
+	] fork.
 
 	top := StandardSystemView new.
 	top extent:(200 @ 200).
 
 	l := Label in:top.
-	l model:model; aspect:#someAspect .
+	l model:model; labelMessage:#value.
+
+	top open
+
+
+     MVC operation (model changes aspect after a while; 
+     two labels on the same model):
+
+	|top l model|
+
+	model := Plug new.
+	model respondTo:#labelValue1 with:['models labelString1'].
+	model respondTo:#labelValue2 with:['models labelString2'].
+
+	top := StandardSystemView new.
+	top extent:(200 @ 200).
+
+	l := Label origin:0.0@0.0 corner:1.0@0.5 in:top.
+	l model:model; aspect:#someAspect; labelMessage:#labelValue1.
+	l := Label origin:0.0@0.5 corner:1.0@1.0 in:top.
+	l model:model; aspect:#someAspect; labelMessage:#labelValue2.
 
 	top open.
+
 	(Delay forSeconds:5) wait.
-	model respondTo:#someAspect with:['new string'].
+	model respondTo:#labelValue1 with:['new string1'].
+	model respondTo:#labelValue2 with:['new string2'].
+
 	model changed:#someAspect 
+
+
+     plugged MVC operation (getBlock returns the label): 
+
+	|top l model|
+
+	model := PluggableAdaptor new
+			getBlock:[:m | 'hello']
+			putBlock:nil
+			updateBlock:nil.
+
+	top := StandardSystemView new.
+	top extent:(200 @ 200).
+
+	l := Label origin:0.0@0.0 corner:1.0@0.5 in:top.
+	l model:model; labelMessage:#value.
+
+	top open.
 "
 ! !
 
 !Label class methodsFor:'instance creation'!
 
 form:aForm
-    "return a new Label showing a form"
+    "return a new Label showing a form.
+     OBSOLETE: you should now use #label: for both text and bitmap labels."
 
     ^ (self on:Display) form:aForm
 !
 
 form:aForm in:aView
-    "return a new Label showing a form"
+    "return a new Label showing a form.
+     OBSOLETE: you should now use #label:in: for both text and bitmap labels."
 
     ^ (self in:aView) form:aForm
 ! !
@@ -368,6 +484,10 @@
     ^ 16 @ 16
 !
 
+defaultFont
+    ^ DefaultFont notNil ifTrue:[DefaultFont] ifFalse:[super defaultFont]
+!
+
 updateStyleCache
     DefaultForegroundColor := StyleSheet colorAt:'labelForegroundColor'.
     DefaultForegroundColor isNil ifTrue:[
@@ -417,22 +537,6 @@
     ^ fgColor
 !
 
-labelString:aString
-    "for ST-80 compatibility: same as label:
-     set the label-string; adjust extent if not already realized"
-
-    self label:aString
-!
-
-label:aString
-    "set the label-string; adjust extent if not already realized"
-
-    (logo = aString) ifFalse:[
-	logo := aString.
-	self newLayout
-    ]
-!
-
 backgroundColor:aColor
     "set the background color"
 
@@ -454,25 +558,65 @@
     self redraw
 !
 
-form:aForm
-    "set the labels form; adjust extent if not already realized"
+labelMessage:aSymbol 
+    "set the symbol used to aquire the labelString/image from the model.
+     The default is nil, which means: leave the label unchanged."
+
+    labelMsg := aSymbol
+!
+
+labelString:aString
+    "for ST-80 compatibility: same as #label:
+     set the label-string; adjust extent if not already realized and not fixedSize"
+
+    self label:aString
+!
 
-    (aForm notNil and:[aForm ~~ logo]) ifTrue:[
-	logo notNil ifTrue:[
-	    logo isImageOrForm ifTrue:[
-		logo extent = aForm extent ifTrue:[
-		    logo := aForm.
-		    ^ self
+label:aStringOrFormOrImage
+    "set the labelString or image; adjust extent if not already realized and
+     not fixedSize"
+
+    (aStringOrFormOrImage ~~ logo) ifTrue:[
+	"/
+	"/ avoid recompute of size, if its an image with
+	"/ the same size
+	"/
+	aStringOrFormOrImage isImageOrForm ifTrue:[
+	    logo notNil ifTrue:[
+		logo isImageOrForm ifTrue:[
+		    logo extent = aStringOrFormOrImage extent ifTrue:[
+			logo := aStringOrFormOrImage.
+			^ self
+		    ]
 		]
 	    ]
+	] ifFalse:[
+	    (logo = aStringOrFormOrImage) ifTrue:[
+		^ self
+	    ]
 	].
-	logo := aForm.
+	logo := aStringOrFormOrImage.
 	self newLayout
     ]
 !
 
+form:aForm
+    "set the labels form; adjust extent if not already realized.
+     OBSOLETE: you should now use #label: for both strings and images"
+
+    self label:aForm
+!
+
+logo:something
+    "set the labels form or string.
+     OBSOLETE: the old version used #form: for images and #label: for strings.
+	       you should now use #label: for any."
+
+    self label:something
+!
+
 label
-    "return the labels string"
+    "return the labels string or image"
 
     ^ logo
 !
@@ -501,9 +645,14 @@
      #left        -> left adjust logo
      #right       -> right adjust logo
      #center      -> center logo
+     #centerRight -> center logo; if no fit, right adjust
+		     (use with filenames, where the interresting part is
+		      at the right if the label is too small)
      #centerLeft  -> center logo; if it does not fit, left adjust it
-     #centerRight -> center logo; if no fit, right adjust
+		     (use with strings where the interresting part is at the
+		      left if the label is too small)
     "
+
     (adjust ~~ how) ifTrue:[
 	adjust := how.
 	self newLayout
@@ -511,22 +660,12 @@
 !
 
 font:aFont
-    "set the font - if I'm not realized, adjust my size"
+    "set the font - if I'm not realized and not fixedSize, adjust my size"
 
     (aFont ~~ font) ifTrue:[
 	super font:(aFont on:device).
 	self newLayout
     ]
-!
-
-logo:something
-    "set the labels form or string"
-
-    something isImageOrForm ifTrue:[
-	self form:something
-    ] ifFalse:[
-	self label:something
-    ]
 ! !
 
 !Label methodsFor:'initialization'!
@@ -549,10 +688,10 @@
 
 realize
     super realize.
-    fgColor := fgColor on:device.
-    bgColor := bgColor on:device.
+"/    fgColor := fgColor on:device.
+"/    bgColor := bgColor on:device.
     (model notNil 
-    and:[aspectSymbol notNil]) ifTrue:[
+    and:[aspectMsg notNil]) ifTrue:[
 	self getLabelFromModel.
     ]
 !
@@ -563,10 +702,8 @@
     font := font on:device.
     self height:(font height + font descent).
     adjust := #center.
-    labelOriginX := 0.
-    labelOriginY := 0.
-    labelWidth := 0.
-    labelHeight := 0.
+    labelOriginX := labelOriginY := 0.
+    labelWidth := labelHeight := 0.
     logo := nil.
     fixSize := false.
     hSpace := (self horizontalPixelPerMillimeter:0.5) rounded.
@@ -652,11 +789,20 @@
 !Label methodsFor:'private'!
 
 getLabelFromModel
-    "ask my model for the label to show"
+    "ask my model for the label to show.
+     Here, we use labelMsg. 
+     This allows multiple labels to react on the same aspect, 
+     but show different labels when changed (also, constant labels
+     which have a nil labelMsg will not try to aquire a labelString)."
 
-    (model notNil 
-    and:[aspectSymbol notNil]) ifTrue:[
-	self label:(model perform: aspectSymbol) printString.
+    |sym|
+
+    model notNil ifTrue:[
+	sym := labelMsg.
+"/        sym isNil ifTrue:[sym := aspect<sg].
+	sym notNil ifTrue:[
+	    self label:(model perform:sym) printString.
+	]
     ].
 !
 
@@ -758,7 +904,8 @@
 !Label methodsFor:'resizing'!
 
 forceResize
-    "resize myself to make text fit into myself."
+    "resize myself to make text fit into myself. Here, this is done even if
+     fixSize is set."
 
     logo notNil ifTrue:[
 	self extent:self preferedExtent.
@@ -768,8 +915,8 @@
 
 resize
     "resize myself to make text fit into myself.
-     but only do so, if I have not been given a relative extent
-     or an extend computation block."
+     but only do so, if I am not fixedSize and I have NOT been 
+     given a relative extent or an extend computation block."
 
     (logo notNil 
     and:[fixSize not
@@ -785,13 +932,16 @@
 
 !Label methodsFor:'change & update'!
 
-update:something
+update:something with:aParameter from:changedObject
     "the MVC way of changing the label ..."
 
-    (aspectSymbol notNil
-    and:[something == aspectSymbol]) ifTrue:[
-	self getLabelFromModel.
-	^ self.
+    changedObject == model ifTrue:[
+	something == aspectMsg ifTrue:[
+	    labelMsg notNil ifTrue:[
+		self getLabelFromModel.
+	    ].
+	    ^ self.
+	]
     ].
     super update:something
 ! !
@@ -810,4 +960,3 @@
 
     ^ super preferedExtent
 ! !
-