Remove COMFY_VUE_NODE_DIMENSIONS constant (#5398)

* Remove COMFY_VUE_NODE_DIMENSIONS

* Update litegraph snapshot test
This commit is contained in:
Benjamin Lu
2025-09-08 12:53:42 -07:00
committed by snomiao
parent 84d93af3ec
commit a53cf2da8b
10 changed files with 32 additions and 186 deletions

View File

@@ -3833,33 +3833,12 @@ export class LGraphNode
? this.getInputPos(slotIndex)
: this.getOutputPos(slotIndex)
if (LiteGraph.vueNodesMode) {
// Vue-based slot dimensions
const dimensions = LiteGraph.COMFY_VUE_NODE_DIMENSIONS.components
if (slot.isWidgetInputSlot) {
// Widget slots have a 20x20 clickable area centered at the position
slot.boundingRect[0] = pos[0] - 10
slot.boundingRect[1] = pos[1] - 10
slot.boundingRect[2] = 20
slot.boundingRect[3] = 20
} else {
// Regular slots have a 20x20 clickable area for the connector
// but the full slot height for vertical spacing
slot.boundingRect[0] = pos[0] - 10
slot.boundingRect[1] = pos[1] - dimensions.SLOT_HEIGHT / 2
slot.boundingRect[2] = 20
slot.boundingRect[3] = dimensions.SLOT_HEIGHT
}
} else {
// Traditional LiteGraph dimensions
slot.boundingRect[0] = pos[0] - LiteGraph.NODE_SLOT_HEIGHT * 0.5
slot.boundingRect[1] = pos[1] - LiteGraph.NODE_SLOT_HEIGHT * 0.5
slot.boundingRect[2] = slot.isWidgetInputSlot
? BaseWidget.margin
: LiteGraph.NODE_SLOT_HEIGHT
slot.boundingRect[3] = LiteGraph.NODE_SLOT_HEIGHT
}
slot.boundingRect[0] = pos[0] - LiteGraph.NODE_SLOT_HEIGHT * 0.5
slot.boundingRect[1] = pos[1] - LiteGraph.NODE_SLOT_HEIGHT * 0.5
slot.boundingRect[2] = slot.isWidgetInputSlot
? BaseWidget.margin
: LiteGraph.NODE_SLOT_HEIGHT
slot.boundingRect[3] = LiteGraph.NODE_SLOT_HEIGHT
}
#measureSlots(): ReadOnlyRect | null {

View File

@@ -24,26 +24,6 @@ import {
} from './types/globalEnums'
import { createUuidv4 } from './utils/uuid'
/**
* Vue node dimensions configuration for the contract between LiteGraph and Vue components.
* These values ensure both systems can independently calculate node, slot, and widget positions
* to place them in identical locations.
*
* IMPORTANT: These values must match the actual rendered dimensions of Vue components
* for the positioning contract to work correctly.
*/
export const COMFY_VUE_NODE_DIMENSIONS = {
spacing: {
BETWEEN_SLOTS_AND_BODY: 8,
BETWEEN_WIDGETS: 8
},
components: {
HEADER_HEIGHT: 34, // 18 header + 16 padding
SLOT_HEIGHT: 24,
STANDARD_WIDGET_HEIGHT: 30
}
} as const
/**
* The Global Scope. It contains all the registered node classes.
*/
@@ -95,14 +75,6 @@ export class LiteGraphGlobal {
WIDGET_SECONDARY_TEXT_COLOR = '#999'
WIDGET_DISABLED_TEXT_COLOR = '#666'
/**
* Vue node dimensions configuration for the contract between LiteGraph and Vue components.
* These values ensure both systems can independently calculate node, slot, and widget positions
* to place them in identical locations.
*/
// WARNING THIS WILL BE REMOVED IN FAVOR OF THE SLOTS LAYOUT TREE useDomSlotRegistration
COMFY_VUE_NODE_DIMENSIONS = COMFY_VUE_NODE_DIMENSIONS
LINK_COLOR = '#9A9'
EVENT_LINK_COLOR = '#A86'
CONNECTING_LINK_COLOR = '#AFA'

View File

@@ -104,7 +104,6 @@ export { BadgePosition, LGraphBadge } from './LGraphBadge'
export { LGraphCanvas } from './LGraphCanvas'
export { LGraphGroup } from './LGraphGroup'
export { LGraphNode, type NodeId } from './LGraphNode'
export { COMFY_VUE_NODE_DIMENSIONS } from './LiteGraphGlobal'
export { LLink } from './LLink'
export { createBounds } from './measure'
export { Reroute, type RerouteId } from './Reroute'

View File

@@ -9,7 +9,6 @@ import type { LGraphNode } from '@/lib/litegraph/src/LGraphNode'
import type {
INodeInputSlot,
INodeOutputSlot,
INodeSlot,
Point,
ReadOnlyPoint
} from '@/lib/litegraph/src/interfaces'
@@ -79,21 +78,6 @@ export function calculateInputSlotPosFromSlot(
const { pos } = input
if (pos) return [nodeX + pos[0], nodeY + pos[1]]
// Check if we should use Vue positioning
if (LiteGraph.vueNodesMode) {
if (isWidgetInputSlot(input)) {
// Widget slot - pass the slot object
return calculateVueSlotPosition(context, true, input, -1)
} else {
// Regular slot - find its index in default vertical inputs
const defaultVerticalInputs = getDefaultVerticalInputs(context)
const slotIndex = defaultVerticalInputs.indexOf(input)
if (slotIndex !== -1) {
return calculateVueSlotPosition(context, true, input, slotIndex)
}
}
}
// Default vertical slots
const offsetX = LiteGraph.NODE_SLOT_HEIGHT * 0.5
const nodeOffsetY = context.slotStartY || 0
@@ -131,15 +115,6 @@ export function calculateOutputSlotPos(
const outputPos = outputSlot.pos
if (outputPos) return [nodeX + outputPos[0], nodeY + outputPos[1]]
// Check if we should use Vue positioning
if (LiteGraph.vueNodesMode) {
const defaultVerticalOutputs = getDefaultVerticalOutputs(context)
const slotIndex = defaultVerticalOutputs.indexOf(outputSlot)
if (slotIndex !== -1) {
return calculateVueSlotPosition(context, false, outputSlot, slotIndex)
}
}
// Default vertical slots
const offsetX = LiteGraph.NODE_SLOT_HEIGHT * 0.5
const nodeOffsetY = context.slotStartY || 0
@@ -195,8 +170,23 @@ export function getSlotPosition(
: calculateOutputSlotPos(context, slotIndex)
}
// Fallback to node's own methods if layout not available
return isInput ? node.getInputPos(slotIndex) : node.getOutputPos(slotIndex)
// Fallback: calculate directly from node properties if layout not available
const context: SlotPositionContext = {
nodeX: node.pos[0],
nodeY: node.pos[1],
nodeWidth: node.size[0],
nodeHeight: node.size[1],
collapsed: node.flags.collapsed || false,
collapsedWidth: node._collapsed_width,
slotStartY: node.constructor.slot_start_y,
inputs: node.inputs,
outputs: node.outputs,
widgets: node.widgets
}
return isInput
? calculateInputSlotPos(context, slotIndex)
: calculateOutputSlotPos(context, slotIndex)
}
/**
@@ -218,66 +208,3 @@ function getDefaultVerticalOutputs(
): INodeOutputSlot[] {
return context.outputs.filter((slot) => !slot.pos)
}
/**
* Calculate slot position using Vue node dimensions.
* This method uses the COMFY_VUE_NODE_DIMENSIONS constants to match Vue component rendering.
* @param context Node context
* @param isInput Whether this is an input slot (true) or output slot (false)
* @param slot The slot object (for widget detection)
* @param slotIndex The index of the slot in the appropriate array
* @returns The [x, y] position of the slot center in graph coordinates
*/
function calculateVueSlotPosition(
context: SlotPositionContext,
isInput: boolean,
slot: INodeSlot,
slotIndex: number
): Point {
const { nodeX, nodeY, nodeWidth, widgets } = context
const dimensions = LiteGraph.COMFY_VUE_NODE_DIMENSIONS.components
const spacing = LiteGraph.COMFY_VUE_NODE_DIMENSIONS.spacing
let slotCenterY: number
// IMPORTANT: LiteGraph's node position (nodeY) is at the TOP of the body (below the header)
// The header is rendered ABOVE this position at negative Y coordinates
// So we need to adjust for the difference between LiteGraph's header (30px) and Vue's header (34px)
const headerDifference =
dimensions.HEADER_HEIGHT - LiteGraph.NODE_TITLE_HEIGHT
if (isInput && isWidgetInputSlot(slot as INodeInputSlot)) {
// Widget input slot - calculate based on widget position
// Count regular (non-widget) input slots
const regularInputCount = getDefaultVerticalInputs(context).length
// Find widget index
const widgetIndex =
widgets?.findIndex(
(w) => w.name === (slot as INodeInputSlot).widget?.name
) ?? 0
// Y position relative to the node body top (not the header)
slotCenterY =
headerDifference +
regularInputCount * dimensions.SLOT_HEIGHT +
(regularInputCount > 0 ? spacing.BETWEEN_SLOTS_AND_BODY : 0) +
widgetIndex *
(dimensions.STANDARD_WIDGET_HEIGHT + spacing.BETWEEN_WIDGETS) +
dimensions.STANDARD_WIDGET_HEIGHT / 2
} else {
// Regular slot (input or output)
// Slots start at the top of the body, but we need to account for Vue's larger header
slotCenterY =
headerDifference +
slotIndex * dimensions.SLOT_HEIGHT +
dimensions.SLOT_HEIGHT / 2
}
// Calculate X position
// Input slots: 10px from left edge (center of 20x20 connector)
// Output slots: 10px from right edge (center of 20x20 connector)
const slotCenterX = isInput ? 10 : nodeWidth - 10
return [nodeX + slotCenterX, nodeY + slotCenterY]
}

View File

@@ -2,7 +2,7 @@
<div v-if="renderError" class="node-error p-1 text-red-500 text-xs"></div>
<div
v-else
class="lg-slot lg-slot--input flex items-center cursor-crosshair group rounded-r-lg"
class="lg-slot lg-slot--input flex items-center cursor-crosshair group rounded-r-lg h-6"
:class="{
'opacity-70': readonly,
'lg-slot--connected': connected,
@@ -10,9 +10,6 @@
'lg-slot--dot-only': dotOnly,
'pr-6 hover:bg-black/5 hover:dark:bg-white/5': !dotOnly
}"
:style="{
height: slotHeight + 'px'
}"
>
<!-- Connection Dot -->
<SlotConnectionDot
@@ -43,11 +40,7 @@ import {
import { useErrorHandling } from '@/composables/useErrorHandling'
import { getSlotColor } from '@/constants/slotColors'
import {
COMFY_VUE_NODE_DIMENSIONS,
INodeSlot,
LGraphNode
} from '@/lib/litegraph/src/litegraph'
import { INodeSlot, LGraphNode } from '@/lib/litegraph/src/litegraph'
// DOM-based slot registration for arbitrary positioning
import {
type TransformState,
@@ -82,9 +75,6 @@ onErrorCaptured((error) => {
// Get slot color based on type
const slotColor = computed(() => getSlotColor(props.slotData.type))
// Get slot height from litegraph constants
const slotHeight = COMFY_VUE_NODE_DIMENSIONS.components.SLOT_HEIGHT
const transformState = inject<TransformState | undefined>(
'transformState',
undefined

View File

@@ -2,7 +2,7 @@
<div v-if="renderError" class="node-error p-1 text-red-500 text-xs"></div>
<div
v-else
class="lg-slot lg-slot--output flex items-center cursor-crosshair justify-end group rounded-l-lg"
class="lg-slot lg-slot--output flex items-center cursor-crosshair justify-end group rounded-l-lg h-6"
:class="{
'opacity-70': readonly,
'lg-slot--connected': connected,
@@ -11,9 +11,6 @@
'pl-6 hover:bg-black/5 hover:dark:bg-white/5': !dotOnly,
'justify-center': dotOnly
}"
:style="{
height: slotHeight + 'px'
}"
>
<!-- Slot Name -->
<span
@@ -45,7 +42,6 @@ import {
import { useErrorHandling } from '@/composables/useErrorHandling'
import { getSlotColor } from '@/constants/slotColors'
import type { INodeSlot, LGraphNode } from '@/lib/litegraph/src/litegraph'
import { COMFY_VUE_NODE_DIMENSIONS } from '@/lib/litegraph/src/litegraph'
// DOM-based slot registration for arbitrary positioning
import {
type TransformState,
@@ -81,9 +77,6 @@ onErrorCaptured((error) => {
// Get slot color based on type
const slotColor = computed(() => getSlotColor(props.slotData.type))
// Get slot height from litegraph constants
const slotHeight = COMFY_VUE_NODE_DIMENSIONS.components.SLOT_HEIGHT
const transformState = inject<TransformState | undefined>(
'transformState',
undefined

View File

@@ -1,21 +1,16 @@
<script setup lang="ts">
import { noop } from 'es-toolkit'
import { COMFY_VUE_NODE_DIMENSIONS } from '@/lib/litegraph/src/litegraph'
import { SimplifiedWidget } from '@/types/simplifiedWidget'
defineProps<{
widget: Pick<SimplifiedWidget<string | number | undefined>, 'name'>
}>()
// Get widget height from litegraph constants
const widgetHeight = COMFY_VUE_NODE_DIMENSIONS.components.STANDARD_WIDGET_HEIGHT
</script>
<template>
<div
class="flex items-center justify-between gap-2 overscroll-contain"
:style="{ height: widgetHeight + 'px' }"
class="flex items-center justify-between gap-2 h-[30px] overscroll-contain"
>
<p
v-if="widget.name"

View File

@@ -1,8 +1,10 @@
import { beforeEach, describe, expect, it, vi } from 'vitest'
import { ref } from 'vue'
import type { VueNodeData } from '@/composables/graph/useGraphNodeManager'
import { useGraphNodeManager } from '@/composables/graph/useGraphNodeManager'
import type {
VueNodeData,
useGraphNodeManager
} from '@/composables/graph/useGraphNodeManager'
import { useNodeEventHandlers } from '@/composables/graph/useNodeEventHandlers'
import type { LGraphCanvas, LGraphNode } from '@/lib/litegraph/src/litegraph'
import { useLayoutMutations } from '@/renderer/core/layout/operations/layoutMutations'

View File

@@ -11,17 +11,6 @@ LiteGraphGlobal {
"CARD_SHAPE": 4,
"CENTER": 5,
"CIRCLE_SHAPE": 3,
"COMFY_VUE_NODE_DIMENSIONS": {
"components": {
"HEADER_HEIGHT": 34,
"SLOT_HEIGHT": 24,
"STANDARD_WIDGET_HEIGHT": 30,
},
"spacing": {
"BETWEEN_SLOTS_AND_BODY": 8,
"BETWEEN_WIDGETS": 8,
},
},
"CONNECTING_LINK_COLOR": "#AFA",
"Classes": {
"InputIndicators": [Function],

View File

@@ -113,7 +113,7 @@ describe('useSubgraphStore', () => {
})
it('should allow subgraphs to be edited', async () => {
await mockFetch({ 'test.json': mockGraph })
store.editBlueprint(store.typePrefix + 'test')
await store.editBlueprint(store.typePrefix + 'test')
//check active graph
expect(comfyApp.loadGraphData).toHaveBeenCalled()
})