[Newbies] Morph Drop Shadows

Benjamin Schroeder benschroeder at acm.org
Mon May 21 16:09:21 UTC 2007

On May 20, 2007, at 3:01 PM, David H. Shanabrook wrote:

> I am experimenting with geometry tutors, such as pentominos.  when  
> trying to fit shapes precisely together the shadow is very  
> disturbing, it is hard to know what is the shadow and what is the  
> shape, especially for kids.

When I want to remove the drag-shadow from Morphs, I often use  
something like the following methods (implemented on my Morph subclass):

	fullDrawOn: aCanvas

		aCanvas isShadowDrawing ifTrue: [^ self].
		super fullDrawOn: aCanvas.
#fullDrawOn: is sent to a Morph to ask it to draw itself, its border,  
and its submorphs. The Hand uses it to draw a shadow copy of the  
Morph. This method says, if that's what's going on, don't draw  
anything (therefore preventing any shadow from being shown).


		^ false

This message is also sent during shadow drawing. It seems to be  
necessary to prevent shadows from being drawn, but I'm afraid I have  
forgotten why! and I'm not sure I have a chance to track it down  
right now. (I almost held off from posting this because of that, but  
I thought it would be better to offer the advice and leave an  
exercise for the reader. :)

Note that the shadow does serve at least one important purpose. In  
the default mouse handling, clicking on a Morph picks it up, and one  
must click the mouse again to drop the Morph. It can be confusing to  
have a Morph "stuck" to the hand without any visual indication.

I often make a simple mouse override to fix this too, if I am not  
doing any more specialized mouse handling on my own. Here is what I do:

	handlesMouseDown: evt

		^ true

This tells Morphic that a particular Morph wants to receive mouse  

	mouseDown: evt

		evt hand
			waitForClicksOrDrag: self
			event: evt
			selectors: #( #click: #doubleClick: #doubleClickTimeout: #startDrag:)
			threshold: 0

This message is sent on mouse down. The method here tells the Hand to  
parse upcoming mouse events, and decide whether a click, double  
click, or drag might be happening. The threshold of "0" says to  
interpret any mouse movement at all as a drag. (There is a simpler  
variant of #waitForClicksOrDrag... that defaults that to 10, which I  
find to be too unresponsive.)

	startDrag: evt

		evt hand grabMorph: self.

This is called when the Hand detects a drag, after the "wait" message  
from above. The method just tells the hand to pick up this Morph.

Of course I'm sure there must be some flag that does the same  
thing! ;) If I am writing a system with many Morphs like this, I of  
course put all of this code in a superclass to avoid clutter.

Hope this helps,
Benjamin Schroeder

More information about the Beginners mailing list