diff --git a/README.md b/README.md
index c31ceec..1afbf90 100644
--- a/README.md
+++ b/README.md
@@ -174,6 +174,18 @@ Note, you can right-click on a bunch of the rgthree-comfy nodes and select `đ
>
+## Power Primitive
+> A single node that can output primitives (STRING, INT, FLOAT, BOOL). If connecting an input, it will cast/convert the primitive input to the desired output.
+>
+> âšī¸ More Information
+>
+> - You can hide the type selector input from the right-click menu or properties.
+> - You can also fast-switch the output type from the right-click menu as well.
+>
+>
+
+
+
## Fast Groups Muter
> The Fast Groups Muter is an input-less node that automatically collects all groups in your current workflow and allows you to quickly mute and unmute all nodes within the group.
>
diff --git a/__init__.py b/__init__.py
index ef556fe..1675983 100644
--- a/__init__.py
+++ b/__init__.py
@@ -39,6 +39,7 @@ from .py.context_merge import RgthreeContextMerge
from .py.context_merge_big import RgthreeContextMergeBig
from .py.image_comparer import RgthreeImageComparer
from .py.power_lora_loader import RgthreePowerLoraLoader
+from .py.power_primitive import RgthreePowerPrimitive
NODE_CLASS_MAPPINGS = {
RgthreeBigContext.NAME: RgthreeBigContext,
@@ -61,6 +62,7 @@ NODE_CLASS_MAPPINGS = {
RgthreeAnySwitch.NAME: RgthreeAnySwitch,
RgthreeImageComparer.NAME: RgthreeImageComparer,
RgthreePowerLoraLoader.NAME: RgthreePowerLoraLoader,
+ RgthreePowerPrimitive.NAME: RgthreePowerPrimitive,
}
if get_config_value('unreleased.dynamic_context.enabled') is True:
diff --git a/src_web/comfyui/base_node.ts b/src_web/comfyui/base_node.ts
index 10ad291..83ff8a3 100644
--- a/src_web/comfyui/base_node.ts
+++ b/src_web/comfyui/base_node.ts
@@ -19,7 +19,7 @@ import {
importIndividualNodesInnerOnDragDrop,
importIndividualNodesInnerOnDragOver,
} from "./feature_import_individual_nodes.js";
-import {defineProperty} from "rgthree/common/shared_utils.js";
+import {defineProperty, moveArrayItem} from "rgthree/common/shared_utils.js";
/**
* A base node with standard methods, directly extending the LGraphNode.
@@ -185,13 +185,30 @@ export abstract class RgthreeBaseNode extends LGraphNode {
if (!this.widgets) {
return;
}
- if (typeof widgetOrSlot === "number") {
- this.widgets.splice(widgetOrSlot, 1);
- } else if (widgetOrSlot) {
- const index = this.widgets.indexOf(widgetOrSlot);
+ const widget = typeof widgetOrSlot === "number" ? this.widgets[widgetOrSlot] : widgetOrSlot;
+ if (widget) {
+ const index = this.widgets.indexOf(widget);
if (index > -1) {
this.widgets.splice(index, 1);
}
+ widget.onRemove?.();
+ }
+ }
+
+ /**
+ * Replaces an existing widget.
+ */
+ replaceWidget(widgetOrSlot: IWidget | number | undefined, newWidget: IWidget) {
+ let index = null;
+ if (widgetOrSlot) {
+ index = typeof widgetOrSlot === 'number' ? widgetOrSlot : this.widgets.indexOf(widgetOrSlot);
+ this.removeWidget(index);
+ }
+ index = index != null ? index : this.widgets.length - 1;
+ if (this.widgets.includes(newWidget)) {
+ moveArrayItem(this.widgets, newWidget, index);
+ } else {
+ this.widgets.splice(index, 0, newWidget);
}
}
diff --git a/src_web/comfyui/constants.ts b/src_web/comfyui/constants.ts
index 51bbace..0b68ab4 100644
--- a/src_web/comfyui/constants.ts
+++ b/src_web/comfyui/constants.ts
@@ -27,6 +27,7 @@ export const NodeTypesString = {
FAST_GROUPS_BYPASSER: addRgthree("Fast Groups Bypasser"),
FAST_ACTIONS_BUTTON: addRgthree("Fast Actions Button"),
LABEL: addRgthree("Label"),
+ POWER_PRIMITIVE: addRgthree("Power Primitive"),
POWER_PROMPT: addRgthree("Power Prompt"),
POWER_PROMPT_SIMPLE: addRgthree("Power Prompt - Simple"),
SDXL_EMPTY_LATENT_IMAGE: addRgthree("SDXL Empty Latent Image"),
diff --git a/web/comfyui/base_node.js b/web/comfyui/base_node.js
index e0a6b9a..8f1cccc 100644
--- a/web/comfyui/base_node.js
+++ b/web/comfyui/base_node.js
@@ -4,7 +4,7 @@ import { LogLevel, rgthree } from "./rgthree.js";
import { addHelpMenuItem } from "./utils.js";
import { RgthreeHelpDialog } from "../../rgthree/common/dialog.js";
import { importIndividualNodesInnerOnDragDrop, importIndividualNodesInnerOnDragOver, } from "./feature_import_individual_nodes.js";
-import { defineProperty } from "../../rgthree/common/shared_utils.js";
+import { defineProperty, moveArrayItem } from "../../rgthree/common/shared_utils.js";
export class RgthreeBaseNode extends LGraphNode {
constructor(title = RgthreeBaseNode.title, skipOnConstructedCall = true) {
super(title);
@@ -93,17 +93,31 @@ export class RgthreeBaseNode extends LGraphNode {
action;
}
removeWidget(widgetOrSlot) {
+ var _a;
if (!this.widgets) {
return;
}
- if (typeof widgetOrSlot === "number") {
- this.widgets.splice(widgetOrSlot, 1);
- }
- else if (widgetOrSlot) {
- const index = this.widgets.indexOf(widgetOrSlot);
+ const widget = typeof widgetOrSlot === "number" ? this.widgets[widgetOrSlot] : widgetOrSlot;
+ if (widget) {
+ const index = this.widgets.indexOf(widget);
if (index > -1) {
this.widgets.splice(index, 1);
}
+ (_a = widget.onRemove) === null || _a === void 0 ? void 0 : _a.call(widget);
+ }
+ }
+ replaceWidget(widgetOrSlot, newWidget) {
+ let index = null;
+ if (widgetOrSlot) {
+ index = typeof widgetOrSlot === 'number' ? widgetOrSlot : this.widgets.indexOf(widgetOrSlot);
+ this.removeWidget(index);
+ }
+ index = index != null ? index : this.widgets.length - 1;
+ if (this.widgets.includes(newWidget)) {
+ moveArrayItem(this.widgets, newWidget, index);
+ }
+ else {
+ this.widgets.splice(index, 0, newWidget);
}
}
defaultGetSlotMenuOptions(slot) {
diff --git a/web/comfyui/constants.js b/web/comfyui/constants.js
index cc506af..666f5d4 100644
--- a/web/comfyui/constants.js
+++ b/web/comfyui/constants.js
@@ -24,6 +24,7 @@ export const NodeTypesString = {
FAST_GROUPS_BYPASSER: addRgthree("Fast Groups Bypasser"),
FAST_ACTIONS_BUTTON: addRgthree("Fast Actions Button"),
LABEL: addRgthree("Label"),
+ POWER_PRIMITIVE: addRgthree("Power Primitive"),
POWER_PROMPT: addRgthree("Power Prompt"),
POWER_PROMPT_SIMPLE: addRgthree("Power Prompt - Simple"),
SDXL_EMPTY_LATENT_IMAGE: addRgthree("SDXL Empty Latent Image"),