<div dir="ltr"><div>Thanks so much for taking the time to reply! See my feedback inline below.</div><div><br></div><div dir="ltr">On Mon, Dec 23, 2024 at 12:47 PM Juan Vuletich <<a href="mailto:juan@cuis.st">juan@cuis.st</a>> wrote:<br></div><div class="gmail_quote gmail_quote_container"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><u></u>
<div bgcolor="#ffffff">
Hi Mark,<br>
<br>
On 12/19/2024 9:56 PM, Mark Volkmann via Cuis-dev wrote:
<blockquote type="cite">
<div dir="ltr">
<div>I've been thinking a lot about the distinctions between
subclassing from Morph, PlacedMorph, and BoxMorph. To me it
seems like the following are the primary distinctions.</div>
<div><br>
</div>
<div>Subclasses of `Morph`:<br>
<br>
- do not have a specified "extent" (size)<br>
- use the coordinate system of their owner (such as a
`WorldMorph`)<br>
For example, if the owner is scaled by a factor of 2 then
this will be also.<br>
- use a `VectorCanvas`<br>
- if the `drawOn:` method is not overridden, it will fill the
morph with a blue rectangle<br>
that is centered at origin, has a width of 150, and a height
of 140<br>
<br>
Subclasses of `PlacedMorph`<br>
<br>
- do not have a specified "extent" (size)<br>
- use their own local coordinate system<br>
- can be dragged to a new location<br>
- use a `VectorCanvas`<br>
- inherits the `drawOn:` method defined in its superclass
`Morph`<br>
<br>
Subclasses of `BoxMorph`:<br>
<br>
- have an "extent" (size) specified by their `defaultExtent`
method which defaults to `50@40`<br>
- use a `HybridCanvas` by default, but will use a
`VectorCanvas`</div>
<div> if their `requiresVectorCanvas` method returns `true`<br>
- if the `drawOn:` method is not overridden, it will fill the
morph with a light green rectangle<br>
- automatically clips its contents to its extent<br>
(major difference between this class and the previous two!)<br>
</div>
<div><br>
</div>
<div>While there is nothing wrong with the class comment for
`BoxMorph`, I think it would be good to emphasize that what
you choose to draw inside it doesn't need to be "rectangular".
It seems that the important thing to know is that whatever you
draw will be CLIPPED to a rectangle whose size is specified by
what is returned from the `defaultExtent` method.</div>
<div><br>
</div>
<div>The warning about when we should not subclass from BoxMorph
could say that we should not do that unless we are okay with
the clipping that it provides.</div></div></blockquote>
Ok. Let's test this hypothesis.<br>
<br>
First, let's play a bit with the most basic example morph included
in the system:<br>
evaluate: Sample01Star new openInHand.<br>
You get a star morph. You can drop it anywhere, grab it agan, move
it around. Open the halo. You can scale and rotate it at will. You
can duplicate it, and embed one into the other. Now both are scaled
/ rotated together (if you grab the outer one).<br></div></blockquote><div><br></div><div>This all makes sense to me because Sample01Star is a subclass of PlacedMorph, not just Morph.</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div bgcolor="#ffffff">Now, let's see what happens with BoxMorph, assuming it
"automatically clips its contents to its extent".<br>
Create StarBoxExperiment as subclass of BoxMorph. Copy
Sample01Star>>#drawOn: here<br>
evaluate: StarBoxExperiment new openInHand.<br>
You get what a morph looks like when there is a problem in #drawOn.
You also get a debugger.<br>
Yo are right. Add #requiresVectorCanvas to answer true.<br>
evaluate: StarBoxExperiment new openInHand.<br>
Move the hand around.<br>
You get a lot of drawing artifacts.<br></div></blockquote><div><br></div><div>I see the artifacts. After selecting "Restore Display" from the World menu, I also see that the star seems to be clipped to the rectangle defined by the extent. I think I confirmed that by adding the following to the drawOn: method.</div><div><br></div><font face="monospace">aCanvas strokeWidth: 2 color: Color red do: [<br> aCanvas<br> moveTo: 0 @ 0;<br></font><span style="font-family:monospace"> <span class="gmail-Apple-converted-space"> </span></span><font face="monospace">lineTo: extent x @ 0;<br></font><span style="font-family:monospace"> <span class="gmail-Apple-converted-space"> </span></span><font face="monospace">lineTo: extent x @ extent y;<br></font><span style="font-family:monospace"> <span class="gmail-Apple-converted-space"> </span></span><font face="monospace">lineTo: 0 @ extent y;<br></font><span style="font-family:monospace"> <span class="gmail-Apple-converted-space"> </span></span><font face="monospace">lineTo: 0 @ 0<br> ].</font></div><div class="gmail_quote gmail_quote_container"><font face="monospace"><br></font></div><div class="gmail_quote gmail_quote_container"><font face="arial, sans-serif">That renders the attached screenshot.<br></font><div><br></div><div> Your hypothesis is not correct. The system expects the shape of a
subclass of BoxMorph to be a rectangle confined to (0@0 corner:
extent), as described in the class comment.</div><div><br></div><div>Is it wrong to say that a BoxMorph clips its contents to the rectangle defined by 0@0 and its extent? It seems to do that regardless of what is drawn on the BoxMorph. I think the point you are making is that it is *bad* to draw outside of a BoxMorph (and violates a restriction stated in the class comment) due to the artifacts that appear if the morph is dragged.<span class="gmail-Apple-converted-space"> I understand that now. Thanks for explaining that!</span></div><div><span class="gmail-Apple-converted-space"><br></span></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div bgcolor="#ffffff">Perhaps what could be added to the BoxMorph class comment is that
the framework system expects that behavior, and will break
otherwise.</div></blockquote><div><br></div><div>Where "break" means it will result in drawing artifacts only if the morph is dragged?</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div bgcolor="#ffffff">And that the reason is to allow for simple, high
performance implementation of SystemWindow and other simple
rectangular morphs, where these assumptions mean that the framework
doesn't need to do the extra work for arbitrary shapes to work
correctly.<br></div></blockquote><div><br></div><div>Got it.</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div bgcolor="#ffffff">As a last comment, play with Sample07Clipping. Grab the inner star
with the brown handle and move it around a bit. This will show the
kind of expensive stuff that regular morphs do, but BoxMorphs avoid.<br></div></blockquote><div><br></div><div>Nice! </div><div> </div></div><span class="gmail_signature_prefix">-- </span><br><div dir="ltr" class="gmail_signature"><div dir="ltr"><div><div dir="ltr"><div><div dir="ltr"><div dir="ltr"><div><font face="arial, helvetica, sans-serif">R. Mark Volkmann</font></div><div><span style="font-size:12.8px"><font face="arial, helvetica, sans-serif">Object Computing, Inc.</font></span></div></div></div></div></div></div></div></div></div>