Overhaul node computeSize - use actual text width (#962)

### Node resize overhaul

- Precisely calculates node minimum size
- Prevents input & output overlap
- Prevents (normal*) widgets from rendering text over the edge of nodes
- Performance impact was sub-millisecond for normal usage in a 500-node
graph


![image](https://github.com/user-attachments/assets/5b6a6cc7-a752-4d7e-bcdf-b4bc8df26c51)

_Minimum size for a few example node configurations_

### Widgets

- Converts hard-coded draw render values to class static properties
- Adds widget button draw function for left/right arrow widgets

_*_ Exception: `control_after_generate`, as it is not a true input /
widget. A check may be added later to handle this special case.
This commit is contained in:
filtered
2025-04-25 00:31:34 +10:00
committed by GitHub
parent 79ce3199d4
commit 080a8da8f4
10 changed files with 97 additions and 52 deletions

View File

@@ -13,6 +13,15 @@ export interface DrawWidgetOptions {
}
export abstract class BaseWidget implements IBaseWidget {
/** From node edge to widget edge */
static margin = 15
/** From widget edge to tip of arrow button */
static arrowMargin = 6
/** Arrow button width */
static arrowWidth = 10
/** Absolute minimum display width of widget values */
static minValueWidth = 42
linkedWidgets?: IWidget[]
name: string
options: IWidgetOptions<unknown>
@@ -82,6 +91,28 @@ export abstract class BaseWidget implements IBaseWidget {
*/
abstract drawWidget(ctx: CanvasRenderingContext2D, options: DrawWidgetOptions): void
drawArrowButtons(ctx: CanvasRenderingContext2D, margin: number, y: number, width: number) {
const { height } = this
const { arrowMargin, arrowWidth } = BaseWidget
const arrowTipX = margin + arrowMargin
const arrowInnerX = arrowTipX + arrowWidth
// Draw left arrow
ctx.fillStyle = this.text_color
ctx.beginPath()
ctx.moveTo(arrowInnerX, y + 5)
ctx.lineTo(arrowTipX, y + height * 0.5)
ctx.lineTo(arrowInnerX, y + height - 5)
ctx.fill()
// Draw right arrow
ctx.beginPath()
ctx.moveTo(width - arrowInnerX, y + 5)
ctx.lineTo(width - arrowTipX, y + height * 0.5)
ctx.lineTo(width - arrowInnerX, y + height - 5)
ctx.fill()
}
/**
* Handles the click event for the widget
* @param options The options for handling the click event