mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-03-13 17:10:06 +00:00
[Refactor] Generalize dom widget layout as Widget.computeLayoutSize hook (#2547)
This commit is contained in:
@@ -20,10 +20,10 @@ interface Rect {
|
||||
y: number
|
||||
}
|
||||
|
||||
interface DOMSizeInfo {
|
||||
interface SizeInfo {
|
||||
minHeight: number
|
||||
prefHeight?: number
|
||||
w: DOMWidget<HTMLElement, object>
|
||||
w: IWidget
|
||||
diff?: number
|
||||
}
|
||||
|
||||
@@ -127,12 +127,6 @@ function getClipPath(
|
||||
return ''
|
||||
}
|
||||
|
||||
function isDomWidget(
|
||||
widget: IWidget
|
||||
): widget is DOMWidget<HTMLElement, object> {
|
||||
return !!widget.element
|
||||
}
|
||||
|
||||
function computeSize(this: LGraphNode, size: Size): void {
|
||||
if (!this.widgets?.[0]?.last_y) return
|
||||
|
||||
@@ -141,7 +135,7 @@ function computeSize(this: LGraphNode, size: Size): void {
|
||||
|
||||
// Collect fixed height widgets first
|
||||
let fixedWidgetHeight = 0
|
||||
const domWidgets: DOMSizeInfo[] = []
|
||||
const layoutWidgets: SizeInfo[] = []
|
||||
|
||||
for (const w of this.widgets) {
|
||||
// @ts-expect-error custom widget type
|
||||
@@ -149,42 +143,15 @@ function computeSize(this: LGraphNode, size: Size): void {
|
||||
// Ignore
|
||||
// @ts-expect-error custom widget type
|
||||
delete w.computedHeight
|
||||
} else if (w.computeSize) {
|
||||
fixedWidgetHeight += w.computeSize()[1] + 4
|
||||
} else if (isDomWidget(w)) {
|
||||
// Extract DOM widget size info
|
||||
const styles = getComputedStyle(w.element)
|
||||
let minHeight =
|
||||
w.options.getMinHeight?.() ??
|
||||
parseInt(styles.getPropertyValue('--comfy-widget-min-height'))
|
||||
let maxHeight =
|
||||
w.options.getMaxHeight?.() ??
|
||||
parseInt(styles.getPropertyValue('--comfy-widget-max-height'))
|
||||
|
||||
let prefHeight: string | number =
|
||||
w.options.getHeight?.() ??
|
||||
styles.getPropertyValue('--comfy-widget-height')
|
||||
// @ts-expect-error number has no endsWith
|
||||
if (prefHeight.endsWith?.('%')) {
|
||||
prefHeight =
|
||||
size[1] *
|
||||
// @ts-expect-error number has no substring
|
||||
(parseFloat(prefHeight.substring(0, prefHeight.length - 1)) / 100)
|
||||
} else {
|
||||
// @ts-expect-error number is not assignable to param of type string
|
||||
prefHeight = parseInt(prefHeight)
|
||||
if (isNaN(minHeight)) {
|
||||
minHeight = prefHeight
|
||||
}
|
||||
}
|
||||
|
||||
domWidgets.push({
|
||||
minHeight: isNaN(minHeight) ? 50 : minHeight,
|
||||
prefHeight: isNaN(prefHeight)
|
||||
? undefined
|
||||
: Math.min(prefHeight, maxHeight ?? Infinity),
|
||||
} else if (w.computeLayoutSize) {
|
||||
const { minHeight, maxHeight } = w.computeLayoutSize(this)
|
||||
layoutWidgets.push({
|
||||
minHeight,
|
||||
prefHeight: maxHeight,
|
||||
w
|
||||
})
|
||||
} else if (w.computeSize) {
|
||||
fixedWidgetHeight += w.computeSize()[1] + 4
|
||||
} else {
|
||||
fixedWidgetHeight += LiteGraph.NODE_WIDGET_HEIGHT + 4
|
||||
}
|
||||
@@ -199,7 +166,7 @@ function computeSize(this: LGraphNode, size: Size): void {
|
||||
this.freeWidgetSpace = freeSpace
|
||||
|
||||
// Prepare space requests for distribution
|
||||
const spaceRequests = domWidgets.map((d) => ({
|
||||
const spaceRequests = layoutWidgets.map((d) => ({
|
||||
minSize: d.minHeight,
|
||||
maxSize: d.prefHeight
|
||||
}))
|
||||
@@ -208,7 +175,7 @@ function computeSize(this: LGraphNode, size: Size): void {
|
||||
const allocations = distributeSpace(Math.max(0, freeSpace), spaceRequests)
|
||||
|
||||
// Apply computed heights
|
||||
domWidgets.forEach((d, i) => {
|
||||
layoutWidgets.forEach((d, i) => {
|
||||
d.w.computedHeight = allocations[i]
|
||||
})
|
||||
|
||||
@@ -307,6 +274,40 @@ export class DOMWidgetImpl<T extends HTMLElement, V extends object | string>
|
||||
this.callback?.(this.value)
|
||||
}
|
||||
|
||||
/** Extract DOM widget size info */
|
||||
computeLayoutSize(node: LGraphNode) {
|
||||
const styles = getComputedStyle(this.element)
|
||||
let minHeight =
|
||||
this.options.getMinHeight?.() ??
|
||||
parseInt(styles.getPropertyValue('--comfy-widget-min-height'))
|
||||
let maxHeight =
|
||||
this.options.getMaxHeight?.() ??
|
||||
parseInt(styles.getPropertyValue('--comfy-widget-max-height'))
|
||||
|
||||
let prefHeight: string | number =
|
||||
this.options.getHeight?.() ??
|
||||
styles.getPropertyValue('--comfy-widget-height')
|
||||
|
||||
if (typeof prefHeight === 'string' && prefHeight.endsWith?.('%')) {
|
||||
prefHeight =
|
||||
node.size[1] *
|
||||
(parseFloat(prefHeight.substring(0, prefHeight.length - 1)) / 100)
|
||||
} else {
|
||||
prefHeight =
|
||||
typeof prefHeight === 'number' ? prefHeight : parseInt(prefHeight)
|
||||
|
||||
if (isNaN(minHeight)) {
|
||||
minHeight = prefHeight
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
minHeight: isNaN(minHeight) ? 50 : minHeight,
|
||||
maxHeight: isNaN(maxHeight) ? undefined : maxHeight,
|
||||
minWidth: 0
|
||||
}
|
||||
}
|
||||
|
||||
draw(
|
||||
ctx: CanvasRenderingContext2D,
|
||||
node: LGraphNode,
|
||||
|
||||
13
src/types/litegraph-augmentation.d.ts
vendored
13
src/types/litegraph-augmentation.d.ts
vendored
@@ -30,6 +30,19 @@ declare module '@comfyorg/litegraph/dist/types/widgets' {
|
||||
* See scripts/domWidget.ts for more details.
|
||||
*/
|
||||
computedHeight?: number
|
||||
|
||||
/**
|
||||
* Compute the layout size of the widget. Overrides {@link IBaseWidget.computeSize}.
|
||||
*/
|
||||
computeLayoutSize?: (
|
||||
this: IBaseWidget,
|
||||
node: LGraphNode
|
||||
) => {
|
||||
minHeight: number
|
||||
maxHeight?: number
|
||||
minWidth: number
|
||||
maxWidth?: number
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user