mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-02-05 15:40:10 +00:00
Remove COMFY_VUE_NODE_DIMENSIONS constant (#5398)
* Remove COMFY_VUE_NODE_DIMENSIONS * Update litegraph snapshot test
This commit is contained in:
@@ -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 {
|
||||
|
||||
@@ -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'
|
||||
|
||||
@@ -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'
|
||||
|
||||
@@ -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]
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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'
|
||||
|
||||
@@ -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],
|
||||
|
||||
@@ -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()
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user