ActionScript.org Flash, Flex and ActionScript Resources - http://www.actionscript.org/resources
Creating a custom window environment in Flex 3
http://www.actionscript.org/resources/articles/960/1/Creating-a-custom-window-environment-in-Flex-3/Page1.html
John Bauschatz
I'm a second-year computer Science major at Wheaton College, Il. As a final requirement in class this semester, I am to publish a tutorial teaching about my class project. This tutorial will teach how to code a customized windowed environment in flex 3. 
By John Bauschatz
Published on December 16, 2009
 
This tutorial will explain how to create a custom windowed environment in flex 3.0.  This environment consists of draggable content panes, the content and style of which can be easily changed by the programmer.

This tutorial will explain how to create a custom windowed environment in flex 3.0.  This environment consists of draggable and collapsible content panes, the content and style of which can be easily changed by the programmer. Here is an example

 

 

I created this system out of necessity while working on a class project. The project consisted of several isolated graphical elements (a guitar neck schematic, a metronome, and a circle-of-fifths). spread throughout the page. I desired that the user should be able to drag these around, or hide them at will. I didn’t want to write all that code for each one of the objects. The conclusion was to create a superclass which encapsulated all the common functionality of the windows.

We will now create the class Window, which is designed to draw a basic title bar and background and have click-and-drag capabilities. Our example subclass will be Menu. One of the features of the Window is that the Menu class will not have to make any adjustments to how it is drawn.  Here is a simple form of Window.as:

[as]package
{
      import flash.display.MovieClip;
      import flash.events.MouseEvent;
      import flash.text.*;
      public class Window extends MovieClip
      {
            protected var h:int;
            protected var w:int;
            protected var header:String;
            public static var barHeight:int = 20;
            public function Window(w:int, h:int, header:String)
            {
                  this.w = w;
                  this.h = h;
                  this.header = header;
            }
            public function draw():void{                        
                  //draw the large frame in gray
                  graphics.beginFill(0x000000,.5);
                  graphics.drawRect(-2, -4-barHeight, w+4, barHeight+6+h);
                  //draw the title bar in blue
                  graphics.beginFill(0x0000ff, .5);
                  graphics.drawRect(0, -2-barHeight, w, barHeight);
                  //write the header text
                  var t:TextField = new TextField();
                  t.textColor = 0xffffff;
                  t.text = header;
                  t.width = 100;
                  t.selectable = false;
                  addChild(t);
                  t.x = -3;
                  t.y = -barHeight+3;
                  //draw content background in gray
                  graphics.beginFill(0x00ff00, .5);
                  graphics.drawRect(0,0,w,h);
                  childDraw();
            }
            public function childDraw():void{}
      }
}[/as]



page2

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:

[as]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
            }
}[/as]


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:

[as]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();
}[/as]

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

[as]this.addEventListener(MouseEvent.MOUSE_DOWN, beginDrag);
this.addEventListener(MouseEvent.MOUSE_UP, endDrag);[/as]

     

     

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.