Archive

You are currently browsing the Scott Morgan blog archives for December, 2007.

Dec

20

onDragOver, onDragOut, and onReleaseOutside in ActionScript 3.0 (AS3)

By scott

In AS2 there were three mouse events that I used quite often. onDragOver was thrown when the mouse button is selected and the cursor was moved over a MovieClip. This was useful to detect if another object was being dragged over a given clip. onDragOut was the opposite, this event was thrown when the mouse button was selected and the cursor was dragged outside of a given clip. And lastly, onReleaseOutside was thrown when a clip was pressed and the user dragged off the clip before releasing the mouse button. Releasing the mouse outside is a common way for a user to bail out of selecting a button among other reasons.

If you look through the AS3 documentation you will notice there are no MouseEvent.DRAG_OVER, MouseEvent.DRAG_OUT, or MouseEvent.RELEASE_OUTSIDE events. This does not mean that this functionality is not available, it’s just not as obvious. The following code shows how to recreate this functionality in AS3.

var button:Sprite = new Sprite();
button.graphics.beginFill(0x000000, 1);
button.graphics.drawRect(50,50,200,100);
addChild(button);

button.buttonMode = true;
button.addEventListener(MouseEvent.MOUSE_DOWN, buttonPress);
button.addEventListener(MouseEvent.MOUSE_UP, buttonRelease);
button.addEventListener(MouseEvent.MOUSE_OVER, buttonOver);
button.addEventListener(MouseEvent.MOUSE_OUT, buttonOut);

function buttonPress(e:MouseEvent):void {
     //the button is pressed, set a MOUSE_UP event on the button's parent stage
     //to caputre the onReleaseOutside event.
     button.parent.stage.addEventListener(MouseEvent.MOUSE_UP, buttonRelease);
}

function buttonRelease(e:MouseEvent):void {
     //remove the parent stage event listener
     button.parent.stage.removeEventListener(MouseEvent.MOUSE_UP, buttonRelease);

     //if the events currentTarget doesn't equal the button we
     //know the mouse was released outside.
     if (e.currentTarget != button) {
          trace('onReleasedOutside');
     } else {
          //the events currentTarget property equals the button instance therefore
          //the mouse was released over the button.
          trace('onRelease');
     }
}

function buttonOver(e:MouseEvent):void {
     if (e.buttonDown) {
          //if the mouse button is selected when the cursor is
          //over our button trigger the onDragOver functionality
          trace('onDragOver');
     } else {
          //if the mouse button isn't selected trigger the standard
          //onRollOver functionality
          trace('onRollOver');
     }
}

function buttonOut(e:MouseEvent):void {
     if (e.buttonDown) {
          //if the mouse button is selected when the cursor is
          //moves off of our button trigger the onDragOut functionality
          trace('onDragOut');
     } else {
          //if the mouse button isn't selected trigger the standard
          //onRollOut functionality
          trace('onRollOut');
     }
}

So let me explain what is going on here.

To recreate the onDragOver and onDragOut functionality we use the buttonDown property of the MouseEvent. The buttonDown property is a Boolean value that indicates if the users mouse button is selected when the event was triggered. If this property is true we know the user is dragging over or dragging out of the button. If the buttonDown property is false we can trigger our standard rollOver or rollOut functionality.

Recreating the onReleaseOutside functionality is a trickier multi-step process. First we must set up a MouseEvent.MOUSE_DOWN event listener on the button. Secondly we set up a MouseEvent.MOUSE_UP event listener on the same button. Third, in the MouseEvent.MOUSE_DOWN event handler we set up another MouseEvent.MOUSE_UP event listener on the button’s stage that triggers the same event handler as the MouseEvent.MOUSE_UP event handler (buttonRelease) that is set on the button. And lastly we check the currentTarget property of the event passed into the MouseEvent.MOUSE_DOWN event handler to see if it equals the button or the button’s parent stage. If the currentTarget equals the button we know the mouse button was released over the button and we can trigger the onRelease functionality. If the currentTarget property isn’t the button we can assume the user released the mouse button outside of the button. Each situation is different, button.parent.stage may not work in your application, you may have to traverse up the display list, possibly right down to the root child (the Stage) to succesfully detect the onReleaseOutside event. Below I have updated the buttonDown method to show a simple way of traversing up the display list as far as you can go and setting the MouseEvent.MOUSE_UP on the root child.

function buttonPress(e:MouseEvent):void {
     //the button is pressed, set a MOUSE_UP event on the root child in the display list
     //to caputre the onReleaseOutside event.
     var rootChild:DisplayObject = button;
     while (rootChild.parent != null) {
          rootChild = rootChild.parent;
     }
     rootChild.stage.addEventListener(MouseEvent.MOUSE_UP, buttonRelease);
}

Enjoy!

Dec

16

Critical Mass releases Google Maps Flash API

By scott

My previous team of Flash Developers at Critical Mass have recently released the start of a Flash API for the popular Google Maps API. You can read more about it here.

Currently AS2 is only supported, they mention an AS3 version will be available sometime in 2008, hopefully early 2008. I have heard from a few people that Google is about to release their own Flash API but until then we have Scott Ingalls and the entire Flash team at Critical Mass to thank.