Eliot Miranda uploaded a new version of VMMakerUI to project VM Maker: http://source.squeak.org/VMMaker/VMMakerUI-eem.1.mcz ==================== Summary ==================== Name: VMMakerUI-eem.1 Author: eem Time: 22 December 2019, 10:21:35.048794 am UUID: dbfca451-fef5-4248-8f2e-49793e2910f6 Ancestors: Move the Morphic GUI methods to VMMakerUI. Add Marcel's gorgeous CogProcessorAlienInspector. ==================== Snapshot ==================== SystemOrganization addCategory: #'VMMakerUI-SqueakInspectors'! SystemOrganization addCategory: #'VMMakerUI-InterpreterSimulation-Morphic'! Model subclass: #CogProcessorAlienInspector instanceVariableNames: 'cogit coInterpreter objectMemory processor registerSelectors windowTitle registerCache' classVariableNames: '' poolDictionaries: '' category: 'VMMakerUI-SqueakInspectors'! !CogProcessorAlienInspector commentStamp: 'eem 12/22/2019 08:27' prior: 0! A CogProcessorAlienInspector is an inspector for a CogProcessorAlien processor simulator that displays the processor simulator's register state. Instance Variables processor: <CogProcessorAlien> registerCache: <Array of Integer> registerSelectors: <Array of Symbol> windowTitle: <String>! ----- Method: CogProcessorAlienInspector class>>open (in category 'instance creation') ----- open ^ToolBuilder open: (self new processor: (Cogit classPool at: #ProcessorClass) new; yourself)! ----- Method: CogProcessorAlienInspector class>>openFor: (in category 'instance creation') ----- openFor: aCogit ^ToolBuilder open: (self new cogit: aCogit; yourself)! ----- Method: CogProcessorAlienInspector>>bitsPerDigit (in category 'defaults') ----- bitsPerDigit "How to format the register state?" ^ 4! ----- Method: CogProcessorAlienInspector>>buildWith: (in category 'building') ----- buildWith: builder | window registers | window := builder pluggableWindowSpec new. window model: self; label: #windowTitle; extent: 400@200; children: OrderedCollection new. registers := builder pluggableTextSpec new. registers model: self; font: Preferences standardFixedFont; getText: #text; frame: (0@0 corner: 1@1); yourself. window children add: registers. ^(builder build: window) paneColor: coInterpreter windowColorToUse; yourself! ----- Method: CogProcessorAlienInspector>>cogit: (in category 'initialization') ----- cogit: aCogit cogit := aCogit. coInterpreter := cogit coInterpreter. objectMemory := coInterpreter objectMemory. processor := cogit processor. registerSelectors := OrderedCollection withAll: processor registerStateGetters! ----- Method: CogProcessorAlienInspector>>defaultWindowColor (in category 'accessing - ui') ----- defaultWindowColor ^ Color fromString: '#6bca61'! ----- Method: CogProcessorAlienInspector>>digitsPerGroup (in category 'defaults') ----- digitsPerGroup "How to format the register state?" ^ 2! ----- Method: CogProcessorAlienInspector>>evaluateExpression: (in category 'evaluation') ----- evaluateExpression: exp "Callback from text widget after do-it, print-it, inspect-it, etc... The return value will be fed back." | register value | register := (exp asString findTokens: '=') first withBlanksTrimmed asLowercase asSymbol. value := self registerCache at: register. self interpret: register. ^ value! ----- Method: CogProcessorAlienInspector>>initialize (in category 'initialization') ----- initialize super initialize. self registerSelectors: OrderedCollection new. self registerCache: IdentityDictionary new.! ----- Method: CogProcessorAlienInspector>>inspect: (in category 'initialization') ----- inspect: aRegisterSelector self registerSelectors add: aRegisterSelector. self changed: #text.! ----- Method: CogProcessorAlienInspector>>inspectAll: (in category 'initialization') ----- inspectAll: someRegisterSelectors self registerSelectors addAll: someRegisterSelectors. self changed: #text.! ----- Method: CogProcessorAlienInspector>>inspectNone (in category 'initialization') ----- inspectNone self registerSelectors removeAll. self changed: #text.! ----- Method: CogProcessorAlienInspector>>interpret: (in category 'evaluation') ----- interpret: registerSelector "Offer some ways of interpretation." | value options choice | self flag: #updates. "mt: The cache value corresponds maybe to the value at interaction time. In case the register changes quickly and it takes the user some time to make a choice?" value := self registerCache at: registerSelector. options := OrderedDictionary newFrom: { 'Object' -> #interpret:asObject:. 'Stack frame' -> #interpret:asStackFrame:. 'Code address' -> #interpret:asCodeAddress:. 'Integer' -> #interpret:asInteger:. 'Character' -> #interpret:asCharacter:. }. choice := Project uiManager chooseFrom: options keys values: options values title: ('{1} {2}' format: {registerSelector asUppercase. coInterpreter whereIs: value}). choice ifNotNil: [:selector | self perform: selector with: registerSelector with: value]! ----- Method: CogProcessorAlienInspector>>interpret:asCharacter: (in category 'evaluation') ----- interpret: registerSelector asCharacter: registerValue registerValue asCharacter explore.! ----- Method: CogProcessorAlienInspector>>interpret:asCodeAddress: (in category 'evaluation') ----- interpret: registerSelector asCodeAddress: registerValue cogit disassembleCodeAt: registerValue! ----- Method: CogProcessorAlienInspector>>interpret:asInteger: (in category 'evaluation') ----- interpret: registerSelector asInteger: registerValue registerValue explore.! ----- Method: CogProcessorAlienInspector>>interpret:asObject: (in category 'evaluation') ----- interpret: registerSelector asObject: registerValue coInterpreter printOop: registerValue! ----- Method: CogProcessorAlienInspector>>interpret:asStackFrame: (in category 'evaluation') ----- interpret: registerSelector asStackFrame: registerValue coInterpreter printFrame: registerValue! ----- Method: CogProcessorAlienInspector>>interpret:asWhoKnows: (in category 'evaluation') ----- interpret: registerSelector asWhoKnows: registerValue UserDialogBoxMorph inform: (coInterpreter whereIs: registerValue) title: registerSelector! ----- Method: CogProcessorAlienInspector>>pcText (in category 'accessing - ui') ----- pcText ^processor pc hex allButFirst: 3! ----- Method: CogProcessorAlienInspector>>processor (in category 'accessing') ----- processor ^processor! ----- Method: CogProcessorAlienInspector>>processor: (in category 'accessing') ----- processor: aCogProcessorAlien processor := aCogProcessorAlien. registerSelectors := processor registerStateGetters. windowTitle := nil. self changed: #windowTitle.! ----- Method: CogProcessorAlienInspector>>registerAt: (in category 'accessing - ui') ----- registerAt: aRegisterSelector ^ self alien perform: aRegisterSelector! ----- Method: CogProcessorAlienInspector>>registerCache (in category 'accessing') ----- registerCache ^ registerCache! ----- Method: CogProcessorAlienInspector>>registerCache: (in category 'accessing') ----- registerCache: anObject registerCache := anObject.! ----- Method: CogProcessorAlienInspector>>registerSelectors (in category 'accessing') ----- registerSelectors ^ registerSelectors! ----- Method: CogProcessorAlienInspector>>registerSelectors: (in category 'accessing') ----- registerSelectors: anObject registerSelectors := anObject. self changed: #text.! ----- Method: CogProcessorAlienInspector>>registerTextAt: (in category 'accessing - ui') ----- registerTextAt: aRegisterSelector | raw current last text | current := processor perform: aRegisterSelector. last := self registerCache at: aRegisterSelector ifAbsent: []. self registerCache at: aRegisterSelector put: current. raw := String streamContents: [:s | current printOn: s base: (2 raisedTo: self bitsPerDigit) length: processor class wordSize * 8 / self bitsPerDigit padded: true]. text := (String streamContents: [:s | raw groupsOf: self digitsPerGroup atATimeCollect: [:group | s nextPutAll: group; space]]) asText. last ~= current ifTrue: [text addAllAttributes: {TextEmphasis bold. TextColor color: Color salmon}]. ^text! ----- Method: CogProcessorAlienInspector>>stepIn: (in category 'stepping') ----- stepIn: window self changed: #text.! ----- Method: CogProcessorAlienInspector>>stepTimeIn: (in category 'stepping') ----- stepTimeIn: window "The minimum update time in milliseconds." ^500! ----- Method: CogProcessorAlienInspector>>text (in category 'accessing - ui') ----- text ^Text streamContents: [:s | | max exclude fpstate | max := (self registerSelectors ifEmpty: [1] ifNotEmpty: [:selector | (selector collect: #size) max]). s nextPutAll: ('PC' padded: #right to: max with: Character space); nextPutAll: ' = '; nextPutAll: self pcText; cr. exclude := Set new. 1 to: (fpstate := processor floatingPointRegisterStateGetters) size by: 4 do: [:index| ((index to: index + 3) allSatisfy: [:fpri| (processor perform: (fpstate at: fpri)) isZero]) ifTrue: [exclude addAll: (fpstate copyFrom: index to: index + 3)]]. self registerSelectors do: [:selector | (exclude includes: selector) ifFalse: [s nextPutAll: ((selector asUppercase padded: #right to: max with: Character space) asText addAttribute: (PluggableTextAttribute evalBlock: [self interpret: selector])); nextPutAll: ' = '; nextPutAll: (self registerTextAt: selector); cr]]]! ----- Method: CogProcessorAlienInspector>>wantsStepsIn: (in category 'stepping') ----- wantsStepsIn: window ^ true! ----- Method: CogProcessorAlienInspector>>windowTitle (in category 'accessing - ui') ----- windowTitle ^windowTitle ifNil: ['Register State of ', (String streamContents: [:s| processor printNameOn: s])]! ----- Method: CogProcessorAlienInspector>>windowTitle: (in category 'accessing - ui') ----- windowTitle: newTitle windowTitle = newTitle ifTrue: [^ self]. windowTitle := newTitle. self changed: #windowTitle.! Model subclass: #SimulatorMorphicModel instanceVariableNames: 'vm title stepping morph' classVariableNames: '' poolDictionaries: 'EventSensorConstants' category: 'VMMakerUI-InterpreterSimulation-Morphic'! !SimulatorMorphicModel commentStamp: 'eem 7/14/2015 17:07' prior: 0! A SimulatorMorphicModel handles Morphic callbacks and UI for (some parts of ) the simulator. I handle event forwarding management.. Currently, I am a listener to HandMorphs>>addPrimitiveEventListener. I am added as a listener by SimulatorMorph>>displayView (which probably needs to change. tty)! ----- Method: SimulatorMorphicModel class>>initialize (in category 'class initialization') ----- initialize "I want to keep it launchable by script only for now. Eliot has a bunch of options that aren't really feasible for a Morphic first approach. " "self registerWindowColor; registerInOpenMenu; registerInFlaps"! ----- Method: SimulatorMorphicModel class>>on:title:transcript: (in category 'instance creation') ----- on: aStackInterpreterSimulator title: aString transcript: aTranscriptStream | simmodel | simmodel := self new. simmodel vm: aStackInterpreterSimulator; title: aString; transcript: aTranscriptStream. ^simmodel. ! ----- Method: SimulatorMorphicModel class>>registerInFlaps (in category 'class initialization') ----- registerInFlaps " Flaps registerQuad: { #StackInterpreterSimulator. #prototypicalToolWindow. 'StackInterpreter Simulator' translated. 'A Morphic Wrapper for VM Simulations' translated } forFlapNamed: 'Tools' translated. Flaps replaceToolsFlap"! ----- Method: SimulatorMorphicModel class>>registerInOpenMenu (in category 'class initialization') ----- registerInOpenMenu (TheWorldMenu respondsTo: #registerOpenCommand:) ifTrue: [ TheWorldMenu unregisterOpenCommand: 'StackInterpreter Simulator'. TheWorldMenu registerOpenCommand: {'StackInterpreter Simulator'. {self. #open}}]. ! ----- Method: SimulatorMorphicModel class>>unload (in category 'class initialization') ----- unload self unregisterFromOpenMenu; unregisterFromFlaps.! ----- Method: SimulatorMorphicModel class>>unregisterFromFlaps (in category 'class initialization') ----- unregisterFromFlaps "Flaps unregisterQuadsWithReceiver: self; replaceToolsFlap"! ----- Method: SimulatorMorphicModel class>>unregisterFromOpenMenu (in category 'class initialization') ----- unregisterFromOpenMenu (TheWorldMenu respondsTo: #registerOpenCommand:) ifTrue: [TheWorldMenu unregisterOpenCommand: 'StackInterpreter Simulator']. ! ----- Method: SimulatorMorphicModel>>bounds (in category 'accessing') ----- bounds ^morph bounds.! ----- Method: SimulatorMorphicModel>>byteCountText (in category 'user interface') ----- byteCountText ^vm byteCountText! ----- Method: SimulatorMorphicModel>>currentContextStack (in category 'user interface - squeakJS') ----- currentContextStack self flag: 'tty'. ^ 'Current Context Stack' printString asText! ----- Method: SimulatorMorphicModel>>defaultWindowColor (in category 'user interface') ----- defaultWindowColor ^ (Color r: 0.645 g: 1.0 b: 1.0)! ----- Method: SimulatorMorphicModel>>displayForm (in category 'accessing') ----- displayForm ^ vm displayForm! ----- Method: SimulatorMorphicModel>>displayView (in category 'accessing') ----- displayView ^ vm displayView! ----- Method: SimulatorMorphicModel>>displayView: (in category 'accessing') ----- displayView: anImageMorph vm displayView: anImageMorph! ----- Method: SimulatorMorphicModel>>forceInterruptCheck (in category 'buttons callbacks') ----- forceInterruptCheck vm forceInterruptCheck "^UserDialogBoxMorph inform: 'Toggle Transcript' title: 'TODO:'"! ----- Method: SimulatorMorphicModel>>fullDisplayUpdate (in category 'buttons callbacks') ----- fullDisplayUpdate vm fullDisplayUpdate "^UserDialogBoxMorph inform: 'Toggle Transcript' title: 'TODO:'"! ----- Method: SimulatorMorphicModel>>hack (in category 'buttons callbacks') ----- hack UserDialogBoxMorph inform: (morph bounds printString) title: 'Hack:'! ----- Method: SimulatorMorphicModel>>handleListenEvent: (in category 'event-forwarding') ----- handleListenEvent: aMorphicEvent "The SimulatorImageMorph regsitered me (a SimulatorMorphicModel ) with HandMorph>>addEventListener HandMorph then broadcasts events to all registered listeners at this method. See HandMorph>>sendListenPrimitiveEvent " morph ifNotNil: [(SimulatorEventTransformer default degenerateEvent: aMorphicEvent) ifNotNil: [:evtBuf| ((evtBuf at: 1) = EventTypeMouse and: [morph bounds containsPoint: aMorphicEvent position]) ifTrue: [| xtranslated ytranslated | xtranslated := (evtBuf at:3) - (morph bounds left) - 2 . "<--heh" ytranslated := (evtBuf at:4) - (morph bounds top). evtBuf at: 3 put: xtranslated. evtBuf at: 4 put: ytranslated]. vm queueForwardedEvent: evtBuf]]! ----- Method: SimulatorMorphicModel>>help (in category 'buttons callbacks') ----- help "Open up a workspace with explanatory info in it about the StackInterpreterSimulator" Workspace new contents: self helpText; openLabel: self windowTitle, ' Help'.! ----- Method: SimulatorMorphicModel>>helpText (in category 'buttons callbacks') ----- helpText ^(String streamContents: [:str | str nextPutAll: 'Stack Intepreter Simulator Help Contents Go Here.']) translated! ----- Method: SimulatorMorphicModel>>initialExtent (in category 'user interface') ----- initialExtent ^ 1286@938! ----- Method: SimulatorMorphicModel>>initialize (in category 'initialize-release') ----- initialize title := 'StackInterpreter Simulator (Beta))'.! ----- Method: SimulatorMorphicModel>>ioExit (in category 'buttons callbacks') ----- ioExit vm ioExit displayView activeHand removeEventListener: self model. "This is a bug as the user in vm ioExit may have cancelled the confirm t.m." "^UserDialogBoxMorph inform: 'Toggle Transcript' title: 'TODO:'"! ----- Method: SimulatorMorphicModel>>loadImage (in category 'buttons callbacks') ----- loadImage ^UserDialogBoxMorph inform: 'load image' title: 'TODO:'! ----- Method: SimulatorMorphicModel>>morph (in category 'accessing') ----- morph "I need the bounds of my morph for filtering mouse events. If there is a canned way of doing this besides this tight binding to my SimulatorMorph, then please refactor me. see my protocol event-forwarding for the gory details" self flag:'tty'. ^morph.! ----- Method: SimulatorMorphicModel>>morph: (in category 'accessing') ----- morph: aMorph "I need the bounds of my morph for filtering mouse events. If there is a canned way of doing this besides this tight binding to my SimulatorMorph, then please refactor me. see my protocol event-forwarding for the gory details" self flag:'tty'. morph := aMorph.! ----- Method: SimulatorMorphicModel>>onItemClicked: (in category 'user interface - squeakJS') ----- onItemClicked: anItem "I am an item in the current context display on the SqueakJS tree view".! ----- Method: SimulatorMorphicModel>>options (in category 'buttons callbacks') ----- options ^UserDialogBoxMorph inform: 'Options Popup--need checkboxes?' title: 'TODO:'! ----- Method: SimulatorMorphicModel>>over (in category 'buttons callbacks') ----- over stepping:=true. ^UserDialogBoxMorph inform: 'Step Over' title: 'TODO:'! ----- Method: SimulatorMorphicModel>>processesAndContextStack (in category 'user interface - squeakJS') ----- processesAndContextStack "just a stub. see top right panel at http://lively-web.org/users/bert/squeak.html for what I intend to present" self flag: 'tty'. ^ 'Processes and ContextStack' printString asText ! ----- Method: SimulatorMorphicModel>>reset (in category 'buttons callbacks') ----- reset ^UserDialogBoxMorph inform: 'Reset' title: 'TODO:'! ----- Method: SimulatorMorphicModel>>return (in category 'buttons callbacks') ----- return ^UserDialogBoxMorph inform: 'Return' title: 'TODO:'! ----- Method: SimulatorMorphicModel>>run (in category 'buttons callbacks') ----- run stepping:=false. vm run "^UserDialogBoxMorph inform: 'Run' title: 'TODO:'"! ----- Method: SimulatorMorphicModel>>send (in category 'buttons callbacks') ----- send ^UserDialogBoxMorph inform: 'Send' title: 'TODO:'! ----- Method: SimulatorMorphicModel>>specialObjectsAndActiveContext (in category 'user interface - squeakJS') ----- specialObjectsAndActiveContext "just a stub. see top left panel at http://lively-web.org/users/bert/squeak.html for what I intend to present" self flag: 'tty'. ^ 'Special Objects and Active Context' printString asText ! ----- Method: SimulatorMorphicModel>>step (in category 'buttons callbacks') ----- step stepping:=true. ^UserDialogBoxMorph inform: 'Step' title: 'TODO:'! ----- Method: SimulatorMorphicModel>>stepping (in category 'accessing') ----- stepping ^stepping! ----- Method: SimulatorMorphicModel>>stepping: (in category 'accessing') ----- stepping: aBoolean stepping := aBoolean! ----- Method: SimulatorMorphicModel>>title: (in category 'accessing') ----- title: aString title := aString! ----- Method: SimulatorMorphicModel>>toggleTranscript (in category 'buttons callbacks') ----- toggleTranscript vm toggleTranscriptForSimulatorMorph: self transcript. "^UserDialogBoxMorph inform: 'Toggle Transcript' title: 'TODO:'"! ----- Method: SimulatorMorphicModel>>transcript (in category 'accessing') ----- transcript ^vm transcript! ----- Method: SimulatorMorphicModel>>transcript: (in category 'accessing') ----- transcript: aTranscriptStream vm transcript: aTranscriptStream.! ----- Method: SimulatorMorphicModel>>utilitiesMenu: (in category 'user interface') ----- utilitiesMenu: aMenuMorph ^vm utilitiesMenu: aMenuMorph! ----- Method: SimulatorMorphicModel>>vm (in category 'accessing') ----- vm ^vm! ----- Method: SimulatorMorphicModel>>vm: (in category 'accessing') ----- vm: aVMSimulator vm := aVMSimulator! ----- Method: SimulatorMorphicModel>>windowTitle (in category 'user interface') ----- windowTitle ^ title translated! ImageMorph subclass: #SimulatorImageMorph instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: 'VMMakerUI-InterpreterSimulation-Morphic'! !SimulatorImageMorph commentStamp: 'eem 7/15/2015 09:48' prior: 0! A SimulatorImageMorph is an ImageMorph that suppresses halos.! ----- Method: SimulatorImageMorph>>extent: (in category 'geometry') ----- extent: aPoint "Override to restore the default resizing behaviour." ^self perform: #extent: withArguments: {aPoint} inSuperclass: ImageMorph superclass! ----- Method: SimulatorImageMorph>>handleMouseDown: (in category 'event handling') ----- handleMouseDown: anEvent anEvent wasHandled: true! ----- Method: SimulatorImageMorph>>handleMouseEnter: (in category 'event handling') ----- handleMouseEnter: anEvent anEvent wasHandled: true! ----- Method: SimulatorImageMorph>>handleMouseLeave: (in category 'event handling') ----- handleMouseLeave: anEvent ^super handleMouseLeave: anEvent! ----- Method: SimulatorImageMorph>>handleMouseOver: (in category 'event handling') ----- handleMouseOver: anEvent anEvent wasHandled: true! ----- Method: SimulatorImageMorph>>handleMouseUp: (in category 'event handling') ----- handleMouseUp: anEvent anEvent wasHandled: true! ----- Method: SimulatorImageMorph>>handlerForMouseDown: (in category 'event handling') ----- handlerForMouseDown: anEvent "Override all mouse button shenanigans like halos by handling any and all mouse down events." ^self! SystemWindow subclass: #SimulatorMorph instanceVariableNames: 'loadButton helpButton resetButton stepButton overButton sendButton returnButton runButton toggleTranscriptButton optionsButton transcriptPanel commandPanel contextPanel stackPanel callStackPanel displayForm displayView eventEncoder ioExitButton fullDisplayUpdateButton forceInterruptCheckButton hackButton' classVariableNames: '' poolDictionaries: '' category: 'VMMakerUI-InterpreterSimulation-Morphic'! !SimulatorMorph commentStamp: 'eem 7/14/2015 17:06' prior: 0! A SimulatorMorph is a copy of PreferenceBrowserMorph that has been mangled into something that will support the simulator. I provide some UI features inspired by Bert Freudenberg's Lively Squeak VM at http://lively-web.org/users/bert/squeak.html. See class protocol 'documentation' for examples of invoking me. My model is SimulatorMorphicModel. My model has a reference to the Simulator and itermediates all (?) interaction with it. The simulator renders the simulated World on a SimulatorImageMorph that I contain. There is some cruft (tight coupling via direct references along all three layers UI-Model-VM) in me that exists to support Eliot's original Simulator>>openAsMorph functionality and use-case. Rumors that said cruft is an artifact of tty's rudimentary Morphic skills are entirely credible. I hold out the barest glimmer of hope that Bert Freudenberg's SqueakJS functionality can be integrated into my functionality as well. see http://lively-web.org/users/bert/squeak.html for the inspiration. I am not amenable to Flaps or the WorldMenu as there is a lot of pre-run configuration that is done to the Simulator prior to its being run. Managing that ability with a GUI is counter-productive. If said functionality is desired in the future, then inspiration can be gleaned by cut-n-paste from PreferenceBrowser and PreferenceBrowserModel.! ----- Method: SimulatorMorph class>>ttyOne (in category 'documentation') ----- ttyOne "Script tty uses to run the stackIntepreter using this class" | vm | Transcript clear. vm := StackInterpreterSimulator newWithOptions: #(#STACKVM). vm openOn: '/home/tty/usr/src/smalltalk/buildCogDevelopmentImageCog.app/Contents/Resources/targets/Squeak4.5.image'. "vm setBreakSelector: #&." vm openAsSimulatorMorph "; toggleTranscript; halt; run" ! ----- Method: SimulatorMorph class>>withVMSimulator:title:transcript: (in category 'instance creation') ----- withVMSimulator: aSimulatorMorphicModel title: aString transcript: aTranscript ^self new initializeWithVMSimulator: aSimulatorMorphicModel title: aString aTranscript: aTranscript; yourself. ! ----- Method: SimulatorMorph>>basicButton (in category 'submorphs - buttons') ----- basicButton | button | button := SimpleButtonMorph new. button borderWidth: 2; borderColor: #raised; on: #mouseEnter send: #value to: [button borderColor: self paneColor]; on: #mouseLeave send: #value to: [button borderColor: #raised]; vResizing: #spaceFill; useRoundedCorners; clipSubmorphs: true; color: self paneColor muchLighter; target: self model. ^button! ----- Method: SimulatorMorph>>buttonRowLayoutFrame (in category 'submorphs - buttons') ----- buttonRowLayoutFrame ^LayoutFrame fractions: (0@0 corner: 1@0) offsets: (0@0 corner: 0@ (TextStyle defaultFont height * 2.5)) ! ----- Method: SimulatorMorph>>callStackPanel (in category 'submorphs - squeakJS') ----- callStackPanel "If any Morphic gurus exist, please have at it." ^callStackPanel ifNil: [callStackPanel := (PluggableTextMorph on: self model text: #processesAndContextStack accept: nil readSelection: nil menu: nil) hideScrollBarsIndefinitely. callStackPanel color: Color transparent; hResizing: #spaceFill; vResizing: #spaceFill; cellInset: 5; yourself]. ! ----- Method: SimulatorMorph>>commandPanel (in category 'submorphs - simulator panel') ----- commandPanel self flag: 'tty'. "does this hybrid of PreferenceBrowser layout and Simulato openAsMorph stuff make sense?" ^commandPanel ifNil: [commandPanel := (PluggableTextMorph on: self model vm text: #byteCountText accept: nil readSelection: nil menu: #utilitiesMenu:) hideScrollBarsIndefinitely. commandPanel color: Color transparent; hResizing: #spaceFill; vResizing: #spaceFill; cellInset: 5; yourself]. ! ----- Method: SimulatorMorph>>contextPanel (in category 'submorphs - squeakJS') ----- contextPanel "This should show the currentContext and Special Objects array. as seen at SqueakJS Doing that requires real talent. talent tty is lacking at the moment on: [ Array with: (MorphWithSubmorphsWrapper with: self) ] Array with: (ObjectExplorerWrapper with: rootObject name: 'root' model: self parent: nil) " ^contextPanel ifNil: [contextPanel := (SimpleHierarchicalListMorph on: [ Array with: (ObjectExplorerWrapper with: (self model vm) name: 'root' model: (self model vm) parent: nil) ] list: #value selected: nil changeSelected: nil menu: nil keystroke: nil) showScrollBarsOnlyWhenNeeded: true. contextPanel color: Color transparent; hResizing: #spaceFill; vResizing: #spaceFill; cellInset: 5; yourself] ! ----- Method: SimulatorMorph>>displayView (in category 'submorphs - simulator display view') ----- displayView "The VM SImulator draws directly on an imageMorph named displayView displayView is housed on a Form named displayForm displayForm is initialized in StackInterpreterSimulator >> initialize. see StackInterpreterSimulator >>openAsMorph for original constructs." ^displayView ifNil: [displayView := SimulatorImageMorph new image: model vm displayForm. self model displayView: displayView. self model morph: displayView. "<-- N.B.. morph bounds are used to filter events in the model. tty" displayView activeHand addEventListener: self model. displayView color: Color transparent; hResizing: #spaceFill; vResizing: #spaceFill; cellInset: 5; yourself]! ----- Method: SimulatorMorph>>displayViewLayoutFrame (in category 'submorphs - simulator display view') ----- displayViewLayoutFrame | squeakJSFrame buttonFrame simulatorFrame| "if any Morphic guru's understand layouts and offsets, please fix this. tty" buttonFrame := self buttonRowLayoutFrame. squeakJSFrame := self squeakJSRowLayoutFrame. simulatorFrame := self simulatorLayoutFrame. ^LayoutFrame fractions: (0@0 corner: 1@1) offsets: (0@(buttonFrame bottomOffset) corner: simulatorFrame leftOffset@squeakJSFrame topOffset)! ----- Method: SimulatorMorph>>extent: (in category 'geometry') ----- extent: aPoint super extent: aPoint. self fullBounds. ! ----- Method: SimulatorMorph>>forceInterruptCheckButton (in category 'submorphs - buttons') ----- forceInterruptCheckButton self flag: 'tty'. ^forceInterruptCheckButton ifNil: [forceInterruptCheckButton := self basicButton label: 'vm forceInterruptCheck' translated; actionSelector: #forceInterruptCheck; setBalloonText: 'Invoke forceInterruptCheck on Simulator.' translated]! ----- Method: SimulatorMorph>>fullDisplayUpdateButton (in category 'submorphs - buttons') ----- fullDisplayUpdateButton self flag: 'tty'. ^fullDisplayUpdateButton ifNil: [fullDisplayUpdateButton := self basicButton label: 'vm fullDisplayUpdate' translated; actionSelector: #fullDisplayUpdate; setBalloonText: 'Invoke fullDisplayUpdate on Simulator.' translated]! ----- Method: SimulatorMorph>>hackButton (in category 'submorphs - buttons') ----- hackButton self flag: 'tty'. ^hackButton ifNil: [hackButton := self basicButton label: 'Display ImageMorph Bounds' translated; actionSelector: #hack; setBalloonText: 'tty needs a hack button.' translated]! ----- Method: SimulatorMorph>>helpButton (in category 'submorphs - buttons') ----- helpButton ^helpButton ifNil: [helpButton := self basicButton label: 'help' translated; setBalloonText: 'Click here to get some hints on use of me ', 'Panel' translated; actionSelector: #help]! ----- Method: SimulatorMorph>>initializeWithVMSimulator:title:aTranscript: (in category 'initialization') ----- initializeWithVMSimulator: aStackInterpreterSimulator title: aString aTranscript: aTranscript self flag: 'tty'. "need to get the layout right at this point. resizers and scroll bars would be nice. Layout offsets need a gimlet eye as well" self model: (SimulatorMorphicModel on: aStackInterpreterSimulator title: aString transcript: aTranscript); clipSubmorphs: true; setLabel: self model windowTitle; name: aString; addMorph: self newButtonRow fullFrame: self buttonRowLayoutFrame; addMorph: self squeakJSRow fullFrame: self squeakJSRowLayoutFrame; addMorph: self simulatorPanel fullFrame: self simulatorLayoutFrame; addMorph: self displayView fullFrame: self displayViewLayoutFrame. ^self! ----- Method: SimulatorMorph>>ioExitButton (in category 'submorphs - buttons') ----- ioExitButton self flag: 'tty'. ^ioExitButton ifNil: [ioExitButton := self basicButton label: 'vm ioExit' translated; actionSelector: #ioExit; setBalloonText: 'Invoke ioExit on Simulator.' translated]! ----- Method: SimulatorMorph>>loadButton (in category 'submorphs - buttons') ----- loadButton ^loadButton ifNil: [loadButton := self basicButton label: 'Load Image' translated; actionSelector: #loadImage; setBalloonText: 'Select an image to load.' translated]! ----- Method: SimulatorMorph>>newButtonRow (in category 'submorphs - buttons') ----- newButtonRow ^BorderedMorph new color: Color transparent; cellInset: 2; layoutInset: 2; layoutPolicy: TableLayout new; listDirection: #leftToRight; listCentering: #topLeft; cellPositioning: #topLeft; on: #mouseEnter send: #paneTransition: to: self; on: #mouseLeave send: #paneTransition: to: self; addMorphBack: self hackButton; addMorphBack: self newSeparator; " addMorphBack: self resetButton; addMorphBack: self newSeparator; addMorphBack: self forceInterruptCheckButton; addMorphBack: self newSeparator; addMorphBack: self fullDisplayUpdateButton; addMorphBack: self newSeparator; addMorphBack: self toggleTranscriptButton;" addMorphBack: self runButton; addMorphBack: self newSeparator; addMorphBack: self ioExitButton; addMorphBack: self newTransparentFiller; addMorphBack: self stepButton; addMorphBack: self newSeparator; addMorphBack: self overButton; addMorphBack: self newSeparator; addMorphBack: self newSeparator; addMorphBack: self sendButton; addMorphBack: self newSeparator; addMorphBack: self returnButton; addMorphBack: self newTransparentFiller; " addMorphBack: self loadButton; addMorphBack: self newSeparator; addMorphBack: self optionsButton; too complex to implement now. See StackInterpreterSimulator class comment for examples" addMorphBack: self newTransparentFiller; addMorphBack: self helpButton; yourself.! ----- Method: SimulatorMorph>>newSeparator (in category 'submorphs - buttons') ----- newSeparator ^BorderedMorph new borderWidth: 2; borderColor: Color transparent; color: self paneColor; hResizing: #rigid; width: 5; vResizing: #spaceFill; yourself! ----- Method: SimulatorMorph>>newTransparentFiller (in category 'submorphs - buttons') ----- newTransparentFiller ^Morph new color: Color transparent; vResizing: #spaceFill; hResizing: #spaceFill; yourself.! ----- Method: SimulatorMorph>>optionsButton (in category 'submorphs - buttons') ----- optionsButton ^optionsButton ifNil: [optionsButton := self basicButton label: 'VM Options' translated; actionSelector: #options; setBalloonText: 'VM Options.' translated]! ----- Method: SimulatorMorph>>overButton (in category 'submorphs - buttons') ----- overButton ^overButton ifNil: [overButton := self basicButton label: 'Over' translated; actionSelector: #over; setBalloonText: 'Step Over.' translated]! ----- Method: SimulatorMorph>>resetButton (in category 'submorphs - buttons') ----- resetButton ^resetButton ifNil: [resetButton := self basicButton label: 'Reset' translated; actionSelector: #reset; setBalloonText: 'Reset running simulation.' translated]! ----- Method: SimulatorMorph>>returnButton (in category 'submorphs - buttons') ----- returnButton self flag: 'tty'. ^returnButton ifNil: [returnButton := self basicButton label: 'Return' translated; actionSelector: #return; setBalloonText: 'Return from what?.' translated]! ----- Method: SimulatorMorph>>runButton (in category 'submorphs - buttons') ----- runButton self flag: 'tty'. ^runButton ifNil: [runButton := self basicButton label: 'vm run' translated; actionSelector: #run; setBalloonText: 'Run Simulation.' translated]! ----- Method: SimulatorMorph>>sendButton (in category 'submorphs - buttons') ----- sendButton self flag: 'tty'. ^sendButton ifNil: [sendButton := self basicButton label: 'Send' translated; actionSelector: #send; setBalloonText: 'Send what exactly?.' translated]! ----- Method: SimulatorMorph>>simulatorLayoutFrame (in category 'submorphs - simulator panel') ----- simulatorLayoutFrame | squeakJSFrame buttonFrame | "I don't understand offsets in the LayoutFrame. I just fiddled until it looked ok. If anybody knows what they are doing, please refactor." self flag: 'tty'. buttonFrame := self buttonRowLayoutFrame. squeakJSFrame := self squeakJSRowLayoutFrame. ^LayoutFrame fractions: (0.7@0 corner: 1@squeakJSFrame topOffset) offsets: (0@(buttonFrame bottomOffset) corner: 0.70@squeakJSFrame topOffset) ! ----- Method: SimulatorMorph>>simulatorPanel (in category 'submorphs - simulator panel') ----- simulatorPanel "standard controls from StackInterpreterSimulator >> openAsMorph" ^BorderedMorph new color: Color transparent; layoutInset: 10; cellInset: 10; layoutPolicy: TableLayout new; listDirection: #topToBottom; listCentering: #topLeft; cellPositioning: #topLeft; on: #mouseEnter send: #paneTransition: to: self; on: #mouseLeave send: #paneTransition: to: self; addMorphBack: self transcriptPanel; addMorphBack: self commandPanel; yourself.! ----- Method: SimulatorMorph>>squeakJSRow (in category 'submorphs - squeakJS') ----- squeakJSRow "row fo SqueakJS context, stack and call-stack panels" ^BorderedMorph new color: Color blue; cellInset: 2; layoutInset: 2; layoutPolicy: TableLayout new; listDirection: #leftToRight; listCentering: #topLeft; cellPositioning: #topLeft; on: #mouseEnter send: #paneTransition: to: self; on: #mouseLeave send: #paneTransition: to: self; addMorphBack: self callStackPanel; addMorphBack: self contextPanel; addMorphBack: self stackPanel; yourself.! ----- Method: SimulatorMorph>>squeakJSRowLayoutFrame (in category 'submorphs - squeakJS') ----- squeakJSRowLayoutFrame ^LayoutFrame fractions: (0@0.8 corner: 1@1) offsets: (0@0.8 corner: 1@ (TextStyle defaultFont height * 2.5)) ! ----- Method: SimulatorMorph>>stackPanel (in category 'submorphs - squeakJS') ----- stackPanel "If any Morphic gurus exist, please have at it." ^stackPanel ifNil: [stackPanel := (PluggableTextMorph on: self model text: #currentContextStack accept: nil readSelection: nil menu: nil) hideScrollBarsIndefinitely. stackPanel color: Color transparent; hResizing: #spaceFill; vResizing: #spaceFill; cellInset: 5; yourself]. ! ----- Method: SimulatorMorph>>stepButton (in category 'submorphs - buttons') ----- stepButton self flag: 'tty'. ^stepButton ifNil: [stepButton := self basicButton label: 'Step' translated; actionSelector: #step; setBalloonText: 'Step Into.' translated]! ----- Method: SimulatorMorph>>toggleTranscriptButton (in category 'submorphs - buttons') ----- toggleTranscriptButton "tty I dont like this. I have diabled the button" self flag: 'tty'. ^toggleTranscriptButton ifNil: [toggleTranscriptButton := self basicButton label: 'Toggle Transcript' translated; actionSelector: #toggleTranscript; setBalloonText: 'Use External Transcript Instead of Internal.' translated]! ----- Method: SimulatorMorph>>transcriptPanel (in category 'submorphs - simulator panel') ----- transcriptPanel self flag: 'tty'. "does this hybrid of PreferenceBrowser layout and Simulato openAsMorph stuff make sense?" ^transcriptPanel ifNil: [transcriptPanel := (PluggableTextMorph on: self model vm transcript text: nil accept: nil readSelection: nil menu: #codePaneMenu:shifted:). transcriptPanel name: 'transcriptPanel'; color: Color transparent; hResizing: #spaceFill; vResizing: #spaceFill; cellInset: 5; yourself]. ! TestCase subclass: #SimulatorMorphicEventTests instanceVariableNames: '' classVariableNames: '' poolDictionaries: 'EventSensorConstants' category: 'VMMakerUI-InterpreterSimulation-Morphic'! ----- Method: SimulatorMorphicEventTests>>testKeyEventDegeneration (in category 'test event') ----- testKeyEventDegeneration |aMorphicEvent evtBuf type| aMorphicEvent := HandMorph new generateKeyboardEvent: {2 . 0. 0. 0. 0. 0. 0. 0}. evtBuf := SimulatorEventTransformer default degenerateEvent: aMorphicEvent. type := evtBuf at:1. self assert:(type = EventTypeKeyboard). ! ----- Method: SimulatorMorphicEventTests>>testMouseEventDegeneration (in category 'test event') ----- testMouseEventDegeneration |aMorphicEvent evtBuf type| "see class comment in EventSensor browse" aMorphicEvent := HandMorph new generateMouseEvent: {1 . 0. 0. 0. 0. 0. 0. 0}. evtBuf := SimulatorEventTransformer default degenerateEvent: aMorphicEvent. type := evtBuf at:1. self assert:(type = EventTypeMouse). ! ----- Method: SimulatorMorphicEventTests>>testNullEventDegeneration (in category 'test event') ----- testNullEventDegeneration |aMorphicEvent evtBuf type| "Test a bad morphic event returns a null event" "see class comment in EventSensor browse" aMorphicEvent := UserInputEvent new. evtBuf := SimulatorEventTransformer default degenerateEvent: aMorphicEvent. type := evtBuf at:1. self assert:(type = EventTypeNone). ! ----- Method: SimulatorMorphicEventTests>>testSimulatorDisplayViewAccess (in category 'test tight coupling') ----- testSimulatorDisplayViewAccess "There is tight coupling between the morph,model and vm simulator on the simulators displayView variable this test makes sure it is accesible and is an ImageMorph." self assert: ((SystemNavigation allImplementorsOf: #displayView localTo: StackInterpreterSimulator) size = 1). self assert: ((SystemNavigation allImplementorsOf: #displayView: localTo: StackInterpreterSimulator)size = 1). ! ----- Method: SimulatorMorphicEventTests>>testStackInterpreterSimulatorDisplayViewAccess (in category 'test tight coupling') ----- testStackInterpreterSimulatorDisplayViewAccess "There is tight coupling between the morph,model and vm simulator on the simulators displayView variable this test makes sure it is accesible and is an ImageMorph." self assert: ((SystemNavigation allImplementorsOf: #displayView localTo: StackInterpreterSimulator) size = 1). self assert: ((SystemNavigation allImplementorsOf: #displayView: localTo: StackInterpreterSimulator)size = 1). ! ----- Method: CogVMSimulator>>openAsMorph (in category '*VMMakerUI-InterpreterSimulation-Morphic') ----- openAsMorph "Open a morphic view on this simulation." | localImageName borderWidth window | localImageName := imageName ifNotNil: [self localNameFor: imageName] ifNil: [' synthetic image']. window := (SystemWindow labelled: 'Simulation of ', localImageName) model: self. window paneColor: self windowColorToUse. window addMorph: (displayView := SimulatorImageMorph new image: displayForm) frame: (0@0 corner: 1@0.8). displayView activeHand addEventListener: self. eventTransformer := SimulatorEventTransformer new. transcript := TranscriptStream on: (String new: 10000). window addMorph: (PluggableTextMorph on: transcript text: nil accept: nil readSelection: nil menu: #codePaneMenu:shifted:) frame: (0@0.8 corner: 0.7@1). window addMorph: (PluggableTextMorph on: self text: #byteCountText accept: nil readSelection: nil menu: #utilitiesMenu:) hideScrollBarsIndefinitely frame: (0.7@0.8 corner: 1@1). borderWidth := [SystemWindow borderWidth] "Squeak 4.1" on: MessageNotUnderstood do: [:ex| 0]. "3.8" borderWidth := borderWidth + window borderWidth. window openInWorldExtent: (self desiredDisplayExtent + (2 * borderWidth @ borderWidth) + (0@window labelHeight) * (1@(1/0.8))) rounded. ^window! ----- Method: CogVMSimulator>>openAsMorphNoTranscript (in category '*VMMakerUI-InterpreterSimulation-Morphic') ----- openAsMorphNoTranscript "Open a morphic view on this simulation." | localImageName borderWidth window | localImageName := imageName ifNotNil: [self localNameFor: imageName] ifNil: [' synthetic image']. window := (SystemWindow labelled: 'Simulation of ', localImageName) model: self. window paneColor: self windowColorToUse. window addMorph: (displayView := SimulatorImageMorph new image: displayForm) frame: (0@0 corner: 1@0.95). displayView activeHand addEventListener: self. eventTransformer := SimulatorEventTransformer new. window addMorph: (PluggableTextMorph on: self text: #byteCountText accept: nil readSelection: nil menu: #utilitiesMenu:) hideScrollBarsIndefinitely frame: (0@0.95 corner: 1@1). borderWidth := [SystemWindow borderWidth] "Squeak 4.1" on: MessageNotUnderstood do: [:ex| 0]. "3.8" borderWidth := borderWidth + window borderWidth. window openInWorldExtent: (self desiredDisplayExtent + (2 * borderWidth@borderWidth) + (0@window labelHeight) * (1@(1/0.95))) rounded! Object subclass: #SimulatorEventTransformer instanceVariableNames: 'buttons modifiers' classVariableNames: 'Default' poolDictionaries: 'EventSensorConstants' category: 'VMMakerUI-InterpreterSimulation-Morphic'! !SimulatorEventTransformer commentStamp: 'eem 7/14/2015 17:05' prior: 0! A SimulatorEventTransformer takes events as wrapped by HandMorph and converts them to a form a StackInterpreterSimulator can deal with. See HandMorph >> handleEvent to see what the wrapping entails. See HandMorph >> ProcessEvents or EventSensor >> fetchMoreEvents for examples of what an unwrapped event looks like when given to the system for pre-wrapping. Instance Variables ! ----- Method: SimulatorEventTransformer class>>default (in category 'initialize-release') ----- default ^Default ifNil:[Default := self new]! ----- Method: SimulatorEventTransformer class>>eventTypeMouse (in category 'accessing') ----- eventTypeMouse ^EventTypeMouse! ----- Method: SimulatorEventTransformer>>degenerateEvent: (in category 'event transformation') ----- degenerateEvent: aMorphicEvent "tty. Bert had mentioned a distinction between events and polling events and that Morphic could handle both. I don't know what he is talking about." aMorphicEvent isMouse ifTrue: [^self degenerateMouseEvent: aMorphicEvent]. aMorphicEvent isKeyboard ifTrue: [^self degenerateKeyboardEvent: aMorphicEvent]. " type = EventTypeDragDropFiles ifTrue: [evt := self generateDropFilesEvent: evtBuf]. type = EventTypeWindow ifTrue:[evt := self generateWindowEvent: evtBuf]." ^nil! ----- Method: SimulatorEventTransformer>>degenerateEvent:for: (in category 'event transformation') ----- degenerateEvent: aMorphicEvent for: client "Handle ''degenerating'' events for aClient. This interface gets the client to queue the event via queueForwardedEvent:, and may generate more than one event for the input event (i.e. a fake mouse move before a button down), in addition to filtering-out excessive mouse moves." aMorphicEvent isMouse ifTrue: [^self degenerateMouseEvent: aMorphicEvent for: client]. aMorphicEvent isKeyboard ifTrue: [^self degenerateKeyboardEvent: aMorphicEvent for: client]. ^self degenerateUnknownEvent: aMorphicEvent for: client! ----- Method: SimulatorEventTransformer>>degenerateKeyboardEvent: (in category 'event transformation') ----- degenerateKeyboardEvent: aMorphicEvent "see HandMorph>>generateKeyboardEvent and EventSensor class comment" ^{ 2. aMorphicEvent timeStamp. aMorphicEvent keyValue. "<--this is wrong. See Sensor FirstEvt: for what needs to happen. hooo boy" aMorphicEvent type caseOf: { [#keyDown] -> [EventKeyDown]. [#keyUp] -> [EventKeyUp]. [#keystroke] -> [EventKeyChar] }. modifiers. aMorphicEvent keyValue. 0. 0 }! ----- Method: SimulatorEventTransformer>>degenerateKeyboardEvent:for: (in category 'event transformation') ----- degenerateKeyboardEvent: aMorphicEvent for: aClient "Convert the keyboard event into a low-level event for the VM simulator (aClient). See HandMorph>>generateKeyboardEvent and EventSensor class comment" aClient queueForwardedEvent: { 2. aMorphicEvent timeStamp. aMorphicEvent keyValue. "<--this is wrong. See Sensor FirstEvt: for what needs to happen. hooo boy" aMorphicEvent type caseOf: { [#keyDown] -> [EventKeyDown]. [#keyUp] -> [EventKeyUp]. [#keystroke] -> [EventKeyChar] }. modifiers. aMorphicEvent keyValue. 0. self windowIndex }! ----- Method: SimulatorEventTransformer>>degenerateMouseEvent: (in category 'event transformation') ----- degenerateMouseEvent: aMorphicEvent "see HandMorph>>generateMouseEvent" modifiers := aMorphicEvent buttons >> 3. "Sad, but modifiers come in on mouse move events..." aMorphicEvent type == #mouseMove ifTrue: [buttons = 0 ifTrue: [^nil]] "filter-out mouse moves unless buttons are pressed, so simulation doersn't get window leave events when we leave its window" ifFalse: [buttons := aMorphicEvent buttons]. ^{ 1. aMorphicEvent timeStamp. aMorphicEvent position x. aMorphicEvent position y. buttons bitAnd: 7. "thanks Ron T." buttons >> 3. "Thanks dtl" 0. 0 }! ----- Method: SimulatorEventTransformer>>degenerateMouseEvent:for: (in category 'event transformation') ----- degenerateMouseEvent: aMorphicEvent for: aClient "Convert the mouse event into low-level events for the VM simulator (aClient). Filter-out mouse moves, and generate a fake mouse move before each button press. See HandMorph>>generateMouseEvent" | translated | translated := aMorphicEvent position - aClient displayView bounds origin. modifiers := aMorphicEvent buttons >> 3. "Sad, but modifiers come in on mouse move events..." aMorphicEvent type == #mouseMove ifTrue: "filter-out mouse moves unless buttons are pressed, so simulation doesn't get window leave events when we leave its window" [buttons = 0 ifTrue: [^nil]] ifFalse:"If the buttons are going down, make sure to add a mouse move event to the current position before the buttons are pressed." [((buttons bitAnd: 7) = 0 and: [(aMorphicEvent buttons bitAnd: 7) ~= 0]) ifTrue: [aClient queueForwardedEvent: { 1. aMorphicEvent timeStamp. translated x. translated y. 0. buttons >> 3. "Thanks dtl" 0. self windowIndex }]. buttons := aMorphicEvent buttons]. aClient queueForwardedEvent: { 1. aMorphicEvent timeStamp. translated x. translated y. buttons bitAnd: 7. "thanks Ron T." buttons >> 3. "Thanks dtl" 0. self windowIndex }! ----- Method: SimulatorEventTransformer>>initialize (in category 'initialize-release') ----- initialize buttons := modifiers := 0! ----- Method: SimulatorEventTransformer>>windowIndex (in category 'event transformation') ----- windowIndex ^1! Inspector subclass: #VMObjectInspector instanceVariableNames: 'memory coInterpreter objectMemory cogit' classVariableNames: '' poolDictionaries: '' category: 'VMMakerUI-SqueakInspectors'! ----- Method: VMObjectInspector class>>memory:coInterpreter:objectMemory: (in category 'instance creation') ----- memory: aByteArray coInterpreter: aStackInterpreter objectMemory: anObjectMemory ^self new memory: aByteArray coInterpreter: aStackInterpreter objectMemory: anObjectMemory cogit: nil! ----- Method: VMObjectInspector class>>memory:coInterpreter:objectMemory:cogit: (in category 'instance creation') ----- memory: aByteArray coInterpreter: aStackInterpreter objectMemory: anObjectMemory cogit: aCogit ^self new memory: aByteArray coInterpreter: aStackInterpreter objectMemory: anObjectMemory cogit: aCogit! ----- Method: VMObjectInspector>>memory:coInterpreter:objectMemory:cogit: (in category 'initialization') ----- memory: aByteArray coInterpreter: aStackInterpreter objectMemory: anObjectMemory cogit: aCogit memory := aByteArray. coInterpreter := aStackInterpreter. objectMemory := anObjectMemory. cogit := aCogit! ----- Method: StackInterpreterSimulator>>openAsMorph (in category '*VMMakerUI-InterpreterSimulation-Morphic') ----- openAsMorph "Open a morphic view on this simulation." | localImageName borderWidth window | localImageName := imageName ifNotNil: [self localNameFor: imageName] ifNil: [' synthetic image']. window := (SystemWindow labelled: 'Simulation of ', localImageName) model: self. window paneColor: self windowColorToUse. window addMorph: (displayView := SimulatorImageMorph new image: displayForm) frame: (0@0 corner: 1@0.8). displayView activeHand addEventListener: self. eventTransformer := SimulatorEventTransformer new. transcript := TranscriptStream on: (String new: 10000). window addMorph: (PluggableTextMorph on: transcript text: nil accept: nil readSelection: nil menu: #codePaneMenu:shifted:) frame: (0@0.8 corner: 0.7@1). window addMorph: (PluggableTextMorph on: self text: #byteCountText accept: nil readSelection: nil menu: #utilitiesMenu:) hideScrollBarsIndefinitely frame: (0.7@0.8 corner: 1@1). borderWidth := [SystemWindow borderWidth] "Squeak 4.1" on: MessageNotUnderstood do: [:ex| 0]. "3.8" borderWidth := borderWidth + window borderWidth. window openInWorldExtent: (self desiredDisplayExtent + (2 * borderWidth@borderWidth) + (0@window labelHeight) * (1@(1/0.8))) rounded. ^window! ----- Method: StackInterpreterSimulator>>openAsMorphNoTranscript (in category '*VMMakerUI-InterpreterSimulation-Morphic') ----- openAsMorphNoTranscript "Open a morphic view on this simulation." | localImageName borderWidth window | localImageName := imageName ifNotNil: [self localNameFor: imageName] ifNil: [' synthetic image']. window := (SystemWindow labelled: 'Simulation of ', localImageName) model: self. window paneColor: self windowColorToUse. window addMorph: (displayView := SimulatorImageMorph new image: displayForm) frame: (0@0 corner: 1@0.95). displayView activeHand addEventListener: self. eventTransformer := SimulatorEventTransformer new. window addMorph: (PluggableTextMorph on: self text: #byteCountText accept: nil readSelection: nil menu: #utilitiesMenu:) hideScrollBarsIndefinitely frame: (0@0.95 corner: 1@1). borderWidth := [SystemWindow borderWidth] "Squeak 4.1" on: MessageNotUnderstood do: [:ex| 0]. "3.8" borderWidth := borderWidth + window borderWidth. window openInWorldExtent: (self desiredDisplayExtent + (2 * borderWidth@borderWidth) + (0@window labelHeight) * (1@(1/0.95))) rounded! ----- Method: StackInterpreterSimulator>>openAsSimulatorMorph (in category '*VMMakerUI-InterpreterSimulation-Morphic') ----- openAsSimulatorMorph "Open a morphic view on this simulation. ala Bert Freudenberg's SqueakJS http://lively-web.org/users/bert/squeak.html " | localImageName borderWidth window | localImageName := imageName ifNil: [' synthetic image'] ifNotNil: [self localNameFor: imageName]. transcript := TranscriptStream on: (String new: 10000). window := SimulatorMorph withVMSimulator: self title: 'Simulation of ' , localImageName, ' (beta)' transcript: transcript. borderWidth := [SimulatorMorph borderWidth] "Squeak 4.1" on: MessageNotUnderstood do: [:ex | 0]. "3.8" borderWidth := borderWidth + window borderWidth. window openInWorldExtent: (self desiredDisplayExtent + (2 * borderWidth) + (0 @ window labelHeight) * (1 @ (1 / 0.8))) rounded. ^window! |
Free forum by Nabble | Edit this page |