I had a quick play, here is what I came up with:
My example has a MovieClip on the stage called "ball", and a number of other MovieClip scattered around for use as dropTargets.
ball.addEventListener(MouseEvent.MOUSE_DOWN, pickUp);
stage.addEventListener(MouseEvent.MOUSE_UP, dropIt);
function pickUp(event:MouseEvent):void
{
var ballPoint:Point = ball.parent.localToGlobal( new Point(ball.x, ball.y) );
ball.parent.removeChild(ball);
addChild(ball);
ball.x = ballPoint.x;
ball.y = ballPoint.y;
ball.startDrag();
}
function dropIt(event:MouseEvent):void
{
ball.stopDrag();
if(!event.target.dropTarget) { return };
var dropT:MovieClip = event.target.dropTarget.parent;
var ballPoint:Point = dropT.globalToLocal( new Point(ball.x, ball.y) );
ball.parent.removeChild(ball);
dropT.addChild(ball);
ball.x = ballPoint.x;
ball.y = ballPoint.y;
}
Basically, the PickUp handler removes the "ball" MovieClip from its parent, and adds it to the root DisplayObject. This makes sure the ball is on top, so the dropTarget will work (dropTarget will only work with Objects lower in the stack order). The ball's x/y position is calculated (using localToGlobal) for its new parent, and applied. Then start drag is called.
The dropIt handler first calls stopDrag, then returns if it can't find a dropTarget. A new x/y position for the ball is calculated using globalToLocal this time, to get its new position in its droptarget. The ball is then removed and added to its new parent (the dropTarget). The new position is applied.
Seems to work really well in my case.
Also... I found that a good way to test if it's working, is to temporarily apply different blur or dropShadow filters to the dropTargets on the stage. That way when you drop the ball onto them, it will inherit the filter, and you can see some visual feedback.
there must be something wrong with your code ... i have a minimum setup here:
package {
import flash.display.*;
import flash.events.*;
import flash.geom.ColorTransform;
public class Test extends Sprite {
private var child:Sprite
public function Test() {
this.addChild(child = new Sprite());
child.graphics.beginFill(0xFF0000);
child.graphics.drawRect(0, 0, 100, 20);
child.addEventListener(MouseEvent.CLICK, onClick);
child.addEventListener(MouseEvent.MOUSE_OUT, onOut);
child.addEventListener(MouseEvent.MOUSE_OVER, onOver);
}
private function onOver(e:MouseEvent):void {
child.transform.colorTransform = new ColorTransform(0, 0, 0, 1, 0, 0xFF);
}
private function onOut(e:MouseEvent):void {
child.transform.colorTransform = new ColorTransform();
}
private function onClick(e:MouseEvent):void {
this.mouseChildren = this.mouseEnabled = false;
}
}
}
should turn green, when you mouse over, and red again, if you mouse out ... on click, it is disabled with this.mouseChildren = this.mouseEnabled = false
... on my machine, this triggers mouseOut (so the rectangle turns red again) ... this makes sense to me ... and the thing with getting mouse outs when clicking, is a definite indicator to me, you must be having a bug somewhere ... could you try to reduce the problem and post it?
greetz
back2dos
Best Answer
I can't remember the specifics, but you can use standard event listeners on the button and prevent those events from being received on the MovieClip underneath it. You need to cancel the event in the button's listening handler.
http://livedocs.adobe.com/flash/9.0/ActionScriptLangRefV3/flash/events/Event.html#stopPropagation%28%29
If you find that the MovieClip has already received the event, change your Button listener to listen in the capture phase of the event(useCapture parameter of addEventListener).