この章では、ドラッグ & ドロップ・ユーザ・モデルと共通デスクトップ環境 (CDE) のドラッグ & ドロップ簡易アプリケーション・プログラム・インタフェース (API) を説明し、ドラッグ & ドロップの使い方を説明します。
共通デスクトップ環境 (CDE) には、あらゆるデスクトップを通じて操作に一貫性のある便利なドラッグ & ドロップを提供するために、Motif に基づくドラッグ & ドロップのためのアプリケーション・プログラム・インタフェース (API) があります。CDE のドラッグ & ドロップ API は、開発者によるドラッグ & ドロップの実現をより簡単にします。ドラッグ & ドロップを使うと、ユーザは、画面上のオブジェクトをグラブし、ディスプレイ上をドラッグし、他のオブジェクトの上にドロップするという直接操作によって、データを転送できます。
テキスト、ファイル、およびバッファは、CDE のドラッグ & ドロップ API で使用されるデータの 3 つのカテゴリです。この文脈のテキストは、入力フィールドのテキストのように、ユーザの目に見えるテキストとして定義されます。ファイルは、ファイル・システム内にあるデータのコンテナです。各ファイルは、その内容を記述する形式を持ちます。バッファは、メモリに含まれるデータです。特徴として、各バッファはその内容を記述する形式を持ちます。
ドラッグ & ドロップを使用するには、DtSvc ライブラリをリンクする必要があります。ヘッダ・ファイルは Dt/Dnd.h です。
ドラッグ & ドロップの例が入っているデモ・プログラムは、/usr/dt/examples/dtdnd にあります。
ドラッグ & ドロップとアプリケーションを統合するには、次の手順に従います。
この節では、デスクトップの他の部分に矛盾せずに、ユーザの期待に反しないアプリケーションが設計できるように、ドラッグ & ドロップの基本となるユーザ・モデルを説明します。
ドラッグ & ドロップの詳細と、ドラッグ & ドロップ要素の外観に関するガイドラインについては、『共通デスクトップ環境 スタイル・ガイド』を参照してください。
ドラッグ & ドロップをデスクトップ上のすべてのアプリケーションで使用できれば、システムはユーザにとってより予測可能なものとなり、したがって、より使いやすく覚えやすくなります。ユーザは、すでに知っている技術を使うことによって、自分が学んだことをより多くのアプリケーションに応用できます。また、多くのユーザはメニューを使うよりもドラッグ & ドロップを好みます。
この章では、ユーザが何かをドロップできる場所としてドロップ領域という用語を使用します。ドロップ領域は、通常、コントロールまたはグラフィック・アイコンによって表示されます。たとえば、ごみ箱アイコンや入力フィールドのグラフィックです。ドロップ領域を表す矩形の領域には、ドロップ・ターゲットという用語を使用します。
ドラッグ & ドロップ機能があれば、ユーザはアイコンとして表されたオブジェクトを選択し、操作できます。
ドラッグ & ドロップは、アプリケーション内でサポートされている他のユーザ・インタフェース・コントロールを通して使用できる機能のアクセラレータです。ただし、すべてのユーザがドラッグ & ドロップを利用できるわけではありません。基本的な操作は、ドラッグ & ドロップ以外にもサポート方法を用意してください。アプリケーションがドラッグ & ドロップを通してサポートする基本的な機能は、メニュー、ボタン、またはダイアログ・ボックスによってもサポートされなければなりません。
ユーザがドラッグ & ドロップを使用してアイコンを選択し、操作するときには、ドラッグされる項目を表すグラフィック・アイコンは、選択からドラッグ & ドロップの終了まで一貫していることをユーザは期待します。ユーザがファイル・マネージャのメッセージ・アイコンを選択してドラッグを開始した場合には、ドラッグ・アイコンの元の部分は、そのメッセージ・アイコンによって表されます。このような一貫性を与えることで、ドラッグ & ドロップはユーザにとって予測可能なものになります。転送先アプリケーションがアイコンを使用する場合、ほとんどのアイコンは、選択されてドラッグ & ドロップされたアイコンと同じでなければなりません。ただし、この動作は、すべてのアプリケーションで常に適切であるとは限りません。テキストのドラッグは例外です。選択されたテキストをドラッグする代わりに、テキスト・ドラッグ・アイコンが使用されます。
転送元と転送先の両方のアプリケーションが、ドラッグ・アイコンの外観を指定します。アプリケーションが一貫した適切なドラッグ・アイコンを持つようにするのは、開発者の責任です。ドラッグ & ドロップ・ライブラリはデフォルトのアイコンを提供しますが、各アプリケーションのために開発者が独自のアイコンを指定するとよいでしょう。アイコンとそのアイコンによって表されるデータ型を関連付けるために、データ型データベースを使用しなければならない場合があります。詳細は、第 9 章「データ型データベースのアクセス」を参照してください。
ユーザがアイコンを選択せずにドラッグを開始する場合は、関連するドラッグ・アイコンを提供しなければなりません。たとえば、アポイント・エディタでは、ユーザはスクロール・リストからアポイントを選択できますが、アイコンが表示される場合と表示されない場合があります。ソース・インジケータとしてアポイント・アイコンを使用しなければなりません。転送先アプリケーション (たとえば、ファイル・マネージャ) は、同じアポイント・アイコンを表示しなければなりません。
ドラッグ・アイコンがドロップ領域の上に来ると、ドラッグオーバ・フィードバックを提供するために外観が変化します。
ドラッグ・アイコンには次の 3 つの部分があり、その組み合わせによってドラッグオーバ・フィードバックを提供します。
状態インジケータ
操作インジケータ
ソース・インジケータ
状態インジケータは、有効または無効ドロップ領域インジケータと組み合わされて、位置付けのために使用されるポインタです。有効状態インジケータは、矢印ポインタです。このポインタにはホット・スポットがあるので、ユーザは予測可能な方法で位置付けることができます。無効状態インジケータは、円と斜線の組み合わせであり、ユーザが無効なドロップ領域の上にカーソルを置いたときに表示されます。
操作インジケータは、ドラッグ時に行われる操作 (移動、コピー、またはリンク) に関するフィードバックをユーザに与えます。ほとんどのドラッグは移動なので、より頻度が少ないコピーまたはリンク操作を実行するときには、追加のフィードバックが与えられます。
操作フィードバックは、状態フィードバックとソース・フィードバックの手前に表示されます。この動作は、Motif のドラッグ & ドロップ動作と一致しています。
ユーザは、表 5-1 に示されている特定のキーを押しながらドラッグすることによって、ドラッグ操作 (移動、コピー、またはリンク) を選択できます。
表 5-1 ドラッグ操作を変更するためのキー
キー |
操作 |
---|---|
[Shift] |
移動 |
[Control] |
コピー |
[Control]+[Shift] |
リンク |
ファイル・マネージャの読み取り専用ウィンドウの場合のように、転送元アプリケーションがコピーを強制することもあります。ユーザが操作を選択したときに、ドロップ領域がその操作と一致しなければドロップできません。一致しない場合には、ドロップ領域は無効です。つまり、ユーザが [Control] キーを押してコピーを選択して、ドラッグ・アイコンをごみ箱アイコンへドラッグした場合には、ごみ箱へのコピーは許可されません。このため、ドラッグ・アイコンはごみ箱アイコンを無効なドロップ領域として表示しなければならず、ドロップは失敗します。
ソース・インジケータは、選択 (すなわち、ドラッグされている項目) を表します。ソース・インジケータは、選択が 1 つの項目または複数の項目を表すか、あるいは選択が表す項目の種類によって変化します。
アプリケーションは、ダイアログ・ボックスまたはウィンドウ内部からのドラッグを可能にする必要がある場合があります。カレンダのアポイントエディタには、アポイントのスクロール・リストとアポイントを編集するための入力領域があります。ユーザは、スクロール・リストからアポイントをドラッグできますが、アポイント入力領域からもドラッグできなければなりません。ユーザが入力領域からドラッグできるのは、アポイントがまだカレンダに挿入されていないときです (たとえば、申し込まれたミーティングの時間を入力したが、カレンダに挿入していないときなどです)。
ドラッグできる項目には、アイコン・グラフィックを関連付ける必要があります。ダイアログ・ボックスのグラフィック・アイコンは、ドラッグされる情報に隣接する適切な領域に置きます。ダイアログ・ボックスまたはウィンドウの右上隅が、望ましいデフォルトの位置です。このアイコンは何かをドラッグできることをユーザに知らせます。また、使用するグラフィックは、ドラッグ・アイコンに使用するグラフィックと同じにして、一貫性を持たせます。アイコンは 32 * 32 ピクセルでなければならず、ファイル・マネージャが使用するアイコンと同様のラベルがなければなりません。詳細は、『共通デスクトップ環境 スタイル・ガイド』の第 3 章「ドラッグ & ドロップ」を参照してください。
ドラッグが可能なのは、選択できるコンポーネントまたは項目を持つヒューマン・インタフェース要素からだけです。ボタンまたはメニューのラベルなど、静的なラベルからはドラッグできません。
この節では、ドロップ領域フィードバックとドラッグ & ドロップの遷移効果を説明します。
デフォルトのドロップ領域フィードバックをドラッグアンダといい、領域を囲む実線、ドロップ領域を囲む斜角の付いた浮き出した表面かくぼんだ表面、またはドロップ領域の上に描かれたピックスマップで表されます。
遷移効果は、ドロップが成功したか失敗したかをユーザに知らせます。メルトとスナップバックという 2 つの遷移効果があります。
メルトは、ユーザがドラッグ・アイコンを有効なドロップ領域にドロップしたときに発生します。ユーザがドラッグ・アイコンを有効なドロップ領域にドロップすると、ドラッグ・アイコンは、ドロップ領域に溶けてなくなります。ドラッグ・アイコンは、転送先アプリケーションにふさわしいアイコンに置き換えられます。フロントパネルのプリンタは、メルト効果以外には何も示しません。開いているファイル・マネージャ・ウィンドウは、適切なアイコンを表示することがあります。
アイコンがドロップされても、メルト効果が直ちに起こらないこともあります。転送が完了するまで、アイコンが位置していた場所に表示されています。転送中は、転送先のカーソルをビジー状態に設定してください。転送が完了するまで、ユーザはアイコンを動かしたり、選択したりできません。ビジー・カーソルによって、転送中であることをユーザに知らせます。
スナップバックは、ドロップが失敗したときに発生します。ドロップの失敗には、2 通りあります。ユーザが無効なドロップ領域にドラッグ・アイコンをドロップした場合には、ドラッグ・アイコンは転送元アプリケーションへ戻ります (スナップバックします)。ドロップが発生したら、転送元と転送先のアプリケーションはデータを転送しなければなりません。データ転送が失敗した場合には、ドラッグ・アイコンはスナップバックし、転送先アプリケーションは失敗したことをユーザに通知し、ドロップが失敗した理由を示さなければなりません。
ドラッグ & ドロップの転送元の動作が理解できるように、表 5-2 に、選択されたテキスト、ファイル、およびバッファのドラッグ・ソースにできる主なデスクトップ・コンポーネントを示します。
表 5-2 ドラッグ・ソースにできるデスクトップ・コンポーネント
ドラッグ・ソース |
選択されたテキスト |
ファイル |
バッファ |
---|---|---|---|
テキスト・フィールド (Motif)* |
選択されたテキスト |
N/A |
N/A |
テキスト・エディタ: メイン・ウィンドウ |
選択されたテキスト |
N/A |
N/A |
端末エミュレータ: メイン・ウィンドウ |
選択されたテキスト |
N/A |
N/A |
ファイル・マネージャ: フォルダ・ウィンドウ |
N/A |
ファイル |
N/A |
ファイル・マネージャ: ごみ箱ウィンドウ |
N/A |
ファイル |
N/A |
メール: メッセージ・リスト |
N/A |
N/A |
メールメッセージ形式のメッセージ |
メール: アタッチメント・リスト |
N/A |
N/A |
アタッチメント形式のアタッチメント |
カレンダ: アポイントエディタ |
N/A |
N/A |
アポイント形式のアポイント |
* Motif テキスト・フィールドの転送元が選択されたアプリケーションは、テキストをドラッグします。
次のデスクトップ・コンポーネントは、ドロップ先になります。
エディタ
ファイル・マネージャ
フロントパネル
各コンポーネントは、選択されたテキスト、ファイル、およびバッファのドロップを受け入れます。テキスト・ドロップの転送先のほとんどは、Motif ライブラリによって自動的に提供されます。ファイルまたはバッファ・データのドロップ先がドロップを受け入れるためには、プログラムを追加しなければなりません。
ユーザがファイルからデータをドロップして、そのファイルが何らかの方法で変更されたときには、ファイルの元の保持者へ変更を書き戻すことができます。この動作をセーブバックといいます。ただし、データがバッファからドロップされたときには、データは元のファイルに関する情報を持ちません。つまり、データの元の保持者がないので、バッファからのデータに加えられた変更を書き戻すことはできません。この動作をセーブバックなしといいます。
たとえば、メール・プログラムは、ドラッグ & ドロップを使用して、メール・アタッチメントをエディタにエクスポートできます。アタッチメントがバッファとしてエクスポートされた (セーブバックがない) 場合、エディタでメール・プログラム内の元のアタッチメントを変更する手段はありません。したがって、エディタは、アタッチメントの変更済みの版を新しいファイルに保存するしかありません。
メール・アタッチメントは、すでに別のファイルではない (メール・フォルダ・ファイルに埋め込まれている) ので、バッファとしてエクスポートされるだけで、他のエディタによって保存できません。
アタッチメントがファイルとしてエクスポートされた (セーブバックがある) 場合には、エディタは変更済みのものを同じファイルに保存します。
表 5-3 は、テキスト・エディタ、アイコン・エディタ、カレンダ、メール・プログラムなどのエディタ型コンポーネントへ、選択されたテキスト、ファイル、およびバッファをドロップする場合を示します。
表 5-3 エディタのドロップ先
ドロップ先 |
選択されたテキスト |
ファイル |
バッファ |
---|---|---|---|
テキスト・エディタ: メイン・ウィンドウ |
挿入 |
挿入 |
挿入 |
端末エミュレータ: メイン・ウィンドウ |
挿入 |
N/A |
N/A |
アイコン・エディタ: メイン・ウィンドウ |
N/A |
読み込み (ファイルがアイコン形式の場合)。セーブバックあり |
読み専用で読み込み (データがアイコン形式の場合)。セーブバックなし |
メール・プログラム: メッセージ・リスト |
N/A |
追加 (ファイルがメール形式の場合) |
追加 (データがメール形式の場合) |
メール・プログラム: メール作成 |
挿入 |
挿入 |
挿入 |
メール・プログラム: アタッチメント・リスト |
挿入 |
挿入 |
挿入 |
カレンダ: メイン・ウィンドウ |
N/A |
アポイントをスケジュール (ファイルがアポイント形式の場合) |
アポイントをスケジュール (データがアポイント形式の場合) |
カレンダ: アポイントエディタ |
テキスト・フィールドへ挿入 |
アポイント・フィールドに記入 (ファイルがアポイント形式の場合) |
アポイント・フィールドに記入 (データがアポイント形式の場合) |
アプリケーション・ビルダ |
N/A |
読み込み (ファイルが BIX または BIL 形式の場合)。セーブバックあり |
読み専用で読み込み (データが BIP 形式の場合)。セーブバックなし |
表 5-4 は、ファイル・マネージャ内のファイルとフォルダ・アイコンへ、選択されたテキスト、ファイル、およびバッファをドロップする場合を示します。
表 5-4 ファイル・マネージャのドロップ先
ドロップ先 |
選択されたテキスト |
ファイル |
バッファ |
---|---|---|---|
ファイル・アイコン |
ターゲット・ファイルとドロップされたテキストに対してドロップ・アクションを呼び出す (ファイルがテキストのドロップを受け入れ、ドロップされたテキストが適切な形式の場合)。セーブバックなし/コピーなし |
ターゲット・ファイルとドロップされたファイルに対してドロップ・アクションを呼び出す (ファイルがファイルのドロップを受け入れ、ドロップされたファイルが適切な形式の場合)。セーブバックあり |
ターゲット・ファイルとドロップされたデータに対してドロップ・アクションを呼び出す (ファイルがデータのドロップを受け入れ、ドロップされたデータが適切な形式の場合)。セーブバックなし/コピーなし |
フォルダ・アイコン |
テキストをフォルダ内の新しいファイルに「タイトルなし」という名前で挿入する |
ファイルをフォルダにコピー/移動する |
データをフォルダ内の新しいファイルに指定された名前 (指定された場合) で挿入する。名前が指定されなかった場合には、「タイトルなし」という名前で挿入する |
アクション・アイコン |
テキストに対してアクションを呼び出す (適切な形式であり、テキストのドロップを受け入れる場合)。セーブバックなし |
ファイルに対してアクションを呼び出す (適切な形式であり、ファイルのドロップを受け入れる場合)。セーブバックあり |
データに対してアクションを呼び出す (適切な形式であり、データのドロップを受け入れる場合)。セーブバックなし |
メール・コンテナ・アイコン |
メールボックスに追加する (テキストがメール形式の場合) |
メールボックスに追加する (ファイルがメール形式の場合) |
メールボックスに追加する (データがメール形式の場合) |
表 5-5 は、フロントパネルのアクション・アイコンへ、選択されたテキスト、ファイル、およびバッファをドロップする場合を示します。
表 5-5 フロントパネルのドロップ先
ドロップ先 |
選択されたテキスト |
ファイル |
バッファ |
---|---|---|---|
テキスト・エディタ |
読み専用で読み込む。セーブバックなし |
読み込む。セーブバックあり |
読み込み専用で読み込む。セーブバックなし |
カレンダ |
アポイントをスケジュールする (テキストがアポイント形式の場合) |
アポイントをスケジュールする (ファイルがアポイント形式の場合) |
アポイントをスケジュールする (データがアポイント形式の場合) |
メール |
テキストを接続してメッセージを作成する |
ファイルを接続してメッセージを作成する |
データを接続してメッセージを作成する |
プリンタ |
テキストを印刷する (印刷方法がテキストに対して有効な場合) |
ファイルの内容を印刷する (印刷方法がファイル形式に対して有効な場合) |
データを印刷する (印刷方法がデータの形式に対して有効な場合) |
ごみ箱 |
N/A |
ファイルをごみ箱へ移動する |
N/A |
サブパネル: アイコンのインストール |
N/A |
アイコンをインストールする |
N/A |
サブパネル: アクション |
ファイル・マネージャと同じ |
ファイル・マネージャと同じ |
ファイル・マネージャと同じ |
サブパネル:実行形式 |
ファイル・マネージャと同じ |
ファイル・マネージャと同じ |
ファイル・マネージャと同じ |
ユーザに対するドラッグ & ドロップの表示方法とガイドラインの詳細は、『共通デスクトップ環境 スタイル・ガイド』を参照してください。
CDE は、デスクトップ内の一貫性と相互運用を促進し、開発者によるドラッグ & ドロップの実現を容易にするために、ドラッグ & ドロップ簡易 API を提供します。
ドラッグ & ドロップのための既存の Motif の API は、トランザクション中の転送元と転送先アプリケーションの通信を達成するための合理的な機能を提供します。データ転送のためのフレームワークを提供しますが、実際のデータ転送の詳細はアプリケーションに依存します。デスクトップ内のアプリケーション間の真の一貫性と相互運用のためには、すべてのアプリケーションが同じデータ転送プロトコルを使用しなければなりません。CDE のドラッグ & ドロップ簡易 API は、共通のデータ転送ルーチンを提供します。
ドラッグ & ドロップのための既存の Motif の API は非常に柔軟性がありますが、その分、未熟な開発者にとっては使いにくい点もあります。CDE のドラッグ & ドロップ簡易 API は、次に説明するいくつかの簡易関数とサービスを提供することによって、より簡単で使いやすい API になっています。
ドラッグ・アイコンの構成と外観を管理します。Motif のドラッグ・アイコンを構成するデフォルトのソース、状態、および操作アイコンのグラフィックが用意されています。これらのアイコンの組み合わせによって、ドラッグされているデータの型をチェックします。
ドロップのアニメーションを可能にします。ドロップが完了したときに呼び出されるアニメーション・プロシージャを定義できます。
テキスト、ファイル、およびバッファ転送のために、標準の X Window System の選択ターゲットを使用してデータ転送を提供します。このデータ転送は、標準のターゲットを直接使用する他のアプリケーションとの相互運用を可能にします。
二重登録を提供します。テキスト・ウィジェットをテキスト以外のデータのためのドロップ領域として登録できます。その場合でも、テキストのドロップを受け入れる機能は変わりません。
ドラッグ & ドロップ API は、次の 3 つの分野のポリシーを確立します。
共通ターゲット。使用可能な場合には、クライアント間通信規約マニュアル (ICCCM) によって定義された既存の選択ターゲットが使用されます。
データ転送プロトコル。API は、データ転送の詳細を隠し、データを単純なデータ構造体の形でアプリケーションに提示します。
デフォルトのドラッグ・アイコン。デフォルトのドラッグ・アイコンは、それらを受け入れることができるアプリケーションのために用意されています。
ドラッグ & ドロップ API は、次の分野での共通の機能性を提供します。
テキスト、ファイル名、およびバッファとしてのデータ転送をサポートします。
データ転送フレームワークによって、新しい組み込みプロトコルの追加をサポートします。
ドラッグ & ドロップのための API は、新しいドラッグ & ドロップ・サブシステムを使用するわけではなく、既存の Motif API を使用しています。また、共通のデータ転送プロトコルが選択されているので、使用可能な場合には、アプリケーションは新しい API をグローバルに使用しなくても、選択プロトコル・レベルで相互運用できます。
テキストとファイルの転送は、既存のプロトコルを使用します。バッファ転送は、新しいプロトコルを使用します。
基本的なドラッグ & ドロップ処理の実行例を、図 5-1 に示します。
図 5-2 は、オプションのドラッグ & ドロップ処理の変化と操作を示します。破線のボックスは、基本的な処理を示します。実線のボックスは、オプションの変化と操作を示します。
この節では、アプリケーションと CDE のドラッグ & ドロップとの統合のためのアクション・プランを提案します。
この章の説明を読んで、ドラッグ & ドロップ API を理解してください。API の基本的な理解ができたら、ドラッグ & ドロップのデモ・プログラム /usr/dt/examples/dtdnd のソースコードを見てください。このコードは、さまざまな API の使い方の例を提供しています。これらの例によって、アプリケーションでドラッグ & ドロップをサポートするために書かなければならないコードの性質と量が理解できます。アクションとデータ型 API の理解にも役立ちます。
アプリケーションがドラッグ & ドロップの処理を通して受け入れるデータの型を決めます。たとえば、ビットマップ・エディタを作成する場合には、ファイルのドロップをサポートしたいことがあります。アプリケーションにドロップできるデータ型を決めたら、ドロップ領域になるウィジェットを決めます。ビットマップ・エディタの例の場合には、ビットマップ編集領域を、アプリケーション上でファイルをドロップできる唯一の場所として決定できます。この場合、DtDndDropRegister() を使用して、この領域を表すウィジェットを登録し、適切なコールバックを提供します。
ファイル名のドロップの処理は最も簡単なので、ファイル名のドロップの実現から始めてください。この手法をマスターすると、簡単にテキストとバッファのドロップの実現へ進むことができます。
アプリケーションがドラッグ & ドロップの処理の転送元として許可するデータの型を決めます。ビットマップ・エディタの例の場合、カット & ペーストのアクセラレータとして、現在のビットマップ選択を含んでいるビットマップ・データをドラッグ・ソースにしたいことがあります。アプリケーションからドラッグできるデータ型を決めたら、ドラッグ・ソースになるウィジェットを決めます。ビットマップ・エディタの例の場合、強調表示されているビットマップ選択を含んでいるビットマップ編集領域がドラッグ・ソースの役目を果たすと決定できます。この場合、この領域を表しているウィジェットがドラッグ・ソースになります。
アプリケーションに最もふさわしい、または特有のバッファのドラッグの実現から始めてください。また、アプリケーションの複数起動間の簡単なデータ転送を可能にするために、アプリケーションにバッファをドロップする機能を追加する必要がある場合もあります。
この節では、ドラッグ & ドロップのアプリケーション・プログラム・インタフェース (API) の概要を説明します。
ドラッグ & ドロップ機能は、デスクトップ・サービス・ライブラリ DtSvc で実現されます。ドラッグ & ドロップ API にアクセスするには、ヘッダ・ファイル <Dt/Dnd.h> を組み込み、-lDtSvc をつけてリンクします。
API には 4 つの関数呼び出しがあり、ヘッダ・ファイル Dnd.h の中で宣言されています。これらの関数について、以下の段落で概説します。これらの関数については、後の節で詳しく説明します。
DtDndDragStart() は、ユーザ・アクションに応答して、ドラッグを開始します。
DtDndCreateSourceIcon() は、DtDndDragStart() で使用するソース・アイコンを作成します。
DtDndDropRegister() は、ウィジェットをドロップ領域として登録します。ドロップ領域の登録は、通常はウィジェットが作成された直後に行われますが、いつ行なってもかまいません。
DtDndDropUnregister() は、以前に登録したウィジェットの登録を解除します。ドロップ領域は、通常は破壊される直前に登録解除されますが、登録後であれば、いつ登録解除してもかまいません。
データ転送を処理するには、DtDndContext のデータ構造を使用します。この構造体には、転送プロトコルのためのフィールド、転送される項目数、および転送されるデータ項目の配列が入ります。この構造体の構文の詳細は、DtDndDragStart(3X) および DtDndDropRegister(3X) のマニュアル・ページを参照してください。
プロトコルは、転送データの型を API に知らせるために使用されます。定義済みプロトコルを表 5-6 に示します。
表 5-6 定義済みプロトコル
プロトコル |
説明 |
---|---|
DtDND_TEXT_TRANSFER |
テキスト転送。コンパウンド・テキスト (Motif は、テキスト転送のためにコンパウンド・テキスト・ターゲットを使用します。) |
DtDND_FILENAME_TRANSFER |
ファイル名転送 |
DtDND_BUFFER_TRANSFER |
メモリ・バッファ |
表 5-7 に示すように、ドラッグ・ソースとドロップ領域は 3 つの方法のいずれか 1 つでデータを転送できます。
表 5-7 データ転送操作
操作 |
説明 |
---|---|
XmDROP_MOVE |
データを移動します (コピーしてから削除します)。 |
XmDROP_COPY |
データをコピーします。 |
XmDROP_LINK |
データへのリンクを含みます。 |
この節では、ドラッグ・ソースの使い方を説明します。
ドラッグは、2 つの方法のどちらかで開始されます。1 つは、ユーザは、Btransfer (中央マウス・ボタン) を押すことで、ドラッグを開始できます。ボタンが押されるとすぐに、ドラッグが開始されます。もう 1 つは、ユーザは Bselect (左マウス・ボタン)を押しながらカーソルを動かすことによって、ドラッグを開始できます。ユーザがマウスを特定の距離だけ動かすと、ドラッグが開始されます。この距離をドラッグしきい値といい、ピクセル単位で示されます。Bselect のデフォルトのドラッグしきい値は、10 ピクセルです。Btransfer のドラッグしきい値は 0 です。ドラッグしきい値がないので、ポインタを動かすとすぐに、ドラッグが開始されます。Motif スクロール・テキスト・リストおよびテキスト・ウィジェットは、Btransfer と Bselect によってテキスト・ドラッグするためのドラッグ・ソースとして自動的に登録されます。
ドラッグ・ソースとして使用できる 2 つの一般的なインタフェース・オブジェクトがあります。すなわち、リストとアイコンです。Motif リスト・ウィジェットは、自動的にテキスト・ドラッグの転送元を示します。他の種類のドラッグが必要な場合には、デフォルトのウィジェット変換を新しい Btn1 と Btn2 変換で無効にすることによって行われます。Motif にはアイコン・ウィジェットはありませんが、通常は描画領域をアイコンのコンテナとして使用します。この場合、ドラッグを開始するために、Btn1Motion のイベント・ハンドラが使用されます。コーディング例の詳細は、/usr/dt/examples/dtdnd のサンプル・コードを参照してください。
Bselect を使用してドラッグを開始するときには、ウィジェット・イベント・ハンドラまたは変換手順は、ドラッグを開始する前に、10 ピクセルのドラッグしきい値を適用しなければなりません。Btransfer にしきい値はないので、直ちにドラッグが開始されます。
スタイル・マネージャの [マウス] カテゴリには、Btn2 (中央マウス・ボタン) が Btransfer として機能するか、それとも Badjust として機能するかを制御する設定があります。この設定は、リソース名 enableBtn1Transfer として格納されます。1 の設定は、Btn2 が Badjust であり、選択を調節することを示します。他の値の設定は、Btn2 が Btransfer であり、ドラッグを開始することを意味します。Btn1 (左マウス・ボタン) は、常にドラッグを開始します。
次の例は、Btn2 が Btransfer か Badjust であるかを決める方法を示します。
Display* display; int adjust; XtVaGetValues ((Widget)XmGetXmDisplay(display, "enableBtn1Transfer", &adjust, NULL); if (adjust == 1) /* Btn2 is adjust */ else /* Btn2 is transfer */
共通デスクトップ環境 1.0 アプリケーションは、DtDndDragStart() を呼び出すことによってドラッグを開始します。この関数は、ドラッグを開始するためにデスクトップに特有の準備を行い、XmDragStart() を呼び出します。DtDndDragStart() 関数の形式とパラメータの使用法は、次のとおりです。
Widget dragSource
ドラッグを始めたイベントを受け取るウィジェット
XEvent *event
ドラッグを始めたボタンが押された、またはボタン・モーション・イベント
DtDndProtocol protocol
データ転送のために使用するプロトコル。プロトコルは、次のいずれか 1 つを使用できます。
DtDND_TEXT_TRANSFER
DtDND_FILENAME_TRANSFER
DtDND_BUFFER_TRANSFER
Cardinal numItems
ドラッグする項目数を指定します。
unsigned char operations
dragSource によってサポートされるオプションを指定します。オプションは、XmDROP_MOVE、XmDROP_COPY、および XmDROP_LINK です。ドラッグ・ソースは、これらの操作の任意の組み合わせをサポートできます。操作の組み合わせを指定するには、or (|) を使用します。たとえば、移動とコピー操作をサポートするには、XmDROP_MOVE | XmDROP_COPY と指定します。
XtCallbackList convertCallback
このコールバックは、ドロップが開始され、ドロップ領域がドラッグ・ソースからデータを要求したときに呼び出されます。convertCallback については、次の節で詳しく説明します。
XtCallbackList dragFinishCallback
このコールバックは、ドラッグ & ドロップ・トランザクションが完了したときに呼び出されます。dragFinishCallback は、dragMotionHandler() をリセットして、ドラッグ & ドロップ・トランザクション時にドラッグ・ソースによって割り当てられたメモリを解放します。
変換コールバックは、ドロップが発生すると、ドロップ領域にデータを提供します。変換コールバックの最初のアクションは、callData の中の reason フィールドの確認です。reason が DtCR_CONVERT_DATA または DtCR_CONVERT_DELETE でない場合には、直ちに戻さなければなりません。そうでない場合には、データの変換を続けます。たとえば、ファイル名の変換を処理する場合には、内部のデータ構造体から該当するファイル名を検索して、ファイル・データ・オブジェクトにコピーします。ドラッグ・ソースが移動操作をサポートしている場合には、DELETE ターゲットの変換をサポートする必要があります。すなわち、reason が DtCR_CONVERT_DELETE で convertCallback が呼ばれた場合は、移動されたデータに対して適切な削除アクションを実行します。ファイル転送の場合には、ファイルを削除します。次に、ファイル名の変換と削除を処理する簡単な convertCallback を示します。
void convertFileCallback( Widget dragContext, XtPointer clientData, XtPointer callData) { DtDndConvertCallbackStruct *convertInfo = (DtDndConvertCallbackStruct*) allData; char *fileName = (char *) clientData; if (convertInfo->reason == DtCR_DND_CONVERT_DATA) { convertInfo->dragData->data.files[0]= XtNewString(fileName); } else if (convertInfo->reason == DtCR_DND_CONVERT_DELETE) { deleteFile(fileName); } else { convertInfo->status = DtDND_FAILURE; } }
この節では、ドロップ領域の使い方を説明します。
一般に、ドロップ領域は、ドロップ領域になるウィジェットが作成された直後に登録します。モード付きドロップ領域にする場合は、ユーザがその上にドロップできるようにするにはウィジェットをドロップ領域として登録し、ユーザがその上にドロップできないようにするには登録を解除します。
Motif テキスト・ウィジェットは、作成されたときに、テキスト用のドロップ領域として自動的に登録されます。二重登録が可能です。テキスト・ウィジェットが、テキストだけでなく、ファイル名など他のデータのドロップも受け入れるようにする場合には、テキスト・ウィジェットをファイル用のドロップ領域としても登録できます。Motif によって提供されるテキスト・ドロップ機能は変わりません。ファイル名 (または他のデータ型) のドロップに対する機能は、その上に重ねられます。
ウィジェットをドロップ領域として登録するには、関数 DtDndDropRegister() を使用します。この関数は、必要に応じて二重登録を処理し、デスクトップに特有の準備を行い、XmDropSiteRegister() を呼び出します。DtDndDropRegister() 関数の形式とパラメータの使用法は、次のとおりです。
void DtDndDropRegister( Widget dropSite, DtDndProtocol protocols; unsigned char operations; XtCallbackList transferCallback; ArgList argList; Cardinal argCount) |
Widget dropSite
ドロップ領域として登録されるウィジェット
DtDndProtocol protocols
ドロップ領域が使用できるデータ転送プロトコルのリストを指定します。複数のプロトコルの使用を指定するには、or (|) とプロトコルの値を使用します。
unsigned char operations
ドロップ領域によってサポートされる操作。ドロップ領域は、目的の操作の組み合わせに対して or (|) を使用することによって、XmDROP_MOVE、XmDROP_COPY、および XmDROP_LINK の任意の組み合わせをサポートできます。
XtCallbackList transferCallback
この関数は、ドロップ領域にドロップされたデータを受け入れます。転送コールバックについては、次の節で詳しく説明します。
ArgList argList
オプションの引き数リストを指定します。
Cardinal argCount
argList 内の引き数の数を指定します。
転送コールバックは、ドロップが発生したときに、ドラッグ・ソースからデータを受け入れます。転送コールバックの最初のアクションは、callData の中の reason フィールドの確認です。reason が DtCR_DND_TRANSFER_DATA ではない場合には、直ちに戻さなければなりません。そうでない場合には、型と reason の中で指定された操作に基づいて、データ転送を続けます。たとえば、ファイルのコピーを処理している場合には、データ構造体からファイル名を検索し、ファイルを開き、その内容をコピーします。ドロップ領域が複数のデータ型をサポートしている場合には、各データ型の転送を適切にサポートする必要があります。
次に、テキストとファイル名のデータ型のコピーをサポートするドロップ領域を描画するための簡単な転送コールバックを示します。
バッファのドロップを受け入れるアプリケーションでは、ドロップされたデータをその型に基づいて異なる方法で処理したいことがあります。データ型を判断するには、データ型 API を使用します。重要なデータ型関数呼び出しは、DtDtsBufferToDataType() と DtDtsBufferToAttributeValue() です。前者はデータのデータ属性名を返し、後者は指定されたデータ属性の値を返します。ドラッグ & ドロップに役立つ属性を、表 5-8 に示します。
表 5-8 データ型属性
属性 |
説明 |
---|---|
ICON |
このデータに対して使用するアイコンのパス |
MEDIA |
このデータに対するメッセージ提携メディア名 |
詳細は、第 9 章「データ型データベースのアクセス」を参照してください。