6.5 KiB
title
| title |
|---|
| Selection Toolbox |
The Selection Toolbox API allows extensions to add custom action buttons that appear when nodes are selected on the canvas. This provides quick access to context-sensitive commands for selected items (nodes, groups, etc.).
Basic Usage
To add commands to the selection toolbox, your extension needs to:
- Define commands with the standard command interface
- Implement the
getSelectionToolboxCommandsmethod to specify which commands appear in the toolbox
Note: The getSelectionToolboxCommands method is called for each item in the selection set whenever a new selection is made.
app.registerExtension({
name: "MyExtension",
commands: [
{
id: "my-extension.duplicate-special",
label: "Duplicate Special",
icon: "pi pi-copy",
function: (selectedItem) => {
// Your command logic here
console.log("Duplicating selected nodes with special behavior");
}
}
],
getSelectionToolboxCommands: (selectedItem) => {
// Return array of command IDs to show in the toolbox
return ["my-extension.duplicate-special"];
}
});
Command Definition
Commands for the selection toolbox use the standard ComfyUI command interface:
{
id: string, // Unique identifier for the command
label: string, // Display text for the button tooltip
icon?: string, // Icon class for the button (optional)
function: (selectedItem) => void // Function executed when clicked
}
The function receives the selected item(s) as a parameter, allowing you to perform actions on the current selection.
Icon Options
Selection toolbox buttons support the same icon libraries as other UI elements:
- PrimeVue icons:
pi pi-[icon-name](e.g.,pi pi-star) - Material Design icons:
mdi mdi-[icon-name](e.g.,mdi mdi-content-copy)
Dynamic Command Visibility
The getSelectionToolboxCommands method is called each time the selection changes, allowing you to show different commands based on what's selected:
app.registerExtension({
name: "ContextualCommands",
commands: [
{
id: "my-ext.align-nodes",
label: "Align Nodes",
icon: "pi pi-align-left",
function: () => {
// Align multiple nodes
}
},
{
id: "my-ext.configure-single",
label: "Configure",
icon: "pi pi-cog",
function: () => {
// Configure single node
}
}
],
getSelectionToolboxCommands: (selectedItem) => {
const selectedItems = app.canvas.selectedItems;
const itemCount = selectedItems ? selectedItems.size : 0;
if (itemCount > 1) {
// Show alignment command for multiple items
return ["my-ext.align-nodes"];
} else if (itemCount === 1) {
// Show configuration for single item
return ["my-ext.configure-single"];
}
return [];
}
});
Working with Selected Items
Access information about selected items through the app's canvas object. The selectedItems property is a Set that includes nodes, groups, and other canvas elements:
app.registerExtension({
name: "SelectionInfo",
commands: [
{
id: "my-ext.show-info",
label: "Show Selection Info",
icon: "pi pi-info-circle",
function: () => {
const selectedItems = app.canvas.selectedItems;
if (selectedItems && selectedItems.size > 0) {
console.log(`Selected ${selectedItems.size} items`);
// Iterate through selected items
selectedItems.forEach(item => {
if (item.type) {
console.log(`Item: ${item.type} (ID: ${item.id})`);
}
});
}
}
}
],
getSelectionToolboxCommands: () => ["my-ext.show-info"]
});
Complete Example
Here's a simple example showing various selection toolbox features:
app.registerExtension({
name: "SelectionTools",
commands: [
{
id: "selection-tools.count",
label: "Count Selection",
icon: "pi pi-hashtag",
function: () => {
const count = app.canvas.selectedItems?.size || 0;
app.extensionManager.toast.add({
severity: "info",
summary: "Selection Count",
detail: `You have ${count} item${count !== 1 ? 's' : ''} selected`,
life: 3000
});
}
},
{
id: "selection-tools.copy-ids",
label: "Copy IDs",
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: "Copied",
detail: `Copied ${ids.length} IDs to clipboard`,
life: 2000
});
}
}
},
{
id: "selection-tools.log-types",
label: "Log Types",
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("Selection types:", 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"];
// Only show copy command if items have IDs
const hasIds = Array.from(selectedItems).some(item => item.id !== undefined);
if (hasIds) {
commands.push("selection-tools.copy-ids");
}
return commands;
}
});
Notes
- The selection toolbox must be enabled in settings:
Comfy.Canvas.SelectionToolbox - Commands must be defined in the
commandsarray before being referenced ingetSelectionToolboxCommands - The toolbox automatically updates when the selection changes
- The
getSelectionToolboxCommandsmethod is called for each item in the selection set whenever a new selection is made - Use
app.canvas.selectedItems(a Set) to access all selected items including nodes, groups, and other canvas elements - For backward compatibility,
app.canvas.selected_nodesstill exists but only contains nodes