Issue #2

 2006-10-21

Morphic 3.0

 

 

I’m working on a redesign of Morphic in Squeak. I named the project Morphic 3.0, because I consider the Morphic in the Self project to be “Morphic 1.0” and the current in Squeak “Morphic 2.0”.

 

Morphic is great. But it can be enhanced. It also needs cleaning. The original design as it first appeared in Squeak was pretty clean. But as time passed, more and more functionality, applications, and so called “enhancements” were added. Morphic became too big and complicated.

 

Besides, John Maloney himself said each morph should define it’s own coordinate system. Read it in the interview in issue 3 of SqueakNews. BTW, SqueakNews is one of the coolest things ever in the Squeak community. If you haven’t read them, download and enjoy all 5 issues.

 

Also Dan Ingalls when presenting Etoys spoke about “the numerous temporary perturbations it has caused to an otherwise elegant Morphic graphics system”. This was for Squeak 2.0! These perturbations became permanent…

 

My objectives are a bit unusual:

 

*       I want complete independency of Display properties such as size or resolution. That’s what we already have in our printers, isn’t it? I’ve never seen warnings such as “best printed with 1200 dpi” or “minimum resolution 1200x600 dpi”. Postscript is a very old and widely adopted technology. We need something alike for GUIs. Also, the programmer should not need to worry about such details.

 

*       I want to separate the handling of coordinate systems from the morphs themselves. A morph should only need to say “I want to use a log scale”, instead of needing to convert every point it draws to World coordinates himself.

 

*       The Morph hierarchy should not be a hierarchy of shapes. The shapes of an object doesn’t’ need to be constant, and shapes are not that important.

 

*       Class Morph should not include general concepts of color, border, etc. Each morph class decides which are the relevant properties for its instances. The same goes for submorph aligning.

 

The main design ideas for Morphic 3.0 are:

 

*       There is no concept of pixel. The GUI is thought at a higher level. Moving away from pixels to general coordinate systems is like going from bits to objects. All the GUI is independent of pixel resolution. All the rendering is antialiased.

 

*       Every Morph defines a space and coordinate system. Its #drawOn: method and the location of its  submorphs are expressed in its own coordinate system. This idea is from John Maloney, the designer of Morphic 1.0 and 2.0. Class Morph has an instance variable ‘coordinateSystem’ to hold an instance of the MorphicCoordinateSystem hierarchy.

 

*       The coordinate systems are 2D but are not restricted to Cartesian or linear. Useful nonlinear coordinate systems include polar, logarithmic Cartesian, hyperbolic and map-like projections.

 

*       A Morph is placed somewhere in an owner. Class Morph has an instance variable ‘location’ to hold an instance of MorphicLocation. A MorphicLocation specifies a position, extent, and rotation angle expressed in the owner’s coordinate system. Separating them eases the moving, zooming and rotation of morphs. The user can easily move, zoom and rotate morphs. Please note that we are talking about zooming and not resizing.

 

*       In general, morphs are not resizeable. The general operation available to the user is called zooming. The zoom is defined by the extent (width/height) in the location of the morph. The user can modify the location of any morph. However, the size of a morph is defined by its own coordinate system and this is generally not modifiable by the user. If some morph also wants to offer the user the possibility of modifying the coordinate system (an hence the size), it is it’s own responsibility.

 

*       All coordinates are Float numbers. This is good for allowing completely arbitrary scales without significant rounding errors.

 

*       The Morph hierarchy is not a shape hierarchy. Morphs don't have a concept of a border or color. There is no general concept of submorph aligning.

 

*       Old Morphs and new Morphs can live together in a World.

 

Let’s see an example.

 

Suppose we have a music application. The relevant Morphs are the World, a MusicSheetMorph and some NoteMorphs. The World contains the musicSheet. The musicSheet has some notes.

 

The World coordinate system is that of the Display. The musicSheet occupies some area in the world, defined by the user and stored in the musicSheet’s location instance variable.

 

The musicSheet defines a coordinate system where the x axis is time in milliseconds [0..2000] and the y axis is midi note [0..127].

 

The notes have a position in musical coordinates, such as 150mS@56. They also define a coordinateSystem [0..1]x[0..1].

 

Let’s see how the rendering works. The #drawOn: method of the notes asks a MorphicCanvas for drawing services. These calls use coordinates between 0 and 1 for drawing the shape of a musical figure. The canvas uses the note’s coordinateSystem and location to translate them to musical coordinates. Then it uses the musicSheet coordinateSystem and location to translate them from musical coordinates to World coordinates. Then it draws as requested.

 

What’s alredy done:

 

To do this, I needed to start with Morphic 2.0. I took Squeak3.7-5989-basic. Then I removed almost all applications. The result is my Cleaner Squeak image that’s good for study (and doesn’t include any of Morphic 3.0). You can find it here.

 

Then I renamed the Morphic 2.0 Morph hierarchy as OldMorph. Not much of it will remain. However, I’m not redoing PluggableMorphs. This means that browsers and similar applications don’t need to be rewritten.

 

We already have a new Morph, MorphicLocation and CartesianCoordinateSystem classes. Not much of the new design is done, but we can create instances of Morph and subclass TestMorph. The hard work of knowing which OldMorph protocol is needed for a new Morph class is already done. And this protocol is implemented in the new design. This is not trivial: Morph and OldMorph are completely different.

 

You can see TestMorph>>drawOn:. It draws in its own coordinate system, without a mechanism for handling rotation (as in OldPolygonMorph) or an external transformation (as in general flexed OldMorphs), even though both rotation and zooming work ok.

 

Nested morphs are not working correctly yet. But you can download my latest image to play with it.

 

How you can help:

 

I know there is not much to look at, but If you'd like to think a bit on the way to model locations and coordinate systems, and discuss about alternatives, etc., that would be great. I want all this to work with any 2d coordinate systems: Cartesian, Polar, various cartographic, logarithmic, hyperbolic, etc. But will my ideas and design scale? Is there a better way?

 

Juan Vuletich