カスタマイズオブジェクト

使用者が要求するコンポーネントやオブジェクトを作り、XPLATFORMで使用することができるようにしたものをカスタマイズオブジェクトと言います。

カスタマイズオブジェクトとは?

カスタマイズオブジェクトを簡単に説明すると、XPLATFORMで提供するバイナリーオブジェクトを利用して使用者が要求する機能を使用者が直接に開発し、既存のXPLATFORMで提供するバイナリーオブジェクトと同様に使用することができます。

XPLATFORMで提供するカスタマイズオブジェクトの種類は、以下の通りです。

カスタマイズオブジェクトをXPLATFORMで開発・使用する内容を簡略に図式化すると、以下の通りです。即ち、UX-Studio、直接に開発してからTypeDefinitionに登録して使用します。

バイナリーオブジェクトとは?

バイナリーオブジェクトとは、XPLATFORMで提供する全てのオブジェクトのことです。このオブジェクトは、以下のようにVisibleオブジェクトとInvisibleオブジェクトに区分されます。

Visibleオブジェクトは、XPLATFORMではコンポーネントという用語を使用します。そして、オブジェクトはXPLATFORMで提供する全てのオブジェクトを示す時に使用します。

Invisibleオブジェクトは、オブジェクトの中でvisualのプロパティを持っていない一部を区分するための便宜上の名称です。通常的にオブジェクトと言えばコンポーネントを含む全てのオブジェクトを称し、特別にコンポーネントと区分しなければならない場合にのみinvisibleオブジェクトとします。

カスタマイズオブジェクトとバイナリーオブジェクトの関係

カスタマイズオブジェクトとバイナリーオブジェクトの関係を簡略に説明すると、以下の通りです。

ユーザーオブジェクトはバイナリーオブジェクトと継承関係があります。従って、ユーザーオブジェクトは基本的にバイナリーオブジェクトの全ての機能を持っています。もちろん、バイナリーオブジェクトを継承できるわけではありません。Final宣言して継承を許容しないオブジェクトを除いた全てのオブジェクトを、継承できます。(参考として、継承可能なオブジェクトのリストはUX-Studioのwizardで提供します。)そして、XPLATFORMは単一継承のみをサポートします。従って、ユーザーオブジェクトも単一継承のみが可能です。

コンポジットコンポーネントは、多数のユーザーオブジェクトとバイナリーオブジェクトの組み合わせにより作成されるカスタマイズコンポーネントです。

フォーム継承は、フォームを継承して構成します。継承することができるフォームには、特に制約がありません。即ち、バイナリーオブジェクト、ユーザーオブジェクト、コンポジットコンポーネントなどで構成されたフォームの継承してバイナリーオブジェクト、ユーザーオブジェクト、コンポジットコンポーネントなどを追加してフォームを構成することができます。

カスタマイズオブジェクトの比較


ユーザ

オブジェクト

コンポジット

コンポーネント

フォーム継承

使用対象

XPLATFORMで定義したオブジェクト、ユーザーオブジェクト、コンポジットコンポーネント

TypeDefinitionに登録されたオブジェクトの中でユーザーフォームタイプでないもの

TypeDefinitioに登録されたオブジェクトの中でユーザーフォームタイプのもの

TypeDefinition の登録設定

O

O

O

デザインの

変更設定

O

X

X

ツールバーの登録可能設定

O

O

X

メンバー変数とnew演算子の合わない使用例と解決策

New演算子は、新しいオブジェクトを生成し、初期化するために生成者関数を呼び出します。

ユーザクラスに宣言されたメンバー変数をnew演算子に、ユーザクラスのメンバー変数としてオブジェクトの生成を意図することができます。このとき、new演算子を暮らす宣言と共に使用すると、意図とは関係なく該当メンバー変数がglobal staticとして使用されます。

従って、メンバー変数を宣言し、そのメンバー変数のオブジェクトを生成するためには、ユーザクラスの生成者関数から該当メンバー変数がnewになるように使用する必要があります。

コンポジットコンポーネント

ユーザーオブジェクトは多重継承をサポートしないため、いくつかのオブジェクトの機能をまとめて作りたいオブジェクトを作ること自体が不可能です。そのため XPLATFORMでは、いくつかのオブジェクトの機能をまとめて1つのコンポーネントに作成することができる機能を提供しますが、それがコンポジットコンポーネントです。

コンポジットコンポーネントの概念

コンポジットコンポーネントは、XPLATFORMで使用可能なオブジェクトを利用して新しいコンポーネントを作成します。コンポジットコンポーネントが持っている基本概念は、以下の通りです。

  1. フォームを持っています。

    1つのフォームに必要なオブジェクトを追加し、コンポジットコンポーネントに保存する方式を使用します。UIを除いたinvisibleオブジェクト(ソケット、データセットなど)やスクリプトにのみ必要な機能を実装してコンポジットコンポーネントを作成することもできますが、必ずフォームの上に貼り付けて保存しコンポジットコンポーネントを作成します。

コンポジットコンポーネントファイルの作成

コンポジットコンポーネントの作成はフォームの作成と同じです。但し、作成したフォームをTypeDefinitionに登録することによって、コンポジットコンポーネントで使用することができます。

コンポジットコンポーネントをTypeDefinitionに登録

開発者が作成したコンポジットコンポーネントをXPLATFORMでバイナリーコンポーネントのように使用するためには、TypeDefinitionに登録しなければなりません。その方法は、以下の通りです。

段階1. Edit TypeDefinition画面を開く
UX-StudioのProject ExplorerでTypeDefinitionをダブルクリックするか、マウスを右クリックしてからeditを選択します。
段階2. Addオブジェクト画面を開く
Edit TypeDefinition画面のオブジェクトでAddボタンをクリックします。
段階3. オブジェクトタイプを選択
Add Object画面でTypeの中のコンポジットタイプを選択します。

段階4. コンポジットコンポーネントファイルの選択
Add Object画面でurl検索ボタンによりExtern File画面を表示し、追加したいコンポジットコンポーネントファイルを選択してからOKボタンをクリックすると、オブジェクトに追加されます。

コンポジットコンポーネントファイルの使用

フォームでコンポジットコンポーネントはバイナリーオブジェクトとユーザーオブジェクトを使用するように、コンポジットコンポーネントidを使用することができます。即ち、コンポジットコンポーネントidがcompositeForm00である場合には、スクリプトによりcompositeForm00にアクセスして該当のコンポジットコンポーネントで作った関数や変数を使用することができます。また、コンポジットコンポーネントにあるオブジェクトもアクセスして使用することができます。

以下は、コンポジットコンポーネントのidがcompositeForm00の場合の例です。

//コンポジットコンポーネントで宣言した変数及び関数へのアプローチ
compositeForm00.myTrace(compositeForm00.strCompositeForm); 
// コンポジットコンポーネント内にあるボタンにonclickイベントが発生
compositeForm00.Button00.onclick.fireEvent(obj, e); 
// コンポジットコンポーネント内にあるボタンのプロパティの変更
compositeForm00.Button00.text = "oh~"; 
compositeForm00.Button00.style.gradation = "linear 0,0 white 100,100 black";
// コンポジットコンポーネント内にあるButton move methodの実行
compositeForm00.Button00.move(374, 20);

コンポジットコンポーネントの例題

データセットにバインドしたグリッドとEdit 2で画面を以下のように構成しました。

スクリプトは以下のように実装しました。

var strCompositeForm = "CompositeForm";

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

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

即ち、フォームに変数(strCompositeForm)1つと関数(myTrace)、そしてボタンに handlerを登録して該当のhandlerを実装しました。

作成したフォームをTypeDefinitionにコンポジットで登録しフォームに貼り付けてから、以下のようにデザインすることができます。

上の画面は、コンポジットコンポーネントを2つ貼り付け、1つはバックグラウンドの指定をグラデーションにしました。

スクリプトは以下のように作成しました。

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);
}

スクリプトの説明は、“10.2.4.章”のコンポジットコンポーネントの使用を参照してください。

フォーム継承

フォーム継承は、既に作られているフォームを継承して他のオブジェクトを追加し、新しいフォームを作成することができます。

フォーム継承の概念

フォーム継承の概念を説明するために、継承されるフォームを親フォーム、継承するフォームを子フォームと呼びます。

  1. 親フォームは、子フォームの座標0,0を基準として描画します。

    親フォームにUIがある場合には、親フォームのコンポーネントは親フォームの座標0,0(上、左基準)を基準として描画します。

子フォームのソースにある親フォームについての情報は、以下のように親フォーム名のみ明示されているだけで何の情報も持っていません。

<?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への登録

    フォームを継承するには、TypeDefinitionに登録されていなければなりません。しかし、ユーザーオブジェクトやコンポジットコンポーネントのように、ツールバーに登録されはしません。フォームを作成する際に継承するフォームを指示するだけでよいです。

  1. 親フォームの修正は不可能

    親フォームのオブジェクトとスクリプトは修正することができません。即ち、デザイン時に親フォーム内のボタンのポジションを変更したりスタイルを変更したりすることは不可能です。しかし、ランタイム時のスクリプトによる変更は可能です。

    以下のように、フォームを継承してからマウスでドラッグした場合には、親フォーム内部のコンポーネントは選択されません。即ち、内部のコンポーネントが選択されないため、該当のプロパティを変更することができません。

フォームをTypeDefinitionに登録

開発者が作成したフォームを継承して使うには、TypeDefinitionに登録しなければなりません。ユーザーオブジェクトとコンポジットコンポーネントは、TypeDefinitionに登録するとUX-Studioのツールバーに該当のコンポーネントidでアイコンが生じますが、フォームはオブジェクトではないためツールバーにアイコンが生じません。

TypeDefinitionに登録する方法は以下の通りです。

ステップ1. Edit TypeDefinition画面を開く
UX-StudioのProject ExplorerでTypeDefinitionをダブルクリックするか、マウス右側のボタンをクリックしてからエディットを選択します。
ステップ2. Addオブジェクト画面を表示
Edit TypeDefinition画面のオブジェクトでAddボタンをクリックします。
ステップ3. タイプを選択
Add Object 画面でユーザーフォーム(UserForm)タイプを選択します。

ステップ4. フォームファイルの選択
Add Object画面でurl検索ボタンによりExtern File画面を開き、追加したいフォームを選択してからOKボタンをクリックすると、オブジェクトに追加されます。

継承してフォームファイルを作成

フォームを作成する際に、継承するフォームを指定します。詳細な方法は以下の通りです。

ステップ1. Create New Form Wizard画面を開く
UX-StudioのツールバーのNewを選択するか、メニュー(File > New > Item > Form)で選択します。

ステップ2. フォーム名及びパスを指定
Create New Form Wizard画面でNameにフォーム名、Locationにパスを指定してNextボタンをクリックします。

ステップ3. 継承フォームを指定
Inheritance FDLで継承するフォームを指定しNextをクリックします。

参考として、Inheritance FDLのリストは、TypeDefinitionのオブジェクトのタイプがユーザーフォームのものだけが表示されます。

ステップ4. フォームサイズの指定
作成するフォームのサイズを指定します。
Widthにはフォームの横の長さを、heightにはフォームの縦の長さを入力します。

ステップ5. ウィジェットフォームを指定するか否かを設定
ウィジェットで開発する時には“A form for creating an widget”をチェックします。その他のフォームはチェックせずにOKボタンをクリックします。

継承してフォームの使用

子フォームから親フォームの変数や関数のみならず、親フォームにあるオブジェクトにもアクセスすることができます。アクセス方法は、子フォームにあるオブジェクト、関数、変数にアクセスするのと同じです。もしも子フォームでオーバーライドした関数があれば、子フォームにあるものを呼び出します。子フォームで強制的に親フォームにあるものを呼び出すには、superという予約語を使用してアクセスします。

ファンクションのオーバーライド

親ファンクションを子で再定義するには、親と同一名でファンクションを作成します。ECMAScript spec3では、同一名のファンクションがいくつかある場合には最後の関数を呼び出すルールに似ています。また、ECMAScript spec3では、ファンクションのパラメータが異なったとしても同一ファンクションとして認識し、最後のファンクションのみを認識します。即ち、ファンクションのオーバーロードはサポートしません。参考として、ファンクションのオーバーロードを実現するには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

フォーム継承の例題

イメージにアニメーション効果を与えるフォームを、以下のように作成しました。

Runボタンをクリックすると自動車型のイメージが前に動き、initボタンをクリックすると最初の位置に戻る簡単なフォームです。アニメーション機能を実装するためにプロパティアニメーションのオブジェクトをフォームに貼り付け、ポジションのx値を変更しました。

ソースは以下の通りです。

<?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>

スクリプトは以下の通りです。

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

アニメーションについての詳細な説明は、“5章のアニメーション機能”を参照してください。

上で実装したフォームが継承できるようにTypeDefinitionに登録します。

TypeDefinitionに登録したフォームが継承され、以下のように子フォームを作成しました。

子フォームは親を継承したため、アニメーションオブジェクトがなくても親フォームと同じくRunボタンをクリックするとイメージが前に動きます。そして、アニメーションを途中で中断する機能を追加するために、Stopボタンを追加してアニメーション中断コードを追加します。

ソースは以下の通りです。

<?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>

そして、スクリプトは以下の通りです。

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

子フォームのソースを見ると、継承するフォーム名がinheritanceidに明示され、新規で追加したボタンのみを持っていることがわかります。また、子フォームにないオブジェクトPropertyAnimation00にスクリプトによりアクセスし、アニメーションを中断する機能を追加したことがわかります。