Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Positionable: Common interface for canvas items #256

Merged
merged 8 commits into from
Nov 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
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
27 changes: 15 additions & 12 deletions src/LGraph.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ export class LGraph {
last_link_id: number
/** The largest ID created by this graph */
last_reroute_id: number
lastGroupId: number = -1
_nodes: LGraphNode[]
_nodes_by_id: Record<NodeId, LGraphNode>
_nodes_in_order: LGraphNode[]
Expand Down Expand Up @@ -647,6 +648,10 @@ export class LGraph {
// LEGACY: This was changed from constructor === LGraphGroup
//groups
if (node instanceof LGraphGroup) {
// Assign group ID
if (node.id == null || node.id === -1) node.id = ++this.lastGroupId
if (node.id > this.lastGroupId) this.lastGroupId = node.id

this._groups.push(node)
this.setDirtyCanvas(true)
this.change()
Expand Down Expand Up @@ -847,28 +852,26 @@ export class LGraph {
* Returns the top-most node in this position of the canvas
* @param {number} x the x coordinate in canvas space
* @param {number} y the y coordinate in canvas space
* @param {Array} nodes_list a list with all the nodes to search from, by default is all the nodes in the graph
* @param {Array} nodeList a list with all the nodes to search from, by default is all the nodes in the graph
* @return {LGraphNode} the node at this position or null
*/
getNodeOnPos(x: number, y: number, nodes_list?: LGraphNode[], margin?: number): LGraphNode | null {
nodes_list = nodes_list || this._nodes
const nRet = null
for (let i = nodes_list.length - 1; i >= 0; i--) {
const n = nodes_list[i]
const skip_title = n.constructor.title_mode == TitleMode.NO_TITLE
if (n.isPointInside(x, y, margin, skip_title))
return n
getNodeOnPos(x: number, y: number, nodeList?: LGraphNode[]): LGraphNode | null {
const nodes = nodeList || this._nodes
let i = nodes.length
while (--i >= 0) {
const node = nodes[i]
if (node.isPointInside(x, y)) return node
}
return nRet
return null
}
/**
* Returns the top-most group in that position
* @param x The x coordinate in canvas space
* @param y The y coordinate in canvas space
* @return The group or null
*/
getGroupOnPos(x: number, y: number, { margin = 2 } = {}): LGraphGroup | undefined {
return this._groups.toReversed().find(g => g.isPointInside(x, y, margin, true))
getGroupOnPos(x: number, y: number): LGraphGroup | undefined {
return this._groups.toReversed().find(g => g.isPointInside(x, y))
}

/**
Expand Down
72 changes: 30 additions & 42 deletions src/LGraphCanvas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1719,7 +1719,7 @@ export class LGraphCanvas {

if (!is_inside) return

let node = this.graph.getNodeOnPos(e.canvasX, e.canvasY, this.visible_nodes, 5)
let node = this.graph.getNodeOnPos(e.canvasX, e.canvasY, this.visible_nodes)
let skip_action = false
const now = LiteGraph.getTime()
const is_primary = (e.isPrimary === undefined || !e.isPrimary)
Expand Down Expand Up @@ -2002,15 +2002,15 @@ export class LGraphCanvas {
this.isDragging = true
}
// Account for shift + click + drag
if (!(e.shiftKey && !e.ctrlKey && !e.altKey) || !node.is_selected) {
if (!(e.shiftKey && !e.ctrlKey && !e.altKey) || !node.selected) {
this.processNodeSelected(node, e)
}
} else { // double-click
/**
* Don't call the function if the block is already selected.
* Otherwise, it could cause the block to be unselected while its panel is open.
*/
if (!node.is_selected) this.processNodeSelected(node, e)
if (!node.selected) this.processNodeSelected(node, e)
}

this.dirty_canvas = true
Expand Down Expand Up @@ -2451,12 +2451,6 @@ export class LGraphCanvas {
nodes.add(n)
n.pos[0] += delta[0] / this.ds.scale
n.pos[1] += delta[1] / this.ds.scale
/*
* Don't call the function if the block is already selected.
* Otherwise, it could cause the block to be unselected while dragging.
*/
if (!n.is_selected) this.processNodeSelected(n, e)

}

if (this.selectedGroups) {
Expand Down Expand Up @@ -3248,15 +3242,15 @@ export class LGraphCanvas {
if (typeof nodes == "string") nodes = [nodes]
for (const i in nodes) {
const node: LGraphNode = nodes[i]
if (node.is_selected) {
if (node.selected) {
this.deselectNode(node)
continue
}

if (!node.is_selected) {
if (!node.selected) {
node.onSelected?.()
}
node.is_selected = true
node.selected = true
this.selected_nodes[node.id] = node

if (node.inputs) {
Expand Down Expand Up @@ -3284,9 +3278,9 @@ export class LGraphCanvas {
* removes a node from the current selection
**/
deselectNode(node: LGraphNode): void {
if (!node.is_selected) return
if (!node.selected) return
node.onDeselected?.()
node.is_selected = false
node.selected = false
delete this.selected_nodes[node.id]

this.onNodeDeselected?.(node)
Expand Down Expand Up @@ -3316,11 +3310,11 @@ export class LGraphCanvas {
const nodes = this.graph._nodes
for (let i = 0, l = nodes.length; i < l; ++i) {
const node = nodes[i]
if (!node.is_selected) {
if (!node.selected) {
continue
}
node.onDeselected?.()
node.is_selected = false
node.selected = false
this.onNodeDeselected?.(node)
}
this.selected_nodes = {}
Expand Down Expand Up @@ -3474,16 +3468,17 @@ export class LGraphCanvas {
computeVisibleNodes(nodes?: LGraphNode[], out?: LGraphNode[]): LGraphNode[] {
const visible_nodes = out || []
visible_nodes.length = 0
nodes ||= this.graph._nodes
for (let i = 0, l = nodes.length; i < l; ++i) {
const n = nodes[i]

const _nodes = nodes || this.graph._nodes
for (const node of _nodes) {
//skip rendering nodes in live mode
if (this.live_mode && !n.onDrawBackground && !n.onDrawForeground) continue
if (this.live_mode && !node.onDrawBackground && !node.onDrawForeground) continue

node.updateArea()
// Not in visible area
if (!overlapBounding(this.visible_area, n.getBounding(LGraphCanvas.#temp, true))) continue
if (!overlapBounding(this.visible_area, node.renderArea)) continue

visible_nodes.push(n)
visible_nodes.push(node)
}
return visible_nodes
}
Expand All @@ -3499,25 +3494,24 @@ export class LGraphCanvas {
this.render_time = (now - this.last_draw_time) * 0.001
this.last_draw_time = now

if (this.graph) {
this.ds.computeVisibleArea(this.viewport)
}
if (this.graph) this.ds.computeVisibleArea(this.viewport)

// Compute node size before drawing links.
if (this.dirty_canvas || force_canvas)
this.computeVisibleNodes(null, this.visible_nodes)

if (this.dirty_bgcanvas ||
force_bgcanvas ||
this.always_render_background ||
(this.graph &&
this.graph._last_trigger_time &&
(this.graph?._last_trigger_time &&
now - this.graph._last_trigger_time < 1000)) {
this.drawBackCanvas()
}

if (this.dirty_canvas || force_canvas) {
this.drawFrontCanvas()
}
if (this.dirty_canvas || force_canvas) this.drawFrontCanvas()

this.fps = this.render_time ? 1.0 / this.render_time : 0
this.frame += 1
this.frame++
}
/**
* draws the front canvas (the one containing all the nodes)
Expand Down Expand Up @@ -3581,10 +3575,7 @@ export class LGraphCanvas {
this.ds.toCanvasContext(ctx)

//draw nodes
const visible_nodes = this.computeVisibleNodes(
null,
this.visible_nodes
)
const visible_nodes = this.visible_nodes

for (let i = 0; i < visible_nodes.length; ++i) {
const node = visible_nodes[i]
Expand Down Expand Up @@ -3784,9 +3775,7 @@ export class LGraphCanvas {

const { strokeStyle, lineWidth } = ctx

const area = LGraphCanvas.#tmp_area
node.measure(area)
node.onBounding?.(area)
const area = node.boundingRect
const gap = 3
const radius = this.round_radius + gap

Expand Down Expand Up @@ -4223,8 +4212,7 @@ export class LGraphCanvas {
ctx.finish?.()

this.dirty_bgcanvas = false
//to force to repaint the front canvas with the bgcanvas
// But why would you actually want to do this?
// Forces repaint of the front canvas.
this.dirty_canvas = true
}
/**
Expand Down Expand Up @@ -4313,7 +4301,7 @@ export class LGraphCanvas {
size,
color,
bgcolor,
node.is_selected
node.selected
)

if (!low_quality) {
Expand Down Expand Up @@ -4590,7 +4578,7 @@ export class LGraphCanvas {
* @param size Size of the background to draw, in graph units. Differs from node size if collapsed, etc.
* @param fgcolor Foreground colour - used for text
* @param bgcolor Background colour of the node
* @param selected Whether to render the node as selected. Likely to be removed in future, as current usage is simply the is_selected property of the node.
* @param selected Whether to render the node as selected. Likely to be removed in future, as current usage is simply the selected property of the node.
* @param mouse_over Deprecated
*/
drawNodeShape(
Expand Down
Loading
Loading