Share 'Tutorial: Creating an alert box with the AS3Commons PopUpManager' on Delicious Share 'Tutorial: Creating an alert box with the AS3Commons PopUpManager' on Facebook Share 'Tutorial: Creating an alert box with the AS3Commons PopUpManager' on Google Bookmarks Share 'Tutorial: Creating an alert box with the AS3Commons PopUpManager' on Twitter

Article | Published: 9. Juni 2011 | Changed: 15. Dezember 2014 | Category: UI | 1 Comment
  1. About the PopUpManager class
  2. About this tutorial
  3. Requirements
  4. Creating a generic alert component
  5. Setup of PopUpManager
  6. Different alerts
  7. Adding transitions
  8. Optimizations
  9. The final code and the compiled swf
  10. Comments (1)
  11. Leave a Comment

About the PopUpManager class

The PopUpManager is included in the layers package of the AS3Commons UI project. The class lets you create, place or remove popups throughout an application. It is meant to be a pure ActionScript alternative to the well-known popup managers incorporated by Flex or the Flash component package.

About this tutorial

In this tutorial we are going to create a small application containing two buttons where each button triggers an alert box showing some text. The first button starts a simple message box that will vanish by a subsequent click anywhere into the application. The second button starts a modal dialog that must be confirmed.

AlertTutorial.swf

If you want to see the final code first, jump to the last section of this tutorial.

The tutorial explains:

  1. Creating and managing an instance of PopUpManager
  2. Creating and removing a popup
  3. Placing a popup
  4. Modal and modeless popups
  5. Animating the popup’s show and hide events

Requirements

To run the code shown in this tutorial you need to install the following libraries.

  • AS3Commons UI 0.3 – Contains the PopUpManager and several layout algorithms
  • AS3Commons Collections 1.3.0 – Data structures required by AS3Commons UI
  • GTween 2.01 – Tweening library of choice
  • AS DataProvider Controls 0.4.0 – User interface components

All libraries are included in the ZIP download of the AS3Commons UI project.

Creating a generic alert component

In the first step of this tutorial we create a simple alert component. The component has a fix size of 300×160 px. It shows a headline and a message. It is possible to configure the alert box to show up to 3 buttons. Each button will dispatch its custom event type. The first button the type AlertBox.ALERT_YES, the second button the type AlertBox.ALERT_NO and the third button the type AlertBox.ALERT_CANCEL. To configure the buttons, the constructor accepts a buttons property (type Array) which contains names for all buttons that should be shown. The event will be forwarded to the callback also specified in a constructor argument. There is actually nothing special with the alert box.

AlertBox.as
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
package layer.popup.alerttutorial.step1 {
  import com.sibirjak.asdpc.button.*;
  import org.as3commons.ui.layout.HGroup;
  import org.as3commons.ui.layout.constants.Align;
  import org.as3commons.ui.layout.shortcut.*;
  import flash.display.Sprite;
  import flash.events.*;
  import flash.text.*;

  public class AlertBox extends Sprite {
    public static const ALERT_YES : String = "yes";
    public static const ALERT_NO : String = "no";
    public static const ALERT_CANCEL : String = "cancel";
    private var _clickCallback : Function;
   
    public function AlertBox(headline : String, text : String, buttons : Array, clickCallback : Function) {
      _clickCallback = clickCallback;
     
      var w : uint = 300;
      var h : uint = 160;
      var padding : uint = 10;

      // shadow and background
      with (graphics) {
        beginFill(0x999999, .15);
        drawRect(8, 8, w, h);
        lineStyle(1, 0xCCCCCC);
        beginFill(0xFFFFFF);
        drawRect(0, 0, w, h);
      }
     
      // headline
      var tf1 : TextField = new TextField();
      tf1.autoSize = TextFieldAutoSize.LEFT;
      tf1.defaultTextFormat = new TextFormat("_sans", 16, 0x444444, false);
      tf1.text = headline; 
     
      // text
      var tf2 : TextField = new TextField();
      tf2.width = w - 2*padding;
      tf2.autoSize = TextFieldAutoSize.LEFT;
      tf2.wordWrap = true;
      tf2.defaultTextFormat = new TextFormat("_sans", 12, 0x444444);
      tf2.text = text;
     
      // buttons
      if (buttons) {
        var bGroup : HGroup = hgroup("gap", 10);
        if (buttons[0]) bGroup.add(createButton(buttons[0], ALERT_YES));
        if (buttons[1]) bGroup.add(createButton(buttons[1], ALERT_NO));
        if (buttons[2]) bGroup.add(createButton(buttons[2], ALERT_CANCEL));
      }

      // layout
      vgroup(
        "marginX", padding, "marginY", padding,
        "minWidth", w - 2*padding, "minHeight", h - 2*padding,
        "vAlign", Align.JUSTIFY,
        vgroup(
          cellconfig("vIndex", 1, "marginY", 10),
          tf1,
          tf2
        ),
        bGroup
      ).layout(this);
    }
   
    private function createButton(label : String, eventType : String) : Button {
      var button : Button = new Button();
      button.setSize(60, 22);
      button.label = label;
      button.addEventListener(ButtonEvent.CLICK, function(event : Event) : void {
        buttonClickHandler(eventType);
      });
      return button;
    }
   
    private function buttonClickHandler(eventType : String) : void {
      _clickCallback(this, eventType);
    }
  }
}
AlertTutorialStep1.as
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
package layer.popup.alerttutorial.step1 {
  import flash.display.Sprite;
  import flash.events.Event;
  import flash.text.TextField;
  import flash.text.TextFormat;

  public class AlertTutorialStep1 extends Sprite {
    private var _tf : TextField;
   
    public function AlertTutorialStep1() {
      addEventListener(Event.ADDED_TO_STAGE, init);
    }

    private function init(event : Event) : void {
      removeEventListener(Event.ADDED_TO_STAGE, init);
     
      _tf = new TextField();
      _tf.defaultTextFormat = new TextFormat("_sans", 11);
      _tf.text = "Click a button";
      addChild(_tf);
     
      var alert : AlertBox = new AlertBox(
        "Popup",
        "This is a simple popup window. Click a button.",
        ["one", "two", "tree"],
        info
      );
      alert.y = 30;
      addChild(alert);
    }
   
    private function info(alert : AlertBox, event : String) : void {
      _tf.text = event;
    }
  }
}
AlertTutorialStep1.swf

Let’s test another configuration with only one button, the third button that should dispatch the event AlertBox.ALERT_CANCEL. We change the buttons property from ["one", "two", "three"] to [null, null, "three"].

22
23
24
25
26
27
var alert : AlertBox = new AlertBox(
  "Popup",
  "This is a simple popup window with only one button. Click it.",
  [null, null, "three"],
  info
);

It works as expected:

AlertTutorialStep1b.swf

In step 1 we have added the alert box right below the main application. In the next step we will use the PopUpManager to add the box to the display list.

Setup of PopUpManager

The PopUpManager expects a popup container display object within its constructor. We we will create the container at the very top of our application. There should be only one instance of PopUpManager for a single application. We hence store the PopUpManager instance in a local variable of the main application. Finally, we call PopUpManager.createPopUp(alert) instead of addChild(alert) to add the alert box to the display list.

AlertTutorialStep2.as
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
package layer.popup.alerttutorial.step2 {
  import layer.popup.alerttutorial.step1.AlertBox;
  import org.as3commons.ui.layer.PopUpManager;
  import flash.display.Sprite;
  import flash.events.Event;
  import flash.text.TextField;
  import flash.text.TextFormat;

  public class AlertTutorialStep2 extends Sprite {
    private var _tf : TextField;
    private var _popUpManager : PopUpManager;
   
    public function AlertTutorialStep2() {
      addEventListener(Event.ADDED_TO_STAGE, init);
    }

    private function init(event : Event) : void {
      removeEventListener(Event.ADDED_TO_STAGE, init);
     
      var container : Sprite = stage.addChild(new Sprite()) as Sprite;
      _popUpManager = new PopUpManager(container);
     
      _tf = new TextField();
      _tf.defaultTextFormat = new TextFormat("_sans", 11);
      _tf.text = "Click a button";
      addChild(_tf);
     
      var alert : AlertBox = new AlertBox(
        "Popup",
        "This is a simple popup window. Click a button.",
        ["one", "two", "tree"],
        info
      );
      alert.x = 10;
      alert.y = 40;
      _popUpManager.createPopUp(alert);
    }
   
    private function info(alert : AlertBox, event : String) : void {
      _tf.text = event;
    }
  }
}

The resulting SWF is identical to the one of step 1.

AlertTutorialStep2.swf

We will now implement the code to remove the popup with a click of each of the buttons. To create a new popup, we will add an appropriate button to the main application.

AlertTutorialStep2b.as
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
package layer.popup.alerttutorial.step2 {
  import layer.popup.alerttutorial.step1.AlertBox;
  import com.sibirjak.asdpc.button.Button;
  import com.sibirjak.asdpc.button.ButtonEvent;
  import org.as3commons.ui.layer.PopUpManager;
  import flash.display.Sprite;
  import flash.events.Event;

  public class AlertTutorialStep2b extends Sprite {
    private var _popUpManager : PopUpManager;
    private var _alertId : uint;
   
    public function AlertTutorialStep2b() {
      addEventListener(Event.ADDED_TO_STAGE, init);
    }

    private function init(event : Event) : void {
      removeEventListener(Event.ADDED_TO_STAGE, init);
     
      var container : Sprite = stage.addChild(new Sprite()) as Sprite;
      _popUpManager = new PopUpManager(container);
     
      var button : Button = new Button();
      button.setSize(50, 20);
      button.addEventListener(ButtonEvent.CLICK, addHandler);
      button.label = "add";
      addChild(button);
     
      addPopUp();
    }

    private function addHandler(event : ButtonEvent) : void {
      addPopUp();
    }
   
    private function addPopUp() : void {
      var alert : AlertBox = new AlertBox(
        "Popup " +  ++_alertId,
        "This is a simple popup window. Click a button.",
        ["one", "two", "tree"],
        alertClickCallback
      );
      alert.x = 10;
      alert.y = 40;
      _popUpManager.createPopUp(alert);
    }
   
    private function alertClickCallback(alert : AlertBox, event : String) : void {
      _popUpManager.removePopUp(alert);
    }
  }
}
AlertTutorialStep2b.swf

Different alerts

In step 3 we add a second button to the main application to be able to show either a modeless or a modal popup. The modeless popup only shows a cancel button. The popups are centered automatically.

AlertTutorialStep3.as
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
package layer.popup.alerttutorial.step3 {
  import layer.popup.alerttutorial.step1.AlertBox;
  import com.sibirjak.asdpc.button.Button;
  import com.sibirjak.asdpc.button.ButtonEvent;
  import org.as3commons.ui.layer.PopUpManager;
  import org.as3commons.ui.layout.shortcut.hgroup;
  import flash.display.Sprite;
  import flash.events.Event;

  public class AlertTutorialStep3 extends Sprite {
    private var _popUpManager : PopUpManager;
    private var _alertId : uint;
   
    public function AlertTutorialStep3() {
      addEventListener(Event.ADDED_TO_STAGE, init);
    }

    private function init(event : Event) : void {
      removeEventListener(Event.ADDED_TO_STAGE, init);
     
      var container : Sprite = stage.addChild(new Sprite()) as Sprite;
      _popUpManager = new PopUpManager(container);
     
      var button1 : Button = new Button();
      button1.setSize(70, 24);
      button1.addEventListener(ButtonEvent.CLICK, noticeHandler);
      button1.label = "Notice";
     
      var button2 : Button = new Button();
      button2.setSize(70, 24);
      button2.addEventListener(ButtonEvent.CLICK, confirmHandler);
      button2.label = "Confirm";
     
      hgroup("gap", 10, button1, button2).layout(this);
    }

    private function noticeHandler(event : ButtonEvent) : void {
      var alert : AlertBox = new AlertBox(
        "Popup " +  ++_alertId,
        "This is a simple popup window. Click the close button to remove this popup.",
        [null, null, "Close"],
        alertClickCallback
      );
      _popUpManager.createPopUp(alert, true);
    }
   
    private function confirmHandler(event : ButtonEvent) : void {
      var alert : AlertBox = new AlertBox(
        "Popup " +  ++_alertId,
        "This is a modal popup window. Click a button to remove this popup.",
        ["Yes", "No", "Cancel"],
        alertClickCallback
      );
      _popUpManager.createPopUp(alert, true, true);
    }
   
    private function alertClickCallback(alert : AlertBox, event : String) : void {
      _popUpManager.removePopUp(alert);
    }
  }
}
AlertTutorialStep3.swf

It is a good idea to not require the user to click the close button of a normal popup. Instead, the popup should also vanish with a click somewhere outside the popup. A clean implementation of such an mouse down outside listener is to let the alert track the mouse down event on demand and notify the main application if it should be closed. In result there will be only one modeless alert at the same time since clicking the add button will automatically remove the present alert box, if any.

AlertBox.as
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
package layer.popup.alerttutorial.step3 {
  import com.sibirjak.asdpc.button.*;
  import org.as3commons.ui.layout.HGroup;
  import org.as3commons.ui.layout.constants.Align;
  import org.as3commons.ui.layout.shortcut.*;
  import flash.display.Sprite;
  import flash.events.*;
  import flash.text.*;

  public class AlertBox extends Sprite {
    public static const ALERT_YES : String = "yes";
    public static const ALERT_NO : String = "no";
    public static const ALERT_CANCEL : String = "cancel";
    private var _clickCallback : Function;
    private var _clickOutsideCallback : Function;
   
    public function AlertBox(headline : String, text : String, buttons : Array, clickCallback : Function) {
      _clickCallback = clickCallback;
     
      var w : uint = 300;
      var h : uint = 160;
      var padding : uint = 10;

      // shadow and background
      with (graphics) {
        beginFill(0x999999, .15);
        drawRect(8, 8, w, h);
        lineStyle(1, 0xCCCCCC);
        beginFill(0xFFFFFF);
        drawRect(0, 0, w, h);
      }
     
      // headline
      var tf1 : TextField = new TextField();
      tf1.autoSize = TextFieldAutoSize.LEFT;
      tf1.defaultTextFormat = new TextFormat("_sans", 16, 0x444444, false);
      tf1.text = headline; 
     
      // text
      var tf2 : TextField = new TextField();
      tf2.width = w - 2*padding;
      tf2.autoSize = TextFieldAutoSize.LEFT;
      tf2.wordWrap = true;
      tf2.defaultTextFormat = new TextFormat("_sans", 12, 0x444444);
      tf2.text = text;
     
      // buttons
      if (buttons) {
        var bGroup : HGroup = hgroup("gap", 10);
        if (buttons[0]) bGroup.add(createButton(buttons[0], ALERT_YES));
        if (buttons[1]) bGroup.add(createButton(buttons[1], ALERT_NO));
        if (buttons[2]) bGroup.add(createButton(buttons[2], ALERT_CANCEL));
      }

      // layout
      vgroup(
        "marginX", padding, "marginY", padding,
        "minWidth", w - 2*padding, "minHeight", h - 2*padding,
        "vAlign", Align.JUSTIFY,
        vgroup(
          cellconfig("vIndex", 1, "marginY", 10),
          tf1,
          tf2
        ),
        bGroup
      ).layout(this);
    }
   
    public function watchClickOutside(clickOutsideCallback : Function) : void {
      _clickOutsideCallback = clickOutsideCallback;
      stage.addEventListener(MouseEvent.MOUSE_DOWN, stageClick);
    }
   
    public function unwatchClickOutside() : void {
      stage.removeEventListener(MouseEvent.MOUSE_DOWN, stageClick);
    }
   
    private function stageClick(event : MouseEvent) : void {
      if (!hitTestPoint(event.stageX, event.stageY)) {
        _clickOutsideCallback(this);
      }
    }

    private function createButton(label : String, eventType : String) : Button {
      var button : Button = new Button();
      button.setSize(60, 22);
      button.label = label;
      button.addEventListener(ButtonEvent.CLICK, function(event : Event) : void {
        buttonClickHandler(eventType);
      });
      return button;
    }
   
    private function buttonClickHandler(eventType : String) : void {
      _clickCallback(this, eventType);
    }
  }
}
AlertTutorialStep3b.as
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
package layer.popup.alerttutorial.step3 {
  import layer.popup.alerttutorial.step3.AlertBox;
  import com.sibirjak.asdpc.button.Button;
  import com.sibirjak.asdpc.button.ButtonEvent;
  import org.as3commons.ui.layer.PopUpManager;
  import org.as3commons.ui.layout.shortcut.hgroup;
  import flash.display.Sprite;
  import flash.events.Event;

  public class AlertTutorialStep3b extends Sprite {
    private var _popUpManager : PopUpManager;
    private var _alertId : uint;
   
    public function AlertTutorialStep3b() {
      addEventListener(Event.ADDED_TO_STAGE, init);
    }

    private function init(event : Event) : void {
      removeEventListener(Event.ADDED_TO_STAGE, init);
     
      var container : Sprite = stage.addChild(new Sprite()) as Sprite;
      _popUpManager = new PopUpManager(container);
     
      var button1 : Button = new Button();
      button1.setSize(70, 24);
      button1.addEventListener(ButtonEvent.CLICK, noticeHandler);
      button1.label = "Notice";
     
      var button2 : Button = new Button();
      button2.setSize(70, 24);
      button2.addEventListener(ButtonEvent.CLICK, confirmHandler);
      button2.label = "Confirm";
     
      hgroup("gap", 10, button1, button2).layout(this);
    }

    private function noticeHandler(event : ButtonEvent) : void {
      var alert : AlertBox = new AlertBox(
        "Popup " +  ++_alertId,
        "This is a simple popup window. Click the close button to remove this popup.",
        [null, null, "Close"],
        alertClickCallback
      );
      _popUpManager.createPopUp(alert, true);

      alert.watchClickOutside(function() : void {
        alert.unwatchClickOutside();
        _popUpManager.removePopUp(alert);
      });
    }
   
    private function confirmHandler(event : ButtonEvent) : void {
      var alert : AlertBox = new AlertBox(
        "Popup " +  ++_alertId,
        "This is a modal popup window. Click a button to remove this popup.",
        ["Yes", "No", "Cancel"],
        alertClickCallback
      );
      _popUpManager.createPopUp(alert, true, true);
    }
   
    private function alertClickCallback(alert : AlertBox, event : String) : void {
      alert.unwatchClickOutside();
      _popUpManager.removePopUp(alert);
    }
  }
}
AlertTutorialStep3b.swf

Adding transitions

We have almost finished our tutorial. In the step 4 we add some show and hide animation using a tweening library. Additionally, we will show a feedback for the case the yes or no button of the modal popup has been clicked. To do the latter, we simply create a new modeless popup showing the feedback right after the modal window has been closed.

AlertTutorialStep4.as
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
package layer.popup.alerttutorial.step4 {
  import layer.popup.alerttutorial.step3.AlertBox;
  import com.gskinner.motion.GTween;
  import com.gskinner.motion.easing.Cubic;
  import com.gskinner.motion.easing.Sine;
  import com.sibirjak.asdpc.button.Button;
  import com.sibirjak.asdpc.button.ButtonEvent;
  import org.as3commons.ui.layer.PopUpManager;
  import org.as3commons.ui.layout.shortcut.hgroup;
  import flash.display.Sprite;
  import flash.events.Event;

  public class AlertTutorialStep4 extends Sprite {
    private var _popUpManager : PopUpManager;
    private var _alertId : uint;
   
    public function AlertTutorialStep4() {
      addEventListener(Event.ADDED_TO_STAGE, init);
    }

    private function init(event : Event) : void {
      removeEventListener(Event.ADDED_TO_STAGE, init);
     
      var container : Sprite = stage.addChild(new Sprite()) as Sprite;
      _popUpManager = new PopUpManager(container);
     
      var button1 : Button = new Button();
      button1.setSize(70, 24);
      button1.addEventListener(ButtonEvent.CLICK, noticeHandler);
      button1.label = "Notice";
     
      var button2 : Button = new Button();
      button2.setSize(70, 24);
      button2.addEventListener(ButtonEvent.CLICK, confirmHandler);
      button2.label = "Confirm";
     
      hgroup("gap", 10, button1, button2).layout(this);
    }

    private function noticeHandler(event : ButtonEvent) : void {
      var alert : AlertBox = new AlertBox(
        "Notice " +  ++_alertId,
        "The information provided by this message box may help you to better understand the system of alerts and popups.",
        [null, null, "Close"],
        noticeClickCallback
      );
      _popUpManager.createPopUp(alert, true);
      tweenIn(alert);

      alert.watchClickOutside(function() : void {
        alert.unwatchClickOutside();
        tweenOut(alert);
      });
    }
   
    private function noticeClickCallback(alert : AlertBox, event : String) : void {
      alert.unwatchClickOutside();
      tweenOut(alert);
    }
   
    private function confirmHandler(event : ButtonEvent) : void {
      var alert : AlertBox = new AlertBox(
        "Confirm " +  ++_alertId,
        "Please confirm, dismiss or cancel the progress. Note, this application will not delete files on your hard disk.",
        ["Yes", "No", "Cancel"],
        confirmClickCallback
      );
      _popUpManager.createPopUp(alert, true, true);
      tweenIn(alert);
    }
   
    private function confirmClickCallback(alert : AlertBox, event : String) : void {
      if (event != AlertBox.ALERT_CANCEL) {
        _popUpManager.removePopUp(alert);

        alert = new AlertBox(
          event.toUpperCase(),
          "The button \"" + event.toUpperCase() + "\" has been clicked. OK?",
          [null, null, "Close"],
          noticeClickCallback
        );
        _popUpManager.createPopUp(alert, true);
 
        alert.watchClickOutside(function() : void {
          alert.unwatchClickOutside();
          tweenOut(alert);
        });

      } else {
        tweenOut(alert);
      }
    }
   
    private function tweenIn(alert : AlertBox) : void {
      var tween : GTween = new GTween();
      tween.target = alert;
      tween.ease = Sine.easeOut;
      tween.duration = .15;

      // tween position
      tween.setValue("x", alert.x);
      tween.setValue("y", alert.y);
      alert.x += alert.width/2;
      alert.y += alert.height/2;
      // tween scale
      alert.scaleX = alert.scaleY = 0;
      alert.scaleX = alert.scaleY = 0;
      tween.setValue("scaleX", 1);
      tween.setValue("scaleY", 1);
      // tween alpha
      alert.alpha = 0;
      tween.setValue("alpha", 1);
    }
   
    private function tweenOut(alert : AlertBox) : void {
      var tween : GTween = new GTween();
      tween.target = alert;
      tween.ease = Cubic.easeIn;
      tween.duration = .2;

      // tween position
      tween.setValue("x", alert.x + alert.width/2);
      tween.setValue("y", alert.y + alert.height/2);
      // tween scale
      tween.setValue("scaleX", 0);
      tween.setValue("scaleY", 0);
      // tween alpha
      tween.setValue("alpha", 0);
     
      tween.onComplete = function(tween : GTween) : void {
        _popUpManager.removePopUp(alert);
      };
    }
  }
}
AlertTutorialStep4.swf

Optimizations

We will finalize our tutorial with a few optimizations. The alert handling can be separated from the main class into a static Alert service. This service needs to know the PopUpManager instance which we will store now separately from the main application in a globally accessible variable. At last we add a custom modal overlay showing a grey area instead of the default white one.

The final code and the compiled swf

AlertTutorial.swf
AlertTutorial.as
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
package layer.popup.alerttutorial.final {
  import com.sibirjak.asdpc.button.Button;
  import com.sibirjak.asdpc.button.ButtonEvent;
  import org.as3commons.ui.layer.PopUpManager;
  import org.as3commons.ui.layout.shortcut.hgroup;
  import flash.display.Sprite;
  import flash.events.Event;

  public class AlertTutorial extends Sprite {
    private var _alertId : uint;

    public function AlertTutorial() {
      addEventListener(Event.ADDED_TO_STAGE, init);
    }

    private function init(event : Event) : void {
      removeEventListener(Event.ADDED_TO_STAGE, init);

      var container : Sprite = stage.addChild(new Sprite()) as Sprite;
      Globals.popUpManager = new PopUpManager(container);
      Globals.popUpManager.modalOverlay = ModalOverlay;
     
      var button1 : Button = new Button();
      button1.setSize(70, 24);
      button1.addEventListener(ButtonEvent.CLICK, noticeHandler);
      button1.label = "Notice";
     
      var button2 : Button = new Button();
      button2.setSize(70, 24);
      button2.addEventListener(ButtonEvent.CLICK, confirmHandler);
      button2.label = "Confirm";
     
      hgroup("gap", 10, button1, button2).layout(this);
    }
   
    private function noticeHandler(event : ButtonEvent) : void {
      Alert.show(
        "Notice " + ++_alertId, "The information provided by this message box may help you to better understand the system of alerts and popups.",
        [null, null, "Close"],
        false, true,
        alertClickCallback, true
      );
    }
   
    private function confirmHandler(event : ButtonEvent) : void {
      Alert.show(
        "Confirm " + ++_alertId, "Please confirm, dismiss or cancel the progress. Note, this application will not delete files on your hard disk.",
        ["Yes", "No", "Cancel"],
        true, false,
        alertClickCallback, true
      );
    }

    private function alertClickCallback(alert : AlertBox, event : String) : void {
      if (event != AlertBox.ALERT_CANCEL) {
        Alert.hide(alert, false);
        Alert.show(
          event.toUpperCase(), "The button \"" + event.toUpperCase() + "\" has been clicked. OK?",
          [null, null, "OK"],
          false, true,
          alertClickCallback, false
        );
      } else {
        Alert.hide(alert, true);
      }
    }
  }
}
AlertBox.as
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
package layer.popup.alerttutorial.final {
  import com.sibirjak.asdpc.button.*;
  import org.as3commons.ui.layout.HGroup;
  import org.as3commons.ui.layout.constants.Align;
  import org.as3commons.ui.layout.shortcut.*;
  import flash.display.Sprite;
  import flash.events.*;
  import flash.text.*;

  public class AlertBox extends Sprite {
    public static const ALERT_YES : String = "yes";
    public static const ALERT_NO : String = "no";
    public static const ALERT_CANCEL : String = "cancel";
    private var _clickCallback : Function;
    private var _clickOutsideCallback : Function;
   
    public function AlertBox(headline : String, text : String, buttons : Array, clickCallback : Function) {
      _clickCallback = clickCallback;
     
      var w : uint = 300;
      var h : uint = 160;
      var padding : uint = 10;

      // shadow and background
      with (graphics) {
        beginFill(0x999999, .15);
        drawRect(8, 8, w, h);
        lineStyle(1, 0xCCCCCC);
        beginFill(0xFFFFFF);
        drawRect(0, 0, w, h);
      }
     
      // headline
      var tf1 : TextField = new TextField();
      tf1.autoSize = TextFieldAutoSize.LEFT;
      tf1.defaultTextFormat = new TextFormat("_sans", 16, 0x444444, false);
      tf1.text = headline; 
     
      // text
      var tf2 : TextField = new TextField();
      tf2.width = w - 2*padding;
      tf2.autoSize = TextFieldAutoSize.LEFT;
      tf2.wordWrap = true;
      tf2.defaultTextFormat = new TextFormat("_sans", 12, 0x444444);
      tf2.text = text;
     
      // buttons
      if (buttons) {
        var bGroup : HGroup = hgroup("gap", 10);
        if (buttons[0]) bGroup.add(createButton(buttons[0], ALERT_YES));
        if (buttons[1]) bGroup.add(createButton(buttons[1], ALERT_NO));
        if (buttons[2]) bGroup.add(createButton(buttons[2], ALERT_CANCEL));
      }

      // layout
      vgroup(
        "marginX", padding, "marginY", padding,
        "minWidth", w - 2*padding, "minHeight", h - 2*padding,
        "vAlign", Align.JUSTIFY,
        vgroup(
          cellconfig("vIndex", 1, "marginY", 10),
          tf1,
          tf2
        ),
        bGroup
      ).layout(this);
    }
   
    public function watchClickOutside(clickOutsideCallback : Function) : void {
      _clickOutsideCallback = clickOutsideCallback;
      stage.addEventListener(MouseEvent.MOUSE_DOWN, stageClick);
    }
   
    public function unwatchClickOutside() : void {
      stage.removeEventListener(MouseEvent.MOUSE_DOWN, stageClick);
    }
   
    private function stageClick(event : MouseEvent) : void {
      if (!hitTestPoint(event.stageX, event.stageY)) {
        _clickOutsideCallback(this);
      }
    }

    private function createButton(label : String, eventType : String) : Button {
      var button : Button = new Button();
      button.setSize(60, 22);
      button.label = label;
      button.addEventListener(ButtonEvent.CLICK, function(event : Event) : void {
        buttonClickHandler(eventType);
      });
      return button;
    }
   
    private function buttonClickHandler(eventType : String) : void {
      _clickCallback(this, eventType);
    }
  }
}
Alert.as
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
package layer.popup.alerttutorial.final {
  import com.gskinner.motion.GTween;
  import com.gskinner.motion.easing.Cubic;
  import com.gskinner.motion.easing.Sine;

  public class Alert {
    public static function show(
      headline : String, text : String, buttons : Array,
      modal : Boolean, hideOnClickOutside : Boolean,
      callback : Function, tweenIn : Boolean
    ) : void {
      var alert : AlertBox = new AlertBox(headline, text, buttons, callback);

      Globals.popUpManager.createPopUp(alert, true, modal);
     
      if (tweenIn) {
        var tween : GTween = new GTween();
        tween.target = alert;
        tween.ease = Sine.easeOut;
        tween.duration = .15;
 
        // tween position
        tween.setValue("x", alert.x);
        tween.setValue("y", alert.y);
        alert.x += alert.width/2;
        alert.y += alert.height/2;
        // tween scale
        alert.scaleX = alert.scaleY = 0;
        alert.scaleX = alert.scaleY = 0;
        tween.setValue("scaleX", 1);
        tween.setValue("scaleY", 1);
        // tween alpha
        alert.alpha = 0;
        tween.setValue("alpha", 1);
      }
     
      if (hideOnClickOutside) {
        alert.watchClickOutside(function() : void {
          if (alert.alpha != 1) return; // tween not finished yet
          hide(alert, true);
        });
      }
    }
   
    public static function hide(alert : AlertBox, tweenOut : Boolean) : void {
      alert.unwatchClickOutside();
     
      if (tweenOut) {
        var tween : GTween = new GTween();
        tween.target = alert;
        tween.ease = Cubic.easeIn;
        tween.duration = .2;
 
        // tween position
        tween.setValue("x", alert.x + alert.width/2);
        tween.setValue("y", alert.y + alert.height/2);
        // tween scale
        tween.setValue("scaleX", 0);
        tween.setValue("scaleY", 0);
        // tween alpha
        tween.setValue("alpha", 0);
       
        tween.onComplete = function(tween : GTween) : void {
          Globals.popUpManager.removePopUp(alert);
        };

      } else {
        Globals.popUpManager.removePopUp(alert);
      }
    }
  }
}
Globals.as
1
2
3
4
5
6
package layer.popup.alerttutorial.final {
  import org.as3commons.ui.layer.PopUpManager;
  public class Globals {
    public static var popUpManager : PopUpManager;
  }
}
ModalOverlay.as
1
2
3
4
5
6
7
8
9
10
11
12
package layer.popup.alerttutorial.final {
  import flash.display.Sprite;
  public class ModalOverlay extends Sprite {
    public function ModalOverlay() {
      with (graphics) {
        clear();
        beginFill(0x000000, .3);
        drawRect(0, 0, 100, 100);
      }
    }
  }
}


1 Comment

  1. dheivarasu

    21. November 2011

    hi..

Leave a Comment

You have a question or have experienced an issue? Please post it in the forum: http://sibirjak.tenderapp.com/ in order to make the discussion available at a more central place.