Curlでのドラッグ&ドロップ
Curlでは、容易にドラッグ&ドロップを実装できます。例えば以下のような機能を作るとします。
円を右側の四角にドラッグ&ドロップするとメッセージが表示されます。右から2番目の四角はドラッグはできますが、ドロップできないように制御します。このプログラムは次のようになります。
{HBox spacing = 2cm, valign = "center", ||ドラッグ対象 「dragee」をセットするとドラッグ対象になります。 {EllipseGraphic width = 1cm, height = 1cm,user-data="黄色",fill-color="yellow", dragee = {ImageDragee}}, {EllipseGraphic width = 1cm, height = 1cm,user-data="赤", fill-color="red",dragee = {ImageDragee}}, {RectangleGraphic width = 1cm,height = 1cm,fill-color = {FillPattern.get-olive}, dragee = {ImageDragee}}, ||ドロップ対象 {Frame "ここにドロップ", width = 3cm, height = 2cm,border-style="flat",border-width=1pt,background="#ffffff", {on e:DragOver do {e.will-accept-drop? {proc {type:Type, x:Distance, y:Distance, effect:#DragEffect}:DragEffect ||ドラッグオーバーされたオブジェクトのタイプを参照できます。 ||以下のように特定のタイプのみドロップを受け付けるようにすることができます。 {if type == EllipseGraphic then {return drag-effect-copy} else {return drag-effect-none}||円以外はドロップを受け付けない } } } }, {on e:Drop do {e.accept-drop {proc {a:any, x:Distance, y:Distance, effect:#DragEffect}:DropResult {return {DropResultCopy action = {proc {}:void ||ドロップされたオブジェクトを参照できます。 ||以下の例では、ドロップされたオブジェクトの「user-data」を参照しています。 {popup-message "ドロップされたのは" & a.user-data & "の円です!",modal? = true} } } } } } } } }
このように、プロパティの設定とドロップイベントを追加をするだけで、ドラッグ&ドロップが実現できます。ドラッグ&ドロップをうまく使えば、より操作しやすいアプリケーションを実装することが可能です。
実際のアクセス権設定画面では、下図のようにドラッグ&ドロップを制御しています。設定したアクセス権はゴミ箱にだけドロップ可に、DB・テーブル一覧のものは中央にだけドロップ可になっています。
||アクセス権ゴミ箱にドラッグオーバーイベントを追加 {self._auth-trash-box.add-event-handler {on e:DragOver at s:MyPartsTrashBox do {self.auth-trash-over e,s}} } ・・・ ||method ||名称:[auth-trash-over 内容:[アクセス側ゴミ箱over] {method protected {auth-trash-over t:DragOver,p_box:MyPartsTrashBox}: void let v_drag-effect:String = "none" ||最初の例ではドラッグオーバーされたオブジェクトのタイプを参照していましたが、 ||この場合は、ドラッグオーバーされたオブジェクトを参照して判断しています。 {t.dss.for-each ||DragOverの「dss」からドラッグされたオブジェクトを取り出します。 {proc {ds: DataTransferSource}: void let v_src: any = {ds.get-data} {switch v_src using isa case MyNodeTextFlowBox do ||DB、テーブルツリーノードの場合 let v_item: MyNodeTextFlowBox = v_src asa MyNodeTextFlowBox ||さらにそのツリーノードの親が「MyPartsHostListDropBox(中央のドロップエリア)」の ||場合にだけドロップを受け付ける {if v_item.parent-box isa MyPartsHostListDropBox then set v_drag-effect = "move" } } } } || v_drag-effecが「move」のときは、ドロップ可の表示になり、「none」の場合はドロップ不可の表示になります。 {{get-gui-manager}.report-drag-drop-effect {DragEffect v_drag-effect} } }