mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-01-26 19:09:52 +00:00
Add support for NO_TITLE in vue, disabling border (#7589)
When `node.title_mode` is set to `TitleMode.NO_TITLE` the node header is not displayed in vue mode. | Before | After | | ------ | ----- | | <img width="360" alt="before" src="https://github.com/user-attachments/assets/0e64c3df-8bcb-496f-a53c-618fdca79610"/> | <img width="360" alt="after" src="https://github.com/user-attachments/assets/34ea3a28-cc2e-4316-a154-40f54bdf8e60" />| When a node has specified both `NO_TITLE` and a transparent background, node borders are also disabled in vue mode. | Before | After | | ------ | ----- | | <img width="360" alt="before" src="https://github.com/user-attachments/assets/e52cf371-ba7e-401c-b9e5-b53607c26778"/> | <img width="360" alt="after" src="https://github.com/user-attachments/assets/979a4ba4-cf6d-49b3-ae97-6e1d62f487cc" />| Known issues: - `NODE_TITLE_HEIGHT` strikes again. <img width="254" height="64" alt="image" src="https://github.com/user-attachments/assets/526b1e2c-66dd-4c5d-9954-8c997a0ab5b8" /> ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-7589-Add-support-for-NO_TITLE-in-vue-disabling-border-2cc6d73d36508182834bc78ea8dffa27) by [Unito](https://www.unito.io)
This commit is contained in:
@@ -31,8 +31,9 @@ import type {
|
||||
LGraphTriggerAction,
|
||||
LGraphTriggerEvent,
|
||||
LGraphTriggerParam
|
||||
} from '../../lib/litegraph/src/litegraph'
|
||||
import { NodeSlotType } from '../../lib/litegraph/src/types/globalEnums'
|
||||
} from '@/lib/litegraph/src/litegraph'
|
||||
import type { TitleMode } from '@/lib/litegraph/src/types/globalEnums'
|
||||
import { NodeSlotType } from '@/lib/litegraph/src/types/globalEnums'
|
||||
|
||||
export interface WidgetSlotMetadata {
|
||||
index: number
|
||||
@@ -55,26 +56,27 @@ export interface SafeWidgetData {
|
||||
}
|
||||
|
||||
export interface VueNodeData {
|
||||
executing: boolean
|
||||
id: NodeId
|
||||
title: string
|
||||
type: string
|
||||
mode: number
|
||||
selected: boolean
|
||||
executing: boolean
|
||||
title: string
|
||||
type: string
|
||||
apiNode?: boolean
|
||||
badges?: (LGraphBadge | (() => LGraphBadge))[]
|
||||
subgraphId?: string | null
|
||||
widgets?: SafeWidgetData[]
|
||||
inputs?: INodeInputSlot[]
|
||||
outputs?: INodeOutputSlot[]
|
||||
hasErrors?: boolean
|
||||
bgcolor?: string
|
||||
color?: string
|
||||
flags?: {
|
||||
collapsed?: boolean
|
||||
pinned?: boolean
|
||||
}
|
||||
color?: string
|
||||
bgcolor?: string
|
||||
hasErrors?: boolean
|
||||
inputs?: INodeInputSlot[]
|
||||
outputs?: INodeOutputSlot[]
|
||||
shape?: number
|
||||
subgraphId?: string | null
|
||||
titleMode?: TitleMode
|
||||
widgets?: SafeWidgetData[]
|
||||
}
|
||||
|
||||
export interface GraphNodeManager {
|
||||
@@ -262,6 +264,7 @@ export function useGraphNodeManager(graph: LGraph): GraphNodeManager {
|
||||
title: typeof node.title === 'string' ? node.title : '',
|
||||
type: nodeType,
|
||||
mode: node.mode || 0,
|
||||
titleMode: node.title_mode,
|
||||
selected: node.selected || false,
|
||||
executing: false, // Will be updated separately based on execution state
|
||||
subgraphId,
|
||||
|
||||
@@ -51,7 +51,10 @@
|
||||
@dragleave="handleDragLeave"
|
||||
@drop.stop.prevent="handleDrop"
|
||||
>
|
||||
<div class="flex flex-col justify-center items-center relative">
|
||||
<div
|
||||
v-if="displayHeader"
|
||||
class="flex flex-col justify-center items-center relative"
|
||||
>
|
||||
<template v-if="isCollapsed">
|
||||
<SlotConnectionDot
|
||||
v-if="hasInputs"
|
||||
@@ -145,6 +148,7 @@ import {
|
||||
LiteGraph,
|
||||
RenderShape
|
||||
} from '@/lib/litegraph/src/litegraph'
|
||||
import { TitleMode } from '@/lib/litegraph/src/types/globalEnums'
|
||||
import { useSettingStore } from '@/platform/settings/settingStore'
|
||||
import { useTelemetry } from '@/platform/telemetry'
|
||||
import { useCanvasStore } from '@/renderer/core/canvas/canvasStore'
|
||||
@@ -165,6 +169,7 @@ import { app } from '@/scripts/app'
|
||||
import { useExecutionStore } from '@/stores/executionStore'
|
||||
import { useNodeOutputStore } from '@/stores/imagePreviewStore'
|
||||
import { useColorPaletteStore } from '@/stores/workspace/colorPaletteStore'
|
||||
import { isTransparent } from '@/utils/colorUtil'
|
||||
import {
|
||||
getLocatorIdFromNodeData,
|
||||
getNodeByLocatorId
|
||||
@@ -215,6 +220,8 @@ const hasAnyError = computed((): boolean => {
|
||||
)
|
||||
})
|
||||
|
||||
const displayHeader = computed(() => nodeData.titleMode !== TitleMode.NO_TITLE)
|
||||
|
||||
const isCollapsed = computed(() => nodeData.flags?.collapsed ?? false)
|
||||
const bypassed = computed(
|
||||
(): boolean => nodeData.mode === LGraphEventMode.BYPASS
|
||||
@@ -368,6 +375,13 @@ const { latestPreviewUrl, shouldShowPreviewImg } = useNodePreviewState(
|
||||
|
||||
const borderClass = computed(() => {
|
||||
if (hasAnyError.value) return 'border-node-stroke-error'
|
||||
//FIXME need a better way to detecting transparency
|
||||
if (
|
||||
!displayHeader.value &&
|
||||
nodeData.bgcolor &&
|
||||
isTransparent(nodeData.bgcolor)
|
||||
)
|
||||
return 'border-0'
|
||||
return ''
|
||||
})
|
||||
|
||||
|
||||
@@ -21,6 +21,15 @@ export interface ColorAdjustOptions {
|
||||
opacity?: number
|
||||
}
|
||||
|
||||
export function isTransparent(color: string) {
|
||||
if (color === 'transparent') return true
|
||||
if (color[0] === '#') {
|
||||
if (color.length === 5) return color[4] === '0'
|
||||
if (color.length === 9) return color.substring(7) === '00'
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
function rgbToHsl({ r, g, b }: RGB): HSL {
|
||||
r /= 255
|
||||
g /= 255
|
||||
|
||||
Reference in New Issue
Block a user