From fd91b83d86500019211baba07072cb5e322b9e6c Mon Sep 17 00:00:00 2001 From: Mary Hipp Date: Wed, 17 Jul 2024 12:05:11 -0400 Subject: [PATCH] build out the rest of the accordions --- .../components/Upscale/ParamCreativity.tsx | 55 +++++++++++++++++++ .../components/Upscale/ParamSharpness.tsx | 55 +++++++++++++++++++ .../components/Upscale/ParamStructure.tsx | 55 +++++++++++++++++++ .../features/parameters/store/upscaleSlice.ts | 2 +- .../AdvancedSettingsAccordion.tsx | 42 ++++++++++---- .../UpscaleSettingsAccordion.tsx | 42 ++++++++++++-- .../UpscaleSizeDetails.tsx | 31 +++++++++++ .../ParametersPanelUpscale.tsx | 4 +- 8 files changed, 268 insertions(+), 18 deletions(-) create mode 100644 invokeai/frontend/web/src/features/parameters/components/Upscale/ParamCreativity.tsx create mode 100644 invokeai/frontend/web/src/features/parameters/components/Upscale/ParamSharpness.tsx create mode 100644 invokeai/frontend/web/src/features/parameters/components/Upscale/ParamStructure.tsx create mode 100644 invokeai/frontend/web/src/features/settingsAccordions/components/UpscaleSettingsAccordion/UpscaleSizeDetails.tsx diff --git a/invokeai/frontend/web/src/features/parameters/components/Upscale/ParamCreativity.tsx b/invokeai/frontend/web/src/features/parameters/components/Upscale/ParamCreativity.tsx new file mode 100644 index 0000000000..f53058224e --- /dev/null +++ b/invokeai/frontend/web/src/features/parameters/components/Upscale/ParamCreativity.tsx @@ -0,0 +1,55 @@ +import { CompositeNumberInput, CompositeSlider, FormControl, FormLabel } from '@invoke-ai/ui-library'; +import { useAppDispatch, useAppSelector } from 'app/store/storeHooks'; +import { InformationalPopover } from 'common/components/InformationalPopover/InformationalPopover'; +import { setSteps } from 'features/parameters/store/generationSlice'; +import { memo, useCallback, useMemo } from 'react'; +import { useTranslation } from 'react-i18next'; + +const ParamCreativity = () => { + const steps = useAppSelector((s) => s.generation.steps); + const initial = useAppSelector((s) => s.config.sd.steps.initial); + const sliderMin = useAppSelector((s) => s.config.sd.steps.sliderMin); + const sliderMax = useAppSelector((s) => s.config.sd.steps.sliderMax); + const numberInputMin = useAppSelector((s) => s.config.sd.steps.numberInputMin); + const numberInputMax = useAppSelector((s) => s.config.sd.steps.numberInputMax); + const coarseStep = useAppSelector((s) => s.config.sd.steps.coarseStep); + const fineStep = useAppSelector((s) => s.config.sd.steps.fineStep); + const dispatch = useAppDispatch(); + const { t } = useTranslation(); + const marks = useMemo(() => [sliderMin, Math.floor(sliderMax / 2), sliderMax], [sliderMax, sliderMin]); + const onChange = useCallback( + (v: number) => { + dispatch(setSteps(v)); + }, + [dispatch] + ); + + return ( + + + Creativity + + + + + ); +}; + +export default memo(ParamCreativity); diff --git a/invokeai/frontend/web/src/features/parameters/components/Upscale/ParamSharpness.tsx b/invokeai/frontend/web/src/features/parameters/components/Upscale/ParamSharpness.tsx new file mode 100644 index 0000000000..747d743d59 --- /dev/null +++ b/invokeai/frontend/web/src/features/parameters/components/Upscale/ParamSharpness.tsx @@ -0,0 +1,55 @@ +import { CompositeNumberInput, CompositeSlider, FormControl, FormLabel } from '@invoke-ai/ui-library'; +import { useAppDispatch, useAppSelector } from 'app/store/storeHooks'; +import { InformationalPopover } from 'common/components/InformationalPopover/InformationalPopover'; +import { setSteps } from 'features/parameters/store/generationSlice'; +import { memo, useCallback, useMemo } from 'react'; +import { useTranslation } from 'react-i18next'; + +const ParamSharpness = () => { + const steps = useAppSelector((s) => s.generation.steps); + const initial = useAppSelector((s) => s.config.sd.steps.initial); + const sliderMin = useAppSelector((s) => s.config.sd.steps.sliderMin); + const sliderMax = useAppSelector((s) => s.config.sd.steps.sliderMax); + const numberInputMin = useAppSelector((s) => s.config.sd.steps.numberInputMin); + const numberInputMax = useAppSelector((s) => s.config.sd.steps.numberInputMax); + const coarseStep = useAppSelector((s) => s.config.sd.steps.coarseStep); + const fineStep = useAppSelector((s) => s.config.sd.steps.fineStep); + const dispatch = useAppDispatch(); + const { t } = useTranslation(); + const marks = useMemo(() => [sliderMin, Math.floor(sliderMax / 2), sliderMax], [sliderMax, sliderMin]); + const onChange = useCallback( + (v: number) => { + dispatch(setSteps(v)); + }, + [dispatch] + ); + + return ( + + + Sharpness + + + + + ); +}; + +export default memo(ParamSharpness); diff --git a/invokeai/frontend/web/src/features/parameters/components/Upscale/ParamStructure.tsx b/invokeai/frontend/web/src/features/parameters/components/Upscale/ParamStructure.tsx new file mode 100644 index 0000000000..cc55bfea50 --- /dev/null +++ b/invokeai/frontend/web/src/features/parameters/components/Upscale/ParamStructure.tsx @@ -0,0 +1,55 @@ +import { CompositeNumberInput, CompositeSlider, FormControl, FormLabel } from '@invoke-ai/ui-library'; +import { useAppDispatch, useAppSelector } from 'app/store/storeHooks'; +import { InformationalPopover } from 'common/components/InformationalPopover/InformationalPopover'; +import { setSteps } from 'features/parameters/store/generationSlice'; +import { memo, useCallback, useMemo } from 'react'; +import { useTranslation } from 'react-i18next'; + +const ParamStructure = () => { + const steps = useAppSelector((s) => s.generation.steps); + const initial = useAppSelector((s) => s.config.sd.steps.initial); + const sliderMin = useAppSelector((s) => s.config.sd.steps.sliderMin); + const sliderMax = useAppSelector((s) => s.config.sd.steps.sliderMax); + const numberInputMin = useAppSelector((s) => s.config.sd.steps.numberInputMin); + const numberInputMax = useAppSelector((s) => s.config.sd.steps.numberInputMax); + const coarseStep = useAppSelector((s) => s.config.sd.steps.coarseStep); + const fineStep = useAppSelector((s) => s.config.sd.steps.fineStep); + const dispatch = useAppDispatch(); + const { t } = useTranslation(); + const marks = useMemo(() => [sliderMin, Math.floor(sliderMax / 2), sliderMax], [sliderMax, sliderMin]); + const onChange = useCallback( + (v: number) => { + dispatch(setSteps(v)); + }, + [dispatch] + ); + + return ( + + + Structure + + + + + ); +}; + +export default memo(ParamStructure); diff --git a/invokeai/frontend/web/src/features/parameters/store/upscaleSlice.ts b/invokeai/frontend/web/src/features/parameters/store/upscaleSlice.ts index 0fb0fdf1d3..a4d8fbf3af 100644 --- a/invokeai/frontend/web/src/features/parameters/store/upscaleSlice.ts +++ b/invokeai/frontend/web/src/features/parameters/store/upscaleSlice.ts @@ -14,7 +14,7 @@ interface UpscaleState { const initialUpscaleState: UpscaleState = { _version: 1, upscaleModel: null, - upscaleInitialImage: null + upscaleInitialImage: null, }; export const upscaleSlice = createSlice({ diff --git a/invokeai/frontend/web/src/features/settingsAccordions/components/AdvancedSettingsAccordion/AdvancedSettingsAccordion.tsx b/invokeai/frontend/web/src/features/settingsAccordions/components/AdvancedSettingsAccordion/AdvancedSettingsAccordion.tsx index 087efba616..ee358df188 100644 --- a/invokeai/frontend/web/src/features/settingsAccordions/components/AdvancedSettingsAccordion/AdvancedSettingsAccordion.tsx +++ b/invokeai/frontend/web/src/features/settingsAccordions/components/AdvancedSettingsAccordion/AdvancedSettingsAccordion.tsx @@ -14,6 +14,10 @@ import { useStandaloneAccordionToggle } from 'features/settingsAccordions/hooks/ import { memo, useMemo } from 'react'; import { useTranslation } from 'react-i18next'; import { useGetModelConfigQuery } from 'services/api/endpoints/models'; +import { activeTabNameSelector } from '../../../ui/store/uiSelectors'; +import { ParamSeedNumberInput } from '../../../parameters/components/Seed/ParamSeedNumberInput'; +import { ParamSeedRandomize } from '../../../parameters/components/Seed/ParamSeedRandomize'; +import { ParamSeedShuffle } from '../../../parameters/components/Seed/ParamSeedShuffle'; const formLabelProps: FormLabelProps = { minW: '9.2rem', @@ -26,6 +30,8 @@ const formLabelProps2: FormLabelProps = { export const AdvancedSettingsAccordion = memo(() => { const vaeKey = useAppSelector((state) => state.generation.vae?.key); const { currentData: vaeConfig } = useGetModelConfigQuery(vaeKey ?? skipToken); + const activeTabName = useAppSelector(activeTabNameSelector); + const selectBadges = useMemo( () => createMemoizedSelector(selectGenerationSlice, (generation) => { @@ -48,9 +54,12 @@ export const AdvancedSettingsAccordion = memo(() => { if (generation.seamlessXAxis || generation.seamlessYAxis) { badges.push('seamless'); } + if (activeTabName === 'upscaling' && !generation.shouldRandomizeSeed) { + badges.push('Manual Seed'); + } return badges; }), - [vaeConfig] + [vaeConfig, activeTabName] ); const badges = useAppSelector(selectBadges); const { t } = useTranslation(); @@ -66,16 +75,27 @@ export const AdvancedSettingsAccordion = memo(() => { - - - - - - - - - - + {activeTabName === 'upscaling' && ( + + + + + + )} + {activeTabName !== 'upscaling' && ( + <> + + + + + + + + + + + + )} ); diff --git a/invokeai/frontend/web/src/features/settingsAccordions/components/UpscaleSettingsAccordion/UpscaleSettingsAccordion.tsx b/invokeai/frontend/web/src/features/settingsAccordions/components/UpscaleSettingsAccordion/UpscaleSettingsAccordion.tsx index 3dc1c3d2a8..e7d45d043d 100644 --- a/invokeai/frontend/web/src/features/settingsAccordions/components/UpscaleSettingsAccordion/UpscaleSettingsAccordion.tsx +++ b/invokeai/frontend/web/src/features/settingsAccordions/components/UpscaleSettingsAccordion/UpscaleSettingsAccordion.tsx @@ -1,24 +1,58 @@ -import { Flex, StandaloneAccordion } from '@invoke-ai/ui-library'; +import { Expander, Flex, StandaloneAccordion } from '@invoke-ai/ui-library'; import { useStandaloneAccordionToggle } from 'features/settingsAccordions/hooks/useStandaloneAccordionToggle'; import { memo } from 'react'; import { useTranslation } from 'react-i18next'; import ParamSpandrelModel from '../../../parameters/components/Upscale/ParamSpandrelModel'; import { UpscaleInitialImage } from './UpscaleInitialImage'; +import { UpscaleSizeDetails } from './UpscaleSizeDetails'; +import { useExpanderToggle } from '../../hooks/useExpanderToggle'; +import ParamSharpness from '../../../parameters/components/Upscale/ParamSharpness'; +import ParamCreativity from '../../../parameters/components/Upscale/ParamCreativity'; +import ParamStructure from '../../../parameters/components/Upscale/ParamStructure'; +import { selectUpscalelice } from '../../../parameters/store/upscaleSlice'; +import { createMemoizedSelector } from '../../../../app/store/createMemoizedSelector'; +import { useAppSelector } from '../../../../app/store/storeHooks'; + +const selector = createMemoizedSelector([selectUpscalelice], (upscale) => { + const badges: string[] = []; + + if (upscale.upscaleModel) { + badges.push(upscale.upscaleModel.name); + } + + return { badges }; +}); export const UpscaleSettingsAccordion = memo(() => { const { t } = useTranslation(); + const { badges } = useAppSelector(selector); const { isOpen: isOpenAccordion, onToggle: onToggleAccordion } = useStandaloneAccordionToggle({ id: 'upscale-settings', defaultIsOpen: true, }); + const { isOpen: isOpenExpander, onToggle: onToggleExpander } = useExpanderToggle({ + id: 'upscale-settings-advanced', + defaultIsOpen: false, + }); + return ( - - + + - + + + + + + + + + + + ); diff --git a/invokeai/frontend/web/src/features/settingsAccordions/components/UpscaleSettingsAccordion/UpscaleSizeDetails.tsx b/invokeai/frontend/web/src/features/settingsAccordions/components/UpscaleSettingsAccordion/UpscaleSizeDetails.tsx new file mode 100644 index 0000000000..2f071d77a6 --- /dev/null +++ b/invokeai/frontend/web/src/features/settingsAccordions/components/UpscaleSettingsAccordion/UpscaleSizeDetails.tsx @@ -0,0 +1,31 @@ +import { Flex, Text } from '@invoke-ai/ui-library'; +import { useAppSelector } from '../../../../app/store/storeHooks'; +import { useMemo } from 'react'; + +export const UpscaleSizeDetails = () => { + const { upscaleInitialImage, upscaleModel } = useAppSelector((s) => s.upscale); + + const scaleFactor = useMemo(() => { + if (upscaleModel) { + const upscaleFactor = upscaleModel.name.match(/x(\d+)/); + if (upscaleFactor && upscaleFactor[1]) { + return parseInt(upscaleFactor[1], 10); + } + } + }, [upscaleModel]); + + if (!upscaleInitialImage || !upscaleModel || !scaleFactor) { + return <>; + } + + return ( + + + Current image size: {upscaleInitialImage.width} x {upscaleInitialImage.height} + + + Output image size: {upscaleInitialImage.width * scaleFactor} x {upscaleInitialImage.height * scaleFactor} + + + ); +}; diff --git a/invokeai/frontend/web/src/features/ui/components/ParametersPanels/ParametersPanelUpscale.tsx b/invokeai/frontend/web/src/features/ui/components/ParametersPanels/ParametersPanelUpscale.tsx index e6ae29cb69..44d99b3abd 100644 --- a/invokeai/frontend/web/src/features/ui/components/ParametersPanels/ParametersPanelUpscale.tsx +++ b/invokeai/frontend/web/src/features/ui/components/ParametersPanels/ParametersPanelUpscale.tsx @@ -1,4 +1,4 @@ -import { Box, Flex, Switch } from '@invoke-ai/ui-library'; +import { Box, Divider, Flex } from '@invoke-ai/ui-library'; import { useAppSelector } from 'app/store/storeHooks'; import { overlayScrollbarsParams } from 'common/components/OverlayScrollbars/constants'; import { Prompts } from 'features/parameters/components/Prompts/Prompts'; @@ -29,8 +29,8 @@ const ParametersPanelUpscale = () => { - {isSDXL ? : } +