At 20:42 20.06.00 +0200, Stephane Ducasse wrote:
I decided to rejump into the morphic
Brave man ;-)
(without the refactoring browser nearly a nightmare ;)
Well, the current state is not the fault of the tools but of the tool users... even with an refactoring browser you can still forget to refactor or even have the delusion that there'll be time in the future to do a redesign.
So I would like to know what are the most important classes that I should study and relationships.
For a minimal morphic system, you need
o Morph o HandMorph o PasteUpMorph (former WorldMorph)
Morph is the base class of everything that can be displayed in a world and which 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.
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 recoder, a HandMorphForReplay thingy. Normally, there's one primaryHand per world and one activeHand during event processing. There's also the notation 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're more instance variables to cache form images and to record damage done by morphs which what 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.
A PasteUpMorph is a container, called a world, that contains all other morphs and bridges that world and other morphic worlds or the old MVC system. 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 hole 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 registered theirself at 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. Morphs ever directy draw theirselves but simply post request 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.
Actually, these three classes are enough to understand morphic and if they would restrict theirselves on the described functionality, morphic might be quite easy to understand and program. Unfortunately, all code is bloaded with support for scripting and probably also contains quite a few obsolete methods that got lost.
Morphs are the building blocks of morphic but if you want to create UIs, you need to know a few other morphs, too. A SystemWindow implements a toplevel window that can contain other morhs, typically Pluggable<whatever>Morphs. To implement menus, you don't need morphic but you can use the PopupMenu class and its friends. You might want to use an AlignmentMorph to layout other morphs but IMHO that is a faulty design and I'd either stick with the automatic layouting support of SystemWindows or construct a real layout morph with plugable layout algorithms, similar to what Java has.
In fact I really have the impression that Morphic are impacted by the scripting, turtle etoy like stuff.
Unfortunately, yes.
Was it the same in Self?
AFAIK, no.
- Has any morph a player?
No. AFAIK, you don't need them if you don't want to use scripting.
I was wondering if Morph could not be split into two classes: one without extension and etoy related stuff and one with extension.
Probably because everyone at Disney was busily working on their internal projects using the Ur-Morphic like a quarry for code, hacking any change in the system, delaying refactorings. A good design was not goal.
A bit like what people made in VisualWorks were they split the View class into three classes (one with the controller, model).
Actually, separating controller and view isn't that useful, but separating the model is. There are MorphicModels but IMHO they're not obvious to use, and different to what one could expect coming from VisualWorks. It's nothing separated from the View (the morph) but a subclass. Pluggable*Morph thingys have no real models - compared with VisualWorks what I'd call a model. There's no automatic update of the view if you change the model. And without that feature, I don't need that models at all. A MorphicModel again is for scripting support as it can for example automatically generate and compile glue code. Pluggable*Morphs are such models but I think they don't use these features at all.
- What is the difference with a player and an actor state?
Don't know
- Is PasteUpMorph is the class of the current screen when I open a morphic project?
Yes.
if yes (I hope that I understood right) why PasteUpMorph needs to have information about lastTurtlePositions, TurtlePen, TurtleTrails........
eToy
I was thinking that only when we use morphic having player we would need that kind of information.
Sure.
- FormCanvas has a strange classVariable called AA that nobody uses.
It's probably some artifact left over in you image. The current 2.9a doesn't have that variable.
bye -- Stefan Matthias Aust \ Truth Until Paradox