CodeZine(コードジン)

特集ページ一覧

Curl Apps Galleryで注目を集める「見積デモ」を紐解く
~ドラッグ&ドロップ~

第2回

  • LINEで送る
  • このエントリーをはてなブックマークに追加

ダウンロード サンプルソース (1.6 KB)

 本連載では、Curl Apps Galleryで公開されている見積デモの主な機能について解説していきます。今回は、見積入力画面で利用されているドラッグ&ドロップの機能について見て行きます。

はじめに

 第1回の連載では見積デモで使用されていたRecordGridというAPIについて説明しました。今回は、見積入力画面で利用されているドラッグ&ドロップの機能について見ていきたいと思います。見積入力画面では、商品名から見積の明細を入力するためにドラッグ&ドロップが利用されています。

見積入力画面。ドラッグ&ドロップの機能が利用されている
見積入力画面。ドラッグ&ドロップの機能が利用されている

 ドラッグ&ドロップを使用することによってユーザーは商品一覧から見積を選択するだけで自動的に売上が計算されます。新規に商品を選択した場合は新しい項目が追加され、既に選択済みの商品については個数が増加します。今回はこのドラッグ&ドロップの機能について見ていきます。

前回の記事

ドラッグ&ドロップとは

 具体的な見積デモの内容を見る前に、まずはドラッグ&ドロップの基本的な機能について見てみましょう。ドラッグ&ドロップのサンプルソースは次のとおりです。

{curl 6.0 applet}
{curl-file-attributes character-encoding = "shift-jis"}
{HBox spacing = 5cm, valign = "center",
    || Step 1: ドラッグしたいグラフィックのdrageeプロパティに
    ||         ImageDrageeを指定します。
    {EllipseGraphic width = 1cm, height = 1cm, dragee = {ImageDragee}},
    || Step 2: これはドロップする対象のグラフィックです。
    {Frame
        width = 2cm, height = 2cm,
        border-width = 2pt,
        background = "#ccccff",
        || 以下は DragOver イベントです。
        || DragOver.will-accept-drop?メソッドの呼び出しにより、
        || グラフィックをドラッグしようとするときの処理を制御します。
        {on e:DragOver do 
            {e.will-accept-drop?
                || ここでは何もせずドロップグラフィックを許容します。
                {proc {type:Type, x:Distance, y:Distance,
                       effect:#DragEffect}:DragEffect
                    {return drag-effect-copy}
                } } }, || stacked for compactness
        || Step 3: 以下は Drop イベントです。
        || Drop.accept-dropイベントの呼び出しにより、
        || グラフィックをドロップしたときの処理を制御します。
        {on e:Drop do
            {e.accept-drop
                {proc {a:any, x:Distance, y:Distance,
                       effect:#DragEffect}:DropResult
                    {return {DropResultCopy
                            || 'action' プロパティは
                            || ボールがドロップされたときに発生するイベントです。
                            action = {proc {}:void
                                    {popup-message
                                        "ボールをドロップしました!",
                                        modal? = true}
} } } } } } } }

 このサンプルを実行すると次のような画面が表示されます。画面左のボールを右側の四角にドラッグすると、メッセージが表示されます。

サンプル画面。画面左のボールをドラッグすると…
サンプル画面。画面左のボールをドラッグすると…
次のようなメッセージが表示される
次のようなメッセージが表示される

 サンプルを見るとわかりますが、ドラッグ&ドロップの処理はドラッグされる側のグラフィックとドロップされる側のグラフィックが一対になって実装されます。そのため実装が難しく感じられるかもしれませんが、実装箇所と内容を整理すれば他の機能の実装とあまり変化はありません。

サンプルの実装解説

 さて、見積デモのドラッグ&ドロップ機能を見ていきましょう。

 見積デモではリストの一覧から項目をドラッグすると、グリッド上にデータが表示されるようになっています。このうち、まずは画面左側のListBoxに注目します。ListBoxは複数の項目から任意の項目を選択するというものですが、今回はこの選択した項目がドラッグできるようにします。項目はListValueItemというクラスによって実装されているので、このListValueItemに対してドラッグ機能を追加します。

見積デモのリスト
見積デモのリスト
{let lb:ListBox = {ListBox width = 100pt,height = 300pt}}

{do
    ||ListBoxにアイテムを追加します。
    {for record:Record in goods-list do
        let new-item:ListValueItem =
            {ListValueItem
                record,
                label = record["name"]
            }

        ||ListValueItemをドラッグするために
        ||drageeを設定します。
        set new-item.dragee = {ImageDragee}
        
        {lb.append new-item}
    }
}

 これで選択した商品がドラッグできるようになりました。

 次に、RecordGridの方にも処理を実装します。RecordGridはグラフィックをドロップされる側なので、ドロップ時に発生するイベントを実装します。

{let rg:RecordGrid =
    {RecordGrid
        width = 500pt,
        height = 300pt,
        record-source = list,
        ||RecordGridにドラッグされたときのイベント
        ||(DragOver)を追加します。
        {on e:DragOver do
            {e.will-accept-drop?
                {proc  {t:Type,x:Distance,y:Distance,effect:#DragEffect}:DragEffect
                    {return
                        ||ここでは、ListValueItemが来たときのみドラッグを許容します。
                        ||それ以外のオブジェクトについてはドラッグすることが出来ないようにします。
                        {if {t.subtype-of? ListValueItem}
                         then
                            drag-effect-copy
                         else
                            drag-effect-none
                        }
                    }
                }
            }
        },
        ||RecordGridにドロップしたときのイベント
        ||(Drop)を追加します。
        {on e:Drop do
            {e.accept-drop
                {proc  {obj:any,x:Distance,y:Distance,effect:#DragEffect}:DropResult
                    
                    {if not obj isa ListValueItem
                     then
                        {return {DropResultNone}}
                    }

                    let item:ListValueItem = obj asa ListValueItem
                    let goods-record:Record = item.value asa Record

                    ||現在表示されているレコードと突合せを行います。
                    ||Codeがドロップした商品のIDと等しい項目があるかどうかで
                    ||処理が分岐します。
                    {if-non-null list-record:Record =
                        {list.select-one
                            filter = {RecordData Code = goods-record["id"]}
                        }
                     then
                        ||レコードが存在する場合は、個数と小計の更新を行います。
                        let count:int = list-record["Count"] asa int
                        let price:int = list-record["Price"] asa int
                        set list-record["Count"] = count + 1
                        set list-record["Subtotal"] = (count + 1) * price
                     else
                        ||レコードが存在しない場合は、新規にレコードを追加します。
                        {list.append
                            {RecordData
                                Code = goods-record["id"],
                                Name = goods-record["name"],
                                Price = goods-record["price"],
                                Count = 1,
                                Subtotal = goods-record["price"]
                                
                            }
                        }
                    }
                    {return {DropResultNone}}
                }
            }
        }
    }
}

 グリッドにDragOverとDropイベントを記述することによって、RecordGridは初めてドラッグされてきたグラフィックを受けつけることができます。これを実際に起動すると、次の図のようなアプリケーションが実行されます。実際のサンプルについては添付のソースを参照してください。なお、Developer Centerではこれ以外にもさまざまなサンプルが紹介されています。

起動すると次のようなアプリケーションが実行される
起動すると次のようなアプリケーションが実行される

ドラッグ&ドロップの利点

 ドラッグ&ドロップの実装方法について理解いただけましたでしょうか? ドラッグ&ドロップを実装することのメリットは、直感的な操作が行えるようになることで、コンピュータの利用に慣れていない初心者でも分かりやすいUIを提供できることにあります。新規システムを構築する際にはぜひ検討してみてください。

 次回は、印刷の機能について詳しく見ていきます。

  • LINEで送る
  • このエントリーをはてなブックマークに追加

著者プロフィール

All contents copyright © 2005-2022 Shoeisha Co., Ltd. All rights reserved. ver.1.5