mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-04-30 19:21:54 +00:00
Type cleanup, annotation as function, fix import
Naming now uniformly refers to the widget as an Annotated Number and the widget is now implemented as a proper typescript class annotatedNumber widgets can optionally have an annotation function set. This allows for extensions to set annotations on ranges of values. Fixed the app import incorrectly having an extension
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
import { LiteGraph, LGraphCanvas } from '@comfyorg/litegraph'
|
import { LiteGraph, LGraphCanvas } from '@comfyorg/litegraph'
|
||||||
import { app } from '../../scripts/app.js'
|
import { app } from '../../scripts/app'
|
||||||
import { getColorPalette } from './colorPalette'
|
import { getColorPalette } from './colorPalette'
|
||||||
import { ComfyWidgets } from '../../scripts/widgets'
|
import { ComfyWidgets } from '../../scripts/widgets'
|
||||||
import { LGraphNode } from '@comfyorg/litegraph'
|
import { LGraphNode } from '@comfyorg/litegraph'
|
||||||
@@ -96,12 +96,21 @@ function draw(ctx, node, widget_width, y, H) {
|
|||||||
this.options.precision !== undefined ? this.options.precision : 3
|
this.options.precision !== undefined ? this.options.precision : 3
|
||||||
)
|
)
|
||||||
ctx.fillText(text, widget_width - margin * 2 - 20, y + H * 0.7)
|
ctx.fillText(text, widget_width - margin * 2 - 20, y + H * 0.7)
|
||||||
if (this.options.mappedValues && this.value in this.options.mappedValues) {
|
let annotation = ''
|
||||||
|
if (this.annotation) {
|
||||||
|
annotation = this.annotation(this.value)
|
||||||
|
} else if (
|
||||||
|
this.options.annotation &&
|
||||||
|
this.value in this.options.annotation
|
||||||
|
) {
|
||||||
|
annotation = this.options.annotation[this.value]
|
||||||
|
}
|
||||||
|
if (annotation) {
|
||||||
//TODO: measure this text
|
//TODO: measure this text
|
||||||
ctx.fillStyle = litegraph_base.WIDGET_OUTLINE_COLOR
|
ctx.fillStyle = litegraph_base.WIDGET_OUTLINE_COLOR
|
||||||
const value_width = ctx.measureText(text).width
|
const value_width = ctx.measureText(text).width
|
||||||
ctx.fillText(
|
ctx.fillText(
|
||||||
this.options.mappedValues[this.value],
|
annotation,
|
||||||
widget_width - margin * 2 - 25 - value_width,
|
widget_width - margin * 2 - 25 - value_width,
|
||||||
y + H * 0.7
|
y + H * 0.7
|
||||||
)
|
)
|
||||||
@@ -171,28 +180,35 @@ function mouse(event, [x, y], node) {
|
|||||||
)
|
)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
function mappednumber(node, inputName, inputData, app): { widget: IWidget } {
|
class AnnotatedNumber implements IWidget {
|
||||||
// @ts-expect-error We are defining a new type
|
// @ts-expect-error We must forcibly set a type here to allow custom mouse and draw
|
||||||
const type: widgetType = 'MAPPEDNUMBER'
|
type: widgetTypes = 'annotatedNumber'
|
||||||
let w = {
|
draw = draw
|
||||||
name: inputName,
|
mouse = mouse
|
||||||
type: type,
|
options = {}
|
||||||
value: 0,
|
linkedWidgets = []
|
||||||
draw: draw,
|
name: string
|
||||||
mouse: mouse,
|
value: number
|
||||||
computeSize: undefined, //TODO: calculate minimum width
|
annotation: (value: number) => string
|
||||||
options: {},
|
computeSize(width: number): [number, number] {
|
||||||
linkedWidgets: []
|
return [width, 20]
|
||||||
}
|
}
|
||||||
if (inputData.length > 1) {
|
constructor(inputName, inputData) {
|
||||||
w.options = inputData[1]
|
this.name = inputName
|
||||||
for (let k of ['default', 'min', 'max']) {
|
if (inputData.length > 1) {
|
||||||
if (inputData[1][k] != undefined) {
|
this.options = inputData[1]
|
||||||
w.value = inputData[1][k]
|
for (let k of ['default', 'min', 'max']) {
|
||||||
break
|
if (inputData[1][k] != undefined) {
|
||||||
|
this.value = inputData[1][k]
|
||||||
|
break
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function annotatedNumber(node, inputName, inputData, app): { widget: IWidget } {
|
||||||
|
let w = new AnnotatedNumber(inputName, inputData)
|
||||||
if (!node.widgets) {
|
if (!node.widgets) {
|
||||||
node.widgets = []
|
node.widgets = []
|
||||||
}
|
}
|
||||||
@@ -209,14 +225,14 @@ ComfyWidgets.FLOAT = function (
|
|||||||
if (
|
if (
|
||||||
inputData[1]?.reset == undefined &&
|
inputData[1]?.reset == undefined &&
|
||||||
inputData[1]?.disable == undefined &&
|
inputData[1]?.disable == undefined &&
|
||||||
inputData[1]?.mappedValues == undefined
|
inputData[1]?.annotation == undefined
|
||||||
) {
|
) {
|
||||||
return originalFLOAT(node, inputName, inputData, app)
|
return originalFLOAT(node, inputName, inputData, app)
|
||||||
}
|
}
|
||||||
if (inputData[1]['display'] === 'slider') {
|
if (inputData[1]['display'] === 'slider') {
|
||||||
return originalFLOAT(node, inputName, inputData, app)
|
return originalFLOAT(node, inputName, inputData, app)
|
||||||
}
|
}
|
||||||
return mappednumber(node, inputName, inputData, app)
|
return annotatedNumber(node, inputName, inputData, app)
|
||||||
}
|
}
|
||||||
const originalINT = ComfyWidgets.INT
|
const originalINT = ComfyWidgets.INT
|
||||||
ComfyWidgets.INT = function (
|
ComfyWidgets.INT = function (
|
||||||
@@ -228,27 +244,23 @@ ComfyWidgets.INT = function (
|
|||||||
if (
|
if (
|
||||||
inputData[1]?.reset ||
|
inputData[1]?.reset ||
|
||||||
inputData[1]?.disable ||
|
inputData[1]?.disable ||
|
||||||
inputData[1]?.mappedValues
|
inputData[1]?.annotation
|
||||||
) {
|
) {
|
||||||
return mappednumber(node, inputName, inputData, app)
|
return annotatedNumber(node, inputName, inputData, app)
|
||||||
}
|
}
|
||||||
return originalINT(node, inputName, inputData, app)
|
return originalINT(node, inputName, inputData, app)
|
||||||
}
|
}
|
||||||
|
|
||||||
app.registerExtension({
|
app.registerExtension({
|
||||||
name: 'Comfy.MappedNumber',
|
name: 'Comfy.AnnotatedNumber',
|
||||||
async getCustomWidgets(app) {
|
async getCustomWidgets(app) {
|
||||||
return {
|
return {
|
||||||
MAPPEDNUMBER: mappednumber
|
ANNOTATEDNUMBER: annotatedNumber
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
registerCustomNodes() {
|
registerCustomNodes() {
|
||||||
class TestNum extends LGraphNode {
|
class TestNum extends LGraphNode {
|
||||||
static category = 'utils'
|
static category = 'utils'
|
||||||
|
|
||||||
color = LGraphCanvas.node_colors.yellow.color
|
|
||||||
bgcolor = LGraphCanvas.node_colors.yellow.bgcolor
|
|
||||||
groupcolor = LGraphCanvas.node_colors.yellow.groupcolor
|
|
||||||
isVirtualNode = true
|
isVirtualNode = true
|
||||||
collapsable = true
|
collapsable = true
|
||||||
title_mode = LiteGraph.NORMAL_TITLE
|
title_mode = LiteGraph.NORMAL_TITLE
|
||||||
@@ -256,25 +268,30 @@ app.registerExtension({
|
|||||||
|
|
||||||
constructor(title?: string) {
|
constructor(title?: string) {
|
||||||
super(title)
|
super(title)
|
||||||
app.widgets.MAPPEDNUMBER(
|
app.widgets.ANNOTATEDNUMBER(
|
||||||
// Should we extends LGraphNode? Yesss
|
// Should we extends LGraphNode? Yesss
|
||||||
this,
|
this,
|
||||||
'x',
|
'x',
|
||||||
[
|
[
|
||||||
'MAPPEDNUMBER',
|
'ANNOTATEDNUMBER',
|
||||||
{
|
{
|
||||||
default: 5,
|
default: 5,
|
||||||
reset: 5,
|
reset: 5,
|
||||||
disable: 0,
|
disable: 0,
|
||||||
mappedValues: { 6: 'def+1', 5: 'default', 0: 'disabled' },
|
annotation: { 6: 'def+1', 5: 'default', 0: 'disabled' },
|
||||||
step: 10
|
step: 10
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
app
|
app
|
||||||
)
|
)
|
||||||
|
let annotatedWidget = this.widgets[0] as AnnotatedNumber
|
||||||
|
annotatedWidget.annotation = function (value) {
|
||||||
|
return ['smol', 'medium', 'big', 'real big'][
|
||||||
|
Math.floor(Math.log10(value))
|
||||||
|
]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load default visibility
|
// Load default visibility
|
||||||
|
|
||||||
LiteGraph.registerNodeType('TestNum', TestNum)
|
LiteGraph.registerNodeType('TestNum', TestNum)
|
||||||
|
|||||||
Reference in New Issue
Block a user