はじめに
Curlも少しずつ認知されるようになってきていますが、それでもまだエンドユーザーのシステム部門の方から、「Curlって何?」と言われることも少なからずあり、その認知度は低いと言わざるを得ません。しかし、もともと米国生まれのCurlですが、今は日本の厳しいユーザーやデベロッパーに鍛えられ、日本から米国に逆輸出される形で米国で広まっています。実際、米国InfoWorld誌の2008年 RIA開発最優秀技術賞を受賞しました。
Curlは固定のコンテンツ記述から、ダイナミックなレイアウト変更、動的なコンテンツの生成、2次元・3次元グラフィック処理、Webサービス連携や複数のサーバとの接続などの処理をオブジェクト指向プログラミングで記述でき、他のグラフィカル言語などの力を借りなくても、Webクライアントで必要な機能のほとんどをCurlのみで実装することが可能です。1つの言語さえ理解すれば、クライアントサイドの機能のほとんどの部分を作れるというのは、開発者にとって大きな魅力ですが、メンテナンス性を考えれば、最終的にはエンドユーザーにとっても十分メリットがあるはずです。
現在は、ブラウザ無しでも動作するデタッチドアプレットを作成できますし、オフラインでもオンラインと同じ使い心地で操作できるOCC機能(随時接続コンピューティング)を利用する事で、こちらから説明しなければWebアプリケーションとは分からないようなコンテンツもあります。そして、高度なユーザーインターフェースだけではない、Curlアプリケーションのリッチさが、ユーザーにも認められつつあります。
Curlの持つ優れたグラフィック機能
このようにじわじわと広がっているCurlですが、「今更新しい言語はちょっとな~っ」と二の足を踏んでいる方にもなるべく分かりやすいように、今回から数回に渡って動的コンテンツを作る仕組みを基礎から解説していきます。最終的には、弊社が開発したパッケージ製品であるRIAGrid/RIADrawの内部処理にも少し触れる事で、Curlの持つ高度なグラフィック機能についても紹介していきたいと思います。
では、Curlの実行環境(Curl RTE)がない方はCurl社Webサイトからダウンロードしていただき、早速話を進めていきましょう。エディタは何でもよいのですが、初めてならいろいろ便利機能が付いた総合開発環境(Curl IDE)を使うとよいでしょう。最近では、CDE(Eclipseプラグイン)も出ましたので、Eclipseに慣れている方はそちらが便利かもしれません。
【注意】ローカルマシンのCurlソースを実行する場合は、Curlコントロールパネルのセキュリティタブから「このコンピュータ」を選択し、特権ディレクトリの追加でCurlソースが置いてあるディレクトリを指定しておかないとなりません。
CDEのインストール手順についてはこちらの記事を参考にしてください。
まずは基本の箱詰めから
オブジェクトの整列
Curlで画面を構築する場合、大別すると2つの座標系を利用できます。
1つは、VLE(Visual Layout Editor)で代表されるように、主にレイアウト領域(キャンバス)にパレットからレイアウトオブジェクトなどをドラッグ&ドロップしていく方式で利用されるもので、キャンバスの左上端を起点としてX、Y方向の距離でオブジェクトの位置を示す座標系です。VBなどではおなじみですよね。
もう1つは、レイアウト領域は大きな箱のようなものだと見なして、その箱の中にさらに大小さまざまな箱を並べて行きオブジェクトの位置決めをする方式です。当然その箱の中には、表示したいオブジェクトや隙間を埋めるためのオブジェクトが入っている事になります。箱は、Visualオブジェクトを入れるコンテナという事になります。
どちらの方式も一長一短があるのですが、今回は後者の方式を使ってオブジェクトの整列を考えてみます。この方式でオブジェクトを整列させるためによく利用されるのが「HBox」と「VBox」です。HBoxはオブジェクトを水平方向に左から右へ配置する手段として、VBoxはオブジェクトを垂直方向に上から下に配置する手段として利用されます。
{curl 5.0, 6.0 applet} {curl-file-attributes character-encoding = "shift-jis"} {value {HBox {CommandButton label="----- CommandButton1 -----"}, {text color="blue", textは文字の表示のプロシージャです。簡単に文字を表示できます。}, {CheckButton label="Check1"} } }
{curl 5.0, 6.0 applet} {curl-file-attributes character-encoding = "shift-jis"} {value {VBox {CommandButton label="----- CommandButton1 -----"}, {text color="blue", textは文字の表示のプロシージャです。簡単に文字を表示できます。}, {CheckButton label="Check1"} } }
テキストと非テキストの動作
整列を考える場合、テキストと非テキストとは動作が異なります。テキストが表示される場合、そのテキストは「TextFlowBox」の内部にラップされて配置されます。
TextFlowBoxは、オブジェクトを垂直方向に伸長または圧縮することはありませんが、常にテキストをコンテナの境界に合わせて伸長しますので、テキストが自動改行される場合があります。HBox-EX1.curlの実行結果で、文字列が改行されているのが、その例です。
TextFlowBoxのcompress-orderは、他のほとんどのグラフィカルオブジェクトよりも高いので、幅に制限があるときにminimum-sizeに圧縮されるオブジェクトになります。非テキストの場合は、グラフィカルオブジェクトそのものや、そのオブジェクトを入れるコンテナの設定に依存します。
それでは、text-width-displayというヘルパープロシージャを使って簡単な例を作って、比較してみましょう。text-width-displayは、ページが表示されるときに、パラメータで渡されたテキストのレイアウトに使用された幅を基準とし、Graphicを伸長または配置するためのプロシージャです。
{curl 5.0, 6.0 applet} {curl-file-attributes character-encoding = "shift-jis"} || Window幅がめいっぱい使われます {text-width-display {HBox background={LinearGradientFillPattern {Fraction2d 0.0, 0.0}, {Fraction2d 1.0, 0.0}, {Spectrum.from-endpoints "#346E50", "white" } }, {bold color="white", Thank you for using Curl}, {Fill}, || Windowの幅になるように伸張 {link href={url "http://www.q-tec.com/"}, QaliTech, Inc.} } }
{curl 5.0, 6.0 applet} {curl-file-attributes character-encoding = "shift-jis"} || VBoxの影響を受けて、ここのtext-width-displayは効力を発揮しない。 || text-width-displayを取ってしまっても同じです。 {text-width-display {VBox {HBox background={LinearGradientFillPattern {Fraction2d 0.0, 0.0}, {Fraction2d 1.0, 0.0}, {Spectrum.from-endpoints "#346E50", "white" } }, {bold color="white", Thank you for using Curl}, {Fill}, || VBoxの幅が未指定なので、その幅が最小になるように縮まる {link href={url "http://www.q-tec.com/"}, QaliTech, Inc.} }, {CommandButton label="Push me!"} } }
{curl 5.0, 6.0 applet} {curl-file-attributes character-encoding = "shift-jis"} {text-width-display {VBox {HBox background={LinearGradientFillPattern {Fraction2d 0.0, 0.0}, {Fraction2d 1.0, 0.0}, {Spectrum.from-endpoints "#346E50", "white" } }, {bold color="white", Thank you for using Curl}, {Fill} , || 下の(1)で決定された幅に合わせて伸張 {link href={url "http://www.q-tec.com/"}, QaliTech, Inc.} }, || VBoxの幅は未指定であので、Windowの幅まで伸張---(1) {CommandButton width={add-stretch}, label="Push me!"} } } || CommandButton ではなく、一番外側のVBox に width={add-stretch}, を || 指定した場合との違いを見てみましょう。
{curl 5.0, 6.0 applet} {curl-file-attributes character-encoding = "shift-jis"} {text-width-display {VBox hstretch?=true, {HBox background={LinearGradientFillPattern {Fraction2d 0.0, 0.0}, {Fraction2d 1.0, 0.0}, {Spectrum.from-endpoints "#346E50", "white" } }, {bold color="white", Thank you for using Curl}, {Fill} , {link href={url "http://www.q-tec.com/"}, QaliTech, Inc.} }, {CommandButton label="Push me!"} } }
ストレッチですっきり
柔軟体操
私たち人間も十分にストレッチをすることで柔軟な動きが可能となるように、Curlでもストレッチは箱を並べてVisualオブジェクトを柔軟に整列させるために非常に大切です。画面デザイン上の凸凹をすっきりそろえるためにも、ストレッチは必要になります。それでは、VBox-EX1の凸凹をすっきりさせてみましょう。
すでに、「テキストと非テキストの動作」の例題に載っているので閃いた方もいらっしゃると思いますが、 VBox-EX1のCommandButtonとCheckButtonに「width=[add-stretch}」を追加してみます。
{curl 5.0, 6.0 applet} {curl-file-attributes character-encoding = "shift-jis"} {value {VBox {CommandButton label="----- CommandButton1 -----", width={add-stretch}}, {text color="blue", textは文字の表示のプロシージャです。簡単に文字を表示できます。}, {CheckButton label="Check1", width={add-stretch}} } }
1番長いオブジェクトであったテキスト文字列の長さに、別な2つのオブジェクトの長さがそろいました。見た目もすっきりしました。 と言っても、CheckButtonの方は、伸張された結果が目で見て分かりません。ラベルの延長線上をクリックして、チェックマークが付くかで判断してください(次の例では、分かりやすい様に色を付けてみます)。
add-stretchプロシージャは、width(heightに指定することもできます)に伸張性を追加するプロシージャで、Elasticのサブクラスのオブジェクトを返します。
実は、add-stretchと同じような動きを、VBox側のオプションを指定することで実現することも可能です。それが、hstretch?オプションで「VBox-EX3」のように指定します。ここで「同じような動き」と言ったのは、CommandButtonのlabelの位置が変化するからです。
hstretch?=trueと同じlabel位置にするには、VBox-EX2のwidthを「width={add-stretch before?=true, after?=false}」とする必要があります。before?、after?オプションについては、Curlのヘルプに詳しく載っていますので見てください。
この他にElasticオブジェクトを明示的に指定することで、サイズの調整をコードによって制御することが可能となります。Elasticオブジェクトは、make-elasticプロシージャを呼び出して作成します。make-elasticプロシージャに関しても、Curlのヘルプを参考にしてください。
{curl 5.0, 6.0 applet} {curl-file-attributes character-encoding = "shift-jis"} {value {VBox hstretch?=true, ||hstretch?オプション {CommandButton label="----- CommandButton1 -----"}, {text color="blue", textは文字の表示のプロシージャです。簡単に文字を表示できます。}, {CheckButton label="Check1", background="cyan"} } }
圧縮と伸張
アプレットを作成する際、一般に入れ子になったグラフィカルオブジェクトを使います。ほとんどの場合、GUI Toolkitでは適切なレイアウト処理が自動実行されます。つまり、グラフィカルオブジェクトはその親オブジェクトおよび兄弟オブジェクトを基準にして、適切に伸長または圧縮されます。
伸長や圧縮が適切でない場合、子オブジェクトが切り詰められ、スクロールバーが表示されることがあります。既に説明しましたが、TextFlowBoxの場合は、テキストが自動改行される場合があります。
VBox-EX3の画面の右下端をつかんで、縮めてみましょう。ボタンのオブジェクトの幅は縮小され、真ん中の文字列は自動的に改行されます。
HBoxの変形のRasterBox
HBoxがGraphicオブジェクトの集合を水平方向の1行に配置するのに対して、Graphicオブジェクトの集合を水平方向に配置し、必要に応じて行の折り返しを行うのがRasterBoxです。
RasterBox-EX1のRasterBoxをHBoxに変更してみて、動きの違いを見てください。
{curl 5.0, 6.0 applet} {curl-file-attributes character-encoding = "shift-jis"} {RasterBox width=3.5cm, background="lightgray", "ここはRasterBoxの中です。", {RegularPolygonGraphic sides=3, width = 1cm, height = 1cm}, {RegularPolygonGraphic sides=4, width = 2cm, height = 1cm}, {RegularPolygonGraphic sides=6, width = 1cm, height = 1cm} }
おまけ
あまりに地味すぎて、おもしろみがなかったと思われる方が多いかもしれませんので、ちょっとだけ動きがあるコンテンツの例を載せます。変数VBにVBoxのオブジェクト(インスタンス)を入れておき、そのVBoxの高さをCommandButton2を押下したときに変化させることで、VBox(とその中のオブジェクト)を表示したり消したりするものです。 何かのヒントになれば幸いです。
{curl 5.0, 6.0 applet} {curl-file-attributes character-encoding = "shift-jis"}
{let VB:VBox = {VBox height=3cm, border-width=2pt, hstretch?=true, {CommandButton label="----- CommandButton1 -----"}, {text color="blue", textは文字の表示のプロシージャです。簡単に文字を表示できます。}, {CheckButton label="Check1", background="cyan"} } } {value {VBox VB, {CommandButton label= "CommandButton2", {on Action do {if VB.height == 0cm then set VB.height = 3cm else set VB.height = 0cm } } } } }
おわりに
今回はこれで終わりですが、そのほかの代表的なコンテナとしては下記のものがあります。ぜひ利用してみてください。
- OverlayBox…Graphicオブジェクトの集合を相互に重ね合わせて配置する
- Grid…指定された揃え方でGraphicオブジェクトを配置する
- Table…Graphicオブジェクトの集合を行と列に整理して配置する
- View…Curlのグラフィックコンテンツを含むウインドウ
- ScrollBox…Graphicオブジェクトを格納して周囲にスクロールバーを表示する