From a26a5c9a87f65b24c4821675791d00e16dc80a1b Mon Sep 17 00:00:00 2001 From: filtered <176114999+webfiltered@users.noreply.github.com> Date: Wed, 12 Mar 2025 05:19:56 +1100 Subject: [PATCH] [Refactor] Prefer param destructuring over manual (#756) - Replaces manual runtime destructuring with built-in param destructuring - Standardises naming - Reorders deprecated code --- src/draw.ts | 25 +++++++++++----------- src/widgets/BaseWidget.ts | 14 +++++++------ src/widgets/BooleanWidget.ts | 34 +++++++++++++++--------------- src/widgets/ButtonWidget.ts | 26 +++++++++++------------ src/widgets/ComboWidget.ts | 40 +++++++++++++++++------------------- src/widgets/KnobWidget.ts | 24 ++++++++++------------ src/widgets/NumberWidget.ts | 38 ++++++++++++++++------------------ src/widgets/SliderWidget.ts | 31 ++++++++++++++-------------- src/widgets/TextWidget.ts | 30 +++++++++++++-------------- 9 files changed, 126 insertions(+), 136 deletions(-) diff --git a/src/draw.ts b/src/draw.ts index 2d78c24e1..744e67fe7 100644 --- a/src/draw.ts +++ b/src/draw.ts @@ -35,7 +35,7 @@ interface IDrawSelectionBoundingOptions { shape?: RenderShape /** The radius of the rounded corners for {@link RenderShape.ROUND} and {@link RenderShape.CARD} */ round_radius?: number - /** Shape will extend above the Y-axis 0 by this amount */ + /** Shape will extend above the Y-axis 0 by this amount @deprecated This is node-specific: it should be removed entirely, and behaviour defined by the caller more explicitly */ title_height?: number /** @deprecated This is node-specific: it should be removed entirely, and behaviour defined by the caller more explicitly */ title_mode?: TitleMode @@ -58,25 +58,26 @@ interface IDrawSelectionBoundingOptions { export function strokeShape( ctx: CanvasRenderingContext2D, area: Rect, - options: IDrawSelectionBoundingOptions = {}, -): void { - // Don't deconstruct in function arguments. If deconstructed in the argument list, the defaults will be evaluated - // once when the function is defined, and will not be re-evaluated when the function is called. - const { + { shape = RenderShape.BOX, - round_radius = LiteGraph.ROUND_RADIUS, - title_height = LiteGraph.NODE_TITLE_HEIGHT, + round_radius, + title_height, title_mode = TitleMode.NORMAL_TITLE, - colour = LiteGraph.NODE_BOX_OUTLINE_COLOR, + colour, padding = 6, collapsed = false, thickness = 1, - } = options + }: IDrawSelectionBoundingOptions = {}, +): void { + // These param defaults are not compile-time static, and must be re-evaluated at runtime + round_radius ??= LiteGraph.ROUND_RADIUS + colour ??= LiteGraph.NODE_BOX_OUTLINE_COLOR // Adjust area if title is transparent if (title_mode === TitleMode.TRANSPARENT_TITLE) { - area[1] -= title_height - area[3] += title_height + const height = title_height ?? LiteGraph.NODE_TITLE_HEIGHT + area[1] -= height + area[3] += height } // Set up context diff --git a/src/widgets/BaseWidget.ts b/src/widgets/BaseWidget.ts index a01ba567e..638b88d15 100644 --- a/src/widgets/BaseWidget.ts +++ b/src/widgets/BaseWidget.ts @@ -5,6 +5,13 @@ import type { IBaseWidget, IWidget, IWidgetOptions, TWidgetType, TWidgetValue } import { Point } from "@/interfaces" import { LiteGraph } from "@/litegraph" +export interface DrawWidgetOptions { + y: number + width: number + show_text?: boolean + margin?: number +} + export abstract class BaseWidget implements IBaseWidget { linkedWidgets?: IWidget[] name: string @@ -72,12 +79,7 @@ export abstract class BaseWidget implements IBaseWidget { * @remarks Not naming this `draw` as `draw` conflicts with the `draw` method in * custom widgets. */ - abstract drawWidget(ctx: CanvasRenderingContext2D, options: { - y: number - width: number - show_text?: boolean - margin?: number - }): void + abstract drawWidget(ctx: CanvasRenderingContext2D, options: DrawWidgetOptions): void /** * Handles the click event for the widget diff --git a/src/widgets/BooleanWidget.ts b/src/widgets/BooleanWidget.ts index 05a68b401..b0dad4231 100644 --- a/src/widgets/BooleanWidget.ts +++ b/src/widgets/BooleanWidget.ts @@ -3,7 +3,7 @@ import type { LGraphNode } from "@/LGraphNode" import type { CanvasMouseEvent } from "@/types/events" import type { IBooleanWidget } from "@/types/widgets" -import { BaseWidget } from "./BaseWidget" +import { BaseWidget, type DrawWidgetOptions } from "./BaseWidget" export class BooleanWidget extends BaseWidget implements IBooleanWidget { // IBooleanWidget properties @@ -16,15 +16,13 @@ export class BooleanWidget extends BaseWidget implements IBooleanWidget { this.value = widget.value } - override drawWidget(ctx: CanvasRenderingContext2D, options: { - y: number - width: number - show_text?: boolean - margin?: number - }) { - const { y, width, show_text = true, margin = 15 } = options - const widget_width = width - const H = this.height + override drawWidget(ctx: CanvasRenderingContext2D, { + y, + width, + show_text = true, + margin = 15, + }: DrawWidgetOptions) { + const { height } = this ctx.textAlign = "left" ctx.strokeStyle = this.outline_color @@ -32,16 +30,16 @@ export class BooleanWidget extends BaseWidget implements IBooleanWidget { ctx.beginPath() if (show_text) - ctx.roundRect(margin, y, widget_width - margin * 2, H, [H * 0.5]) - else ctx.rect(margin, y, widget_width - margin * 2, H) + ctx.roundRect(margin, y, width - margin * 2, height, [height * 0.5]) + else ctx.rect(margin, y, width - margin * 2, height) ctx.fill() if (show_text && !this.disabled) ctx.stroke() ctx.fillStyle = this.value ? "#89A" : "#333" ctx.beginPath() ctx.arc( - widget_width - margin * 2, - y + H * 0.5, - H * 0.36, + width - margin * 2, + y + height * 0.5, + height * 0.36, 0, Math.PI * 2, ) @@ -50,14 +48,14 @@ export class BooleanWidget extends BaseWidget implements IBooleanWidget { ctx.fillStyle = this.secondary_text_color const label = this.label || this.name if (label != null) { - ctx.fillText(label, margin * 2, y + H * 0.7) + ctx.fillText(label, margin * 2, y + height * 0.7) } ctx.fillStyle = this.value ? this.text_color : this.secondary_text_color ctx.textAlign = "right" ctx.fillText( this.value ? this.options.on || "true" : this.options.off || "false", - widget_width - 40, - y + H * 0.7, + width - 40, + y + height * 0.7, ) } } diff --git a/src/widgets/ButtonWidget.ts b/src/widgets/ButtonWidget.ts index b407c095b..2f0410072 100644 --- a/src/widgets/ButtonWidget.ts +++ b/src/widgets/ButtonWidget.ts @@ -3,7 +3,7 @@ import type { LGraphNode } from "@/LGraphNode" import type { CanvasMouseEvent } from "@/types/events" import type { IButtonWidget, IWidgetOptions } from "@/types/widgets" -import { BaseWidget } from "./BaseWidget" +import { BaseWidget, type DrawWidgetOptions } from "./BaseWidget" export class ButtonWidget extends BaseWidget implements IButtonWidget { // IButtonWidget properties @@ -23,20 +23,18 @@ export class ButtonWidget extends BaseWidget implements IButtonWidget { * @param ctx The canvas context * @param options The options for drawing the widget */ - override drawWidget(ctx: CanvasRenderingContext2D, options: { - y: number - width: number - show_text?: boolean - margin?: number - }) { + override drawWidget(ctx: CanvasRenderingContext2D, { + y, + width, + show_text = true, + margin = 15, + }: DrawWidgetOptions) { // Store original context attributes const originalTextAlign = ctx.textAlign const originalStrokeStyle = ctx.strokeStyle const originalFillStyle = ctx.fillStyle - const { y, width, show_text = true, margin = 15 } = options - const widget_width = width - const H = this.height + const { height } = this // Draw button background ctx.fillStyle = this.background_color @@ -44,12 +42,12 @@ export class ButtonWidget extends BaseWidget implements IButtonWidget { ctx.fillStyle = "#AAA" this.clicked = false } - ctx.fillRect(margin, y, widget_width - margin * 2, H) + ctx.fillRect(margin, y, width - margin * 2, height) // Draw button outline if not disabled if (show_text && !this.disabled) { ctx.strokeStyle = this.outline_color - ctx.strokeRect(margin, y, widget_width - margin * 2, H) + ctx.strokeRect(margin, y, width - margin * 2, height) } // Draw button text @@ -58,8 +56,8 @@ export class ButtonWidget extends BaseWidget implements IButtonWidget { ctx.fillStyle = this.text_color ctx.fillText( this.label || this.name || "", - widget_width * 0.5, - y + H * 0.7, + width * 0.5, + y + height * 0.7, ) } diff --git a/src/widgets/ComboWidget.ts b/src/widgets/ComboWidget.ts index 5d236c2c7..0d4bd53cc 100644 --- a/src/widgets/ComboWidget.ts +++ b/src/widgets/ComboWidget.ts @@ -5,7 +5,7 @@ import type { IComboWidget, IWidgetOptions } from "@/types/widgets" import { LiteGraph } from "@/litegraph" -import { BaseWidget } from "./BaseWidget" +import { BaseWidget, type DrawWidgetOptions } from "./BaseWidget" export class ComboWidget extends BaseWidget implements IComboWidget { // IComboWidget properties @@ -24,20 +24,18 @@ export class ComboWidget extends BaseWidget implements IComboWidget { * @param ctx The canvas context * @param options The options for drawing the widget */ - override drawWidget(ctx: CanvasRenderingContext2D, options: { - y: number - width: number - show_text?: boolean - margin?: number - }) { + override drawWidget(ctx: CanvasRenderingContext2D, { + y, + width, + show_text = true, + margin = 15, + }: DrawWidgetOptions) { // Store original context attributes const originalTextAlign = ctx.textAlign const originalStrokeStyle = ctx.strokeStyle const originalFillStyle = ctx.fillStyle - const { y, width, show_text = true, margin = 15 } = options - const widget_width = width - const H = this.height + const { height } = this ctx.textAlign = "left" ctx.strokeStyle = this.outline_color @@ -45,9 +43,9 @@ export class ComboWidget extends BaseWidget implements IComboWidget { ctx.beginPath() if (show_text) - ctx.roundRect(margin, y, widget_width - margin * 2, H, [H * 0.5]) + ctx.roundRect(margin, y, width - margin * 2, height, [height * 0.5]) else - ctx.rect(margin, y, widget_width - margin * 2, H) + ctx.rect(margin, y, width - margin * 2, height) ctx.fill() if (show_text) { @@ -57,14 +55,14 @@ export class ComboWidget extends BaseWidget implements IComboWidget { ctx.fillStyle = this.text_color ctx.beginPath() ctx.moveTo(margin + 16, y + 5) - ctx.lineTo(margin + 6, y + H * 0.5) - ctx.lineTo(margin + 16, y + H - 5) + ctx.lineTo(margin + 6, y + height * 0.5) + ctx.lineTo(margin + 16, y + height - 5) ctx.fill() // Draw right arrow ctx.beginPath() - ctx.moveTo(widget_width - margin - 16, y + 5) - ctx.lineTo(widget_width - margin - 6, y + H * 0.5) - ctx.lineTo(widget_width - margin - 16, y + H - 5) + ctx.moveTo(width - margin - 16, y + 5) + ctx.lineTo(width - margin - 6, y + height * 0.5) + ctx.lineTo(width - margin - 16, y + height - 5) ctx.fill() } @@ -72,7 +70,7 @@ export class ComboWidget extends BaseWidget implements IComboWidget { ctx.fillStyle = this.secondary_text_color const label = this.label || this.name if (label != null) { - ctx.fillText(label, margin * 2 + 5, y + H * 0.7) + ctx.fillText(label, margin * 2 + 5, y + height * 0.7) } // Draw value @@ -92,7 +90,7 @@ export class ComboWidget extends BaseWidget implements IComboWidget { } const labelWidth = ctx.measureText(label || "").width + margin * 2 - const inputWidth = widget_width - margin * 4 + const inputWidth = width - margin * 4 const availableWidth = inputWidth - labelWidth const textWidth = ctx.measureText(displayValue).width @@ -124,8 +122,8 @@ export class ComboWidget extends BaseWidget implements IComboWidget { ctx.fillText( displayValue, - widget_width - margin * 2 - 20, - y + H * 0.7, + width - margin * 2 - 20, + y + height * 0.7, ) } diff --git a/src/widgets/KnobWidget.ts b/src/widgets/KnobWidget.ts index b9eacd9b7..f7536618a 100644 --- a/src/widgets/KnobWidget.ts +++ b/src/widgets/KnobWidget.ts @@ -6,7 +6,7 @@ import { clamp } from "@/litegraph" import { CanvasMouseEvent } from "@/types/events" import { getWidgetStep } from "@/utils/widget" -import { BaseWidget } from "./BaseWidget" +import { BaseWidget, type DrawWidgetOptions } from "./BaseWidget" export class KnobWidget extends BaseWidget implements IKnobWidget { declare type: "knob" @@ -45,30 +45,28 @@ export class KnobWidget extends BaseWidget implements IKnobWidget { drawWidget( ctx: CanvasRenderingContext2D, - options: { - y: number - width: number - show_text?: boolean - margin?: number - gradient_stops?: string - }, + { + y, + width, + show_text = true, + margin = 15, + }: DrawWidgetOptions, ): void { // Store original context attributes const originalTextAlign = ctx.textAlign const originalStrokeStyle = ctx.strokeStyle const originalFillStyle = ctx.fillStyle - const { y, width: widget_width, show_text = true, margin = 15 } = options const { gradient_stops = "rgb(14, 182, 201); rgb(0, 216, 72)" } = this.options const effective_height = this.computedHeight || this.height // Draw background const size_modifier = Math.min(this.computedHeight || this.height, this.width || 20) / 20 // TODO: replace magic numbers - const arc_center = { x: widget_width / 2, y: effective_height / 2 + y } + const arc_center = { x: width / 2, y: effective_height / 2 + y } ctx.lineWidth = - (Math.min(widget_width, effective_height) - margin * size_modifier) / 6 + (Math.min(width, effective_height) - margin * size_modifier) / 6 const arc_size = - (Math.min(widget_width, effective_height) - + (Math.min(width, effective_height) - margin * size_modifier - ctx.lineWidth) / 2 { @@ -188,7 +186,7 @@ export class KnobWidget extends BaseWidget implements IKnobWidget { const fixedValue = Number(this.value).toFixed(this.options.precision ?? 3) ctx.fillText( `${this.label || this.name}\n${fixedValue}`, - widget_width * 0.5, + width * 0.5, y + effective_height * 0.5, ) } diff --git a/src/widgets/NumberWidget.ts b/src/widgets/NumberWidget.ts index c319a396d..1aa648efc 100644 --- a/src/widgets/NumberWidget.ts +++ b/src/widgets/NumberWidget.ts @@ -5,7 +5,7 @@ import type { INumericWidget, IWidgetOptions } from "@/types/widgets" import { getWidgetStep } from "@/utils/widget" -import { BaseWidget } from "./BaseWidget" +import { BaseWidget, type DrawWidgetOptions } from "./BaseWidget" export class NumberWidget extends BaseWidget implements INumericWidget { // INumberWidget properties @@ -24,20 +24,18 @@ export class NumberWidget extends BaseWidget implements INumericWidget { * @param ctx The canvas context * @param options The options for drawing the widget */ - override drawWidget(ctx: CanvasRenderingContext2D, options: { - y: number - width: number - show_text?: boolean - margin?: number - }) { + override drawWidget(ctx: CanvasRenderingContext2D, { + y, + width, + show_text = true, + margin = 15, + }: DrawWidgetOptions) { // Store original context attributes const originalTextAlign = ctx.textAlign const originalStrokeStyle = ctx.strokeStyle const originalFillStyle = ctx.fillStyle - const { y, width, show_text = true, margin = 15 } = options - const widget_width = width - const H = this.height + const { height } = this ctx.textAlign = "left" ctx.strokeStyle = this.outline_color @@ -45,9 +43,9 @@ export class NumberWidget extends BaseWidget implements INumericWidget { ctx.beginPath() if (show_text) - ctx.roundRect(margin, y, widget_width - margin * 2, H, [H * 0.5]) + ctx.roundRect(margin, y, width - margin * 2, height, [height * 0.5]) else - ctx.rect(margin, y, widget_width - margin * 2, H) + ctx.rect(margin, y, width - margin * 2, height) ctx.fill() if (show_text) { @@ -57,14 +55,14 @@ export class NumberWidget extends BaseWidget implements INumericWidget { ctx.fillStyle = this.text_color ctx.beginPath() ctx.moveTo(margin + 16, y + 5) - ctx.lineTo(margin + 6, y + H * 0.5) - ctx.lineTo(margin + 16, y + H - 5) + ctx.lineTo(margin + 6, y + height * 0.5) + ctx.lineTo(margin + 16, y + height - 5) ctx.fill() // Draw right arrow ctx.beginPath() - ctx.moveTo(widget_width - margin - 16, y + 5) - ctx.lineTo(widget_width - margin - 6, y + H * 0.5) - ctx.lineTo(widget_width - margin - 16, y + H - 5) + ctx.moveTo(width - margin - 16, y + 5) + ctx.lineTo(width - margin - 6, y + height * 0.5) + ctx.lineTo(width - margin - 16, y + height - 5) ctx.fill() } @@ -72,7 +70,7 @@ export class NumberWidget extends BaseWidget implements INumericWidget { ctx.fillStyle = this.secondary_text_color const label = this.label || this.name if (label != null) { - ctx.fillText(label, margin * 2 + 5, y + H * 0.7) + ctx.fillText(label, margin * 2 + 5, y + height * 0.7) } // Draw value @@ -84,8 +82,8 @@ export class NumberWidget extends BaseWidget implements INumericWidget { ? this.options.precision : 3, ), - widget_width - margin * 2 - 20, - y + H * 0.7, + width - margin * 2 - 20, + y + height * 0.7, ) } diff --git a/src/widgets/SliderWidget.ts b/src/widgets/SliderWidget.ts index c2193205a..be9fabd59 100644 --- a/src/widgets/SliderWidget.ts +++ b/src/widgets/SliderWidget.ts @@ -5,7 +5,7 @@ import type { ISliderWidget, IWidgetSliderOptions } from "@/types/widgets" import { clamp } from "@/litegraph" -import { BaseWidget } from "./BaseWidget" +import { BaseWidget, type DrawWidgetOptions } from "./BaseWidget" export class SliderWidget extends BaseWidget implements ISliderWidget { // ISliderWidget properties @@ -27,23 +27,22 @@ export class SliderWidget extends BaseWidget implements ISliderWidget { * @param ctx The canvas context * @param options The options for drawing the widget */ - override drawWidget(ctx: CanvasRenderingContext2D, options: { - y: number - width: number - show_text?: boolean - margin?: number - }) { + override drawWidget(ctx: CanvasRenderingContext2D, { + y, + width, + show_text = true, + margin = 15, + }: DrawWidgetOptions) { // Store original context attributes const originalTextAlign = ctx.textAlign const originalStrokeStyle = ctx.strokeStyle const originalFillStyle = ctx.fillStyle - const { y, width: widget_width, show_text = true, margin = 15 } = options - const H = this.height + const { height } = this // Draw background ctx.fillStyle = this.background_color - ctx.fillRect(margin, y, widget_width - margin * 2, H) + ctx.fillRect(margin, y, width - margin * 2, height) // Calculate normalized value const range = this.options.max - this.options.min @@ -52,12 +51,12 @@ export class SliderWidget extends BaseWidget implements ISliderWidget { // Draw slider bar ctx.fillStyle = this.options.slider_color ?? "#678" - ctx.fillRect(margin, y, nvalue * (widget_width - margin * 2), H) + ctx.fillRect(margin, y, nvalue * (width - margin * 2), height) // Draw outline if not disabled if (show_text && !this.disabled) { ctx.strokeStyle = this.outline_color - ctx.strokeRect(margin, y, widget_width - margin * 2, H) + ctx.strokeRect(margin, y, width - margin * 2, height) } // Draw marker if present @@ -66,10 +65,10 @@ export class SliderWidget extends BaseWidget implements ISliderWidget { marker_nvalue = clamp(marker_nvalue, 0, 1) ctx.fillStyle = this.options.marker_color ?? "#AA9" ctx.fillRect( - margin + marker_nvalue * (widget_width - margin * 2), + margin + marker_nvalue * (width - margin * 2), y, 2, - H, + height, ) } @@ -80,8 +79,8 @@ export class SliderWidget extends BaseWidget implements ISliderWidget { const fixedValue = Number(this.value).toFixed(this.options.precision ?? 3) ctx.fillText( `${this.label || this.name} ${fixedValue}`, - widget_width * 0.5, - y + H * 0.7, + width * 0.5, + y + height * 0.7, ) } diff --git a/src/widgets/TextWidget.ts b/src/widgets/TextWidget.ts index f86054b47..0c2d2b86b 100644 --- a/src/widgets/TextWidget.ts +++ b/src/widgets/TextWidget.ts @@ -3,7 +3,7 @@ import type { LGraphNode } from "@/LGraphNode" import type { CanvasMouseEvent } from "@/types/events" import type { IStringWidget, IWidgetOptions } from "@/types/widgets" -import { BaseWidget } from "./BaseWidget" +import { BaseWidget, type DrawWidgetOptions } from "./BaseWidget" export class TextWidget extends BaseWidget implements IStringWidget { // IStringWidget properties @@ -22,20 +22,18 @@ export class TextWidget extends BaseWidget implements IStringWidget { * @param ctx The canvas context * @param options The options for drawing the widget */ - override drawWidget(ctx: CanvasRenderingContext2D, options: { - y: number - width: number - show_text?: boolean - margin?: number - }) { + override drawWidget(ctx: CanvasRenderingContext2D, { + y, + width, + show_text = true, + margin = 15, + }: DrawWidgetOptions) { // Store original context attributes const originalTextAlign = ctx.textAlign const originalStrokeStyle = ctx.strokeStyle const originalFillStyle = ctx.fillStyle - const { y, width, show_text = true, margin = 15 } = options - const widget_width = width - const H = this.height + const { height } = this ctx.textAlign = "left" ctx.strokeStyle = this.outline_color @@ -43,23 +41,23 @@ export class TextWidget extends BaseWidget implements IStringWidget { ctx.beginPath() if (show_text) - ctx.roundRect(margin, y, widget_width - margin * 2, H, [H * 0.5]) + ctx.roundRect(margin, y, width - margin * 2, height, [height * 0.5]) else - ctx.rect(margin, y, widget_width - margin * 2, H) + ctx.rect(margin, y, width - margin * 2, height) ctx.fill() if (show_text) { if (!this.disabled) ctx.stroke() ctx.save() ctx.beginPath() - ctx.rect(margin, y, widget_width - margin * 2, H) + ctx.rect(margin, y, width - margin * 2, height) ctx.clip() // Draw label ctx.fillStyle = this.secondary_text_color const label = this.label || this.name if (label != null) { - ctx.fillText(label, margin * 2, y + H * 0.7) + ctx.fillText(label, margin * 2, y + height * 0.7) } // Draw value @@ -68,8 +66,8 @@ export class TextWidget extends BaseWidget implements IStringWidget { ctx.fillText( // 30 chars max String(this.value).substr(0, 30), - widget_width - margin * 2, - y + H * 0.7, + width - margin * 2, + y + height * 0.7, ) ctx.restore() }