Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 2 additions & 13 deletions src/components/rightSidePanel/parameters/TabNodes.vue
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { useCanvasStore } from '@/renderer/core/canvas/canvasStore'
import FormSearchInput from '@/renderer/extensions/vueNodes/widgets/components/form/FormSearchInput.vue'
import { useRightSidePanelStore } from '@/stores/workspace/rightSidePanelStore'

import { searchWidgetsAndNodes } from '../shared'
import { computedSectionDataList, searchWidgetsAndNodes } from '../shared'
import type { NodeWidgetsListList } from '../shared'
import SectionWidgets from './SectionWidgets.vue'

Expand All @@ -24,18 +24,7 @@ const nodes = computed((): LGraphNode[] => {
const rightSidePanelStore = useRightSidePanelStore()
const { searchQuery } = storeToRefs(rightSidePanelStore)

const widgetsSectionDataList = computed((): NodeWidgetsListList => {
return nodes.value.map((node) => {
const { widgets = [] } = node
const shownWidgets = widgets
.filter((w) => !(w.options?.canvasOnly || w.options?.hidden))
.map((widget) => ({ node, widget }))
return {
widgets: shownWidgets,
node
}
})
})
const { widgetsSectionDataList } = computedSectionDataList(nodes)

const searchedWidgetsSectionDataList = shallowRef<NodeWidgetsListList>(
widgetsSectionDataList.value
Expand Down
21 changes: 7 additions & 14 deletions src/components/rightSidePanel/parameters/TabNormalInputs.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import type { LGraphNode } from '@/lib/litegraph/src/litegraph'
import FormSearchInput from '@/renderer/extensions/vueNodes/widgets/components/form/FormSearchInput.vue'
import { useRightSidePanelStore } from '@/stores/workspace/rightSidePanelStore'

import { searchWidgetsAndNodes } from '../shared'
import { computedSectionDataList, searchWidgetsAndNodes } from '../shared'
import type { NodeWidgetsListList } from '../shared'
import SectionWidgets from './SectionWidgets.vue'

Expand All @@ -21,21 +21,14 @@ const { t } = useI18n()
const rightSidePanelStore = useRightSidePanelStore()
const { searchQuery } = storeToRefs(rightSidePanelStore)

const widgetsSectionDataList = computed((): NodeWidgetsListList => {
return nodes.map((node) => {
const { widgets = [] } = node
const shownWidgets = widgets
.filter(
(w) =>
!(w.options?.canvasOnly || w.options?.hidden || w.options?.advanced)
)
.map((widget) => ({ node, widget }))

return { widgets: shownWidgets, node }
})
})
const { widgetsSectionDataList, includesAdvanced } = computedSectionDataList(
() => nodes
)

const advancedWidgetsSectionDataList = computed((): NodeWidgetsListList => {
if (includesAdvanced.value) {
return []
}
return nodes
.map((node) => {
const { widgets = [] } = node
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<script setup lang="ts">
import InputNumber from 'primevue/inputnumber'
import Select from 'primevue/select'
import { computed, ref } from 'vue'
import { computed } from 'vue'
import { useI18n } from 'vue-i18n'

import Button from '@/components/ui/button/Button.vue'
Expand All @@ -23,7 +23,11 @@ const settingStore = useSettingStore()
const dialogService = useDialogService()

// NODES settings
const showAdvancedParameters = ref(false) // Placeholder for future implementation
const showAdvancedParameters = computed({
get: () => settingStore.get('Comfy.Node.AlwaysShowAdvancedWidgets'),
set: (value) =>
settingStore.set('Comfy.Node.AlwaysShowAdvancedWidgets', value)
})

const showToolbox = computed({
get: () => settingStore.get('Comfy.Canvas.SelectionToolbox'),
Expand Down
31 changes: 31 additions & 0 deletions src/components/rightSidePanel/shared.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import type { LGraphGroup } from '@/lib/litegraph/src/LGraphGroup'
import type { LGraphNode } from '@/lib/litegraph/src/LGraphNode'
import type { IBaseWidget } from '@/lib/litegraph/src/types/widgets'
import { isLGraphGroup, isLGraphNode } from '@/utils/litegraphUtil'
import { useSettingStore } from '@/platform/settings/settingStore'

export const GetNodeParentGroupKey: InjectionKey<
(node: LGraphNode) => LGraphGroup | null
Expand Down Expand Up @@ -203,3 +204,33 @@ function repeatItems<T>(items: T[]): T[] {
}
return result
}

export function computedSectionDataList(nodes: MaybeRefOrGetter<LGraphNode[]>) {
const settingStore = useSettingStore()

const includesAdvanced = computed(() =>
settingStore.get('Comfy.Node.AlwaysShowAdvancedWidgets')
)

const widgetsSectionDataList = computed((): NodeWidgetsListList => {
return toValue(nodes).map((node) => {
const { widgets = [] } = node
const shownWidgets = widgets
.filter(
(w) =>
!(
w.options?.canvasOnly ||
w.options?.hidden ||
(w.options?.advanced && !includesAdvanced.value)
)
)
.map((widget) => ({ node, widget }))
return { widgets: shownWidgets, node }
})
})

return {
widgetsSectionDataList,
includesAdvanced
}
}
3 changes: 2 additions & 1 deletion src/locales/en/main.json
Original file line number Diff line number Diff line change
Expand Up @@ -2686,7 +2686,8 @@
"noneSearchDesc": "No items match your search",
"nodesNoneDesc": "NO NODES",
"fallbackGroupTitle": "Group",
"fallbackNodeTitle": "Node"
"fallbackNodeTitle": "Node",
"hideAdvancedInputsButton": "Hide advanced inputs"
},
"help": {
"recentReleases": "Recent releases",
Expand Down
10 changes: 10 additions & 0 deletions src/platform/settings/constants/coreSettings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1174,5 +1174,15 @@ export const CORE_SETTINGS: SettingParams[] = [
'Replaces the floating job queue panel with an equivalent job queue embedded in the Assets side panel. You can disable this to return to the floating panel layout.',
defaultValue: true,
experimental: true
},
{
id: 'Comfy.Node.AlwaysShowAdvancedWidgets',
category: ['LiteGraph', 'Node Widget', 'AlwaysShowAdvancedWidgets'],
name: 'Always show advanced widgets on all nodes',
tooltip:
'When enabled, advanced widgets are always visible on all nodes without needing to expand them individually.',
type: 'boolean',
defaultValue: false,
versionAdded: '1.39.0'
}
]
69 changes: 55 additions & 14 deletions src/renderer/extensions/vueNodes/components/LGraphNode.vue
Original file line number Diff line number Diff line change
Expand Up @@ -130,10 +130,16 @@
'transition-all cursor-pointer hover:bg-accent-background duration-150 active:scale-95'
)
"
@click.stop="handleShowAdvancedInputs"
@click.stop="showAdvancedState = !showAdvancedState"
>
<i class="icon-[lucide--settings-2] size-4" />
<span>{{ t('rightSidePanel.showAdvancedInputsButton') }}</span>
<template v-if="showAdvancedState">
<i class="icon-[lucide--chevron-up] size-4" />
<span>{{ t('rightSidePanel.hideAdvancedInputsButton') }}</span>
</template>
<template v-else>
<i class="icon-[lucide--settings-2] size-4" />
<span>{{ t('rightSidePanel.showAdvancedInputsButton') }} </span>
</template>
</button>
</div>
</div>
Expand All @@ -152,7 +158,15 @@

<script setup lang="ts">
import { storeToRefs } from 'pinia'
import { computed, nextTick, onErrorCaptured, onMounted, ref, watch } from 'vue'
import {
computed,
customRef,
nextTick,
onErrorCaptured,
onMounted,
ref,
watch
} from 'vue'
import { useI18n } from 'vue-i18n'

import type { VueNodeData } from '@/composables/graph/useGraphNodeManager'
Expand Down Expand Up @@ -212,6 +226,8 @@ const { nodeData, error = null } = defineProps<LGraphNodeProps>()

const { t } = useI18n()

const settingStore = useSettingStore()

const { handleNodeCollapse, handleNodeTitleUpdate, handleNodeRightClick } =
useNodeEventHandlers()
const { bringNodeToFront } = useNodeZIndex()
Expand Down Expand Up @@ -248,7 +264,7 @@ const bypassed = computed(
const muted = computed((): boolean => nodeData.mode === LGraphEventMode.NEVER)

const nodeOpacity = computed(() => {
const globalOpacity = useSettingStore().get('Comfy.Node.Opacity') ?? 1
const globalOpacity = settingStore.get('Comfy.Node.Opacity') ?? 1

// For muted/bypassed nodes, apply the 0.5 multiplier on top of global opacity
if (bypassed.value || muted.value) {
Expand Down Expand Up @@ -493,20 +509,45 @@ const showAdvancedInputsButton = computed(() => {

// For regular nodes: show button if there are advanced widgets and they're currently hidden
const hasAdvancedWidgets = nodeData.widgets?.some((w) => w.options?.advanced)
return hasAdvancedWidgets && !node.showAdvanced
const alwaysShowAdvanced = settingStore.get(
'Comfy.Node.AlwaysShowAdvancedWidgets'
)
return hasAdvancedWidgets && !alwaysShowAdvanced
})

function handleShowAdvancedInputs() {
const showAdvancedState = customRef((track, trigger) => {
let internalState = false

const node = lgraphNode.value
if (!node) return
if (node && !(node instanceof SubgraphNode)) {
internalState = !!node.showAdvanced
}

if (node instanceof SubgraphNode) {
const rightSidePanelStore = useRightSidePanelStore()
rightSidePanelStore.focusSection('advanced-inputs')
} else {
node.showAdvanced = true
return {
get() {
track()
return internalState
},
set(value: boolean) {
const node = lgraphNode.value
if (!node) return

if (node instanceof SubgraphNode) {
// Do not modify internalState for subgraph nodes
const rightSidePanelStore = useRightSidePanelStore()
if (value) {
rightSidePanelStore.focusSection('advanced-inputs')
} else {
rightSidePanelStore.closePanel()
}
} else {
node.showAdvanced = value
internalState = value
}
trigger()
}
}
}
})

const nodeMedia = computed(() => {
const newOutputs = nodeOutputs.nodeOutputs[nodeOutputLocatorId.value]
Expand Down
11 changes: 9 additions & 2 deletions src/renderer/extensions/vueNodes/components/NodeWidgets.vue
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
<div
v-if="
!widget.simplified.options?.hidden &&
(!widget.simplified.options?.advanced || nodeData?.showAdvanced)
(!widget.simplified.options?.advanced || showAdvanced)
"
class="lg-node-widget group col-span-full grid grid-cols-subgrid items-stretch"
>
Expand Down Expand Up @@ -78,6 +78,7 @@ import type {
VueNodeData,
WidgetSlotMetadata
} from '@/composables/graph/useGraphNodeManager'
import { useSettingStore } from '@/platform/settings/settingStore'
import { useErrorHandling } from '@/composables/useErrorHandling'
import { st } from '@/i18n'
import { useCanvasInteractions } from '@/renderer/core/canvas/useCanvasInteractions'
Expand Down Expand Up @@ -130,6 +131,12 @@ onErrorCaptured((error) => {
})

const nodeType = computed(() => nodeData?.type || '')
const settingStore = useSettingStore()
const showAdvanced = computed(
() =>
nodeData?.showAdvanced ||
settingStore.get('Comfy.Node.AlwaysShowAdvancedWidgets')
)
const { getWidgetTooltip, createTooltipConfig } = useNodeTooltips(
nodeType.value
)
Expand Down Expand Up @@ -213,7 +220,7 @@ const gridTemplateRows = computed((): string => {
(w) =>
processedNames.has(w.name) &&
!w.options?.hidden &&
(!w.options?.advanced || nodeData?.showAdvanced)
(!w.options?.advanced || showAdvanced.value)
)
.map((w) =>
shouldExpand(w.type) || w.hasLayoutSize ? 'auto' : 'min-content'
Expand Down
3 changes: 2 additions & 1 deletion src/schemas/apiSchema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -430,7 +430,8 @@ const zSettings = z.object({
'LiteGraph.Node.DefaultPadding': z.boolean(),
'LiteGraph.Pointer.TrackpadGestures': z.boolean(),
'Comfy.VersionCompatibility.DisableWarnings': z.boolean(),
'Comfy.RightSidePanel.IsOpen': z.boolean()
'Comfy.RightSidePanel.IsOpen': z.boolean(),
'Comfy.Node.AlwaysShowAdvancedWidgets': z.boolean()
})

export type EmbeddingsResponse = z.infer<typeof zEmbeddingsResponse>
Expand Down