Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
74 changes: 12 additions & 62 deletions src/renderer/extensions/vueNodes/components/LGraphNode.vue
Original file line number Diff line number Diff line change
Expand Up @@ -117,17 +117,14 @@
</div>
</template>

<!-- Resize handles -->
<template v-if="!isCollapsed">
<div
v-for="handle in cornerResizeHandles"
:key="handle.id"
role="button"
:aria-label="handle.ariaLabel"
:class="cn(baseResizeHandleClasses, handle.classes)"
@pointerdown.stop="handleResizePointerDown(handle.direction)($event)"
/>
</template>
<!-- Resize handle (bottom-right only) -->
<div
v-if="!isCollapsed"
role="button"
:aria-label="t('g.resizeFromBottomRight')"
:class="cn(baseResizeHandleClasses, 'right-0 bottom-0 cursor-se-resize')"
@pointerdown.stop="handleResizePointerDown"
/>
</div>
</template>

Expand Down Expand Up @@ -171,7 +168,6 @@ import {
} from '@/utils/graphTraversalUtil'
import { cn } from '@/utils/tailwindUtil'

import type { ResizeHandleDirection } from '../interactions/resize/resizeMath'
import { useNodeResize } from '../interactions/resize/useNodeResize'
import LivePreview from './LivePreview.vue'
import NodeContent from './NodeContent.vue'
Expand Down Expand Up @@ -263,7 +259,7 @@ onErrorCaptured((error) => {
return false // Prevent error propagation
})

const { position, size, zIndex, moveNodeTo } = useNodeLayout(() => nodeData.id)
const { position, size, zIndex } = useNodeLayout(() => nodeData.id)
const { pointerHandlers } = useNodePointerInteractions(() => nodeData.id)
const { onPointerdown, ...remainingPointerHandlers } = pointerHandlers
const { startDrag } = useNodeDrag()
Expand Down Expand Up @@ -314,41 +310,6 @@ onMounted(() => {

const baseResizeHandleClasses =
'absolute h-3 w-3 opacity-0 pointer-events-auto focus-visible:outline focus-visible:outline-2 focus-visible:outline-white/40'
const POSITION_EPSILON = 0.01

type CornerResizeHandle = {
id: string
direction: ResizeHandleDirection
classes: string
ariaLabel: string
}

const cornerResizeHandles: CornerResizeHandle[] = [
{
id: 'se',
direction: { horizontal: 'right', vertical: 'bottom' },
classes: 'right-0 bottom-0 cursor-se-resize',
ariaLabel: t('g.resizeFromBottomRight')
},
{
id: 'ne',
direction: { horizontal: 'right', vertical: 'top' },
classes: 'right-0 top-0 cursor-ne-resize',
ariaLabel: t('g.resizeFromTopRight')
},
{
id: 'sw',
direction: { horizontal: 'left', vertical: 'bottom' },
classes: 'left-0 bottom-0 cursor-sw-resize',
ariaLabel: t('g.resizeFromBottomLeft')
},
{
id: 'nw',
direction: { horizontal: 'left', vertical: 'top' },
classes: 'left-0 top-0 cursor-nw-resize',
ariaLabel: t('g.resizeFromTopLeft')
}
]

const MIN_NODE_WIDTH = 225

Expand All @@ -361,22 +322,11 @@ const { startResize } = useNodeResize((result, element) => {
// Apply size directly to DOM element - ResizeObserver will pick this up
element.style.setProperty('--node-width', `${clampedWidth}px`)
element.style.setProperty('--node-height', `${result.size.height}px`)

const currentPosition = position.value
const deltaX = Math.abs(result.position.x - currentPosition.x)
const deltaY = Math.abs(result.position.y - currentPosition.y)

if (deltaX > POSITION_EPSILON || deltaY > POSITION_EPSILON) {
moveNodeTo(result.position)
}
})

const handleResizePointerDown = (direction: ResizeHandleDirection) => {
return (event: PointerEvent) => {
if (nodeData.flags?.pinned) return

startResize(event, direction, { ...position.value })
}
const handleResizePointerDown = (event: PointerEvent) => {
if (nodeData.flags?.pinned) return
startResize(event)
}

watch(isCollapsed, (collapsed) => {
Expand Down
104 changes: 0 additions & 104 deletions src/renderer/extensions/vueNodes/interactions/resize/resizeMath.ts

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,14 @@ import { ref } from 'vue'
import type { Point, Size } from '@/renderer/core/layout/types'
import { useNodeSnap } from '@/renderer/extensions/vueNodes/composables/useNodeSnap'
import { useShiftKeySync } from '@/renderer/extensions/vueNodes/composables/useShiftKeySync'

import type { ResizeHandleDirection } from './resizeMath'
import { createResizeSession, toCanvasDelta } from './resizeMath'
import { useTransformState } from '@/renderer/core/layout/transform/useTransformState'

interface ResizeCallbackPayload {
size: Size
position: Point
}

/**
* Composable for node resizing functionality
* Composable for node resizing functionality (bottom-right corner only)
*
* Provides resize handle interaction that integrates with the layout system.
* Handles pointer capture, coordinate calculations, and size constraints.
Expand All @@ -27,28 +23,15 @@ export function useNodeResize(

const isResizing = ref(false)
const resizeStartPointer = ref<Point | null>(null)
const resizeSession = ref<
| ((
delta: Point,
snapFn?: (size: Size) => Size
) => {
size: Size
position: Point
})
| null
>(null)
const resizeStartSize = ref<Size | null>(null)

// Snap-to-grid functionality
const { shouldSnap, applySnapToSize } = useNodeSnap()

// Shift key sync for LiteGraph canvas preview
const { trackShiftKey } = useShiftKeySync()

const startResize = (
event: PointerEvent,
handle: ResizeHandleDirection,
startPosition: Point
) => {
const startResize = (event: PointerEvent) => {
event.preventDefault()
event.stopPropagation()

Expand All @@ -74,45 +57,44 @@ export function useNodeResize(

isResizing.value = true
resizeStartPointer.value = { x: event.clientX, y: event.clientY }
resizeSession.value = createResizeSession({
startSize,
startPosition: { ...startPosition },
handle
})
resizeStartSize.value = startSize

const handlePointerMove = (moveEvent: PointerEvent) => {
if (
!isResizing.value ||
!resizeStartPointer.value ||
!resizeSession.value
)
!resizeStartSize.value
) {
return
}

const scale = transformState.camera.z
const deltaX =
(moveEvent.clientX - resizeStartPointer.value.x) / (scale || 1)
const deltaY =
(moveEvent.clientY - resizeStartPointer.value.y) / (scale || 1)

const startPointer = resizeStartPointer.value
const session = resizeSession.value
let newSize: Size = {
width: resizeStartSize.value.width + deltaX,
height: resizeStartSize.value.height + deltaY
}

const delta = toCanvasDelta(
startPointer,
{ x: moveEvent.clientX, y: moveEvent.clientY },
transformState.camera.z
)
// Apply snap if shift is held
if (shouldSnap(moveEvent)) {
newSize = applySnapToSize(newSize)
}

const nodeElement = target.closest('[data-node-id]')
if (nodeElement instanceof HTMLElement) {
const outcome = session(
delta,
shouldSnap(moveEvent) ? applySnapToSize : undefined
)

resizeCallback(outcome, nodeElement)
resizeCallback({ size: newSize }, nodeElement)
}
}

const handlePointerUp = (upEvent: PointerEvent) => {
if (isResizing.value) {
isResizing.value = false
resizeStartPointer.value = null
resizeSession.value = null
resizeStartSize.value = null

// Stop tracking shift key state
stopShiftSync()
Expand Down
Loading
Loading