flex2로 만든 Tree로 메뉴를 보여주는 샘플 입니다. xml에서 데이터를 읽어 오기 때문에 메뉴 이름이나 URL이 변경되더라도 다시 컴파일할 필요가 없습니다. 그리고 제목을 클릭해도 오픈/클로즈가 가능하고 링크가 있을 시에는 해당 링크가 오픈됩니다.


lmenu.mxml (flex2 소스 파일)
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"
    creationComplete="initData()" width="180" height="200" fontSize="11">
    <mx:Script>
        <![CDATA[
            import mx.rpc.events.FaultEvent;
            import mx.rpc.events.ResultEvent;
            import flash.net.navigateToURL;

            /* murl 파라미터에서 설정된 url로 부터 xml 데이터를 가져 온다. */
            private function initData():void {
                xmlService.url = Application.application.parameters.murl;
                xmlService.send();
            }
           
            /* xml 가져오기 오류 시 메시지 출력 */
            private function faultHandler(event:FaultEvent):void {
                mx.controls.Alert.show(event.fault.message);
            }
           
            /* Tree 마우스 클릭 이벤트 처리 */
            private function onItemClicked(event:Event):void {
                if(event.currentTarget.selectedItem.@data) {
                   
                    /* 현재 선택된 아이템의 데이터 값을 가져 온다. */
                    var dataString:String = "";
                    dataString = event.currentTarget.selectedItem.@data;
                   
                    /* data(link)가 있을 시에는 url을 연다 */
                    if(dataString.length > 0)
                    {
                        var url:URLRequest = new URLRequest(dataString);
                        navigateToURL(url);
                    }   

                    /* 아이템이 열려 있으면 닫고, 닫혀있으면 연다 */
                    var openFlag = !(menuTree.isItemOpen(event.currentTarget.selectedItem) == true);
                    menuTree.expandItem(event.currentTarget.selectedItem, openFlag);   
                }
            }
        ]]>
    </mx:Script>

    <mx:HTTPService id="xmlService" resultFormat="e4x" fault="faultHandler(event)" useProxy="false" />
    <mx:XMLListCollection id="xc" source="{xmlService.lastResult.item}" />

    <mx:Tree id="menuTree" labelField="@label" showRoot="true"
        x="0" y="0" width="180" height="200"
        dataProvider="{xc}" click="onItemClicked(event);" />
</mx:Application>
현재 창에서 링크가 열리기를 원하시면 navigateToURL(url)을 navigateToURL(url, "_self")로 변경합니다.

test.html (html 샘플 파일)
<html lang="ko">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Flex Menu Test</title>
<script type="text/javascript">
function goURL(url)
{
    document.location.href = url;
}
</script>
</head>
<body>
<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
            id="flexMenu" width="500" height="400"
            codebase= "http://fpdownload.macromedia.com/get/flashplayer/current/swflash.cab">
<param name="movie" value="[swf url]?murl=[xml url]" />
<param name="quality" value="high" />
<embed src="[swf url]?murl=[xml url]" quality="high" bgcolor="#efefef"
                width="500" height="400" name="flex" align="middle"
                play="true"
                loop="false"
                quality="high"
                type="application/x-shockwave-flash"
                pluginspage="http://www.adobe.com/go/getflashplayer">
            </embed>
    </object>
</body>
</html>
murl로 xml 파일의 url을 전달합니다.

[swf url] 컴파일된 swf 파일의 url입니다.
[xml url] 메뉴 구조가 정의된 xml의 url입니다. 구조는 아래와 같습니다.

src와 movie에서의 내용을http://www.domain1.com/lmenu.swf?murl=http://www.domain2.com/menu.xml 과 같이 입력하시면 됩니다.

menu.xml (메뉴 구조 샘플 파일)
<?xml version="1.0" encoding="UTF-8"?>
<root>
    <item label="포탈 사이트">
        <item label="네이버" data="http://www.naver.com"/>
        <item label="다음" data="http://www.daum.net"/>
        <item label="야후" data="http://www.yahoo.co.kr"/>
        <item label="엠파스" data="http://www.empas.com"/>
    </item>
    <item label="블로그">
        <item label="내 블로그" data="http://www.cocoadev.co.kr"/>
        <item label="올블로그" data="http://www.allblog.net"/>
        <item label="티스토리" data="http://www.tisotry.com"/>
    </item>
</root>
서브 메뉴를 포함하고 있을 때는 "<item>[.. sub item]</item>"과 같이 포함하지 않으면 "<item />"과 같이 사용하시면 됩니다. 링크가 필요한 경우에는 item의 data 필드를 이용합니다.

crossdomain.xml
<?xml version="1.0"?>
<cross-domain-policy>
    <allow-access-from domain="*"/>
</cross-domain-policy>

swf가 있는 도메인과 xml이 있는 도메인이 다를 경우에는 xml이 있는 곳에 위와 같은 crossdomain.xml 파일이 존재하여야 합니다.

1. 프로젝트 및 관련 파일 생성

Xcode를 실행하고 New Project를 클릭합니다. 이전 포스트에서 추가한 Flash >  FlexApplication을 선택하고 "Hello"란 이름으로 프로젝트를 생성합니다.

사용자 삽입 이미지
Hello 프로젝트를 우클릭하고 Add/NewFile 메뉴에서 액션스크립트를 위한 소스 파일인 Hello.as와 테스트를 위한 Test.html을 생성합니다.

좌측과 같이 생성되어 있음을 확인합니다.



2. Hello.mxml 편집

하나의 버튼을 추가하고 과 Hello.as 파일을 인클루드 하기위해 아래의 내용을 추가합니다.

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" xmlns="*" layout="absolute">
    <mx:Script source="Hello.as"/>
   
    <mx:Box backgroundColor="#efefef" width="200" height="100" horizontalAlign="center" verticalAlign="middle">
    <mx:Button label="Click" click="buttonClicked()"/>
    </mx:Box>   
</mx:Application>


3. Test.html 편집

생성된 Hello.swf를 테스트 하기 위한 html 파일을 편집합니다.

<html lang="ko">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Flex Hello</title>
</head>
<body>
<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
            id="flexTest" width="200" height="100"
            codebase= "http://fpdownload.macromedia.com/get/flashplayer/current/swflash.cab">
<param name="movie" value="bin/Hello.swf" />
<param name="quality" value="high" />
<embed src="bin/Hello.swf" quality="high" bgcolor="#efefef"
                width="200" height="100" name="flex" align="middle"
                play="true"
                loop="false"
                quality="high"
                type="application/x-shockwave-flash"
                pluginspage="http://www.adobe.com/go/getflashplayer">
            </embed>
    </object>
</body>
</html>


3. Hello.as 편집

버튼이 클릭되었을 경우 호출되는 "buttonClicked" 메소드를 작성합니다. 간단히 Hello World 창을 오픈합니다.

function buttonClicked()
{
    mx.controls.Alert.show('Hello World!', 'Flex');
}     


4. 확인

사용자 삽입 이미지
파일들을 저작하고 빌드를 실행합니다. 빌드가 오류없이 완료되면, Test.html 파일을 우클릭하여 Open With Finder를 클릭합니다.

Test.html이 브라우져에서 실행됩니다.


아래와 같이 사파리에서 Test.html이 오픈됩니다.. "Click" 버튼을 누르면 우측과 같이 Hello 메시지 창이 뜨는 것을 확인할 수 있습니다.
사용자 삽입 이미지사용자 삽입 이미지

몇일전 즉흥적으로 Flex에 대한 포스트를 올렸다가, 댓글을 주신 Jason님의 블로그에서 흥미있는 내용을 발견하였습니다. Xcode에서 Flex를 개발하는 방법에 관한 링크였습니다. 이번 내용들은 그 링크가 된 사이트인 joshbuhler.com에 서 보고 따라 해 본 것입니다.


방법 1

1. Flex SDK 설치

아도비 사이트에서 free Flex SDK를 다운로드 받습니다. 다운로드 받은 폴더를 flex로 변경하고 /Developer/SDKs/ 아래로 옮겨 놓습니다.(원작자 분이 거기다 놓는게 좋답니다. 나중에 보니 이해가 가더군요.) 쓰기 권한이 없기 때문에 복사를 할 수가 없어, 터미널에서 root 계정으로 옮겨 놓았습니다. 파인더에서 아래와 같이 flex가 복사 되어 있음을 확인합니다.
(저는 flex2로 했는데 이는 나중에 두번째 방법에서 번거로움이 있으니 flex로 하시기 바랍니다.)

사용자 삽입 이미지


2. Xcode 설정

1) Project 생성

사용자 삽입 이미지
이제 Xcode를 실행하고 New Project에서 새로운 프로젝트를 생성합니다. Empty Project를 선택합니다.

New Project를 처음 본 것은 아닌데 맨 위의 Empty Project는 처음 보는 항목이었습니다.





2)  사용자빌드 환경 설정

Xcode 좌측의 Groups & Files 바로 아래에서 프로젝트명을 더블클릭하여 Info창을 열고 Genral 항목을 선택합니다. 하단에서 Cross-Devleop Using Target SDK 항목을 Other로 변경합니다. 변경 후에 확인하는 경고창이 뜨는데 Change를 클릭합니다. 그리고 아래의 Choose 버튼을 클릭하여 이전 단계에서 flex를 설치한 디렉토리를 선택합니다.

사용자 삽입 이미지


사용자 삽입 이미지
좌측과 같이 타겟을 우클릭(or control+클릭)하여 Add/New Target을 선택합니다. 선택창에서 Special Targets > External Target을 선택하고 Next를 클릭합니다.

Taget Name을 mxmlc로 하고 종료 합니다.


Targets 밑에 mxmlc가 생성된 것을 확인하시고 mxmlc를 더블클릭하여 아래와 같은 정보 창을 오픈합니다.
사용자 삽입 이미지

위와 같이 Build Tool에 /usr/bin/java 를 입력하시고, Arguments에는 -jar $(SDKROOT)/lib/mxmlc.jar -flexlib $(SDKROOT)/frameworks -verbose=true -file-specs $(PROJECT_NAME).as 와 같이 입력합니다.


3) 소스 파일 생성

눈여겨 보실점은 $(PROJECT_NAME).as로 되어 있으니, 후에 생성할 소스파일명이 프로젝트와 동일해야 합니다. 저는  testFlex로 하였으니 testFlex.as로 생성하였습니다. 소스 파일명을 변경하실려면 이 부분을 변경하셔야 할 것 같습니다.

사용자 삽입 이미지
이제 좌측과 같이 New File...을 클릭합니다. 첫번째 항목인 Empty File in Project를 선택하고 프로젝트명과 동일하게 파일명을 testFlex.as로 하고 종료 합니다.



아래와 같이 소스 파일과 타겟이 생성된 것을 확인합니다.
사용자 삽입 이미지

열심히 해 보았지만 위의 -flexlib 옵션 때문에 컴파일 시 오류가 납니다. 다시 잘 살펴 보니 글 쓴 시점이 2005년 10월 21일이고 아래와 같은 내용을 보았습니다.
사용자 삽입 이미지

빌드 오류는 그 사이 Flex SDK가 업그레이드 되면서 변경사항이 있었는 것 같습니다. 터미널 쉘상에서 해봐도 마찬가지였습니다. 일단 Xcode의 새로운 사용법을 알았다는데 만족하고 새로운 링크로 다시 갑니다.


방법 2

방법1에서와 같이 flex SDK를 다운 받고 /Developer/SDKs/flex에 flexSDK에 있어야 합니다.

1. Flex 프로젝트 템플릿 설치

원 저작자가 만드신 것 같은데 프로젝트 템플릿 파일을 다운 받습니다. 압축을 풀고 생성된 FlexApplication 디렉토리를 /Library/Application Support/Apple/Developer Tools/Project Templates /Flash로 복사합니다. 마지막에 /Flash 디렉토리는 만드셔야 합니다.

위의 폴더를 보시면  Xcode에서 프로젝트 생성 시 나오는 템플릿들과 같은 내용을 보실 수 있습니다.


2. 프로젝트 생성

사용자 삽입 이미지
이제 Xcode를 다시 실행하고 새로운 프로젝트를 만드시면 좌측과 같이 Flash 밑에 FlexApplication이라는 새로운 항목이 생긴 것을 보실 수 있습니다.

이 항목을 선택하고 새로운 프로젝트를 생성합니다. 위에서 수동으로 작업하였던 내용이 자동으로 설정되어 있으며, [프로젝트명].mxml이 생성되어 있음을 확인하실 수 있습니다.




Custom Build Command를 확인하시면 방법1의 java를 이용한 것과는 달리 다른 명령어와 인자로 되어 있습니다. java에 의존하던 것을 네이티브한 실행파일로 변경한 것인지는 잘 모르겠습니다.

사용자 삽입 이미지

위 1의 방법에서 아래의 내용으로 변경하고 mxml파일을 프로젝트에 추가해주면 컴파일이 가능할 것 같습니다. Build Tool에 보면 경로이 Flex로 자동으로 설정되어 있는데, 저는 괜히 처음에 flex2로 만들어 놓아 flex2로 변경하였습니다. 빈 프로젝트지만 컴파일은 이상이 없었습니다. 간단한 Flex 사용기는 다음으로 미룰려고 합니다.

쉽게 Xcode에서 Flex를 사용할 수 있는 방법을 알려주신 Jason님에게  감사드립니다. 사실 Josh님께도 감사를 드려야 하는데 "hi, thanks ^^"만 쓰고 튈수도 없고 해서 그냥 마음으로만 드립니다.

이전 어쩔 수없이 짧은 지식으로 플래쉬 작업을 한 적이 있습니다. 타임라인이니 레이어 같은 알수 없는 환경에 좌절하고 오로지 액션스크립트로만 작업을 하고 넘겼는데, 플래쉬를 하시는 분이 소스를 보셨으면 무슨 생각이 드셨을지 모르겠네요. 아마 회사에 엄청 불만있는 사람으로 생각했을 것 같습니다.
 
아직도 모르겠지만 플래쉬에 비해 개발자 친화적인 환경과 공짜라는 점에 무척 관심이 갑니다. 코코아는 물만 끓여 놓고  자꾸 딴데만 두리번 거리고 있네요.

오늘 오전에 유프리에 관련된 포스트를 보았습니다. 관련된 글을 읽다 아래와 같은 내용을 보았습니다.
ETRI는 유프리를 공개SW로 배포하여 자신이 필요한 각종 SW를 사용자가 직접 개발할 수 있게 유도하고 유프리 센터를 통해 배포하여 공개SW의 활성화에 기여할 수 있을 것이라고 기대했다.
내용 중 "사용자가 직접 개발"이란 문구를 보고 바로 사이트로 가 보았습니다. 웹 주소가 http://www.youfree.or.kr/flex/로 뒤에 flex가 눈에 확 들어 오더군요. 아~ 아도비의 플렉스를 이용한 기술인가 보다 하고 많은 기대를 하였습니다.

제가 못 찾은 것인지 사이트 어디에서도 개발자 버젼은 찾을 수가 없었습니다. 그래서 일반 사용자 버젼인 YouFREE 베이직을 다운 받았습니다. 다운로드 받은 압축 파일을 풀다 보니 *.dll, *.exe 파일들이 보이더군요. 확인을 해봤었어야 했는데 윈도우즈 전용이었습니다.

다시 비스타에서 다운로드 받아서 설치를 해 보았습니다. 아파치와 MySQL에서 사용하는 포트를 현재 다른 프로그램에서 사용중이라고 정상적인 실행이 안된다고 메시지가 나왔습니다.(사용하는 프로그램 없는데...) etri 사이트에 가서 보니 비스타와 리눅스는 아직 지원하지 않는다는 내용을 보고 지웠습니다.

내용을 자세히 읽어 보지 않아서 그런지, 관련 사이트의 글들을 보고는 뭐하는 프로그램인지 정확히 모르겠네요. 아쉬움에 플렉스라도 깔아 보자라는 생각으로 아도비 사이트에서 다운로드 받고 설치해 보았습니다.

30일 사용 가능한 무료 버젼을 다운로드 받았는데, 사이트에서 가격을 보니 249달러 였습니다. 설치는 쉽게 되고 튜토리얼중 하나를 따라해 보았습니다. 막연히 플랙스는 플래쉬와 유사한 것으로 생각했었는데 일단 처음 본 모습과 언어는 제 생각과 틀렸습니다. 통합개발툴은 이클립스를 기반으로 만들어진 것 같습니다.

사용자 삽입 이미지

튜토리얼 내용을 보면서 New/Flex Project를 클릭했습니다.  뭔지 모르지만 Basic을 선택하고 Next를 클릭했습니다. 그리고 프로젝트명에 Test를 입력하고 Finish를 클릭했습니다.

사용자 삽입 이미지

그 후 소스파일 편집에 튜토리얼에서 본 내용중 블로그 주소만 제 블로그의 RSS 주소로 변경하였습니다.

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
    creationComplete="feedRequest.send()" layout="absolute">

    <mx:HTTPService
        id="feedRequest"
        url="http://www.cocoadev.co.kr/rss/"
        useProxy="false"/>

    <mx:Panel x="10" y="10" width="475" height="400" title="{feedRequest.lastResult.rss.channel.title}">

        <mx:DataGrid id="dgPosts" x="20" y="20" width="400" dataProvider="{feedRequest.lastResult.rss.channel.item}">
            <mx:columns>
                <mx:DataGridColumn headerText="Posts" dataField="title"/>
                <mx:DataGridColumn headerText="Date" dataField="pubDate" width="150"/>
            </mx:columns>
        </mx:DataGrid>

        <mx:TextArea x="20" y="175" width="400"/>
        <mx:LinkButton x="20" y="225" label="Read Full Post"/>
    </mx:Panel>
</mx:Application>

그리고 실행하니 아래와 같이 파이어폭스에서 실행되었습니다.

사용자 삽입 이미지

제가 아는 한에서는 가장 단시간에 만든 RSS 리더기입니다. 브라우져에서 HTML 소스를 보니 아래와 같았습니다.
<!-- saved from url=(0014)about:internet -->
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title></title>
<script src="AC_OETags.js" language="javascript"></script>
<style>
body { margin: 0px; overflow:hidden }
</style>
<script language="JavaScript" type="text/javascript">
<!--
// -----------------------------------------------------------------------------
// Globals
// Major version of Flash required
var requiredMajorVersion = 9;
// Minor version of Flash required
var requiredMinorVersion = 0;
// Minor version of Flash required
var requiredRevision = 0;
// -----------------------------------------------------------------------------
// -->
</script>
</head>

<body scroll="no">
<script language="JavaScript" type="text/javascript" src="history.js"></script>
<script language="JavaScript" type="text/javascript">
<!--
// Version check for the Flash Player that has the ability to start Player Product Install (6.0r65)
var hasProductInstall = DetectFlashVer(6, 0, 65);

// Version check based upon the values defined in globals
var hasRequestedVersion = DetectFlashVer(requiredMajorVersion, requiredMinorVersion, requiredRevision);


// Check to see if a player with Flash Product Install is available and the version does not meet the requirements for playback
if ( hasProductInstall && !hasRequestedVersion ) {
// MMdoctitle is the stored document.title value used by the installation process to close the window that started the process
// This is necessary in order to close browser windows that are still utilizing the older version of the player after installation has completed
// DO NOT MODIFY THE FOLLOWING FOUR LINES
// Location visited after installation is complete if installation is required
var MMPlayerType = (isIE == true) ? "ActiveX" : "PlugIn";
var MMredirectURL = window.location;
document.title = document.title.slice(0, 47) + " - Flash Player Installation";
var MMdoctitle = document.title;

AC_FL_RunContent(
"src", "playerProductInstall",
"FlashVars", "MMredirectURL="+MMredirectURL+'&MMplayerType='+MMPlayerType+'&MMdoctitle='+MMdoctitle+"",
"width", "100%",
"height", "100%",
"align", "middle",
"id", "Test",
"quality", "high",
"bgcolor", "#869ca7",
"name", "Test",
"allowScriptAccess","sameDomain",
"type", "application/x-shockwave-flash",
"pluginspage", "http://www.adobe.com/go/getflashplayer"
);
} else if (hasRequestedVersion) {
// if we've detected an acceptable version
// embed the Flash Content SWF when all tests are passed
AC_FL_RunContent(
"src", "Test",
"width", "100%",
"height", "100%",
"align", "middle",
"id", "Test",
"quality", "high",
"bgcolor", "#869ca7",
"name", "Test",
"flashvars",'historyUrl=history.htm%3F&lconid=' + lc_id + '',
"allowScriptAccess","sameDomain",
"type", "application/x-shockwave-flash",
"pluginspage", "http://www.adobe.com/go/getflashplayer"
);
} else { // flash is too old or we can't detect the plugin
var alternateContent = 'Alternate HTML content should be placed here. '
+ 'This content requires the Adobe Flash Player. '
+ '<a href=http://www.adobe.com/go/getflash/>Get Flash</a>';
document.write(alternateContent); // insert non-flash content
}
// -->
</script>
<noscript>
<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
id="Test" width="100%" height="100%"
codebase="http://fpdownload.macromedia.com/get/flashplayer/current/swflash.cab">
<param name="movie" value="Test.swf" />
<param name="quality" value="high" />
<param name="bgcolor" value="#869ca7" />
<param name="allowScriptAccess" value="sameDomain" />
<embed src="Test.swf" quality="high" bgcolor="#869ca7"
width="100%" height="100%" name="Test" align="middle"
play="true"
loop="false"
quality="high"
allowScriptAccess="sameDomain"
type="application/x-shockwave-flash"
pluginspage="http://www.adobe.com/go/getflashplayer">
</embed>
</object>
</noscript>
<iframe name="_history" src="history.htm" frameborder="0" scrolling="no" width="22" height="0"></iframe>
</body>
</html>

swf 파일로 봐서는 플래쉬와 무관한 것 같지는 않습니다. 아직은 정확히 플랙스가 무엇인지 어떻게 돌아 가는 것인지 알지도 못하지만 흥미있는 툴 같습니다. 다만 공짜였으면...

유프리가 웹기반이고 etri에서 만들었단 말 때문에 맥에서 실행되는 개발툴이 우리나라에서 나온줄 알고  많은 기대를 했었는데, 아직은 윈도우즈 전용이라 다소 아쉽습니다. 곧 리눅스도 지원한다고 하는데 하는 김에 맥까지 바라는 것은 욕심이겠죠?

&gt;&gt; 덧글 (2007.12.04 08:40)