Skip to content

Commit

Permalink
Group update - titlebar, resize, config (#270)
Browse files Browse the repository at this point in the history
* Backport group header from frontend

* nit - TS types & redundant code

* Refactor - simplify group resize

* Fix group resize can be inverted

* Move group resize check to group class

* Add config for group padding & default colour

* nit - Remove redundant code
  • Loading branch information
webfiltered authored Nov 3, 2024
1 parent 3be1937 commit ce8d39f
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 38 deletions.
47 changes: 22 additions & 25 deletions src/LGraphCanvas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,9 @@ export class LGraphCanvas {
selected_nodes: Dictionary<LGraphNode> = {}
/** All selected nodes, groups, and reroutes */
selectedItems: Set<Positionable> = new Set()
/** The group currently being resized. */
resizingGroup: LGraphGroup | null = null
/** @deprecated See {@link LGraphCanvas.selectedItems} */
selected_group: LGraphGroup | null = null
visible_nodes: LGraphNode[] = []
node_dragged?: LGraphNode
Expand Down Expand Up @@ -299,6 +302,7 @@ export class LGraphCanvas {
block_click?: boolean
last_click_position?: Point
resizing_node?: LGraphNode
/** @deprecated See {@link LGraphCanvas.resizingGroup} */
selected_group_resizing?: boolean
last_mouse_dragging: boolean
onMouseDown: (arg0: CanvasMouseEvent) => void
Expand Down Expand Up @@ -1253,7 +1257,6 @@ export class LGraphCanvas {
this.dragging_rectangle = null

this.selected_nodes = {}
/** The group currently being resized */
this.selected_group = null

this.visible_nodes = []
Expand Down Expand Up @@ -1428,13 +1431,14 @@ export class LGraphCanvas {

if (!skip_events) this.bindEvents()
}
//used in some events to capture them
_doNothing(e: Event) {
/** Captures an event and prevents default - returns false. */
_doNothing(e: Event): boolean {
//console.log("pointerevents: _doNothing "+e.type);
e.preventDefault()
return false
}
_doReturnTrue(e: Event) {
/** Captures an event and prevents default - returns true. */
_doReturnTrue(e: Event): boolean {
e.preventDefault()
return true
}
Expand Down Expand Up @@ -1722,15 +1726,14 @@ export class LGraphCanvas {
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)
const is_double_click = (now - this.last_mouseclick < 300)
this.mouse[0] = e.clientX
this.mouse[1] = e.clientY
this.graph_mouse[0] = e.canvasX
this.graph_mouse[1] = e.canvasY
this.last_click_position = [this.mouse[0], this.mouse[1]]

this.pointer_is_double = this.pointer_is_down && is_primary
this.pointer_is_double = this.pointer_is_down && e.isPrimary
this.pointer_is_down = true

this.canvas.focus()
Expand Down Expand Up @@ -2057,19 +2060,16 @@ export class LGraphCanvas {
this.ctx.lineWidth = lineWidth
}


this.selected_group = this.graph.getGroupOnPos(e.canvasX, e.canvasY)
this.selected_group_resizing = false

const group = this.selected_group
const group = this.graph.getGroupOnPos(e.canvasX, e.canvasY)
this.selected_group = group
if (group && !this.read_only) {
if (e.ctrlKey) {
this.dragging_rectangle = null
}

const dist = distance([e.canvasX, e.canvasY], [group.pos[0] + group.size[0], group.pos[1] + group.size[1]])
if (dist * this.ds.scale < 10) {
this.selected_group_resizing = true
this.resizingGroup = group
} else {
const f = group.font_size || LiteGraph.DEFAULT_GROUP_FONT_SIZE
const headerHeight = f * 1.4
Expand All @@ -2086,7 +2086,7 @@ export class LGraphCanvas {
this.emitEvent({
subType: "group-double-click",
originalEvent: e,
group: this.selected_group,
group,
})
}
} else if (is_double_click && !this.read_only) {
Expand Down Expand Up @@ -2259,19 +2259,20 @@ export class LGraphCanvas {

//get node over
const node = this.graph.getNodeOnPos(e.canvasX, e.canvasY, this.visible_nodes)
const { resizingGroup } = this

if (this.dragging_rectangle) {
this.dragging_rectangle[2] = e.canvasX - this.dragging_rectangle[0]
this.dragging_rectangle[3] = e.canvasY - this.dragging_rectangle[1]
this.dirty_canvas = true
}
else if (this.selected_group_resizing && !this.read_only) {
//moving/resizing a group
this.selected_group.resize(
e.canvasX - this.selected_group.pos[0],
e.canvasY - this.selected_group.pos[1]
else if (resizingGroup && !this.read_only) {
// Resizing a group
const resized = resizingGroup.resize(
e.canvasX - resizingGroup.pos[0],
e.canvasY - resizingGroup.pos[1]
)
this.dirty_bgcanvas = true
if (resized) this.dirty_bgcanvas = true
} else if (this.dragging_canvas) {
this.ds.offset[0] += delta[0] / this.ds.scale
this.ds.offset[1] += delta[1] / this.ds.scale
Expand Down Expand Up @@ -2494,19 +2495,15 @@ export class LGraphCanvas {
this.block_click &&= false

if (e.which == 1) {
this.resizingGroup = null

if (this.node_widget) {
this.processNodeWidgets(this.node_widget[0], this.graph_mouse, e)
}

//left button
this.node_widget = null

if (this.selected_group) {
this.dirty_canvas = true
this.selected_group = null
}
this.selected_group_resizing = false
this.selected_group = null
this.isDragging = false

let node = this.graph.getNodeOnPos(
Expand Down
55 changes: 42 additions & 13 deletions src/LGraphGroup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,18 @@ export interface IGraphGroupFlags extends Record<string, unknown> {
}

export class LGraphGroup implements Positionable {
static minWidth = 140
static minHeight = 80
static resizeLength = 10
static padding = 4
static defaultColour = '#335'

id: number
color: string
title: string
font?: string
font_size: number = LiteGraph.DEFAULT_GROUP_FONT || 24
_bounding: Float32Array = new Float32Array([10, 10, 140, 80])
_bounding: Float32Array = new Float32Array([10, 10, LGraphGroup.minWidth, LGraphGroup.minHeight])
_pos: Point = this._bounding.subarray(0, 2)
_size: Size = this._bounding.subarray(2, 4)
/** @deprecated See {@link _children} */
Expand Down Expand Up @@ -54,10 +60,11 @@ export class LGraphGroup implements Positionable {
set size(v) {
if (!v || v.length < 2) return

this._size[0] = Math.max(140, v[0])
this._size[1] = Math.max(80, v[1])
this._size[0] = Math.max(LGraphGroup.minWidth, v[0])
this._size[1] = Math.max(LGraphGroup.minHeight, v[1])
}


get boundingRect() {
return this._bounding
}
Expand Down Expand Up @@ -113,26 +120,37 @@ export class LGraphGroup implements Positionable {
* @param {CanvasRenderingContext2D} ctx
*/
draw(graphCanvas: LGraphCanvas, ctx: CanvasRenderingContext2D): void {
const padding = 4
const { padding, resizeLength, defaultColour } = LGraphGroup
const font_size = this.font_size || LiteGraph.DEFAULT_GROUP_FONT_SIZE

ctx.fillStyle = this.color
ctx.strokeStyle = this.color
const [x, y] = this._pos
const [width, height] = this._size

// Titlebar
ctx.globalAlpha = 0.25 * graphCanvas.editor_alpha
ctx.fillStyle = this.color || defaultColour
ctx.strokeStyle = this.color || defaultColour
ctx.beginPath()
ctx.rect(x + 0.5, y + 0.5, width, font_size * 1.4)
ctx.fill()

// Group background, border
ctx.fillStyle = this.color
ctx.strokeStyle = this.color
ctx.beginPath()
ctx.rect(x + 0.5, y + 0.5, width, height)
ctx.fill()
ctx.globalAlpha = graphCanvas.editor_alpha
ctx.stroke()

// Resize marker
ctx.beginPath()
ctx.moveTo(x + width, y + height)
ctx.lineTo(x + width - 10, y + height)
ctx.lineTo(x + width, y + height - 10)
ctx.lineTo(x + width - resizeLength, y + height)
ctx.lineTo(x + width, y + height - resizeLength)
ctx.fill()

const font_size = this.font_size || LiteGraph.DEFAULT_GROUP_FONT_SIZE
// Title
ctx.font = font_size + "px Arial"
ctx.textAlign = "left"
ctx.fillText(this.title + (this.pinned ? "📌" : ""), x + padding, y + font_size)
Expand All @@ -148,11 +166,12 @@ export class LGraphGroup implements Positionable {
}
}

resize(width: number, height: number): void {
if (this.pinned) return
resize(width: number, height: number): boolean {
if (this.pinned) return false

this._size[0] = width
this._size[1] = height
this._size[0] = Math.max(LGraphGroup.minWidth, width)
this._size[1] = Math.max(LGraphGroup.minHeight, height)
return true
}

move(deltaX: number, deltaY: number, skipChildren: boolean = false): void {
Expand Down Expand Up @@ -264,6 +283,16 @@ export class LGraphGroup implements Positionable {
return isInsideRectangle(x, y, b[0], b[1], b[2], this.titleHeight)
}

isInResize(x: number, y: number): boolean {
const b = this._bounding
const right = b[0] + b[2]
const bottom = b[1] + b[3]

return x < right
&& y < bottom
&& (x - right) + (y - bottom) > -LGraphGroup.resizeLength
}

isPointInside = LGraphNode.prototype.isPointInside
setDirtyCanvas = LGraphNode.prototype.setDirtyCanvas
}

0 comments on commit ce8d39f

Please sign in to comment.