groupOptions.js 9.16 KB
Newer Older
1
2
3
4
5
6
7
import {app} from "../../scripts/app.js";

function setNodeMode(node, mode) {
    node.mode = mode;
    node.graph.change();
}

Jairo Correa's avatar
Jairo Correa committed
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
function addNodesToGroup(group, nodes=[]) {
    var x1, y1, x2, y2;
    var nx1, ny1, nx2, ny2;
    var node;

    x1 = y1 = x2 = y2 = -1;
    nx1 = ny1 = nx2 = ny2 = -1;

    for (var n of [group._nodes, nodes]) {
        for (var i in n) {
            node = n[i]

            nx1 = node.pos[0]
            ny1 = node.pos[1]
            nx2 = node.pos[0] + node.size[0]
            ny2 = node.pos[1] + node.size[1]

25
26
27
28
29
30
31
32
33
34
35
36
            if (node.type != "Reroute") {
                ny1 -= LiteGraph.NODE_TITLE_HEIGHT;
            }

            if (node.flags?.collapsed) {
                ny2 = ny1 + LiteGraph.NODE_TITLE_HEIGHT;

                if (node?._collapsed_width) {
                    nx2 = nx1 + Math.round(node._collapsed_width);
                }
            }

Jairo Correa's avatar
Jairo Correa committed
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
            if (x1 == -1 || nx1 < x1) {
                x1 = nx1;
            }

            if (y1 == -1 || ny1 < y1) {
                y1 = ny1;
            }

            if (x2 == -1 || nx2 > x2) {
                x2 = nx2;
            }

            if (y2 == -1 || ny2 > y2) {
                y2 = ny2;
            }
        }
    }

    var padding = 10;

57
    y1 = y1 - Math.round(group.font_size * 1.4);
Jairo Correa's avatar
Jairo Correa committed
58
59
60
61
62

    group.pos = [x1 - padding, y1 - padding];
    group.size = [x2 - x1 + padding * 2, y2 - y1 + padding * 2];
}

63
64
65
66
67
68
69
70
71
app.registerExtension({
    name: "Comfy.GroupOptions",
    setup() {
        const orig = LGraphCanvas.prototype.getCanvasMenuOptions;
        // graph_mouse
        LGraphCanvas.prototype.getCanvasMenuOptions = function () {
            const options = orig.apply(this, arguments);
            const group = this.graph.getGroupOnPos(this.graph_mouse[0], this.graph_mouse[1]);
            if (!group) {
Jairo Correa's avatar
Jairo Correa committed
72
73
74
75
76
77
78
79
80
81
82
                options.push({
                    content: "Add Group For Selected Nodes",
                    disabled: !Object.keys(app.canvas.selected_nodes || {}).length,
                    callback: () => {
                        var group = new LiteGraph.LGraphGroup();
                        addNodesToGroup(group, this.selected_nodes)
                        app.canvas.graph.add(group);
                        this.graph.change();
                    }
                });

83
84
85
86
87
88
89
                return options;
            }

            // Group nodes aren't recomputed until the group is moved, this ensures the nodes are up-to-date
            group.recomputeInsideNodes();
            const nodesInGroup = group._nodes;

90
91
92
93
94
95
96
97
98
            options.push({
                content: "Add Selected Nodes To Group",
                disabled: !Object.keys(app.canvas.selected_nodes || {}).length,
                callback: () => {
                    addNodesToGroup(group, this.selected_nodes)
                    this.graph.change();
                }
            });

99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
            // No nodes in group, return default options
            if (nodesInGroup.length === 0) {
                return options;
            } else {
                // Add a separator between the default options and the group options
                options.push(null);
            }

            // Check if all nodes are the same mode
            let allNodesAreSameMode = true;
            for (let i = 1; i < nodesInGroup.length; i++) {
                if (nodesInGroup[i].mode !== nodesInGroup[0].mode) {
                    allNodesAreSameMode = false;
                    break;
                }
            }

Jairo Correa's avatar
Jairo Correa committed
116
117
118
119
120
121
122
123
            options.push({
                content: "Fit Group To Nodes",
                callback: () => {
                    addNodesToGroup(group)
                    this.graph.change();
                }
            });

Jairo Correa's avatar
Jairo Correa committed
124
125
126
127
128
129
130
131
132
            options.push({
                content: "Select Nodes",
                callback: () => {
                    this.selectNodes(nodesInGroup);
                    this.graph.change();
                    this.canvas.focus();
                }
            });

133
134
            // Modes
            // 0: Always
135
            // 1: On Event
136
            // 2: Never
137
            // 3: On Trigger
138
139
140
141
            // 4: Bypass
            // If all nodes are the same mode, add a menu option to change the mode
            if (allNodesAreSameMode) {
                const mode = nodesInGroup[0].mode;
142
143
144
145
146
147
148
149
150
                switch (mode) {
                    case 0:
                        // All nodes are always, option to disable, and bypass
                        options.push({
                            content: "Set Group Nodes to Never",
                            callback: () => {
                                for (const node of nodesInGroup) {
                                    setNodeMode(node, 2);
                                }
151
                            }
152
153
154
155
156
157
158
                        });
                        options.push({
                            content: "Bypass Group Nodes",
                            callback: () => {
                                for (const node of nodesInGroup) {
                                    setNodeMode(node, 4);
                                }
159
                            }
160
161
162
163
164
165
166
167
168
169
                        });
                        break;
                    case 2:
                        // All nodes are never, option to enable, and bypass
                        options.push({
                            content: "Set Group Nodes to Always",
                            callback: () => {
                                for (const node of nodesInGroup) {
                                    setNodeMode(node, 0);
                                }
170
                            }
171
172
173
174
175
176
177
                        });
                        options.push({
                            content: "Bypass Group Nodes",
                            callback: () => {
                                for (const node of nodesInGroup) {
                                    setNodeMode(node, 4);
                                }
178
                            }
179
180
181
182
183
184
185
186
187
188
                        });
                        break;
                    case 4:
                        // All nodes are bypass, option to enable, and disable
                        options.push({
                            content: "Set Group Nodes to Always",
                            callback: () => {
                                for (const node of nodesInGroup) {
                                    setNodeMode(node, 0);
                                }
189
                            }
190
191
192
193
194
195
196
                        });
                        options.push({
                            content: "Set Group Nodes to Never",
                            callback: () => {
                                for (const node of nodesInGroup) {
                                    setNodeMode(node, 2);
                                }
197
                            }
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
                        });
                        break;
                    default:
                        // All nodes are On Trigger or On Event(Or other?), option to disable, set to always, or bypass
                        options.push({
                            content: "Set Group Nodes to Always",
                            callback: () => {
                                for (const node of nodesInGroup) {
                                    setNodeMode(node, 0);
                                }
                            }
                        });
                        options.push({
                            content: "Set Group Nodes to Never",
                            callback: () => {
                                for (const node of nodesInGroup) {
                                    setNodeMode(node, 2);
                                }
                            }
                        });
                        options.push({
                            content: "Bypass Group Nodes",
                            callback: () => {
                                for (const node of nodesInGroup) {
                                    setNodeMode(node, 4);
                                }
                            }
                        });
                        break;
227
228
229
230
                }
            } else {
                // Nodes are not all the same mode, add a menu option to change the mode to always, never, or bypass
                options.push({
231
                    content: "Set Group Nodes to Always",
232
233
234
235
236
237
238
                    callback: () => {
                        for (const node of nodesInGroup) {
                            setNodeMode(node, 0);
                        }
                    }
                });
                options.push({
239
                    content: "Set Group Nodes to Never",
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
                    callback: () => {
                        for (const node of nodesInGroup) {
                            setNodeMode(node, 2);
                        }
                    }
                });
                options.push({
                    content: "Bypass Group Nodes",
                    callback: () => {
                        for (const node of nodesInGroup) {
                            setNodeMode(node, 4);
                        }
                    }
                });
            }

            return options
        }
    }
});