Widget overhaul (#1010)

### Widget text overhaul

#### Current
- Numbers and text overlap
- Combo boxes truncate the value before the label

![image](https://github.com/user-attachments/assets/c991b0b6-879f-4455-92d4-4254ef25b55c)

#### Proposed

**By default, widgets will now truncate their labels before their
values.**


https://github.com/user-attachments/assets/296ea5ab-d2ff-44f2-9139-5d97789e4f12

- Changes the way widget text is rendered, calculated, and truncated
- Truncation now applies in a standard way to the following widgets:
  - Text
  - Combo
  - Number
- Centralises widget draw routines in base class

### Config

```ts
// Truncate **both** widgets and labels evenly
LiteGraph.truncateWidgetTextEvenly = true

// Swap the default from truncating labels before values, to truncating values first (restores legacy behaviour)
// truncateWidgetTextEvenly **must** be `false`.
LiteGraph.truncateWidgetValuesFirst = true
```

### API / interfaces  

- Adds rich `Rectangle` concrete impl., with many methods and helpful
accessors (e.g. `right`, `bottom`)
- Actually _improves_ performance due to switch from Float32Array to
Float64Array
- Impact vs plain Float64Array was not detectable outside of a 2M+
instantiation-loop with random data
  - Lazy `pos` & `size` `subarray` properties
- Adds `ReadOnlySize`
- Adds higher-level text draw functions to abstract the nitty gritty in
a performant way (binary search)

- Resolves Comfy-Org/ComfyUI_frontend/issues/457
This commit is contained in:
filtered
2025-05-05 10:48:06 +10:00
committed by GitHub
parent 406abd7731
commit 75df19521b
14 changed files with 591 additions and 261 deletions

View File

@@ -24,54 +24,16 @@ export class TextWidget extends BaseWidget implements IStringWidget {
showText = true,
}: DrawWidgetOptions) {
// Store original context attributes
const originalTextAlign = ctx.textAlign
const originalStrokeStyle = ctx.strokeStyle
const originalFillStyle = ctx.fillStyle
const { fillStyle, strokeStyle, textAlign } = ctx
const { height, y } = this
const { margin } = BaseWidget
ctx.textAlign = "left"
ctx.strokeStyle = this.outline_color
ctx.fillStyle = this.background_color
ctx.beginPath()
if (showText)
ctx.roundRect(margin, y, width - margin * 2, height, [height * 0.5])
else
ctx.rect(margin, y, width - margin * 2, height)
ctx.fill()
this.drawWidgetShape(ctx, { width, showText })
if (showText) {
if (!this.computedDisabled) ctx.stroke()
ctx.save()
ctx.beginPath()
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 + height * 0.7)
}
// Draw value
ctx.fillStyle = this.text_color
ctx.textAlign = "right"
ctx.fillText(
// 30 chars max
String(this.value).substr(0, 30),
width - margin * 2,
y + height * 0.7,
)
ctx.restore()
this.drawTruncatingText({ ctx, width, leftPadding: 0, rightPadding: 0 })
}
// Restore original context attributes
ctx.textAlign = originalTextAlign
ctx.strokeStyle = originalStrokeStyle
ctx.fillStyle = originalFillStyle
Object.assign(ctx, { textAlign, strokeStyle, fillStyle })
}
override onClick({ e, node, canvas }: WidgetEventOptions) {