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):
http://st-www.cs.uiuc.edu/users/johnson/cs497/notes98/online-course.html

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.

Tuesday, 30 January 2007

Useful quickstart for Magritte

Ramon Leon's ever-impressive blog has a great quick screencast introduction to Seaside and Magritte, and reading between the lines, it does appear that the approach that I described in my previous post is the right way to be thinking about the role of Magritte.

Magritte vs Seaside

I'm just starting to experiment with using Magritte and Seaside in Squeak, and it's proving to be interesting if slightly hard going!

I think where I've got to with Magritte is that it's best thought of as a tool for building "edit" screens for objects (a task that it does very effectively under Seaside), but if you're trying to do anything else with your object, then it's back to plain old Seaside!

What I was trying to do was to put Magritte descriptions on an object subclassed from WAComponent, to allow me to use asComponent addValidatedForm to edit the object, but also use renderContentOn: to display the object. However, Magritte relies on a number of introduced messages on Object that WAComponent defines independently.

What I've had to do is introduce a 'wrapper' object to handle the view. This seems a bit cumbersome, but I've had a look at another Seaside/Matisse application — Conrad, a conference attendee management application developed by Stéphane Ducasse — and that appears to be the approach that he took. "Appears to be" as I'm having the usual problem of working out which way is up when looking at new code!