Add Litegraph multi-select & group nesting (#1416)

* Allow nested groups

Pass all selected items (new litegraph feature) instead of just selected nodes.

* Allow nested groups - context menus

* Update litegraph

* Update litegraph (Select all / Delete selected)

* Add playwright test

* nit

* Update test expectations [skip ci]

---------

Co-authored-by: huchenlei <huchenlei@proton.me>
Co-authored-by: github-actions <github-actions@github.com>
This commit is contained in:
filtered
2024-11-04 10:08:42 +11:00
committed by GitHub
parent 0a784d9236
commit 3ba776e6ca
10 changed files with 267 additions and 77 deletions

View File

@@ -1,66 +1,17 @@
// @ts-strict-ignore
import { LGraphGroup } from '@comfyorg/litegraph'
import { app } from '../../scripts/app'
import { LGraphCanvas, LiteGraph } from '@comfyorg/litegraph'
import { LGraphCanvas } from '@comfyorg/litegraph'
import type { Positionable } from '@comfyorg/litegraph/dist/interfaces'
import type { LGraphNode } from '@comfyorg/litegraph'
function setNodeMode(node, mode) {
function setNodeMode(node: LGraphNode, mode: number) {
node.mode = mode
node.graph.change()
node.graph?.change()
}
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]
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)
}
}
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
y1 = y1 - Math.round(group.font_size * 1.4)
group.pos = [x1 - padding, y1 - padding]
group.size = [x2 - x1 + padding * 2, y2 - y1 + padding * 2]
function addNodesToGroup(group: LGraphGroup, items: Iterable<Positionable>) {
group.resizeTo([...group.children, ...items])
}
app.registerExtension({
@@ -68,7 +19,9 @@ app.registerExtension({
setup() {
const orig = LGraphCanvas.prototype.getCanvasMenuOptions
// graph_mouse
LGraphCanvas.prototype.getCanvasMenuOptions = function () {
LGraphCanvas.prototype.getCanvasMenuOptions = function (
this: LGraphCanvas
) {
const options = orig.apply(this, arguments)
const group = this.graph.getGroupOnPos(
this.graph_mouse[0],
@@ -77,11 +30,11 @@ app.registerExtension({
if (!group) {
options.push({
content: 'Add Group For Selected Nodes',
disabled: !Object.keys(app.canvas.selected_nodes || {}).length,
disabled: !this.selectedItems?.size,
callback: () => {
const group = new LGraphGroup()
addNodesToGroup(group, this.selected_nodes)
app.canvas.graph.add(group)
addNodesToGroup(group, this.selectedItems)
this.graph.add(group)
this.graph.change()
}
})
@@ -95,9 +48,9 @@ app.registerExtension({
options.push({
content: 'Add Selected Nodes To Group',
disabled: !Object.keys(app.canvas.selected_nodes || {}).length,
disabled: !this.selectedItems?.size,
callback: () => {
addNodesToGroup(group, this.selected_nodes)
addNodesToGroup(group, this.selectedItems)
this.graph.change()
}
})
@@ -122,7 +75,8 @@ app.registerExtension({
options.push({
content: 'Fit Group To Nodes',
callback: () => {
addNodesToGroup(group)
group.recomputeInsideNodes()
group.resizeTo(group.children)
this.graph.change()
}
})

View File

@@ -361,14 +361,13 @@ export const useCommandStore = defineStore('command', () => {
label: 'Group Selected Nodes',
versionAdded: '1.3.7',
function: () => {
if (
!app.canvas.selected_nodes ||
Object.keys(app.canvas.selected_nodes).length === 0
) {
const { canvas } = app
if (!canvas.selectedItems?.size) {
useToastStore().add({
severity: 'error',
summary: 'No nodes selected',
detail: 'Please select nodes to group',
summary: 'Nothing to group',
detail:
'Please select the nodes (or other groups) to create a group for',
life: 3000
})
return
@@ -377,8 +376,8 @@ export const useCommandStore = defineStore('command', () => {
const padding = useSettingStore().get(
'Comfy.GroupSelectedNodes.Padding'
)
group.addNodes(Object.values(app.canvas.selected_nodes), padding)
app.canvas.graph.add(group)
group.resizeTo(canvas.selectedItems, padding)
canvas.graph.add(group)
useTitleEditorStore().titleEditorTarget = group
}
},