Skip to content

Commit 1fe5fb1

Browse files
committed
fix(ui): conditional widget toggles now also collapse the DOM-backed input element + its .dom-widget wrapper, so re-toggling actually shows/hides the field (centralised via _widget_visibility.js)
1 parent f076e5c commit 1fe5fb1

4 files changed

Lines changed: 70 additions & 63 deletions

File tree

js/_widget_visibility.js

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
// Shared widget show/hide helper for MEC nodes.
2+
//
3+
// Modern ComfyUI renders many widgets via DOM (number inputs, textareas,
4+
// combo selects). Setting ``widget.type = "hidden"`` and collapsing
5+
// ``computeSize`` only fixes the LiteGraph layout — the DOM element and
6+
// its ``.dom-widget`` wrapper stay visible on top of the node, producing
7+
// the "I toggled false then true and the field never came back / never
8+
// went away" symptom. This helper toggles BOTH layers and remembers the
9+
// original styles so re-showing restores them exactly.
10+
//
11+
// Usage:
12+
// import { setWidgetVisible } from "./_widget_visibility.js";
13+
// setWidgetVisible(w, true); // show
14+
// setWidgetVisible(w, false); // hide
15+
16+
export function setWidgetVisible(widget, visible) {
17+
if (!widget) return;
18+
if (visible) {
19+
if (widget.__mec_origType !== undefined) {
20+
widget.type = widget.__mec_origType;
21+
delete widget.__mec_origType;
22+
}
23+
if (widget.__mec_origComputeSize !== undefined) {
24+
widget.computeSize = widget.__mec_origComputeSize;
25+
delete widget.__mec_origComputeSize;
26+
}
27+
widget.hidden = false;
28+
const el = widget.element;
29+
if (el) {
30+
el.style.display = widget.__mec_origElDisplay ?? "";
31+
delete widget.__mec_origElDisplay;
32+
const wrap = el.parentElement;
33+
if (wrap && wrap.classList?.contains("dom-widget")) {
34+
wrap.style.display = widget.__mec_origWrapDisplay ?? "";
35+
delete widget.__mec_origWrapDisplay;
36+
}
37+
}
38+
delete widget.__mec_hidden;
39+
} else {
40+
if (widget.__mec_origType === undefined) widget.__mec_origType = widget.type;
41+
if (widget.__mec_origComputeSize === undefined) widget.__mec_origComputeSize = widget.computeSize;
42+
widget.type = "hidden";
43+
widget.computeSize = () => [0, -4];
44+
widget.hidden = true;
45+
const el = widget.element;
46+
if (el) {
47+
if (widget.__mec_origElDisplay === undefined) {
48+
widget.__mec_origElDisplay = el.style.display || "";
49+
}
50+
el.style.display = "none";
51+
const wrap = el.parentElement;
52+
if (wrap && wrap.classList?.contains("dom-widget")) {
53+
if (widget.__mec_origWrapDisplay === undefined) {
54+
widget.__mec_origWrapDisplay = wrap.style.display || "";
55+
}
56+
wrap.style.display = "none";
57+
}
58+
}
59+
widget.__mec_hidden = true;
60+
}
61+
}
62+
63+
export function setHidden(widget, hidden) {
64+
setWidgetVisible(widget, !hidden);
65+
}

js/draw_shape.js

Lines changed: 3 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// DrawShapeMEC: conditional widget visibility based on `shape` dropdown.
22
// Pattern modeled on KJNodes — hide irrelevant widgets by overriding computeSize to [0,-4].
33
import { app } from "../../scripts/app.js";
4+
import { setWidgetVisible } from "./_widget_visibility.js";
45

56
const SHAPE_FIELDS = {
67
circle: ["cx","cy","radius"],
@@ -29,35 +30,12 @@ function applyShapeVisibility(node) {
2930
if (ALWAYS_VISIBLE.has(w.name)) continue;
3031
// polygon's points_json is in ALWAYS_VISIBLE so we hide it for non-polygon below
3132
const shouldShow = allowed.has(w.name);
32-
if (shouldShow) {
33-
if (w.__origComputeSize) {
34-
w.computeSize = w.__origComputeSize;
35-
delete w.__origComputeSize;
36-
}
37-
w.hidden = false;
38-
w.type = w.__origType || w.type;
39-
} else {
40-
if (!w.__origComputeSize) {
41-
w.__origComputeSize = w.computeSize;
42-
w.__origType = w.type;
43-
}
44-
w.computeSize = () => [0, -4];
45-
w.hidden = true;
46-
w.type = "hidden";
47-
}
33+
setWidgetVisible(w, shouldShow);
4834
}
4935
// Special: points_json only for polygon
5036
const pj = node.widgets.find(w => w.name === "points_json");
5137
if (pj) {
52-
const isPoly = shape === "polygon";
53-
if (isPoly) {
54-
if (pj.__origComputeSize) { pj.computeSize = pj.__origComputeSize; delete pj.__origComputeSize; }
55-
pj.hidden = false;
56-
} else {
57-
if (!pj.__origComputeSize) pj.__origComputeSize = pj.computeSize;
58-
pj.computeSize = () => [0, -4];
59-
pj.hidden = true;
60-
}
38+
setWidgetVisible(pj, shape === "polygon");
6139
}
6240
const sz = node.computeSize();
6341
node.size[0] = Math.max(node.size[0], sz[0]);

js/motion_mask_tracker.js

Lines changed: 1 addition & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -7,32 +7,14 @@
77
// - "histogram_diff" : only hist_* visible
88
// combine_method only applies when detection_mode == "combined".
99
import { app } from "../../scripts/app.js";
10+
import { setHidden } from "./_widget_visibility.js";
1011

1112
const PIXEL_DIFF = ["pixel_diff_enabled", "pixel_diff_threshold"];
1213
const FLOW = ["flow_enabled", "flow_threshold", "flow_algorithm"];
1314
const BG_SUB = ["bg_sub_enabled", "bg_model_frames", "bg_sub_threshold"];
1415
const HIST = ["hist_enabled", "hist_grid_size", "hist_threshold"];
1516
const COMBINE = ["combine_method"];
1617

17-
function setHidden(w, hidden) {
18-
if (hidden) {
19-
if (!w.__origComputeSize) {
20-
w.__origComputeSize = w.computeSize;
21-
w.__origType = w.type;
22-
}
23-
w.computeSize = () => [0, -4];
24-
w.hidden = true;
25-
w.type = "hidden";
26-
} else {
27-
if (w.__origComputeSize) {
28-
w.computeSize = w.__origComputeSize;
29-
delete w.__origComputeSize;
30-
}
31-
w.hidden = false;
32-
w.type = w.__origType || w.type;
33-
}
34-
}
35-
3618
function applyVisibility(node) {
3719
const get = (n) => node.widgets?.find(w => w.name === n);
3820
const mode = String(get("detection_mode")?.value ?? "combined");

js/vae_merge.js

Lines changed: 1 addition & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,12 @@
11
// VAEMergeMEC: per-block sliders only visible when use_blocks=True AND auto_alpha=False.
22
import { app } from "../../scripts/app.js";
3+
import { setHidden } from "./_widget_visibility.js";
34

45
const BLOCKS = [
56
"block_conv_in", "block_conv_out", "block_norm_out",
67
"block_0", "block_1", "block_2", "block_3", "block_mid",
78
];
89

9-
function setHidden(w, hidden) {
10-
if (hidden) {
11-
if (!w.__origComputeSize) {
12-
w.__origComputeSize = w.computeSize;
13-
w.__origType = w.type;
14-
}
15-
w.computeSize = () => [0, -4];
16-
w.hidden = true;
17-
w.type = "hidden";
18-
} else {
19-
if (w.__origComputeSize) {
20-
w.computeSize = w.__origComputeSize;
21-
delete w.__origComputeSize;
22-
}
23-
w.hidden = false;
24-
w.type = w.__origType || w.type;
25-
}
26-
}
27-
2810
function applyVisibility(node) {
2911
const get = (n) => node.widgets?.find(w => w.name === n);
3012
const useBlocks = !!get("use_blocks")?.value;

0 commit comments

Comments
 (0)