Twiddling a twinkling Star (was: Re: Morphic question)

Helge Horch Helge.Horch at munich.netsurf.de
Fri Jul 14 10:08:41 UTC 2000


At 11:05 13.07.2000 -0500, Michael Bauers wrote:
>Well the more people keep talk, the more it sounds like the only way to
>access a sub morph you created in a Morphic project window, and dropped on
>its owner (PasteUpMoprh), is through some sort of iteration??
>
>Or using that helper stuff some one else posted?
>
>I understand how to do it if I am instantiating my own Morphs, that is
>straightforward.  But it seems as if it is not so easy if I build up Morphs
>using the Morphic project.
>
>Wow, I thought it would be easier than all that.

Well, I don't know if you'd consider it easy, but you may like to follow 
this short excursion into Morphic hackery.

First, have you all played with the "Play With Me" windows that Squeak 
starts up with?  Let's open "Play With Me - 1" and twiddle the Slider and 
the ScrollBar for a while, and awe at how both are in sync, and how the 
StringMorph displays the current value.

How does it know?  As far as we're concerned, they are just different 
Morphs in a PasteUpMorph, so let's see how the slider value travels to the 
StringMorph.  Bring up the halos on the world, and choose "explore 
morph".  We see it's a MVCWiWPasteUpMorph, and that it has 12 submorphs 
(expand them).  Here, there's the Slider, expand that, too.

Ah, it has a model, a PlayWithMe1.  Let's bring up a menu on that model 
instance variable, and choose "browse class".  What we see is a class that 
was generated when the Slider was added to this world.  (If we look at the 
ScrollBar's model, we'll find it refers to the same model.)

In PlayWithMe1>>slider1Value: (in the "public access" category), we finally 
see what makes the StringMorph tick:

slider1Value: x
         valuePrinter contents: x printString.
         scrollBar1 value: x

So the PlayWithMe1 instance has a reference to both the StringMorph 
(valuePrinter) and the ScrollBar (scrollBar1), and when the Slider slides 
to a new value, the model is notified through the method above and duly 
sync the other two Morphs.

The scrollBar1 instance variable was added automatically when the ScrollBar 
was added to the world, but the valuePrinter reference to the StringMorph 
was added manually [Dan, can you confirm/remember?], as was the specific 
implementation of #slider1Value:.

So let's try something like this on our own.

Open a new Morphic Project, enter it, and open a Workspace.  Evaluate 
"MorphicModel subclasses size".  So what, you say.

Now add a new StarMorph (from the Widgets category) and a new Slider (from 
the Windows category), and drop both on the world.  When creating the 
Slider, we're asked to name the part -- just accept the default 
'slider1'.  And if we first click on the Slider, we're asked whether the 
system "shall compile a null response for 
MorphicModelX>>slider1Value:".  Answer "yes".

[Be careful!  If you happen to cancel the second request, you encounter a 
"self halt", the intention for which is beyond me.  If you're caught in 
that halt, drop into the debugger, and restart the offending method, then 
you'll get a second chance to answer "yes".  Works for me. <shrug>]

If you now reevaluate "MorphicModel subclasses size", the number should 
have increased by one.  Let's now find and modify that model class to do 
something useful.

 From the world's debug halo, choose "explore morph".  See how the Slider 
shares the model (a MorphicModel123 or so) with root (a 
PasteUpMorph).  Choose "browse class" on the model item and see what the 
system meant by "null response":  There is a #slider1 method for access, 
and #slider1Value: that just answers self.

What we (erm, I) now would like to do is to modify some aspect of the 
StarMorph based on the Slider value.  Pity is, the MorphicModel123 doesn't 
know about the StarMorph.  So let's beat it into submission:  In the class 
browser, add an instance variable "star" and a setter like this:

star: aMorph
         star _ aMorph

Now for the tricky bit.  We don't know about the StarMorph instance either, 
really.  All we have is a fishy reference in the Explorer, in the submorphs 
list of the root PasteUpMorph.  Shrug, we'll do just that: punch the 
reference in from the Explorer.  It isn't called Explorer for nothing.

Carefully select the "root" item in the Explorer and venture to the lower 
pane.  Let's check if everything reacts as intended:  In the lower pane, 
evaluate "self submorphOfClass: StarMorph".  The answer should be "a 
StarMorph".

Drum roll.  Take a deep breath and while holding it, edit the expression in 
the lower pane to

   self model star: (self submorphOfClass: StarMorph)

and expand the model instance variable to see it "it took".  The model's 
star instance variable should now reference the StarMorph.  Also, remember 
to continue breathing now.

We're nearly there.  What's missing is that MorphicModel123>>slider1Value: 
still doesn't do something "useful".  Let's try this:

slider1Value: t1
    star
       ifNotNil:
         [star color:
            ((Color hotColdShades: 25) at: (t1 * 24) truncated + 1)]

Accept that in the class browser for MorphicModel123 that's still around 
somewhere.  Now twiddle the slider.  Instant fun.


So, to sum up the relevant bit:  In a Morphic project, the corresponding 
(auto-generated) MorphicModel subclass can coordinate and orchestrate 
widget responses.  The MorphicModel subclass is specific to the project, 
and can be extended and modified (even renamed, IIRC) at will.

"Is Morphic its own GUI builder?"   Maybe the resident Morphic experts or 
the PlayWithMe creators can chime in with corrections, insights and 
explanations.

Twinkle, twinkle, little star.

Cheers, and thanks for listening,
Helge





More information about the Squeak-dev mailing list