'From Squeak6.0alpha of 4 May 2018 [latest update: #17949] on 4 May 2018 at 4:43:42 pm'!
TestCase subclass: #BorderedMorphTests
	instanceVariableNames: ''
	classVariableNames: ''
	poolDictionaries: ''
	category: 'MorphicTests-Basic'!

!BorderStyle methodsFor: '*60Deprecated-accessing' stamp: 'mt 4/23/2018 08:58'!
colorsAtCorners

	self deprecated: 'See #topLeftColor and #bottomRightColor.'.
	^Array new: 4 withAll: self color! !

!BorderStyle methodsFor: '*60Deprecated-accessing' stamp: 'mt 4/23/2018 09:01'!
dotOfSize: diameter forDirection: aDirection

	self deprecated: 'See Form for such convenience functions.'.
	^ Form dotOfSize: diameter color: self color! !

!BorderStyle methodsFor: '*60Deprecated-accessing' stamp: 'mt 4/23/2018 09:02'!
widthForRounding

	self deprecated: 'See BalloonCanvas for drawing rounded corners.'.
	^self width! !


!BorderStyle class methodsFor: 'instance creation' stamp: 'mt 4/11/2018 10:20'!
borderStyleForSymbol: sym
	"Answer a border style corresponding to the given symbol"

	| aSymbol |
	aSymbol := sym == #none ifTrue: [#simple] ifFalse: [sym].
	^ (self borderStyleChoices includes: aSymbol)
		ifTrue: [self perform: aSymbol]
		ifFalse: [nil]
"
	| aSymbol selector |
	aSymbol := sym == #none ifTrue: [#simple] ifFalse: [sym].
	selector := Vocabulary eToyVocabulary translationKeyFor: aSymbol.
	selector isNil ifTrue: [selector := aSymbol].
	^ self perform: selector
"
! !


!BorderedMorphTests methodsFor: 'tests' stamp: 'mt 4/14/2018 10:46'!
test01OldInstVarRefs
	"Only BorderedMorph should reference the (deprecated) borderWidth and borderColor isntance variables."
	
	self
		assert: 2
		equals: (SystemNavigation default allAccessesTo: #borderWidth from: BorderedMorph) size.
		
	self
		assert: 2
		equals: (SystemNavigation default allAccessesTo: #borderColor from: BorderedMorph) size.! !

!BorderedMorphTests methodsFor: 'tests' stamp: 'mt 5/4/2018 16:42'!
test02ConvertColorSymbols
	"The use of #inset or #raised as border color should result in the use of a new border style."
	
	| sut |
	sut := BorderedMorph new.
	self
		assert: #simple equals: sut borderStyle style;
		assert: Color black equals: sut borderStyle color.
	
	sut borderColor: #raised.
	self
		assert: #raised equals: sut borderStyle style;
		assert: Color black equals: sut borderStyle color.
	
	"Enable color tracking."
	sut borderColor: Color transparent.
	self assert: sut color equals: sut borderStyle color.
	
	sut borderColor: #inset.
	self
		assert: #inset equals: sut borderStyle style;
		assert: sut color equals: sut borderStyle color.
! !

!BorderedMorphTests methodsFor: 'tests' stamp: 'mt 5/4/2018 16:43'!
test03ColorTracking
	
	| sut c1 c2 |
	sut := BorderedMorph new.
	self assert: Color black equals: sut borderStyle baseColor.

	sut borderInset.
	self
		assert: Color transparent equals: sut borderStyle baseColor;
		assert: sut borderStyle topLeftColor ~= sut color;
		assert: sut borderStyle bottomRightColor ~= sut color;
		assert: sut borderStyle bottomRightColor ~= sut borderStyle topLeftColor.

	c1 := sut borderStyle topLeftColor.
	c2 := sut borderStyle bottomRightColor.
	sut color: Color yellow.
	self
		assert: Color transparent equals: sut borderStyle baseColor;
		assert: sut borderStyle topLeftColor ~= c1;
		assert: sut borderStyle bottomRightColor ~= c2.

	c1 := sut borderStyle topLeftColor.
	c2 := sut borderStyle bottomRightColor.		
	sut borderStyle: BorderStyle raised.
	self
		assert: Color transparent equals: sut borderStyle baseColor;
		assert: sut borderStyle topLeftColor = c2;
		assert: sut borderStyle bottomRightColor = c1.! !


!Canvas methodsFor: 'drawing-rectangles' stamp: 'mt 5/4/2018 11:10'!
frameAndFillRoundRect: aRectangle radius: cornerRadius fillStyle: fillStyle borderStyle: borderStyle

	self
		frameAndFillRoundRect: aRectangle
		radius: cornerRadius
		fillStyle: fillStyle asColor
		borderWidth: borderStyle width
		borderColor: borderStyle color.! !

!Canvas methodsFor: 'drawing-rectangles' stamp: 'mt 5/4/2018 11:57'!
frameRoundRect: aRectangle radius: radius borderStyle: borderStyle

	self
		frameRoundRect: aRectangle
		radius: radius
		width: borderStyle width
		color: borderStyle color.! !


!CommunityTheme class methodsFor: 'instance creation' stamp: 'mt 4/11/2018 10:35'!
addDarkMenusAndDockingBars: aUserInterfaceTheme
	"self createDark apply."
	aUserInterfaceTheme
		set: #borderWidth for: #MenuMorph to: 0;
		set: #color for: #MenuMorph to: Color darkGray twiceDarker;
		set: #titleTextColor for: #MenuMorph to: Color white;
		set: #lineColor for: #MenuMorph to: Color darkGray;
		set: #lineStyle for: #MenuMorph to: BorderStyle simple;
		set: #lineWidth for: #MenuMorph to: 1.
	aUserInterfaceTheme
		set: #textColor for: #MenuItemMorph to: self dbForeground;
		set: #selectionColor for: #MenuItemMorph to: self dbSelection;
		set: #selectionTextColor for: #MenuItemMorph to: Color white ;
		set: #disabledTextColor for: #MenuItemMorph to: self dbForeground muchDarker.
		"set: #subMenuMarker for: #MenuItemMorph to: nil." "Use hard-coded default. See MenuItemMorph."
	"The world main docking bar."
	aUserInterfaceTheme
"		set: #color for: #DockingBarMorph to: Color darkGray;"
"		set: #selectionColor for: #DockingBarItemMorph to: self darkContentSecondary;"
		set: #logoColor for: #TheWorldMainDockingBar to: Color white;
		set: #selectionLogoColor for: #TheWorldMainDockingBar to: Color white! !


!Flaps class methodsFor: 'miscellaneous' stamp: 'mt 4/10/2018 11:24'!
paintFlapButton
	"Answer a button to serve as the paint flap"

	| pb oldArgs brush myButton m |
	pb := PaintBoxMorph new submorphNamed: #paint:.
	pb
		ifNil:
			[(brush := Form extent: 16@16 depth: 16) fillColor: Color red]
		ifNotNil:
			[oldArgs := pb arguments.
			brush := oldArgs third.
			brush := brush copy: (2@0 extent: 42@38).
			brush := brush scaledToSize: brush extent // 2].
	myButton := BorderedMorph new.
	myButton color: (Color r: 0.833 g: 0.5 b: 0.0); borderStyle: (BorderStyle raised width: 2).
	myButton addMorph: (m := brush asMorph lock).
	myButton extent: m extent + (myButton borderWidth + 6).
	m position: myButton center - (m extent // 2).
	^ myButton

! !


!Form class methodsFor: 'examples' stamp: 'mt 4/23/2018 09:06'!
dotOfSize: diameter color: color

	| form |
	form := self extent: diameter asPoint depth: Display depth.
	form getCanvas fillOval: form boundingBox color: color.
	^form! !


!FreeCellStatistics methodsFor: 'user interface' stamp: 'mt 4/10/2018 11:25'!
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);
		color: Color gray.
	a := AlignmentMorph newColumn
		wrapCentering: #center; cellPositioning: #topCenter;
		hResizing: #spaceFill;
		vResizing: #shrinkWrap;
		color: Color transparent;
		layoutInset: 1.
	a addMorph: aButton.
	^ a

! !

!FreeCellStatistics methodsFor: 'user interface' stamp: 'mt 4/10/2018 10:59'!
makeControls
	| row |

	row := AlignmentMorph newRow.
	row
		wrapCentering: #center; cellPositioning: #leftCenter;
		hResizing: #spaceFill;
		vResizing: #shrinkWrap;
		color: self color;
		borderStyle: (BorderStyle inset width: 2);
		addMorphBack: self makeOkButton;
		addMorphBack: self makeResetButton.
	^row.! !

!FreeCellStatistics methodsFor: 'user interface' stamp: 'mt 4/10/2018 10:59'!
makeStatistics
	| row |

	row := AlignmentMorph newRow.
	row
		wrapCentering: #center; cellPositioning: #leftCenter;
		hResizing: #spaceFill;
		vResizing: #spaceFill;
		color: self color;
		borderStyle: (BorderStyle inset width: 2);
		addMorphBack: (AlignmentMorph newColumn
			wrapCentering: #center; cellPositioning: #topCenter;
			color: self color;
			addMorph: (statsMorph := TextMorph new contents: self statsText)).
	^row.! !


!MonokaiTheme class methodsFor: 'instance creation' stamp: 'mt 4/11/2018 10:35'!
addDarkMenusAndDockingBars: theme
	"self createDark apply."
	theme
		set: #borderWidth for: #MenuMorph to: 1;
		set: #borderColor for: #MenuMorph to: self invisibleColor;
		set: #color for: #MenuMorph to: self backgroundColor;
		set: #titleTextColor for: #MenuMorph to: self yellow;
		set: #lineColor for: #MenuMorph to: self invisibleColor;
		set: #lineStyle for: #MenuMorph to: BorderStyle simple;
		set: #lineWidth for: #MenuMorph to: 1.
		
	theme
		set: #textColor for: #MenuItemMorph to: self foregroundColor;
		set: #disabledTextColor for: #MenuItemMorph to: self grayLight;
		set: #selectionColor for: #MenuItemMorph to: self invisibleColor;
		set: #selectionTextColor for: #MenuItemMorph to: self yellow.
		"set: #subMenuMarker for: #MenuItemMorph to: nil." "Use hard-coded default. See MenuItemMorph."
		
	"The world main docking bar."
	theme
		set: #color for: #DockingBarMorph to: self invisibleColor;
		set: #selectionColor for: #DockingBarItemMorph to: self grayLight;
		set: #logoColor for: #TheWorldMainDockingBar to: self foregroundColor;
		set: #selectionLogoColor for: #TheWorldMainDockingBar to: self yellow.! !


!Morph methodsFor: 'accessing' stamp: 'mt 5/4/2018 15:09'!
borderColor: aColorOrSymbolOrNil 

	self flag: #compatibility. "mt: For old code. Should be removed in the future."
	aColorOrSymbolOrNil
		ifNil: [self borderStyle: nil]
		ifNotNil: [:colorOrSymbol |
			colorOrSymbol isSymbol ifTrue: [
				^ self borderStyle: ((self borderStyleForSymbol: colorOrSymbol)
											width: self borderStyle width;
											baseColor: self borderStyle baseColor;
											trackColorFrom: self;
											yourself)]].

	"Set the color of the current border style."			
	self borderStyle
		baseColor: aColorOrSymbolOrNil;
		trackColorFrom: self.

	self changed.! !

!Morph methodsFor: 'accessing' stamp: 'mt 4/11/2018 10:06'!
borderStyle
	^ self valueOfProperty: #borderStyle ifAbsentPut: [BorderStyle default]! !

!Morph methodsFor: 'accessing' stamp: 'mt 5/4/2018 15:10'!
borderStyleForSymbol: aStyleSymbol
	"Answer a suitable BorderStyle for me of the type represented by a given symbol"

	^ (BorderStyle borderStyleForSymbol: aStyleSymbol asSymbol)
		ifNotNil: [:style | | existing |
			existing := self borderStyle.
			style
				width: existing width;
				baseColor: existing baseColor;
				trackColorFrom: self;
				yourself]! !

!Morph methodsFor: 'accessing' stamp: 'mt 5/4/2018 15:10'!
borderStyle: aBorderStyle

	aBorderStyle = self borderStyle ifTrue: [^ self].
	
	"If we cannot draw the new border, accept at least its color and width."
	((self canDrawBorder: aBorderStyle) or: [aBorderStyle isNil])
		ifTrue: [self setProperty: #borderStyle toValue: aBorderStyle]
		ifFalse: [
			self borderStyle
				width: aBorderStyle width;
				baseColor: aBorderStyle baseColor].

	self borderStyle trackColorFrom: self.

	self
		layoutChanged;
		changed.! !

!Morph methodsFor: 'accessing' stamp: 'mt 4/11/2018 10:08'!
borderWidth: aNumber
	"Sets the width of the border in the current border style. If there is no border yet, set up a simple one so that the user can actually see the border width."

	self borderStyle width = aNumber ifTrue: [^ self].
	
	self borderStyle style = #none
		ifTrue: [^ self borderStyle: (BorderStyle simple width: aNumber; yourself)].
	
	self borderStyle width: aNumber.
	self layoutChanged; changed.! !

!Morph methodsFor: 'accessing' stamp: 'mt 4/11/2018 09:32'!
color: aColor
	"Set the receiver's color.  Directly set the color if appropriate, else go by way of fillStyle"

	(aColor isColor or: [aColor isKindOf: InfiniteForm]) ifFalse:[^ self fillStyle: aColor].
	color = aColor ifFalse:
		[self removeProperty: #fillStyle.
		color := aColor.
		self borderStyle trackColorFrom: self.
		self changed]! !

!Morph methodsFor: 'accessing' stamp: 'mt 4/11/2018 10:21'!
setBorderStyle: aSymbol
	"Set the border style of my costume"

	(self borderStyleForSymbol: aSymbol)
		ifNotNil: [:style | self borderStyle: style].! !

!Morph methodsFor: 'drawing' stamp: 'mt 5/4/2018 11:08'!
drawOn: aCanvas

	self wantsRoundedCorners
		ifTrue: [aCanvas frameAndFillRoundRect: self bounds radius: self cornerRadius fillStyle: self fillStyle borderStyle: self borderStyle]
		ifFalse: [aCanvas frameAndFillRectangle: self bounds fillStyle: self fillStyle borderStyle: self borderStyle].
	
! !

!Morph methodsFor: 'visual properties' stamp: 'mt 4/11/2018 09:32'!
fillStyle: aFillStyle
	"Set the current fillStyle of the receiver."
	self setProperty: #fillStyle toValue: aFillStyle.
	"Workaround for Morphs not yet converted"
	color := aFillStyle asColor.
	self borderStyle trackColorFrom: self.
	self changed.! !

!Morph methodsFor: '*60Deprecated-accessing' stamp: 'mt 4/11/2018 08:57'!
doesBevels
	"To return true means that this object can show bevelled borders, and
	therefore can accept, eg, #raised or #inset as valid borderColors.
	Must be overridden by subclasses that do not support bevelled borders."

	self deprecated: 'Use border styles such as InsetBorder or RaisedBorder.'.
	^ false! !


!BorderedMorph methodsFor: 'accessing' stamp: 'mt 4/11/2018 10:56'!
borderColor: aColorOrSymbolOrNil

	super borderColor: aColorOrSymbolOrNil.

	self flag: #compatibility. "mt: For older code, update the instance variables. Should be removed in the future."
	borderColor := self borderStyle color.! !

!BorderedMorph methodsFor: 'accessing' stamp: 'mt 4/11/2018 10:02'!
borderStyle: aBorderStyle 

	super borderStyle: aBorderStyle.

	self flag: #compatibility. "mt: For older code, update the instance variables. Should be removed in the future."
	borderWidth := aBorderStyle width.
	borderColor := aBorderStyle color.! !

!BorderedMorph methodsFor: 'accessing' stamp: 'mt 4/11/2018 10:56'!
borderWidth: anInteger
	
	super borderWidth: anInteger.
		
	self flag: #compatibility. "mt: For older code, update the instance variables. Should be removed in the future."
	borderWidth := self borderStyle width.! !

!BorderedMorph methodsFor: 'accessing' stamp: 'mt 4/10/2018 11:43'!
hasTranslucentColor
	"Answer true if this any of this morph is translucent but not transparent."

	(self color isColor and: [self color isTranslucentColor]) ifTrue: [^ true].
	(self borderColor isColor and: [self borderColor isTranslucentColor]) ifTrue: [^ true].
	^ false
! !

!BorderedMorph methodsFor: 'geometry' stamp: 'mt 4/10/2018 10:01'!
acquireBorderWidth: aBorderWidth
	"Gracefully acquire the new border width, keeping the interior area intact and not seeming to shift"

	| delta |
	(delta := aBorderWidth- self borderWidth) = 0 ifTrue: [^ self].
	self bounds: ((self bounds origin - (delta @ delta)) corner: (self bounds corner + (delta @ delta))).
	self borderWidth: aBorderWidth.! !

!BorderedMorph methodsFor: 'initialization' stamp: 'mt 5/4/2018 13:58'!
borderInitialize
	"initialize the receiver state related to border"

	self borderStyle: (
		self defaultBorderStyle
			baseColor: self defaultBorderColor;
			width: self defaultBorderWidth;
			trackColorFrom: self;
			yourself).! !

!BorderedMorph methodsFor: 'initialization' stamp: 'mt 5/4/2018 15:16'!
borderInset
	"Change border to inset. Preserve width and color."
	
	self borderStyle: (
		BorderStyle inset
			width: self borderStyle width;
			baseColor: Color transparent;
			trackColorFrom: self;
			yourself).! !

!BorderedMorph methodsFor: 'initialization' stamp: 'mt 5/4/2018 15:16'!
borderRaised
	"Change border to inset. Preserve width and color."
	
	self borderStyle: (
		BorderStyle raised
			width: self borderStyle width;
			baseColor: Color transparent;
			trackColorFrom: self;
			yourself).! !

!BorderedMorph methodsFor: 'initialization' stamp: 'mt 5/4/2018 15:15'!
borderSimple
	"Change border to simple. Preserve width and color."
	
	self borderStyle: (
		BorderStyle simple
			width: self borderStyle width;
			baseColor: self borderStyle color; "Override any raised/inset specials."
			trackColorFrom: self;
			yourself).! !

!BorderedMorph methodsFor: 'initialization' stamp: 'mt 4/11/2018 08:49'!
defaultBorderStyle
	^ BorderStyle simple! !

!BorderedMorph methodsFor: 'menu' stamp: 'mt 4/11/2018 08:30'!
changeBorderWidth: evt
	| handle origin aHand newWidth oldWidth |
	aHand := evt ifNil: [self primaryHand] ifNotNil: [evt hand].
	origin := aHand position.
	oldWidth := self borderWidth.
	(handle := HandleMorph new)
		forEachPointDo:
			[:newPoint | handle removeAllMorphs.
			handle addMorph:
				(LineMorph from: origin to: newPoint color: Color black width: 1).
			newWidth := (newPoint - origin) r asInteger // 5.
			self borderWidth: newWidth]
		lastPointDo:
			[:newPoint | handle deleteBalloon.
			self halo ifNotNil: [:halo | halo addHandles].
			self rememberCommand:
				(Command new cmdWording: 'border change' translated;
					undoTarget: self selector: #borderWidth: argument: oldWidth;
					redoTarget: self selector: #borderWidth: argument: newWidth)].
	aHand attachMorph: handle.
	handle setProperty: #helpAtCenter toValue: true.
	handle showBalloon:
'Move cursor farther from
this point to increase border width.
Click when done.' translated hand: evt hand.
	handle startStepping! !

!BorderedMorph methodsFor: '*60Deprecated-accessing' stamp: 'mt 4/11/2018 08:56'!
doesBevels
	"To return true means that this object can show bevelled borders, and
	therefore can accept, eg, #raised or #inset as valid borderColors.
	Must be overridden by subclasses that do not support bevelled borders."

	self deprecated: 'Use border styles such as InsetBorder or RaisedBorder.'.
	^ false! !

!BorderedMorph methodsFor: '*MorphicExtras-printing' stamp: 'mt 4/10/2018 11:43'!
fullPrintOn: aStream
	aStream nextPutAll: '('.
	super fullPrintOn: aStream.
	aStream nextPutAll: ') setBorderWidth: '; print: self borderWidth;
		nextPutAll: ' borderColor: ' , (self colorString: self borderColor)! !


!AnonymousSoundMorph methodsFor: 'initialization' stamp: 'mt 4/10/2018 11:53'!
sound: aSampledSound interimName: anInterimName
	"Establish the sound object and an interim name."

	| aStringMorph |
	self removeAllMorphs.
	self hResizing: #shrinkWrap; vResizing: #shrinkWrap.
	self borderWidth: 2.
	self listDirection: #topToBottom.
	sound := aSampledSound.
	interimName := anInterimName.

	aStringMorph := StringMorph contents: interimName font: ScriptingSystem fontForEToyButtons.
	self addMorphBack: aStringMorph.
	self addButtonRow.

	self balloonTextSelector: #soundMorphHelpString.
	self setNameTo: interimName! !


!BasicButton methodsFor: 'as yet unclassified' stamp: 'mt 4/10/2018 11:53'!
label: aString

	| oldLabel m |
	(oldLabel := self findA: StringMorph)
		ifNotNil: [oldLabel delete].
	m := StringMorph contents: aString font: TextStyle defaultFont.
	self extent: m extent + (self borderWidth + 6).
	m position: self center - (m extent // 2).
	self addMorph: m.
	m lock! !


!BookMorph methodsFor: 'menu' stamp: 'mt 4/10/2018 11:17'!
bookmarkForThisPage
	"If this book exists on a server, make the reference via a URL"
	| bb url um |
	(url := self url) ifNil: [
		bb := SimpleButtonMorph new target: self.
		bb actionSelector: #goToPageMorph:fromBookmark:.
		bb label: 'Bookmark' translated.
		bb arguments: (Array with: currentPage with: bb).
		self primaryHand attachMorph: bb.
		^ bb].
	currentPage url ifNil: [currentPage saveOnURLbasic].
	um := URLMorph newForURL: currentPage url.
	um setURL: currentPage url page: currentPage sqkPage.
	(SqueakPage stemUrl: url) = (SqueakPage stemUrl: currentPage url) 
		ifTrue: [um book: true]
		ifFalse: [um book: url].  	"remember which book"
	um isBookmark: true; label: 'Bookmark' translated.
	um borderStyle: (BorderStyle raised width: 1).
	um color: (Color r: 0.4 g: 0.8 b: 0.6).
	self primaryHand attachMorph: um.
	^ um! !


!CalendarMorph methodsFor: 'building' stamp: 'mt 4/10/2018 11:19'!
newButtonWithContents: aByteString 
	^SimpleButtonMorph new 
		label: aByteString;
		color: (self color mixed: 0.5 with: Color gray);
		borderStyle: (BorderStyle raised width: 2)! !

!CalendarMorph methodsFor: 'building' stamp: 'mt 4/10/2018 11:21'!
newDateButtonWithContents: aByteString 
	^SimpleButtonMorph new
		label: aByteString;
		cornerStyle: #square;
		color: self color muchLighter;
		borderStyle: (BorderStyle raised width: 2);
		width: 30! !


!ChessMorph methodsFor: 'initialize' stamp: 'mt 5/4/2018 11:31'!
addButtonRow

	| r m |
	r := AlignmentMorph newRow hResizing: #shrinkWrap; vResizing: #shrinkWrap; color: Color transparent.
	r cellInset: 2.
	r addMorphBack: (self buttonName: '  New  ' translated action: #newGame).
	r addMorphBack: (self buttonName: '  Help  ' translated action: #findBestMove).
	r addMorphBack: (self buttonName: '  Play  ' translated action: #thinkAndMove).
	r addMorphBack: (self buttonName: '  Auto  ' translated action: #autoPlay).
	r addMorphBack: (self buttonName: '  Undo  ' translated action: #undoMove).
	r addMorphBack: (self buttonName: '  Redo  ' translated action: #redoMove).
	r addMorphBack: (self buttonName: '  Quit  ' translated action: #delete).
	r disableTableLayout: true.
	r align: r bounds topLeft with: self layoutBounds topLeft.
	self addMorphFront: r.
	m := UpdatingStringMorph on: self selector: #statusString.
	m useStringFormat.
	m disableTableLayout: true.
	m align: m bounds topLeft with: r fullBounds bottomLeft.
	self addMorphFront: m.! !

!ChessMorph methodsFor: 'initialize' stamp: 'mt 5/4/2018 11:30'!
buttonName: aString action: aSymbol

	^ SimpleButtonMorph new
		target: self;
		label: aString;
		actionSelector: aSymbol;
		color: (Color gray: 0.8);  "old color"
		fillStyle: self buttonFillStyle;
		borderWidth: 1;
		borderRaised.
! !

!ChessMorph methodsFor: 'initialization' stamp: 'mt 5/4/2018 15:22'!
defaultBorderColor
	^ Color transparent! !

!ChessMorph methodsFor: 'initialization' stamp: 'mt 4/11/2018 08:49'!
defaultBorderStyle
	^ BorderStyle raised! !

!ChessMorph methodsFor: 'initialization' stamp: 'mt 5/4/2018 11:32'!
initialize
	"initialize the state of the receiver"
	super initialize.
	""
	animateMove := false.
	autoPlay := false.

	self cornerStyle: #square.
	self layoutPolicy: TableLayout new.
	self listDirection: #leftToRight;
		 wrapDirection: #bottomToTop.
	self addSquares.
	self addButtonRow.
	self newGame! !


!CommandTilesMorph methodsFor: 'initialization' stamp: 'mt 4/10/2018 11:53'!
initialize

	super initialize.
	self wrapCentering: #center; cellPositioning: #leftCenter.
	self hResizing: #shrinkWrap.
	self borderWidth: 0.
	self layoutInset: 0.
	self extent: 5@5.  "will grow to fit"
! !


!DialogWindow methodsFor: 'initialization' stamp: 'mt 4/11/2018 11:39'!
setDefaultParameters
	"change the receiver's appareance parameters"

	self
		color: (self userInterfaceTheme color ifNil: [Color white]);
		borderStyle: (self userInterfaceTheme borderStyle ifNil: [BorderStyle simple]) copy;
		borderColor: (self userInterfaceTheme borderColor ifNil: [Color gray]);
		borderWidth: (self userInterfaceTheme borderWidth ifNil: [1]);
		layoutInset: ((self class roundedDialogCorners and: [self class gradientDialog])
			"This check compensates a bug in balloon."
			ifTrue: [0] ifFalse: [self borderWidth negated asPoint]).

	Preferences menuAppearance3d ifTrue: [self addDropShadow].! !

!DialogWindow methodsFor: 'initialization' stamp: 'mt 4/11/2018 11:39'!
setTitleParameters

	(self submorphNamed: #title) ifNotNil: [:title |
		title
			fillStyle: (self class gradientDialog
				ifFalse: [SolidFillStyle color: (self userInterfaceTheme titleColor ifNil: [Color r: 0.658 g: 0.678 b: 0.78])]
				ifTrue: [self titleGradientFor: title from: (self userInterfaceTheme titleColor ifNil: [Color r: 0.658 g: 0.678 b: 0.78])]);
			borderStyle: (self userInterfaceTheme titleBorderStyle ifNil: [BorderStyle simple]) copy;
			borderColor: (self userInterfaceTheme titleBorderColor ifNil: [Color r: 0.6 g: 0.7 b: 1]);
			borderWidth: (self userInterfaceTheme titleBorderWidth ifNil: [0]);
			cornerStyle: (self wantsRoundedCorners ifTrue: [#rounded] ifFalse: [#square]);
			vResizing: #shrinkWrap;
			hResizing: #spaceFill;
			wrapCentering: #center;
			cellPositioning: #center;
			cellInset: 0;
			layoutInset: (5@3 corner: 5@ (2+(self wantsRoundedCorners ifFalse: [0] ifTrue: [self cornerRadius])))].
	
	titleMorph ifNotNil: [
		| fontToUse colorToUse |
		fontToUse := self userInterfaceTheme titleFont ifNil: [TextStyle defaultFont].
		colorToUse := self userInterfaceTheme titleTextColor ifNil: [Color black].
	
		"Temporary HACK for 64-bit CI build. Can be removed in the future."
		titleMorph contents isText ifFalse: [^ self].
	
		titleMorph contents
			addAttribute: (TextFontReference toFont: fontToUse);
			addAttribute: (TextColor color: colorToUse).
		titleMorph releaseParagraph; changed].! !


!DockingBarMorph methodsFor: 'initialize-release' stamp: 'mt 4/11/2018 11:39'!
setDefaultParameters
	"private - set the default parameter using Preferences as the inspiration source"

	self
		color: (self userInterfaceTheme color ifNil: [Color r: 0.9 g: 0.9 b: 0.9]);
		borderStyle: (self userInterfaceTheme borderStyle ifNil: [BorderStyle simple]) copy;
		borderColor: (self userInterfaceTheme borderColor ifNil: [Color gray]);
		borderWidth: (self userInterfaceTheme borderWidth ifNil: [0]).
		
	self extent: (Preferences standardMenuFont height asPoint).! !

!DockingBarMorph methodsFor: 'update' stamp: 'mt 4/11/2018 11:42'!
applyUserInterfaceTheme

	| colorToUse |
	gradientRamp := nil.
	
	super applyUserInterfaceTheme.
	
	self setDefaultParameters.
	
	"Update properties of separating lines."
	colorToUse := self userInterfaceTheme lineColor ifNil: [Color gray: 0.9].
	self submorphs
		select: [:ea | ea knownName = #line]
		thenDo: [:line |
			line
				color: colorToUse;
				extent: (self userInterfaceTheme lineWidth ifNil: [2]) asPoint;
				borderStyle: (self userInterfaceTheme lineStyle ifNil: [BorderStyle inset]) copy;
				borderColor: colorToUse].! !


!EToyProjectHistoryMorph methodsFor: 'as yet unclassified' stamp: 'mt 4/10/2018 11:23'!
rebuild

	| history r1 |
	history := ProjectHistory currentHistory mostRecentCopy.
	changeCounter := ProjectHistory changeCounter.
	self removeAllMorphs.
	self rubberBandCells: false. "enable growing"
	r1 := self addARow: {
		self inAColumn: {
			StringMorph new contents: 'Jump...' translated; lock.
		}.
	}.
	r1 on: #mouseUp send: #jumpToProject to: self.

	history do: [ :each |
		(
			self addARow: {
				(self inAColumn: {
					StretchyImageMorph new form: each second; minWidth: 35; minHeight: 35; lock
				}) vResizing: #spaceFill.
				self inAColumn: {
					StringMorph new contents: each first; lock.
					"StringMorph new contents: each fourth first; lock."
				}.
				(self inAColumn: {
					StringMorph new
						color: Color red;
						contents: 'X';
						on: #mouseDown send: #confirmedDelete:evt:from: to: self withValue: each fourth first
				}) hResizing: #rigid.
			}
		)
			color: Color paleYellow;
			borderStyle: (BorderStyle raised width: 1);
			vResizing: #spaceFill;
			on: #mouseUp send: #mouseUp:in: to: self;
			on: #mouseDown send: #mouseDown:in: to: self;
			on: #mouseMove send: #mouseMove:in: to: self;
			on: #mouseLeave send: #mouseLeave:in: to: self;
			setProperty: #projectParametersTuple toValue: each;
			setBalloonText: (each third isEmptyOrNil ifTrue: ['not saved'] ifFalse: [each third])
	].
"---
	newTuple := {
		aProject name.
		aProject thumbnail.
		aProject url.
		WeakArray with: aProject.
	}.
---"! !

!EToyProjectHistoryMorph methodsFor: 'initialization' stamp: 'mt 5/4/2018 15:53'!
defaultBorderColor
	^ Color transparent! !

!EToyProjectHistoryMorph methodsFor: 'initialization' stamp: 'mt 4/11/2018 08:49'!
defaultBorderStyle
	^ BorderStyle raised! !


!EllipseMorph methodsFor: 'drawing' stamp: 'mt 4/10/2018 11:43'!
drawOn: aCanvas 

	aCanvas isShadowDrawing
		ifTrue: [^ aCanvas fillOval: self bounds fillStyle: self fillStyle borderWidth: 0 borderColor: nil].
	aCanvas fillOval: self bounds fillStyle: self fillStyle borderWidth: self borderWidth borderColor: self borderColor.
! !

!EllipseMorph methodsFor: '*60Deprecated-accessing' stamp: 'mt 4/11/2018 08:56'!
doesBevels
	self deprecated: 'Use border styles such as InsetBorder or RaisedBorder.'.
	^ false! !


!EmbeddedWorldBorderMorph methodsFor: 'as yet unclassified' stamp: 'mt 4/10/2018 11:53'!
myWorldChanged
	| trans |
	trans := self myTransformation.
	self changed.
	self layoutChanged.
	trans ifNotNil:[
		trans extentFromParent: self innerBounds extent.
		bounds := self bounds topLeft extent: trans extent + (self borderWidth * 2).
	].
	self changed.
! !

!EmbeddedWorldBorderMorph methodsFor: 'boxes' stamp: 'mt 4/10/2018 11:53'!
genericBoxArea: countDownFromTop

	^self innerBounds right @ (self top + (countDownFromTop * 2 * self borderWidth)) 
		extent: self borderWidth asPoint
! !


!EventRecorderMorph methodsFor: 'initialization' stamp: 'mt 5/4/2018 15:53'!
defaultBorderColor
	^ Color transparent! !

!EventRecorderMorph methodsFor: 'initialization' stamp: 'mt 4/11/2018 08:49'!
defaultBorderStyle
	^ BorderStyle raised! !


!FreeCell methodsFor: 'private' stamp: 'mt 4/10/2018 11:25'!
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);
		color: Color gray.
	a := AlignmentMorph newColumn
		wrapCentering: #center; cellPositioning: #topCenter;
		hResizing: #shrinkWrap;
		vResizing: #shrinkWrap;
		color: Color transparent;
		layoutInset: 1.
	a addMorph: aButton.
	^ a

! !

!FreeCell methodsFor: 'initialization' stamp: 'mt 4/10/2018 10:58'!
makeControlBar

	^AlignmentMorph newRow
		color: self colorNearBottom;
		borderStyle: (BorderStyle inset width: 2);
		layoutInset: 0;
		hResizing: #spaceFill; vResizing: #shrinkWrap; wrapCentering: #center; cellPositioning: #leftCenter;
		yourself.! !


!GradientEditor methodsFor: 'initialization' stamp: 'mt 4/10/2018 10:59'!
initialize
	super initialize.
	self myLayout.
	self extent: 500 @ 200.
	row := RectangleMorph new extent: self width @ 100;
				 color: Color transparent;
				 borderStyle: BorderStyle inset.
	row addMorph: (gradientDisplay := GradientDisplayMorph new position: 20 @ 20;
					 extent: self width - 40 @ 40).
	gradientDisplay fillStyle direction: gradientDisplay width @ 0.
	self addMorph: row.
	self addButtonRow.
	self addMorph: self colorRampExpressionMorph! !


!GradientFillMorph methodsFor: 'initialization' stamp: 'mt 4/10/2018 11:56'!
initialize
	super initialize.
	self borderWidth: 0.
	fillColor2 := Color black.
	gradientDirection := #vertical! !


!GraphMorph methodsFor: 'commands' stamp: 'mt 4/10/2018 11:56'!
centerCursor
	"Scroll so that the cursor is as close as possible to the center of my window."

	| w |
	w := self width - (2 * self borderWidth).
	self startIndex: ((cursor - (w // 2)) max: 1).
! !

!GraphMorph methodsFor: 'event handling' stamp: 'mt 4/11/2018 08:10'!
mouseMove: evt

	| x w |
	x := evt cursorPoint x - (self bounds left + self borderWidth).
	w := self width - (2 * self borderWidth).

	self changed.
	x < 0 ifTrue: [
		cursor := startIndex + (3 * x).
		cursor := (cursor max: 1) min: data size.
		^ self startIndex: cursor].
	x > w ifTrue: [
		cursor := startIndex + w + (3 * (x - w)).
		cursor := (cursor max: 1) min: data size.
		^ self startIndex: cursor - w].

	cursor := ((startIndex + x) max: 1) min: data size.
! !

!GraphMorph methodsFor: 'private' stamp: 'mt 4/10/2018 11:57'!
drawDataOn: aCanvas

	| yScale baseLine x start end value left top bottom right |
	super drawOn: aCanvas.

	data isEmpty ifTrue: [^ self].
	maxVal = minVal ifTrue: [
		yScale := 1.
	] ifFalse: [
		yScale := (self bounds height - (2 * self borderWidth)) asFloat / (maxVal - minVal)].
	baseLine := self bounds bottom - self borderWidth + (minVal * yScale) truncated.
	left := top := 0. right := 10. bottom := 0.
	x := self bounds left + self borderWidth.
	start := (startIndex asInteger max: 1) min: data size.
	end := (start + self bounds width) min: data size.
	start to: end do: [:i |
		left := x truncated. right := x + 1.
		right > (self bounds right - self borderWidth) ifTrue: [^ self].
		value := (data at: i) asFloat.
		value >= 0.0 ifTrue: [
			top := baseLine - (yScale * value) truncated.
			bottom := baseLine.
		] ifFalse: [
			top := baseLine.
			bottom := baseLine - (yScale * value) truncated].
		aCanvas fillRectangle: (left@top corner: right@bottom) color: dataColor.
		x := x + 1].
! !

!GraphMorph methodsFor: 'private' stamp: 'mt 4/11/2018 08:10'!
keepIndexInView: index

	| w newStart |
	w := self bounds width - (2 * self borderWidth).
	index < startIndex ifTrue: [
		newStart := index - w + 1.
		^ self startIndex: (newStart max: 1)].
	index > (startIndex + w) ifTrue: [
		^ self startIndex: (index min: data size)].
! !


!MagnifierMorph methodsFor: 'geometry' stamp: 'mt 4/11/2018 08:12'!
defaultExtent
	^(srcExtent * magnification) truncated + (2 * self borderWidth)! !

!MagnifierMorph methodsFor: 'geometry' stamp: 'mt 4/11/2018 08:12'!
extent: aPoint
	"Round to multiples of magnification"
	srcExtent := (aPoint - (2 * self borderWidth)) // magnification.
	^super extent: self defaultExtent! !


!FishEyeMorph methodsFor: 'geometry' stamp: 'mt 4/10/2018 11:56'!
extent: aPoint
	"Round to a number divisible by grid.  Note that the superclass has its own implementation."
	| g gridSize |
	gridSize := self gridSizeFor: aPoint.
	"self halt."
	g := (aPoint - (2 * self borderWidth)) // gridSize.
	srcExtent := g * gridSize.
	gridNum := g.
	^super extent: self defaultExtent! !


!MenuMorph methodsFor: 'initialization' stamp: 'mt 4/11/2018 11:40'!
setDefaultParameters
	"change the receiver's appareance parameters"

	self
		color: (self userInterfaceTheme color ifNil: [Color r: 0.9 g: 0.9 b: 0.9]);
		borderStyle: (self userInterfaceTheme borderStyle ifNil: [BorderStyle simple]) copy;
		borderColor: (self userInterfaceTheme borderColor ifNil: [Color gray]);
		borderWidth: (self userInterfaceTheme borderWidth ifNil: [1]).

	Preferences menuAppearance3d ifTrue: [self addDropShadow].
	
	self layoutInset: 3.
! !

!MenuMorph methodsFor: 'initialization' stamp: 'mt 4/11/2018 11:40'!
setTitleParametersFor: aMenuTitle 

	aMenuTitle
		color: (self userInterfaceTheme titleColor ifNil: [Color transparent]);
		borderStyle: (self userInterfaceTheme titleBorderStyle ifNil: [BorderStyle simple]) copy;
		borderColor: (self userInterfaceTheme titleBorderColor ifNil: [Color r: 0.6 g: 0.7 b: 1]);
		borderWidth: (self userInterfaceTheme titleBorderWidth ifNil: [0]);
		cornerStyle: (self wantsRoundedCorners ifTrue: [#rounded] ifFalse: [#square]);
		vResizing: #shrinkWrap;
		wrapCentering: #center;
		cellPositioning: #center;
		cellInset: 5;
		layoutInset: (5@0 corner: 5@0).! !

!MenuMorph methodsFor: 'update' stamp: 'mt 4/11/2018 11:42'!
applyUserInterfaceTheme

	| colorToUse |
	super applyUserInterfaceTheme.
	
	self setDefaultParameters.
	
	"Update properties of separating lines."
	colorToUse := self userInterfaceTheme lineColor ifNil: [Color gray: 0.9].
	self submorphs
		select: [:ea | ea knownName = #line]
		thenDo: [:line |
			line
				color: colorToUse;
				height: (self userInterfaceTheme lineWidth ifNil: [2]);
				borderStyle: (self userInterfaceTheme lineStyle ifNil: [BorderStyle inset]) copy;
				borderColor: colorToUse].! !


!MidiInputMorph methodsFor: 'as yet unclassified' stamp: 'mt 4/10/2018 11:28'!
addChannelControlsFor: channelIndex

	| r divider col |
	r := self makeRow
		hResizing: #shrinkWrap;
		vResizing: #shrinkWrap.
	r addMorphBack: (self channelNumAndMuteButtonFor: channelIndex).
	r addMorphBack: (Morph new extent: 10@5; color: color).  "spacer"
	r addMorphBack: (self panAndVolControlsFor: channelIndex).

	divider := AlignmentMorph new
		extent: 10@1;
		layoutInset: 0;
		borderStyle: (BorderStyle raised width: 1);
		color: color;
		hResizing: #spaceFill;
		vResizing: #rigid.

	col := self lastSubmorph.
	col addMorphBack: divider.
	col addMorphBack: r.
! !

!MidiInputMorph methodsFor: 'as yet unclassified' stamp: 'mt 4/10/2018 11:28'!
makeControls

	| bb r reverbSwitch onOffSwitch |
	bb := SimpleButtonMorph new
		target: self;
		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@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;
		label: 'On';
		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;
		label: 'Reverb Disable';
		actionSelector: #disableReverb:;
		target: self;
		setSwitchState: SoundPlayer isReverbOn not.
	r addMorphBack: reverbSwitch.
	^ r
! !


!Mines methodsFor: 'initialize' stamp: 'mt 4/10/2018 11:28'!
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);
		color: color.
	a := AlignmentMorph newColumn
		wrapCentering: #center; cellPositioning: #topCenter;
		hResizing: #spaceFill;
		vResizing: #shrinkWrap;
		color: color.
	a addMorph: aButton.
	^ a

! !

!Mines methodsFor: 'initialize' stamp: 'mt 4/10/2018 11:00'!
makeControls
	| row |
	row := AlignmentMorph newRow color: color;
				 borderWidth: 2;
				 layoutInset: 3.
	row borderStyle: BorderStyle inset.
	row hResizing: #spaceFill;
		 vResizing: #shrinkWrap;
		 wrapCentering: #center;
		 cellPositioning: #leftCenter;
		 extent: 5 @ 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 
	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 @ 15.
	row
		addMorph: (self wrapPanel: minesDisplay label: 'Mines:' translated).
	timeDisplay := LedTimerMorph new digits: 3;
				 extent: 3 * 10 @ 15.
	row
		addMorph: (self wrapPanel: timeDisplay label: 'Time:' translated).
	^ row! !

!Mines methodsFor: 'initialization' stamp: 'mt 5/4/2018 15:20'!
defaultBorderColor
	^ Color transparent! !

!Mines methodsFor: 'initialization' stamp: 'mt 4/11/2018 08:49'!
defaultBorderStyle
	^ BorderStyle raised! !


!MinesBoard methodsFor: 'initialization' stamp: 'mt 5/4/2018 15:19'!
defaultBorderColor
	^ Color transparent! !

!MinesBoard methodsFor: 'initialization' stamp: 'mt 4/11/2018 08:49'!
defaultBorderStyle
	^ BorderStyle inset! !


!NebraskaCommunicatorMorph methodsFor: 'collaborative' stamp: 'mt 4/10/2018 11:30'!
addGateKeeperMorphs

	| list currentTime choices |

	self setProperty: #gateKeeperCounterValue toValue: NebraskaGateKeeperMorph updateCounter.
	choices := #(
		(60 'm' 'in the last minute')
		(3600 'h' 'in the last hour')
		(86400 'd' 'in the last day')
	).
	currentTime := Time totalSeconds.
	list := NebraskaGateKeeperMorph knownIPAddresses.
	list do: [ :each | | age row |
		age := each timeBetweenLastAccessAnd: currentTime.
		age := choices
			detect: [ :x | age <= x first]
			ifNone: [{0. '-'. (age // 86400) printString,'days ago'}].
		row := self addARow:
		(NebraskaIncomingMessage allTypes collect: [ :type |
				self toggleButtonFor: each attribute: type]
		),
		{

			(self inAColumn: {
				(StringMorph contents: age second) lock.
			}) layoutInset: 2; hResizing: #shrinkWrap; setBalloonText: 'Last attempt was ',age third.

			(self inAColumn: {
				(StringMorph contents: each ipAddress) lock.
			}) layoutInset: 2; hResizing: #shrinkWrap.

			(self inAColumn: {
				(StringMorph contents: each latestUserName) lock.
			}) layoutInset: 2.
		}.
		row
			color: (Color r: 0.6 g: 0.8 b: 1.0);
			borderStyle: (BorderStyle raised width: 1);
			vResizing: #spaceFill;
			"on: #mouseUp send: #mouseUp:in: to: self;"
			setBalloonText: each fullInfoString
	].! !


!NebraskaFridgeMorph methodsFor: 'initialization' stamp: 'mt 5/4/2018 15:53'!
defaultBorderColor
	^ Color transparent! !

!NebraskaFridgeMorph methodsFor: 'initialization' stamp: 'mt 4/11/2018 08:49'!
defaultBorderStyle
	^ BorderStyle raised! !

!NebraskaFridgeMorph methodsFor: 'as yet unclassified' stamp: 'mt 4/11/2018 08:12'!
rebuild

	| row filler fudge people maxPerRow insetY |

	updateCounter := self class updateCounter.
	self removeAllMorphs.
	(self addARow: {
		filler := Morph new color: Color transparent; extent: 4@4.
	}) vResizing: #shrinkWrap.
	self addARow: {
		(StringMorph contents: 'the Fridge' translated) lock.
		self groupToggleButton.
	}.
	row := self addARow: {}.
	people := self class fridgeRecipients.
	maxPerRow := people size < 7 ifTrue: [2] ifFalse: [3].	
		"how big can this get before we need a different approach?"
	people do: [ :each |
		row submorphCount >= maxPerRow ifTrue: [row := self addARow: {}].
		row addMorphBack: (
			groupMode ifTrue: [
				(each userPicture scaledToSize: 35@35) asMorph lock
			] ifFalse: [
				each veryDeepCopy killExistingChat
			]
		)
	].
	fullBounds := nil.
	self fullBounds.
	"htsBefore := submorphs collect: [ :each | each height]."

	fudge := 20.
	insetY := self layoutInset.
	insetY isPoint ifTrue: [insetY := insetY y].
	filler extent: 
		4 @ (self height - filler height * 0.37 - insetY - self borderWidth - fudge) truncated.

	"self fixLayout.
	htsAfter := submorphs collect: [ :each | each height].
	{htsBefore. htsAfter} explore."

! !


!NebraskaGateKeeperMorph methodsFor: 'initialization' stamp: 'mt 5/4/2018 15:52'!
defaultBorderColor
	^ Color transparent! !

!NebraskaGateKeeperMorph methodsFor: 'initialization' stamp: 'mt 4/11/2018 08:49'!
defaultBorderStyle
	^ BorderStyle raised! !


!NebraskaServerMorph methodsFor: 'initialization' stamp: 'mt 4/10/2018 11:32'!
setColorsAndBorder
	| worldColor c |
	c := ((Preferences menuColorFromWorld and: [Display depth > 4]) 
				and: [(worldColor := self currentWorld color) isColor]) 
					ifTrue: 
						[worldColor luminance > 0.7 
							ifTrue: [worldColor mixed: 0.8 with: Color black]
							ifFalse: [worldColor mixed: 0.4 with: Color white]]
					ifFalse: [Color r: 0.9 g: 0.9 b: 0.9]. 
	self color: c.
	self borderStyle: (BorderStyle raised width: 1).
	self useRoundedCorners! !


!NewHandleMorph methodsFor: 'all' stamp: 'mt 4/11/2018 08:13'!
followHand: aHand forEachPointDo: block1 lastPointDo: block2 withCursor: aCursor
	
	hand := aHand.
	hand showTemporaryCursor: aCursor "hotSpotOffset: aCursor offset negated".
	
	color := Color transparent.
	pointBlock := block1.
	lastPointBlock := block2.
	
	self borderWidth: 0.
	self position: hand lastEvent cursorPoint - (self extent // 2)! !


!NewVariableDialogMorph methodsFor: 'build' stamp: 'mt 4/10/2018 11:32'!
buildDecimalPlacesButton
	| button |
	button := SimpleButtonMorph new					
		labelString: self decimalPlaces asString font: Preferences standardEToysButtonFont;
		color: (Color r: 0.806 g: 1.0 b: 0.645);
		target: self;
		actionSelector: #chooseDecimalPlaces;
		extent: 200 @ (TextStyle defaultFont height + 10);
		cornerStyle: #square;
		borderStyle: BorderStyle raised;
		yourself.
	self addArrowsOn: button.
	^ button
	! !

!NewVariableDialogMorph methodsFor: 'build' stamp: 'mt 4/10/2018 11:32'!
buildVarTypeButton
	| button |
	button := SimpleButtonMorph new					
		labelString: self varType translated font: Preferences standardEToysButtonFont;
		color: (Color r: 0.806 g: 1.0 b: 0.645);
		target: self;
		actionSelector: #chooseType;
		extent: 200 @ (TextStyle defaultFont height + 10);
		cornerStyle: #square;
		borderStyle: BorderStyle raised;
		yourself.
	self addArrowsOn: button.
	^ button
	! !


!PBNumericPreferenceView methodsFor: 'user interface' stamp: 'mt 5/4/2018 16:34'!
textField
	^(PluggableTextMorph
		on: self
		text: #preferenceValue
		accept: #preferenceValue:)
			borderStyle: BorderStyle inset;
			borderWidth: 1;
			hideScrollBarsIndefinitely;
			acceptOnCR: true;
			vResizing: #rigid;
			hResizing: #spaceFill;
			height: TextStyle defaultFont height + 6;
			yourself.! !


!PBTextPreferenceView methodsFor: 'user interface' stamp: 'mt 5/4/2018 16:34'!
textField
	^(PluggableTextMorph
		on: self
		text: #preferenceValue
		accept: #preferenceValue:)
			hideScrollBarsIndefinitely;
			borderStyle: BorderStyle inset;
			borderWidth: 1;
			vResizing: #rigid;
			hResizing: #spaceFill;
			height: TextStyle defaultFont height + 6;
			yourself.! !


!PBClassPreferenceView methodsFor: 'user interface' stamp: 'mt 5/4/2018 16:34'!
textField

	| field |
	field := PluggableTextMorphPlus
		on: self
		text: #preferenceValue
		accept: #preferenceValue:.
	field
		borderStyle: BorderStyle inset;
		borderWidth: 1;
		hideScrollBarsIndefinitely;
		acceptOnCR: true;
		minimumHeight: 0;
		vResizing: #rigid;
		hResizing: #spaceFill;
		height: TextStyle defaultFont height + 6.
	
	styler ifNotNil: [:s | field styler: (s view: field)].
	
	^ field! !


!PianoKeyboardMorph methodsFor: 'simple keyboard' stamp: 'mt 4/11/2018 08:13'!
buildKeyboard
	| wtWid bkWid keyRect octavePt nWhite nBlack |
	self removeAllMorphs.
	wtWid := 8. bkWid := 5.
	self extent: 10 @ 10.
	1 to: nOctaves + 1 do:
		[:i | i <= nOctaves ifTrue: [nWhite := 7.  nBlack := 5]
						ifFalse: [nWhite := 1.  nBlack := 0 "High C"].
		octavePt := self innerBounds topLeft + ((7 * wtWid * (i - 1) - 1) @ -1).
		1 to: nWhite do:
			[:j | keyRect := octavePt + (j - 1 * wtWid @ 0) extent: (wtWid + 1) @ 36.
			self addMorph: ((RectangleMorph newBounds: keyRect color: whiteKeyColor)
								borderWidth: 1;
				on: #mouseDown send: #mouseDownPitch:event:noteMorph: to: self
								withValue: i - 1 * 12 + (#(1 3 5 6 8 10 12) at: j))].
		1 to: nBlack do:
			[:j | keyRect := octavePt + ((#(6 15 29 38 47) at: j) @ 1) extent: bkWid @ 21.
			self addMorph: ((Morph newBounds: keyRect color: blackKeyColor)
				on: #mouseDown send: #mouseDownPitch:event:noteMorph: to: self
								withValue: i - 1 * 12 + (#(2 4 7 9 11) at: j))]].
	self submorphsDo:
		[:m | m on: #mouseMove send: #mouseMovePitch:event:noteMorph: to: self;
				on: #mouseUp send: #mouseUpPitch:event:noteMorph: to: self;
				on: #mouseEnterDragging send: #mouseDownPitch:event:noteMorph: to: self;
				on: #mouseLeaveDragging send: #mouseUpPitch:event:noteMorph: to: self].
	self extent: (self fullBounds extent + self borderWidth - 1)! !


!KeyboardMorphForInput methodsFor: 'initialization' stamp: 'mt 4/11/2018 08:12'!
addRecordingControls
	| button switch playRow durRow articRow modRow |

	"Add chord, rest and delete buttons"
	playRow := AlignmentMorph newRow.
	playRow color: color; borderWidth: 0; layoutInset: 0.
	playRow hResizing: #shrinkWrap; vResizing: #shrinkWrap; extent: 5@5.
	switch := SimpleSwitchMorph new target: self; borderWidth: 2;
		offColor: color; onColor: (Color r: 1.0 g: 0.6 b: 0.6); setSwitchState: false.
	playRow addMorphBack: (switch label: 'chord' translated; actionSelector: #buildChord:).
	button := SimpleButtonMorph new target: self;
		borderStyle: (BorderStyle raised width: 2); color: color.
	playRow addMorphBack: (button label: '          rest          ' translated; actionSelector: #emitRest).
	button := SimpleButtonMorph new target: self;
		borderStyle: (BorderStyle raised width: 2); color: color.
	playRow addMorphBack: (button label: 'del' translated; actionSelector: #deleteNotes).
	self addMorph: playRow.
	playRow align: playRow fullBounds topCenter
			with: self fullBounds bottomCenter.

	"Add note duration buttons"
	durRow := AlignmentMorph newRow.
	durRow color: color; borderWidth: 0; layoutInset: 0.
	durRow hResizing: #shrinkWrap; vResizing: #shrinkWrap; extent: 5@5.
	switch := SimpleSwitchMorph new target: self; borderWidth: 2;
		offColor: color; onColor: (Color r: 1.0 g: 0.6 b: 0.6); setSwitchState: false.
	durRow addMorphBack: (switch label: 'whole' translated;
				actionSelector: #duration:onOff:; arguments: #(1)).
	switch := SimpleSwitchMorph new target: self; borderWidth: 2;
		offColor: color; onColor: (Color r: 1.0 g: 0.6 b: 0.6); setSwitchState: false.
	durRow addMorphBack: (switch label: 'half' translated;
				actionSelector: #duration:onOff:; arguments: #(2)).
	switch := SimpleSwitchMorph new target: self; borderWidth: 2;
		offColor: color; onColor: (Color r: 1.0 g: 0.6 b: 0.6); setSwitchState: false.
	durRow addMorphBack: (switch label: 'quarter' translated;
				actionSelector: #duration:onOff:; arguments: #(4)).
	switch := SimpleSwitchMorph new target: self; borderWidth: 2;
		offColor: color; onColor: (Color r: 1.0 g: 0.6 b: 0.6); setSwitchState: false.
	durRow addMorphBack: (switch label: 'eighth' translated;
				actionSelector: #duration:onOff:; arguments: #(8)).
	switch := SimpleSwitchMorph new target: self; borderWidth: 2;
		offColor: color; onColor: (Color r: 1.0 g: 0.6 b: 0.6); setSwitchState: false.
	durRow addMorphBack: (switch label: 'sixteenth' translated;
				actionSelector: #duration:onOff:; arguments: #(16)).
	self addMorph: durRow.
	durRow align: durRow fullBounds topCenter
			with: playRow fullBounds bottomCenter.

	"Add note duration modifier buttons"
	modRow := AlignmentMorph newRow.
	modRow color: color; borderWidth: 0; layoutInset: 0.
	modRow hResizing: #shrinkWrap; vResizing: #shrinkWrap; extent: 5@5.
	switch := SimpleSwitchMorph new target: self; borderWidth: 2;
		offColor: color; onColor: (Color r: 1.0 g: 0.6 b: 0.6); setSwitchState: false.
	modRow addMorphBack: (switch label: 'dotted' translated;
				actionSelector: #durMod:onOff:; arguments: #(dotted)).
	switch := SimpleSwitchMorph new target: self; borderWidth: 2;
		offColor: color; onColor: (Color r: 1.0 g: 0.6 b: 0.6); setSwitchState: false.
	modRow addMorphBack: (switch label: 'normal' translated;
				actionSelector: #durMod:onOff:; arguments: #(normal)).
	switch := SimpleSwitchMorph new target: self; borderWidth: 2;
		offColor: color; onColor: (Color r: 1.0 g: 0.6 b: 0.6); setSwitchState: false.
	modRow addMorphBack: (switch label: 'triplets' translated;
				actionSelector: #durMod:onOff:; arguments: #(triplets)).
	switch := SimpleSwitchMorph new target: self; borderWidth: 2;
		offColor: color; onColor: (Color r: 1.0 g: 0.6 b: 0.6); setSwitchState: false.
	modRow addMorphBack: (switch label: 'quints' translated;
				actionSelector: #durMod:onOff:; arguments: #(quints)).
	self addMorph: modRow.
	modRow align: modRow fullBounds topCenter
			with: durRow fullBounds bottomCenter.

	"Add articulation buttons"
	articRow := AlignmentMorph newRow.
	articRow color: color; borderWidth: 0; layoutInset: 0.
	articRow hResizing: #shrinkWrap; vResizing: #shrinkWrap; extent: 5@5.
	switch := SimpleSwitchMorph new target: self; borderWidth: 2;
		offColor: color; onColor: (Color r: 1.0 g: 0.6 b: 0.6); setSwitchState: false.
	articRow addMorphBack: (switch label: 'legato' translated;
				actionSelector: #articulation:onOff:; arguments: #(legato)).
	switch := SimpleSwitchMorph new target: self; borderWidth: 2;
		offColor: color; onColor: (Color r: 1.0 g: 0.6 b: 0.6); setSwitchState: false.
	articRow addMorphBack: (switch label: 'normal' translated;
				actionSelector: #articulation:onOff:; arguments: #(normal)).
	switch := SimpleSwitchMorph new target: self; borderWidth: 2;
		offColor: color; onColor: (Color r: 1.0 g: 0.6 b: 0.6); setSwitchState: false.
	articRow addMorphBack: (switch label: 'staccato' translated;
				actionSelector: #articulation:onOff:; arguments: #(staccato)).
	self addMorph: articRow.
	articRow align: articRow fullBounds topCenter
			with: modRow fullBounds bottomCenter.

	self bounds: (self fullBounds expandBy: (0@0 extent: 0 @ self borderWidth))
! !


!PianoRollScoreMorph methodsFor: 'drawing' stamp: 'mt 4/11/2018 08:13'!
addNotes
	"Recompute the set of morphs that should be visible at the current scroll position."

	| visibleMorphs rightEdge topEdge rightEdgeTime |
	visibleMorphs := OrderedCollection new: 500.
	rightEdge := self right - self borderWidth.
	rightEdgeTime := self timeForX: rightEdge.
	topEdge := self top + self borderWidth + 1.

	"Add ambient morphs first (they will be front-most)"
	score eventMorphsWithTimeDo:
		[:m :t | m addMorphsTo: visibleMorphs pianoRoll: self eventTime: t
					betweenTime: leftEdgeTime and: rightEdgeTime].

	"Then add note morphs"
	score tracks withIndexDo:
		[:track :trackIndex | | done n i nRight nTop nLeft trackColor |
		trackColor := colorForTrack at: trackIndex.
		i := indexInTrack at: trackIndex.
		done := scorePlayer mutedForTrack: trackIndex.
		[done | (i > track size)] whileFalse: [
			n := track at: i.
			(n isNoteEvent and: [n midiKey >= lowestNote]) ifTrue: [
				n time > rightEdgeTime
					ifTrue: [done := true]
					ifFalse: [
						nLeft := self xForTime: n time.
						nTop := (self yForMidiKey: n midiKey) - 1.
						nTop > topEdge ifTrue: [
							nRight := nLeft + (n duration * timeScale) truncated - 1.
							visibleMorphs add:
								((PianoRollNoteMorph
									newBounds: (nLeft@nTop corner: nRight@(nTop + 3))
									color: trackColor)
									trackIndex: trackIndex indexInTrack: i)]]].
			i := i + 1].
			(selection notNil
				and: [trackIndex = selection first
				and: [i >= selection second and: [(indexInTrack at: trackIndex) <= selection third]]])
				ifTrue: [visibleMorphs do:
						[:vm | (vm isKindOf: PianoRollNoteMorph) ifTrue: [vm selectFrom: selection]]]].

	"Add the cursor morph in front of all notes; height and position are set later."
	cursor ifNil: [cursor := Morph newBounds: (self topLeft extent: 1@1) color: Color red].
	visibleMorphs addFirst: cursor.

	self changed.
	self removeAllMorphs.
	self addAllMorphs: visibleMorphs.
! !

!PianoRollScoreMorph methodsFor: 'drawing' stamp: 'mt 4/11/2018 08:13'!
drawMeasureLinesOn: aCanvas

	| ticksPerMeas x measureLineColor inner |
	showBeatLines ifNil: [showBeatLines := false].
	showMeasureLines ifNil: [showMeasureLines := true].
	notePerBeat ifNil: [self timeSignature: 4 over: 4].
	showBeatLines ifTrue:
		[measureLineColor := Color gray: 0.8.
		ticksPerMeas := score ticksPerQuarterNote.
		inner := self innerBounds.
		(leftEdgeTime + ticksPerMeas truncateTo: ticksPerMeas)
			to: ((self timeForX: self right - self borderWidth) truncateTo: ticksPerMeas)
			by: ticksPerMeas
			do: [:tickTime | x := self xForTime: tickTime.
				aCanvas fillRectangle: (x @ inner top extent: 1 @ inner height)
					color: measureLineColor]].

	showMeasureLines ifTrue:
		[measureLineColor := Color gray: 0.7.
		ticksPerMeas := beatsPerMeasure*score ticksPerQuarterNote*4//notePerBeat.
		inner := self innerBounds.
		(leftEdgeTime + ticksPerMeas truncateTo: ticksPerMeas)
			to: ((self timeForX: self right - self borderWidth) truncateTo: ticksPerMeas)
			by: ticksPerMeas
			do: [:tickTime | x := self xForTime: tickTime.
				aCanvas fillRectangle: (x @ inner top extent: 1 @ inner height)
						color: (tickTime = 0 ifTrue: [Color black] ifFalse: [measureLineColor])]].
! !

!PianoRollScoreMorph methodsFor: 'drawing' stamp: 'mt 4/11/2018 08:14'!
drawStaffOn: aCanvas

	| blackKeyColor l r topEdge y |
	self drawMeasureLinesOn: aCanvas.

	blackKeyColor := Color gray: 0.5.
	l := self left + self borderWidth.
	r := self right - self borderWidth.
	topEdge := self top + self borderWidth + 3.
	lowestNote to: 127 do: [:k |
		y := self yForMidiKey: k.
		y <= topEdge ifTrue: [^ self].  "over the top!!"
		(self isBlackKey: k) ifTrue: [
			aCanvas
				fillRectangle: (l@y corner: r@(y + 1))
				color: blackKeyColor]].
! !

!PianoRollScoreMorph methodsFor: 'geometry' stamp: 'mt 4/11/2018 08:14'!
midiKeyForY: y

	^ lowestNote - ((y - (bounds bottom - self borderWidth - 4)) // 3)
! !

!PianoRollScoreMorph methodsFor: 'geometry' stamp: 'mt 4/11/2018 08:14'!
timeForX: aNumber

	^ ((aNumber - self left - self borderWidth) asFloat / timeScale + leftEdgeTime) asInteger! !

!PianoRollScoreMorph methodsFor: 'geometry' stamp: 'mt 4/11/2018 08:14'!
xForTime: aNumber

	^ ((aNumber - leftEdgeTime) asFloat * timeScale) asInteger + self left + self borderWidth
! !

!PianoRollScoreMorph methodsFor: 'geometry' stamp: 'mt 4/11/2018 08:15'!
yForMidiKey: midiKey

	^ (self bottom - self borderWidth - 4) - (3 * (midiKey - lowestNote))
! !

!PianoRollScoreMorph methodsFor: 'scrolling' stamp: 'mt 4/11/2018 08:14'!
moveCursorToTime: scoreTime

	| cursorOffset desiredCursorHeight |
	scorePlayer isPlaying
		ifTrue:
			[cursorOffset := ((scoreTime - leftEdgeTime) asFloat * timeScale) asInteger.
			(cursorOffset < 0
				or: [cursorOffset > (self width-20)])
				ifTrue:
				[self goToTime: scoreTime - (20/timeScale).
				cursorOffset := ((scoreTime - leftEdgeTime) asFloat * timeScale) asInteger]]
		ifFalse:
			[self goToTime: (scoreTime - (self width//2 / timeScale)
							max: (self width//10 / timeScale) negated).
			cursorOffset := ((scoreTime - leftEdgeTime) asFloat * timeScale) asInteger].

	cursor position: (self left + self borderWidth + cursorOffset)@(self top + self borderWidth).
	desiredCursorHeight := self height.
	cursor height ~= desiredCursorHeight ifTrue: [cursor extent: 1@desiredCursorHeight].
! !


!PlayingCardDeck methodsFor: 'initialization' stamp: 'mt 4/11/2018 08:15'!
initialize
	super initialize.
	self cellPositioning: #topLeft.
	self reverseTableCells: true.
	self layout: #grid.
	self hResizing: #shrinkWrap.
	self vResizing: #shrinkWrap.
	self borderWidth: 0.
	self layoutInset: 0.
	stackingPolicy := #stagger.
	stackingOrder := #ascending.
	emptyDropPolicy := #any.
	self newSeed.
	^self! !


!PluggableButtonMorph methodsFor: 'initialization' stamp: 'mt 4/11/2018 11:40'!
setDefaultParameters
	"change the receiver's appareance parameters"

	self
		color: (self userInterfaceTheme color ifNil: [Color gray: 0.91]);
		borderStyle: (self userInterfaceTheme borderStyle ifNil: [BorderStyle default]) copy;
		borderColor: (self userInterfaceTheme borderColor ifNil: [Color gray]);
		borderWidth: (self userInterfaceTheme borderWidth ifNil: [1]);
		font: (self userInterfaceTheme font ifNil: [TextStyle defaultFont]);
		textColor: (self userInterfaceTheme textColor ifNil: [Color black]).

	borderColor := self borderColor.
	self	offColor: self color.! !


!PluggableButtonMorphPlus methodsFor: 'initialize-release' stamp: 'mt 5/4/2018 16:31'!
updateFillStylePressing: isPressing hovering: isHovering

	enabled ifFalse: [
		self color: (disabledColor ifNil: [Color transparent]).
		self borderStyle baseColor: disabledTextColor.
		^ self].
	
	super updateFillStylePressing: isPressing hovering: isHovering.! !


!PolygonMorph methodsFor: 'accessing' stamp: 'mt 4/11/2018 08:33'!
borderColor: aColor 
	"Recompute fillForm and borderForm if translucency of border changes."
	
	super borderColor: aColor.

	(self borderColor isColor and: [self borderColor isTranslucentColor]) 
		== (aColor isColor and: [aColor isTranslucentColor]) 
			ifFalse: [self releaseCachedState]! !

!PolygonMorph methodsFor: 'accessing' stamp: 'mt 4/10/2018 11:47'!
borderDashSpec
	^ borderDashSpec! !

!PolygonMorph methodsFor: 'accessing' stamp: 'mt 4/14/2018 09:55'!
borderStyle: aBorderStyle

	super borderStyle: aBorderStyle.
	self computeBounds! !

!PolygonMorph methodsFor: 'accessing' stamp: 'mt 4/11/2018 08:29'!
borderWidth: anInteger

	super borderWidth: anInteger.
	self computeBounds! !

!PolygonMorph methodsFor: 'drawing' stamp: 'mt 4/10/2018 11:45'!
drawArrowOn: aCanvas at: endPoint from: priorPoint 
	"Draw a triangle oriented along the line from priorPoint to  
	endPoint. Answer the wingBase."

	| pts spec wingBase |
	pts := self arrowBoundsAt: endPoint from: priorPoint.
	wingBase := pts size = 4 
				ifTrue: [pts third]
				ifFalse: [(pts copyFrom: 2 to: 3) average].
	spec := self valueOfProperty: #arrowSpec ifAbsent: [5 @ 4].
	spec x sign = spec y sign 
		ifTrue: [aCanvas drawPolygon: pts fillStyle: self borderColor]
		ifFalse: 
			[aCanvas 
				drawPolygon: pts
				fillStyle: Color transparent
				borderWidth: (self borderWidth + 1) // 2
				borderColor: self borderColor].
	^wingBase! !

!PolygonMorph methodsFor: 'drawing' stamp: 'mt 4/10/2018 11:45'!
drawArrowsOn: aCanvas 
	"Answer (possibly modified) endpoints for border drawing"
	"ArrowForms are computed only upon demand"
	| array |

	self hasArrows
		ifFalse: [^ #() ].
	"Nothing to do"

	array := Array with: vertices first with: vertices last.

	"Prevent crashes for #raised or #inset borders"
	self borderColor isColor
		ifFalse: [ ^array ].

	(arrows == #forward or: [arrows == #both])
		ifTrue: [ array at: 2 put: (self
				drawArrowOn: aCanvas
				at: vertices last
				from: self nextToLastPoint) ].

	(arrows == #back or: [arrows == #both])
		ifTrue: [ array at: 1 put: (self
				drawArrowOn: aCanvas
				at: vertices first
				from: self nextToFirstPoint) ].

	^array! !

!PolygonMorph methodsFor: 'drawing' stamp: 'mt 4/10/2018 11:47'!
drawDashedBorderOn: aCanvas usingEnds: anArray 
	"Display my border on the canvas. NOTE: mostly copied from  
	drawBorderOn:"
	| bevel topLeftColor bottomRightColor bigClipRect lineColor segmentOffset |
	(self borderColor isNil
			or: [self borderColor isColor
					and: [self borderColor isTransparent]])
		ifTrue: [^ self].
	lineColor := self borderColor.
	bevel := false.
	"Border colors for bevelled effects depend on CW ordering of  
	vertices"
	self borderStyle style == #raised
		ifTrue: [topLeftColor := self color lighter.
			bottomRightColor := self color darker.
			bevel := true].
	self borderStyle style == #inset
		ifTrue: [topLeftColor := owner colorForInsets darker.
			bottomRightColor := owner colorForInsets lighter.
			bevel := true].
	bigClipRect := aCanvas clipRect expandBy: self borderWidth + 1 // 2.
	segmentOffset := self borderDashOffset.
	self
		lineSegmentsDo: [:p1 :p2 | | p1i p2i | 
			p1i := p1 asIntegerPoint.
			p2i := p2 asIntegerPoint.
			self hasArrows
				ifTrue: ["Shorten line ends so as not to interfere with tip  
					of arrow."
					((arrows == #back
								or: [arrows == #both])
							and: [p1 = vertices first])
						ifTrue: [p1i := anArray first asIntegerPoint].
					((arrows == #forward
								or: [arrows == #both])
							and: [p2 = vertices last])
						ifTrue: [p2i := anArray last asIntegerPoint]].
			(closed
					or: ["bigClipRect intersects: (p1i rect: p2i)  
						optimized:"
						((p1i min: p2i)
							max: bigClipRect origin)
							<= ((p1i max: p2i)
									min: bigClipRect corner)])
				ifTrue: [bevel
						ifTrue: [lineColor := (p1i quadrantOf: p2i)
											> 2
										ifTrue: [topLeftColor]
										ifFalse: [bottomRightColor]].
					segmentOffset := aCanvas
								line: p1i
								to: p2i
								width: self borderWidth
								color: lineColor
								dashLength: self borderDashSpec first
								secondColor: self borderDashSpec third
								secondDashLength: self borderDashSpec second
								startingOffset: segmentOffset]]! !

!PolygonMorph methodsFor: 'drawing' stamp: 'mt 4/10/2018 11:48'!
drawOnFormCanvas: aCanvas 
	"Display the receiver, a spline curve, approximated by straight line segments."

	| |
	vertices size < 1 ifTrue: [self error: 'a polygon must have at least one point'].
	closed & color isTransparent not
		ifTrue: [aCanvas stencil: self filledForm at: self bounds topLeft - 1 color: self color].
	(self borderColor isColor and: [self borderColor isTranslucentColor])
		ifTrue: [aCanvas stencil: self borderForm at: self bounds topLeft
						color: self borderColor]
		ifFalse: [self drawBorderOn: aCanvas].
	self arrowForms do:
		[:f | aCanvas stencil: f at: f offset
			color: (self borderColor isColor ifTrue: [self borderColor] ifFalse: [self color])]! !

!PolygonMorph methodsFor: 'dropping/grabbing' stamp: 'mt 4/11/2018 08:16'!
justDroppedInto: newOwner event: evt

	| delta |
	(newOwner isKindOf: PasteUpMorph) ifTrue:
		["Compensate for border width so that gridded drop
			is consistent with gridded drag of handles."
		delta := self borderWidth+1//2.
		self position: (newOwner gridPoint: self position + delta) - delta].
	^ super justDroppedInto: newOwner event: evt! !

!PolygonMorph methodsFor: 'geometry testing' stamp: 'mt 4/11/2018 08:16'!
containsPoint: aPoint
	(super containsPoint: aPoint) ifFalse: [^ false].

	closed & color isTransparent not ifTrue:
		[^ (self filledForm pixelValueAt: aPoint - self topLeft + 1) > 0].

	self lineSegmentsDo:
		[:p1 :p2 |
		(aPoint onLineFrom: p1 to: p2 within: (3 max: self borderWidth+1//2) asFloat)
				ifTrue: [^ true]].

	self arrowForms do:
		[:f | (f pixelValueAt: aPoint - f offset) > 0 ifTrue: [^ true]].

	^ false! !

!PolygonMorph methodsFor: 'initialization' stamp: 'mt 4/14/2018 09:57'!
vertices: verts color: aColor borderWidth: borderWidthInteger borderColor: anotherColor 
	super initialize.
""
	vertices := verts.
	color := aColor.
		
	closed := vertices size > 2.
	arrows := #none.

	self borderStyle
		color: anotherColor;
		width: borderWidthInteger.

	self computeBounds! !

!PolygonMorph methodsFor: 'private' stamp: 'mt 4/11/2018 08:15'!
arrowBoundsAt: endPoint from: priorPoint 
	"Answer a triangle oriented along the line from priorPoint to endPoint."
	| d v angle wingBase arrowSpec length width |
	v := endPoint - priorPoint.
	angle := v degrees.
	d := self borderWidth max: 1.
	arrowSpec := self valueOfProperty: #arrowSpec ifAbsent: [5@4].
	length := arrowSpec x abs.  width := arrowSpec y abs.
	wingBase := endPoint + (Point r: d * length degrees: angle + 180.0).
	arrowSpec x >= 0
		ifTrue: [^ {	endPoint.
					wingBase + (Point r: d * width degrees: angle + 125.0).
					wingBase + (Point r: d * width degrees: angle - 125.0) }]
		ifFalse: ["Negative length means concave base."
				^ {	endPoint.
					wingBase + (Point r: d * width degrees: angle + 125.0).
					wingBase.
					wingBase + (Point r: d * width degrees: angle - 125.0) }]! !

!PolygonMorph methodsFor: 'private' stamp: 'mt 4/14/2018 09:55'!
computeBounds
	| oldBounds delta excludeHandles |
	
	self flag: #refactor. "mt: Make it lazy like all layout policies in Morph. See #fullBounds and #doLayoutIn:."
	
	vertices ifNil: [^ self].

	self changed.
	oldBounds := bounds.
	self releaseCachedState.
	bounds := self curveBounds expanded copy.
	self arrowForms do:
		[:f | bounds swallow: (f offset extent: f extent)].
	handles ifNotNil: [self updateHandles].

	"since we are directly updating bounds, see if any ordinary submorphs exist and move them accordingly"
	(oldBounds notNil and: [(delta := bounds origin - oldBounds origin) ~= (0@0)]) ifTrue: [
		excludeHandles := IdentitySet new.
		handles ifNotNil: [excludeHandles addAll: handles].
		self submorphsDo: [ :each |
			(excludeHandles includes: each) ifFalse: [
				each position: each position + delta
			].
		].
	].
	self layoutChanged.
	self changed.
! !

!PolygonMorph methodsFor: 'private' stamp: 'mt 4/11/2018 08:16'!
curveBounds
	"Compute the bounds from actual curve traversal, with 
	leeway for borderWidth. 
	Also note the next-to-first and next-to-last points for arrow 
	directions."
	"wiz - to avoid roundoff errors we return unrounded curvebounds."
	"we expect our receiver to take responsibility for approriate rounding adjustment."
	"hint: this is most likely 'self curveBounds expanded' "
	| pointAfterFirst pointBeforeLast  oX oY cX cY |
	self isCurvy
		ifFalse: [^ (Rectangle encompassing: vertices)
				expandBy: self borderWidth * 0.5 ].
	curveState := nil.
	"Force recomputation"
	"curveBounds := vertices first corner: vertices last."
	pointAfterFirst := nil.
	self
		lineSegmentsDo: [:p1 :p2 | 
			pointAfterFirst isNil
				ifTrue: [pointAfterFirst := p2 floor .
					oX := cX := p1 x.
					oY := cY := p1 y. ].
			"curveBounds := curveBounds encompass: p2 ."
			oX:= oX min: p2 x.
			cX := cX max: p2 x.
			oY := oY min: p2 y.
			cY := cY max: p2 y.
			pointBeforeLast := p1 floor ].
	curveState at: 2 put: pointAfterFirst.
	curveState at: 3 put: pointBeforeLast.
	^ ( oX @ oY corner: cX @ cY )  expandBy: self borderWidth * 0.5 ! !

!PolygonMorph methodsFor: 'private' stamp: 'mt 4/10/2018 11:48'!
filledForm
	"Note: The filled form is actually 2 pixels bigger than bounds, and the point corresponding to this morphs' position is at 1@1 in the form.  This is due to the details of the fillig routines, at least one of which requires an extra 1-pixel margin around the outside.  Computation of the filled form is done only on demand."
	| bb origin |
	closed ifFalse: [^ filledForm := nil].
	filledForm ifNotNil: [^ filledForm].
	filledForm := Form extent: bounds extent+2.

	"Draw the border..."
	bb := (BitBlt toForm: filledForm) sourceForm: nil; fillColor: Color black;
			combinationRule: Form over; width: 1; height: 1.
	origin := bounds topLeft asIntegerPoint-1.
	self lineSegmentsDo: [:p1 :p2 | bb drawFrom: p1 asIntegerPoint-origin
										to: p2 asIntegerPoint-origin].

	"Fill it in..."
	filledForm convexShapeFill: Color black.

	(self borderColor isColor and: [self borderColor isTranslucentColor]) ifTrue:
		["If border is stored as a form, then erase any overlap now."
		filledForm copy: self borderForm boundingBox from: self borderForm
			to: 1@1 rule: Form erase].

	^ filledForm! !


!EnvelopeLineMorph methodsFor: 'initialization' stamp: 'mt 4/10/2018 11:44'!
vertices: verts borderWidth: bw borderColor: bc 
	super initialize.
	vertices := verts.
	
	self borderWidth: bw.
	self borderColor: bc.
	
	closed := false.
	arrows := #none.
	self computeBounds! !


!ProjectNavigationMorph methodsFor: 'as yet unclassified' stamp: 'mt 4/10/2018 11:33'!
makeButton: aString balloonText: anotherString for: aSymbol

	^ SimpleButtonDelayedMenuMorph new target: self;
		 borderStyle: BorderStyle raised;
		 color: self colorForButtons;
		 label: aString font: self fontForButtons;
		 setBalloonText: anotherString;
		 actionSelector: aSymbol! !

!ProjectNavigationMorph methodsFor: 'as yet unclassified' stamp: 'mt 4/10/2018 11:33'!
makeUpdatingButtonWithBalloonText: balloonString actionSelector: actionSymbol wordingSelector: wordingSymbol
	"Answer a button  whose target is the receiver (i.e. a ProjectNavigationMorph), who gets its wording by sending the wordingSelector to me.  The given string"

	| aButton |
	aButton := UpdatingSimpleButtonMorph new.
	aButton
		target: self;
		borderStyle: BorderStyle raised;
		color: self colorForButtons;
		label: '-' font: self fontForButtons;
		setBalloonText: balloonString translated;
		actionSelector: actionSymbol;
		wordingSelector: wordingSymbol.
	aButton step.
	^ aButton
	
	! !

!ProjectNavigationMorph methodsFor: 'the buttons' stamp: 'mt 4/10/2018 11:32'!
buttonLanguage
	"Answer a button for finding/loading projects"
	^ SimpleButtonDelayedMenuMorph new target: self;
		 borderStyle: BorderStyle raised;
		 color: self colorForButtons;
		 label: Project current naturalLanguage font: self fontForButtons;
		 setBalloonText: 'Click here to choose your language.' translated;
		 actionSelector: #chooseLanguage! !

!ProjectNavigationMorph methodsFor: '*MorphicExtras-Sound' stamp: 'mt 4/10/2018 11:33'!
buttonSound

	| myButton m |

	myButton := RectangleMorph new 
		cornerStyle: #rounded;
		borderStyle: (BorderStyle raised width: 1);
		color: self colorForButtons;
		setBalloonText: 'Change sound volume' translated;
		on: #mouseDown send: #soundDownEvt:morph: to: self;
		on: #mouseStillDown send: #soundStillDownEvt:morph: to: self;
		on: #mouseUp send: #soundUpEvt:morph: to: self;
		yourself.

	myButton addMorph: (m := self speakerIcon lock).
	myButton extent: m extent + (myButton borderWidth + 6).
	m position: myButton center - (m extent // 2).
	^myButton
! !

!ProjectNavigationMorph methodsFor: '*MorphicExtras-Sound' stamp: 'mt 4/10/2018 11:34'!
soundDownEvt: a morph: b

	soundSlider ifNotNil: [soundSlider delete].
	(soundSlider := RectangleMorph new)
		setProperty: #morphicLayerNumber toValue: 1;
		extent: b width @ (b width * 3);
		color: self colorForButtons;
		borderStyle: BorderStyle raised;
		bottomLeft: b boundsInWorld origin.
	soundSlider addMorph: (
		RectangleMorph new
			color: self colorForButtons;
			borderColor: #raised;
			extent: b width @ 8;
			center: soundSlider center x @ 
				(soundSlider bottom - (soundSlider height * self getSoundVolume) asInteger)
	).
	soundSlider openInWorld.! !


!RecordingControls methodsFor: 'initialization' stamp: 'mt 4/11/2018 08:17'!
initialize
	"Initialize the receiver."

	| r full |
	super initialize.
	self hResizing: #shrinkWrap; vResizing: #shrinkWrap.
	self borderWidth: 2.
	self listDirection: #topToBottom.
	recorder := SoundRecorder new.
	recordingSaved := false.
	full := self addButtonRows.
	self changeCodec: OggSpeexCodec name: 'Speex'.

	"self addRecordLevelSliderIn: full."  "Doesn't work in most or maybe even all platforms..."

	r := AlignmentMorph newRow vResizing: #shrinkWrap.
	r addMorphBack: (self makeRecordMeterIn: full).
	self addMorphBack: r.
	self extent: 10@10.  "make minimum size"
	self setButtonEnablement
! !


!RecordingControlsMorph methodsFor: 'initialization' stamp: 'mt 4/11/2018 08:17'!
initialize

	| r full |
	super initialize.
	self hResizing: #shrinkWrap; vResizing: #shrinkWrap.
	self borderWidth: 2.
	self listDirection: #topToBottom.
	recorder := SoundRecorder new.
	full := self addButtonRows.
	self addRecordLevelSliderIn: full.

	r := AlignmentMorph newRow vResizing: #shrinkWrap.
	r addMorphBack: (self makeRecordMeterIn: full).
	self addMorphBack: r.
	self extent: 10@10.  "make minimum size"
! !


!ReferenceMorph methodsFor: 'menu' stamp: 'mt 4/11/2018 08:18'!
preserveDetails
	"The receiver is being switched to use a different format.  Preserve the existing details (e.g. wording if textual, grapheme if graphical) so that if the user reverts back to the current format, the details will be right"

	self isCurrentlyTextual
		ifTrue:
			[self setProperty: #priorWording toValue: self existingWording.
			self setProperty: #priorColor toValue: self color.
			self setProperty: #priorBorderWidth toValue: self borderWidth]
		ifFalse:
			[self setProperty: #priorGraphic toValue: self firstSubmorph form]! !


!FlapTab methodsFor: 'textual tabs' stamp: 'mt 4/10/2018 11:24'!
assumeString: aString font: aFont orientation: orientationSymbol color: aColor 
	| aTextMorph workString tabStyle |
	labelString := aString asString.
	workString := orientationSymbol == #vertical 
				ifTrue: 
					[String streamContents: 
							[:s | 
							labelString do: [:c | s nextPut: c] separatedBy: [s nextPut: Character cr]]]
				ifFalse: [labelString]. 
	tabStyle := (TextStyle new)
				leading: 0;
				newFontArray: (Array with: aFont).
	aTextMorph := (TextMorph new setTextStyle: tabStyle) 
				contents: (workString asText addAttribute: (TextKern kern: 3)).
	self removeAllMorphs.
	self borderStyle: (BorderStyle raised width: 2).
	aColor ifNotNil: [self color: aColor].
	self addMorph: aTextMorph centered.
	aTextMorph lock
	"
FlapTab allSubInstancesDo: [:ft | ft reformatTextualTab]
"! !


!RulerMorph methodsFor: 'drawing' stamp: 'mt 4/11/2018 08:18'!
drawOn: aCanvas

	| s |
	super drawOn: aCanvas.
	s := self width printString, 'x', self height printString.
	aCanvas drawString: s in: (self bounds insetBy: self borderWidth + 5) font: nil color: Color red.
! !


!SameGame methodsFor: 'initialization' stamp: 'mt 4/10/2018 11:34'!
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);
		color: color.
	a := AlignmentMorph newColumn
		wrapCentering: #center; cellPositioning: #topCenter;
		hResizing: #spaceFill;
		vResizing: #shrinkWrap;
		color: color.
	a addMorph: aButton.
	^ a

! !


!ScorePlayerMorph methodsFor: 'initialization' stamp: 'mt 4/23/2018 07:44'!
onScorePlayer: aScorePlayer title: scoreName
	| divider col r |
	scorePlayer := aScorePlayer.
	scorePlayer ifNotNil:
		[scorePlayer  reset.
		instrumentSelector := Array new: scorePlayer score tracks size].

	self removeAllMorphs.
	self addMorphBack: self makeControls.
	scorePlayer ifNil: [^ self].

	r := self makeRow
		hResizing: #spaceFill;
		vResizing: #shrinkWrap.
	r addMorphBack: self rateControl;
		addMorphBack: (Morph newBounds: (0@0 extent: 20@0) color: Color transparent);
		addMorphBack: self volumeControl.
	self addMorphBack: r.
	self addMorphBack: self scrollControl.

	col := AlignmentMorph newColumn color: color; layoutInset: 0.
	self addMorphBack: col.
	1 to: scorePlayer trackCount do: [:trackIndex |
		divider := AlignmentMorph new
			extent: 10@1;
			layoutInset: 0;
			borderStyle: (BorderStyle raised width: 1);
			color: color;
			hResizing: #spaceFill;
			vResizing: #rigid.
		col addMorphBack: divider.
		col addMorphBack: (self trackControlsFor: trackIndex)].

	LastMIDIPort ifNotNil: [
		"use the most recently set MIDI port"
		scorePlayer openMIDIPort: LastMIDIPort].
! !

!ScorePlayerMorph methodsFor: 'layout' stamp: 'kfr 5/1/2018 09:30'!
makeControls

	| bb r reverbSwitch repeatSwitch |
	r := AlignmentMorph newRow.
	r color: color; borderWidth: 0; layoutInset: 0.
	r hResizing: #shrinkWrap; vResizing: #shrinkWrap; extent: 5@5.
	bb := SimpleButtonMorph new target: self; borderColor: #raised;
			borderWidth: 2; color: color.
	r addMorphBack: (bb label: 'Menu' translated; actWhen: #buttonDown;
												actionSelector: #invokeMenu).
	bb := SimpleButtonMorph new target: self; borderColor: #raised;
			borderWidth: 2; color: color.
	r addMorphBack: (bb label: 'Piano Roll' translated;		actionSelector: #makePianoRoll).
	bb := SimpleButtonMorph new target: self; borderColor: #raised;
			borderWidth: 2; color: color.
	r addMorphBack: (bb label: 'Rewind' translated;		actionSelector: #rewind).
	bb := SimpleButtonMorph new target: scorePlayer; borderColor: #raised;
			borderWidth: 2; color: color.
	r addMorphBack: (bb label: 'Play' translated;			actionSelector: #resumePlaying).
	bb := SimpleButtonMorph new target: scorePlayer; borderColor: #raised;
			borderWidth: 2; color: color.
	r addMorphBack: (bb label: 'Pause' translated;			actionSelector: #pause).
	reverbSwitch := SimpleSwitchMorph new
		offColor: color;
		onColor: (Color r: 1.0 g: 0.6 b: 0.6);
		borderWidth: 2;
		label: 'Reverb Disable' translated;
		actionSelector: #disableReverb:;
		target: scorePlayer;
		setSwitchState: SoundPlayer isReverbOn not.
	r addMorphBack: reverbSwitch.
	scorePlayer ifNotNil:
		[repeatSwitch := SimpleSwitchMorph new
			offColor: color;
			onColor: (Color r: 1.0 g: 0.6 b: 0.6);
			borderWidth: 2;
			label: 'Repeat' translated;
			actionSelector: #repeat:;
			target: scorePlayer;
			setSwitchState: scorePlayer repeat.
		r addMorphBack: repeatSwitch].
	^ r
! !

!ScorePlayerMorph methodsFor: 'layout' stamp: 'mt 4/10/2018 11:35'!
standaloneResumeButton

	| r |

	r := AlignmentMorph newRow.
	r color: Color red; borderWidth: 0; layoutInset: 6; useRoundedCorners.
	r hResizing: #shrinkWrap; vResizing: #shrinkWrap; extent: 5@5.
	r addMorphBack: (
		SimpleButtonMorph new
			target: [
				scorePlayer resumePlaying.
				r delete
			];
			borderStyle: (BorderStyle raised width: 2);
			color: Color green;
			label: 'Continue' translated;
			actionSelector: #value
	).
	r setBalloonText: 'Continue playing a paused presentation' translated.
	^r


! !


!ScriptEditorMorph methodsFor: 'other' stamp: 'mt 4/11/2018 08:18'!
extent: x

	| newExtent tw menu |
	newExtent := x max: self minWidth @ self minHeight.
	(tw := self findA: TwoWayScrollPane) 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 @ -4).  "inset?"
	^ super extent: newExtent! !


!ScrollPane methodsFor: 'accessing' stamp: 'mt 4/10/2018 11:03'!
borderStyle: aBorderStyle 
	super borderStyle: aBorderStyle.
	scroller ifNotNil: [self setScrollDeltas].! !

!ScrollPane methodsFor: 'accessing' stamp: 'mt 5/4/2018 16:06'!
insetColor

	^ self containingWindow
		ifNil: [super insetColor]
		ifNotNil: [:window | window colorForInsets]! !

!ScrollPane methodsFor: 'accessing' stamp: 'mt 5/4/2018 16:05'!
raisedColor

	^ self containingWindow
		ifNil: [super raisedColor]
		ifNotNil: [:window | window raisedColor]! !

!ScrollPane methodsFor: 'geometry' stamp: 'mt 4/11/2018 08:19'!
hResizeScrollBar

	| topLeft h border offset |
	self hScrollBarPolicy == #never ifTrue: [^self].
	self bounds ifNil: [self fullBounds].
	
	h := self scrollBarThickness.
	border := self borderWidth.
	offset := (scrollBarOnLeft and: [self vIsScrollbarShowing and: [retractableScrollBar not]])
		ifTrue: [h]
		ifFalse: [0].
	
	topLeft := retractableScrollBar
				ifTrue: [bounds bottomLeft + (offset @ border negated)]
				ifFalse: [bounds bottomLeft + (offset @ h negated)].

	hScrollBar bounds: (topLeft extent: self hScrollBarWidth@ h)! !

!ScrollPane methodsFor: 'initialization' stamp: 'mt 4/11/2018 11:40'!
setDefaultParameters
	"change the receiver's appareance parameters"

	self
		color: (self userInterfaceTheme color ifNil: [Color white]);
		borderStyle: (self userInterfaceTheme borderStyle ifNil: [BorderStyle simple]) copy;
		borderColor: (self userInterfaceTheme borderColor ifNil: [Color gray: 0.6]);
		borderWidth: (self userInterfaceTheme borderWidth ifNil: [1]).! !

!ScrollPane methodsFor: 'drawing' stamp: 'mt 5/4/2018 11:58'!
drawOverlayOn: aCanvas
	"Draw my border OVER my submorphs because the scrollbars overlap."
	
	self wantsRoundedCorners
		ifTrue: [aCanvas frameRoundRect: self bounds radius: self cornerRadius borderStyle: self borderStyle]
		ifFalse: [aCanvas frameRectangle: self bounds borderStyle: self borderStyle].
		
	super drawOverlayOn: aCanvas.! !


!SimpleBorder methodsFor: 'accessing' stamp: 'mt 5/4/2018 16:33'!
baseColor: aColor

	baseColor = aColor ifTrue:[^self].
	baseColor := aColor ifNil: [Color transparent].
	self color: baseColor "#color: will do  #releaseCachedState"! !


!ComplexBorder methodsFor: '*60Deprecated-accessing' stamp: 'mt 4/23/2018 09:03'!
widthForRounding

	self deprecated: 'See BalloonCanvas for drawing rounded corners.'.
	^0! !


!InsetBorder methodsFor: 'accessing' stamp: 'mt 4/23/2018 09:30'!
bottomRightColor
	^ color mixed: 0.65 with: Color white! !

!InsetBorder methodsFor: 'accessing' stamp: 'mt 4/23/2018 09:24'!
topLeftColor
	^ color mixed: 0.70 with: Color black! !

!InsetBorder methodsFor: '*60Deprecated-accessing' stamp: 'mt 4/23/2018 09:04'!
colorsAtCorners

	| c c14 c23 |
	self deprecated: 'See #topLeftColor and #bottomRightColor.'.

	c := self color.
	c14 := c lighter. c23 := c darker.
	^Array with: c23 with: c14 with: c14 with: c23.! !


!RaisedBorder methodsFor: 'accessing' stamp: 'mt 4/23/2018 09:24'!
bottomRightColor
	^ color mixed: 0.70 with: Color black! !

!RaisedBorder methodsFor: 'accessing' stamp: 'mt 4/23/2018 09:30'!
topLeftColor
	^ color mixed: 0.65 with: Color white! !

!RaisedBorder methodsFor: '*60Deprecated-accessing' stamp: 'mt 4/23/2018 09:04'!
colorsAtCorners

	| c c14 c23 |
	self deprecated: 'See #topLeftColor and #bottomRightColor.'.
	c := self color.
	c14 := c lighter. c23 := c darker.
	^Array with: c14 with: c23 with: c23 with: c14! !


!SimpleButtonMorph methodsFor: 'accessing' stamp: 'mt 4/11/2018 08:20'!
fitContents
	| aMorph aCenter |
	aCenter := self center.
	self hasSubmorphs ifFalse: [^self].
	aMorph := self firstSubmorph.
	self extent: aMorph extent + (self borderWidth + 6).
	self center: aCenter.
	aMorph position: aCenter - (aMorph extent // 2)! !

!SimpleButtonMorph methodsFor: 'accessing' stamp: 'mt 4/11/2018 08:20'!
label: aString

	| oldLabel m |
	(oldLabel := self findA: StringMorph)
		ifNotNil: [oldLabel delete].
	m := StringMorph contents: aString font: TextStyle defaultFont.
	self extent: m extent + (self borderWidth + 6).
	m position: self center - (m extent // 2).
	self addMorph: m.
	m lock! !

!SimpleButtonMorph methodsFor: 'event handling' stamp: 'mt 4/23/2018 09:40'!
mouseUp: evt
	super mouseUp: evt.
	oldColor ifNotNil:
		["if oldColor nil, it signals that mouse had not gone DOWN
		inside me, e.g. because of a cmd-drag; in this case we want
		to avoid triggering the action!!"
		self color: oldColor.
		oldColor := nil.
		(self containsPoint: evt cursorPoint) 
				ifTrue: [ actWhen == #buttonUp 
							ifTrue: [self doButtonAction]  ]
				ifFalse: [ self mouseLeave: evt "This is a balk. Note that we have left." ]].
	self borderStyle style = #inset ifTrue: [self borderRaised].
		
! !

!SimpleButtonMorph methodsFor: 'visual properties' stamp: 'mt 4/23/2018 09:38'!
updateVisualState: evt
	
	(self containsPoint: evt cursorPoint)
		ifTrue: [
			oldColor ifNotNil: [self color: (oldColor mixed: 1/2 with: Color white)].
			self borderStyle style = #raised ifTrue: [self borderInset]]
		ifFalse: [
			oldColor ifNotNil: [self color: oldColor].
			self borderStyle style = #inset ifTrue: [self borderRaised]].
! !


!IconicButton methodsFor: 'as yet unclassified' stamp: 'mt 4/11/2018 08:11'!
labelGraphic: aForm
	| oldLabel graphicalMorph |
	(oldLabel := self findA: SketchMorph)
		ifNotNil: [oldLabel delete].
	graphicalMorph := SketchMorph withForm: aForm.
	self extent: graphicalMorph extent + (self borderWidth + 6).
	graphicalMorph position: self center - (graphicalMorph extent // 2).
	self addMorph: graphicalMorph.
	graphicalMorph 
		baseGraphic;
		lock.
! !

!IconicButton methodsFor: 'initialization' stamp: 'mt 4/11/2018 09:37'!
defaultBorderWidth
	^ 2! !


!IconicButtonWithLabel methodsFor: 'as yet unclassified' stamp: 'mt 4/11/2018 08:11'!
labelGraphic: aForm color: nonTranslucent andLabel: aStringMorph
	| graphicalMorph labeledItem actualForm |

	labeledItem := AlignmentMorph newColumn.
	labeledItem hResizing: #shrinkWrap.
	labeledItem vResizing: #shrinkWrap.
	labeledItem color: nonTranslucent.
	labeledItem borderWidth: 0.
	labeledItem
		layoutInset: 4@0;
		cellPositioning: #center.

	self removeAllMorphs.
	actualForm := (Form extent: aForm extent depth: 32) fillColor: nonTranslucent.
	aForm displayOn: actualForm at: 0@0 rule: 34.
	graphicalMorph := SketchMorph withForm: actualForm.

	labeledItem addMorph: graphicalMorph.
	labeledItem addMorphBack: (Morph new extent: (4@4)) beTransparent.
	aStringMorph ifNotNil: [
		labeledItem addMorphBack: aStringMorph
	].

	self addMorph: labeledItem.
	self extent: submorphs first fullBounds extent + (self borderWidth + 6).
	labeledItem lock.
! !

!IconicButtonWithLabel methodsFor: 'as yet unclassified' stamp: 'mt 4/11/2018 08:11'!
labelString: aString

	labelMorph ifNotNil: [
		labelMorph contents: aString.
		self extent: self firstSubmorph fullBounds extent + (self borderWidth + 6).
	].
! !


!ScriptableButton methodsFor: 'accessing' stamp: 'mt 4/11/2018 08:18'!
label: aString
	"Set the receiver's label as indicated"

	| aLabel |
	(aLabel := self findA: StringMorph)
		ifNotNil:
			[aLabel contents: aString]
		ifNil:
			[aLabel := StringMorph contents: aString font: Preferences standardEToysButtonFont.
			self addMorph: aLabel].

	self extent: aLabel extent + (self borderWidth + 6).
	aLabel position: self center - (aLabel extent // 2).

	aLabel lock! !


!SimpleSwitchMorph methodsFor: 'initialization' stamp: 'mt 4/23/2018 09:32'!
initializeWithLabel: labelString

	super initializeWithLabel: labelString.
	self borderWidth: 3.
	self extent: self extent + 2.
	onColor := Color r: 1.0 g: 0.6 b: 0.6.
	offColor := Color lightGray.
	
	self turnOff.! !

!SimpleSwitchMorph methodsFor: 'switching' stamp: 'mt 4/23/2018 09:29'!
turnOff
	self borderRaised.
	self color: offColor! !

!SimpleSwitchMorph methodsFor: 'switching' stamp: 'mt 4/23/2018 09:29'!
turnOn
	self borderInset.
	self color: onColor! !


!MinesTile methodsFor: 'accessing' stamp: 'mt 5/4/2018 10:52'!
switchState: aBoolean

	switchState := aBoolean.
	disabled ifFalse:
		[switchState
			ifTrue:[
				"flag ifTrue: [self setFlag]." "if this is a flagged tile, unflag it."
				self borderStyle: (BorderStyle inset width: 1).
				self color: onColor]
			ifFalse:[
				self borderStyle: (BorderStyle raised width: 3).
				self color: offColor]]! !

!MinesTile methodsFor: 'drawing' stamp: 'mt 5/4/2018 11:27'!
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 emphasized: 1.
			rct := self bounds insetBy: ((self bounds width) - (font widthOfString: '*'))/2@0.
			rct := rct top: rct top + 1.
			aCanvas drawString: '*' in: (rct translateBy: 1@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 emphasized: 1.
			rct := self bounds insetBy: ((self bounds width) - (font widthOfString: nearMines asString))/2@0.
			rct := rct top: rct top + 1.
			aCanvas drawString: nearMines asString in: (rct translateBy: 1@1) font: font color: Color black.
			^ aCanvas drawString: nearMines asString in: rct font: font color: ((palette at: nearMines) ) .]].! !


!SameGameTile methodsFor: 'accessing' stamp: 'mt 5/4/2018 11:42'!
setSwitchState: aBoolean

	switchState := aBoolean.
	disabled ifFalse:
		[switchState
			ifTrue:
				[self borderInset.
				self color: onColor]
			ifFalse:
				[self borderRaised.
				self color: offColor]]! !

!SameGameTile methodsFor: 'initialization' stamp: 'sw 11/30/1999 08:21'!
initialize

	super initialize.
	self label: ''.
	self borderWidth: 2.
	bounds := 0@0 corner: 16@16.
	offColor := Color gray.
	onColor := Color gray.
	switchState := false.
	oldSwitchState := false.
	disabled := false.
	self useSquareCorners
	! !


!Slider methodsFor: 'other events' stamp: 'mt 4/10/2018 11:15'!
mouseDownInSlider: event 

	slider borderStyle style == #raised
		ifTrue: [slider borderStyle: (BorderStyle inset width: slider borderWidth)].
	
	self showSliderShadow.! !

!Slider methodsFor: 'other events' stamp: 'mt 4/10/2018 11:15'!
mouseUpInSlider: event 

	slider borderStyle style == #inset
		ifTrue: [slider borderStyle: (BorderStyle raised width: slider borderWidth)].
	
	self hideSliderShadow.! !


!ScrollBar class methodsFor: 'images' stamp: 'mt 4/11/2018 09:57'!
arrowOfDirection: aSymbol size: finalSizeInteger color: aColor 
	"answer a form with an arrow based on the parameters"
	^ ArrowImagesCache at: {aSymbol. finalSizeInteger max: 1. aColor}! !


!SolarizedTheme class methodsFor: 'instance creation' stamp: 'mt 4/11/2018 10:35'!
addDarkMenusAndDockingBars: theme
	"self createDark apply."
	theme
		set: #borderWidth for: #MenuMorph to: 1;
		set: #borderColor for: #MenuMorph to: self darkBackgroundHighlights;
		set: #color for: #MenuMorph to: self darkBackground;
		set: #titleTextColor for: #MenuMorph to: self darkContentEmphasizedMore;
		set: #lineColor for: #MenuMorph to: self darkBackgroundHighlights;
		set: #lineStyle for: #MenuMorph to: BorderStyle simple;
		set: #lineWidth for: #MenuMorph to: 1.
		
	theme
		set: #textColor for: #MenuItemMorph to: self darkContentEmphasized;
		set: #disabledTextColor for: #MenuItemMorph to: self darkContentSecondary;
		set: #selectionColor for: #MenuItemMorph to: self darkSelectionColor;
		set: #selectionTextColor for: #MenuItemMorph to: self darkSelectionTextColor.
		"set: #subMenuMarker for: #MenuItemMorph to: nil." "Use hard-coded default. See MenuItemMorph."
		
	"The world main docking bar."
	theme
		set: #color for: #DockingBarMorph to: self darkBackgroundHighlights;
		set: #selectionColor for: #DockingBarItemMorph to: self darkContentSecondary;
		set: #logoColor for: #TheWorldMainDockingBar to: self darkContentEmphasized;
		set: #selectionLogoColor for: #TheWorldMainDockingBar to: self darkContentEmphasizedMore.! !

!SolarizedTheme class methodsFor: 'instance creation' stamp: 'mt 4/11/2018 10:35'!
addLightMenusAndDockingBars: theme
	"self createLight apply."
	theme
		set: #borderWidth for: #MenuMorph to: 1;
		set: #borderColor for: #MenuMorph to: self lightBackgroundHighlights;
		set: #color for: #MenuMorph to: self lightBackground;
		set: #titleTextColor for: #MenuMorph to: self lightContentEmphasizedMore;
		set: #lineColor for: #MenuMorph to: self lightBackgroundHighlights;
		set: #lineStyle for: #MenuMorph to: BorderStyle simple;
		set: #lineWidth for: #MenuMorph to: 1.
		
	theme
		set: #textColor for: #MenuItemMorph to: self lightContentEmphasized;
		set: #disabledTextColor for: #MenuItemMorph to: self lightContentSecondary;
		set: #selectionColor for: #MenuItemMorph to: self lightBackgroundHighlights darker;
		set: #selectionTextColor for: #MenuItemMorph to: self lightContentEmphasizedMore.
		"set: #subMenuMarker for: #MenuItemMorph to: nil." "Use hard-coded default. See MenuItemMorph."
		
	"The world main docking bar."
	theme
		set: #color for: #DockingBarMorph to: self lightBackgroundHighlights;
		set: #selectionColor for: #DockingBarItemMorph to: self lightContentSecondary;
		set: #logoColor for: #TheWorldMainDockingBar to: self lightContentEmphasized;
		set: #selectionLogoColor for: #TheWorldMainDockingBar to: self lightContentEmphasizedMore.! !


!SoundLoopMorph methodsFor: 'playing' stamp: 'mt 4/11/2018 08:21'!
buildSound
	"Build a compound sound for the next iteration of the loop."

	| mixer soundMorphs |
	mixer := MixedSound new.
	mixer add: (RestSound dur: (self width - (2 * self borderWidth)) / 128.0).
	soundMorphs := self submorphs select: [:m | m respondsTo: #sound].
	soundMorphs do: [:m |
		| startTime pan |
		startTime := (m position x - (self left + self borderWidth)) / 128.0.
		pan := (m position y - (self top + self borderWidth)) asFloat / (self height - (2 * self borderWidth) - m height).
		mixer add: ((RestSound dur: startTime), m sound copy) pan: pan].
	^ mixer
! !


!SqueakTheme class methodsFor: 'instance creation' stamp: 'mt 4/11/2018 10:35'!
addButtons: theme

	theme
		set: #borderColor for: #PluggableButtonMorph to: Color gray;
		set: #borderWidth for: #PluggableButtonMorph to: 1;
		set: #borderStyle for: #PluggableButtonMorph to: BorderStyle simple;
		set: #color for: #PluggableButtonMorph to: (Color gray: 0.91);
		
		set: #font for: #PluggableButtonMorph to: [Preferences standardButtonFont];
		set: #textColor for: #PluggableButtonMorph to: Color black;

		set: #selectionModifier for: #PluggableButtonMorph to: [ [:c | c adjustBrightness: -0.2] ];
		set: #hoverModifier for: #PluggableButtonMorph to: [ [:c | c adjustBrightness: -0.1] ];
		set: #feedbackModifier for: #PluggableButtonMorph to: [ [:c | c adjustBrightness: -0.3] ].
	
	"And the plus-version."
	theme
		set: #disabledColor for: #PluggableButtonMorphPlus to: Color transparent;
		set: #disabledTextColor for: #PluggableButtonMorphPlus to: (Color gray: 0.6).

	"And the three-phase button."
	theme
		derive: #color for: #ThreePhaseButtonMorph from: #PluggableButtonMorph at: #textColor;
		derive: #font for: #ThreePhaseButtonMorph from: #PluggableButtonMorph;
		derive: #textColor for: #ThreePhaseButtonMorph from: #PluggableButtonMorph.! !

!SqueakTheme class methodsFor: 'instance creation' stamp: 'mt 4/11/2018 10:36'!
addDialogs: theme
	"self create apply."
	
	theme
		set: #borderColor for: #DialogWindow to: Color gray;
		set: #borderWidth for: #DialogWindow to: 1;
		set: #borderStyle for: #DialogWindow to: BorderStyle simple;
		set: #color for: #DialogWindow to: Color white;

		set: #titleBorderColor for: #DialogWindow to: Color gray;
		set: #titleBorderWidth for: #DialogWindow to: 0;
		set: #titleBorderStyle for: #DialogWindow to: BorderStyle default;
		set: #titleColor for: #DialogWindow to: (Color r: 0.658 g: 0.678 b: 0.78);
		set: #titleFont for: #DialogWindow to: [Preferences windowTitleFont];
		set: #titleTextColor for: #DialogWindow to: Color black;
		
		set: #font for: #DialogWindow to: [Preferences standardSystemFont];
		set: #textColor for: #DialogWindow to: Color black;
		
		set: #okColor for: #DialogWindow to: (Color r: 0.49 g: 0.749 b: 0.49);
		set: #cancelColor for: #DialogWindow to: (Color r: 1 g: 0.6 b: 0.588);
		set: #buttonColor for: #DialogWindow to: (Color r: 0.658 g: 0.678 b: 0.78) twiceLighter;
		set: #selectionModifier for: #DialogWindow to: [ [:c | Color orange muchLighter ] ].
	
	"The List Chooser is a dialog, too."
	theme
		derive: #okColor for: #ListChooser from: #DialogWindow;
		derive: #cancelColor for: #ListChooser from: #DialogWindow;
		set: #addColor for: #ListChooser to: Color blue muchLighter;
		set: #disabledColor for: #ListChooser to: Color gray.

	"And the mulitple list chooser."
	theme
		derive: #okColor for: #ListMultipleChooser from: #DialogWindow;
		derive: #cancelColor for: #ListMultipleChooser from: #DialogWindow.
		
	"And the system progress bar."
	theme
		derive: #borderColor for: #SystemProgressMorph from: #MenuMorph;
		derive: #borderWidth for: #SystemProgressMorph from: #MenuMorph;
		derive: #borderStyle for: #SystemProgressMorph from: #MenuMorph;
		derive: #color for: #SystemProgressMorph from: #MenuMorph;
		derive: #font for: #SystemProgressMorph from: #MenuItemMorph;
		derive: #textColor for: #SystemProgressMorph from: #MenuItemMorph;
		
		set: #borderColor for: #SystemProgressBarMorph to: Color transparent;
		set: #borderWidth for: #SystemProgressBarMorph to: 0;
		set: #borderStyle for: #SystemProgressBarMorph to: BorderStyle default;
		set: #color for: #SystemProgressBarMorph to: (Color r: 0.977 g: 0.977 b: 0.977);
		set: #barColor for: #SystemProgressBarMorph to: (Color r: 0.72 g: 0.72 b: 0.9).
		
	"And the balloon morphs."
	theme
		set: #borderColor for: #NewBalloonMorph to: (Color r: 0.46 g: 0.46 b: 0.353);
		set: #borderWidth for: #NewBalloonMorph to: 1;
		set: #color for: #NewBalloonMorph to:(Color r: 0.92 g: 0.92 b: 0.706);
		set: #font for: #NewBalloonMorph to: [Preferences standardBalloonHelpFont];
		derive: #textColor for: #NewBalloonMorph from: #PluggableButtonMorph.
		
	theme
		derive: #borderColor for: #BalloonMorph from: #NewBalloonMorph;
		set: #borderWidth for: #BalloonMorph to: 0;
		derive: #color for: #BalloonMorph from: #NewBalloonMorph;
		derive: #font for: #BalloonMorph from: #NewBalloonMorph;
		derive: #textColor for: #BalloonMorph from: #NewBalloonMorph.
	
	"And the transfer morphs."
	theme
		derive: #borderColor for: #TransferMorph from: #NewBalloonMorph;
		derive: #borderWidth for: #TransferMorph from: #NewBalloonMorph;
		derive: #color for: #TransferMorph from: #NewBalloonMorph;
		derive: #font for: #TransferMorph from: #NewBalloonMorph;
		derive: #textColor for: #TransferMorph from: #NewBalloonMorph.	! !

!SqueakTheme class methodsFor: 'instance creation' stamp: 'mt 4/11/2018 10:36'!
addMenusAndDockingBars: theme

	theme
		set: #borderColor for: #MenuMorph to: Color gray;
		set: #borderWidth for: #MenuMorph to: 1;
		set: #borderStyle for: #MenuMorph to: BorderStyle simple;
		set: #color for: #MenuMorph to: (Color gray: 0.9);

		set: #titleBorderColor for: #MenuMorph to: (Color r: 0.6 g: 0.7 b: 1);
		set: #titleBorderWidth for: #MenuMorph to: 0;
		set: #titleBorderStyle for: #MenuMorph to: BorderStyle simple;
		set: #titleColor for: #MenuMorph to: Color transparent;
		set: #titleFont for: #MenuMorph to: [Preferences windowTitleFont];
		set: #titleTextColor for: #MenuMorph to: Color black;
		
		set: #lineColor for: #MenuMorph to: (Color gray: 0.9);
		set: #lineStyle for: #MenuMorph to: BorderStyle inset;
		set: #lineWidth for: #MenuMorph to: 2.
		
	theme
		set: #font for: #MenuItemMorph to: [Preferences standardMenuFont];
		set: #textColor for: #MenuItemMorph to: Color black;
		set: #disabledTextColor for: #MenuItemMorph to: Color gray;
		set: #selectionColor for: #MenuItemMorph to: (Color r: 0.4 g: 0.5 b: 0.7);
		set: #selectionTextColor for: #MenuItemMorph to: Color white.
		
	"Derive some stuff for the docking bar morph, which looks mostly like a menu morph."
	theme
		set: #borderWidth for: #DockingBarMorph to: 0;
		derive: #borderColor for: #DockingBarMorph from: #MenuMorph;
		derive: #borderStyle for: #DockingBarMorph from: #MenuMorph;
		derive: #color for: #DockingBarMorph from: #MenuMorph;
	
		derive: #lineColor for: #DockingBarMorph from: #MenuMorph;
		derive: #lineStyle for: #DockingBarMorph from: #MenuMorph;
		derive: #lineWidth for: #DockingBarMorph from: #MenuMorph.
		
	"The world main docking bar."
	theme
		derive: #font for: #TheWorldMainDockingBar from: #MenuItemMorph;
		derive: #textColor for: #TheWorldMainDockingBar from: #MenuItemMorph;
		set: #logoColor for: #TheWorldMainDockingBar to: Color black;
		set: #selectionLogoColor for: #TheWorldMainDockingBar to: Color white.! !

!SqueakTheme class methodsFor: 'instance creation' stamp: 'mt 4/11/2018 10:33'!
addScrollables: theme
	"self create apply"
	
	"Sliders"
	theme
		set: #borderColor for: #Slider to: Color gray;
		set: #borderWidth for: #Slider to: 1;
		set: #color for: #Slider to: Color lightGray;
		set: #thumbBorderColor for: #Slider to: [Color gray: 0.6];
		set: #thumbBorderWidth for: #Slider to: 0;
		set: #thumbColor for: #Slider to: Color veryVeryLightGray;
		set: #thumbShadowModifier for: #Slider to: [ [:c | c alpha: 0.7] ].
				
	"Scroll bars"
	theme
		set: #thumbBorderWidth for: #ScrollBar to: 1;
		set: #thumbColorModifier for: #ScrollBar to: [ [:c | c] ];
		set: #pagingAreaColorModifier for: #ScrollBar to: [ [:c | c darker alpha: 0.35] ];
		set: #borderColorModifier for: #ScrollBar to: [ [:c | c adjustBrightness: -0.3] ].
	
	"Scroll panes (includes generic stuff for list widgets, tree widgets, and text widgets."
	theme
		set: #borderColor for: #ScrollPane to: (Color gray: 0.6);
		set: #borderWidth for: #ScrollPane to: 1;
		set: #borderStyle for: #ScrollPane to: BorderStyle simple;
		set: #color for: #ScrollPane to: Color white.
		
	"List widgets"
	theme
		set: #font for: #PluggableListMorph to: [Preferences standardListFont];
		set: #textColor for: #PluggableListMorph to: Color black;
		set: #selectionColor for: #PluggableListMorph to: (Color r: 0.72 g: 0.72 b: 0.9);
		derive: #multiSelectionColor for: #PluggableListMorph from: #PluggableListMorph at: #selectionColor do: [:c | c lighter];
		set: #selectionTextColor for: #PluggableListMorph to: Color black;
		set: #filterColor for: #PluggableListMorph to: Color yellow paler;
		set: #filterTextColor for: #PluggableListMorph to: Color black;
		set: #preSelectionModifier for: #PluggableListMorph to: [ [:c | Color gray: 0.9] ];
		set: #hoverSelectionModifier for: #PluggableListMorph to: [ [:c | c darker alpha: 0.3] ].
		
	"Tree widgets"
	theme
		derive: #font for: #SimpleHierarchicalListMorph from: #PluggableListMorph;
		derive: #textColor for: #SimpleHierarchicalListMorph from: #PluggableListMorph;
		derive: #selectionColor for: #SimpleHierarchicalListMorph from: #PluggableListMorph;
		derive: #selectionTextColor for: #SimpleHierarchicalListMorph from: #PluggableListMorph;
		derive: #filterColor for: #SimpleHierarchicalListMorph from: #PluggableListMorph;
		derive: #filterTextColor for: #SimpleHierarchicalListMorph from: #PluggableListMorph;
		derive: #hoverSelectionModifier for: #SimpleHierarchicalListMorph from: #PluggableListMorph;
		
		set: #higlightTextColor for: #SimpleHierarchicalListMorph to: Color red;
		set: #lineColor for: #SimpleHierarchicalListMorph to: Color veryLightGray.
	
	"Text widgets"
	theme
		set: #font for: #PluggableTextMorph to: [Preferences standardSystemFont];
		set: #textColor for: #PluggableTextMorph to: Color black;
		set: #caretColor for: #PluggableTextMorph to: Color red;
		set: #selectionColor for: #PluggableTextMorph to: (TranslucentColor r: 0.0 g: 0.0 b: 0.8 alpha: 0.2);
		set: #unfocusedSelectionModifier for: #PluggableTextMorph to: [ [:c | Color gray: 0.9] ];
		set: #adornmentReadOnly for: #PluggableTextMorph to: Color black;
		set: #adornmentRefuse for: #PluggableTextMorph to: Color tan;
		set: #adornmentConflict for: #PluggableTextMorph to: Color red;
		set: #adornmentDiff for: #PluggableTextMorph to: Color green;
		set: #adornmentNormalEdit for: #PluggableTextMorph to: Color orange;
		set: #adornmentDiffEdit for: #PluggableTextMorph to: Color yellow;
		set: #frameAdornmentWidth for: #PluggableTextMorph to: 1.
	theme
		set: #balloonTextColor for: #PluggableTextMorphPlus to: (Color gray: 0.7);
		derive: #balloonTextFont for: #PluggableTextMorphPlus from: #PluggableTextMorph at: #font.! !


!StackMorph methodsFor: 'menu' stamp: 'mt 4/10/2018 11:36'!
formatList: pl
	| rr ff |
	"Turn this plugglable list into a good looking morph."

	pl color: Color transparent; borderWidth: 0.
	pl font: ((TextStyle named: #Palatino) fontOfSize: 14).
	pl toggleCornerRounding; width: 252; retractableOrNot; hResizing: #spaceFill.
	rr := (RectangleMorph new) toggleCornerRounding; extent: pl extent + (30@30).
	rr color: self currentPage color; fillStyle: (ff := self currentPage fillStyle copy).
	ff isGradientFill ifTrue: [
		rr fillStyle direction: (ff direction * self currentPage extent / rr extent) rounded.
		rr fillStyle origin: rr bounds origin].
	rr addMorph: pl.
	rr layoutPolicy: TableLayout new.
	rr layoutInset: 10@15; cellInset: 10@15; wrapDirection: #leftToRight.
	rr listCentering: #center; borderStyle: (BorderStyle raised width: 5).
	"Up and down buttons on left with arrows in a holder."
	"lb := (RectangleMorph new) color: transparent; borderWidth: 0."
	^ rr! !


!StandardViewer methodsFor: 'initialization' stamp: 'mt 4/10/2018 11:36'!
addHeaderMorphWithBarHeight: anInteger includeDismissButton: aBoolean
	"Add the header morph to the receiver, using anInteger as a guide for its height, and if aBoolean is true, include a dismiss buton for it"

	| header aButton aTextMorph nail wrpr costs headWrapper |
	header := AlignmentMorph newRow color: Color transparent; wrapCentering: #center; cellPositioning: #leftCenter.
	aBoolean ifTrue:
		[aButton := self tanOButton.
		header addMorph: aButton.
		aButton actionSelector: #dismiss;
				setBalloonText: 'remove this entire Viewer from the screen
don''t worry -- nothing will be lost!!.' translated.
		header addTransparentSpacerOfSize: 3].

	costs := scriptedPlayer costumes.
	costs ifNotNil:
	[(costs size > 1 or: [costs size = 1 and: [costs first ~~ scriptedPlayer costume]]) ifTrue:
		[header addUpDownArrowsFor: self.
		"addArrowsOn: adds the box with two arrow at the front."
		(wrpr := header submorphs first) submorphs second setBalloonText: 'switch to previous costume' translated.	
		wrpr submorphs first  setBalloonText: 'switch to next costume' translated].
		header addTransparentSpacerOfSize: 3].	

	self viewsMorph ifTrue: [scriptedPlayer costume assureExternalName].
	aTextMorph := UpdatingStringMorph new
		useStringFormat;
		target:  scriptedPlayer;
		getSelector: #nameForViewer;
		setNameTo: 'name';
		font: ScriptingSystem fontForNameEditingInScriptor.
	self viewsMorph ifTrue:
		[aTextMorph putSelector: #setName:.
		aTextMorph setProperty: #okToTextEdit toValue: true].
	aTextMorph step.
	header  addMorphBack: aTextMorph.
	aTextMorph setBalloonText: 'Click here to edit the player''s name.' translated.	
	header addMorphBack: ((self transparentSpacerOfSize: 0) hResizing: #spaceFill; color: Color red).

	aButton := ThreePhaseButtonMorph
				labelSymbol: #AddInstanceVariable
				target: scriptedPlayer
				actionSelector: #addInstanceVariable
				arguments: #().
	aButton setBalloonText: 'click here to add a variable
to this object.' translated.
	header addMorphBack: aButton.

	header addTransparentSpacerOfSize: 3.

	nail := (self hasProperty: #noInteriorThumbnail)
		ifFalse:
			[ThumbnailMorph new objectToView: scriptedPlayer viewSelector: #costume]
		ifTrue:
			[ImageMorph new image: (ScriptingSystem formAtKey: #MenuIcon)].
	nail on: #mouseDown send: #offerViewerMenuForEvt:morph: to: scriptedPlayer.
	header addMorphBack: nail.
	nail setBalloonText: 'click here to get a menu
that will allow you to
locate this object,
tear off a tile, etc..' translated.
	(self hasProperty: #noInteriorThumbnail)
		ifFalse:
			[nail borderStyle: (BorderStyle raised width: 3)].

	header addTransparentSpacerOfSize: 3.

	aButton := ThreePhaseButtonMorph labelSymbol: #AddCategoryViewer.
	aButton
			actWhen: #buttonUp;
			target: self;
			actionSelector: #addCategoryViewer;
			setBalloonText: 'click here to add
another category pane' translated.
	header addMorphBack: aButton.

	header beSticky.
	anInteger > 0
		ifTrue:
			[headWrapper := AlignmentMorph newColumn color: self color.
			headWrapper addTransparentSpacerOfSize: (0 @ anInteger).
			headWrapper addMorphBack: header.
			self addMorph: headWrapper]
		ifFalse:
			[self addMorph: header]! !


!SyntaxMorph methodsFor: 'accessing' stamp: 'mt 4/11/2018 10:18'!
borderColor: colorOrSymbolOrNil

	self borderColor = colorOrSymbolOrNil ifFalse: [
		super borderColor: colorOrSymbolOrNil.
		self bounds area < 40000
			ifTrue: [self invalidRect: self bounds]
			ifFalse: [(self bounds areasOutside: (self bounds insetBy: self borderWidth))
						do: [:r | self invalidRect: r]]].
! !

!SyntaxMorph methodsFor: 'highlighting' stamp: 'mt 4/10/2018 11:39'!
unhighlight

	self setDeselectedColor.! !

!SyntaxMorph methodsFor: 'highlighting' stamp: 'mt 4/10/2018 11:41'!
unhighlightBorder

	self currentSelectionDo: [:innerMorph :mouseDownLoc :outerMorph |
		self borderColor: (
			(self == outerMorph or: [owner notNil and: [owner isSyntaxMorph not]])
				ifFalse: [self borderColor: self stdBorderColor]
				ifTrue: [
					(self hasProperty: #deselectedBorderColor)
						ifTrue: [self borderColor: (self valueOfProperty: #deselectedBorderColor)]
						ifFalse: [self borderStyle: (BorderStyle raised width: self borderWidth)]] )].! !

!SyntaxMorph methodsFor: 'insertion drop zones' stamp: 'mt 4/11/2018 08:21'!
trackDropZones
	| hand i localPt insertion insHt ii prevBot nxtHt d c1 c2 ht2 spacer1 spacer2 wid ht1 dc each |
	hand := self primaryHand.
	("hand lastEvent redButtonPressed &" hand hasSubmorphs
		and: [(self hasOwner: hand) not]) ifFalse: [^ self].

	insertion := hand firstSubmorph renderedMorph.
	insertion isSyntaxMorph ifFalse: [^ self].
	insertion isNoun ifFalse: [(insertion nodeClassIs: CommentNode) ifFalse: [^ self]].
	localPt := self globalPointToLocal: hand position.
	insHt := insertion height.  "**just use standard line height here"
	self removeDropZones.  "Maybe first check if in right place, then just tweak heights."
	i := (ii := self indexOfMorphAbove: localPt) min: submorphs size-1.
	prevBot := i <= 0 ifTrue: [(self innerBounds) top]
					ifFalse: [(self submorphs at: i) bottom].
	nxtHt := (submorphs isEmpty
		ifTrue: [insertion]
		ifFalse: [self submorphs at: i+1]) height.
	d := ii > i ifTrue: [nxtHt "for consistent behavior at bottom"]
			ifFalse: [0 max: (localPt y - prevBot min: nxtHt)].

	"Top and bottom spacer heights cause continuous motion..."
	c1 := Color transparent.  c2 := Color transparent.
	ht2 := d*insHt//nxtHt.  ht1 := insHt - ht2.
	wid := self width - (2*self borderWidth) - (2*self layoutInset).
	wid isPoint ifTrue: [wid := wid x].
	(spacer1 := BorderedMorph newBounds: (0@0 extent: wid@ht1)
				color: (ht1 > (insHt//2) ifTrue: [c1] ifFalse: [c2]))
					borderWidth: 1; borderColor: spacer1 color.
	self privateAddMorph: spacer1 atIndex: (i+1 max: 1).
	(spacer2 := BorderedMorph newBounds: (0@0 extent: wid@ht2)
				color: (ht2 > (insHt//2+1) ifTrue: [c1] ifFalse: [c2]))
					borderWidth: 1; borderColor: spacer2 color.
	spacer1 setProperty: #dropZone toValue: true.
	spacer2 setProperty: #dropZone toValue: true.
	self privateAddMorph: spacer2 atIndex: (i+3 min: submorphs size+1).
	self fullBounds.  "Force layout prior to testing for cursor containment"

	"Maintain the drop target highlight -- highlight spacer if hand is in it."
	{spacer1. spacer2} do:
		[:spacer | (spacer containsPoint: localPt) ifTrue:
			[spacer color: self dropColor.
			"Ignore border color.  Maybe do it later.
			self borderColor = self dropColor
				ifTrue: [self borderColor: self stdBorderColor]"]].
	"If no submorph (incl spacers) highlighted, then re-highlight the block."
	"Ignore border color.  Maybe do it later.
	((self wantsDroppedMorph: insertion event: hand lastEvent) and:
		[(self submorphs anySatisfy: [:m | m containsPoint: localPt]) not])
			ifTrue: [self borderColor: self dropColor].
	"

	"Dragging a tile within a Block, if beside a tile, color it a dropzone"
	"Transcript show: localPt y printString; space; show: submorphs first top 
		printString; space; show: submorphs last top printString; cr."
	dc := self dropColor.
	1 to: ((ii+4 min: submorphs size) max: 1) do: [:ind | 
		each := submorphs at: ind.
		each isSyntaxMorph ifTrue: [
			localPt y >= each top 
				ifTrue: ["in this one or beyond"
					(localPt y < each bottom) 
						ifTrue: [(each submorphs anySatisfy: [:m | 
								m containsPoint: localPt])
							ifTrue: [each setDeselectedColor]
							ifFalse: [each color: dc]]
						ifFalse: [each color = dc ifTrue: [each setDeselectedColor]]]
				ifFalse: [each color = dc ifTrue: [each setDeselectedColor]]]].
! !

!SyntaxMorph methodsFor: 'selection' stamp: 'mt 4/10/2018 11:36'!
select
	self deselect.
	"Outer block is not colored and has no popup"
	(owner isSyntaxMorph and: [owner nodeClassIs: MethodNode]) 
		ifTrue: [self setDeselectedColor "normal"]
		ifFalse: [self color: Color lightBrown].
	self borderStyle: (BorderStyle raised width: self borderWidth).
	self offerPopUp.! !


!SystemProgressBarMorph methodsFor: 'initialization' stamp: 'mt 4/11/2018 11:40'!
setDefaultParameters
	"change the receiver's appareance parameters"

	self
		color: (self userInterfaceTheme color ifNil: [Color r: 0.977 g: 0.977 b: 0.977]);
		borderStyle: (self userInterfaceTheme borderStyle ifNil: [BorderStyle simple]) copy;
		borderColor: (self userInterfaceTheme borderColor ifNil: [Color transparent]);
		borderWidth: (self userInterfaceTheme borderWidth ifNil: [0]);
		barColor: (self userInterfaceTheme barColor ifNil: [Color r: 0.72 g: 0.72 b: 0.9]).! !


!SystemProgressMorph methodsFor: 'initialization' stamp: 'mt 4/11/2018 11:40'!
setDefaultParameters
	"change the receiver's appareance parameters"

	self
		color: (self userInterfaceTheme color ifNil: [Color r: 0.9 g: 0.9 b: 0.9]);
		borderStyle: (self userInterfaceTheme borderStyle ifNil: [BorderStyle simple]) copy;
		borderColor: (self userInterfaceTheme borderColor ifNil: [Color gray]);
		borderWidth: (self userInterfaceTheme borderWidth ifNil: [1]).

	Preferences menuAppearance3d ifTrue: [self addDropShadow].

	self
		font: (self userInterfaceTheme font ifNil: [TextStyle defaultFont]);
		textColor: (self userInterfaceTheme textColor ifNil: [Color black]).

	self
		updateColor: self
		color: self color
		intensity: 1.! !


!SystemWindow methodsFor: 'label' stamp: 'mt 4/11/2018 08:22'!
setLabel: aString
	| frame |
	labelString := aString.
	label ifNil: [^ self].
	label contents: (aString ifNil: ['']).
	self labelWidgetAllowance.  "Sets it if not already"
	self isCollapsed
		ifTrue: [self extent: (label width + labelWidgetAllowance) @ (self labelHeight + 2)]
		ifFalse: [label fitContents; setWidth: (label width min: self width - labelWidgetAllowance).
				label align: label bounds topCenter with: self topCenter + (0@self borderWidth).
				collapsedFrame ifNotNil:
					[collapsedFrame := collapsedFrame withWidth: label width + labelWidgetAllowance]].
	frame := LayoutFrame new.
	frame leftFraction: 0.5;
		 topFraction: 0.5;
		 leftOffset: label width negated // 2;
		 topOffset: label height negated // 2.
	label layoutFrame: frame.
! !

!SystemWindow methodsFor: 'focus' stamp: 'mt 2/21/2018 08:13'!
lookUnfocused
	"See #lookFocused, #activate, and #passivate."

	self isLookingFocused ifFalse: [^ self].
	self isLookingFocused: false.

	label ifNotNil: [ label color: (self userInterfaceTheme unfocusedLabelColor ifNil: [Color darkGray]) ].
	self dimWindowButtons.
	self paneColorToUseWhenNotActive in: [ : col |
		self
			 setStripeColorsFrom: col ;
			 adoptPaneColor: col ]! !


!HTTPProxyEditor methodsFor: 'initialization' stamp: 'mt 4/10/2018 11:26'!
updateWidgets
"update the receiver's widgets"
	acceptWidget isNil
		ifFalse: [""
			acceptWidget color: Color lightGreen;
				 borderStyle: (BorderStyle raised width: 2)].
	cancelWidget isNil
		ifFalse: [""
			cancelWidget color: Color lightRed;
				 borderStyle: (BorderStyle raised width: 2)].
	""
	serverNameLabelWidget isNil
		ifFalse: [""
			serverNameLabelWidget color: self paneColor lighter;
				 borderStyle: (BorderStyle raised width: serverNameLabelWidget borderWidth)].
	portLabelWidget isNil
		ifFalse: [""
			portLabelWidget color: self paneColor lighter;
				 borderStyle: (BorderStyle raised width: portLabelWidget borderWidth)]! !


!LanguageEditor methodsFor: 'initialization - toolbar' stamp: 'mt 4/10/2018 11:27'!
createButtonLabel: aString action: actionSelector help: helpString 
	"create a toolbar for the receiver"
	| button |
	button := SimpleButtonMorph new target: self;
				 label: aString translated "font: Preferences standardButtonFont";
				 actionSelector: actionSelector;
				 setBalloonText: helpString translated;
				 color: translator defaultBackgroundColor twiceDarker;
				 borderStyle: (BorderStyle raised width: 2).
	""
	^ button! !

!LanguageEditor methodsFor: 'initialization - toolbar' stamp: 'mt 4/10/2018 11:27'!
createUpdatingButtonWording: wordingSelector action: actionSelector help: helpString 
	"create a toolbar for the receiver"
	| button |
	button := (UpdatingSimpleButtonMorph newWithLabel: '-') target: self;
				 wordingSelector: wordingSelector;
				 actionSelector: actionSelector;
				 setBalloonText: helpString translated;
				 color: translator defaultBackgroundColor twiceDarker;
				 borderStyle: (BorderStyle raised width: 1);
				 cornerStyle: #square.
	""
	^ button! !


!PreferenceBrowserMorph methodsFor: 'updating' stamp: 'mt 5/4/2018 16:28'!
updateSelectedCategoryPreferences
	Cursor wait showWhile: 
		[self preferenceList 
				hScrollBarValue: 0;
				vScrollBarValue: 0.
		self preferenceList scroller removeAllMorphs.
		self preferenceList scroller addMorphBack: self newPreferenceListInnerPanel.
		self adjustPreferenceListItemsWidth.
		self adoptPaneColor: self paneColor]! !


!TTSampleFontMorph methodsFor: '*60Deprecated-accessing' stamp: 'mt 4/11/2018 08:57'!
doesBevels
	self deprecated: 'Use border styles such as InsetBorder or RaisedBorder.'.
	^ false! !

!TTSampleFontMorph methodsFor: 'drawing' stamp: 'mt 4/10/2018 11:49'!
drawOn: aCanvas
	| origin extent offset |
	(font isNil) 
		ifTrue:[^aCanvas frameRectangle: self bounds color: Color black].
	origin := self position asIntegerPoint.
	extent := self extent asIntegerPoint.
	0 to: 16 do:[:i|
		offset := (extent x * i // 16) @ (extent y * i // 16).
		aCanvas line: origin x @ (origin y + offset y) 
				to: (origin x + extent x) @ (origin y + offset y)
				width: self borderWidth color: self borderColor.
		aCanvas line: (origin x + offset x) @ origin y 
				to: (origin x + offset x) @ (origin y + extent y)
				width: self borderWidth color: self borderColor.
	].
	aCanvas asBalloonCanvas preserveStateDuring:[:balloonCanvas|
		balloonCanvas transformBy: self transform.
		balloonCanvas aaLevel: self smoothing.
		self drawCharactersOn: balloonCanvas.
	].! !


!TTSampleStringMorph methodsFor: 'drawing' stamp: 'mt 4/10/2018 11:49'!
drawOn: aCanvas
	| xStart |
	(font isNil or:[string isNil or:[string isEmpty]]) 
		ifTrue:[^aCanvas frameRectangle: self bounds color: Color black].
	xStart := 0.
	aCanvas asBalloonCanvas preserveStateDuring:[:balloonCanvas|
		balloonCanvas transformBy: self transform.
		balloonCanvas aaLevel: self smoothing.
		string do:[:char| | glyph |
			glyph := font at: char.
			balloonCanvas preserveStateDuring:[:subCanvas|
				subCanvas transformBy: (MatrixTransform2x3 withOffset: xStart@0).
				subCanvas 
					drawGeneralBezierShape: glyph contours
					color: self color 
					borderWidth: self borderWidth 
					borderColor: self borderColor].
			xStart := xStart + glyph advanceWidth.
		].
	].! !

!TTSampleStringMorph methodsFor: 'initialize' stamp: 'mt 4/11/2018 08:22'!
initializeString
	| xStart char glyph |
	(font isNil or: [string isNil]) ifTrue: [^ self].
	xStart := 0.
	ttBounds := 0@0 corner: 0@0.
	1 to: string size do:
		[:i |
		char := string at: i.
		glyph := font at: char.
		ttBounds := ttBounds quickMerge: (glyph bounds translateBy: xStart@0).
		xStart := xStart + glyph advanceWidth.
	].
	self extent: ttBounds extent // 40.
	self borderWidth: ttBounds height // 40! !

!TTSampleStringMorph methodsFor: 'private' stamp: 'mt 4/11/2018 08:22'!
computeTransform
	| cy |
	cy := bounds origin y + bounds corner y * 0.5.
	transform := MatrixTransform2x3 
			transformFromLocal: (ttBounds insetBy: self borderWidth negated)
			toGlobal: bounds.
	transform := transform composedWithGlobal:(MatrixTransform2x3 withOffset: 0 @ cy negated).
	transform := transform composedWithGlobal:(MatrixTransform2x3 withScale: 1.0 @ -1.0).
	transform := transform composedWithGlobal:(MatrixTransform2x3 withOffset: 0 @ cy).
	^transform! !


!TabSorterMorph methodsFor: 'initialization' stamp: 'mt 4/11/2018 08:22'!
initialize
	"Initialize the receiver."

	super initialize.
	self removeAllMorphs.

	self extent: 300@100.
	pageHolder := PasteUpMorph new.
	pageHolder vResizeToFit: true; autoLineLayout: true.
	pageHolder extent: self extent - self borderWidth.
	pageHolder padding: 8.
	pageHolder cursor: 0.
	pageHolder wantsMouseOverHalos: false.
	self addControls.
	self addMorphBack: pageHolder! !


!Tetris methodsFor: 'initialization' stamp: 'mt 4/10/2018 11:42'!
buildButtonTarget: aTarget label: aLabel selector: aSelector help: aString

	^self rowForButtons
		addMorph: (
			SimpleButtonMorph new 
				target: aTarget;
				label: aLabel;
				actionSelector: aSelector;
				borderStyle: (BorderStyle raised width: 2);
				color: color
		)

! !


!TextMorph methodsFor: 'accessing' stamp: 'mt 4/10/2018 11:50'!
hasTranslucentColor
	"Overridden from BorderedMorph to test backgroundColor instead of (text) color."

	^ self backgroundColor isNil
		or: [self backgroundColor isColor and: [self backgroundColor isTranslucentColor]]
		or: [self borderColor isColor and: [self borderColor isTranslucentColor]]! !

!TextMorph methodsFor: 'drawing' stamp: 'mt 4/10/2018 11:50'!
areasRemainingToFill: aRectangle
	"Overridden from BorderedMorph to test backgroundColor instead of (text) color."
	(self backgroundColor isNil or: [self backgroundColor asColor isTranslucent])
		ifTrue: [^ Array with: aRectangle].
	self wantsRoundedCorners
	ifTrue: [(self borderWidth > 0 and: [self borderColor isColor and: [self borderColor isTranslucent]])
				ifTrue: [^ aRectangle areasOutside: (self innerBounds intersect: self boundsWithinCorners)]
				ifFalse: [^ aRectangle areasOutside: self boundsWithinCorners]]
	ifFalse: [(self borderWidth > 0 and: [self borderColor isColor and: [self borderColor isTranslucent]])
				ifTrue: [^ aRectangle areasOutside: self innerBounds]
				ifFalse: [^ aRectangle areasOutside: self bounds]]! !

!TextMorph methodsFor: 'initialization' stamp: 'mt 4/11/2018 08:25'!
defaultBorderWidth
	^ 0! !

!TextMorph methodsFor: 'initialization' stamp: 'mt 4/11/2018 08:26'!
initialize

	super initialize.

	textStyle := TextStyle default copy.
	wrapFlag := true.
! !

!TextMorph methodsFor: 'layout' stamp: 'mt 4/11/2018 08:27'!
minHeight

	| result |
	textStyle ifNil: [^ 16].

	result := (textStyle lineGrid + 2) + (self borderWidth*2).
	margins ifNil: [^ result].
	
	^ margins isRectangle
		ifTrue: [result + margins top + margins bottom]
		ifFalse: [margins isPoint
			ifTrue: [result + margins y + margins y]
			ifFalse: [result + (2*margins)]]! !

!TextMorph methodsFor: 'layout' stamp: 'mt 4/11/2018 08:28'!
minWidth

	| result |
	textStyle ifNil: [^ 9].

	result := 9 + (self borderWidth*2).
	margins ifNil: [^ result].
	
	^ margins isRectangle
		ifTrue: [result + margins left + margins right]
		ifFalse: [margins isPoint
			ifTrue: [result + margins x + margins x]
			ifFalse: [result + (2*margins)]]! !

!TextMorph methodsFor: 'objects from disk' stamp: 'mt 4/11/2018 08:23'!
convertToCurrentVersion: varDict refStream: smartRefStrm
	
	self borderWidth ifNil: [
		self borderWidth: 0.
		self removeProperty: #fillStyle].
	^ super convertToCurrentVersion: varDict refStream: smartRefStrm.

! !

!TextMorph methodsFor: 'private' stamp: 'mt 4/11/2018 08:24'!
fit
	"Adjust my bounds to fit the text.  Should be a no-op if autoFit is not specified.
	Required after the text changes,
	or if wrapFlag is true and the user attempts to change the extent."

	| newExtent para cBounds lastOfLines heightOfLast wid |
	self isAutoFit 
		ifTrue: 
			[wid := (text notNil and: [text size > 2]) ifTrue: [5] ifFalse: [40].
			newExtent := (self paragraph extent max: wid @ ( self defaultLineHeight)) + (0 @ 2).
			newExtent := newExtent + (2 * self borderWidth).
			margins 
				ifNotNil: [newExtent := ((0 @ 0 extent: newExtent) expandBy: margins) extent].
			newExtent ~= bounds extent 
				ifTrue: 
					[(container isNil and: [successor isNil]) 
						ifTrue: 
							[para := paragraph.	"Save para (layoutChanged smashes it)"
							super extent: newExtent.
							paragraph := para]].
			container notNil & successor isNil 
				ifTrue: 
					[cBounds := container bounds truncated.
					"23 sept 2000 - try to allow vertical growth"
					lastOfLines := self paragraph lines last.
					heightOfLast := lastOfLines bottom - lastOfLines top.
					(lastOfLines last < text size 
						and: [lastOfLines bottom + heightOfLast >= self bottom]) 
							ifTrue: 
								[container releaseCachedState.
								cBounds := cBounds origin corner: cBounds corner + (0 @ heightOfLast)].
					self privateBounds: cBounds]].

	"These statements should be pushed back into senders"
	self paragraph positionWhenComposed: self position.
	successor ifNotNil: [successor predecessorChanged].
	self changed	"Too conservative: only paragraph composition
					should cause invalidation."! !


!ThreadNavigationMorph methodsFor: 'initialization' stamp: 'mt 4/10/2018 11:42'!
makeButton: aString balloonText: anotherString for: aSymbol 
	^ SimpleButtonDelayedMenuMorph new target: self;
		 borderStyle: BorderStyle raised;
		 color: self colorForButtons;
		 label: aString translated font: self fontForButtons;
		 setBalloonText: anotherString translated;
		 actionSelector: aSymbol! !


!TileMorph methodsFor: 'misc' stamp: 'mt 4/10/2018 11:50'!
typeColor: aColor
	"Set the receiver's typeColor"

	self borderColor: ScriptingSystem standardTileBorderColor.

	typeColor := aColor.
	color := ScriptingSystem uniformTileInteriorColor ! !


!TrimTheme class methodsFor: 'instance creation' stamp: 'mt 4/11/2018 10:36'!
addButtons: theme

	theme
		set: #borderColor for: #PluggableButtonMorph to: self gray102;
		set: #borderWidth for: #PluggableButtonMorph to: 1;
		set: #borderStyle for: #PluggableButtonMorph to: BorderStyle simple;
		set: #color for: #PluggableButtonMorph to: self gray76;
		
		set: #textColor for: #PluggableButtonMorph to: self white;

		set: #selectionModifier for: #PluggableButtonMorph to: [ [:c | self gray39] ];
		set: #hoverModifier for: #PluggableButtonMorph to: [ [:c | self gray51] ];
		set: #feedbackModifier for: #PluggableButtonMorph to: [ [:c | self gray39] ].
	
	"And the plus-version."
	theme
		set: #disabledColor for: #PluggableButtonMorphPlus to: Color transparent;
		set: #disabledTextColor for: #PluggableButtonMorphPlus to: self gray128.! !

!TrimTheme class methodsFor: 'instance creation' stamp: 'mt 4/11/2018 10:36'!
addDialogs: theme
	"self create apply."
	
	theme
		set: #borderColor for: #DialogWindow to: self gray59;
		set: #borderWidth for: #DialogWindow to: 0;
		set: #borderStyle for: #DialogWindow to: BorderStyle simple;
		set: #color for: #DialogWindow to: self gray64;

		set: #titleBorderColor for: #DialogWindow to: self gray59;
		set: #titleBorderWidth for: #DialogWindow to: 0;
		set: #titleBorderStyle for: #DialogWindow to: BorderStyle simple;
		set: #titleColor for: #DialogWindow to: self gray51;
		set: #titleTextColor for: #DialogWindow to: self white;
		
		set: #textColor for: #DialogWindow to: self white;
		
		set: #okColor for: #DialogWindow to: self green;
		set: #cancelColor for: #DialogWindow to: self red;
		set: #buttonColor for: #DialogWindow to: self gray59;
		set: #selectionModifier for: #DialogWindow to: [ [:c | self blue ] ].
	
	"The List Chooser is a dialog, too."
	theme
		set: #addColor for: #ListChooser to: self yellow;
		set: #disabledColor for: #ListChooser to: Color transparent.

		
	"And the system progress bar."
	theme		
		set: #borderColor for: #SystemProgressBarMorph to: Color transparent;
		set: #borderWidth for: #SystemProgressBarMorph to: 0;
		set: #borderStyle for: #SystemProgressBarMorph to: BorderStyle simple;
		set: #color for: #SystemProgressBarMorph to: self gray64;
		set: #barColor for: #SystemProgressBarMorph to: self blue.
		
	"And the balloon morphs."
	theme
		set: #borderColor for: #NewBalloonMorph to: self gray168;
		set: #borderWidth for: #NewBalloonMorph to: 1;
		set: #color for: #NewBalloonMorph to: self gray102;
		set: #textColor for: #NewBalloonMorph to: self white.! !

!TrimTheme class methodsFor: 'instance creation' stamp: 'mt 4/11/2018 10:36'!
addMenusAndDockingBars: theme

	theme
		set: #borderColor for: #MenuMorph to: self gray51;
		set: #borderWidth for: #MenuMorph to: 1;
		set: #borderStyle for: #MenuMorph to: BorderStyle simple;
		set: #color for: #MenuMorph to: self gray27;

		set: #titleBorderColor for: #MenuMorph to: (Color r: 0.6 g: 0.7 b: 1);
		set: #titleBorderWidth for: #MenuMorph to: 0;
		set: #titleBorderStyle for: #MenuMorph to: BorderStyle simple;
		set: #titleColor for: #MenuMorph to: Color transparent;
		set: #titleTextColor for: #MenuMorph to: self white;
		
		set: #lineColor for: #MenuMorph to: self gray51;
		set: #lineStyle for: #MenuMorph to: BorderStyle simple;
		set: #lineWidth for: #MenuMorph to: 1.
		
	theme
		set: #textColor for: #MenuItemMorph to: self white;
		set: #disabledTextColor for: #MenuItemMorph to: self gray128;
		set: #selectionColor for: #MenuItemMorph to: self gray102;
		set: #selectionTextColor for: #MenuItemMorph to: self white.
		
	"The world main docking bar."
	theme
		set: #logoColor for: #TheWorldMainDockingBar to: self white;
		set: #selectionLogoColor for: #TheWorldMainDockingBar to: self white.! !

!TrimTheme class methodsFor: 'instance creation' stamp: 'mt 4/11/2018 10:36'!
addScrollables: theme
	"self create apply"
	
	"Sliders"
	theme
		set: #borderColor for: #Slider to: self gray76;
		set: #borderWidth for: #Slider to: 1;
		set: #color for: #Slider to: self gray61;
		set: #thumbBorderColor for: #Slider to: self gray61;
		set: #thumbBorderWidth for: #Slider to: 1;
		set: #thumbColor for: #Slider to: self gray128;
		set: #thumbShadowModifier for: #Slider to: [ [:c | c alpha: 0.7] ].
				
	"Scroll bars"
	theme
		set: #thumbBorderWidth for: #ScrollBar to: 1;
		set: #thumbColorModifier for: #ScrollBar to: [ [:c | c adjustBrightness: 0.2] ];
		"set: #pagingAreaColorModifier for: #ScrollBar to: [ [:c | self gray51] ];"
		set: #borderColorModifier for: #ScrollBar to: [ [:c | c adjustBrightness: 0.2] ].
	
	"Scroll panes (includes generic stuff for list widgets, tree widgets, and text widgets."
	theme
		set: #borderColor for: #ScrollPane to: self gray76;
		set: #borderWidth for: #ScrollPane to: 1;
		set: #borderStyle for: #ScrollPane to: BorderStyle simple;
		set: #color for: #ScrollPane to: self gray51.
		
	"List widgets"
	theme
		set: #textColor for: #PluggableListMorph to: self white;
		set: #selectionColor for: #PluggableListMorph to: self blue;
		derive: #multiSelectionColor for: #PluggableListMorph from: #PluggableListMorph at: #selectionColor do: [:c | c lighter];
		set: #selectionTextColor for: #PluggableListMorph to: self white;
		set: #filterColor for: #PluggableListMorph to: self orange;
		set: #filterTextColor for: #PluggableListMorph to: self white;
		set: #preSelectionModifier for: #PluggableListMorph to: [ [:c | c alpha: 0.3] ];
		set: #hoverSelectionModifier for: #PluggableListMorph to: [ [:c | c darker alpha: 0.3] ].
		
	"Tree widgets"
	theme		
		set: #higlightTextColor for: #SimpleHierarchicalListMorph to: self red;
		set: #lineColor for: #SimpleHierarchicalListMorph to: self gray168.
	
	"Text widgets"
	theme
		set: #textColor for: #PluggableTextMorph to: self white;
		set: #caretColor for: #PluggableTextMorph to: self white;
		set: #selectionColor for: #PluggableTextMorph to: (self blue alpha: 0.4);
		set: #unfocusedSelectionModifier for: #PluggableTextMorph to: [ [:c | self blue alpha: 0.3] ];
		set: #adornmentReadOnly for: #PluggableTextMorph to: self black;
		set: #adornmentRefuse for: #PluggableTextMorph to: self blue;
		set: #adornmentConflict for: #PluggableTextMorph to: self red;
		set: #adornmentDiff for: #PluggableTextMorph to: self green;
		set: #adornmentNormalEdit for: #PluggableTextMorph to: self orange;
		set: #adornmentDiffEdit for: #PluggableTextMorph to: self yellow;
		set: #frameAdornmentWidth for: #PluggableTextMorph to: 1.
	theme
		set: #balloonTextColor for: #PluggableTextMorphPlus to: self gray102.! !


!TwoWayScrollPane methodsFor: 'geometry' stamp: 'mt 4/11/2018 08:26'!
fitContents
	"Adjust my size to fit my contents reasonably snugly"

	self extent: scroller submorphBounds extent
				+ (yScrollBar width @ xScrollBar height)
				+ (self borderWidth*2)
				 ! !

!TwoWayScrollPane methodsFor: 'initialization' stamp: 'mt 4/10/2018 11:15'!
createScrollBarNamed: aString 
"creates a scroll bar named as aString"
	| result |
	result := ScrollBar new model: self slotName: aString.
	result borderStyle: (BorderStyle inset width: 2).
	^ result! !

!TwoWayScrollPane methodsFor: 'initialization' stamp: 'mt 5/4/2018 15:52'!
defaultBorderColor
	^ Color transparent! !

!TwoWayScrollPane methodsFor: 'initialization' stamp: 'mt 4/11/2018 08:49'!
defaultBorderStyle
	^ BorderStyle inset! !


!URLMorph methodsFor: 'drawing' stamp: 'mt 4/10/2018 11:51'!
drawOn: aCanvas
	"Draw thumbnail for my page, if it is available. Otherwise, just draw a rectangle." 

	| thumbnail oldExt |
	self color == Color transparent 
	ifTrue: ["show thumbnail"
		thumbnail := self thumbnailOrNil.
		thumbnail
			ifNil: [aCanvas frameRectangle: self bounds width: self borderWidth 
						color: self borderColor.
				aCanvas fillRectangle: (self bounds insetBy: self borderWidth) color: self color]
			ifNotNil: [oldExt := self bounds extent.
				bounds := self bounds origin extent: thumbnail extent + (2@2).
				aCanvas frameRectangle: self bounds width: self borderWidth color: self borderColor.
				aCanvas paintImage: thumbnail at: self bounds origin + self borderWidth.
				oldExt = thumbnail extent ifFalse: [self layoutChanged]]]
	ifFalse: ["show labeled button"
		^ super drawOn: aCanvas]
! !


!WatchMorph methodsFor: 'drawing' stamp: 'mt 4/10/2018 11:52'!
drawOn: aCanvas
	"Draw the watch on the given canvas"

	| pHour pMin pSec time centerColor |
	time := Time now.
	pHour := self radius: 0.6 hourAngle: time hours + (time minutes/60.0).
	pMin := self radius: 0.72 hourAngle: (time minutes / 5.0).
	pSec := self radius: 0.8 hourAngle: (time seconds / 5.0).
	centerColor := cColor
		ifNil:
			[Color transparent]
		ifNotNil:
			[time hours < 12
				ifTrue: [cColor muchLighter]
				ifFalse: [cColor]].

	antialias ifTrue:
		[aCanvas asBalloonCanvas
			aaLevel: 4;
			drawOval: (self bounds insetBy: self borderWidth // 2 + 1) color: self fillStyle
				borderWidth: self borderWidth borderColor: self borderColor;
			drawOval: (self bounds insetBy: self extent*0.35) color: centerColor
				borderWidth: 0 borderColor: Color black;
			drawPolygon: {self center. pHour}
				color: Color transparent borderWidth: 3 borderColor: handsColor;
			drawPolygon: {self center. pMin}
				color: Color transparent borderWidth: 2 borderColor: handsColor;
			drawPolygon: {self center. pSec}
				color: Color transparent borderWidth: 1 borderColor: handsColor]
		ifFalse:
			[super drawOn: aCanvas.
			aCanvas
				fillOval: (self bounds insetBy: self extent*0.35) color: centerColor;
				line: self center to: pHour width: 3 color: handsColor;
				line: self center to: pMin width: 2 color: handsColor;
				line: self center to: pSec width: 1 color: handsColor]
! !


!PDAClockMorph methodsFor: 'drawing' stamp: 'mt 4/10/2018 11:45'!
drawOn: aCanvas

	aCanvas frameAndFillRectangle: self bounds fillColor: backgroundColor
				borderWidth: self borderWidth borderColor: self borderColor.
	super drawOn: aCanvas.
! !


!TTSampleFontMorph reorganize!
('accessing' font font: smoothing smoothing: transform)
('*60Deprecated-accessing' doesBevels)
('copying' veryDeepFixupWith: veryDeepInner:)
('drawing' areasRemainingToFill: drawCharactersOn: drawOn:)
('geometry' extent: position:)
('halos and balloon help' addOptionalHandlesTo:box: balloonHelpTextForHandle:)
('initialization' defaultBorderWidth defaultColor initialize openInWorld)
('initialize' open)
('menu' createSample getSmoothingLevel nextSmoothingLevel)
('menus' addCustomMenuItems:hand:)
('rotate scale and flex' newTransformationMorph)
('testing' canDrawBorder:)
('updating' changed)
('private' computeTransform privateMoveBy:)
('connectors' fontWithoutString: glyphAt: glyphIndexAt: printOn: selectGlyph selectGlyphAndSendTo: selectGlyphBlock:event:from:)
!

PreferenceBrowserMorph removeSelector: #isWindowForModel:!

!PreferenceBrowserMorph reorganize!
('event handling' basicKeyPressed: downKeyPressed: endKeyPressed: homeKeyPressed: keyPressed: mouseDownOn:event: pageDownKeyPressed: pageUpKeyPressed: upKeyPressed:)
('geometry' extent:)
('initialization' initializeWithModel:)
('model access' selectedCategory selectedCategoryIndex selectedCategoryIndex: selectedCategoryPreferences selectedPreference selectedPreferenceIndex selectedPreferenceIndex: selectedPreference:)
('submorphs - buttons' basicButton buttonRowLayoutFrame defaultButton helpButton loadButton loadFromDiskButton newButtonRow newSeparator newTransparentFiller saveButton saveToDiskButton themeButton)
('submorphs - category list' newCategoryList newCategoryListPanel newCategoryListPanelLabel)
('submorphs - main panel' mainPanel)
('submorphs - preference list' newPreferenceButtonFor: newPreferenceListInnerPanel newPreferenceListPanel newPreferenceListPanelLabel preferenceList preferenceListInnerPanel preferencesShowing selectedPreferenceButton turnOffSelectedPreference turnOnSelectedPreference)
('submorphs - root panel' rootPanel rootPanelLayoutFrame)
('submorphs - search panel' newSearchButton newSearchPanel newSearchTextField)
('updating' adjustPreferenceListItemsWidth updateSelectedCategoryPreferences updateSelectedPreference update:)
!

IconicButton removeSelector: #borderInset!
IconicButton removeSelector: #borderRaised!

!IconicButton reorganize!
('as yet unclassified' darken darkenedForm labelFromString: labelGraphic: restoreImage shedSelvedge)
('events' mouseEnter: mouseLeave:)
('initialization' borderNormal borderThick buttonSetup defaultBorderWidth initialize initializeWithThumbnail:withLabel:andColor:andSend:to: initializeWithThumbnail:withLabel:andSend:to: setDefaultLabel stationarySetup)
('menu' addLabelItemsTo:hand:)
('*MorphicExtras-initialization' initializeToShow:withLabel:andSend:to:)
('button' doButtonAction)
('*Etoys-Squeakland-menu' launchPartFromClick)
!


!RaisedBorder reorganize!
('accessing' bottomRightColor style topLeftColor)
('*60Deprecated-accessing' colorsAtCorners)
('color tracking' trackColorFrom:)
!


!InsetBorder reorganize!
('accessing' bottomRightColor style topLeftColor)
('*60Deprecated-accessing' colorsAtCorners)
('color tracking' trackColorFrom:)
!


!ComplexBorder reorganize!
('accessing' colors style style:)
('*60Deprecated-accessing' widthForRounding)
('color tracking' trackColorFrom:)
('drawing' drawLineFrom:to:on: drawPolyPatchFrom:to:on:usingEnds: framePolygon2:on: framePolygon:on: frameRectangle:on:)
('initialize' releaseCachedState)
('testing' isComplex)
('private' colorsForDirection: computeAltFramedColors computeAltInsetColors computeAltRaisedColors computeColors computeFramedColors computeInsetColors computeRaisedColors fillStyleForDirection: intersectFrom:with:to:with:)
!

SameGameBoard removeSelector: #defaultBorderStyle!

!ProjectViewMorph reorganize!
('accessing' borderWidthForRounding project thumbnail)
('as yet unclassified' addProjectNameMorph addProjectNameMorphFiller editTheName: expungeProject)
('caching' releaseCachedState)
('copying' veryDeepFixupWith: veryDeepInner:)
('drawing' colorAroundName drawOn: ensureImageReady fontForName isEditingName isTheRealProjectPresent safeProjectName safeProjectName: showBorderAs: updateImageFrom: updateNamePosition)
('dropping/grabbing' wantsDroppedMorph:event:)
('event handling' handlesMouseDown: handlesMouseOver: handlesMouseOverDragging: mouseDown: mouseEnter: mouseLeave: mouseLeaveDragging: mouseUp: wantsKeyboardFocusFor:)
('events' balloonText checkForNewerVersionAndLoad doButtonAction enter enterAsActiveSubproject enterWhenNotPresent lastProjectThumbnail: on: project: seeIfNameChanged showMenuForProjectView showMouseState: withProgressDo:)
('fileIn/out' storeSegment)
('geometry' extent:)
('initialization' dismissViaHalo initialize)
('layout' acceptDroppingMorph:event:)
('objects from disk' objectForDataStream:)
('rounding' wantsRoundedCorners)
('stepping and presenter' step)
('submorphs-add/remove' abandon)
('testing' stepTime)
('*MorphicExtras-event handling' handlesMouseStillDown: mouseStillDown:)
('*60Deprecated-accessing')
('*MorphicExtras-*morphic-Postscript Canvases' fullDrawPostscriptOn:)
('*Etoys-user interface' eToyStreamedRepresentationNotifying:)
('*Morphic-Sound-piano rolls' triggerActionFromPianoRoll)
!


!PolygonMorph reorganize!
('access' isClosed isCurve isOpen makeOpenOrClosed midVertices openOrClosePhrase smoothOrSegmentedPhrase vertices)
('accessing' borderColor: borderDashSpec borderStyle: borderWidth: couldHaveRoundedCorners)
('caching' loadCachedState releaseCachedState)
('dashes' borderDashOffset dashedBorder dashedBorder: removeVertex: vertexAt:)
('debug and other' installModelIn: rotateTestFlip:)
('drawing' areasRemainingToFill: drawArrowOn:at:from: drawArrowsOn: drawBorderOn: drawBorderOn:usingEnds: drawClippedBorderOn:usingEnds: drawDashedBorderOn: drawDashedBorderOn:usingEnds: drawOnFormCanvas: drawOn:)
('dropping/grabbing' justDroppedInto:event:)
('editing' addHandles clickVertex:event:fromHandle: deleteVertexAt: dragVertex:event:fromHandle: dragVertex:fromHandle:vertIndex: dropVertex:event:fromHandle: dropVertex:fromHandle:vertIndex: handleColorAt: insertVertexAt:put: newVertex:event:fromHandle: newVertex:fromHandle:afterVert: updateHandles verticesAt:put:)
('event handling' handlesMouseDown: mouseDown:)
('geometry' arrowsContainPoint: bounds: closestPointTo: closestSegmentTo: extent: flipHAroundX: flipVAroundY: intersectionsWith: intersectionWithLineSegmentFromCenterTo: intersects: isBordered lineBorderColor lineBorderColor: lineBorderWidth lineBorderWidth: lineColor lineColor: lineWidth lineWidth: mergeDropThird:in:from: merge: nextDuplicateVertexIndex reduceVertices straighten transformedBy:)
('geometry eToy' referencePosition rotationCenter rotationCenter:)
('geometry testing' containsPoint:)
('halo control' rotationDegrees:)
('initialization' beSmoothCurve beStraightSegments defaultBorderColor defaultColor initialize vertices:color:borderWidth:borderColor:)
('menu' addCustomMenuItems:hand: addPolyArrowMenuItems:hand: addPolyLIneCurveMenuItems:hand: addPolyShapingMenuItems:hand: arrowLength: arrowSpec: arrows customizeArrows: handlesShowingPhrase makeBackArrow makeBothArrows makeClosed makeForwardArrow makeNoArrows makeOpen quickFill: removeHandles setRotationCenterFrom: showingHandles showOrHideHandles specifyDashedLine standardArrows toggleHandles toggleSmoothing unrotatedLength unrotatedLength: unrotatedWidth unrotatedWidth:)
('objects from disk' convertToCurrentVersion:refStream:)
('rotate scale and flex' addFlexShellIfNecessary rotationDegrees)
('smoothing' coefficients computeNextToEndPoints derivs:first:second:third: lineSegmentsDo: nextToFirstPoint nextToLastPoint slopes: straightLineSegmentsDo:)
('stepping and presenter' step)
('testing' hasArrows isCurvier isCurvy isLineMorph stepTime wantsSteps)
('visual properties' canHaveFillStyles fillStyle fillStyle:)
('*MorphicExtras-geometry eToy' scale:)
('*MorphicExtras-*morphic-Postscript Canvases' drawPostscriptOn:)
('private' arrowBoundsAt:from: arrowForms borderForm computeArrowFormAt:from: computeBounds curveBounds filledForm getVertices includesHandle: lineSegments privateMoveBy: setVertices: transformVerticesFrom:to:)
('shaping' diamondOval rectOval)
('attachments' boundsSignatureHash defaultAttachmentPointSpecs endShapeColor: endShapeWidth: firstVertex lastVertex midpoint nudgeForLabel: totalLength)
('rounding' cornerStyle:)
('*Etoys-geometry' heading:)
('*Etoys-Squeakland-vertices operations' appendVertex insertVertexAtCursor prependVertex removeAllButCursor removeVertexAtCursor setVerticesCount: shuffleVertices vertexAtCursor vertexAtCursorPut: vertexCursor vertexCursor: xAtCursor xAtCursor: yAtCursor yAtCursor:)
('*Etoys-Squeakland-menu' smoothPhrase)
!


!EllipseMorph reorganize!
('accessing' couldHaveRoundedCorners)
('drawing' areasRemainingToFill: drawOn:)
('geometry testing' containsPoint:)
('initialization' defaultBorderWidth defaultColor)
('testing' canDrawBorder:)
('visual properties' canHaveFillStyles)
('*60Deprecated-accessing' doesBevels)
('geometry' bottomLeftCorner bottomRightCorner closestPointTo: intersectionWithLineSegmentFromCenterTo: topLeftCorner topRightCorner)
('rounding' cornerStyle:)
!

BorderedMorph removeSelector: #borderColor!
BorderedMorph removeSelector: #borderStyle!
BorderedMorph removeSelector: #borderWidth!

!BorderedMorph reorganize!
('accessing' borderColor: borderStyle: borderWidth: hasTranslucentColor useRoundedCorners useSquareCorners)
('drawing' areasRemainingToFill:)
('geometry' acquireBorderWidth: closestPointTo: intersectionWithLineSegmentFromCenterTo:)
('initialization' borderInitialize borderInset borderRaised borderSimple defaultBorderColor defaultBorderStyle defaultBorderWidth initialize)
('menu' addBorderStyleMenuItems:hand: changeBorderColor: changeBorderWidth:)
('*60Deprecated-accessing' doesBevels)
('*MorphicExtras-initialization' basicInitialize)
('*MorphicExtras-printing' fullPrintOn:)
('private' setBorderWidth:borderColor: setColor:borderWidth:borderColor:)
('*Etoys' understandsBorderVocabulary)
('resize handling' addCornerGrips addEdgeGrips addMorph:fullFrame: addPaneHSplitterBetween:and: addPaneHSplitters addPaneSplitters addPaneVSplitterBetween:and: addPaneVSplitters doFastWindowReframe: fastFramingOn grips linkSubmorphsToSplitters paneMorphs removeCornerGrips removePaneSplitters splitters wantsPaneSplitters wantsPaneSplitters:)
('*Etoys-Squeakland-accessing' useRoundedCornersInEtoys)
!


!Morph reorganize!
('accessing' actorStateOrNil actorState: adoptPaneColor: balloonText balloonText: balloonTextSelector balloonTextSelector: beFlap: beSticky beUnsticky borderColor borderColor: borderStyle borderStyleForSymbol: borderStyle: borderWidth borderWidth: borderWidthForRounding clearArea color colorForInsets color: couldHaveRoundedCorners defaultNameStemForInstances eventHandler eventHandler: forwardDirection hasTranslucentColor highlight highlightColor highlightColor: insetColor isFlap isLocked isShared isSticky lock lock: methodCommentAsBalloonHelp modelOrNil player playerRepresented player: presenter raisedColor regularColor regularColor: rememberedColor rememberedColor: resistsRemoval resistsRemoval: scaleFactor setBorderStyle: sqkPage sticky: toggleLocked toggleResistsRemoval toggleStickiness unHighlight unlock unlockContents url userString viewBox visibleClearArea wantsToBeCachedByHand wantsToBeTopmost)
('accessing - extension' assureExtension extension hasExtension initializeExtension privateExtension: resetExtension)
('accessing - properties' hasProperty: otherProperties removeProperty: setProperties: setProperty:toValue: valueOfProperty: valueOfProperty:ifAbsentPut: valueOfProperty:ifAbsent: valueOfProperty:ifPresentDo:)
('caching' fullLoadCachedState fullReleaseCachedState loadCachedState releaseCachedState)
('change reporting' addedMorph: colorChangedForSubmorph: invalidRect: invalidRect:from: ownerChanged privateInvalidateMorph: userSelectedColor:)
('classification' demandsBoolean isAlignmentMorph isBalloonHelp isCompoundTileMorph isFlapOrTab isFlapTab isFlexMorph isHandMorph isKedamaMorph isModalShell isNumericReadoutTile isPhraseTileMorph isPlayfieldLike isRenderer isSoundTile isStandardViewer isStickySketchMorph isSyntaxMorph isTextMorph isTileMorph isTilePadMorph isViewer isWorldMorph isWorldOrHandMorph)
('connectors-scripting' wantsConnectorVocabulary)
('converting' asDraggableMorph asSnapshotThumbnail)
('copying' copy deepCopy duplicate duplicateMorphCollection: fullCopy updateReferencesUsing: usableSiblingInstance veryDeepCopyWith: veryDeepFixupWith: veryDeepInner:)
('creation' asMorph)
('debug and other' addDebuggingItemsTo:hand: addMouseActionIndicatorsWidth:color: addMouseUpAction addMouseUpActionWith: addViewingItemsTo: allStringsAfter: altSpecialCursor0 altSpecialCursor1 altSpecialCursor2 altSpecialCursor3 altSpecialCursor3: buildDebugMenu: defineTempCommand deleteAnyMouseActionIndicators inspectArgumentsPlayerInMorphic: inspectOwnerChain installModelIn: mouseUpCodeOrNil ownerChain programmedMouseDown:for: programmedMouseEnter:for: programmedMouseLeave:for: programmedMouseUp:for: removeMouseUpAction resumeAfterDrawError resumeAfterStepError tempCommand viewMorphDirectly)
('dispatching' disableSubmorphFocusForHand:)
('drawing' areasRemainingToFill: boundingBoxOfSubmorphs boundsWithinCorners changeClipSubmorphs clipLayoutCells clipLayoutCells: clippingBounds clipSubmorphs clipSubmorphs: doesOwnRotation drawDropHighlightOn: drawDropShadowOn: drawErrorOn: drawKeyboardFocusIndicationOn: drawMouseDownHighlightOn: drawOn: drawOverlayOn: drawRolloverBorderOn: drawSubmorphsOn: expandFullBoundsForDropShadow: expandFullBoundsForRolloverBorder: flashBounds fullDrawOn: hasClipSubmorphsString hide highlightedForMouseDown highlightForMouseDown highlightForMouseDown: imageForm imageFormDepth: imageFormForRectangle: imageFormWithout:andStopThere: imageForm:backgroundColor:forRectangle: imageForm:forRectangle: keyboardFocusColor keyboardFocusWidth refreshWorld shadowForm show updateDropShadowCache visible visible:)
('drop shadows' addDropShadow addDropShadowMenuItems:hand: changeShadowColor hasDropShadow hasDropShadowString hasDropShadow: hasRolloverBorder hasRolloverBorder: removeDropShadow setShadowOffset: shadowColor shadowColor: shadowOffset shadowOffset: shadowPoint: toggleDropShadow useSoftDropShadow useSoftDropShadow:)
('dropping/grabbing' aboutToBeGrabbedBy: disableDragNDrop dragEnabled dragEnabled: dragNDropEnabled dragSelectionColor dropEnabled dropEnabled: dropHighlightColor dropSuccessColor enableDragNDrop enableDragNDrop: enableDrag: enableDrop: formerOwner formerOwner: formerPosition formerPosition: grabTransform handledOwnDraggingBy:on: highlightedForDrop highlightForDrop highlightForDrop: justDroppedInto:event: justGrabbedFrom: morphToDropInPasteUp: nameForUndoWording rejectDropMorphEvent: repelsMorph:event: resetHighlightForDrop separateDragAndDrop slideBackToFormerSituation: slideToTrash: startDrag:with: toggleDragNDrop transportedMorph undoGrabCommand vanishAfterSlidingTo:event: wantsDroppedMorph:event: wantsToBeDroppedInto: wantsToBeOpenedInWorld willingToBeDiscarded)
('event handling' click click: cursorPoint doubleClickTimeout: doubleClick: dropFiles: firstClickTimedOut: handlerForMouseDown: handlerForYellowButtonDown: handlesKeyboard: handlesMouseDown: handlesMouseMove: handlesMouseOverDragging: handlesMouseOver: handlesMouseStillDown: handlesMouseWheel: hasFocus hasKeyboardFocus hasKeyboardFocus: hasMouseFocus hasMouseFocus: keyboardFocusChange: keyDown: keyStroke: keyUp: keyboardFocusDelegate mouseDown: mouseEnterDragging: mouseEnter: mouseLeaveDragging: mouseLeave: mouseMove: mouseStillDownThreshold mouseStillDown: mouseUp: mouseWheel: moveOrResizeFromKeystroke: on:send:to: on:send:to:withValue: preferredKeyboardBounds preferredKeyboardPosition removeLink: restoreSuspendedEventHandler startDrag: suspendEventHandler tabAmongFields transformFromOutermostWorld transformFromWorld transformFrom: wantsDropFiles: wantsEveryMouseMove wantsKeyboardFocus wantsKeyboardFocusFor: wantsWindowEvents: windowEvent: wouldAcceptKeyboardFocus wouldAcceptKeyboardFocusUponTab yellowButtonActivity:)
('events-accessing' actionMap updateableActionMap)
('events-alarms' addAlarm:after: addAlarm:at: addAlarm:withArguments:after: addAlarm:withArguments:at: addAlarm:with:after: addAlarm:with:at: addAlarm:with:with:after: addAlarm:with:with:at: alarmScheduler removeAlarm: removeAlarm:at:)
('events-processing' containsPoint:event: defaultEventDispatcher handleDropFiles: handleDropMorph: handleEvent: handleFocusEvent: handleKeyDown: handleKeyUp: handleKeystroke: handleListenEvent: handleMouseDown: handleMouseEnter: handleMouseLeave: handleMouseMove: handleMouseOver: handleMouseStillDown: handleMouseUp: handleMouseWheel: handleUnknownEvent: handleWindowEvent: mouseDownPriority mouseDownPriority: processEvent: processEvent:using: processFocusEvent: processFocusEvent:using: rejectDropEvent: rejectsEvent: sendFilterEvent:for:to: sendFilterEventBubble:for: sendFilterEventBubbleAgain:for: sendFilterEventCapture:for: sendFilterEventCaptureAgain:for: transformedFrom:)
('events-removing' releaseActionMap)
('fileIn/out' attachToResource prepareToBeSaved reserveUrl: saveAsResource saveDocPane saveOnFile saveOnURL saveOnURLbasic saveOnURL: updateAllFromResources updateFromResource)
('filter streaming' drawOnCanvas:)
('geometry' align:with: bottom bottomCenter bottomLeft bottomLeft: bottomRight bottomRight: bottom: bounds boundsInWorld boundsIn: bounds: bounds:from: bounds:in: center center: extent extent: fullBoundsInWorld globalPointToLocal: griddedPoint: gridPoint: height height: innerBounds intersects: left leftCenter left: localPointToGlobal: minimumExtent minimumExtent: minimumHeight minimumHeight: minimumWidth minimumWidth: outerBounds overlapsShadowForm:bounds: pointFromWorld: pointInWorld: point:from: point:in: position positionInWorld positionSubmorphs position: right rightCenter right: screenLocation screenRectangle setConstrainedPosition:hangOut: shiftSubmorphsOtherThan:by: top topCenter topLeft topLeft: topRight topRight: top: transformedBy: width width: worldBounds worldBoundsForHalo)
('geometry testing' containsPoint: fullContainsPoint: obtrudesBeyondContainer)
('halos and balloon help' addHalo addHalo: addHalo:from: addHandlesTo:box: addMagicHaloFor: addOptionalHandlesTo:box: addSimpleHandlesTo:box: addWorldHandlesTo:box: balloonColor balloonColor: balloonFont balloonFont: balloonHelpAligner balloonHelpDelayTime balloonHelpTextForHandle: balloonMorphClass boundsForBalloon comeToFrontAndAddHalo createHalo defaultBalloonColor defaultBalloonFont defersHaloOnClickTo: deleteBalloon editBalloonHelpContent: editBalloonHelpText halo haloClass haloDelayTime hasHalo hasHalo: isLikelyRecipientForMouseOverHalos mouseDownOnHelpHandle: noHelpString okayToAddDismissHandle okayToAddGrabHandle okayToBrownDragEasily okayToExtractEasily okayToResizeEasily okayToRotateEasily preferredDuplicationHandleSelector removeHalo setBalloonText: setBalloonText:maxLineLength: setCenteredBalloonText: showBalloon showBalloon: showBalloon:at: showBalloon:hand: transferHalo:from: wantsBalloon wantsDirectionHandles wantsDirectionHandles: wantsHalo wantsHaloFor: wantsHaloFromClick wantsHaloFromClick: wantsHaloHandleWithSelector:inHalo: wantsScriptorHaloHandle wantsSimpleSketchMorphHandles)
('initialization' basicInitialize defaultBounds defaultColor inAScrollPane inATwoWayScrollPane initialize intoWorld: openCenteredInWorld openInHand openInWindow openInWindowLabeled: openInWindowLabeled:inWorld: openInWorld openInWorld: openNear: openNear:in: openNearMorph: outOfWorld: resourceJustLoaded standardPalette)
('layout' acceptDroppingMorph:event: adjustLayoutBounds doLayoutIn: fullBounds layoutBounds layoutBounds: layoutChanged layoutInBounds: layoutProportionallyIn: minExtent minExtent: minHeight minHeight: minWidth minWidth: privateFullBounds submorphBounds)
('layout-menu' addCellLayoutMenuItems:hand: addLayoutMenuItems:hand: addTableLayoutMenuItems:hand: changeCellInset: changeClipLayoutCells changeDisableTableLayout changeLayoutInset: changeListDirection: changeMaxCellSize: changeMinCellSize: changeNoLayout changeProportionalLayout changeReverseCells changeRubberBandCells changeTableLayout hasClipLayoutCellsString hasDisableTableLayoutString hasNoLayoutString hasProportionalLayoutString hasReverseCellsString hasRubberBandCellsString hasTableLayoutString layoutMenuPropertyString:from:)
('layout-properties' assureLayoutProperties assureTableProperties cellInset cellInset: cellPositioning cellPositioningString: cellPositioning: cellSpacing cellSpacingString: cellSpacing: copyLayoutProperties disableTableLayout disableTableLayout: hResizing hResizingString: hResizing: layoutFrame layoutFrame: layoutInset layoutInset: layoutPolicy layoutPolicy: layoutProperties layoutProperties: listCentering listCenteringString: listCentering: listDirection listDirectionString: listDirection: listSpacing listSpacingString: listSpacing: maxCellSize maxCellSize: minCellSize minCellSize: reverseTableCells reverseTableCells: rubberBandCells rubberBandCells: spaceFillWeight spaceFillWeight: vResizeToFit: vResizing vResizingString: vResizing: wrapCentering wrapCenteringString: wrapCentering: wrapDirection wrapDirectionString: wrapDirection:)
('macpal' flash)
('menu' addBorderStyleMenuItems:hand: addGestureMenuItems:hand: addGraphModelYellowButtonItemsTo:event: addModelYellowButtonItemsTo:event: addMyYellowButtonMenuItemsToSubmorphMenus addNestedYellowButtonItemsTo:event: addTitleForHaloMenu: addYellowButtonMenuItemsTo:event: buildYellowButtonMenu: hasYellowButtonMenu offerCostumeViewerMenu: outermostOwnerWithYellowButtonMenu startWiring wantsMetaMenu wantsMetaMenu: wantsYellowButtonMenu wantsYellowButtonMenu:)
('menus' absorbStateFromRenderer: addAddHandMenuItemsForHalo:hand: addCopyItemsTo: addCustomHaloMenuItems:hand: addCustomMenuItems:hand: addExportMenuItems:hand: addFillStyleMenuItems:hand: addHaloActionsTo: addMiscExtrasTo: addPaintingItemsTo:hand: addStandardHaloMenuItemsTo:hand: addToggleItemsToHaloMenu: addWorldTargetSightingItems:hand: adhereToEdge adhereToEdge: adjustedCenter adjustedCenter: allMenuWordings changeColor changeDirectionHandles changeDragAndDrop chooseNewGraphic chooseNewGraphicCoexisting: chooseNewGraphicFromHalo collapse defaultArrowheadSize doMenuItem: exploreInMorphic exploreInMorphic: exportAsBMP exportAsBMPNamed: exportAsGIF exportAsGIFNamed: exportAsJPEG exportAsJPEGNamed: exportAsPNG exportAsPNGNamed: hasDirectionHandlesString hasDragAndDropEnabledString helpButton inspectInMorphic inspectInMorphic: lockedString lockUnlockMorph makeNascentScript maybeAddCollapseItemTo: menuItemAfter: menuItemBefore: model presentHelp reasonableBitmapFillForms reasonableForms resetForwardDirection resistsRemovalString setArrowheads setRotationCenter setRotationCenterFrom: setToAdhereToEdge: snapToEdgeIfAppropriate stickinessString transferStateToRenderer: uncollapseSketch)
('meta-actions' addEmbeddingMenuItemsTo:hand: applyStatusToAllSiblings: beThisWorldsModel bringAllSiblingsToMe: buildHandleMenu: buildMetaMenu: changeColorTarget:selector:originalColor:hand: copyToPasteBuffer: dismissMorph dismissMorph: duplicateMorphImage: duplicateMorph: embedInto: grabMorph: indicateAllSiblings inspectAt:event: invokeHaloOrMove: invokeMetaMenuAt:event: invokeMetaMenu: makeMultipleSiblings: makeNewPlayerInstance: makeSiblingsLookLikeMe: makeSiblings: maybeDuplicateMorph maybeDuplicateMorph: openAPropertySheet openATextPropertySheet potentialEmbeddingTargets potentialTargets potentialTargetsAt: resizeFromMenu resizeMorph: saveAsPrototype showActions showHiders sightTargets: sightWorldTargets: subclassMorph targetFromMenu: targetWith:)
('miscellaneous' roundUpStrays setExtentFromHalo: setFlexExtentFromHalo:)
('naming' downshiftedNameOfObjectRepresented innocuousName nameForFindWindowFeature nameInModel nameOfObjectRepresented name: setNamePropertyTo: setNameTo: specialNameInModel tryToRenameTo: updateAllScriptingElements)
('objects from disk' objectForDataStream: storeDataOn:)
('other events' menuButtonMouseEnter: menuButtonMouseLeave:)
('parts bin' initializeToStandAlone inPartsBin isPartsBin isPartsDonor isPartsDonor: markAsPartsDonor partRepresented residesInPartsBin)
('printing' clipText colorString: constructorString fullPrintOn: initString morphReport morphReportFor: morphReportFor:on:indent: pagesHandledAutomatically printConstructorOn:indent: printConstructorOn:indent:nodeDict: printOn: printSpecs printSpecs: printStructureOn:indent: reportableSize structureString textToPaste)
('rotate scale and flex' addFlexShell addFlexShellIfNecessary keepsTransform newTransformationMorph removeFlexShell rotationDegrees)
('rounding' cornerRadius cornerRadius: cornerStyle cornerStyle: roundedCorners roundedCornersString toggleCornerRounding wantsRoundedCorners)
('stepping and presenter' arrangeToStartStepping arrangeToStartSteppingIn: isStepping isSteppingSelector: start startStepping startSteppingIn: startSteppingSelector: startStepping:at:arguments:stepTime: step stepAt: stop stopStepping stopSteppingSelector: stopSteppingSelfAndSubmorphs)
('structure' activeHand allOwners allOwnersDo: containingWindow firstOwnerSuchThat: hasOwner: isInDockingBar isInSystemWindow isInWorld morphPreceding: nearestOwnerThat: orOwnerSuchThat: outermostMorphThat: outermostWorldMorph owner ownerThatIsA: ownerThatIsA:orA: pasteUpMorph pasteUpMorphHandlingTabAmongFields primaryHand renderedMorph root rootAt: topPasteUp topRendererOrSelf withAllOwners withAllOwnersDo: world)
('submorphs-accessing' allKnownNames allMorphs allMorphsDo: allNonSubmorphMorphs allSubmorphNamesDo: dockingBars findA: findDeeplyA: findDeepSubmorphThat:ifAbsent: findSubmorphBinary: firstSubmorph hasSubmorphs hasSubmorphWithProperty: indexOfMorphAbove: lastSubmorph mainDockingBars morphsAt: morphsAt:behind:unlocked: morphsAt:unlocked: morphsAt:unlocked:do: morphsInFrontOf:overlapping:do: morphsInFrontOverlapping: morphsInFrontOverlapping:do: noteNewOwner: rootMorphsAtGlobal: rootMorphsAt: shuffleSubmorphs submorphAfter submorphBefore submorphCount submorphNamed: submorphNamed:ifNone: submorphOfClass: submorphs submorphsBehind:do: submorphsDo: submorphsInFrontOf:do: submorphsReverseDo: submorphsSatisfying: submorphThat:ifNone: submorphWithProperty:)
('submorphs-add/remove' abandon actWhen actWhen: addAllMorphs: addAllMorphs:after: addAllMorphs:behind: addAllMorphs:inFrontOf: addAllMorphsBack: addAllMorphsFront: addMorphBack: addMorphCentered: addMorphFrontFromWorldPosition: addMorphFront: addMorphFront:fromWorldPosition: addMorphNearBack: addMorph: addMorph:after: addMorph:asElementNumber: addMorph:behind: addMorph:fullFrame: addMorph:inFrontOf: allMorphsWithPlayersDo: comeToFront copyWithoutSubmorph: delete deleteDockingBars deleteSubmorphsWithProperty: deleteUnlessHasFocus dismissViaHalo goBehind privateDelete removeAllMorphs removeAllMorphsIn: removedMorph: removeMorph: replaceSubmorph:by: submorphIndexOf:)
('testing' canDrawAtHigherResolution canDrawBorder: completeModificationHash couldMakeSibling indicateKeyboardFocus isDockingBar isFlexed isFullOnScreen isImageMorph isLineMorph isMenuItemMorph isMorph isSafeToServe isSelectionMorph isSketchMorph knownName modificationHash renameInternal: renameTo: shouldDropOnMouseUp stepTime wantsSteps)
('text-anchor' addTextAnchorMenuItems:hand: changeDocumentAnchor changeInlineAnchor changeParagraphAnchor hasDocumentAnchorString hasInlineAnchorString hasParagraphAnchorString relativeTextAnchorPosition relativeTextAnchorPosition: textAnchorType textAnchorType:)
('thumbnail' demandsThumbnailing icon iconOrThumbnail iconOrThumbnailOfSize: morphRepresented permitsThumbnailing readoutForField: representativeNoTallerThan:norWiderThan:thumbnailHeight: thumbnail updateThumbnailUrl updateThumbnailUrlInBook:)
('undo' commandHistory undoMove:redo:owner:bounds:predecessor:)
('updating' applyUserInterfaceTheme changed)
('user interface' defaultLabelForInspector doCancel initialExtent)
('viewer' externalName)
('visual properties' canApplyUserInterfaceTheme canHaveFillStyles defaultBitmapFillForm fillStyle fillStyle: fillWithRamp:oriented: useBitmapFill useDefaultFill useGradientFill useSolidFill)
('WiW support' addMorphInFrontOfLayer: addMorphInLayer: eToyRejectDropMorph:event: morphicLayerNumber morphicLayerNumberWithin: randomBoundsFor: shouldGetStepsFrom:)
('*MorphicExtras-accessing' highlightOnlySubmorph:)
('*MorphicExtras-geometry' shiftSubmorphsBy:)
('*MorphicExtras-menus' dismissButton printPSToFileNamed:)
('*services-base' requestor)
('private' canBeEncroached privateAddAllMorphs:atIndex: privateAddMorph:atIndex: privateBounds: privateColor: privateDeleteWithAbsolutelyNoSideEffects privateFullBounds: privateFullMoveBy: privateMoveBy: privateOwner: privateRemoveMorphWithAbsolutelyNoSideEffects: privateRemove: privateSubmorphs privateSubmorphs:)
('accessing-backstop' target:)
('e-toy support' adaptToWorld: allMorphsAndBookPagesInto: asNumber: automaticViewing currentPlayerDo: cursor cursor: decimalPlacesForGetter: defaultValueOrNil embeddedInMorphicWindowLabeled: embedInWindow getNumericValue gridFormOrigin:grid:background:line: handUserASibling isAViewer isTileEditor makeGraphPaper makeGraphPaperGrid:background:line: mustBeBackmost noteDecimalPlaces:forGetter: objectViewed referencePlayfield rotationStyle rotationStyle: setAsActionInButtonProperties: setNumericValue: setStandardTexture textureParameters unlockOneSubpart updateCachedThumbnail wantsRecolorHandle wrappedInWindowWithTitle: wrappedInWindow:)
('geniestubs' allowsGestureStart: isGestureStart: mouseStillDownStepRate redButtonGestureDictionaryOrName: yellowButtonGestureDictionaryOrName:)
('*morphic-Postscript Canvases' asPostscript clipPostscript drawPostscriptOn: fullDrawPostscriptOn: printPSToFile)
('player' assureExternalName okayToDuplicate shouldRememberCostumes)
('player commands' playSoundNamed:)
('button' doButtonAction)
('model access' models)
('player viewer' openViewerForArgument)
('other' removeAllButFirstSubmorph)
('selected object' selectedObject)
('polymorph' modalLockTo: modalUnlockFrom: openModal:)
('*Etoys-card in a stack' abstractAModel addStackItemsTo: assuredCardPlayer beAStackBackground becomeSharedBackgroundField containsCard: couldHoldSeparateDataForEachInstance currentDataInstance currentDataValue explainDesignations goToNextCardInStack goToPreviousCardInStack holdsSeparateDataForEachInstance insertAsStackBackground insertCard installAsCurrent: isStackBackground makeHoldSeparateDataForEachInstance newCard reassessBackgroundShape relaxGripOnVariableNames reshapeBackground setAsDefaultValueForNewCard showBackgroundObjects showDesignationsOfObjects showForegroundObjects stack stackDo: stopHoldingSeparateDataForEachInstance tabHitWithEvent: variableDocks wrapWithAStack)
('*Etoys' accumlatePlayersInto:andSelectorsInto: actorState addPlayerItemsTo: assuredPlayer boundsSignatureHash categoriesForViewer choosePenColor: choosePenSize currentVocabulary ensuredButtonProperties forward: getPenColor getPenDown getPenSize isPlayer:ofReferencingTile: isTurtleRow liftPen lowerPen moveWithPenDownBy: newPlayerInstance penColor: penUpWhile: putOnBackground putOnForeground scriptPerformer selectorsForViewer selectorsForViewerIn: showPlayerMenu trailMorph traverseRowTranslateSlotOld:of:to: traverseRowTranslateSlotOld:to: turn: understandsBorderVocabulary unfilteredCategoriesForViewer)
('*Etoys-support' adoptVocabulary: affiliatedSelector appearsToBeSameCostumeAs: asWearableCostume asWearableCostumeOfExtent: beep: buttonProperties buttonProperties: changeAllBorderColorsFrom:to: configureForKids copyCostumeStateFrom: creationStamp defaultVariableName definePath deletePath enclosingEditor enforceTileColorPolicy fenceEnabled fire firedMouseUpCode followPath getCharacters handMeTilesToFire hasButtonProperties isCandidateForAutomaticViewing jumpTo: listViewLineForFieldList: makeFenceSound noteNegotiatedName:for: pinkXButton restoreBaseGraphic set: slotSpecifications succeededInRevealing: tanOButton topEditor updateLiteralLabel)
('*Etoys-scripting' arrowDeltaFor: asEmptyPermanentScriptor bringTileScriptingElementsUpToDate bringUpToDate defaultFloatPrecisionFor: filterViewerCategoryDictionary: isTileLike isTileScriptingElement jettisonScripts makeAllTilesColored makeAllTilesGreen restoreTypeColor scriptEditorFor: tearOffTile triggerScript: useUniformTileColor viewAfreshIn:showingScript:at: wantsConnectionVocabulary)
('*Etoys-customevents-scripting' instantiatedUserScriptsDo: removeAllEventTriggers removeAllEventTriggersFor: removeEventTrigger: removeEventTrigger:for: renameScriptActionsFor:from:to: triggerCustomEvent: triggerEtoyEvent: triggerEtoyEvent:from:)
('*Etoys-geometry' addTransparentSpacerOfSize: beTransparent cartesianBoundsTopLeft cartesianXY: color:sees: colorUnder degreesOfFlex forwardDirection: getIndexInOwner goHome heading heading: move:toPosition: referencePosition referencePosition: referencePositionInWorld referencePositionInWorld: rotationCenter rotationCenter: scale: scaleFactor: setDirectionFrom: setIndexInOwner: simplySetVisible: touchesColor: transparentSpacerOfSize: wrap x x: x:y: y y:)
('*Etoys-latter day support' isEtoyReadout)
('*MorphicExtras-postscript' asEPS asPostscriptPrintJob)
('*Morphic-Sound-piano rolls' addMorphsTo:pianoRoll:eventTime:betweenTime:and: encounteredAtTime:inScorePlayer:atIndex:inEventTrack:secsPerTick: justDroppedIntoPianoRoll:event: pauseFrom: resetFrom: resumeFrom: triggerActionFromPianoRoll)
('*MorphicExtras' nextOwnerPage previousOwnerPage)
('events-filtering-bubbling' addEventBubbleFilter: addKeyboardBubbleFilter: addMouseBubbleFilter: eventBubbleFilters eventBubbleFilters: keyboardBubbleFilters keyboardBubbleFilters: mouseBubbleFilters mouseBubbleFilters: removeEventBubbleFilter: removeKeyboardBubbleFilter: removeMouseBubbleFilter:)
('events-filtering-capturing' addEventCaptureFilter: addKeyboardCaptureFilter: addMouseCaptureFilter: eventCaptureFilters eventCaptureFilters: keyboardCaptureFilters keyboardCaptureFilters: mouseCaptureFilters mouseCaptureFilters: removeEventCaptureFilter: removeKeyboardCaptureFilter: removeMouseCaptureFilter:)
('events-filtering' addFilter:to: eventFilterDocumentation removeFilter:from:)
('*Etoys-Squeakland-halo notification' aboutToBeBrownDragged aboutToBeGrownViaHalo aboutToBeRotatedViaHalo aboutToBeScaledViaHalo brownDragConcluded growConcluded rotationConcluded scaleConcluded)
('*Etoys-Squeakland-menu & halo' addLockingItemsTo: menuButton offerMenu)
('*Etoys-Squeakland-WiW support' addMorphInLayer:centeredNear:)
('*Etoys-Squeakland-geometry' boundsInStagingArea collapsible spanContainerVertically: stagingArea)
('*Etoys-Squeakland-Etoys-SpeechBubbles' bubble bubble: say: sayGraphic: sayObject: showGraphic:inBubbleType: showMessage:inBubbleType: showObject:inBubbleType: stopSayingOrThinking think: thinkGraphic: thinkObject:)
('*Etoys-Squeakland-meta-actions' changeColorSimply changeColorTarget:selector:originalColor:hand:showPalette: embedEnabled openAppropriatePropertySheet showEmbedMenu targetFromMenu:popupAt:)
('*Etoys-Squeakland-visual properties' changeGraphPaper useGraphPaperFill)
('*Etoys-Squeakland-e-toy support' chosenColor: enclosingTestTile fixLayoutOfSubmorphs hideWillingnessToAcceptDropFeedback outmostScriptEditor putUpGraphPaperPanel removeViewersOnSubsIn: showWillingnessToAcceptDropFeedback unembedSubmorphsInWindow)
('*Etoys-Squeakland-accessing - extension' convertExtension)
('*Etoys-Squeakland-object fileIn' convertNovember2000DropShadow:using:)
('*Etoys-Squeakland-accessing' deepSubpartNamed: eventRoll)
('*Etoys-Squeakland-classification' defersHaloToInterior defersHaloToInteriorMorph: fontsForText)
('*Etoys-Squeakland-misc' doesColorAndBorder)
('*Etoys-Squeakland-display' editMenuButtonDefinition)
('*Etoys-Squeakland-latter day support' encouragesHaloTransferToEnclosedPasteUpMorph)
('*Etoys-Squeakland-viewing' establishGraphPaperFrom:)
('*Etoys-Squeakland-miscellaneous' finalTilePadSubmorph)
('*Etoys-Squeakland-other' fixUpCarets)
('*Etoys-Squeakland-debug and other' inspectMorphsProperties)
('*Etoys-Squeakland-layout' justAddedAsTileRow)
('*Etoys-Squeakland-drop outside' mimeTypes)
('*Etoys-Squeakland-initialization' naviHeight: openInWorldOrWorldlet openNearTopLeftOfScreen)
('*Etoys-Squeakland-submorphs-accessing' ownerSatisfying:)
('*Etoys-Squeakland-event roll' putEventsOnto: suitableForDroppingIntoEventRoll)
('*Etoys-Squeakland-structure' referenceWorld referenceWorldViaOwnwer)
('*Etoys-Squeakland-dropping/grabbing' repelEnabledForMorph:)
('*Etoys-Squeakland-geometry eToy' rotationDegrees:)
('*Etoys-Squeakland-fileIn/out' saveOnFile:)
('*Etoys-Squeakland-translation' traverseSearchForKedamaTurtleIfFound:)
('*Etoys-Squeakland-testing' isButton wantsGraphPaperAlternative)
('*60Deprecated-meta-actions' blueButtonDown: blueButtonUp: handlerForBlueButtonDown: handlerForMetaMenu:)
('*60Deprecated-accessing' doesBevels)
('*60Deprecated-user-interface' becomeModal)
('*ToolBuilder-Morphic-opening' buildWith: openAsTool)
!


!BorderStyle reorganize!
('accessing' baseColor baseColor: color color: inset style width width:)
('color tracking' trackColorFrom:)
('comparing' = hash)
('*60Deprecated-accessing' colorsAtCorners dotOfSize:forDirection: widthForRounding)
('drawing' drawLineFrom:to:on: frameOval:on: framePolygon:on: framePolyline:on: frameRectangle:on:)
('initialize' releaseCachedState)
('testing' isBorderStyle isComplex)
!

"Postscript:
Leave the line above, and replace the rest of this comment by a useful one.
Executable statements should follow this comment, and should
be separated by periods, with no exclamation points (!!).
Be sure to put any further comments in double-quotes, like this one."

UserInterfaceTheme cleanUp: true.
(UserInterfaceTheme named: UserInterfaceTheme current name) apply.

Project allMorphicProjects do: [:p |
	p world allMorphsDo: [:m |
		(m isKindOf: BorderedMorph) ifTrue: [
			m borderColor: (m instVarNamed: #borderColor).
			m borderWidth: (m instVarNamed: #borderWidth)]]].!

