https://pharo.fogbugz.com/f/cases/21233/Disabling-a-MenuGroupModel-bug
2018-02-02 10:10 GMT-03:00 Hernán Morales Durand <hernan.mora...@gmail.com>: > Hi guys, > > If you develop an application window with multiple grouped menu items, > you will certainly be able to enable/disable menu groups at once. > Currently it is not possible with MenuGroupModel (Morphic). > > - A menu (item or group) model manages its state using enabledHolder > instance variable (the enabledHolder is configured in its superclass' > initialize) > -- Being a value holder, one might think there is a propagation of > state (enabled/disabled) changes to subwidgets, but it does not happen > currently. > --- Longer explanation: On static menu building, MenuGroupModel does > not propagate #enable: state changes to its widget because "widget" > i.v. is nil. The reason is a MenuGroupModel #enabled: is evaluated > BEFORE its widget is built. > > How to reproduce: > | mm | > mm := MenuModel new > addGroup: [ :group | > group > addItem: [ :item | > item > name: 'File'; > icon: #openIcon asIcon; > subMenu: (MenuModel new > addGroup: [ : gp | > gp > disable; " <------ HERE we > disable the group " > addItem: [ : it | > it > name: 'Open'; > icon: #openIcon asIcon; > shortcut: $o meta; > action: [ self inform: 'Open' ] ]; > addItem: [ : it | > it > name: 'Save'; > icon: #smallSaveIcon asIcon; > shortcut: $s meta; > action: [ self inform: 'Save' ] ] ]) ] ]; > yourself. > mm extent: 200 @ 100. > mm openWithSpec. > mm inspect. > > (it doesn't matter if #disable is sent after the #addItem: block evaluation) > > - Even after all MenuGroupModel widgets were built, if you try to > disable a menu group dinamically: > > mm menuGroups anyOne menuItems anyOne subMenu menuGroups anyOne disable. > > you would get "Instance of OrderedCollection did not understand > #enabled:" (the widget of a MenuGroupModel is an OrderedCollection!!). > > - However disabling/enabling MenuItemModel works: > > mm menuGroups anyOne menuItems anyOne subMenu menuGroups anyOne > menuItems first disable. > > - MenuItemModel gets actually disabled in the > ToggleMenuItemMorph/UpdatingMenuMorph (#isEnabled:) when the Canvas > draws it. > > - Incredibly, all disabled groups are re-enabled from several places > in the image. > > -- When the menu is clicked, a ToolDockingBarMorph triggers > re-enablement of the MenuMorph in > #removeMatchString/#displayFiltered:. This is presumably the code > triggered when a menu is displayed and you type to filter the menu > items. Something like this: "As initially there is no matchString in > the activeSubMenu, then enable all menu items". Obviously it cleans > disabled items. > > The message flow is: > > DockingBarMorph>>activeSubmenu: -> MenuMorph>>removeMatchString -> > MenuMorph>>displayFiltered: --> m isEnabled: isMatch > > - Another place where menu items are automatically disabled is this flow: > > FormCanvas>>draw: -> ToggleMenuItemMorph>>drawOn: --> > ToggleMenuItemMorph>>isEnabled --> ToggleMenuItemMorph>>isEnabled: !!! > --> MorphicMenuItemAdapter>>enabled (This actually CHANGES the > enabled state on the Model, disconnecting enabled state between the > morph and the model adapter) > > This seem to have multiple paths of resolution. I'm going to propose a > fix that I tested in Pharo 6.1 and Pharo 7. > I don't know yet how to fix the menu search auto-enable on key-press > but would be glad to read a solution to distinguish between both uses. > My idea for now is to have a Morphic property which sets > #doNotAutoReEnableItems. > > However I will open an issue and let people check. > > You can test it with > > " Disable the group " > mm menuGroups anyOne menuItems anyOne subMenu menuGroups anyOne disable. > > " Enable the group " > mm menuGroups anyOne menuItems anyOne subMenu menuGroups anyOne enable. > > Cheers, > > Hernán