[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