Tuesday, September 25, 2012

Creating Advanced Alert Window class: Part 23

In this tutorial we'll add click event listeners to our buttons, add a way for developers to handle the events, and close the alert window on button press.

First of all, we'll need to go to AdvAlertButton.as and set the txt variable public instead of private:

public var txt;

Full AdvAlertButton.as code:

package com.kircode.AdvAlert 
{
import flash.display.MovieClip;
import flash.events.MouseEvent;
import flash.geom.Point;
import flash.text.TextField;
import flash.text.TextFormat;
import flash.ui.Mouse;

/**
 * Advanced Alert window object.
 * @author Kirill Poletaev
 */
public class AdvAlertButton extends MovieClip
{

public var w:Number;
public var h:Number;
public var currentSkin:AdvAlertButtonSkin;
public var txt;

private var textFormat:TextFormat;
private var bgStroke:*;
private var bgRect:*;
private var pos:Point;
private var textPadding:TextPadding;
private var filt:Array;

private var hover_w:Number;
private var hover_h:Number;
private var hover_textFormat:TextFormat;
private var hover_bgStroke:*;
private var hover_bgRect:*;
private var hover_pos:Point;
private var hover_textPadding:TextPadding;
private var hover_filt:Array;

private var textField:TextField;
private var over:Boolean = false;

/**
 * Button object placed in the alert window.
 * @paramlabel Text label of the button.
 */

public function AdvAlertButton(label:String, skin:AdvAlertButtonSkin = null) 
{
txt = label;
textField = new TextField();
addChild(textField);

if (skin == null) {
skin = new AdvAlertButtonSkin();
setSkin(skin);
currentSkin = null;
}else{
setSkin(skin);
}

updateDraw();

addEventListener(MouseEvent.ROLL_OVER, onOver);
addEventListener(MouseEvent.ROLL_OUT, onOut);
}

private function onOver(evt:MouseEvent):void {
over = true;
updateDraw();
Mouse.cursor = "button";
}

private function onOut(evt:MouseEvent):void {
over = false;
updateDraw();
Mouse.cursor = "auto";
}

public function setSkin(skin:AdvAlertButtonSkin):void {
currentSkin = skin;
w = skin.w;
h = skin.h;
textFormat = skin.textFormat;
bgStroke = skin.bgStroke;
bgRect = skin.bgRect;
pos = skin.pos;
textPadding = skin.textPadding;
filt = skin.filters;
hover_w = skin.hover_w;
hover_h = skin.hover_h;
hover_textFormat = skin.hover_textFormat;
hover_bgStroke = skin.hover_bgStroke;
hover_bgRect = skin.hover_bgRect;
hover_pos = skin.hover_pos;
hover_textPadding = skin.hover_textPadding;
hover_filt = skin.hover_filters;
}

public function updateDraw():void {
this.graphics.clear();

if(!over){
//filters
this.filters = filt;

// bg stroke
if (bgStroke is SolidColorStroke) {
this.graphics.lineStyle(bgStroke._lineThickness, bgStroke._lineColor, bgStroke._lineAlpha);
}
if (bgStroke is GradientColorStroke) {
this.graphics.lineStyle(bgStroke._lineThickness);
this.graphics.lineGradientStyle(bgStroke._gradientType, bgStroke._colors, bgStroke._alphas, bgStroke._ratios, bgStroke._matrix, bgStroke._spreadMethod, bgStroke._interpolationMethod, bgStroke._focalPointRatio);
}
if (bgStroke is BitmapStroke) {
this.graphics.lineStyle(bgStroke._lineThickness);
this.graphics.lineBitmapStyle(bgStroke._bitmap, bgStroke._matrix, bgStroke._repeat, bgStroke._smooth);
}

// bg fill
if (bgRect is SolidColorRect) this.graphics.beginFill(bgRect._backgroundColor, bgRect._alpha);
if (bgRect is GradientColorRect) this.graphics.beginGradientFill(bgRect._gradientType, bgRect._colors, bgRect._alphas, bgRect._ratios, bgRect._matrix, bgRect._spreadMethod, bgRect._interpolationMethod, bgRect._focalPointRatio);
if (bgRect is BitmapRect) this.graphics.beginBitmapFill(bgRect._bitmap, bgRect._matrix, bgRect._repeat, bgRect._smooth);

this.graphics.drawRoundRectComplex(pos.x, pos.y, w, h,
bgRect._radius[0], bgRect._radius[1], bgRect._radius[2], bgRect._radius[3]);
this.graphics.endFill();

// text field
textField.width = w;
textField.height = h;
textField.text = txt;
textField.setTextFormat(textFormat);
textField.selectable = false;
textField.x = pos.x + textPadding.right;
textField.y = pos.y + textPadding.top;
}

if(over){
//filters
this.filters = hover_filt;

// bg stroke
if (hover_bgStroke is SolidColorStroke) {
this.graphics.lineStyle(hover_bgStroke._lineThickness, hover_bgStroke._lineColor, hover_bgStroke._lineAlpha);
}
if (hover_bgStroke is GradientColorStroke) {
this.graphics.lineStyle(hover_bgStroke._lineThickness);
this.graphics.lineGradientStyle(hover_bgStroke._gradientType, hover_bgStroke._colors, hover_bgStroke._alphas, hover_bgStroke._ratios, hover_bgStroke._matrix, hover_bgStroke._spreadMethod, hover_bgStroke._interpolationMethod, hover_bgStroke._focalPointRatio);
}
if (hover_bgStroke is BitmapStroke) {
this.graphics.lineStyle(hover_bgStroke._lineThickness);
this.graphics.lineBitmapStyle(hover_bgStroke._bitmap, hover_bgStroke._matrix, hover_bgStroke._repeat, hover_bgStroke._smooth);
}

// bg fill
if (hover_bgRect is SolidColorRect) this.graphics.beginFill(hover_bgRect._backgroundColor, hover_bgRect._alpha);
if (hover_bgRect is GradientColorRect) this.graphics.beginGradientFill(hover_bgRect._gradientType, hover_bgRect._colors, hover_bgRect._alphas, hover_bgRect._ratios, hover_bgRect._matrix, hover_bgRect._spreadMethod, hover_bgRect._interpolationMethod, hover_bgRect._focalPointRatio);
if (hover_bgRect is BitmapRect) this.graphics.beginBitmapFill(hover_bgRect._bitmap, hover_bgRect._matrix, hover_bgRect._repeat, hover_bgRect._smooth);

this.graphics.drawRoundRectComplex(hover_pos.x, hover_pos.y, hover_w, hover_h,
hover_bgRect._radius[0], hover_bgRect._radius[1], hover_bgRect._radius[2], hover_bgRect._radius[3]);
this.graphics.endFill();

// text field
textField.width = hover_w;
textField.height = hover_h;
textField.text = txt;
textField.setTextFormat(hover_textFormat);
textField.selectable = false;
textField.x = hover_pos.x + hover_textPadding.right;
textField.y = hover_pos.y + hover_textPadding.top;
}
}


}

}

Now go to AdvAlertManager class, and find the alert() function.

Add one more optional parameter to the function - a Function closeHandler, set to null by default.

public function alert(text:String, title:String = "", buttons:Array = null, closeHandler:Function = null, width:int = 300, height:int = 200, position:Point = null):void {

Declare a variable currentIndex, which stores the index of this alert window, by using the windows.length value before adding a new element to windows array.

var currentIndex:int = windows.length;

In the for loop inside this function, if the provided button is a legit button, add a click event listener for it.

for (var i:int = buttons.length - 1; i >= 0; i--) {
if (!buttons[i] is AdvAlertButton) {
throw new Error("An item in 'buttons' array is not an AdvAlertButton instance. Ignoring...");
buttons.splice(i, 1);
}else {
buttons[i].addEventListener(MouseEvent.CLICK, buttonHandler);
}
}

Add an internal function buttonHandler, handle the mouse event. If closeHandler is not null, call the closeHandler function, pass 1 attribute value - evt.currentTarget.txt (the label of the button). Delete the window and its blur screen using the windows array, delete the element from the windows array.

function buttonHandler(evt:MouseEvent):void {
if (closeHandler != null) closeHandler.call(evt.currentTarget, evt.currentTarget.txt);
windows[currentIndex].window.parent.removeChild(windows[currentIndex].window);
windows[currentIndex].blur.parent.removeChild(windows[currentIndex].blur);
windows.splice(currentIndex,1);
}

Full function:

/**
 * Create an alert window.
 * @paramtext Text value of the alert window.
 * @paramtitle Title value of the alert window.
 * @parambuttons (Optional) Array of AdvAlertButton objects that represent buttons in the alert window.
 * @paramcloseHandler (Optional) Close handling function. Must receive a string value as parameter (which will hold the label of the button that was clicked).
 * @paramwidth (Optional) Width of the alert window. 300 by default.
 * @paramheight (Optional) Height of the alert window. 200 by default.
 * @paramposition (Optional) Coordinates of top-left corner of the alert window. If not specified - the window is centered.
 */

public function alert(text:String, title:String = "", buttons:Array = null, closeHandler:Function = null, width:int = 300, height:int = 200, position:Point = null):void {
if (position == null) position = new Point((pWidth / 2) - (width / 2), (pHeight / 2) - (height / 2));
if (buttons == null) buttons = [];
for (var i:int = buttons.length - 1; i >= 0; i--) {
if (!buttons[i] is AdvAlertButton) {
throw new Error("An item in 'buttons' array is not an AdvAlertButton instance. Ignoring...");
buttons.splice(i, 1);
}else {
buttons[i].addEventListener(MouseEvent.CLICK, buttonHandler);
}
}
var w:AdvAlertWindow = new AdvAlertWindow(text, title, width, height, position, skin, buttons, bSkin);
var b:AdvAlertBlur = new AdvAlertBlur(pWidth, pHeight, skin);
var currentIndex:int = windows.length;
windows.push( { window:w, blur:b } );
defaultContainer.addChild(b);
defaultContainer.addChild(w);

function buttonHandler(evt:MouseEvent):void {
if (closeHandler != null) closeHandler.call(evt.currentTarget, evt.currentTarget.txt);
windows[currentIndex].window.parent.removeChild(windows[currentIndex].window);
windows[currentIndex].blur.parent.removeChild(windows[currentIndex].blur);
windows.splice(currentIndex,1);
}
}

Full AdvAlertManager class:

package com.kircode.AdvAlert 
{
import flash.display.DisplayObjectContainer;
import flash.display.MovieClip;
import flash.events.MouseEvent;
import flash.geom.Point;
/**
 * Advanced Alert window manager.
 * @author Kirill Poletaev
 */
public class AdvAlertManager 
{
private var windows:Array;
private var defaultContainer:DisplayObjectContainer;
private var pWidth:int;
private var pHeight:int;
private var skin:AdvAlertSkin;
private var bSkin:AdvAlertButtonSkin;

/**
 * AdvAlertManager constructor.
 * @paramdefaultWindowContainer Parent container of alert windows.
 * @paramparentWidth Container's width.
 * @paramparentHeight Container's height.
 * @paramwindowSkin Default skin for alert windows.
 * @parambuttonSkin Default skin for buttons in this window.
 */

public function AdvAlertManager(defaultWindowContainer:DisplayObjectContainer, parentWidth:int, parentHeight:int, windowSkin:AdvAlertSkin = null, buttonSkin:AdvAlertButtonSkin = null) 
{
trace(": AdvAlertManager instance created.");
skin = windowSkin;
bSkin = buttonSkin;
if (skin == null) skin = new AdvAlertSkin();
if (bSkin == null) bSkin = new AdvAlertButtonSkin();
defaultContainer = defaultWindowContainer;
pWidth = parentWidth;
pHeight = parentHeight;
windows = [];
}

/**
 * Set skin of all future created alert windows.
 * @paramwindowSkin Reference to an AdvAlertSkin object.
 */

public function setSkin(windowSkin:AdvAlertSkin):void {
skin = windowSkin;
}

/**
 * Set skin of all buttons of future created alert windows.
 * @parambuttonSkin Reference to an AdvAlertButtonSkin object.
 */

public function setButtonSkin(buttonSkin:AdvAlertButtonSkin):void {
bSkin = buttonSkin;
}

/**
 * Create an alert window.
 * @paramtext Text value of the alert window.
 * @paramtitle Title value of the alert window.
 * @parambuttons (Optional) Array of AdvAlertButton objects that represent buttons in the alert window.
 * @paramcloseHandler (Optional) Close handling function. Must receive a string value as parameter (which will hold the label of the button that was clicked).
 * @paramwidth (Optional) Width of the alert window. 300 by default.
 * @paramheight (Optional) Height of the alert window. 200 by default.
 * @paramposition (Optional) Coordinates of top-left corner of the alert window. If not specified - the window is centered.
 */

public function alert(text:String, title:String = "", buttons:Array = null, closeHandler:Function = null, width:int = 300, height:int = 200, position:Point = null):void {
if (position == null) position = new Point((pWidth / 2) - (width / 2), (pHeight / 2) - (height / 2));
if (buttons == null) buttons = [];
for (var i:int = buttons.length - 1; i >= 0; i--) {
if (!buttons[i] is AdvAlertButton) {
throw new Error("An item in 'buttons' array is not an AdvAlertButton instance. Ignoring...");
buttons.splice(i, 1);
}else {
buttons[i].addEventListener(MouseEvent.CLICK, buttonHandler);
}
}
var w:AdvAlertWindow = new AdvAlertWindow(text, title, width, height, position, skin, buttons, bSkin);
var b:AdvAlertBlur = new AdvAlertBlur(pWidth, pHeight, skin);
var currentIndex:int = windows.length;
windows.push( { window:w, blur:b } );
defaultContainer.addChild(b);
defaultContainer.addChild(w);

function buttonHandler(evt:MouseEvent):void {
if (closeHandler != null) closeHandler.call(evt.currentTarget, evt.currentTarget.txt);
windows[currentIndex].window.parent.removeChild(windows[currentIndex].window);
windows[currentIndex].blur.parent.removeChild(windows[currentIndex].blur);
windows.splice(currentIndex,1);
}
}

}

}

Now you can create listeners for buttons, and the buttons close the alert windows on click.

Example in main.as:

private function init(evt:Event):void {
var mySkin:AdvAlertSkin = new AdvAlertSkin();
mySkin.buttonbarAlign = "center";

AlertManager = new AdvAlertManager(this, stage.stageWidth, stage.stageHeight, mySkin);
AlertManager.alert("This is an alert window with the default skin.", "Example alert!", [new AdvAlertButton("OK"), new AdvAlertButton("Cancel"), new AdvAlertButton("Back")], onClose);
}

private function onClose(label:String):void {
trace("Button clicked: " + label);
}

Thanks for reading!

No comments:

Post a Comment