はじめに
5月31日に公開された、Curlの業務向けUIコンポーネント群「Curl External Library(Curl EXT)」。このコンポーネント群を使用すれば、開発者は生産性がさらに向上する業務システムを容易に構築することが可能です。
今回は、Curl EXTの中でも画面遷移のエフェクトが全部で32種類用意されている「TransitionFrame」と、Excelのように使える「WorkSheet」の使い方を紹介します。
また、Curl EXTの開発に実際に携わった開発者インタビューの記事も公開しているので、ぜひご覧ください。
対象読者
- Curlアプリケーションの開発に興味がある方
- コンポーネントを使って効率よくCurlアプリケーションを作りたい方
必要環境
- Curl CDEまたはCurl IDE Ver.7以上
- Curl External Library Ver.6.0.1
ダウンロード
まずは、Curlの統合開発環境CDE(もしくはCurl IDE)とCurl External Libraryをダウンロードします。
ダウンロード後、Curl EXTを各プロジェクトで利用するため、以下のようにデリゲートする必要があります。
CDEの場合
- Eclipseのメニューバーの[Window]-[Preferences]を選択して[Preferences]ダイアログを開く
- [Curl]-[インストール済みのライブラリ]を選択
- インストールボタンを押して、展開したディレクトリの「COM.CURL.EXT-V0.6.1/manifest.mcurl」を選択し、開くボタンを押下(※注意)
- プロジェクトエクスプローラーからプロジェクトを右クリックして[Curlマニフェスト]-[ライブラリの管理]で「COM.CURL.EXT」にチェック
APIドキュメントも同時にインストールする場合は「COM.CURL.EXT-V0.6.1-doc/manifest.mcurl」を選択してください。
Classic IDEの場合
- Curl IDEで、メニューからプロジェクト→デリゲート先の追加を選択
- 展開したディレクトリの「COM.CURL.EXT-V0.6.1/manifest.mcurl」を選択し、[開く]ボタンを押下
これで、Curl External LibraryのAPIが利用できます(Curl EXTのimportは必要です)。なお、文中のサンプルは、添付のサンプルコードでも確認できます。
TransitionFrameの使い方
Curl External Libraryには、アニメーションによる画面遷移が可能なコンポーネントが含まれています。通常の画面の切り替えだけでなく、ダイアログなどのポップアップウィンドウなどにも適用できます。

パッケージのインポートとTransitionFrameクラスの使用
Curl EXTをCurlのアプリケーションで使用するには、「COM.CURL.EXT.TRANSITION-LIBRARY」パッケージのインポートとTransitionFrameクラスを利用します。
まずはTransitionFrameのインスタンスを生成します。
def tf = {TransitionFrame background = "white", border-color = "blue", border-width = 1px, transition-effect = {CrossFadeTransitionEffect} }
次に、このTransitionFrameに遷移する元や先のコンテナ(Frameなど)を追加します。
{tf.add {Frame width=5cm, height=5cm, background="red"}} {tf.add {Frame width=5cm, height=5cm, background="blue"}} {tf.add {Frame width=5cm, height=5cm, background="yellow"}}
画面の切り替えは、set-active-screenメソッドによって、アニメーションを伴った画面遷移が可能となります。
|| 引数には、tfにaddされたコンテナの番号(スタートは0)を指定します(左の例では2個目にaddしたFrame)。 {tf.set-active-screen 1}
また、いろいろなエフェクトをTransitionFrameのtransition-effectプロパティに指定することで、アニメーション方法を変更できます。例えば、CrossFadeTransitionEffect、DoorOpenTransitionEffect、Spin3dTransitionEffect、StiffPageTurnTransitionEffect、PageTurnTransitionEffect、ExplodeTransitionEffect/ImplodeTransitionEffectなどがあり、そのほかにも多数のエフェクトが用意されています。
さらに、このエフェクトクラスに、durationやpacingを指定することでアニメーションの速度を変更でき、orientationを指定することでアニメーションの方向を変更できます。特に、pacingを指定すると、徐々に早くすることもできます。
{DoorOpenTransitionEffect duration = 0.5s, pacing = {cubic-bezier 0.5, 1}, orientation = "horizontal"}
アニメーションを用いたウィンドウのポップアップについては、AnimatedViewクラスを利用します。アニメーションのエフェクトはGrowViewAnimatorやfadeViewAnimator、GenieViewAnimatorなどがあります。
def v = {AnimatedView {Frame width=3cm, height=3cm, background="red"}, animator = {GrowViewAnimator duration=0.5s, pacing={cubic-bezier 0.5, 1}} } {v.show}
なお、サンプルはCurl EXTをダウンロードしたフォルダの以下のフォルダに格納されているので、確認ください。
docs/samples/sample-transition-frame.curl docs/samples/sample-view-animation.curl
WorkSheetの使い方
Worksheetは、Excelのようにスプレッドシート風になっているGUIコンポーネントです。以下のような特徴があります。
- 式を埋め込み、セルの値を入力値として計算
- 値の入力のために標準GUIコントロールをセルに埋め込んで使用可能
- フォームやRecordGridを埋め込んでRecordSetデータを表示
Worksheetクラス
Worksheetクラスのコンストラクタには、以下のようなプロシージャがセットできます。
プロシージャ名 | 機能 |
value-cell | 値を表示するセル |
input-cell | 編集、入力するセル |
currency-cell | 通貨を含むセル |
formula-cell | 式を含むセル |
これらはCellSpecオブジェクトを戻り値として返し、セルの表示を制御します。

使い方
サンプルのWorksheetは、以下のようなコードで作成されています。
{Worksheet 4, 2, row = 0, col = 0, "A", {input-cell 0.0}, row = 1, col = 0, "B", {input-cell 0.0}, row = 2, col = 0, "C", {input-cell 0.0}, row = 3, col = 0, "A + B + C", {formula-cell {proc {dest:DataRef, a:DataRef, b:DataRef, c:DataRef}:void set dest.value = a.as-double + b.as-double + c.as-double }, {RelativeCellRef -3, 0}, {RelativeCellRef -2, 0}, {RelativeCellRef -1, 0} } }
ここでは、ワークシートのコンストラクタの中で、4行2列のワークシートのセルを以下のように1つずつ設定しています。
セルの場所 | 値 |
1行1列目 | "A", |
1行2列目 | {input-cell 0.0} |
2行1列目 | "B", |
2行2列目 | {input-cell 0.0}, |
3行1列目 | "C", |
3行2列目 | {input-cell 0.0}, |
4行1列目 | "A + B + C", |
4行2列目("A + B + C"の次)のセルとして記述されているformula-cellプロシージャが、数式のセルを設定しています。
formula-cellの第1引数となっているプロシージャ定義が、このセルが表示する値を決める数式です。引数として与えられたaセルの値とbセルの値を加算して、destセルにセットしています。destセルは数式を設定しているセル(row = 2,col = 0)、aセルはこのセルの3行上のセル、bセルは2行上のセル、cセルは3行上です。aとbをこれらのセルに紐付けているのが、続く3行のRelativeCellRefオブジェクトです。
{RelativeCellRef -3, 0}が3行上、{RelativeCellRef -2, 0}が2行上、{RelativeCellRef -1, 0}が1行上のセルを指し、この順に書くことで、aが3行上、bが2行上、cが1行上のセルを指すことを示しています。destセルはプログラマが明示的に設定する必要はなく、内部で自動的にこのセルを指します。
ここで、以下の部分は、Formula.sumに置き換えても同じ動作になります。
{proc {dest:DataRef, a:DataRef, b:DataRef}:void set dest.value = a.as-double + b.as-double }
Formulaクラスには、以下のような基本的な演算プロシージャが組み込みで用意されています。
プロシージャ名 | 機能 |
copy | 1つの引数を取り、ターゲットセルにそのセルの内容を表示します |
add | 2つの引数を取り、ターゲットセルにその値の和を表示します |
subtract | 2つの引数を取り、ターゲットセルにその値の差を表示します |
multiply | 2つの引数を取り、ターゲットセルにその値の積を表示します |
divide | 2つの引数を取り、ターゲットセルにその値の商を表示します |
sum | すべての引数の合計をターゲットセルに表示します |
product | すべての引数をかけ合わせた値をターゲットセルに表示します |
concat | すべての引数を連結した値をターゲットセルに表示します |
count | すべて引数の数をターゲットセルに表示します |
上記サンプルをFormula.sumプロシージャで書き換えると、次のようになります。
{Worksheet 4, 2, row = 0, col = 0, "A", {input-cell 0.0}, row = 1, col = 0, "B", {input-cell 0.0}, row = 2, col = 0, "C", {input-cell 0.0}, row = 3, col = 0, "A + B + C", {formula-cell Formula.sum, {RelativeRangeRef 3, 1, row = -3} } }
こちらの場合は、数式プロシージャの引数の指定に、1つずつセルを参照するRelativeCellRefの代わりに、RelativeRangeRefが使われています。RelativeRangeRefは複数のセルを含む矩形領域を参照します。
コンストラクタ引数は以下のようになっています。
コンストラクタ引数 | 参照値 |
rows:int | ターゲットセルの行番号に加えるオフセット値 |
cols:int | ターゲットセルの列番号に加えるオフセット値 |
row:int | 領域に含まれる行の数(デフォルト:0) |
col:int | 領域に含まれる列の数(デフォルト:0) |
上のコードでは、3行1列の矩形領域を、ターゲットセルの3行上のセルから定義しています。
カスタムセルエディタ
セルの値の編集には、通常TextFieldが使われますが(日付の場合はDateField)、ユーザーがそのコントロールを指定できます。各セルは以下の3つのパラメータを取ります。
パラメータ名 | 機能 |
editable?:bool | ユーザーによる編集の可否(デフォルト:false) |
locked?:bool | セルの編集可否状態を固定表示するかどうかの設定(デフォルト:false) |
ui-spec:any | セルの値の編集/表示方法の設定(デフォルト: null) |
このui-specへの設定によって、コントロールを指定できます。ValueControlを指定した場合には、WorksheetがValueFinishedイベントを自動的に認識してセルを更新し、再計算を行います。

使い方
以下のように、ui-specとしてSliderオブジェクトを設定します。
{Worksheet 4, 3, {widths 18pt, 2in}, row = 1, col = 1, row-height = 48pt, {input-cell 4, domain = int, ui-spec = {Slider}}, {formula-cell Formula.copy, {RelativeCellRef 0, -1}}, ... }
EmbeddedRecordGridの埋め込み
WorksheetにはRecordGridを埋め込むことができます。

使い方
EmbeddedRecordGridコントロールをセルに埋め込んでいます。RecordGridの列数+1となる値(ここでは5)をcolspanにセットすると、グリッドの1列にワークシートの1列が自動的に割り当てられ、ワークシートのカラム幅を調整するとグリッドのカラム幅も連動して変更できます。
EmbeddedRecordGridをインスタンス化する際のコンストラクタ引数は、以下のようになります。
EmbeddedRecordGrid.default worksheet:#Worksheet ||このEmbeddedRecordGridと関連付けられるWorksheet(デフォルト:null) record-source:#RecordSet ||ここから取り出される各レコードがグリッドを生成します(デフォルト:null) sort:#RecordSort ||表示データのソート順定義(デフォルト:null) filter:#RecordFilter ||データの一部を表示するためのフィルタ(デフォルト:null) key-spec:any ||RecordGrid.key-specの初期値を与える(デフォルト:null) header-options:RecordGridRowOptions ||ヘッダのためのグラフィックオプション(デフォルト:{RecordGridRowOptions}) ui-object:#RecordGridUI ||代替UIオブジェクト(デフォルト:{ProtoSkinnableRecordGridUI}) ...
EmbeddedRecordFormの埋め込み
WorksheetにはRecordFormを埋め込むことができます。

使い方
EmbeddedRecordFormをインスタンス化する際のコンストラクタ引数は、以下のようになります。
EmbeddedRecordForm.default data-source:RecordSetDataSource ||ここから取り出される各レコードがフォームを生成します id-field:String ||キーとなるフィールド名(デフォルト:"id") worksheet:#Worksheet ||このEmbeddedRecordFormWorksheetが属しているWorksheet(デフォルト:null) sort:#RecordSort ||適用するソート(デフォルト:null) filter:#RecordFilter ||適用するフィルタ(デフォルト:null)
FieldSpecクラスが、レコードの各フィールドの値を表示、編集するためのセルとなります。コンストラクタの引数は以下のようになります。
FieldSpec.default field-name:String ||フィールド名 rowspan:int ||行の範囲(デフォルト:1) colspan:int ||列の範囲(デフォルト:1) editable?:bool ||ユーザーによる編集の可否(デフォルト:false) locked?:bool ||セルの編集可否状態を固定表示するかどうかの設定(デフォルト:false) ui-spec:any ||セルの値の編集/表示方法の設定(デフォルト: null) ...
まとめ
今回は、サンプルソースを交えて、Curl EXTについて紹介しました。
このほかにも、さまざまなUIコンポーネントを用意しています。次回は、第2段として地図などの図形情報を読み込んでオブジェクトとして表示させる「ジオグラフィックAPI」などの機能を中心にご紹介します。
この機会にぜひ、Curl開発環境CDEを利用してCurl EXTに触れてみてください。