From 7429161b57355ba95b8d9803f3d21d00a0abccee Mon Sep 17 00:00:00 2001 From: Julien Lubimiv Date: Mon, 27 Mar 2023 18:12:13 -0400 Subject: [PATCH 1/4] Seed controls added to Ksamplers --- web/extensions/core/widgetInputs.js | 8 ++-- web/scripts/widgets.js | 67 +++++++++++++++++++---------- 2 files changed, 49 insertions(+), 26 deletions(-) diff --git a/web/extensions/core/widgetInputs.js b/web/extensions/core/widgetInputs.js index ff9227d28..d571f00a9 100644 --- a/web/extensions/core/widgetInputs.js +++ b/web/extensions/core/widgetInputs.js @@ -1,4 +1,4 @@ -import { ComfyWidgets, addRandomizeWidget } from "/scripts/widgets.js"; +import { ComfyWidgets, addSeedControlWidget } from "/scripts/widgets.js"; import { app } from "/scripts/app.js"; const CONVERTED_TYPE = "converted-widget"; @@ -23,7 +23,7 @@ function hideWidget(node, widget, suffix = "") { return widget.value; }; - // Hide any linked widgets, e.g. seed+randomize + // Hide any linked widgets, e.g. seed+seedControl if (widget.linkedWidgets) { for (const w of widget.linkedWidgets) { hideWidget(node, w, ":" + widget.name); @@ -40,7 +40,7 @@ function showWidget(widget) { delete widget.origComputeSize; delete widget.origSerializeValue; - // Hide any linked widgets, e.g. seed+randomize + // Hide any linked widgets, e.g. seed+seedControl if (widget.linkedWidgets) { for (const w of widget.linkedWidgets) { showWidget(w); @@ -285,7 +285,7 @@ app.registerExtension({ } if (widget.type === "number") { - addRandomizeWidget(this, widget, "Random after every gen"); + addSeedControlWidget(this, widget, "fixed_seed"); } // When our value changes, update other widgets to reflect our changes diff --git a/web/scripts/widgets.js b/web/scripts/widgets.js index 5f5043cd0..d7fc9ad6b 100644 --- a/web/scripts/widgets.js +++ b/web/scripts/widgets.js @@ -10,37 +10,60 @@ function getNumberDefaults(inputData, defaultStep) { return { val: defaultVal, config: { min, max, step: 10.0 * step } }; } -export function addRandomizeWidget(node, targetWidget, name, defaultValue = false) { - const randomize = node.addWidget("toggle", name, defaultValue, function (v) {}, { - on: "enabled", - off: "disabled", - serialize: false, // Don't include this in prompt. - }); +export function addSeedControlWidget(node, targetWidget, defauly, options) { + const seedControl = node.addWidget("combo", "seed control after generating", "Fixed Seed", function (v) { }, { + values: ["Fixed Seed", "increment", "decrement", "randomize"] },) + seedControl.afterQueued = () => { - randomize.afterQueued = () => { - if (randomize.value) { - const min = targetWidget.options?.min; - let max = targetWidget.options?.max; - if (min != null || max != null) { - if (max) { - // limit max to something that javascript can handle - max = Math.min(1125899906842624, max); + const min = targetWidget.options?.min; + let max = targetWidget.options?.max; + + + + var v = seedControl.value; + + switch (v) { + case ("Fixed Seed"): + console.log("Fixed Seed"); + break; + case ("increment"): + targetWidget.value += 1; + console.log("increment"); + break; + case ("decrement"): + targetWidget.value -= 1; + console.log("decrement"); + break; + case ("randomize"): + const min = targetWidget.options?.min; + let max = targetWidget.options?.max; + if (min != null || max != null) { + if (max) { + // limit max to something that javascript can handle + max = Math.min(1125899906842624, max); + console.log("Random"); + } + targetWidget.value = Math.floor(Math.random() * ((max ?? 9999999999) - (min ?? 0) + 1) + (min ?? 0)); + console.log("Random"); + } else { + targetWidget.value = Math.floor(Math.random() * 1125899906842624); + console.log("Random"); } - targetWidget.value = Math.floor(Math.random() * ((max ?? 9999999999) - (min ?? 0) + 1) + (min ?? 0)); - } else { - targetWidget.value = Math.floor(Math.random() * 1125899906842624); - } + break; + default: + console.log("default (fail)"); } }; - return randomize; + + return seedControl; } function seedWidget(node, inputName, inputData) { const seed = ComfyWidgets.INT(node, inputName, inputData); - const randomize = addRandomizeWidget(node, seed.widget, "Random seed after every gen", true); + const seedControl = addSeedControlWidget(node, seed.widget, "Fixed Seed"); - seed.widget.linkedWidgets = [randomize]; - return { widget: seed, randomize }; + seed.widget.linkedWidgets = [seedControl]; + return { widget: seed, seedControl}; } const MultilineSymbol = Symbol(); From 53ead930025ad5a5079fac720ddb19dcfe19400e Mon Sep 17 00:00:00 2001 From: Julien Lubimiv Date: Wed, 29 Mar 2023 15:14:01 -0400 Subject: [PATCH 2/4] +fixed default value -problems with last push caused issues --- .gitignore | 1 + web/scripts/app.js | 136 +++-------------------------------------- web/scripts/widgets.js | 14 ++--- 3 files changed, 15 insertions(+), 136 deletions(-) diff --git a/.gitignore b/.gitignore index d311a2a09..56ed55ee1 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,4 @@ temp/ custom_nodes/ !custom_nodes/example_node.py.example extra_model_paths.yaml +.vs/ diff --git a/web/scripts/app.js b/web/scripts/app.js index 43d7f7b59..dfa7cd02c 100644 --- a/web/scripts/app.js +++ b/web/scripts/app.js @@ -371,96 +371,6 @@ class ComfyApp { }); } - /** - * Handle mouse - * - * Move group by header - */ - #addProcessMouseHandler() { - const self = this; - - const origProcessMouseDown = LGraphCanvas.prototype.processMouseDown; - LGraphCanvas.prototype.processMouseDown = function(e) { - const res = origProcessMouseDown.apply(this, arguments); - - this.selected_group_moving = false; - - if (this.selected_group && !this.selected_group_resizing) { - var font_size = - this.selected_group.font_size || LiteGraph.DEFAULT_GROUP_FONT_SIZE; - var height = font_size * 1.4; - - // Move group by header - if (LiteGraph.isInsideRectangle(e.canvasX, e.canvasY, this.selected_group.pos[0], this.selected_group.pos[1], this.selected_group.size[0], height)) { - this.selected_group_moving = true; - } - } - - return res; - } - - const origProcessMouseMove = LGraphCanvas.prototype.processMouseMove; - LGraphCanvas.prototype.processMouseMove = function(e) { - const orig_selected_group = this.selected_group; - - if (this.selected_group && !this.selected_group_resizing && !this.selected_group_moving) { - this.selected_group = null; - } - - const res = origProcessMouseMove.apply(this, arguments); - - if (orig_selected_group && !this.selected_group_resizing && !this.selected_group_moving) { - this.selected_group = orig_selected_group; - } - - return res; - }; - } - - /** - * Draws group header bar - */ - #addDrawGroupsHandler() { - const self = this; - - const origDrawGroups = LGraphCanvas.prototype.drawGroups; - LGraphCanvas.prototype.drawGroups = function(canvas, ctx) { - if (!this.graph) { - return; - } - - var groups = this.graph._groups; - - ctx.save(); - ctx.globalAlpha = 0.7 * this.editor_alpha; - - for (var i = 0; i < groups.length; ++i) { - var group = groups[i]; - - if (!LiteGraph.overlapBounding(this.visible_area, group._bounding)) { - continue; - } //out of the visible area - - ctx.fillStyle = group.color || "#335"; - ctx.strokeStyle = group.color || "#335"; - var pos = group._pos; - var size = group._size; - ctx.globalAlpha = 0.25 * this.editor_alpha; - ctx.beginPath(); - var font_size = - group.font_size || LiteGraph.DEFAULT_GROUP_FONT_SIZE; - ctx.rect(pos[0] + 0.5, pos[1] + 0.5, size[0], font_size * 1.4); - ctx.fill(); - ctx.globalAlpha = this.editor_alpha; - } - - ctx.restore(); - - const res = origDrawGroups.apply(this, arguments); - return res; - } - } - /** * Draws node highlights (executing, drag drop) and progress bar */ @@ -608,8 +518,6 @@ class ComfyApp { canvasEl.tabIndex = "1"; document.body.prepend(canvasEl); - this.#addProcessMouseHandler(); - this.graph = new LGraph(); const canvas = (this.canvas = new LGraphCanvas(canvasEl, this.graph)); this.ctx = canvasEl.getContext("2d"); @@ -653,7 +561,6 @@ class ComfyApp { setInterval(() => localStorage.setItem("workflow", JSON.stringify(this.graph.serialize())), 1000); this.#addDrawNodeHandler(); - this.#addDrawGroupsHandler(); this.#addApiUpdateHandlers(); this.#addDropHandler(); this.#addPasteHandler(); @@ -683,10 +590,7 @@ class ComfyApp { const nodeData = defs[nodeId]; const node = Object.assign( function ComfyNode() { - var inputs = nodeData["input"]["required"]; - if (nodeData["input"]["optional"] != undefined){ - inputs = Object.assign({}, nodeData["input"]["required"], nodeData["input"]["optional"]) - } + const inputs = nodeData["input"]["required"]; const config = { minWidth: 1, minHeight: 1 }; for (const inputName in inputs) { const inputData = inputs[inputName]; @@ -707,10 +611,8 @@ class ComfyApp { } } - for (const o in nodeData["output"]) { - const output = nodeData["output"][o]; - const outputName = nodeData["output_name"][o] || output; - this.addOutput(outputName, output); + for (const output of nodeData["output"]) { + this.addOutput(output, output); } const s = this.computeSize(); @@ -771,6 +673,11 @@ class ComfyApp { widget.value = widget.value.slice(7); } } + + if (widget.name == "seed control after generating") { + if (widget.value == true) + widget.value = "fixed seed"; + } } } } @@ -856,7 +763,7 @@ class ComfyApp { if (node.widgets) { for (const widget of node.widgets) { // Allow widgets to run callbacks after a prompt has been queued - // e.g. random seed after every gen + // e.g. seed control after every gen if (widget.afterQueued) { widget.afterQueued(); } @@ -901,31 +808,6 @@ class ComfyApp { } this.extensions.push(extension); } - - /** - * Refresh combo list on whole nodes - */ - async refreshComboInNodes() { - const defs = await api.getNodeDefs(); - - for(let nodeNum in this.graph._nodes) { - const node = this.graph._nodes[nodeNum]; - - const def = defs[node.type]; - - for(const widgetNum in node.widgets) { - const widget = node.widgets[widgetNum] - - if(widget.type == "combo" && def["input"]["required"][widget.name] !== undefined) { - widget.options.values = def["input"]["required"][widget.name][0]; - - if(!widget.options.values.includes(widget.value)) { - widget.value = widget.options.values[0]; - } - } - } - } - } } export const app = new ComfyApp(); diff --git a/web/scripts/widgets.js b/web/scripts/widgets.js index d7fc9ad6b..2e085b9d8 100644 --- a/web/scripts/widgets.js +++ b/web/scripts/widgets.js @@ -10,20 +10,16 @@ function getNumberDefaults(inputData, defaultStep) { return { val: defaultVal, config: { min, max, step: 10.0 * step } }; } -export function addSeedControlWidget(node, targetWidget, defauly, options) { - const seedControl = node.addWidget("combo", "seed control after generating", "Fixed Seed", function (v) { }, { - values: ["Fixed Seed", "increment", "decrement", "randomize"] },) +export function addSeedControlWidget(node, targetWidget, defaultValue = "fixed seed", values) { + const seedControl = node.addWidget("combo", "seed control after generating", "fixed seed", function (v) { }, { + values: ["fixed seed", "increment", "decrement", "randomize"] },) seedControl.afterQueued = () => { - const min = targetWidget.options?.min; - let max = targetWidget.options?.max; - - var v = seedControl.value; switch (v) { - case ("Fixed Seed"): + case ("fixed seed"): console.log("Fixed Seed"); break; case ("increment"): @@ -60,7 +56,7 @@ export function addSeedControlWidget(node, targetWidget, defauly, options) { function seedWidget(node, inputName, inputData) { const seed = ComfyWidgets.INT(node, inputName, inputData); - const seedControl = addSeedControlWidget(node, seed.widget, "Fixed Seed"); + const seedControl = addSeedControlWidget(node, seed.widget, "fixed seed"); seed.widget.linkedWidgets = [seedControl]; return { widget: seed, seedControl}; From 3d856e62dd72c566512379bad2efe86bc5b5e323 Mon Sep 17 00:00:00 2001 From: Julien Lubimiv Date: Wed, 29 Mar 2023 16:04:19 -0400 Subject: [PATCH 3/4] returned to latest (almost) and kept seedControl changes --- .gitignore | 2 +- .vs/ComfyUI/FileContentIndex/read.lock | 0 .vs/ComfyUI/v17/.suo | Bin 0 -> 32768 bytes .vs/ProjectSettings.json | 3 + .vs/VSWorkspaceState.json | 11 +++ .vs/slnx.sqlite | Bin 0 -> 114688 bytes web/extensions/core/widgetInputs.js | 4 +- web/scripts/app.js | 131 ++++++++++++++++++++++++- web/scripts/widgets.js | 5 +- 9 files changed, 146 insertions(+), 10 deletions(-) create mode 100644 .vs/ComfyUI/FileContentIndex/read.lock create mode 100644 .vs/ComfyUI/v17/.suo create mode 100644 .vs/ProjectSettings.json create mode 100644 .vs/VSWorkspaceState.json create mode 100644 .vs/slnx.sqlite diff --git a/.gitignore b/.gitignore index 56ed55ee1..df6adbe4b 100644 --- a/.gitignore +++ b/.gitignore @@ -8,4 +8,4 @@ temp/ custom_nodes/ !custom_nodes/example_node.py.example extra_model_paths.yaml -.vs/ +/.vs diff --git a/.vs/ComfyUI/FileContentIndex/read.lock b/.vs/ComfyUI/FileContentIndex/read.lock new file mode 100644 index 000000000..e69de29bb diff --git a/.vs/ComfyUI/v17/.suo b/.vs/ComfyUI/v17/.suo new file mode 100644 index 0000000000000000000000000000000000000000..564078dfddaac2a51743bd40fde17e4a912f1676 GIT binary patch literal 32768 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 literal 0 HcmV?d00001 diff --git a/.vs/ProjectSettings.json b/.vs/ProjectSettings.json new file mode 100644 index 000000000..f8b488856 --- /dev/null +++ b/.vs/ProjectSettings.json @@ -0,0 +1,3 @@ +{ + "CurrentProjectSetting": null +} \ No newline at end of file diff --git a/.vs/VSWorkspaceState.json b/.vs/VSWorkspaceState.json new file mode 100644 index 000000000..6e79ddaa6 --- /dev/null +++ b/.vs/VSWorkspaceState.json @@ -0,0 +1,11 @@ +{ + "ExpandedNodes": [ + "", + "\\web", + "\\web\\extensions", + "\\web\\extensions\\core", + "\\web\\scripts" + ], + "SelectedNode": "\\web\\scripts\\widgets.js", + "PreviewInSolutionExplorer": false +} \ No newline at end of file diff --git a/.vs/slnx.sqlite b/.vs/slnx.sqlite new file mode 100644 index 0000000000000000000000000000000000000000..3bcc9c10f5baba018d739dd40590ab0357ba7aab GIT binary patch literal 114688 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 Znlk?*<4GKDjmP$;P`PNtg#O#;{|8NHt7-rM literal 0 HcmV?d00001 diff --git a/web/extensions/core/widgetInputs.js b/web/extensions/core/widgetInputs.js index d571f00a9..f55abfc45 100644 --- a/web/extensions/core/widgetInputs.js +++ b/web/extensions/core/widgetInputs.js @@ -284,8 +284,8 @@ app.registerExtension({ } } - if (widget.type === "number") { - addSeedControlWidget(this, widget, "fixed_seed"); + if (widget.type === "combo") { + addSeedControlWidget(this, widget, "fixed seed"); } // When our value changes, update other widgets to reflect our changes diff --git a/web/scripts/app.js b/web/scripts/app.js index dfa7cd02c..a26c3547a 100644 --- a/web/scripts/app.js +++ b/web/scripts/app.js @@ -371,6 +371,96 @@ class ComfyApp { }); } + /** + * Handle mouse + * + * Move group by header + */ + #addProcessMouseHandler() { + const self = this; + + const origProcessMouseDown = LGraphCanvas.prototype.processMouseDown; + LGraphCanvas.prototype.processMouseDown = function(e) { + const res = origProcessMouseDown.apply(this, arguments); + + this.selected_group_moving = false; + + if (this.selected_group && !this.selected_group_resizing) { + var font_size = + this.selected_group.font_size || LiteGraph.DEFAULT_GROUP_FONT_SIZE; + var height = font_size * 1.4; + + // Move group by header + if (LiteGraph.isInsideRectangle(e.canvasX, e.canvasY, this.selected_group.pos[0], this.selected_group.pos[1], this.selected_group.size[0], height)) { + this.selected_group_moving = true; + } + } + + return res; + } + + const origProcessMouseMove = LGraphCanvas.prototype.processMouseMove; + LGraphCanvas.prototype.processMouseMove = function(e) { + const orig_selected_group = this.selected_group; + + if (this.selected_group && !this.selected_group_resizing && !this.selected_group_moving) { + this.selected_group = null; + } + + const res = origProcessMouseMove.apply(this, arguments); + + if (orig_selected_group && !this.selected_group_resizing && !this.selected_group_moving) { + this.selected_group = orig_selected_group; + } + + return res; + }; + } + + /** + * Draws group header bar + */ + #addDrawGroupsHandler() { + const self = this; + + const origDrawGroups = LGraphCanvas.prototype.drawGroups; + LGraphCanvas.prototype.drawGroups = function(canvas, ctx) { + if (!this.graph) { + return; + } + + var groups = this.graph._groups; + + ctx.save(); + ctx.globalAlpha = 0.7 * this.editor_alpha; + + for (var i = 0; i < groups.length; ++i) { + var group = groups[i]; + + if (!LiteGraph.overlapBounding(this.visible_area, group._bounding)) { + continue; + } //out of the visible area + + ctx.fillStyle = group.color || "#335"; + ctx.strokeStyle = group.color || "#335"; + var pos = group._pos; + var size = group._size; + ctx.globalAlpha = 0.25 * this.editor_alpha; + ctx.beginPath(); + var font_size = + group.font_size || LiteGraph.DEFAULT_GROUP_FONT_SIZE; + ctx.rect(pos[0] + 0.5, pos[1] + 0.5, size[0], font_size * 1.4); + ctx.fill(); + ctx.globalAlpha = this.editor_alpha; + } + + ctx.restore(); + + const res = origDrawGroups.apply(this, arguments); + return res; + } + } + /** * Draws node highlights (executing, drag drop) and progress bar */ @@ -518,6 +608,8 @@ class ComfyApp { canvasEl.tabIndex = "1"; document.body.prepend(canvasEl); + this.#addProcessMouseHandler(); + this.graph = new LGraph(); const canvas = (this.canvas = new LGraphCanvas(canvasEl, this.graph)); this.ctx = canvasEl.getContext("2d"); @@ -561,6 +653,7 @@ class ComfyApp { setInterval(() => localStorage.setItem("workflow", JSON.stringify(this.graph.serialize())), 1000); this.#addDrawNodeHandler(); + this.#addDrawGroupsHandler(); this.#addApiUpdateHandlers(); this.#addDropHandler(); this.#addPasteHandler(); @@ -590,7 +683,10 @@ class ComfyApp { const nodeData = defs[nodeId]; const node = Object.assign( function ComfyNode() { - const inputs = nodeData["input"]["required"]; + var inputs = nodeData["input"]["required"]; + if (nodeData["input"]["optional"] != undefined){ + inputs = Object.assign({}, nodeData["input"]["required"], nodeData["input"]["optional"]) + } const config = { minWidth: 1, minHeight: 1 }; for (const inputName in inputs) { const inputData = inputs[inputName]; @@ -611,8 +707,10 @@ class ComfyApp { } } - for (const output of nodeData["output"]) { - this.addOutput(output, output); + for (const o in nodeData["output"]) { + const output = nodeData["output"][o]; + const outputName = nodeData["output_name"][o] || output; + this.addOutput(outputName, output); } const s = this.computeSize(); @@ -763,7 +861,7 @@ class ComfyApp { if (node.widgets) { for (const widget of node.widgets) { // Allow widgets to run callbacks after a prompt has been queued - // e.g. seed control after every gen + // e.g. random seed after every gen if (widget.afterQueued) { widget.afterQueued(); } @@ -808,6 +906,31 @@ class ComfyApp { } this.extensions.push(extension); } + + /** + * Refresh combo list on whole nodes + */ + async refreshComboInNodes() { + const defs = await api.getNodeDefs(); + + for(let nodeNum in this.graph._nodes) { + const node = this.graph._nodes[nodeNum]; + + const def = defs[node.type]; + + for(const widgetNum in node.widgets) { + const widget = node.widgets[widgetNum] + + if(widget.type == "combo" && def["input"]["required"][widget.name] !== undefined) { + widget.options.values = def["input"]["required"][widget.name][0]; + + if(!widget.options.values.includes(widget.value)) { + widget.value = widget.options.values[0]; + } + } + } + } + } } export const app = new ComfyApp(); diff --git a/web/scripts/widgets.js b/web/scripts/widgets.js index 2e085b9d8..dbaa44908 100644 --- a/web/scripts/widgets.js +++ b/web/scripts/widgets.js @@ -10,17 +10,16 @@ function getNumberDefaults(inputData, defaultStep) { return { val: defaultVal, config: { min, max, step: 10.0 * step } }; } -export function addSeedControlWidget(node, targetWidget, defaultValue = "fixed seed", values) { +export function addSeedControlWidget(node, targetWidget, defauly, options) { const seedControl = node.addWidget("combo", "seed control after generating", "fixed seed", function (v) { }, { values: ["fixed seed", "increment", "decrement", "randomize"] },) seedControl.afterQueued = () => { - var v = seedControl.value; switch (v) { case ("fixed seed"): - console.log("Fixed Seed"); + console.log("fixed seed"); break; case ("increment"): targetWidget.value += 1; From 1518b385a7a2f22887dabd97f45548197f65fad3 Mon Sep 17 00:00:00 2001 From: Julien Lubimiv Date: Wed, 29 Mar 2023 16:54:45 -0400 Subject: [PATCH 4/4] seedControl can no longer become an input, removes .vs files --- .vs/ComfyUI/FileContentIndex/read.lock | 0 .vs/ComfyUI/v17/.suo | Bin 32768 -> 0 bytes .vs/ProjectSettings.json | 3 --- .vs/VSWorkspaceState.json | 11 ----------- .vs/slnx.sqlite | Bin 114688 -> 0 bytes web/extensions/core/widgetInputs.js | 6 +++++- web/scripts/app.js | 3 ++- web/scripts/widgets.js | 11 ++++++----- 8 files changed, 13 insertions(+), 21 deletions(-) delete mode 100644 .vs/ComfyUI/FileContentIndex/read.lock delete mode 100644 .vs/ComfyUI/v17/.suo delete mode 100644 .vs/ProjectSettings.json delete mode 100644 .vs/VSWorkspaceState.json delete mode 100644 .vs/slnx.sqlite diff --git a/.vs/ComfyUI/FileContentIndex/read.lock b/.vs/ComfyUI/FileContentIndex/read.lock deleted file mode 100644 index e69de29bb..000000000 diff --git a/.vs/ComfyUI/v17/.suo b/.vs/ComfyUI/v17/.suo deleted file mode 100644 index 564078dfddaac2a51743bd40fde17e4a912f1676..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 32768 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 diff --git a/.vs/ProjectSettings.json b/.vs/ProjectSettings.json deleted file mode 100644 index f8b488856..000000000 --- a/.vs/ProjectSettings.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "CurrentProjectSetting": null -} \ No newline at end of file diff --git a/.vs/VSWorkspaceState.json b/.vs/VSWorkspaceState.json deleted file mode 100644 index 6e79ddaa6..000000000 --- a/.vs/VSWorkspaceState.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "ExpandedNodes": [ - "", - "\\web", - "\\web\\extensions", - "\\web\\extensions\\core", - "\\web\\scripts" - ], - "SelectedNode": "\\web\\scripts\\widgets.js", - "PreviewInSolutionExplorer": false -} \ No newline at end of file diff --git a/.vs/slnx.sqlite b/.vs/slnx.sqlite deleted file mode 100644 index 3bcc9c10f5baba018d739dd40590ab0357ba7aab..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 114688 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 Znlk?*<4GKDjmP$;P`PNtg#O#;{|8NHt7-rM diff --git a/web/extensions/core/widgetInputs.js b/web/extensions/core/widgetInputs.js index f55abfc45..0b2695f23 100644 --- a/web/extensions/core/widgetInputs.js +++ b/web/extensions/core/widgetInputs.js @@ -5,9 +5,13 @@ const CONVERTED_TYPE = "converted-widget"; const VALID_TYPES = ["STRING", "combo", "number"]; function isConvertableWidget(widget, config) { - return VALID_TYPES.includes(widget.type) || VALID_TYPES.includes(config[0]); + if (widget.name == "seed control after generating") + widget.allowConvertToInput = false; + else + return VALID_TYPES.includes(widget.type) || VALID_TYPES.includes(config[0]); } + function hideWidget(node, widget, suffix = "") { widget.origType = widget.type; widget.origComputeSize = widget.computeSize; diff --git a/web/scripts/app.js b/web/scripts/app.js index a26c3547a..17d699507 100644 --- a/web/scripts/app.js +++ b/web/scripts/app.js @@ -773,8 +773,9 @@ class ComfyApp { } if (widget.name == "seed control after generating") { - if (widget.value == true) + if (widget.value == true) { widget.value = "fixed seed"; + } } } } diff --git a/web/scripts/widgets.js b/web/scripts/widgets.js index dbaa44908..9f1302ed4 100644 --- a/web/scripts/widgets.js +++ b/web/scripts/widgets.js @@ -10,16 +10,17 @@ function getNumberDefaults(inputData, defaultStep) { return { val: defaultVal, config: { min, max, step: 10.0 * step } }; } -export function addSeedControlWidget(node, targetWidget, defauly, options) { +export function addSeedControlWidget(node, targetWidget, defaultValue = "fixed seed", values) { const seedControl = node.addWidget("combo", "seed control after generating", "fixed seed", function (v) { }, { - values: ["fixed seed", "increment", "decrement", "randomize"] },) + values: ["fixed seed", "increment", "decrement", "randomize"] + }) seedControl.afterQueued = () => { var v = seedControl.value; switch (v) { case ("fixed seed"): - console.log("fixed seed"); + console.log("Fixed Seed"); break; case ("increment"): targetWidget.value += 1; @@ -49,7 +50,7 @@ export function addSeedControlWidget(node, targetWidget, defauly, options) { console.log("default (fail)"); } }; - + return seedControl; } @@ -58,7 +59,7 @@ function seedWidget(node, inputName, inputData) { const seedControl = addSeedControlWidget(node, seed.widget, "fixed seed"); seed.widget.linkedWidgets = [seedControl]; - return { widget: seed, seedControl}; + return { widget: seed, seedControl }; } const MultilineSymbol = Symbol();