Dynamic open menus (was: Re: A summary of a few recent projects)

danielv at netvision.net.il danielv at netvision.net.il
Sat Oct 12 12:52:53 UTC 2002


This is the next installment on a series of summary mails to recent
projects that make Squeak friendly to external packages.

The technical part is simple, since a dynamic open menu is really a
simple, humble thing. A motivating example comes first (skip to the
second ***** line if you already know why this needs to be done).

******** Motivating example
The newcomer to Squeak probably discovers pretty quickly that many of
basic tools of the squeak environment are to be found in the World menu,
open submenu. The class browser, change sorters, file browser, mail
reader, and so forth.

This list is currently maintained as code, in 
TheWorldMenu>>openMenu
        | menu |
        menu _ self menu: 'open...'.
        self fillIn: menu from: {
                {'browser (b)' . { Browser . #openBrowser} }.
...
                {'file list' . {self . #openFileList} }.
...
                {'dual change sorter' . {self . #openChangeSorter2} }.
                nil.
                {'email reader' . {self . #openEmail} }.
                {'web browser' . { Scamper . #openAsMorph} }.
                {'IRC chat' . {self . #openIRC} }.
                nil.
        }.
        self mvcProjectsAllowed ifTrue:
                [self fillIn: menu from: { {'mvc project' . {self.
#openMVCProject} } }].

        ^ self fillIn: menu from: { 
                {'morphic project' . {self. #openMorphicProject} }.
        }.

Now say that contributor Buddha writes a package Dharma. At the moment,
on the instructions to using his package, he will likely have write
something like "After load, evaluate DharmaMorph open". Thus his package
is second class - it will never become one of the first tier of visible
tools, that have a place in the open menu.

Unless he modifies TheWorldMenu>>open.
He can add the line
{'dharma'. {DharmaMorph. #open}}
to that critical open method, and then he's done. When someone loads
Dharma, they'll get his version of TWM>>open. His package has achieved
eternity.

Now suppose Moses writes the package Commandments. He too, will want to
modify TWM>>open, to include The First, The Second, and so forth. 

Except that loading both Dharma and Commandments will create an annoying
conflict - only the last one loaded will actually appear in the open
menu, because only that packages version of TWM>>open will be active.

******** Solution

The solution? to make the TWM>>open method static, and put the knowledge
of which packages are loaded into a collection of some sort.

How does it work?

First, let's load it up. Filein the following -
http://modules.squeakfoundation.org/People/dvf/Packages/DynamicOpenMenu.
2.cs
http://modules.squeakfoundation.org/People/dvf/Packages/SM-Loader.st
http://modules.squeakfoundation.org/People/dvf/Packages/DynamicOpenMenuE
ntries.2.cs

Now open the world menu>open - there, you have a new section, including
Celeste mail reader, IRC Chat, and Package Loader.

Look at TWM>>open, and you will none of those is mentioned there. If you
put a halt in the open method, you can see how the extra applications
are stored.

SM-Loader is only needed because I added it's entry in the third filein.
If you don't have the SqueakMap loaded, it's actually broken. 

So let's remove it. You can do this in the completely ordinary way -
open a browser, find the SMLoader class, remove it. 

Or, to do it manually and see how the list is maintained nice and clean,
do:
3 halt. SMLoader removeFromSystem

Either way, the open menu no longer mentions it.

IRCConnection class>>initialize provides an example of how to arrange
for a class to get added into the open menu as soon as it is filed in.

Of course the proper way to manage this code is to have every tool
register itself, which will be practical if/when a dynamic open menu is
added to the standard image.

A dynamic open menu adds 3 methods, simplifies 1, and removes 1, adding
one class instance variable - not all that big. It then requires 2
methods modified/added per client.

Of course, this is just one place where a list of reference is held in
code, that should be instead updated by packages as they load/are
removed. The Tools flaps come to mind as another, and I'm sure there are
more.

Daniel Vainsencher



More information about the Squeak-dev mailing list