mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-02-04 23:20:07 +00:00
add control_after_generate ui
This commit is contained in:
@@ -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": {
|
||||
|
||||
@@ -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>
|
||||
@@ -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"
|
||||
|
||||
@@ -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>
|
||||
Reference in New Issue
Block a user