[squeak-dev] The Trunk: EToys-mt.489.mcz
commits at source.squeak.org
commits at source.squeak.org
Wed Jan 11 14:40:32 UTC 2023
Marcel Taeumel uploaded a new version of EToys to project The Trunk:
http://source.squeak.org/trunk/EToys-mt.489.mcz
==================== Summary ====================
Name: EToys-mt.489
Author: mt
Time: 11 January 2023, 3:40:29.715326 pm
UUID: 7d2816dd-cc6e-6243-93bf-6c782448b0be
Ancestors: EToys-kfr.478, EToys-ct.461, EToys-lrnp.480, EToys-ct.480, EToys-kfr.487, EToys-kfr.488
Merge EToys-kfr.478, EToys-ct.461, EToys-lrnp.480, EToys-ct.480, EToys-kfr.487, EToys-kfr.488
EToys-kfr.478:
When heading changes in a Player, it gets added to a TransformationMorph. During this process it's x and y values get set to 0. [...]
EToys-ct.461:
Proposal: Do not play sounds while initializing the players tool. Opening a fresh image and selecting the Scripting category should not make a sound. [...]
EToys-lrnp.480:
fix code rot in StackMorph logic [...]
EToys-ct.480:
Proposal: Improves state indication in Tetris game. Makes the pause button stateful. When the game is over, change the status display to red.
EToys-kfr.487:
MineGame scale to HD Display
EToys-kfr.488:
Add a undo button to FreeCell
=============== Diff against EToys-ct.477 ===============
Item was changed:
SystemOrganization addCategory: #'Etoys-Buttons'!
SystemOrganization addCategory: #'Etoys-CustomEvents'!
SystemOrganization addCategory: #'Etoys-Experimental'!
SystemOrganization addCategory: #'Etoys-OLPC-Display'!
SystemOrganization addCategory: #'Etoys-Outliner'!
SystemOrganization addCategory: #'Etoys-Protocols'!
SystemOrganization addCategory: #'Etoys-Protocols-Type Vocabularies'!
SystemOrganization addCategory: #'Etoys-ReleaseBuilder'!
SystemOrganization addCategory: #'Etoys-Scripting'!
SystemOrganization addCategory: #'Etoys-Scripting Support'!
SystemOrganization addCategory: #'Etoys-Scripting Tiles'!
SystemOrganization addCategory: #'Etoys-Squeakland-EToys-Kedama'!
SystemOrganization addCategory: #'Etoys-Squeakland-Etoys-Buttons'!
SystemOrganization addCategory: #'Etoys-Squeakland-Etoys-Calendar'!
SystemOrganization addCategory: #'Etoys-Squeakland-Etoys-Debugger'!
SystemOrganization addCategory: #'Etoys-Squeakland-Etoys-Help'!
SystemOrganization addCategory: #'Etoys-Squeakland-Etoys-Input'!
SystemOrganization addCategory: #'Etoys-Squeakland-Etoys-Scripting'!
SystemOrganization addCategory: #'Etoys-Squeakland-Etoys-Scripting Support'!
SystemOrganization addCategory: #'Etoys-Squeakland-Etoys-Scripting Tiles'!
SystemOrganization addCategory: #'Etoys-Squeakland-Etoys-SpeechBubbles'!
SystemOrganization addCategory: #'Etoys-Squeakland-Etoys-Tile Scriptors'!
SystemOrganization addCategory: #'Etoys-Squeakland-Graphics-Text'!
SystemOrganization addCategory: #'Etoys-Squeakland-Graphics-Tools-Intersection'!
SystemOrganization addCategory: #'Etoys-Squeakland-Graphics-Tools-Simplification'!
SystemOrganization addCategory: #'Etoys-Squeakland-Graphics-Tools-Triangulation'!
SystemOrganization addCategory: #'Etoys-Squeakland-Morphic-Basic'!
SystemOrganization addCategory: #'Etoys-Squeakland-Morphic-Books'!
SystemOrganization addCategory: #'Etoys-Squeakland-Morphic-Components'!
SystemOrganization addCategory: #'Etoys-Squeakland-Morphic-Demo'!
SystemOrganization addCategory: #'Etoys-Squeakland-Morphic-Experimental'!
SystemOrganization addCategory: #'Etoys-Squeakland-Morphic-Games'!
SystemOrganization addCategory: #'Etoys-Squeakland-Morphic-Games-Chess'!
SystemOrganization addCategory: #'Etoys-Squeakland-Morphic-Games-Chess960'!
SystemOrganization addCategory: #'Etoys-Squeakland-Morphic-GeeMail'!
SystemOrganization addCategory: #'Etoys-Squeakland-Morphic-Kernel'!
SystemOrganization addCategory: #'Etoys-Squeakland-Morphic-Mentoring'!
SystemOrganization addCategory: #'Etoys-Squeakland-Morphic-Navigators'!
SystemOrganization addCategory: #'Etoys-Squeakland-Morphic-PDA'!
SystemOrganization addCategory: #'Etoys-Squeakland-Morphic-PartsBin'!
SystemOrganization addCategory: #'Etoys-Squeakland-Morphic-Support'!
SystemOrganization addCategory: #'Etoys-Squeakland-Morphic-Widgets'!
SystemOrganization addCategory: #'Etoys-Squeakland-Morphic-Windows'!
SystemOrganization addCategory: #'Etoys-Squeakland-Morphic-Worlds'!
SystemOrganization addCategory: #'Etoys-Squeakland-MorphicExtras-AdditionalMorphs'!
SystemOrganization addCategory: #'Etoys-Squeakland-MorphicExtras-Charts'!
SystemOrganization addCategory: #'Etoys-Squeakland-MorphicExtras-Postscript Filters'!
SystemOrganization addCategory: #'Etoys-Squeakland-MorphicExtras-Widgets'!
SystemOrganization addCategory: #'Etoys-Squeakland-Network-HTML-Formatter'!
SystemOrganization addCategory: #'Etoys-Squeakland-Network-HTML-Forms'!
SystemOrganization addCategory: #'Etoys-Squeakland-Network-HTML-Parser'!
SystemOrganization addCategory: #'Etoys-Squeakland-Network-HTML-Parser Entities'!
SystemOrganization addCategory: #'Etoys-Squeakland-Network-HTML-Tokenizer'!
SystemOrganization addCategory: #'Etoys-Squeakland-Network-MIME'!
SystemOrganization addCategory: #'Etoys-Squeakland-Network-TelNet WordNet'!
SystemOrganization addCategory: #'Etoys-Squeakland-Network-UI'!
SystemOrganization addCategory: #'Etoys-Squeakland-Network-Url'!
SystemOrganization addCategory: #'Etoys-Squeakland-SISS-Serialization'!
SystemOrganization addCategory: #'Etoys-Squeakland-ST80-Morphic'!
SystemOrganization addCategory: #'Etoys-Squeakland-SUnit'!
SystemOrganization addCategory: #'Etoys-Squeakland-Sound-Interface'!
SystemOrganization addCategory: #'Etoys-Squeakland-Sound-Ogg'!
SystemOrganization addCategory: #'Etoys-Squeakland-Sound-Scores'!
SystemOrganization addCategory: #'Etoys-Squeakland-Sugar'!
SystemOrganization addCategory: #'Etoys-Squeakland-Support'!
SystemOrganization addCategory: #'Etoys-Squeakland-System-Clipboard-Extended'!
SystemOrganization addCategory: #'Etoys-Squeakland-System-Compiler'!
SystemOrganization addCategory: #'Etoys-Squeakland-System-Exceptions Kernel'!
SystemOrganization addCategory: #'Etoys-Squeakland-System-Support'!
SystemOrganization addCategory: #'Etoys-Squeakland-Tools-Changes'!
SystemOrganization addCategory: #'Etoys-Squeakland-Tools-Explorer'!
SystemOrganization addCategory: #'Etoys-Squeakland-Tools-Process Browser'!
SystemOrganization addCategory: #'Etoys-Squeakland-Tweak-Kedama-ObjectVectors'!
SystemOrganization addCategory: #'Etoys-Squeakland-Tweak-Kedama-ParseTree-AttributeDefinition'!
SystemOrganization addCategory: #'Etoys-Squeakland-Tweak-Kedama-ParseTreeTransformer'!
SystemOrganization addCategory: #'Etoys-Stacks'!
SystemOrganization addCategory: #'Etoys-StarSqueak'!
SystemOrganization addCategory: #'Etoys-Support'!
SystemOrganization addCategory: #'Etoys-Tests'!
SystemOrganization addCategory: #'Etoys-Tile Scriptors'!
SystemOrganization addCategory: #'Etoys-UserInterfaceTheme'!
SystemOrganization addCategory: #'Etoys-Widgets'!
+ SystemOrganization addCategory: #'Etoys-Help'!
Item was changed:
----- Method: AllPlayersTool>>reinvigorate (in category 'reinvigoration') -----
reinvigorate
"Referesh the contents of the receiver"
(submorphs copyFrom: 3 to: submorphs size) do: [:m | m delete].
self currentWorld doOneCycleNow.
+ self currentWorld presenter reinvigoratePlayersTool: self.!
- self playSoundNamed: 'scritch'.
- (Delay forMilliseconds: 700) wait.
- self currentWorld presenter reinvigoratePlayersTool: self.
- self playSoundNamed: 'scratch'.!
Item was changed:
----- Method: CalendarMorph>>dayInitialsRow (in category 'building') -----
dayInitialsRow
| newRow |
newRow := self newRow.
Week dayNames
do: [:dayName|
newRow addMorphBack: (TextMorph new
contentsWrapped: dayName translated first asString;
textColor: self labelsDefaultColor;
autoFit: false;
+ width: 30 px;
- width: 30;
centered;
lock)]
separatedBy: [newRow addMorphBack: AlignmentMorph newVariableTransparentSpacer].
^newRow !
Item was changed:
----- Method: CalendarMorph>>newButtonWithContents: (in category 'building') -----
+ newButtonWithContents: aString
+
+ ^ SimpleButtonMorph new
+ label: aString;
- newButtonWithContents: aByteString
- ^SimpleButtonMorph new
- label: aByteString;
color: (self color mixed: 0.5 with: Color gray);
+ borderStyle: (BorderStyle raised width: 2 px);
+ yourself!
- borderStyle: (BorderStyle raised width: 2)!
Item was changed:
----- Method: CalendarMorph>>newDateButtonWithContents: (in category 'building') -----
+ newDateButtonWithContents: aString
+
+ ^ SimpleButtonMorph new
+ label: aString;
- newDateButtonWithContents: aByteString
- ^SimpleButtonMorph new
- label: aByteString;
cornerStyle: #square;
color: self color muchLighter;
+ borderStyle: (BorderStyle raised width: 2 px);
+ width: 30 px;
+ yourself!
- borderStyle: (BorderStyle raised width: 2);
- width: 30!
Item was changed:
----- Method: CipherPanel>>buttonRow (in category 'menu') -----
buttonRow
| row aButton |
row := AlignmentMorph newRow color: self color;
hResizing: #shrinkWrap;
vResizing: #shrinkWrap.
#('show help' 'show hints' 'clear typing' 'enter a new cipher' 'quote from Squeak' ) translatedNoop
with: #(#showHelpWindow #showHintsWindow #clearTyping #enterANewCipher #squeakCipher )
do: [:label :selector |
aButton := SimpleButtonMorph new target: self.
aButton color: Color transparent;
+ borderWidth: 1 px;
- borderWidth: 1;
borderColor: Color black.
aButton actionSelector: selector.
aButton label: label translated.
row addMorphBack: aButton.
+ row addTransparentSpacerOfSize: 3 px @ 0].
- row addTransparentSpacerOfSize: 3 @ 0].
^ row!
Item was changed:
----- Method: CipherPanel>>encodedQuote: (in category 'initialization') -----
encodedQuote: aString
"World addMorph: CipherPanel new"
| morph prev |
aString isEmpty
ifTrue: [^ self].
(letterMorphs isNil
or: [self isClean])
ifFalse: [(self confirm: 'Are you sure you want to discard all typing?' translated)
ifFalse: [^ self]].
haveTypedHere := false.
quote := aString asUppercase.
prev := nil.
originalMorphs := quote asArray
withIndexCollect: [:c :i | WordGameLetterMorph new plain indexInQuote: i id1: nil;
setLetter: (quote at: i)].
letterMorphs := OrderedCollection new.
decodingMorphs := quote asArray
withIndexCollect: [:c :i | (quote at: i) isLetter
ifTrue: [morph := WordGameLetterMorph new underlined indexInQuote: i id1: nil.
morph
on: #mouseDown
send: #mouseDownEvent:letterMorph:
to: self.
morph
on: #keyStroke
send: #keyStrokeEvent:letterMorph:
to: self.
letterMorphs addLast: morph.
morph predecessor: prev.
prev
ifNotNil: [prev successor: morph].
prev := morph]
ifFalse: [WordGameLetterMorph new plain indexInQuote: i id1: nil;
setLetter: (quote at: i)]].
self color: originalMorphs first color.
+ self extent: 500 px @ 500 px.!
- self extent: 500 @ 500!
Item was changed:
----- Method: CipherPanel>>extent: (in category 'geometry') -----
extent: newExtent
"Lay out with word wrap, alternating bewteen decoded and encoded lines."
"Currently not tolerant of narrow (less than a word) margins"
| w h relLoc topLeft thisWord i m corner row firstWord |
self removeAllMorphs.
+ w := originalMorphs first width - 1 px. h := originalMorphs first height * 2 + 10 px.
+ topLeft := self position + self borderWidth + (0 @ 10 px).
- w := originalMorphs first width - 1. h := originalMorphs first height * 2 + 10.
- topLeft := self position + self borderWidth + (0 at 10).
thisWord := OrderedCollection new.
i := 1. firstWord := true. relLoc := 0 at 0. corner := topLeft.
[i <= originalMorphs size] whileTrue:
[m := originalMorphs at: i.
thisWord addLast: ((decodingMorphs at: i) position: topLeft + relLoc).
thisWord addLast: (m position: topLeft + relLoc + (0 at m height)).
(m letter = Character space or: [i = originalMorphs size])
ifTrue: [self addAllMorphs: thisWord.
corner := corner max: thisWord last bounds bottomRight.
thisWord reset. firstWord := false].
relLoc := relLoc + (w at 0).
(relLoc x + w) > newExtent x
ifTrue: [firstWord
ifTrue: ["No spaces -- force a line break"
thisWord removeLast; removeLast.
self addAllMorphs: thisWord.
corner := corner max: thisWord last bounds bottomRight]
ifFalse: [i := i - (thisWord size//2) + 1].
thisWord reset. firstWord := true.
relLoc := 0@(relLoc y + h)]
ifFalse: [i := i + 1]].
row := self buttonRow. row fullBounds.
self addMorph: row.
+ super extent: (corner - topLeft) + (self borderWidth * 2) + (0 @ row height + 10 px).
+ row align: row bounds bottomCenter with: self bounds bottomCenter - (0 @ 2 px).!
- super extent: (corner - topLeft) + (self borderWidth * 2) + (0 at row height+10).
- row align: row bounds bottomCenter with: self bounds bottomCenter - (0 at 2).!
Item was changed:
----- Method: CipherPanel>>showHelpWindow (in category 'menu') -----
showHelpWindow
- ((PluggableTextMorph new setText: 'The Cipher Panel displays an encrypted message. The encryption is a simple substitution code; each letter of the alphabet has been changed to a different one.
+ 'The Cipher Panel displays an encrypted message. The encryption is a simple substitution code; each letter of the alphabet has been changed to a different one.
+
You can solve the cipher by clicking above any letter in the message, and typing the letter you think it should be. The Cipher Panel automatically makes the same substitution anywhere else that letter occurs in the encoded message.
+ If you are having trouble, you can use the command menu to ''show cipher hints''. That will display how many of each letter occurs, which is often a help in solving ciphers.' translated
+ editWithLabel: 'About the Cipher Panel' translated.!
- If you are having trouble, you can use the command menu to ''show cipher hints''. That will display how many of each letter occurs, which is often a help in solving ciphers.' translated )
- embeddedInMorphicWindowLabeled: 'About the Cipher Panel' translated)
- setWindowColor: (Color
- r: 1.0
- g: 0.6
- b: 0.0);
- openInWorld: self world extent: 389 @ 209!
Item was changed:
----- Method: CipherPanel>>showHintsWindow (in category 'menu') -----
showHintsWindow
+
+ ('Most bodies of english text follow a general pattern of letter usage. The following are the most common letters, in approximate order of frequency:
- ((PluggableTextMorph new setText: 'Most bodies of english text follow a general pattern of letter usage. The following are the most common letters, in approximate order of frequency:
E T A O N I R S H
The following are the most common digraphs:
EN ER RE NT TH ON IN
+ The message you are trying to decode has the following specific statistics: {1}
- The message you are trying to decode has the following specific statistics:' translated , self cipherStats , '
+ Good luck!!' translated format: {self cipherStats})
+ editWithLabel: 'Some Useful Statistics' translated.!
- Good luck!!' translated)
- embeddedInMorphicWindowLabeled: 'Some Useful Statistics' translated)
- setWindowColor: (Color
- r: 1.0
- g: 0.6
- b: 0.0);
- openInWorld: self world extent: 318 @ 326!
Item was changed:
----- Method: CrosticPanel>>buttonRow (in category 'menu') -----
buttonRow
| row aButton |
row := AlignmentMorph newRow color: self color;
hResizing: #shrinkWrap;
vResizing: #shrinkWrap.
#('show help' 'show errors' 'show hints' 'clear' 'open...' ) translatedNoop
with: #(#showHelpWindow #showErrors #showHintsWindow #clearTyping #openFile )
do: [:label :selector |
aButton := SimpleButtonMorph new target: self.
aButton color: Color transparent;
+ borderWidth: 1 px;
- borderWidth: 1;
borderColor: Color black.
aButton actionSelector: selector.
aButton label: label translated.
row addMorphBack: aButton.
+ row addTransparentSpacerOfSize: 3 px @ 0].
- row addTransparentSpacerOfSize: 3 @ 0].
^ row!
Item was changed:
----- Method: CrosticPanel>>quote:clues:answers:quotePanel: (in category 'initialization') -----
quote: indexableQuote clues: clueStrings answers: answerIndices quotePanel: panel
| row clue answer answerMorph letterMorph prev clueText clueStyle |
quote := indexableQuote.
quotePanel := panel.
clues := clueStrings.
answers := answerIndices.
cluesPanel := AlignmentMorph newColumn color: self color;
hResizing: #shrinkWrap; vResizing: #shrinkWrap;
+ cellPositioning: #topLeft; layoutInset: 1 px.
- cellPositioning: #topLeft; layoutInset: 1.
letterMorphs := Array new: quotePanel letterMorphs size.
clueStyle := nil.
1 to: clues size do:
[:i | clue := clues at: i. answer := answers at: i.
row := AlignmentMorph newRow cellPositioning: #bottomLeft.
+ clueText := (TextMorph newBounds: (0 @ 0 extent: 120 px @ 20 px) color: Color black)
- clueText := (TextMorph newBounds: (0 at 0 extent: 120 at 20) color: Color black)
string: (CrosticPanel oldStyle
ifTrue: [(($A to: $Z) at: i) asString , '. ' , clue]
ifFalse: [clue])
+ fontName: 'ComicPlain' size: 13 px.
- fontName: 'ComicPlain' size: 13.
clueStyle ifNil: ["Make up a special style with decreased leading"
clueStyle := clueText textStyle copy.
clueStyle gridForFont: 1 withLead: -2].
clueText text: clueText asText textStyle: clueStyle. "All clues share same style"
clueText composeToBounds.
row addMorphBack: clueText.
answerMorph := AlignmentMorph newRow layoutInset: 0.
prev := nil.
answer do:
[:n | letterMorph := WordGameLetterMorph new underlined
indexInQuote: n
id1: (CrosticPanel oldStyle ifTrue: [n printString] ifFalse: [nil]);
setLetter: Character space.
letterMorph on: #mouseDown send: #mouseDownEvent:letterMorph: to: self.
letterMorph on: #keyStroke send: #keyStrokeEvent:letterMorph: to: self.
letterMorph predecessor: prev.
prev ifNotNil: [prev successor: letterMorph].
prev := letterMorph.
letterMorphs at: n put: letterMorph.
answerMorph addMorphBack: letterMorph].
answerMorph color: answerMorph firstSubmorph color.
row addMorphBack: answerMorph.
row fullBounds.
row color: answerMorph firstSubmorph color.
cluesPanel addMorphBack: row].
self addMorph: cluesPanel.
+ self bounds: cluesPanel fullBounds.!
- self bounds: cluesPanel fullBounds.
- !
Item was changed:
----- Method: CrosticPanel>>showHelpWindow (in category 'menu') -----
showHelpWindow
- ((PluggableTextMorph new setText: 'The Crostic Panel presents an acrostic puzzle for solution. As you type in answers for the clues, the letters also get entered in the text of the hidden quote. Conversely, as you guess words in the quote, those letters will fill in missing places in your answers. In addition, the first letters of all the answers together form the author''s name and title of the work from which the quote is taken.
+ 'The Crostic Panel presents an acrostic puzzle for solution. As you type in answers for the clues, the letters also get entered in the text of the hidden quote. Conversely, as you guess words in the quote, those letters will fill in missing places in your answers. In addition, the first letters of all the answers together form the author''s name and title of the work from which the quote is taken.
+
If you wish to make up other acrostic puzzles, follow the obvious file format in the sampleFile method. If you wish to print an acrostic to work it on paper, then change the oldStyle method to return true, and it will properly cross-index all the cells.
+ Have fun!!' translated
+ editWithLabel: 'About the Crostic Panel' translated.!
- Have fun.' translated)
- embeddedInMorphicWindowLabeled: 'About the Crostic Panel' translated)
- setWindowColor: (Color
- r: 1.0
- g: 0.6
- b: 0.0);
- openInWorld: self world extent: 409 @ 207!
Item was changed:
----- Method: CrosticPanel>>showHintsWindow (in category 'menu') -----
showHintsWindow
| hints |
(self confirm: 'As hints, you will be given the five longest answers.
Do you really want to do this?' translated)
ifFalse: [^ self].
hints := (answers sorted: [:x :y | x size > y size]) first: 5.
+ (('The five longest answers are...
- ((PluggableTextMorph new setText: 'The five longest answers are...
' translated
, (String
streamContents: [:strm |
hints
do: [:hint | strm cr;
nextPutAll: (hint
collect: [:i | quote at: i])].
+ strm cr; cr]) , 'Good luck!!' translated))
+ editWithLabel: 'Crostic Hints' translated.!
- strm cr; cr]) , 'Good luck!!' translated)
- embeddedInMorphicWindowLabeled: 'Crostic Hints' translated)
- setWindowColor: (Color
- r: 1.0
- g: 0.6
- b: 0.0);
- openInWorld: self world extent: 198 @ 154!
Item was changed:
----- Method: CrosticQuotePanel>>extent: (in category 'geometry') -----
extent: newExtent
| w h nAcross relLoc topLeft |
+ w := self firstSubmorph width - 1 px. h := self firstSubmorph height - 1 px.
+ nAcross := newExtent x - (self borderWidth - 1 px * 2) - 1 px // w.
+ topLeft := self position + self borderWidth - 1 px.
- w := self firstSubmorph width - 1. h := self firstSubmorph height - 1.
- nAcross := newExtent x - (self borderWidth-1*2)-1 // w.
- topLeft := self position + self borderWidth - 1.
submorphs withIndexDo:
[:m :i |
relLoc := (i-1 \\ nAcross * w) @ (i-1 // nAcross * h).
m position: topLeft + relLoc].
super extent: ((w * nAcross + 1) @ (submorphs size - 1 // nAcross + 1 * h+1))
+ + (self borderWidth - 1 px * 2).!
- + (self borderWidth - 1 * 2).
- !
Item was changed:
----- Method: CrosticQuotePanel>>quote:answers:cluesPanel: (in category 'initialization') -----
quote: quoteWithBlanks answers: theAnswers cluesPanel: panel
| n morph prev clueIxs |
cluesPanel := panel.
self color: Color gray.
clueIxs := Array new: quoteWithBlanks size.
theAnswers withIndexDo: [:a :i | a do: [:j | clueIxs at: j put: i]].
letterMorphs := OrderedCollection new.
prev := nil.
self addAllMorphs: (quoteWithBlanks asArray collect:
[:c |
c isLetter
ifTrue: [n := letterMorphs size + 1.
morph := WordGameLetterMorph new boxed.
CrosticPanel oldStyle
ifTrue: [morph indexInQuote: n id1: n printString.
morph id2: (($A to: $Z) at: (clueIxs at: n)) asString]
ifFalse: [morph indexInQuote: n id1: nil].
morph setLetter: Character space.
morph on: #mouseDown send: #mouseDownEvent:letterMorph: to: self.
morph on: #keyStroke send: #keyStrokeEvent:letterMorph: to: self.
letterMorphs addLast: morph]
ifFalse: [morph := WordGameLetterMorph new boxed indexInQuote: nil id1: nil.
+ CrosticPanel oldStyle ifTrue: [morph extent: 26 px @ 24 px "Oops"]].
- CrosticPanel oldStyle ifTrue: [morph extent: 26 at 24 "Oops"]].
morph predecessor: prev.
prev ifNotNil: [prev successor: morph].
+ prev := morph]).!
- prev := morph]).
- !
Item was changed:
----- Method: FileList2 class>>buildFileTypeButtons:actionRow:fileList: (in category '*Etoys-Squeakland-blue ui') -----
buildFileTypeButtons: window actionRow: actionRow fileList: aFileList
| fileTypeInfo fileTypeButtons fileTypeRow aButton |
fileTypeInfo := self endingSpecs.
fileTypeRow := window addARowCentered: #().
fileTypeRow color: ScriptingSystem paneColor.
+ fileTypeRow layoutInset: 3 px @ 3 px.
+ fileTypeRow cellInset: 2 px @ 0 px.
- fileTypeRow layoutInset: 3 @ 3.
- fileTypeRow cellInset: 2 @ 0.
fileTypeRow hResizing: #spaceFill.
fileTypeButtons := fileTypeInfo
collect: [:each |
aButton := self
buildButtonText: each first
balloonText: nil
receiver: aFileList
selector: #update:fileTypeRow:morphUp:.
aButton arguments: {actionRow. fileTypeRow. aButton}.
aButton setProperty: #enabled toValue: true.
aButton setProperty: #buttonText toValue: each first.
aButton].
fileTypeRow addAllMorphs: fileTypeButtons.
aFileList directoryChangeBlock: [:newDir | self
enableTypeButtons: fileTypeButtons
info: fileTypeInfo
+ forDir: newDir].!
- forDir: newDir].
- !
Item was changed:
----- Method: FileList2 class>>buildLoadButtons:fileList:reallyLoad: (in category '*Etoys-Squeakland-blue ui') -----
buildLoadButtons: window fileList: aFileList reallyLoad: aBoolean
| aRow okButton cancelButton |
okButton := self
buildButtonText: 'OK' translated
balloonText: nil
receiver: aFileList
selector: (aBoolean
ifTrue: [#okHitForProjectLoader]
ifFalse: [#okHit]).
+ okButton width: 150 px.
- okButton width: 150.
cancelButton := self
buildButtonText: 'Cancel' translated
balloonText: nil
receiver: aFileList
selector: #cancelHit.
+ cancelButton width: 150 px.
- cancelButton width: 150.
"aFileList updateLoginButtonAppearance."
aRow := window addARow: {aFileList loginButton. aFileList loginField. okButton. cancelButton}.
aRow color: ScriptingSystem paneColor.
aRow listCentering: #bottomRight.
+ aRow layoutInset: 3 px @ 3 px.
+ aRow cellInset: 6 px @ 3 px.
- aRow layoutInset: 3 @ 3.
- aRow cellInset: 6 @ 3.
^ aRow!
Item was changed:
----- Method: FileList2 class>>buildPane:fileList:window:dirFilterType: (in category '*Etoys-Squeakland-blue ui') -----
buildPane: aWorld fileList: aFileList window: window dirFilterType: aSymbol
| treeExtent filesExtent treePane fileListPane pane2a pane2b aRow |
+ aWorld width < 800 px
+ ifTrue: [treeExtent := 150 px @ 300 px.
+ filesExtent := 350 px @ 300 px]
+ ifFalse: [treeExtent := 250 px @ 300 px.
+ filesExtent := 350 px @ 300 px].
- aWorld width < 800
- ifTrue: [treeExtent := 150 @ 300.
- filesExtent := 350 @ 300]
- ifFalse: [treeExtent := 250 @ 300.
- filesExtent := 350 @ 300].
(treePane := aFileList morphicDirectoryTreePaneFiltered: aSymbol) extent: treeExtent;
retractable: false;
borderWidth: 0.
fileListPane := aFileList morphicFileListPane extent: filesExtent;
retractable: false;
borderWidth: 0.
+ aRow := window addARow: {(window inAColumn: {(pane2a := window inARow: {window inAColumn: {treePane}}) useRoundedCornersInEtoys; layoutInset: 3 px})
+ layoutInset: 3 px. (window inAColumn: {(pane2b := window inARow: {window inAColumn: {fileListPane}}) useRoundedCornersInEtoys; layoutInset: 3 px})
+ layoutInset: 3 px}.
- aRow := window addARow: {(window inAColumn: {(pane2a := window inARow: {window inAColumn: {treePane}}) useRoundedCornersInEtoys; layoutInset: 3})
- layoutInset: 3. (window inAColumn: {(pane2b := window inARow: {window inAColumn: {fileListPane}}) useRoundedCornersInEtoys; layoutInset: 3})
- layoutInset: 3}.
aRow color: ScriptingSystem paneColor.
window fullBounds.
{pane2a. pane2b}
do: [:each |
+ each borderWidth: 1 px.
- each borderWidth: 1.
each borderColor: ScriptingSystem borderColor].
^ treePane.!
Item was changed:
----- Method: FileList2 class>>buildSaveButtons:fileList: (in category '*Etoys-Squeakland-blue ui') -----
buildSaveButtons: window fileList: aFileList
| buttonData buttons aRow |
buttonData := Preferences enableLocalSave
ifTrue: [#(#('Save' #okHit 'Save in the place specified above')
#('Save on local disk only' #saveLocalOnlyHit 'saves in the Squeaklets folder')
#('Cancel' #cancelHit 'return without saving') ) translatedNoop]
ifFalse: [#(#('Save' #okHit 'Save in the place specified above')
#('Cancel' #cancelHit 'return without saving') ) translatedNoop].
buttons := buttonData
collect: [:each | self
buildButtonText: each first translated
balloonText: each third translated
receiver: aFileList
selector: each second].
aFileList updateLoginButtonAppearance.
buttons := {aFileList loginButton. aFileList loginField. Morph new color: Color transparent; width: 50}, buttons.
aRow := window addARow: buttons.
aRow color: ScriptingSystem paneColor.
aRow listCentering: #bottomRight.
+ aRow layoutInset: 3 px @ 3 px.
+ aRow cellInset: 6 px @ 3 px.
- aRow layoutInset: 3 @ 3.
- aRow cellInset: 6 @ 3.
^ aRow!
Item was changed:
----- Method: FileList2 class>>fontForBlueFileListButtons (in category '*Etoys-Squeakland-blue ui') -----
fontForBlueFileListButtons
"Answer the font to use in the buttons of the blue file-list dialogs used by olpc users of etoys."
+ ^ Preferences standardButtonFont!
- ^ Preferences standardEToysFont!
Item was changed:
----- Method: FileList2>>updateLoginButtonAppearance (in category '*Etoys-Squeakland-private') -----
updateLoginButtonAppearance
| old oldField notLoggedInMessage |
notLoggedInMessage := '(not logged in)' translated.
old := self loginButton.
oldField := self loginField.
self loginField: (Morph new color: Color white).
+ self loginField borderWidth: 2 px.
- self loginField borderWidth: 2.
self loginField borderColor: ScriptingSystem baseColor.
self loginField beSticky.
+ self loginField width: 150 px.
+ self loginField height: 30 px.
- self loginField width: 150.
- self loginField height: 30.
self loginField clipSubmorphs: true.
EtoysUtilities loggedIn ifTrue: [
self loginButton: (self class
buildButtonText: 'Logout' translated
balloonText: nil
receiver: self
selector: #logoutHit).
self loginButton color: ScriptingSystem baseColor.
self loginField addMorphCentered: (StringMorph contents: (Utilities authorNamePerSe ifNil: [notLoggedInMessage]) font: Preferences standardEToysButtonFont).
self loginButton setBalloonText: 'Log out from the Squeakland server' translated.
self loginField setBalloonText: 'Your Squeakland user name' translated.
]
ifFalse: [
self loginButton: (self class
buildButtonText: 'Login' translated
balloonText: nil
receiver: self
selector: #loginHit).
self loginButton color: ScriptingSystem baseColor.
self loginField addMorphCentered: (StringMorph contents: notLoggedInMessage font: Preferences standardEToysButtonFont).
self loginButton setBalloonText: 'Log in to share projects on the Squeakland server' translated.
self loginField setBalloonText: 'Your Squeakland user name' translated
].
self loginButton setNamePropertyTo: 'login'.
+ self loginButton width: 150 px.
- self loginButton width: 150.
old ifNotNil: [
old owner addMorph: self loginButton inFrontOf: old.
old delete].
oldField ifNotNil: [
oldField owner addMorph: self loginField inFrontOf: oldField.
+ oldField delete].!
- oldField delete].
- !
Item was changed:
----- Method: FreeCell>>buildButton:target:label:selector: (in category 'private') -----
buildButton: aButton target: aTarget label: aLabel selector: aSelector
"wrap a button or switch in an alignmentMorph to provide some space around the button"
| a |
aButton
target: aTarget;
label: aLabel;
actionSelector: aSelector;
+ borderStyle: (BorderStyle raised width: 2 px);
- borderStyle: (BorderStyle raised width: 2);
color: Color gray.
a := AlignmentMorph newColumn
wrapCentering: #center; cellPositioning: #topCenter;
hResizing: #shrinkWrap;
vResizing: #shrinkWrap;
color: Color transparent;
+ layoutInset: 1 px.
- layoutInset: 1.
a addMorph: aButton.
+ ^ a!
- ^ a
-
- !
Item was changed:
----- Method: FreeCell>>defaultBorderWidth (in category 'initialization') -----
defaultBorderWidth
"answer the default border width for the receiver"
+ ^ 2 px!
- ^ 2!
Item was changed:
----- Method: FreeCell>>makeCardsRemainingDisplay (in category 'initialization') -----
makeCardsRemainingDisplay
cardsRemainingDisplay := LedMorph new digits: 2;
+ extent: 10 px * 2 @ 15 px.
- extent: 2 * 10 @ 15.
^ self wrapPanel: cardsRemainingDisplay label: 'Cards Left: ' translated!
Item was changed:
----- Method: FreeCell>>makeControlBar (in category 'initialization') -----
makeControlBar
^AlignmentMorph newRow
color: self colorNearBottom;
+ borderStyle: (BorderStyle inset width: 2 px);
- borderStyle: (BorderStyle inset width: 2);
layoutInset: 0;
hResizing: #spaceFill; vResizing: #shrinkWrap; wrapCentering: #center; cellPositioning: #leftCenter;
yourself.!
Item was changed:
----- Method: FreeCell>>makeControls (in category 'initialization') -----
makeControls
^self makeControlBar
addMorph: AlignmentMorph newVariableTransparentSpacer;
+ addMorph: self makeUndoButton;
addMorph: self makeHelpButton;
addMorph: self makeQuitButton;
addMorph: self makeStatisticsButton;
addMorph: self makeGameNumberDisplay;
addMorph: self makePickGameButton;
addMorph: self makeSameGameButton;
addMorph: self makeNewGameButton;
addMorph: self makeElapsedTimeDisplay;
addMorph: self makeCardsRemainingDisplay;
yourself.!
Item was changed:
----- Method: FreeCell>>makeElapsedTimeDisplay (in category 'initialization') -----
makeElapsedTimeDisplay
elapsedTimeDisplay := LedTimerMorph new digits: 3;
+ extent: 10 px * 3 @ 15 px.
- extent: 3 * 10 @ 15.
^ self wrapPanel: elapsedTimeDisplay label: 'Elapsed Time: ' translated!
Item was changed:
----- Method: FreeCell>>makeGameNumberDisplay (in category 'initialization') -----
makeGameNumberDisplay
gameNumberDisplay := LedMorph new digits: 5;
+ extent: 10 px * 5 @ 15 px.
- extent: 5 * 10 @ 15.
^ self wrapPanel: gameNumberDisplay label: 'Game #: ' translated!
Item was added:
+ ----- Method: FreeCell>>makeUndoButton (in category 'initialization') -----
+ makeUndoButton
+ ^ self
+ buildButton: SimpleButtonMorph new
+ target: self
+ label: 'Undo' translated
+ selector: #undo!
Item was added:
+ ----- Method: FreeCell>>undo (in category 'actions') -----
+ undo
+
+ ^ self commandHistory undoOrRedoCommand!
Item was changed:
----- Method: FreeCell>>wrapPanel:label: (in category 'private') -----
wrapPanel: anLedPanel label: aLabel
"wrap an LED panel in an alignmentMorph with a label to its left"
| a |
a := AlignmentMorph newRow
wrapCentering: #center; cellPositioning: #leftCenter;
hResizing: #shrinkWrap;
vResizing: #shrinkWrap;
borderWidth: 0;
+ layoutInset: 5 px;
- layoutInset: 5;
color: Color transparent.
a addMorph: anLedPanel.
a addMorph: (StringMorph contents: aLabel).
+ ^ a!
- ^ a
- !
Item was changed:
----- Method: FreeCellBoard>>cardCell (in category 'layout') -----
cardCell
^PlayingCardDeck new
layout: #pile;
listDirection: #topToBottom;
enableDragNDrop;
color: Color transparent;
borderColor: (Color gray alpha: 0.5);
+ borderWidth: 2 px;
- borderWidth: 2;
layoutBounds: (0 at 0 extent: PlayingCardMorph width @ PlayingCardMorph height);
yourself!
Item was changed:
----- Method: FreeCellBoard>>initialize (in category 'initialization') -----
initialize
"initialize the state of the receiver"
super initialize.
""
self listDirection: #topToBottom;
hResizing: #shrinkWrap;
vResizing: #rigid;
+ height: 500 px;
- height: 500;
layout!
Item was changed:
----- Method: FreeCellStatistics>>buildButton:target:label:selector: (in category 'user interface') -----
buildButton: aButton target: aTarget label: aLabel selector: aSelector
"wrap a button or switch in an alignmentMorph to provide some space around the button"
| a |
aButton
target: aTarget;
label: aLabel;
actionSelector: aSelector;
+ borderStyle: (BorderStyle raised width: 2 px);
- borderStyle: (BorderStyle raised width: 2);
color: Color gray.
a := AlignmentMorph newColumn
wrapCentering: #center; cellPositioning: #topCenter;
hResizing: #spaceFill;
vResizing: #shrinkWrap;
color: Color transparent;
+ layoutInset: 1 px.
- layoutInset: 1.
a addMorph: aButton.
+ ^ a!
- ^ a
-
- !
Item was changed:
----- Method: FreeCellStatistics>>display (in category 'user interface') -----
display
| panel |
(window notNil and: [window owner notNil]) ifTrue: [window activate. ^nil].
panel := AlignmentMorph newColumn.
panel
wrapCentering: #center; cellPositioning: #topCenter;
hResizing: #rigid;
vResizing: #rigid;
+ extent: 250 px @ 150 px;
- extent: 250 at 150;
color: self color;
addMorphBack: self makeStatistics;
addMorphBack: self makeControls.
window := panel openInWindowLabeled: 'FreeCell Statistics' translated.!
Item was changed:
----- Method: FreeCellStatistics>>makeControls (in category 'user interface') -----
makeControls
| row |
row := AlignmentMorph newRow.
row
wrapCentering: #center; cellPositioning: #leftCenter;
hResizing: #spaceFill;
vResizing: #shrinkWrap;
color: self color;
+ borderStyle: (BorderStyle inset width: 2 px);
- borderStyle: (BorderStyle inset width: 2);
addMorphBack: self makeOkButton;
addMorphBack: self makeResetButton.
^row.!
Item was changed:
----- Method: FreeCellStatistics>>makeStatistics (in category 'user interface') -----
makeStatistics
| row |
row := AlignmentMorph newRow.
row
wrapCentering: #center; cellPositioning: #leftCenter;
hResizing: #spaceFill;
vResizing: #spaceFill;
color: self color;
+ borderStyle: (BorderStyle inset width: 2 px);
- borderStyle: (BorderStyle inset width: 2);
addMorphBack: (AlignmentMorph newColumn
wrapCentering: #center; cellPositioning: #topCenter;
color: self color;
addMorph: (statsMorph := TextMorph new contents: self statsText)).
^row.!
Item was changed:
----- Method: MidiInputMorph>>addChannelControlsFor: (in category 'accessing') -----
addChannelControlsFor: channelIndex
| r divider col |
r := self makeRow
hResizing: #shrinkWrap;
vResizing: #shrinkWrap.
r addMorphBack: (self channelNumAndMuteButtonFor: channelIndex).
+ r addMorphBack: (Morph new extent: 10 px @ 5 px; color: color). "spacer"
- r addMorphBack: (Morph new extent: 10 at 5; color: color). "spacer"
r addMorphBack: (self panAndVolControlsFor: channelIndex).
divider := AlignmentMorph new
+ extent: 10 px @ 1 px;
- extent: 10 at 1;
layoutInset: 0;
+ borderStyle: (BorderStyle raised width: 1 px);
- borderStyle: (BorderStyle raised width: 1);
color: color;
hResizing: #spaceFill;
vResizing: #rigid.
col := self lastSubmorph.
col addMorphBack: divider.
+ col addMorphBack: r.!
- col addMorphBack: r.
- !
Item was changed:
----- Method: MidiInputMorph>>channelNumAndMuteButtonFor: (in category 'accessing') -----
channelNumAndMuteButtonFor: channelIndex
| muteButton instSelector r |
muteButton := SimpleSwitchMorph new
onColor: (Color r: 1.0 g: 0.6 b: 0.6);
offColor: color;
color: color;
label: 'Mute' translated;
target: midiSynth;
actionSelector: #mutedForChannel:put:;
arguments: (Array with: channelIndex).
+ instSelector := DropDownChoiceMorph new
+ extent: 120 px @ 18 px;
- instSelector := PopUpChoiceMorph new
- extent: 95 at 14;
contentsClipped: 'oboe1';
target: self;
actionSelector: #atChannel:from:selectInstrument:;
getItemsSelector: #instrumentChoicesForChannel:;
getItemsArgs: (Array with: channelIndex).
instSelector arguments:
(Array with: channelIndex with: instSelector).
instrumentSelector at: channelIndex put: instSelector.
r := self makeRow
+ hResizing: #spaceFill;
- hResizing: #rigid;
vResizing: #spaceFill;
+ extent: 70 px @ 10 px.
- extent: 70 at 10.
r addMorphBack:
(StringMorph
contents: channelIndex printString
+ font: (TextStyle defaultFont asPointSize: TextStyle defaultFont pointSize * 1.57)).
- font: (TextStyle default fontOfSize: 24)).
channelIndex < 10
+ ifTrue: [r addMorphBack: (Morph new color: color; extent: 19 px @ 8 px)] "spacer"
+ ifFalse: [r addMorphBack: (Morph new color: color; extent: 8 px @ 8 px)]. "spacer"
- ifTrue: [r addMorphBack: (Morph new color: color; extent: 19 at 8)] "spacer"
- ifFalse: [r addMorphBack: (Morph new color: color; extent: 8 at 8)]. "spacer"
r addMorphBack: instSelector.
r addMorphBack: (AlignmentMorph newRow color: color). "spacer"
r addMorphBack: muteButton.
^ r!
Item was changed:
----- Method: MidiInputMorph>>defaultBorderWidth (in category 'initialization') -----
defaultBorderWidth
"answer the default border width for the receiver"
+ ^ 2 px!
- ^ 2!
Item was changed:
----- Method: MidiInputMorph>>initialize (in category 'initialization') -----
initialize
"initialize the state of the receiver"
super initialize.
""
self listDirection: #topToBottom;
wrapCentering: #center;
cellPositioning: #topCenter;
+ hResizing: #shrinkWrap;
+ vResizing: #shrinkWrap;
+ layoutInset: 3 px.
- hResizing: #spaceFill;
- vResizing: #spaceFill;
- layoutInset: 3.
midiPortNumber := nil.
midiSynth := MIDISynth new.
instrumentSelector := Array new: 16.
self removeAllMorphs.
self addMorphBack: self makeControls.
self addMorphBack: (AlignmentMorph newColumn color: color;
layoutInset: 0).
self addChannelControlsFor: 1.
+ self extent: 20 px @ 20 px!
- self extent: 20 @ 20!
Item was changed:
----- Method: MidiInputMorph>>makeControls (in category 'initialization') -----
makeControls
| bb r reverbSwitch onOffSwitch |
bb := SimpleButtonMorph new
target: self;
+ borderStyle: (BorderStyle raised width: 2 px);
- borderStyle: (BorderStyle raised width: 2);
color: color.
r := AlignmentMorph newRow.
r color: bb color; borderWidth: 0; layoutInset: 0.
+ r hResizing: #shrinkWrap; vResizing: #shrinkWrap; extent: 5 px @ 5 px.
- r hResizing: #shrinkWrap; vResizing: #shrinkWrap; extent: 5 at 5.
r addMorphBack: (
bb label: '<>';
actWhen: #buttonDown;
actionSelector: #invokeMenu).
onOffSwitch := SimpleSwitchMorph new
offColor: color;
onColor: (Color r: 1.0 g: 0.6 b: 0.6);
+ borderWidth: 2 px;
- borderWidth: 2;
label: 'On' translated;
actionSelector: #toggleOnOff;
target: self;
setSwitchState: false.
r addMorphBack: onOffSwitch.
reverbSwitch := SimpleSwitchMorph new
offColor: color;
onColor: (Color r: 1.0 g: 0.6 b: 0.6);
+ borderWidth: 2 px;
- borderWidth: 2;
label: 'Reverb Disable' translated;
actionSelector: #disableReverb:;
target: self;
setSwitchState: SoundPlayer isReverbOn not.
r addMorphBack: reverbSwitch.
^ r!
Item was changed:
----- Method: MidiInputMorph>>panAndVolControlsFor: (in category 'initialization') -----
panAndVolControlsFor: channelIndex
| volSlider panSlider c r middleLine |
volSlider := SimpleSliderMorph new
color: color;
+ extent: 101 px @ 6 px;
+ minWidth: 101 px;
- extent: 101 at 2;
target: midiSynth;
arguments: (Array with: channelIndex);
+ orientation: #horizontal;
actionSelector: #volumeForChannel:put:;
minVal: 0.0;
maxVal: 1.0;
adjustToValue: (midiSynth volumeForChannel: channelIndex).
panSlider := SimpleSliderMorph new
color: color;
+ extent: 101 px @ 6 px;
+ minWidth: 101 px;
- extent: 101 at 2;
target: midiSynth;
arguments: (Array with: channelIndex);
actionSelector: #panForChannel:put:;
minVal: 0.0;
maxVal: 1.0;
adjustToValue: (midiSynth panForChannel: channelIndex).
c := AlignmentMorph newColumn
color: color;
layoutInset: 0;
wrapCentering: #center; cellPositioning: #topCenter;
hResizing: #spaceFill;
vResizing: #shrinkWrap.
middleLine := Morph new "center indicator for pan slider"
color: (Color r: 0.4 g: 0.4 b: 0.4);
+ extent: 1 px @ (panSlider height - 4 px);
+ position: panSlider center x @ (panSlider top + 2 px).
- extent: 1@(panSlider height - 4);
- position: panSlider center x@(panSlider top + 2).
panSlider addMorphBack: middleLine.
r := self makeRow.
r addMorphBack: (StringMorph contents: '0').
r addMorphBack: volSlider.
r addMorphBack: (StringMorph contents: '10').
c addMorphBack: r.
r := self makeRow.
r addMorphBack: (StringMorph contents: 'L').
r addMorphBack: panSlider.
r addMorphBack: (StringMorph contents: 'R').
c addMorphBack: r.
+ ^ c!
- ^ c
- !
Item was changed:
----- Method: MidiInputMorph>>setMIDIPort (in category 'accessing') -----
setMIDIPort
| portNum |
+ portNum := SimpleMIDIPort inputPortNumFromUser.
- portNum := SimpleMIDIPort outputPortNumFromUser.
portNum ifNil: [^ self].
midiPortNumber := portNum.
!
Item was changed:
----- Method: Mines>>defaultBorderWidth (in category 'initialization') -----
defaultBorderWidth
"answer the default border width for the receiver"
+ ^ 2 px!
- ^ 2!
Item was changed:
----- Method: Mines>>initialize (in category 'initialization') -----
initialize
"initialize the state of the receiver"
super initialize.
level := 1.
self listDirection: #topToBottom;
wrapCentering: #center;
cellPositioning: #topCenter;
vResizing: #shrinkWrap;
hResizing: #shrinkWrap;
+ layoutInset: 3 px;
- layoutInset: 3;
addMorph: self makeControls;
addMorph: self board.
helpText := nil.
self newGame!
Item was changed:
----- Method: Mines>>makeControls (in category 'initialize') -----
makeControls
| row |
row := AlignmentMorph newRow color: color;
+ borderWidth: 2 px;
+ layoutInset: 3 px.
- borderWidth: 2;
- layoutInset: 3.
row borderStyle: BorderStyle inset.
row hResizing: #spaceFill;
vResizing: #shrinkWrap;
wrapCentering: #center;
cellPositioning: #leftCenter;
+ extent: 5 px @ 5 px.
- extent: 5 @ 5.
row
addMorph: (self
buildButton: SimpleSwitchMorph new
target: self
label: ' Help ' translated
selector: #help:).
row
addMorph: (self
buildButton: (levelButton := SimpleButtonMorph new)
target: self
label: level asString translated
selector: #nextLevel).
row
addMorph: (self
buildButton: SimpleButtonMorph new
target: self
label: ' Quit ' translated
selector: #delete).
"row
addMorph: (self
buildButton: SimpleButtonMorph new
target: self
label: ' Hint ' translated
selector: #hint)."
row
addMorph: (self
buildButton: SimpleButtonMorph new
target: self
label: ' New game ' translated
selector: #newGame).
minesDisplay := LedMorph new digits: 2;
+ extent: 2 * 10 px @ 15 px.
- extent: 2 * 10 @ 15.
row
addMorph: (self wrapPanel: minesDisplay label: 'Mines:' translated).
+ timeDisplay := LedTimerMorph new digits: 3; extent: 3 * 10 px @ 15 px.
- timeDisplay := LedTimerMorph new digits: 3; extent: 3 * 10 @ 15.
row
addMorph: (self wrapPanel: timeDisplay label: 'Time:' translated).
+ hiScoreDisplay := LedMorph new digits: 3; extent: 3 * 10 px@ 15 px.
- hiScoreDisplay := LedMorph new digits: 3; extent: 3 * 10 @ 15.
row
addMorph: (self wrapPanel: hiScoreDisplay label: 'Hi Score:' translated).
^ row!
Item was changed:
----- Method: Mines>>wrapPanel:label: (in category 'initialize') -----
wrapPanel: anLedPanel label: aLabel
"wrap an LED panel in an alignmentMorph with a label to its left"
| a |
a := AlignmentMorph newRow
wrapCentering: #center; cellPositioning: #leftCenter;
hResizing: #shrinkWrap;
vResizing: #shrinkWrap;
borderWidth: 0;
+ layoutInset: 3 px;
- layoutInset: 3;
color: color lighter.
a addMorph: anLedPanel.
a addMorph: (StringMorph contents: aLabel).
^ a
!
Item was changed:
----- Method: MinesBoard>>defaultBorderWidth (in category 'initialization') -----
defaultBorderWidth
"answer the default border width for the receiver"
+ ^ 2 px!
- ^ 2!
Item was changed:
----- Method: MinesTile>>drawOn: (in category 'drawing') -----
drawOn: aCanvas
"Draw a rectangle with a solid, inset, or raised border.
Note: the raised border color *and* the inset border color are generated
from the receiver's own color, instead of having the inset border color
generated from the owner's color, as in BorderedMorph."
| font rct |
super drawOn: aCanvas.
self borderStyle style == #inset ifTrue: [
self isMine ifTrue: [
+ font := StrikeFont familyName: 'Atlanta' size: 22 px emphasized: 1.
+ rct := self bounds insetBy: ((self bounds width) - (font widthOfString: '*'))/2 @0.
- font := StrikeFont familyName: 'Atlanta' size: 22 emphasized: 1.
- rct := self bounds insetBy: ((self bounds width) - (font widthOfString: '*'))/2 at 0.
rct := rct top: rct top + 1.
aCanvas drawString: '*' in: (rct translateBy: 1 at 1) font: font color: Color black.
^ aCanvas drawString: '*' in: rct font: font color: Color red .].
self nearMines > 0 ifTrue: [
+ font := StrikeFont familyName: 'ComicBold' size: 22 px emphasized: 1.
+ rct := self bounds insetBy: ((self bounds width) - (font widthOfString: nearMines asString))/2 @0.
- font := StrikeFont familyName: 'ComicBold' size: 22 emphasized: 1.
- rct := self bounds insetBy: ((self bounds width) - (font widthOfString: nearMines asString))/2 at 0.
rct := rct top: rct top + 1.
aCanvas drawString: nearMines asString in: (rct translateBy: 1 at 1) font: font color: Color black.
^ aCanvas drawString: nearMines asString in: rct font: font color: ((palette at: nearMines) ) .]].!
Item was changed:
----- Method: MinesTile>>initialize (in category 'initialization') -----
initialize
super initialize.
self label: ''.
+ self borderWidth: 3 px.
+ bounds := 0 at 0 corner: 20 px at 20 px.
- self borderWidth: 3.
- bounds := 0 at 0 corner: 20 at 20.
offColor := self preferredColor.
onColor := self preferredColor.
switchState := false.
oldSwitchState := false.
disabled := false.
isMine := false.
nearMines := 0.
self useSquareCorners.
palette := (Color wheel: 8) asOrderedCollection reverse.
" flashColor := palette removeLast."
!
Item was changed:
----- Method: Morph>>assuredCardPlayer (in category '*Etoys-card in a stack') -----
assuredCardPlayer
"Answer the receiver's player, creating a new one if none currently exists"
| aPlayer |
(aPlayer := self player) ifNotNil: [
(aPlayer isKindOf: CardPlayer)
+ ifTrue: [aPlayer]
- ifTrue: [^ aPlayer]
ifFalse: [self error: 'Must convert to a CardPlayer']
"later convert using as: and remove the error"].
self assureExternalName. "a default may be given if not named yet"
+ self player: CardPlayer newUserInstance.
- self player: (aPlayer := UnscriptedPlayer newUserInstance).
"Force it to be a CardPlayer. Morph class no longer dictates what kind of player"
+ self player costume: self.
- aPlayer costume: self.
self presenter ifNotNil: [self presenter flushPlayerListCache].
+ ^ self player!
- ^ aPlayer!
Item was changed:
----- Method: Morph>>reassessBackgroundShape (in category '*Etoys-card in a stack') -----
reassessBackgroundShape
"A change has been made which may affect the instance structure of the Card uniclass that holds the instance state, which can also be thought of as the 'card data'."
- "Caution: still to be done: the mechanism so that when a new instance variable is added, it gets initialized in all subinstances of the receiver's player, which are the cards of this shape. One needs to take into account here the instance variable names coming in; those that are unchanged should keep their values, but those that have newly arrived should obtain their default values from the morphs on whose behalf they are being maintained in the model"
-
| requestedName |
self isStackBackground ifFalse: [^Beeper beep]. "bulletproof against deconstruction"
Cursor wait showWhile:
[ | variableDocks takenNames sepDataMorphs existing |variableDocks := OrderedCollection new. "This will be stored in the uniclass's
class-side inst var #variableDocks"
takenNames := OrderedCollection new.
sepDataMorphs := OrderedCollection new. "fields, holders of per-card data"
self submorphs do:
[:aMorph |
aMorph renderedMorph holdsSeparateDataForEachInstance
ifTrue: [sepDataMorphs add: aMorph renderedMorph]
ifFalse:
["look for buried fields, inside a frame"
aMorph renderedMorph isShared
ifTrue:
[aMorph allMorphs do:
[:mm |
mm renderedMorph holdsSeparateDataForEachInstance
ifTrue: [sepDataMorphs add: mm renderedMorph]]]]].
sepDataMorphs
sort: [:a :b | (a valueOfProperty: #cardInstance) notNil]; "puts existing ones first"
do:
[:aMorph | | docks |
docks := aMorph variableDocks.
"Each morph can request multiple variables.
This complicates matters somewhat but creates a generality for Fabrk-like uses.
Each spec is an instance of VariableDock, and it provides a point of departure
for the negotiation between the PasteUp and its constitutent morphs"
docks do:
[:aVariableDock | | uniqueName |
uniqueName := self player
uniqueInstanceVariableNameLike: (requestedName := aVariableDock
variableName)
excluding: takenNames.
uniqueName ~= requestedName
ifTrue:
[aVariableDock variableName: uniqueName.
aMorph noteNegotiatedName: uniqueName for: requestedName].
takenNames add: uniqueName].
variableDocks addAll: docks].
existing := self player class instVarNames.
variableDocks sort:
[:dock1 :dock2 | | name2 name1 |
name1 := dock1 variableName.
name2 := dock2 variableName.
(existing indexOf: name1)
< (existing indexOf: name2 ifAbsent: [variableDocks size])].
self player class setNewInstVarNames: (variableDocks
collect: [:info | info variableName asString]).
"NB: sets up accessors, and removes obsolete ones"
self player class newVariableDocks: variableDocks]!
Item was changed:
----- Method: ObjectsTool>>initializeForFlap: (in category '*Etoys-Squeakland-initialization') -----
initializeForFlap: forStartup
| buttonPane aBin aColor heights tabsPane |
forStartup ifTrue: [
self basicInitialize.
self layoutInset: 0;
layoutPolicy: ProportionalLayout new;
hResizing: #shrinkWrap;
vResizing: #rigid;
+ borderWidth: 2 px; borderColor: Color darkGray;
- borderWidth: 2; borderColor: Color darkGray;
extent: (self minimumWidth @ self minimumHeight).
].
"mode buttons"
buttonPane := self paneForTabs: self modeTabs.
buttonPane
vResizing: #shrinkWrap;
setNameTo: 'ButtonPane';
color: (aColor := buttonPane color) darker;
+ layoutInset: 6 px;
- layoutInset: 6;
wrapDirection: nil;
width: self width;
layoutChanged; fullBounds.
"Place holder for a tabs or text pane"
tabsPane := Morph new
setNameTo: 'TabPane';
hResizing: #spaceFill;
yourself.
+ heights := { buttonPane height. 40 px }.
- heights := { buttonPane height. 40 }.
buttonPane vResizing: #spaceFill.
self
addMorph: buttonPane
fullFrame: (LayoutFrame
fractions: (0 @ 0 corner: 1 @ 0)
offsets: (0 @ 0 corner: 0 @ heights first)).
self
addMorph: tabsPane
fullFrame: (LayoutFrame
fractions: (0 @ 0 corner: 1 @ 0)
offsets: (0 @ heights first corner: 0 @ (heights first + heights second))).
aBin := (PartsBin newPartsBinWithOrientation: #leftToRight from: #())
listDirection: #leftToRight;
wrapDirection: #topToBottom;
color: aColor lighter lighter;
setNameTo: 'Parts';
dropEnabled: false;
vResizing: #spaceFill;
yourself.
self
addMorph: aBin
fullFrame: (LayoutFrame
fractions: (0 @ 0 corner: 1 @ 1)
offsets: (0 @ (heights first + heights second) corner: 0 @ 0)).
aBin color: (Color orange muchLighter);
setNameTo: 'Objects' translated.
self color: (Color orange muchLighter);
+ setNameTo: 'Objects' translated.!
- setNameTo: 'Objects' translated.
- !
Item was changed:
----- Method: ObjectsTool>>initializeToStandAlone: (in category '*Etoys-Squeakland-initialization') -----
initializeToStandAlone: forStartup
| buttonPane aBin aColor heights tabsPane |
forStartup ifTrue: [
self basicInitialize.
+ self layoutInset: 6 px;
- self layoutInset: 6;
layoutPolicy: ProportionalLayout new;
useRoundedCorners;
hResizing: #rigid;
vResizing: #rigid;
extent: (self minimumWidth @ self minimumHeight).
].
"mode buttons"
buttonPane := self paneForTabs: self modeTabs.
buttonPane
vResizing: #shrinkWrap;
setNameTo: 'ButtonPane';
addMorphFront: self dismissButton;
addMorphBack: self helpButton;
color: (aColor := buttonPane color) darker;
+ layoutInset: 6 px;
- layoutInset: 6;
wrapDirection: nil;
width: self width;
layoutChanged; fullBounds.
"Place holder for a tabs or text pane"
tabsPane := Morph new
setNameTo: 'TabPane';
hResizing: #spaceFill;
yourself.
+ heights := { buttonPane height. 40 px }.
- heights := { buttonPane height. 40 }.
buttonPane vResizing: #spaceFill.
self
addMorph: buttonPane
fullFrame: (LayoutFrame
fractions: (0 @ 0 corner: 1 @ 0)
offsets: (0 @ 0 corner: 0 @ heights first)).
self
addMorph: tabsPane
fullFrame: (LayoutFrame
fractions: (0 @ 0 corner: 1 @ 0)
offsets: (0 @ heights first corner: 0 @ (heights first + heights second))).
aBin := (PartsBin newPartsBinWithOrientation: #leftToRight from: #())
listDirection: #leftToRight;
wrapDirection: #topToBottom;
color: aColor lighter lighter;
setNameTo: 'Parts';
dropEnabled: false;
vResizing: #spaceFill;
yourself.
self
addMorph: aBin
fullFrame: (LayoutFrame
fractions: (0 @ 0 corner: 1 @ 1)
offsets: (0 @ (heights first + heights second) corner: 0 @ 0)).
self color: (Color r: 0.0 g: 0.839 b: 0.226);
setNameTo: 'Objects' translated.
forStartup ifTrue: [
self showCategories.
]!
Item was changed:
----- Method: PartsBin>>listDirection:quadList:withPreviousEntries: (in category '*Etoys-Squeakland-initialization') -----
listDirection: aListDirection quadList: quadList withPreviousEntries: aCollection
"Initialize the receiver to run horizontally or vertically, obtaining its elements from the list of tuples of the form:
(<receiver> <selector> <label> <balloonHelp>)"
| aButton aClass oldDict |
self layoutPolicy: TableLayout new.
self listDirection: aListDirection.
self wrapCentering: #topLeft.
+ self layoutInset: 2 px.
- self layoutInset: 2.
self cellPositioning: #bottomCenter.
oldDict := Dictionary new.
aCollection ifNotNil: [
aCollection do: [:e | oldDict at: e target put: e]
].
aListDirection == #leftToRight
ifTrue:
[self vResizing: #rigid.
self hResizing: #spaceFill.
self wrapDirection: #topToBottom]
ifFalse:
[self hResizing: #rigid.
self vResizing: #spaceFill.
self wrapDirection: #leftToRight].
quadList do:
[:tuple |
aClass := Smalltalk at: tuple first.
aButton := oldDict at: aClass ifAbsent: [].
(aButton isNil or: [#(TextMorph ScriptableButton) includes: aClass name]) ifTrue: [
aButton := IconicButtonWithLabel new initializeWithThumbnail: (self class thumbnailForQuad: tuple color: self color) withLabel: tuple third andColor: self color andSend: tuple second to: aClass.
(tuple size > 3 and: [tuple fourth isEmptyOrNil not]) ifTrue:
[aButton setBalloonText: tuple fourth].
] ifFalse: [
aButton labelString: tuple third.
aButton arguments: {aButton arguments first. tuple third}.
(tuple size > 3 and: [tuple fourth isEmptyOrNil not]) ifTrue:
[aButton setBalloonText: tuple fourth].
].
self addMorphBack: aButton]!
Item was changed:
----- Method: Player class>>setNewInstVarNames: (in category 'user-defined inst vars') -----
setNewInstVarNames: listOfStrings
"Make listOfStrings be the new list of instance variable names for the receiver"
+ | disappearing firstAppearing instVarList |
- | disappearing firstAppearing instVarString instVarList |
instVarList := self instVarNames asOrderedCollection.
disappearing := instVarList copy.
disappearing removeAllFoundIn: listOfStrings.
disappearing do:
+ [:oldName | self removeAccessorsFor: oldName.
+ self removeInstVarName: oldName].
- [:oldName | self removeAccessorsFor: oldName].
firstAppearing := listOfStrings copy.
firstAppearing removeAllFoundIn: instVarList.
+ firstAppearing do: [:newName |
+ self addInstVarName: newName.
+ self compileAccessorsFor: newName].!
- instVarString := String streamContents:
- [:aStream | listOfStrings do: [:aString | aStream nextPutAll: aString; nextPut: $ ]].
-
- superclass subclass: self name instanceVariableNames: instVarString
- classVariableNames: '' poolDictionaries: '' category: self categoryForUniclasses.
- self flag: #todo. self flag: #uniclasses. "Discuss if we really want to hide uniclasses again"
- superclass environment forgetClass: self logged: false.
- superclass removeSubclass: self.
- firstAppearing do:
- [:newName | self compileAccessorsFor: newName].
- !
Item was changed:
----- Method: Player class>>variableDocks (in category 'other') -----
variableDocks
"Backward compatibility -- answer the formal list of VariableDocks associated with the class, assuming the class to be a CardPlayer subclass. Somewhere a long time ago evidently the players assigned to Worlds stopped being CardPlayers, so this method is now provided as a backstop."
+ ^ variableDocks ifNil: [#()] ifNotNil: [:it | it]!
- ^ #()!
Item was changed:
----- Method: Player>>setHeading: (in category 'slot getters/setters') -----
setHeading: newHeading
"Set the heading as indicated"
+ | aCostume penDown |
- | aCostume |
aCostume := self costume.
aCostume isWorldMorph ifTrue: [^ self].
+ (penDown :=self getPenDown) ifTrue:[self liftPen].
aCostume heading: newHeading.
aCostume := self costume. "in case we just got flexed for no apparent reason"
(aCostume isFlexMorph and:[aCostume hasNoScaleOrRotation])
+ ifTrue: [aCostume removeFlexShell].
+ penDown ifTrue:[self lowerPen]
+ !
- ifTrue: [aCostume removeFlexShell]!
Item was changed:
----- Method: PlayingCardDeck>>staggerOffset (in category 'layout') -----
staggerOffset
+ ^18 px!
- ^18!
Item was changed:
----- Method: PlayingCardMorph class>>cardSize (in category 'access') -----
cardSize
" a real hack, but I don't want to muck with Dan's class "
+ ^71 px @ 96 px!
- ^71 at 96.!
Item was changed:
----- Method: PlayingCardMorph class>>the:of: (in category 'initialize-release') -----
the: cardNumber of: suit
+ | image |
+ image := (PlayingCard the: cardNumber of: suit) cardForm.
+ image := image scaledToSize: image extent * RealEstateAgent scaleFactor.
^ self new
+ image: image;
- image: (PlayingCard the: cardNumber of: suit) cardForm;
cardNumber: cardNumber suitNumber: (self suits indexOf: suit)!
Item was changed:
----- Method: Project>>name: (in category '*Etoys-Squeakland-accessing') -----
name: aString
+ changeSet ifNil: [
+ self flag: #ct. "Can we redirect to #explicitName: here instead of creating change set, or does anyone rely on this side effect?"
+ changeSet := ChangeSet new].
- changeSet ifNil: [changeSet := ChangeSet new].
(aString isEmpty or: [aString = changeSet name])
ifFalse: [changeSet name: (ChangeSet uniqueNameLike: aString)]!
Item was changed:
----- Method: SameGame>>buildButton:target:label:selector: (in category 'initialization') -----
buildButton: aButton target: aTarget label: aLabel selector: aSelector
"wrap a button or switch in an alignmentMorph to allow a row of buttons to fill space"
| a |
aButton
target: aTarget;
label: aLabel;
actionSelector: aSelector;
+ borderStyle: (BorderStyle raised width: 2 px);
- borderStyle: (BorderStyle raised width: 2);
color: color.
a := AlignmentMorph newColumn
wrapCentering: #center; cellPositioning: #topCenter;
hResizing: #spaceFill;
vResizing: #shrinkWrap;
color: color.
a addMorph: aButton.
+ ^ a!
- ^ a
-
- !
Item was changed:
----- Method: SameGame>>initialize (in category 'initialization') -----
initialize
"initialize the state of the receiver"
super initialize.
""
self listDirection: #topToBottom;
wrapCentering: #center;
cellPositioning: #topCenter;
vResizing: #shrinkWrap;
hResizing: #shrinkWrap;
+ layoutInset: 3 px;
- layoutInset: 3;
addMorph: self makeControls;
addMorph: self board.
helpText := nil.
self newGame!
Item was changed:
----- Method: SameGame>>makeControls (in category 'initialization') -----
makeControls
| row |
row := AlignmentMorph newRow
color: color;
borderWidth: 0;
+ layoutInset: 3 px.
+ row hResizing: #spaceFill; vResizing: #shrinkWrap; wrapCentering: #center; cellPositioning: #leftCenter; extent: 5 px @ 5 px.
- layoutInset: 3.
- row hResizing: #spaceFill; vResizing: #shrinkWrap; wrapCentering: #center; cellPositioning: #leftCenter; extent: 5 at 5.
row addMorph:
(self
buildButton: SimpleSwitchMorph new
target: self
label: 'Help' translated
selector: #help:).
row addMorph:
(self
buildButton: SimpleButtonMorph new
target: self
label: 'Quit' translated
selector: #delete).
row addMorph:
(self
buildButton: SimpleButtonMorph new
target: self board
label: 'Hint' translated
selector: #hint).
row addMorph:
(self
buildButton: SimpleButtonMorph new
target: self
label: 'New game' translated
selector: #newGame).
selectionDisplay := LedMorph new
digits: 2;
+ extent: (10 px * 2 @ 15 px).
- extent: (2*10 at 15).
row addMorph: (self wrapPanel: selectionDisplay label: 'Selection:' translated).
scoreDisplay := LedMorph new
digits: 4;
+ extent: (10 px * 4 @ 15 px).
- extent: (4*10 at 15).
row addMorph: (self wrapPanel: scoreDisplay label: 'Score:' translated).
^ row!
Item was changed:
----- Method: SameGameBoard>>defaultBorderWidth (in category 'initialization') -----
defaultBorderWidth
"answer the default border width for the receiver"
+ ^ 2 px!
- ^ 2!
Item was changed:
----- Method: SameGameTile>>initialize (in category 'initialization') -----
initialize
super initialize.
self label: ''.
+ self borderWidth: 2 px.
+ bounds := 0 @ 0 corner: 16 px @ 16 px.
- self borderWidth: 2.
- bounds := 0 at 0 corner: 16 at 16.
offColor := Color gray.
onColor := Color gray.
switchState := false.
oldSwitchState := false.
disabled := false.
+ self useSquareCorners.!
- self useSquareCorners
- !
Item was changed:
----- Method: ScriptEditorMorph>>buttonRowForEditor (in category 'buttons') -----
buttonRowForEditor
"Answer a row of buttons that comprise the header at the top of the Scriptor"
| aRow aString aStatusMorph aButton aTile aMorph goldBoxButton aBox |
+ aRow := AlignmentMorph newRow color: ScriptingSystem baseColor; layoutInset: 1 px.
- aRow := AlignmentMorph newRow color: ScriptingSystem baseColor; layoutInset: 1.
aRow hResizing: #spaceFill.
aRow vResizing: #shrinkWrap.
self addDismissButtonTo: aRow.
+ aRow addTransparentSpacerOfSize: 9 px.
- aRow addTransparentSpacerOfSize: 9.
"Player's name"
aString := playerScripted externalName.
aMorph := StringMorph contents: aString font: ScriptingSystem fontForTiles.
aMorph setNameTo: 'title'.
aRow addMorphBack: aMorph.
+ aRow addTransparentSpacerOfSize: 6 px.
- aRow addTransparentSpacerOfSize: 6.
"Script's name"
aBox := AlignmentMorph newRow.
aBox hResizing: #shrinkWrap; vResizing: #shrinkWrap.
aBox color: (Color r: 0.839 g: 1.0 b: 0.806).
+ aBox borderWidth: 1 px.
- aBox borderWidth: 1.
aBox borderColor: (Color r: 0.645 g: 0.774 b: 0.613).
aButton := UpdatingStringMorph new.
aButton useStringFormat;
target: self;
getSelector: #scriptTitle;
setNameTo: 'script name';
font: ScriptingSystem fontForNameEditingInScriptor;
putSelector: #setScriptNameTo:;
setProperty: #okToTextEdit toValue: true;
step;
yourself.
aBox addMorph: aButton.
aRow addMorphBack: aBox.
aBox setBalloonText: 'Click here to edit the name of the script.' translated.
"aRow addTransparentSpacerOfSize: 9."
aRow addVariableTransparentSpacer.
"Try It button"
self hasParameter ifFalse:
[aRow addMorphBack:
((ThreePhaseButtonMorph
labelSymbol: #TryIt
target: self
actionSelector: #tryMe
arguments: #())
actWhen: #whilePressed;
balloonTextSelector: #tryMe).
+ aRow addTransparentSpacerOfSize: 3 px].
- aRow addTransparentSpacerOfSize: 3].
"Step button, only for non-Kedama"
(self playerScripted isPrototypeTurtlePlayer or: [self hasParameter]) ifFalse:
[aRow addMorphBack: (aButton := ThreePhaseButtonMorph
labelSymbol: #StepMe
target: self
actionSelector: #stepMe
arguments: #()).
aButton balloonTextSelector: #stepMe.
+ aRow addTransparentSpacerOfSize: 3 px].
- aRow addTransparentSpacerOfSize: 3].
"Status controller"
self hasParameter
ifTrue:
[aTile := TypeListTile new choices: Vocabulary typeChoicesForUserVariables dataType: nil.
aTile addArrows.
aTile setLiteral: self typeForParameter.
aRow addMorphBack: aTile.
aTile borderColor: Color red.
aTile color: ScriptingSystem uniformTileInteriorColor.
aTile setBalloonText: 'Drag from here to get a parameter tile' translated.
aTile addCaretsAsAppropriate: true]
ifFalse:
[aRow addMorphBack: (aStatusMorph := self scriptInstantiation statusControlMorph)].
+ "aRow addTransparentSpacerOfSize: 3 px."
- "aRow addTransparentSpacerOfSize: 3."
aRow addVariableTransparentSpacer.
"Gold-box"
aRow addMorphBack: (goldBoxButton := IconicButton new).
goldBoxButton borderWidth: 0;
labelGraphic: (ScriptingSystem formAtKey: 'RoundGoldBox'); color: Color transparent;
actWhen: #buttonDown;
target: self;
actionSelector: #offerGoldBoxMenu;
shedSelvedge;
setBalloonText: 'click here to get a palette of useful tiles to use in your script.' translated.
+ aRow addTransparentSpacerOfSize: 6 px @ 1 px.
- aRow addTransparentSpacerOfSize: 6 at 1.
"Menu Button"
aButton := self menuButton.
aButton actionSelector: #offerScriptorMenu.
aRow addMorphBack: aButton.
(playerScripted existingScriptInstantiationForSelector: scriptName)
ifNotNil:
[:inst | inst updateStatusMorph: aStatusMorph].
^ aRow!
Item was changed:
----- Method: ScriptEditorMorph>>createThreadShowing (in category 'menu commands') -----
createThreadShowing
| vertices |
self deleteThreadShowing.
vertices := OrderedCollection new.
self tileRows do: [:row | | b |
row first isTurtleRow ifTrue: [
b := row first bounds.
+ vertices add: ((b topLeft + (4 px @ 0)) + ((0 * 0.1 * b width) @ 0)).
- vertices add: ((b topLeft + (4 @ 0)) + ((0 * 0.1 * b width) @ 0)).
0 to: 9 do: [:i |
+ vertices add: ((b topLeft + (4 px @ 4 px))+ ((i * 0.1 * b width ) @ 0)).
+ vertices add: ((b bottomLeft + (4 px @ -4 px)) + ((i * 0.1 * b width) @ 0)).
- vertices add: ((b topLeft + (4 @ 4))+ ((i * 0.1 * b width ) @ 0)).
- vertices add: ((b bottomLeft + (4 @ -4)) + ((i * 0.1 * b width) @ 0)).
].
+ vertices add: ((b bottomLeft + (4 px @ 0)) + ((9 * 0.1 * b width) @ 0)).
- vertices add: ((b bottomLeft + (4 @ 0)) + ((9 * 0.1 * b width) @ 0)).
] ifFalse: [
b := row first bounds.
vertices add: ((b origin x + b corner x) // 2) @ (b origin y).
+ vertices add: ((b origin x + b corner x) // 2) @ (b origin y + 4 px).
+ vertices add: ((b origin x + b corner x) // 2) @ (b corner y - 4 px).
- vertices add: ((b origin x + b corner x) // 2) @ (b origin y + 4).
- vertices add: ((b origin x + b corner x) // 2) @ (b corner y - 4).
vertices add: ((b origin x + b corner x) // 2) @ (b corner y).
].
].
+ threadPolygon := PolygonMorph vertices: vertices color: Color black borderWidth: 2 px borderColor: Color black.
- threadPolygon := PolygonMorph vertices: vertices color: Color black borderWidth: 2 borderColor: Color black.
threadPolygon makeOpen.
+ threadPolygon openInWorld.!
- threadPolygon openInWorld.
- !
Item was changed:
----- Method: ScriptEditorMorph>>defaultBorderWidth (in category 'initialization') -----
defaultBorderWidth
"answer the default border width for the receiver"
+ ^ 1 px!
- ^ 1!
Item was changed:
----- Method: ScriptEditorMorph>>explainStatusAlternatives (in category 'customevents-other') -----
explainStatusAlternatives
"Explain the scripting-status alternatives."
+ ScriptingSystem putUpInfoPanelFor:(ScriptingSystem statusHelpStringFor: playerScripted) title: 'Script Status' translated extent: 800 px @ 500 px!
- ScriptingSystem putUpInfoPanelFor:(ScriptingSystem statusHelpStringFor: playerScripted) title: 'Script Status' translated extent: 800 at 500!
Item was changed:
----- Method: ScriptEditorMorph>>extent: (in category 'other') -----
extent: x
| newExtent tw menu |
newExtent := x max: self minWidth @ self minHeight.
(tw := self findA: ScrollPane) ifNil:
["This was the old behavior"
^ super extent: newExtent].
(self hasProperty: #autoFitContents) ifTrue: [
menu := MenuMorph new defaultTarget: self.
menu addUpdating: #autoFitString target: self action: #autoFitOnOff.
menu addTitle: 'To resize the script, uncheck the box below' translated.
menu popUpEvent: nil in: self world .
^ self].
"Allow the user to resize to any size"
tw extent: ((newExtent x max: self firstSubmorph width)
+ @ (newExtent y - self firstSubmorph height)) - (self borderWidth * 2) + (-4 px @ -4 px). "inset?"
- @ (newExtent y - self firstSubmorph height)) - (self borderWidth * 2) + (-4 @ -4). "inset?"
^ super extent: newExtent!
Item was changed:
----- Method: ScriptEditorMorph>>initialize (in category 'initialization') -----
initialize
"initialize the state of the receiver"
super initialize.
""
self listDirection: #topToBottom;
hResizing: #shrinkWrap;
vResizing: #shrinkWrap;
cellPositioning: #topLeft;
setProperty: #autoFitContents toValue: true;
minHeight: TileMorph defaultH;
+ layoutInset: 2 px.
- layoutInset: 2.
self useRoundedCornersInEtoys.
self borderColor: ScriptingSystem borderColor.
self setNameTo: 'Script Editor' translated.
firstTileRow := 1.
"index of first tile-carrying submorph"
self addNewRow.
+ showingMethodPane := false.!
- showingMethodPane := false.
- !
Item was changed:
----- Method: ScriptEditorMorph>>setupMethodMorph (in category '*Etoys-Squeakland-buttons') -----
setupMethodMorph
"create textual source instead"
| aCodePane |
aCodePane := MethodHolder
isolatedCodePaneForClass: playerScripted class
selector: scriptName.
aCodePane
hResizing: #spaceFill;
vResizing: #spaceFill;
+ minHeight: 100 px.
- minHeight: 100.
self
hResizing: #shrinkWrap;
vResizing: #shrinkWrap.
self addMorphBack: aCodePane.
self fullBounds.
self
listDirection: #topToBottom;
hResizing: #rigid;
vResizing: #rigid;
rubberBandCells: true;
minWidth: self width.
showingMethodPane := true.
self currentWorld startSteppingSubmorphsOf: self!
Item was removed:
- ----- Method: SpectrumAnalyzerMorph>>addLevelSlider (in category 'private') -----
- addLevelSlider
-
- | levelSlider r |
- levelSlider := SimpleSliderMorph new
- color: color;
- extent: 100 at 2;
- target: soundInput;
- actionSelector: #recordLevel:;
- adjustToValue: soundInput recordLevel.
- r := AlignmentMorph newRow
- color: color;
- layoutInset: 0;
- wrapCentering: #center; cellPositioning: #leftCenter;
- hResizing: #shrinkWrap;
- vResizing: #rigid;
- height: 24.
- r addMorphBack: (StringMorph contents: '0 ').
- r addMorphBack: levelSlider.
- r addMorphBack: (StringMorph contents: ' 10').
- self addMorphBack: r.
- !
Item was changed:
----- Method: SpectrumAnalyzerMorph>>addLevelSliderIn: (in category 'private') -----
addLevelSliderIn: aPoint
| levelSlider r |
+ (levelSlider := SimpleSliderMorph new)
- levelSlider := SimpleSliderMorph new
color: color;
+ sliderColor: Color gray;
+ extent: (aPoint x * 0.75) asInteger @ (aPoint y * 0.6) asInteger;
+ minimumExtent: levelSlider extent;
- extent: (aPoint x * 0.75) asInteger@(aPoint y*0.6) asInteger;
target: soundInput;
actionSelector: #recordLevel:;
+ orientation: #horizontal;
adjustToValue: soundInput recordLevel.
r := AlignmentMorph newRow
color: color;
layoutInset: 0;
wrapCentering: #center; cellPositioning: #leftCenter;
hResizing: #shrinkWrap;
vResizing: #rigid;
+ height: aPoint y + 2 px.
- height: aPoint y + 2.
r addMorphBack: (StringMorph contents: '0 ' font: Preferences standardEToysButtonFont).
r addMorphBack: levelSlider.
r addMorphBack: (StringMorph contents: ' 10' font: Preferences standardEToysButtonFont).
+ self addMorphBack: r.!
- self addMorphBack: r.
- !
Item was changed:
----- Method: SpectrumAnalyzerMorph>>defaultBorderWidth (in category 'initialization') -----
defaultBorderWidth
"answer the default border width for the receiver"
+ ^ 2 px!
- ^ 2!
Item was changed:
----- Method: SpectrumAnalyzerMorph>>initialize (in category 'initialization') -----
initialize
"initialize the state of the receiver"
| full |
super initialize.
""
self listDirection: #topToBottom.
soundInput := SoundInputStream new samplingRate: 22050.
fft := FFT new: 512.
displayType := 'sonogram'.
self hResizing: #shrinkWrap.
self vResizing: #shrinkWrap.
full := self addButtonRow.
submorphs last addMorphBack: (self makeStatusLightIn: full extent).
self addLevelSliderIn: full extent.
self addMorphBack: (self makeLevelMeterIn: full extent).
+ self addMorphBack: (Morph new extent: 10 px @ 10 px;
- self addMorphBack: (Morph new extent: 10 @ 10;
color: Color transparent).
"spacer"
self resetDisplay!
Item was removed:
- ----- Method: SpectrumAnalyzerMorph>>makeLevelMeter (in category 'private') -----
- makeLevelMeter
-
- | outerBox |
- outerBox := RectangleMorph new extent: 125 at 14; color: Color lightGray.
- levelMeter := Morph new extent: 2 at 10; color: Color yellow.
- levelMeter position: outerBox topLeft + (2 at 2).
- outerBox addMorph: levelMeter.
- ^ outerBox
- !
Item was changed:
----- Method: SpectrumAnalyzerMorph>>makeLevelMeterIn: (in category 'private') -----
makeLevelMeterIn: aPoint
| outerBox h |
h := (aPoint y * 0.6) asInteger.
+ outerBox := Morph new extent: aPoint x asInteger @ h; color: Color gray.
+ levelMeter := Morph new extent: 1 px @ h; color: Color yellow.
+ levelMeter position: outerBox topLeft + (1 px @ 1 px).
- outerBox := Morph new extent: (aPoint x) asInteger at h; color: Color gray.
- levelMeter := Morph new extent: 1 at h; color: Color yellow.
- levelMeter position: outerBox topLeft + (1 at 1).
outerBox addMorph: levelMeter.
+ ^ outerBox!
- ^ outerBox
- !
Item was removed:
- ----- Method: SpectrumAnalyzerMorph>>makeStatusLight (in category 'private') -----
- makeStatusLight
-
- | s |
- statusLight := RectangleMorph new extent: 24 at 19.
- statusLight color: Color gray.
- s := StringMorph contents: 'On' translated.
- s position: statusLight center - (s extent // 2).
- statusLight addMorph: s.
- ^ statusLight
- !
Item was changed:
----- Method: SpectrumAnalyzerMorph>>makeStatusLightIn: (in category 'private') -----
makeStatusLightIn: aPoint
| s p |
p := (aPoint x min: aPoint y) asPoint.
statusLight := RectangleMorph new extent: p.
statusLight color: Color gray.
+ s := StringMorph contents: '' font: Preferences standardButtonFont.
- s := StringMorph contents: 'On' translated font: Preferences standardEToysFont.
- s position: statusLight center - (s extent // 2).
statusLight addMorph: s.
+ ^ statusLight!
- ^ statusLight
- !
Item was changed:
----- Method: SpectrumAnalyzerMorph>>showSignal (in category 'private') -----
showSignal
"Display the actual signal waveform."
displayType := 'signal'.
self removeAllDisplays.
graphMorph := GraphMorph new.
+ graphMorph extent: (400 px + (graphMorph borderWidth * 2)) @ 128 px.
- graphMorph extent: (400 + (2 * graphMorph borderWidth))@128.
graphMorph data: (Array new: 100 withAll: 0).
graphMorph color: (Color r: 0.8 g: 1.0 b: 1.0).
self addMorphBack: graphMorph.
+ self extent: 10 px @ 10 px. "shrink to minimum size"!
- self extent: 10 at 10. "shrink to minimum size"
- !
Item was changed:
----- Method: SpectrumAnalyzerMorph>>showSonogram (in category 'private') -----
showSonogram
"Display a sonogram showing the frequency spectrum versus time."
| zeros h w |
displayType := 'sonogram'.
self removeAllDisplays.
h := fft n // 2.
+ h := h min: 512 px max: 64 px.
+ w := 400 px.
- h := h min: 512 max: 64.
- w := 400.
sonogramMorph :=
Sonogram new
extent: w at h
minVal: 0.0
maxVal: 1.0
scrollDelta: w.
zeros := Array new: sonogramMorph height withAll: 0.
sonogramMorph width timesRepeat: [sonogramMorph plotColumn: zeros].
self addMorphBack: sonogramMorph.
+ self extent: 10 px @ 10 px. "shrink to minimum size"!
- self extent: 10 at 10. "shrink to minimum size"
- !
Item was changed:
----- Method: SpectrumAnalyzerMorph>>showSpectrum (in category 'private') -----
showSpectrum
"Display the frequency spectrum."
displayType := 'spectrum'.
self removeAllDisplays.
graphMorph := GraphMorph new.
+ graphMorph extent: ((fft n // 2) + (graphMorph borderWidth * 2)) @ 128 px.
- graphMorph extent: ((fft n // 2) + (2 * graphMorph borderWidth))@128.
graphMorph data: (Array new: fft n // 2 withAll: 0).
self addMorphBack: graphMorph.
+ self extent: 10 px @ 10 px. "shrink to minimum size"!
- self extent: 10 at 10. "shrink to minimum size"
- !
Item was changed:
----- Method: SpectrumAnalyzerMorph>>step (in category 'stepping and presenter') -----
step
"Update the record light, level meter, and display."
| w |
"update the record light and level meter"
+ statusLight color:
+ (soundInput isRecording ifTrue: [Color yellow] ifFalse: [Color gray]).
+ statusLight firstSubmorph in: [:stringMorph |
+ stringMorph contents:
+ (soundInput isRecording ifTrue: ['On' translated] ifFalse: ['Off' translated]).
+ stringMorph position: statusLight center - (stringMorph extent // 2)].
+
+ w := ((121 px * soundInput meterLevel) // 100) max: 1.
+ levelMeter width: w.
+
- soundInput isRecording
- ifTrue: [statusLight color: Color yellow]
- ifFalse: [statusLight color: Color gray].
- w := ((121 * soundInput meterLevel) // 100) max: 1.
- levelMeter width ~= w ifTrue: [levelMeter width: w].
-
"update the display if any data is available"
+ self updateDisplay.!
- self updateDisplay.
- !
Item was added:
+ SqueakTutorials subclass: #SqueakTutorialsEToys
+ instanceVariableNames: ''
+ classVariableNames: ''
+ poolDictionaries: ''
+ category: 'Etoys-Help'!
Item was added:
+ ----- Method: SqueakTutorialsEToys class>>bookName (in category 'accessing') -----
+ bookName
+
+ ^ 'Etoys'!
Item was added:
+ ----- Method: SqueakTutorialsEToys class>>makingAnEtoy (in category 'pages') -----
+ makingAnEtoy
+ "This method was automatically generated. Edit it using:"
+ "SqueakTutorialsEToys edit: #makingAnEtoy"
+ <generated>
+ ^(HelpTopic
+ title: 'Making an eToy'
+ contents:
+ 'To start making an EToy, you always draw a picture. Click on the "Supplies" flap below. Drag out the Painting icon. When you drop it, you can paint a new object. Click "Keep" to end painting.
+
+ There is another way to start a painting. Open the "Nav bar" flap at the bottom of the screen. Click on the picture of the paintbrush.
+
+ When you finish a painting, the picture turns into a real Squeak object. In order to make scripts for this object, you''ll want a viewer on it. Command-click (right-click on a PC, or Alt-click) on the object to get a halo. Then click on the aqua icon of an eye.!!' readStream nextChunkText)
+ key: #makingAnEtoy;
+ shouldStyle: false;
+ yourself!
Item was added:
+ ----- Method: SqueakTutorialsEToys class>>pages (in category 'accessing') -----
+ pages
+
+ ^ self class methodsInCategory: #pages!
Item was added:
+ ----- Method: SqueakTutorialsEToys class>>raceCar (in category 'pages') -----
+ raceCar
+ "This method was automatically generated. Edit it using:"
+ "SqueakTutorialsEToys edit: #raceCar"
+ <generated>
+ ^(HelpTopic
+ title: 'Race Car'
+ contents:
+ 'There are many ways to make things in Squeak. EToys let you draw fun things and then tell them what to do.
+
+ At the right is an EToy that lets you drive a car. If you don''t see it yet, click here.
+
+ Put your mouse over the blue steering wheel (between this window and the status display). Press the "blue button" of your mouse (this can either be your right or your middle mouse key, or use the left mouse button while pressing the cmd key). A "halo" of buttons will appear. Locate the blue handle at the lower left. This rotation control lets you turn the steering wheel. Drag it around and see what happens.
+
+ Press the green "Go" button in the Stop-Step-Go controls. The race car will start moving. Put your mouse back over the steering wheel and steer the car. Press "Stop" to stop the car.
+
+ The script in the center of the racetrack makes the car go. It changes the car''s heading by reading the heading of the steering wheel. You can increase the speed of the car by clicking the up arrow of the number after "Car forward by".
+
+ Press the "Try it" button on the script, this is the left-most mouse icon.
+
+ Scripts are constructed using a parts bin called a "Viewer". Press the blue button on the race car and its halo will appear. Click at cyan eye handle on the left and press "Open viewer for player". A flap will open with the Car''s viewer in it. (Click the tiny car again to close the flap.)
+
+ You can make a new script for the Car by grabbing the tile for "Car emptyScript" and dropping it. Then grab other tiles and drop them into the script. You can see other categories of tiles by clicking on the green arrows beside the category name.
+
+ Just for fun, let''s add more things to our car. There is an alert light to the dashboard, but it does not work. If you drive off the road, we want the light to shine red.
+ 1) From the "tests" section in the car''s viewer, grab the test tile into the drive script.
+ 2) From the same category, find the test "isOverColor" tile and drag it next to the label "test" in our script.
+ 3) The tile says "Car''s isOverColor __" and a patch of color. Click on the patch of color. You will see a color picker and have an eyedropper as the cursor. Click on the gray of the street.
+ 4) Open the halo on the Alert light, and open a viewer for its player from the cyan eye handle.
+ 5) In the Alert''s viewer, find the category of commands "color & border". You may have to click on the plus icon at the right top of the viewer or on the green arrows to get it.
+ 6) The first command is "Alert''s color". Click on the square on the right with the green arrow in it. Suddenly you will have the tiles that set Alert''s color.
+ 7) Drag the left arrow for this command and drop those tiles into the "Yes" section of the script.
+ 8) Grab from the arrow next to the square again to get another copy of the tiles and put them in the "No" section.
+ 9) Decide what color the Alert should be when everything is OK. Click on the patch of color in the "No" tiles, and choose the color.
+
+ Now click Go, drive the car, and see what the Alert light does.!!
+ ]style[(184 10 450 21 2390),Rcode://
+ Player extraExampleCar do: #openInWorld;,,Rcode://
+ AllScriptsTool newStandAlone openInHand;,!!' readStream nextChunkText)
+ key: #raceCar;
+ shouldStyle: false;
+ yourself!
Item was added:
+ ----- Method: SqueakTutorialsEToys class>>usesCodeStyling (in category 'testing') -----
+ usesCodeStyling
+
+ ^ false!
Item was changed:
----- Method: StackMorph>>fullControlSpecs (in category 'page controls') -----
fullControlSpecs
"Answer specifications for the long form of iconic stack/book controls"
^ {
#spacer.
#variableSpacer.
{'-'. #deleteCard. 'Delete this card' translated}.
#spacer.
+ { '«' . #goToFirstCardOfStack. 'First card' translated}.
- { '¬´' . #goToFirstCardOfStack. 'First card' translated}.
#spacer.
{ '<'. #goToPreviousCardInStack. 'Previous card' translated}.
#spacer.
+ {'·'. #invokeBookMenu. 'Click here to get a menu of options for this stack.' translated}.
- {'¬'. #invokeBookMenu. 'Click here to get a menu of options for this stack.' translated}.
"#spacer. {'¬'. #reshapeBackground. 'Reshape' translated}. "
#spacer.
+ {'§'. #showDesignationsOfObjects. 'Show designations' translated}.
- {'§'. #showDesignationsOfObjects. 'Show designations' translated}.
#spacer.
{'>' . #goToNextCardInStack. 'Next card' translated}.
#spacer.
+ { '»'. #goToLastCardOfStack. 'Final card' translated}.
- { '»'. #goToLastCardOfStack. 'Final card' translated}.
#spacer.
{'+'. #insertCard. 'Add a new card after this one' translated}.
#variableSpacer.
+ {'o'. #fewerPageControls. 'Fewer controls
- {'¬'. #fewerPageControls. 'Fewer controls
(if shift key pressed,
deletes controls)' translated}
}!
Item was changed:
----- Method: StackMorph>>shortControlSpecs (in category 'page controls') -----
shortControlSpecs
"Answer specficiations for the shorter form of stack controls"
^ {
#spacer.
#variableSpacer.
+ { #PrevPage. #goToPreviousCardInStack. 'Previous card' translated}.
- { '<'. #goToPreviousCardInStack. 'Previous card' translated}.
#spacer.
+ {#MenuIcon. #invokeBookMenu. 'Click here to get a menu for this stack.' translated}.
- {'¬'. #invokeBookMenu. 'Click here to get a menu for this stack.' translated}.
#spacer.
+ {#NextPage. #goToNextCardInStack. 'Next card' translated}.
- {'>'. #goToNextCardInStack. 'Next card' translated}.
#variableSpacer.
+ {'...'. #showMoreControls. 'More controls
- {'¬'. #showMoreControls. 'More controls
(if shift key pressed,
deletes controls)' translated}
}!
Item was changed:
----- Method: String>>fromCamelCase (in category '*Etoys-Squeakland-converting') -----
fromCamelCase
+ "convert 'anExampleString' to 'an example string'"
- "convert 'anExampleString' to 'an example string'"
| upper nextWord start |
upper := ($A to: $Z) asCharacterSet.
nextWord := self indexOfAnyOf: upper.
nextWord = 0 ifTrue: [^self].
start := 1.
^String streamContents: [:strm |
[
strm nextPutAll: (self copyFrom: start to: nextWord-1).
strm space; nextPut: (self at: nextWord) asLowercase.
start := nextWord+1.
nextWord := self indexOfAnyOf: upper startingAt: start.
nextWord = 0
] whileFalse.
strm nextPutAll: (self copyFrom: start to: self size).
].!
Item was changed:
AlignmentMorph subclass: #Tetris
+ instanceVariableNames: 'board scoreDisplay pauseSwitch'
- instanceVariableNames: 'board scoreDisplay'
classVariableNames: ''
poolDictionaries: ''
category: 'Etoys-Squeakland-Morphic-Games'!
!Tetris commentStamp: '<historical>' prior: 0!
This is a port of JTetris.java 1.0.0.
How to start:
choose new morph.../Games/Tetris
How to play:
1) using buttons
2) using keyboard:
drop - spacebar
move to left - left arrow
move to right - right arrow
rotate clockwise - up arrow
rotate anticlockwise - down arrow
NOTE: mouse must be over Tetris!
Item was changed:
----- Method: Tetris>>buildButtonTarget:label:selector:help: (in category 'initialization') -----
buildButtonTarget: aTarget label: aLabel selector: aSelector help: aString
^self rowForButtons
addMorph: (
SimpleButtonMorph new
target: aTarget;
label: aLabel;
actionSelector: aSelector;
+ borderStyle: (BorderStyle raised width: 2 px);
- borderStyle: (BorderStyle raised width: 2);
color: color
+ )!
- )
-
- !
Item was added:
+ ----- Method: Tetris>>buildSwitchTarget:label:selector:help: (in category 'initialization') -----
+ buildSwitchTarget: aTarget label: aLabel selector: aSelector help: aString
+
+ ^self rowForButtons
+ addMorph: (
+ SimpleSwitchMorph new
+ target: aTarget;
+ label: aLabel;
+ actionSelector: aSelector;
+ borderStyle: (BorderStyle raised width: 2 px);
+ color: color
+ )!
Item was changed:
----- Method: Tetris>>initialize (in category 'initialization') -----
initialize
"initialize the state of the receiver"
super initialize.
""
board := TetrisBoard new game: self.
+ board addDependent: self.
self listDirection: #topToBottom;
wrapCentering: #center;
vResizing: #shrinkWrap;
hResizing: #shrinkWrap;
+ layoutInset: 3 px;
- layoutInset: 3;
addMorphBack: self makeGameControls;
addMorphBack: self makeMovementControls;
addMorphBack: self showScoreDisplay;
addMorphBack: board.
+ board newGame.
+
+ self updateGameOver.!
- board newGame!
Item was added:
+ ----- Method: Tetris>>isGameOver (in category 'testing') -----
+ isGameOver
+
+ ^ board isGameOver!
Item was changed:
----- Method: Tetris>>makeGameControls (in category 'initialization') -----
makeGameControls
^ self rowForButtons
addMorph: (self
buildButtonTarget: self
label: 'Quit' translated
selector: #delete
help: 'quit' translated);
+ addMorph: (pauseSwitch := (self
+ buildSwitchTarget: self
- addMorph: (self
- buildButtonTarget: self
label: 'Pause' translated
selector: #pause
+ help: 'pause' translated) firstSubmorph) owner;
- help: 'pause' translated);
addMorph: (self
buildButtonTarget: self
label: 'New game' translated
selector: #newGame
help: 'new game' translated)!
Item was changed:
----- Method: Tetris>>pause (in category 'actions') -----
pause
+ board pause.
+ pauseSwitch setSwitchState: self paused.!
- board pause.!
Item was added:
+ ----- Method: Tetris>>paused (in category 'testing') -----
+ paused
+
+ ^ board paused!
Item was changed:
----- Method: Tetris>>rowForButtons (in category 'initialization') -----
rowForButtons
^AlignmentMorph newRow
color: color;
borderWidth: 0;
+ layoutInset: 3 px;
- layoutInset: 3;
vResizing: #shrinkWrap;
wrapCentering: #center
!
Item was changed:
----- Method: Tetris>>showScoreDisplay (in category 'initialization') -----
showScoreDisplay
^ self rowForButtons hResizing: #shrinkWrap;
addMorph: (self wrapPanel: ((scoreDisplay := LedMorph new) digits: 5;
+ extent: 10 px * 4 @ 15 px) label: 'Score:' translated)!
- extent: 4 * 10 @ 15) label: 'Score:' translated)!
Item was added:
+ ----- Method: Tetris>>update: (in category 'updating') -----
+ update: what
+
+ what = #paused ifTrue:
+ [pauseSwitch setSwitchState: self paused].
+ what = #isGameOver ifTrue:
+ [self updateGameOver].
+
+ ^ super update: what!
Item was added:
+ ----- Method: Tetris>>updateGameOver (in category 'events') -----
+ updateGameOver
+
+ scoreDisplay color: (self isGameOver ifTrue: [Color red] ifFalse: [Color green]).!
Item was changed:
----- Method: TetrisBlock>>defaultBounds (in category 'initialization') -----
defaultBounds
"answer the default bounds for the receiver"
+ ^ (2 px @ 2 px) negated extent: 1 px @ 1 px!
- ^ (2 @ 2) negated extent: 1 @ 1!
Item was added:
+ ----- Method: TetrisBoard>>basicGameOver: (in category 'accessing') -----
+ basicGameOver: aBoolean
+
+ gameOver := aBoolean.
+ self changed: #isGameOver.!
Item was added:
+ ----- Method: TetrisBoard>>basicPaused: (in category 'accessing') -----
+ basicPaused: aBoolean
+
+ paused := aBoolean.
+ self changed: #paused.!
Item was changed:
----- Method: TetrisBoard>>cellSize (in category 'accessing') -----
cellSize
+ ^12 px @ 12 px!
- ^12 at 12!
Item was changed:
----- Method: TetrisBoard>>defaultBounds (in category 'initialization') -----
defaultBounds
"answer the default bounds for the receiver"
+ ^ 0 @ 0 extent: self numColumns @ self numRows * self cellSize + (1 px @ 1 px)!
- ^ 0 @ 0 extent: self numColumns @ self numRows * self cellSize + (1 @ 1)!
Item was added:
+ ----- Method: TetrisBoard>>isGameOver (in category 'testing') -----
+ isGameOver
+
+ ^ gameOver!
Item was changed:
----- Method: TetrisBoard>>newGame (in category 'button actions') -----
newGame
self removeAllMorphs.
+ self basicGameOver: false.
+ self basicPaused: false.
- gameOver := paused := false.
delay := 500.
currentBlock := nil.
self score: 0.
!
Item was changed:
----- Method: TetrisBoard>>pause (in category 'button actions') -----
pause
gameOver ifTrue: [^ self].
+ self basicPaused: self paused not.!
- paused := paused not.
- !
Item was added:
+ ----- Method: TetrisBoard>>paused (in category 'testing') -----
+ paused
+
+ ^ paused!
Item was changed:
----- Method: TetrisBoard>>storePieceOnBoard (in category 'other') -----
storePieceOnBoard
currentBlock submorphs do: [ :each |
self addMorph: each.
((each top - self top) // self cellSize y) < 3 ifTrue: [
+ self basicPaused: true.
+ self basicGameOver: true.
- paused := gameOver := true.
].
].
currentBlock delete.
currentBlock := nil.
self checkForFullRows.
self score: score + 10.
delay := delay - 2 max: 80.
!
Item was changed:
----- Method: TileMorph>>arrowDelta (in category 'mouse handling') -----
arrowDelta
"Answer the amount by which a number I display should increase at a time"
| readout |
(readout := self findA: UpdatingStringMorph) ifNotNil: [^readout floatPrecision ].
+ ^ 1 px!
- ^ 1!
Item was changed:
----- Method: TileMorph>>basicWidth (in category 'misc') -----
basicWidth
"Provide a nominal minimum, exclusive of arrows and independent of label width"
^ operatorOrExpression
+ ifNotNil: [3 px]
+ ifNil: [18 px]!
- ifNotNil: [3]
- ifNil: [18]!
Item was changed:
----- Method: TileMorph>>buildHPopArrows (in category '*Etoys-Squeakland-arrows popup') -----
buildHPopArrows
| panel left right |
self outmostScriptEditor
ifNil: [^ nil].
(retractArrow isNil
and: [suffixArrow isNil])
ifTrue: [^ nil].
panel := Morph new.
panel cornerStyle: #rounded.
left := SketchMorph new
form: (ScriptingSystem formAtKey: #LargeLeftArrow).
right := SketchMorph new
form: (ScriptingSystem formAtKey: #LargeRightArrow).
panel
color: color.
panel sticky: true.
panel layoutPolicy: TableLayout new.
panel listDirection: #leftToRight.
panel hResizing: #shrinkWrap.
panel vResizing: #shrinkWrap.
+ panel cellInset: 4 px.
+ panel layoutInset: 2 px.
- panel cellInset: 4.
- panel layoutInset: 2.
retractArrow
ifNotNil: [panel addMorphBack: left].
suffixArrow
ifNotNil: [panel addMorphBack: right].
panel
on: #mouseLeave
send: #hidePopArrows
to: self.
left
on: #mouseUp
send: #popArrowRetractArrowHit:
to: self.
right
on: #mouseUp
send: #popArrowSuffixArrowHit:
to: self.
^ panel!
Item was changed:
----- Method: TileMorph>>buildVPopArrows (in category '*Etoys-Squeakland-arrows popup') -----
buildVPopArrows
| panel up down |
upArrow
ifNil: [^ nil].
panel := Morph new.
panel cornerStyle: #rounded.
up := SketchMorph new
form: (ScriptingSystem formAtKey: #LargeUpArrow).
down := SketchMorph new
form: (ScriptingSystem formAtKey: #LargeDownArrow).
panel color: color.
panel sticky: true.
panel layoutPolicy: TableLayout new.
panel listDirection: #topToBottom.
panel hResizing: #shrinkWrap.
panel vResizing: #shrinkWrap.
+ panel cellInset: 4 px.
+ panel layoutInset: 2 px.
- panel cellInset: 4.
- panel layoutInset: 2.
panel addMorphBack: up.
panel addMorphBack: down.
panel
on: #mouseLeave
send: #hidePopArrows
to: self.
up
on: #mouseDown
send: #popArrowUp:
to: self.
up
on: #mouseMove
send: #popArrowMouseMove:
to: self.
down
on: #mouseDown
send: #popArrowDown:
to: self.
down
on: #mouseMove
send: #popArrowMouseMove:
to: self.
^ panel!
Item was changed:
----- Method: TileMorph>>convertAlignment (in category 'private') -----
convertAlignment
"Convert the receiver's alignment rules"
| where frame |
owner ifNotNil:[
owner class == TilePadMorph ifTrue:[
owner layoutPolicy: TableLayout new.
owner hResizing: #shrinkWrap.
owner vResizing: #spaceFill.
].
].
self layoutPolicy: TableLayout new.
+ self cellInset: 2 px @ 0.
+ self layoutInset: 1 px @ 0.
- self cellInset: 2 at 0.
- self layoutInset: 1 at 0.
self listDirection: #leftToRight.
self wrapCentering: #center.
self hResizing: #shrinkWrap.
self vResizing: #spaceFill.
"Now convert up and down arrow"
(upArrow notNil and:[upArrow owner == self "e.g., not converted"
and:[downArrow notNil and:[downArrow owner == self]]]) ifTrue:[
"where to insert the frame"
where := (submorphs indexOf: upArrow) min: (submorphs indexOf: downArrow).
frame := Morph new color: Color transparent.
frame
layoutPolicy: TableLayout new;
listDirection: #topToBottom;
hResizing: #shrinkWrap;
vResizing: #shrinkWrap;
+ cellInset: 0 @ 1 px;
+ layoutInset: 0 @ 1 px.
- cellInset: 0 at 1;
- layoutInset: 0 at 1.
self privateAddMorph: frame atIndex: where.
frame addMorphBack: upArrow; addMorphBack: downArrow.
+ ].!
- ].
- !
Item was changed:
----- Method: TileMorph>>defaultBorderWidth (in category 'initialization') -----
defaultBorderWidth
"answer the default border width for the receiver"
+ ^ 1 px!
- ^ 1!
Item was changed:
----- Method: TileMorph>>emblazonPlayerNameOnReferenceTileWithin: (in category '*Etoys-Squeakland-initialization') -----
emblazonPlayerNameOnReferenceTileWithin: scriptorOrViewer
"Make the string within the receiver be the right thing."
| newLabel usePad |
newLabel := actualObject externalName.
Preferences implicitSelfInTiles ifTrue:
[scriptorOrViewer ifNotNil:
[scriptorOrViewer playerScripted == actualObject ifTrue:
[newLabel := '']]].
(newLabel notEmpty and: [self isPossessive]) ifTrue:
[newLabel := newLabel, '''s' translated].
self line1: newLabel.
usePad := owner isKindOf: TilePadMorph.
newLabel
ifEmpty:
[usePad ifTrue: [owner hResizing: #rigid; width: 0; clipSubmorphs: true].
self hResizing: #rigid; width: 0; borderWidth: 0]
ifNotEmpty:
[usePad ifTrue: [owner hResizing: #shrinkWrap; clipSubmorphs: false].
+ self hResizing: #shrinkWrap; borderWidth: 1 px]
- self hResizing: #shrinkWrap; borderWidth: 1]
!
Item was changed:
----- Method: TileMorph>>initialize (in category 'initialization') -----
initialize
"initialize the state of the receiver"
super initialize.
""
+ self extent: 1 px @ 1 px.
- self extent: 1 @ 1.
self
typeColor: (Color
r: 0.8
g: 1.0
b: 0.6).
type := #literal.
"#literal, #slotRef, #objRef, #operator, #expression"
slotName := ''.
literal := 1.
self layoutPolicy: TableLayout new.
self minCellSize: 0 @ TileMorph defaultH.
+ self cellInset: 2 px @ 0.
+ self layoutInset: 1 px @ 0.
- self cellInset: 2 @ 0.
- self layoutInset: 1 @ 0.
self listDirection: #leftToRight.
self wrapCentering: #center.
self hResizing: #shrinkWrap.
self vResizing: #spaceFill!
Item was changed:
----- Method: TileMorph>>layoutChanged (in category 'layout') -----
layoutChanged
| vpanel hpanel popArrows |
super layoutChanged.
self labelMorph
ifNil: [^ self].
popArrows := self activeHand ifNil: [^ self] ifNotNil: [:ac |
ac valueOfProperty: #popArrows
ifAbsent: [^ self]].
popArrows first == self
ifFalse: [^ self].
vpanel := popArrows second.
hpanel := popArrows third.
vpanel
ifNotNil: [vpanel openInWorld.
vpanel center: self labelMorph center.
+ vpanel right: self labelMorph left - 2 px].
- vpanel right: self labelMorph left - 2].
hpanel
ifNotNil: [hpanel openInWorld.
hpanel center: self labelMorph center.
+ hpanel left: self labelMorph right + 2 px]!
- hpanel left: self labelMorph right + 2]!
Item was changed:
----- Method: TileMorph>>line1: (in category 'private') -----
line1: line1
"Emblazon the receiver with the requested label. If the receiver already has a label, make the new label be of the same class"
| m desiredW classToUse lab f |
classToUse := (lab := self labelMorph) ifNotNil: [lab class] ifNil: [StringMorph].
self removeAllMorphs.
f := ScriptingSystem fontForTiles.
(type = #operator and: [#(+ - * / // \\ < <= > >= = ~=) includes: operatorOrExpression]) ifTrue: [
f := f emphasized: 1].
m := classToUse contents: line1 font: f.
+ desiredW := m width + 6 px.
- desiredW := m width + 6.
self extent: (desiredW max: self minimumWidth) @ self class defaultH.
m position: self center - (m extent // 2).
self addMorph: m.
!
Item was changed:
----- Method: TileMorph>>setVisibilityOfUpDownCarets: (in category '*Etoys-Squeakland-arrows') -----
setVisibilityOfUpDownCarets: showCarets
"If the argument is true, make all the 'up and down' carets, such as those that let you change the value of a number or of a boolean constant, visible; if false, remove them from sight. "
(submorphs detect: [:m | m hasProperty: #arrows] ifNone: [nil]) ifNotNil:
[:wrapper |
showCarets
+ ifTrue: [wrapper width: 9 px]
- ifTrue: [wrapper width: 9]
ifFalse: [wrapper width: 0]]!
Item was changed:
----- Method: TileMorph>>test (in category 'private') -----
test
| pos |
"Set the position of all my submorphs. Compute my bounds. Caller must call layoutChanged or set fullBounds to nil."
fullBounds ifNil: [
pos := self topLeft.
self submorphsDo: [:sub | | hh |
hh := (self class defaultH - sub height) // 2. "center in Y"
+ sub privateBounds: (pos + (2 px @ hh) extent: sub extent).
+ pos x: (sub right min: 1200 px)]. "2 pixels spacing on left"
+ bounds := bounds topLeft corner: pos + (2 px @ self class defaultH).
- sub privateBounds: (pos + (2 at hh) extent: sub extent).
- pos x: (sub right min: 1200)]. "2 pixels spacing on left"
- bounds := bounds topLeft corner: pos + (2 @ self class defaultH).
fullBounds := bounds.
].
owner class == TilePadMorph ifTrue: [owner bounds: bounds].
^ fullBounds!
Item was changed:
----- Method: WatchMorph>>initialize (in category 'initialization') -----
initialize
"initialize the state of the receiver"
super initialize.
""
self handsColor: Color red.
self centerColor: Color gray.
romanNumerals := false.
antialias := false.
fontName := 'NewYork'.
+ self extent: 130 px @ 130 px.
- self extent: 130 @ 130.
self start!
Item was changed:
----- Method: WordGameLetterMorph>>id2: (in category 'initialization') -----
id2: idString
"Add further clue id for acrostic puzzles."
| idMorph |
idString ifNotNil:
[idMorph := StringMorph contents: idString font: IDFont.
+ idMorph align: idMorph bounds topRight with: self bounds topRight + (-1 px @ -1 px).
- idMorph align: idMorph bounds topRight with: self bounds topRight + (-1@ -1).
self addMorph: idMorph].
!
Item was changed:
----- Method: WordGameLetterMorph>>indexInQuote:id1: (in category 'initialization') -----
indexInQuote: qi id1: aString
"Initialize me with the given index and an optional aString"
| idMorph y |
style = #boxed
ifTrue: [aString isNil
+ ifTrue: [self extent: 18 px @ 16 px;
+ borderWidth: 1 px]
+ ifFalse: [self extent: 26 px @ 24 px;
+ borderWidth: 1 px]]
- ifTrue: [self extent: 18 @ 16;
- borderWidth: 1]
- ifFalse: [self extent: 26 @ 24;
- borderWidth: 1]]
ifFalse: [aString isNil
+ ifTrue: [self extent: 18 px @ 16 px;
- ifTrue: [self extent: 18 @ 16;
borderWidth: 0]
+ ifFalse: [self extent: 18 px @ 26 px;
- ifFalse: [self extent: 18 @ 26;
borderWidth: 0]].
qi
ifNil: [^ self color: Color gray].
"blank"
self color: self normalColor.
indexInQuote := qi.
style == #underlined
+ ifTrue: [y := self bottom - 2 px.
- ifTrue: [y := self bottom - 2.
aString
+ ifNotNil: [y := y - IDFont ascent + 2 px].
- ifNotNil: [y := y - IDFont ascent + 2].
lineMorph := PolygonMorph
+ vertices: {self left + 2 px @ y. self right - 3 px @ y}
- vertices: {self left + 2 @ y. self right - 3 @ y}
color: Color gray
+ borderWidth: 1 px
- borderWidth: 1
borderColor: Color gray.
self addMorph: lineMorph.
aString
ifNil: [^ self].
idMorph := StringMorph contents: aString font: IDFont.
+ idMorph align: idMorph bounds bottomCenter with: self bounds bottomCenter + (0 @ (IDFont descent - 1 px)).
- idMorph align: idMorph bounds bottomCenter with: self bounds bottomCenter + (0 @ (IDFont descent - 1)).
self addMorphBack: idMorph]
ifFalse: [aString
ifNil: [^ self].
idMorph := StringMorph contents: aString font: IDFont.
+ idMorph align: idMorph bounds topLeft with: self bounds topLeft + (2 px @ -1 px).
- idMorph align: idMorph bounds topLeft with: self bounds topLeft + (2 @ -1).
self addMorph: idMorph
"
World addMorph: (WordGameLetterMorph new boxed
indexInQuote: 123 id1: '123';
id2: 'H'; setLetter: $W).
World addMorph: (WordGameLetterMorph new underlined
indexInQuote: 123 id1: '123';
setLetter: $W).
World addMorph: (WordGameLetterMorph new underlined
indexInQuote: 123 id1: nil;
setLetter: $W).
"]!
Item was changed:
----- Method: WordGameLetterMorph>>setLetter:color: (in category 'initialization') -----
setLetter: aLetter color: aColor
letterMorph ifNotNil: [letterMorph delete].
letter := aLetter.
letter ifNil: [^letterMorph := nil].
letterMorph := StringMorph contents: aLetter asString font: LetterFont.
letterMorph color: aColor.
style == #boxed
ifTrue:
[letterMorph align: letterMorph bounds bottomCenter
+ with: self bounds bottomCenter + (0 @ (LetterFont descent - 2 px))]
- with: self bounds bottomCenter + (0 @ (LetterFont descent - 2))]
ifFalse:
[lineMorph isNil
ifTrue:
[letterMorph align: letterMorph bounds bottomCenter
+ with: self bounds bottomCenter + (0 @ (LetterFont descent - 4 px))]
- with: self bounds bottomCenter + (0 @ (LetterFont descent - 4))]
ifFalse:
[letterMorph align: letterMorph bounds bottomCenter
with: self center x @ (lineMorph top + LetterFont descent)]].
self addMorphBack: letterMorph!
More information about the Squeak-dev
mailing list
|