Hi all
I decided to rejump into the morphic (without the refactoring browser nearly a nightmare ;) Everybody should look at that if we want to have a chance to have good good. (if doing a change cost 5 min and you have 10 s may be in 2s you will do it!))
So I would like to know what are the most important classes that I should study and relationships.
For the moment I have: Morph (horrible Blob class) MorphExtension Player?? PasteUpMorph HandMorph
Up until now my view is extremely blurry. I understand how to use pluggableMorph to create widget. I understand that a morph may have an extension that provide extra state. I understand that a world has a worldstate that holds a canvas on which every morph will draws itself.
I try to understand Morphic by looking at class catgerories per categories.
In fact I really have the impression that Morphic are impacted by the scripting, turtle etoy like stuff.
Was it the same in Self? I was dreaming that in Self the model was simpler.
I have a bunch of questions
- Has any morph a player? For example, I have the impression that the pluggableMorph do not have one. When the player is necessary it is hold in the morph extension. I have the impression that the player is only needed for the scripting environment. So or a basic player should be put in the Morphic Kernel or I was wondering if Morph could not be split into two classes: one without extension and etoy related stuff and one with extension.
A bit like what people made in VisualWorks were they split the View class into three classes (one with the controller, model).
- What is the difference with a player and an actor state? I really the impression that actorState has nothing to do with Morph but is just an impact of scripting eToy,
- Is PasteUpMorph is the class of the current screen when I open a morphic project? if yes (I hope that I understood right) why PasteUpMorph needs to have information about lastTurtlePositions, TurtlePen, TurtleTrails........ I was thinking that only when we use morphic having player we would need that kind of information.
- FormCanvas has a strange classVariable called AA that nobody uses.
Stef
Stephane Ducasse wrote:
Hi all
I decided to rejump into the morphic (without the refactoring browser nearly a nightmare ;) Everybody should look at that if we want to have a chance to have good good. (if doing a change cost 5 min and you have 10 s may be in 2s you will do it!))
So I would like to know what are the most important classes that I should study and relationships.
Try eg. RectangleMorph as a reasonably representative, plain vanilla morph, and the 'core' categories of Morph and HandMorph for core functionality. I proposed a couple of months ago that the core of Morphic be purified, especially by separating out all the eToy stuff that is spread all over the place.
For the moment I have: Morph (horrible Blob class)
well then you haven't looked closely at HandMorph ;)
MorphExtension Player?? PasteUpMorph HandMorph
Up until now my view is extremely blurry. I understand how to use pluggableMorph to create widget.
Unfortunately, pluggableMorphs are not very representative, but rather serve for backward compatibility. In general, widgets are not good examples of how Morphic is meant to be used--in fact much the opposite. They have been brought into it as the Smalltalk legacy.
I understand that a morph may have an extension that provide extra state. I understand that a world has a worldstate that holds a canvas on which every morph will draws itself.
I try to understand Morphic by looking at class catgerories per categories.
Good strategy. Unortunately it doesn't work very well here :)
In fact I really have the impression that Morphic are impacted by the scripting, turtle etoy like stuff.
You got that part right :)
Was it the same in Self? I was dreaming that in Self the model was simpler.
I think it was better there--because there was no eToy stuff--all the experimentation that has been done with eToy seems to have left its traces in more than one place.
The dream I have been having is that the eToy stuff would be separated from Morphic to the point of being removable from the image/in a separate namespace. But I don't see it at all in my crystal ball...
I have a bunch of questions
- Has any morph a player?
For example, I have the impression that the pluggableMorph do not have one. When the player is necessary it is hold in the morph extension.
I'd say, forget about players, unless you're in eToy. They're completely eToy-related. I still don't really know what they do :) In fact, my best hint for learning Morphic is to completely disregard the eToy stuff. Now if that was just a little bit easy, since it is so completely intermingled with everything else in all the wrong places...
I have the impression that the player is only needed for the scripting environment. So or a basic player should be put in the Morphic Kernel or I was wondering if Morph could not be split into two classes: one without extension and etoy related stuff and one with extension.
The extension is really a general mechanism used to save memory, by putting rarely used items there. I think this could be done a lot more cleanly in Self by adding slots to any single object.
A bit like what people made in VisualWorks were they split the View class into three classes (one with the controller, model).
- What is the difference with a player and an actor state?
I really the impression that actorState has nothing to do with Morph but is just an impact of scripting eToy,
eToy, eToy, neither are relevant to Morphic in general.
- Is PasteUpMorph is the class of the current screen when I open
a morphic project? if yes (I hope that I understood right) why PasteUpMorph needs to have information about lastTurtlePositions, TurtlePen, TurtleTrails........
Yes, and that's a good question, and that's a good example of what I mean by eToy showing up in all the weirdest places, which is why I think the chance of it being factored out is slim...
As I see it now, no one outside SqC can really even try to do much cleaning up in the core, since it would surely ruin eToy, which would probably reduce its appeal to SqC as an 'improvement' to Squeak. After all, to a major extent, eToy is what SqC is using Squeak for...
Henrik
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
Stefan,
great comments.
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.
I've been thinking a lot about the HandMorph, much because I've had to implement a different (I just barely managed not to write "better :) interaction style, which is _very_ difficult. Refactoring the hand is very difficult since there are loads of gratuitous dependencies in there, esp. wrt eToy. I've now come to think that this could be remedied by introducing an "InteractionStyle" class that the hand delegates event handling to. This is the only reasonable way I see for improving the situation while still not breaking scripting and a lot of other stuff. We'll see how far I get.
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. ...
(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.
There is really little reason why the world would have to be a PasteUpMorph--the functionality you mention is all related to eToy stuff, none relevant for the world as such (as opposed to eg. the worldState et al.). This is a great 'refactoring opportunity'. In fact, it would be interesting to see if a plain generic Morph or similar could be used for the world.
I was wondering if Morph could not be split into two classes: one without extension and etoy related stuff and one with extension.
The MorphExtension is in fact meant to do just this, sort of--it is meant to hold stuff that needn't go into most morphs. Most of these things are _not_ related to scripting/eToy: eg. locking, being sticky, and so on.
Henrik
Stefan Matthias Aust wrote:
Actually, separating controller and view isn't that useful, but separating the model is.
Just now I noticed that this is what MorphicWrappers started for: to supply a [generic then specific] view-controller for every/any object-model in Squeak... And I think they'r good at it. Historical note (not so historical): When we started the MathMorphs course, we created some mathematical objects, and then we wanted them to show up in a morphic World, our first approach was to make Polynomial to be a subclass of Morph, but, after some (not much) time, it started to sound ridiculous, so we moved Polynomial to some better place, and created a wrapper for it, realizing that such a wrapper could be used to place any object in a morphic World. After this, we ended up with a lot of objects living in our World, and then, we wanted to interact with them. It was straight forward to add support for menus showing every message that could be sent to this objects, after this we needed the ability to supply arguments for this messages, so we gave it the ability to receive dropped morphs. But it was not easy to place new morphs/objects in the world, so we tried several different aproaches: first, we used a little workspace where everything you wrote in it got added to the World, we didn't liked it too much, because there were to different context, the Workspaces context and the morphic context... finally we found this type-in-the-air stuff, that is really direct. And it's a closer aproach to real-world object handling.
That's it.
thanks
Modeled Bye! Richie++
--- For a personal reply use gera@core-sdi.com
Stefan Matthias Aust wrote:
Actually, separating controller and view isn't that useful, but separating the model is.
You're kidding! By separating view from controller you get to have a variety of controller classes to do different things with the visual presentation. At the most trivial level this allows you to have read-only and read-write widgets for the same model without the model having to worry about it. You can have controllers that interact via mouse type inputs or key type inputs, or both or neither. You can have controllers that read interactions from a stream and auto-demonstrate an application.
squeak-dev@lists.squeakfoundation.org