4. ClipDragger continued: Accessing the Stage from the class

But how do we get a reference to the stage from inside our class file? There are several ways of doing this, but the easiest way in this case is just to get it from the clip we just passed in. Every display object (of which our MovieClip is one) has a property called “stage” that’s an instance of the Stage class. In other words, every display object “knows” what stage it’s on. So, revise the ClipDragger class as follows:

package com.mysite.mouse {
    import flash.display.MovieClip;
    import flash.events.MouseEvent;
    public class ClipDragger {
        private var _clip:MovieClip;
        public function ClipDragger(clip:MovieClip) {
            _clip = clip;
            _clip.addEventListener(MouseEvent.MOUSE_DOWN, drag);
            _clip.stage.addEventListener(MouseEvent.MOUSE_UP, drop);
        }
        private function drag(event:MouseEvent) {
            _clip.startDrag();
        }
        private function drop(event:MouseEvent) {
            _clip.stopDrag();
        }
    }
}

Now that you have drag and drop functionality in your class, you can now simply apply it to any MovieClip you want, even apply it to multiple MovieClips. Go back to the fla file, and create two more MovieClips. Make a circle MovieClip and a square MovieClip, and give them those as instance names. Next, add the code to create new instances of your class to make those clips draggable too. So the code in the fla file now becomes:

import com.mysite.mouse.ClipDragger;
var clipDragger:ClipDragger = new ClipDragger(myClip);
var clipDragger2:ClipDragger = new ClipDragger(circle);
var clipDragger3:ClipDragger = new ClipDragger(square);

The above few lines of code will make all three clips exhibit drag and drop behavior. Run the fla file and test it out. You should now be able to drag and drop all three MovieClips, quite independently of each other.

You may notice when you run this that there are a couple of other refinements we ought to make. For one thing, there’s no hand cursor when we mouse over the clips. This is an easy fix—just set the _clip’s buttonMode property to true, and we’ll do that right in the constructor, by adding this line:

_clip.buttonMode = true

The other thing is that whatever clip we’re currently dragging ought to come to the front of Flash’s stacking order. You may have noticed that one of the clips will pass behind another when it’s being dragged, and that just looks weird. This is also fairly easy to fix, you just need to add this line to the mouse down event:

_clip.parent.setChildIndex(_clip, _clip.parent.numChildren - 1);

In plain English, this line is telling our clip’s parent (which is the main timeline of the fla) to set our clip’s display index to a certain value. However many children there are, set the index to that number minus one. This just involves knowing that Flash’s Display Object Containers (of which the main timeline is one) keep an internal list of whatever display objects are added to them. This list starts it’s numbering at 0, so the number of children minus one would give you the highest index, no matter how many children there are. And setting the index to the highest number has the effect of bringing our clip to the front.

package com.mysite.mouse {
    import flash.display.MovieClip;
    import flash.events.MouseEvent;
    public class ClipDragger {
        private var _clip:MovieClip;
        public function ClipDragger(clip:MovieClip) {
            _clip = clip;
            _clip.buttonMode = true;
            _clip.addEventListener(MouseEvent.MOUSE_DOWN, drag);
            _clip.stage.addEventListener(MouseEvent.MOUSE_UP, drop);
        }
        private function drag(event:MouseEvent) {
            _clip.parent.setChildIndex(_clip, _clip.parent.numChildren - 1);
            _clip.startDrag();
        }
        private function drop(event:MouseEvent) {
            _clip.stopDrag();
        }
    }
}

When you test and run the fla this time, you’ll get a hand cursor when you hover the mouse over each clip. When you press the mouse button down to drag a clip, that clip will come to the front and overlap any other clips there might be. And that concludes the discussion of this first example. Let’s move on to create our next truly useful class, wherein we’ll move a MovieClip around the screen using the keyboard.