=== Top of the Swiki === Attachments ===

Morphic Architecture

This page overviews the architecture of morphic. It's a great place to start before getting into deep pragmatics.



There are three main classes users should know about:
  1. Morph
  2. HandMorph
  3. PasteUpMorph (formerly "WorldMorph")


Class Morph


Morph is the base class of everything that can be displayed in a world and of what you can interact via a hand. If we look at the instance variables, Morphs have bounds and can contain other morphs as submorphs. The morph's own bounds merged with the submorphs' bounds is called fullBounds. As each morph can be a submorph of another morph, it has an owner. Every morph is directly or indirected owned by the world. The only exceptions are morphs picked up by the hand. Their owner is a hand which is not part of the world. Finally, each morph has a color (actually not the best idea) and other attributes which are modelled by the MorphExtension helper class.


Class HandMorph


HandMorph is the class representing a mouse cursor. Morphic supports more than one hand, even hands controlled by other systems, called remote hands, or controlled by an event recorder, a HandMorphForReplay thingy. Normally, there's one primaryHand per world and one activeHand during event processing. There's also the notion of a currentHand but I think, either primary or current but not both makes sense. A hand morph has some 30 instance variables - most of them results of poor refactorings. They hold internal states like time between double clicks or the active popup menu.

Each hand is an event source and you can register yourself for receiving events like mouse down or mouse moved. Normally, the hand automatically interacts with morphs so you don't need to register event handlers. Each hand also knows a keyboard focus, a morph that receives keyStroke events.

Each hand - normally represented by the hardware cursor - can switch to any form it wants and can bear user initials which helps to distinguish different mouse cursors. Actually all images but the primary hand are simulated. There are more instance variables to cache form images and to record damage done by morphs with which to redisplay theirselves while picked up.

Then a hand can send all events via a socket connection to some other remote hand. This code which burdens the already not trivial implementation, should be better factored out.

Finally, a hand controls tool tips (aka bubble help), popup menus and drag and drop. The hand also synthesizes the events it gets from polling during a world display loop.


Class PasteUpMorph


When in morphic, the morph at the top of the ownership hierarchy is called a "world". It is usually a member of class PasteUpMorph. It uses a few helper classes like WorldState or MorphWorldView and the things gets further complicated by the fact that you can have worlds in worlds and starting with 2.9a multiple active worlds. (Actually the whole class is a mess and as Stephane already noticed, it contains a lot of stuff which should better refactored to specialized classes). Looking at the instance variables, we see that a world can have a presenter and a model (I don't understand that) and much other stuff like a background or some not yet working (or agan broken) things like support for hypercard-like stacks. More important are the variables of the world state.

Here we see, that a world knows its hands, bounds and a so called step list which is used to animate morphs which register themselves with the world. Actually each morph is steppable, that is, in periodic time steps, the world automatically calls a #step method which most often leads to drawing that morph.

The world is responsible to displaying it all. Morphs never directly draw themselves but simply post requests for redisplay which are collected by the world, optimized and then performed by calling the morphs' drawOn: methods. The world knows how often this should happen at most. Between each redisplay, all events of all hands are processed.



Other Useful Classes

These three classes are enough to understand Morphic. To build practical applications, though, you need to know a few other morphs too.


A SystemWindow implements a toplevel window that can contain other morhs, typically PluggableMorphs. To implement menus, you don't need morphic but you can use the PopupMenu class and its friends. AlignmentMorph can be used to layout other morphs but it is too limitted right now; many will prefer to use the builtin layout support in SystemWindows, or build something better which is more flexible.


Balloon help

As a final note, to add balloon help to a morph, use the #setBalloonText: method. Try the following example to see how it works:
	World currentHand 
		attachMorph: (RectangleMorph new setBalloonText: 'Testing').