Skip to content

Commit 714e3e9

Browse files
committed
refactor(ComboWidget): just use ComboWidget
1 parent 878c3b0 commit 714e3e9

File tree

13 files changed

+1488
-846
lines changed

13 files changed

+1488
-846
lines changed

src/components/graph/GraphCanvas.vue

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,6 @@ import SideToolbar from '@/components/sidebar/SideToolbar.vue'
115115
import TopbarBadges from '@/components/topbar/TopbarBadges.vue'
116116
import WorkflowTabs from '@/components/topbar/WorkflowTabs.vue'
117117
import { useChainCallback } from '@/composables/functional/useChainCallback'
118-
import { useCanvasRefresh } from '@/composables/graph/useCanvasRefresh'
119118
import type { VueNodeData } from '@/composables/graph/useGraphNodeManager'
120119
import { useViewportCulling } from '@/composables/graph/useViewportCulling'
121120
import { useVueNodeLifecycle } from '@/composables/graph/useVueNodeLifecycle'
@@ -128,7 +127,6 @@ import { usePaste } from '@/composables/usePaste'
128127
import { useVueFeatureFlags } from '@/composables/useVueFeatureFlags'
129128
import { i18n, t } from '@/i18n'
130129
import { LiteGraph } from '@/lib/litegraph/src/litegraph'
131-
import { isCloud } from '@/platform/distribution/types'
132130
import { useLitegraphSettings } from '@/platform/settings/composables/useLitegraphSettings'
133131
import { CORE_SETTINGS } from '@/platform/settings/constants/coreSettings'
134132
import { useSettingStore } from '@/platform/settings/settingStore'
@@ -148,7 +146,6 @@ import { ChangeTracker } from '@/scripts/changeTracker'
148146
import { IS_CONTROL_WIDGET, updateControlWidgetLabel } from '@/scripts/widgets'
149147
import { useColorPaletteService } from '@/services/colorPaletteService'
150148
import { newUserService } from '@/services/newUserService'
151-
import { useAssetsStore } from '@/stores/assetsStore'
152149
import { useCommandStore } from '@/stores/commandStore'
153150
import { useExecutionStore } from '@/stores/executionStore'
154151
import { useNodeDefStore } from '@/stores/nodeDefStore'
@@ -175,8 +172,6 @@ const toastStore = useToastStore()
175172
const colorPaletteStore = useColorPaletteStore()
176173
const colorPaletteService = useColorPaletteService()
177174
const canvasInteractions = useCanvasInteractions()
178-
const assetsStore = useAssetsStore()
179-
const { refreshCanvas } = useCanvasRefresh()
180175
181176
const betaMenuEnabled = computed(
182177
() => settingStore.get('Comfy.UseNewMenu') !== 'Disabled'
@@ -227,18 +222,6 @@ watch(
227222
}
228223
)
229224
230-
// Refresh canvas when input assets are loaded (cloud only)
231-
if (isCloud) {
232-
watch(
233-
() => assetsStore.inputAssets.length,
234-
(newLength, oldLength) => {
235-
if (oldLength === 0 && newLength > 0) {
236-
refreshCanvas()
237-
}
238-
}
239-
)
240-
}
241-
242225
const allNodes = computed((): VueNodeData[] =>
243226
Array.from(vueNodeLifecycle.nodeManager.value?.vueNodeData?.values() ?? [])
244227
)

src/lib/litegraph/src/litegraph.ts

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -148,11 +148,7 @@ export { BaseWidget } from './widgets/BaseWidget'
148148

149149
export { LegacyWidget } from './widgets/LegacyWidget'
150150

151-
export {
152-
isComboWidget,
153-
isMappedComboWidget,
154-
isAssetWidget
155-
} from './widgets/widgetMap'
151+
export { isComboWidget, isAssetWidget } from './widgets/widgetMap'
156152
// Additional test-specific exports
157153
export { LGraphButton } from './LGraphButton'
158154
export { MovingOutputLink } from './canvas/MovingOutputLink'

src/lib/litegraph/src/types/widgets.ts

Lines changed: 6 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ export interface IWidgetOptions<TValues = unknown[]> {
2929
canvasOnly?: boolean
3030

3131
values?: TValues
32+
/** Optional function to format values for display (e.g., hash → human-readable name) */
33+
getOptionLabel?: (value?: string | null) => string
3234
callback?: IWidget['callback']
3335
}
3436

@@ -63,7 +65,6 @@ export type IWidget =
6365
| IStringWidget
6466
| IComboWidget
6567
| IStringComboWidget
66-
| IMappedComboWidget
6768
| ICustomWidget
6869
| ISliderWidget
6970
| IButtonWidget
@@ -117,37 +118,22 @@ export interface IStringComboWidget
117118
value: string
118119
}
119120

120-
export type ComboWidgetValues =
121+
type ComboWidgetValues =
121122
| string[]
122123
| Record<string, string>
123124
| ((widget?: IComboWidget, node?: LGraphNode) => string[])
124125

125-
/**
126-
* Type accepts both 'combo' and 'mapped_combo' for polymorphism with {@link IMappedComboWidget}.
127-
*
128-
* This matches runtime: MappedComboWidget class extends ComboWidget class, so instances of
129-
* MappedComboWidget must be assignable to functions/properties expecting IComboWidget.
130-
*/
126+
/** A combo-box widget (dropdown, select, etc) */
131127
export interface IComboWidget
132128
extends IBaseWidget<
133129
string | number,
134-
'combo' | 'mapped_combo',
130+
'combo',
135131
RequiredProps<IWidgetOptions<ComboWidgetValues>, 'values'>
136132
> {
137-
type: 'combo' | 'mapped_combo'
133+
type: 'combo'
138134
value: string | number
139135
}
140136

141-
/** A mapped combo widget that displays human-readable names for hash-based filenames */
142-
export interface IMappedComboWidget
143-
extends Omit<IComboWidget, 'type' | 'options'> {
144-
type: 'mapped_combo'
145-
options: RequiredProps<IWidgetOptions<ComboWidgetValues>, 'values'> & {
146-
/** Optional function to map widget value to display value (e.g., hash filename to human-readable name) */
147-
mapValue?: (value: string) => string
148-
}
149-
}
150-
151137
/** A widget with a string value */
152138
export interface IStringWidget
153139
extends IBaseWidget<string, 'string' | 'text', IWidgetOptions<string[]>> {

src/lib/litegraph/src/utils/hashFilenameUtils.ts

Lines changed: 0 additions & 22 deletions
This file was deleted.

src/lib/litegraph/src/widgets/ComboWidget.ts

Lines changed: 39 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,17 +30,28 @@ export class ComboWidget
3030
extends BaseSteppedWidget<IStringComboWidget | IComboWidget>
3131
implements IComboWidget
3232
{
33-
// Accepts 'mapped_combo' to allow MappedComboWidget subclass to override
34-
override type: 'combo' | 'mapped_combo' = 'combo'
33+
override type = 'combo' as const
3534

3635
override get _displayValue() {
3736
if (this.computedDisabled) return ''
37+
38+
if (this.options.getOptionLabel) {
39+
try {
40+
return this.options.getOptionLabel(
41+
this.value ? String(this.value) : null
42+
)
43+
} catch (e) {
44+
console.error('Failed to map value:', e)
45+
return this.value ? String(this.value) : ''
46+
}
47+
}
48+
3849
const { values: rawValues } = this.options
3950
if (rawValues) {
4051
const values = typeof rawValues === 'function' ? rawValues() : rawValues
4152

4253
if (values && !Array.isArray(values)) {
43-
return values[String(this.value)]
54+
return values[this.value]
4455
}
4556
}
4657
return typeof this.value === 'number' ? String(this.value) : this.value
@@ -132,7 +143,31 @@ export class ComboWidget
132143
const values = this.getValues(node)
133144
const values_list = toArray(values)
134145

135-
// Handle center click - show dropdown menu
146+
// Use addItem to solve duplicate filename issues
147+
if (this.options.getOptionLabel) {
148+
const menuOptions = {
149+
scale: Math.max(1, canvas.ds.scale),
150+
event: e,
151+
className: 'dark',
152+
callback: (value: string) => {
153+
this.setValue(value, { e, node, canvas })
154+
}
155+
}
156+
const menu = new LiteGraph.ContextMenu([], menuOptions)
157+
158+
for (const value of values_list) {
159+
try {
160+
const label = this.options.getOptionLabel(String(value))
161+
menu.addItem(label, value, menuOptions)
162+
} catch (err) {
163+
console.error('Failed to map value:', err)
164+
menu.addItem(String(value), value, menuOptions)
165+
}
166+
}
167+
return
168+
}
169+
170+
// Show dropdown menu when user clicks on widget label
136171
const text_values = values != values_list ? Object.values(values) : values
137172
new LiteGraph.ContextMenu(text_values, {
138173
scale: Math.max(1, canvas.ds.scale),

src/lib/litegraph/src/widgets/MappedComboWidget.ts

Lines changed: 0 additions & 95 deletions
This file was deleted.

src/lib/litegraph/src/widgets/widgetMap.ts

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ import type {
33
IAssetWidget,
44
IBaseWidget,
55
IComboWidget,
6-
IMappedComboWidget,
76
IWidget,
87
TWidgetType
98
} from '@/lib/litegraph/src/types/widgets'
@@ -21,7 +20,6 @@ import { GalleriaWidget } from './GalleriaWidget'
2120
import { ImageCompareWidget } from './ImageCompareWidget'
2221
import { KnobWidget } from './KnobWidget'
2322
import { LegacyWidget } from './LegacyWidget'
24-
import { MappedComboWidget } from './MappedComboWidget'
2523
import { MarkdownWidget } from './MarkdownWidget'
2624
import { MultiSelectWidget } from './MultiSelectWidget'
2725
import { NumberWidget } from './NumberWidget'
@@ -37,7 +35,6 @@ export type WidgetTypeMap = {
3735
slider: SliderWidget
3836
knob: KnobWidget
3937
combo: ComboWidget
40-
mapped_combo: MappedComboWidget
4138
number: NumberWidget
4239
string: TextWidget
4340
text: TextWidget
@@ -95,11 +92,6 @@ export function toConcreteWidget<TWidget extends IWidget | IBaseWidget>(
9592
return toClass(KnobWidget, narrowedWidget, node)
9693
case 'combo':
9794
return toClass(ComboWidget, narrowedWidget, node)
98-
case 'mapped_combo':
99-
if (!isMappedComboWidget(narrowedWidget)) {
100-
throw new Error('Expected IMappedComboWidget but got IComboWidget')
101-
}
102-
return toClass(MappedComboWidget, narrowedWidget, node)
10395
case 'number':
10496
return toClass(NumberWidget, narrowedWidget, node)
10597
case 'string':
@@ -141,13 +133,6 @@ export function isComboWidget(widget: IBaseWidget): widget is IComboWidget {
141133
return widget.type === 'combo'
142134
}
143135

144-
/** Type guard: Narrow **from {@link IBaseWidget}** to {@link IMappedComboWidget}. */
145-
export function isMappedComboWidget(
146-
widget: IBaseWidget
147-
): widget is IMappedComboWidget {
148-
return widget.type === 'mapped_combo'
149-
}
150-
151136
/** Type guard: Narrow **from {@link IBaseWidget}** to {@link IAssetWidget}. */
152137
export function isAssetWidget(widget: IBaseWidget): widget is IAssetWidget {
153138
return widget.type === 'asset'

0 commit comments

Comments
 (0)