はじめに
ツリービューを実装する時、ドラッグ&ドロップを実装したいと思ったことはありませんか?
今回は、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間の親子関係を調整する必要があります。
それらの具体的な方法については、いずれまたどこかで解説できると幸いです。
参考にした記事