Showing posts with label advanced. Show all posts
Showing posts with label advanced. Show all posts

Sunday, February 1, 2015

Creating Advanced Alert Window class Part 10

In this tutorial we will improve our skinning system. Well add support for skinning strokes and fills separately, so that its also possible to use solid colored, gradient and bitmap line strokes.

We will start by creating a new class called SolidColorStroke.as.

Add 3 variables:

public var _lineThickness:Number;
public var _lineColor:uint;
public var _lineAlpha:Number;

Receive the values in constructor and apply them to these variables:

package com.kircode.AdvAlert 
{
/**
* ...
* @author Kirill Poletaev
*/
public class SolidColorStroke
{
public var _lineThickness:Number;
public var _lineColor:uint;
public var _lineAlpha:Number;

/**
* Create a solid colored line stroke for rectangles.
* @paramlineThickness Thickness of the stroke.
* @paramlineColor Color of the stroke.
* @paramlineAlpha Alpha channel of the stroke.
*/

public function SolidColorStroke(lineThickness:Number = 1, lineColor:uint = 0x333333, lineAlpha:Number = 1)
{
_lineThickness = lineThickness;
_lineColor = lineColor;
_lineAlpha = lineAlpha;
}

}

}

Now we need to go to SolidColorRect, GradientColorRect and BitmapRect and remove these three variables from each class completely.

New SolidColorRect.as:

package com.kircode.AdvAlert 
{
/**
* ...
* @author Kirill Poletaev
*/
public class SolidColorRect
{
public var _backgroundColor:uint;
public var _radius:Array;
public var _alpha:Number;

/**
* Create a rectangle filled with solid color.
* @parambackgroundColor Background color fill of the box.
* @paramcornerRadius Radius of the corners of the box - top left, top right, bottom left, bottom right.
* @paramalpha Alpha channel of the background fill.
*/

public function SolidColorRect(backgroundColor:uint = 0xE2E2E2, cornerRadius:Array = null, alpha:Number = 1)
{
if (cornerRadius == null) cornerRadius = [10, 10, 0, 0];
_backgroundColor = backgroundColor;
_radius = cornerRadius;
_alpha = alpha
}

}

}

New GradientColorRect.as:

package com.kircode.AdvAlert 
{
import flash.geom.Matrix;
/**
* ...
* @author Kirill Poletaev
*/
public class GradientColorRect
{
public var _gradientType:String;
public var _colors:Array;
public var _alphas:Array;
public var _ratios:Array;
public var _matrix:Matrix;
public var _spreadMethod:String;
public var _interpolationMethod:String;
public var _focalPointRatio:Number;
public var _radius:Array;

/**
* Create a gradient filled rectangle. Has the same parameters as beginGradientFill(), plus cornerRadius.
* @paramgradientType A value from the GradientType class that specifies which gradient type to use: GradientType.LINEAR or GradientType.RADIAL.
* @paramcolors An array of RGB hexadecimal color values used in the gradient; for example, red is 0xFF0000, blue is 0x0000FF, and so on. You can specify up to 15 colors. For each color, specify a corresponding value in the alphas and ratios parameters.
* @paramalphas An array of alpha values for the corresponding colors in the colors array; valid values are 0 to 1. If the value is less than 0, the default is 0. If the value is greater than 1, the default is 1.
* @paramratios An array of color distribution ratios; valid values are 0-255. This value defines the percentage of the width where the color is sampled at 100%. The value 0 represents the left position in the gradient box, and 255 represents the right position in the gradient box.
* @parammatrix A transformation matrix as defined by the flash.geom.Matrix class. The flash.geom.Matrix class includes a createGradientBox() method, which lets you conveniently set up the matrix for use with the beginGradientFill() method.
* @paramspreadMethod A value from the SpreadMethod class that specifies which spread method to use, either: SpreadMethod.PAD, SpreadMethod.REFLECT, or SpreadMethod.REPEAT.
* @paraminterpolationMethod A value from the InterpolationMethod class that specifies which value to use: InterpolationMethod.LINEAR_RGB or InterpolationMethod.RGB
* @paramfocalPointRation A number that controls the location of the focal point of the gradient. 0 means that the focal point is in the center. 1 means that the focal point is at one border of the gradient circle. -1 means that the focal point is at the other border of the gradient circle. A value less than -1 or greater than 1 is rounded to -1 or 1.
* @paramcornerRadius Radius of the corners of the box - top left, top right, bottom left, bottom right.
*/

public function GradientColorRect(gradientType:String, colors:Array, alphas:Array, ratios:Array, matrix:Matrix = null, spreadMethod:String = "pad", interpolationMethod:String = "rgb", focalPointRation:Number = 0, cornerRadius:Array = null)
{
if (cornerRadius == null) cornerRadius = [10, 10, 0, 0];
_gradientType = gradientType;
_colors = colors;
_alphas = alphas;
_ratios = ratios;
_matrix = matrix;
_spreadMethod = spreadMethod;
_interpolationMethod = interpolationMethod;
_focalPointRatio = focalPointRation;
_radius = cornerRadius;
}

}

}

New BitmapRect.as:

package com.kircode.AdvAlert 
{
import flash.display.BitmapData;
import flash.geom.Matrix;
/**
* ...
* @author Kirill Poletaev
*/
public class BitmapRect
{
public var _bitmap:BitmapData;
public var _matrix:Matrix;
public var _repeat:Boolean;
public var _smooth:Boolean;
public var _radius:Array;
public var _alpha:Number;

/**
* Create a rectangle filled with bitmap. Has the same parameters as beginBitmapFill(), plus lineThickness, lineColor, lineAlpha and cornerRadius.
* @parambitmap BitmapData to be used to fill the rectangle.
* @parammatrix Matrix object for transformation.
* @paramrepeat Repeat the bitmap when filling.
* @paramsmooth Smoothen the bitmap.
* @paramcornerRadius Radius of the corners of the box - top left, top right, bottom left, bottom right.
* @paramalpha Alpha channel of the background fill.
*/

public function BitmapRect(bitmap:BitmapData, matrix:Matrix = null, repeat:Boolean = true, smooth:Boolean = false, cornerRadius:Array = null, alpha:Number = 1)
{
if (cornerRadius == null) cornerRadius = [10, 10, 0, 0];
_bitmap = bitmap;
_matrix = matrix;
_repeat = repeat;
_smooth = smooth;
_radius = cornerRadius;
_alpha = alpha
}

}

}

Go to AdvAlertSkin.as. Add 2 new variables - bgStroke and headerStroke, set them to new SolidColorStroke objects in the constructor:

package com.kircode.AdvAlert 
{
import flash.text.TextFormat;
/**
* Object containing skinning data for AdvAlertWindow.
* @author Kirill Poletaev
*/
public class AdvAlertSkin
{

public var textPadding:TextPadding;
public var headerPadding:TextPadding;
public var titlePadding:TextPadding;
public var headerHeight:int;
public var titleFormat:TextFormat;
public var textFormat:TextFormat;
public var selectable:Boolean;
public var headerRect:*;
public var bgRect:*;
public var bgStroke:*;
public var headerStroke:*;

public function AdvAlertSkin()
{
// default values
textPadding = new TextPadding(5, 5, 5, 5);
headerPadding = new TextPadding(5, 5, 5, 5);
titlePadding = new TextPadding(2, 2, 2, 2);
headerHeight = 30;
titleFormat = new TextFormat();
titleFormat.size = 20;
titleFormat.font = "Arial";
titleFormat.bold = true;
titleFormat.color = 0xffffff;
textFormat = new TextFormat();
textFormat.size = 16;
textFormat.font = "Arial";
textFormat.color = 0xffffff;
selectable = false;
bgRect = new SolidColorRect(0x7777cc, [10, 10, 10, 10], 1);
headerRect = new SolidColorRect(0x9999ff, [10, 10, 0, 0], 1);
bgStroke = new SolidColorStroke(2, 0x4444aa, 1);
headerStroke = new SolidColorStroke(0, 0x000000, 0);
}

}

}

Now go to AdvAlertWindow.as and add The headerStroke and bgStroke variables here too:

private var headerStroke:*;
private var bgStroke:*;

Apply values in the setSkin() function:

public function setSkin(skin:AdvAlertSkin):void {
textPadding = skin.textPadding;
headerPadding = skin.headerPadding;
titlePadding = skin.titlePadding;
headerHeight = skin.headerHeight;
titleFormat = skin.titleFormat;
textFormat = skin.textFormat;
selectable = skin.selectable;
bgRect = skin.bgRect;
headerRect = skin.headerRect;
bgStroke = skin.bgStroke;
headerStroke = skin.headerStroke;
}

Now set line styles in updateDraw() before drawing the rectangles.

// bg stroke
if (bgStroke is SolidColorStroke) {
this.graphics.lineStyle(bgStroke._lineThickness, bgStroke._lineColor, bgStroke._lineAlpha);
}

// header stroke
if (headerStroke is SolidColorStroke) {
this.graphics.lineStyle(headerStroke._lineThickness, headerStroke._lineColor, headerStroke._lineAlpha);
}

Full AdvAlertWindow.as code:

package com.kircode.AdvAlert 
{
import flash.display.MovieClip;
import flash.geom.Point;
import flash.text.TextField;
import flash.text.TextFormat;
import flash.display.GradientType;

/**
* Advanced Alert window object.
* @author Kirill Poletaev
*/
public class AdvAlertWindow extends MovieClip
{
private var t:String;
private var tt:String;
private var w:int;
private var h:int;
private var pos:Point;

private var textField:TextField;
private var titleField:TextField;

private var textPadding:TextPadding;
private var headerPadding:TextPadding;
private var titlePadding:TextPadding;
private var headerHeight:int;
private var titleFormat:TextFormat;
private var textFormat:TextFormat;
private var selectable:Boolean;
private var headerRect:*;
private var bgRect:*;
private var headerStroke:*;
private var bgStroke:*;

public function AdvAlertWindow(pt:String, ptt:String, pw:int, ph:int, ppos:Point, sk:AdvAlertSkin)
{
t = pt;
tt = ptt;
w = pw;
h = ph;
pos = ppos;

setSkin(sk);

textField = new TextField();
addChild(textField);

titleField = new TextField();
addChild(titleField);

updateDraw();
}

public function setSkin(skin:AdvAlertSkin):void {
textPadding = skin.textPadding;
headerPadding = skin.headerPadding;
titlePadding = skin.titlePadding;
headerHeight = skin.headerHeight;
titleFormat = skin.titleFormat;
textFormat = skin.textFormat;
selectable = skin.selectable;
bgRect = skin.bgRect;
headerRect = skin.headerRect;
bgStroke = skin.bgStroke;
headerStroke = skin.headerStroke;
}

public function updateDraw():void {
this.graphics.clear();
// bg stroke
if (bgStroke is SolidColorStroke) {
this.graphics.lineStyle(bgStroke._lineThickness, bgStroke._lineColor, bgStroke._lineAlpha);
}
// bg fill
if (bgRect is SolidColorRect) {
this.graphics.beginFill(bgRect._backgroundColor, bgRect._alpha);
this.graphics.drawRoundRectComplex(pos.x, pos.y, w, h,
bgRect._radius[0], bgRect._radius[1], bgRect._radius[2], bgRect._radius[3]);
this.graphics.endFill();
}
if (bgRect is GradientColorRect) {
this.graphics.beginGradientFill(bgRect._gradientType, bgRect._colors, bgRect._alphas, bgRect._ratios, bgRect._matrix, bgRect._spreadMethod, bgRect._interpolationMethod, bgRect._focalPointRatio);
this.graphics.drawRoundRectComplex(pos.x, pos.y, w, h,
bgRect._radius[0], bgRect._radius[1], bgRect._radius[2], bgRect._radius[3]);
this.graphics.endFill();
}
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();
}
// header stroke
if (headerStroke is SolidColorStroke) {
this.graphics.lineStyle(headerStroke._lineThickness, headerStroke._lineColor, headerStroke._lineAlpha);
}
// header fill
if (headerRect is SolidColorRect) {
this.graphics.beginFill(headerRect._backgroundColor, headerRect._alpha);
this.graphics.drawRoundRectComplex(pos.x + headerPadding.left, pos.y + headerPadding.top, w - (headerPadding.left + headerPadding.right), headerHeight,
headerRect._radius[0], headerRect._radius[1], headerRect._radius[2], headerRect._radius[3]);
this.graphics.endFill();
}
if (headerRect is GradientColorRect) {
this.graphics.beginGradientFill(headerRect._gradientType, headerRect._colors, headerRect._alphas, headerRect._ratios, headerRect._matrix, headerRect._spreadMethod, headerRect._interpolationMethod, headerRect._focalPointRatio);
this.graphics.drawRoundRectComplex(pos.x + headerPadding.left, pos.y + headerPadding.top, w - (headerPadding.left + headerPadding.right), headerHeight,
headerRect._radius[0], headerRect._radius[1], headerRect._radius[2], headerRect._radius[3]);
this.graphics.endFill();
}
if (headerRect is BitmapRect) {
this.graphics.beginBitmapFill(headerRect._bitmap, headerRect._matrix, headerRect._repeat, headerRect._smooth);
this.graphics.drawRoundRectComplex(pos.x + headerPadding.left, pos.y + headerPadding.top, w - (headerPadding.left + headerPadding.right), headerHeight,
headerRect._radius[0], headerRect._radius[1], headerRect._radius[2], headerRect._radius[3]);
this.graphics.endFill();
}
// title
titleField.width = w - (headerPadding.left + headerPadding.right);
titleField.text = tt;
titleField.height = headerHeight;
titleField.x = pos.x + headerPadding.left + titlePadding.left;
titleField.y = pos.y + headerPadding.top + titlePadding.top;
// text
textField.width = w - (textPadding.right + textPadding.left);
textField.height = h - (textPadding.top + textPadding.bottom + headerPadding.top + headerPadding.bottom + headerHeight);
textField.text = t;
textField.x = pos.x + textPadding.right;
textField.y = pos.y + textPadding.top + headerHeight + headerPadding.bottom + headerPadding.top;
// formats
textField.setTextFormat(textFormat);
titleField.setTextFormat(titleFormat);
textField.selectable = selectable;
titleField.selectable = selectable;
textField.multiline = true;
textField.wordWrap = true;
}


}

}

You can create an alert with a default skin in main.as:

package  
{
import com.kircode.AdvAlert.AdvAlertManager;
import com.kircode.AdvAlert.AdvAlertSkin;
import com.kircode.AdvAlert.BitmapRect;
import flash.display.BitmapData;
import flash.display.MovieClip;
import flash.events.Event;
/**
* ...
* @author Kirill Poletaev
*/
public class main extends MovieClip
{
private var AlertManager:AdvAlertManager;

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

private function init(evt:Event):void {
AlertManager = new AdvAlertManager(this, stage.stageWidth, stage.stageHeight);
AlertManager.alert("Text message.", "Title");
}

}

}

And youll see that the default strokes are displayed properly. You are also able to set your own custom values for the stroke. The visuals of the alert window did not change, but the code behind it sure did - it is now easier to manage strokes and fills separately, and well add new types of stroke skinning in the next tutorials.

Thanks for reading!
Read more »

Thursday, January 22, 2015

Creating Advanced Alert Window class Part 39

In this tutorial we will add the ability to add default button index for alert windows (for tab navigation), as well as improve the tab navigation itself.

By adding a default button index I mean setting an index of the button that the developer wants to be selected by default. So, if the alert pops up and the user simply presses Enter on his keyboard, the default button is pressed. The default index is 0 by default (which represents the first button in the array).

There are a few things we need to keep in mind while implementing the feature.

The first important thing is that when there are more than 1 alert windows present, when the user closes the first one, we need to update the new button index (focusedButton variable) according to the next windows default button index.

The second thing is related to how we handle tab navigation. Right now the kDown function increases focusedButton by 1 and executes all the code in it using that value, which is why we have focusedButton set to -1 by default (-1 + 1 = 0, and 0 is the index we want to start with). Were going to modify the code, so that the focusedButton value is increased by 1 ONLY if there is a button in the window, which has "over" property set to true.

This means, that if the default button index is 1 (second button), and there are no buttons currently rolled over or selected using tab, if the user presses Enter - the second button is pressed. If they press Tab, the second button is selected, instead of third, so that the user can see what button is highlighted and press enter again to press it.

So, as long as nothing is initially selected: pressing Enter = pressing Tab and then Enter.

This makes the navigation more user-friendly and intuitive.

Lets get started. Go to AdvAlertManager class, find the alert() function and add a new parameter to it right after the buttons one - defaultButton:int = 0.

public function alert(text:String, title:String = "", buttons:Array = null, defaultButton:int = 0, closeHandler:Function = null, width:int = 0, height:int = 0, position:Point = null, minHeight:int = 0, maxHeight:int = 0, maxWidth:int = 0, horizontalStretch:Boolean = true, openSound:Sound = null):AdvAlertWindow {

Add a new parameter to the object that is added to the windows array in alert() function - set the attribute name to defButton and the value to defaultButton:

windows.push( {window:w, blur:b, onclose:closeHandler, defButton:defaultButton} );

In the same function set focusedButton to defaultButton:

focusedButton = defaultButton;

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.
* @paramdefaultButton (Optional) Index of the default button (used for tab navigation).
* @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. If 0, set to default.
* @paramheight (Optional) Height of the alert window. If 0, set to default. If default is 0, window will be auto sized.
* @paramposition (Optional) Coordinates of top-left corner of the alert window. If not specified - the window is centered.
* @paramminHeight (Optional) The minimum height value of the alert window. If 0, set to default.
* @parammaxHeight (Optional) The maximum height value of the alert window. If 0, set to default.
* @parammaxWidth (Optional) The maximum width value of the alert window. If 0, set to default.
* @paramhorizontalStretch (Optional) If set to true, will stretch the window horizontally if the text doesnt fit and the height has already reached maxHeight.
* @paramopenSound (Optional) Sound to play when the window opens. Specified default sound plays by default.
*/

public function alert(text:String, title:String = "", buttons:Array = null, defaultButton:int = 0, closeHandler:Function = null, width:int = 0, height:int = 0, position:Point = null, minHeight:int = 0, maxHeight:int = 0, maxWidth:int = 0, horizontalStretch:Boolean = true, openSound:Sound = null):AdvAlertWindow {
if (width == 0) width = defWidth;
if (height == 0) height = defHeight;
if (minHeight == 0) minHeight = defMinHeight;
if (maxHeight == 0) maxHeight = defMaxHeight;
if (maxWidth == 0) maxWidth = defMaxWidth;
if (openSound != null) {
openSound.play();
}else
if (openingSound != null) {
openingSound.play();
}
if (position == null) position = new Point((pWidth / 2) - (width / 2), (pHeight / 2) - (height / 2));
if (buttons == null) buttons = [new AdvAlertButton("OK")];
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, pWidth, pHeight, minHeight, maxHeight, maxWidth, horizontalStretch);
var b:AdvAlertBlur = new AdvAlertBlur(pWidth, pHeight, skin);
var currentIndex:int = windows.length;
windows.push( {window:w, blur:b, onclose:closeHandler, defButton:defaultButton} );
defaultContainer.addChild(b);
defaultContainer.addChild(w);

topWindow = w;
focusedButton = defaultButton;
if (tabDisable) {
defaultContainer.tabChildren = false;
defaultContainer.tabEnabled = false;
}

function buttonHandler(evt:MouseEvent):void {
closeWindow(currentIndex, closeHandler, evt.currentTarget as AdvAlertButton);
}
return w;
}

Go to kDown() function. Inside the keyCode==9 if...statement add 2 variables - needIncrease and i.

Set needIncrease to false by default. Then loop through all buttons, and if at least one button has its over property set to true - set needIncrease to true.

Check if needIncrease is true, if so - increase focusedButton by 1.

private function kDown(evt:KeyboardEvent):void {
if(tabDisable){
if (evt.keyCode == 9 && topWindow != null && topWindow.buttons.length > 0) {
var needIncrease:Boolean = false;
var i:int;
for (i = 0; i < topWindow.buttons.length; i++) {
if (topWindow.buttons[i].over == true) needIncrease = true;
}
if (needIncrease) focusedButton++;
if (focusedButton >= topWindow.buttons.length) {
focusedButton = 0;
}
for (i = 0; i < topWindow.buttons.length; i++) {
topWindow.buttons[i].over = false;
topWindow.buttons[i].updateDraw();
}
topWindow.buttons[focusedButton].over = true;
topWindow.buttons[focusedButton].updateDraw();
}
if (evt.keyCode == 13 && topWindow != null && topWindow.buttons.length > 0) {
var currentIndex:int = windows.length - 1;
var closeHandler:Function = windows[currentIndex].onclose;
closeWindow(currentIndex, closeHandler, topWindow.buttons[focusedButton]);
}
}
}

Now go to closeWindow() function. Remove the line that sets focusedButton to -1, instead add a new line to windows.length>0 if...statement and set focusedButton to the defButton value of the next window:

private function closeWindow(currentIndex:int, closeHandler:Function, currentButton:AdvAlertButton):void {
if (closeHandler != null && currentButton != null) closeHandler.call(currentButton, currentButton.txt);
windows[currentIndex].window.parent.removeChild(windows[currentIndex].window);
windows[currentIndex].blur.parent.removeChild(windows[currentIndex].blur);
windows.splice(currentIndex, 1);
if (windows.length > 0) {
focusedButton = windows[windows.length - 1].defButton;
topWindow = windows[windows.length - 1].window;
}
if (windows.length == 0) topWindow = null;
if (tabDisable && windows.length==0) {
defaultContainer.tabChildren = true;
defaultContainer.tabEnabled = true;
}
}

And thats it!

Full AdvAlertManager class code:

package com.kircode.AdvAlert 
{
import flash.display.DisplayObjectContainer;
import flash.display.MovieClip;
import flash.display.Stage;
import flash.events.MouseEvent;
import flash.geom.Point;
import flash.events.KeyboardEvent;
import flash.events.Event;
import flash.media.Sound;
/**
* 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;
private var tabDisable:Boolean;
private var topWindow:AdvAlertWindow;
private var focusedButton:int;
private var stg:Stage;
private var openingSound:Sound;
private var defWidth:int;
private var defHeight:int;
private var defMinHeight:int;
private var defMaxHeight:int;
private var defMaxWidth:int;

/**
* AdvAlertManager constructor.
* @paramdefaultWindowContainer Parent container of alert windows.
* @paramstage Stage reference.
* @paramwindowSkin Default skin for alert windows.
* @parambuttonSkin Default skin for buttons in this window.
* @paramopenSound Default window open sound.
* @paramdisableTab Disable tab focusing on the parent container when an alert window is visible. This also enables tab navigation for the alert windows buttons.
* @paramdefaultWidth Set default width for all window alerts. 300 by default.
* @paramdefaultHeight Set default height for all window alerts. 0 by default. If 0, the window is auto-sized based on the text length.
* @paramdefaultMinHeight Set default minimal height for all window alerts. 0 by default.
* @paramdefaultMaxHeight Set default maximal height for all window alerts. 0 by default. If 0, automatically set to the height of the stage.
* @paramdefaultMaxWidth Set default maximal width for all window alerts. 0 by default. If 0, automatically set to the width of the stage.
*/

public function AdvAlertManager(defaultWindowContainer:DisplayObjectContainer, stage:Stage, windowSkin:AdvAlertSkin = null, buttonSkin:AdvAlertButtonSkin = null, openSound:Sound = null, disableTab:Boolean = true, defaultWidth:int = 300, defaultHeight:int = 0, defaultMinHeight:int = 0, defaultMaxHeight:int = 0, defaultMaxWidth:int = 0)
{
defWidth = defaultWidth;
defHeight = defaultHeight;
defMinHeight = defaultMinHeight;
defMaxHeight = defaultMaxHeight;
defMaxWidth = defaultMaxWidth;
if (defMaxHeight == 0) defMaxHeight = stage.stageHeight;
if (defMaxWidth == 0) defMaxWidth = stage.stageWidth;
openingSound = openSound;
skin = windowSkin;
bSkin = buttonSkin;
tabDisable = disableTab;
if (skin == null) skin = new AdvAlertSkin();
if (bSkin == null) bSkin = new AdvAlertButtonSkin();
defaultContainer = defaultWindowContainer;
pWidth = stage.stageWidth;
pHeight = stage.stageHeight;
stg = stage;
windows = [];
stg.addEventListener(KeyboardEvent.KEY_DOWN, kDown);
}

private function kDown(evt:KeyboardEvent):void {
if(tabDisable){
if (evt.keyCode == 9 && topWindow != null && topWindow.buttons.length > 0) {
var needIncrease:Boolean = false;
var i:int;
for (i = 0; i < topWindow.buttons.length; i++) {
if (topWindow.buttons[i].over == true) needIncrease = true;
}
if (needIncrease) focusedButton++;
if (focusedButton >= topWindow.buttons.length) {
focusedButton = 0;
}
for (i = 0; i < topWindow.buttons.length; i++) {
topWindow.buttons[i].over = false;
topWindow.buttons[i].updateDraw();
}
topWindow.buttons[focusedButton].over = true;
topWindow.buttons[focusedButton].updateDraw();
}
if (evt.keyCode == 13 && topWindow != null && topWindow.buttons.length > 0) {
var currentIndex:int = windows.length - 1;
var closeHandler:Function = windows[currentIndex].onclose;
closeWindow(currentIndex, closeHandler, topWindow.buttons[focusedButton]);
}
}
}

/**
* Close the top alert window.
*/

public function closeLast():void {
var currentIndex:int = windows.length - 1;
var closeHandler:Function = windows[currentIndex].onclose;
closeWindow(currentIndex, closeHandler, null);
}

private function closeWindow(currentIndex:int, closeHandler:Function, currentButton:AdvAlertButton):void {
if (closeHandler != null && currentButton != null) closeHandler.call(currentButton, currentButton.txt);
windows[currentIndex].window.parent.removeChild(windows[currentIndex].window);
windows[currentIndex].blur.parent.removeChild(windows[currentIndex].blur);
windows.splice(currentIndex, 1);
if (windows.length > 0) {
focusedButton = windows[windows.length - 1].defButton;
topWindow = windows[windows.length - 1].window;
}
if (windows.length == 0) topWindow = null;
if (tabDisable && windows.length==0) {
defaultContainer.tabChildren = true;
defaultContainer.tabEnabled = true;
}
}

/**
* 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;
}

/**
* Set new options for the alert manager object - has the same parameters as the constructor.
* @paramdefaultWindowContainer Parent container of alert windows.
* @paramstage Stage reference.
* @paramwindowSkin Default skin for alert windows.
* @parambuttonSkin Default skin for buttons in this window.
* @paramopenSound Default window open sound.
* @paramdisableTab Disable tab focusing on the parent container when an alert window is visible. This also enables tab navigation for the alert windows buttons.
* @paramdefaultWidth Set default width for all window alerts. 300 by default.
* @paramdefaultHeight Set default height for all window alerts. 0 by default. If 0, the window is auto-sized based on the text length.
* @paramdefaultMinHeight Set default minimal height for all window alerts. 0 by default.
* @paramdefaultMaxHeight Set default maximal height for all window alerts. 0 by default. If 0, automatically set to the height of the parent.
* @paramdefaultMaxWidth Set default maximal width for all window alerts. 0 by default. If 0, automatically set to the width of the stage.
*/

public function reset(defaultWindowContainer:DisplayObjectContainer, stage:Stage, windowSkin:AdvAlertSkin = null, buttonSkin:AdvAlertButtonSkin = null, openSound:Sound = null, disableTab:Boolean = true, defaultWidth:int = 300, defaultHeight:int = 0, defaultMinHeight:int = 0, defaultMaxHeight:int = 0, defaultMaxWidth:int = 0)
{
defWidth = defaultWidth;
defHeight = defaultHeight;
defMinHeight = defaultMinHeight;
defMaxHeight = defaultMaxHeight;
defMaxWidth = defaultMaxWidth;
if (defMaxHeight == 0) defMaxHeight = stage.stageHeight;
if (defMaxWidth == 0) defMaxWidth = stage.stageWidth;
openingSound = openSound;
skin = windowSkin;
bSkin = buttonSkin;
tabDisable = disableTab;
if (skin == null) skin = new AdvAlertSkin();
if (bSkin == null) bSkin = new AdvAlertButtonSkin();
defaultContainer = defaultWindowContainer;
pWidth = stage.stageWidth;
pHeight = stage.stageHeight;
stg = stage;
}

/**
* 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.
* @paramdefaultButton (Optional) Index of the default button (used for tab navigation).
* @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. If 0, set to default.
* @paramheight (Optional) Height of the alert window. If 0, set to default. If default is 0, window will be auto sized.
* @paramposition (Optional) Coordinates of top-left corner of the alert window. If not specified - the window is centered.
* @paramminHeight (Optional) The minimum height value of the alert window. If 0, set to default.
* @parammaxHeight (Optional) The maximum height value of the alert window. If 0, set to default.
* @parammaxWidth (Optional) The maximum width value of the alert window. If 0, set to default.
* @paramhorizontalStretch (Optional) If set to true, will stretch the window horizontally if the text doesnt fit and the height has already reached maxHeight.
* @paramopenSound (Optional) Sound to play when the window opens. Specified default sound plays by default.
*/

public function alert(text:String, title:String = "", buttons:Array = null, defaultButton:int = 0, closeHandler:Function = null, width:int = 0, height:int = 0, position:Point = null, minHeight:int = 0, maxHeight:int = 0, maxWidth:int = 0, horizontalStretch:Boolean = true, openSound:Sound = null):AdvAlertWindow {
if (width == 0) width = defWidth;
if (height == 0) height = defHeight;
if (minHeight == 0) minHeight = defMinHeight;
if (maxHeight == 0) maxHeight = defMaxHeight;
if (maxWidth == 0) maxWidth = defMaxWidth;
if (openSound != null) {
openSound.play();
}else
if (openingSound != null) {
openingSound.play();
}
if (position == null) position = new Point((pWidth / 2) - (width / 2), (pHeight / 2) - (height / 2));
if (buttons == null) buttons = [new AdvAlertButton("OK")];
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, pWidth, pHeight, minHeight, maxHeight, maxWidth, horizontalStretch);
var b:AdvAlertBlur = new AdvAlertBlur(pWidth, pHeight, skin);
var currentIndex:int = windows.length;
windows.push( {window:w, blur:b, onclose:closeHandler, defButton:defaultButton} );
defaultContainer.addChild(b);
defaultContainer.addChild(w);

topWindow = w;
focusedButton = defaultButton;
if (tabDisable) {
defaultContainer.tabChildren = false;
defaultContainer.tabEnabled = false;
}

function buttonHandler(evt:MouseEvent):void {
closeWindow(currentIndex, closeHandler, evt.currentTarget as AdvAlertButton);
}
return w;
}

}

}

Now you acn go to main.as and try this code, which creates 2 windows with 3 buttons each, but different default indices. If you just press enter (or tab and then enter), youll see that different buttons are selected by default in each window.

private function init(evt:Event):void {
var mySkin:AdvAlertSkin = new AdvAlertSkin();
mySkin.addContent(warning_icon, new Point(5, 40));
mySkin.textPadding.left = 140;
mySkin.titleFilters = [new DropShadowFilter(0, 0, 0, 1, 3, 3, 2, 3)];
mySkin.textFilters = [new DropShadowFilter(1, 45, 0, 0.4, 0, 0, 5, 1)];

var myButtonSkin:AdvAlertButtonSkin = new AdvAlertButtonSkin();
myButtonSkin.textFilters = [new DropShadowFilter(1, 45, 0, 0.4, 0, 0, 5, 1)];
myButtonSkin.hover_textFilters = [new DropShadowFilter(1, 45, 0, 0.4, 0, 0, 5, 1), new DropShadowFilter(0, 0, 0, 1, 3, 3, 1, 3)];

AlertManager = new AdvAlertManager(this, stage, mySkin, myButtonSkin);
AlertManager.alert("A window with 3 buttons. Default index: 1", "Example alert!", [new AdvAlertButton("One"), new AdvAlertButton("Two"), new AdvAlertButton("Three")], 1, onClose, 300, 200);
AlertManager.alert("A window with 3 buttons. Default index: 2", "Example alert!", [new AdvAlertButton("One"), new AdvAlertButton("Two"), new AdvAlertButton("Three")], 2, onClose, 300, 200);
}

private function onClose(str:String):void {
trace(str);
}

Thanks for reading!
Read more »