[Refactor] useFloatWidget composable (#2504)

This commit is contained in:
Chenlei Hu
2025-02-10 22:06:11 -05:00
committed by GitHub
parent b4c59ffae1
commit d4122a7510
3 changed files with 93 additions and 34 deletions

View File

@@ -0,0 +1,59 @@
import type { LGraphNode } from '@comfyorg/litegraph'
import type { INumericWidget } from '@comfyorg/litegraph/dist/types/widgets'
import type { ComfyWidgetConstructor } from '@/scripts/widgets'
import { useSettingStore } from '@/stores/settingStore'
import type { InputSpec } from '@/types/apiTypes'
import { getNumberDefaults } from '@/utils/mathUtil'
export const useFloatWidget = () => {
const widgetConstructor: ComfyWidgetConstructor = (
node: LGraphNode,
inputName: string,
inputData: InputSpec
) => {
// TODO: Move to outer scope to avoid re-initializing on every call
// Blocked on ComfyWidgets lazy initialization.
const settingStore = useSettingStore()
const sliderEnabled = !settingStore.get('Comfy.DisableSliders')
const inputOptions = inputData[1]
const widgetType = sliderEnabled
? inputOptions.display === 'slider'
? 'slider'
: 'number'
: 'number'
const precision =
settingStore.get('Comfy.FloatRoundingPrecision') || undefined
const enableRounding = !settingStore.get('Comfy.DisableFloatRounding')
const { val, config } = getNumberDefaults(inputOptions, {
defaultStep: 0.5,
precision,
enableRounding
})
return {
widget: node.addWidget(
widgetType,
inputName,
val,
function (this: INumericWidget, v: number) {
if (config.round) {
this.value =
Math.round((v + Number.EPSILON) / config.round) * config.round
if (this.value > config.max) this.value = config.max
if (this.value < config.min) this.value = config.min
} else {
this.value = v
}
},
config
)
}
}
return widgetConstructor
}

View File

@@ -14,6 +14,7 @@ import TiptapTableRow from '@tiptap/extension-table-row'
import TiptapStarterKit from '@tiptap/starter-kit'
import { Markdown as TiptapMarkdown } from 'tiptap-markdown'
import { useFloatWidget } from '@/composables/widgets/useFloatWidget'
import { useRemoteWidget } from '@/composables/widgets/useRemoteWidget'
import { useStringWidget } from '@/composables/widgets/useStringWidget'
import { useSettingStore } from '@/stores/settingStore'
@@ -434,40 +435,7 @@ function isSlider(display, app) {
export const ComfyWidgets: Record<string, ComfyWidgetConstructor> = {
'INT:seed': seedWidget,
'INT:noise_seed': seedWidget,
FLOAT(node, inputName, inputData: InputSpec, app) {
let widgetType: 'number' | 'slider' = isSlider(inputData[1]['display'], app)
let precision = app.ui.settings.getSettingValue(
'Comfy.FloatRoundingPrecision'
)
let disable_rounding = app.ui.settings.getSettingValue(
'Comfy.DisableFloatRounding'
)
if (precision == 0) precision = undefined
const { val, config } = getNumberDefaults(
inputData,
0.5,
precision,
!disable_rounding
)
return {
widget: node.addWidget(
widgetType,
inputName,
val,
function (v) {
if (config.round) {
this.value =
Math.round((v + Number.EPSILON) / config.round) * config.round
if (this.value > config.max) this.value = config.max
if (this.value < config.min) this.value = config.min
} else {
this.value = v
}
},
config
)
}
},
FLOAT: useFloatWidget(),
INT(node, inputName, inputData: InputSpec, app) {
return createIntWidget(node, inputName, inputData, app)
},

32
src/utils/mathUtil.ts Normal file
View File

@@ -0,0 +1,32 @@
import type { InputSpec } from '@/types/apiTypes'
export function getNumberDefaults(
inputOptions: InputSpec[1],
options: {
defaultStep: number
precision?: number
enableRounding: boolean
}
) {
const { defaultStep } = options
const {
default: defaultVal = 0,
min = 0,
max = 2048,
step = defaultStep
} = inputOptions
// precision is the number of decimal places to show.
// by default, display the the smallest number of decimal places such that changes of size step are visible.
const { precision = Math.max(-Math.floor(Math.log10(step)), 0) } = options
let round = inputOptions.round
if (options.enableRounding && (round == undefined || round === true)) {
// by default, round the value to those decimal places shown.
round = Math.round(1000000 * Math.pow(0.1, precision)) / 1000000
}
return {
val: defaultVal,
config: { min, max, step: 10.0 * step, round, precision }
}
}