Issue #9

 2007-March-04

An update on Morphic 3.0

 

 

My Morphic 3.0 keeps advancing, at a slow pace. I’m not in a hurry, and I’m pretty busy with paid work and other projects. But I think a lot about Morphic, and I do stuff from time to time. If you don’t know what’s all this about, you can check issue 2, issue 3 and issue 5.

 

Recent work

 

I have been working on the conversion of points across owners and submorphs, you can see that MorphicCanvas>>line:to:width:color:in: got a lot smaller, thanks to a better distribution of responsibilities.

 

I also worked on the #bounds and related methods. I removed the fullBounds instance variable in Morph. Now a Morph state only consist of the relevant knowledge a Morph must have. There is no extra, artificial state. Oh, this is nice! And the calculation of the bounds got smaller because I removed a lot of stuff from OldMorph that is non-essential.

 

I also worked on the #containsPoint: method. It is needed, for example, to be able to pick a morph. When looking at the implementation in OldMorph I realized of this. Many (really many!) morphs need to implement it. That’s wrong. A simple morph (for example EllipseMorph) only needs to say how to draw itself. It should only implement #drawOn: . There should be a standard way to see if a point lies inside the morph, inherited from Morph, that should serve most, if not all, subclasses. If it is a bit slow, it doesn’t matter. It is not called that often, basically when selecting a morph. I implemented it using the #shadowForm method. It is simple and general. So my TestMorphs now answer correctly #containsPoint:, and can be picked precisely, even when rotated, etc.

 

There is still a lot to do, but it is getting better!

 

Next steps – Scrolling in Morphic 3.0

 

Perhaps what I’ll do next is about scrolling. This is what I’ve been thinking about this.

 

For this, my objectives are basically the same as always. I want it to be:

- Simple: No “extra” unintuitive objects

- Clear: It must be easy to understand, by exploring with the halos and looking at the code

- Efficient: Only draw what is visible

 

The best way is to have a ScrollingMorph class. It will have a ‘content’ instance variable that will hold a single morph that is scrolled. I.e. the content will be partially visible. The ScrollingMorph will have scroll bars and zoom sliders, and it will control which part or the content will be visible.

 

If no extra state is involved, all the ScrollingMorph can do is to modify somehow the coordinate system and the location of the content. It can’t play with its own coordinate system because that would also affect the scroll bars and zoom sliders.

 

- Alternative 1: Modify the coordinate system of the content. It would be necessary to store somewhere the original coordinate system, and change it for a new one that shows only the visible area. But this would violate the encapsulation of the content. Any morph can assume that only he will change its own coordinate system, and it can do it at will anytime.

 

- Alternative 2: Adjust the location of the content. We must think that the scrolling morph lies on top of the contents, and it has a hole, or window so we can see it. It also moves the content to set the visible part. Thinking this way, scrolling only adjusts centerX and centerY, the position. And zooming modifies the extent. This makes sense. The location of the contents would otherwise be useless. A morph in a scrolling morph can not be moved or zoomed by itself.

 

- Alternative 3: To have some third morph in between. It would adjust its own coordinate system, without touching the contents. The problems with this alternative are that we are adding a third object. We won’t like it when cycling with the halos. And it would be an invisible morph. Something that goes against the old idea that in Morphic every object should be visible.

 

Well, I made my choice. It will be Alternative 2.

 

Something pending is the means for drawing only what is really visible. The first I can think of is a 2nd parameter to #drawOn:, consisting of a clipping rectangle. It is usually nil. In any case, it can safely be ignored. But if a morph wants to use it (a text morph, or a paste up should use it always), then it can avoid drawing stuff and rendering submorphs that would not be visible. The method that draws submorphs should not be reimplemented by subclasses, so this could be easily done for all the morphs.

 

Well, this is all. As always, you can download it. Any comment is welcome. So far I only got some nice words, but what I’d really like is you to play with it, take a look at the code, and send me criticism and suggestions.

 

Juan Vuletich