On 1 May 2007, at 1:07, Andreas Raab wrote:
... it's the world which implements the default behavior of dragging objects. In other words the action is contextual (objects in the world can be dragged) not builtin.
Aha! This was an insight that I was missing. Someone should write a book that explains all this stuff ;-)
This code seems both overly complicated as well as at least somewhat buggy (grabMorph:from: should only be used for owner-less morphs). Try the following instead:
rect := RectangleMorph new. rect extent: 100@100. circle := EllipseMorph new. circle extent: 100@100. rect addMorphCentered: circle. rect on: #mouseDown send: #value to:["ignore drags"]. circle on: #mouseDown send: #value to:[circle world primaryHand grabMorph: circle]. rect openInWorld.
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.
I could probably find all of the bits of code that I need, to handle mouse move and so on, taking care of the offset between mouse click event and the origin of the Morph that I'm moving — most of the code must be in HaloMorph. But this was the Default Behavior of the circle before I embedded it in the rectangle — surely there must be an easier way to get that default behavior back, other than duplicating the code from whereever it is hidden!
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).
Thank you!
Andrew P. Black Department of Computer Science Portland State University +1 503 725 2411