Hi Peter, On Thu, Aug 10, 2017 at 12:48 AM, Peter Uhnak <i.uhnak@gmail.com> wrote:
Hi Stef,
I use both a variant with an argument and without, however I have slightly modified PragmaMenuBuilder to support this.
e.g. I have
<opEditorToolbarMenu> which always adds entries to a particular menu. <opEditorToolbarMenu: #OPUmlClassEditorPlugin> which adds entries only when some particular context is active (here it would mean that the items are added only when ClassEditor plugin is active)
(The second case can be done with a local if condition, but I found this to be more practical.)
I don't see a benefit in having 'order' as part of the pragma, because you can specify the order for the menu items themselves.
What I am still wondering is whether it is better to have a different pragma for each menu, or have the menu name as an argument. The same goes for differentiating pragmas between different tools.
e.g.
<opEditorToolBarMenu: #OPUmlClassEditorPlugin> vs <menu: #EditorToolbar tool: #OP context: #OPUmlClassEditorPlugin>
I very strongly recommend the latter. Why? If designed appropriately the second form is used as a selector in *building* the menu. So the idea is to have the menu builder perform the pragma to add that item to it. Then there are many menu items in the system that use the same pragma and one can see both senders of the pragma (which are examples of menu extensions) /and/ the implementor(s) (which is an example of how to actually extend a menu). With the former one has to have somewhere that relates a specific menu to the pragma that extends only that menu, a way of extracting that information form that pragma, and finally a way of extending the menu. With the latter there needs be only one version of the code that collects the pragmas for any menu and extends that menu. It becomes a standard library feature.
the latter seems like it's adding more complexity.
But when used in a real system it actually reduces complexity, and provides examples to the user of how to define menu extensions and to implementors of how to extend menus. VisualWorks works like this and has since 1998 when Steve Dahl and I designed the pragma system for just this case. We /did/ add a grouping facility based on floating point numbers, a hack, but a reasonable one. If you look at, say, the standard programming text menu, which at its simplest might be again undo ----------- cut copy paste ----------- do it print it debug it ----------- accept cancel ----------- format spawn explain the grouping of related items is quite important in the menu being easy to navigate. But if we want to extend it we wan to be able to add groups to it. In VW we number the groups in the base menu in tens, so again/undo is 10.0, cut/copy/paste is 20.0, etc. Then anyone can define a new group relative to the base groups by providing a group number such as 35.0 to add between do it/print it/debug it and accept/cancel
Peter
On Wed, Aug 09, 2017 at 09:58:54PM +0200, Stephane Ducasse wrote:
Hi Peter
Yes I was thinking about it. Now from your experience what kind of pragma should we provide?
<group: 'name' order: 10>
Not sure that we need the argument to the group.
<menusForGroup: 'name'>
<menuForGroup: 'name' order: 10>
Stef
On Sun, Aug 6, 2017 at 12:09 AM, Peter Uhnak <i.uhnak@gmail.com> wrote:
Hi Stef,
I faced similar issue and then I've found out that PragmaMenuBuilder is compatible with Spec.
Something like...
builder := PragmaMenuBuilder pragmaKeyword: 'myPragma' model: self. menu := MenuModel new. menu fromSpec: builder menuSpec.
Peter
On Sat, Aug 05, 2017 at 06:26:45PM +0200, Stephane Ducasse wrote:
Hi guys
I would like to know if there is a pattern to build extensible menu in Spec. For example, I extending Epicea to support pillar fileout so that I can turn a coding section into a pillar steps of action.
I wanted to extend the epicea browser to get my menu in: But the code is like that:
EPLogBrowserModel >> addMenuItemsForSelectedItemsIn: aMenu
aMenu addGroup: [ :aGroup | self menuActionsForSelectedItems do: [ :oldStyleMenuItemArray | aGroup addItem: [ :anItem | anItem name: oldStyleMenuItemArray first; description: oldStyleMenuItemArray third; icon: (self iconNamed: oldStyleMenuItemArray fourth); action: [ self perform: oldStyleMenuItemArray second ] ] ] ].
aMenu addGroup: [ :aGroup | aGroup addItem: [ :anItem | anItem name: 'Filters'; icon: (self iconNamed: #smallFindIcon); subMenu: self filtersSubMenu ] ].
aMenu addGroup: [ :aGroup | aGroup addItem: [ :anItem | anItem name: 'File Out'; description: 'Write selected entries to an Ombu file'; icon: (self iconNamed: #smallSaveAsIcon); action: [ self fileOutSelection ] ] ].
EPLogBrowserModel >> menuMorphForSelectedItems
| aMenu | aMenu := MenuModel new. showEntryItemMenu ifTrue: [ self addMenuItemsForSelectedItemsIn: aMenu ]. ^ aMenu buildWithSpecAsPopup
So I would like to improve Epicea but I face the problem of the limits of Spec (presumably). I'm thinking to add a <specMenu: 10> pragma to handle this case. Any thought.
Stef
-- _,,,^..^,,,_ best, Eliot