'From Squeakland 3.2.4913 of 10 July 2002 [latest update: #222] on 28 July 2004 at 10:59:11 pm'! "Change Set: e15AllPlayersTool-sw Date: 1 August 2004 Author: Scott Wallace Derived from update Squeakland update 0224allPlayersTool-sw.cs A tool letting you discover and inspect all the players in your project."! AlignmentMorph subclass: #AllPlayersTool instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: 'Morphic-Scripting'! !AllPlayersTool commentStamp: '' prior: 0! A tool that lets you see find, view, and obtain tiles for all the active players in the project.! AlignmentMorph subclass: #PlayerSurrogate instanceVariableNames: 'playerRepresented ' classVariableNames: '' poolDictionaries: '' category: 'Morphic-Scripting'! !PlayerSurrogate commentStamp: '' prior: 0! An morph representing an E-Toy "Player" in an AllPlayersTool.! ThumbnailMorph subclass: #ThumbnailForAllPlayersTool instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: 'Morphic-Scripting'! !ThumbnailForAllPlayersTool commentStamp: '' prior: 0! A thumbnail for use in an All-Players tool! !AllPlayersTool methodsFor: 'initialization' stamp: 'sw 7/28/2004 22:12'! addHeaderRow "Add the header morph at the top of the tool" | aRow title | aRow _ AlignmentMorph newRow. aRow listCentering: #justified; color: Color transparent. aRow addMorphFront: self dismissButton. "aRow addMorphBack: self menuButton." aRow addMorphBack: (title _ StringMorph contents: 'Gallery of Players' translated). title setBalloonText: 'Double-click here to refresh the contents' translated. title on: #doubleClick send: #reinvigorate to: self. aRow addMorphBack: self helpButton. self addMorphFront: aRow. ! ! !AllPlayersTool methodsFor: 'initialization' stamp: 'sw 7/28/2004 20:48'! initializeFor: aPresenter "Initialize the receiver as a tool which shows, and allows the user to change the status of, all the instantiations of all the user-written scripts in the scope of the containing pasteup's presenter" | placeHolder | self color: Color brown muchLighter muchLighter; wrapCentering: #center; cellPositioning: #topCenter; vResizing: #shrinkWrap; hResizing: #shrinkWrap. self useRoundedCorners. self borderStyle: BorderStyle complexAltInset; borderWidth: 4; borderColor: (Color r: 0.452 g: 0.839 b: 1.0). "Color fromUser" self addHeaderRow. placeHolder _ Morph new beTransparent. placeHolder extent: 200@1. self addMorphBack: placeHolder. ActiveWorld presenter reinvigoratePlayersTool: self ! ! !AllPlayersTool methodsFor: 'initialization' stamp: 'sw 7/28/2004 18:08'! initializeToStandAlone "Initialize the receiver" super initializeToStandAlone. self layoutPolicy: TableLayout new; listDirection: #topToBottom; hResizing: #spaceFill; extent: 1@1; vResizing: #spaceFill; rubberBandCells: true; yourself. self initializeFor: self currentWorld presenter! ! !AllPlayersTool methodsFor: 'reinvigoration' stamp: 'sw 7/19/2004 16:37'! invigorateButton "Answer a button that triggers reinvigoration" | aButton | aButton _ IconicButton new target: self; borderWidth: 0; labelGraphic: (ScriptingSystem formAtKey: #Refresh); color: Color transparent; actWhen: #buttonUp; actionSelector: #reinvigorate; yourself. aButton setBalloonText: 'Click here to refresh the list of players'. ^ aButton ! ! !AllPlayersTool methodsFor: 'reinvigoration' stamp: 'sw 7/19/2004 16:17'! menuButton "Answer a button that brings up a menu. Useful when adding new features, but at present is between uses" | aButton | aButton _ IconicButton new target: self; borderWidth: 0; labelGraphic: (ScriptingSystem formAtKey: #TinyMenu); color: Color transparent; actWhen: #buttonDown; actionSelector: #offerMenu; yourself. aButton setBalloonText: 'click here to get a menu with further options'. ^ aButton ! ! !AllPlayersTool methodsFor: 'reinvigoration' stamp: 'sw 7/28/2004 18:08'! reinvigorate "Referesh the contents of the receiver" (submorphs copyFrom: 3 to: submorphs size) do: [:m | m delete]. ActiveWorld doOneCycleNow. self playSoundNamed: 'scritch'. (Delay forMilliseconds: 700) wait. ActiveWorld presenter reinvigoratePlayersTool: self. self playSoundNamed: 'scratch'! ! !AllPlayersTool methodsFor: 'menus' stamp: 'sw 7/28/2004 18:32'! addCustomMenuItems: aMenu hand: aHand "Add further items to the menu" aMenu add: 'reinvigorate' target: self action: #reinvigorate. Preferences eToyFriendly ifFalse: [aMenu add: 'inspect' target: self action: #inspect]! ! !AllPlayersTool methodsFor: 'menus' stamp: 'sw 7/28/2004 22:58'! presentHelp "Sent when a Help button is hit; provide the user with some form of help for the tool at hand" | aString aTextMorph | aString _ 'About the Gallery of Players Click on an object''s picture to reveal its location. Click on the turquoise eye to open the object''s viewer. Click on an object''s name to obtain a tile representing the object. Double-click on the title ("Gallery of Players") to refresh the tool; this may allow you to see newly-added or newly-scripted objects.'. aTextMorph _ TextMorph new contents: aString translated. aTextMorph useRoundedCorners; borderWidth: 3; borderColor: Color gray; margins: 3@3. aTextMorph backgroundColor: Color blue muchLighter. aTextMorph beAllFont: (StrikeFont familyName: #ComicBold size: 18); centered; lock. AlignmentMorph new beTransparent hResizing: #shrinkWrap; vResizing: #shrinkWrap; addMorphBack: aTextMorph; openInHand! ! !AllPlayersTool class methodsFor: 'parts bin' stamp: 'sw 7/19/2004 10:37'! descriptionForPartsBin "Answer a description for use in parts bins" ^ self partName: 'Players' categories: #('Scripting') documentation: 'A tool showing all the players in your project'! ! !AllPlayersTool class methodsFor: 'instance-creation defaults' stamp: 'sw 7/19/2004 10:38'! defaultNameStemForInstances "Answer the default name stem for new instances of this class" ^ 'Players'! ! !PasteUpMorph methodsFor: 'world menu' stamp: 'sw 7/28/2004 16:34'! galleryOfPlayers "Put up a tool showing all the players in the project" (ActiveWorld findA: AllPlayersTool) ifNotNilDo: [:aTool | ^ aTool comeToFront]. AllPlayersTool newStandAlone openInHand "ActiveWorld galleryOfPlayers"! ! !Player methodsFor: 'misc' stamp: 'sw 7/28/2004 20:51'! beRevealedInActiveWorld "Reveal my corresponding morph in the active world" self revealPlayerIn: ActiveWorld! ! !Player methodsFor: 'misc' stamp: 'sw 7/28/2004 20:52'! entryForPlayersTool: aPlayersTool "Answer an entry for the receiver in the All Players tool" ^ PlayerSurrogate newRow playerRepresented: self! ! !Player methodsFor: 'misc' stamp: 'sw 7/19/2004 16:41'! grabPlayerInActiveWorld "Invoked from a Viewer: rip my morph out of its container, wherever that may be, and place it in the hand, being careful to set things up so that if the subsequent drop is rejected, the morph will end up in a visible location on the screen" self grabPlayerIn: ActiveWorld! ! !Player methodsFor: 'misc' stamp: 'sw 5/4/2001 07:12'! tileReferringToSelf "answer a tile that refers to the receiver" | aTile nn tile | Preferences universalTiles ifTrue: [nn _ self externalName. "name it, if necessary, and put in References" (References includesKey: nn asSymbol) ifFalse: [ References at: nn asSymbol put: self]. tile _ SyntaxMorph new parseNode: (VariableNode new name: nn key: nn code: nil). tile layoutInset: 1; addMorph: (tile addString: nn special: false). tile color: (SyntaxMorph translateColor: #variable). tile extent: tile firstSubmorph extent + (2@2). ^ tile]. aTile _ TileMorph new setToReferTo: self. ^ aTile! ! !CardPlayer methodsFor: 'slots-kernel' stamp: 'sw 7/28/2004 21:03'! tileReferringToSelf "Answer a tile that refers to the receiver. For CardPlayer, want 'self', not the specific name of this card. Script needs to work for any card of the background." Preferences universalTiles ifTrue: [^ self universalTileReferringToSelf]. ^ TileMorph new setToReferTo: self! ! !PlayerSurrogate methodsFor: 'accessing' stamp: 'sw 7/19/2004 12:48'! playerRepresented "Answer the value of playerRepresented" ^ playerRepresented! ! !PlayerSurrogate methodsFor: 'accessing' stamp: 'sw 7/28/2004 21:16'! playerRepresented: anObject "Set the value of playerRepresented" playerRepresented _ anObject. self rebuildRow. self setNameTo: anObject costume topRendererOrSelf externalName! ! !PlayerSurrogate methodsFor: 'accessing' stamp: 'sw 7/28/2004 22:19'! rebuildRow "Rebuild the row" | aThumbnail aTileButton aViewerButton | self removeAllMorphs. self layoutInset: 2; cellInset: 3. self beTransparent. aThumbnail _ ThumbnailForAllPlayersTool new objectToView: playerRepresented viewSelector: #graphicForViewerTab. aThumbnail setBalloonText: 'Click here to reveal this object' translated. self addMorphBack: aThumbnail. aThumbnail on: #mouseUp send: #beRevealedInActiveWorld to: playerRepresented. "aMenuButton _ IconicButton new labelGraphic: Cursor menu. aMenuButton target: self; actionSelector: #playerButtonHit; color: Color transparent; borderWidth: 0; shedSelvedge; actWhen: #buttonDown. aMenuButton setBalloonText: 'Press here to get a menu'. self addMorphBack: aMenuButton." aViewerButton _ IconicButton new labelGraphic: (ScriptingSystem formAtKey: #Viewer). aViewerButton color: Color transparent; actWhen: #buttonUp; actionSelector: #beViewed; target: playerRepresented; setBalloonText: 'click here to obtain this object''s Viewer' translated; color: Color transparent; borderWidth: 0; shedSelvedge. self addMorphBack: aViewerButton. aTileButton _ IconicButton new borderWidth: 0. aTileButton labelGraphic: (TileMorph new setToReferTo: playerRepresented) imageForm. aTileButton color: Color transparent; actWhen: #buttonDown; actionSelector: #tearOffTileForSelf; target: playerRepresented; setBalloonText: 'click here to obtain a tile that refers to this player.' translated. self addMorphBack: aTileButton. " aNameMorph _ UpdatingStringMorph new useStringFormat; target: playerRepresented; getSelector: #nameForViewer; setNameTo: 'name'; font: ScriptingSystem fontForNameEditingInScriptor. aNameMorph putSelector: #setName:. aNameMorph setProperty: #okToTextEdit toValue: true. aNameMorph step. self addMorphBack: aNameMorph. aNameMorph setBalloonText: 'Click here to edit the player''s name.'. " ! ! !PlayerSurrogate methodsFor: 'menu' stamp: 'sw 7/28/2004 21:18'! addCustomMenuItems: aMenu hand: aHand "Add cu stom items to the menu" aMenu addList: #( ('grab this object' grabThisObject 'wherever it may be rip this object out of its container and hand it to me.') ('reveal this object' revealThisObject 'make this object visible and put up its halo') ('hand me a tile' handMeATile 'hand me a tile for this object') ('open viewer' viewerForThisObject 'open this object''s Viewer'))! ! !PlayerSurrogate methodsFor: 'menu' stamp: 'sw 7/28/2004 20:54'! grabThisObject "Hand the user the object represented by the receiver. Invoked from menu, formerly at least." playerRepresented grabPlayerInActiveWorld! ! !PlayerSurrogate methodsFor: 'menu' stamp: 'sw 7/28/2004 20:52'! handMeATile "Hand the user a tile representing the player for which the receiver is a surrogate" playerRepresented tearOffTileForSelf! ! !PlayerSurrogate methodsFor: 'menu' stamp: 'sw 7/28/2004 18:05'! revealThisObject "Reveal the object I represent" playerRepresented revealPlayerIn: ActiveWorld! ! !PlayerSurrogate methodsFor: 'menu' stamp: 'sw 7/28/2004 20:53'! viewerForThisObject "Open a viewer for the object represented by the receiver" playerRepresented beViewed! ! !PlayerSurrogate methodsFor: 'updating' stamp: 'sw 7/28/2004 20:55'! bringUpToDate "To react to changes in the corrreponding player, rebuild the display with fresh information from its surrogate" self rebuildRow! ! !PlayerSurrogate methodsFor: 'updating' stamp: 'sw 7/28/2004 20:54'! isTileScriptingElement "Answer (for the purpose of updating) whether the receiver is a tile-scripting element" ^ true! ! !Presenter methodsFor: 'playerList' stamp: 'sw 7/28/2004 21:00'! reinvigoratePlayersTool: aPlayersTool "Rebuild the contents of the Players tool" | firstTwo oldList newList rowsForPlayers | firstTwo _ {aPlayersTool submorphs first. aPlayersTool submorphs second}. oldList _ (aPlayersTool submorphs copyFrom: 3 to: aPlayersTool submorphs size) collect: [:aRow | aRow playerRepresented]. self flushPlayerListCache. newList _ self allExtantPlayers. oldList asSet = newList asSet ifFalse: [aPlayersTool removeAllMorphs; addAllMorphs: firstTwo. rowsForPlayers _ newList collect: [:aPlayer | aPlayer entryForPlayersTool: aPlayersTool]. aPlayersTool addAllMorphs: rowsForPlayers ]! ! !Presenter methodsFor: 'intialize' stamp: 'sw 7/19/2004 14:44'! allExtantPlayers "The initial intent here was to produce a list of Player objects associated with any Morph in the tree beneath the receiver's associatedMorph. whether it is the submorph tree or perhaps off on unseen bookPages. We have for the moment moved away from that initial intent, and in the current version we only deliver up players associated with the submorph tree only. <-- this note dates from 4/21/99 Call #flushPlayerListCache; to force recomputation." | fullList objectsReferredToByTiles | playerList ifNotNil: [^ playerList]. fullList _ associatedMorph allMorphs select: [:m | m player ~~ nil] thenCollect: [:m | m player]. fullList copy do: [:aPlayer | aPlayer class scripts do: [:aScript | aScript isTextuallyCoded ifFalse: [objectsReferredToByTiles _ aScript currentScriptEditor allMorphs select: [:aMorph | (aMorph isKindOf: TileMorph) and: [aMorph type == #objRef]] thenCollect: [:aMorph | aMorph actualObject]. fullList addAll: objectsReferredToByTiles]]]. ^ playerList _ (fullList asSet asSortedCollection: [:a :b | a externalName < b externalName]) asArray! ! !TheWorldMenu methodsFor: 'construction' stamp: 'sw 7/18/2004 23:03'! scriptingMenu "Build the authoring-tools menu for the world." ^ self fillIn: (self menu: 'authoring tools...') from: { { 'objects (o)' . { #myWorld . #activateObjectsTool }. 'A searchable source of new objects.'}. nil. "----------" { 'view trash contents' . { #myWorld . #openScrapsBook:}. 'The place where all your trashed morphs go.'}. { 'empty trash can' . { Utilities . #emptyScrapsBook}. 'Empty out all the morphs that have accumulated in the trash can.'}. nil. "----------" { 'new scripting area' . { #myWorld . #detachableScriptingSpace}. 'A window set up for simple scripting.'}. nil. "----------" { 'status of scripts' . {#myWorld . #showStatusOfAllScripts}. 'Lets you view the status of all the scripts belonging to all the scripted objects of the project.'}. { 'summary of scripts' . {#myWorld . #printScriptSummary}. 'Produces a summary of scripted objects in the project, and all of their scripts.'}. { 'browser for scripts' . {#myWorld . #browseAllScriptsTextually}. 'Allows you to view all the scripts in the project in a traditional programmers'' "browser" format'}. nil. { 'gallery of players' . {#myWorld . #galleryOfPlayers}. 'A tool that lets you find out about all the players used in this project'}. " { 'gallery of scripts' . {#myWorld . #galleryOfScripts}. 'Allows you to view all the scripts in the project'}." { 'attempt misc repairs' . {#myWorld . #attemptCleanup}. 'Take measures that may help fix up some things about a faulty or problematical project.'}. { 'remove all viewers' . {#myWorld . #removeAllViewers}. 'Remove all the Viewers from this project.'}. nil. "----------" { 'unlock locked objects' . { #myWorld . #unlockContents}. 'If any items on the world desktop are currently locked, unlock them.'}. { 'unhide hidden objects' . { #myWorld . #showHiders}. 'If any items on the world desktop are currently hidden, make them visible.'}. }! ! !ThumbnailForAllPlayersTool methodsFor: 'stepping' stamp: 'sw 7/28/2004 22:23'! step "periodic action" | aMorph | ((aMorph _ objectToView costume) notNil and: [aMorph isInWorld]) ifTrue: [super step] "don't bother changing my readout to blank when/if object disappears"! ! !ThumbnailForAllPlayersTool methodsFor: 'stepping' stamp: 'sw 7/28/2004 22:19'! stepTime "Don't update too aggressively" ^ 2500! ! !UniclassScript methodsFor: 'script editor' stamp: 'sw 7/28/2004 18:32'! currentScriptEditor "Answer the currentScriptEditor" ^ currentScriptEditor! ! "Postscript:" ScriptingSystem saveForm: (Form extent: 16@16 depth: 16 fromArray: #( 0 0 1 65537 65537 65536 0 0 0 1 66559 67044351 67044351 67043329 65536 0 0 66559 67044351 67044351 67044351 67044351 67043329 0 1 67044351 67044351 67044351 67044351 67044351 67044351 65536 1 67044351 67043329 65537 65537 66559 67044351 65536 66559 67043329 65537 67044351 65537 65537 66559 67043329 66559 66559 65537 67043329 65537 65537 67043329 67043329 65537 67044351 65537 65537 65537 65537 67044351 65537 66559 66559 67043329 65537 65537 66559 67043329 67043329 66559 67043329 66559 65537 65537 67043329 66559 67043329 66559 67044351 67043329 65537 65537 66559 67044351 67043329 1 67044351 67044351 67044351 67044351 67044351 67044351 65536 1 67044351 67044351 67044351 67044351 67044351 67044351 65536 0 66559 67044351 67044351 67044351 67044351 67043329 0 0 1 66559 67044351 67044351 67043329 65536 0 0 0 1 65537 65537 65536 0 0) offset: 0@0) atKey: #Viewer. !