レイアウトの使い方

はじめに

多くの場合、Curl® IDE エディタを Curl ビジュアル レイアウト エディタと併用する必要があります。イベント ハンドラの追加などのアクションを実行する際には、IDE ソース エディタを使用して VLE が生成したコードを編集する必要があります。このセクションでは、VLE が生成するコード、その構造、および最も効果的な VLE の使用法について説明します。

IDE でのレイアウトの表示

このセクションでは、VLE で表示したときのレイアウトと IDE ソース エディタに表示されたときの生成済みコードとの関係を理解するのに役立つ、いくつかの目印を提供します。
VLE レイアウト ファイル内の各レイアウトは、生成済みコード内の define-layout-class マクロ呼び出しに対応します。define-layout-class マクロ呼び出しはレイアウト クラスを定義します。レイアウトのトップレベルのコンテナに割り当てるデザイン名がこのクラスの名前になります。既定の名前は MyContainer です。これはクラス名なので、クラスの命名に使用する命名規則に従う必要があります。
次の図は、レイアウト クラスが VLE の [レイアウト ツリー][レイアウト]、および [プロパティ] ペインと生成済みコードにどのように現れるかを示しています。レイアウトのトップレベルのオブジェクトの名前と生成済みコードに定義されているレイアウト クラスとの対応を強調するため、MyContainer という名前が赤丸で囲まれています。
Figure: VLE および IDE におけるレイアウト クラス
define-layout-class マクロ呼び出しは、レイアウト クラスのフィールドを定義する layout-containerlayout-element、および argument-container マクロ呼び出しを含むことができます。レイアウト内のオブジェクトに割り当てるデザイン名が、これらのフィールドの名前です。フィールドの命名に使用する命名規則に従う必要があります。
次の図は、VLE レイアウト内の CommandButton と結果の生成済みコードを示しています。VLE のデザイン名と生成済みコードのフィールド名との対応を強調するため、my-button という名前が赤丸で囲まれています。
Figure: VLE および IDE の CommandButton

VLE オブジェクト用のイベント ハンドラ

生成された VLE コードを編集する理由としては、レイアウト内のオブジェクト用のイベント ハンドラを作成することが最も大きいと思われます。イベントとイベント ハンドラについては、「イベント」を参照してください。VLE イベント ハンドラの作成はクラス定義との関連で行うので、レイアウト内のオブジェクトの参照には self. 構文をします。
すべてのレイアウト クラスには、container と呼ばれ、自動的に生成されるフィールドがあります。このフィールドは、レイアウトのトップレベルのコンテナ オブジェクトを含みます。この名前に直接アクセスすることはできません。また、この名前を変更することもできません。このトップレベルのオブジェクトをブラウザで表示するために生成されるコードは次のとおりです。
{value {new MyContainer}.container}
このコードは、レイアウト クラス (この例では MyContainer と名付けられている) のインスタンスを作成し、このオブジェクトを container という名前のインスタンスで返します。
次の図は、VLE レイアウト内のボタン用のイベント ハンドラを定義するコードを示しています。このイベント ハンドラは、トップレベルのコンテナの背景色を "小麦色" に変えます。イベント ハンドラがレイアウトをブラウザに表示するオブジェクトを参照するという事実を強調するため、container という名前が赤丸で囲まれています。
Figure: container オブジェクト
次の図は、レイアウト内のオブジェクトのためのイベント ハンドラを示しています。各イベント ハンドラは self.field-name を使用して他方の EllipseShape を参照するので、一方の楕円が押されると他方の楕円の色が変わります。この楕円のフィールド名は、[レイアウト ツリー] ペインとソース コードの両方で、赤丸で囲まれています。
Figure: VLE のイベント ハンドラ

クラス メンバの追加

レイアウト クラス指定には、定義するクラスの場合とほぼ同様に、追加のフィールド、メソッド、および祖先を含めたクラス メンバを追加できます。例えば、レイアウト内の複数のイベント ハンドラで同じコードを実行しなければならない場合があります。このような場合は、そのコードをメソッドに組み込んで、そのメソッドを各イベント ハンドラから呼び出すようにすることが賢明です。
また、コンストラクタに追加コードを追加することもできます。既定のコンストラクタの生成済みコードは、組み込みのレイアウト クラス メソッド initialize-components を呼び出します。
{constructor {default}
    {self.initialize-components}
}
このメソッドは、トップレベルのオブジェクトの container、およびレイアウト クラス定義で指定されたすべての子オブジェクトをインスタンス化します。状態の初期化を必要とするオブジェクトがレイアウト内にある場合は、状態を初期化するコードをコンストラクタに追加する必要があります。また、レイアウト クラスにフィールドを追加し、それらのフィールドを初期化するコードをコンストラクタに追加することもできます。また、コンストラクタに引数を追加して、必要な情報を提供できるようにしなければならない場合もあります。

あるレイアウトからの別のレイアウトの参照

レイアウト内のあるオブジェクトを別のオブジェクトから参照する方法は、セクション「VLE オブジェクトのためのイベント ハンドラ」に説明されています。Web アプリケーションは一緒に機能する複数のレイアウトから構成できるので、これらのパーツも相互に連絡し合う必要があります。このセクションでは、あるレイアウト内のオブジェクトを別のレイアウト内のオブジェクトから参照する方法について説明します。
この説明では、Curl IDE の拡張例にある 2 つのコード例に言及します。これらの例をブラウザで実行し、それぞれのソース コードを IDE エディタおよび VLE で表示できます。拡張例の使用法の詳細については、「拡張例」を参照してください。
アーカイブ d:\automated-build-temp\build\win32-atom\docs\default\examples\layout-editor\Layouts.zip に入っている例を抽出します。このアーカイブには 2 つのディレクトリがあり、それぞれに VLE プロジェクトが入っています。1 つのレイアウトに実装された簡単なアプリケーションを説明するアプレット例を one-layout で実行します。プロジェクトを開き、IDE エディタで vle-container.scurl ファイルを開いてそこに入っているコードを調べます。次のコードを調べます。このコードは、TextFieldemail-field というデザイン名で定義します。イベント ハンドラは self.design-name 構文を使用してレイアウトの他のコンポーネントを参照することに、注意してください。
{layout-element email-field:TextField
    {TextField
        text-preserve-whitespace? = true,
        text-breakable? = true,
        {on ValueFinished do
            {self.display-area.clear}
            {self.display-area.add 
                {format "You are: %s %s",
                    self.name-field.value,
                    self.email-field.value}}
        }
    }
}
例を抽出して two-layouts で実行します。この例は one-layout のアプレットと同じ機能を実行しますが、この例では、アプリケーションのデータ入力部分は別のレイアウトにあります。例を実行したとき最初に表示されるレイアウトは MainPage と呼ばれます。テキスト Tell us about yourself... が現在、MainPageCommandButton のラベルになっています。そのコマンド ボタンの Action イベント ハンドラが、レイアウト NameEmail に定義されているデータ入力ダイアログを呼び出します。
この例は、その行に NameEmail というデザイン名があるレイアウト クラスのインスタンスを作成します。
{let name-email:NameEmail = {new NameEmail}}
name-email はタイプ NameEmail のオブジェクトであることに注意してください。このレイアウトのトップレベルのコンテナとして Dialog が選択されたので、NameEmail は、Dialog をトップレベルのオブジェクトとして含むレイアウト クラスです。レイアウトを VLE で表示すると、トップレベルのコンテナのタイプとして Dialog が現れます。また、コードを IDE で表示すると、文字列 "Dialog"design-time-class および run-time-class の値になります。
レイアウト MainPage のコードには、もう 1 つのレイアウト NameEmail を呼び出すコマンド ボタンを定義する次のコードが入っています。
{layout-container void:CommandButton
    {CommandButton
        label = "Tell us about yourself...",
        {on Action do
            {name-email.container.show title = "Tell us about yourself..."}
            {self.display-area.clear}
            {self.display-area.add 
                {format "You are: %s %s",
                    name-email.name-field.value,
                    name-email.email-field.value}}

        }
    }
}
このコードは name-email を表示するもので、CommandButtonon Action イベント ハンドラに入っています。
{name-email.container.show title = "Tell us about yourself..."}
このコードは、name-email にある暗黙のトップレベルのオブジェクトの container を使用します。このオブジェクトは Dialog であるため、show メソッドが name-email を表示します。
ユーザーが名前と電子メール アドレスを入力してダイアログを閉じると、コード
{self.display-area.clear}
self. 構文を使用して、現行レイアウト内のオブジェクト (この場合は、display-area という表示名を持つ TextFlowBox) を参照します。
最後に、イベント ハンドラはユーザーの入力を display-area に追加します。イベント ハンドラは、name-email にある name-fieldemail-fieldvalue プロパティからユーザーの入力を取得します。
NameEmail レイアウトでは、email-fieldValueFinished イベント ハンドラが {self.container.close "OK"} を使用してダイアログを閉じます。この表現は、ダイアログそのものである暗黙のトップレベルのレイアウト オブジェクト container に適用されます。