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

Reply via email to