mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-02-03 22:59:14 +00:00
Backport of #6789 to `cloud/1.32` Automatically created by backport workflow. ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-6861-backport-cloud-1-32-Feat-Alt-Drag-to-clone-Vue-Nodes-2b46d73d3650819e83e7f55bb16fdf9d) by [Unito](https://www.unito.io) Co-authored-by: Alexander Brown <drjkl@comfy.org> Co-authored-by: github-actions <github-actions@github.com>
99 lines
2.7 KiB
TypeScript
99 lines
2.7 KiB
TypeScript
import type { LGraph } from '@/lib/litegraph/src/litegraph'
|
|
import { calculateNodeBounds } from '@/renderer/core/spatial/boundsCalculator'
|
|
import type { PositionedNode } from '@/renderer/core/spatial/boundsCalculator'
|
|
|
|
import type {
|
|
IMinimapDataSource,
|
|
MinimapBounds,
|
|
MinimapGroupData,
|
|
MinimapLinkData,
|
|
MinimapNodeData
|
|
} from '../types'
|
|
|
|
/**
|
|
* Abstract base class for minimap data sources
|
|
* Provides common functionality and shared implementation
|
|
*/
|
|
export abstract class AbstractMinimapDataSource implements IMinimapDataSource {
|
|
constructor(protected graph: LGraph | null) {}
|
|
|
|
// Abstract methods that must be implemented by subclasses
|
|
abstract getNodes(): MinimapNodeData[]
|
|
abstract getNodeCount(): number
|
|
abstract hasData(): boolean
|
|
|
|
// Shared implementation using calculateNodeBounds
|
|
getBounds(): MinimapBounds {
|
|
const nodes = this.getNodes()
|
|
if (nodes.length === 0) {
|
|
return { minX: 0, minY: 0, maxX: 100, maxY: 100, width: 100, height: 100 }
|
|
}
|
|
|
|
// Convert MinimapNodeData to the format expected by calculateNodeBounds
|
|
const compatibleNodes = nodes.map(
|
|
(node): PositionedNode => ({
|
|
pos: [node.x, node.y],
|
|
size: [node.width, node.height]
|
|
})
|
|
)
|
|
|
|
const bounds = calculateNodeBounds(compatibleNodes)
|
|
if (!bounds) {
|
|
return { minX: 0, minY: 0, maxX: 100, maxY: 100, width: 100, height: 100 }
|
|
}
|
|
|
|
return bounds
|
|
}
|
|
|
|
// Shared implementation for groups
|
|
getGroups(): MinimapGroupData[] {
|
|
if (!this.graph?._groups) return []
|
|
return this.graph._groups.map((group) => ({
|
|
x: group.pos[0],
|
|
y: group.pos[1],
|
|
width: group.size[0],
|
|
height: group.size[1],
|
|
color: group.color
|
|
}))
|
|
}
|
|
|
|
// TODO: update when Layoutstore supports links
|
|
getLinks(): MinimapLinkData[] {
|
|
if (!this.graph) return []
|
|
return this.extractLinksFromGraph(this.graph)
|
|
}
|
|
|
|
protected extractLinksFromGraph(graph: LGraph): MinimapLinkData[] {
|
|
const links: MinimapLinkData[] = []
|
|
const nodeMap = new Map(this.getNodes().map((n) => [n.id, n]))
|
|
|
|
for (const node of graph._nodes) {
|
|
if (!node.outputs) continue
|
|
|
|
const sourceNodeData = nodeMap.get(String(node.id))
|
|
if (!sourceNodeData) continue
|
|
|
|
for (const output of node.outputs) {
|
|
if (!output.links) continue
|
|
|
|
for (const linkId of output.links) {
|
|
const link = graph.links[linkId]
|
|
if (!link) continue
|
|
|
|
const targetNodeData = nodeMap.get(String(link.target_id))
|
|
if (!targetNodeData) continue
|
|
|
|
links.push({
|
|
sourceNode: sourceNodeData,
|
|
targetNode: targetNodeData,
|
|
sourceSlot: link.origin_slot,
|
|
targetSlot: link.target_slot
|
|
})
|
|
}
|
|
}
|
|
}
|
|
|
|
return links
|
|
}
|
|
}
|