UX: improve navigation and single-stepping in disassembly view
..by adding actions to context menu. Allow for context menu to be
pinned.
--- a/VDBAbstractListApplication.st Sat Sep 01 14:40:24 2018 +0100
+++ b/VDBAbstractListApplication.st Sat Sep 01 14:44:55 2018 +0100
@@ -367,10 +367,11 @@
delayedInvalidateInternalList
internalListView notNil ifTrue:[
- internalListView scrolledView invalidate.
+ internalListView scrolledView invalidateRepairNow: true
].
"Created: / 06-02-2018 / 12:43:48 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+ "Modified: / 01-09-2018 / 22:24:04 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!
delayedUpdateInternalList
--- a/VDBInstructionListApplication.st Sat Sep 01 14:40:24 2018 +0100
+++ b/VDBInstructionListApplication.st Sat Sep 01 14:44:55 2018 +0100
@@ -13,7 +13,9 @@
VDBAbstractTreeApplication subclass:#VDBInstructionListApplication
instanceVariableNames:'instructionListHolder instructionBasicBlocks
selectedInstructionHolder selectedInstructionBranchTargetAddress
- selectedInstructionBasicBlock frameHolder'
+ selectedInstructionBasicBlock frameHolder
+ canExecStepOverInstructionHolder canExecStepIntoInstructionHolder
+ canExecBackOverInstructionHolder canExecBackIntoInstructionHolder'
classVariableNames:''
poolDictionaries:''
category:'VDB-UI-Others'
@@ -40,6 +42,154 @@
"Created: / 22-06-2018 / 12:25:51 / Jan Vrany <jan.vrany@fit.cvut.cz>"
! !
+!VDBInstructionListApplication class methodsFor:'menu specs'!
+
+contextMenu
+ "This resource specification was automatically generated
+ by the MenuEditor of ST/X."
+
+ "Do not manually edit this!! If it is corrupted,
+ the MenuEditor may not be able to read the specification."
+
+
+ "
+ MenuEditor new openOnClass:VDBInstructionListApplication andSelector:#contextMenu
+ (Menu new fromLiteralArrayEncoding:(VDBInstructionListApplication contextMenu)) startUp
+ "
+
+ <resource: #menu>
+
+ ^
+ #(Menu
+ (
+ (MenuItem
+ label: 'Context Menu Slice'
+ isVisible: true
+ submenuChannel: contextMenuApplSlice
+ isMenuSlice: true
+ )
+ (MenuItem
+ label: 'Item Menu Slice'
+ isVisible: true
+ submenuChannel: contextMenuItemSlice
+ isMenuSlice: true
+ )
+ (MenuItem
+ label: 'Copy Menu Slice'
+ isVisible: true
+ submenuChannel: contextMenuCopySlice
+ isMenuSlice: true
+ )
+ (MenuItem
+ label: '-'
+ isVisible: true
+ )
+ (MenuItem
+ label: 'Inspect Menu Slice'
+ isVisible: true
+ submenuChannel: contextMenuInspectSlice
+ isMenuSlice: true
+ )
+ (MenuItem
+ label: '-'
+ )
+ (MenuItem
+ label: 'Pin Menu'
+ itemValue: doPinMenuAs:item:
+ isVisible: true
+ labelImage: (ResourceRetriever VDBIconLibrary pin 'Pin Menu')
+ argument: 'Disassembly Actions'
+ )
+ )
+ nil
+ nil
+ )
+
+ "Modified: / 01-09-2018 / 14:55:49 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+contextMenuApplSlice
+ "This resource specification was automatically generated
+ by the MenuEditor of ST/X."
+
+ "Do not manually edit this!! If it is corrupted,
+ the MenuEditor may not be able to read the specification."
+
+
+ "
+ MenuEditor new openOnClass:VDBInstructionListApplication andSelector:#contextMenuApplSlice
+ (Menu new fromLiteralArrayEncoding:(VDBInstructionListApplication contextMenuApplSlice)) startUp
+ "
+
+ <resource: #menu>
+
+ ^
+ #(Menu
+ (
+ (MenuItem
+ enabled: canShowCurrentHolder
+ label: 'Show Current Instruction'
+ itemValue: doShowCurrent
+ isVisible: true
+ )
+ (MenuItem
+ enabled: canShowBranchTargetHolder
+ label: 'Show Branch Traget'
+ itemValue: doShowBranchTarget
+ isVisible: true
+ )
+ (MenuItem
+ enabled: canShowSelectionHolder
+ label: 'Show Selection'
+ itemValue: doShowSelection
+ isVisible: true
+ )
+ (MenuItem
+ label: '-'
+ isVisible: true
+ )
+ (MenuItem
+ enabled: canExecStepOverInstructionHolder
+ label: 'Step Over'
+ itemValue: doExecStepOverInstruction
+ isVisible: true
+ labelImage: (ResourceRetriever VDBIconLibrary actionStepOver6x16 'Step Over One Instruction')
+ )
+ (MenuItem
+ enabled: canExecStepIntoInstructionHolder
+ label: 'Step Into'
+ itemValue: doExecStepIntoInstruction
+ isVisible: true
+ labelImage: (ResourceRetriever VDBIconLibrary actionStepInto6x16 'Step Into One Instruction')
+ )
+ (MenuItem
+ label: '-'
+ isVisible: true
+ )
+ (MenuItem
+ enabled: canExecBackOverInstructionHolder
+ label: 'Back Over'
+ itemValue: doExecBackOverInstruction
+ isVisible: true
+ )
+ (MenuItem
+ enabled: canExecBackIntoInstructionHolder
+ label: 'Back Into'
+ itemValue: doExecBackIntoInstruction
+ isVisible: true
+ )
+ (MenuItem
+ label: '-'
+ isVisible: true
+ )
+ )
+ nil
+ nil
+ )
+
+ "Modified: / 01-09-2018 / 22:02:42 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
!VDBInstructionListApplication class methodsFor:'utilities'!
instructions: aCollection title: aString
@@ -235,9 +385,11 @@
!
updateAfterFrameChanged
- self debugger: self frame debugger
+ self debugger: self frame debugger.
+ self updateButtonEnablements.
"Created: / 06-08-2018 / 13:24:28 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+ "Modified: / 01-09-2018 / 22:13:17 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!
updateAfterSelectedInstructionChanged
@@ -265,6 +417,26 @@
"Created: / 26-06-2018 / 11:33:06 / Jan Vrany <jan.vrany@fit.cvut.cz>"
"Modified: / 03-07-2018 / 14:56:10 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+updateButtonEnablements
+ | frame thread threadIsStopped canReverse |
+
+ frame := self frameHolder value.
+ frame notNil ifTrue:[
+ thread := frame thread.
+ ].
+ threadIsStopped := thread notNil and:[ thread isStopped ].
+ canReverse := debugger hasFeature: 'reverse'.
+
+ self canExecStepIntoInstructionHolder value: threadIsStopped.
+ self canExecStepOverInstructionHolder value: threadIsStopped.
+
+ self canExecBackIntoInstructionHolder value: threadIsStopped & canReverse.
+ self canExecBackOverInstructionHolder value: threadIsStopped & canReverse.
+
+ "Created: / 01-09-2018 / 14:49:02 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+ "Modified: / 01-09-2018 / 22:15:00 / Jan Vrany <jan.vrany@fit.cvut.cz>"
! !
!VDBInstructionListApplication methodsFor:'change & update-delayed'!
@@ -326,12 +498,28 @@
!VDBInstructionListApplication methodsFor:'event handling'!
+onCommandResultEvent: aGDBStoppedEvent
+ self updateButtonEnablements
+
+ "Created: / 01-06-2017 / 23:43:00 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+onRunningEvent: aGDBStoppedEvent
+ self updateButtonEnablements
+
+ "Created: / 21-09-2014 / 22:44:16 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+ "Modified: / 01-06-2017 / 23:18:18 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
onStoppedEvent: aGDBStoppedEvent
- self frame notNil ifTrue:[
+ self frame notNil ifTrue:[
+ self frame thread stack. "/ to force update of (cached) frames.
self enqueueDelayedInvalidateInternalList
].
+ self updateButtonEnablements
"Created: / 06-08-2018 / 14:45:03 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+ "Modified: / 01-09-2018 / 22:39:15 / Jan Vrany <jan.vrany@fit.cvut.cz>"
! !
!VDBInstructionListApplication methodsFor:'initialization & release'!
@@ -340,9 +528,159 @@
"Register for debugger events. To be overrided by subclasses"
debugger announcer
- when: GDBStoppedEvent send: #onStoppedEvent: to: self.
+ when: GDBStoppedEvent send: #onStoppedEvent: to: self;
+ when: GDBRunningEvent send: #onRunningEvent: to: self;
+ "/when: GDBExitEvent send: #onExitEvent: to: self;
+ when: GDBCommandResultEvent send: #onCommandResultEvent: to: self.
"Created: / 06-08-2018 / 14:44:10 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+ "Modified: / 01-09-2018 / 14:48:44 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!VDBInstructionListApplication methodsFor:'menu actions'!
+
+doShowBranchTarget
+ | selection |
+
+ selection := self selectedInstructionHolder value.
+ (selection notNil and:[selection isBranch]) ifTrue:[
+ | branchTarget |
+
+ branchTarget := selection branchTarget.
+ "/ For indirect jumps, `branchTarget` is `nil`.
+ branchTarget notNil ifTrue:[
+ self doShowInstructionAtAddress: branchTarget
+ ].
+ ].
+
+ "Modified: / 01-09-2018 / 14:32:39 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+doShowCurrent
+ | frame |
+
+ frame := self frameHolder value.
+ frame notNil ifTrue:[
+ self doShowInstructionAtAddress: frame address
+ ].
+
+ "Modified: / 01-09-2018 / 14:27:58 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+doShowInstructionAtAddress: address
+ self scrollToAddress: address
+
+ "Created: / 01-09-2018 / 14:26:54 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+doShowSelection
+ | selection |
+
+ selection := self selectedInstructionHolder value.
+ selection notNil ifTrue:[
+ self doShowInstructionAtAddress: selection address
+ ].
+
+ "Modified: / 01-09-2018 / 14:32:53 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!VDBInstructionListApplication methodsFor:'menu actions-exec'!
+
+doExec: command
+ debugger send: command andWait: false.
+ self enqueueDelayedInvalidateInternalList
+
+ "Created: / 21-09-2014 / 21:50:19 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+ "Modified: / 26-03-2018 / 17:57:15 / jv"
+ "Modified: / 01-09-2018 / 22:33:06 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+doExecBackIntoInstruction
+ self doExec:(GDBMI_exec_step_instruction arguments:#('--reverse'))
+
+ "Modified: / 01-09-2018 / 22:16:11 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+doExecBackOverInstruction
+ self doExec:(GDBMI_exec_next_instruction arguments:#('--reverse'))
+
+ "Modified: / 01-09-2018 / 22:16:01 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+doExecSteIntoInstruction
+ self doExec:GDBMI_exec_step_instruction new
+
+ "Created: / 01-09-2018 / 22:00:05 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+doExecStepOverInstruction
+ self doExec:GDBMI_exec_next_instruction new
+
+ "Modified: / 01-09-2018 / 21:59:50 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!VDBInstructionListApplication methodsFor:'menu aspects'!
+
+canShowBranchTargetHolder
+ ^ BlockValue
+ with:[ :selection | selection value notNil and:[selection value isBranch and:[selection value branchTarget notNil]]]
+ argument: self selectedInstructionHolder
+
+ "Modified: / 01-09-2018 / 15:32:32 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+canShowCurrentHolder
+ ^ BlockValue
+ with:[ :frame | frame value notNil and:[frame value address notNil ]]
+ argument: self frameHolder
+
+ "Modified: / 01-09-2018 / 15:33:48 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+canShowSelectionHolder
+ ^ BlockValue
+ with:[ :selection | selection value notNil ]
+ argument: self selectedInstructionHolder
+
+ "Modified: / 01-09-2018 / 15:33:20 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!VDBInstructionListApplication methodsFor:'menu aspects-exec'!
+
+canExecBackIntoInstructionHolder
+ canExecBackIntoInstructionHolder isNil ifTrue:[
+ canExecBackIntoInstructionHolder := ValueHolder with: false.
+ ].
+ ^ canExecBackIntoInstructionHolder
+
+ "Modified: / 01-09-2018 / 22:07:33 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+canExecBackOverInstructionHolder
+ canExecBackOverInstructionHolder isNil ifTrue:[
+ canExecBackOverInstructionHolder := ValueHolder with: false.
+ ].
+ ^ canExecBackOverInstructionHolder
+
+ "Modified: / 01-09-2018 / 22:07:52 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+canExecStepIntoInstructionHolder
+ canExecStepOverInstructionHolder isNil ifTrue:[
+ canExecStepOverInstructionHolder := ValueHolder with: false.
+ ].
+ ^ canExecStepOverInstructionHolder
+
+ "Modified: / 01-09-2018 / 22:08:24 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+canExecStepOverInstructionHolder
+ canExecStepOverInstructionHolder isNil ifTrue:[
+ canExecStepOverInstructionHolder := ValueHolder with: false.
+ ].
+ ^ canExecStepOverInstructionHolder
+
+ "Modified: / 01-09-2018 / 22:08:11 / Jan Vrany <jan.vrany@fit.cvut.cz>"
! !
!VDBInstructionListApplication methodsFor:'private'!