Flash에는 Dialog 컴포넌트가 따로 없어 대화상자를 구현하기가 참 힘들다.
이번 프로젝트에서 구현할 일이 있어 만들게 되었는데 자주 사용할거 같아 기록해 둔다.
먼저 아래와 같은 형태로 대화상자 모양을 만들고 라이브러리에 등록한다.
등록할때 9-slice 를 체크하고 클래스를 Dialog 라는 이름으로 export한다.
#ads_1
Class 부분의 namespace는 본인의 환경에 맞게 기입한다.
아래는 소스다.
package com.plug.led {
import flash.display.Sprite;
import flash.display.Stage;
import flashx.textLayout.container.ContainerController;
import flash.text.TextField;
import flash.text.TextFieldAutoSize;
import flash.text.TextFormat;
import fl.controls.Button;
import flash.events.MouseEvent;
import flash.display.DisplayObjectContainer;
public class UserForm extends Sprite{
protected static var inst:UserForm = null;
protected static const BOTTOM_HEIGHT:int = 60;
protected var dialog:Dialog = null;
protected var lightbox:LightBox = null;
protected var par:DisplayObjectContainer = null;
protected var dialogTitle:String = null;
protected var dialogMessage:String = null;
protected var posiLabel:String = null;
protected var negaLabel:String = null;
protected var posiButton:Button = null;
protected var negaButton:Button = null;
protected var posiFunc:Function = null;
protected var negaFunc:Function = null;
public function UserForm(par:DisplayObjectContainer) {
this.par = par;
lightbox = new LightBox();
lightbox.alpha = 0.7;
addChild(lightbox);
dialog = new Dialog();
addChild(dialog);
}
public function showDialog():void{
//제목영역
var tformat:TextFormat = new TextFormat();
tformat.bold = true;
var dtitle:TextField = new TextField();
dtitle.text = dialogTitle;
dtitle.autoSize = TextFieldAutoSize.LEFT;
dtitle.setTextFormat(tformat);
dtitle.x = 10;
dtitle.y = (dialog.head.height - dtitle.height) / 2;
//trace(dialog.head.height + ', ' + dtitle.height);
dialog.addChild(dtitle);
//내용영역
drawBody();
resizing();
//버튼영역
var botY:Number = dialog.height - BOTTOM_HEIGHT;
if(posiLabel != null && negaLabel != null){
createPosiButton();
createNegaButton();
posiButton.x = dialog.width / 2 - posiButton.width - 10;
posiButton.y = botY + ((BOTTOM_HEIGHT - posiButton.height) / 2);
negaButton.x = dialog.width / 2 + 10;
negaButton.y = botY + ((BOTTOM_HEIGHT - negaButton.height) / 2);
dialog.addChild(posiButton);
dialog.addChild(negaButton);
}else{
createPosiButton();
posiButton.x = (dialog.width - posiButton.width) / 2;
posiButton.y = botY + ((BOTTOM_HEIGHT - posiButton.height) / 2);
dialog.addChild(posiButton);
}
//배경
lightbox.x = 0;
lightbox.y = 0;
lightbox.width = par.stage.stageWidth;
lightbox.height = par.stage.stageHeight;
lightbox.alpha = 0.5;
dialog.x = (par.stage.stageWidth - dialog.width) / 2;
dialog.y = (par.stage.stageHeight - dialog.height) / 2;
//trace(dialog.head.y + ', ' + dialog.head.height);
//trace(dialog.body.y + ', ' + dialog.body.height);
//trace(dialog.tail.y + ', ' + dialog.tail.height);
par.stage.addChild(this);
}
protected function drawBody():void{
var dmessage:TextField = new TextField();
dmessage.width = dialog.body.width;
dmessage.multiline = true;
dmessage.wordWrap = true;
dmessage.autoSize = TextFieldAutoSize.LEFT;
dmessage.text = dialogMessage;
dialog.body.addChild(dmessage);
}
private function resizing():void{
dialog.frame.height = dialog.head.height + dialog.body.height + BOTTOM_HEIGHT;
}
private function createPosiButton():void{
posiButton = new Button();
if(posiLabel != null) posiButton.label = posiLabel;
else posiButton.label = "확인";
var ref:DisplayObjectContainer = this;
posiButton.addEventListener(
MouseEvent.CLICK, function(e:MouseEvent):void{
if(!onPositiveClick(e)) return;
if(posiFunc != null){
posiFunc(ref);
}
closeDialog();
}
);
}
private function createNegaButton():void{
negaButton = new Button();
negaButton.label = negaLabel;
var ref:DisplayObjectContainer = this;
negaButton.addEventListener(
MouseEvent.CLICK, function(e:MouseEvent):void{
if(!onNegativeClick(e)) return;
if(negaFunc != null){
negaFunc(ref);
}
closeDialog();
}
);
}
public function hideDialog():void{
par.stage.removeChild(this);
}
public function setTitle(title:String):UserForm{
dialogTitle = title;
return this;
}
public function setMessage(message:String):UserForm{
dialogMessage = message;
return this;
}
public function setPositive(plabel:String, func:Function):UserForm{
setPositiveLabel(plabel);
setPositiveFunc(func);
return this;
}
public function setNegative(nlabel:String, func:Function):UserForm{
setNegativeLabel(nlabel);
setNegativeFunc(func);
return this;
}
public function setPositiveLabel(plabel:String):UserForm{
posiLabel = plabel;
return this;
}
public function setNegativeLabel(nlabel:String):UserForm{
negaLabel = nlabel;
return this;
}
public function setPositiveFunc(func:Function):UserForm{
posiFunc = func;
return this;
}
public function setNegativeFunc(func:Function):UserForm{
negaFunc = func;
return this;
}
public function closeDialog():void{
par.stage.removeChild(this);
}
/* override 용 */
protected function onPositiveClick(e:MouseEvent):Boolean{return true}
protected function onNegativeClick(e:MouseEvent):Boolean{return true}
public static function create(par:DisplayObjectContainer):UserForm{
inst = new UserForm(par);
return inst;
}
}
}
#ads_2
사용방법은 아래와 같다.
1. 일반 alert 창
UserForm.create(this) //this는 현재 MovieClip이나 Sprite의 인스턴스
.setTitle("경고")
.setMessage("삭제할까요?")
.showDialog();
2. 예/아니오 창
UserForm.create(this)
.setTitle("이메일확인")
.setPositive("확인", function(object:Object){
trace("확인을 눌렀음");
})
.setNegative("취소", function(object:Object){
trace("취소를 눌렀음");
})
.showDialog();
※ 소스중에 LightBox는 반투명 사각형을 라이브러리로등록한것에 불과하다. 사각형모양을 그리고 라이브러리를 만들어 준다. 등록할때 그냥 LightBox로 export해주면 된다.
이 클래스를 확장하여 폼입력을 받을 수도 있다.
아래는 이메일을 입력받는 대화상자이다.
package com.plug.led {
import flash.display.DisplayObjectContainer;
import flash.events.MouseEvent;
public class UserFormEmail extends UserForm{
public var formEmail:FormEmail = null;
public function UserFormEmail(par:DisplayObjectContainer) {
super(par);
formEmail = new FormEmail();
// constructor code
}
public function getEmail():String{
return formEmail.cl_email.text;
}
override protected function drawBody():void{
dialog.body.addChild(formEmail);
}
override protected function onPositiveClick(e:MouseEvent):Boolean{
if(Helper.trim(formEmail.cl_email.text) == ""){
Helper.alert(this, "이메일을 입력해 주세요",
function(object:Object):void{
formEmail.cl_email.setFocus();
}
);
return false;
}
return true;
}
public static function create(par:DisplayObjectContainer):UserFormEmail{
inst = new UserFormEmail(par);
return UserFormEmail(inst);
}
}
}
결과화면은 아래와 같다.(이미지 캡처가 좀 지저분하넹...쩝...)
#ads_3