Skip to content

remove_or_add_widget

chrisgoringe edited this page Sep 30, 2023 · 1 revision

Dynamically adding and removing widgets

Adding a widget

Suppose you want to add a widget to display some text... the code will look a bit like this (assuming a context where this is the node)

import { ComfyWidgets } from "../../../scripts/widgets.js";
//...
	var w = this.widgets?.find((w) => w.name === "name_of_the_widget");  // see if it already exists
	if (w === undefined) {
		w = ComfyWidgets["STRING"](this, "name_of_the_widget", ["STRING", { multiline: true }], app).widget; // see description below
		w.inputEl.readOnly = true;            // make it read only
		w.inputEl.style.opacity = 0.6;        // any css styling you want
		w.inputEl.style.fontSize = "9pt";
	}
	w.value = "Text to display";
	this.onResize?.(this.size);                   // this will make it redraw

The main line is a call to a method in the file scripts/widgets.js, where there is

export const ComfyWidgets = {
//...
	STRING(node, inputName, inputData, app) {
// code that creates the widget as res and adds it to the node using node.addWidget or similar calls
	return res;

Take a look - it's around line 318 at time of writing.

The first thing to notice is the parameters - it takes a parent node (this in our call), an input name, inputData, and a reference to the app. The inputData is the javascript equivalent of the tuple(str, dict) that you use to define an INPUT_TYPE in python.

The other thing to notice is that what gets returned is an object which includes the widget as a .widget attribute. I haven't seen an example of what else might be included in res - in any case, our code just pulls out the .widget attribute.


Deleting a widget

Here's a function that will remove a named widget from a node if it exists:

function remove_widget(node, widget_name) {
    const w = node.widgets?.findIndex((w) => w.name === widget_name); // search for the widget name
    if (w>=0) {                           // if we find it (if not, w = -1)
        const wid = node.widgets[w];      // get the widget itself (w is the index)
        node.widgets.splice(w,1);         // remove it
        wid?.onRemove();                  // let the widget do any cleaning up
        node.size = node.computeSize();   // work out what size the node should be now
        node.setDirtyCanvas(true, true);  // mark for redrawing
    }
}

The last line there is an alternative (probably better) way of causing a node to be drawn - we mark its canvas as 'dirty' (the two parameters are foreground and background)

Clone this wiki locally