Prevent doubled promotion, add demotion option

This commit is contained in:
Austin Mroz
2025-09-26 08:48:27 -05:00
parent aeafee4e12
commit 92f2578357
2 changed files with 68 additions and 13 deletions

View File

@@ -1,4 +1,7 @@
import type { LGraphNode } from '@/lib/litegraph/src/litegraph'
import type {
IContextMenuValue,
LGraphNode
} from '@/lib/litegraph/src/litegraph'
import { SubgraphNode } from '@/lib/litegraph/src/subgraph/SubgraphNode'
import type { IBaseWidget } from '@/lib/litegraph/src/types/widgets.ts'
import { parseProxyWidgets } from '@/schemas/proxyWidget'
@@ -15,18 +18,75 @@ function getProxyWidgets(node: SubgraphNode) {
/**
* Enables display of a widget on the parent subgraphNode
* @param {{IBaseWidget}} widget - The widget to be promoted
* @param {{LGraphNode}} node - the node which owns the widget
* @param {IBaseWidget} widget - The widget to be promoted
* @param {LGraphNode} node - the node which owns the widget
*/
export function promoteWidget(widget: IBaseWidget, node: LGraphNode) {
function promoteWidget(
widget: IBaseWidget,
node: LGraphNode,
parents: SubgraphNode[]
) {
for (const parent of parents) pushWidgets(parent, [`${node.id}`, widget.name])
widget.promoted = true
}
function demoteWidget(
widget: IBaseWidget,
node: LGraphNode,
parents: SubgraphNode[]
) {
for (const parent of parents) {
const pw = getProxyWidgets(parent).filter(
([id, name]) => node.id != id || widget.name !== name
)
parent.properties.proxyWidgets = JSON.stringify(pw)
}
widget.promoted = false
}
function getParentNodes(): SubgraphNode[] {
//NOTE: support for determining parents of a subgraph is limited
//This function will require rework to properly support linked subgraphs
//Either by including actual parents in the navigation stack,
//or by adding a new event for parent listeners to collect from
const { navigationStack } = useSubgraphNavigationStore()
const subgraph = navigationStack.at(-1)
if (!subgraph) throw new Error("Can't promote widget when not in subgraph")
const validNodes = []
const parentGraph = navigationStack.at(-2) ?? subgraph.rootGraph
for (const onode of parentGraph.nodes) {
if (onode.type === subgraph.id && onode.isSubgraphNode()) {
pushWidgets(onode, [`${node.id}`, widget.name])
validNodes.push(onode)
}
}
widget.promoted = true
return validNodes
}
export function addWidgetPromotionOptions(
options: (IContextMenuValue<unknown> | null)[],
widget: IBaseWidget,
node: LGraphNode
) {
const parents = getParentNodes()
const promotableParents = parents.filter(
(s) =>
!getProxyWidgets(s).some(
([id, name]) => node.id == id && widget.name === name
)
)
if (promotableParents.length > 0)
options.unshift({
content: `Promote Widget: ${widget.label ?? widget.name}`,
callback: () => {
promoteWidget(widget, node, promotableParents)
}
})
else {
options.unshift({
content: `Un-Promote Widget: ${widget.label ?? widget.name}`,
callback: () => {
demoteWidget(widget, node, parents)
}
})
}
}

View File

@@ -4,7 +4,7 @@ import { useSelectedLiteGraphItems } from '@/composables/canvas/useSelectedLiteG
import { useNodeAnimatedImage } from '@/composables/node/useNodeAnimatedImage'
import { useNodeCanvasImagePreview } from '@/composables/node/useNodeCanvasImagePreview'
import { useNodeImage, useNodeVideo } from '@/composables/node/useNodeImage'
import { promoteWidget } from '@/core/graph/subgraph/proxyWidgetUtils'
import { addWidgetPromotionOptions } from '@/core/graph/subgraph/proxyWidgetUtils'
import { st, t } from '@/i18n'
import {
type IContextMenuValue,
@@ -837,12 +837,7 @@ export const useLitegraphService = () => {
const [x, y] = canvas.canvas_mouse
const overWidget = this.getWidgetOnPos(x, y, true)
if (overWidget) {
options.unshift({
content: `Promote Widget: ${overWidget.label ?? overWidget.name}`,
callback: () => {
promoteWidget(overWidget, this)
}
})
addWidgetPromotionOptions(options, overWidget, this)
}
}