[squeak-dev] menu pragmas (was "The Trunk: Monticello-eem.617.mcz")

H. Hirzel hannes.hirzel at gmail.com
Fri Sep 4 11:29:57 UTC 2015


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 <Das.Linux at gmx.de> wrote:
> Hi all
>
> On 03.09.2015, at 01:21, Craig Latta <craig at netjam.org> 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)
>>
>>
>
>
>


More information about the Squeak-dev mailing list