mirror of
https://github.com/invoke-ai/InvokeAI
synced 2024-08-30 20:32:17 +00:00
build out the rest of the accordions
This commit is contained in:
parent
a0a54348e8
commit
fd91b83d86
@ -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 (
|
||||
<FormControl>
|
||||
<InformationalPopover feature="paramSteps">
|
||||
<FormLabel>Creativity</FormLabel>
|
||||
</InformationalPopover>
|
||||
<CompositeSlider
|
||||
value={steps}
|
||||
defaultValue={initial}
|
||||
min={sliderMin}
|
||||
max={sliderMax}
|
||||
step={coarseStep}
|
||||
fineStep={fineStep}
|
||||
onChange={onChange}
|
||||
marks={marks}
|
||||
/>
|
||||
<CompositeNumberInput
|
||||
value={steps}
|
||||
defaultValue={initial}
|
||||
min={numberInputMin}
|
||||
max={numberInputMax}
|
||||
step={coarseStep}
|
||||
fineStep={fineStep}
|
||||
onChange={onChange}
|
||||
/>
|
||||
</FormControl>
|
||||
);
|
||||
};
|
||||
|
||||
export default memo(ParamCreativity);
|
@ -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 (
|
||||
<FormControl>
|
||||
<InformationalPopover feature="paramSteps">
|
||||
<FormLabel>Sharpness</FormLabel>
|
||||
</InformationalPopover>
|
||||
<CompositeSlider
|
||||
value={steps}
|
||||
defaultValue={initial}
|
||||
min={sliderMin}
|
||||
max={sliderMax}
|
||||
step={coarseStep}
|
||||
fineStep={fineStep}
|
||||
onChange={onChange}
|
||||
marks={marks}
|
||||
/>
|
||||
<CompositeNumberInput
|
||||
value={steps}
|
||||
defaultValue={initial}
|
||||
min={numberInputMin}
|
||||
max={numberInputMax}
|
||||
step={coarseStep}
|
||||
fineStep={fineStep}
|
||||
onChange={onChange}
|
||||
/>
|
||||
</FormControl>
|
||||
);
|
||||
};
|
||||
|
||||
export default memo(ParamSharpness);
|
@ -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 (
|
||||
<FormControl>
|
||||
<InformationalPopover feature="paramSteps">
|
||||
<FormLabel>Structure</FormLabel>
|
||||
</InformationalPopover>
|
||||
<CompositeSlider
|
||||
value={steps}
|
||||
defaultValue={initial}
|
||||
min={sliderMin}
|
||||
max={sliderMax}
|
||||
step={coarseStep}
|
||||
fineStep={fineStep}
|
||||
onChange={onChange}
|
||||
marks={marks}
|
||||
/>
|
||||
<CompositeNumberInput
|
||||
value={steps}
|
||||
defaultValue={initial}
|
||||
min={numberInputMin}
|
||||
max={numberInputMax}
|
||||
step={coarseStep}
|
||||
fineStep={fineStep}
|
||||
onChange={onChange}
|
||||
/>
|
||||
</FormControl>
|
||||
);
|
||||
};
|
||||
|
||||
export default memo(ParamStructure);
|
@ -14,7 +14,7 @@ interface UpscaleState {
|
||||
const initialUpscaleState: UpscaleState = {
|
||||
_version: 1,
|
||||
upscaleModel: null,
|
||||
upscaleInitialImage: null
|
||||
upscaleInitialImage: null,
|
||||
};
|
||||
|
||||
export const upscaleSlice = createSlice({
|
||||
|
@ -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(() => {
|
||||
<ParamVAEModelSelect />
|
||||
<ParamVAEPrecision />
|
||||
</Flex>
|
||||
<FormControlGroup formLabelProps={formLabelProps}>
|
||||
<ParamClipSkip />
|
||||
<ParamCFGRescaleMultiplier />
|
||||
</FormControlGroup>
|
||||
<Flex gap={4} w="full">
|
||||
<FormControlGroup formLabelProps={formLabelProps2}>
|
||||
<ParamSeamlessXAxis />
|
||||
<ParamSeamlessYAxis />
|
||||
</FormControlGroup>
|
||||
</Flex>
|
||||
{activeTabName === 'upscaling' && (
|
||||
<Flex gap={4} alignItems="center">
|
||||
<ParamSeedNumberInput />
|
||||
<ParamSeedShuffle />
|
||||
<ParamSeedRandomize />
|
||||
</Flex>
|
||||
)}
|
||||
{activeTabName !== 'upscaling' && (
|
||||
<>
|
||||
<FormControlGroup formLabelProps={formLabelProps}>
|
||||
<ParamClipSkip />
|
||||
<ParamCFGRescaleMultiplier />
|
||||
</FormControlGroup>
|
||||
<Flex gap={4} w="full">
|
||||
<FormControlGroup formLabelProps={formLabelProps2}>
|
||||
<ParamSeamlessXAxis />
|
||||
<ParamSeamlessYAxis />
|
||||
</FormControlGroup>
|
||||
</Flex>
|
||||
</>
|
||||
)}
|
||||
</Flex>
|
||||
</StandaloneAccordion>
|
||||
);
|
||||
|
@ -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 (
|
||||
<StandaloneAccordion label="Upscale" isOpen={isOpenAccordion} onToggle={onToggleAccordion}>
|
||||
<Flex p={4} w="full" h="full" flexDir="column" data-testid="image-settings-accordion">
|
||||
<StandaloneAccordion label="Upscale" badges={badges} isOpen={isOpenAccordion} onToggle={onToggleAccordion}>
|
||||
<Flex pt={4} px={4} w="full" h="full" flexDir="column" data-testid="image-settings-accordion">
|
||||
<Flex gap={4}>
|
||||
<UpscaleInitialImage />
|
||||
<ParamSpandrelModel />
|
||||
<Flex direction="column" w="full" alignItems="center" gap={4}>
|
||||
<ParamSpandrelModel />
|
||||
<UpscaleSizeDetails />
|
||||
</Flex>
|
||||
</Flex>
|
||||
<Expander label={t('accordions.advanced.options')} isOpen={isOpenExpander} onToggle={onToggleExpander}>
|
||||
<Flex gap={4} pb={4} flexDir="column">
|
||||
<ParamSharpness />
|
||||
<ParamCreativity />
|
||||
<ParamStructure />
|
||||
</Flex>
|
||||
</Expander>
|
||||
</Flex>
|
||||
</StandaloneAccordion>
|
||||
);
|
||||
|
@ -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 (
|
||||
<Flex direction="column">
|
||||
<Text variant="subtext" fontWeight="bold">
|
||||
Current image size: {upscaleInitialImage.width} x {upscaleInitialImage.height}
|
||||
</Text>
|
||||
<Text variant="subtext" fontWeight="bold">
|
||||
Output image size: {upscaleInitialImage.width * scaleFactor} x {upscaleInitialImage.height * scaleFactor}
|
||||
</Text>
|
||||
</Flex>
|
||||
);
|
||||
};
|
@ -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 = () => {
|
||||
<Box position="absolute" top={0} left={0} right={0} bottom={0}>
|
||||
<OverlayScrollbarsComponent defer style={overlayScrollbarsStyles} options={overlayScrollbarsParams.options}>
|
||||
<Flex gap={2} flexDirection="column" h="full" w="full">
|
||||
<UpscaleSettingsAccordion />
|
||||
{isSDXL ? <SDXLPrompts /> : <Prompts />}
|
||||
<UpscaleSettingsAccordion />
|
||||
<GenerationSettingsAccordion />
|
||||
<AdvancedSettingsAccordion />
|
||||
</Flex>
|
||||
|
Loading…
Reference in New Issue
Block a user