ワークシート

Worksheetは、Excelのようにスプレッドシート風のGUIコンポーネントです。
以下のような特徴があります。

・式を埋め込み、セルの値を入力値として計算することができます。
・値の入力のために標準GUIコントロールをセルに埋め込んで使用することができます。
・フォームやRecordGridを埋め込んでRecordSetデータを表示することができます。

 

 

Worksheetクラス

Worksheetクラスのコンストラクタに以下のようなプロシージャがセットできます。

value-cell 値を表示するセル
input-cell 編集、入力するセル
currency-cell 通貨を含むセル
formula-cell 式を含むセル

これらはCellSpecオブジェクトを戻り値として返し、セルの表示を制御します。

サンプル

以下はWorksheetでごく簡単な計算を行うサンプルです。

worksheet1.jpg

http://developers.curlap.com/curl/curl-ext/hp2/worksheetdemo1.curl

使い方

この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列目 “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の第一引数となっているプロシージャ定義が、このセルが表示する値を決める数式です。引数として与えられたaセルの値とbセルの値を加算してdestセルにセットしています。destセルは数式を設定しているこのセル(row = 2,col = 0)、aセルはこのセルの3行上のセル、bセルは2行上のセル、cセルは3行上です。aとbをこれらのセルに紐付けているのが続く三行のRelativeCellRefオブジェクトです。

{RelativeCellRef -3, 0}が3行上、
{RelativeCellRef -2, 0}が2行上、
{RelativeCellRef -1, 0}が1行上のセルを指し、

この順に書くことでaが3行上、bが2行上、cが1行上のセルを指すことを示しています。
destセルはプログラマが明示的に設定する必要はなく、内部で自動的にこのセルを指します。

ここで、

{proc {dest:DataRef, a:DataRef, b:DataRef}:void
    set dest.value = a.as-double + b.as-double
}

の部分は Formula.sumに置き換えても同じ動作をします。

Formulaクラスには以下のような基本的な演算プロシージャが組み込みで用意されています。

copy 一つの引数を取り、ターゲットセルにそのセルの内容を表示します。
add 二つの引数を取り、ターゲットセルにその値の和を表示します
subtract 二つの引数を取り、ターゲットセルにその値の差を表示します
multiply 二つの引数を取り、ターゲットセルにその値の積を表示します
divide 二つの引数を取り、ターゲットセルにその値の商を表示します
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}
    }
}

こちらの場合は、数式プロシージャの引数の指定に、
一つずつセルを参照するRelativeCellRefの代わりに
RelativeRangeRefが使われています。
RelativeRangeRefは複数のセルを含む矩形領域を参照します。

コンストラクタ引数は以下のようになっています。

RelativeRangeRef.default
    rows:int ターゲットセルの行番号に加えるオフセット値
    cols:int ターゲットセルの列番号に加えるオフセット値
    row:int 領域に含まれる行の数(デフォルト:0)
    col:int 領域に含まれる列の数(デフォルト:0)

上のコードでは、3行1列の矩形領域を、ターゲットセルの3行上のセルから定義しています。

カスタムセルエディタ

セルの値の編集には、普通TextFieldが使われますが(日付の場合はDateField)、
ユーザがそのコントロールを指定することができます。
各セルは以下の三つのパラメータを取ります。

editable?:bool ユーザによる編集の可否(デフォルト:false)
locked?:bool セルの編集可否状態を固定表示するかどうかの設定(デフォルト:false)
ui-spec:any セルの値の編集/表示方法の設定(デフォルト: null)

このui-specへの設定によってコントロールを指定することができます。

ValueControlを指定した場合には、WorksheetがValueFinishedイベントを
自動的に認識してセルを更新し再計算を行います。

サンプル

以下はSliderコントロールを埋め込んだサンプルです。

worksheet2.jpg

http://developers.curlap.com/curl/curl-ext/hp2/worksheetdemo2.curl

使い方

以下のように、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を埋め込むことができます。

サンプル

以下は、セルに埋め込んだRecordグリッドでRecordSetを表示するサンプルです。

worksheet3.jpg

http://developers.curlap.com/curl/curl-ext/hp2/worksheetdemo3.curl

使い方

EmbeddedRecordGridコントロールをセルに埋め込んでいます。
RecordGridの列数+1となる値(ここでは5)をcolspanにセットすると
グリッドの一列にワークシートの一列が自動的に割り当てられ、
ワークシートのカラム幅を調整するとグリッドのカラム幅も連動して変更できます。

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を埋め込むことができます。

サンプル

次のサンプルは、RecordSetをフォームで表現することで実現したToDoリストです。
EmbeddedRecordFormが埋め込まれています。

worksheet4.jpg

http://developers.curlap.com/curl/curl-ext/hp2/worksheetdemo4.curl

使い方

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)
   …