The real meat of the class is in the childDraw function, but first a note about the constructor, Window(…). The class’s private variables ‘h’, ‘w’, and header are set here. ‘h’ and ‘w’ correspond to the height and width of the content of the window, not of the window itself. This is important, because remember that the subclass, which draws the contents of the window, should not have to compensate in any way for using the superclass Wndow. Instead Window must compensate by drawing all frames and bars around the content area.

The first lines of code in draw() draws the background, which extends past the content on all sides to act as a border. This frame is the absolute bottom layer, and so it is drawn first. It extends two pixels on either side of the content area, so it’s width is w+2. It also must extend above the title bar by two pixels.

The title bar floats above the content area. By allowing the content to be drawn originating at (0,0), we force the bar to be drawn in the –y direction.

The gray content background fits exactly in the area the content will fill. It is meant to be a uniform background for all the subclasses.

The very last step is to call childDraw(). This is a function that each subclass will override, and will contain all the drawing particular to that class. Here is an example of a subclass:

public class Metronome extends Window
{
            //… do other things
            public function Metronome()
            {
                  super(100, 50, "Metronome");
                  //… do other things
            }
            public override function childDraw():void{
                  //… do other things
            }
}


It is important to have the word override before childDraw(). It is also important to make a call to the constructor of Window by using the super(…) call.

The next step is to add the click-and-drag capability to Window. AS3 has some built-in functions called startDrag() and stopDrag(). We will call these functions when the mouse is pressed and released over the bar, respectively. To Window we add a few more functions. I found these necessary to only sense mouse actions which  occur over the bar, not the whole window. Here they are:

private function localX(gx:int):int{
      return gx-this.x;
}
private function localY(gy:int):int{
      return gy-this.y;
}
public function beginDrag(m:MouseEvent):void{
      if(localY(m.stageY)<0 && localY(m.stageY)>-barHeight && localX(m.stageX)>0 && localX(m.stageX)<width){
            startDrag();
            parent.setChildIndex(this, parent.numChildren-1);
      }
}

public function endDrag(m:MouseEvent):void{
      stopDrag();
}

And now to the end of the Window constructor we add:

this.addEventListener(MouseEvent.MOUSE_DOWN, beginDrag);
this.addEventListener(MouseEvent.MOUSE_UP, endDrag);

     

     

This is all of the code for click-and-drag. The mouse listeners on the window call the begin and end drag functions. beginDrag() tests whether the user clicked directly over the bar or not. It then calls the startDrag() function. This causes the whole window to follow the mouse around, until stopDrag() is called when the user releases the mouse.