コンピュータのインターフェースにおいて、ドラッグ&ドロップ は定番の操作です。リストボックスの場合、複数のアイテムを同時に移動させるには、これまでは “Alt” キーを使っておこなっていましたが、4D v19 R7 以降は必要なくなりました。
よりユーザーフレンドリーなインターフェース
技術的・歴史的な理由により、複数の項目を同時移動させるにはキーボードの “Alt” キーを押しておこなう必要がありましたが、この制限はもう過去のものです。新しい振る舞いは、macOS や Windows がファイルやフォルダーを管理するのに使用する振る舞いに非常に近いため、ユーザーフレンドリーな改善と言えます。ユーザーは操作性の違いに混乱することなく、意図した操作を自然におこなえます。
もし…
既存のアプリケーションのユーザーが “Alt” キーを使う操作に慣れている場合も、心配はありません。その場合にも、ドラッグ&ドロップは同じように動作します。他の目的で “Alt” キーを考慮するようなプログラミングをしない限り、”Alt” キーは無視されます (例: “alt” キーが押されている場合に、移動 だけでなく コピー もおこなう)。
つまり…
新しい振る舞いは OS に準じており、よりユーザーフレンドリーです。このブログ記事をここでやめることもできますが、この機会にリストボックスの振る舞い (プロパティや、処理可能なイベントなど) について思い出してみましょう。興味を持たれた方は、ぜひ読み進んでください。
選択モード、複数選択、そしてイベント
3種類の選択モード
リストボックスには、プロパティリストのプロパティによって決まる 3つの選択モードがあります:
- なし
- 単一
- 複数
複数選択用の 2つの操作
キーボードのキーを使って、複数の要素を選択することができます:
- Shiftキーを押しながら: 連続した範囲を選択します (例: “ささき” から “さとう” まで)
- Ctrlキー (macOS では Cmdキー) を押しながら: 不連続な範囲を選択します (例: “ささき” と “たなか” と “はしもと” と “よねだ“)
3つのイベント
“ドラッグ&ドロップ” 時には、3つのイベントを管理することができます。
- on begin drag over
- on drag over
- on drop
重要: これらのイベントは、draggable (ドラッグ有効) および droppable (ドロップ有効) のプロパティが “カスタム” に設定されている場合にのみトリガーされます。
1 – 最初のイベント (on begin drag over) は、ドラッグ元のリストボックスでドラッグが開始されると発生します。この時点で、「次のステップ」を準備する必要があります。つまり、選択されたものを何らかの方法で保存する必要があるのです。たとえば、クリップボードや Form 変数に格納することができます。このイベントは一度だけ発生することに注意してください。
If (Form event code=On Begin Drag Over)
$drag:=New object
// (…) Form.drag オブジェクトに必要なものを格納します
// オブジェクトを BLOB に変換し、
VARIABLE TO BLOB($drag; $blob)
// シグネチャ (xxxx) とともにペーストボードに入れます
APPEND DATA TO PASTEBOARD("xxxx"; $blob)
End if
2 – 次のイベント (on drag over) は、リストボックスの上にカーソルを置くと発生しますが、先に on begin drag over が発生しているか、または他のものをリストボックスの上にドロップできる場合にのみ発生します。
このイベントを考慮することは必須ではありませんが、ドロップ操作を拒否することができるため、有益なイベントです。
ドロップの可否を判断するには、ドロップされそうなものの中身を確認します。ドロップされそうな内容に問題がなければ、$0 に 0 (ゼロ) を返し、ドロップを拒否するには -1 (マイナス1) を返します (この場合、on drop イベントも生成されません)。
If (Form event code=On Drag Over)
If (Pasteboard data size("xxxx")<=0)
$0:=-1 // 受け入れられない内容の場合、ドロップを拒否します
Else
$0:=0
End if
End if
3 – 最後のイベント (on drop) は、その名前が示すように、ドロップ先のリストボックス (ソースと同じリストボックスでも可) 上で “ドロップ” 操作が実際に実行された瞬間に生成されます。
このイベントでは、どの位置でドロップされたかをテストしたり、ドロップされるコンテンツに応じた操作をおこなうことができます。ドロップ操作は、必ずしも他のリストボックスからのドラッグ操作による結果であるとは限らないことに留意が必要です。システム環境のファイルやフォルダーなど、アプリケーションの外部要素がドロップ元であることさえあるのです。
if(Form event code=On Drop)
// ペーストボードの内容を取得します
GET PASTEBOARD DATA("xxxx"; $blob)
BLOB TO VARIABLE($blob; $drag)
// 取得したオブジェクトで必要な操作をおこないます
(…)
end if
まとめ
これらの情報はすべて HDI サンプルでカバーされています。ぜひダウンロードして、実用的な実装を確認してください。
それでは、よいコーディングを!