Flex Builder 또는 Flash Builder 에서 유용하게 사용할 수 있는 플러그인을 소개했습니다. 더 많을 것이라 생각하는데 함께 공유했으면 좋겠네요. 댓글, 트랙백 모두 환영합니다.

http://opencast.naver.com/FL188/8


참고로 Flash Builder는 아래 링크로 가서 다운받으세요.
http://www.adoberia.co.kr/pds/down.html?src=text&kw=000026 


글쓴이 : 지돌스타(http://blog.jidolstar.com/581)

 

Flash/Flex 개발에 있어서 데이타와 UI의 의존성을 줄여주어 장기적으로 유지보수 및 효율적 관리를 하기 위해 MVC 디자인 패턴이 기본적으로 적용된 프레임워크를 직접 제작하거나 무료로 공개된 것들을 사용할 수 있다. 여기서 소개하는 프레임워크들은 Flex, Flash 개발하는데 MVC를 적절하게 활용해볼 수 있는 것들이다. 유용한 정보가 되길 바라며 관련된 많은 글들이 올라왔으면 한다.

 

http://opencast.naver.com/FL188/7

어제 무사히 Flex 기술세미나를 마쳤습니다.

(비트기술세미나라고 명칭되어 있었네요. 그게 좀 전달이 안된 것 같네요.)

 

무려 200개의 자리를 꽉 채울 정도로 많은 분들이 밤 늦은 시간까지 경청하시고 가셨습니다. 정말 수고 많으셨어요. ^^

 

세미나에서 옥상훈님께서는 UX(User Experience)에 대해서 매우 자세히 잘 말씀해주셨습니다. UX에 대해 다시 한번 생각해보는 계기가 되었구요. 또 배준균님께서 BlazeDS에 대해 현업에서 어떻게 쓰일지에 대해서 자세히 말씀해 주셨습니다. 아쉽게도 인터넷이 잘 안되어서 난감해 하셨는데... 알고보니 그거 유동IP가 아니라 고정IP였다는... ^^

 

저는 Flex 4에 대해 설명드렸습니다. 사실 저도 Flex 4를 공부한다는 마음을 가지고 이번 세미나 주제로 다룬겁니다. 덕분에 저도 열심히 공부할 수 있었고 많은 분들에게 Flex 4에 대해서 처음으로 소개할 수 있게 되어서 기분도 좋았답니다. 하지만 시간이 촉박해서 마지막에 질의시간을 가지지 못한 것 죄송합니다.

 

Flex 4에 대해 잠깐 언급했고 Flex 4를 이용해서 개발하는 툴인 Flash Builder 4와 Flash Catalyst에 대해서 소개했습니다. CSS, FXG, Namespace, State, Data Binding, Effect, None Visual Component 다루는 법, Spark Component와 Spark Layout 등에 대해서 약간 맛배기 정도로 다뤘습니다. 사실 소개드린 하나하나가 무거운 주제로 다루어도 몇시간씩은 해야하는 것들입니다. 그러므로 더 깊이 있는 공부를 위해서 관련 내용을 프리젠테이션에 있는 링크를 보시고 습득하시길 바래요.


아래 파일은 어제 발표했던 프리젠테이션 파일입니다.


 

아래 파일들은 어제 다뤘던 예제입니다.

 

invalid-file

출처 : http://evtimmy.com/2009/06/wheellayout-source-and-quick-mashup/

 

아래 두개는 시간이 없어서 소개하지 못한것인데 Flex 4를 이용해 컴포넌트를 만든 예제입니다. (제가 만든거 아닙니다. ^^)

invalid-file

출처 : http://www.hulstkamp.com/2009/07/09/custom-popup-rating-component-in-spark-flex-4-gumbo/464

invalid-file

참고 : http://blog.jidolstar.com/570

 

위 예제를 실험하기 위해서는 Flash Builder 4를 다운 받아야겠지요?
http://www.adoberia.co.kr/pds/down.html?src=text&kw=000026 

위의 예제는 Flash Builder 4에서 import 해서 사용할 수 있는데 다음과 같이 해보세요.

  1. Flash Builder 4를 실행
  2. File > New > Flex Project를 통해 Project를 생성
  3. File > Import > Other 선택
  4. 새창이 뜨면 General > Archive File 선택 후 Next 버튼 클릭
  5. "From archive file"에서 Browse 버튼을 클릭하여 위 Zip파일중 하나를 선택
  6. "Into folder" 에서 Browse 버튼을 눌러 새로 생성한 프로젝트를 선택후 Finish 버튼 클릭 (진행도중 Overwrite 경고 뜨면 모두 Overwrite합니다.)
  7. src 폴더에 들어간 mxml파일은 모두 Application입니다. 이중 하나를 열고 Run 메뉴에서 실행하거나 Ctrl+F11로 실행하면 되겠습니다.

 

다른 분의 자료는 http://okgosu.net 에서 제공이 될겁니다.

 

개인적인 소망이 있습니다. 많은 분들이 제 블로그를 통해 Flex 관련자료를 접하고 계신것 잘 알고 있습니다. 하지만 저도 다른 사람들을 통해서 많이 배우고 싶은 사람입니다. 서로 소통이 되어야 진정으로 정보공유라고 생각하고 바람직한 방향이라고 생각해요. 앞으로 Flex 4든 Flash Platform에 대한 어떤 자료든지 아시는 것있다면 함께 공유해서 함께 커갔으면 합니다. 어짜피 기술이라는 것은 시간이 지나면 또 바뀌고 사라질 수도 있잖아요? 자기만 알고 있다고 해서 다 좋은 것은 아니라는 겁니다. Flex 5, Flex 6가 나올때도 한국에서 한국 블로거 또는 카페등을 통해 매일 피상적인 정보만 얻어가는 정도나 질문에만 답해야하는 그런 상황이 반복된다면 정말 암울할 것 같아요. 정보생산의 주체가 적어도 어제 참석한 분들의 수만 되도 한국의 IT 미래는 매우 밝아질 것입니다.

 

 

012345

 

글쓴이 : 지돌스타(http://blog.jidolstar.com/579)

후기 : http://blog.jidolstar.com/579

내일 okgosu.net Flex 세미나가 있습니다.

자세한 내용은 다음과 같습니다.

 

■ 주제:
1. Flex 활용 UX 구현 테크닉
2. BlazeDS 활용
3. Flex 4의 새로운 기능

■ 대상 : 웹전산학관련 학과생 및 졸업생, IT분야 종사자, 플렉스 개발자

■ 내용
1. Flex 활용 UX 구현 테크닉
- UX 개요
- Flex UX 기획 및 설계
- UX를 위한 Flex 테크닉
2. BlazeDS 활용
- BlazeDS의 개요
- BlazeDS의 주요 기능
- LCDS와 BlazeDS의 차이
- Flex 연동 방법
3. Flex 4의 새로운 기능
- Flex 3와의 차이점
- Flex 4의 새로운 기능
- Flex의 비전

■ 일시 : 2009년 8월 13일(목요일) 19:00~ 22:00

■ 장소 :  비트교육센터 지하 2층 멀티미디어관(서울 서초구 서초 2동 1327-15 비트아카데미빌딩)

주차지원안됨

지하철 2호선 강남역 3번 출구 삼성화재 건물까지 직진 후,
오른쪽 골목길로 50M 가량 직진하면 우측에 일식집 “일조수사” 건물

■ 형식 : 전문강사의 세미나와 질의 응답

■ 시간별 진행일정
오프닝: 19:00 ~ 19:10
세션1: 19:10~20:00 Flex를 활용한 UX 구현 테크닉 - 옥상훈
세션2: 20:10~21:00 BlazeDS 활용 - 배준균
세션3: 21:10~22:00 Flex 4 새로운 기능 - 지용호

■ 강사소개

옥상훈
OkGosu.Net 운영자
한국SW아키텍트 연합회장
예제로 배우는 플렉스 저자
전 한국 Adobe 컨설턴트
배준균
Adobe Community Champion
한국 키스코 플렉스 개발팀장
지용호
Adobe Community Champion
flexdocs.kr 운영자
위콘 커뮤니케이션 UI 개발팀장


■ 후원
OkGosu.Net

 

접수는 http://www.bitacademy.com/etc/semina_info.asp  에서 하시면 됩니다.

 

아참~ 참석비용 없습니다.

Flash가 Cross OS, Cross Browser를 지향하지만 한글문제를 비롯해 각종 몇가지 기능을 제대로 수행하지 못하는 경우가 있다. 마우스 휠(Mouse Wheel)도 그와 같은 맥락이다.

 

Mac 운영체제에서는 마우스 휠 기능이 전혀 먹지 않는다. MS Window에서 wmode가 transparent일때 Internet Explorer를 제외하고 다른 브라우저에서는 마우스 휠 기능을 사용할 수 없다.

 

이 문제를 해결할 수 있는 유일한 방법은 Javascript를 이용하는 방법이다. ActionScript3의 ExternalInterface를 이용해 Javascript와 통신해서 마우스 휠 이벤트를 사용하는 것이다. 자바스크립트를 이용하는 방법은 내 블로그에도 몇번 글을 올렸다.

 

ActionScript 3.0 만으로 쿠키를 제어 - Actionscript Cookie Util 소개

[Flex/Flash] ActionScript 3.0 으로 브라우저 종류 알아내기

 

Pixelbreaker 블로그에 Mac에서 마우스 휠을 해결하는 방법을 다룬 유명한 글이 올라와 있다.

 

AS3.0 MouseWheel on Mac OS

 

하지만 이 방법은 Mac에만 유용하고 wmode=transparent 일때 대처를 하지 못한다. 또한 js파일을 따로 html에 포함 해야하니 사용하기 귀찮다.

 

위 소스를 개선하여 어떤 경우에라도 마우스 휠을 사용할 수 있으면서 따로 js파일을 포함안하고 actionscript 코드만으로 해결한 소스가 있다. 일본 Spark 프로젝트 팀에서 만든 SWFWheel이라는 하나의 클래스 코드인데 사용하기도 쉽고 깔끔하다.

 

공식홈페이지 : http://www.libspark.org/wiki/SWFWheel 

 

아래에서 공개한 JS파일을 AS 3.0 코드에 포함한다. 아래 링크를 보면 쉽게 이해할 수 있겠다.

swfwheel.js : http://www.libspark.org/browser/as3/SWFWheel/trunk/zoo/swfwheel.js

SWFWheel.as : http://www.libspark.org/browser/as3/SWFWheel/trunk/src/org/libspark/ui/SWFWheel.as

 

다운로드는 아래 링크에서 AS파일만 다운받아 사용하면 되겠다.

http://www.libspark.org/svn/as3/SWFWheel/trunk/src/org/libspark/ui/

 

 

사용법은 너무 간단하다.

import org.libspark.ui.SWFWheel;
SWFWheel.initialize(stage);

 

위처럼 하고 ActionScript 를 통해 마우스 휠 이벤트를 stage로 부터 등록하여 사용한다.

stage.addEventListener( MouseEvent.MOUSE_WHEEL, mouseWheelHandler );

SWFObject를 이용해 아래와 같은 방법으로 Flash Content를 삽입한다.

var flashvars = {};
var params = {};
var attributes = {
    id: "myDynamicContent",
    name: "myDynamicContent"
};

swfobject.embedSWF("myContent.swf", "myContent", "300", "120", "9.0.0", "expressInstall.swf", flashvars, params, attributes);

 

단, 위 방법이 잘될 수 있도록 하기 위해 allowScripAccess는 같은 도메인의 swf인 경우 sameDomain, 다른 도메인의 swf인 경우 always로 지정해야한다. allowNetworking은 항상 all로 설정해야한다. 이에 대한 자세한 내용은 다음글을 참고한다.

 

위젯도 마음대로 못다는 네이버 블로그

 

 

SWFWheel 클래스는 browserScroll 속성이 있다. 이것을 이용해면 Flash 위에서 MouseWheel을 이용할 때 Flash를 담은 브라우저의 스크롤링을 허용할 것인가 설정할 수 있다. 기본값은 false이다.

 

네이버 오픈캐스트의 메인 프로그램이 Flash로 만들어져 있는데 마우스 휠 기능이 어떤 운영체제든 브라우져든 잘 동작한다. 아마도 이 SWFWheel을 사용하지 않았나 생각된다.

 

이렇게 꽁수 안부리고 마우스 휠이든 한글문제든 Flash Player가 문제 없이 잘 동작하면 얼마나 좋을까?

 

[생각더하기]일본의 Spark 프로젝트의 이름에 눈길이 간다. Flex 4의 새로운 컴포넌트는 Spark로 명명했다. 그럼 Flex 4가 만들어질때 일본의 Spark 프로젝트의 역할이 컷던 것 아닐까? 실제로 Spark 프로젝트는 일본내에서 매우 활발하고 유명한 Flash 관련 프로젝트이다. 그 유명한 증강현실(FLARToolKit)도 이 프로젝트에서 만들어진 것이다. 우리 나라에는 왜 이런 멋진 프로젝트 팀이 없는 것일까? 안타깝다.

 

 

글쓴이 : 지돌스타(http://blog.jidolstar.com/577)

 

 

 

 

 

 

Flash 3D에 관련된 3D 엔진 및 학습할 만한 사이트를 골라 네이버 오픈캐스트에 발행했습니다. 요즘 Flash 3D에 푹빠져 있는데 관심있는 분들과 함께 공부하고 싶네요. 전 3D 초급수준이라 공부할 것도 많네요. ㅎㅎ

 

http://opencast.naver.com/FL188/5

 

좋은 자료 되길 바랍니다.

 

글쓴이 : 지돌스타(http://blog.jidolstar.com/576 )

 


Flash 3D 엔진하면 Away3D, Papervision3D 정도로 생각했다. 최근에서 ND3D라는 것도 접했는데... Away3D, Papervision3D 처럼 기능이 좋으면 속도/메모리가 문제이고 ND3D처럼 속도가 좋으면 기능이 문제이다.

그런데... 오늘 Alternativa3D를 접하고 그냥 Flash 3D의 새 장을 본듯한 느낌이 들었다.(예전에도 봤는데... 그때는 3D에 관심이 없어서 그냥 지나쳤다... ㅎㅎ)

Alternativa3D는 러시아에서 만든 Flash 3D 엔진이다.
이 엔진은 Flash Player 9과 10에 대응하도록 무료로 SWC로 배포하고 있다. 비상업적 개발의 경우에는 무료이나 상업적으로 개발시에는 유료이다. Flash로 3D를 만든다면 그냥 이거 구입하는게 좋겠다는 생각이 들었다.

기본 3D 엔진 뿐 아니라, 물리엔진, 소리엔진등을 제공하고 각종 인터렉션등에도 대응하도록 되어 있다. 속도는 왜이렇게 빠른가? 렌더링에 있어서 정말 최적화를 이뤘다고 해도 과언이 아니다. 게임엔진으로는 그만이다.

얼마나 대단한지 아래 사진을 클릭해서 데모 프로그램을 보자.

아래는 Tanki Online이라는 프로그램이다. Alternativa3D를 이용했고 온라인 멀티게임이다. 물리엔진을 적극 써서 흥미를 더했다. 아래 사진 클릭하면 해당 페이지로 간다.



볼 것도 없다. 현재로선 네가 최고다!

Alternativa3D 공식페이지 : http://alternativaplatform.com/en/alternativa3d/

근데 발음은 어떻게 하지? 알터네이티바?

글쓴이 : 지돌스타(http://blog.jidolstar.com/575)

3D 환경맵핑(Environment Mapping)의 한 기법으로 Cube Maps가 있다. 말그대로 직육면체의 각면에 대한 텍스쳐 이미지로 3D 환경을 조성하는 방법인데 아래 이미지를 보면 바로 이해할 수 있다.

 

Cube Map

출처 : developer.com

 

Cube Maps는 환경 맵핑 방법중 가장 빠르고 매우 사실적으로 묘사할 수 있는 방법으로 내가 알기로는 게임등에 자주 사용하는 것으로 알고  있다. 단점은 모서리 부분에서 약간 티가 난다는 점이다.

 

Flash Player 10부터 3D API를 제공한다. 이 API들을 적절히 활용하면 Papervision3D나 Away3D와 같은 라이브러리를 이용하지 않고도 어려움 없이 Cube Maps을 구현할 수 있다.

 

아래 프로그램은 Flash Player 10에서 제공하는 3D API만 이용해서 Cube Map을 구현한 것이다. 마우스 드래그로 회전이 가능하다.

 

마우스로 Drag하면 회전이 됩니다.
(Mac에서 화면이 작게 나오는데 아직 이유를 모르겠네요 ^^;)

 

위와 같은 프로그램을 만들기 위해 6면을 가지는 텍스쳐 이미지가 필요하다. 인터넷에 많이 있는데 아래처럼 Layout이 여러종류가 있다.

 

Cube Map Layout

Cube Map Layout 출처 : cgtextures.com

 

나는 가장 일반적이고 자주 쓰이는 Horizontal Cross방식 대신에 Horizontal Strip(NVidia DDS Exporter Layout)을 이용했다. 이 방식은 아래같이 구성된다.

 

Cube Map Layout 출처 : cgtextures.com

 

이러한 이미지가 어떻게 Cube Map을 만들 수 있는지 아래 화면을 보면 쉽게 알 수 있다.

 

마우스로 Drag하면 회전이 됩니다.

 

아래는 위 프로그램에 대한 소스이다.

 

 

package
{
	import flash.display.*;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.geom.*;
	import flash.utils.getTimer;
	
	[SWF(frameRate=60, backgroundColor=0x000000)]

	/**
	 * Cube Map 예제 
	 * @author Yongho, Ji (http://blog.jidolstar.com/574)
	 * @since 2009.08.05
	 */
	public class CubeSky extends Sprite
	{
		[Embed(source="sky.jpg")]
		private const SKY:Class;
		
		//투영된 Vectex 정보
		private var projected:Vector.<Number>;
		
		//World 변환 행렬 
		private var world:Matrix3D;
		
		//투영을 위한 변환행렬 
		private var projection:Matrix3D;
		
		//Mesh 데이터 
		private var mesh:GraphicsTrianglePath
				
		//Texture
		private var texture:BitmapData = (new SKY as Bitmap).bitmapData;
		
		//Viewport (3D 렌더링 대상)
		private var viewport:Shape;
		
		//Viewport의 Z축 위치 
		private var viewPortZAxis:Number = 0;		
		
		public function CubeSky()
		{
			//Viewport 
			viewport = new Shape;
			addChild( viewport );
			
			//투영 변환 행렬 
			var p:PerspectiveProjection = new PerspectiveProjection()
			p.fieldOfView = 30;
			projection = p.toMatrix3D();

			//World 변환 행렬
			world = new Matrix3D();
			
			var check3D:Vector3D = Utils3D.projectVector(
										projection, 
										new Vector3D(1.0,0,1.0)
									);			
									
			//Mesh 데이타 
			mesh = createCubeMesh( check3D.x );
			projected = new Vector.<Number>(0,false);
			viewPortZAxis = check3D.x;// * 4;
			
			//이벤트 핸들러 등록 
			stage.addEventListener( Event.RESIZE, resize );
			stage.addEventListener( Event.ENTER_FRAME, render );		
			//stage.addEventListener( MouseEvent.MOUSE_WHEEL, onMouseWheel );	
			stage.addEventListener( MouseEvent.MOUSE_DOWN, onMouseEvent );
			resize();
		}
		
		private function resize( event:Event = null ):void
		{
			viewport.x = stage.stageWidth/2;
			viewport.y = stage.stageHeight/2;	
		}		
		
		private function render( event:Event = null ):void
		{
            world.identity(); //단위행렬로 전환 
			world.appendRotation( zRotation, Vector3D.Z_AXIS );
			world.appendRotation( 90+xRotation, Vector3D.X_AXIS );
            world.appendTranslation(0, 0, viewPortZAxis); //이동 
            world.append(projection); //투영 변환 적용 
            
            // mesh 데이터를  투영하여  projected 생성 
            // uvtData도 갱신된다. 갱신되는 데이터는 T값이다.             
            Utils3D.projectVectors( world, mesh.vertices, projected, mesh.uvtData );
  
            // texture를 이용해 렌더링
            viewport.graphics.clear();
            //viewport.graphics.lineStyle( 1, 0xff0000 );
        	viewport.graphics.beginBitmapFill( texture, null, false, true );
            viewport.graphics.drawTriangles( projected, mesh.indices, mesh.uvtData, mesh.culling );
        	//Cube는  z축을 굳이 정렬할 필요 없다.
            //viewport.graphics.drawTriangles( projected, getSortedIndices(mesh), mesh.uvtData, mesh.culling );            	
		}
		
		/**
		 * 마우스 휠 처리 
		 */ 
		private function onMouseWheel( event:MouseEvent ):void
		{
			viewPortZAxis += event.delta * 10;
		}	

		private var xRotation:Number = 0;
		private var zRotation:Number = 0;
		private var prevX:Number;
		private var prevY:Number;		
		/**
		 * 마우스 이벤트 - x,y축 회전
		 */ 
		private function onMouseEvent( event:MouseEvent ):void
		{
			switch( event.type )
			{
				case MouseEvent.MOUSE_DOWN:
					stage.addEventListener( MouseEvent.MOUSE_MOVE, onMouseEvent );
					stage.addEventListener( MouseEvent.MOUSE_UP, onMouseEvent );
					prevX = mouseX;
					prevY = mouseY;
					break;
				case MouseEvent.MOUSE_MOVE:
					if( event.buttonDown == false )
					{
						stage.removeEventListener( MouseEvent.MOUSE_MOVE, onMouseEvent );
						stage.removeEventListener( MouseEvent.MOUSE_UP, onMouseEvent );
						break;
					}
					var dx:Number = mouseX - prevX;
					var dy:Number = mouseY - prevY;
					zRotation += dx;
					xRotation += dy;
					if( xRotation > 90 ) xRotation = 90;
					if( xRotation < -90 ) xRotation = -90;
					prevX = mouseX;
					prevY = mouseY;
					break;
				case MouseEvent.MOUSE_UP:
					stage.removeEventListener( MouseEvent.MOUSE_MOVE, onMouseEvent );
					stage.removeEventListener( MouseEvent.MOUSE_UP, onMouseEvent );
					break;
			}	
		}
	}
}

import flash.display.GraphicsTrianglePath;
import flash.display.TriangleCulling;

/**
 * Cube Mesh 데이타 작성 
 * @param size 한변의 사이즈
 * @return mesh 데이터 
 */ 
function createCubeMesh( size:Number = 512 ):GraphicsTrianglePath
{
	var vertices:Vector.<Number> = new Vector.<Number>( 0, false );
	var indices:Vector.<int> = new Vector.<int>( 0, false );
	var uvtData:Vector.<Number> = new Vector.<Number>( 0, false );
	var mesh:GraphicsTrianglePath = new GraphicsTrianglePath( vertices, indices, uvtData, TriangleCulling.POSITIVE );
	var s:Number = size/2;
	var w:Number = size * 6;
	var u00:Number = 0;
	var u01:Number = (size-1)/w;
	var u10:Number = size/w;
	var u11:Number = (size*2-1)/w;
	var u20:Number = (size*2)/w;
	var u21:Number = (size*3-1)/w;
	var u30:Number = (size*3)/w;
	var u31:Number = (size*4-1)/w;
	var u40:Number = (size*4)/w;
	var u41:Number = (size*5-1)/w;
	var u50:Number = (size*5)/w;
	var u51:Number = (size*6-1)/w;
	
	mesh.vertices.push( 
		//Right		
		s,-s,-s,	//0
		s,-s,s,		//1
		s,s,s,		//2
		s,s,-s, 	//3

		//Left
		-s,s,-s, 	//4
		-s,s,s, 	//5
		-s,-s,s, 	//6
		-s,-s,-s, 	//7
		
	
		//Top
		-s,-s,s, 	//8
		-s,s,s, 	//9
		s,s,s, 		//10
		s,-s,s, 	//11
		
		//Bottom
		-s,s,-s, 	//12
		-s,-s,-s, 	//13
 		s,-s,-s, 	//14
		s,s,-s, 	//15
		
		//Front
		-s,-s,-s, 	//16
		-s,-s,s, 	//17
		s,-s,s, 	//18
		s,-s,-s, 	//19

		//Back
		s,s,-s, 	//20
		s,s,s, 		//21
		-s,s,s, 	//22
		-s,s,-s 	//23
	);
	
	
	mesh.indices.push( 
		0,1,2, 0,2,3, 	//Right
		4,5,6, 4,6,7,  	//Left
		8,9,10, 8,10,11, //Top
		12,13,14, 12,14,15, //Bottom
		16,17,18, 16,18,19, //Front
		20,21,22, 20,22,23 //Back
	 );
		
	mesh.uvtData.push( 
		//Right
		u00, 1, 1,
		u00, 0, 1,
		u01, 0, 1,
		u01, 1, 1,

		//Left
		u10, 1, 1,
		u10, 0, 1,
		u11, 0, 1,
		u11, 1, 1,

		//Top
		u20, 1, 1,
		u20, 0, 1,
		u21, 0, 1,
		u21, 1, 1,

		//Bottom
		u30, 1, 1,
		u30, 0, 1,
		u31, 0, 1,
		u31, 1, 1,

		//Front
		u40, 1, 1,
		u40, 0, 1,
		u41, 0, 1,
		u41, 1, 1,

		//Back
		u50, 1, 1,
		u50, 0, 1,
		u51, 0, 1,
		u51, 1, 1
	 );

	
	return mesh;
}

/**
 * GraphicsTrianglePath를 기반으로, Z축으로 sort된 인덱스를 돌려준다.
 * 이 작업을 해주어야 z축 깊이에 따라 Triangle이 제대로 그려진다. 
 * @param mesh 정보 
 * @return sort된 index 데이터 
 */
function getSortedIndices( mesh:GraphicsTrianglePath ):Vector.<int> 
{
    var triangles:Array = [];
    var length:uint = mesh.indices.length;
    
    //z축 sort를 위한 기반 제작 
    for ( var i:uint=0; i < length; i += 3 ) 
    {
        var i1:uint = mesh.indices[ i+0 ];
        var i2:uint = mesh.indices[ i+1 ];
        var i3:uint = mesh.indices[ i+2 ];
        var z:Number = Math.min( mesh.uvtData[i1 * 3 + 2], mesh.uvtData[i2 * 3 + 2], mesh.uvtData[i3 * 3 + 2] );
        if (z > 0) 
        { 
        	triangles.push({i1:i1, i2:i2, i3:i3, z:z}); 
        }
    }
    
    //z축으로 sort
    triangles = triangles.sortOn("z", Array.NUMERIC);
    
    //sort된 값을 이용해 Vector값 만듬 
    var sortedIndices:Vector.<int> = new Vector.<int>(0, false);
    for each (var triangle:Object in triangles) 
    {
        sortedIndices.push(triangle.i1, triangle.i2, triangle.i3);
    }
    return sortedIndices;
}

 

 

아래 이미지는 위 프로그램에서 사용한 이미지이다.

 

위 프로그램에서는 Graphics.drawTriangle() 메소드를 이용했다. 하지만 이 함수를 사용하지 않고도 만들수 있다. 왜냐하면 Flash Player 10부터는 DisplayObject에 대해 x,y,z축 회전 및 이동 API가 추가되었기 때문이다. 그러면 위 프로그램 소스처럼 힘들게 vertex, index, uvt 데이타를 만들지 않아도 될 것이다.

 

내 생각에 Flash에서 3D 개발을 위해 Graphics.drawTriangle()와 DisplayObject의 3D API, Matrix3D 등을 서로 섞어가면서 만드는 것이 좋을 것 같다.

 

개발환경 : Flash Builder 4 Beta 1 (Flash CS4 에서도 개발할 수 있음.)

 

참고내용

 

글쓴이 : 지돌스타(http://blog.jidolstar.com/574)

 

단지 25줄의 ActionScript 코드로 얼마나 멋진 애플리케이션을 만드는가 가리는 대회이다. 웹서핑하다가 우연치 않게 본 페이지에서 25줄이라고는 믿기지 않을 정도의 결과물들을 보고 이 세상에는 정말 천재들이 많구나라는 생각이 들었다.

 

대회 규정 및 이전 대회 결과물들은 아래 홈페이지를 통해 볼 수 있다.

 

http://www.25lines.com

 

아래에서 소개하고 있는 ActionScript 결과물들은 2009년 1월 결승전에 올라온 작품들이다. 작품 하나하나마다 25줄의 코드라고는 믿기지 않는 작품들임을 볼 수 있을 것이다. 만든것도 대단하지만 창의적인 면에 있어서도 높은 점수를 주고 싶다.

 

올라온 소스 코드를 분석해보려고 읽기 쉽게 정리하면서 봐도 이해못하는... ㅜㅜ

언젠간.. 나도 저 대열에....

 

Entry 001
Code
SWF

Entry 002
Code
SWF

Entry 007
Code
SWF

Entry 008
Code
SWF

Entry 009
Code
SWF

Entry 014
Code
SWF

Entry 021
Code
SWF

Entry 023
Code
SWF

Entry 027
Code
SWF

Entry 029
Code
SWF

Entry 030
Code
SWF

Entry 032
Code
SWF

 

글쓴이 : 지돌스타(http://blog.jidolstar.com)

 

Flex Explorer만 선별하여 네이버 오픈케스트에 발행했습니다. Flex, AIR 개발자라면 꼭 들어가서 볼 필요있는 것만 나름대로 엄선했으니 참고 바랍니다. Flex를 처음 공부하는 사람에게는 더욱 필요한 정보가 될 것입니다.  현재 Flex 4 Beta가 나와 있는 상태이지만 Flex 2, Flex 3에 대한 Explorer로 포함합니다. 이는 Flex SDK 버전에 상관없이 유용할 것이 판단했기 때문에 넣었습니다.

 

그럼 즐 Flex/AIR 하세요.

 

http://opencast.naver.com/FL188/4

 

제 오픈케스트는 1주일에 한번씩 발행됩니다.

마음에 드신다면 꼭 구독도 하세요 ^^

 

이외에 아래 링크들도 유용합니다.

 

 

 

글쓴이 : 지돌스타(http://blog.jidolstar.com/571)

 

Flex 4에 대해서 자료를 모으고 공부하는 중에 매우 괜찮은 블로그를 찾았다.

http://www.hulstkamp.com/

이 사람 블로그에 가면 Flex 4기반 커스텀 컴포넌트를 만든 예제들이 정말 많다. 한동안 이 사람 블로그와 친해져야 겠다는 생각이 들었다. ㅎㅎ

올라온 자료중에 Gumbo(4.0.0.4932) 버전으로 만든 Knob Button 예제가 있었는데 Flex 4 SDK Beta버전이 정식으로 나오기 전이라 바로 실행할 수 없었다. 그래서 소스를 보면서 마이그레이션 작업을 해보았다. 아래 실행 예제는 바로 이 작업의 결과물이다.

위 프로그램은 Knob Button에 대한 데모이다. 마우스로 돌려볼 수 있다.


마이그레이션 하면서 Spark 기반 커스텀 컴포넌트를 제작하는 법에 더욱 익숙해질 수 있었다.

Flex 3의 Halo 기반 컴포넌트는 스킨이 그래픽 기반만 지원했는데 Flex 4의 Spark기반 컴포넌트들은 스킨이 그래픽적 요소 뿐 아니라, 상태변화(state), 다른 컴포넌트 배치, 데이타 표현등이 된다. 또한 FXG를 지원하고 MXML형태로 스킨을 만들 수 있기 때문에 그 확장력이 무궁무진하게 되었다. Halo 컴포넌트의 경우에는 상태변화 바꾸거나 내부 컴포넌트 배치만 달라져도 컴포넌트 자체를 확장해서 다시 만들어야 하는 불편함이 있었지만 Spark컴포넌트는 큰 변경없이 커스텀 스킨만 제작하는 것만으로도 충분히 해결할 수 있게 되었다. 이 내용은 여기에 올려놓은 소스 또는 "Spark DropDownList 사용하기"를 보면 알 수 있을 것이다.

Spark 컨테이너의 경우에는 Layout까지 동적으로 변경할 수 있도록 만들어져서 언제든지 다른 Layout으로 바꿀 수 있고 또는 커스텀 Layout를 만들어 쓸 수도 있다. 반면 Halo 기반 컨테이너는 컨테이너의 Layout을 바꾸기 위해 기존 컨테이너를 다시 확장하거나 새로 만들어야만 했다. 이 내용에 대해서는 "Spark 컨테이너의 Layout, Scrolling, Viewport 소개"를 읽어보길 바란다.

CSS는 정말 획기적으로 많이 추가 되었다. 기존 Class, Type Selector밖에 없었는데 Flex 4로 넘어오면서 ID, Descendant, Pseudo, Mutiple Class등 다양한 Selector가 추가되었다. 이에 대한 글은 "Flex 4의 CSS"를 참고하길 바란다.

아래는 위 프로그램의 소스이다. 참고바란다.


개발 환경은 Flash Builder 4 Beta 1 이다. Flash Builder는 아래 링크에서 다운 받을 수 있다.

Adobe 에서 ACC(Adobe Community Champion)들에게

깜짝 선물을 줬는데

나는 HYATT 호텔식사권을 받았다.

 

 

Adobe의 박민형 전무님의 정성어린 친필이 담긴 편지와 함께온 하야트 호텔식사권이다. ㅎㅎ

다른 ACC분들은 가족끼리 갈 수 있는 케리안베이 이용권을 받았다.

울 아내가 임신중이라 거긴 갈 수 없어서 식사권을 받은 것이다. ㅋㅋ

 

울 아내는 이거 보고 너무 좋아서 어쩔 줄 몰라했는데...

내가 "이거 그렇게 좋은거야?" 물어보니깐....

"헉" 하더라...

그러면서 하야트가 뭔지 모르냐고 묻는다...

나의 대답 : "응"

......

 

아무튼 하야트도 모르는 무식한 남편이지만

아내가 좋아하니 나도 기분 좋다.

시간나면 함께 데이트 가야 겠다. ㅎ

Flex 4는 Flex 3의 컨테이너의 Scrolling 기능보다 더욱 강화되고 직관적으로 바뀌었다. 여기에 Layout, Viewport라는 개념까지 포함되어 더욱 다루기 편하도록 만들어졌다. 이 글은 Flex 4 Spark 컨테이너의 Layout, Scrolling, Viewport에 대해서 소개한다.

아래는 Flash Builder 4 환경에서 작업했다. Flash Builder 4는 아래 링크를 통해 다운받을 수 있다.

http://www.adoberia.co.kr/pds/down.html?src=text&kw=000026  

Spark 컨테이너의 Layout

 

Flex 3에서 Halo 기반 컨테이너는 Canvas, Box, HBox, VBox, Tile등이 있었지만 Flex 4의 Spark 기반 컨테이너는 모두 Group 하나로 통일되었고 layout 속성을 통해 BasicLayout, HorizontalLayout, VerticalLayout, TileLayout을 설정하여 Flex 3의 Canvas, HBox, VBox, Tile역할을 할 수 있도록 했다. Flex 4 Spark 기반 컨테이너는 이와 같이 동적으로 Layout을 바꿀 수 있도록 만들어졌기 때문에 좀 더 유연한 컨테이너 환경을 만들 수 있다.

 

아래는 위 프로그램의 소스이다.

<?xml version="1.0" encoding="utf-8"?>
<s:Application 
	xmlns:fx="http://ns.adobe.com/mxml/2009" 
	xmlns:s="library://ns.adobe.com/flex/spark" 
	xmlns:mx="library://ns.adobe.com/flex/halo" 
	minWidth="300" minHeight="300">
	<s:layout>
		<s:VerticalLayout/>
	</s:layout>
	<fx:Script>
		<![CDATA[
			import spark.layouts.TileLayout;
			import spark.layouts.VerticalLayout;
			import spark.layouts.HorizontalLayout;
		]]>
	</fx:Script>
	
	<s:DropDownList id="ddl" requiresSelection="true" labelField="label">
		<s:dataProvider>
			<s:ArrayList>
				<fx:Object label="TileLayout" layout="{new TileLayout()}"/>
				<fx:Object label="HorizontalLayout" layout="{new HorizontalLayout()}"/>
				<fx:Object label="VerticalLayout" layout="{new VerticalLayout()}"/>
			</s:ArrayList>
		</s:dataProvider>
	</s:DropDownList>
		
	<s:Group>
		<s:layout>{ddl.selectedItem.layout}</s:layout>
		<s:Button label="1"/>
		<s:Button label="2"/>
		<s:Button label="3"/>
		<s:Button label="4"/>
		<s:Button label="5"/>
		<s:Button label="6"/>
		<s:Button label="7"/>
		<s:Button label="8"/>
		<s:Button label="9"/>
		<s:Button label="10"/>
	</s:Group>

</s:Application>

 

Spark 컨테이너의 Scrolling

 

Flex 3의 모든 컨테이너는 Scroller기능이 내장되어 있었는데 반해 Flex 4 Spark 기반 컨테이너는 기본적으로 Scroller 기능이 없다. 그래서 컨테이너는 더욱 가벼워졌고 필요할 때 ScrollBar를 Group 태그 밖으로 감싸주기만 하는 것으로 스크롤을 추가할 수 있도록 되었다.

 

 

아래는 앞선 소스에서 Scroller만 추가한 것이다.

<s:Scroller width="200" height="100" left="1" right="1" top="1" bottom="1">
	<s:Group>
		<s:layout>{ddl.selectedItem.layout}</s:layout>
		<s:Button label="1"/>
		<s:Button label="2"/>
		<s:Button label="3"/>
		<s:Button label="4"/>
		<s:Button label="5"/>
		<s:Button label="6"/>
		<s:Button label="7"/>
		<s:Button label="8"/>
		<s:Button label="9"/>
		<s:Button label="10"/>
	</s:Group>
</s:Scroller>

 

Flex 4 Spark 컨테이너(List, Group등)는 이렇게 쉽게 Layout을 임의대로 바꿀 수 있고 Scroller도 쉽게 배치할 수 있도록 되어 있다. Flex 4 Spark 기반 컨테이너는 Flex 3의 Halo 컨테이너보다 더욱 사용하기 간편하고 직관적이며 활용도가 높다는 것을 해본 사람은 알 수 있을 것이다.

 

 

Spark 컨테이너의 Viewports

 

Spark 컨테이너에서 들어간 재미있으면서 유용한 개념이 들어갔는데 Viewport 라는 것이다. Viewport는 말그대로 보여지는 영역이다. 아래 그림만 봐도 Viewport의 의미를 쉽게 이해할 수 있을 것이다.

 

출처 : http://hansmuller-flex.blogspot.com/2009/06/introduction-to-viewports-and-scrolling.html

 

방금 설명했던 Scroller는 시각적으로 보이는 horizontalScrollbar, verticalScrollbar와 ViewPort의 horizontalScrollPosition, verticalScrollPosition 속성의 값을 묶어(Bind)준다. 그러므로 어느 한쪽이 조절되면 다른 한쪽이 변경되어지게 된다. 백문의 불여일타.... 아래 예제만 봐도 이게 무슨 말인지 바로 알게 된다.

 

 

<?xml version="1.0" encoding="utf-8"?>
<!-- 출처 :http://hansmuller-flex.blogspot.com/2009/06/introduction-to-viewports-and-scrolling.html-->
<s:Application 
    xmlns:fx="http://ns.adobe.com/mxml/2009" 
    xmlns:s="library://ns.adobe.com/flex/spark" 
    xmlns:mx="library://ns.adobe.com/flex/halo">
    <s:Group>
        <s:Group left="20" top="1" width="110" height="160">
            <s:Scroller id="scrollbar" left="2" right="2" top="2" bottom="2">
                <s:Group id="vp" horizontalScrollPosition="57" verticalScrollPosition="198">
                    <mx:Image source="http://sites.google.com/site/hansmuller/Home/archive/gyro-original.jpg"/>
                </s:Group>
            </s:Scroller>
            <s:Rect left="0" right="0" top="0" bottom="0">
                <s:stroke>
                    <s:SolidColorStroke weight="1" color="0xD8D8D8"/>
                </s:stroke>
            </s:Rect>
        </s:Group>
        <s:SimpleText horizontalCenter="10" top="175" text="viewport.width = {vp.width}"/>
        <s:SimpleText verticalCenter="-10" rotation="-90" text="viewport.height = {vp.height}"/>                
    </s:Group>

    <s:VGroup left="140" top="10" gap="15">
        <s:SimpleText text="viewport.contentWidth = {vp.contentWidth}"/>
        <s:SimpleText text="viewport.contentHeight = {vp.contentHeight}"/>
        <s:SimpleText text="viewport.horizontalScrollPosition = {vp.horizontalScrollPosition}"/>
        <s:SimpleText text="viewport.verticalScrollPosition = {vp.verticalScrollPosition}"/>
    </s:VGroup>

</s:Application>

 

Spark 컨테이너인 Group은 GroupBase를 상속받고 GroupBase는 IViewport 인터페이스를 구현하고 있다. Scroller는 이 IViewport과 바인딩되어 있다는 것을 이해하는 것이 중요하다.

 

    public interface IViewport extends IVisualElement
    {
        function get width():Number;
        function get height():Number;
        function get contentWidth():Number;
        function get contentHeight():Number;
        function get horizontalScrollPosition():Number;
        function set horizontalScrollPosition(value:Number):void;
        function get verticalScrollPosition():Number;
        function set verticalScrollPosition(value:Number):void;
        function getHorizontalScrollPositionDelta(scrollUnit:uint):Number;
        function getVerticalScrollPositionDelta(scrollUnit:uint):Number;
        function get clipAndEnableScrolling():Boolean;
        function set clipAndEnableScrolling(value:Boolean):void;
    }

 

그러므로 IViewport 인터페이스를 구현한 GroupBase, Group, DataGroup, RichEditableText, SkinnableContainer, SkinnableDataContainer 등은 모두 Scroller를 사용할 수 있게 되는 것이다.

 

위 소스에서 사용자가 Scroller를 컨트롤 하지 않고 Viewport를 컨트롤하여 스크롤바를 움직이게 할 수 있다.

 

위 프로그램은 앞선 소스에서 아래 코드를 추가하면 된다

<s:VGroup top="196" gap="15" x="20">
	<s:HGroup>
		<s:SimpleText text="HScroll Controller"/>    		
		<s:HSlider id="hSlider" 
			liveDragging="true"
			minimum="0" 
			maximum="{vp.contentWidth-vp.width}" 
			value="{vp.horizontalScrollPosition}" 
			change="vp.horizontalScrollPosition=hSlider.value"/>
	</s:HGroup>

	<s:HGroup>
		<s:SimpleText text="VScroll Controller"/>    		
		<s:HSlider id="vSlider" 
			liveDragging="true"
			minimum="0" 
			maximum="{vp.contentHeight-vp.height}" 
			value="{vp.verticalScrollPosition}" 
			change="vp.verticalScrollPosition=vSlider.value"/>
	</s:HGroup>
</s:VGroup>

 

이 코드가 의미하는 바는 사용자가 ScrollBar를 직접 컨트롤하지 않아도 Viewport를 통해 ScrollBar를 프로그램적으로도 컨트롤 할 수 있다는 것을 보여주고 있다.

 

(위 프로그램에서 Slider에 Viewport의 위치 값이 초반에 제대로 업데이트 안되는 이유는 이미지 로딩시점과 관련되어 있다. 이미지 로딩 뒤에 Viewport의 위치를 변경하면 아마도 문제가 해결될 것이므로 참고바란다. )

 

 

참고내용

Spark Layouts with Flex 4 Beta

Introduction to Viewports and Scrolling in Gumbo

 

 

글쓴이 : 지돌스타(http://blog.jidolstar.com/568)

Flex 4의 Spark 계열 DropDownList는 List를 확장한 컴포넌트이다. Flex 3에서 ComboBox와 유사하게 사용할 수 있다.

 

DropDownList는 DropDownBase대신 List를 서브클래스로 한 것이 커다란 변화이다. 이렇게 된데에는 Iwo Banas라는 사람이 기존 Gumbo의 FxComboBox을 더욱 확장이 가능하고 내부적으로 독립화된 구조의 필요성에 대한 제안을 반영한 결과이다. 이에 따라 DropDownList는 dropDown 스킨 부분을 더이상 가지지 않고 List의 dataGroup 스킨을 사용하게 되었다.

 

DropDownList 컴포넌트의 기능 및 디자인 스펙을 보고 싶다면 아래 글을 보기 바란다. 이 글만 잘봐도 DropDownList에 내부구현 및 사용방법에 대해 어느정도 이해할 수 있을 것이라 생각한다.

 

http://opensource.adobe.com/wiki/display/flexsdk/Spark+DropDownList

 

또한 API에 대한 자세한 내용은 아래 글을 참고한다.

http://livedocs.adobe.com/flex/gumbo/langref/spark/components/DropDownList.html

 

DropDownList를 사용하는 방법은 Peter deHaan의 블로그만 봐도 쉽게 학습할 수 있다.

나는 이 블로그에서 DropDownList를 언급한 글들만 골라서 사용해 보았다. Flex 3와 달라 약간 생소하지만 놀라운 스킨 적용의 확장성에 매력을 느끼게 될 것이다. 아래에서 소개하는 4개의 큰 제목을 누르면 해당 포스트로 이동한다.

 

Setting a content background color on a Spark DropDownList control in Flex Gumbo

 

이 예제는 DropDownList를 이용하는 매우 간단한 예제로 DropDownList의 DropDown되는 리스트의 배경색을 바꾸는 것이다.

 

 

Setting the symbol color on the Spark DropDownList control in Flex 4

 

 

이 예제도 그 전 예제와 비슷한 난이도의 예제로 DropDownList의 Symbol의 색을 변경하는 예제이다.

 

 

Creating a tile layout Spark DropDownList control in Flex Gumbo

 

 

이 예제는 DropDownList의 커스텀 스킨을 적용하는 방법을 보여주고 있다. 블로그에 있는 커스텀 스킨은 Gumbo버전이라 작동을 잘 안하는데 스킨은 아래 것을 받아 해보길 바란다. Peter deHaan의 예제에서 PopUp을 사용했는데 Flex 4부터는 PopUpAnchor로 바뀌었다.

 

List에 보여지는 아이템이 원래 DropDownList의 기본 Skin인 spark.skins.DropDownListSkin과 달라진 점은 PopupAnchor의 DataGroup를 VerticalLayout으로 지정하는데 여기서 사용한 Layout은 HorizontalLayout이라는 점이 다르다. 게다가 위치도 아래표시가 아니라 우측에 표시되도록 했다. 이처럼 스킨부분에서 모든 Layout을 수정할 수 있도록 한 것이 Flex 4 컴포넌트의 컨셉이다. 이것은 Flex 3의 단점을 잘 극복한 부분중에 하나이다.

 

조금 더 재미있게 바꿔보자. Application과 DropDownSkin을 아래 코드로 바꿔보자.

 

 

스킨만 바꿨을 뿐인데...(갑자기 어느 광고가 생각남.. ㅋ)

위 프로그램 처럼 DropDownList의 스킨을 바꿀 수 있다. 그것도 아주 쉽게~~

 

 

Displaying images in a Spark DropDownList control in Flex Gumbo

 

방금 예제에서 DropDownList의 스킨을 바꾸는 것을 보여주었다. 그럼 DropDownList에 이미지도 보여줄 수 있을까? 당근 아주아주 쉽게 할 수 있다.

 

 

여기에서 사용된 BitmapImage는  spark.primitives.* 패키지에 포함되는 것으로 Group을 확장한 Graphic내에 넣을 수 있다. Graphic에 넣을 수 있는 것중에는 <Rect>, <Path>, <Ellipse>등도 포함한다. 관련 내용은 아래 링크를 참고한다.

 

http://livedocs.adobe.com/flex/gumbo/langref/spark/primitives/package-detail.html

 

 

정리하며

지금까지 Flex 4의 Spark DropDownList에 대해서 살펴보았다. Flex 3와 달리 Flex 4에서는 스킨 적용시 ActionScript 3.0 기반이 아닌 MXML이라 직관적이고 편리하게 할 수 있다는 것이 큰 매력이였다. 또한 기능도 매우 확대되었다. Spark 컴포넌트라면 이와 같은 방법으로 스킨을 적용할 수 있다는 것을 이해하는 것이 중요하겠다.


테스트 환경 : Flash Builder 4 + Flex SDK 4

Flash Builder 는 아래 링크에서 다운 받자.

http://www.adoberia.co.kr/pds/down.html?src=text&kw=000026 

글쓴이 : 지돌스타(http://blog.jidolstar.com/567)

Flex Builder 3 및 Flash Builder 4 로 개발하면서 도움말 참조는 흔히 있는 일이다. Blueprint는 이들 IDE에 plug-in 형태로 제공되며 단축키(Win:Alt+B, Mac:Control+B)만으로 쉽게 도움말을 찾을 수 있게 지원해준다.

 

 

라이브 독을 찾아다닐 필요없이 단축키만으로 쉽게 설명을 찾을 수 있으니 이 얼마나 편한가? ^^

 

다음 글을 통해 Blueprint를 경험해 보길 바란다.

 

Blueprint 설치하기 : http://labs.adobe.com/wiki/index.php/Blueprint:Installation_Instructions

Blueprint 사용하기 : http://labs.adobe.com/wiki/index.php/Blueprint:Using_Blueprint

 

Blueprint 공식 페이지 : http://labs.adobe.com/technologies/blueprint/

 

글쓴이 : 지돌스타(http://blog.jidolstar.com/565)

 

Flex의 SystemManager는 Flex가 구동될 때 Application이 동작하기전 각종 설정을 하면서 사용자들에게 충분히 그 시간을 기다릴 수 있도록 UI적으로 Preloading 화면을 보여준다. 하지만 Flex가 아닌 ActionScript 3.0 프로젝트로 만들면 이런 UI를 보여주지 않는다. Flex는 되는데 ActionScript라고 못할까? 사실 매우 쉬운 방법으로 이 기능을 추가할 수 있다. 방법은 다음 글을 참고하길 바란다.

 

http://www.diebuster.com/?p=681

http://www.bit-101.com/blog/?p=946

 

ActionScript 3.0도 Flex 컴파일러인 mxmlc로 컴파일하는 것이기 때문에 [Frame] 메타 데이타 태그를 이용해 Preloading 기능을 추가할 수 있는 것이 핵심이다. 이를 이용해 만들어진 Preloading 기능 추가한 클래스에 각종 설정 및 자원관리를 할 수 있는 로직을 만들어 사용하면 좋겠다.

 

한가지 팁을 소개하자면....

 

mxmlc가 Flex 컴파일러라서 내부적으로 [Frame] 메타 데이타 태그를 사용하면 기본 CSS를 포함하게 된다. 그래서 위 글대로 하면 다음과 같은 경고 문구가 나온다.

 

Default css file not found

 

이 경고 문구를 없애려면 내용이 아무 것도 없는 null.css를 하나 만들고 컴파일 옵션으로 -defaults-css-url null.css를 추가하면 경고문구가 사라진다.

 

글쓴이 : 지돌스타(http://blog.jidolstar.com)

 

네이버 오픈케스트에 "Adobe ColdFusion에 대해 알아봐요."라는 제목으로 발행했습니다.

 

 

국내에서는 이상하게도 ColdFusion에 대해 많이 무관심한 편입니다. 알고 보면 정말 멋진 RIA 기술인데도 말이죠. 개발은 쉽게하고 유지보수도 편하게 하는 것을 좋아하시는 분들에게 ColdFusion은 큰 매력으로 자리 잡을 수 있을 것이라 생각합니다. 물론 개인 뿐 아니라 기업 입장에서도 효율적인 개발 및 유지보수 차원에서 도입한다면 좋을 것이라 생각합니다.

 

아래 링크에 접속하시면 보실 수 있습니다.

 

http://opencast.naver.com/FL188/3

 

한번 ColdFusion의 매력에 푹~ 빠져보시기 바랍니다.

2009년 7월 22일 오전 9시 34분 경부터 2시간동안 일어나 세기 최대 일식을 관측했습니다. 일하는 시간이였지만 이런 멋진 천문쇼를 놓칠 수 없기 때문에 회사 직원들과 함께 보게 되었죠.

일식(Solar Eclipse)이란 달이 태양을 가리는 천문현상입니다. 부분적으로 가리면 부분일식, 전체를 가리면 개기일식이라고 하는데 아쉽게도 한국에서는 80%~90% 정도 가리는 것을 관측할 수 있었습니다. 중국에 다녀오신 분들은 개기일식까지 봐서 멋진 코로라와 대 낮에 별도 볼 수 있는 진기한 현상을 목격했을 겁니다.

아래는 소유하고 있는 12인치 돕소니안 천체망원경을 통해 흰판에 투영시켜 본 태양의 모습입니다. 주변에 구름까지 끼어서 사진촬영이 가능했네요.

망원경을 통해 본 일식(촬영:임형준)



아래 사진을 구름이 태양앞을 지나갈때 찍은 사진입니다. 멋지죠? 저렇게 되면 맨눈으로도 일식을 감상할 수 있습니다.

일식(촬영:임형준)



소유하고 있는 천체망원경입니다. 모델은 저... ㅋ

아래 사진처럼 천체망원경을 통해 투영해서 볼 수 있었습니다. 사실 망원경 앞에다 선필터(Sun Filter)를 달아야하는데... 준비를 못했네요 ^^;;

너무 태양이 밝아서 아래 처럼 플로피 디스크 분해한 것으로 직접 볼 수 있죠. 물론 저것가지고 직접 태양봐도 볼 수 있고요.




아래는 그날 찍은 동영상입니다.


유튜브에 일식에 대한 멋진 영상이 있네요. 참고하세요. ^^



멋진 경험이였고 중국에서 보지 못한게 못내 아쉽네요. ^^

글쓴이 : 지돌스타(http://blog.jidolstar.com/562)

Adobe에서 TLF(Text Layout Framework)의 소스를 공개했다.

 

먼저 어떤 것인지 데모 버전을 보자.

아래 링크로 보면 되겠다.

 

http://labs.adobe.com/technologies/textlayout/fma/Shell.swf

 

TLF는 Flash Player 10, AIR 1.5 기반의 새로운 Text 엔진이다. Adobe Flash CS4 및 Flex 4 에서 사용할 수 있다. Flash API에서 제공하는 TextField의 부족한 부분을 개선하고 일반 워드 처럼 Text 편집 작업을 할 수 있도록 하는 것이 이 프레임워크의 목적이 아닌가 싶다.

 

Adobe Labs에 다운로드 페이지에서 직접 받을 수 있다. 소스는 최신 Flex 4 SDK에 포함되어 있다고 한다. Night Build 버전으로 다운로드 받을 수 있고 [여기]를 참조한다.

 

TLF의 Beta 1 버전은 다운로드 받으면 CS4, Flex 3, Flex 4 환경에서 개발할 수 있고 꼭 Flash Player 10 버전으로 컴파일 옵션으로 지정해야한다. 그리고 3개의 SWC파일인 textLayout_conversion.swc, textLayout_core.swc, textLayout_edit.swc 를 라이브러리로 포함하면 되겠다.

 

관련 페이지는 다음 링크를 참고한다.

 

- Text Layout Framework(Adobe Open Source)

- Text Layout Framework(Adobe Labs)

 

다음 TLF 기반 예제들도 참고할만 하겠다.

- AIR기반의 Times Reader 2.0 http://timesreader.nytimes.com/timesreader/
- Acrobat.com Presentations http://labs.adobe.com/technologies/presentations/
- makebook http://www.makebook.com/

 

하지만 아직 한국에서 사용하기에는 무리이다. 한글입력을 할 때, 자음, 모음이 먼저 보여지지 않는 것도 있고 기능적으로도 부족한 점이 많다. Open Source라지만 근본적인 한글 입력문제는 Flash Player 10 자체에서 해결해 주어야 할 듯 싶다.

 

글쓴이 : 지돌스타(http://blog.jidolstar.com/561)

 

코드네임 Strobe였던 OSMF(Open Source Media Framework)가 2009년 7월 21일 기점으로 오픈 소스로 공개되었다. 현재 버전은 0.3 2.0(2013-12-17)이다.

 

OSMF는 3개 부분의 구조로 나뉜다. User Interface, Monetization workflows, media delivery가 그것이다.

 

OSMF는 최적의 Media Player를 개발할 수 있는 프레임워크로 플레이어 개발의 복잡성을 줄어준다.

재생컨트롤, 비디오 네비게이션, 버퍼링, 다이나믹 스트리밍, 리포트 분석과 같은 플러그 인 설치등을 지원한다. 무엇보다 이 모든 기능이 오픈소스화 되어 어느 개발자든지 만들어진 소스를 공유하고 수정하며 다시 배포할 수 있게 되었다. 정확한 라이센스는 MPL에 따른다.

 

공식사이트는 아래 링크를 참고한다.

http://osmf.org/


아래는 OSMF 블로그이다. 

http://blogs.adobe.com/osmf/ 


다운로드는 아래 링크를 참고한다.

http://sourceforge.net/projects/osmf.adobe/files/


빠르게 익숙해지려면 아래 링크 동영상을 보도록 하자.

http://www.gotoandlearn.com/play.php?id=129 

http://tv.adobe.com/show/rich-media-player-development-with-osmf/ 


아래 링크에서 OSMF Examples를 볼 수 있다.

http://mediapm.edgesuite.net/osmf/swf/ExamplePlayer.swf  


Flash Builder, Flash CS3, CS4 환경이면 OSMF API로 개발이 가능하겠다.

본인도 OSMF를 다운로드 받아서 예제 소스를 가지고 Flash Builder 4 에서 만들어 보았다. Flex 소스가 Flex 3라서 Flash Builder 4에서는 SDK를 3.4 버전으로 맞춰줘야 한다.


참고: 아래소스는 0.3버전 시절겁니다. 그냥 참고만 하세요. (2013-12-17)

 

 

CompositionPlayer.zip

 

위 결과물은 OSMF 배포된 소스 안에 있는 샘플로 만든 것이다. UI는 형편없지만 다양한 방법로 Media 컨텐츠를 읽어와 재생하고 볼륨조정, Pan 조정도 가능하다는 것을 보여주고 있다.

 

아래 프로그램은 순수하게 ActionScript 3.0 프로젝트로만 만들어 본것이다.

 

FlashMediaPlayerTest.zip

 

필요하다면 OSMF를 프로젝트에 복사해서 사용해도 된다.

 

아니면 아래 처럼 라이브러리 형태로 배포된 SWC를 자신의 프로젝트의 libs에 추가해서 사용해도 된다.

 

예제만 잘 보면 활용방법도 쉽게 얻을 수 있다. ^^

이제 Media 관련 플레이어를 제작하는데 많은 노력없이 OSMF만 이용해도 충분히 만들 수 있게 되었다. 너무 멋지다 이런 멋진 플레이어의 소스를 볼 수 있다는 것이 말이다.

 

글쓴이 : 지돌스타(http://blog.jidolstar.com/560)

Flex 4로 넘어오면서 생소하게 느꼈던 부분 중에 하나가 바로 자식(Child) 관리 메소드들의 변화가 아닌가 생각한다. 바뀐 부분이 무엇이고 왜 바뀌었는지 알아보도록 하겠다.

 

Flex 3에서 Canvas, Box 등의 컨테이너는 모두 mx.core.Container 클래스를 확장해서 만들어졌다. 이 Container 클래스는 flash.display.DisplayObjectContainer에서 정의되어 있는 자식관리 메소드인 numChildren, addChild(), addChildAt(), removeChild(), removeChildAt() 등을 그대로 Override(재정의) 해서 사용했다. 그런데 이렇게 재정의 한것이 문제가 컸다. Flex 3의 Container는 DisplayObjectContainer의 메소드를 그대로 사용하므로 자식은 모두 flash.display.DisplayObject로 받게 된다. 하지만 실제 자식으로 사용할 수 있는 것은 IUIComponent를 구현한 클래스만 자식으로 받을 수 있다. 즉 UIComponent만 자식으로 받을 수 있는 것이다. 아래 코드는 Flex 3의 Container에서 자식을 추가할 때 내부적으로 addingChild()메소드가 호출되는데 거기에 있는 코드이다.

var uiChild:IUIComponent = IUIComponent(child);

 

Flex 3에서 addChild()를 통해 받는 자식은 DisplayObject인데 런타임시 사용될 수 있는 컴포넌트는 IUIComponent이니 실제 Flex 3를 이용해서 개발하는 사람들은 오용할 소지가 크게 된 것이다. 나도 Container에 Sprite 객체를 넣으려고 하다가 안되서 애먹은 적이 있었는데 바로 이것때문이다.

 

Flex 4부터는 이 문제를 말끔히 없애고자 DisplayObjectContainer의 자식 관리 메소드를 재정의 하지 않고 다른 메소드를 만들었다. 그 다른 메소드는 무엇일까?

 

Flex 4에서는 아래와 같이 IVisualElementContainer 인터페이스를 정의했다. 이 인터페이스는 Flex 4의 모든 Spark, Halo 컨테이너에서 모두 구현하고 있다. 보면 알겠지만 addChild대신 addElement, removeChild대신 removeElement로 된 것이다. 결국 Child 대신 Element를 사용한거다.

package mx.core
{
public interface IVisualElementContainer
{
    function get numElements():int;
    function getElementAt(index:int):IVisualElement
    function addElement(element:IVisualElement):IVisualElement;
    function addElementAt(element:IVisualElement, index:int):IVisualElement;
    function removeElement(element:IVisualElement):IVisualElement;
    function removeElementAt(index:int):IVisualElement;
    function removeAllElements():void;
    function getElementIndex(element:IVisualElement):int;
    function setElementIndex(element:IVisualElement, index:int):void;
    function swapElements(element1:IVisualElement, element2:IVisualElement):void;
    function swapElementsAt(index1:int, index2:int):void;

}
}

 

위 인터페이스는 정확히 무엇을 의미하는가? 자식 추가할 때 이제 더이상 DisplayObject가 아니라는 것에 주목하자. DisplayObject대신 IVisibleElement를 관리하고 있다. 이것이 핵심이다. 즉 이제 런타임시가 아닌 컴파일 단계서부터 원천적으로 컨테이너에 자식들은 모두 IVisibleElement을 구현한 것만 다루겠다는 것이다. Flex 4는 Flex 3와 다르게 모든 컨테이너는 IVisibleElementContainer를 구현한 것이다. 그리고 mx.core.UIComponent는 IVisibleElement를 구현했다. 이로서 컨터이너에 붙는 자식들을 더욱 명확하게 사용할 수 있게 되었다.

 

그럼 addChild, addChildAt은 어떻게 했을까? 아래 코드는 Spark 컨테이너의 SkinnableComponent와 GroupBase에 재정의된 것이다. 즉 이들 메소드를 사용하면 런타임시 예외처리를 해준다. 이 클래스를 확장해서 만든 Spark 계열의 컨테이너인 SkinnableContainer, SkinnableDataContainer, Group, DataGroup, Panel 전부 이렇게 동작한다.

    /**
     *  @private
     */
    override public function addChild(child:DisplayObject):DisplayObject
    {
        throw(new Error(resourceManager.getString("components", "addChildError")));
    }
    
    /**
     *  @private
     */
    override public function addChildAt(child:DisplayObject, index:int):DisplayObject
    {
        throw(new Error(resourceManager.getString("components", "addChildAtError")));
    }

 

하지만 기존 Halo 기반의 컨테이너(mx.core.Container)는 addChild(), removeChild() 사용시 예외처리를 해두지 않았다. 물론 IVisualElementContainer는 구현했지만 말이다. 이는 기존 Flex 3 Halo 기반의 컴포넌트와의 호환성 문제 때문에 그리 한 것이라 판단한다.

 

Flex 4 문서를 보면 되도록이면 Halo보다 Spark 기반의 컴포넌트와 컨테이너를 사용할 것을 권장하고 있다. 지금까지 소개한 내용도 그렇게 권장하는 이유중에 하나일 것이다.

 

Flex SDK 개발자들이 Flex 2 시절 전부터 이런 문제를 알고 있었을 텐데 왜 지금에서야 바꿨는지... ㅎㅎㅎ

 

 

참고글

Spark Group - Functional and Design Specification

 

 

글쓴이 : 지돌스타(http://blog.jidolstar.com/559)

 

 

InsideRIA에 올라온 Getting started with Spark skins 의 글을 읽고 따라해보았다.

 

아래는 Skin 소스이다. com.jidolstar.skins.MyButtonSkin으로 이름을 지었다.

<?xml version="1.0" encoding="utf-8"?>
<s:Skin 
	xmlns:fx="http://ns.adobe.com/mxml/2009" 
	xmlns:s="library://ns.adobe.com/flex/spark" 
	xmlns:mx="library://ns.adobe.com/flex/halo" 
	>
	<fx:Metadata>
		[HostComponent("spark.components.Button")]
	</fx:Metadata>
	
	<s:states>
		<mx:State name="up"/>
		<mx:State name="down"/>
		<mx:State name="over"/>
		<mx:State name="disabled"/>
	</s:states>
	
	<s:filters>
		<s:DropShadowFilter quality="3"
			alpha="0.5" alpha.over="0.3"
			distance="5" distance.over="15"
			blurX.over="15" blurY.over="15"
			inner.down="true"
		/>
	</s:filters>
	
	<s:Rect left="0" right="0" top="0" bottom="0" radiusX="5" radiusY="5">
		<s:fill>
			<mx:LinearGradient rotation="90">
				<mx:entries>
					<mx:GradientEntry color="#0a5c00" ratio="0.00"/>
					<mx:GradientEntry color="#84a381" ratio="0.50" ratio.over="0.25"/>
					<mx:GradientEntry color="#0a5c00" ratio="0.80"/>
				</mx:entries>
			</mx:LinearGradient>
		</s:fill>
	</s:Rect>
	
	<s:SimpleText id="labelElement" color="#ffffff"
		horizontalCenter="0" verticalCenter="0"
     	left="10" right="10" top="5" bottom="5"
     />	
	
	<s:layout>
		<s:BasicLayout/>
	</s:layout>
</s:Skin>

 

아래는 위 Skin을 사용한 소스이다.

<?xml version="1.0" encoding="utf-8"?>
<s:Application 
	xmlns:fx="http://ns.adobe.com/mxml/2009" 
	xmlns:s="library://ns.adobe.com/flex/spark" 
	xmlns:mx="library://ns.adobe.com/flex/halo" 
	minWidth="500" minHeight="400"
	>
	<s:Button label="확인" skinClass="com.jidolstar.skins.MyButtonSkin"/>
</s:Application>

 

코딩하면서 느끼는 것이지만 Flex 4는 Flex 3하고 너무 다르다. ㅎㅎ  

스킨 부분에 있어서 Flex 3에서는 ProgrammaticSkin을 기반으로 Skin을 ActionScript 코드로 만들었는데 Flex 4부터는 MXML로 만들 수 있도록 했다. 이 부분이 가장 크게 달라진거다.

 

위의 Skin 코드를 살펴보면 몇가지 재미있는 점을 발견할 수 있다. 살펴보자.

 

먼저 HostComponent 메타 데이타를 볼 수 있다. Flex 4에서 나온 새로운 메타 데이타이다. 이것은 이 스킨이 어떤 컴포넌트가 Host인가 명시적으로 지칭해주는 역할을 한다. Button은 ButtonBase를 확장해서 만들었고 ButtonBase는 SkinnableComponent를 확장해서 만들어졌는데 HostComponent가 쓰이는 부분은 SkinnableComponent인 듯 보인다. 아래는 SkinnableComponent내에 정의된 attachSkin() 메소드이다. 이것은 createChildren() 혹은 commitProperties()가 호출될때 이 메소드가 호출되는데 skinClass 스타일이 바뀔 때 Skin을 붙여주는 역할을 담당한다.

 

    /**
     *  Create the skin for the component. 
     *  You do not call this method directly. 
     *  Flex calls it automatically when it calls createChildren() or  
     *  the UIComponent.commitProperties() method.
     *  Typically, a subclass of SkinnableComponent does not override this method.
     * 
     *  

This method instantiates the skin for the component, * adds the skin as a child of the component, and * resolves all part associations for the skin

* * @langversion 3.0 * @playerversion Flash 10 * @playerversion AIR 1.5 * @productversion Flex 4 */ protected function attachSkin():void { // Factory var skinClassFactory:IFactory = getStyle("skinFactory") as IFactory; if (skinClassFactory) setSkin( skinClassFactory.newInstance() as Skin ); // Class if (!skin) { var skinClass:Class = getStyle("skinClass") as Class; if (skinClass) setSkin( new skinClass() ); } if (skin) { skin.owner = this; // As a convenience if someone has declared hostComponent // we assign a reference to ourselves. If the hostComponent // property exists as a direct result of utilizing [HostComponent] // metadata it will be strongly typed. We need to do more work // here and only assign if the type exactly matches our component // type. if ("hostComponent" in skin) { try { Object(skin).hostComponent = this; } catch (err:Error) {} } // the skin's styles should be the same as the components skin.styleName = this; super.addChild(skin); skin.addEventListener(PropertyChangeEvent.PROPERTY_CHANGE, skin_propertyChangeHandler); } else { throw(new Error(resourceManager.getString("components", "skinNotFound", [this]))); } findSkinParts(); invalidateSkinState(); }

위 코드에 보면 hostComponent 부분이 보이는데 바로 HostComponent 메타데이터와 관련이 있어 보인다. 아직 정확한 동작방식은 모르겠다.

 

주제를 바꿔서 맨 위 코드에 <s:state>가 존재하는 것을 볼 수 있다. 이것은 상태를 의미하는 것으로 이미 Button 자체에 up, down, over, up 상태가 메타 데이터 형태로 정의 되어 있다. . ButtonBase에 보면 아래와 같은 방식으로 4개의 상태를 나타내는 메타 데이터가 정의되어 있다.

/**
 *  Up State of the Button
 *  
 *  @langversion 3.0
 *  @playerversion Flash 10
 *  @playerversion AIR 1.5
 *  @productversion Flex 4
 */
[SkinState("up")]

/**
 *  Over State of the Button
 *  
 *  @langversion 3.0
 *  @playerversion Flash 10
 *  @playerversion AIR 1.5
 *  @productversion Flex 4
 */
[SkinState("over")]

/**
 *  Down State of the Button
 *  
 *  @langversion 3.0
 *  @playerversion Flash 10
 *  @playerversion AIR 1.5
 *  @productversion Flex 4
 */
[SkinState("down")]

/**
 *  Disabled State of the Button
 *  
 *  @langversion 3.0
 *  @playerversion Flash 10
 *  @playerversion AIR 1.5
 *  @productversion Flex 4
 */
[SkinState("disabled")]

public class ButtonBase extends SkinnableComponent implements IFocusManagerComponent
{
   ...
}

 

저 상태변화는 SkinnableComponent 클래스에서 알아서 처리하도록 되어 있다. Button의 스킨의 상태에 따른 변화의 동작방식을 이해하기 위해 SkinnableComponent를 분석해야한다. 뭐, 분석까지 아니더라도 SkinnableComponent를 활용하는 방법만 알면 될 것이다. SkinnableComponent는 UIComponent를 확장한 것이고 모든 Spark 계열의 컴포넌트는 SkinnableComponent를 확장한 형태이다. ColorPicker나 DateChooser와 같이 예전 Halo 계열의 컴포넌트는 SkinnableComponent를 확장하지 않았다.

 

<s:filters>는 말그대로 필터를 설정하는 것을 의미한다. 여기서는 DropShadowFilter를 사용했다. Flex 4에서 추가한 새로운 기능중에 각 속성에 state를 지정할 수 있다. DropShadowFilter를 사용할 때도 아래 처럼 속성에 이 기능을 적용했다.  

 

alpha="0.5" alpha.over="0.3"

 

DropShadowFilter를 사용한 부분 중에 alpha값을 위처럼 사용했다. 보통때는 alpha값이 0.5이지만 상태가 over이면 0.3을 사용하겠다는 것을 의미한다. alpha.over="0.3" 부분이 어떻게 ActionScript 로 바뀌는가 살펴보려면 컴파일 옵션에 -keep-generated-actionscript를 해보면 알 수 있다. 그럼 컴파일을 하면 src/generated 폴더가 생성된다. 그 안에 com.jidolstar.skins 패키지로 가보면 MyButtonSkin-generated.as 파일이 있는데 열어보면 alpha.over="0.3" 가 어떻게 바뀌는가 한눈에 알 수 있다. 아래 코드는 MyButtonSkin-generated.as의 일부분이다.

 

    /**
     * @private
     **/
    public function MyButtonSkin()
    {
        super();
        // our style settings

        // properties
        this.filters = [_MyButtonSkin_DropShadowFilter1_i()];
        this.layout = _MyButtonSkin_BasicLayout1_c();
        this.mxmlContent = [_MyButtonSkin_Rect1_c(), _MyButtonSkin_SimpleText1_i()];
        this.currentState = "up";


        // events
		states = [
		  new State ({
		    name: "up",
		    overrides: [
		    ]
		  })
		  ,
		  new State ({
		    name: "down",
		    overrides: [
		      new mx.states.SetProperty().initializeFromObject({
		        target: "_MyButtonSkin_DropShadowFilter1",
		        name: "inner",
		        value: true
		      })
		    ]
		  })
		  ,
		  new State ({
		    name: "over",
		    overrides: [
		      new mx.states.SetProperty().initializeFromObject({
		        target: "_MyButtonSkin_DropShadowFilter1",
		        name: "alpha",
		        value: 0.3
		      })
		      ,
		      new mx.states.SetProperty().initializeFromObject({
		        target: "_MyButtonSkin_DropShadowFilter1",
		        name: "distance",
		        value: 15
		      })
		      ,
		      new mx.states.SetProperty().initializeFromObject({
		        target: "_MyButtonSkin_DropShadowFilter1",
		        name: "blurX",
		        value: 15
		      })
		      ,
		      new mx.states.SetProperty().initializeFromObject({
		        target: "_MyButtonSkin_DropShadowFilter1",
		        name: "blurY",
		        value: 15
		      })
		      ,
		      new mx.states.SetProperty().initializeFromObject({
		        target: "_MyButtonSkin_GradientEntry2",
		        name: "ratio",
		        value: 0.25
		      })
		    ]
		  })
		  ,
		  new State ({
		    name: "disabled",
		    overrides: [
		    ]
		  })
		];
    }

private function _MyButtonSkin_DropShadowFilter1_i() : spark.filters.DropShadowFilter
{
	var temp : spark.filters.DropShadowFilter = new spark.filters.DropShadowFilter();
	temp.quality = 3;
	temp.alpha = 0.5;
	temp.distance = 5;
	_MyButtonSkin_DropShadowFilter1 = temp;
	return temp;
}

 

결국 alpha.over="0.3"는 State 객체를 만들어 각 상태에 따른 속성으로 지정해버리도록 만들어진다. currentState를 "up"으로 설정하고 상태가 바뀔 때마다 등록된 State를 실행하도록 되는 것이다. 이걸 보니깐 원리가 확실히 이해가 된다.

 

다시 돌아가서....

<s:Rect>과 <s:SimpleText>는 mxmlContent=[_MyButtonSkin_Rect1_c(), _MyButtonSkin_SimpleText1_i()] 의 형태로 추가 된다. mxmlContent도 Flex 4부터 추가된 속성인데 생소하기 짝이 없다. ㅎㅎ 좀 알아보기 위해 또 뒤져봤다.

 

//----------------------------------
//  mxmlContent
//----------------------------------

private var mxmlContentChanged:Boolean = false;
private var _mxmlContent:Array;

[ArrayElementType("mx.core.IVisualElement")]

/**
 *  The visual content children for this Group.
 *
 *  

The content items should only be IVisualItem objectss. * An mxmlContent Array should not be shared between multiple * Group containers because visual elements can only live in one container * at a time.

* *

If the content is an Array, do not modify the Array * directly. Use the methods defined by Group class instead.

* * @default null * * @langversion 3.0 * @playerversion Flash 10 * @playerversion AIR 1.5 * @productversion Flex 4 */ public function get mxmlContent():Array { if (_mxmlContent) return _mxmlContent.concat(); else return null; } /** * @private */ public function set mxmlContent(value:Array):void { if (createChildrenCalled) { setMXMLContent(value); } else { mxmlContentChanged = true; _mxmlContent = value; // we will validate this in createChildren(); } } /** * @private * Adds the elements in mxmlContent to the Group. * Flex calls this method automatically; you do not call it directly. * * @langversion 3.0 * @playerversion Flash 10 * @playerversion AIR 1.5 * @productversion Flex 4 */ private function setMXMLContent(value:Array):void { var i:int; // if there's old content and it's different than what // we're trying to set it to, then let's remove all the old // elements first. if (_mxmlContent != null && _mxmlContent != value) { for (i = _mxmlContent.length - 1; i >= 0; i--) { elementRemoved(_mxmlContent[i], i); } } _mxmlContent = (value) ? value.concat() : null; // defensive copy if (_mxmlContent != null) { var n:int = _mxmlContent.length; for (i = 0; i < n; i++) { var elt:IVisualElement = _mxmlContent[i]; // A common mistake is to bind the viewport property of an Scroller // to a group that was defined in the MXML file with a different parent if (elt.parent && (elt.parent != this)) throw new Error(resourceManager.getString("components", "mxmlElementNoMultipleParents", [elt])); elementAdded(elt, i); } } }

 

위 코드는 Group 클래스이다. mxmlContent는 Skin 클래스의 부모 클래스인 Group에 구현되어 있는 속성인 것이다. mxmlContent에 값을 설정하면 setMXMLContent() 함수가 호출되어 기존의 MXML 추가된 Element들을 지우고 새로운 Element인 Rect과 SimpleText를 추가한다. 또한 IVisibelElement인 컴포넌트만 자식으로 추가하도록 되어 있고 다른 부모를 가지는 컴포넌트인 경우에 예외처리도 한다. 결국 mxmlContent은 Group에서 사용된 MXML형태의 비주얼 컴포넌트를 Flex 컴파일러가 AS3로 추가해주기 위해 만들어진 것이다.

 

<s:Application> 부분에 버튼 추가한 부분은 어떻게 변해 있을까? 살펴보면 아래 처럼 되어 있다.

private function _sparkskin_Button1_c() : spark.components.Button
{
	var temp : spark.components.Button = new spark.components.Button();
	temp.label = "확인";
	temp.setStyle("skinClass", com.jidolstar.skins.MyButtonSkin);
	if (!temp.document) temp.document = this;
	return temp;
}

skinClass가 원래 Style속성이다. SkinnableComponent를 보면 [Style(name="skinClass", type="Class")]로 정의 되어 있다. 이는 validateSkinChange() 함수에서 붙여주게 된다.

 

/**
 *  @private
 */
private function validateSkinChange():void
{
    // If our new skin Class happens to match our existing skin Class there is no
    // reason to fully unload then reload our skin.  
    var skipReload:Boolean = false;
    
    if (_skin)
    {
        var factory:Object = getStyle("skinFactory");
        var newSkinClass:Class;
        
        if (factory)
            newSkinClass = (factory is ClassFactory) ? ClassFactory(factory).generator : null;
        else
            newSkinClass = getStyle("skinClass");
            
        skipReload = newSkinClass && 
            getQualifiedClassName(newSkinClass) == getQualifiedClassName(_skin);
    }
    
    if (!skipReload)
    {
        if (skin)
            detachSkin();
        attachSkin();
    }
}

 

내가 한가지 흥미를 느꼈던 것은 바로 <s:SimpleText> 부분이였다. Flex 4의 Button은 Label의 컴포넌트를 바꿀 수 없었는데 Flex 4에서는 스킨 기능을 이용해 Text엔진을 바꿀 수 있다. 가령 <s:SimpleText> 대신 <s:RichText>로 바꿔보길 바란다. 잘 된다. 이는 TextGraphicElement를 확장한 SimpleText와 RichText만 가능하다. 만약 TextArea와 같은 것을 사용하면 아래와 같은 에러가 나오게 된다.

 

TypeError: Error #1034: 유형 강제 변환에 실패했습니다. spark.components::TextArea@70c36d1을(를) spark.primitives.supportClasses.TextGraphicElement(으)로 변환할 수 없습니다.

 

이런 식의 사용은 Spark 컴포넌트 전체에서 사용할 수 있다. 참 좋은 방법이다.

 

 

생각하기

 

Flex 4는 Flex 3 처럼 무리하게 ActionScript 3.0까지 분석할 필요까지 느끼게 해주지 않도록 하는 것이 컨셉인 것 같다. 하지만 내가 좀 독특한 건가 예전 버릇을 버리지 못해 어찌 돌아가는지 알고 싶어서 Flex 4 SDK를 훑어보게 되었다. 하지만 이렇게 저렇게 분석하면서 살펴봤지만 아직도 모르는게 산적해있다. 먼저 사용하는 법부터 좀 공부해야겠다. ㅎㅎ

 

관련글

Getting started with Spark skins

Creating Spark Skins

The Spark Group and Spark SkinnableContainer containers

 

 

글쓴이 : 지돌스타(http://blog.jidolstar.com/558)

 

 

2번째로 네이버 오픈케스트에 Adobe RIA 추천사이트를 올렸습니다. 제가 자주 가고 또 유용하다고 생각되는 사이트만 10개 엄선했습니다. 네이버 메인에서 구독할 수 있습니다. 1주일에 한번씩 업데이트합니다. 많은 구독 부탁드려요 ^^

 

지돌스타의 Adobe RIA 오픈 캐스트 보기 : http://opencast.naver.com/FL188

 

7월 13일에서 14일까지 한국에서 인터넷으로 접속시에 Adobe 관련 사이트 접속에 장애 있었다. 요즘 DDoS때문에 Adobe가 한국 IP를 차단한 줄로 예상하고 외국 Proxy에 돌려서 접속해 보니 잘 접속되었다. 결국 Adobe가 막은 줄 알았다. 그런데 의외의 정보를 접했다.

 

7월13일~14일까지 국내 인터넷 서비스망을 통한 인터넷 접속시 www.adobe.com/kr 포함한 www.adobe.com 웹사이트 접속이 불가능하였으나, 어제 오후 7시부로 다시 접속이 가능해졌습니다.


KISA(한국정보보호진흥원) 상황실에서 근래 있었던 DDoS 공격을 의심, 어도비에게 사전공지 없이 독단적으로 어도비 홈페이지 IP 접속을 차단시켰던 것으로 확인 되었습니다.
따라서 어도비 홈페이지가 DDoS와 전혀 상관이 없음을 인정하고 다시 차단된 IP를 해제, 접속 에러 문제가 해결되었습니다.


며칠 사이 어도비의 수많은 중요한 고객분들께 불편을 끼친 점을 안타깝게 생각하며, 이는 폐사의 불찰이 아니었음을 양해하여 주시기 바랍니다.

애꿎은 Adobe를 나무랐던 것이다. KISA(한국정보보호진흥원)이 DDoS 공격 의심으로 Adobe 한국지사를 비롯한 관련 업체에게 아무런 공지없이 그냥 IP를 차단한거다.

 

정말 어이없다. 도데체 저 단체는 한국내 있는거 맞나? 막으려면 알려주고나 막지. Adobe가 작은 업체인가? 정말 무식한거 아닌가? 답답하기만 하다. 세금내는게 아깝다. 몇일간 Adobe에 접속 못해서 습득하지 못한 정보 때문에 시간 낭비 했는데 아무래도 KISA가 책임져야한다고 생각이 든다. 좀!!!! 제대로 일좀 하십시다.

서기님의 블로그를 보다가 너무 멋진 그림을 봐서 따왔다.

 

Life Cycle of the Flex UIComponent Base Class

 

그림의 출처 : http://danorlando.com/?p=122

 

Flex의 모든 비주얼 컴포넌트는 Sprite를 확장한 UIComponent를 기반으로 한다. 생성할 대 호출되는 함수와 발생되는 이벤트에 대해서 하나의 그림으로 표현되어 있다. Flex 커스텀 컴포넌트를 작성해야할 때 Life Cycle을 이해하는 것은 반드시 필요하다. 그러므로 눈에다 팍팍 익혀두면 도움이 될 것이다.

 

글쓴이 : 지돌스타(http://blog.jidolstar.com)

 

 

Adobe가 Coldfusion 9 Beta 및 새 Builder를 배포했습니다.

 

Adobe Labs(http://labs.adobe.com)에서 다운로드 받을 수 있습니다.

 

벌써 설치기까지 나왔는데 Coldfusion에 큰 관심과 애정을 가지고 계신 장창학 님의 블로그에서 보실 수 있습니다.

 

Coldfusion 9 Beta 및 Coldfusion Builder 간단 설치기

 

Coldfusion은 빠르고 쉬운 웹서비스를 개발하는 방법중에 하나입니다.

매우 강력함에도 불구하고 한국에서는 많이 쓰이지 않고 있는데요.

그래서 아쉽게도 한글로된 문서도 많이 없는 편입니다.

그래도 몇몇 선구자님들이 계셔서 다행입니다.

 

제 생각에 그 선구자 중에서 장창학님이 대표적인 것 같습니다.

그래서 Coldfusion에 대해서는 장창학님의 블로그에 잘 정리되어 있습니다.

관심있으신 분은 꼭 훑어보시고요.

 

용스님이 쓰신 ColdFusion 웹서비스 간단하게 만들어보는 예제도 있네요.

ColdFusion CFC로 웹서비스 간단하게 만들어보기

 

위키피디아에 ColdFusion에 대해서 자세히 나와있네요. ^^

 

http://en.wikipedia.org/wiki/ColdFusion

 

카페도 있습니다. 이것 역시 장창학님이 운영하시는... 대단하십니다.

http://cafe.naver.com/opencfml.cafe

 

아무튼 공부하고자 마음만 먹으면 할 수 있습니다. ^^

 

 

MS Windows에 Subversion을 설치할 일이 생겨서 설치했다. 이 글은 설치하는 방법 및 테스트를 위한 나만의 기록이다. 다른 방법도 얼마든지 있지만 모두 생략한다.

 

 

Subversion 서버 구축하기

 

1. 설치 목표

Http 프로토콜로 SVN 서비스 지원하도록 서버측 환경을 만드는 것을 목적으로 한다. svn 프로토콜이나 https로 하는 방법은 생략한다. 이 목표를 달성하기 위해 다음과 같은 프로그램을 다운로드 받아 설치해야 한다.

 

- Apache 웹서버 2.2.x

- Subversion 1.6.x

- TortoiseSVN 1.6.x

 

2. Apache 웹서버 설치 하기

http://httpd.apache.org/download.cgi 에서 Openssl을 지원하는 Win32 Binary 설치프로그램을 다운로드 받아 설치한다. 현 최신 버전인 apache_2.2.11-win32-x86-openssl-0.9.8i.msi를 받아 설치함

 

3. Subversion 서버 설치

http://subversion.tigris.org/servlets/ProjectDocumentList?folderID=8100 에서 Apache 2.2 모듈을 포함하는 최신 SVN 바이너리 프로그램을 받는다. 현 최신 버전인 Setup-Subversion-1.6.3.msi를 받아 설치함

 

4. TortoiseSVN 설치 하기

이 프로그램은 클라이언트에서 주로 사용한다. 콘솔창에서 svnadmin create와 같은 명령어를 이용해 저장소 만드는 불편함을 없애기 위해 설치한다.

 

http://tortoisesvn.net/downloads 에 가서 다운로드 받아 설치한다. 현 최신 버전인 TortoiseSVN-1.6.3.16613-win32-svn-1.6.3.msi를 설치하면 된다.

 

5. SVN 저장소(Repository)를 생성한다.

저장소를 만들기 위해svnadmin create 명령어를 콘솔창에서 하는 방법도 있지만 방금 설치한 TortoiseSVN을 이용하면 쉽게 만들 수 있다. 먼저 아래 그림처럼 임의의 위치에 저장소 폴더를 만든다. 그리고 오른쪽 마우스 버튼을 눌러 컨텍스트 메뉴에서 TortoiseSVN을 선택한 뒤 Create repository here를 선택하면 된다. 그럼 The repository was successfully created 메시지가 뜨면서 저장소가 만들어진다. 테스트를 위해 저장소를 C:\svn 에 만들었다.

 

 

 

만들어진 저장소에 들어가보면 아래와 같은 내용이 만들어진 것을 확인할 수 있겠다.

 

conf 폴더 안에 있는 authz, passwd, svnserve.conf를 설정하여 이 저장소에 접근할 수 있는 권한 및 운영제반 사항을 설정할 수 있다. http 프로토콜로 서비스를 할 것이므로 authz 설정만 하면 된다. 즉, passwd와 svnserve.conf는 건드릴 필요가 없다. 이들은 svn프로토콜을 이용하면 반드시 설정해야한다.  설정 방법은 다음에 설명한다.

 

6. Apache 서버에 SVN 모듈 등록

 

Subversion의 설치 폴더(C:/Program Files/Subversion)에 bin폴더에 있는 mod_dav_svn.so와 mod_authz_svn.so 파일을 Apache의 modules 폴더에 복사한다.

 

그 다음 Apache 설치 폴더에 conf 폴더에 있는 http.conf를 아래와 같이 편집한다.

 

# 아파치 모듈 설정 부분에서 다음 부분의 주석을 푼다.
LoadModule dav_module modules/mod_dav.so
LoadModule dav_fs_module modules/mod_dav_fs.so

 

# 다음과 같은 SVN 모듈을 추가한다.
LoadModule dav_svn_module modules/mod_dav_svn.so
LoadModule authz_svn_module modules/mod_authz_svn.so

 

7. Apache 가상 호스트 설정

 

가상호스트는 말그대로 가상적인 호스트를 의미한다. 앞으로 만들 SVN 저장소에 접근할 수 있도록 가상으로 정한 주소를 이용해 Apache에 설정하는 것을 의미한다.

 

여기서 Apache 2.2 버전을 설치했으므로 http.conf에 아래 부분 처럼 가상 호스트 관련 설정파일을 포함하도록 되어 있다. Include 앞에 #을 지워준다.

 

# Virtual hosts
Include conf/extra/httpd-vhosts.conf

Apache 설치폴더에서 conf/extra/httpd-vhosts.conf 를 열어서 다음과 같이 추가한다.

 

############################################
# Sample 테스트용 SVN 가상호스트
############################################
<VirtualHost *:80>
    <Location /svn/test>
        DAV svn
        SVNPath "C:\svn"
        #SVNParentPath "C:\svn"
        #SVNListParentPath On
        AuthType Basic
        AuthName "SVN Test Repository"
        AuthUserFile "c:\svn\htpasswd"
        AuthzSVNAccessFile "c:\svn\conf\authz" 
        Require valid-user
    </Location>
</VirtualHost>

위 설정은 http://주소/svn/test 로 접근하게 되면 C:\svn 을 SVN 저장소 위치로 찾게 해준다는 의미가 내포되어 있다.

 

AuthUserFile은 사용자 목록 위치이며 AuthzSVNAccessFile은 접근권한 파일을 의미한다. 주석 처리된 SVNParentPath는 각 프로젝트의 저장소 디렉토리가 아닌 그 바로 위의 디렉토리를 뜻한다. http://주소/svn/test로 접속하여 C:\svn 뿐 아니라 http://주소/svn/test/other 로 하면  C:\svn\other 로도 접근이 가능해지는 것이다.

 

Require valid-user는 인증된 사용자만 사용할 수 있다. 만약 체크아웃(check-out)은 아무나(Anonymous)가 할 수 있게 하고 커밋(commit)은 지정된 사용자만 할 수 있게 하려면 Require valid-user 대신 아래처럼 사용할 수 있다.

 

############################################
# Sample 테스트용 SVN 가상호스트
############################################
<VirtualHost *:80>
    <Location /svn/test>
        DAV svn
        SVNPath "C:\svn"
        #SVNParentPath "C:\svn"
        #SVNListParentPath On
        AuthType Basic
        AuthName "SVN Test Repository"
        AuthUserFile "c:\svn\htpasswd"
        AuthzSVNAccessFile "c:\svn\conf\authz"  
        <LimitExcept GET PROPFIND OPTIONS REPORT>
            Require valid-user
        </LimitExcept>
    </Location>
</VirtualHost>

 

8. Apache 사용자 인증 파일 생성

 

위에서 AuthUserFile의 경로를 설정할 것을 보았을 것이다. 이제 그 파일을 만들자.

 

http 프로토콜을 사용하여 SVN에 접근하므로 Apache의 htpasswd를 이용해 사용자 인증을 한다.

 

htpasswd 파일을 생성은 다음과 같이 한다.

{아파치 설치 폴더}\bin\htpasswd -c htpasswd 사용자계정

 

htpasswd 파일에 사용자 추가 명령

{아파치 설치 폴더}\bin\htpasswd htpasswd 사용자계정

 

위와 같은 방법으로 사용자 계정을 추가해보자.

C:\svn\conf>C:\Apache\Apache2.2\bin\htpasswd -c htpasswd jidolstar
Automatically using MD5 format.
New password: ********
Re-type new password: ********
Adding password for user user1

만들어진 c:\svn\htpasswd 파일을 보면 아래와 같이 추가 되어 있는 것을 확인할 수 있을 것이다.

 

jidolstar:$apr1$IswHvHiJ$rBcOZc8bs59IUJIC/hWgO.

 

중요한 것은 -c는 한번만 사용한다. 안그러면 이전 내용이 지워져 버린다.

 

9. Subversion 접근 권한 파일 설정

c:\svn\conf 폴더에 보면 authz, passwd, svnserve.conf 파일이 있다. svn 프로토콜로 접근하지 않을 것이므로 authz만 수정하면 된다.

 

다음은 authz 파일 접근 권한 설정의 예이다.

 

[groups]
group1 = user1,user2
group2 = user3,user4,user5

 

[/]
* = r

 

[/project1]
@group1 = rw
@group2 = r

 

[/project2]
@group1 = rw
@group2 = r

무엇을 의미하는가? 2개의 그룹이 있다. 그룹 group1에는 사용자 1,2가 있고 그룹  group2에는 사용자 3,4,5가 있다. 이들은 http://주소/svn/test로 접근했을때 모두 read할 수 있으나 write권한은 없다. http://주소/svn/test/project1 에는 group1은 read/write를 다할 수 있으나 group2는 read만 할 수 있다. project2는 그 반대이다. 이런 식으로 svn에 접근 권한을 설정할 수 있는 것이다. 앞서 설명했지만 이 파일은 앞서 수정했던 가상 호스트 설정에서 Apache가 실행될 때 로드되어 진다.

 

본인은 앞서 jidolstar 아파치 계정을 하나 만들었으므로 다음과 같이 authz를 설정했다.

 

[groups]
group1 = jidolstar

 

[/]
* = rw

 

10. 웹브라우저에서 SVN 서버에 http로 접근하기

아래와 같은 윈도우 맨 우측아래 트레이 아이콘을 두번 클릭해 창이 뜨면 아파치를 구동하자. 미리 구동되어 있는 경우에는 새로운 설정을 로드해야하므로 stop했다가 다시 start한다. 위 설정을 잘 했다면 에러없이 구동이 될 것이다.

 

먼저 아파치가 잘 구동되는지 확인한다. 아래와 같이 창이 뜨면 정상이다. (참고로 이 페이지는 {아파치 설치경로}\htdocs에 있는 index.html 파일이다.)

 

 

이제 http://localhost/svn/test 로 접속해보자. 아래와 같은 인증창이 나오면 등록했던 사용자계정정보를 넣자.

 

인증이 완료되면 아래와 같은 화면이 나왔으면 성공이다.

 

이것으로 SVN 서버 구축을 모두 완료했더 테스트 까지 마쳤다.

 

여기서는 c:\svn에 저장소를 만들었지만 사람마다 다른 곳에 저장소를 만들고 싶을 것이다. 원하는 곳에 저장소를 만들어 테스트를 꼭 해보길 바란다. 가상호스트는 중복으로 만들 수 있으니 여러개의 저장소를 만드는 것도 가능하다.

 

 

Subversion 서버에 HTTP로 접속해 사용해 보기

 

SVN 서버는 모두 구축이 되었다. 이제 개인 소스 관리를 위한 테스트를 해보자. 만약 다른 컴퓨터에서 테스트 해보고 싶다면 그 컴퓨터에 TortoiseSVN 을 설치하길 바란다.

 

1. 체크아웃(check-out)

먼저 SVN 서버에 c:\svn에 있는 자료를 첫번째로 가져오는 일을 해야할 것이다. 이때 하는 일이 check-out이다. 바탕화면에 TestSVN 폴더를 만들어보자. 그런다음 아래 그림처럼 SVN Checkout를 실시한다.

 

그럼 아래처럼 Checkout 창이 뜬다. 우리는 http://localhost/svn/test 로 접속해서 이전에 만들어진 저장소 C:\svn에 있는 내용을 읽어올 수 있다고 했다. 아래처럼 URL of repository에 이 URL을 적고 OK버튼을 누른다.

 

 

브라우져에서 접속할때와 마찬가지로 인정절차가 필요하다. username과 password를 넣자. 다음부터 이 절차를 생략하고 싶다면 Save authentication을 check한다.

 

 

아래와 같이 Completed 가 나오면 완료가 된것이다. 지금은 아무 내용이 없다. ^^;

 

바탕화면에 만든 TestSVN 폴더에 보면 .svn 이 생성된다. .svn은 TestSVN이 접속한 저장소에 대한 정보를 가지고 있다. 앞에 점(.)이 있기 때문에 폴더옵션에서 숨김 파일 및 폴더 표시를 해주어야 보인다. 그렇지 않으면 TestSVN은 빈폴더처럼 보일것이다.

 

 

2. 커밋(commit)

체크아웃 한 소스를 수정, 파일 추가, 삭제 등을 한 뒤 저장소에 저장하여 갱신 하는 것이다. 커밋을 하면 전체 리비전이 1 증가하게 된다.

 

해보자. 앞에서 체크아웃한 TestSVN 폴더 내로 가서 tags, trunk, branches 폴더를 만든다. 또 각각의 폴더안에 tags.txt, trunk.txt, branches.txt를 만들어 본다. ? 표가 표시된 것은 이 파일이 어떤 상태인지 모른다는 것을 의미한다.

 

모두 선택한 뒤 아래처럼 TortoiseSVN > Add를 선택해서 커밋할 목록으로 등록한다.

 

이제 ?표에서 벗어나 + 표시로 바뀌었다. SVN 서버로 커밋할 준비가 된 것이다.

 

모두 선택한 뒤 아래 화면처럼 SVN Commit을 실시한다.

 

아래 그림의 창이 뜨면 SVN으로 전송할 목록이 선택되어 있고 Message를 남길 수 있게 된다. 이런식으로 만들어진 자료를 SVN로 전송할 수 있다. 지금은 추가된 내역만 올라가지만 만약 폴더 이름이 바뀌거나 위치를 옮기거나 삭제 되었거나 했을때는 added가 아니라 deleted, moved 이런 표시가 붙을 것이다.

 

아래 화면처럼 추가했던 + 표시는 없어지고 체크표시가 되었다. 정상적으로 SVN 서버에 올라간 것이다.

 

trunk를 선택하고 오른쪽 마우스 키를 눌러 Tortoise > show log를 보자. 아래처럼 Revision 번호가 1로 되어 있는 것을 확인할 수 있으며 그에 대한 Message와 함께 Commit된 것들도 확인할 수 있다.

 

 

TestSVN/trunk/trunk.txt 파일을 열어 내용을 입력하고 저장해보자. 아래처럼 !(느낌표) 표시가 될 것이다.

 

이것을 커밋해보자. 기존에 있는 것을 수정했으므로 상태는 modified가 되어 있다. 커밋하면 이제 리비전(revision)은 1에서 2로 바뀌게 된다.

 

브라우저에서도 확인해보자. http://localhost/svn/test 로 접속해서 아래와 같은 화면을 확인하자. add, modify 두번 처리해서 커밋했으므로 Revision이 2이다.

 

 

3. 업데이트(Update)

 

체크아웃을 해서 소스를 가져 왔더라도 다른 사람이 커밋(추가, 삭제, 이동, 변경등)을 하였다면 소스가 달라졌을 것이다. 이럴 경우 업데이트를 하여 저장소에 있는 최신 버전의 소스를 가져온다. 물론 바뀐 부분만 가져온다.

 

다른 사람이 변경한 내용이 있더라도 내가 변경한 내용이 따로 있다면 그 파일이나 폴더는 무시한다. 그러므로 항상 작업을 할 때는 먼저 업데이트를 하고 난다음 수정, 추가, 삭제, 이동의 작업을 완료후에 커밋해야 다른 사람 변경내용과 충돌이 일어나지 않는다. SVN은 겹쳐서 작업해서 서로 소스가 달라지는 경우 충돌보고를 해주기 때문에 안심하고 작업할 수 있다.

 

업데이트 방법은 매우 단순하다. 아래 그림처럼 SVN Update만 해주면 된다.

 


정리하며

 

윈도우 환경에서 Subversion 서버를 구축하는 방법과 사용법을 간단히 논했다. 사실 아주 일부분만 설명되어 있는 것이고 실무에서는 더욱 다양하게 쓰이게 된다. 개발자의 경우 TortoiseSVN을 이용한다기 보다 Eclipse나 Flash Builder 등에 SVN 플러그인을 설치하여 개발 코드 관리를 하는 것처럼 사용한다.

 

외부 컴퓨터에서 접속이 가능하게 하려면 반드시 80번 포트의 방화벽을 해제해주어야 한다.

 

쉬운 내용이지만 한번 정도는 정리할 필요가 있다고 생각했다. 막상 작성해보니 내용이 너무 길다. ^^;

 

 

글쓴이 : 지돌스타(http://blog.jidolstar.com/552)

 

위 그림은 Flex Builder 3(Flash Builder 4)의 Profiling(프로파일링) 기능에서 시간별 메모리의 상태를 보여주고 있는 것이다. 프로젝트를 하다가 저놈의 메모리가 도데체 왜 올라가는지 이해할 수 없었다. 분명 참조를 제대로 지워주고 있지 않으렸다!

 

등록했던 이벤트도 지워주고 자식들도 빼주고 붙여주면서 원인을 분석해갔다. 전체에서 부분으로 부분에서 전체를 훑어보면서 메모리의 변화를 계속 살펴봤다.

 

 

위 그림은 메모리가 정상적으로 반환되고 있는 모습이다. Flash Player에서는 참조관계가 root에 묶여 있거나 환형참조일때 가비지 컬렉션(Garbage Collection)으로 인식하여 어느 서점에 메모리에서 해지를 시킨다. 그래서 개발자는 참조를 잘 지워줘야 한다.

 

메모리가 비정상적으로 올라간 첫번째 원인은 이벤트 핸들러를 등록만 하고 지우지 않은데서 비롯되었다. 그래서 이벤트 핸들러를 약참조(weak reference)로 하도록 해서 해결했다. 약참조의 경우 소멸시점이 명확하지 않을때 유용하게 사용할 수 있다. 그리고 객체 중복 참조로 인해 메모리가 상승했는데 한쪽에서만 참조를 없애고 다른 한 곳에서는 삭제하지 않은 오류를 범했다. ㅡㅡ;

 

아~ Flex Builder에 이 기능이 없었다면 저걸 어떻게 찾을 수 있었을까? Flash Builder 4부터는 이 프로파일링 기능에 퍼포먼스 해석(performance analysis)기능 까지 추가 되고 개선되었다는데~~ 어찌하는지 해봐야 겠다.

 

Flex Builder에서 디버깅&프로파일링 하기 - 1부 -

Flex Builder에서 디버깅&프로파일링 하기 - 2부 -

 
Flash Builder는 아래 링크에서 다운로드 받을 수 있습니다.
http://www.adoberia.co.kr/pds/down.html?src=text&kw=000026 

 

Adobe RIA에 대한 정보에 대한 소통의 도구로 네이버 오픈캐스트를 개설했습니다. Flex, Flash, ActionScript 3.0을 주로 다룰 것이고 그와 관련된 LCDS, BlazeDS, ColdFusion등, 다양한 Adobe RIA와 관련된 기술도 공유하고자 합니다.

 

제 오픈 케스트에 올라왔으면 하는 글 있으면 언제든지 추천해주시고요.

구독도 많이 해주세요~~~

더욱 좋은 정보 공유를 위해 앞장서도록 노력하겠습니다. ^^

 

지금 생각하는 주제를 몇가지 적어보면

한글문제, 3D, 컴포넌트 제작, 보안, Stratus, Alchemy, LCDS, BlazeDS, CF.... , 또... 이들에 대한 세부 주제까지... 정말 많네요. ㅎㅎ

 

지돌스타의 Adobe RIA 오픈캐스트 : http://opencast.naver.com/FL188

 

 

 

일전에 Flex 4 CSS에 대한 글을 올렸습니다. Flex 4의 CSS는 Flex 3까지의 CSS의 한계를 극복하도록 만들어졌죠. 그런데 이 CSS가 기능이 확장된 계기가 있었습니다. 갑자기 궁금해지지 않나요? Flex 개발에 관련된 Adobe 개발자들이 머리를 짜서 하자고 했을까요? 아니면 어떤 요청이 있었을까요? 답은 Adobe Bug reporting 시스템에 있었습니다.

 

Adobe에서는 Adobe Bug Reporting 시스템을 운영하고 있습니다. 들어가보면 알겠지만 Flex, BlazeDS, Flash Player, ActionScript Compiler 주제로 개설되어 있고 개발자들의 요구사항 및 버그를 이곳에서 전부 받고 같은 요구사항이 있는 사람들이 투표하는 방식으로 진행되어 투표수가 많으면 Adobe에서 우선순위를 가려서 개발착수에 들어가지요.

Adobe Bug 리포팅 시스템 첫화면

 

 

Flex 4의 고급 CSS도 이런 과정을 통해 탄생된 겁니다.

 

https://bugs.adobe.com/jira/browse/SDK-14385

 

Flex CSS 지원해달라는 요구사항 페이지

 

Jacob Wright라는 사람이 리포팅을 했고 투표수가 75입니다. 그만큼 CSS의 기능이 더욱 확장되었으면 좋겠다는 사람의 수가 많은 거지요. 투표수가 많으니 Adobe 측에서도 무시할 수 없게 된 것이고 이번 Flex 4에서 지원하게 된 것입니다.

 

 

 

버그 리포팅에 참여하자.

 

그럼 우리도 참여할 수 있을까요?

때론 그럴겁니다 영어 못하기 때문에 참여 못한다고....

하지만 꼭 그렇지 않습니다. 자주 들어가 내용을 살펴보고 투표로써 작은 관심을 가져주는 것만으로도 충분합니다. 개발자중에서도 영어 잘하는 사람이 이런 글을 올립니다. 그럼 그 사람의 요청이 있으면 가서 투표해주면 되는 겁니다. 절대 어려운 일이 아닙니다. 아래에 버그 리포팅에서 추천(투표)의 중요성에 대해 알 수 있을 겁니다.

 

[열이아빠]플렉스 버그 리포팅에서 추천의 중요성

 

Adobe Flex/AIR 관련되어 한글문제가 꽤 있습니다. 이 한글문제를 해결하기 위해서도 이 버그 리포트 시스템을 이용하면 됩니다. 이미 Flash Platform 한글문제 공동대응팀이 생겼고 지속적으로 이 문제를 해결하기 위해 다양한 각도로 일하고 있습니다. 대응팀 총괄을 맡고 있는 이희덕씨 블로그에 관련 글이 많습니다.

 

[희희덕덕]한글문제 이슈 관련글

 

아래글은 열이아빠님이 쓰신 플렉스 버그 검색하는 방법입니다..

 

[열이아빠]플렉스 버그 검색해보기

 

투표에 참여해서 Flex/AIR/Flash 한글문제를 해결하는 방법입니다.

 

[희희덕덕]여러분의 참여로 한글 문제를 함께 해결해 봅시다!

 

 

앞으로 Flash Platform 한글문제 공동대응팀은 관련 자료를 종합하고 관리할 것입니다.

 

 

정리하며

 

여러분도 Adobe RIA 기술에 대한 불만 또는 원하는 사항들이 있을겁니다. 앞에서 설명드린데로 잘 정리해서 Adobe Bug Reporting 시스템에 올리시거나 투표를 적극적으로 참여함으로써 성취할 수 있는 겁니다. 한국 개발자들은 유독 영어 울렁증이 있다고들 호소하는데(저를 비롯) 사실 핑계라고 생각합니다. 필요하면 공부하면 되고요. 이런 일들은 꼭 영어를 잘해서 하는 일도 아니거든요. 한국 Adobe RIA 기술에 관련된 시장은 일본에 비해 거의 8배 정도 부족합니다.  그리고 적극성도 일본에 비해 많이 뒤쳐지며 나오는 컨텐츠의 창의력도 훨씬 뒤지는 편입니다. 왜 유독 일본어만 Flex Livedocs가 있을까요? Adobe는 시장성이 없는 한국에 한글문서 작성 인력을 투자하기에는 그들도 아깝다는 생각을 하는겁니다. 물론 Adobe는 그런 마음을 가지면 안되는 것이지만 또한 적극적이지 못한 우리도 반성해야될 일이라고 생각합니다. 우리가 안으로만 숨지않고 적극적으로 활동하면 Adobe에서 한국시장을 무시 못하게 될겁니다. 그런 날이 오길 반드시 바랍니다.

 

글쓴이 : 지돌스타(http://blog.jidolstar.com/549)

+ Recent posts