[AS3] UIScrollBar 동적으로 스킨 적용하기

Programming/ActionScript 3.0 2007. 9. 12. 06:43
UIComponent에 해당하는 컴포넌트들의 스킨을 적용하는 방법에 대해서 FlashCS3의 레퍼런스에서는 컴포넌트를 라이브러리에 등록하고 등록된 컴포넌트를 스테이지에 끌어다 놓고 무비클립을 직접 수정하는 방법 이외에는 이렇다 할 설명을 하지 않고 있는 듯 하다.

개인적으로 웹상에 올려지는 스크립트들을 이쁘게(?!) 보이도록 만들어 보려고 AScodeViewer를 작업하고 있는데, 외부에 있는 Style xml 데이터를 로드하여 사용자가 작성한 xml에 따라서 UIScrollBar와 기타 화면상의 DisplayObject들의 스타일을 적용하는 과정에서 컴포넌트의 스킨을 동적으로 적용을 해야 했다. 웹상에서 찾아보았지만 그와 관련된 자료를 찾지 못하여 임의로 적용해 보게 되었다.

일단은 컴포넌트의 스킨을 동적으로 적용하기 위해서는 기존의 컴포넌트들이 어떠한 형태로 스킨을 적용하고 있는지, 구조를 파악할 필요가 있다. 컴포넌트를 스테이지에 올려놓고 안으로 들어가보면 해당 컴포넌트에서 사용되는 기능별 무비클립들을 볼 수 있는데 이러한 무비클립들은 2 프레임에 위치하고 있기 때문에 외부에서 직접 해당 무비클립에 접근 할 수는 없다.

라이브러리에 있는 Component Assets -> ScrollBarSkins 폴더에 보면 사용되는 무비클립들을 볼 수 있는데 이들 무비클립들에는 각각 내부 클래스가 지정되어 있다. 이 클래스들이 각각의 무비클립을 대변한다고 볼 수 있다.

그럼 각각의 무비클립의 색을 변경하기 위해서는 어떻게 해야 할까… 여러가지로 실험도 해보고 고민을 해보았는데 일단은 아래 방법은 개인적으로 작업하는 과정에서 만들어 낸 결과이기 때문에 옳은 방법이 아닐 수 있음을 밝혀둔다.

UIScrollBar 컴포넌트의 상속 관계에서 setStyle 메소드를 발견할 수 있는데 이 메소드는 스타일 적용에 필요한 default 클래스를 custom 클래스로 대체할 수 있도록 해준다. 따라서 setStyle 메소드를 통해서 기존에 등록되어 있는 각 무비클립의 클래스를 자신이 원하는 기능을 하는 클래스로 대체할 수 있다는 이야기다. 아래는 디폴트로 지정되어 있는 클래스들이다.

ScrollArrowDown_disabledSkin
ScrollArrowDown_downSkin
ScrollArrowDown_overSkin
ScrollArrowDown_upSkin
ScrollThumb_downSkin
ScrollBar_thumbIcon
ScrollThumb_overSkin
ScrollThumb_upSkin
ScrollTrack_Skin
ScrollArrowUp_disabledSkin
ScrollArrowUp_downSkin
ScrollArrowUp_overSkin
ScrollArrowUp_upSkin

그리고 아래는 디폴트 클래스와 매칭되는 문자열들이다.

downArrowDisabledSkin
downArrowDownSkin
downArrowOverSkin
downArrowUpSkin
thumbDownSkin
thumbIcon
thumbOverSkin
thumbUpSkin
trackSkin
upArrowDisabledSkin
upArrowDownSkin
upArrowOverSkin
upArrowUpSkin

일단 적용한 형태를 보면 아래와 같다.
private function setScrollBarStyle(s:UIScrollBar):void{
s.setStyle("downArrowDisabledSkin", DScrollArrowDown_disabledSkin);
s.setStyle("downArrowDownSkin", DScrollArrowDown_downSkin);
s.setStyle("downArrowOverSkin", DScrollArrowDown_overSkin);
s.setStyle("downArrowUpSkin", DScrollArrowDown_upSkin);

s.setStyle("upArrowDisabledSkin", DScrollArrowUp_disabledSkin);
s.setStyle("upArrowDownSkin", DScrollArrowUp_downSkin);
s.setStyle("upArrowOverSkin", DScrollArrowUp_overSkin);
s.setStyle("upArrowUpSkin", DScrollArrowUp_upSkin);

s.setStyle("thumbDownSkin", DScrollThumb_downSkin);
s.setStyle("thumbIcon", DScrollBar_thumbIcon);
s.setStyle("thumbOverSkin", DScrollThumb_overSkin);
s.setStyle("thumbUpSkin", DScrollThumb_upSkin);
s.setStyle("trackSkin", DScrollTrack_Skin);
}

위 코드에서는 적용할 UIScrollBar를 전달 받아서 setStyle 메소드를 통해서 각 무비클립의 클래스들을 새로운 클래스(D로 시작하는 클래스들)들로 대체했다. 새로 대체한 클래스에서는 각각 디폴트로 지정되어 있는 클래스들을 extends 시켰다. 이렇게 한 이유는 라이브러리에 있는 컴포넌트 무비클립들을 그대로 사용하기 위함이다.

이렇게 작성하게 되면 컴포넌트에서 사용하는 각각의 무비클립에서 원하는 기능을 수행할 수 있는 새로운 클래스들로 대체했기 때문에 새로 등록된 클래스 안에서 무슨 짓을 하더라도 플래시가 용서해 준다…쿠쿠

각 클래스 안에서는 자신의 무비클립의 색을 변경하는 클래스를 통해서 색과 알파값등을 세팅하도록 하였고 셋팅하는 방법으로는 중앙에 Singleton 클래스를 만들어 놓고 xml에서 전달받은 스타일을 각 무비클립에 입히는 방법으로 사용했다. 참고로 색 변경에 사용한 간단한 클래스도 올려 놓는다.
package viewer.skins{
import flash.display.DisplayObject;
import flash.geom.Transform;
import flash.geom.ColorTransform;

public class TintColor{
public function TintColor():void{}
public static function setTintColor(d:DisplayObject, c:uint, a:Number):void{
var resultColorTransform:ColorTransform = new ColorTransform();
resultColorTransform.alphaMultiplier = a;
resultColorTransform.color = c;

var transformation:Transform = d.transform;
transformation.colorTransform = resultColorTransform;
}
}
}

이 과정중에서 버그를 발견하게 되었는데 다른 것들은 위에서 언급한 문자열을 통해서 클래스를 대체할 수 있었으나 유독 trackSkin(스크롤바의 기본 바탕이 되는 배경)의 경우 클래스를 대체하지 못하는 문제가 있다. 이 문제로 검색을 해 보니 adobe에 버그로 등록되어 있는 것 같은데 그 해결책은 찾지 못하였다.. 그렇다고 그냥 지나칠 수 있낭…자존심이 허락하는 범위 안에서 꼼수를 부렸다.

적용한 방법은 쿠쿠 웃기는 이야기이긴 하지만 컴포넌트 스킨에서 스크롤바의 배경이 되는 무비클립을 투명으로 처리하고 스크롤바 아래에 무비클립을 두어 스테이지가 변경될 때 스크롤바의 크기와 위치에 따라 이동하는 배경 무비클립을 따로 만들어 놓고 그 무비클립의 색을 변경하는 방법으로 적용했다…쿠쿠 약간 찜찜하지만 trackSkin 버그 문제가 해결되기 전까지 임시방편으로 적용해 두기로 했다.

스테이지 상에서 무비클립들을 직접 수정하여 사용할 경우 일단 사용된 최초 컴포넌트만을 사용하기 때문에 서로 다른 스킨을 적용하기가 어렵지만 이러한 방법을 사용하면 컴포넌트 각 인스턴스에 개별적인 스킨을 적용할 수 있다.

AScodeViewer는 거의 85% 정도 완성된 것 같다. FlashDevelop의 as 코드 스킨과 스크립트 창의 배경까지 직접 xml을 편집하여 사용할 수 있도록 하였기 때문에 자신의 FlashDevelop 환경과 거의 비슷한 화면을 웹상에 올려놓을 수 있을 듯 싶다. FlashDevelop에서 사용하는 xml데이터를 그대로 사용하다보니 AS 코드 뿐만이 아니라 Java나 기타 언어에서도 사용 할 수 있을 듯 싶다. 중요 포인트는 풀스크린 모드 기능을 지원한다는 것이 아닐까 싶다....
    

설정

트랙백

댓글

  • 조기 2011.10.12 16:19 ADDR 수정/삭제 답글

    안녕하세요~ 글 잘읽었습니다. uiscrollbar가 아닌 그냥 scrollbar에서는 이 방법이 안 먹히더군요;;
    해결 방안이 있을 까요??