# ドラッグ＆ドロップとの統合

この章では、ドラッグ＆ドロップ・ユーザ・モデルと共通デスクトップ環境の ドラッグ＆ドロップ簡易アプリケーション・プログラム・インタフェース (API)を説明し、ドラッグ＆ドロップの使い方を説明します。

PG.dndPG.mkr.2
PG.dndPG.mkr.6
PG.dndPG.mkr.13
PG.dndPG.mkr.14
PG.dndPG.mkr.17
PG.dndPG.mkr.18
PG.dndPG.mkr.21
PG.dndPG.mkr.22

## 要約

共通デスクトップ環境には、あらゆるデスクトップを通じて操作に一貫性のある便利なドラッグ＆ドロップを提供するために、 Motifに基づくドラッグ＆ドロップのためのアプリケーション・プログラム・インタフェース (API)があります。 共通デスクトップ環境のドラッグ＆ドロップAPIは、開発者によるドラッグ＆ドロップの実現をより簡単にします。 ドラッグ＆ドロップを使うと、ユーザは画面上のオブジェクトをグラブし、ディスプレイ上をドラッグし、他のオブジェクトの上にドロップするという直接操作によって、データの転送を実行することができます。

テキスト、ファイル、バッファは、共通デスクトップ環境のドラッグ＆ドロップAPIで使われるデータの３つのカテゴリです。 この文脈のテキストは、入力フィールドのテキストのように、ユーザの目に見えるテキストとして定義されます。ファイルは、 ファイル・システム内にあるデータのコンテナです。 各ファイルは、その内容を記述する形式を持ちます。バッファは、 メモリに含まれるデータです。 各バッファも,その内容を記述する形式を持ちます。

### ライブラリとヘッダ・ファイル

ドラッグ＆ドロップを使用するには、`DtSvc`ライブラリをリンクする必要があります。 ヘッダ・ファイルは`Dt/Dnd.h`です。

### デモ・プログラム

ドラッグ＆ドロップの例が入っているデモ・プログラムが`/usr/dt/examples/dtdnd`にあります。

### ドラッグ＆ドロップの使い方

#### ドラッグ＆ドロップと統合するには

ドラッグ＆ドロップとアプリケーションを統合するには、次の手順に従います。

1. `Dt/Dnd.h`を組み込みます。

2. `libDtsvc`をリンクします。

3. 受信側として

4. `DtDndDropRegister`を使用して、ドロップ領域を登録します。

5. オプションとして、ドロップ・アニメーションのコールバックを書くこともできます。

6. 転送コールバックを書きます。

7. 送信側として

8. ユーザ・アクションを認識し（おそらく変換テーブルの変更が必要）、`DtDndDragStart`を呼び出します。

9. 変換コールバックを書きます。

10. ドラッグ終了コールバックを書きます。

## ドラッグ＆ドロップ・
ユーザ・モデル

この節では、デスクトップのほかの部分に矛盾せずに、ユーザの期待に反しないアプリケーションが設計できるように、ドラッグ＆ドロップの基本となるユーザ・モデルを説明します。

ドラッグ＆ドロップの詳細と、ドラッグ＆ドロップ要素の外観に関するガイドラインについては、CDE/Motif スタイルガイドおよび認証チェックリストを参照してください。

ドラッグ＆ドロップがデスクトップ上のすべてのアプリケーションで使うことができれば、 システムはユーザにとってより予測可能なものとなり、したがって、より使いやすく覚えやすくなります。 ユーザは、すでに知っている技術を使うことによって、自分が学んだことをより多くのアプリケーションに応用できます。 また、ユーザの多くはメニューを使うよりもドラッグ＆ドロップを好みます。

この章では、ユーザが何かをドロップできる場所を説明するために、ドロップ領域という用語を使います。 ドロップ領域は、通常コントロールまたはグラフィック・アイコンによって表されます。たとえば、ごみ箱アイコンや入力フィールドのグラフィックです。 ドロップ領域を表す矩形の領域を説明するには、ドロップ・ターゲットという用語を使います。

### ドラッグ＆ドロップ機能

ドラッグ＆ドロップ機能があれば、ユーザはアイコンとして表されたオブジェクトを選択し、操作することができます。

ドラッグ＆ドロップは、アプリケーション内でサポートされている他のユーザ・インタフェース・コントロールを通して使用できる機能のアクセラレータです。 ただし、すべてのユーザがドラッグ＆ドロップを利用できるわけではありません。 基本的な操作は、ドラッグ＆ドロップ以外にもサポート方法を用意してください。 アプリケーションがドラッグ＆ドロップを通してサポートする基本的な機能は、メニュー、ボタン、またはダイアログ・ボックスによってもサポートしなければなりません。

### ドラッグ・アイコン

ユーザがドラッグ＆ドロップを使用してアイコンを選択し、操作するときには、ドラッグされる項目を表すグラフィック・アイコンは、選択からドラッグ＆ドロップの終了まで一貫していることをユーザは期待します。 ユーザがファイル・マネージャの メッセージ・アイコンを選択してドラッグを開始した場合には、ドラッグ・アイコンの元の部分は、そのメッセージ・アイコンによって表されます。 この種の一貫性を提供することによって、ドラッグ＆ドロップはユーザにとってより予測可能なものになります。 転送先アプリケーションがアイコンを使用する場合、示されるアイコンは、ほとんどの場合、選択され、ドラッグ＆ドロップされたアイコンと同じでなければなりません。 ただし、この動作はすべてのアプリケーションで常に適切であるとは限りません。 テキストのドラッグは例外です。選択されたテキストをドラッグする代わりに、テキスト・ドラッグ・アイコンが使われます。

転送先と転送元の両方のアプリケーションが、 ドラッグ・アイコンの外観を指定します。 アプリケーションが一貫した適切なドラッグ・アイコンを持つようにするのは、開発者の責任です。 ドラッグ＆ドロップ・ライブラリはデフォルトのアイコンを提供しますが、各アプリケーションのために開発者が独自のアイコンを指定するとよいでしょう。 アイコンとそのアイコンによって表される型データを関連づけるためには、データ型データベースを使わなければならない場合が多いでしょう。 PG.datat.mkr.1を参照してください。

ユーザがアイコンを選択せずにドラッグを開始するときには、関連するドラッグ・アイコンを提供しなければなりません。 たとえば、アポイントエディタでは、ユーザはスクロール・リストからアポイントを選択できますが、アイコンが表示される場合と表示されない場合があります。 ソース・インジケータとしてアポイント・アイコンを使用しなければなりません。 転送先アプリケーション(たとえば、ファイル・マネージャ)は、同じアポイント・アイコンを表示しなければなりません。

#### ドラッグ・アイコンの各部

ドラッグ・アイコンがドロップ領域の上に来ると、ドラッグオーバ・フィードバックを提供するために外観が変化します。

ドラッグ・アイコンには次の３つの 部分があり、その組み合わせによってドラッグオーバ・フィードバックを提供します。

- 状態インジケータ

- 操作インジケータ

- ソース・インジケータ

状態インジケータは、有効または無効ドロップ領域インジケータと組み合わされて、位置付けのために使われるポインタです。 有効状態インジケータは、矢印ポインタです。 このポインタにはホット・スポットがあるので、ユーザは予測可能な方法で位置付けることができます。 無効状態インジケータは、円と斜線の組み合わせであり、ユーザが無効なドロップ領域にカーソルを置いたときに表示されます。

操作インジケータは、ドラッグ時に行われる操作（移動、コピー、またはリンク）に関するフィードバックをユーザに与えます。 ほとんどのドラッグは移動なので、ユーザがより頻度の少ないコピーまたはリンク操作を実行するときには、追加のフィードバックが与えられます。

操作フィードバックは、状態フィードバックとソース・フィードバックの手前に表示されます。 この動作は、Motifのドラッグ＆ドロップ動作と一致しています。

ユーザは、 PG.dndPG.mkr.7に示されている特定のキーを押しながらドラッグすることによって、ドラッグ操作（移動、コピー、またはリンク）を選ぶことができます。

#### ドラッグ操作を変更するためのキー

`修飾キー` | `操作`
[Shift] | 移動
[Control] | コピー
[Control]+[Shift] | リンク

ファイル・マネージャの読みとり専用ウィンドウの場合のように、転送元アプリケーションがコピーを強制することもあります。 ユーザが操作を選んだとき、 ドロップ領域がその操作と一致しなければ、ドロップを行うことはできません。 一致しない場合には、ドロップ領域は無効です。言い換えると、ユーザが[Control]キーを押すことでコピーを選び、ドラッグ・アイコンをごみ箱アイコンへドラッグした場合には、ごみ箱へのコピーは許されないので、ドラッグ・アイコンはごみ箱アイコンを無効なドロップ領域として表示しなければならず、ドロップは失敗します。

ソース・インジケータ は、選択（すなわち、ドラッグされている項目）を表します。 ソース・インジケータは、選択が１つの項目を表すか、それとも複数の項目を表すかによって、また、選択が表す項目の種類によって変化します。 PG.dndPG.mkr.8は、 共通デスクトップ環境でのデフォルトのソース・インジケータを示します。 これらのソース・インジケータは共通デスクトップ環境の ドラッグ＆ドロップ簡易APIを使用すると、自動的に生成されます。これらのアイコンは、正確な画面描写ではなく、おおよその形を表したものです。

#### ドラッグ・アイコンの種類

`ドラッグ・アイコン` | `` 選択されたテキスト | `単一選択` | `複数選択`
有効な移動 |  |  |
有効なコピー |  |  |
有効なリンク |  |  |
無効な移動 None |  |  |
無効なコピー |  |  |
無効なリンク |  |  |

### ウィンドウ内部からのドラッグ

ときには、アプリケーションはダイアログ・ボックスまたはウィンドウ内部からのドラッグを可能にする必要があります。 カレンダのアポイントエディタには、アポイントのスクロール・リストとアポイントを編集するための入力領域があります。 ユーザは、スクロール・リストからアポイントをドラッグできますが、アポイント入力領域からもドラッグできなければなりません。 ユーザが入力領域からドラッグできるのは、アポイントがまだカレンダに挿入されていないときです（たとえば、申し込まれたミーティングの時間を入力したが、カレンダに挿入していないとき）。

ドラッグできる項目には、アイコン・グラフィックを関連付ける必要があります。 ダイアログ・ボックスのアイコン・グラフィックは、ドラッグされる情報に隣接する適切な領域に置きます。 ダイアログ・ボックスまたはウィンドウの右上隅が、望ましいデフォルトの位置です。 このアイコンは何かをドラッグできることをユーザに知らせるものであり、使われるグラフィックは、ドラッグ・アイコンに使われるグラフィックと同じにして、一貫性を持たせます。 アイコンは３２×３２ピクセルでなければならず、ファイル・マネージャが使用するアイコンと同様のラベルがなければなりません。 詳しくは、CDE/Motif スタイルガイドおよび認証チェックリスト のドラッグ＆ドロップの章を参照してください。

ドラッグが可能なのは、選択できるコンポーネントまたは項目を持つヒューマン・インタフェース要素からだけです。 ボタンまたはメニューのラベルなど、静的なラベルからのドラッグはできません。

### 視覚的なフィードバック

以下の節では、ドロップ領域フィードバックとドラッグ＆ドロップの遷移効果を説明します。

#### ドロップ領域フィードバック

デフォルトのドロップ領域フィードバックをドラッグアンダといい、領域を囲む実線、ドロップ領域を囲む斜角 の付いた浮き出した表面かくぼんだ表面、またはドロップ領域の上に描かれたピックスマップで表されます。

#### 遷移効果

遷移効果は、ドロップが成功したか 失敗したかをユーザに知らせます。 メルトとスナップバックという２つの遷移効果があります。

メルトは、ユーザがドラッグ・アイコンを有効なドロップ領域にドロップしたときに発生します。 ユーザがドラッグ・アイコンを有効なドロップ領域にドロップすると、ドラッグ・アイコンはドロップ領域に溶けてなくなります。 ドラッグ・アイコンは、転送先アプリケーションにふさわしいアイコンに置き換えられます。 フロントパネルのプリンタは,メルト効果以外にはなにも示しません。 開いているファイル・マネージャ・ウィンドウは、適切なアイコンを表示することもあります。

アイコンがドロップされても、メルト効果が直ちに起こらないこともあります。 転送が完了するまで、それが位置していた場所にアイコンが表示されています。 転送中は、転送先のカーソルをビジー状態に設定してください。 転送が完了するまで、ユーザはアイコンを動かしたり、選択することはできません。 ビジー・カーソルによって、転送中であることをユーザに知らせます。

スナップバックは、ドロップが失敗したときに発生します。 ドロップの失敗には、２通りあります。 ユーザが無効なドロップ領域にドラッグ・アイコンをドロップした場合には、 ドラッグ・アイコンは転送元アプリケーションへ戻ります（スナップバックします）。 ドロップが発生したら、転送元と転送先のアプリケーションはデータを転送しなければなりません。データ転送が失敗した場合には、ドラッグ・アイコンはスナップバックし、転送先アプリケーションは失敗したことをユーザに通知し、ドロップが失敗した理由を示さなければなりません。

### ドラッグ＆ドロップの転送元（ソース）

ドラッグ＆ドロップの転送元の動作が理解できるように、 PG.dndPG.mkr.9に、 選択されたテキスト、ファイル、バッファのドラッグ・ソースにできる主なデスクトップ・コンポーネントを示します。

### ドラッグ・ソースにできるデスクトップ・コンポー ネント

`ドラッグ・ソース` | `選択されたテキスト` | `ファイル` | `バッファ`
テキスト・フィールド(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ライブラリによって自動的に提供されます。 ファイルまたはバッファ・データのドロップ先がドロップを受け入れるためには、プログラムを追加しなければなりません。

ユーザがファイルからデータをドロップして、そのファイルが何らかの方法で変更されたときには、ファイルの元の保持者へ変更を書き戻すことができます。 この動作をセーブバックといいます。 ただし、データがバッファからドロップされたときには、データは元のファイルに関する情報を持ちません。 つまり、データの元の保持者がないので、バッファからのデータ に加えられた変更を書き戻すことはできません。 この動作をセーブバックなしといいます。

たとえば、メール・プログラムはドラッグ＆ドロップを利用して、メール・アタッチメントをエディタにエクスポートすることができます。 アタッチメントがバッファとしてエクスポートされた（セーブバックがない）場合、エディタでメール・プログラム内の元のアタッチメントを変更する手段はありません。 したがって、エディタはアタッチメントの変更済みの版を新しいファイルに保存するしかありません。

メール・アタッチメントはすでに別々のファイルではない（メール・フォルダ・ファイルに埋め込まれている）ので、バッファとしてエクスポートされるだけで、ほかのエディタによって保存することはできません。

アタッチメントがファイルとしてエクスポートされた（セーブバックがある）場合には、エディタは変更済みのものを同じファイルに保存します。

PG.dndPG.mkr.12は、 テキスト・エディタ、アイコン・エディタ、カレンダ、メール・プログラム、アプリケーションビルダなどのエディタ型コンポーネントへの選択されたテキスト、ファイル、およびバッファのドロップを示します。

### エディタのドロップ先

`ドロップ先` | `選択されたテキスト` | `ファイル` | `バッファ`
テキスト・エディタ：メイン・ウィンドウ | 挿入 | 挿入 | 挿入
端末エミュレータ：メイン・ウィンドウ | 挿入 | N/A | N/A
アイコン・エディタ：メイン・ウィンドウ | N/A | 読み込み（ファイルがアイコン形式の場合）、 セーブバックあり | 読み専用で読み込み（データがアイコン形式の場合）、 セーブバックなし
メール・プログラム：メッセージ・リスト | N/A | 追加（ファイルがメール形式の場合） | 追加（データがメール形式の場合）
メール・プログラム：メール作成 | 挿入 | 挿入 | 挿入
メール・プログラム：アタッチメント・リスト | 接続 | 接続 | 接続
カレンダ：メイン・ウィンドウ | N/A | アポイントをスケジュール（ファイルがアポイント形式の場合） | アポイントをスケジュール（データがアポイント形式の場合）
カレンダ： アポイントエディタ | テキスト・フィールドに挿入 | アポイント・フィールドに記入（ファイルがアポイント形式の場合） | アポイント・フィールドに記入（データがアポイント形式の場合）
アプリケーションビルダ | N/A | 読み込み（ファイルがBIXまたはBIL形式の場合）、 セーブバックあり | 読み専用で読み込み（データがBIP形式の場合）、 セーブバックなし

PG.dndPG.mkr.10は、 ファイル・マネージャ内のファイルおよびフォルダ・アイコンへの選択されたテキスト、ファイル、およびバッファへのドロップを示します。

### ファイル・マネージャのドロップ先

`ドロップ先` | `選択されたテ キスト` | `ファイル` | `バッファ`
ファイル・アイコン | ターゲット・ファイルとドロップされたテキストに対してドロップ・アクションを呼び出す（ファイルがテキストのドロップを受け入れ、ドロップされたテキストが適切な形式の場合）、 セーブバックなし/コピーなし。 | ターゲット・ファイルとドロップされたファイルに対してドロッ プ・アクションを呼び出す（ファイルがファイルのドロップを受け入れ、ドロップされた ファイルが適切な形式の場合）、 セーブバックあり。 | ターゲット・ファイルとドロップされたデータ に対してドロップ・アク ションを呼び出す（ファイルがデータのドロップを受け入れ、ドロップされたデータ が適切な形式の場合）、 セーブバックなし/コピーなし。
フォルダ・アイコン | テキストをフォルダ内の新しいファイルに「名称未設定」という名前で挿入する。 | ファイルをフォルダにコピー/移動する。 | データをフォルダ内の新しいファイルに指定された名前（指定された場合）で挿入する。名前が指定されなかった場合には、「名称未設定」という名前で 挿入する。
アクション・アイコン | テキストに対してアクションを呼び出す（適切な形式であり、テキストのドロップを受け入れる場合）。 セーブバックなし。 | ファイルに対してアクションを呼び出す（適切な形式であり、ファイルの ドロップを受け入れる場合）。 セーブバックあり。 | データに対してアクションを呼び出す（適切な形式であり、データの ドロップを受け入れる場合）。 セーブバックなし。
メール・コンテナ・アイコン | メールボックスに追加する（テキストがメール形式の場合）。 | メールボックスに追加する（ファイルがメール形式の場合）。 | メールボックスに追加する（データがメール形式の場合）。

PG.dndPG.mkr.11は、フロントパネルのアクション・アイコンへの選択されたテキスト、ファイル、およびバッファへのドロップを示します。

### フロントパネルのドロップ先

`ドロップ先` | `選択されたテキスト` | `ファイル` | `バッファ`
テキスト・エディタ | 読み専用で読み込む。 セーブバックなし。 | 読み込む。セーブバックあり。 | 読み専用で読み込む。 セーブバックなし。
カレンダ | アポイントをスケジュールする（テキストがアポイント形式の場合）。 | アポイントをスケジュールする（ファイルがアポイント形式の場合）。 | アポイントをスケジュールする（データがアポイント形式の場合）。
メール | テキストを接続して、メッセージを作成する。 | ファイルを接続して、メッセージを作成する。 | データを接続して、メッセージを作成する。
プリンタ | テキストを印刷する （印刷方法がテキストに対して有効な場合）。 | ファイルの内容を印刷する （印刷方法がファイル形式に対して有効な場合）。 | データを印刷する （印刷方法がデータの形式に対して有効な場合）。
ごみ箱 | N/A | ファイルをごみ箱に移動する。 | N/A
サブパネル：アイコンのインストール | N/A | アイコンをインストールする。 | N/A
サブパネル：アクション | ファイル・マネージャと同じ | ファイル・マネージャと同じ | ファイル・マネージャと同じ
サブパネル：実行形式 | ファイル・マネージャと同じ | ファイル・マネージャと同じ | ファイル・マネージャと同じ

ユーザに対するドラッグ＆ドロップの表示方法の詳細とガイドラインについては、 CDE/Motif スタイルガイドおよび認証チェックリストを参照してください。

## ドラッグ＆ドロップ簡易API

共通デスクトップ環境は、デスクトップ内の一貫性と相互運用を促進し、開発者による ドラッグ＆ドロップの実現を容易にするために、ドラッグ＆ドロップ簡易APIを提供します。

ドラッグ＆ドロップのための既存のMotifのAPIは、トランザクションの中の転送元と転送先アプリケーションの連絡を達成するための合理的な機能を提供します。 データ転送のためのフレームワークを提供しますが、 実際のデータ転送の詳細はアプリケーションに依存します。 デスクトップ内のアプリケーション間の真の一貫性と相互運用のためには、 すべてのアプリケーションが同じ データ転送プロトコルを使わなければなりません。 共通デスクトップ環境のドラッグ＆ドロップ簡易 APIは、共通のデータ転送ルーチンを提供します。

### 開発者が簡単に使用できる

ドラッグ＆ドロップのための既存のMotifのAPIは非常に柔軟性がありますが、 その分、未熟な開発者にとっては使いにくい点もあります。 共通デスクトップ環境のドラッグ＆ドロップ簡易APIは、次のサービスを提供する簡易関数を備えることによって、より簡単で使いやすいAPIになっています。

- ドラッグ・アイコンの構成と外観を管理します。 Motifのドラッグ・アイコンを構成するデフォルトのソース、状態、及び操作アイコンのグラフィックが用意されています。 これらのアイコンの組み合わせによって、ドラッグされているデータの型をチェックします。

- ドロップのアニメーションを可能にします。 ドロップが完了したときに呼び出されるアニメーション・プロシージャを定義することができます。

- テキスト、 ファイル、及びバッファ転送のためのX ウィンドウ・システムの標準セレクション・ターゲットを使用して、データ転送を提供します。 このデータ転送は、標準のターゲットを直接使用する他のアプリケーションとの相互運用を可能にします。

- 二重登録を提供します。 テキスト・ウイジェットをテキスト以外のデータのためのドロップ領域として登録でき、その場合でも、テキストのドロップを受け入れる機能には変わりません。

### ポリシーの確立

ドラッグ＆ドロップAPIは、次の3つの分野のポリシーを確立します。

- 共通ターゲット。使用可能な場合には、クライアント間通信規約マニュアル (ICCCM)によって定義された既存のセレクション・ ターゲットが使われます。

- データ転送プロトコル。 APIは、データ転送の詳細を隠し、 データを単純なデータ構造体の形で アプリケーションに提示します。

- デフォルトのドラッグ・アイコン。デフォルトのドラッグ・アイコンは、それらを受け入れることができるアプリケーションのために用意されています。

### 共通の機能性の提供

ドラッグ＆ドロップAPIは、 次の分野での共通の機能性を提供します。

- テキスト、ファイル名、およびバッファとしてのデータ転送をサポートします。

- データ転送フレームワークによって、新しい組み込みプロトコルの追加をサポートします。

### 既存のMotif APIの応用

ドラッグ＆ドロップのためのAPIは、新しいドラッグ＆ドロップ・サブシステムを作るのではなく、既存のMotif APIを使用しています。 また、共通のデータ転送プロトコルが選ばれているので、使用可能な場合には、 アプリケーションは新しいAPIをグローバルに使用しなくても、選択プロトコル・レベルで相互運用できます。

テキストとファイルの転送は、既存のプロトコルを使用します。 バッファ転送は、新しいプロトコルを使用します。

## ドラッグ＆ドロップ処理

PG.dndPG.mkr.15に、基本的なドラッグ＆ドロップ処理の実行例を示します。 破線のボックスは、基本的な処理を示します。 実線のボックスは、オプションの変化と操作を示します。

### 基本的なドラッグ＆ドロップ処理

### オプションのドラッグ＆ドロップの変化と操作

PG.dndPG.mkr.16は、オプションのドラッグ＆ドロップの変化と操作を示します。

## 統合アクション・プラン

この節では、アプリケーションと 共通デスクトップ環境 1.0のドラッグ＆ドロップとの統合のためのアクション・プランを提案します。

### ドラッグ＆ドロップAPIとサンプル・コードの検討

この章の説明とCommon Desktop Environment: Programmer's Referenceの関連する節の説明を読んで、 ドラッグ＆ドロップAPIを理解してください。 APIの基本的な理解ができたら、ドラッグ＆ドロップのデモ・プログラム`/usr/dt/examples/dtdnd`のソースコードを見てください。 このコードは、さまざまなAPIの使い方の例を提供しています。 これらの例によって、アプリケーションで ドラッグ＆ドロップをサポートするために書かなければならないコードの性質と量が、理解できます。 アクションとデータ型APIの理解にも役立ちます。

### 可能なドロップ領域についてのアプリケーションの検討

アプリケーションがドラッグ＆ドロップの処理を通して受け入れるデータの型を決めます。 たとえば、ビットマップ・エディタを作成する場合には、ファイルのドロップをサポートしたいことがあります。 アプリケーションにドロップできるデータの型を決めたら、 ドロップ領域になるウィジェットを決めます。 ビットマップ・エディタの例の場合には、ビットマップ編集領域を、アプリケーション上でファイルをドロップできる唯一の場所として決定できます。 この場合、`DtDndDropRegister()`を使用して、この領域を表すウィジェット を登録し、適切なコールバックを提供します。

ファイル名のドロップの処理は最も簡単なので、ファイル名のドロップの実現から始めてください。 この手法をマスターすると、簡単にテキストとバッファのドロップの実現に進むことができます。

### 可能なドラッグ・ソースに関するアプリケーションの検討

アプリケーションがドラッグ＆ドロップの処理の転送元として許可するデータの型を決めます。 ビットマップ・エディタの例の場合、カット＆ペーストのアクセラレータとして、現在のビットマップ選択を含んでいるビットマップ・エディタをドラッグ・ソースにしたいことがあります。 アプリケーションからドラッグできるデータ型を決めたら、ドラッグ・ソースになるウィジェットを決めます。 ビットマップ・エディタの例の場合、強調表示されているビットマップ選択を含んでいるビットマップ編集領域がドラッグ・ソースの役目を果たすと決定できます。 この場合、この領域を表しているウィジェットがドラッグ・ソースになります。

アプリケーションに最もふさわしい、または特有のバッファのドラッグの実現から始めてください。 また、アプリケーションの複数起動間の簡単なデータ転送を可能にするために、アプリケーションにバッファをドロップする機能を追加する必要がある場合もあります。

## APIの概要

この節では、ドラッグ＆ドロップのアプリケーション・プログラム・インタフェース(API)の概要を説明します。

### DtSvcライブラリとヘッダ・ファイル

ドラッグ＆ドロップ機能は、デスクトップ・サービス・ライブラリ`DtSvc`で実現されます。 ドラッグ＆ドロップAPIにアクセスするには、ヘッダ・ファイル`<Dt/Dnd.h>`を 組み込み、`-lDtSvc`をつけてリンクします。

### 関数

APIには４つの関数呼び出しがあり、ヘッダ・ファイル`Dnd.h`の中で 宣言されています。 これらの関数について、以下の段落で概説します。 詳しくは、後の節で説明します。

- `DtDndDragStart()`は、ユーザ・アクションに応答して、ドラッグを開始します。

- `DtDndCreateSourceIcon()`は、`DtDndDragStart()`で使用するソース・アイコンを作成します。

- `DtDndDropRegister()`は、ウィジェットをドロップ領域として登録します。 ドロップ領域の登録は、通常はウィジェットが作成された直後に行われますが、いつ行ってもかまいません。

- `DtDndDropUnregister()`は、以前に登録したウィジェトの登録を解除します。 ドロップ領域は、通常は破壊される直前に登録解除されますが、登録後であればいつ登録解除してもかまいません。

### DtDndContext構造体

データ転送を処理するためには、`DtDndContext`データ構造体を使用します。 この構造体には、転送プロトコルのためのフィールド、転送される項目の数、および転送されるデータ項目の配列が入ります。 この構造体の構文の詳細については、`DtDndDragStart`(3)および`DtDndDropRegister`(3)を参照してください。

### プロトコル

プロトコルは、転送データの型をAPIに知らせるために使われます。 定義済みプロトコルを PG.dndPG.mkr.19に示します。

### 定義済みプロトコル

`プロトコル` | `説明`
`DtDND_TEXT_TRANSFER` | テキスト転送。コンパウンド・テキスト。（Motifは、テキスト転送のためにコンパウンド・テキスト・ターゲットを使用します。）
`DtDND_FILENAME_TRANSFER` | ファイル名転送。
`DtDND_BUFFER_TRANSFER` | メモリ・バッファ。

### 操作

PG.dndPG.mkr.20に示すように、ドラッグ・ソースとドロップ領域は３つの方法のうち の１つで、データを転送することができます。

### データ転送操作

`操作` | `説明`
`XmDROP_MOVE` | データを移動します。（コピーしてから削除します。）
`XmDROP_COPY` | データをコピーします。
`XmDROP_LINK` | データへのリンクを含みます。

## ドラッグ・ソースの使い方

この節では、ドラッグ・ソースの使い方を説明します。

### ドラッグの開始

ドラッグは、２つの方法のどちらかで開始されます。 １つは、ユーザは`Btransfer`（中央マウス・ボタン）を押すことで、ドラッグを開始できます。 ボタンが押されるとすぐに、ドラッグが開始されます。 もう１つは、ユーザは`Bselect`（左マウス・ボタン）を押しながらカーソルを動かすことによって、 ドラッグを開始できます。 ユーザがマウスを特定の距離だけ動かすと、ドラッグが開始されます。 この距離をドラッグしきい値といい、ピクセル単位で示されます。`Bselect`のデフォルトのドラッグしきい値は、 １０ピクセルです。`Btransfer`の ドラッグしきい値は０です。 ドラッグしきい値がないので、ポインタが動かされるとすぐに、ドラッグが開始されます。 Motifスクロール・テキスト・リストおよびテキスト・ウィジェットは、`Btransfer`と`Bselect`によって、 テキスト・ドラッグするための ドラッグ・ソースとして自動的に登録されます。

### リストまたはアイコンからのドラッグ

ドラッグ・ソースとして使用できる２つの一般的なインタフェース・オブジェクトがあります。 すなわち、リストとアイコンです。 Motifリスト・ウィジェットは、自動的にテキスト・ドラッグの転送元を示します。 他の種類のドラッグが必要な場合、それはデフォルトのウィジェット変換を新しい`Bntl`と`Btn2`変換で 無効にすることによって行われます。 Motifには、アイコン・ウィジェットはありませんが、 描画領域がアイコンのコンテナとしてよく使われます。 この場合、ドラッグを開始するために`Btn1Motion`の イベント・ハンドラが使われます。 詳しいコーディング例については、`/usr/dt/examples/dtdnd`のサンプル・コードを参照してください。

### ドラッグしきい値

`Bselect`を使用してドラッグを開始するときには、 ウィジェット・イベント・ハンドラまたは変換手順は、ドラッグを開始する前に １０ピクセルのドラッグしきい値を適用しなければなりません。`Btransfer`には、 しきい値はないので、直ちにドッラグが開始されます。

### BtransferまたはBadjust

スタイル・マネージャのマウス（ボタン）の使い方として`Btn2`（中央マウス・ボタン）が、 `Btransfer`として機能するか、または`Badjus t`として機能するかを制御する設定があります。 この設定は、リソース名`enableBtn1Transfer`として格納されます。 １の設定は、`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
    DtDndDragStart(
     Widget    dragSource,
     XEvent     *event,
     DtDndProtocol    protocol,
     Cardinal    numItems,
     unsigned char    operations,
     XtCallbackList  convertCallback,
     XtCallbackList  dragFinishCallback
     ArgList    argList,
     Cardinal    argCount)

Widget dragSource

ドラッグを始めたイベントを受け取るウィジェット。

XEvent *event

ドラッグ開始の契機となったボタン・プレスまたはボタン・モーションのイベント。

DtDndProtocol protocol

データ転送のために使用するプロトコル。 プロトコルは、次の１つにすることができます。

`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*) callData;
     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の中で指定された操作に基づいて、 データ転送を続けます。 たとえば、ファイルのコピーを処理している場合には、データ構造からファイル名を検索し、 ファイルを開き、その内容をコピーします。 ドロップ領域が複数のデータ型をサポートしている場合には、 各データ型の転送を適切にサポートする必要があります。

次に、テキストとファイル名のデータ型のコピーをサポートするドロップ領域を描画するための簡単な転送コールバックの例を示します。

    void
     TransferCallback(
     Widget widget,
     XtPointer clientData,
     XtPointer callData)
    {
        DtDndTransferCallbackStruct *transferInfo =
      (DtDndTransferCallbackStruct*) callData;
        int ii;
        DtDndcontext * dropData = transferInfo->dropData;
      return;
        switch dropData->protocol {
     case DtDND_FILENAME_TRANSFER:
      for (ii=0; ii < dropData->numItems; ii++) {
       drawTheString(dropData->data, strings[ii]);
      }
      break;
     case DtDND_TEXT_TRANSFER:
      for (ii=0; ii<dropData->numItems; ii++){
      drawTheFile(dropData->data.files[ii]);
      }
            break;
     default:
      transferInfo->status = DtDND_FAILURE;
        }
    }

### データ型の使い方

バッファのドロップを受け入れるアプリケーションでは、 ドロップされたデータをその型に基づいた異なる方法で処理したいことがあります。 データ型を判断するには、データ型APIを使います。 重要なデータ型関数呼び出しは、`DtDtsBufferToDataType()`と`DtDtsBufferToAttributeValue()`です。 前者はデータのデータ属性を返し、後者は指定されたデータ属性の値を返します。 ドラッグ＆ドロップに役立つ属性を、 PG.dndPG.mkr.23に示します。

### データ型属性

`属性` | `説明`
`ICON` | このデータに対して使用するアイコンのパス。
`MEDIA` | このデータに対するメッセージ提携メディア名。

詳しくは、 PG.datat.mkr.1を参照してください。