diff --git a/src/composables/useCoreCommands.ts b/src/composables/useCoreCommands.ts index dbcc96efc6..2acf3fad5c 100644 --- a/src/composables/useCoreCommands.ts +++ b/src/composables/useCoreCommands.ts @@ -5,7 +5,11 @@ import { DEFAULT_DARK_COLOR_PALETTE, DEFAULT_LIGHT_COLOR_PALETTE } from '@/constants/coreColorPalettes' -import { promoteRecommendedWidgets } from '@/core/graph/subgraph/proxyWidgetUtils' +import { + promoteRecommendedWidgets, + tryToggleWidgetPromotion +} from '@/core/graph/subgraph/proxyWidgetUtils' +import { showSubgraphNodeDialog } from '@/core/graph/subgraph/useSubgraphNodeDialog' import { t } from '@/i18n' import { LGraphEventMode, @@ -888,7 +892,7 @@ export function useCoreCommands(): ComfyCommand[] { }, { id: 'Comfy.Graph.ConvertToSubgraph', - icon: 'pi pi-sitemap', + icon: 'icon-[lucide--shrink]', label: 'Convert Selection to Subgraph', versionAdded: '1.20.1', category: 'essentials' as const, @@ -916,10 +920,9 @@ export function useCoreCommands(): ComfyCommand[] { }, { id: 'Comfy.Graph.UnpackSubgraph', - icon: 'pi pi-sitemap', + icon: 'icon-[lucide--expand]', label: 'Unpack the selected Subgraph', - versionAdded: '1.20.1', - category: 'essentials' as const, + versionAdded: '1.26.3', function: () => { const canvas = canvasStore.getCanvas() const graph = canvas.subgraph ?? canvas.graph @@ -931,6 +934,20 @@ export function useCoreCommands(): ComfyCommand[] { graph.unpackSubgraph(subgraphNode) } }, + { + id: 'Comfy.Graph.EditSubgraphWidgets', + label: 'Edit Subgraph Widgets', + icon: 'icon-[lucide--settings-2]', + versionAdded: '1.28.5', + function: showSubgraphNodeDialog + }, + { + id: 'Comfy.Graph.ToggleWidgetPromotion', + icon: 'icon-[lucide--arrow-left-right]', + label: 'Toggle promotion of hovered widget', + versionAdded: '1.30.1', + function: tryToggleWidgetPromotion + }, { id: 'Comfy.OpenManagerDialog', icon: 'mdi mdi-puzzle-outline', diff --git a/src/core/graph/subgraph/proxyWidgetUtils.ts b/src/core/graph/subgraph/proxyWidgetUtils.ts index 0c2e9bc232..f253d93ae3 100644 --- a/src/core/graph/subgraph/proxyWidgetUtils.ts +++ b/src/core/graph/subgraph/proxyWidgetUtils.ts @@ -1,11 +1,14 @@ import { parseProxyWidgets } from '@/core/schemas/proxyWidget' import type { ProxyWidgetsProperty } from '@/core/schemas/proxyWidget' +import { t } from '@/i18n' import type { IContextMenuValue, LGraphNode } from '@/lib/litegraph/src/litegraph' import type { SubgraphNode } from '@/lib/litegraph/src/subgraph/SubgraphNode' import type { IBaseWidget } from '@/lib/litegraph/src/types/widgets.ts' +import { useToastStore } from '@/platform/updates/common/toastStore' +import { useCanvasStore } from '@/renderer/core/canvas/canvasStore' import { useLitegraphService } from '@/services/litegraphService' import { useSubgraphNavigationStore } from '@/stores/subgraphNavigationStore' @@ -63,7 +66,15 @@ function getParentNodes(): SubgraphNode[] { //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") + if (!subgraph) { + useToastStore().add({ + severity: 'error', + summary: t('g.error'), + detail: t('subgraphStore.promoteOutsideSubgraph'), + life: 2000 + }) + return [] + } const parentGraph = navigationStack.at(-2) ?? subgraph.rootGraph return parentGraph.nodes.filter( (node): node is SubgraphNode => @@ -96,6 +107,21 @@ export function addWidgetPromotionOptions( }) } } +export function tryToggleWidgetPromotion() { + const canvas = useCanvasStore().getCanvas() + const [x, y] = canvas.graph_mouse + const node = canvas.graph?.getNodeOnPos(x, y, canvas.visible_nodes) + if (!node) return + const widget = node.getWidgetOnPos(x, y, true) + const parents = getParentNodes() + if (!parents.length || !widget) return + const promotableParents = parents.filter( + (s) => !getProxyWidgets(s).some(matchesPropertyItem([node, widget])) + ) + if (promotableParents.length > 0) + promoteWidget(node, widget, promotableParents) + else demoteWidget(node, widget, parents) +} const recommendedNodes = [ 'CLIPTextEncode', 'LoadImage', diff --git a/src/locales/en/main.json b/src/locales/en/main.json index 320c425574..b9f51b5abc 100644 --- a/src/locales/en/main.json +++ b/src/locales/en/main.json @@ -1102,6 +1102,7 @@ "overwriteBlueprintTitle": "Overwrite existing blueprint?", "overwriteBlueprint": "Saving will overwrite the current blueprint with your changes", "blueprintName": "Subgraph name", + "promoteOutsideSubgraph": "Can't promote widget when not in subgraph", "publish": "Publish Subgraph", "publishSuccess": "Saved to Nodes Library", "publishSuccessMessage": "You can find your subgraph blueprint in the nodes library under \"Subgraph Blueprints\"", diff --git a/src/services/litegraphService.ts b/src/services/litegraphService.ts index b731e978bd..c173f24a03 100644 --- a/src/services/litegraphService.ts +++ b/src/services/litegraphService.ts @@ -845,7 +845,7 @@ export const useLitegraphService = () => { ) } if (this.graph && !this.graph.isRootGraph) { - const [x, y] = canvas.canvas_mouse + const [x, y] = canvas.graph_mouse const overWidget = this.getWidgetOnPos(x, y, true) if (overWidget) { addWidgetPromotionOptions(options, overWidget, this)