fix vue node color change

This commit is contained in:
bymyself
2025-09-21 21:32:12 -07:00
parent 856eb446a5
commit 7414b94be1
5 changed files with 136 additions and 3 deletions

View File

@@ -0,0 +1,52 @@
import {
comfyExpect as expect,
comfyPageFixture as test
} from '../../../fixtures/ComfyPage'
test.describe('Vue Node Custom Colors', () => {
test.beforeEach(async ({ comfyPage }) => {
await comfyPage.setSetting('Comfy.UseNewMenu', 'Top')
await comfyPage.setSetting('Comfy.Canvas.SelectionToolbox', true)
await comfyPage.setSetting('Comfy.VueNodes.Enabled', true)
await comfyPage.vueNodes.waitForNodes()
})
test('displays color picker button and allows color selection', async ({
comfyPage
}) => {
const loadCheckpointNode = comfyPage.page.locator('[data-node-id]').filter({
hasText: 'Load Checkpoint'
})
await loadCheckpointNode.getByText('Load Checkpoint').click()
await comfyPage.page.locator('.selection-toolbox .pi-circle-fill').click()
await comfyPage.page
.locator('.color-picker-container')
.locator('i[data-testid="blue"]')
.click()
await expect(comfyPage.canvas).toHaveScreenshot(
'vue-node-custom-color-blue.png'
)
})
// TODO: implement loading node colors from workflow in Vue system
test.fail('should load node colors from workflow', async ({ comfyPage }) => {
await comfyPage.loadWorkflow('nodes/every_node_color')
await expect(comfyPage.canvas).toHaveScreenshot(
'vue-node-custom-colors-dark-all-colors.png'
)
})
// TODO: implement loading node colors from workflow in Vue system
test.fail(
'should show brightened node colors on light theme',
async ({ comfyPage }) => {
await comfyPage.setSetting('Comfy.ColorPalette', 'light')
await comfyPage.loadWorkflow('nodes/every_node_color')
await expect(comfyPage.canvas).toHaveScreenshot(
'vue-node-custom-colors-light-all-colors.png'
)
}
)
})

View File

@@ -41,6 +41,8 @@ export interface VueNodeData {
collapsed?: boolean
pinned?: boolean
}
color?: string
bgcolor?: string
}
export interface GraphNodeManager {
@@ -126,7 +128,9 @@ export function useGraphNodeManager(graph: LGraph): GraphNodeManager {
widgets: safeWidgets,
inputs: node.inputs ? [...node.inputs] : undefined,
outputs: node.outputs ? [...node.outputs] : undefined,
flags: node.flags ? { ...node.flags } : undefined
flags: node.flags ? { ...node.flags } : undefined,
color: node.color || undefined,
bgcolor: node.bgcolor || undefined
}
}
@@ -449,6 +453,24 @@ export function useGraphNodeManager(graph: LGraph): GraphNodeManager {
...currentData,
mode: typeof event.newValue === 'number' ? event.newValue : 0
})
break
case 'color':
vueNodeData.set(nodeId, {
...currentData,
color:
typeof event.newValue === 'string'
? event.newValue
: undefined
})
break
case 'bgcolor':
vueNodeData.set(nodeId, {
...currentData,
bgcolor:
typeof event.newValue === 'string'
? event.newValue
: undefined
})
}
}
} else if (

View File

@@ -332,6 +332,9 @@ export class LGraphNode
/** @inheritdoc {@link IColorable.setColorOption} */
setColorOption(colorOption: ColorOption | null): void {
const oldColor = this.color
const oldBgcolor = this.bgcolor
if (colorOption == null) {
delete this.color
delete this.bgcolor
@@ -339,6 +342,29 @@ export class LGraphNode
this.color = colorOption.color
this.bgcolor = colorOption.bgcolor
}
// Trigger property change events for Vue node synchronization
if (this.graph) {
const newColor = this.color // undefined if deleted
const newBgcolor = this.bgcolor // undefined if deleted
if (oldColor !== newColor) {
this.graph.trigger('node:property:changed', {
nodeId: this.id,
property: 'color',
oldValue: oldColor,
newValue: newColor
})
}
if (oldBgcolor !== newBgcolor) {
this.graph.trigger('node:property:changed', {
nodeId: this.id,
property: 'bgcolor',
oldValue: oldBgcolor,
newValue: newBgcolor
})
}
}
}
/** @inheritdoc {@link IColorable.getColorOption} */

View File

@@ -34,7 +34,8 @@
:style="[
{
transform: `translate(${position.x ?? 0}px, ${(position.y ?? 0) - LiteGraph.NODE_TITLE_HEIGHT}px)`,
zIndex: zIndex
zIndex: zIndex,
backgroundColor: nodeData.bgcolor || ''
},
dragStyle
]"
@@ -49,7 +50,13 @@
</template>
<!-- Header only updates on title/color changes -->
<NodeHeader
v-memo="[nodeData.title, isCollapsed, nodeData.flags?.pinned]"
v-memo="[
nodeData.title,
nodeData.color,
nodeData.bgcolor,
isCollapsed,
nodeData.flags?.pinned
]"
:node-data="nodeData"
:readonly="readonly"
:collapsed="isCollapsed"

View File

@@ -73,6 +73,8 @@ import { useErrorHandling } from '@/composables/useErrorHandling'
import { st } from '@/i18n'
import { useNodeTooltips } from '@/renderer/extensions/vueNodes/composables/useNodeTooltips'
import { app } from '@/scripts/app'
import { useColorPaletteStore } from '@/stores/workspace/colorPaletteStore'
import { adjustColor } from '@/utils/colorUtil'
import { normalizeI18nKey } from '@/utils/formatUtil'
import {
getLocatorIdFromNodeData,
@@ -123,6 +125,30 @@ const tooltipConfig = computed(() => {
return createTooltipConfig(description)
})
// Header style that replicates LiteGraph's ColorOption and drawNode logic
const headerStyle = computed(() => {
if (!nodeData?.color) {
return { backgroundColor: '' } // Explicitly clear background color
}
const colorPaletteStore = useColorPaletteStore()
let headerColor = nodeData.color
// Apply base header darkening to replicate LiteGraph's ColorOption system
// When header and body colors are the same/similar, darken the header
if (nodeData.bgcolor && nodeData.color === nodeData.bgcolor) {
// Darken header relative to body (opposite of light theme adjustment)
headerColor = adjustColor(nodeData.color, { lightness: -0.15 })
}
// Apply light theme lightening on top of base darkening (same as drawNode monkey patch)
if (colorPaletteStore.completedActivePalette.light_theme) {
headerColor = adjustColor(headerColor, { lightness: 0.5 })
}
return { backgroundColor: headerColor }
})
const resolveTitle = (info: VueNodeData | undefined) => {
const title = (info?.title ?? '').trim()
if (title.length > 0) return title