'From Squeak3.2alpha of 4 October 2001 [latest update: #4461] on 2 November 2001 at 2:05:52 pm'! "Change Set: Stack-A-tk Date: 30 October 2001 Author: Ted Kaehler Reformulate StackMorphs. Any morphs may be a page (background), not just a PasteUpMorph. Menu item 'be a card in an existing stack...' (insertAsStackBackground) that lets the user click on the stack to add this morph to it. Menu item 'make an instance for my data' (abstractAModel) for any morph with fields. A menu item, wrapWithAStack, that takes any morph and encloses it in a StackMorph. Fields become background fields, sketches are also per-card, and FancyWatchers become background numeric holders. Fix bug in macroBenchmarks. Was decompiling a large method to tiles. When AlansTest1 is off (in standard images), it was not answering selector when a spacing layer of MessageNode had no receiverNode. Dragging on a tile no longer peels off a duplicate. Selecting a tile shows a popUp. Now the popUp includes a duplicate handle. (a String = a Text) and (a Text = a String) now actually do a compare. Does this harm anything else in the system? Hash fixed. Two texts are equal if they have equal characters, regardless of the emphasis. "! !CardPlayer methodsFor: 'scripts-kernel' stamp: 'svp 10/15/2001 14:44'! renameScript: oldSelector newSelector: newSelector "Find all buttons that fire this script and tell them the new name" | stack | super renameScript: oldSelector newSelector: newSelector. costume allMorphsDo: [:mm | self retargetButton: mm oldSelector: oldSelector newSelector: newSelector]. stack _ costume valueOfProperty: #myStack. stack ifNotNil: [stack cards do: [:cc | cc privateMorphs do: [:pp | pp allMorphsDo: [:mm | self retargetButton: mm oldSelector: oldSelector newSelector: newSelector]]]]! ! !Morph methodsFor: 'structure' stamp: 'tk 11/2/2001 13:49'! pasteUpMorphHandlingTabAmongFields "Answer the nearest PasteUpMorph in my owner chain that has the tabAmongFields property, or nil if none" | aPasteUp | aPasteUp _ self owner. [aPasteUp notNil] whileTrue: [(aPasteUp hasProperty: #tabAmongFields) ifTrue: [^ aPasteUp]. aPasteUp _ aPasteUp owner]. ^ nil! ! !Morph methodsFor: 'menus' stamp: 'tk 11/2/2001 14:05'! addCustomMenuItems: aCustomMenu hand: aHandMorph | realOwner realMorph | "Add morph-specific items to the given menu which was invoked by the given hand. Note the special-casing of Worlds, for which some of the the otherwise generic items are excluded." aCustomMenu addUpdating: #hasDragAndDropEnabledString action: #changeDragAndDrop. self isWorldMorph ifFalse: [(self isKindOf: SystemWindow) ifFalse: [aCustomMenu add: 'put in a window' action: #embedInWindow]. aCustomMenu addUpdating: #stickinessString target: self action: #toggleStickiness. aCustomMenu add: 'adhere to edge...' action: #adhereToEdge] ifTrue: [aCustomMenu add: 'desktop menu...' target: self action: #putUpDesktopMenu:. aCustomMenu addLine]. Preferences noviceMode ifFalse: [self addDebuggingItemsTo: aCustomMenu hand: aHandMorph]. realOwner _ (realMorph _ self topRendererOrSelf) owner. (realOwner isKindOf: TextPlusPasteUpMorph) ifTrue: [aCustomMenu add: 'GeeMail stuff...' subMenu: (realOwner textPlusMenuFor: realMorph)]. aCustomMenu addLine. (self isStackBackground) ifFalse: [ aCustomMenu add: 'be a card in an existing stack...' action: #insertAsStackBackground]. aCustomMenu add: 'make an instance for my data' action: #abstractAModel. (self isStackBackground) ifFalse: [ aCustomMenu add: 'become a stack of cards' action: #wrapWithAStack]. aCustomMenu addLine. ! ! !Morph methodsFor: 'menus' stamp: 'tk 11/2/2001 13:49'! putOnForeground "Place the receiver, formerly on the background, onto the foreground. If the receiver needs data carried on its behalf by the card, those data will be lost, so in this case get user confirmation before proceeding." self holdsSeparateDataForEachInstance "later add the refinement of not putting up the following confirmer if only a single instance of the current background's uniclass exists" ifTrue: [self confirm: 'Caution -- every card of this background formerly had its own value for this item. If you put it on the foreground, the values of this item on all other cards will be lost' orCancel: [^ self]]. self removeProperty: #shared. self stack reassessBackgroundShape. "still work to be done here!!"! ! !Morph methodsFor: 'player' stamp: 'tk 10/30/2001 12:13'! assuredCardPlayer "Answer the receiver's player, creating a new one if none currently exists" | aPlayer | (aPlayer _ self player) ifNotNil: [ (aPlayer isKindOf: CardPlayer) ifTrue: [^ aPlayer] ifFalse: [self error: 'Must convert to a CardPlayer'] "later convert using as: and remove the error"]. self assureExternalName. "a default may be given if not named yet" self player: (aPlayer _ UnscriptedCardPlayer newUserInstance). "Force it to be a CardPlayer. Morph class no longer dictates what kind of player" aPlayer costume: self. self presenter ifNotNil: [self presenter flushPlayerListCache]. ^ aPlayer! ! !Morph methodsFor: 'card in a stack' stamp: 'tk 11/2/2001 13:40'! abstractAModel "Find data-containing fields in me. Make a new class, whose instance variables are named for my fields, and whose values are the values I am showing. Use a CardPlayer for now. Force the user to name the fields. Make slots for text, Number Watchers, SketchMorphs, and ImageMorphs." | instVarNames unnamed ans player twoListsOfMorphs holdsSepData docks | self player ifNotNil: [self inform: 'I already have a Player'. ^ true]. twoListsOfMorphs _ StackMorph discoverSlots: self. holdsSepData _ twoListsOfMorphs first. docks _ OrderedCollection new. instVarNames _ ''. holdsSepData do: [:ea | instVarNames _ instVarNames, ea knownName, ' '. docks addAll: ea variableDocks]. unnamed _ twoListsOfMorphs second. "have default names" instVarNames size = 0 ifTrue: [ self inform: 'No named fields were found. Please get a halo on each field and give it a name. Labels or non-data fields should be named "shared xxx".'. ^ false]. unnamed size > 0 ifTrue: [ ans _ PopUpMenu confirm: 'Data fields are ', instVarNames printString, ('\Some fields are not named. Are they labels or non-data fields?', '\Please get a halo on each data field and give it a name.') withCRs trueChoice: 'All other fields are non-data fields' falseChoice: 'Stop. Let me give a name to some more fields'. ans ifFalse: [^ false]]. unnamed withIndexDo: [:mm :ind | mm setName: 'shared label ', ind printString]. "Make a Player with instVarNames. Make me be the costume" player _ CardPlayer instanceOfUniqueClassWithInstVarString: instVarNames andClassInstVarString: ''. self player: player. player costume: self. "Fill in the instance values. Make docks first." holdsSepData do: [:morph | morph setProperty: #shared toValue: true. "in case it is deeply embedded" morph setProperty: #holdsSeparateDataForEachInstance toValue: true. player class compileInstVarAccessorsFor: morph knownName]. player class newVariableDocks: docks. docks do: [:dd | dd storeMorphDataInInstance: player]. ^ true "success"! ! !Morph methodsFor: 'card in a stack' stamp: 'tk 11/2/2001 13:31'! beAStackBackground "Transform the receiver into one that has stack-background behavior. If just becoming a stack, allocate a uniclass to represent the cards (if one does not already exist" self assuredCardPlayer assureUniClass. self setProperty: #tabAmongFields toValue: true. self setProperty: #stackBackground toValue: true. "put my submorphs onto the background" submorphs do: [:mm | mm setProperty: #shared toValue: true]. self reassessBackgroundShape! ! !Morph methodsFor: 'card in a stack' stamp: 'tk 10/30/2001 18:54'! containsCard: aCard "Answer whether the given card belongs to the uniclass representing the receiver" ^ self isStackBackground and: [aCard isKindOf: self player class baseUniclass]! ! !Morph methodsFor: 'card in a stack' stamp: 'tk 10/30/2001 13:32'! currentDataInstance "Answer the current data instance" ^ self player! ! !Morph methodsFor: 'card in a stack' stamp: 'tk 10/30/2001 13:33'! explainDesignations "Hand the user an object that contains explanations for the designation feedback used" StackMorph designationsExplainer openInHand "self currentWorld explainDesignations"! ! !Morph methodsFor: 'card in a stack' stamp: 'tk 11/1/2001 15:51'! insertAsStackBackground "I am not yet in a stack. Find a Stack that my reference point (center) overlaps, and insert me as a new background." | aMorph | self isStackBackground ifTrue: [^ self beep]. "already in a stack. Must clear flags when remove." " self potentialEmbeddingTargets do: [:mm | No, force user to choose a stack. (mm respondsTo: #insertAsBackground:resize:) ifTrue: [ ^ mm insertAsBackground: self resize: false]]. " "None found, ask user" self inform: 'Please click on a Stack'. Sensor waitNoButton. aMorph _ self world chooseClickTarget. aMorph ifNil: [^ self]. (aMorph ownerThatIsA: StackMorph) insertAsBackground: self resize: false.! ! !Morph methodsFor: 'card in a stack' stamp: 'tk 10/30/2001 13:35'! insertCard "Insert a new card in the stack, with the receiver as its background, and have it become the current card of the stack" self stackDo: [:aStack | aStack insertCardOfBackground: self]! ! !Morph methodsFor: 'card in a stack' stamp: 'tk 10/30/2001 13:51'! installAsCurrent: anInstance "Install anInstance as the one currently viewed in the receiver. Dock up all the morphs in the receiver which contain data rooted in the player instance to the instance data. Run any 'opening' scripts that pertain." | fieldList itsFocus | self player == anInstance ifTrue: [^ self]. fieldList _ self allMorphs select: [:aMorph | (aMorph wouldAcceptKeyboardFocusUponTab) and: [aMorph isLocked not]]. self currentWorld hands do: [:aHand | (itsFocus _ aHand keyboardFocus) notNil ifTrue: [(fieldList includes: itsFocus) ifTrue: [aHand newKeyboardFocus: nil]]]. self player uninstallFrom: self. "out with the old" anInstance installPrivateMorphsInto: self. self changed. anInstance costume: self. self player: anInstance. self player class variableDocks do: [:aVariableDock | aVariableDock dockMorphUpToInstance: anInstance]. self currentWorld startSteppingSubmorphsOf: self. anInstance runAllOpeningScripts! ! !Morph methodsFor: 'card in a stack' stamp: 'tk 10/30/2001 13:42'! isStackBackground "Answer whether the receiver serves as a background of a stack" ^ ((owner isKindOf: StackMorph) and: [owner currentPage == self]) or: [self hasProperty: #stackBackground] "This odd property-based check is because when a paste-up-morph is not the *current* background of a stack, it is maddeningly ownerlyess"! ! !Morph methodsFor: 'card in a stack' stamp: 'tk 11/2/2001 13:38'! makeHoldSeparateDataForEachInstance "Mark the receiver as holding separate data for each instance (i.e., like a 'background field') and reassess the shape of the corresponding background so that it will be able to accommodate this arrangement." self setProperty: #holdsSeparateDataForEachInstance toValue: true. self stack reassessBackgroundShape.! ! !Morph methodsFor: 'card in a stack' stamp: 'tk 10/30/2001 13:44'! newCard "Create a new card for the receiver and return it" | aNewInstance | self isStackBackground ifFalse: [^ self beep]. "bulletproof against deconstruction" aNewInstance _ self player class baseUniclass new. ^ aNewInstance! ! !Morph methodsFor: 'card in a stack' stamp: 'tk 10/30/2001 13:45'! reassessBackgroundShape "A change has been made which may affect the instance structure of the Card uniclass that holds the instance state, which can also be thought of as the 'card data'." | takenNames uniqueName requestedName variableDocks docks sepDataMorphs sorted | "Caution: still to be done: the mechanism so that when a new instance variable is added, it gets initialized in all subinstances of the receiver's player, which are the cards of this shape. One needs to take into account here the instance variable names coming in; those that are unchanged should keep their values, but those that have newly arrived should obtain their default values from the morphs on whose behalf they are being maintained in the model" self isStackBackground ifFalse: [^ self beep]. "bulletproof against deconstruction" Cursor wait showWhile: [variableDocks _ OrderedCollection new. "This will be stored in the uniclass's class-side inst var #variableDocks" takenNames _ OrderedCollection new. sepDataMorphs _ OrderedCollection new. "fields, holders of per-card data" self submorphs do: [:aMorph | aMorph renderedMorph holdsSeparateDataForEachInstance ifTrue: [sepDataMorphs add: aMorph renderedMorph] ifFalse: ["look for buried fields, inside a frame" aMorph renderedMorph isShared ifTrue: [ aMorph allMorphs do: [:mm | mm renderedMorph holdsSeparateDataForEachInstance ifTrue: [ sepDataMorphs add: mm renderedMorph]]]]]. sorted _ (SortedCollection new) sortBlock: [:a :b | (a valueOfProperty: #cardInstance) ~~ nil]. "puts existing ones first" sorted addAll: sepDataMorphs. sorted do: [:aMorph | docks _ aMorph variableDocks. "Each morph can request multiple variables. This complicates matters somewhat but creates a generality for Fabrk-like uses. Each spec is an instance of VariableDock, and it provides a point of departure for the negotiation between the PasteUp and its constitutent morphs" docks do: [:aVariableDock | uniqueName _ self player uniqueInstanceVariableNameLike: (requestedName _ aVariableDock variableName) excluding: takenNames. uniqueName ~= requestedName ifTrue: [aVariableDock variableName: uniqueName. aMorph noteNegotiatedName: uniqueName for: requestedName]. takenNames add: uniqueName]. variableDocks addAll: docks]. self player class setNewInstVarNames: (variableDocks collect: [:info | info variableName asString]). "NB: sets up accessors, and removes obsolete ones" self player class newVariableDocks: variableDocks] ! ! !Morph methodsFor: 'card in a stack' stamp: 'tk 10/30/2001 13:46'! relaxGripOnVariableNames "Abandon any memory of specific variable names that should be preserved. The overall situation here is not yet completely understood, and this relaxation is basically always done on each reassessment of the background shape nowadays. But this doesn't feel quite right, because if the user has somehow intervened to specify certain name preference we should perhaps honored it. Or perhaps that is no longer relevant. ????" self submorphs do: [:m | m removeProperty: #variableName. m removeProperty: #setterSelector]. self reassessBackgroundShape ! ! !Morph methodsFor: 'card in a stack' stamp: 'tk 10/30/2001 13:47'! reshapeBackground "Abandon any memory of variable-name preferences, and reassess the shape of the background" self relaxGripOnVariableNames. "self reassessBackgroundShape. already done there"! ! !Morph methodsFor: 'card in a stack' stamp: 'tk 10/30/2001 13:48'! showBackgroundObjects "Momentarily highlight just the background objects on the current playfield" self isStackBackground ifFalse: [^ self]. self invalidRect: self bounds. self currentWorld doOneCycle. Display restoreAfter: [self submorphsDo: [:aMorph | (aMorph renderedMorph hasProperty: #shared) ifTrue: [Display border: (aMorph fullBoundsInWorld insetBy: -6) width: 6 rule: Form over fillColor: Color blue]]]! ! !Morph methodsFor: 'card in a stack' stamp: 'tk 10/30/2001 13:48'! showDesignationsOfObjects "Momentarily show the designations of objects on the receiver" | colorToUse aLabel | self isStackBackground ifFalse: [^ self]. self submorphsDo: [:aMorph | aMorph renderedMorph holdsSeparateDataForEachInstance ifTrue: [colorToUse _ Color orange. aLabel _ aMorph externalName] ifFalse: [colorToUse _ aMorph isShared ifFalse: [Color red] ifTrue: [Color green]. aLabel _ nil]. Display border: (aMorph fullBoundsInWorld insetBy: -6) width: 6 rule: Form over fillColor: colorToUse. aLabel ifNotNil: [aLabel asString displayOn: Display at: (aMorph fullBoundsInWorld bottomLeft + (0 @ 5))]]. Sensor anyButtonPressed ifTrue: [Sensor waitNoButton] ifFalse: [Sensor waitButton]. World fullRepaintNeeded.! ! !Morph methodsFor: 'card in a stack' stamp: 'tk 10/30/2001 13:50'! showForegroundObjects "Temporarily highlight the foreground objects" self isStackBackground ifFalse: [^ self]. Display restoreAfter: [self submorphsDo: [:aMorph | aMorph renderedMorph isShared ifFalse: [Display border: (aMorph fullBoundsInWorld insetBy: -6) width: 6 rule: Form over fillColor: Color orange]]]! ! !Morph methodsFor: 'card in a stack' stamp: 'tk 11/2/2001 13:53'! stack "Answer the nearest containing Stack, or, if none, a stack in the current project, and if still none, nil. The extra messiness is because uninstalled backgrounds don't have an owner pointers to their stack." | aStack bkgnd | bkgnd _ self orOwnerSuchThat: [:oo | oo hasProperty: #myStack]. bkgnd ifNotNil: [^ bkgnd valueOfProperty: #myStack]. "fallbacks" (aStack _ self ownerThatIsA: StackMorph) ifNotNil: [^ aStack]. ^ Project current currentStack! ! !Morph methodsFor: 'card in a stack' stamp: 'tk 11/2/2001 13:38'! stopHoldingSeparateDataForEachInstance "Make the receiver no longer hold separate data for each instance" self removeProperty: #holdsSeparateDataForEachInstance. self stack reassessBackgroundShape.! ! !Morph methodsFor: 'card in a stack' stamp: 'tk 10/30/2001 13:50'! tabHitWithEvent: anEvent "The tab key was hit. The keyboard focus has referred this event to me, though this perhaps seems rather backwards. Anyway, the assumption is that I have the property #tabAmongFields, so now the task is to tab to the next field" | currentFocus fieldList anIndex itemToHighlight | currentFocus _ anEvent hand keyboardFocus. fieldList _ self allMorphs select: [:aMorph | (aMorph wouldAcceptKeyboardFocusUponTab) and: [aMorph isLocked not]]. anIndex _ fieldList indexOf: currentFocus ifAbsent: [nil]. itemToHighlight _ fieldList atWrap: (anIndex ifNotNil: [anEvent shiftPressed ifTrue: [anIndex - 1] ifFalse: [anIndex + 1]] ifNil: [1]). anEvent hand newKeyboardFocus: itemToHighlight. self flag: #arNote. "really???" itemToHighlight editor selectAll. itemToHighlight invalidRect: itemToHighlight bounds ! ! !Morph methodsFor: 'card in a stack' stamp: 'tk 11/2/2001 14:01'! wrapWithAStack "Install me as a card inside a new stack. The stack has no border or controls, so I my look is unchanged. If I don't already have a CardPlayer, find my data fields and make one. Be ready to make new cards in the stack that look like me, but hold different field data." self player ifNil: [self abstractAModel ifFalse: [^ false]]. self player class officialClass == CardPlayer ifFalse: [ ^ self inform: 'I already have a regular Player, so I can''t have a CardPlayer']. StackMorph new initializeWith: self. self stack addHalo. "Makes it easier for the user"! ! !Morph methodsFor: 'layout-properties' stamp: 'tk 10/30/2001 18:39'! vResizeToFit: aBoolean aBoolean ifTrue:[ self vResizing: #shrinkWrap. ] ifFalse:[ self vResizing: #rigid. ].! ! !BookMorph methodsFor: 'insert and delete' stamp: 'tk 10/30/2001 18:40'! insertPageColored: aColor "Insert a new page for the receiver, using the given color as its background color" | sz newPage bw bc | currentPage == nil ifTrue: [sz _ pageSize. bw _ 0. bc _ Color blue muchLighter] ifFalse: [sz _ currentPage extent. bw _ currentPage borderWidth. bc _ currentPage borderColor]. newPagePrototype ifNil: [newPage _ PasteUpMorph new extent: sz; color: aColor. newPage borderWidth: bw; borderColor: bc] ifNotNil: [Cursor wait showWhile: [newPage _ newPagePrototype veryDeepCopy]]. newPage setNameTo: self defaultNameStemForNewPages. newPage vResizeToFit: false. pages isEmpty ifTrue: [pages add: (currentPage _ newPage)] ifFalse: [pages add: newPage after: currentPage]. self nextPage ! ! !BookMorph methodsFor: 'insert and delete' stamp: 'tk 10/30/2001 18:40'! insertPageSilentlyAtEnd "Create a new page at the end of the book. Do not turn to it." | sz newPage bw bc cc | currentPage == nil ifTrue: [sz _ pageSize. bw _ 0. bc _ Color blue muchLighter. cc _ color] ifFalse: [sz _ currentPage extent. bw _ currentPage borderWidth. bc _ currentPage borderColor. cc _ currentPage color]. newPagePrototype ifNil: [newPage _ PasteUpMorph new extent: sz; color: cc. newPage borderWidth: bw; borderColor: bc] ifNotNil: [Cursor wait showWhile: [newPage _ newPagePrototype veryDeepCopy]]. newPage setNameTo: self defaultNameStemForNewPages. newPage vResizeToFit: false. pages isEmpty ifTrue: [pages add: (currentPage _ newPage)] "had been none" ifFalse: [pages add: newPage after: pages last]. ^ newPage! ! !ImageMorph methodsFor: 'card & stack' stamp: 'tk 11/1/2001 12:43'! basicType "Answer a symbol representing the inherent type I hold" "Number String Boolean player collection sound color etc" ^ #Image! ! !NumericReadoutTile methodsFor: 'card in a stack' stamp: 'tk 11/1/2001 12:41'! basicType "Answer a symbol representing the inherent type I hold" "Number String Boolean player collection sound color etc" ^ #Number! ! !PasteUpMorph methodsFor: 'initialization' stamp: 'tk 10/30/2001 12:14'! newPlayerInstance "Answer a naked CardPlayer instance given that one does not yet exist; hence, launch a uniclass and answer an instance of it. cf inherited version." self halt: 'Please tell Ted how was this called'. ^ UnscriptedCardPlayer newUserInstance! ! !PasteUpMorph methodsFor: 'options' stamp: 'tk 10/30/2001 18:40'! behaveLikeHolder self vResizeToFit: true; autoLineLayout: true; indicateCursor: true! ! !PasteUpMorph methodsFor: 'options' stamp: 'tk 10/30/2001 18:40'! behaveLikeHolder: aBoolean "Change the receiver's viewing properties such that they conform to what we commonly call a Holder, viz: resize-to-fit, do auto-line-layout, and indicate the 'cursor'" self vResizeToFit: aBoolean; autoLineLayout: aBoolean; indicateCursor: aBoolean ! ! !PasteUpMorph methodsFor: 'options' stamp: 'tk 10/30/2001 18:41'! toggleResizeToFit "Toggle whether the receiver is set to resize-to-fit" self vResizeToFit: self resizeToFit not! ! !SketchEditorMorph methodsFor: 'morphic' stamp: 'tk 10/30/2001 13:29'! mouseEnter: evt "Set the cursor. Reread colors if embedded editable polygon needs it." | poly cColor | super mouseEnter: evt. (self get: #action for: evt) == #scaleOrRotate ifTrue: [ self set: #action for: evt to: (self get: #priorAction for: evt). ]. "scale and rotate are not real modes. If we enter with one, wear the previous tool." evt hand showTemporaryCursor: (self getCursorFor: evt). palette getSpecial == #polygon: ifFalse: [^self]. (poly _ self valueOfProperty: #polygon) ifNil: [^ self]. cColor _ self getColorFor: evt. poly color: cColor; borderWidth: 1. poly changed.! ! !SketchMorph methodsFor: 'other' stamp: 'tk 11/1/2001 12:42'! basicType "Answer a symbol representing the inherent type I hold" "Number String Boolean player collection sound color etc" ^ #Image! ! !StackMorph methodsFor: 'initialization' stamp: 'tk 10/30/2001 09:57'! initialize "Initialize the stack" | initialBackground | super initialize. initialBackground _ pages first. initialBackground extent: (640@480); beSticky. initialBackground beAStackBackground. self beUnsticky. self setProperty: #controlsAtBottom toValue: true. cards _ OrderedCollection with: initialBackground currentDataInstance. "self currentHand attachMorph: StackMorph authoringPrototype"! ! !StackMorph methodsFor: 'initialization' stamp: 'tk 11/2/2001 11:37'! initializeWith: aCardMorph "Install the card inside a new stack. Make no border or controls, so I the card's look is unchanged. Card already has a CardPlayer." | wld | wld _ aCardMorph world. self initialize. self pageSize: aCardMorph extent. self borderWidth: 0; layoutInset: 0. pages _ Array with: aCardMorph. currentPage _ aCardMorph. cards _ OrderedCollection with: currentPage currentDataInstance. currentPage beAStackBackground. self position: aCardMorph position. self hidePageControls. submorphs last delete. self addMorph: currentPage. wld addMorph: self. ! ! !StackMorph methodsFor: 'background' stamp: 'tk 10/30/2001 19:00'! insertAsBackground: newPage resize: doResize "Make a new background for the stack. Obtain a name for it from the user. It starts out life empty" | aName | aName _ FillInTheBlank request: 'What should we call this new background?' initialAnswer: 'alternateBackground'. aName isEmptyOrNil ifTrue: [^ self]. newPage beSticky. doResize ifTrue: [newPage extent: currentPage extent]. newPage beAStackBackground. newPage setNameTo: aName. newPage vResizeToFit: false. pages isEmpty ifTrue: [pages add: newPage] ifFalse: [pages add: newPage after: currentPage]. cards add: newPage currentDataInstance after: currentPage currentDataInstance. self nextPage. ! ! !StackMorph methodsFor: 'background' stamp: 'tk 10/30/2001 19:01'! makeNewBackground "Make a new background for the stack. Obtain a name for it from the user. It starts out life empty" | newPage | (newPage _ PasteUpMorph newSticky) color: self color muchLighter. newPage borderWidth: currentPage borderWidth; borderColor: currentPage borderColor. self insertAsBackground: newPage resize: true. ! ! !StackMorph class methodsFor: 'misc' stamp: 'tk 11/1/2001 13:45'! discoverSlots: aMorph "Examine the parts of the morph for ones that couldHoldSeparateData. Return a pair of lists: Named morphs, and unnamed morphs (which may be labels, and non-data). Examine all submorphs." | named unnamed | named _ OrderedCollection new. unnamed _ OrderedCollection new. aMorph allMorphsDo: [:sub | sub == aMorph ifFalse: [ sub couldHoldSeparateDataForEachInstance ifTrue: [ sub knownName ifNil: [unnamed add: sub] ifNotNil: [(sub knownName beginsWith: 'shared' "label") ifFalse: [named add: sub]]]]]. ^ Array with: named with: unnamed ! ! !String methodsFor: 'comparing' stamp: 'tk 10/17/2001 14:06'! = aString "Answer whether the receiver sorts equally as aString. The collation order is simple ascii (with case differences)." aString species == String ifFalse: [ aString isText ifTrue: [^ self = aString string]. ^ false]. ^ (self compare: self with: aString collated: AsciiOrder) = 2! ! !SyntaxMorph methodsFor: 'accessing' stamp: 'tk 10/15/2001 08:47'! selector | sel cnt | "Find the selector I represent, or have inside of me. My parseNode is a SelectorNode or a MessageNode." parseNode class == SelectorNode ifTrue: [ ^ self decompile asString asSymbol]. parseNode class == KeyWordNode ifTrue: [ ^ self decompile asString asSymbol]. (parseNode class == MessageNode) | (parseNode class == MessagePartNode) ifFalse: [^ nil]. "Must be one of those to have a selector" "Beware of messageParts. If MessagePartNode, only returns this one keyword." sel _ ''. cnt _ 0. submorphs do: [:mm | mm isSyntaxMorph ifTrue: [ cnt _ cnt + 1. (mm nodeClassIs: SelectorNode) ifTrue: [^ mm selector]. (mm nodeClassIs: MessagePartNode) ifTrue: [ sel _ sel, mm selector]. (mm nodeClassIs: KeyWordNode) ifTrue: [ sel _ sel, mm decompile asString]. (mm nodeClassIs: ReturnNode) ifTrue: [cnt _ cnt - 1]. (mm nodeClassIs: MessageNode) ifTrue: [ parseNode receiver ifNil: [sel _ mm selector]. cnt = 2 & (sel size = 0) ifTrue: ["not the receiver. Selector and arg" sel _ mm selector]]]]. sel ifNil: [^ nil]. sel size > 0 ifTrue: [^ sel asSymbol]. ^ nil! ! !SyntaxMorph methodsFor: 'event handling' stamp: 'tk 10/17/2001 13:41'! mouseMove: evt | dup selection | owner isSyntaxMorph ifFalse: [^ self]. false ifTrue: ["for now, do not drag off a tile" self currentSelectionDo: [:innerMorph :mouseDownLoc :outerMorph | mouseDownLoc ifNotNil: [ (evt cursorPoint dist: mouseDownLoc) > 4 ifTrue: ["If drag 5 pixels, then tear off a copy of outer selection." selection _ outerMorph ifNil: [self]. selection deletePopup. evt hand attachMorph: (dup _ selection duplicate). Preferences tileTranslucentDrag ifTrue: [dup lookTranslucent] ifFalse: [dup align: dup topLeft with: evt hand position + self cursorBaseOffset]. self setSelection: nil. "Why doesn't this deselect?" (self firstOwnerSuchThat: [:m | m isSyntaxMorph and: [m isBlockNode]]) ifNotNilDo: [:m | "Activate enclosing block." m startStepping]]]]. ].! ! !SyntaxMorph methodsFor: 'pop ups' stamp: 'tk 10/17/2001 13:38'! dupTile: evt | dup | self deletePopup. "self deselect." dup _ self duplicateMorph: evt. Preferences tileTranslucentDrag ifTrue: [dup align: dup center with: evt hand position. dup lookTranslucent] ifFalse: [dup align: dup topLeft with: evt hand position + self cursorBaseOffset]. ! ! !SyntaxMorph methodsFor: 'pop ups' stamp: 'tk 10/17/2001 13:29'! duplicator "Return the icon to duplicate this tile." | handle handleSpec colorToUse iconName form | handleSpec _ Preferences haloSpecifications at: 11. "duplicate" handle _ EllipseMorph newBounds: (Rectangle center: 10@10 extent: 16 asPoint) color: (colorToUse _ Color colorFrom: handleSpec color). iconName _ handleSpec iconSymbol. form _ ScriptingSystem formAtKey: iconName. "#'Halo-Dup'" handle addMorphCentered: (ImageMorph new image: form; color: colorToUse makeForegroundColor; lock). handle on: #mouseDown send: #dupTile: to: self. ^ handle! ! !SyntaxMorph methodsFor: 'pop ups' stamp: 'tk 10/17/2001 13:16'! offerPopUp "Put up a halo to allow user to change Literals (Integer, true), Selector (beep: sound, +,-,*,//,\\, r:g:b:, setX: incX: decX: for any X,), Variable (Color), not AssignmentNode (_ inc dec), Extend arrows on each literal, variable, and message, (block that is by itself). Retract arrows on each literal or variable, or message or block that is an argument. Any literal can be changed by Shift-clicking and typing." | panel any upDown retract extend colorPatch edge dismiss rr duplicate | (self hasProperty: #myPopup) ifTrue: [^ self]. "already has one" any _ false. (upDown _ self upDownArrows) ifNotNil: [any _ true]. "includes menu of selectors" (retract _ self retractArrow) ifNotNil: [any _ true]. (extend _ self extendArrow) ifNotNil: [any _ true]. (dismiss _ self dismisser) ifNotNil: [any _ true]. (duplicate _ self duplicator) ifNotNil: [any _ true]. "(assign _ self assignmentArrow) ifNotNil: [any _ true]. get from menu or any other assignment" submorphs last class == ColorTileMorph ifFalse: [ (colorPatch _ self colorPatch) ifNotNil: [any _ true]]. any ifFalse: [^ self]. "Transcript cr; print: parseNode class; space; print: (self hasProperty: #myPopup); endEntry." panel _ RectangleMorph new color: Color transparent; borderWidth: 0. upDown ifNotNil: [ panel addMorphBack: upDown first. upDown first align: upDown first topLeft with: panel topLeft + (0@0). panel addMorphBack: upDown second. upDown second align: upDown second topLeft with: upDown first bottomLeft + (0@1). upDown size > 2 ifTrue: [ panel addMorphBack: upDown third. upDown third align: upDown third topLeft with: upDown first topRight + (2@3). ]]. rr _ self right. colorPatch ifNotNil: [ rr _ rr + colorPatch submorphs first width + 1. self addMorphBack: colorPatch. "always in tile" "colorPatch align: colorPatch topLeft with: panel topLeft + (1@1)"]. retract ifNotNil: [ edge _ panel submorphs size = 0 ifTrue: [panel left] ifFalse: [panel submorphs last right]. panel addMorphBack: retract. retract align: retract topLeft with: (edge+2) @ (panel top + 3)]. extend ifNotNil: [ edge _ panel submorphs size = 0 ifTrue: [panel left] ifFalse: [panel submorphs last right]. panel addMorphBack: extend. extend align: extend topLeft with: (edge+2) @ (panel top + 3)]. duplicate ifNotNil: [ edge _ panel submorphs size = 0 ifTrue: [panel left] ifFalse: [panel submorphs last right]. panel addMorphBack: duplicate. duplicate align: duplicate topLeft with: (edge+2) @ (panel top + 1)]. dismiss ifNotNil: [ edge _ panel submorphs size = 0 ifTrue: [panel left] ifFalse: [panel submorphs last right]. panel addMorphBack: dismiss. dismiss align: dismiss topLeft with: (edge+2) @ (panel top + 1)]. " assign ifNotNil: [ edge _ panel submorphs size = 0 ifTrue: [panel left] ifFalse: [panel submorphs last right]. panel addMorphBack: assign. assign align: assign topLeft with: (edge+2) @ (panel top + 2)]. " panel align: panel topLeft with: rr @ (self top -2). panel extent: panel submorphs last bottomRight - panel topLeft. self setProperty: #myPopup toValue: panel. self addMorphBack: panel. "Any reason ever to have panel below?" "(owner listDirection = #topToBottom and: [self listDirection = #leftToRight]) ifTrue: [self addMorphBack: panel] ifFalse: [owner addMorph: panel after: self]." ! ! !TabSorterMorph methodsFor: 'as yet unclassified' stamp: 'tk 10/30/2001 18:41'! initialize super initialize. self removeAllMorphs. self extent: 300@100. pageHolder _ PasteUpMorph new. pageHolder vResizeToFit: true; autoLineLayout: true. pageHolder extent: self extent - borderWidth. pageHolder padding: 8. pageHolder cursor: 0. self addControls. self addMorphBack: pageHolder! ! !Text methodsFor: 'comparing' stamp: 'tk 10/19/2001 17:48'! = other "Am I equal to the other Text or String? ***** Warning ***** Two Texts are considered equal if they have the same characters in them. They might have completely different emphasis, fonts, sizes, text actions, or embedded morphs. If you need to find out if one is a true copy of the other, you must do (text1 = text2 and: [text1 runs = text2 runs])." other isText ifTrue: ["This is designed to run fast even for megabytes" ^ string == other string or: [string = other string]]. other isString ifTrue: [^ string == other or: [string = other]]. ^ false! ! !Text methodsFor: 'comparing' stamp: 'tk 10/17/2001 14:12'! hash "#hash is implemented, because #= is implemented. We are now equal to a string with the same characters. Hash must reflect that." ^ string hash! ! !Text methodsFor: 'attributes' stamp: 'tk 11/1/2001 14:37'! basicType "Answer a symbol representing the inherent type I hold" "Number String Boolean player collection sound color etc" ^ #Text! ! !TextMorph methodsFor: 'card & stack' stamp: 'tk 11/1/2001 14:37'! basicType "Answer a symbol representing the inherent type I hold" "Number String Boolean player collection sound color etc" ^ #Text! ! SyntaxMorph removeSelector: #dupTile! StackMorph removeSelector: #insertAsBackground:! PasteUpMorph removeSelector: #beAStackBackground! PasteUpMorph removeSelector: #currentDataInstance! PasteUpMorph removeSelector: #doWrap! PasteUpMorph removeSelector: #explainDesignations! PasteUpMorph removeSelector: #insertCard! PasteUpMorph removeSelector: #installAsCurrent:! PasteUpMorph removeSelector: #isStackBackground! PasteUpMorph removeSelector: #newCard! PasteUpMorph removeSelector: #reassessBackgroundShape! PasteUpMorph removeSelector: #relaxGripOnVariableNames! PasteUpMorph removeSelector: #reshapeBackground! PasteUpMorph removeSelector: #resizeToFit:! PasteUpMorph removeSelector: #showBackgroundObjects! PasteUpMorph removeSelector: #showDesignationsOfObjects! PasteUpMorph removeSelector: #showForegroundObjects! PasteUpMorph removeSelector: #tabHitWithEvent:! !PasteUpMorph reorganize! ('initialization' adaptedToWorld: becomeActiveDuring: initialize initializeToStandAlone newPlayerInstance newResourceLoaded releaseCachedState) ('classification' isWorldMorph world) ('cursor' cursor cursor: cursorWrapped: numberAtCursor rectifyCursor selectedRect valueAtCursor valueAtCursor:) ('display' canHaveFillStyles drawOn: gradientFillColor: printOn: setGradientColor:) ('dropping/grabbing' acceptDroppingMorph:event: automaticPhraseExpansion automaticViewing dropEnabled dropFiles: justDroppedInto:event: morphToDropFrom: originAtCenter positionNear:forExtent:adjustmentSuggestion: repelsMorph:event: wantsDropFiles: wantsDroppedMorph:event:) ('layout' addCenteredAtBottom:offset: convertAlignment laySubpartsOutInOneRow layoutChanged) ('menu & halo' addAddHandMenuItemsForHalo:hand: addCustomMenuItems:hand: addPenMenuItems:hand: addPenTrailsMenuItemsTo: addPlayfieldMenuItems:hand: addScalingMenuItems:hand: addStackMenuItems:hand: autoExpansionString autoLineLayoutString autoViewingString batchPenTrailsString buildDebugMenu: defersHaloOnClickTo: defineApplicationView defineFactoryView deleteBalloonTarget: fenceEnabledString indicateCursorString isOpenForDragNDropString isPartsBinString mightEntertainDirectionHandles mouseOverHalosString originAtCenterString playfieldOptionsMenu presentCardAndStackMenu presentPlayfieldMenu presentViewMenu reformulateUpdatingMenus saveOnFile showApplicationView showExpandedView showFactoryView showFullView showReducedView showThumbnailString transformToShow: wantsDirectionHandles wantsHaloFor: wantsHaloFromClick) ('model' createCustomModel model modelOrNil setModel:) ('naming' defaultNameStemForInstances) ('options' autoLineLayout autoLineLayout: automaticViewing: batchPenTrails batchPenTrails: becomeLikeAHolder behaveLikeAHolderString behaveLikeHolder behaveLikeHolder: behavingLikeAHolder fenceEnabled fenceEnabled: indicateCursor indicateCursor: isPartsBin isPartsBin: replaceTallSubmorphsByThumbnails resizeToFit resizeToFitString setPartsBinStatusTo: setThumbnailHeight toggleAlwaysShowThumbnail toggleAutoLineLayout toggleAutomaticPhraseExpansion toggleAutomaticViewing toggleBatchPenTrails toggleBehaveLikeAHolder toggleFenceEnabled toggleIndicateCursor toggleIsPartsBin toggleMouseOverHalos toggleOriginAtCenter toggleResizeToFit updateSubmorphThumbnails wantsMouseOverHalos wantsMouseOverHalos:) ('painting' backgroundSketch backgroundSketch: deleteBackgroundPainting makeNewDrawingWithin paintBackground paintingBoundsAround: prepareToPaint prepareToPaint: reasonablePaintingExtent) ('pen' addImageToPenTrailsFor: arrowheadsOnAllPens clearTurtleTrails createOrResizeTrailsForm drawPenTrailFor:from:to: liftAllPens lowerAllPens noArrowheadsOnAllPens noteNewLocation:forPlayer: notePenDown:forPlayer:at: trailMorph updateTrailsForm) ('scripting' abandonOldReferenceScheme allTileScriptingElements currentVocabulary currentVocabularyFor: hideAllPlayers isCandidateForAutomaticViewing modernizeBJProject recreateScripts relaunchAllViewers scriptorForTextualScript:ofPlayer: showAllPlayers) ('misc' abandonCostumeHistory allScriptEditors allScriptors alwaysShowThumbnail cachedOrNewThumbnailFrom: cartesianOrigin closedViewerFlapTabs containsCard: demandsBoolean heightForThumbnails hideViewerFlaps hideViewerFlapsOtherThanFor: impartPrivatePresenter innocuousName invalidRect:from: isPlayfieldLike makeDetachable maxHeightToAvoidThumbnailing maximumThumbnailWidth mouseX mouseY nameForCopyIfAlreadyNamed: padding: position: prepareToBeSaved presenter residesInPartsBin roundUpStrays shouldGetStepsFrom: smallThumbnailForPageSorter startRunningAll step stepAll stepTime stopRunningAll thumbnailForPageSorter unhideHiddenObjects updateStatusForAllScriptEditors viewerFlapTabFor: wantsKeyboardFocusFor:) ('object fileIn' convertToCurrentVersion:refStream:) ('flaps' accommodateFlap: addGlobalFlaps assureFlapTabsFitOnScreen bringFlapTabsToFront correspondingFlapTab deleteAllFlapArtifacts deleteGlobalFlapArtifacts enableGlobalFlaps flapTabs localFlapTabs offsetForAccommodating:onEdge: paintingFlapTab releaseViewers removeAccommodationForFlap:) ('project state' activeHand canvas firstHand hands handsDo: isStepping: isStepping:selector: listOfSteppingMorphs modelWakeUp stepListSize stepListSummary steppingMorphsNotInWorld viewBox viewBox:) ('update cycle' startBackgroundProcess) ('stepping' cleanseStepList runLocalStepMethods runStepMethods startStepping: startStepping:at:selector:arguments:stepTime: stopStepping: stopStepping:selector:) ('world state' abandonAllHalos abandonVocabularyPreference activeHand: addAllMorphs: addHand: addMorph:centeredNear: addMorphsAndModel: allMorphsDo: allNonFlapRelatedSubmorphs assureNotPaintingElse: assureNotPaintingEvent: assuredCanvas beWorldForProject: checkCurrentHandForObjectToPaste checkCurrentHandForObjectToPaste2 chooseClickTarget colorAt:belowMorph: currentNaturalLanguage deEmphasizeViewMVC: deleteAllHalos displayWorld displayWorldAsTwoTone displayWorldNonIncrementally displayWorldSafely doOneCycle doOneCycleInBackground doOneSubCycle dragThroughOnDesktop: embeddedProjectDisplayMode endDrawing: exit extent: flashRects:color: fullContainsPoint: fullRepaintNeeded goBack haloMorphOrNil haloMorphs handleFatalDrawingError: initForProject: install installAsActiveSubprojectIn:at:titled: installAsActiveSubprojectIn:titled: installFlaps installVectorVocabulary jumpToProject nextPage open openWithTitle:cautionOnClose: optimumExtentFromAuthor paintArea paintAreaFor: paintBox paintBoxOrNil patchAt:without:andNothingAbove: pauseEventRecorder previousPage privateMoveBy: privateOuterDisplayWorld referencePlayfield removeHand: repairEmbeddedWorlds restoreDisplay restoreFlapsDisplay restoreMorphicDisplay saveAsWorld sketchEditorOrNil sleep someHalo specialNameInModelFor: standardPlayerHit standardSystemController startSteppingSubmorphsOf: triggerClosingScripts triggerOpeningScripts veryDeepCopyWith:) ('accessing' assureFlapWidth: flapTab useRoundedCorners) ('project' project releaseSqueakPages storeProjectsAsSegments) ('interaction loop' doOneCycleNow keyStroke:) ('WiW support' restartWorldCycleWithEvent: validateMouseEvent:) ('private' morphicLayerNumber privateFullMoveBy:) ('Nebraska' addRemoteClient: convertRemoteClientToBuffered: hasRemoteServer releaseRemoteServer remoteServer remoteServer: removeRemoteClient: transferRemoteServerFrom:) ('gridding' gridModulus gridModulus: gridOrigin gridOrigin: gridPoint: gridSpec gridSpecPut: gridVisible gridVisibleOnOff gridVisibleString griddingOn griddingOnOff griddingString setGridSpec) ('undo' clearCommandHistory commandHistory) ('alarms-scheduler' addAlarm:withArguments:for:at: removeAlarm:for:) ('submorphs-add/remove' addMorphFront: addMorphInLayer:) ('viewing' addViewingItemsTo: imposeListViewSortingBy:retrieving: restoreBoundsOfSubmorphs saveBoundsOfSubmorphs scriptSelectorToTriggerFor: showingListView sortSubmorphsBy: viewByIcon viewByName viewBySize viewNonOverlapping viewingByIconString viewingByNameString viewingBySizeString viewingNonOverlappingString viewingNormally) ('event handling' handlesKeyboard: handlesMouseDown: morphToGrab: mouseDown: mouseUp: processEvent:using:) ('world menu' activateObjectsTool addUndoItemsTo: bringWindowsFullOnscreen buildWorldMenu: closeUnchangedWindows collapseAll collapseNonWindows connectRemoteUser connectRemoteUserWithName:picture:andIPAddress: deleteNonWindows detachableScriptingSpace disconnectAllRemoteUsers disconnectRemoteUser drawingClass expandAll extractScreenRegion:andPutSketchInHand: findAChangeSorter: findAMessageNamesWindow: findAPreferencesPanel: findATranscript: findDirtyBrowsers: findDirtyWindows: findWindow: getWorldMenu: grabDrawingFromScreen: grabFloodFromScreen: grabLassoFromScreen: grabRubberBandFromScreen: invokeWorldMenu: keystrokeInWorld: makeNewDrawing: makeNewDrawing:at: newDrawingFromMenu: openRecentSubmissionsBrowser: openScrapsBook: printScriptSummary putUpDesktopMenu: putUpWorldMenu: removeAllViewers reportLocalAddress showStatusOfAllScripts yellowButtonClickOnDesktopWithEvent:) ('submorphs-accessing' morphsInFrontOf:overlapping:do:) ! !Morph reorganize! ('initialization' basicInitialize currentVocabulary inATwoWayScrollPane initialExtent initialize intoWorld: openCenteredInWorld openInHand openInMVC openInWindow openInWindowLabeled: openInWindowLabeled:inWorld: openInWorld openInWorld: outOfWorld: resourceJustLoaded standardPalette) ('classification' isAlignmentMorph isBalloonHelp isFlapOrTab isFlapTab isFlashMorph isFlexMorph isHandMorph isModalShell isMorph isMorphicModel isPlayfieldLike isRenderer isStandardViewer isSyntaxMorph isWorldMorph isWorldOrHandMorph) ('accessing' actorState actorState: actorStateOrNil asMorph balloonText balloonTextSelector balloonTextSelector: beFlap: beSticky beUnsticky borderColor borderColor: borderWidth borderWidth: borderWidthForRounding color color: colorForInsets eventHandler eventHandler: forwardDirection hasTranslucentColor highlight highlightColor highlightColor: highlightOnlySubmorph: insetColor isFlap isLocked isShared isSticky lock lock: methodCommentAsBalloonHelp modelOrNil player player: raisedColor regularColor regularColor: rememberedColor rememberedColor: sqkPage sticky: toggleLocked toggleStickiness unHighlight unlock unlockContents url userString wantsToBeCachedByHand) ('access properties' hasProperty: removeProperty: setProperty:toValue: valueOfProperty: valueOfProperty:ifAbsent: valueOfProperty:ifAbsentPut: valueOfProperty:ifPresentDo:) ('copying' copy deepCopy duplicate fullCopy updateReferencesUsing: usableSiblingInstance veryDeepCopyWith: veryDeepFixupWith: veryDeepInner:) ('structure' activeHand allOwners allOwnersDo: firstOwnerSuchThat: hasOwner: isInWorld morphPreceding: nearestOwnerThat: orOwnerSuchThat: outermostMorphThat: outermostWorldMorph owner ownerThatIsA: ownerThatIsA:orA: pasteUpMorph pasteUpMorphHandlingTabAmongFields presenter primaryHand renderedMorph root rootAt: topPasteUp topRendererOrSelf withAllOwners withAllOwnersDo: world) ('submorphs-accessing' allKnownNames allMorphs allMorphsDo: allNonSubmorphMorphs findA: findDeepSubmorphThat:ifAbsent: findDeeplyA: findSubmorphBinary: firstSubmorph hasSubmorphWithProperty: hasSubmorphs indexOfMorphAbove: knownNamesOfSubmorphs lastSubmorph morphsAt: morphsAt:behind:unlocked: morphsAt:unlocked: morphsAt:unlocked:do: morphsInFrontOf:overlapping:do: morphsInFrontOverlapping: morphsInFrontOverlapping:do: rootMorphsAt: rootMorphsAtGlobal: shuffleSubmorphs submorphAfter submorphBefore submorphCount submorphNamed: submorphNamed:ifNone: submorphOfClass: submorphThat:ifNone: submorphWithProperty: submorphs submorphsBehind:do: submorphsDo: submorphsInFrontOf:do: submorphsReverseDo: submorphsSatisfying:) ('submorphs-add/remove' abandon actWhen actWhen: addAllMorphs: addAllMorphs:after: addMorph: addMorph:after: addMorph:asElementNumber: addMorph:behind: addMorph:fullFrame: addMorph:inFrontOf: addMorphBack: addMorphCentered: addMorphFront: addMorphFront:fromWorldPosition: addMorphNearBack: comeToFront copyWithoutSubmorph: delete deleteSubmorphsWithProperty: dismissViaHalo goBehind privateDelete removeAllMorphs removeAllMorphsIn: replaceSubmorph:by: submorphIndexOf:) ('drawing' areasRemainingToFill: boundingBoxOfSubmorphs boundsWithinCorners changeClipSubmorphs clipLayoutCells clipLayoutCells: clipSubmorphs clipSubmorphs: clippingBounds doesOwnRotation drawDropHighlightOn: drawDropShadowOn: drawErrorOn: drawMouseDownHighlightOn: drawOn: drawOnCanvas: drawPostscriptOn: drawRolloverBorderOn: drawSubmorphsOn: expandFullBoundsForDropShadow: expandFullBoundsForRolloverBorder: flash fullDrawOn: fullDrawPostscriptOn: hasClipSubmorphsString hide highlightForMouseDown highlightForMouseDown: highlightedForMouseDown imageForm imageForm:forRectangle: imageFormDepth: imageFormForRectangle: imageFormWithout:andStopThere: refreshWorld shadowForm show visible visible:) ('geometry' align:with: bottom bottom: bottomLeft bottomLeft: bottomRight bottomRight: bounds bounds: bounds:from: bounds:in: boundsIn: boundsInWorld center center: extent extent: fullBoundsInWorld globalPointToLocal: gridPoint: griddedPoint: height height: innerBounds left left: localPointToGlobal: minimumExtent minimumExtent: nextOwnerPage outerBounds point:from: point:in: pointFromWorld: pointInWorld: position position: positionInWorld positionSubmorphs previousOwnerPage right right: screenLocation screenRectangle setConstrainedPosition:hangOut: shiftSubmorphsBy: shiftSubmorphsOtherThan:by: top top: topLeft topLeft: topRight topRight: transformedBy: width width: worldBounds worldBoundsForHalo) ('rotate scale and flex' addFlexShell keepsTransform newTransformationMorph rotationDegrees) ('geometry testing' containsPoint: fullContainsPoint: obtrudesBeyondContainer) ('geometry eToy' addTransparentSpacerOfSize: beTransparent cartesianBoundsTopLeft cartesianXY cartesianXY: color:sees: colorUnder degreesOfFlex forwardDirection: getIndexInOwner goHome heading heading: move:toPosition: referencePosition referencePosition: referencePositionInWorld referencePositionInWorld: rotationCenter rotationCenter: setDirectionFrom: setIndexInOwner: touchesColor: transparentSpacerOfSize: wrap x x: x:y: y y:) ('thumbnail' demandsThumbnailing morphRepresented permitsThumbnailing readoutForField: representativeNoTallerThan:norWiderThan:thumbnailHeight: updateThumbnailUrl updateThumbnailUrlInBook:) ('dropping/grabbing' aboutToBeGrabbedBy: asDraggableMorph disableDragNDrop dragEnabled dragEnabled: dragNDropEnabled dragSelectionColor dropEnabled dropEnabled: dropHighlightColor dropSuccessColor enableDrag: enableDragNDrop enableDragNDrop: enableDrop: formerOwner formerOwner: formerPosition formerPosition: grabTransform highlightForDrop highlightForDrop: highlightedForDrop justDroppedInto:event: justGrabbedFrom: 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 doubleClick: doubleClickTimeout: dropFiles: firstClickTimedOut: handlesKeyboard: handlesMouseDown: handlesMouseOver: handlesMouseOverDragging: handlesMouseStillDown: hasFocus keyDown: keyStroke: keyUp: keyboardFocusChange: mouseDown: mouseEnter: mouseEnterDragging: mouseLeave: mouseLeaveDragging: mouseMove: mouseStillDown: mouseStillDownThreshold mouseUp: on:send:to: on:send:to:withValue: removeLink: restoreSuspendedEventHandler startDrag: suspendEventHandler transformFrom: transformFromOutermostWorld transformFromWorld wantsDropFiles: wantsEveryMouseMove wantsKeyboardFocusFor: wouldAcceptKeyboardFocus wouldAcceptKeyboardFocusUponTab) ('pen' choosePenColor: choosePenSize getPenColor getPenDown getPenSize liftPen lowerPen penColor: penUpWhile: trailMorph) ('naming' choosePartName defaultNameStemForInstances downshiftedNameOfObjectRepresented externalName innocuousName knownName name: nameForFindWindowFeature nameInModel nameOfObjectRepresented renameTo: setNamePropertyTo: setNameTo: specialNameInModel tryToRenameTo: updateAllScriptingElements) ('stepping and presenter' arrangeToStartStepping arrangeToStartSteppingIn: isStepping isSteppingSelector: start startStepping startStepping:at:arguments:stepTime: startSteppingIn: startSteppingSelector: step stepAt: stepTime stop stopStepping stopSteppingSelector: stopSteppingSelfAndSubmorphs wantsSteps) ('menus' absorbStateFromRenderer: addAddHandMenuItemsForHalo:hand: addCustomHaloMenuItems:hand: addCustomMenuItems:hand: addExportMenuItems:hand: addFillStyleMenuItems:hand: addPaintingItemsTo:hand: addTitleForHaloMenu: adhereToEdge adhereToEdge: adjustedCenter adjustedCenter: allMenuWordings changeColor changeDragAndDrop chooseNewGraphic chooseNewGraphicCoexisting: chooseNewGraphicFromHalo collapse dismissButton doMenuItem: exportAsBMP exportAsGIF hasDragAndDropEnabledString helpButton inspectInMorphic inspectInMorphic: lockUnlockMorph lockedString makeNascentScript maybeAddCollapseItemTo: menuItemAfter: menuItemBefore: presentHelp printPSToFile printPSToFileNamed: putOnBackground putOnForeground resetForwardDirection setRotationCenter setRotationCenterFrom: setToAdhereToEdge: snapToEdgeIfAppropriate stickinessString transferStateToRenderer: uncollapseSketch) ('halos and balloon help' addHalo addHalo: addHalo:from: addHandlesTo:box: addMagicHaloFor: addOptionalHandlesTo:box: addSimpleHandlesTo:box: addWorldHandlesTo:box: balloonColor balloonColor: balloonHelpAligner balloonHelpDelayTime balloonHelpTextForHandle: boundsForBalloon comeToFrontAndAddHalo defaultBalloonColor defersHaloOnClickTo: deleteBalloon editBalloonHelpContent: editBalloonHelpText halo haloClass haloDelayTime hasHalo hasHalo: isLikelyRecipientForMouseOverHalos mightEntertainDirectionHandles mouseDownOnHelpHandle: noHelpString okayToAddGrabHandle removeHalo setBalloonText: setBalloonText:maxLineLength: setCenteredBalloonText: showBalloon: showBalloon:hand: transferHalo:from: wantsBalloon wantsDirectionHandles wantsHalo wantsHaloFor: wantsHaloFromClick wantsScriptorHaloHandle) ('change reporting' changed colorChangedForSubmorph: invalidRect: invalidRect:from: ownerChanged userSelectedColor:) ('player' assureExternalName assuredCardPlayer assuredPlayer currentDataValue newPlayerInstance okayToDuplicate shouldRememberCostumes showPlayerMenu variableDocks) ('player commands' beep beep: jumpTo: makeFenceSound set:) ('player viewer' openViewerForArgument updateLiteralLabel) ('scripting' asEmptyPermanentScriptor bringTileScriptingElementsUpToDate bringUpToDate categoriesForViewer instantiatedUserScriptsDo: isTileLike isTileScriptingElement jettisonScripts makeAllTilesColored makeAllTilesGreen restoreTypeColor scriptEditorFor: scriptPerformer selectorsForViewer tearOffTile triggerScript: useUniformTileColor viewAfreshIn:showingScript:at:) ('e-toy support' adaptToWorld: adoptVocabulary: allMorphsAndBookPagesInto: appearsToBeSameCostumeAs: asNumber: asWearableCostume asWearableCostumeOfExtent: automaticViewing changeAllBorderColorsFrom:to: configureForKids containingWindow copyCostumeStateFrom: creationStamp currentPlayerDo: cursor cursor: defaultFloatPrecisionFor: defaultValueOrNil defaultVariableName definePath deletePath embedInWindow embeddedInMorphicWindowLabeled: enclosingEditor enforceTileColorPolicy fenceEnabled followPath getNumericValue gridFormOrigin:grid:background:line: isAViewer isCandidateForAutomaticViewing isTileEditor listViewLineForFieldList: makeGraphPaper makeGraphPaperGrid:background:line: mustBeBackmost noteNegotiatedName:for: objectViewed referencePlayfield rotationStyle rotationStyle: setAsActionInButtonProperties: setNaturalLanguageTo: setNumericValue: setStandardTexture slotSpecifications succeededInRevealing: textureParameters topEditor unlockOneSubpart updateCachedThumbnail wrappedInWindow: wrappedInWindowWithTitle:) ('button' doButtonAction fire firedMouseUpCode) ('parts bin' inPartsBin initializeToStandAlone isPartsBin isPartsDonor isPartsDonor: markAsPartsDonor partRepresented residesInPartsBin) ('printing' asEPS asPostscript asPostscriptPrintJob clipPostscript colorString: constructorString defaultLabelForInspector fullPrintOn: initString morphReport morphReportFor: morphReportFor:on:indent: pagesHandledAutomatically printConstructorOn:indent: printConstructorOn:indent:nodeDict: printOn: printSpecs printSpecs: printStructureOn:indent: structureString textToPaste) ('property extension' assureExtension extension otherProperties resetExtension) ('caching' fullLoadCachedState fullReleaseCachedState loadCachedState releaseCachedState) ('debug and other' addDebuggingItemsTo:hand: addMouseActionIndicatorsWidth:color: addMouseUpAction addMouseUpActionWith: addViewingItemsTo: allStringsAfter: altSpecialCursor0 altSpecialCursor1 altSpecialCursor2 altSpecialCursor3 altSpecialCursor3: buildDebugMenu: defineTempCommand deleteAnyMouseActionIndicators handMeTilesToFire inspectArgumentsPlayerInMorphic: inspectOwnerChain installModelIn: mouseUpCodeOrNil ownerChain programmedMouseDown:for: programmedMouseEnter:for: programmedMouseLeave:for: programmedMouseUp:for: programmedMouseUp:for:with: removeMouseUpAction reportableSize resumeAfterDrawError resumeAfterStepError tempCommand viewMorphDirectly) ('private' moveWithPenDownBy: moveWithPenDownByRAA: myEvents myEvents: privateAddMorph:atIndex: privateBounds: privateColor: privateDeleteWithAbsolutelyNoSideEffects privateFullBounds: privateFullMoveBy: privateMoveBy: privateOwner: privateRemoveMorph: privateRemoveMorphWithAbsolutelyNoSideEffects: privateSubmorphs privateSubmorphs:) ('fileIn/out' attachToResource objectForDataStream: prepareToBeSaved reserveUrl: saveAsResource saveDocPane saveOnFile saveOnURL saveOnURL: saveOnURLbasic storeDataOn: updateAllFromResources updateFromResource) ('object fileIn' convertAugust1998:using: convertNovember2000DropShadow:using: convertToCurrentVersion:refStream:) ('visual properties' canHaveFillStyles canSetColor colorsAtCorners cornerStyle defaultColor fillStyle fillStyle: fillWithRamp:oriented: useBitmapFill useDefaultFill useGradientFill useSolidFill) ('texture support' asTexture installAsWonderlandTextureOn: isValidWonderlandTexture isValidWonderlandTexture: mapPrimitiveVertex: wonderlandTexture wonderlandTexture:) ('card in a stack' abstractAModel beAStackBackground containsCard: couldHoldSeparateDataForEachInstance currentDataInstance explainDesignations goToNextCardInStack goToPreviousCardInStack holdsSeparateDataForEachInstance insertAsStackBackground insertCard installAsCurrent: isStackBackground makeHoldSeparateDataForEachInstance newCard reassessBackgroundShape relaxGripOnVariableNames reshapeBackground setAsDefaultValueForNewCard showBackgroundObjects showDesignationsOfObjects showForegroundObjects stack stackDo: stopHoldingSeparateDataForEachInstance tabHitWithEvent: wrapWithAStack) ('WiW support' addMorphInFrontOfLayer: addMorphInLayer: eToyRejectDropMorph:event: morphicLayerNumber morphicLayerNumberWithin: randomBoundsFor: shouldGetStepsFrom:) ('rounding' cornerStyle: roundedCorners roundedCornersString toggleCornerRounding wantsRoundedCorners) ('undo' commandHistory undoMove:redo:owner:bounds:predecessor:) ('events-alarms' addAlarm:after: addAlarm:at: addAlarm:with:after: addAlarm:with:at: addAlarm:with:with:after: addAlarm:with:with:at: addAlarm:withArguments:after: addAlarm:withArguments: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: handleUnknownEvent: handlerForMouseDown: mouseDownPriority processEvent: processEvent:using: rejectDropEvent: rejectsEvent: transformedFrom:) ('meta-actions' applyStatusToAllSiblings: beThisWorldsModel blueButtonDown: blueButtonUp: bringAllSiblingsToMe: buildHandleMenu: buildMetaMenu: changeColorTarget:selector:originalColor:hand: copyToPasteBuffer: dismissMorph: duplicateMorph: embedInto: grabMorph: handlerForBlueButtonDown: handlerForMetaMenu: inspectAt:event: invokeMetaMenu: invokeMetaMenuAt:event: makeMultipleSiblings: makeNewPlayerInstance: makeSiblings: makeSiblingsLookLikeMe: maybeDuplicateMorph: openAButtonPropertySheet openAPropertySheet openATextPropertySheet potentialEmbeddingTargets resizeMorph: saveAsPrototype showActions showHiders subclassMorph) ('testing' canDrawAtHigherResolution completeModificationHash isFlexed modificationHash) ('drop shadows' addDropShadow addDropShadowMenuItems:hand: changeShadowColor hasDropShadow hasDropShadow: hasDropShadowString hasRolloverBorder hasRolloverBorder: removeDropShadow setShadowOffset: shadowColor shadowColor: shadowOffset shadowOffset: shadowPoint: toggleDropShadow) ('layout' acceptDroppingMorph:event: adjustLayoutBounds doLayoutIn: fullBounds layoutBounds layoutBounds: layoutChanged layoutInBounds: layoutProportionallyIn: 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 cellPositioning: cellPositioningString: cellSpacing cellSpacing: cellSpacingString: disableTableLayout disableTableLayout: hResizing hResizing: hResizingString: layoutFrame layoutFrame: layoutInset layoutInset: layoutPolicy layoutPolicy: layoutProperties layoutProperties: listCentering listCentering: listCenteringString: listDirection listDirection: listDirectionString: listSpacing listSpacing: listSpacingString: maxCellSize maxCellSize: minCellSize minCellSize: reverseTableCells reverseTableCells: rubberBandCells rubberBandCells: spaceFillWeight spaceFillWeight: vResizeToFit: vResizing vResizing: vResizingString: wrapCentering wrapCentering: wrapCenteringString: wrapDirection wrapDirection: wrapDirectionString:) ('piano rolls' addMorphsTo:pianoRoll:eventTime:betweenTime:and: encounteredAtTime:inScorePlayer:atIndex:inEventTrack:secsPerTick: justDroppedIntoPianoRoll:event: pauseFrom: resetFrom: resumeFrom: triggerActionFromPianoRoll) ('genie-menu' addGenieMenuItems:hand: changeGestureDictionary hasNotExportedGestureDictionary hasReferencedGestureDictionary inspectGestureDictionary makeOwnCopyOfGestureDictionary makeOwnSubGestureDictionary) ('genie-dispatching' blueButtonClickHand:shift: gesture: gestureCode: gestureCommand: gestureKeystrokes: gestureMouseEvent: gestureStrokes: handleGesture: isGestureUndoable: isSpecialCharacterUndoable: modifyGesture:by: undoGesture:) ('genie-processing' allowsGestureEscape allowsGesturePreprocessing allowsGestureStart: defaultGestureDictionaryOrName disableGestures gestureDictionary gestureDictionaryOrName gestureDictionaryOrName: gestureHandler gestureStart: handlesGestureStart: onGestureSend:to:) ('button properties' buttonProperties buttonProperties: ensuredButtonProperties hasButtonProperties) ('other events' menuButtonMouseEnter: menuButtonMouseLeave:) ('miscellaneous' setExtentFromHalo:) !