Files
ComfyUI_frontend/src/widgets/TextWidget.ts
filtered 75df19521b 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
2025-05-05 10:48:06 +10:00

54 lines
1.4 KiB
TypeScript

import type { IStringWidget, IWidgetOptions } from "@/types/widgets"
import { BaseWidget, type DrawWidgetOptions, type WidgetEventOptions } from "./BaseWidget"
export class TextWidget extends BaseWidget implements IStringWidget {
// IStringWidget properties
declare type: "text" | "string"
declare value: string
declare options: IWidgetOptions<string>
constructor(widget: IStringWidget) {
super(widget)
this.type = widget.type ?? "string"
this.value = widget.value?.toString() ?? ""
}
/**
* Draws the widget
* @param ctx The canvas context
* @param options The options for drawing the widget
*/
override drawWidget(ctx: CanvasRenderingContext2D, {
width,
showText = true,
}: DrawWidgetOptions) {
// Store original context attributes
const { fillStyle, strokeStyle, textAlign } = ctx
this.drawWidgetShape(ctx, { width, showText })
if (showText) {
this.drawTruncatingText({ ctx, width, leftPadding: 0, rightPadding: 0 })
}
// Restore original context attributes
Object.assign(ctx, { textAlign, strokeStyle, fillStyle })
}
override onClick({ e, node, canvas }: WidgetEventOptions) {
// Show prompt dialog for text input
canvas.prompt(
"Value",
this.value,
(v: string) => {
if (v !== null) {
this.setValue(v, { e, node, canvas })
}
},
e,
this.options?.multiline ?? false,
)
}
}