menu pragmas (was "The Trunk: Monticello-eem.617.mcz")

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

menu pragmas (was "The Trunk: Monticello-eem.617.mcz")

ccrraaiigg

Hi all--

     This is just a new thread to make Eliot's description of menu
pragmas more prominent in the list archives. Perhaps there are others
who, like me, don't read all the "trunk" threads in their entirety and
might miss stuff like this.


     thanks,

-C

***

     Tobias writes to Eliot:

> Can you explain what you want to achieve [with menu pragmas] and how
> I can make [their use] more convenient?

     Eliot responds:

> We can talk this over when we meet in Palo Alto, but the idea is an
> important one, and I'm paying for having been too lazy to write it up
> properly.  Let me try and give a quick sketch here.
>
> The goals are to:
>
> - allow package load to augment menus without the original definitions
>   of those menus knowing anything about the subsequently loaded
>   packages.
> - to allow menus to be augmented with single actions defined in
>   methods that implement those actions
> - and, depending on menu implementation, either
>   - if menus are created every time a user invokes a menu, then to
>     simply include the relevant extensions in the menu
>   - if menus are stored in variables, to automatically construct, or
>     reconstruct the menu when either loading or unloading of a package
>     changes the items in a menu
>
> We design menu pragmas in action methods to specify:

> - the (name of the) menu to be extended
> - the text of the menu entry
> - information regarding what group of items the menu item belongs with
> - information regarding the menu item's relative order with respect to
>   other elements in the group
>
> Rationale:
> With this specification a package can extend any number of menus in
> tools simply by being loaded, with no collisions with any other
> packages defining extensions on those menus.  Tools become freely
> pluggable, and system configurations constructed from different sets
> of loaded packages are decoupled; we don't need many menu
> definitions, just an initial base menu which is extended with the
> current set of extensions.
>
> For this to work we need to "name" menus, and to use some numbering
> scheme to define groups (menu entries between lines) and elements
> within each group.  One simple scheme is to use numbers:
>
> - the definitions of initial base menus number groups, so that the
>   first group (the items before the first line) is numbered group 10,
>   and the second group 20, and so on, allowing extensions to specify
>   new groups by using group numbers that are not a multiple of 10
> - the definitions of entries within groups are numbered, again in
>   multiples of 10, so that the extension can fit anywhere in the
>   group
>
> So given:
>
> MenuMorph fromArray: {
>     {'find...(f)' translated.            #find}.
>     {'find again (g)' translated.        #findAgain}.
>     {'set search string (h)' translated. #setSearchString}.
>     #-.
>     {'do again (j)' translated.          #again}.
>     {'undo (z)' translated.              #undo}.
>     #-.
>     {'copy (c)' translated.              #copySelection}.
>     {'cut (x)' translated.               #cut}.
>     {'paste (v)' translated.             #paste}.
>     {'paste...' translated.              #pasteRecent}.
>     #-.
>     {'set font... (k)' translated.       #offerFontMenu}.
>     {'set style... (K)' translated.      #changeStyle}.
>     {'set alignment...' translated.      #chooseAlignment}.
>     "
>     #-.
>     {'more...' translated.               #shiftedTextPaneMenuRequest}.
>     "
>     }
>
> you could imagine the following numberings:
>
>     10.01    find
>     10.02    findAgain
>     10.03    setSearchString
> -
>     20.01    again
>     20.02    undo
> -
>     30.01    copySelection
>     30.02    cut
>     30.03    paste
>     30.04    pasteRecent
> -
>     40.01    offerFontMenu
>     40.02    changeStyle
>     40.03    chooseAlignment
>
> So I can specify e.g. a new group inserted before the first one by
> using, e.g. 5.005 as an index, and can slot an item between again and
> undo using 20.015, etc.
>
> This gives us menu pragmas that look like:
>
> TextEditor methodsFor: '*SpellChecker-extensions' stamp: 'mad hacker
> 9/9/1999'
> spellCheck
>     <menuAction: #yellowButtonMenu
>      label: 'spell check selection (s)'
>      position: 10.035>
>     ...code implementing spell checking...
>
> (note that the action, #spellCheck, is implicit, it is the selector of
> the method containing the pragma)
>
> and:
>
> - if menus are created every time a user invokes a menu, then search
>   for pragmas within the relevant class hierarchy, compute, sort and
>   insert individual extensions to the menu
> - if menus are stored in variables, to have compilation and method
>   removal send a message to the class to/from which method(s) are
>   added/removed so that the class can recompute menus (as in the line
>   above) when code is added/removed.
>
> What I saw in ChangeSorter was quite different.  It seems to be a way
> of specifying entire menus, and I'm not sure how these menus are to be
> combined.  Maybe I'm misunderstanding the way the scheme is supposed
> to work.  What I've described above is very close to the one that
> pragmas came from in the first place, which was my attempt to
> decouple the components that could be loaded into VisualWorks when we
> decomposed the system into easily loadable parcels.  Up until that
> point VisualWorks had had all its tool menus predefined, disabling
> items that were to do with components delivered as file-ins that
> weren't yet filed-in.  It was too rigid.  It didn't allow for future
> expansion.  And so I had the idea of menu pragmas to decouple
> things.  Steve Dahl then came up with the scheme to define a base
> menu, number its items appropriately, and extend the menu.
>
> One of the things that's really nice about the VisualWorks scheme is
> that the menu pragma itself is actually implemented (remember that
> pragmas are Message instances with literal parameters).  The class
> MenuBuilder (IIRC) implemented various menu pragma methods so the
> pattern is:
>
> - in the method that defines the base menu, define the base menu,
>   create an editor on it, ask the editor to collect the pragmas and
>   augment the menu with those found
> - the menu editor then collects the menu pragmas and then performs
>   each one to collect the information from it
>
> So one can find other menu pragmas using senders, and find the editor
> using implementors, and one can extend the scheme by adding additional
> methods to MenuEditor, again possibly loaded from packages.
>
>
> HTH
>
> _,,,^..^,,,_
> best, Eliot

--
Craig Latta
netjam.org
+31   6 2757 7177 (SMS ok)
+ 1 415  287 3547 (no SMS)


Reply | Threaded
Open this post in threaded view
|

Re: menu pragmas (was "The Trunk: Monticello-eem.617.mcz")

Tobias Pape
Hi all

On 03.09.2015, at 01:21, Craig Latta <[hidden email]> wrote:

>
> Hi all--
>
>     This is just a new thread to make Eliot's description of menu
> pragmas more prominent in the list archives. Perhaps there are others
> who, like me, don't read all the "trunk" threads in their entirety and
> might miss stuff like this.


I read that and I'll comment on all that later.
Still on vacation and on my way to the beach.
Probably tonight (CEST) :)

Best
        -Tobias

>
>
>     thanks,
>
> -C
>
> ***
>
>     Tobias writes to Eliot:
>
>> Can you explain what you want to achieve [with menu pragmas] and how
>> I can make [their use] more convenient?
>
>     Eliot responds:
>
>> We can talk this over when we meet in Palo Alto, but the idea is an
>> important one, and I'm paying for having been too lazy to write it up
>> properly.  Let me try and give a quick sketch here.
>>
>> The goals are to:
>>
>> - allow package load to augment menus without the original definitions
>>  of those menus knowing anything about the subsequently loaded
>>  packages.
>> - to allow menus to be augmented with single actions defined in
>>  methods that implement those actions
>> - and, depending on menu implementation, either
>>  - if menus are created every time a user invokes a menu, then to
>>    simply include the relevant extensions in the menu
>>  - if menus are stored in variables, to automatically construct, or
>>    reconstruct the menu when either loading or unloading of a package
>>    changes the items in a menu
>>
>> We design menu pragmas in action methods to specify:
>
>> - the (name of the) menu to be extended
>> - the text of the menu entry
>> - information regarding what group of items the menu item belongs with
>> - information regarding the menu item's relative order with respect to
>>  other elements in the group
>>
>> Rationale:
>> With this specification a package can extend any number of menus in
>> tools simply by being loaded, with no collisions with any other
>> packages defining extensions on those menus.  Tools become freely
>> pluggable, and system configurations constructed from different sets
>> of loaded packages are decoupled; we don't need many menu
>> definitions, just an initial base menu which is extended with the
>> current set of extensions.
>>
>> For this to work we need to "name" menus, and to use some numbering
>> scheme to define groups (menu entries between lines) and elements
>> within each group.  One simple scheme is to use numbers:
>>
>> - the definitions of initial base menus number groups, so that the
>>  first group (the items before the first line) is numbered group 10,
>>  and the second group 20, and so on, allowing extensions to specify
>>  new groups by using group numbers that are not a multiple of 10
>> - the definitions of entries within groups are numbered, again in
>>  multiples of 10, so that the extension can fit anywhere in the
>>  group
>>
>> So given:
>>
>> MenuMorph fromArray: {
>>    {'find...(f)' translated.            #find}.
>>    {'find again (g)' translated.        #findAgain}.
>>    {'set search string (h)' translated. #setSearchString}.
>>    #-.
>>    {'do again (j)' translated.          #again}.
>>    {'undo (z)' translated.              #undo}.
>>    #-.
>>    {'copy (c)' translated.              #copySelection}.
>>    {'cut (x)' translated.               #cut}.
>>    {'paste (v)' translated.             #paste}.
>>    {'paste...' translated.              #pasteRecent}.
>>    #-.
>>    {'set font... (k)' translated.       #offerFontMenu}.
>>    {'set style... (K)' translated.      #changeStyle}.
>>    {'set alignment...' translated.      #chooseAlignment}.
>>    "
>>    #-.
>>    {'more...' translated.               #shiftedTextPaneMenuRequest}.
>>    "
>>    }
>>
>> you could imagine the following numberings:
>>
>>    10.01    find
>>    10.02    findAgain
>>    10.03    setSearchString
>> -
>>    20.01    again
>>    20.02    undo
>> -
>>    30.01    copySelection
>>    30.02    cut
>>    30.03    paste
>>    30.04    pasteRecent
>> -
>>    40.01    offerFontMenu
>>    40.02    changeStyle
>>    40.03    chooseAlignment
>>
>> So I can specify e.g. a new group inserted before the first one by
>> using, e.g. 5.005 as an index, and can slot an item between again and
>> undo using 20.015, etc.
>>
>> This gives us menu pragmas that look like:
>>
>> TextEditor methodsFor: '*SpellChecker-extensions' stamp: 'mad hacker
>> 9/9/1999'
>> spellCheck
>>    <menuAction: #yellowButtonMenu
>>     label: 'spell check selection (s)'
>>     position: 10.035>
>>    ...code implementing spell checking...
>>
>> (note that the action, #spellCheck, is implicit, it is the selector of
>> the method containing the pragma)
>>
>> and:
>>
>> - if menus are created every time a user invokes a menu, then search
>>  for pragmas within the relevant class hierarchy, compute, sort and
>>  insert individual extensions to the menu
>> - if menus are stored in variables, to have compilation and method
>>  removal send a message to the class to/from which method(s) are
>>  added/removed so that the class can recompute menus (as in the line
>>  above) when code is added/removed.
>>
>> What I saw in ChangeSorter was quite different.  It seems to be a way
>> of specifying entire menus, and I'm not sure how these menus are to be
>> combined.  Maybe I'm misunderstanding the way the scheme is supposed
>> to work.  What I've described above is very close to the one that
>> pragmas came from in the first place, which was my attempt to
>> decouple the components that could be loaded into VisualWorks when we
>> decomposed the system into easily loadable parcels.  Up until that
>> point VisualWorks had had all its tool menus predefined, disabling
>> items that were to do with components delivered as file-ins that
>> weren't yet filed-in.  It was too rigid.  It didn't allow for future
>> expansion.  And so I had the idea of menu pragmas to decouple
>> things.  Steve Dahl then came up with the scheme to define a base
>> menu, number its items appropriately, and extend the menu.
>>
>> One of the things that's really nice about the VisualWorks scheme is
>> that the menu pragma itself is actually implemented (remember that
>> pragmas are Message instances with literal parameters).  The class
>> MenuBuilder (IIRC) implemented various menu pragma methods so the
>> pattern is:
>>
>> - in the method that defines the base menu, define the base menu,
>>  create an editor on it, ask the editor to collect the pragmas and
>>  augment the menu with those found
>> - the menu editor then collects the menu pragmas and then performs
>>  each one to collect the information from it
>>
>> So one can find other menu pragmas using senders, and find the editor
>> using implementors, and one can extend the scheme by adding additional
>> methods to MenuEditor, again possibly loaded from packages.
>>
>>
>> HTH
>>
>> _,,,^..^,,,_
>> best, Eliot
>
> --
> Craig Latta
> netjam.org
> +31   6 2757 7177 (SMS ok)
> + 1 415  287 3547 (no SMS)
>
>


Reply | Threaded
Open this post in threaded view
|

Re: menu pragmas (was "The Trunk: Monticello-eem.617.mcz")

Hannes Hirzel
I saved the proposal here

   http://wiki.squeak.org/squeak/6210

until there is time for discussion. It is also advisable to check what
Pharo has been doing and what is planned in Cuis.

--Hannes

On 9/3/15, Tobias Pape <[hidden email]> wrote:

> Hi all
>
> On 03.09.2015, at 01:21, Craig Latta <[hidden email]> wrote:
>
>>
>> Hi all--
>>
>>     This is just a new thread to make Eliot's description of menu
>> pragmas more prominent in the list archives. Perhaps there are others
>> who, like me, don't read all the "trunk" threads in their entirety and
>> might miss stuff like this.
>
>
> I read that and I'll comment on all that later.
> Still on vacation and on my way to the beach.
> Probably tonight (CEST) :)
>
> Best
> -Tobias
>
>>
>>
>>     thanks,
>>
>> -C
>>
>> ***
>>
>>     Tobias writes to Eliot:
>>
>>> Can you explain what you want to achieve [with menu pragmas] and how
>>> I can make [their use] more convenient?
>>
>>     Eliot responds:
>>
>>> We can talk this over when we meet in Palo Alto, but the idea is an
>>> important one, and I'm paying for having been too lazy to write it up
>>> properly.  Let me try and give a quick sketch here.
>>>
>>> The goals are to:
>>>
>>> - allow package load to augment menus without the original definitions
>>>  of those menus knowing anything about the subsequently loaded
>>>  packages.
>>> - to allow menus to be augmented with single actions defined in
>>>  methods that implement those actions
>>> - and, depending on menu implementation, either
>>>  - if menus are created every time a user invokes a menu, then to
>>>    simply include the relevant extensions in the menu
>>>  - if menus are stored in variables, to automatically construct, or
>>>    reconstruct the menu when either loading or unloading of a package
>>>    changes the items in a menu
>>>
>>> We design menu pragmas in action methods to specify:
>>
>>> - the (name of the) menu to be extended
>>> - the text of the menu entry
>>> - information regarding what group of items the menu item belongs with
>>> - information regarding the menu item's relative order with respect to
>>>  other elements in the group
>>>
>>> Rationale:
>>> With this specification a package can extend any number of menus in
>>> tools simply by being loaded, with no collisions with any other
>>> packages defining extensions on those menus.  Tools become freely
>>> pluggable, and system configurations constructed from different sets
>>> of loaded packages are decoupled; we don't need many menu
>>> definitions, just an initial base menu which is extended with the
>>> current set of extensions.
>>>
>>> For this to work we need to "name" menus, and to use some numbering
>>> scheme to define groups (menu entries between lines) and elements
>>> within each group.  One simple scheme is to use numbers:
>>>
>>> - the definitions of initial base menus number groups, so that the
>>>  first group (the items before the first line) is numbered group 10,
>>>  and the second group 20, and so on, allowing extensions to specify
>>>  new groups by using group numbers that are not a multiple of 10
>>> - the definitions of entries within groups are numbered, again in
>>>  multiples of 10, so that the extension can fit anywhere in the
>>>  group
>>>
>>> So given:
>>>
>>> MenuMorph fromArray: {
>>>    {'find...(f)' translated.            #find}.
>>>    {'find again (g)' translated.        #findAgain}.
>>>    {'set search string (h)' translated. #setSearchString}.
>>>    #-.
>>>    {'do again (j)' translated.          #again}.
>>>    {'undo (z)' translated.              #undo}.
>>>    #-.
>>>    {'copy (c)' translated.              #copySelection}.
>>>    {'cut (x)' translated.               #cut}.
>>>    {'paste (v)' translated.             #paste}.
>>>    {'paste...' translated.              #pasteRecent}.
>>>    #-.
>>>    {'set font... (k)' translated.       #offerFontMenu}.
>>>    {'set style... (K)' translated.      #changeStyle}.
>>>    {'set alignment...' translated.      #chooseAlignment}.
>>>    "
>>>    #-.
>>>    {'more...' translated.               #shiftedTextPaneMenuRequest}.
>>>    "
>>>    }
>>>
>>> you could imagine the following numberings:
>>>
>>>    10.01    find
>>>    10.02    findAgain
>>>    10.03    setSearchString
>>> -
>>>    20.01    again
>>>    20.02    undo
>>> -
>>>    30.01    copySelection
>>>    30.02    cut
>>>    30.03    paste
>>>    30.04    pasteRecent
>>> -
>>>    40.01    offerFontMenu
>>>    40.02    changeStyle
>>>    40.03    chooseAlignment
>>>
>>> So I can specify e.g. a new group inserted before the first one by
>>> using, e.g. 5.005 as an index, and can slot an item between again and
>>> undo using 20.015, etc.
>>>
>>> This gives us menu pragmas that look like:
>>>
>>> TextEditor methodsFor: '*SpellChecker-extensions' stamp: 'mad hacker
>>> 9/9/1999'
>>> spellCheck
>>>    <menuAction: #yellowButtonMenu
>>>     label: 'spell check selection (s)'
>>>     position: 10.035>
>>>    ...code implementing spell checking...
>>>
>>> (note that the action, #spellCheck, is implicit, it is the selector of
>>> the method containing the pragma)
>>>
>>> and:
>>>
>>> - if menus are created every time a user invokes a menu, then search
>>>  for pragmas within the relevant class hierarchy, compute, sort and
>>>  insert individual extensions to the menu
>>> - if menus are stored in variables, to have compilation and method
>>>  removal send a message to the class to/from which method(s) are
>>>  added/removed so that the class can recompute menus (as in the line
>>>  above) when code is added/removed.
>>>
>>> What I saw in ChangeSorter was quite different.  It seems to be a way
>>> of specifying entire menus, and I'm not sure how these menus are to be
>>> combined.  Maybe I'm misunderstanding the way the scheme is supposed
>>> to work.  What I've described above is very close to the one that
>>> pragmas came from in the first place, which was my attempt to
>>> decouple the components that could be loaded into VisualWorks when we
>>> decomposed the system into easily loadable parcels.  Up until that
>>> point VisualWorks had had all its tool menus predefined, disabling
>>> items that were to do with components delivered as file-ins that
>>> weren't yet filed-in.  It was too rigid.  It didn't allow for future
>>> expansion.  And so I had the idea of menu pragmas to decouple
>>> things.  Steve Dahl then came up with the scheme to define a base
>>> menu, number its items appropriately, and extend the menu.
>>>
>>> One of the things that's really nice about the VisualWorks scheme is
>>> that the menu pragma itself is actually implemented (remember that
>>> pragmas are Message instances with literal parameters).  The class
>>> MenuBuilder (IIRC) implemented various menu pragma methods so the
>>> pattern is:
>>>
>>> - in the method that defines the base menu, define the base menu,
>>>  create an editor on it, ask the editor to collect the pragmas and
>>>  augment the menu with those found
>>> - the menu editor then collects the menu pragmas and then performs
>>>  each one to collect the information from it
>>>
>>> So one can find other menu pragmas using senders, and find the editor
>>> using implementors, and one can extend the scheme by adding additional
>>> methods to MenuEditor, again possibly loaded from packages.
>>>
>>>
>>> HTH
>>>
>>> _,,,^..^,,,_
>>> best, Eliot
>>
>> --
>> Craig Latta
>> netjam.org
>> +31   6 2757 7177 (SMS ok)
>> + 1 415  287 3547 (no SMS)
>>
>>
>
>
>