<div id="__MailbirdStyleContent" style="font-size: 10pt;font-family: Arial;color: #000000">
                                        
                                        
                                            
                                        
                                        
                                        -1 :-)<div><br></div><div>I like the idea of improving the code here. However, I disagree with adding more magic into Morph >> #buildDebugMenu:. </div><div><br></div><div>The concept of "debug action" doesn't seem to be a single, tangible concept that morphs have in common. For one morph, "action" could mean #step; for another, it could be #mouseDown:. Maybe both should be made available in a debug menu under certain conditions? Only the receiver can know for sure.</div><div><br></div><div>This is just my opinion. I know that, in a system like Squeak, it is sometimes challenging to decide between such meta programming (i.e., #respondsTo:) and good old subclassing/overrides. :-) In this case, I prefer the latter. It seems to be easier to debug and maintain.</div><div><br></div><div>Best,</div><div>Marcel</div><div><br></div><div><span style="font-size: 13.3333px">P.S.: In buttons and menus, #browseImplementorsOfActions seems unnecessary vague because we know the exact receiver of the action and can thus point to a specific implementation.</span></div><div><span style="font-size: 13.3333px"><br></span></div><div class="mb_sig"></div>
                                        
                                        <blockquote class="history_container" type="cite" style="border-left-style: solid;border-width: 1px;margin-top: 20px;margin-left: 0px;padding-left: 10px;min-width: 500px">
                        <p style="color: #AAAAAA; margin-top: 10px;">Am 01.10.2019 15:08:10 schrieb commits@source.squeak.org <commits@source.squeak.org>:</p><div style="font-family:Arial,Helvetica,sans-serif">A new version of Morphic was added to project The Inbox:<br>http://source.squeak.org/inbox/Morphic-ct.1554.mcz<br><br>==================== Summary ====================<br><br>Name: Morphic-ct.1554<br>Author: ct<br>Time: 1 October 2019, 3:07:47.979339 pm<br>UUID: 39fdea5d-c5bf-f04f-9d4b-5cb0e64a1af0<br>Ancestors: Morphic-ul.1552<br><br>Refactor & extend "browse implementors" entry of Morphic debug menu<br><br>- Introduce common selector #browseImplementorsOfAction and deprecate PluggableButtonMorph>>#browseAllImplementorsOfActionSelector + MenuItemMorph>>#browseAllImplementorsOfRealSelector<br>- Use #respondsTo: check instead of overriding #buildDebugMenu: multiple times<br>- Using the same pattern, introduce #debugAction for PluggableButtonMorph and MenuItemMorph, and add an item for it into the debug menu<br><br>=============== Diff against Morphic-ul.1552 ===============<br><br>Item was changed:<br>+ ----- Method: MenuItemMorph>>browseAllImplementorsOfRealSelector (in category 'debug and other') -----<br>- ----- Method: MenuItemMorph>>browseAllImplementorsOfRealSelector (in category 'browse') -----<br>  browseAllImplementorsOfRealSelector<br>+       self deprecated: 'Use #browseImplementorsOfAction'.<br>+  ^ self browseImplementorsOfAction!<br>-   SystemNavigation default browseAllImplementorsOf: self realSelector localTo: target class!<br><br>Item was added:<br>+ ----- Method: MenuItemMorph>>browseImplementorsOfAction (in category 'debug and other') -----<br>+ browseImplementorsOfAction<br>+ <br>+       SystemNavigation default browseAllImplementorsOf: self realSelector localTo: target class!<br><br>Item was removed:<br>- ----- Method: MenuItemMorph>>buildDebugMenu: (in category 'browse') -----<br>- buildDebugMenu: aHandMorph<br>-     | aMenu |<br>-    aMenu := super buildDebugMenu: aHandMorph.<br>-   aMenu addLine.<br>-       aMenu add: 'implementors of' translated target: self action: #browseAllImplementorsOfRealSelector.<br>-   ^ aMenu!<br><br>Item was added:<br>+ ----- Method: MenuItemMorph>>debugAction (in category 'debug and other') -----<br>+ debugAction<br>+ <br>+       ToolSet debugMethod: (self class lookupSelector: #invoke) forReceiver: self inContext: nil.!<br><br>Item was added:<br>+ ----- Method: MenuItemMorph>>invoke (in category 'debug and other') -----<br>+ invoke<br>+ <br>+     ^ self invokeWithEvent: nil!<br><br>Item was changed:<br>+ ----- Method: MenuItemMorph>>realSelector (in category 'debug and other') -----<br>- ----- Method: MenuItemMorph>>realSelector (in category 'browse') -----<br>  realSelector<br>    selector == #perform:orSendTo: ifTrue: [^arguments first].<br>    ^selector!<br><br>Item was changed:<br>  ----- Method: Morph>>buildDebugMenu: (in category 'debug and other') -----<br>  buildDebugMenu: aHand<br>          "Answer a debugging menu for the receiver.  The hand argument is seemingly historical and plays no role presently"<br>  <br>      | aMenu aPlayer |<br>     aMenu := MenuMorph new defaultTarget: self.<br>   aMenu addStayUpItem.<br>          (self hasProperty: #errorOnDraw) ifTrue:<br>              [aMenu add: 'start drawing again' translated action: #resumeAfterDrawError.<br>           aMenu addLine].<br>       (self hasProperty: #errorOnStep) ifTrue:<br>              [aMenu add: 'start stepping again' translated action: #resumeAfterStepError.<br>                  aMenu addLine].<br>  <br>   aMenu add: 'inspect morph' translated action: #inspectInMorphic:.<br>     aMenu add: 'inspect owner chain' translated action: #inspectOwnerChain.<br>       Smalltalk isMorphic ifFalse:<br>                  [aMenu add: 'inspect morph (in MVC)' translated action: #inspect].<br>  <br>        self isMorphicModel ifTrue:<br>           [aMenu add: 'inspect model' translated target: self model action: #inspect;<br>                   add: 'explore model' translated target: self model action: #explore].<br>         (aPlayer := self player) ifNotNil:<br>            [aMenu add: 'inspect player' translated target: aPlayer action: #inspect].<br>  <br>       aMenu add: 'explore morph' translated target: self selector: #exploreInMorphic:.<br>  <br>   aMenu addLine.<br>        aPlayer ifNotNil:<br>             [ aMenu add: 'viewer for Player' translated target: self player action: #beViewed.<br>    aMenu balloonTextForLastItem: 'Opens a viewer on my Player -- this is the same thing you get if you click on the cyan "View" halo handle' translated ].<br>  <br>         aMenu add: 'viewer for Morph' translated target: self action: #viewMorphDirectly.<br>     aMenu balloonTextForLastItem: 'Opens a Viewer on this Morph, rather than on its Player' translated.<br>   aMenu addLine.<br>  <br>    aPlayer ifNotNil:<br>             [aPlayer class isUniClass ifTrue: [<br>                   aMenu add: 'browse player class' translated target: aPlayer selector: #haveFullProtocolBrowsedShowingSelector: argumentList: #(nil)]].<br>        aMenu add: 'browse morph class' translated target: self selector: #browseHierarchy.<br>   (self isMorphicModel)<br>                 ifTrue: [aMenu<br>                                add: 'browse model class'<br>                             target: self model<br>                            selector: #browseHierarchy].<br>          aMenu addLine.<br>  <br>    self addViewingItemsTo: aMenu.<br>        aMenu <br>                add: 'make own subclass' translated action: #subclassMorph;<br>           add: 'save morph in file' translated  action: #saveOnFile;<br>            addLine;<br>              add: 'call #tempCommand' translated action: #tempCommand;<br>             add: 'define #tempCommand' translated action: #defineTempCommand;<br>             addLine;<br>  <br>                  add: 'control-menu...' translated target: self selector: #invokeMetaMenu:;<br>            add: 'edit balloon help' translated action: #editBalloonHelpText.<br>+    <br>+     ((self respondsTo: #browseImplementorsOfAction) or: [self respondsTo: #debugAction]) ifTrue: [<br>+               aMenu addLine.<br>+               (self respondsTo: #browseImplementorsOfAction) ifTrue: [<br>+                     aMenu add: 'implementors of' translated target: self action: #browseImplementorsOfAction].<br>+           (self respondsTo: #debugAction) ifTrue: [<br>+                    aMenu add: 'debug action' translated target: self action: #debugAction]].<br>+    <br>- <br>          ^ aMenu!<br><br>Item was changed:<br>+ ----- Method: PluggableButtonMorph>>browseAllImplementorsOfActionSelector (in category 'debug and other') -----<br>- ----- Method: PluggableButtonMorph>>browseAllImplementorsOfActionSelector (in category 'browse') -----<br>  browseAllImplementorsOfActionSelector<br>+      self deprecated: 'Use #browseImplementorsOfAction'.<br>+  ^ self browseImplementorsOfAction!<br>-   SystemNavigation default browseAllImplementorsOf: actionSelector localTo: model class!<br><br>Item was added:<br>+ ----- Method: PluggableButtonMorph>>browseImplementorsOfAction (in category 'debug and other') -----<br>+ browseImplementorsOfAction<br>+ <br>+    SystemNavigation default browseAllImplementorsOf: actionSelector localTo: model class!<br><br>Item was removed:<br>- ----- Method: PluggableButtonMorph>>buildDebugMenu: (in category 'browse') -----<br>- buildDebugMenu: aHandMorph<br>-  | aMenu |<br>-    aMenu := super buildDebugMenu: aHandMorph.<br>-   aMenu addLine.<br>-       aMenu add: 'implementors of' translated target: self action: #browseAllImplementorsOfActionSelector.<br>-         ^ aMenu!<br><br>Item was added:<br>+ ----- Method: PluggableButtonMorph>>debugAction (in category 'debug and other') -----<br>+ debugAction<br>+ <br>+        ToolSet debugMethod: (self class lookupSelector: #performAction) forReceiver: self inContext: nil.!<br><br><br></div></blockquote></div>