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
|