8.Customized Object

사용자가 원하는 component나 object를 만들어서 XLATFORM에서 사용할 수 있는 것을 Customized Object라고 합니다.

8.1Customized Object 란?

Customized Object을 쉽게 설명하자면, XPLATFORM에서 제공하는 Binary Object를 이용해서 사용자가 원하는 기능을 사용자가 직접 개발을 해서, 기존 XPLATFORM에서 제공하는 Binary Object와 동일하게 사용 할 수는 것을 말합니다.

XPLATFORM에서 제공하는 Customized Object의 종류는 다음과 같습니다.

Customized Object을 XPLATFORM에서 개발하고 사용하는 것을 간략히 도식화 하면 다음과 같습니다. 즉, UX-Studio에서 직접 개발을 한 후 TypeDefinition에 등록해서 사용을 합니다.

8.1.1Binary Object란?

Binary Object란 XPLATFORM에서 제공하는 모든 object입니다. 이 object는 다음과 같이 Visible Object와 Invisible Object로 구분을 합니다.

Visible Object를 XPLATFORM에서는 component라는 용어로 사용을 합니다. 그리고 object는 XPLATFORM에서 제공하는 모든 객체를 칭할 때 사용합니다.

Invisible Object는 Object중 visual 속성을 갖고 있지 않은 일부를 구분하기 위한 편의상의 명칭입니다. 통상적으로 object라고 하면 component를 포함한 모든 객체를 칭하는 것이고, 특별히 component와 구분을 해야 할 경우만 invisible object라고 사용합니다.

8.1.2Customized Object와 Binary Object의 관계

Customized Object와 Binary object의 관계를 간략히 설명하면 다음과 같습니다.

User Object는 Binary Object와 상속관계 입니다. 따라서 User Object는 Binary Object의 모든 기능을 기본적으로 가지고 있습니다. 물론 모든 Binary Object들을 상속 받을 수 있는 것은 아닙니다. Final로 선언해서 상속을 허용하지 않은 object를 제외한 모든 object은 상속을 받을 수 있습니다. (참고로 상속 가능한 object list는 UX-Studio의 wizard에서 제공을 합니다.) 그리고 XPLATFORM은 단일 상속만을 지원 합니다. 따라서 User Object도 단일 상속만 가능합니다.

Composite 컴포넌트는 다수의 User Object들과 Binary Object들을 조합하여 만드는 Customized 컴포넌트입니다.

Form Inheritance는 Form을 상속 받아서 구성합니다. 상속 받을 수 있는 form에는 특별한 제약이 없습니다. 즉, Binary object, User Object, Composite 컴포넌트들로 구성된 form을 상속 받아서 Binary object, user object, composite component들을 추가해서 form을 구성할 수 있습니다.

8.1.3Customized Object들의 비교


User Object

Composite 컴포넌트

Form Inheritance

사용 대상

XPLATFORM에서 정의한 object, User Object, Composite 컴포넌트

TypeDefinition에 등록된 object중 type이 UserForm이 아닌 것

TypeDefinition에 등록된 object중 type이 UserForm인 것

TypeDefinition 등록 여부

O

O

O

Design 변경여부

O

X

X

Toolbar 등록가능 여부

O

O

X

멤버 변수와 new 연산자의 맞지 않는 사용 예와 해결책

new 연산자는 새로운 객체를 생성하고 이를 초기화 하기 위하여 생성자 함수를 호출합니다.

사용자 클래스에 선언된 멤버변수를 new 연산자로, 사용자 클래스의 멤버변수로써 객체 생성을 의도 할 수 있습니다. 이때 new 연산자를 클래스 선언과 함께 사용하면, 의도와는 달리 해당 멤버변수가 global static으로 사용됩니다.

따라서 멤버변수를 선언하고, 이 멤버변수의 객체를 생성 할 때는, 사용자 클래스의 생성자 함수에서 해당 멤버 변수를 new가 되도록 사용해야 합니다.

8.2Composite 컴포넌트

User Object는 다중 상속을 지원하지 않기 때문에 여러 Object들의 기능을 묶어서 원하는 Object를 만드는 것 자체가 불가능합니다. 이에 XPLATFORM에서는 여러 Object들의 기능을 묶어서 하나의 component로 만들 수 있는 기능을 제공하는 데, 그것이 바로 Composite 컴포넌트입니다.

8.2.1Composite 컴포넌트 개념

Composite 컴포넌트는 XPLATFORM에서 사용 가능한 Object을 이용해서 새로운 component를 만드는 것입니다. Composite 컴포넌트가 가지고 있는 기본 개념은 다음과 같습니다.

8.2.2Composite 컴포넌트 파일 만들기

Composite 컴포넌트는 Form을 만드는 것과 동일하게 만들면 됩니다. 단, 만든 form을 TypeDefinition에 등록해야만 Composite 컴포넌트로 사용할 수 있습니다.

8.2.3Composite 컴포넌트 TypeDefinition에 등록하기

개발자가 만든 Composite 컴포넌트를 XPLATFORM에서 Binary 컴포넌트처럼 사용하기 위해서는 TypeDefinition에 등록을 해야 합니다. 그 방법은 다음과 같습니다.

단계 1. Edit TypeDefinition windows 띄우기
UX-Studio의 Project Explorer에서 TypeDefinition을 double click 하거나, 오른쪽 마우스 클릭 후 edit를 선택합니다.
단계 2. Add Object windows 띄우기
Edit TypeDefinition windows의 Objects에서 Add button을 클릭합니다.
단계 3. Object Type 선택하기
Add Object windows에서 Type중에 Composite를 선택합니다.

단계 4. Composite 컴포넌트 파일 선택
Add Object windows에서 url 찾기 버튼을 통해서 Extern File windows를 띄워서 추가하려는 Composite 컴포넌트 file을 선택하고, OK 버튼을 누르면 Object에 추가 됩니다.

8.2.4Composite 컴포넌트 사용하기

Form에서 Composite 컴포넌트는 binary Object와 User Object를 사용하는 것처럼 Composite 컴포넌트 id로 사용할 수 있습니다. 즉 Composite 컴포넌트 id가 compositeForm00이라고 했을 경우, script로 compositeForm00으로 접근을 해서 해당 Composite 컴포넌트에서 만든 함수, 변수를 사용할 수 있습니다. 또한 Composite 컴포넌트에 있는 Object들도 접근해서 사용할 수 있습니다.

다음은 Composite 컴포넌트의 id가 compositeForm00인 경우 사용하는 예들입니다.

// Composite 컴포넌트에서 선언한 변수 및 함수 접근
compositeForm00.myTrace(compositeForm00.strCompositeForm); 
// Composite 컴포넌트안에 있는 Button에 onclick event를 발생
compositeForm00.Button00.onclick.fireEvent(obj, e); 
// Composite 컴포넌트안에 있는 Button 속성 변경
compositeForm00.Button00.text = "oh~"; 
compositeForm00.Button00.style.gradation = "linear 0,0 white 100,100 black";
// Composite 컴포넌트안에 있는 Button move method 실행
compositeForm00.Button00.move(374, 20);

8.2.5Composite 컴포넌트 예제

Dataset에 bind한 Grid와 Edit 2로 화면을 다음과 같이 구성했습니다.

Script는 다음과 같이 구현했습니다.

var strCompositeForm = "CompositeForm";

function Button00_onclick(obj:Button, e:ClickEventInfo)
{
    alert(Dataset00.rowcount);
    myTrace("Button00_onclick");
}

function myTrace(val)
{
    trace("my trace : " + val);
}

즉, form에 변수(strCompositeForm) 하나와 함수(myTrace), 그리고 button에 handler를 등록해서 해당 handler를 구현했습니다.

만든 form을 TypeDefinition에 composite로 등록해서 form에 올린 다음 다음과 같이 디자인을 할 수 있습니다.

위 화면은 composite component를 2개 올려서 하나는 background에 gradation을 지정했습니다.

Script는 다음과 같이 만들었습니다.

function Button00_onclick(obj:Button, e:ClickEventInfo)
{
    compositeForm00.myTrace(compositeForm00.Button00.text);
    compositeForm00.Button00.onclick.fireEvent(obj, e);
    alert("^^");
}

function compositeForm00_onclick(obj:compositeForm02, e:ClickEventInfo)
{
    trace("compositeForm00_onclick");
    for (x in e)
        trace(x + " : " + e[x]);

    trace("object ");
    for (y in obj)
        trace(y + " : " + obj[y]);
}

function Button01_onclick(obj:Button, e:ClickEventInfo)
{
    compositeForm00.Button00.text = "oh~";
    compositeForm00.Button00.style.gradation = "linear 0,0 white 100,100 black";
}

function Button02_onclick(obj:Button, e:ClickEventInfo)
{
    compositeForm00.Button00.move(374, 20);
    trace(compositeForm00.strCompositeForm);
}

Script의 설명은 “10.2.4.장” Composite 컴포넌트 사용하기를 참조하십시오.

8.3Form Inheritance

이미 만들어진 Form을 상속받아서 다른 Object들을 추가하여 새로운 Form을 만들 수 있는 것이 Form Inheritance입니다.

8.3.1Form Inheritance 개념

Form Inheritance 개념을 설명하기 위해서 상속 받을 form을 parent form이라고 하고, 상속 받은 form을 child form이라고 하고 설명을 하겠습니다.

  1. Parent form은 child form의 좌표 0,0을 기준으로 그립니다.

    Parent form에 UI가 있는 경우 parent form의 component들은 child form의 좌표0,0 (Top, left 기준)를 기준으로 그립니다.

Child form의 Source에는 parent form에 대한 정보는 다음과 같이 parent form명만 명시되어 있을 뿐 어떠한 정보도 가지고 있지 않습니다.

<?xml version="1.0" encoding="utf-8"?>
<FDL version="1.0">
    <TypeDefinition url="..\..\default_typedef.xml"/>
    <Form id="childForm03" classname="childForm03" inheritanceid="baseForm01" 
        cachelevel="" position="absolute 0 0 1024 768" version="" 
        titletext="New Form">
        <Layout>
            <Button id="Button02" position="absolute 407 37 527 87" 
                taborder="0" text="Button02"/>
        </Layout>
    </Form>
</FDL>
  1. TypeDefinition 등록

    Form을 상속 받기 위해서는 TypeDefinition에 등록 돼있어야 합니다. User Object와 Composite 컴포넌트처럼 Toolbar에 등록되지는 않습니다. 단지 form을 만들 때 상속 받을 form을 지정만 하면 됩니다.

  1. Parent Form 수정 불가

    Parent form의 object, script는 수정할 수 없습니다. 즉 Design 시 parent form안의 Button의 position을 변경한다거나 style을 변경하는 것은 불가능합니다. 하지만, Runtime시 script로는 변경 가능합니다.

    다음과 같이 form을 상속 받은 다음 마우스를 drag한 경우 parent form의 내부 component들은 선택이 되지 않음을 알 수 있습니다. 즉, 내부 component들이 선택되지 않으므로 해당 property를 변경할 수 없게 되는 것입니다.

8.3.2Form을 TypeDefinition에 등록하기

개발자가 만든 form을 상속해서 사용하기 위해서는 TypeDefinition에 등록을 해야 합니다. User Object와 Composite 컴포넌트는 TypeDefinition에 등록을 하면 UX-Studio의 toolbar에 해당 component id로 icon이 생기지만 Form은 Object가 아니기 때문에 toolbar에 icon이 생기지는 않습니다.

TypeDefinition에 등록하는 방법은 다음과 같습니다.

단계 1. Edit TypeDefinition windows 띄우기
UX-Studio의 Project Explorer에서 TypeDefinition을 double click 하거나, 오른쪽 마우스 클릭 후 edit를 선택합니다.
단계 2. Add Object windows 띄우기
Edit TypeDefinition windows의 Objects에서 Add button을 클릭합니다.
단계 3. Type 선택하기
Add Object windows에서 Type중에 UserForm을 선택합니다.

단계 4. Form 파일 선택
Add Object windows에서 url 찾기 버튼을 통해서 Extern File windows를 띄워서 추가하려는 form을 선택하고, OK 버튼을 누르면 Objects에 추가 됩니다.

8.3.3상속 받아서 Form 파일 만들기

Form을 만들 때 상속 받을 form을 지정해서 만들면 됩니다. 자세한 방법은 다음과 같습니다.

단계 1. Create New Form Wizard windows 띄우기
UX-Studio의 Toolbar의 New를 선택하거나, 메뉴(File > New > Item > Form)에서 선택합니다.

단계 2. Form 이름 및 경로 지정하기
Create New Form Wizard windows에서 Name에 Form의 이름을 Location에 경로를 지정하고 Next 버튼을 누릅니다.

단계 3. 상속 받을 form 지정하기
Inheritance FDL에서 상속 받을 form을 지정하고 Next를 누릅니다.

Inheritance FDL의 목록은 TypeDefinition의 Objects의 type이 UserForm인 것만 나옵니다.

단계 4. form size 지정하기
만들고자 하는 form의 크기를 지정합니다.
Width에 form의 가로 길이를 height에 form의 세로 길이를 입력합니다.

단계 5. Widget form 지정여부 설정하기
Widget으로 개발할 때는 “A form for creating an widget”을 check 합니다. 그 외의 form들은 check하지 않고 OK 버튼을 누르면 됩니다.

8.3.4상속받은 form 사용하기

Child form에서 parent form의 변수, 함수뿐만 아니라 parent form에 있는 object들도 접근할 수 있습니다. 접근하는 방법은 child form에 있는 object, 함수, 변수를 접근하는 것과 동일하게 접근하면 됩니다. 만약 child form에서 override한 함수가 있으면 child form에 있는 것을 호출하게 됩니다. Child form에서 강제적으로 parent form에 있는 것을 호출하려면 super라는 reserved word를 사용해서 접근하면 됩니다.

8.3.5Function Override

Parent에 있는 function을 child에서 재 정의하고 싶으면 parent와 동일한 이름으로 function을 만들면 됩니다. ECMAScript spec3에서는 동일한 이름의 function이 여러 개 있을 경우 맨 마지막에 함수를 호출하는 원리와 비슷합니다. 또한 ECMAScript spec3에서는 function의 parameter가 다르다고 하더라도 동일한 function으로 인식하고 맨 마지막 function만 인식합니다. 즉, function overload는 지원하지 않습니다. 참고로 function overload를 사용하려면 arguments를 이용해서 사용해야 합니다.

arguments.length를 이용한 overload 구현 예

function myOverload () 
{
    if(arguments.length == 1) {
        return(arguments[0] + 10);
    } else if (arguments.length == 2) {
        return(arguments[0] * arguments[1]);
    }
}

alert(myOverload(10)); // 20
alert(myOverload(10, 10)); // 100

8.3.6Form Inheritance 예제

Image에 animation효과를 준 form을 다음과 같이 만들었습니다.

Run button을 누르면 자동차 모양의 이미지가 앞으로 움직이고, init button을 누르면 처음 위치로 되 돌아가는 간단한 form입니다. Animation 기능을 구현하기 위해서 PropertyAnimation 객체를 form에 올려서 position x값을 변경해 주었습니다.

Source는 다음과 같습니다.

<?xml version="1.0" encoding="utf-8"?>
<FDL version="1.0">
    <TypeDefinition url="..\default_typedef.xml"/>
    <Form id="parentForm" classname="parentForm" inheritanceid="" cachelevel="" 
        position="absolute 0 0 1024 768" version="" titletext="New Form">
        <Layout>
            <ImageViewer id="ImageViewer00" taborder="0" text="ImageViewer00" 
                image="URL('images::intro_image01.png')" 
                position="absolute 10 80 640 196"/>
            <Button id="Button00" taborder="1" text="Run" 
                position="absolute 483 32 560 58" 
                style="clickeffect:PropertyAnimation00;"/>
            <Button id="Button01" taborder="2" 
                position="absolute 566 32 643 58" text="init" 
                onclick="Button01_onclick"/>
        </Layout>
        <Objects>
            <PropertyAnimation id="PropertyAnimation00" starttime="0" 
                targetcomp="ImageViewer00" interpolation="Interpolation.bounceOut" 
                fromvalue="10" duration="3000" targetprop="position.x" 
                tovalue="400" endingmode="current"/>
        </Objects>
    </Form>
</FDL>

Script는 다음과 같습니다.

function Button01_onclick(obj:Button, e:ClickEventInfo)
{
    ImageViewer00.move(10, 80);
}

Animation에 대한 자세한 설명은 “5장 Animation 기능”을 참조하십시오.

위에서 구현한 form을 상속 받기 위해서 TypeDefinition에 등록합니다.

TypeDefinition에 등록한 form을 상속 받아서 다음과 같이 child form을 만들었습니다.

Child form은 parent를 상속 받았기 때문에 Animation객체가 없어도 parent form과 동일하게 Run button을 누르면 이미지가 앞으로 움직입니다. 그리고 Animation을 중간에 중단하는 기능을 추가하기 위해서 Stop button을 추가해서 Animation 중단 코드를 추가했습니다.

Source는 다음과 같습니다.

<?xml version="1.0" encoding="utf-8"?>
<FDL version="1.0">
    <TypeDefinition url="..\default_typedef.xml"/>
    <Form id="childForm" classname="childForm" inheritanceid="parentForm" 
        cachelevel="" position="absolute 0 0 1024 768" version="" 
        titletext="New Form">
        <Layout>
            <Button id="Button03" taborder="1" text="stop" 
                onclick="Button03_onclick" position="absolute 648 31 711 58"/>
        </Layout>
        <Objects/>
    </Form>
</FDL>

그리고 script는 다음과 같습니다.

function Button03_onclick(obj:Button, e:ClickEventInfo)
{
    PropertyAnimation00.stop();
}

Child form의 source를 보면 상속 받은 form명을 inheritanceid에 명시하고 신규로 추가한 Button만 가지고 있음을 알 수 있습니다. 또한 child form에는 없는 object인 PropertyAnimation00을 script로 접근을 해서 Animation을 중단하는 기능을 추가했음을 알 수 있습니다.