Saturday, 17 February 2007

A new GUI builder for Morphic

A few weeks ago I posted a comment to the squeak-dev mailing list bemoaning the current state of UI support in Squeak. My concerns were:

Most of [the many GUI-builders in Squeak] are incomplete, out-of-date, and abandoned; but they show that developers are repeatedly coming back to a need to find an easy way to create and manage a user interface that employs the metaphors that have become familiar to most desktop users. Not a "Windows clone", but perhaps something like Tk or Swing Metal -- familiar enough, but not tied to the platform -- and not requiring extra installation above and beyond the Squeak VM & image.

After looking at the options (and trying unsuccessfully to make prefab usable for me), I gave up! I'm now using Seaside to build the UI for my applications. This isn't a perfect answer, in fact using a complex mix of HTML CSS and JS to replicate a rich client interface is pretty
mad, but it quickly gives me a user interface that is familiar and can be layed out quickly and easily.

If I had access within Squeak to a full set of UI widgets that had a consistent look and feel, were more 'mainstream', and preferably came with builder tools (perhaps Magritte with layout hinting), I'd love to have the power of Morphic under the covers, but as it is, Seaside is
the best game in town.

Well, it looks as though half of my dream has come true! Noury Bouraqadi has published details of his Easy Morphic GUI, which allows you to build up the GUI for a Morphic application, and some of the event handling, using a drag and drop interface. It requires your parent morph to be a subclass of his EMGGuiMorph, but will accept any morphs from the Parts Bin.

This may well inspire me to try to build a few UI elements with a more conventional look and feel.

Friday, 16 February 2007

Sample Image Viewer - a simple SystemWindow application

One of the problems I, and many other beginners, had when coming to Squeak was in building a GUI for my application. There are many half-built and unmaintained GUI builders out there, but most of the core Squeak applications are built manually using SystemWindow. Although these are thought of as self-documenting, I found it difficult to see the wood for the trees when examining them.

My first experiment was to build a simple Image-viewer application, which demonstrates how to build a SystemWindow-based application, how to access the file system and how to interact with the user.

It's packaged up as a Monticello package. If this is not something you've used before, have a look at the Wiki notes page, which gives full instructions on how to download using Monticello.

Wednesday, 14 February 2007

Good (though old) lecture notes on Smalltalk

I've just found a link from the Squeak wiki to a set of lecture notes from Ralph Johnson (one of the Design Patterns "Gang of Four") on Smalltalk (based on VisualWorks, though he has since migrated to Squeak):

The lecture notes are accessible, but the video links aren't as they're copyrighted by the university. If you're interested in finding the videos, you could try searching the squeak beginners' mailing list to find a reference...

Wednesday, 7 February 2007

anObject select: #aMethodName considered harmful

I was browsing some of the Magritte source code, when I saw a message that confused me:
       selectors := anObject class allSelectors
select: #isDescriptionSelector.
I couldn't understand how you could pass a Symbol to #select: instead of a block-- certainly the definition of Collection>>select: implies it should only take a block. But trying it for myself, I saw it worked-- eg
{ 1. 2. 3. 4. } select: #even.
can be used in place of:
{ 1. 2. 3. 4. } select: [ :each | each even ]
Given how much simpler this looks, I was surprised I'd not seen this usage before, and searching for senders of #select: shows that the wordier version seems to be generally preferred. So what's this all about?

A posted a question to the Squeak-Beginners mailing list, and very quickly got some good feedback. Ron Teitelbaum gave a full explanation:
It's a trick. It only works because #value: is implemented on symbol as:
Symbol>>value: anObject
^anObject perform: self.
So the following works too.
#asUppercase value: 'I am a trick'
My suggestion is that you shouldn't follow such tricks. Although I do it too sometimes with things like:
aDictionary at: #foo ifAbsent: nil.
Since nil responds self to #value it seems redundant to me to put the nil in a block so that it can return nil when the block is evaluated with #value. Even though in this case the execution is faster but in the case of sending a symbol to select it is slower.

In both cases it is harder to read so in my opinion it is best to stick with arguments that are expected.
Lukas Renggli-- the author and maintainer of Magritte-- also responded, echoing Ron's comments, and adding that the latest versions of Magritte no longer use this idiom, so this is possibly the first and last place you will ever see this idiom used!

Friday, 2 February 2007

Making sense of it all

I've been playing about with Magritte a bit more over the past couple of days, and I'm beginning to get a better understanding of it - I can build edit-forms and reports now. I can't quite see how readonly views work, but I'm sure I'll crack it eventually...

More impressive (to me anyway) is that I've found a couple of bugs in Squeak!

The Traits-Tests suite of tests leaves lots of classes like anObsoleteClassC3 hanging around very reluctant to leave again. I raised this on the squeak-dev list and was advised to raise it on Mantis (bug reporting tool). So my first Squeak bug has now been created.

I uncovered this issue because the Refactoring Browser started generating messages telling me that "AnObsoleteC3 class does not understand #directlyDefinesMethod". As I wasn't able to solve the underlying problem I fixed the symptoms instead, by amending the RB to ignore obsolete classes. I don't know how useful a fix this is, as the obsolete classes shouldn't be hanging around in such an offensive way, but it's my first Squeak bug-fix, and is now part of the RB codebase.