dom widget promotion

This commit is contained in:
bymyself
2025-07-15 22:39:52 -07:00
parent 7f774542f7
commit a5f165cdf1
3 changed files with 54 additions and 11 deletions

View File

@@ -11,7 +11,6 @@
</template>
<script setup lang="ts">
import type { LGraphNode } from '@comfyorg/litegraph'
import { whenever } from '@vueuse/core'
import { computed } from 'vue'
@@ -21,24 +20,37 @@ import { useDomWidgetStore } from '@/stores/domWidgetStore'
import { useCanvasStore } from '@/stores/graphStore'
const domWidgetStore = useDomWidgetStore()
const widgetStates = computed(() => domWidgetStore.activeWidgetStates)
const widgetStates = computed(() => {
return [
...domWidgetStore.activeWidgetStates,
...domWidgetStore.inactiveWidgetStates
]
})
const updateWidgets = () => {
const lgCanvas = canvasStore.canvas
if (!lgCanvas) return
const lowQuality = lgCanvas.low_quality
const currentGraph = lgCanvas.graph
for (const widgetState of widgetStates.value) {
const widget = widgetState.widget
const node = widget.node as LGraphNode
// Use containerNode for promoted widgets, otherwise use widget.node
const node = widget.containerNode || widget.node
const visible =
node &&
currentGraph?.nodes.includes(node) &&
lgCanvas.isNodeVisible(node) &&
!(widget.options.hideOnZoom && lowQuality) &&
widget.isVisible()
widgetState.visible = visible
if (visible) {
widgetState.visible = visible ?? false
if (widgetState.visible && node) {
const margin = widget.margin
widgetState.pos = [node.pos[0] + margin, node.pos[1] + margin + widget.y]
widgetState.size = [

View File

@@ -61,10 +61,15 @@ const updateDomClipping = () => {
if (!lgCanvas || !widgetElement.value) return
const selectedNode = Object.values(lgCanvas.selected_nodes ?? {})[0]
if (!selectedNode) return
if (!selectedNode) {
// Clear clipping when no node is selected
updateClipPath(widgetElement.value, lgCanvas.canvas, false, undefined)
return
}
const node = widget.node
const isSelected = selectedNode === node
// Use containerNode for promoted widgets, otherwise use widget.node
const positioningNode = widget.containerNode || widget.node
const isSelected = selectedNode === positioningNode
const renderArea = selectedNode?.renderArea
const offset = lgCanvas.ds.offset
const scale = lgCanvas.ds.scale
@@ -143,11 +148,28 @@ if (isDOMWidget(widget)) {
const inputSpec = widget.node.constructor.nodeData
const tooltip = inputSpec?.inputs?.[widget.name]?.tooltip
onMounted(() => {
if (isDOMWidget(widget) && widgetElement.value) {
widgetElement.value.appendChild(widget.element)
// Mount DOM element when widget is or becomes visible
const mountElementIfVisible = () => {
if (widgetState.visible && isDOMWidget(widget) && widgetElement.value) {
// Only append if not already a child
if (!widgetElement.value.contains(widget.element)) {
widgetElement.value.appendChild(widget.element)
}
}
}
// Check on mount
onMounted(() => {
mountElementIfVisible()
})
// And watch for visibility changes
watch(
() => widgetState.visible,
() => {
mountElementIfVisible()
}
)
</script>
<style scoped>

View File

@@ -33,6 +33,7 @@ import type {
import type { ComfyNodeDef as ComfyNodeDefV1 } from '@/schemas/nodeDefSchema'
import { ComfyApp, app } from '@/scripts/app'
import { $el } from '@/scripts/ui'
import { useDomWidgetStore } from '@/stores/domWidgetStore'
import { useExecutionStore } from '@/stores/executionStore'
import { useCanvasStore } from '@/stores/graphStore'
import { useNodeOutputStore } from '@/stores/imagePreviewStore'
@@ -88,6 +89,14 @@ export const useLitegraphService = () => {
constructor() {
super(app.graph, subgraph, instanceData)
// Set up callback for promoted widget registration
this.onPromotedWidgetAdded = (widget) => {
const domWidgetStore = useDomWidgetStore()
if (!domWidgetStore.widgetStates.has(widget.id)) {
domWidgetStore.registerWidget(widget)
}
}
this.#setupStrokeStyles()
this.#addInputs(ComfyNode.nodeData.inputs)
this.#addOutputs(ComfyNode.nodeData.outputs)