はじめに
ツリービューを実装する時、ドラッグ&ドロップを実装したいと思ったことはありませんか?
今回は、VSCodeの拡張機能にて、ツリービューを実装する際に、要素間のドラッグ&ドロップを実現する方法について紹介します。
TreeDragAndDropControllerを実装する
VSCodeのツリービューにて、ドラッグ&ドロップを実装するには、TreeDataProviderを継承したクラスにて、新たにTreeDragAndDropControllerを継承することで実現させます。
export class SampleTreeProvider
implements
vscode.TreeDataProvider<SampleTreeItem>,
vscode.TreeDragAndDropController<SampleTreeItem>
{
// 実際のコードがここに記述されます。
}
handleDrago()メソッドを実装する
ドラッグの動作を実現するためには、handleDrag()を実装します。
handleDrag(
source: readonly SampleTreeItem[],
dataTransfer: vscode.DataTransfer,
token: vscode.CancellationToken
): void | Thenable<void> {
// 実際のコードがここに記述されます
}
handleDrag()は、3つの引数を受け取ります。
最初の引数は、sourceです。
sourceは、ドラッグされた要素の配列を表します。
次の引数は、dataTransferです。dataTransferは、ドラッグされた要素をドラッグイベントに渡すために使用されます。
最後の引数は、tokenです。この引数を使うことで、ドラッグイベントがキャンセルされたかどうかを確認することができます。
handleDrop()メソッドを実装する
ドロップの動作を実現するためには、handleDrop()を実装します。
handleDrop(
target: SampleTreeItem | undefined,
dataTransfer: vscode.DataTransfer,
token: vscode.CancellationToken
): void | Thenable<void> {
// 実際のコードがここに記述されます。
}
handleDrop()は、3つの引数を受け取ります。
最初の引数は、targetです。
targetは、ドロップ先の要素を表します。
次の引数は、dataTransferです。この引数を通して、handleDrag()にて渡された要素を取得することができます。
最後の引数は、tokenです。この引数を使うことで、ドラッグイベントがキャンセルされたかどうかを確認することができます。
tokenの使い方
tokenを使って、ドラッグイベントがキャンセルされたかどうかを確認するには、次のようにします。
if (token.isCancellationRequested) {
return;
}
dataTransferの使い方
dataTransferを使って、ドラッグイベントに要素を渡すには、次のようにします。
dataTransfer.set(
"application/vnd.code.tree.sampleView",
new vscode.DataTransferItem(source[0])
);
また、上記で渡された要素をhandleDrop()内で受け取るには、次のようにします。
const transferItem = dataTransfer.get(
"application/vnd.code.tree.sampleView"
);
取得されたtransferItemは、SampleTreeItemまたはundefinedの可能性があるので、使用する前に必ずチェックします。
if (!transferItem) {
return;
}
dropMimeTypesとdragMimeTypes
TreeDragAndDropControllerを実装する場合、dropMimeTypesとdragMimeTypesプロパティを実装しなければなりません。
dropMimeTypes = ['application/vnd.code.tree.sampleView'];
dragMimeTypes = ['text/uri-list'];
dragMimeTypesについて
dragMimeTypesに指定されるMIMEタイプは、handleDrag()メソッド内で、dataTransferに対して指定することができるMIMEタイプを表します。
'application/vnd.code.tree.ツリービューのID'は自動的に追加されるので、ここでは任意で'text/uri-list'のみを追加しています。
この、text/uri-listというMIMEタイプは、一般的にドラッグ&ドロップの操作を実装する際に使用されます。ファイルやフォルダなどのオブジェクトの参照先を表すために使われるそうです。
dropMimeTypesについて
dropMimeTypesに指定されるMIMEタイプは、handleDrop()メソッドにて受け入れることができるMIMEタイプを表します。
なので、特定のツリーからのドロップをサポートするには、そのツリーのMIMEタイプを指定する必要があります。
例えば、handleDrag()内にて、dataTransferに対して'application/vnd.code.tree.sampleView'が指定されている場合は、そのMIMEタイプを指定しましょう。
dataTransfer.set(
"application/vnd.code.tree.sampleView",
new vscode.DataTransferItem(source[0])
);
ドキュメントでも、application/vnd.code.tree.ツリービューのIDを指定することが推奨されています。
ツリービューでドラッグ&ドロップを有効にする
ツリービューを作成するには、createTreeView()の呼び出しが欠かせません。
createTreeView()を呼び出す際、dragAndDropControllerフィールドの値として、TreeDragAndDropControllerを継承したクラスのインスタンスを指定します。
ツリービューにて、要素のドラッグ&ドロップができるようになります。treeDataProviderフィールドに指定するだけでは、この機能が有効にならないので、忘れずに設定を行いましょう。
vscode.window.createTreeView("sampleView", {
treeDataProvider: sampleTreeProvider,
showCollapseAll: true,
canSelectMany: false,
dragAndDropController: sampleTreeProvider,
})
まとめ
実際に、handleDrag()やhandleDrop()を実装する際には、渡したり、受け取ったりしたデータをもとに、TreeItem間の親子関係を調整する必要があります。
それらの具体的な方法については、いずれまたどこかで解説できると幸いです。
参考にした記事