> ## Documentation Index
> Fetch the complete documentation index at: https://dripart-docs-recommend-assets-api.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# 選択ツールボックス

選択ツールボックス API により、拡張機能はキャンバス上でノードが選択された際に表示されるカスタムアクションボタンを追加できます。これにより、選択されたアイテム（ノード、グループなど）に対する文脈依存のコマンドにすばやくアクセスできます。

## 基本的な使い方

選択ツールボックスにコマンドを追加するには、拡張機能は以下を行う必要があります：

1. 標準の [コマンドインターフェース](https://docs.comfy.org/custom-nodes/js/javascript_commands_keybindings) を使用してコマンドを定義する
2. ツールボックスに表示されるコマンドを指定するために `getSelectionToolboxCommands` メソッドを実装する

注：`getSelectionToolboxCommands` メソッドは、新しい選択が行われるたびに、選択セット内の各アイテムに対して呼び出されます。

```javascript theme={null}
app.registerExtension({
  name: "MyExtension",
  commands: [
    {
      id: "my-extension.duplicate-special",
      label: "特殊複製",
      icon: "pi pi-copy",
      function: (selectedItem) => {
        // ここにコマンドのロジックを記述
        console.log("特殊な動作で選択されたノードを複製中");
      }
    }
  ],
  getSelectionToolboxCommands: (selectedItem) => {
    // ツールボックスに表示するコマンド ID の配列を返す
    return ["my-extension.duplicate-special"];
  }
});
```

## コマンド定義

選択ツールボックスのコマンドは、標準の ComfyUI コマンドインターフェースを使用します：

```javascript theme={null}
{
  id: string,          // コマンドの一意の識別子
  label: string,       // ボタンのツールチップに表示されるテキスト
  icon?: string,       // ボタンのアイコンクラス（オプション）
  function: (selectedItem) => void  // クリック時に実行される関数
}
```

`function` は選択されたアイテムをパラメータとして受け取り、現在の選択に対してアクションを実行できます。

## アイコンオプション

選択ツールボックスのボタンは、他の UI 要素と同じアイコンライブラリをサポートします：

* PrimeVue アイコン：`pi pi-[icon-name]`（例：`pi pi-star`）
* Material Design アイコン：`mdi mdi-[icon-name]`（例：`mdi mdi-content-copy`）

## 動的なコマンドの表示

`getSelectionToolboxCommands` メソッドは選択が変更されるたびに呼び出され、選択内容に基づいて異なるコマンドを表示できます：

```javascript theme={null}
app.registerExtension({
  name: "ContextualCommands",
  commands: [
    {
      id: "my-ext.align-nodes",
      label: "ノードを整列",
      icon: "pi pi-align-left",
      function: () => {
        // 複数のノードを整列
      }
    },
    {
      id: "my-ext.configure-single",
      label: "設定",
      icon: "pi pi-cog",
      function: () => {
        // 単一のノードを設定
      }
    }
  ],
  getSelectionToolboxCommands: (selectedItem) => {
    const selectedItems = app.canvas.selectedItems;
    const itemCount = selectedItems ? selectedItems.size : 0;
    
    if (itemCount > 1) {
      // 複数のアイテムに対して整列コマンドを表示
      return ["my-ext.align-nodes"];
    } else if (itemCount === 1) {
      // 単一のアイテムに対して設定を表示
      return ["my-ext.configure-single"];
    }
    
    return [];
  }
});
```

## 選択されたアイテムの操作

アプリのキャンバスオブジェクトを通じて、選択されたアイテムに関する情報にアクセスできます。`selectedItems` プロパティは、ノード、グループ、およびその他のキャンバス要素を含む Set です：

```javascript theme={null}
app.registerExtension({
  name: "SelectionInfo",
  commands: [
    {
      id: "my-ext.show-info",
      label: "選択情報を表示",
      icon: "pi pi-info-circle",
      function: () => {
        const selectedItems = app.canvas.selectedItems;
        
        if (selectedItems && selectedItems.size > 0) {
          console.log(`${selectedItems.size} 個のアイテムが選択されました`);
          
          // 選択されたアイテムを繰り返し処理
          selectedItems.forEach(item => {
            if (item.type) {
              console.log(`アイテム：${item.type} (ID: ${item.id})`);
            }
          });
        }
      }
    }
  ],
  getSelectionToolboxCommands: () => ["my-ext.show-info"]
});
```

## 完全な例

これは、さまざまな選択ツールボックス機能を示す簡単な例です：

```javascript theme={null}
app.registerExtension({
  name: "SelectionTools",
  commands: [
    {
      id: "selection-tools.count",
      label: "選択数をカウント",
      icon: "pi pi-hashtag",
      function: () => {
        const count = app.canvas.selectedItems?.size || 0;
        app.extensionManager.toast.add({
          severity: "info",
          summary: "選択数",
          detail: `${count} 個のアイテムが選択されています`,
          life: 3000
        });
      }
    },
    {
      id: "selection-tools.copy-ids",
      label: "ID をコピー",
      icon: "pi pi-copy",
      function: () => {
        const items = Array.from(app.canvas.selectedItems || []);
        const ids = items.map(item => item.id).filter(id => id !== undefined);
        
        if (ids.length > 0) {
          navigator.clipboard.writeText(ids.join(', '));
          app.extensionManager.toast.add({
            severity: "success",
            summary: "コピー済み",
            detail: `${ids.length} 個の ID をクリップボードにコピーしました`,
            life: 2000
          });
        }
      }
    },
    {
      id: "selection-tools.log-types",
      label: "タイプをログ出力",
      icon: "pi pi-info-circle",
      function: () => {
        const items = Array.from(app.canvas.selectedItems || []);
        const typeCount = {};
        
        items.forEach(item => {
          const type = item.type || 'unknown';
          typeCount[type] = (typeCount[type] || 0) + 1;
        });
        
        console.log("選択タイプ：", typeCount);
      }
    }
  ],
  
  getSelectionToolboxCommands: (selectedItem) => {
    const selectedItems = app.canvas.selectedItems;
    const itemCount = selectedItems ? selectedItems.size : 0;
    
    if (itemCount === 0) return [];
    
    const commands = ["selection-tools.count", "selection-tools.log-types"];
    
    // アイテムに ID がある場合のみコピーコマンドを表示
    const hasIds = Array.from(selectedItems).some(item => item.id !== undefined);
    if (hasIds) {
      commands.push("selection-tools.copy-ids");
    }
    
    return commands;
  }
});
```

## 注意事項

* 選択ツールボックスは設定で有効にする必要があります：`Comfy.Canvas.SelectionToolbox`
* コマンドは `getSelectionToolboxCommands` で参照される前に、`commands` 配列で定義されている必要があります
* 選択が変更されるとツールボックスは自動的に更新されます
* `getSelectionToolboxCommands` メソッドは、新しい選択が行われるたびに、選択セット内の各アイテムに対して呼び出されます
* `app.canvas.selectedItems`（Set）を使用して、ノード、グループ、およびその他のキャンバス要素を含むすべての選択されたアイテムにアクセスします
* 後方互換性のため、`app.canvas.selected_nodes` は依然存在しますが、ノードのみを含みます
