AS3 Button with Text and Basic Styling

It’s been a while since I had the opportunity to work on a pure AS3 project. I recently had a need for a simple AS3 button that displays text and decided to customize the SimpleButton control. As I quickly discovered, the SimpleButton control isn’t really setup to support text or a lot of other features, and hacking these features into it doesn’t make much sense. So I built a quick little class that emulates the behavior of SimpleButton but could display text and offer a few other features for styling the button dynamically.

SimpleButtonProject.swf

SimpleButtonProject.as

package
{
	import com.components.CustomButton;
	import flash.display.Sprite;
	import flash.events.MouseEvent;

	[SWF( width = '200', height = '200', backgroundColor = '#FFFFFF', frameRate = '20')]
	public class SimpleButtonProject extends Sprite
	{
		private var button:CustomButton;

		public function SimpleButtonProject()
		{
			button = new CustomButton("Welcome");
			button.x = 0;
			button.addEventListener(MouseEvent.CLICK, handleMouseClick);
			addChild(button);
		}

		private function handleMouseClick(event:MouseEvent):void
		{
			button.label = "Clicked"

			/*
			     // remove the button and mark it for garbage collection
			     button.removeEventListener(MouseEvent.CLICK, handleMouseClick);
			     this.removeChild(button);
			     button = null;
			*/
		}
	}
}

CustomButton.as

package com.components
{
	import flash.display.Shape;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.text.TextField;
	import flash.text.TextFormat;
	import flash.text.TextFormatAlign;

	public class CustomButton extends Sprite
	{
		// ---- Properties -----

		protected var __button:CustomSimpleButton;
		protected var __txtFormat:TextFormat;
		protected var __txtField:TextField;
		protected var __background:Shape;
		protected var __hitarea:Sprite;

		protected var _label:String = "";
		protected var _font:String = "Arial";
		protected var _fontSize:int = 12;
		protected var _fontColor:uint = 0x000000;
		protected var _upColor:uint = 0xFFCC00;
		protected var _overColor:uint = 0xCCFF00;
		protected var _downColor:uint = 0x00CCFF;
		protected var _buttonWidth:int;
		protected var _buttonHeight:int;
		protected var _buttonStrokeColor:int = 0x000000;

		public function get label():String
		{
			return _label;
		}
		public function set label(value:String):void
		{
			_label = value;
			updateDisplayList();
		}

		public function get buttonStrokeColor():uint
		{
			return _buttonStrokeColor;
		}
		public function set buttonStrokeColor(value:uint):void
		{
			_buttonStrokeColor = value;
			updateDisplayList();
		}

		public function get font():String
		{
			return _font;
		}
		public function set font(value:String):void
		{
			_font = value;
			updateDisplayList();
		}

		public function get fontSize():int
		{
			return _fontSize;
		}
		public function set fontSize(value:int):void
		{
			_fontSize= value;
			updateDisplayList();
		}

		public function get fontColor():uint
		{
			return _fontColor;
		}
		public function set fontColor(value:uint):void
		{
			_fontColor= value;
			updateDisplayList();
		}

		public function get upColor():uint
		{
			return _upColor;
		}
		public function set upColor(value:uint):void
		{
			_upColor = value;
			updateDisplayList();
		}

		public function get overColor():uint
		{
			return _overColor;
		}
		public function set overColor(value:uint):void
		{
			_overColor = value;
		}

		public function get downColor():uint
		{
			return _downColor;
		}
		public function set downColor(value:uint):void
		{
			_downColor = value;
		}

		// ---- Constructor -----

		public function CustomButton(label:String = "", w:int = 80, h:int = 22)
		{
			super();

			if(label != "") this.label = label;

			this.addEventListener(Event.REMOVED_FROM_STAGE, destroy);

			_buttonWidth = w;
			_buttonHeight = h;

			createChildren();
			updateDisplayList();
		}

		// ---- Public Methods -----

		public function destroy(event:Event = null):void
		{
			this.removeEventListener(Event.REMOVED_FROM_STAGE, destroy);

			if(__background) {
				__background.graphics.clear();
				__background = null;
			}

			if(__hitarea){
				__hitarea.removeEventListener(MouseEvent.MOUSE_OVER, onMouseOver);
				__hitarea.removeEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
				__hitarea.removeEventListener(MouseEvent.MOUSE_UP, onMouseOver);
				__hitarea.removeEventListener(MouseEvent.MOUSE_OUT, onMouseOut);
				__hitarea.graphics.clear();
				__hitarea = null;
			}

			if(__txtField) {
				__txtField.text = "";
				__txtField = null;
				__txtFormat = null;
			}
		}

		// ---- Protected Methods -----

		protected function createChildren():void
		{
			if(!__background) {
				__background = new Shape();
				addChild(__background);
			}

			if(!__txtField) {
				__txtField = new TextField();
				__txtField.selectable = false
				addChild(__txtField);
			}

			if(!__hitarea) {
				__hitarea = new Sprite();
				__hitarea.addEventListener(MouseEvent.MOUSE_OVER, onMouseOver);
				__hitarea.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
				__hitarea.addEventListener(MouseEvent.MOUSE_UP, onMouseOver);
				__hitarea.addEventListener(MouseEvent.MOUSE_OUT, onMouseOut);
				addChild(__hitarea);
			}
		}

		protected function drawButtonBackground(color:uint):void
		{
			if(__background){
				__background.graphics.beginFill(color);
				__background.graphics.lineStyle(1, buttonStrokeColor);
				__background.graphics.drawRect(0, 0, _buttonWidth, _buttonHeight);
				__background.graphics.endFill();
			}
		}

		protected function updateDisplayList():void
		{
			if(__txtField){
				__txtFormat = new TextFormat(font, fontSize, fontColor, false, null, null, null, null, TextFormatAlign.CENTER);
				__txtField.width = _buttonWidth;
				__txtField.defaultTextFormat = __txtFormat;
				__txtField.text = _label;
				__txtField.y = (_buttonHeight - __txtField.textHeight)/2;
			}

			if(__background) {
				drawButtonBackground(upColor);
			}

			if(__hitarea){
				__hitarea.graphics.beginFill(0x000000, 0);
				__hitarea.graphics.drawRect(0, 0, _buttonWidth, _buttonHeight);
				__hitarea.graphics.endFill();
			}
		}

		protected function onMouseOver(e:Event):void
		{
			e.stopPropagation();
			drawButtonBackground(overColor);
		}

		protected function onMouseDown(e:Event):void
		{
			e.stopPropagation();
			drawButtonBackground(downColor);
		}

		protected function onMouseUp(e:Event):void
		{
			e.stopPropagation();
			drawButtonBackground(overColor);
		}

		protected function onMouseOut(e:Event):void
		{
			e.stopPropagation();
			drawButtonBackground(upColor);
		}
	}
}

So there you have it, a very simple button that displays text and has a few other features. I realize its not so simple ( # lines of code), but I added a lot of public properties to change the style and label dynamically, as well as logic for garbage collection. If you don’t need those extra features, you can easily be customize it to fit any your needs.

-Mister

2 Comments

  1. Thank you wery much for this awesome custom text button class !! =) That’s just what I needed and I was unable to do it.

    You saved me a lot of time ! Thank again !

    Florent.

Comments are closed.