Monday, September 10, 2012

Creating Advanced Alert Window class: Part 8

Today we're going to add support for gradient color filled rectangles for alert window's header and body.

Create a new class similar to SolidColorRect, call it GradientColorRect.

Declare the following variables:

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 _lineThickness:Number;
public var _lineColor:uint;
public var _lineAlpha:Number;
public var _radius:Array;

Add the constructor which receives all the values and applies them to these varaibles:

public function GradientColorRect(gradientType:String, colors:Array, alphas:Array, ratios:Array, matrix:Matrix = null, spreadMethod:String = "pad", interpolationMethod:String = "rgb", focalPointRation:Number = 0, lineThickness:Number = 1, lineColor:uint = 0x000000, lineAlpha:Number = 1, 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;
_lineThickness = lineThickness;
_lineColor = lineColor;
_lineAlpha = lineAlpha;
_radius = cornerRadius;
}

The usage of the parameters is explained in the comments:

/**
 * Create a gradient filled rectangle. Has the same parameters as beginGradientFill(), plus lineThickness, lineColor, lineAlpha and 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.
 * @paramlineThickness Thickness of line stroke.
 * @paramlineColor Color of line stroke.
 * @paramlineAlpha Alpha of line stroke.
 * @paramcornerRadius Radius of the corners of the box - top left, top right, bottom left, bottom right.
 */

Full class code:

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 _lineThickness:Number;
public var _lineColor:uint;
public var _lineAlpha:Number;
public var _radius:Array;

/**
 * Create a gradient filled rectangle. Has the same parameters as beginGradientFill(), plus lineThickness, lineColor, lineAlpha and 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.
 * @paramlineThickness Thickness of line stroke.
 * @paramlineColor Color of line stroke.
 * @paramlineAlpha Alpha of line stroke.
 * @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, lineThickness:Number = 1, lineColor:uint = 0x000000, lineAlpha:Number = 1, 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;
_lineThickness = lineThickness;
_lineColor = lineColor;
_lineAlpha = lineAlpha;
_radius = cornerRadius;
}

}

}

Go to AdvAlertWindow.as class and find the updateDraw() function. Add 2 if...statements that draw background and header in case if bgRect or headerRect is an object of GradientColorRect class.

We simply pass the values that we received from the skin object:

public function updateDraw():void {
// bg
this.graphics.clear();
if (bgRect is SolidColorRect) {
this.graphics.beginFill(bgRect._backgroundColor, bgRect._alpha);
this.graphics.lineStyle(bgRect._lineThickness, bgRect._lineColor, bgRect._lineAlpha);
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.lineStyle(bgRect._lineThickness, bgRect._lineColor, bgRect._lineAlpha);
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
if (headerRect is SolidColorRect) {
this.graphics.beginFill(headerRect._backgroundColor, headerRect._alpha);
this.graphics.lineStyle(headerRect._lineThickness, headerRect._lineColor, headerRect._lineAlpha);
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.lineStyle(headerRect._lineThickness, headerRect._lineColor, headerRect._lineAlpha);
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;
}

Full class 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:*;

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

public function updateDraw():void {
// bg
this.graphics.clear();
if (bgRect is SolidColorRect) {
this.graphics.beginFill(bgRect._backgroundColor, bgRect._alpha);
this.graphics.lineStyle(bgRect._lineThickness, bgRect._lineColor, bgRect._lineAlpha);
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.lineStyle(bgRect._lineThickness, bgRect._lineColor, bgRect._lineAlpha);
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
if (headerRect is SolidColorRect) {
this.graphics.beginFill(headerRect._backgroundColor, headerRect._alpha);
this.graphics.lineStyle(headerRect._lineThickness, headerRect._lineColor, headerRect._lineAlpha);
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.lineStyle(headerRect._lineThickness, headerRect._lineColor, headerRect._lineAlpha);
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;
}


}

}

Now we can create a custom skin that uses gradient background in main.as.

An example of creating and applying such a skin:

package  
{
import com.kircode.AdvAlert.AdvAlertManager;
import com.kircode.AdvAlert.AdvAlertSkin;
import com.kircode.AdvAlert.GradientColorRect;
import com.kircode.AdvAlert.SolidColorRect;
import flash.display.MovieClip;
import flash.events.Event;
import flash.geom.Matrix;
import flash.geom.Point;
import flash.display.GradientType;
/**
 * ...
 * @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 {
var mySkin:AdvAlertSkin = new AdvAlertSkin();
var matrix:Matrix = new Matrix();
matrix.createGradientBox(300, 200, 3.14, 0, 0);
mySkin.bgRect = new GradientColorRect(GradientType.LINEAR, [0x8888ff, 0x0000ff], [1, 1], [0, 255], matrix, "pad", "rgb", 0, 2, 0x4444aa, 1, [20, 00, 0, 20]);

AlertManager = new AdvAlertManager(this, stage.stageWidth, stage.stageHeight, mySkin);
AlertManager.alert("Text message.", "Custom skin - way 1");
}

}

}

Thanks for reading!

4 comments:

Aimo said...

It would be nice to see a picture of what it looks like.

Jury said...

What's your problem? You can copy and paste the code into your IDE, to see the result without pictures :)

Aimo said...

I read this blog in my mobile gadget, and I have no IDE :/

Kirill Poletaev said...

The reason I haven't put up pictures yet is because there is not much to show (the code right now is more impressive than the visual results).

In 13th part of the tutorial (which is sort of a milestone) I'll put up a picture of what the window with default skin looks like.

Since I've scheduled that ahead, I can give you a sneak peek! Note that the screenshot is from part 13 and, even though it's a milestone, it still lacks most of the elements and functionality I've planned.

Thanks for following my tutorials!

Post a Comment