diff --git a/src/composables/canvas/useSelectionToolboxPosition.ts b/src/composables/canvas/useSelectionToolboxPosition.ts index e98d4d5ef..75dca4b2e 100644 --- a/src/composables/canvas/useSelectionToolboxPosition.ts +++ b/src/composables/canvas/useSelectionToolboxPosition.ts @@ -4,7 +4,7 @@ import type { Ref } from 'vue' import { useCanvasTransformSync } from '@/composables/canvas/useCanvasTransformSync' import { useSelectedLiteGraphItems } from '@/composables/canvas/useSelectedLiteGraphItems' import { useVueFeatureFlags } from '@/composables/useVueFeatureFlags' -import type { ReadOnlyRect } from '@/lib/litegraph/src/interfaces' +import type { Rect } from '@/lib/litegraph/src/interfaces' import { LGraphNode } from '@/lib/litegraph/src/litegraph' import { useCanvasStore } from '@/renderer/core/canvas/canvasStore' import { layoutStore } from '@/renderer/core/layout/store/layoutStore' @@ -71,7 +71,7 @@ export function useSelectionToolboxPosition( visible.value = true // Get bounds for all selected items - const allBounds: ReadOnlyRect[] = [] + const allBounds: Rect[] = [] for (const item of selectableItems) { // Skip items without valid IDs if (item.id == null) continue diff --git a/src/lib/litegraph/src/DragAndScale.ts b/src/lib/litegraph/src/DragAndScale.ts index c71fca2d2..4d921ba78 100644 --- a/src/lib/litegraph/src/DragAndScale.ts +++ b/src/lib/litegraph/src/DragAndScale.ts @@ -1,4 +1,4 @@ -import type { Point, ReadOnlyRect, Rect } from './interfaces' +import type { Point, Rect } from './interfaces' import { EaseFunction, Rectangle } from './litegraph' export interface DragAndScaleState { @@ -188,10 +188,7 @@ export class DragAndScale { * Fits the view to the specified bounds. * @param bounds The bounds to fit the view to, defined by a rectangle. */ - fitToBounds( - bounds: ReadOnlyRect, - { zoom = 0.75 }: { zoom?: number } = {} - ): void { + fitToBounds(bounds: Rect, { zoom = 0.75 }: { zoom?: number } = {}): void { const cw = this.element.width / window.devicePixelRatio const ch = this.element.height / window.devicePixelRatio let targetScale = this.scale @@ -223,7 +220,7 @@ export class DragAndScale { * @param bounds The bounds to animate the view to, defined by a rectangle. */ animateToBounds( - bounds: ReadOnlyRect, + bounds: Rect | Rectangle, setDirty: () => void, { duration = 350, diff --git a/src/lib/litegraph/src/LGraph.ts b/src/lib/litegraph/src/LGraph.ts index 139919c60..466db7521 100644 --- a/src/lib/litegraph/src/LGraph.ts +++ b/src/lib/litegraph/src/LGraph.ts @@ -4,6 +4,7 @@ import { SUBGRAPH_INPUT_ID, SUBGRAPH_OUTPUT_ID } from '@/lib/litegraph/src/constants' +import { Rectangle } from '@/lib/litegraph/src/infrastructure/Rectangle' import type { UUID } from '@/lib/litegraph/src/utils/uuid' import { createUuidv4, zeroUuid } from '@/lib/litegraph/src/utils/uuid' import { useLayoutMutations } from '@/renderer/core/layout/operations/layoutMutations' @@ -1707,7 +1708,12 @@ export class LGraph ...subgraphNode.subgraph.groups ].map((p: { pos: Point; size?: Size }): HasBoundingRect => { return { - boundingRect: [p.pos[0], p.pos[1], p.size?.[0] ?? 0, p.size?.[1] ?? 0] + boundingRect: new Rectangle( + p.pos[0], + p.pos[1], + p.size?.[0] ?? 0, + p.size?.[1] ?? 0 + ) } }) const bounds = createBounds(positionables) ?? [0, 0, 0, 0] diff --git a/src/lib/litegraph/src/LGraphCanvas.ts b/src/lib/litegraph/src/LGraphCanvas.ts index 6ef5fa417..1ee1c68ef 100644 --- a/src/lib/litegraph/src/LGraphCanvas.ts +++ b/src/lib/litegraph/src/LGraphCanvas.ts @@ -47,8 +47,6 @@ import type { NullableProperties, Point, Positionable, - ReadOnlyPoint, - ReadOnlyRect, Rect, Size } from './interfaces' @@ -628,7 +626,7 @@ export class LGraphCanvas dirty_area?: Rect | null /** @deprecated Unused */ node_in_panel?: LGraphNode | null - last_mouse: ReadOnlyPoint = [0, 0] + last_mouse: Point = [0, 0] last_mouseclick: number = 0 graph: LGraph | Subgraph | null get _graph(): LGraph | Subgraph { @@ -3166,7 +3164,7 @@ export class LGraphCanvas LGraphCanvas.active_canvas = this this.adjustMouseEvent(e) - const mouse: ReadOnlyPoint = [e.clientX, e.clientY] + const mouse: Point = [e.clientX, e.clientY] this.mouse[0] = mouse[0] this.mouse[1] = mouse[1] const delta = [mouse[0] - this.last_mouse[0], mouse[1] - this.last_mouse[1]] @@ -4829,7 +4827,7 @@ export class LGraphCanvas } /** Get the target snap / highlight point in graph space */ - #getHighlightPosition(): ReadOnlyPoint { + #getHighlightPosition(): Point { return LiteGraph.snaps_for_comfy ? this.linkConnector.state.snapLinksPos ?? this._highlight_pos ?? @@ -4844,7 +4842,7 @@ export class LGraphCanvas */ #renderSnapHighlight( ctx: CanvasRenderingContext2D, - highlightPos: ReadOnlyPoint + highlightPos: Point ): void { const linkConnectorSnap = !!this.linkConnector.state.snapLinksPos if (!this._highlight_pos && !linkConnectorSnap) return @@ -5930,8 +5928,8 @@ export class LGraphCanvas */ renderLink( ctx: CanvasRenderingContext2D, - a: ReadOnlyPoint, - b: ReadOnlyPoint, + a: Point, + b: Point, link: LLink | null, skip_border: boolean, flow: number | null, @@ -5948,9 +5946,9 @@ export class LGraphCanvas /** When defined, render data will be saved to this reroute instead of the {@link link}. */ reroute?: Reroute /** Offset of the bezier curve control point from {@link a point a} (output side) */ - startControl?: ReadOnlyPoint + startControl?: Point /** Offset of the bezier curve control point from {@link b point b} (input side) */ - endControl?: ReadOnlyPoint + endControl?: Point /** Number of sublines (useful to represent vec3 or rgb) @todo If implemented, refactor calculations out of the loop */ num_sublines?: number /** Whether this is a floating link segment */ @@ -8421,7 +8419,7 @@ export class LGraphCanvas * Starts an animation to fit the view around the specified selection of nodes. * @param bounds The bounds to animate the view to, defined by a rectangle. */ - animateToBounds(bounds: ReadOnlyRect, options: AnimationOptions = {}) { + animateToBounds(bounds: Rect | Rectangle, options: AnimationOptions = {}) { const setDirty = () => this.setDirty(true, true) this.ds.animateToBounds(bounds, setDirty, options) } diff --git a/src/lib/litegraph/src/LGraphGroup.ts b/src/lib/litegraph/src/LGraphGroup.ts index d2e306c9d..f7138c157 100644 --- a/src/lib/litegraph/src/LGraphGroup.ts +++ b/src/lib/litegraph/src/LGraphGroup.ts @@ -1,4 +1,5 @@ import { NullGraphError } from '@/lib/litegraph/src/infrastructure/NullGraphError' +import { Rectangle } from '@/lib/litegraph/src/infrastructure/Rectangle' import type { LGraph } from './LGraph' import { LGraphCanvas } from './LGraphCanvas' @@ -11,7 +12,6 @@ import type { IPinnable, Point, Positionable, - ReadOnlyRect, Size } from './interfaces' import { LiteGraph } from './litegraph' @@ -108,8 +108,13 @@ export class LGraphGroup implements Positionable, IPinnable, IColorable { this._size[1] = Math.max(LGraphGroup.minHeight, v[1]) } - get boundingRect(): ReadOnlyRect { - return [this._pos[0], this._pos[1], this._size[0], this._size[1]] as const + get boundingRect(): Rectangle { + return Rectangle.from([ + this._pos[0], + this._pos[1], + this._size[0], + this._size[1] + ]) } get nodes() { @@ -214,7 +219,7 @@ export class LGraphGroup implements Positionable, IPinnable, IColorable { ) if (LiteGraph.highlight_selected_group && this.selected) { - strokeShape(ctx, [...this.boundingRect], { + strokeShape(ctx, this.boundingRect, { title_height: this.titleHeight, padding }) diff --git a/src/lib/litegraph/src/LGraphNode.ts b/src/lib/litegraph/src/LGraphNode.ts index c76db298a..8c9014361 100644 --- a/src/lib/litegraph/src/LGraphNode.ts +++ b/src/lib/litegraph/src/LGraphNode.ts @@ -18,7 +18,6 @@ import type { Reroute, RerouteId } from './Reroute' import { getNodeInputOnPos, getNodeOutputOnPos } from './canvas/measureSlots' import type { IDrawBoundingOptions } from './draw' import { NullGraphError } from './infrastructure/NullGraphError' -import type { ReadOnlyRectangle } from './infrastructure/Rectangle' import { Rectangle } from './infrastructure/Rectangle' import type { ColorOption, @@ -37,8 +36,6 @@ import type { ISlotType, Point, Positionable, - ReadOnlyPoint, - ReadOnlyRect, Rect, Size } from './interfaces' @@ -387,7 +384,7 @@ export class LGraphNode * Called once at the start of every frame. Caller may change the values in {@link out}, which will be reflected in {@link boundingRect}. * WARNING: Making changes to boundingRect via onBounding is poorly supported, and will likely result in strange behaviour. */ - onBounding?(this: LGraphNode, out: Rect): void + onBounding?(this: LGraphNode, out: Rectangle): void console?: string[] _level?: number _shape?: RenderShape @@ -418,7 +415,7 @@ export class LGraphNode * Rect describing the node area, including shadows and any protrusions. * Determines if the node is visible. Calculated once at the start of every frame. */ - get renderArea(): ReadOnlyRect { + get renderArea(): Rect { return this.#renderArea } @@ -429,12 +426,12 @@ export class LGraphNode * * Determines the node hitbox and other rendering effects. Calculated once at the start of every frame. */ - get boundingRect(): ReadOnlyRectangle { + get boundingRect(): Rectangle { return this.#boundingRect } /** The offset from {@link pos} to the top-left of {@link boundingRect}. */ - get boundingOffset(): ReadOnlyPoint { + get boundingOffset(): Point { const { pos: [posX, posY], boundingRect: [bX, bY] @@ -1978,7 +1975,7 @@ export class LGraphNode * @param out `x, y, width, height` are written to this array. * @param ctx The canvas context to use for measuring text. */ - measure(out: Rect, ctx: CanvasRenderingContext2D): void { + measure(out: Rectangle, ctx: CanvasRenderingContext2D): void { const titleMode = this.title_mode const renderTitle = titleMode != TitleMode.TRANSPARENT_TITLE && @@ -3844,7 +3841,7 @@ export class LGraphNode slot.boundingRect[3] = LiteGraph.NODE_SLOT_HEIGHT } - #measureSlots(): ReadOnlyRect | null { + #measureSlots(): Rect | null { const slots: (NodeInputSlot | NodeOutputSlot)[] = [] for (const [slotIndex, slot] of this.#concreteInputs.entries()) { diff --git a/src/lib/litegraph/src/Reroute.ts b/src/lib/litegraph/src/Reroute.ts index 0d8026b14..f21b6631a 100644 --- a/src/lib/litegraph/src/Reroute.ts +++ b/src/lib/litegraph/src/Reroute.ts @@ -1,3 +1,4 @@ +import { Rectangle } from '@/lib/litegraph/src/infrastructure/Rectangle' import { useLayoutMutations } from '@/renderer/core/layout/operations/layoutMutations' import { LayoutSource } from '@/renderer/core/layout/types' @@ -12,8 +13,8 @@ import type { LinkSegment, Point, Positionable, - ReadOnlyRect, - ReadonlyLinkNetwork + ReadonlyLinkNetwork, + Rect } from './interfaces' import { distance, isPointInRect } from './measure' import type { Serialisable, SerialisableReroute } from './types/serialisation' @@ -87,17 +88,17 @@ export class Reroute } /** @inheritdoc */ - get boundingRect(): ReadOnlyRect { + get boundingRect(): Rectangle { const { radius } = Reroute const [x, y] = this.#pos - return [x - radius, y - radius, 2 * radius, 2 * radius] + return Rectangle.from([x - radius, y - radius, 2 * radius, 2 * radius]) } /** * Slightly over-sized rectangle, guaranteed to contain the entire surface area for hover detection. * Eliminates most hover positions using an extremely cheap check. */ - get #hoverArea(): ReadOnlyRect { + get #hoverArea(): Rect { const xOffset = 2 * Reroute.slotOffset const yOffset = 2 * Math.max(Reroute.radius, Reroute.slotRadius) diff --git a/src/lib/litegraph/src/draw.ts b/src/lib/litegraph/src/draw.ts index 2b8987ef8..b8510e1a9 100644 --- a/src/lib/litegraph/src/draw.ts +++ b/src/lib/litegraph/src/draw.ts @@ -67,7 +67,7 @@ interface IDrawTextInAreaOptions { */ export function strokeShape( ctx: CanvasRenderingContext2D, - area: Rect, + area: Rect | Rectangle, { shape = RenderShape.BOX, round_radius, diff --git a/src/lib/litegraph/src/infrastructure/ConstrainedSize.ts b/src/lib/litegraph/src/infrastructure/ConstrainedSize.ts index 3238e4d29..07d0be16e 100644 --- a/src/lib/litegraph/src/infrastructure/ConstrainedSize.ts +++ b/src/lib/litegraph/src/infrastructure/ConstrainedSize.ts @@ -1,10 +1,6 @@ import { clamp } from 'es-toolkit/compat' -import type { - ReadOnlyRect, - ReadOnlySize, - Size -} from '@/lib/litegraph/src/interfaces' +import type { Rect, Size } from '@/lib/litegraph/src/interfaces' /** * Basic width and height, with min/max constraints. @@ -55,15 +51,15 @@ export class ConstrainedSize { this.desiredHeight = height } - static fromSize(size: ReadOnlySize): ConstrainedSize { + static fromSize(size: Size): ConstrainedSize { return new ConstrainedSize(size[0], size[1]) } - static fromRect(rect: ReadOnlyRect): ConstrainedSize { + static fromRect(rect: Rect): ConstrainedSize { return new ConstrainedSize(rect[2], rect[3]) } - setSize(size: ReadOnlySize): void { + setSize(size: Size): void { this.desiredWidth = size[0] this.desiredHeight = size[1] } diff --git a/src/lib/litegraph/src/infrastructure/LGraphEventMap.ts b/src/lib/litegraph/src/infrastructure/LGraphEventMap.ts index dcf836a3e..cec1fb8d5 100644 --- a/src/lib/litegraph/src/infrastructure/LGraphEventMap.ts +++ b/src/lib/litegraph/src/infrastructure/LGraphEventMap.ts @@ -1,6 +1,6 @@ import type { LGraph } from '@/lib/litegraph/src/LGraph' import type { LLink, ResolvedConnection } from '@/lib/litegraph/src/LLink' -import type { ReadOnlyRect } from '@/lib/litegraph/src/interfaces' +import type { Rect } from '@/lib/litegraph/src/interfaces' import type { Subgraph } from '@/lib/litegraph/src/subgraph/Subgraph' import type { ExportedSubgraph, @@ -29,7 +29,7 @@ export interface LGraphEventMap { /** The type of subgraph to create. */ subgraph: Subgraph /** The boundary around every item that was moved into the subgraph. */ - bounds: ReadOnlyRect + bounds: Rect /** The raw data that was used to create the subgraph. */ exportedSubgraph: ExportedSubgraph /** The links that were used to create the subgraph. */ diff --git a/src/lib/litegraph/src/infrastructure/Rectangle.ts b/src/lib/litegraph/src/infrastructure/Rectangle.ts index 4403848b6..35bd17226 100644 --- a/src/lib/litegraph/src/infrastructure/Rectangle.ts +++ b/src/lib/litegraph/src/infrastructure/Rectangle.ts @@ -1,9 +1,7 @@ import type { CompassCorners, Point, - ReadOnlyPoint, - ReadOnlyRect, - ReadOnlySize, + Rect, Size } from '@/lib/litegraph/src/interfaces' import { isInRectangle } from '@/lib/litegraph/src/measure' @@ -29,7 +27,7 @@ export class Rectangle extends Array { this.length = 4 } - static override from([x, y, width, height]: ReadOnlyRect): Rectangle { + static override from([x, y, width, height]: Rect): Rectangle { return new Rectangle(x, y, width, height) } @@ -54,17 +52,13 @@ export class Rectangle extends Array { * @param height The height of the rectangle. Default: {@link width} * @returns A new rectangle whose centre is at {@link x} */ - static fromCentre( - [x, y]: ReadOnlyPoint, - width: number, - height = width - ): Rectangle { + static fromCentre([x, y]: Point, width: number, height = width): Rectangle { const left = x - width * 0.5 const top = y - height * 0.5 return new Rectangle(left, top, width, height) } - static ensureRect(rect: ReadOnlyRect): Rectangle { + static ensureRect(rect: Rect | Rectangle): Rectangle { return rect instanceof Rectangle ? rect : new Rectangle(rect[0], rect[1], rect[2], rect[3]) @@ -77,7 +71,7 @@ export class Rectangle extends Array { return [this[0], this[1]] } - set pos(value: ReadOnlyPoint) { + set pos(value: Point) { this[0] = value[0] this[1] = value[1] } @@ -89,7 +83,7 @@ export class Rectangle extends Array { return [this[2], this[3]] } - set size(value: ReadOnlySize) { + set size(value: Size) { this[2] = value[0] this[3] = value[1] } @@ -182,7 +176,7 @@ export class Rectangle extends Array { * Updates the rectangle to the values of {@link rect}. * @param rect The rectangle to update to. */ - updateTo(rect: ReadOnlyRect) { + updateTo(rect: Rect) { this[0] = rect[0] this[1] = rect[1] this[2] = rect[2] @@ -205,7 +199,7 @@ export class Rectangle extends Array { * @param point The point to check * @returns `true` if {@link point} is inside this rectangle, otherwise `false`. */ - containsPoint([x, y]: ReadOnlyPoint): boolean { + containsPoint([x, y]: Point): boolean { const [left, top, width, height] = this return x >= left && x < left + width && y >= top && y < top + height } @@ -216,7 +210,7 @@ export class Rectangle extends Array { * @param other The rectangle to check * @returns `true` if {@link other} is inside this rectangle, otherwise `false`. */ - containsRect(other: ReadOnlyRect): boolean { + containsRect(other: Rect | Rectangle): boolean { const { right, bottom } = this const otherRight = other[0] + other[2] const otherBottom = other[1] + other[3] @@ -241,7 +235,7 @@ export class Rectangle extends Array { * @param rect The rectangle to check * @returns `true` if {@link rect} overlaps with this rectangle, otherwise `false`. */ - overlaps(rect: ReadOnlyRect): boolean { + overlaps(rect: Rect | Rectangle): boolean { return ( this.x < rect[0] + rect[2] && this.y < rect[1] + rect[3] && @@ -374,12 +368,12 @@ export class Rectangle extends Array { } /** @returns The offset from the top-left of this rectangle to the point [{@link x}, {@link y}], as a new {@link Point}. */ - getOffsetTo([x, y]: ReadOnlyPoint): Point { + getOffsetTo([x, y]: Point): Point { return [x - this[0], y - this[1]] } /** @returns The offset from the point [{@link x}, {@link y}] to the top-left of this rectangle, as a new {@link Point}. */ - getOffsetFrom([x, y]: ReadOnlyPoint): Point { + getOffsetFrom([x, y]: Point): Point { return [this[0] - x, this[1] - y] } @@ -460,14 +454,4 @@ export class Rectangle extends Array { } } -export type ReadOnlyRectangle = Omit< - Readonly, - | 'setHeightBottomAnchored' - | 'setWidthRightAnchored' - | 'resizeTopLeft' - | 'resizeBottomLeft' - | 'resizeTopRight' - | 'resizeBottomRight' - | 'resizeBottomRight' - | 'updateTo' -> +// ReadOnlyRectangle is now just Rectangle since we unified the types diff --git a/src/lib/litegraph/src/interfaces.ts b/src/lib/litegraph/src/interfaces.ts index 290091c02..70b7bfa8c 100644 --- a/src/lib/litegraph/src/interfaces.ts +++ b/src/lib/litegraph/src/interfaces.ts @@ -1,4 +1,4 @@ -import type { Rectangle } from '@/lib/litegraph/src/infrastructure/Rectangle' +import { Rectangle } from '@/lib/litegraph/src/infrastructure/Rectangle' import type { CanvasPointerEvent } from '@/lib/litegraph/src/types/events' import type { ContextMenu } from './ContextMenu' @@ -60,7 +60,7 @@ export interface HasBoundingRect { * @readonly * @see {@link move} */ - readonly boundingRect: ReadOnlyRect + readonly boundingRect: Rectangle } /** An object containing a set of child objects */ @@ -230,50 +230,8 @@ export type Point = [x: number, y: number] /** A size represented as `[width, height]` */ export type Size = [width: number, height: number] -/** A very firm array */ -type ArRect = [x: number, y: number, width: number, height: number] - /** A rectangle starting at top-left coordinates `[x, y, width, height]` */ -export type Rect = ArRect | Float32Array | Float64Array | number[] - -/** A point represented as `[x, y]` co-ordinates that will not be modified */ -export type ReadOnlyPoint = - | readonly [x: number, y: number] - | ReadOnlyTypedArray - | ReadOnlyTypedArray - | readonly number[] - -/** A size represented as `[width, height]` that will not be modified */ -export type ReadOnlySize = - | readonly [width: number, height: number] - | ReadOnlyTypedArray - | ReadOnlyTypedArray - | readonly number[] - -/** A rectangle starting at top-left coordinates `[x, y, width, height]` that will not be modified */ -export type ReadOnlyRect = - | readonly [x: number, y: number, width: number, height: number] - | ReadOnlyTypedArray - | ReadOnlyTypedArray - | readonly number[] - -type TypedArrays = - | Int8Array - | Uint8Array - | Uint8ClampedArray - | Int16Array - | Uint16Array - | Int32Array - | Uint32Array - | Float32Array - | Float64Array - -type TypedBigIntArrays = BigInt64Array | BigUint64Array -export type ReadOnlyTypedArray = - Omit< - Readonly, - 'fill' | 'copyWithin' | 'reverse' | 'set' | 'sort' | 'subarray' - > +export type Rect = [number, number, number, number] /** Union of property names that are of type Match */ type KeysOfType = Exclude< @@ -332,7 +290,7 @@ export interface INodeSlot extends HasBoundingRect { nameLocked?: boolean pos?: Point /** @remarks Automatically calculated; not included in serialisation. */ - boundingRect: Rect + boundingRect: Rectangle /** * A list of floating link IDs that are connected to this slot. * This is calculated at runtime; it is **not** serialized. diff --git a/src/lib/litegraph/src/measure.ts b/src/lib/litegraph/src/measure.ts index a664ddbb7..4a6e35587 100644 --- a/src/lib/litegraph/src/measure.ts +++ b/src/lib/litegraph/src/measure.ts @@ -1,10 +1,5 @@ -import type { - HasBoundingRect, - Point, - ReadOnlyPoint, - ReadOnlyRect, - Rect -} from './interfaces' +import type { Rectangle } from './infrastructure/Rectangle' +import type { HasBoundingRect, Point, Rect } from './interfaces' import { Alignment, LinkDirection, hasFlag } from './types/globalEnums' /** @@ -13,7 +8,7 @@ import { Alignment, LinkDirection, hasFlag } from './types/globalEnums' * @param b Point b as `x, y` * @returns Distance between point {@link a} & {@link b} */ -export function distance(a: ReadOnlyPoint, b: ReadOnlyPoint): number { +export function distance(a: Point, b: Point): number { return Math.sqrt( (b[0] - a[0]) * (b[0] - a[0]) + (b[1] - a[1]) * (b[1] - a[1]) ) @@ -61,10 +56,7 @@ export function isInRectangle( * @param rect The rectangle, as `x, y, width, height` * @returns `true` if the point is inside the rect, otherwise `false` */ -export function isPointInRect( - point: ReadOnlyPoint, - rect: ReadOnlyRect -): boolean { +export function isPointInRect(point: Point, rect: Rect | Rectangle): boolean { return ( point[0] >= rect[0] && point[0] < rect[0] + rect[2] && @@ -80,7 +72,11 @@ export function isPointInRect( * @param rect The rectangle, as `x, y, width, height` * @returns `true` if the point is inside the rect, otherwise `false` */ -export function isInRect(x: number, y: number, rect: ReadOnlyRect): boolean { +export function isInRect( + x: number, + y: number, + rect: Rect | Rectangle +): boolean { return ( x >= rect[0] && x < rect[0] + rect[2] && @@ -121,7 +117,10 @@ export function isInsideRectangle( * @param b Rectangle B as `x, y, width, height` * @returns `true` if rectangles overlap, otherwise `false` */ -export function overlapBounding(a: ReadOnlyRect, b: ReadOnlyRect): boolean { +export function overlapBounding( + a: Rect | Rectangle, + b: Rect | Rectangle +): boolean { const aRight = a[0] + a[2] const aBottom = a[1] + a[3] const bRight = b[0] + b[2] @@ -137,7 +136,7 @@ export function overlapBounding(a: ReadOnlyRect, b: ReadOnlyRect): boolean { * @param rect The rectangle, as `x, y, width, height` * @returns The centre of the rectangle, as `x, y` */ -export function getCentre(rect: ReadOnlyRect): Point { +export function getCentre(rect: Rect | Rectangle): Point { return [rect[0] + rect[2] * 0.5, rect[1] + rect[3] * 0.5] } @@ -147,7 +146,10 @@ export function getCentre(rect: ReadOnlyRect): Point { * @param b Sub-rectangle B as `x, y, width, height` * @returns `true` if {@link a} contains most of {@link b}, otherwise `false` */ -export function containsCentre(a: ReadOnlyRect, b: ReadOnlyRect): boolean { +export function containsCentre( + a: Rect | Rectangle, + b: Rect | Rectangle +): boolean { const centreX = b[0] + b[2] * 0.5 const centreY = b[1] + b[3] * 0.5 return isInRect(centreX, centreY, a) @@ -159,7 +161,10 @@ export function containsCentre(a: ReadOnlyRect, b: ReadOnlyRect): boolean { * @param b Sub-rectangle B as `x, y, width, height` * @returns `true` if {@link a} wholly contains {@link b}, otherwise `false` */ -export function containsRect(a: ReadOnlyRect, b: ReadOnlyRect): boolean { +export function containsRect( + a: Rect | Rectangle, + b: Rect | Rectangle +): boolean { const aRight = a[0] + a[2] const aBottom = a[1] + a[3] const bRight = b[0] + b[2] @@ -289,8 +294,8 @@ export function rotateLink( * the right */ export function getOrientation( - lineStart: ReadOnlyPoint, - lineEnd: ReadOnlyPoint, + lineStart: Point, + lineEnd: Point, x: number, y: number ): number { @@ -310,10 +315,10 @@ export function getOrientation( */ export function findPointOnCurve( out: Point, - a: ReadOnlyPoint, - b: ReadOnlyPoint, - controlA: ReadOnlyPoint, - controlB: ReadOnlyPoint, + a: Point, + b: Point, + controlA: Point, + controlB: Point, t: number = 0.5 ): void { const iT = 1 - t @@ -330,7 +335,7 @@ export function findPointOnCurve( export function createBounds( objects: Iterable, padding: number = 10 -): ReadOnlyRect | null { +): Rect | null { const bounds: [number, number, number, number] = [ Infinity, Infinity, @@ -384,11 +389,11 @@ export function snapPoint(pos: Point | Rect, snapTo: number): boolean { * @returns The original {@link rect}, modified in place. */ export function alignToContainer( - rect: Rect, + rect: Rect | Rectangle, anchors: Alignment, - [containerX, containerY, containerWidth, containerHeight]: ReadOnlyRect, - [insetX, insetY]: ReadOnlyPoint = [0, 0] -): Rect { + [containerX, containerY, containerWidth, containerHeight]: Rect | Rectangle, + [insetX, insetY]: Point = [0, 0] +): Rect | Rectangle { if (hasFlag(anchors, Alignment.Left)) { // Left rect[0] = containerX + insetX @@ -427,11 +432,11 @@ export function alignToContainer( * @returns The original {@link rect}, modified in place. */ export function alignOutsideContainer( - rect: Rect, + rect: Rect | Rectangle, anchors: Alignment, - [otherX, otherY, otherWidth, otherHeight]: ReadOnlyRect, - [outsetX, outsetY]: ReadOnlyPoint = [0, 0] -): Rect { + [otherX, otherY, otherWidth, otherHeight]: Rect | Rectangle, + [outsetX, outsetY]: Point = [0, 0] +): Rect | Rectangle { if (hasFlag(anchors, Alignment.Left)) { // Left rect[0] = otherX - outsetX - rect[2] diff --git a/src/lib/litegraph/src/node/NodeInputSlot.ts b/src/lib/litegraph/src/node/NodeInputSlot.ts index 8a6af55e9..d2ea0374e 100644 --- a/src/lib/litegraph/src/node/NodeInputSlot.ts +++ b/src/lib/litegraph/src/node/NodeInputSlot.ts @@ -5,7 +5,7 @@ import type { INodeInputSlot, INodeOutputSlot, OptionalProps, - ReadOnlyPoint + Point } from '@/lib/litegraph/src/interfaces' import { LiteGraph } from '@/lib/litegraph/src/litegraph' import { type IDrawOptions, NodeSlot } from '@/lib/litegraph/src/node/NodeSlot' @@ -32,7 +32,7 @@ export class NodeInputSlot extends NodeSlot implements INodeInputSlot { this.#widget = widget ? new WeakRef(widget) : undefined } - get collapsedPos(): ReadOnlyPoint { + get collapsedPos(): Point { return [0, LiteGraph.NODE_TITLE_HEIGHT * -0.5] } diff --git a/src/lib/litegraph/src/node/NodeOutputSlot.ts b/src/lib/litegraph/src/node/NodeOutputSlot.ts index a1120dd8e..4c7eeff81 100644 --- a/src/lib/litegraph/src/node/NodeOutputSlot.ts +++ b/src/lib/litegraph/src/node/NodeOutputSlot.ts @@ -5,7 +5,7 @@ import type { INodeInputSlot, INodeOutputSlot, OptionalProps, - ReadOnlyPoint + Point } from '@/lib/litegraph/src/interfaces' import { LiteGraph } from '@/lib/litegraph/src/litegraph' import { type IDrawOptions, NodeSlot } from '@/lib/litegraph/src/node/NodeSlot' @@ -24,7 +24,7 @@ export class NodeOutputSlot extends NodeSlot implements INodeOutputSlot { return false } - get collapsedPos(): ReadOnlyPoint { + get collapsedPos(): Point { return [ this.#node._collapsed_width ?? LiteGraph.NODE_COLLAPSED_WIDTH, LiteGraph.NODE_TITLE_HEIGHT * -0.5 diff --git a/src/lib/litegraph/src/node/NodeSlot.ts b/src/lib/litegraph/src/node/NodeSlot.ts index 48f0a443c..1dab9af2f 100644 --- a/src/lib/litegraph/src/node/NodeSlot.ts +++ b/src/lib/litegraph/src/node/NodeSlot.ts @@ -8,8 +8,7 @@ import type { INodeSlot, ISubgraphInput, OptionalProps, - Point, - ReadOnlyPoint + Point } from '@/lib/litegraph/src/interfaces' import { LiteGraph, Rectangle } from '@/lib/litegraph/src/litegraph' import { getCentre } from '@/lib/litegraph/src/measure' @@ -36,7 +35,7 @@ export abstract class NodeSlot extends SlotBase implements INodeSlot { pos?: Point /** The offset from the parent node to the centre point of this slot. */ - get #centreOffset(): ReadOnlyPoint { + get #centreOffset(): Point { const nodePos = this.node.pos const { boundingRect } = this @@ -52,7 +51,7 @@ export abstract class NodeSlot extends SlotBase implements INodeSlot { } /** The center point of this slot when the node is collapsed. */ - abstract get collapsedPos(): ReadOnlyPoint + abstract get collapsedPos(): Point #node: LGraphNode get node(): LGraphNode { diff --git a/src/lib/litegraph/src/subgraph/SubgraphInput.ts b/src/lib/litegraph/src/subgraph/SubgraphInput.ts index 63465d2b5..4f1d7ed1a 100644 --- a/src/lib/litegraph/src/subgraph/SubgraphInput.ts +++ b/src/lib/litegraph/src/subgraph/SubgraphInput.ts @@ -7,7 +7,7 @@ import type { INodeInputSlot, INodeOutputSlot, Point, - ReadOnlyRect + Rect } from '@/lib/litegraph/src/interfaces' import { LiteGraph } from '@/lib/litegraph/src/litegraph' import { NodeSlotType } from '@/lib/litegraph/src/types/globalEnums' @@ -213,7 +213,7 @@ export class SubgraphInput extends SubgraphSlot { } /** For inputs, x is the right edge of the input node. */ - override arrange(rect: ReadOnlyRect): void { + override arrange(rect: Rect): void { const [right, top, width, height] = rect const { boundingRect: b, pos } = this diff --git a/src/lib/litegraph/src/subgraph/SubgraphOutput.ts b/src/lib/litegraph/src/subgraph/SubgraphOutput.ts index 96901d423..440957fc6 100644 --- a/src/lib/litegraph/src/subgraph/SubgraphOutput.ts +++ b/src/lib/litegraph/src/subgraph/SubgraphOutput.ts @@ -7,7 +7,7 @@ import type { INodeInputSlot, INodeOutputSlot, Point, - ReadOnlyRect + Rect } from '@/lib/litegraph/src/interfaces' import { LiteGraph } from '@/lib/litegraph/src/litegraph' import { NodeSlotType } from '@/lib/litegraph/src/types/globalEnums' @@ -119,7 +119,7 @@ export class SubgraphOutput extends SubgraphSlot { return [x + height, y + height * 0.5] } - override arrange(rect: ReadOnlyRect): void { + override arrange(rect: Rect): void { const [left, top, width, height] = rect const { boundingRect: b, pos } = this diff --git a/src/lib/litegraph/src/subgraph/SubgraphSlotBase.ts b/src/lib/litegraph/src/subgraph/SubgraphSlotBase.ts index 997c86b4b..98cbc7c28 100644 --- a/src/lib/litegraph/src/subgraph/SubgraphSlotBase.ts +++ b/src/lib/litegraph/src/subgraph/SubgraphSlotBase.ts @@ -11,8 +11,8 @@ import type { INodeInputSlot, INodeOutputSlot, Point, - ReadOnlyRect, - ReadOnlySize + Rect, + Size } from '@/lib/litegraph/src/interfaces' import { LiteGraph } from '@/lib/litegraph/src/litegraph' import { SlotBase } from '@/lib/litegraph/src/node/SlotBase' @@ -133,7 +133,7 @@ export abstract class SubgraphSlot } } - measure(): ReadOnlySize { + measure(): Size { const width = LGraphCanvas._measureText?.(this.displayName) ?? 0 const { defaultHeight } = SubgraphSlot @@ -141,7 +141,7 @@ export abstract class SubgraphSlot return this.measurement.toSize() } - abstract arrange(rect: ReadOnlyRect): void + abstract arrange(rect: Rect): void abstract connect( slot: INodeInputSlot | INodeOutputSlot, diff --git a/src/lib/litegraph/test/LGraphNode.test.ts b/src/lib/litegraph/test/LGraphNode.test.ts index ea9b880ea..c7e898dc5 100644 --- a/src/lib/litegraph/test/LGraphNode.test.ts +++ b/src/lib/litegraph/test/LGraphNode.test.ts @@ -1,5 +1,6 @@ import { afterEach, beforeEach, describe, expect, vi } from 'vitest' +import { Rectangle } from '@/lib/litegraph/src/infrastructure/Rectangle' import type { INodeInputSlot, Point } from '@/lib/litegraph/src/interfaces' import { LGraphNode, LiteGraph } from '@/lib/litegraph/src/litegraph' import { LGraph } from '@/lib/litegraph/src/litegraph' @@ -571,7 +572,7 @@ describe('LGraphNode', () => { name: 'test_in', type: 'string', link: null, - boundingRect: new Float32Array([0, 0, 0, 0]) + boundingRect: new Rectangle(0, 0, 0, 0) } }) test('should return position based on title height when collapsed', () => { @@ -594,7 +595,7 @@ describe('LGraphNode', () => { name: 'test_in_2', type: 'number', link: null, - boundingRect: new Float32Array([0, 0, 0, 0]) + boundingRect: new Rectangle(0, 0, 0, 0) } node.inputs = [inputSlot, inputSlot2] const slotIndex = 0 @@ -629,13 +630,13 @@ describe('LGraphNode', () => { name: 'in0', type: 'string', link: null, - boundingRect: new Float32Array([0, 0, 0, 0]) + boundingRect: new Rectangle(0, 0, 0, 0) } const input1: INodeInputSlot = { name: 'in1', type: 'number', link: null, - boundingRect: new Float32Array([0, 0, 0, 0]), + boundingRect: new Rectangle(0, 0, 0, 0), pos: [5, 45] } node.inputs = [input0, input1] diff --git a/src/lib/litegraph/test/measure.test.ts b/src/lib/litegraph/test/measure.test.ts index 854365810..1f2f8ef1e 100644 --- a/src/lib/litegraph/test/measure.test.ts +++ b/src/lib/litegraph/test/measure.test.ts @@ -1,5 +1,6 @@ import { test as baseTest } from 'vitest' +import { Rectangle } from '../src/infrastructure/Rectangle' import type { Point, Rect } from '../src/interfaces' import { addDirectionalOffset, @@ -131,8 +132,8 @@ test('snapPoint correctly snaps points to grid', ({ expect }) => { test('createBounds correctly creates bounding box', ({ expect }) => { const objects = [ - { boundingRect: [0, 0, 10, 10] as Rect }, - { boundingRect: [5, 5, 10, 10] as Rect } + { boundingRect: new Rectangle(0, 0, 10, 10) }, + { boundingRect: new Rectangle(5, 5, 10, 10) } ] const defaultBounds = createBounds(objects) diff --git a/src/renderer/core/canvas/litegraph/litegraphLinkAdapter.ts b/src/renderer/core/canvas/litegraph/litegraphLinkAdapter.ts index 49c0feec9..21cfed891 100644 --- a/src/renderer/core/canvas/litegraph/litegraphLinkAdapter.ts +++ b/src/renderer/core/canvas/litegraph/litegraphLinkAdapter.ts @@ -7,11 +7,14 @@ * Maintains backward compatibility with existing litegraph integration. */ import type { LGraph } from '@/lib/litegraph/src/LGraph' -import type { LLink } from '@/lib/litegraph/src/LLink' +import type { LGraphNode } from '@/lib/litegraph/src/LGraphNode' +import { LLink } from '@/lib/litegraph/src/LLink' import type { Reroute } from '@/lib/litegraph/src/Reroute' import type { CanvasColour, - ReadOnlyPoint + INodeInputSlot, + INodeOutputSlot, + Point as LitegraphPoint } from '@/lib/litegraph/src/interfaces' import { LiteGraph } from '@/lib/litegraph/src/litegraph' import { @@ -24,6 +27,7 @@ import { type ArrowShape, CanvasPathRenderer, type Direction, + type DragLinkData, type LinkRenderData, type RenderContext as PathRenderContext, type Point, @@ -205,6 +209,7 @@ export class LitegraphLinkAdapter { case LinkDirection.DOWN: return 'down' case LinkDirection.CENTER: + case LinkDirection.NONE: return 'none' default: return 'right' @@ -306,22 +311,22 @@ export class LitegraphLinkAdapter { * Critically: does nothing for CENTER/NONE directions (no case for them) */ private applySplineOffset( - point: Point, + point: LitegraphPoint, direction: LinkDirection, distance: number ): void { switch (direction) { case LinkDirection.LEFT: - point.x -= distance + point[0] -= distance break case LinkDirection.RIGHT: - point.x += distance + point[0] += distance break case LinkDirection.UP: - point.y -= distance + point[1] -= distance break case LinkDirection.DOWN: - point.y += distance + point[1] += distance break // CENTER and NONE: no offset applied (original behavior) } @@ -333,8 +338,8 @@ export class LitegraphLinkAdapter { */ renderLinkDirect( ctx: CanvasRenderingContext2D, - a: ReadOnlyPoint, - b: ReadOnlyPoint, + a: LitegraphPoint, + b: LitegraphPoint, link: LLink | null, skip_border: boolean, flow: number | boolean | null, @@ -344,8 +349,8 @@ export class LitegraphLinkAdapter { context: LinkRenderContext, extras: { reroute?: Reroute - startControl?: ReadOnlyPoint - endControl?: ReadOnlyPoint + startControl?: LitegraphPoint + endControl?: LitegraphPoint num_sublines?: number disabled?: boolean } = {} @@ -406,13 +411,19 @@ export class LitegraphLinkAdapter { y: a[1] + (extras.startControl![1] || 0) } const end = { x: b[0], y: b[1] } - this.applySplineOffset(end, endDir, dist * factor) + const endArray: LitegraphPoint = [end.x, end.y] + this.applySplineOffset(endArray, endDir, dist * factor) + end.x = endArray[0] + end.y = endArray[1] cps.push(start, end) linkData.controlPoints = cps } else if (!hasStartCtrl && hasEndCtrl) { // End provided, derive start via direction offset (CENTER => no offset) const start = { x: a[0], y: a[1] } - this.applySplineOffset(start, startDir, dist * factor) + const startArray: LitegraphPoint = [start.x, start.y] + this.applySplineOffset(startArray, startDir, dist * factor) + start.x = startArray[0] + start.y = startArray[1] const end = { x: b[0] + (extras.endControl![0] || 0), y: b[1] + (extras.endControl![1] || 0) @@ -423,8 +434,14 @@ export class LitegraphLinkAdapter { // Neither provided: derive both from directions (CENTER => no offset) const start = { x: a[0], y: a[1] } const end = { x: b[0], y: b[1] } - this.applySplineOffset(start, startDir, dist * factor) - this.applySplineOffset(end, endDir, dist * factor) + const startArray: LitegraphPoint = [start.x, start.y] + const endArray: LitegraphPoint = [end.x, end.y] + this.applySplineOffset(startArray, startDir, dist * factor) + this.applySplineOffset(endArray, endDir, dist * factor) + start.x = startArray[0] + start.y = startArray[1] + end.x = endArray[0] + end.y = endArray[1] cps.push(start, end) linkData.controlPoints = cps } @@ -463,8 +480,8 @@ export class LitegraphLinkAdapter { if (this.enableLayoutStoreWrites && link && link.id !== -1) { // Calculate bounds and center only when writing const bounds = this.calculateLinkBounds( - [linkData.startPoint.x, linkData.startPoint.y] as ReadOnlyPoint, - [linkData.endPoint.x, linkData.endPoint.y] as ReadOnlyPoint, + [linkData.startPoint.x, linkData.startPoint.y] as LitegraphPoint, + [linkData.endPoint.x, linkData.endPoint.y] as LitegraphPoint, linkData ) const centerPos = linkData.centerPos || { @@ -497,33 +514,57 @@ export class LitegraphLinkAdapter { } } + /** + * Render a link being dragged from a slot to mouse position + * Used during link creation/reconnection + */ renderDraggingLink( ctx: CanvasRenderingContext2D, - from: ReadOnlyPoint, - to: ReadOnlyPoint, - colour: CanvasColour, - startDir: LinkDirection, - endDir: LinkDirection, - context: LinkRenderContext + fromNode: LGraphNode | null, + fromSlot: INodeOutputSlot | INodeInputSlot, + fromSlotIndex: number, + toPosition: LitegraphPoint, + context: LinkRenderContext, + options: { + fromInput?: boolean + color?: CanvasColour + disabled?: boolean + } = {} ): void { - this.renderLinkDirect( - ctx, - from, - to, - null, - false, - null, - colour, - startDir, - endDir, - { - ...context, - linkMarkerShape: LinkMarkerShape.None - }, - { - disabled: false - } + if (!fromNode) return + + // Get slot position using layout tree if available + const slotPos = getSlotPosition( + fromNode, + fromSlotIndex, + options.fromInput || false ) + if (!slotPos) return + + // Get slot direction + const slotDir = + fromSlot.dir || + (options.fromInput ? LinkDirection.LEFT : LinkDirection.RIGHT) + + // Create drag data + const dragData: DragLinkData = { + fixedPoint: { x: slotPos[0], y: slotPos[1] }, + fixedDirection: this.convertDirection(slotDir), + dragPoint: { x: toPosition[0], y: toPosition[1] }, + color: options.color ? String(options.color) : undefined, + type: fromSlot.type !== undefined ? String(fromSlot.type) : undefined, + disabled: options.disabled || false, + fromInput: options.fromInput || false + } + + // Convert context + const pathContext = this.convertToPathRenderContext(context) + + // Hide center marker when dragging links + pathContext.style.showCenterMarker = false + + // Render using pure renderer + this.pathRenderer.drawDraggingLink(ctx, dragData, pathContext) } /** @@ -531,8 +572,8 @@ export class LitegraphLinkAdapter { * Includes padding for line width and control points */ private calculateLinkBounds( - startPos: ReadOnlyPoint, - endPos: ReadOnlyPoint, + startPos: LitegraphPoint, + endPos: LitegraphPoint, linkData: LinkRenderData ): Bounds { let minX = Math.min(startPos[0], endPos[0]) diff --git a/src/renderer/core/layout/sync/useLinkLayoutSync.ts b/src/renderer/core/layout/sync/useLinkLayoutSync.ts index fd6b3b19c..5e7c1e7fd 100644 --- a/src/renderer/core/layout/sync/useLinkLayoutSync.ts +++ b/src/renderer/core/layout/sync/useLinkLayoutSync.ts @@ -12,7 +12,7 @@ import type { LGraph } from '@/lib/litegraph/src/LGraph' import type { LGraphCanvas } from '@/lib/litegraph/src/LGraphCanvas' import { LLink } from '@/lib/litegraph/src/LLink' import { Reroute } from '@/lib/litegraph/src/Reroute' -import type { ReadOnlyPoint } from '@/lib/litegraph/src/interfaces' +import type { Point as LitegraphPoint } from '@/lib/litegraph/src/interfaces' import { LinkDirection } from '@/lib/litegraph/src/types/globalEnums' import { LitegraphLinkAdapter } from '@/renderer/core/canvas/litegraph/litegraphLinkAdapter' import type { LinkRenderContext } from '@/renderer/core/canvas/litegraph/litegraphLinkAdapter' @@ -125,7 +125,7 @@ export function useLinkLayoutSync() { // Special handling for floating input chain const isFloatingInputChain = !sourceNode && targetNode - const startControl: ReadOnlyPoint = isFloatingInputChain + const startControl: LitegraphPoint = isFloatingInputChain ? [0, 0] : [dist * reroute.cos, dist * reroute.sin] @@ -161,7 +161,7 @@ export function useLinkLayoutSync() { (endPos[1] - lastReroute.pos[1]) ** 2 ) const finalDist = Math.min(Reroute.maxSplineOffset, finalDistance * 0.25) - const finalStartControl: ReadOnlyPoint = [ + const finalStartControl: LitegraphPoint = [ finalDist * lastReroute.cos, finalDist * lastReroute.sin ] diff --git a/src/utils/mathUtil.ts b/src/utils/mathUtil.ts index 8655451c5..6faad5767 100644 --- a/src/utils/mathUtil.ts +++ b/src/utils/mathUtil.ts @@ -1,4 +1,4 @@ -import type { ReadOnlyRect } from '@/lib/litegraph/src/interfaces' +import type { Rect } from '@/lib/litegraph/src/interfaces' import type { Bounds } from '@/renderer/core/layout/types' /** @@ -33,9 +33,7 @@ export const lcm = (a: number, b: number): number => { * @param rectangles - Array of rectangle tuples in [x, y, width, height] format * @returns Bounds object with union rectangle, or null if no rectangles provided */ -export function computeUnionBounds( - rectangles: readonly ReadOnlyRect[] -): Bounds | null { +export function computeUnionBounds(rectangles: readonly Rect[]): Bounds | null { const n = rectangles.length if (n === 0) { return null diff --git a/tests-ui/tests/litegraph/core/LGraphNode.test.ts b/tests-ui/tests/litegraph/core/LGraphNode.test.ts index ec7f398b2..558d4004a 100644 --- a/tests-ui/tests/litegraph/core/LGraphNode.test.ts +++ b/tests-ui/tests/litegraph/core/LGraphNode.test.ts @@ -1,6 +1,7 @@ import { afterEach, beforeEach, describe, expect, vi } from 'vitest' import type { INodeInputSlot, Point } from '@/lib/litegraph/src/litegraph' +import { Rectangle } from '@/lib/litegraph/src/litegraph' import { LGraphNode, LiteGraph } from '@/lib/litegraph/src/litegraph' import { LGraph } from '@/lib/litegraph/src/litegraph' import { NodeInputSlot } from '@/lib/litegraph/src/litegraph' @@ -571,7 +572,7 @@ describe('LGraphNode', () => { name: 'test_in', type: 'string', link: null, - boundingRect: new Float32Array([0, 0, 0, 0]) + boundingRect: new Rectangle(0, 0, 0, 0) } }) test('should return position based on title height when collapsed', () => { @@ -594,7 +595,7 @@ describe('LGraphNode', () => { name: 'test_in_2', type: 'number', link: null, - boundingRect: new Float32Array([0, 0, 0, 0]) + boundingRect: new Rectangle(0, 0, 0, 0) } node.inputs = [inputSlot, inputSlot2] const slotIndex = 0 diff --git a/tests-ui/tests/litegraph/core/measure.test.ts b/tests-ui/tests/litegraph/core/measure.test.ts index dc588a09f..581613fd0 100644 --- a/tests-ui/tests/litegraph/core/measure.test.ts +++ b/tests-ui/tests/litegraph/core/measure.test.ts @@ -1,6 +1,7 @@ // TODO: Fix these tests after migration import { test as baseTest } from 'vitest' +import { Rectangle } from '@/lib/litegraph/src/infrastructure/Rectangle' import type { Point, Rect } from '@/lib/litegraph/src/interfaces' import { addDirectionalOffset, @@ -132,8 +133,8 @@ test('snapPoint correctly snaps points to grid', ({ expect }) => { test('createBounds correctly creates bounding box', ({ expect }) => { const objects = [ - { boundingRect: [0, 0, 10, 10] as Rect }, - { boundingRect: [5, 5, 10, 10] as Rect } + { boundingRect: new Rectangle(0, 0, 10, 10) }, + { boundingRect: new Rectangle(5, 5, 10, 10) } ] const defaultBounds = createBounds(objects) diff --git a/tests-ui/tests/utils/mathUtil.test.ts b/tests-ui/tests/utils/mathUtil.test.ts index c4cb16dd8..deebe2840 100644 --- a/tests-ui/tests/utils/mathUtil.test.ts +++ b/tests-ui/tests/utils/mathUtil.test.ts @@ -1,6 +1,6 @@ import { describe, expect, it } from 'vitest' -import type { ReadOnlyRect } from '@/lib/litegraph/src/interfaces' +import type { Rect } from '@/lib/litegraph/src/interfaces' import { computeUnionBounds, gcd, lcm } from '@/utils/mathUtil' describe('mathUtil', () => { @@ -27,9 +27,9 @@ describe('mathUtil', () => { expect(computeUnionBounds([])).toBe(null) }) - // Tests for tuple format (ReadOnlyRect) - it('should work with ReadOnlyRect tuple format', () => { - const tuples: ReadOnlyRect[] = [ + // Tests for tuple format (Rect) + it('should work with Rect tuple format', () => { + const tuples: Rect[] = [ [10, 20, 30, 40] as const, // bounds: 10,20 to 40,60 [50, 10, 20, 30] as const // bounds: 50,10 to 70,40 ] @@ -44,8 +44,8 @@ describe('mathUtil', () => { }) }) - it('should handle single ReadOnlyRect tuple', () => { - const tuple: ReadOnlyRect = [10, 20, 30, 40] as const + it('should handle single Rect tuple', () => { + const tuple: Rect = [10, 20, 30, 40] as const const result = computeUnionBounds([tuple]) expect(result).toEqual({ @@ -57,7 +57,7 @@ describe('mathUtil', () => { }) it('should handle tuple format with negative dimensions', () => { - const tuples: ReadOnlyRect[] = [ + const tuples: Rect[] = [ [100, 50, -20, -10] as const, // x+width=80, y+height=40 [90, 45, 15, 20] as const // x+width=105, y+height=65 ] @@ -74,7 +74,7 @@ describe('mathUtil', () => { it('should maintain optimal performance with SoA tuples', () => { // Test that array access is as expected for typical selection sizes - const tuples: ReadOnlyRect[] = Array.from( + const tuples: Rect[] = Array.from( { length: 10 }, (_, i) => [