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.
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!
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