Another stupid Morphic Question

Andreas Raab andreas.raab at gmx.de
Wed May 2 02:38:56 UTC 2007


PS. Forgot to mention that of course you can contextualize those actions 
just as well. For example try the following (which has all the actions 
associated with the container):

rect := RectangleMorph new.
rect extent: 200 at 200.

#(red green blue yellow) do:[:cc|
   circle := EllipseMorph new.
   circle extent: 50 at 50.
   circle color: (Color perform: cc).
   circle position: (0 to: 150) atRandom @ (0 to: 150) atRandom.
   rect addMorph: circle.
].

rect on: #mouseDown send: #value: to:[:evt|
   list := rect rootMorphsAt: evt position.
   target := list isEmpty ifTrue:[nil] ifFalse:[list first].
   target ifNotNil:[
     target comeToFront.
     offset := target position - evt hand position.
     target addDropShadow]].

rect on: #mouseMove send: #value: to:[:evt|
   target ifNotNil:[target position: evt hand position + offset]].

rect on: #mouseUp send: #value to:[
   target ifNotNil:[
     target removeDropShadow.
     target := nil]].

rect openInWorld.

Cheers,
   - Andreas

Andreas Raab wrote:
> Andrew P. Black wrote:
>> Well, this is much more elegant: the use of on:send:to: simplifies 
>> things considerably, and, along the way, explains how to use 
>> EventHandlers, which were another mystery.  But it has the same bug: 
>> once the circle has been "picked up", it is no longer a submorph of 
>> the rectangle.  Presumably that could be fixed by a #mouseUp handler, 
>> although I tried adding
>>
>> circle on: #mouseUp   send: #value
>>        to:[rect addMorph: circle].
>>
>> which appeared to have no effect.
> 
> Yes, indeed, it would have no effect. Once you asked the hand to grab 
> the morph the hand is in control and not the morph. I think I 
> misunderstood that part - if you simply want to move the circle inside 
> the rectangle (without taking it out of the structure) you should be 
> doing something like this:
> 
> rect := RectangleMorph new.
> rect extent: 100 at 100.
> circle := EllipseMorph new.
> circle extent: 100 at 100.
> rect addMorphCentered: circle.
> rect on: #mouseDown send: #value to:["ignore drags"].
> 
> circle on: #mouseDown send: #value:
>   to:[:evt| offset := circle position - evt hand position.
>             circle addDropShadow].
> 
> circle on: #mouseMove send: #value:
>   to:[:evt| circle position: evt hand position + offset].
> 
> circle on: #mouseUp send: #value
>   to:[circle removeDropShadow].
> 
> rect openInWorld.
> 
>>> Well, by far the easiest way is to use a PasteUpMorph instead of a 
>>> RectangleMorph - PasteUps have this behavior builtin.
>>>
>>
>> That is the answer I was looking for!  Inter alia, it explains what a 
>> PasteUpMorph is for, somthing that I had never appreciated (except to 
>> know that the World was one).
> 
> Well, partly. PasteUps provide the default drag and drop you see in the 
> world but they *do* rip morphs out of their structure when you click on 
> them. If your entities are sensitive to structural changes (or if they 
> need to preserve the z-order) you'll be better off with something like 
> the above.
> 
> Cheers,
>   - Andreas
> 
> 




More information about the Squeak-dev mailing list