Tx!
On Sat, Feb 3, 2018 at 12:25 AM, Hernán Morales Durand
wrote:
> https://pharo.fogbugz.com/f/cases/21233/Disabling-a-MenuGroupModel-bug
>
>
> 2018-02-02 10:10 GMT-03:00 Hernán Morales Durand :
>> 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
>