add control_after_generate ui

This commit is contained in:
bymyself
2025-10-04 15:24:31 -07:00
parent 6541f5cda5
commit 23fdbe4c88
4 changed files with 203 additions and 4 deletions

View File

@@ -2069,6 +2069,22 @@
"placeholderVideo": "Select video...",
"placeholderModel": "Select model...",
"placeholderUnknown": "Select media..."
},
"seed": {
"controlHeaderBefore": "Automatically update the seed value",
"controlHeaderAfter": "AFTER",
"controlHeaderBefore2": "BEFORE",
"controlHeaderEnd": "running the workflow:",
"linkToGlobal": "Link to",
"linkToGlobalSeed": "Global Seed",
"linkToGlobalDesc": "Unique seed linked to the Global Seed's control setting",
"randomize": "Randomize Seed",
"randomizeDesc": "Shuffles the seed randomly after each generation",
"increment": "Increment Seed",
"incrementDesc": "Adds 1 to the seed number",
"decrement": "Decrement Seed",
"decrementDesc": "Subtracts 1 from the seed number",
"editSettings": "Edit seed control settings"
}
},
"nodeHelpPage": {

View File

@@ -0,0 +1,132 @@
<script setup lang="ts">
import Button from 'primevue/button'
import Popover from 'primevue/popover'
import ToggleSwitch from 'primevue/toggleswitch'
import { computed, ref } from 'vue'
import { useSettingStore } from '@/platform/settings/settingStore'
type ControlSettings = {
linkToGlobal: boolean
randomize: boolean
increment: boolean
decrement: boolean
}
type ControlOption = {
key: keyof ControlSettings
icon?: string
title: string
description: string
text?: string
}
const popover = ref()
const settingStore = useSettingStore()
const controlSettings = ref<ControlSettings>({
linkToGlobal: false,
randomize: false,
increment: true,
decrement: false
})
const widgetControlMode = computed(() =>
settingStore.get('Comfy.WidgetControlMode')
)
const toggle = (event: Event) => {
popover.value.toggle(event)
}
const controlOptions: ControlOption[] = [
{
key: 'linkToGlobal',
icon: 'pi pi-link',
title: 'linkToGlobal',
description: 'linkToGlobalDesc'
},
{
key: 'randomize',
icon: 'icon-[lucide--shuffle]',
title: 'randomize',
description: 'randomizeDesc'
},
{
key: 'increment',
text: '+1',
title: 'increment',
description: 'incrementDesc'
},
{
key: 'decrement',
text: '-1',
title: 'decrement',
description: 'decrementDesc'
}
]
defineExpose({ toggle })
</script>
<template>
<Popover ref="popover">
<div class="w-105 p-4 space-y-4">
<p class="text-sm text-slate-100">
{{ $t('widgets.seed.controlHeaderBefore') }}
<span class="text-white">
{{
widgetControlMode === 'before'
? $t('widgets.seed.controlHeaderBefore2')
: $t('widgets.seed.controlHeaderAfter')
}}
</span>
{{ $t('widgets.seed.controlHeaderEnd') }}
</p>
<div class="space-y-2">
<div
v-for="option in controlOptions"
:key="option.key"
class="flex items-center justify-between p-2 rounded"
>
<div class="flex gap-3 flex-1">
<div
class="w-8 h-8 bg-charcoal-400 rounded-lg flex items-center justify-center flex-shrink-0"
>
<i v-if="option.icon" :class="`${option.icon} text-sm`" />
<span v-if="option.text" class="text-xs">
{{ option.text }}
</span>
</div>
<div class="min-w-0 flex-1">
<div class="text-sm font-normal">
<span v-if="option.key === 'linkToGlobal'">
{{ $t('widgets.seed.linkToGlobal') }}
<em>{{ $t('widgets.seed.linkToGlobalSeed') }}</em>
</span>
<span v-else>
{{ $t(`widgets.seed.${option.title}`) }}
</span>
</div>
<div class="text-sm font-normal text-slate-100">
{{ $t(`widgets.seed.${option.description}`) }}
</div>
</div>
</div>
<ToggleSwitch
v-model="controlSettings[option.key]"
class="flex-shrink-0"
/>
</div>
</div>
<hr class="border-charcoal-400 border-1" />
<Button severity="secondary" size="small" class="w-full">
<i class="pi pi-cog mr-2 text-xs" />
{{ $t('widgets.seed.editSettings') }}
</Button>
</div>
</Popover>
</template>

View File

@@ -1,22 +1,31 @@
<script setup lang="ts">
import { computed } from 'vue'
import type { SimplifiedWidget } from '@/types/simplifiedWidget'
import WidgetInputNumberInput from './WidgetInputNumberInput.vue'
import WidgetInputNumberSlider from './WidgetInputNumberSlider.vue'
import WidgetInputNumberWithControl from './WidgetInputNumberWithControl.vue'
defineProps<{
const props = defineProps<{
widget: SimplifiedWidget<number>
}>()
const modelValue = defineModel<number>({ default: 0 })
const hasControlAfterGenerate = computed(() => {
return props.widget.spec?.control_after_generate === true
})
</script>
<template>
<component
:is="
widget.type === 'slider'
? WidgetInputNumberSlider
: WidgetInputNumberInput
hasControlAfterGenerate
? WidgetInputNumberWithControl
: widget.type === 'slider'
? WidgetInputNumberSlider
: WidgetInputNumberInput
"
v-model="modelValue"
:widget="widget"

View File

@@ -0,0 +1,42 @@
<script setup lang="ts">
import Button from 'primevue/button'
import { ref } from 'vue'
import type { SimplifiedWidget } from '@/types/simplifiedWidget'
import SeedControlPopover from './SeedControlPopover.vue'
import WidgetInputNumberInput from './WidgetInputNumberInput.vue'
defineProps<{
widget: SimplifiedWidget<number>
readonly?: boolean
}>()
const modelValue = defineModel<number>({ default: 0 })
const popover = ref()
const togglePopover = (event: Event) => {
popover.value.toggle(event)
}
</script>
<template>
<div class="relative">
<WidgetInputNumberInput
v-model="modelValue"
:widget="widget"
:readonly="readonly"
/>
<Button
variant="link"
size="small"
class="absolute right-12 top-1/2 -translate-y-1/2 h-4 w-7 p-0 bg-blue-100/30 rounded-xl"
@click="togglePopover"
>
<i class="icon-[lucide--shuffle] text-blue-100" />
</Button>
<SeedControlPopover ref="popover" />
</div>
</template>