'From Squeak6.0alpha of 10 April 2018 [latest update: #17879] on 11 April 2018 at 11:52:16 am'! !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 " ! ! !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 ! ! !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 4/11/2018 11:05'! 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)]]. "Set the color of the current border style." self borderStyle color: aColorOrSymbolOrNil. self changed.! ! !Morph methodsFor: 'accessing' stamp: 'mt 4/11/2018 10:06'! borderStyle ^ self valueOfProperty: #borderStyle ifAbsentPut: [BorderStyle default]! ! !Morph methodsFor: 'accessing' stamp: 'mt 4/11/2018 10:24'! 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 4/11/2018 10:26'! 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 baseColor: aBorderStyle baseColor; width: aBorderStyle width; 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: '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 4/11/2018 09:35'! borderInitialize "initialize the receiver state related to border" borderColor:= self defaultBorderColor. borderWidth := self defaultBorderWidth. self borderStyle: (self defaultBorderStyle color: self defaultBorderColor; width: self defaultBorderWidth; trackColorFrom: self; yourself).! ! !BorderedMorph methodsFor: 'initialization' stamp: 'mt 4/11/2018 10:51'! borderInset "Change border to inset. Preserve width and color." self borderStyle: (BorderStyle inset width: self borderWidth; baseColor: self borderStyle baseColor; color: self borderColor; trackColorFrom: self; yourself).! ! !BorderedMorph methodsFor: 'initialization' stamp: 'mt 4/11/2018 10:52'! borderRaised "Change border to inset. Preserve width and color." self borderStyle: (BorderStyle raised width: self borderWidth; baseColor: self borderStyle baseColor; color: self borderColor; trackColorFrom: self; yourself).! ! !BorderedMorph methodsFor: 'initialization' stamp: 'mt 4/11/2018 10:52'! borderSimple "Change border to simple. Preserve width and color." self borderStyle: (BorderStyle simple width: self borderWidth; baseColor: self borderStyle baseColor; color: self borderColor; 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: 'initialization' stamp: 'mt 4/11/2018 08:49'! defaultBorderStyle ^ BorderStyle raised! ! !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 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 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 4/11/2018 08:49'! defaultBorderStyle ^ BorderStyle raised! ! !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 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 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 ! ! !PBTextPreferenceView methodsFor: 'user interface' stamp: 'mt 4/10/2018 11:12'! textField ^(PluggableTextMorph on: self text: #preferenceValue accept: #preferenceValue:) hideScrollBarsIndefinitely; borderStyle: BorderStyle inset; acceptOnCR: true; color: Color gray veryMuchLighter; vResizing: #rigid; hResizing: #spaceFill; height: TextStyle defaultFont height + 6; yourself.! ! !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.! ! !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/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/10/2018 11:48'! vertices: verts color: aColor borderWidth: borderWidthInteger borderColor: anotherColor super initialize. "" vertices := verts. color := aColor. self borderWidth: borderWidthInteger. self borderColor: anotherColor. closed := vertices size > 2. arrows := #none. 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/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/10/2018 11:35'! 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: #shrinkWrap; 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: 'mt 4/10/2018 11:35'! 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; borderStyle: (BorderStyle raised width: 2); color: color. r addMorphBack: (bb label: '<>'; actWhen: #buttonDown; actionSelector: #invokeMenu). bb := SimpleButtonMorph new target: self; borderStyle: (BorderStyle raised width: 2); color: color. r addMorphBack: (bb label: 'Piano Roll' translated; actionSelector: #makePianoRoll). bb := SimpleButtonMorph new target: self; borderStyle: (BorderStyle raised width: 2); color: color. r addMorphBack: (bb label: 'Rewind' translated; actionSelector: #rewind). bb := SimpleButtonMorph new target: scorePlayer; borderStyle: (BorderStyle raised width: 2); color: color. r addMorphBack: (bb label: 'Play' translated; actionSelector: #resumePlaying). bb := SimpleButtonMorph new target: scorePlayer; borderStyle: (BorderStyle raised width: 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: '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]).! ! !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! ! !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: 'switching' stamp: 'mt 4/10/2018 11:18'! turnOff self borderStyle: (BorderStyle raised width: self borderWidth). self color: offColor! ! !SimpleSwitchMorph methodsFor: 'switching' stamp: 'mt 4/10/2018 11:18'! turnOn self borderStyle: (BorderStyle inset width: self borderWidth). self color: onColor! ! !MinesTile methodsFor: 'accessing' stamp: 'mt 4/10/2018 11:09'! 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: self borderWidth). self color: onColor] ifFalse:[ self borderStyle: (BorderStyle raised width: self borderWidth). self color: offColor]]! ! !MinesTile methodsFor: 'drawing' stamp: 'mt 4/10/2018 11:08'! 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 | self borderWidth = 0 ifTrue: [ "no border" aCanvas fillRectangle: self bounds color: self color. ^ self.]. self borderStyle style == #raised ifTrue: [ ^ aCanvas frameAndFillRectangle: self bounds fillColor: self color borderWidth: self borderWidth topLeftColor: self color lighter lighter bottomRightColor: self color darker darker darker]. self borderStyle style == #inset ifTrue: [ aCanvas frameAndFillRectangle: self bounds fillColor: self color borderWidth: 1 " self borderWidth" topLeftColor: (self color darker darker darker) bottomRightColor: self color lighter. 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) ) .]. ^self. ]. "solid color border" aCanvas frameAndFillRectangle: self bounds fillColor: self color borderWidth: self borderWidth borderColor: self borderColor.! ! !SameGameTile methodsFor: 'accessing' stamp: 'mt 4/10/2018 11:13'! setSwitchState: aBoolean switchState := aBoolean. disabled ifFalse: [switchState ifTrue: [self borderStyle: BorderStyle inset. self color: onColor] ifFalse: [self borderStyle: BorderStyle raised. self color: offColor]]! ! !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! ! !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 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. ! ! TwoWayScrollPane removeSelector: #defaultBorderColor! !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:) ! 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) ! !ProjectViewMorph reorganize! ('accessing' 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' borderWidthForRounding) ('*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 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) ! NebraskaGateKeeperMorph removeSelector: #defaultBorderColor! NebraskaFridgeMorph removeSelector: #defaultBorderColor! MinesBoard removeSelector: #defaultBorderColor! Mines removeSelector: #defaultBorderColor! EventRecorderMorph removeSelector: #defaultBorderColor! !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:) ! EToyProjectHistoryMorph removeSelector: #defaultBorderColor! ChessMorph removeSelector: #defaultBorderColor! 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: 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' borderWidthForRounding doesBevels) ('*60Deprecated-user-interface' becomeModal) ('*ToolBuilder-Morphic-opening' buildWith: openAsTool) ! "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)]]].!