Controlling menu visibility If there's a public protocol for adding items to the browser menus, people will use it. Since the menus are quite large already, we also implemented methods to control the visibility of menu items. Similar to the enable block that ENVY already offers, we have a visible block. This block is evaluated when the menu is needed, and, depending on the block returning true or false, the menu item will be displayed or not. For the sake of ease of use, we have added "visible" versions of all the standard CwMenu menu hooks. • add:label:enable:toggle:visible:for: • add:label:enable:toggle:visible:for:accelerator:acceleratorText: • add:label:enable:toggle:visible:for:after: • add:label:enable:toggle:visible:for:before: • add:label:enable:visible:for: • add:label:enable:visible:for:after: • add:label:enable:visible:for:before: • add:label:toggle:visible:for: • addSubMenu:label:enable:visible:for: • addSubMenu:label:enable:visible:for:after: • addSubMenu:label:enable:visible:for:before: As an example, let's take a look at a method used in the Refactoring Browser Extensions application supplied in the repository. addToDefaultTextMenu: aMenu browser: aBrowser | block aNode notNil isVariable isMessage | block := aMenu configureBlock. ^aMenu configureBlock: [ block value. aNode := aBrowser findNode. notNil := aNode notNil. isVariable := notNil and: [ aNode isVariable ]. isMessage := notNil and: [ aNode isMessage ] ]; add: #extractMethod label: 'Extract Method' enable: [ aBrowser isOneMethodSelected ] for: aBrowser; addSubMenu: #temporaryMenu label: 'Selection...' enable: true visible: [ isVariable and: [ (aNode whoDefines: aNode name) notNil ] ] for: aBrowser; addSubMenu: #instVarSubMenu label: 'Selection...' enable: true visible: [ isVariable and: [ | cl | (cl := aBrowser selectedClass) notNil and: [ cl allInstVarNames includes: aNode name ] ] ] for: aBrowser; ... addSubMenu: #messageMenu label: 'Selection...' enable: true visible: [ isMessage ] for: aBrowser; ... yourself The reason for using this technique is that the Refactoring Browser itself has context-sensitive submenus in the text pane, which offer different options depending on what text, if any, is selected. VA Smalltalk caches the browser menus upon creating the browser, making dynamic menu changes very difficult. If we look at the code excerpt above, we see that all the necessary submenus are instantiated, but only the submenu with a true #visible: block will be displayed.