CS 683 Emerging Technologies: Embracing Change Spring Semester, 2001 Squeak GUI |
||
---|---|---|
© 2001, All Rights Reserved, SDSU & Roger Whitney San Diego State University -- This page last updated 03-Apr-01 |
Squeak GUI
For Fun - Worlds Smallest Drawing Program
Draws while Mouse is down (left-click windows)
End program with yellow button
| aPen color | aPen := Pen new. color := 0. [Sensor yellowButtonPressed] whileFalse: [aPen place: Sensor cursorPoint; color: (color := color + 1). [Sensor redButtonPressed] whileTrue: [aPen goto: Sensor cursorPoint]]. Sensor waitNoButton.
Pen
| pen | pen := Pen newOnForm: Display. pen defaultNib: 2. 1 to: 50 do: [:i | pen go: i*4; turn: 89].
Note that we are drawing directly on the screen over what ever is displayed
Some Pen Operations
Initializing defaultNib: nibSize
Pen Operations continued
north
Some More Examples
| pen | pen := Pen newOnForm: Display. pen defaultNib: 2. pen fill: [:each | 6 timesRepeat: [each go: 100;turn: 60]] color: Color red
Display restoreAfter:
Drawing directly on the screen requires cleaning up afterwards
Display restoreAfter: aBlock
Display restoreAfter: [Pen new mandala: 30]
Display restoreAfter: [| pen | pen := Pen new. pen squareNib: 2; color: Color red; turn: 45. pen print: 'The owl and the pussycat went to sea in a beautiful pea green boat.' withFont: TextStyle defaultFont]
Color
Instance Creation The Color class responds to the following color names:
black |
blue |
brown |
cyan |
darkGray |
gray |
green |
lightBlue |
lightBrown |
lightCyan |
lightGray |
lightGreen |
lightMagenta |
lightOrange |
lightRed |
lightYellow |
magenta |
orange |
paleBlue |
paleBuff |
paleGreen |
paleMagenta |
paleOrange |
palePeach |
paleRed |
paleTan |
paleYellow |
red |
tan |
transparent |
veryDarkGray |
veryLightGray |
veryPaleRed |
veryVeryDarkGray |
veryVeryLightGray |
white |
yellow |
|
|
|
Forms
A rectangular array of pixels, used for holding images
Using a form we can draw an image then display it
| form pen | form := Form extent: 150@150 depth: Display depth. form fillColor: Color green. pen := Pen newOnForm: form. pen roundNib: 2; color: Color red; dragon: 9. form displayAt: Display center - form center.
A Less Ephemeral Drawing
Up to now we have been drawing directly on the Screen
Usually one displays a drawing in a window so it can be moved, resized etc.
A form can be converted to a morph and displayed
| form pen | form := Form extent: 150@150 depth: Display depth. form fillColor: Color green. pen := Pen newOnForm: form. pen roundNib: 2; color: Color red; dragon: 9. form asMorph openInWorld
In a Window
| form pen | form := Form extent: 150@150 depth: Display depth. form fillColor: Color green. pen := Pen newOnForm: form. pen roundNib: 2; color: Color red; dragon: 9. window := SystemWindow labelled: 'Image'. window addMorph: form asMorph frame: (0@0 extent: 1@1). window openInWorld
Observer
Defines a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically
Use the Observer pattern:
Structure
Collaborations
Smalltalk Observer
Subject is called model
A model can be:
GUI Examples
A Button Example
Object subclass: #Toggle instanceVariableNames: 'isOn ' classVariableNames: '' poolDictionaries: '' category: 'Whitney-Examples'
An example of using PluggableButtonMorph. This model toggles the color and text of the button when pressed.
Structure:
isOn boolean -- toggle between on and off state
Class Methods new ^super new initialize
openInWorld "Toggle openInWorld" ^self new openInWorld
Instance Methods
initialize isOn := true.
isOn ^isOn
Instance Methods - Continued
changeStateLabel ^isOn ifTrue:['Turn Off'] ifFalse:['Turn On']
toggle isOn := isOn not. self changed: #changeStateLabel
openInWorld | window toggleButton | window := SystemWindow labelled: 'Toggle Example'. window model: self. toggleButton := PluggableButtonMorph on: self getState: #isOn action: #toggle label: #changeStateLabel menu: nil. toggleButton onColor: Color red offColor: Color blue. toggleButton feedbackColor: Color yellow. window addMorph: toggleButton frame: (0@0 extent: 1@1). window openInWorld.
How Does this Work
toggleButton := PluggableButtonMorph on: self getState: #isOn action: #toggle label: #changeStateLabel menu: nil.
PluggableTextMorph
getTextSelector
Text Field Example
Object subclass: #TextModelExample instanceVariableNames: 'changeCount text ' classVariableNames: '' poolDictionaries: '' category: 'Whitney-Examples'
This class is an example of using a PluggableTextMorph. When a user changes and saves text in the text field, the text and its reverse is displayed in the text field. A count of the number of changes is shown before the text. The original text saved by the user is highlighted.
Structure:
changeCount integer -- number of times user has saved text text String or Text -- text last saved by user
Class Methods new ^super new initialize
openInWorld "TextModelExample openInWorld" ^self new openInWorld
Instance Methods initialize changeCount := 0. text := 'Starting'
openInWorld "TextModelExample openInWorld" | window display | window := SystemWindow labelled: 'Text Example'. window model: self. display := PluggableTextMorph on: self text: #text accept: #text: readSelection: #selectTextInterval menu: nil. window addMorph: display frame: (0@0 extent: 1@1). window openInWorld.
selectTextInterval |headerSize | headerSize := changeCount printString size + 1. ^Interval from: headerSize + 1 to: text size /2 + headerSize
text ^changeCount printString , ' ' , text
text: aString changeCount := changeCount + 1. text := aString , aString reversed. self changed: #text. ^true
PluggableButtonMorph
Important PluggableButtonMorph state
label (label: aString)
Text & Button Example
Counter - No GUI
Object subclass: #Counter instanceVariableNames: 'count ' classVariableNames: '' poolDictionaries: '' category: 'Whitney-Examples'
Class Methods new ^super new initialize
Instance Methods printOn: aStream aStream nextPutAll: count printString add: amount count := count + amount. decrease self add: -1 increase self add: 1 initialize count := 0
Counter - With GUI
Object subclass: #Counter instanceVariableNames: 'count ' classVariableNames: '' poolDictionaries: '' category: 'Whitney-Examples'Class Methods new ^super new initialize openInWorld ^self new openInWorld
Instance Methods printOn: aStream aStream nextPutAll: count printString add: amount count := count + amount. self changed: #printString count: aNumberOrText count := aNumberOrText asNumber. ^true decrease self add: -1 increase self add: 1 initialize count := 0
Instance Methods - Continued
openInWorld | window increaseButton decreaseButton display | window := SystemWindow labelled: 'Counter'. window model: self. increaseButton := PluggableButtonMorph new model: self; action: #increase; label: 'Increase'; borderWidth: 1. decreaseButton := PluggableButtonMorph new model: self; action: #decrease; label: 'Decrease'; borderWidth: 1. display := PluggableTextMorph on: self text: #printString accept: #count:. window addMorph: display frame: (0@0 extent: 1@0.5). window addMorph: increaseButton frame: (0@0.5 extent: 0.5@0.5). window addMorph: decreaseButton frame: (0.5@0.5 extent: 0.5@0.5). window openInWorld.
Copyright ©, All rights reserved.
2001 SDSU & Roger Whitney, 5500 Campanile Drive, San Diego, CA 92182-7700 USA.
OpenContent license defines the copyright on this document.
Previous    visitors since 03-Apr-01    Next