VLE 機能拡張エディタ の章は、
ユーザー自身によって VLE パレット選択の拡張・強化する目的の VLE パレット拡張ファイルの作成ツールである
VLE 機能拡張エディタの説明があります。この章では、VLE 機能拡張ファイルの内容と構成のさらに詳しい説明があります。
この章では最も簡単なケースから始めて、いくつかの高度なトピックに進んで解説します。
以下のセクションでは簡単な概要を説明しています。これらを読んだ後、他のセクションでさらに深く掘り下げて学ぶことができます。
実行時クラスを定義してその VLE 機能拡張を作成する場合は、以下のセクションにも目を通す必要があります。
Curl IDE ドキュメントには、このセクションに関する豊富なサンプルが含まれています。これらのサンプルをブラウザで実行し、IDE エディタと VLE でソース コードを見ることができます。「
内容の充実したサンプル ファイル」を参照してください。
この章では、追加の リーフ
(取り外し可能)オブジェクトを扱うために VLE 機能を拡張するための十分な情報が含まれています。
リーフ
オブジェクトは、VLE で編集される他のオブジェクトのコンテナとしての機能を持ちません。
ここで説明されている方法よりさらに洗練された方法で VLE を拡張する場合は、VLE
のアーキテクチャに関するより詳細な知識が必要です。これを習得するには、次のディレクトリにある
VLE ソース ファイルを直接調べてみてください。
d:\automated-build-temp\build\win32-atom\ide\vle\editor
以下のセクションのいくつかには、このディレクトリにある特定ファイルへの参照が含まれていて、そこで特定の VLE 機能についてさらに学習することができます。「
コンテナ オブジェクトのエディタ」のセクションでは、コンテナ オブジェクトを編集するための VLE 機能拡張の作成について解説しています。
ここで説明する VLE の機能拡張テクノロジーは、Curl IDE のバージョン 3.0.4 とそれ以降のバージョンに関連しています。このテクノロジーは、バージョン 2.0 と 3.0.0 から大幅に変化しています。その結果、これらの以前のバージョンで作成された VLE 機能拡張はバージョン 3.0.4 とそれ以降のバージョンで必ず動作するとは限らず、さらに、この章で説明されている手順に従って作成された VLE 機能拡張が以前のバージョンで動作するという保証はありません。以前のバージョンの VLE を使って作成された VLE ソース ファイルをバージョン 3.0.4 とそれ以降のバージョンの VLE にインポートすることは可能ですが、3.0.4 以前のバージョンで作成された VLE 機能拡張ファイルのほとんどは、手動で更新する必要があります。
先の話になりますが、この章に掲載されている情報に従って作成された VLE 機能拡張は、今後の VLE バージョンでも動作することになっています。だたし、VLE 機能拡張ファイルが複数の VLE ソース ファイルを読み取って集められた情報に依存する場合は、今後の VLE バージョンで動作するために修正が必要になることがあります。
VLE では、オブジェクト エディタをパレット上のアイコンとして表します。オブジェクト エディタでは、VLE が
[レイアウト ツリー] ペインにオブジェクトを追加する方法、
[レイアウト] ペインで表現する方法、
[プロパティ] ペインでオブジェクトのプロパティを編集する方法も定義します。このセクションでは、Curl API オブジェクトの 1 つである
Scrollbar の VLE オブジェクト エディタについて説明します。VLE オブジェクト エディタを作成する前に、次の点を考慮する必要があります。
- プロパティ シートで Scrollbar のどのプロパティをユーザーが編集できるようにするか、およびこれらのプロパティ エディタにはそれぞれどのようなユーザー インターフェイスが必要か。
- [プロパティ] ペインから Scrollbar のどのイベント ハンドラをユーザーが編集できるようにするか。
- VLE ユーザーが VLE で新しい Scrollbar をインスタンス化するときに、どの Scrollbar プロパティで既定値を設定しておくか。
- Scrollbar アイコンを既存のパレット タブまたは新規パレットのどちらに表示するか。
- Scrollbar アイコンにどのような画像を表示するか。
このサンプル コードは、次のファイルに含まれています。
d:\automated-build-temp\build\win32-atom\docs\default\examples\layout-editor\Scrollbar.zip
アーカイブからファイルを解凍したら、scrollbar-ext.scurl を探します。IDE エディタでファイルを確認し、[パレット機能拡張] ダイアログを使ってこのファイルを VLE にロードし、動作させてみてください。
{import * from CURL.GUI.STANDARD}
{let public constant direction-pmd:PropertyMetaData =
{OptionMetaData
"direction",
{EnumerationEditor
{StringArray "vertical", "horizontal"}
},
help-text =
{message
Specifies whether a Scrollbar stretches out
vertically or horizontally.
}
}
}
{define-class public DesignTimeScrollbar {inherits DesignTimeGraphic}
{constructor public {default}
{construct-super
{ObjectMetaData
{MetaDataCategory
name = "General",
design-name-pmd,
direction-pmd
},
standard-geometry-meta-data-category,
{MetaDataCategory
name = "Colors",
color-pmd,
control-color-pmd,
background-pmd
},
standard-border-meta-data-category,
{EventHandlerCategory
{EventHandlerMetaData "Adjustment"}
},
default-selected-property = "design-name",
default-selected-event = "Adjustment"
}
}
}
{getter public open {initial-properties}:{Array-of PropertyDescriptor}
{return
{new {Array-of PropertyDescriptor},
{PropertyDescriptor direction-pmd, "\"horizontal\""}
}
}
}
{getter public {runtime-class-name}:String
{return "Scrollbar"}
}
{method protected {new-object element:LayoutElement}:GraphicOptions
{return {Scrollbar}}
}
{getter public {palette-tab-name}:String
{return "Controls"}
}
{getter protected {palette-graphic}:Graphic
{return
{image
blocking? = true,
source = {url "images/scrollbar-icon.gif"}
}
}
}
}
{register-palette-item DesignTimeScrollbar}
このファイルの 4 つのステートメントは、オブジェクト エディタを定義する 4 つのステップに対応しています。
- import ステートメントを使って、必要な実行環境を設定します。
- オブジェクトのプロパティ情報を提供します。この例では、定数 direction-pmd を定義するコードで、direction プロパティの情報を提供しています。color や background などの Scrollbar プロパティは他の多数の Curl API にも存在しますが、これらについては VLE で PropertyMetaData オブジェクトが既に定義されています。したがって VLE 実行コードでこれらを再定義する必要はありません。事前定義されているこれらのオブジェクトの完全なリストは、「事前定義されている PropertyMetaData オブジェクト」を参照してください。
- DesignTimeGraphic のサブクラスを定義して、VLE が新しいオブジェクト タイプをどのように扱うかを記述します。この例では、サブクラスは DesignTimeScrollbar と呼ばれています。慣例により、オブジェクトの実行時の名前が Name の場合、これを編集する DesignTimeGraphic のサブクラスには、DesignTimeName という名前を使います。
- register-palette-item プロシージャを呼び出して、新しいパレット アイコンを実際に追加します。
VLE 機能拡張ファイルを 1 つ作成し、1 つ以上のオブジェクト エディタを定義することができます。 この場合、VLE 機能拡張ファイルで複数の DesignTimeGraphic サブクラスを定義し、それぞれに register-palette-items の呼び出しを含めます。機能拡張により複数のアイコンが同じ [パレット] タブに置かれる場合、タブ内で左から右へ表示される順序は、機能拡張ファイル内の register-palette-items 呼び出しの順序に一致します。
以下の複数のセクションでは、これらの手順についてさらに詳しく解説します。
VLE は、
COM.CURL.LAYOUT-EDITOR.EDITOR パッケージが既にインポートされている環境内で機能拡張ファイルを評価します。このパッケージでは、
DesignTimeGraphic、
register-palette-item および前述の機能拡張ファイルの例で使われているその他の VLE 特有の API アイテムが定義されています。このパッケージの実装を確認するには、次の VLE ソース ファイルを開いて、ファイルの終わりにある
include ステートメントのリストに現れるファイルを調べてください。
d:\automated-build-temp\build\win32-atom\ide\vle\editor\load.scurl
ただし、
COM.CURL.LAYOUT-EDITOR.EDITOR は
CURL.GUI.STANDARD スーパーパッケージから標準 Curl グラフィックス API をエクスポートしていません。この機能拡張ファイルでは、これらの API の一部 (
Graphic、
Scrollbar および
image など) が参照されているので、このファイルは
CURL.GUI.STANDARD のインポートから始まっています。
PropertyMetaData オブジェクトは、VLE で編集可能な各オブジェクト プロパティがデザイン時にどのように扱われるかを記述するものです。
OptionMetaData は
PropertyMetaData のサブクラスで、ローカルまたは非ローカル オプションのプロパティの記述に使われます。
direction はローカル オプションなので、サンプル コードでは
OptionMetaData のコンストラクタを呼び出しています。この例に示されるような簡単なケースでは、このコンストラクタは 2 つの位置引数と 1 つのキーワード引数を取ります。
- 最初の位置引数はオプションの名前です。この名前は VLE プロパティ シートの 名前 列に OptionMetaData コンストラクタに提供した通りに表示されることに注目してください。このドキュメントについている機能拡張の例では、この名前は英語で提供されています。VLE オブジェクト エディタをその他の言語での使用するために書き込んでいる場合、適切な言語でプロパティ名を提供するか、機能拡張ファイルをローカライズしてください。「ローカライズ可能な VLE 機能拡張ファイルの作成」を参照してください。
- 2 番目の位置引数では、このプロパティ値の編集に使われるプロパティ エディタ (VLE の PropertyEditor クラスのサブクラス) を指定します。
- help-text キーワード引数では、このプロパティを編集するために選択したときに VLE の [プロパティ] ペインの下に表示されるヘルプ テキストを指定します。 let ステートメントでは、結果の PropertyMetaData オブジェクトの名前として direction-pmd を定義しています。
- Orientation.vertical
- Orientation.horizontal
VLE では EnumerationEditor クラスが用意されています。これは、列挙型の値を持つオプションを編集するための PropertyEditor のサブクラスです。この例では EnumerationEditor を使ってこのオプションのプロパティ エディタを生成しています。
DesignTimeScrollbar クラスでは、
Scrollbar 自体の編集に関する VLE の動作を指定します。このクラスのコンストラクタはスーパークラスのコンストラクタを呼び出し、
ObjectMetaData 引数を渡します。
ObjectMetaData では、VLE で
Scrollbar 型のオブジェクトが編集される際のプロパティ シートの内容を指定します。オブジェクトのメタデータには、
PropertyMetaData オブジェクトのグループがいくつか含まれます。各グループは
MetaDataCategory と呼ばれ、オブジェクトの個々のプロパティを表す 1 つまたは複数の
PropertyMetaData オブジェクトがこのグループに含まれます。
EventHandlerCategory はこれらのグループの 1 つですが、特別に扱われます。このカテゴリのプロパティはすべて、
[プロパティ] ペインの
[イベント ハンドラ] タブに表示されます。その他のプロパティはすべて
[プロパティ] ペインの
[プロパティ] タブに表示されます。下図に示されるように、この
Scrollbar エディタは
[プロパティ] タブ内で、
[全般]、
[配置]、
[色] および
[境界] の 4 つのプロパティ グループを定義します。これらのグループにはそれぞれ独自の
MetaDataCategory オブジェクトが存在します。
[全般] グループには
design-name プロパティが含まれ(ほとんどの場合、常に含めるようにします)、
direction も含まれています。
direction プロパティ エディタは、前述の
direction-pmd プロパティ メタデータ オブジェクトで指定されています。
design-name プロパティ エディタは
design-name-pmd オブジェクトによって指定されています。このオブジェクト自体は
COM.CURL.LAYOUT-EDITOR.EDITOR パッケージで定義されています。このパッケージでは、Curl 言語のグラフィカル オブジェクトに関するその他多数の共通プロパティについて、プロパティのメタデータ オブジェクトが定義されています。これらの事前定義されているプロパティ メタデータ オブジェクトのリストは、「
事前定義されている PropertyMetaData オブジェクト」を参照してください。
[配置] グループは
standard-geometry-meta-data-category によって指定されています。これは標準 VLE で事前定義されている
MetaDataCategory オブジェクトで、
width、
height、
horigin および
vorigin オプションが含まれています。ほとんどの場合、このグループに必要なオプションのセットはこれだけです。
[色] グループには、
Scrollbar の外観に影響を与えるカラー関連オプション (
color、
control-color および
background) が含まれています。これらの 3 つのオプションのプロパティ メタデータ オブジェクトは、
COM.CURL.LAYOUT-EDITOR.EDITOR で
color-pmd、
control-color-pmd および
background-pmd として既に定義されています。
[境界] グループは standard-border-meta-data-category によって指定されています。standard-geometry-meta-data-category と同様に、これは COM.CURL.LAYOUT-EDITOR.EDITOR で既に定義されている MetaDataCategory オブジェクトです。グラフィカル オブジェクトの境界線や余白を制御する標準 Curl オプションのエディタが含まれています。
最後に、この簡単な
Scrollbar エディタでは、1 つのイベント タイプのイベント ハンドラ エディタを提供しています。このイベント タイプは、
Scrollbar の値が変更された場合に発生する
Adjustment イベントです。
Scrollbar プロパティ シートのこの部分は、
[境界] グループの指定に続く
EventHandlerCategory 式によって指定されています。
VLE が
Scrollbar のプロパティ シートを初めて表示するときには、プロパティ エディタの 1 つがアクティブな状態になります。この最初に選択されるプロパティは、
ObjectMetaData コンストラクタの
default-selected-property キーワード引数によって指定します。この例では
design-name です。同様に、VLE が
Scrollbar のプロパティ シートの
[イベント ハンドラ] タブを初めて表示するときには、いずれかのイベント ハンドラが選択された状態になります。最初に選択されるイベント タイプは
default-selected-event キーワード引数によって指定します。この例では
Adjustment です。
DesignTimeGraphic サブクラスの
initial-properties メソッドでは、VLE ユーザーがオブジェクトのインスタンスを新規作成してレイアウトに置くときに使われる、特定プロパティの初期値を指定します。この例では、
direction オプションを
"horizontal" に設定して新しい
Scrollbar をそれぞれ作成するように
DesignTimeScrollbar で指定しています。VLE ユーザーは、オブジェクトを作成した後で
[プロパティ値を元に戻す] コマンドを使い、このオプションを設定解除できます。この初期値は次の行で指定されています。
{PropertyDescriptor direction-pmd, "\"horizontal\""}
initial-properties ゲッターは、初期のプロパティ値を指定する PropertyDescriptor の配列を返します。空の配列が返される場合もあります。この配列の各要素は、次のような呼び出しで生成されます。
{PropertyDescriptor pmd, source-code}
この要素により、
pmd で示されるプロパティに関して、設定された値を使ってスクロール バーを作成するように VLE に指示します。
source-code 引数には
String 値で、ここには VLE が初期プロパティ値を計算するために評価するソース コードを含めます。この例では、プロパティを設定するソース コードは次のとおりです。
direction = "horizontal"
したがって、このキーワード引数の値の部分は "horizontal" になります。皆さんは、この式には、次のようにもう 1 組の引用符があるのではと予想されているのではないでしょうか。
{PropertyDescriptor direction-pmd, "\"horizontal\""}
事実その通りで、必要なソース コード自体に引用符が含まれているため、
追加
の引用符が必要になります。
"\"horizontal\"" の外側にある引用符のペアは、これが
String リテラルであるために必要で、バックスラッシュ文字でエスケープされている内側のペアは、この
String リテラルの値自体がその先頭と末尾に引用符文字が付いたソース コードであるため必要になります。 複雑なケースでは、
stringify マクロを使ってこのような source-code 文字列を作成すると便利です。
この簡単な
Scrollbar エディタを利用できるようにするために、いくつかの情報項目を指定する必要があります。これらの各項目は、それぞれ異なる
DesignTimeGraphic のメソッドか、
DesignTimeScrollbar のゲッターをオーバーライドすることによって制御します。
- runtime-class-name ゲッターは String を返し、編集されたオブジェクトに関して、実行時の動作を提供するクラスの名前を指定します。この場合、実行時のクラスは Scrollbar なので、このゲッターは "Scrollbar" を返します。
- new-object メソッドは、編集されたオブジェクトを表すためにデザイン時に使われるオブジェクトを返します。この簡単なケースでは、デザイン時のオブジェクトは実行時に使われるのと同じクラスのインスタンスなので、DesignTimeScrollbar では新規に作成された Scrollbar オブジェクトを返すようにこのメソッドを定義しています。
- palette-tab-name ゲッターは String を返し、このエディタのアイコンを格納する VLE パレット タブの名前を指定します。DesignTimeScrollbar では、[コントロール] タブに Scrollbar アイコンが収まるように指定されています。このゲッターは既存のタブの名前を返さなくてもかまいません。ゲッターが既存のタブ名に一致しない名前を返す場合、指定された名前のタブが VLE パレットに追加され、その新規作成タブにアイコンが置かれます。文字列の照合は VLE ユーザー インターフェイスで使用された言語に依存することに注目してください。このドキュメントについている機能拡張の例では、タブの名前「コントロール」は英語で提供されています。この名前は、VLE を他の言語のユーザー インターフェイスで実行している場合は、コントロール タブの名前と一致しません。VLE ユーザー インターフェイスで使用されている言語でタブの名前を提供するか、タブの名前をローカライズする必要があります。「ローカライズ可能な VLE 機能拡張ファイルの作成」を参照してください。
- palette-graphic ゲッターは、このエディタのアイコンとして使われる Graphic を返します。標準の VLE で指定されているアイコンはすべて 28x28 ピクセルの画像です。外観をよくするために、このメソッドが返す Graphic のサイズは 28x28 ピクセルにしてください。
このセクションでは、VLE 機能拡張でプロパティ メタデータを定義する場合に VLE がサポートしているその他の方法について説明します。このサポートは複数の形で存在します。
次の表には、COM.CURL.LAYOUT-EDITOR.EDITOR パッケージで定義済みの便利な PropertyMetaData オブジェクトが一覧表示されています。
似たようなプロパティの PropertyMetaData オブジェクトを定義する方法については、次の VLE ソース ファイルを開いてこれらの変数の定義を調べることにより詳細な情報が得られます。
d:\automated-build-temp\build\win32-atom\ide\vle\editor\design-time-class.scurl
COM.CURL.LAYOUT-EDITOR.EDITOR パッケージでは以下の MetaDataCategory オブジェクトが定義されています。
- standard-geometry-meta-data-category は [配置] グループを定義します。ここには、前述の Scrollbar の編集例で示されたような、Graphic の配置プロパティを制御するプロパティ エディタの標準セットが含まれています。
- standard-border-meta-data-category は [境界] グループを定義します。ここには、前述の Scrollbar の編集例で示されたような、Graphic の境界線プロパティを制御するプロパティ エディタの標準セットが含まれています。
- standard-font-meta-data-category は [フォント] グループを定義します。ここには、グラフィカル オブジェクトのテキストに使われるフォントを制御するためのプロパティ エディタの標準セットが含まれています。このグループには、font-size、font-family、font-style および font-weight オプション用のエディタが含まれます。
COM.CURL.LAYOUT-EDITOR.EDITOR パッケージには、最も一般的なデータ型のプロパティ エディタがすぐに使える状態で用意されています。独自の
PropertyMetaData オブジェクトを定義するときにこれらのエディタを使うことができます。
Scrollbar の例では、事前定義の
EnumerationEditor を使って
direction-pmd を定義しました。
プロパティ エディタは VLE に次のようなサービスを提供します。
プロパティ値のソース コードを分析し、デザイン時にそのプロパティで使われる値を決定します。
例えば色に関するプロパティ エディタは、ソース コードの "red" を読み取り、これが赤という色に対応することを判定します。通常プロパティ エディタは実際にソース コードを実行しないので、プロパティ エディタで認識できるパターンにソース コードの構文が適合しない場合、エディタはデザイン時のプロパティ値が認識不可能であると通知します。例えば、次のソース コードでは、
{if profit < 0 then "red" else "black"}
色のプロパティ エディタはデザイン時のプロパティ値を判定できません。これは、変数 profit の値が実行時までわからないためです。
- プロパティ値がプロパティ シートに表示される方法を制御します。例えば、色のプロパティ エディタがデザイン時のプロパティ値を判定できる場合、プロパティ シートには色の名前だけでなく、その色見本も表示されます。
- プロパティ値を編集するためのグラフィカル ユーザー インターフェイスを提供します。
さまざまなプロパティ エディタは、実行時に処理する値の型、認識できる source-code パターンの範囲、およびプロパティ値の表示や編集用に提供するユーザー インターフェイスがそれぞれ異なります。通常プロパティ エディタのユーザー インターフェイスは、次のようなプロパティ値の編集方法を提供します。
- ソース コードに関連するプロパティ値をプロパティ エディタが認識できる場合は、ネイティブ エディタが使われます。ネイティブ エディタの多くは、プロパティ値の解釈や表現方法において非常に精巧にできています。例えば、色のプロパティのネイティブ エディタには、現在選択されている色の見本が表示され、色の選択ダイアログ ボックスを開くためのボタンが含まれています。
- プロパティ エディタがプロパティの現在のソース コードを分析できない場合は、インライン コード エディタが使われます。このエディタは、プロパティのソース コードの先頭行をプロパティ シートに直接表示します。プロパティのソース コードが 1 行しかない場合は、プロパティ シートで直接編集することができます。
- IDE のソース エディタに制御を移し、そこでプロパティのソース コードを編集できます。
次の表に示されるプロパティ エディタには、VLE 機能拡張を定義する際に便利な機能が搭載されています。これらはすべて COM.CURL.LAYOUT-EDITOR.EDITOR で定義されています。
これらのプロパティ エディタはすべて、次のような構文を使って OptionMetaData または NonOptionMetaData の引数に指定できます。
{OptionMetaData property-name, property-editor-class-name.instance}
次に例を示します。
{OptionMetaData "enabled?", BoolPropertyEditor.instance}
特別なクラスである
EnumerationEditor を使って、任意の列挙型のプロパティ エディタを作成することができます。前述の例題では、このクラスを使って
direction オプションの
direction-pmd PropertyMetaData オブジェクトを作成しています。この例から推測できるように、値が
v1、
v2、
v3 などの名前を持つ列挙型に対しては、通常は次のようにプロパティ エディタを作成します。
{EnumerationEditor {StringArray "v1", "v2", "v3", ...}}
COM.CURL.LAYOUT-EDITOR.EDITOR には上の図で省略されたエディタもいくつか定義されていますが、これらは非常に特別で、VLE の機能拡張にあまり役立つものではありません。事前定義されているプロパティ エディタの完全なセットを調べるには、次の VLE ソース ファイルを開いてください。
d:\automated-build-temp\build\win32-atom\ide\vle\editor\property-editors.scurl
独自の PropertyEditor サブクラスの定義は高度なトピックで、この概要では詳細には解説していませんが、次の VLE ソース ファイルで PropertyEditor クラスの定義を参照して、
d:\automated-build-temp\build\win32-atom\ide\vle\editor\property-editors.scurl
このファイルの詳細なコメントに含まれている情報を参考にすることができます。これらのコメントを読み、このファイルで実装されている PropertyEditor サブクラスを調べることにより、独自のプロパティ エディタを作成する方法を学ぶことができます。
「
組み込み Curl API の VLE 機能拡張」で解説されている
Scrollbar エディタでは、
direction オプションに対して独自の
PropertyMetaData オブジェクトが定義されています。他のプロパティに対しても、独自の
PropertyMetaData オブジェクトを定義するには以下を実行する必要があります。
- 適切な PropertyMetaData サブクラスを選択します。OptionMetaData と NonOptionMetaData からいずれかを選択します。
- 選択したサブクラスのコンストラクタに、適切な引数を提供します。
実行時にオプションとして定義されるプロパティには OptionMetaData を使う必要があります。上述の例で direction-pmd の定義に示されているように、OptionMetaData コンストラクタを最も簡単に呼び出す方法としては引数を 2 つだけ使います。
{OptionMetaData property-name, property-editor}
ここで、
property-name はプロパティの名前を提供する
String で、
property-editor は、このプロパティ用のプロパティ シートの行の動作を制御する
PropertyEditor オブジェクトをその値に持つ式になります。この
PropertyEditor は、「
事前定義されているプロパティ エディタ」の説明に従って指定します。
Scrollbar の例ではキーワード引数も 1 つ指定されています。以下に示すオプションのキーワード引数はすべて
OptionMetaData コンストラクタに提供することができます。
- help-text: String 値で、このプロパティを編集する目的で選択したときに、[プロパティ] ペインの下に表示されるヘルプ テキストを指定します。
- nonlocal?: bool 値で、このプロパティが非ローカル オプションの場合は true、ローカル オプションの場合は false (既定値) を指定します。
- default-source: String 値で、このオプションの既定値として評価する source-code 文字列を指定します。このキーワード引数が指定されない場合は既定により "null" になります。これは、既定値が null のオプションには適切な値です。
- 表示名: String 値で、プロパティ シートの左側の欄に表示される、このプロパティの名前を制御します。この引数が指定されない場合は property-name が使われます。この引数の主な用途は、VLE 機能拡張ファイルのローカライズに関連するものです。
- ソートキー: String 値で、プロパティを名前のアルファベット順にソートする場合のソート キーとして使われます。名前によるソートは、VLE ユーザーが [プロパティ] ペインで [名前] 列見出しをクリックすると起こります。Unicode 文字コードによる編纂法に基づいてソートされます。この引数が指定されない場合、表示名 で使われたのと同じ文字列がこの目的でも使われます。表示名 と同様に、この引数はローカライズ可能な VLE 機能拡張ファイルを作成する場合に主に役に立ちます。
CommandButton.style のように、実行時にオプションとして定義されないプロパティは
NonOptionMetaData オブジェクトによって記述します。
NonOptionMetaData は広範囲にわたる状況に対応するため、
OptionMetaData よりも本質的に複雑なものです。
OptionMetaData の場合と同様に、基本的な
NonOptionMetaData コンストラクタの呼び出しでは、
property-name と
property-editor の位置引数を 2 つだけ指定します。以下に示すような、さまざまなキーワード引数も利用できます。
- help-text: OptionMetaData の場合と同じ。
- meta-data?: この bool 値の引数を true に設定すると、このプロパティ値は、ソース コードの meta-data セグメント内で Begin meta-data DO NOT EDIT と End meta-data コメントの間に表示されます。この引数は、高度なアプリケーションで Canvas などのコンテナ用に精巧なエディタを作成する場合にのみ役に立ちます。この引数を指定しない場合、既定により false になります。
- unsettable?: この bool 値の引数を true に設定すると、このプロパティに対して [プロパティ値を元に戻す] コマンドを使えるようになります。この引数を false に設定すると、[プロパティ値を元に戻す] コマンドは無効になります。値を指定しない場合、この引数の既定値は meta-data? 値の反対になります。meta-data? が false の場合はこの引数の既定値は true になり、meta-data? が true の場合は false になるので、通常はこの引数を明示的に指定する必要はありません。
- data-bindable?: この bool 値の引数を true に設定すると、このプロパティに対して [データ バインディングの編集] コマンドを使えるようになります。この引数を false に設定すると、[データ バインディングの編集] コマンドは無効になります。値を指定しない場合、この引数の既定値は unsettable? の値になります。
- choices?: この bool 値の引数を true に設定すると、キーワード引数ではなく 1 つまたは複数の位置引数としてこのプロパティ値のソース コードがフォーマットされます。この引数を指定しない場合、既定により false になります。
- default-source。OptionMetaData の場合と同様に、これは String 値で、プロパティの既定値として評価する source-code 文字列です。ただし NonOptionMetaData の場合は、この引数の既定値は空の文字列 "" で、キーワード プロパティのソース コードとして正しいものではありません。したがって、choices? が true である場合を除き、このキーワード引数を常に指定する必要があります。
- set-at-design-time?: この bool 値の引数を true (既定値) に設定した場合、VLE でこのプロパティを設定すると、[レイアウト] ペインでこのオブジェクトを表現するデザイン時オブジェクトのプロパティを設定することになります。この引数を false に設定した場合は、このプロパティは [レイアウト] ペインにあるオブジェクトの外観に影響を及ぼしません。いずれの場合でも、VLE ユーザーがこのプロパティの値を設定すると、値はソース コードに書き込まれ、実行時のオブジェクトの動作に影響を及ぼします。
- display-name: OptionMetaData の場合と同じ。
- sort-key: OptionMetaData の場合と同じ。
- db-default-value-source:
VLE ユーザーがプロパティのデータ バインドを作成すると、VLE は
bind オペレータの呼び出しを含むソース コードを生成します。
db-default-value-source はこの
bind 式の
default-value 句を制御します。
db-default-value-source が null の場合、VLE は
default-value 句を生成しません。その他の場合は次の形式で句を生成します。
default-value = expr
ここで、
db-default-value-source が
expr のソース コードを提供する
String 値になります。
unsettable? が true の場合、
db-default-value-source の既定値は null になります。それ以外の場合、既定値は
default-source の値に等しくなります。
pd-creator: これは高度な機能であり、その動作を把握するには以下のファイルのソース コードを調べてみてください。
d:\automated-build-temp\build\win32-atom\ide\vle\editor\design-time-class.scurl
d:\automated-build-temp\build\win32-atom\ide\vle\editor\data-access-design-time-classes.scurl
この機能が必要になる可能性はおそらくありません。
このセクションでは、DesignTimeGraphic のその他のいくつかの便利な機能について説明します。
DesignTimeScrollbar オブジェクト エディタの例では、VLE で編集するオブジェクトは
Scrollbar 型です。実行時には、このオブジェクトは
Scrollbar クラスの既定のコンストラクタを使って作成されます。これは最も一般的なパターンです。VLE 機能拡張ファイルでこのパターンをサポートするには、
runtime-class-name ゲッターをオーバーライドして、該当するクラスの名前を返すだけで済みます。上述の例でもこれを行っています。
だたし、状況がかなり複雑な場合があります。例えば、
submit-button API の VLE パレット アイコンを考えてみましょう。
submit-button はクラスではなく、
CommandButton を返すプロシージャです。この場合、クラス名とコンストラクタ式を別々に制御できるようにする必要があります。
DesignTimeGraphic には、この目的でオーバーライドできる
design-time-class-name というゲッターがあります。さらに、ツールヒントを提供したり、オブジェクトを
[レイアウト ツリー] ペインに表示する目的で独自のオブジェクトのインスタンスにラベルを付ける場合は、クラス名以外の名前を選択することが推奨されています。この目的で
class-name-for-display ゲッターを使うことができます。これらのゲッターはそれぞれ
String を返します。次の表はこれらのプロパティの要約です。
ゲッターの名前 | 既定値 | 目的 |
runtime-class-name | なし。 | 実行時にオブジェクトのインスタンスを作成するコンストラクタ式のオペレータに対応するソース コードを返します。 |
design-time-class-name | runtime-class-name が返す値。 | 実行時のオブジェクト型を記述する式に対応するソース コードを返します。通常これはクラス名です。 |
class-name-for-display | design-time-class-name が返す値。 | VLE のユーザー インターフェイス内のオブジェクト ラベルに使われる文字列を返します。 |
例えば、
submit-button の VLE アイコンを定義する場合に、VLE のユーザー インターフェイスにある submit-button オブジェクトのラベルとして、「
Submit Button」を使うとします。この場合、
DesignTimeGraphic サブクラスの定義内で次のようにゲッターを定義します。
{getter public {runtime-class-name}:String
{return "submit-button"}
}
{getter public {design-time-class-name}:String
{return "CommandButton"}
}
{getter public {class-name-for-display}:String
{return "Submit Button"}
}
ところで、runtime-class-name と design-time-class-name という名前は、この章の他のセクションで使われている 実行時
と デザイン時
の概念とは関係がありません。これらの名前は VLE の以前のバージョンで確定されたもので、互換性のためにそのまま使われています。
この章では、
リーフ
型 オブジェクト、つまり VLE で編集される他のオブジェクトのコンテナとしての役目を持たない、追加のオブジェクト型を扱えるような VLE の機能拡張に焦点をあてています。VLE の機能を拡張して新しいタイプのコンテナ オブジェクトを扱うことも可能ですが、これは高度なトピックで、この概要で説明する範囲には含まれていません。新しいコンテナ クラスを VLE に追加する必要がある場合は、まず VLE に組み込まれている
VBox エディタの実装を調べることから始めてみてください。これには、次の VLE ソース ファイルで
DesignTimeVBox と
DesignVBox クラスおよびそのサブクラスの定義に目を通します。
d:\automated-build-temp\build\win32-atom\ide\vle\editor\standard-design-time-classes.scurl
Scrollbar に基づく例では、標準 Curl API で既に定義されているオブジェクトを編集できるように VLE 機能を拡張する方法が示されています。しかし、オブジェクトの定義も自分で提供し、これを編集できるように VLE 機能を拡張することを望まれるのがほどんどの場合です。このセクションでは、VLE 機能拡張で使われるオブジェクトの実行時の動作をどのように定義するかを示し、その過程で留意すべき大切な点について解説します。
新しい実行時のオブジェクト型の定義を含むパッケージを作成する必要があります。通常このパッケージには、VLE ユーザーがアプリケーション作成に使う
Graphic のサブクラスを 1 つまたは複数含めます。
パッケージは次の場所でインポートする必要があります。
- VLE 機能拡張ファイル -- パッケージをインポートすることにより、VLE が機能拡張をロードしたときに、デザイン時オブジェクトをレイアウトに配置できるようになる。
- VLE で編集したソース コード -- パッケージをインポートすることにより、実行時に RTE が実行時オブジェクトを作成できる。この必要条件は、VLE で編集するファイルに import ステートメントを追加して、実行時にこのパッケージを見つける方法を正確に記述しなければならいということを意味します。
get-the-applet などの一部の Curl API は、アプレットの一部として実行されたときだけ呼び出すことができます。VLE 自体はアプレットではないので、VLE で使われる実行時パッケージ内でこれらの API を 直接または間接的に使用することはできません。
Curl IDE のプロジェクトでパッケージを定義すると、IDE はパッケージのマニフェストを作成します。ただし、このパッケージが他のパッケージをインポートせず、
manifest-url を使ってリソースにアクセスしない場合は、マニフェストがなくてもパッケージは適切に機能します。パッケージがこれらの操作のいずれかを実行する場合は、マニフェストがなければパッケージは適切に機能しません。さらに、アプレットでパッケージをインポートする場合は、このパッケージで使われるマニフェストを含むマニフェストか、またはそのようなマニフェストに委任するマニフェストを使うようにアプレットを構成する必要があります。アプレットが IDE プロジェクトに属する場合、このようなマニフェストの作成は自動的に処理されますが、アプレットがプロジェクトに属さない場合、アプレットのプログラマーは明示的にマニフェストを作成しなければなりません。
マニフェスト不要のパッケージは任意のアプレットにインポートできます。マニフェストを必要とするパッケージは、適切なマニフェストが存在するアプレットにしかインポートできません。マニフェストの使用は Curl のプログラミングで推奨されている慣行で、これは IDE とそのプロジェクト メカニズムでもサポートされています。ただし、パッケージを作成し、VLE 機能拡張で必要な実行時オブジェクト型を定義する場合にこの慣行を実行すると、そのパッケージはマニフェストが必要になり、その使用はマニフェストが指定されているアプリケーションに制限されてしまいます。したがって、パッケージ作成状況を詳細に理解した上で、作成する VLE 機能拡張の使用においてこのような制限が許容できるかどうかを判断する必要があります。
次の Curl ソース コードでは、非常に簡単な progress bar (進捗状況バー)
オブジェクトを実装するパッケージを定義しています。このパッケージはマニフェスト経由でリソースにアクセスしないので、マニフェストは不要です。
このコードは、次の場所にサンプルの一部として含まれています。
d:\automated-build-temp\build\win32-atom\docs\default\examples\layout-editor\ProgressBar.zip
アーカイブからファイルを解凍して、progressbar-ext/progress/load.scurl を参照してください。
{curl 8.0 package}
{package COM.WIDGETS.PROGRESS, version = "1.0"}
{import * from CURL.GUI.STANDARD}
{define-class public DocProgressBar {inherits Fill}
|| This field holds a value from 0 to 1, representing
|| the amount of progress to be displayed.
field private _progress:double = 0.0
|| This getter fetches the current progress value.
{getter public {progress}:double
{return self._progress}
}
|| This setter changes the current progress value,
|| ensuring that it is in the proper range, and
|| signals that a a redraw is necessary.
{setter public {progress new-value:double}:void
set self._progress = {max 0.0, {min 1.0, new-value}}
{self.request-draw}
}
{constructor public {default ...}
{construct-super ...}
}
{method public {draw r:Renderer2d}:void
let bounds:GRect = {self.layout.get-bounds}
let width:Distance = self._progress * bounds.width
{r.render-rectangle
-bounds.lextent,
-bounds.ascent,
width,
bounds.height,
fill-pattern = self.color
}
}
}
DocProgressBar オブジェクト用の VLE オブジェクト エディタの定義は、先の例の
Scrollbar エディタの定義プロセスに似ています。これは次の VLE 機能拡張ファイルで定義されています。このコードは、
ProgressBar.zip 内の
progressbar-ext.scurl サンプル ファイルに収められています。
{import * from CURL.GUI.STANDARD}
{import * from COM.WIDGETS.PROGRESS,
location = "progress/load.scurl"
}
{define-class public final DesignTimeProgressBar
{inherits DesignTimeGraphic}
{constructor public {default}
{construct-super
{ObjectMetaData
default-selected-property = "design-name",
default-selected-event = "PointerPress",
{MetaDataCategory
name = "General",
design-name-pmd,
name-pmd
},
standard-geometry-meta-data-category,
{MetaDataCategory
name = "Colors",
color-pmd,
background-pmd
},
standard-border-meta-data-category,
{EventHandlerCategory
{EventHandlerMetaData "PointerEnter"},
{EventHandlerMetaData "PointerLeave"},
{EventHandlerMetaData "PointerPress"},
{EventHandlerMetaData "PointerRelease"}
}
}
}
}
{getter public open {initial-properties}:{Array-of PropertyDescriptor}
{return
{new {Array-of PropertyDescriptor},
{PropertyDescriptor background-pmd, "\"silver\""},
{PropertyDescriptor color-pmd, "\"blue\""},
{PropertyDescriptor border-color-pmd, "\"black\""},
{PropertyDescriptor border-width-pmd, "1pt"},
{PropertyDescriptor width-pmd, "144pt"},
{PropertyDescriptor height-pmd, "24pt"}
}
}
}
{getter public {runtime-class-name}:String
{return "DocProgressBar"}
}
{method protected {new-object element:LayoutElement}:GraphicOptions
{return {DocProgressBar}}
}
{getter public open {palette-tab-name}:String
{return "Widgets"}
}
{getter protected {palette-graphic}:Graphic
{return
{image
blocking? = true,
source = {url "images/progressbar-icon.gif"}
}
}
}
{method public open
{collect-import-descriptors layout-file:LayoutToolFile}:void
{layout-file.add-import-descriptor
{CopyImportDescriptor
"COM.WIDGETS.PROGRESS",
version = "1.0",
{url "progress/load.scurl"},
dest-path = "progress-1-0/load.scurl"
}
}
}
}
{register-palette-item DesignTimeProgressBar}
この VLE 機能拡張ファイルと前述の
Scrollbar の例には少しずつ異なる点がいくつかあります。
initial-properties ゲッターで挙げられているプロパティのセットが異なり、
palette-tab-name では、
DocProgressBar アイコンが
[コントロール] タブではなく
[Widgets] という名前の新しいパレット タブに表示されるよう指定されていますが、これらは既に説明した VLE 機能拡張の異なる適用方法にすぎません。この例と前述の例にはもっと重要な相違点が 2 つあります。
- この例では COM.WIDGETS.PROGRESS パッケージをインポートしています。この import ステートメントにより、DocProgressBar クラスの定義をデザイン時に利用できます。編集中に VLE ユーザーが [レイアウト] ペインに表示される DocProgressBar を見るためには、このクラス定義が必要です。
- この例には collect-import-descriptors メソッドが含まれています。これについては次のセクションで説明します。
作成したパッケージに関する機能拡張を VLE に追加した場合、VLE においては、その機能拡張を使うソース コード ファイルがパッケージを利用できるようにする必要が生じます。これを行うには、上記の
DocProgressBar の例で示されるように、
DesignTimeGraphic サブクラスの
collect-import-descriptors メソッドをオーバーライドして VLE に必要な情報を提供します。VLE は提供された情報を使って、編集中のソース コードに適切な
import ステートメントを挿入し、ソース ファイルが実行時パッケージを簡単にインストールできる場所にそのコピーをインストールします。
collect-import-descriptors メソッドは 1 つの引数として LayoutToolFile を取ります。DocProgressBar の例では、この引数は layout-file と呼ばれています。collect-import-descriptors メソッドの本体には、LayoutToolFile の add-import-descriptor メソッド呼び出しが 1 つまたは複数含まれています。これらの各呼び出しの引数は ImportDescriptor です。ImportDescriptor には 2 種類あります。
- CopyImportDescriptor は、全部を 1 つのファイルで実装した、マニフェスト不要の実行時パッケージと使用します。
- DelegateImportDescriptor は、マニフェストが必要な実行時パッケージと使用します。パッケージがプロジェクトの一部であり、プロジェクトのマニフェストにこのパッケージが記されていて、さらにこのパッケージを使うアプリケーションもマニフェストを使う必要があることが認められている場合は、マニフェスト不要のパッケージに対してこの記述子を使っても問題はありません。
ソース ファイルの書き出しや IDE ソース エディタへのファイル転送を VLE に要求すると、まずファイル内でインスタンス化されるすべてのオブジェクトをスキャンして、それぞれに対して
collect-import-descriptors メソッドを呼び出します。VLE はその結果の
ImportDescriptor オブジェクトを収集します。これらのオブジェクトは、VLE が書き出すソース ファイルに
import ステートメントを書き加えるよう指示します。次に、VLE は
ImportDescriptor を再度スキャンして、アプリケーションに関連する実行時パッケージをインストールする (他のファイルを適切に更新する) よう各記述子に要求します。
import ステートメント生成および実行時パッケージのインストールの詳細は、
ImportDescriptor の種類によって異なります。以下のセクションではこれらについて説明します。
DocProgressBar の例では CopyImportDescriptor が使われています。これは、実行時パッケージがマニフェストを必要としないためです。CopyImportDescriptor コンストラクタの一般的な呼び出しは次のように行われます。
{CopyImportDescriptor
package-name,
[version = version,]
source-url,
dest-path = dest-path
}
package-name は実行時パッケージの名前です。
version 引数はオプションですが、指定した場合は、ソース コードで生成される
import ステートメントの
version 引数にこの
version を含めます。
source-url は、パッケージのソース コードの場所を示す
Url です。
DocProgressBar の例でも示されているように、通常この引数には相対 URL を指定します。この URL は VLE 機能拡張ファイルの場所を基準とする相対パスです。したがって、前述の例にある引数を見ると、
{url "progress/load.scurl"}
progress という名前のディレクトリがあり、これは VLE 機能拡張ファイルと兄弟の位置関係にあることを示しています。このディレクトリには
load.scurl という名前のファイルがあり、
DocProgressBar クラスを定義するパッケージがそこに含まれています。最後に、
dest-path 引数は
String 型の値で、VLE が生成する
import ステートメントの
location キーワード引数を制御します。
import ステートメントの生成中、
CopyImportDescriptor は、
package-name をパッケージ名とし、
version (指定された場合) をそのバージョンとする
import ステートメントがソース コードに既に含まれているかどうかを調べます。そのような
import ステートメントが含まれている場合、ソース コードでそのまま変更されずに残ります。含まれていない場合、次に実行されるアクションは、現在 IDE でプロジェクトが開かれていて、そのプロジェクトのディレクトリ ツリーに現在 VLE で編集中のファイルが存在するかどうかによって異なります。
このファイルが現在開いているプロジェクトのディレクトリ ツリーに存在しない場合 (おそらく、現在開いているプロジェクトがないため)、次の形式の
import ステートメントが生成されます。
{import * from package-name,
version = version,
location = dest-path
}
例えば、
DesignTimeProgressBar で指定されている
CopyImportDescriptor は次の
import ステートメントを生成します。
{import * from COM.WIDGETS.PROGRESS,
version = "1.0",
location = "progress-1-0/load.scurl"
}
このファイルが現在開いているプロジェクトのディレクトリ ツリー内に存在する場合、VLE はこのファイルが実行時にプロジェクト マニフェストを使ってリソースを発見すると判断し、
import ステートメントから
location 引数を省きます。結果の
import ステートメントは次のようになります。
{import * from package-name,
version = version
}
VLE が実行時パッケージをインストールする際のアクションは、現在開いているプロジェクトのディレクトリ ツリーにソース ファイルが存在するかどうかによって異なります。
マニフェストを必要とする実行時パッケージには、
DelegateImportDescriptor を使うことができます。
DelegateImportDescriptor は、編集するソース コード ファイルが含まれているプロジェクトのマニフェストに、
delegate-to 宣言を書き込むよう VLE に指示します。この
delegate-to 宣言は、実行時パッケージが必要とするマニフェストへの委譲を表します。
DelegateImportDescriptor コンストラクタの一般的な呼び出しは次のように行われます。
{DelegateImportDescriptor
package-name,
version = version,
manifest-url
}
DelegateImportDescriptor では、
CopyImportDescriptor と同じ方法で
package-name と
version 引数が処理されます。
manifest-url は、パッケージが必要とするマニフェストの場所を示す
Url です。
import ステートメントの生成中、
DelegateImportDescriptor は、
package-name をパッケージ名とし、
version (指定された場合) をそのバージョンとする
import ステートメントがソース コードに既に含まれているかどうかを調べます。そのような
import ステートメントが含まれている場合、ソース コードでそのまま変更されずに残ります。含まれていない場合、次に実行されるアクションは、現在 IDE でプロジェクトが開かれていて、そのプロジェクトのディレクトリ ツリーに現在 VLE で編集中のファイルが存在するかどうかによって異なります。この動作は
CopyImportDescriptor の場合と同じです。
import ステートメントが
location キーワード引数を伴う場合は、その引数が削除されます。
指定パッケージ名とバージョンの
import ステートメントがソース コードにまだ含まれていない場合、VLE は
import ステートメントを追加します。この
import ステートメントが
location キーワード引数を伴うことはありません。
VLE が実行時パッケージをインストールする際のアクションは、現在開いているプロジェクトのディレクトリ ツリーにソース ファイルが存在するかどうかによって異なります。
マニフェストを必要とする実行時パッケージに基づいて VLE 機能拡張を定義する場合は、いくつかの異なる手順を実行する必要があります。既に説明したとおり、
CopyImportDescriptor の代わりに
DelegateImportDescriptor を使用する必要があります。また、VLE 機能拡張自体の定義においても異なるアプローチを使う必要があります。その理由は、前述の
DesignTimeProgressBar の例では
COM.WIDGETS.PROGRESS をインポートする
import ステートメントで
location キーワードを使いましたが、この
COM.WIDGETS.PROGRESS パッケージがマニフェストを必要とする場合、これは不正になるためです。
このような問題すべてを解決する最良の方法は、以下の手順に従うことです。
- プロジェクトを作成します。このプロジェクトには、実行時パッケージと、VLE 機能拡張を定義するファイルの両方を含めます。その他のパッケージ、アプレット、および他の VLE 機能拡張ファイルも含めることができます。
- 実行時パッケージをこのプロジェクトの一部として作成します。
- 同じプロジェクトの一部として、デザイン時に使用するパッケージを別に作成します。このパッケージでは、実行時パッケージをインポートし、DesignTimeGraphic サブクラスをパブリック クラスとして定義します。
- 同じプロジェクトのトップレベルのディレクトリにファイルを作成し、手順 (3) のデザイン時パッケージをインポートして、そのパッケージで定義されている DesignTimeGraphic サブクラスそれぞれに対して register-palette-item を呼び出します。このファイルが実際の VLE 機能拡張ファイルです。
この手順を特定の問題に応用した例として、次のコードでは、DesignTimeProgressBar を定義するデザイン時パッケージ (手順 (3) で説明) を定義しています。このファイルは、COM.WIDGETS.PROGRESS パッケージがマニフェストを必要とするかどうかに関係なく使用できます。これに対して、前述の VLE 機能拡張例では、COM.WIDGETS.PROGRESS にマニフェストが必要な場合には機能しなくなります。
このコードは、次の場所にサンプルの一部として含まれています。
d:\automated-build-temp\build\win32-atom\docs\default\examples\layout-editor\ProgressBarManifest.zip
アーカイブからファイルを解凍して、progressbar-ext/progress/designtime-load.scurl を参照してください。
{curl 8.0 package}
{package COM.WIDGETS.PROGRESS-VLE-EXT}
{import * from CURL.GUI.STANDARD}
{import * from COM.CURL.LAYOUT-EDITOR.EDITOR}
{import * from COM.WIDGETS.PROGRESS}
{define-class public final DesignTimeProgressBar
{inherits DesignTimeGraphic}
{constructor public {default}
{construct-super
{ObjectMetaData
default-selected-property = "design-name",
default-selected-event = "PointerPress",
{MetaDataCategory
name = "General",
design-name-pmd,
name-pmd
},
standard-geometry-meta-data-category,
{MetaDataCategory
name = "Colors",
color-pmd,
background-pmd
},
standard-border-meta-data-category,
{EventHandlerCategory
{EventHandlerMetaData "PointerEnter"},
{EventHandlerMetaData "PointerLeave"},
{EventHandlerMetaData "PointerPress"},
{EventHandlerMetaData "PointerRelease"}
}
}
}
}
{getter public open {initial-properties}:{Array-of PropertyDescriptor}
{return
{new {Array-of PropertyDescriptor},
{PropertyDescriptor background-pmd, "\"silver\""},
{PropertyDescriptor color-pmd, "\"blue\""},
{PropertyDescriptor border-color-pmd, "\"black\""},
{PropertyDescriptor border-width-pmd, "1pt"},
{PropertyDescriptor width-pmd, "144pt"},
{PropertyDescriptor height-pmd, "24pt"}
}
}
}
{getter public {runtime-class-name}:String
{return "DocProgressBar"}
}
{method protected {new-object element:LayoutElement}:GraphicOptions
{return {DocProgressBar}}
}
{getter public open {palette-tab-name}:String
{return "Widgets"}
}
{getter protected {palette-graphic}:Graphic
{return
{image
blocking? = true,
source = {url "images/progressbar-icon.gif"}
}
}
}
{method public open {collect-import-descriptors layout-file:LayoutToolFile}:void
{layout-file.add-import-descriptor
{DelegateImportDescriptor
"COM.WIDGETS.PROGRESS",
version = "1.0",
{url "../manifest.mcurl"}
}
}
}
}
このパッケージを使用する実際の VLE 機能拡張ファイル (手順 (4) で説明) は非常に簡単なものです。次に示すとおりで、これだけです。
{import * from COM.WIDGETS.PROGRESS-VLE-EXT}
{register-palette-item DesignTimeProgressBar}
上記 2 つのファイルに関して、以下の点に注意してください。
- VLE 機能拡張ファイルは、location キーワードの指定なしで COM.WIDGETS.PROGRESS-VLE-EXT をインポートします。これは問題なく機能します。その理由は、VLE が VLE 機能拡張ファイルを実行する際には、手順 (1) で作成されたプロジェクトのマニフェストに委譲するマニフェストによって制御されるためです。VLE が起動時に機能拡張ファイルを実行するときには、このファイル自体が置かれているディレクトリで manifest.mcurl という名前のマニフェスト ファイルを探します。マニフェストが見つかった場合は、その manifest.mcurl マニフェストに委譲するマニフェストを使って機能拡張ファイルを実行します。COM.WIDGETS.PROGRESS-VLE-EXT パッケージの定義を含むプロジェクトには、VLE 機能拡張ファイルも含まれているので、このパッケージの場所はマニフェストに記されています。
- デザイン時パッケージ (COM.WIDGETS.PROGRESS-VLE-EXT) では、DesignTimeGraphic や color-pmd などの定義にアクセスするために、明示的に COM.CURL.LAYOUT-EDITOR.EDITOR パッケージをインポートする必要があります。ただし、この import ステートメントは location キーワード引数を必要としません。その理由は、VLE が機能拡張ファイル実行のために作成するマニフェストに、COM.CURL.LAYOUT-EDITOR.EDITOR が含まれているためです。事実、この import ステートメントには location キーワード引数を指定してはいけません。明示的に場所を指定しようとすると、VLE 機能拡張が正常に動作しなくなります。
- 実行時パッケージ (COM.WIDGETS.PROGRESS) は、location キーワード引数を使わずにデザイン時パッケージにインポートできます。これは、既に説明したように実行時パッケージの場所が manifest.mcurl ファイルで示されているためです。
- DesignTimeProgressBar の定義では、collect-import-descriptors メソッドで CopyImportDescriptor ではなく DelegateImportDescriptor を使用します。DelegateImportDescriptor コンストラクタの manifest-url 引数には、このパッケージを含むプロジェクトのマニフェスト URL を与えます。これは、COM.WIDGETS.PROGRESS-VLE-EXT パッケージ ソース ファイル自体の場所を基点として相対的に指定します。
- collect-import-descriptors メソッドの変更点を除き、この例における DesignTimeProgressBar の定義は上述の例とまったく同じです。
VLE 自体は、Curl
ローカライゼーション API を使い、現在の
ホスト ロケールに応じてユーザー インターフェイスをカスタマイズしています。これらの API を使って複数言語の VLE 機能拡張を作成することができます。これには以下を実行する必要があります。
- 上述の例にある COM.WIDGETS.PROGRESS-VLE-EXT パッケージなどのパッケージで VLE 機能拡張のローカライズ可能な部分を実装します。
- 翻訳ファイルの指定方法としてサポートされているいずれかの方法が使われるようにこのパッケージを構成します。
- VLE 機能拡張ファイル内の翻訳可能なテキストに、host-localize および/または hlmessage の注釈を適宜追加します。通常は、MetaDataCategory の name プロパティなどのユーザー インターフェイス要素はローカライズできますが、Curl API 要素の名前参照はローカライズしないでください。これには、イベント タイプ名 (PointerPress など) やグラフィカル クラス名 (runtime-class-name ゲッターが返す値など) が含まれます。具体的に示すと、PropertyMetaData オブジェクトの name はローカライズすべきではなく、PropertyMetaData コンストラクタの 表示名 や ソートキー キーワード引数を使って、ユーザーに実際に表示される名前をローカライズします。
次の VLE 機能拡張ファイルで DesignTimeGraphic サブクラスの定義を参照してください。上記のガイドラインに従ってローカライズされたパレット アイテムの定義例が含まれています。
d:\automated-build-temp\build\win32-atom\ide\vle\editor\standard-design-time-classes.scurl
VLE を通常の使い方で、つまり Curl IDE の制御下で稼動する場合、VLE 機能拡張のデバッグを行うのにふさわしい環境は提供されません。これには次の 2 つの理由があります。
- VLE 機能拡張を実験的に実行しているときエラーが発生した場合、内部 IDE エラーとしてレポートされるだけで、デバッグ機能を使用できません。
- インポートされる任意のパッケージを VLE 機能拡張ファイルの実行中に変更した場合、[パレット機能拡張] ダイアログ ボックスを使って VLE 機能拡張を削除および再ロードしても、変更したパッケージは再インポートされません。変更したパッケージの使用を開始するには、Curl RTE を完全に終了して再起動する必要があります。これは、通常のデバッグ作業より時間がかかり面倒です。
VLE 機能拡張の開発およびデバッグ プロセスを能率的に行うために推奨されている手順を以下に示します。
- 最初に、VLE を使用せずに実行時パッケージを開発およびデバッグする。パッケージが正しく動作すると確認できるまで、1 つまたは複数のアプレットを使い、実行時パッケージで定義したクラスの動作をテストします。
- VLE 機能拡張ファイルの開発およびデバッグ中は、VLE を Curl IDE の一部ではなく、アプレットとして実行します。
VLE をアプレットとして実行するには、ブラウザのアドレス フィールドに次のファイル名を入力します。
d:\automated-build-temp\build\win32-atom\ide\vle\run-layout-tool.curl
空のブラウザ ウィンドウが表示され、その後すぐに VLE ウィンドウが表示されるはずです。これを最初に実行するときには、VLE コードをアプレット用にコンパイルするためにかなり時間をとられる場合がありますが、その後は VLE ウィンドウの表示にほどんど時間がかかりません。VLE 機能拡張ファイル、または機能拡張でインポートされるパッケージに変更を加えるたびに、空のブラウザ ウィンドウで [更新] をクリックして最新の VLE インスタンスに更新し、最後に行った変更をテストできるようにします。
アプレットの実行中、VLE は通常の環境で IDE が実行するサービスにアクセスできません。結果として一部の動作が変わります。以下の変更点に注意してください。
- VLE は IDE によって保管されているパーシスタント構成情報にアクセスできません。したがって、VLE をアプレットとして実行している間は、[パレット機能拡張] と [データ接続の一覧] ダイアログ ボックスは常に最初は空の状態で表示されることになります。この状態は、IDE の一部として VLE を使用するときにはこれらのダイアログが空でない場合にもあてはまります。アプレットとして VLE を実行中にこれらのダイアログ ボックスを使うことは可能ですが、ブラウザ ウィンドウで [更新] をクリックしたり、他の方法を使って最新の VLE インスタンスに更新すると、これらのダイアログ ボックスはまた空の状態になります。そのため、最新の VLE インスタンスに更新するたびに [パレット機能拡張] ダイアログ ボックスを開いて、テスト中の VLE 機能拡張を手動で再ロードする必要があります。
- VLE は IDE ソース エディタへのデータの書き込みや、エディタからのデータの読み取りができません。したがって、[コードの編集] メニューのコマンド、プロパティ シートの [ {} ] ボタンは機能しません。
- VLE は、編集中のファイルが現在 IDE で開かれているプロジェクトの一部であるかどうかわかりません。したがって、collect-import-descriptors メソッドの ImportDescriptor 指定により実行されるすべてのアクションは、VLE で編集中のファイルが IDE で現在開いているプロジェクトに属さないという前提に基づいています。
Copyright © 1998-2019 SCSK Corporation.
All rights reserved.
Curl, the Curl logo, Surge, and the Surge logo are trademarks of SCSK Corporation.
that are registered in the United States. Surge
Lab, the Surge Lab logo, and the Surge Lab Visual Layout Editor (VLE)
logo are trademarks of SCSK Corporation.