From: benson@siemens.com. (Dan Benson)
Newsgroups: comp.lang.smalltalk
Subject: Re: How do I center something in a LayoutFrame in Objectworks 4.1?
Keywords: smalltalk, graphics
Date: 11 Dec 92 18:13:54 GMT
Organization: Siemens Corp. Res., Inc.

In article <6226@vexpert.dbai.tuwien.ac.at> mst@vexpert.dbai.tuwien.ac.at (Markus Stumptner) writes:
>Assume you have an graphic object whose size you don't know
>beforehand.  Is there any way to specify a LayoutFrame (or any kind of
>Wrapper) so that it's going to be centered inside the frame? 
>
>Primitive example: Centering text inside a button.  Centering
>ComposedText implies that the text knows the width of the frame, which
>is of course not the case.
>
>I've browsed through some classes without finding a clue.  Quite
>appropriately, there is no centered text used in the Objectworks tools
>that I know of right now.  (The only centered text I found was window
>labels, and that's done with a primitive. :-)
>
>So, is there any simple way?  Of course, I could write it myself, but
>I might have overlooked something.  Thanks in advance for any clues.
>
>-- 
>Markus Stumptner                                mst@vexpert.dbai.tuwien.ac.at
>University of Technology Vienna                 vexpert!mst@relay.eu.net
>Paniglg. 16, A-1040 Vienna, Austria             ...mcsun!vexpert!mst


Here is yet another example answer to your centering question. This is
a class definition for centered buttons. There are a couple examples
in the class methods you can look at.

Dan


'From Objectworks\Smalltalk(R), Release 4.1 of 15 April 1992 on 10 December 1992 at 4:54:06 pm'!

LabeledBooleanView subclass: #CenteredLabeledBooleanView
	instanceVariableNames: 'labelStyle '
	classVariableNames: ''
	poolDictionaries: ''
	category: 'View Extras'!
CenteredLabeledBooleanView comment:
'I represent the class of labeled boolean views that center their visual contents (i.e. labels and images). My instances also add an instance variable (labelStyle) so that each one can have its own label style. My instances can have both an image and a label, where the label is displayed below the image (sometimes it gets cut off). See class examples.

Send any comments, corrections, suggestions to:

Dan Benson
Siemens Corporate Research
755 College Road East
Princeton, NJ 08540
(609) 734-3668
dbenson@siemens.siemens.com
'!


!CenteredLabeledBooleanView methodsFor: 'displaying'!

displayOn: aGraphicsContext
	"Display the receiver according to
	the current state of the model."

	| extent image bounds |
	image := self getImage.
	extent := self bounds extent.
	(self useFilling and: [self isSelected or: [self isInTransition]])
		ifTrue:
			[aGraphicsContext paint: self selectionBackgroundColor.
			aGraphicsContext displayRectangle: self bounds.
			aGraphicsContext paint: self selectionForegroundColor].
	(onImage == nil and: [offImage == nil])
		ifFalse:
			[image isNil ifTrue: [image := offImage].  "onImage is nil"
			bounds := image preferredBounds.
			image
				displayOn: aGraphicsContext
				at: (self bounds center x - (bounds width / 2)) @ (extent y - bounds height // 2)].
	label notNil
		ifTrue:
			[| font string |
			font := aGraphicsContext findFont: self getFont.	
			aGraphicsContext font: font.
			string := label asString.
			self setTextColorOn: aGraphicsContext.
			aGraphicsContext
				displayString: string
				at: ((self bounds width / 2) - (string asComposedText width / 2)) @
						(image isNil 
							ifTrue: [(extent y + font ascent - font descent // 2)]
							ifFalse: [bounds height + (extent y + font ascent - font descent // 2)])].
	(self drawBorder and: [self isSelected])
		ifTrue:
			[aGraphicsContext paint: self selectionForegroundColor.
			self container border displayOn: aGraphicsContext forDisplayBox: self bounds]! !

!CenteredLabeledBooleanView methodsFor: 'accessing'!

labelStyle
	^labelStyle isNil
		ifTrue: [LabelStyle]
		ifFalse: [labelStyle]!

labelStyle: aTextAttribute
	labelStyle := aTextAttribute! !

!CenteredLabeledBooleanView methodsFor: 'private'!

getFont
	"Answer a font to use in displaying the receiver's label."

	^(self useFilling or: [self isSelected not])
		ifTrue: [self labelStyle fontAt: nil]
		ifFalse: [self labelStyle fontAt: #bold]! !
"-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!

CenteredLabeledBooleanView class
	instanceVariableNames: ''!


!CenteredLabeledBooleanView class methodsFor: 'examples'!

example1
	"CenteredLabeledBooleanView example1"

	(ScheduledWindow new)
		label: 'CenteredLabeledBooleanView example1';
		component: ((CompositePart new) 
			add: ((BorderedWrapper on: (self
					on: Screen default
					label: 'Ring Bell'
					action: #ringBell))
				insideColor: ColorValue lightYellow)
			in: ((LayoutFrame new) 
				leftFraction: 0 offset: 10;
				rightFraction: 0.7;
				topFraction: 0 offset: 10;
				bottomFraction: 0.8); yourself); 
			insideColor: ColorValue veryLightGray; 
		openWithExtent: 400 @ 100!

example2
	"CenteredLabeledBooleanView example2"

	| offset delta cp |
	offset := 0.1.
	delta := 0.1.
	cp := CompositePart new.
	TextAttributes styles do: [:s | 
		cp add: ((BorderedWrapper on: ((self
					on: Screen default
					label: s asString
					action: #ringBell)
					labelStyle: (TextAttributes styleNamed: s)))
				insideColor: ColorValue lightCyan)
			in: ((LayoutFrame new) 
					leftFraction: 0.3; 
					rightFraction: 0.7; 
					topFraction: (offset := offset + delta); 
					bottomFraction: offset + delta)].
	(ScheduledWindow new) 
		label: 'CenteredLabeledBooleanView example2'; 
		component: cp; 
		insideColor: ColorValue veryLightGray; 
		openWithExtent: 300 @ 300!

example3
	"CenteredLabeledBooleanView example3"
	| aButton |
	DialogView warn: 'Get ready to grab a small image from the screen.'.
	aButton := self model: [false].
	aButton label: 'Grab Image'.
	aButton beVisual: Image fromUser.
	aButton controller beButton.
	aButton controller controlBlock: [:cursorPoint :button | button = #wentUp
		ifTrue: [aButton beVisual: Image fromUser; update: #display]].
	(ScheduledWindow new)
		label: 'CenteredLabeledBooleanView example3';
		component: ((CompositePart new) 
			add: ((BorderedWrapper on: aButton)
				insideColor: ColorValue lightYellow)
			in: ((LayoutFrame new) 
				leftFraction: 0.3;
				rightFraction: 0.7;
				topFraction: 0.2;
				bottomFraction: 0.8); yourself); 
			insideColor: ColorValue veryLightGray; 
		openWithExtent: 300 @ 300! !

!CenteredLabeledBooleanView class methodsFor: 'instance creation'!

on: aModel label: aString action: aSelector 
	"Answer a pluggable CenteredLabeledBooleanView with label aString that 
	sends aModel aSelector when pressed. Note that the button's model is
	simply 'false' so that it never toggles."

	| aButton |
	aButton := self model: [false].
	aButton label: aString.
	aButton controller beButton.
	aButton controller controlBlock: [:cursorPoint :button | button = #wentDown 
		ifTrue: [(aModel respondsTo: aSelector)
				ifTrue: [aModel perform: aSelector]]].
	^aButton! !





--
Dan Benson                           Siemens Corporate Research, Inc.
(609) 734-3668                       755 College Road East
dbenson@siemens.siemens.com          Princeton, NJ  08540
Newsgroups: comp.lang.smalltalk