Tips

外部ファイルのドラッグ&ドロップをハンドリングする方法

日付2008/08/14
ID08-021
バージョン11
プラットフォームWin / Mac

4D v11 SQLより、ドラッグ&ドロップを用いた外部アプリケーションとのデータの受け渡しができるようになり、これまで以上にフレンドリーで効果的なインタフェースがデザインできるようになりました。これは、ボタンクリック/ファイル選択を多用した従来型のインタフェースから、ドラッグ&ドロップ主体のインタフェースへとバージョンアップを図る良い機会です。

オブジェクトの選定

ドラッグ&ドロップの窓口となるオブジェクトは、いろいろありますが、たいていの場合は次のいずれかを使用します。


  • リストボックス
  • 階層リスト
  • ピクチャ
  • 4D アプリケーションそのもの

  • 新しいコマンド

    次のドラッグ&ドロップコマンドを使用します。


  • GET PASTEBOARD DATA TYPE
  • Get file from pasteboard
  • SET FILE TO PASTEBOARD

  • ドラッグ&ドロップコマンドではありませんが、次の新コマンドも便利です。


  • Count in array
  • Choose
  • SET LIST ITEM PARAMETER
  • SET LIST ITEN ICON

  • 新しいフォームイベント


  • On Begin Drag Over

  • 新しいデータベースイベント


  • On Drop

  • リストボックスの場合

    外部ファイルへの参照をリストボックスで受け付けることができます。まずはリストボックスを作成します。ポイントは、デフォルトで付けられる変数名(Column1, Column2...)を変えないということです。これに独自の変数名を付けることはかえって開発効率を下げます。(どうしても名前が必要であれば、ポインタ経由などにすると良いかもしれません。)列の数は必要に応じて増減することができます。

    On Drag Over

    リストボックス上を浮遊しているオブジェクトがファイルのショートカットであるかどうかは、GET PASTEBOARD DATA TYPEで調べます。"com.private.file.url"が含まれていれば、ファイルシステムのURL(ドキュメントまたはファイル)がドラッグオーバされていることを意味します。ドロップできるアイテムであればオブジェクトメソッドの$0に0を、そうでなければ-1を代入します。

    例:

    : ($FormEvent_l=On Drag Over )
    
    ARRAY TEXT($Signatures_at;0)
    ARRAY TEXT($Types_at;0)
    
    GET PASTEBOARD DATA TYPE($Signatures_at;$Types_at)
    
    C_LONGINT($Accept_l;$Refuse_l)
    
    $Accept_l:=0
    $Refuse_l:=-1
    
    $0:=Choose(Find in array($Signatures_at;"com.4d.private.file.url")#-1;$Accept_l;$Refuse_l)

    Choose文の第二引数以降の型は"expression(式)"です。コンパイラはこの型を明示的に知らされる必要があります。リテラルな数値(0, -1)を記述すると、コンパイルモードでランタイムエラーが発生します。

    On Drop

    はじめにマウスポインタを通常の概観にするためにSET CURSORを実行します。次にループの中でGet file from pasteboardを実行し、ドロップされた複数のアイテムのファイルパスを素早く取得します。この処理に時間をかけていると、ユーザがマウスボタンを手放すなどしてしまい、アイテム数が欠落するかもしれません。ファイルごとの処理が必要だとしても、まずはパスを収集し、ループを抜けた後に実行するようにします。

    例:

    : ($FormEvent_l=On Drop )
    
    SET CURSOR  `need this to recover normal state
    
    ARRAY TEXT(Column1;0)
    
    $i:=1
    
    Repeat 
    
    $FilePath_t:=Get file from pasteboard($i)
    
    If ($FilePath_t#"")
    
    APPEND TO ARRAY(Column1;$FilePath_t)
    
    End if 
    
    $i:=$i+1
    
    Until ($FilePath_t="")
    
    End case 

    たとえばピクチャのサムネイルなど、ファイルごとに関連する情報も取得しておきたい場合、パスの配列を受け取った後、個別に参照先を処理することができます。リストボックスに非表示属性の列を用意しておき、そこにピクチャなどの情報を格納しておければ、ユーザがリストボックスの行を選択するたびにファイルを処理しなくても済みます。

    On Begin Drag Over

    リストボックスの行をユーザが選択し、外へドラッグしようとしたときに発生するイベントです。ここではファイルパスをドラッグしようとしているので、SET FILE TO PASTEBOARDでペーストボードにファイルパスをコピーします。

    : ($FormEvent_l=On Begin Drag Over )
    
    If (Test path name(Column1{Column1})=Is a document )
    
    SET FILE TO PASTEBOARD(Column1{Column1})
    
    End if 

    階層リストの場合

    階層リストのコーディングは基本的にリストボックスのそれと同じです。リストボックスの非表示列で補足的な情報が行ごとに登録できるのと同じように、SET LIST ITEM PARAMETERで任意のキー/値ペアをアイテムごとに作ることができます。またSET LIST ITEN ICONでピクチャ変数・フィールド・前述に対するポインタを割り当てることができます。

    ピクチャの場合

    ピクチャの場合、自動ドラッグ&ドロップという選択肢もあります。これはピクチャからピクチャへのドラッグ&ドロップを自動的に処理するものです。ただし、この場合はピクチャをドラッグ&ドロップでファイルとして書き出すことはできません。そのような動きが必要であれば、あらかじめピクチャをファイルに書き出しておき、On Begin Drag Overでペーストボードにファイルパスをコピーする必要があります。

    4Dアプリケーションそのものの場合

    データベースイベントのOn Dropフェーズでコードを実行する点を除けば、コーディングは基本的にオブジェクトメソッドののそれと同じです。On Drag Overに相当するハンドリングメソッドがないので、4Dはどのファイルタイプでも受け付けようとします。外部からのドロップを全面的に拒否するには環境設定の互換性タブで該当するオプションを有効にします。