イベントの作成

Curlはユーザや他のプログラムが実行した操作(イベント)に対応して処理を行なうことができるイベントドリブン方式のプログラム言語です。一般的なイベントは「テキスト入力エリアに文字を入力する」時に発生するイベント(Curlの場合はValueChengedイベント)やボタンを押下するイベント(Curlの場合はActionイベント)また選択式のリストからデータを選択したときのイベント(Curlの場合はValueChangedイベント)があります。通常のWebのユーザーインタフェースのイベントは「ボタンを押下する」イベントによって処理が実行されるのみのものが多いのですが、その他にもユーザーの操作というものはさまざまになってきました。まさにこれらの操作に対応していることがリッチクライアントCurlの醍醐味です。

 

GUIコントロール部品の一般的なイベント

ボタンやリストボックスなどで発生する一般的なイベント処理のサンプルをご紹介します。以下にそれぞれのボタンを使用したサンプルソースを紹介します。

{curl 6.0 applet}
{curl-file-attributes character-encoding = “shift-jis”}
{CommandButton
   label = “OK”,
   {on Action do
       {popup-message “ボタンが押されました!” }
   }
}
{CheckButton
   label = “Check for a kayak”,
   {on ValueFinished at cb:CheckButton do
       {if cb.value==true then
           {popup-message “チェックされました”}
        else
           {popup-message “チェックが解除されました”}
       }
   }
}
{VBox
   {text Select your favorite city},
   ||{italic Combo},
   {ComboBox
       width=3cm,
       “Milan”,
       “Moscow”,
       “Manchester”,
       value = “Milan”,
       {on ValueFinished at combo:ComboBox do
           {popup-message “Your favorite city is: ” & {value combo.value}}
       }
   },
   {italic Dropdown},
   {DropdownList
       width=3cm,
       “Milan”,
       “Moscow”,
       “Manchester”,
       value = “Moscow”,
       {on ValueFinished at drop:DropdownList do
           {popup-message “Your favorite city is: ” & {value drop.value}}
       }
   }
}

基本的なイベントの操作ははon構文を使用してダイナミックイベントハンドラを設定してイベントを処理します。
上記のサンプルを例に説明しますとCommandButtonやDropdownListオブジェクトの中に”{on Action do …}”や”{on ValueFinished do …}”という構文がありますように、”{on XXX do …}”でダイナミックイベントを設定できます。XXXの部分にはそれぞれイベントタイプを設定します。
CommandButtonの場合はActionクラスを指定していまして「押された時」に発生するイベントクラスです。”…”の部分にはイベントが発生した時の処理を記述します。Commandbuttonの例ですとボタンを押したときにポップアップで「ボタンが押されました。」と出力されます。

ポインタイベント

一般的なWebアプリケーションのGUIの処理は「押す」や「選択する」といったイベントのみの場合が多いですが、Curlはより複雑なユーザー操作のイベントを処理できます。
以下はマウスポインタの処理の例です。

{VBox
    height = 2in,
    width = 1in,
    background = “blue”,
    {on e:PointerPress at v:VBox do
        set v.background = “red”
        {e.consume}
    },
    {on e:PointerRelease at v:VBox do
        set v.background = “blue”
        {e.consume}
    }
}
{VBox
    height = 1in,
    width = 1in,
    background = “blue”,
    {on e:PointerEnter at v:VBox do
        {if e.shift? then
            set v.background = “red”
         else
            set v.background = “cyan”
        }
        set v.height = 2in
        {e.consume}
    },
    {on e:PointerLeave at v:VBox do
        set v.background = “blue”
        set v.height = 1in
        {e.consume}
    }
}

上記の例では2つのVBox(垂直方向に子オブジェクトをならべる箱)にダイナミックイベントを設定しています。
上のVBoxではポインタが「左クリックされた」ときと「左クリックを離した」ときのイベントを設定します。
下のVBoxではポインタが「VBoxに入った」ときと「出ていった」ときのイベントの設定にくわえて、「Shiftキーを押しながら入った」ときとそうでない時で処理を分けています。
このようにポインタの処理だけでも色々なイベントを処理することができ、またキーボード操作と組み合わせて処理することもできます。

キーイベント

キーボードの操作に対する処理もポインタイベントと同じように処理することができます。
以下はキーボードイベントのサンプルコードです。

{Frame
   width=2in,
   height=1in,
   background=”blue”,
   {on p:PointerPress at f:Frame do
       {f.request-key-focus}
       set f.background = “green”
       {p.consume}
   },
   {on kp:KeyPress at f:Frame do
       {if kp.shift? then
           set f.background = “red”
        else
           set f.background = “yellow”
       }
       {if kp.value == KeyPressValue.home then
           {popup-message “You pressed home”}}
   }
}

Frameに先ほどのポインタ操作のイベントにくわえ、”KeyPress”というイベントを使ってキーボード操作に対する処理を記述しています。
このサンプルはFrameにフォーカスがある状態のときに何かのキーを押すと黄色になり、またShiftキーを押しながら、任意のキーを押すと赤になります。最後のコードはHomeキーを押したときのイベント処理を設定しています。このように特定のキー入力に対してや、またショートカットキーでよくある”Ctrl+C”や”Ctrl+V”などの修飾キーとの連携イベントまでも制御できます。

 

ドラッグアンドドロップイベント

ドラッグアンドドロップイベントはまさにリッチクライアントでユーザーインタフェースを使うことの醍醐味です。
ドラッグアンドドロップを実現するのは難しいと思われがちですが、Curlの場合は他のイベント処理と同じようにドラッグアンドドロップイベントを操作することができます。
以下に簡単なドラッグアンドドロップのサンプルを紹介します。

drag-drop.jpg

{text 丸を四角エリアにドラッグしてください。}
{text CTRを押しながらドラッグするとコピーされます}

{HBox
    valign = “center”, width = 9cm,
    {EllipseGraphic
        width = 1cm, height = 1cm, dragee = {ImageDragee}},
    {Fill width = {make-elastic preferred-size = 10cm}},
    {VBox
        width = 1.5cm, height = 1.5cm, border-width = 1pt,
        border-color = {FillPattern.get-black},
        opaque-to-events? = true,
        {on e:DragOver do
            {e.will-accept-drop?
                {proc
                    {a:Type,
                     b:Distance,
                     c:Distance,
                     d:#DragEffect
                    }:DragEffect
                    {if {d.has-effect? “copy”} then
                        {return drag-effect-copy}
                     else
                        {return drag-effect-move}
                    }
                }
            }
        },
        {on e:Drop at vb:VBox do
            {e.accept-drop
                {proc
                    {w:any,
                     x:Distance,
                     y:Distance,
                     z:#DragEffect
                    }:DropResult

                    {if {z.has-effect? “copy”} then
                        {return
                            {DropResultCopy
                                action =
                                    {proc {}:void
                                        {vb.add {w.clone-appearance}}
                                    }
                            }
                        }
                     else
                        {return
                            {DropResultMove
                                action =
                                    {proc {}:void
                                        {vb.add w}
                                    }
} } } } } } } }

ソースサンプル

関連ヘルプドキュメント

Curl開発者ガイド-グラフィカルユーザーインタフェース-イベント
Curl開発者ガイド-グラフィカルユーザーインタフェース-ドラッグアンドドロップ