mirror of
https://github.com/invoke-ai/InvokeAI
synced 2024-08-30 20:32:17 +00:00
[WebUI] They see me slidin .. they hatin... (#2614)
Porting over as many usable options to slider as possible. - Ported Face Restoration settings to Sliders. - Ported Upscale Settings to Sliders. - Ported Variation Amount to Sliders. - Ported Noise Threshold to Sliders <-- Optimized slider so the values actually make sense. - Ported Perlin Noise to Sliders. - Added a suboption hook for the High Res Strength Slider. - Fixed a couple of small issues with the Slider component. - Ported Main Options to Sliders.
This commit is contained in:
commit
41bc160cb8
638
invokeai/frontend/dist/assets/index-12bd70ca.js
vendored
638
invokeai/frontend/dist/assets/index-12bd70ca.js
vendored
File diff suppressed because one or more lines are too long
1
invokeai/frontend/dist/assets/index-14cb2922.css
vendored
Normal file
1
invokeai/frontend/dist/assets/index-14cb2922.css
vendored
Normal file
File diff suppressed because one or more lines are too long
638
invokeai/frontend/dist/assets/index-9237ac63.js
vendored
Normal file
638
invokeai/frontend/dist/assets/index-9237ac63.js
vendored
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
4
invokeai/frontend/dist/index.html
vendored
4
invokeai/frontend/dist/index.html
vendored
@ -5,8 +5,8 @@
|
|||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<title>InvokeAI - A Stable Diffusion Toolkit</title>
|
<title>InvokeAI - A Stable Diffusion Toolkit</title>
|
||||||
<link rel="shortcut icon" type="icon" href="./assets/favicon-0d253ced.ico" />
|
<link rel="shortcut icon" type="icon" href="./assets/favicon-0d253ced.ico" />
|
||||||
<script type="module" crossorigin src="./assets/index-12bd70ca.js"></script>
|
<script type="module" crossorigin src="./assets/index-9237ac63.js"></script>
|
||||||
<link rel="stylesheet" href="./assets/index-c1af841f.css">
|
<link rel="stylesheet" href="./assets/index-14cb2922.css">
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
|
@ -1,10 +1,12 @@
|
|||||||
{
|
{
|
||||||
|
"general": "General",
|
||||||
"images": "Images",
|
"images": "Images",
|
||||||
"steps": "Steps",
|
"steps": "Steps",
|
||||||
"cfgScale": "CFG Scale",
|
"cfgScale": "CFG Scale",
|
||||||
"width": "Width",
|
"width": "Width",
|
||||||
"height": "Height",
|
"height": "Height",
|
||||||
"sampler": "Sampler",
|
"sampler": "Sampler",
|
||||||
|
"imageToImage": "Image To Image",
|
||||||
"seed": "Seed",
|
"seed": "Seed",
|
||||||
"randomizeSeed": "Randomize Seed",
|
"randomizeSeed": "Randomize Seed",
|
||||||
"shuffle": "Shuffle",
|
"shuffle": "Shuffle",
|
||||||
|
@ -1,10 +1,12 @@
|
|||||||
{
|
{
|
||||||
|
"general": "General",
|
||||||
"images": "Images",
|
"images": "Images",
|
||||||
"steps": "Steps",
|
"steps": "Steps",
|
||||||
"cfgScale": "CFG Scale",
|
"cfgScale": "CFG Scale",
|
||||||
"width": "Width",
|
"width": "Width",
|
||||||
"height": "Height",
|
"height": "Height",
|
||||||
"sampler": "Sampler",
|
"sampler": "Sampler",
|
||||||
|
"imageToImage": "Image To Image",
|
||||||
"seed": "Seed",
|
"seed": "Seed",
|
||||||
"randomizeSeed": "Randomize Seed",
|
"randomizeSeed": "Randomize Seed",
|
||||||
"shuffle": "Shuffle",
|
"shuffle": "Shuffle",
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
"confirmOnDelete": "Confirm On Delete",
|
"confirmOnDelete": "Confirm On Delete",
|
||||||
"displayHelpIcons": "Display Help Icons",
|
"displayHelpIcons": "Display Help Icons",
|
||||||
"useCanvasBeta": "Use Canvas Beta Layout",
|
"useCanvasBeta": "Use Canvas Beta Layout",
|
||||||
|
"useSlidersForAll": "Use Sliders For All Options",
|
||||||
"enableImageDebugging": "Enable Image Debugging",
|
"enableImageDebugging": "Enable Image Debugging",
|
||||||
"resetWebUI": "Reset Web UI",
|
"resetWebUI": "Reset Web UI",
|
||||||
"resetWebUIDesc1": "Resetting the web UI only resets the browser's local cache of your images and remembered settings. It does not delete any images from disk.",
|
"resetWebUIDesc1": "Resetting the web UI only resets the browser's local cache of your images and remembered settings. It does not delete any images from disk.",
|
||||||
|
@ -1,10 +1,12 @@
|
|||||||
{
|
{
|
||||||
|
"general": "General",
|
||||||
"images": "Images",
|
"images": "Images",
|
||||||
"steps": "Steps",
|
"steps": "Steps",
|
||||||
"cfgScale": "CFG Scale",
|
"cfgScale": "CFG Scale",
|
||||||
"width": "Width",
|
"width": "Width",
|
||||||
"height": "Height",
|
"height": "Height",
|
||||||
"sampler": "Sampler",
|
"sampler": "Sampler",
|
||||||
|
"imageToImage": "Image To Image",
|
||||||
"seed": "Seed",
|
"seed": "Seed",
|
||||||
"randomizeSeed": "Randomize Seed",
|
"randomizeSeed": "Randomize Seed",
|
||||||
"shuffle": "Shuffle",
|
"shuffle": "Shuffle",
|
||||||
|
@ -1,10 +1,12 @@
|
|||||||
{
|
{
|
||||||
|
"general": "General",
|
||||||
"images": "Images",
|
"images": "Images",
|
||||||
"steps": "Steps",
|
"steps": "Steps",
|
||||||
"cfgScale": "CFG Scale",
|
"cfgScale": "CFG Scale",
|
||||||
"width": "Width",
|
"width": "Width",
|
||||||
"height": "Height",
|
"height": "Height",
|
||||||
"sampler": "Sampler",
|
"sampler": "Sampler",
|
||||||
|
"imageToImage": "Image To Image",
|
||||||
"seed": "Seed",
|
"seed": "Seed",
|
||||||
"randomizeSeed": "Randomize Seed",
|
"randomizeSeed": "Randomize Seed",
|
||||||
"shuffle": "Shuffle",
|
"shuffle": "Shuffle",
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
"confirmOnDelete": "Confirm On Delete",
|
"confirmOnDelete": "Confirm On Delete",
|
||||||
"displayHelpIcons": "Display Help Icons",
|
"displayHelpIcons": "Display Help Icons",
|
||||||
"useCanvasBeta": "Use Canvas Beta Layout",
|
"useCanvasBeta": "Use Canvas Beta Layout",
|
||||||
|
"useSlidersForAll": "Use Sliders For All Options",
|
||||||
"enableImageDebugging": "Enable Image Debugging",
|
"enableImageDebugging": "Enable Image Debugging",
|
||||||
"resetWebUI": "Reset Web UI",
|
"resetWebUI": "Reset Web UI",
|
||||||
"resetWebUIDesc1": "Resetting the web UI only resets the browser's local cache of your images and remembered settings. It does not delete any images from disk.",
|
"resetWebUIDesc1": "Resetting the web UI only resets the browser's local cache of your images and remembered settings. It does not delete any images from disk.",
|
||||||
|
@ -6,7 +6,6 @@
|
|||||||
min-width: max-content;
|
min-width: max-content;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
font-size: 0.9rem;
|
|
||||||
color: var(--text-color-secondary);
|
color: var(--text-color-secondary);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -78,7 +78,7 @@ export default function IAISlider(props: IAIFullSliderProps) {
|
|||||||
tooltipSuffix = '',
|
tooltipSuffix = '',
|
||||||
withSliderMarks = false,
|
withSliderMarks = false,
|
||||||
sliderMarkLeftOffset = 0,
|
sliderMarkLeftOffset = 0,
|
||||||
sliderMarkRightOffset = -7,
|
sliderMarkRightOffset = -1,
|
||||||
withInput = false,
|
withInput = false,
|
||||||
isInteger = false,
|
isInteger = false,
|
||||||
inputWidth = '5.5rem',
|
inputWidth = '5.5rem',
|
||||||
@ -164,6 +164,7 @@ export default function IAISlider(props: IAIFullSliderProps) {
|
|||||||
>
|
>
|
||||||
<FormLabel
|
<FormLabel
|
||||||
className="invokeai__slider-component-label"
|
className="invokeai__slider-component-label"
|
||||||
|
fontSize="sm"
|
||||||
{...sliderFormLabelProps}
|
{...sliderFormLabelProps}
|
||||||
>
|
>
|
||||||
{label}
|
{label}
|
||||||
|
55
invokeai/frontend/src/common/components/SubItemHook.tsx
Normal file
55
invokeai/frontend/src/common/components/SubItemHook.tsx
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
import { Box } from '@chakra-ui/react';
|
||||||
|
|
||||||
|
interface SubItemHookProps {
|
||||||
|
active?: boolean;
|
||||||
|
width?: string | number;
|
||||||
|
height?: string | number;
|
||||||
|
side?: 'left' | 'right';
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function SubItemHook(props: SubItemHookProps) {
|
||||||
|
const {
|
||||||
|
active = true,
|
||||||
|
width = '1rem',
|
||||||
|
height = '1.3rem',
|
||||||
|
side = 'right',
|
||||||
|
} = props;
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
{side === 'right' && (
|
||||||
|
<Box
|
||||||
|
width={width}
|
||||||
|
height={height}
|
||||||
|
margin="-0.5rem 0.5rem 0 0.5rem"
|
||||||
|
borderLeft={
|
||||||
|
active
|
||||||
|
? '3px solid var(--subhook-color)'
|
||||||
|
: '3px solid var(--tab-hover-color)'
|
||||||
|
}
|
||||||
|
borderBottom={
|
||||||
|
active
|
||||||
|
? '3px solid var(--subhook-color)'
|
||||||
|
: '3px solid var(--tab-hover-color)'
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
{side === 'left' && (
|
||||||
|
<Box
|
||||||
|
width={width}
|
||||||
|
height={height}
|
||||||
|
margin="-0.5rem 0.5rem 0 0.5rem"
|
||||||
|
borderRight={
|
||||||
|
active
|
||||||
|
? '3px solid var(--subhook-color)'
|
||||||
|
: '3px solid var(--tab-hover-color)'
|
||||||
|
}
|
||||||
|
borderBottom={
|
||||||
|
active
|
||||||
|
? '3px solid var(--subhook-color)'
|
||||||
|
: '3px solid var(--tab-hover-color)'
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
@ -170,6 +170,9 @@ export const frontendToBackendParameters = (
|
|||||||
let esrganParameters: false | BackendEsrGanParameters = false;
|
let esrganParameters: false | BackendEsrGanParameters = false;
|
||||||
let facetoolParameters: false | BackendFacetoolParameters = false;
|
let facetoolParameters: false | BackendFacetoolParameters = false;
|
||||||
|
|
||||||
|
// Multiplying it by 10000 so the Slider can have values between 0 and 1 which makes more sense
|
||||||
|
generationParameters.threshold = threshold * 1000;
|
||||||
|
|
||||||
if (negativePrompt !== '') {
|
if (negativePrompt !== '') {
|
||||||
generationParameters.prompt = `${prompt} [${negativePrompt}]`;
|
generationParameters.prompt = `${prompt} [${negativePrompt}]`;
|
||||||
}
|
}
|
||||||
|
@ -68,7 +68,7 @@ const BoundingBoxSettings = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Flex direction="column" gap="1rem">
|
<Flex direction="column" gap={2}>
|
||||||
<IAISlider
|
<IAISlider
|
||||||
label={t('parameters:width')}
|
label={t('parameters:width')}
|
||||||
min={64}
|
min={64}
|
||||||
@ -82,6 +82,7 @@ const BoundingBoxSettings = () => {
|
|||||||
inputReadOnly
|
inputReadOnly
|
||||||
withReset
|
withReset
|
||||||
handleReset={handleResetWidth}
|
handleReset={handleResetWidth}
|
||||||
|
sliderMarkRightOffset={-7}
|
||||||
/>
|
/>
|
||||||
<IAISlider
|
<IAISlider
|
||||||
label={t('parameters:height')}
|
label={t('parameters:height')}
|
||||||
@ -96,6 +97,7 @@ const BoundingBoxSettings = () => {
|
|||||||
inputReadOnly
|
inputReadOnly
|
||||||
withReset
|
withReset
|
||||||
handleReset={handleResetHeight}
|
handleReset={handleResetHeight}
|
||||||
|
sliderMarkRightOffset={-7}
|
||||||
/>
|
/>
|
||||||
</Flex>
|
</Flex>
|
||||||
);
|
);
|
||||||
|
@ -107,7 +107,7 @@ const InfillAndScalingSettings = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Flex direction="column" gap="1rem">
|
<Flex direction="column" gap={4}>
|
||||||
<IAISelect
|
<IAISelect
|
||||||
label={t('parameters:scaleBeforeProcessing')}
|
label={t('parameters:scaleBeforeProcessing')}
|
||||||
validValues={BOUNDING_BOX_SCALES_DICT}
|
validValues={BOUNDING_BOX_SCALES_DICT}
|
||||||
@ -130,6 +130,7 @@ const InfillAndScalingSettings = () => {
|
|||||||
inputReadOnly
|
inputReadOnly
|
||||||
withReset
|
withReset
|
||||||
handleReset={handleResetScaledWidth}
|
handleReset={handleResetScaledWidth}
|
||||||
|
sliderMarkRightOffset={-7}
|
||||||
/>
|
/>
|
||||||
<IAISlider
|
<IAISlider
|
||||||
isInputDisabled={!isManual}
|
isInputDisabled={!isManual}
|
||||||
@ -147,6 +148,7 @@ const InfillAndScalingSettings = () => {
|
|||||||
inputReadOnly
|
inputReadOnly
|
||||||
withReset
|
withReset
|
||||||
handleReset={handleResetScaledHeight}
|
handleReset={handleResetScaledHeight}
|
||||||
|
sliderMarkRightOffset={-7}
|
||||||
/>
|
/>
|
||||||
<IAISelect
|
<IAISelect
|
||||||
label={t('parameters:infillMethod')}
|
label={t('parameters:infillMethod')}
|
||||||
|
@ -6,7 +6,7 @@ import SeamStrength from './SeamStrength';
|
|||||||
|
|
||||||
const SeamCorrectionSettings = () => {
|
const SeamCorrectionSettings = () => {
|
||||||
return (
|
return (
|
||||||
<Flex direction="column" gap="1rem">
|
<Flex direction="column" gap={2}>
|
||||||
<SeamSize />
|
<SeamSize />
|
||||||
<SeamBlur />
|
<SeamBlur />
|
||||||
<SeamStrength />
|
<SeamStrength />
|
||||||
|
@ -0,0 +1,36 @@
|
|||||||
|
import type { RootState } from 'app/store';
|
||||||
|
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
|
||||||
|
import IAISlider from 'common/components/IAISlider';
|
||||||
|
import { setCodeformerFidelity } from 'features/parameters/store/postprocessingSlice';
|
||||||
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
|
export default function CodeformerFidelity() {
|
||||||
|
const isGFPGANAvailable = useAppSelector(
|
||||||
|
(state: RootState) => state.system.isGFPGANAvailable
|
||||||
|
);
|
||||||
|
|
||||||
|
const codeformerFidelity = useAppSelector(
|
||||||
|
(state: RootState) => state.postprocessing.codeformerFidelity
|
||||||
|
);
|
||||||
|
|
||||||
|
const { t } = useTranslation();
|
||||||
|
const dispatch = useAppDispatch();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<IAISlider
|
||||||
|
isSliderDisabled={!isGFPGANAvailable}
|
||||||
|
isInputDisabled={!isGFPGANAvailable}
|
||||||
|
isResetDisabled={!isGFPGANAvailable}
|
||||||
|
label={t('parameters:codeformerFidelity')}
|
||||||
|
step={0.05}
|
||||||
|
min={0}
|
||||||
|
max={1}
|
||||||
|
onChange={(v) => dispatch(setCodeformerFidelity(v))}
|
||||||
|
handleReset={() => dispatch(setCodeformerFidelity(1))}
|
||||||
|
value={codeformerFidelity}
|
||||||
|
withReset
|
||||||
|
withSliderMarks
|
||||||
|
withInput
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
@ -1,99 +1,23 @@
|
|||||||
import { Flex } from '@chakra-ui/react';
|
import { Flex } from '@chakra-ui/react';
|
||||||
|
import { useAppSelector } from 'app/storeHooks';
|
||||||
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
|
import type { RootState } from 'app/store';
|
||||||
|
import FaceRestoreType from './FaceRestoreType';
|
||||||
import { FacetoolType } from 'features/parameters/store/postprocessingSlice';
|
import FaceRestoreStrength from './FaceRestoreStrength';
|
||||||
|
import CodeformerFidelity from './CodeformerFidelity';
|
||||||
import {
|
|
||||||
setCodeformerFidelity,
|
|
||||||
setFacetoolStrength,
|
|
||||||
setFacetoolType,
|
|
||||||
} from 'features/parameters/store/postprocessingSlice';
|
|
||||||
|
|
||||||
import { createSelector } from '@reduxjs/toolkit';
|
|
||||||
import { FACETOOL_TYPES } from 'app/constants';
|
|
||||||
import IAINumberInput from 'common/components/IAINumberInput';
|
|
||||||
import IAISelect from 'common/components/IAISelect';
|
|
||||||
import { postprocessingSelector } from 'features/parameters/store/postprocessingSelectors';
|
|
||||||
import { systemSelector } from 'features/system/store/systemSelectors';
|
|
||||||
import { isEqual } from 'lodash';
|
|
||||||
import { ChangeEvent } from 'react';
|
|
||||||
import { useTranslation } from 'react-i18next';
|
|
||||||
|
|
||||||
const optionsSelector = createSelector(
|
|
||||||
[postprocessingSelector, systemSelector],
|
|
||||||
(
|
|
||||||
{ facetoolStrength, facetoolType, codeformerFidelity },
|
|
||||||
{ isGFPGANAvailable }
|
|
||||||
) => {
|
|
||||||
return {
|
|
||||||
facetoolStrength,
|
|
||||||
facetoolType,
|
|
||||||
codeformerFidelity,
|
|
||||||
isGFPGANAvailable,
|
|
||||||
};
|
|
||||||
},
|
|
||||||
{
|
|
||||||
memoizeOptions: {
|
|
||||||
resultEqualityCheck: isEqual,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Displays face-fixing/GFPGAN options (strength).
|
* Displays face-fixing/GFPGAN options (strength).
|
||||||
*/
|
*/
|
||||||
const FaceRestoreSettings = () => {
|
const FaceRestoreSettings = () => {
|
||||||
const dispatch = useAppDispatch();
|
const facetoolType = useAppSelector(
|
||||||
const {
|
(state: RootState) => state.postprocessing.facetoolType
|
||||||
facetoolStrength,
|
);
|
||||||
facetoolType,
|
|
||||||
codeformerFidelity,
|
|
||||||
isGFPGANAvailable,
|
|
||||||
} = useAppSelector(optionsSelector);
|
|
||||||
|
|
||||||
const handleChangeStrength = (v: number) => dispatch(setFacetoolStrength(v));
|
|
||||||
|
|
||||||
const handleChangeCodeformerFidelity = (v: number) =>
|
|
||||||
dispatch(setCodeformerFidelity(v));
|
|
||||||
|
|
||||||
const handleChangeFacetoolType = (e: ChangeEvent<HTMLSelectElement>) =>
|
|
||||||
dispatch(setFacetoolType(e.target.value as FacetoolType));
|
|
||||||
|
|
||||||
const { t } = useTranslation();
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Flex direction="column" gap={2}>
|
<Flex direction="column" gap={2} minWidth="20rem">
|
||||||
<IAISelect
|
<FaceRestoreType />
|
||||||
label={t('parameters:type')}
|
<FaceRestoreStrength />
|
||||||
validValues={FACETOOL_TYPES.concat()}
|
{facetoolType === 'codeformer' && <CodeformerFidelity />}
|
||||||
value={facetoolType}
|
|
||||||
onChange={handleChangeFacetoolType}
|
|
||||||
/>
|
|
||||||
<IAINumberInput
|
|
||||||
isDisabled={!isGFPGANAvailable}
|
|
||||||
label={t('parameters:strength')}
|
|
||||||
step={0.05}
|
|
||||||
min={0}
|
|
||||||
max={1}
|
|
||||||
onChange={handleChangeStrength}
|
|
||||||
value={facetoolStrength}
|
|
||||||
width="90px"
|
|
||||||
isInteger={false}
|
|
||||||
/>
|
|
||||||
{facetoolType === 'codeformer' && (
|
|
||||||
<IAINumberInput
|
|
||||||
isDisabled={!isGFPGANAvailable}
|
|
||||||
label={t('parameters:codeformerFidelity')}
|
|
||||||
step={0.05}
|
|
||||||
min={0}
|
|
||||||
max={1}
|
|
||||||
onChange={handleChangeCodeformerFidelity}
|
|
||||||
value={codeformerFidelity}
|
|
||||||
width="90px"
|
|
||||||
isInteger={false}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</Flex>
|
</Flex>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -0,0 +1,36 @@
|
|||||||
|
import { RootState } from 'app/store';
|
||||||
|
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
|
||||||
|
import IAISlider from 'common/components/IAISlider';
|
||||||
|
import { setFacetoolStrength } from 'features/parameters/store/postprocessingSlice';
|
||||||
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
|
export default function FaceRestoreStrength() {
|
||||||
|
const isGFPGANAvailable = useAppSelector(
|
||||||
|
(state: RootState) => state.system.isGFPGANAvailable
|
||||||
|
);
|
||||||
|
|
||||||
|
const facetoolStrength = useAppSelector(
|
||||||
|
(state: RootState) => state.postprocessing.facetoolStrength
|
||||||
|
);
|
||||||
|
|
||||||
|
const { t } = useTranslation();
|
||||||
|
const dispatch = useAppDispatch();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<IAISlider
|
||||||
|
isSliderDisabled={!isGFPGANAvailable}
|
||||||
|
isInputDisabled={!isGFPGANAvailable}
|
||||||
|
isResetDisabled={!isGFPGANAvailable}
|
||||||
|
label={t('parameters:strength')}
|
||||||
|
step={0.05}
|
||||||
|
min={0}
|
||||||
|
max={1}
|
||||||
|
onChange={(v) => dispatch(setFacetoolStrength(v))}
|
||||||
|
handleReset={() => dispatch(setFacetoolStrength(0.75))}
|
||||||
|
value={facetoolStrength}
|
||||||
|
withReset
|
||||||
|
withSliderMarks
|
||||||
|
withInput
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
@ -0,0 +1,31 @@
|
|||||||
|
import { FACETOOL_TYPES } from 'app/constants';
|
||||||
|
import { type RootState } from 'app/store';
|
||||||
|
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
|
||||||
|
import IAISelect from 'common/components/IAISelect';
|
||||||
|
import {
|
||||||
|
type FacetoolType,
|
||||||
|
setFacetoolType,
|
||||||
|
} from 'features/parameters/store/postprocessingSlice';
|
||||||
|
import { type ChangeEvent } from 'react';
|
||||||
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
|
export default function FaceRestoreType() {
|
||||||
|
const facetoolType = useAppSelector(
|
||||||
|
(state: RootState) => state.postprocessing.facetoolType
|
||||||
|
);
|
||||||
|
|
||||||
|
const dispatch = useAppDispatch();
|
||||||
|
const { t } = useTranslation();
|
||||||
|
|
||||||
|
const handleChangeFacetoolType = (e: ChangeEvent<HTMLSelectElement>) =>
|
||||||
|
dispatch(setFacetoolType(e.target.value as FacetoolType));
|
||||||
|
|
||||||
|
return (
|
||||||
|
<IAISelect
|
||||||
|
label={t('parameters:type')}
|
||||||
|
validValues={FACETOOL_TYPES.concat()}
|
||||||
|
value={facetoolType}
|
||||||
|
onChange={handleChangeFacetoolType}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
@ -4,6 +4,7 @@ import type { RootState } from 'app/store';
|
|||||||
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
|
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
|
||||||
import IAISlider from 'common/components/IAISlider';
|
import IAISlider from 'common/components/IAISlider';
|
||||||
import IAISwitch from 'common/components/IAISwitch';
|
import IAISwitch from 'common/components/IAISwitch';
|
||||||
|
import SubItemHook from 'common/components/SubItemHook';
|
||||||
import { postprocessingSelector } from 'features/parameters/store/postprocessingSelectors';
|
import { postprocessingSelector } from 'features/parameters/store/postprocessingSelectors';
|
||||||
import {
|
import {
|
||||||
setHiresFix,
|
setHiresFix,
|
||||||
@ -39,23 +40,27 @@ const HiresStrength = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<IAISlider
|
<Flex>
|
||||||
label={t('parameters:hiresStrength')}
|
<SubItemHook active={hiresFix} />
|
||||||
step={0.01}
|
<IAISlider
|
||||||
min={0.01}
|
label={t('parameters:hiresStrength')}
|
||||||
max={0.99}
|
step={0.01}
|
||||||
onChange={handleHiresStrength}
|
min={0.01}
|
||||||
value={hiresStrength}
|
max={0.99}
|
||||||
isInteger={false}
|
onChange={handleHiresStrength}
|
||||||
withInput
|
value={hiresStrength}
|
||||||
withSliderMarks
|
isInteger={false}
|
||||||
inputWidth="5.5rem"
|
withInput
|
||||||
withReset
|
withSliderMarks
|
||||||
handleReset={handleHiResStrengthReset}
|
inputWidth={'5.5rem'}
|
||||||
isSliderDisabled={!hiresFix}
|
withReset
|
||||||
isInputDisabled={!hiresFix}
|
handleReset={handleHiResStrengthReset}
|
||||||
isResetDisabled={!hiresFix}
|
isSliderDisabled={!hiresFix}
|
||||||
/>
|
isInputDisabled={!hiresFix}
|
||||||
|
isResetDisabled={!hiresFix}
|
||||||
|
sliderMarkRightOffset={-7}
|
||||||
|
/>
|
||||||
|
</Flex>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -75,7 +80,7 @@ const HiresSettings = () => {
|
|||||||
dispatch(setHiresFix(e.target.checked));
|
dispatch(setHiresFix(e.target.checked));
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Flex gap={2} direction="column">
|
<Flex rowGap="0.8rem" direction={'column'}>
|
||||||
<IAISwitch
|
<IAISwitch
|
||||||
label={t('parameters:hiresOptim')}
|
label={t('parameters:hiresOptim')}
|
||||||
fontSize="md"
|
fontSize="md"
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { RootState } from 'app/store';
|
import { RootState } from 'app/store';
|
||||||
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
|
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
|
||||||
import IAINumberInput from 'common/components/IAINumberInput';
|
import IAISlider from 'common/components/IAISlider';
|
||||||
import { setPerlin } from 'features/parameters/store/generationSlice';
|
import { setPerlin } from 'features/parameters/store/generationSlice';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
@ -9,17 +9,18 @@ export default function Perlin() {
|
|||||||
const perlin = useAppSelector((state: RootState) => state.generation.perlin);
|
const perlin = useAppSelector((state: RootState) => state.generation.perlin);
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
const handleChangePerlin = (v: number) => dispatch(setPerlin(v));
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<IAINumberInput
|
<IAISlider
|
||||||
label={t('parameters:perlinNoise')}
|
label={t('parameters:perlinNoise')}
|
||||||
min={0}
|
min={0}
|
||||||
max={1}
|
max={1}
|
||||||
step={0.05}
|
step={0.05}
|
||||||
onChange={handleChangePerlin}
|
onChange={(v) => dispatch(setPerlin(v))}
|
||||||
|
handleReset={() => dispatch(setPerlin(0))}
|
||||||
value={perlin}
|
value={perlin}
|
||||||
isInteger={false}
|
withInput
|
||||||
|
withReset
|
||||||
|
withSliderMarks
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { RootState } from 'app/store';
|
import { RootState } from 'app/store';
|
||||||
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
|
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
|
||||||
import IAINumberInput from 'common/components/IAINumberInput';
|
import IAISlider from 'common/components/IAISlider';
|
||||||
import { setThreshold } from 'features/parameters/store/generationSlice';
|
import { setThreshold } from 'features/parameters/store/generationSlice';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
@ -11,17 +11,19 @@ export default function Threshold() {
|
|||||||
);
|
);
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
const handleChangeThreshold = (v: number) => dispatch(setThreshold(v));
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<IAINumberInput
|
<IAISlider
|
||||||
label={t('parameters:noiseThreshold')}
|
label={t('parameters:noiseThreshold')}
|
||||||
min={0}
|
min={0}
|
||||||
max={1000}
|
max={1}
|
||||||
step={0.1}
|
step={0.005}
|
||||||
onChange={handleChangeThreshold}
|
onChange={(v) => dispatch(setThreshold(v))}
|
||||||
|
handleReset={() => dispatch(setThreshold(0))}
|
||||||
value={threshold}
|
value={threshold}
|
||||||
isInteger={false}
|
withInput
|
||||||
|
withReset
|
||||||
|
withSliderMarks
|
||||||
|
inputWidth="6rem"
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,38 @@
|
|||||||
|
import { RootState } from 'app/store';
|
||||||
|
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
|
||||||
|
import IAISlider from 'common/components/IAISlider';
|
||||||
|
import { setUpscalingDenoising } from 'features/parameters/store/postprocessingSlice';
|
||||||
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
|
export default function UpscaleDenoisingStrength() {
|
||||||
|
const isESRGANAvailable = useAppSelector(
|
||||||
|
(state: RootState) => state.system.isESRGANAvailable
|
||||||
|
);
|
||||||
|
|
||||||
|
const upscalingDenoising = useAppSelector(
|
||||||
|
(state: RootState) => state.postprocessing.upscalingDenoising
|
||||||
|
);
|
||||||
|
|
||||||
|
const { t } = useTranslation();
|
||||||
|
const dispatch = useAppDispatch();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<IAISlider
|
||||||
|
label={t('parameters:denoisingStrength')}
|
||||||
|
value={upscalingDenoising}
|
||||||
|
min={0}
|
||||||
|
max={1}
|
||||||
|
step={0.01}
|
||||||
|
onChange={(v) => {
|
||||||
|
dispatch(setUpscalingDenoising(v));
|
||||||
|
}}
|
||||||
|
handleReset={() => dispatch(setUpscalingDenoising(0.75))}
|
||||||
|
withSliderMarks
|
||||||
|
withInput
|
||||||
|
withReset
|
||||||
|
isSliderDisabled={!isESRGANAvailable}
|
||||||
|
isInputDisabled={!isESRGANAvailable}
|
||||||
|
isResetDisabled={!isESRGANAvailable}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
@ -0,0 +1,36 @@
|
|||||||
|
import { UPSCALING_LEVELS } from 'app/constants';
|
||||||
|
import type { RootState } from 'app/store';
|
||||||
|
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
|
||||||
|
import IAISelect from 'common/components/IAISelect';
|
||||||
|
import {
|
||||||
|
setUpscalingLevel,
|
||||||
|
type UpscalingLevel,
|
||||||
|
} from 'features/parameters/store/postprocessingSlice';
|
||||||
|
import type { ChangeEvent } from 'react';
|
||||||
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
|
export default function UpscaleScale() {
|
||||||
|
const isESRGANAvailable = useAppSelector(
|
||||||
|
(state: RootState) => state.system.isESRGANAvailable
|
||||||
|
);
|
||||||
|
|
||||||
|
const upscalingLevel = useAppSelector(
|
||||||
|
(state: RootState) => state.postprocessing.upscalingLevel
|
||||||
|
);
|
||||||
|
|
||||||
|
const { t } = useTranslation();
|
||||||
|
const dispatch = useAppDispatch();
|
||||||
|
|
||||||
|
const handleChangeLevel = (e: ChangeEvent<HTMLSelectElement>) =>
|
||||||
|
dispatch(setUpscalingLevel(Number(e.target.value) as UpscalingLevel));
|
||||||
|
|
||||||
|
return (
|
||||||
|
<IAISelect
|
||||||
|
isDisabled={!isESRGANAvailable}
|
||||||
|
label={t('parameters:scale')}
|
||||||
|
value={upscalingLevel}
|
||||||
|
onChange={handleChangeLevel}
|
||||||
|
validValues={UPSCALING_LEVELS}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
@ -1,104 +1,17 @@
|
|||||||
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
|
|
||||||
|
|
||||||
import {
|
|
||||||
setUpscalingDenoising,
|
|
||||||
setUpscalingLevel,
|
|
||||||
setUpscalingStrength,
|
|
||||||
UpscalingLevel,
|
|
||||||
} from 'features/parameters/store/postprocessingSlice';
|
|
||||||
|
|
||||||
import { createSelector } from '@reduxjs/toolkit';
|
|
||||||
import { UPSCALING_LEVELS } from 'app/constants';
|
|
||||||
import IAISelect from 'common/components/IAISelect';
|
|
||||||
import { postprocessingSelector } from 'features/parameters/store/postprocessingSelectors';
|
|
||||||
import { systemSelector } from 'features/system/store/systemSelectors';
|
|
||||||
import { isEqual } from 'lodash';
|
|
||||||
import { ChangeEvent } from 'react';
|
|
||||||
import { useTranslation } from 'react-i18next';
|
|
||||||
import IAISlider from 'common/components/IAISlider';
|
|
||||||
import { Flex } from '@chakra-ui/react';
|
import { Flex } from '@chakra-ui/react';
|
||||||
|
import UpscaleDenoisingStrength from './UpscaleDenoisingStrength';
|
||||||
const parametersSelector = createSelector(
|
import UpscaleStrength from './UpscaleStrength';
|
||||||
[postprocessingSelector, systemSelector],
|
import UpscaleScale from './UpscaleScale';
|
||||||
|
|
||||||
(
|
|
||||||
{ upscalingLevel, upscalingStrength, upscalingDenoising },
|
|
||||||
{ isESRGANAvailable }
|
|
||||||
) => {
|
|
||||||
return {
|
|
||||||
upscalingLevel,
|
|
||||||
upscalingDenoising,
|
|
||||||
upscalingStrength,
|
|
||||||
isESRGANAvailable,
|
|
||||||
};
|
|
||||||
},
|
|
||||||
{
|
|
||||||
memoizeOptions: {
|
|
||||||
resultEqualityCheck: isEqual,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Displays upscaling/ESRGAN options (level and strength).
|
* Displays upscaling/ESRGAN options (level and strength).
|
||||||
*/
|
*/
|
||||||
const UpscaleSettings = () => {
|
const UpscaleSettings = () => {
|
||||||
const dispatch = useAppDispatch();
|
|
||||||
const {
|
|
||||||
upscalingLevel,
|
|
||||||
upscalingStrength,
|
|
||||||
upscalingDenoising,
|
|
||||||
isESRGANAvailable,
|
|
||||||
} = useAppSelector(parametersSelector);
|
|
||||||
|
|
||||||
const { t } = useTranslation();
|
|
||||||
|
|
||||||
const handleChangeLevel = (e: ChangeEvent<HTMLSelectElement>) =>
|
|
||||||
dispatch(setUpscalingLevel(Number(e.target.value) as UpscalingLevel));
|
|
||||||
|
|
||||||
const handleChangeStrength = (v: number) => dispatch(setUpscalingStrength(v));
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Flex flexDir="column" rowGap="1rem" minWidth="20rem">
|
<Flex flexDir="column" rowGap={2} minWidth="20rem">
|
||||||
<IAISelect
|
<UpscaleScale />
|
||||||
isDisabled={!isESRGANAvailable}
|
<UpscaleDenoisingStrength />
|
||||||
label={t('parameters:scale')}
|
<UpscaleStrength />
|
||||||
value={upscalingLevel}
|
|
||||||
onChange={handleChangeLevel}
|
|
||||||
validValues={UPSCALING_LEVELS}
|
|
||||||
/>
|
|
||||||
<IAISlider
|
|
||||||
label={t('parameters:denoisingStrength')}
|
|
||||||
value={upscalingDenoising}
|
|
||||||
min={0}
|
|
||||||
max={1}
|
|
||||||
step={0.01}
|
|
||||||
onChange={(v) => {
|
|
||||||
dispatch(setUpscalingDenoising(v));
|
|
||||||
}}
|
|
||||||
handleReset={() => dispatch(setUpscalingDenoising(0.75))}
|
|
||||||
withSliderMarks
|
|
||||||
withInput
|
|
||||||
withReset
|
|
||||||
isSliderDisabled={!isESRGANAvailable}
|
|
||||||
isInputDisabled={!isESRGANAvailable}
|
|
||||||
isResetDisabled={!isESRGANAvailable}
|
|
||||||
/>
|
|
||||||
<IAISlider
|
|
||||||
label={`${t('parameters:upscale')} ${t('parameters:strength')}`}
|
|
||||||
value={upscalingStrength}
|
|
||||||
min={0}
|
|
||||||
max={1}
|
|
||||||
step={0.05}
|
|
||||||
onChange={handleChangeStrength}
|
|
||||||
handleReset={() => dispatch(setUpscalingStrength(0.75))}
|
|
||||||
withSliderMarks
|
|
||||||
withInput
|
|
||||||
withReset
|
|
||||||
isSliderDisabled={!isESRGANAvailable}
|
|
||||||
isInputDisabled={!isESRGANAvailable}
|
|
||||||
isResetDisabled={!isESRGANAvailable}
|
|
||||||
/>
|
|
||||||
</Flex>
|
</Flex>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -0,0 +1,35 @@
|
|||||||
|
import type { RootState } from 'app/store';
|
||||||
|
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
|
||||||
|
import IAISlider from 'common/components/IAISlider';
|
||||||
|
import { setUpscalingStrength } from 'features/parameters/store/postprocessingSlice';
|
||||||
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
|
export default function UpscaleStrength() {
|
||||||
|
const isESRGANAvailable = useAppSelector(
|
||||||
|
(state: RootState) => state.system.isESRGANAvailable
|
||||||
|
);
|
||||||
|
const upscalingStrength = useAppSelector(
|
||||||
|
(state: RootState) => state.postprocessing.upscalingStrength
|
||||||
|
);
|
||||||
|
|
||||||
|
const { t } = useTranslation();
|
||||||
|
const dispatch = useAppDispatch();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<IAISlider
|
||||||
|
label={`${t('parameters:upscale')} ${t('parameters:strength')}`}
|
||||||
|
value={upscalingStrength}
|
||||||
|
min={0}
|
||||||
|
max={1}
|
||||||
|
step={0.05}
|
||||||
|
onChange={(v) => dispatch(setUpscalingStrength(v))}
|
||||||
|
handleReset={() => dispatch(setUpscalingStrength(0.75))}
|
||||||
|
withSliderMarks
|
||||||
|
withInput
|
||||||
|
withReset
|
||||||
|
isSliderDisabled={!isESRGANAvailable}
|
||||||
|
isInputDisabled={!isESRGANAvailable}
|
||||||
|
isResetDisabled={!isESRGANAvailable}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
@ -1,6 +1,6 @@
|
|||||||
import { RootState } from 'app/store';
|
import { RootState } from 'app/store';
|
||||||
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
|
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
|
||||||
import IAINumberInput from 'common/components/IAINumberInput';
|
import IAISlider from 'common/components/IAISlider';
|
||||||
import { setVariationAmount } from 'features/parameters/store/generationSlice';
|
import { setVariationAmount } from 'features/parameters/store/generationSlice';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
@ -16,19 +16,22 @@ export default function VariationAmount() {
|
|||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
const handleChangevariationAmount = (v: number) =>
|
|
||||||
dispatch(setVariationAmount(v));
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<IAINumberInput
|
<IAISlider
|
||||||
label={t('parameters:variationAmount')}
|
label={t('parameters:variationAmount')}
|
||||||
value={variationAmount}
|
value={variationAmount}
|
||||||
step={0.01}
|
step={0.01}
|
||||||
min={0}
|
min={0}
|
||||||
max={1}
|
max={1}
|
||||||
isDisabled={!shouldGenerateVariations}
|
isSliderDisabled={!shouldGenerateVariations}
|
||||||
onChange={handleChangevariationAmount}
|
isInputDisabled={!shouldGenerateVariations}
|
||||||
isInteger={false}
|
isResetDisabled={!shouldGenerateVariations}
|
||||||
|
onChange={(v) => dispatch(setVariationAmount(v))}
|
||||||
|
handleReset={() => dispatch(setVariationAmount(0.1))}
|
||||||
|
withInput
|
||||||
|
withReset
|
||||||
|
withSliderMarks
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import { RootState } from 'app/store';
|
import { RootState } from 'app/store';
|
||||||
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
|
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
|
||||||
import IAINumberInput from 'common/components/IAINumberInput';
|
import IAINumberInput from 'common/components/IAINumberInput';
|
||||||
|
import IAISlider from 'common/components/IAISlider';
|
||||||
import { setCfgScale } from 'features/parameters/store/generationSlice';
|
import { setCfgScale } from 'features/parameters/store/generationSlice';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
@ -9,11 +10,29 @@ export default function MainCFGScale() {
|
|||||||
const cfgScale = useAppSelector(
|
const cfgScale = useAppSelector(
|
||||||
(state: RootState) => state.generation.cfgScale
|
(state: RootState) => state.generation.cfgScale
|
||||||
);
|
);
|
||||||
|
const shouldUseSliders = useAppSelector(
|
||||||
|
(state: RootState) => state.ui.shouldUseSliders
|
||||||
|
);
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
const handleChangeCfgScale = (v: number) => dispatch(setCfgScale(v));
|
const handleChangeCfgScale = (v: number) => dispatch(setCfgScale(v));
|
||||||
|
|
||||||
return (
|
return shouldUseSliders ? (
|
||||||
|
<IAISlider
|
||||||
|
label={t('parameters:cfgScale')}
|
||||||
|
step={0.5}
|
||||||
|
min={1.01}
|
||||||
|
max={30}
|
||||||
|
onChange={handleChangeCfgScale}
|
||||||
|
handleReset={() => dispatch(setCfgScale(7.5))}
|
||||||
|
value={cfgScale}
|
||||||
|
sliderMarkRightOffset={-5}
|
||||||
|
sliderNumberInputProps={{ max: 200 }}
|
||||||
|
withInput
|
||||||
|
withReset
|
||||||
|
withSliderMarks
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
<IAINumberInput
|
<IAINumberInput
|
||||||
label={t('parameters:cfgScale')}
|
label={t('parameters:cfgScale')}
|
||||||
step={0.5}
|
step={0.5}
|
||||||
|
@ -2,29 +2,50 @@ import { HEIGHTS } from 'app/constants';
|
|||||||
import { RootState } from 'app/store';
|
import { RootState } from 'app/store';
|
||||||
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
|
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
|
||||||
import IAISelect from 'common/components/IAISelect';
|
import IAISelect from 'common/components/IAISelect';
|
||||||
|
import IAISlider from 'common/components/IAISlider';
|
||||||
import { setHeight } from 'features/parameters/store/generationSlice';
|
import { setHeight } from 'features/parameters/store/generationSlice';
|
||||||
import { activeTabNameSelector } from 'features/ui/store/uiSelectors';
|
import { activeTabNameSelector } from 'features/ui/store/uiSelectors';
|
||||||
import { ChangeEvent } from 'react';
|
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
export default function MainHeight() {
|
export default function MainHeight() {
|
||||||
const height = useAppSelector((state: RootState) => state.generation.height);
|
const height = useAppSelector((state: RootState) => state.generation.height);
|
||||||
|
const shouldUseSliders = useAppSelector(
|
||||||
|
(state: RootState) => state.ui.shouldUseSliders
|
||||||
|
);
|
||||||
const activeTabName = useAppSelector(activeTabNameSelector);
|
const activeTabName = useAppSelector(activeTabNameSelector);
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
const handleChangeHeight = (e: ChangeEvent<HTMLSelectElement>) =>
|
return shouldUseSliders ? (
|
||||||
dispatch(setHeight(Number(e.target.value)));
|
<IAISlider
|
||||||
|
isSliderDisabled={activeTabName === 'unifiedCanvas'}
|
||||||
return (
|
isInputDisabled={activeTabName === 'unifiedCanvas'}
|
||||||
|
isResetDisabled={activeTabName === 'unifiedCanvas'}
|
||||||
|
label={t('parameters:height')}
|
||||||
|
value={height}
|
||||||
|
min={64}
|
||||||
|
step={64}
|
||||||
|
max={2048}
|
||||||
|
onChange={(v) => dispatch(setHeight(v))}
|
||||||
|
handleReset={() => dispatch(setHeight(512))}
|
||||||
|
withInput
|
||||||
|
withReset
|
||||||
|
withSliderMarks
|
||||||
|
sliderMarkRightOffset={-8}
|
||||||
|
inputWidth="6.2rem"
|
||||||
|
sliderNumberInputProps={{ max: 15360 }}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
<IAISelect
|
<IAISelect
|
||||||
isDisabled={activeTabName === 'unifiedCanvas'}
|
isDisabled={activeTabName === 'unifiedCanvas'}
|
||||||
label={t('parameters:height')}
|
label={t('parameters:height')}
|
||||||
value={height}
|
value={height}
|
||||||
flexGrow={1}
|
flexGrow={1}
|
||||||
onChange={handleChangeHeight}
|
onChange={(e) => dispatch(setHeight(Number(e.target.value)))}
|
||||||
validValues={HEIGHTS}
|
validValues={HEIGHTS}
|
||||||
styleClass="main-settings-block"
|
styleClass="main-settings-block"
|
||||||
|
width="5.5rem"
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,39 +1,41 @@
|
|||||||
import { createSelector } from '@reduxjs/toolkit';
|
|
||||||
import type { RootState } from 'app/store';
|
import type { RootState } from 'app/store';
|
||||||
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
|
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
|
||||||
import IAINumberInput from 'common/components/IAINumberInput';
|
import IAINumberInput from 'common/components/IAINumberInput';
|
||||||
import {
|
import IAISlider from 'common/components/IAISlider';
|
||||||
GenerationState,
|
import { setIterations } from 'features/parameters/store/generationSlice';
|
||||||
setIterations,
|
|
||||||
} from 'features/parameters/store/generationSlice';
|
|
||||||
import { isEqual } from 'lodash';
|
|
||||||
|
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
const mainIterationsSelector = createSelector(
|
|
||||||
[(state: RootState) => state.generation],
|
|
||||||
(parameters: GenerationState) => {
|
|
||||||
const { iterations } = parameters;
|
|
||||||
|
|
||||||
return {
|
|
||||||
iterations,
|
|
||||||
};
|
|
||||||
},
|
|
||||||
{
|
|
||||||
memoizeOptions: {
|
|
||||||
resultEqualityCheck: isEqual,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
export default function MainIterations() {
|
export default function MainIterations() {
|
||||||
|
const iterations = useAppSelector(
|
||||||
|
(state: RootState) => state.generation.iterations
|
||||||
|
);
|
||||||
|
|
||||||
|
const shouldUseSliders = useAppSelector(
|
||||||
|
(state: RootState) => state.ui.shouldUseSliders
|
||||||
|
);
|
||||||
|
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
const { iterations } = useAppSelector(mainIterationsSelector);
|
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
const handleChangeIterations = (v: number) => dispatch(setIterations(v));
|
const handleChangeIterations = (v: number) => dispatch(setIterations(v));
|
||||||
|
|
||||||
return (
|
return shouldUseSliders ? (
|
||||||
|
<IAISlider
|
||||||
|
label={t('parameters:images')}
|
||||||
|
step={1}
|
||||||
|
min={1}
|
||||||
|
max={16}
|
||||||
|
onChange={handleChangeIterations}
|
||||||
|
handleReset={() => dispatch(setIterations(1))}
|
||||||
|
value={iterations}
|
||||||
|
withInput
|
||||||
|
withReset
|
||||||
|
withSliderMarks
|
||||||
|
sliderMarkRightOffset={-5}
|
||||||
|
sliderNumberInputProps={{ max: 9999 }}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
<IAINumberInput
|
<IAINumberInput
|
||||||
label={t('parameters:images')}
|
label={t('parameters:images')}
|
||||||
step={1}
|
step={1}
|
||||||
|
@ -1,3 +1,8 @@
|
|||||||
|
import { Flex } from '@chakra-ui/react';
|
||||||
|
import { type RootState } from 'app/store';
|
||||||
|
import { useAppSelector } from 'app/storeHooks';
|
||||||
|
import { useTranslation } from 'react-i18next';
|
||||||
|
import ParametersAccordion from '../ParametersAccordion';
|
||||||
import MainCFGScale from './MainCFGScale';
|
import MainCFGScale from './MainCFGScale';
|
||||||
import MainHeight from './MainHeight';
|
import MainHeight from './MainHeight';
|
||||||
import MainIterations from './MainIterations';
|
import MainIterations from './MainIterations';
|
||||||
@ -8,20 +13,40 @@ import MainWidth from './MainWidth';
|
|||||||
export const inputWidth = 'auto';
|
export const inputWidth = 'auto';
|
||||||
|
|
||||||
export default function MainSettings() {
|
export default function MainSettings() {
|
||||||
return (
|
const { t } = useTranslation();
|
||||||
<div className="main-settings">
|
|
||||||
<div className="main-settings-list">
|
const shouldUseSliders = useAppSelector(
|
||||||
<div className="main-settings-row">
|
(state: RootState) => state.ui.shouldUseSliders
|
||||||
|
);
|
||||||
|
|
||||||
|
const accordionItems = {
|
||||||
|
main: {
|
||||||
|
header: `${t('parameters:general')}`,
|
||||||
|
feature: undefined,
|
||||||
|
content: shouldUseSliders ? (
|
||||||
|
<Flex flexDir="column" rowGap={2}>
|
||||||
<MainIterations />
|
<MainIterations />
|
||||||
<MainSteps />
|
<MainSteps />
|
||||||
<MainCFGScale />
|
<MainCFGScale />
|
||||||
</div>
|
|
||||||
<div className="main-settings-row">
|
|
||||||
<MainWidth />
|
<MainWidth />
|
||||||
<MainHeight />
|
<MainHeight />
|
||||||
<MainSampler />
|
<MainSampler />
|
||||||
</div>
|
</Flex>
|
||||||
</div>
|
) : (
|
||||||
</div>
|
<Flex flexDirection="column" rowGap={2}>
|
||||||
);
|
<Flex gap={2}>
|
||||||
|
<MainIterations />
|
||||||
|
<MainSteps />
|
||||||
|
<MainCFGScale />
|
||||||
|
</Flex>
|
||||||
|
<Flex>
|
||||||
|
<MainWidth />
|
||||||
|
<MainHeight />
|
||||||
|
<MainSampler />
|
||||||
|
</Flex>
|
||||||
|
</Flex>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
return <ParametersAccordion accordionInfo={accordionItems} />;
|
||||||
}
|
}
|
||||||
|
@ -27,6 +27,7 @@ export default function MainSampler() {
|
|||||||
activeModel.format === 'diffusers' ? DIFFUSERS_SAMPLERS : SAMPLERS
|
activeModel.format === 'diffusers' ? DIFFUSERS_SAMPLERS : SAMPLERS
|
||||||
}
|
}
|
||||||
styleClass="main-settings-block"
|
styleClass="main-settings-block"
|
||||||
|
minWidth="9rem"
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,17 +1,36 @@
|
|||||||
import { RootState } from 'app/store';
|
import { RootState } from 'app/store';
|
||||||
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
|
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
|
||||||
import IAINumberInput from 'common/components/IAINumberInput';
|
import IAINumberInput from 'common/components/IAINumberInput';
|
||||||
|
|
||||||
|
import IAISlider from 'common/components/IAISlider';
|
||||||
import { setSteps } from 'features/parameters/store/generationSlice';
|
import { setSteps } from 'features/parameters/store/generationSlice';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
export default function MainSteps() {
|
export default function MainSteps() {
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
const steps = useAppSelector((state: RootState) => state.generation.steps);
|
const steps = useAppSelector((state: RootState) => state.generation.steps);
|
||||||
|
const shouldUseSliders = useAppSelector(
|
||||||
|
(state: RootState) => state.ui.shouldUseSliders
|
||||||
|
);
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
const handleChangeSteps = (v: number) => dispatch(setSteps(v));
|
const handleChangeSteps = (v: number) => dispatch(setSteps(v));
|
||||||
|
|
||||||
return (
|
return shouldUseSliders ? (
|
||||||
|
<IAISlider
|
||||||
|
label={t('parameters:steps')}
|
||||||
|
min={1}
|
||||||
|
step={1}
|
||||||
|
onChange={handleChangeSteps}
|
||||||
|
handleReset={() => dispatch(setSteps(20))}
|
||||||
|
value={steps}
|
||||||
|
withInput
|
||||||
|
withReset
|
||||||
|
withSliderMarks
|
||||||
|
sliderMarkRightOffset={-6}
|
||||||
|
sliderNumberInputProps={{ max: 9999 }}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
<IAINumberInput
|
<IAINumberInput
|
||||||
label={t('parameters:steps')}
|
label={t('parameters:steps')}
|
||||||
min={1}
|
min={1}
|
||||||
|
@ -2,30 +2,51 @@ import { WIDTHS } from 'app/constants';
|
|||||||
import { RootState } from 'app/store';
|
import { RootState } from 'app/store';
|
||||||
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
|
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
|
||||||
import IAISelect from 'common/components/IAISelect';
|
import IAISelect from 'common/components/IAISelect';
|
||||||
|
import IAISlider from 'common/components/IAISlider';
|
||||||
import { setWidth } from 'features/parameters/store/generationSlice';
|
import { setWidth } from 'features/parameters/store/generationSlice';
|
||||||
import { activeTabNameSelector } from 'features/ui/store/uiSelectors';
|
import { activeTabNameSelector } from 'features/ui/store/uiSelectors';
|
||||||
import { ChangeEvent } from 'react';
|
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
export default function MainWidth() {
|
export default function MainWidth() {
|
||||||
const width = useAppSelector((state: RootState) => state.generation.width);
|
const width = useAppSelector((state: RootState) => state.generation.width);
|
||||||
|
const shouldUseSliders = useAppSelector(
|
||||||
|
(state: RootState) => state.ui.shouldUseSliders
|
||||||
|
);
|
||||||
const activeTabName = useAppSelector(activeTabNameSelector);
|
const activeTabName = useAppSelector(activeTabNameSelector);
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
|
|
||||||
const handleChangeWidth = (e: ChangeEvent<HTMLSelectElement>) =>
|
return shouldUseSliders ? (
|
||||||
dispatch(setWidth(Number(e.target.value)));
|
<IAISlider
|
||||||
|
isSliderDisabled={activeTabName === 'unifiedCanvas'}
|
||||||
return (
|
isInputDisabled={activeTabName === 'unifiedCanvas'}
|
||||||
|
isResetDisabled={activeTabName === 'unifiedCanvas'}
|
||||||
|
label={t('parameters:width')}
|
||||||
|
value={width}
|
||||||
|
min={64}
|
||||||
|
step={64}
|
||||||
|
max={2048}
|
||||||
|
onChange={(v) => dispatch(setWidth(v))}
|
||||||
|
handleReset={() => dispatch(setWidth(512))}
|
||||||
|
withInput
|
||||||
|
withReset
|
||||||
|
withSliderMarks
|
||||||
|
sliderMarkRightOffset={-8}
|
||||||
|
inputWidth="6.2rem"
|
||||||
|
inputReadOnly
|
||||||
|
sliderNumberInputProps={{ max: 15360 }}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
<IAISelect
|
<IAISelect
|
||||||
isDisabled={activeTabName === 'unifiedCanvas'}
|
isDisabled={activeTabName === 'unifiedCanvas'}
|
||||||
label={t('parameters:width')}
|
label={t('parameters:width')}
|
||||||
value={width}
|
value={width}
|
||||||
flexGrow={1}
|
flexGrow={1}
|
||||||
onChange={handleChangeWidth}
|
onChange={(e) => dispatch(setWidth(Number(e.target.value)))}
|
||||||
validValues={WIDTHS}
|
validValues={WIDTHS}
|
||||||
styleClass="main-settings-block"
|
styleClass="main-settings-block"
|
||||||
|
width="5.5rem"
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -22,7 +22,7 @@ export interface PostprocessingState {
|
|||||||
|
|
||||||
const initialPostprocessingState: PostprocessingState = {
|
const initialPostprocessingState: PostprocessingState = {
|
||||||
codeformerFidelity: 0.75,
|
codeformerFidelity: 0.75,
|
||||||
facetoolStrength: 0.8,
|
facetoolStrength: 0.75,
|
||||||
facetoolType: 'gfpgan',
|
facetoolType: 'gfpgan',
|
||||||
hiresFix: false,
|
hiresFix: false,
|
||||||
hiresStrength: 0.75,
|
hiresStrength: 0.75,
|
||||||
|
@ -14,7 +14,7 @@ import {
|
|||||||
} from '@chakra-ui/react';
|
} from '@chakra-ui/react';
|
||||||
import { createSelector } from '@reduxjs/toolkit';
|
import { createSelector } from '@reduxjs/toolkit';
|
||||||
import { IN_PROGRESS_IMAGE_TYPES } from 'app/constants';
|
import { IN_PROGRESS_IMAGE_TYPES } from 'app/constants';
|
||||||
import { RootState } from 'app/store';
|
import { type RootState } from 'app/store';
|
||||||
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
|
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
|
||||||
import IAINumberInput from 'common/components/IAINumberInput';
|
import IAINumberInput from 'common/components/IAINumberInput';
|
||||||
import IAISelect from 'common/components/IAISelect';
|
import IAISelect from 'common/components/IAISelect';
|
||||||
@ -27,9 +27,14 @@ import {
|
|||||||
setShouldConfirmOnDelete,
|
setShouldConfirmOnDelete,
|
||||||
setShouldDisplayGuides,
|
setShouldDisplayGuides,
|
||||||
setShouldDisplayInProgressType,
|
setShouldDisplayInProgressType,
|
||||||
|
type SystemState,
|
||||||
} from 'features/system/store/systemSlice';
|
} from 'features/system/store/systemSlice';
|
||||||
import { uiSelector } from 'features/ui/store/uiSelectors';
|
import { uiSelector } from 'features/ui/store/uiSelectors';
|
||||||
import { setShouldUseCanvasBetaLayout } from 'features/ui/store/uiSlice';
|
import {
|
||||||
|
setShouldUseCanvasBetaLayout,
|
||||||
|
setShouldUseSliders,
|
||||||
|
} from 'features/ui/store/uiSlice';
|
||||||
|
import { type UIState } from 'features/ui/store/uiTypes';
|
||||||
import { isEqual, map } from 'lodash';
|
import { isEqual, map } from 'lodash';
|
||||||
import { persistor } from 'persistor';
|
import { persistor } from 'persistor';
|
||||||
import { ChangeEvent, cloneElement, ReactElement } from 'react';
|
import { ChangeEvent, cloneElement, ReactElement } from 'react';
|
||||||
@ -37,7 +42,7 @@ import { useTranslation } from 'react-i18next';
|
|||||||
|
|
||||||
const selector = createSelector(
|
const selector = createSelector(
|
||||||
[systemSelector, uiSelector],
|
[systemSelector, uiSelector],
|
||||||
(system, ui) => {
|
(system: SystemState, ui: UIState) => {
|
||||||
const {
|
const {
|
||||||
shouldDisplayInProgressType,
|
shouldDisplayInProgressType,
|
||||||
shouldConfirmOnDelete,
|
shouldConfirmOnDelete,
|
||||||
@ -47,7 +52,7 @@ const selector = createSelector(
|
|||||||
enableImageDebugging,
|
enableImageDebugging,
|
||||||
} = system;
|
} = system;
|
||||||
|
|
||||||
const { shouldUseCanvasBetaLayout } = ui;
|
const { shouldUseCanvasBetaLayout, shouldUseSliders } = ui;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
shouldDisplayInProgressType,
|
shouldDisplayInProgressType,
|
||||||
@ -57,6 +62,7 @@ const selector = createSelector(
|
|||||||
saveIntermediatesInterval,
|
saveIntermediatesInterval,
|
||||||
enableImageDebugging,
|
enableImageDebugging,
|
||||||
shouldUseCanvasBetaLayout,
|
shouldUseCanvasBetaLayout,
|
||||||
|
shouldUseSliders,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -100,6 +106,7 @@ const SettingsModal = ({ children }: SettingsModalProps) => {
|
|||||||
saveIntermediatesInterval,
|
saveIntermediatesInterval,
|
||||||
enableImageDebugging,
|
enableImageDebugging,
|
||||||
shouldUseCanvasBetaLayout,
|
shouldUseCanvasBetaLayout,
|
||||||
|
shouldUseSliders,
|
||||||
} = useAppSelector(selector);
|
} = useAppSelector(selector);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -191,6 +198,14 @@ const SettingsModal = ({ children }: SettingsModalProps) => {
|
|||||||
dispatch(setShouldUseCanvasBetaLayout(e.target.checked))
|
dispatch(setShouldUseCanvasBetaLayout(e.target.checked))
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
<IAISwitch
|
||||||
|
styleClass="settings-modal-item"
|
||||||
|
label={t('settings:useSlidersForAll')}
|
||||||
|
isChecked={shouldUseSliders}
|
||||||
|
onChange={(e: ChangeEvent<HTMLInputElement>) =>
|
||||||
|
dispatch(setShouldUseSliders(e.target.checked))
|
||||||
|
}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="settings-modal-items">
|
<div className="settings-modal-items">
|
||||||
|
@ -0,0 +1,26 @@
|
|||||||
|
import { Flex } from '@chakra-ui/react';
|
||||||
|
import ImageFit from 'features/parameters/components/AdvancedParameters/ImageToImage/ImageFit';
|
||||||
|
import ImageToImageStrength from 'features/parameters/components/AdvancedParameters/ImageToImage/ImageToImageStrength';
|
||||||
|
import ParametersAccordion from 'features/parameters/components/ParametersAccordion';
|
||||||
|
|
||||||
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
|
export default function ImageToImageOptions() {
|
||||||
|
const { t } = useTranslation();
|
||||||
|
const imageToImageAccordionItems = {
|
||||||
|
imageToImage: {
|
||||||
|
header: `${t('parameters:imageToImage')}`,
|
||||||
|
feature: undefined,
|
||||||
|
content: (
|
||||||
|
<Flex gap={2} flexDir="column">
|
||||||
|
<ImageToImageStrength
|
||||||
|
label={t('parameters:img2imgStrength')}
|
||||||
|
styleClass="main-settings-block image-to-image-strength-main-option"
|
||||||
|
/>
|
||||||
|
<ImageFit />
|
||||||
|
</Flex>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
return <ParametersAccordion accordionInfo={imageToImageAccordionItems} />;
|
||||||
|
}
|
@ -2,8 +2,6 @@ import { Flex } from '@chakra-ui/react';
|
|||||||
import { Feature } from 'app/features';
|
import { Feature } from 'app/features';
|
||||||
import FaceRestoreSettings from 'features/parameters/components/AdvancedParameters/FaceRestore/FaceRestoreSettings';
|
import FaceRestoreSettings from 'features/parameters/components/AdvancedParameters/FaceRestore/FaceRestoreSettings';
|
||||||
import FaceRestoreToggle from 'features/parameters/components/AdvancedParameters/FaceRestore/FaceRestoreToggle';
|
import FaceRestoreToggle from 'features/parameters/components/AdvancedParameters/FaceRestore/FaceRestoreToggle';
|
||||||
import ImageFit from 'features/parameters/components/AdvancedParameters/ImageToImage/ImageFit';
|
|
||||||
import ImageToImageStrength from 'features/parameters/components/AdvancedParameters/ImageToImage/ImageToImageStrength';
|
|
||||||
import ImageToImageOutputSettings from 'features/parameters/components/AdvancedParameters/Output/ImageToImageOutputSettings';
|
import ImageToImageOutputSettings from 'features/parameters/components/AdvancedParameters/Output/ImageToImageOutputSettings';
|
||||||
import SeedSettings from 'features/parameters/components/AdvancedParameters/Seed/SeedSettings';
|
import SeedSettings from 'features/parameters/components/AdvancedParameters/Seed/SeedSettings';
|
||||||
import UpscaleSettings from 'features/parameters/components/AdvancedParameters/Upscale/UpscaleSettings';
|
import UpscaleSettings from 'features/parameters/components/AdvancedParameters/Upscale/UpscaleSettings';
|
||||||
@ -17,6 +15,7 @@ import NegativePromptInput from 'features/parameters/components/PromptInput/Nega
|
|||||||
import PromptInput from 'features/parameters/components/PromptInput/PromptInput';
|
import PromptInput from 'features/parameters/components/PromptInput/PromptInput';
|
||||||
import InvokeOptionsPanel from 'features/ui/components/InvokeParametersPanel';
|
import InvokeOptionsPanel from 'features/ui/components/InvokeParametersPanel';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
import ImageToImageOptions from './ImageToImageOptions';
|
||||||
|
|
||||||
export default function ImageToImagePanel() {
|
export default function ImageToImagePanel() {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
@ -60,11 +59,7 @@ export default function ImageToImagePanel() {
|
|||||||
</Flex>
|
</Flex>
|
||||||
<ProcessButtons />
|
<ProcessButtons />
|
||||||
<MainSettings />
|
<MainSettings />
|
||||||
<ImageToImageStrength
|
<ImageToImageOptions />
|
||||||
label={t('parameters:img2imgStrength')}
|
|
||||||
styleClass="main-settings-block image-to-image-strength-main-option"
|
|
||||||
/>
|
|
||||||
<ImageFit />
|
|
||||||
<ParametersAccordion accordionInfo={imageToImageAccordions} />
|
<ParametersAccordion accordionInfo={imageToImageAccordions} />
|
||||||
</InvokeOptionsPanel>
|
</InvokeOptionsPanel>
|
||||||
);
|
);
|
||||||
|
@ -32,7 +32,7 @@
|
|||||||
.parameters-panel {
|
.parameters-panel {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
row-gap: 1rem;
|
row-gap: 0.5rem;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
@include HideScrollbar;
|
@include HideScrollbar;
|
||||||
background-color: var(--background-color);
|
background-color: var(--background-color);
|
||||||
|
@ -20,6 +20,11 @@ export default function UnifiedCanvasPanel() {
|
|||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
const unifiedCanvasAccordions = {
|
const unifiedCanvasAccordions = {
|
||||||
|
seed: {
|
||||||
|
header: `${t('parameters:seed')}`,
|
||||||
|
feature: Feature.SEED,
|
||||||
|
content: <SeedSettings />,
|
||||||
|
},
|
||||||
boundingBox: {
|
boundingBox: {
|
||||||
header: `${t('parameters:boundingBoxHeader')}`,
|
header: `${t('parameters:boundingBoxHeader')}`,
|
||||||
feature: Feature.BOUNDING_BOX,
|
feature: Feature.BOUNDING_BOX,
|
||||||
@ -35,11 +40,6 @@ export default function UnifiedCanvasPanel() {
|
|||||||
feature: Feature.INFILL_AND_SCALING,
|
feature: Feature.INFILL_AND_SCALING,
|
||||||
content: <InfillAndScalingSettings />,
|
content: <InfillAndScalingSettings />,
|
||||||
},
|
},
|
||||||
seed: {
|
|
||||||
header: `${t('parameters:seed')}`,
|
|
||||||
feature: Feature.SEED,
|
|
||||||
content: <SeedSettings />,
|
|
||||||
},
|
|
||||||
variations: {
|
variations: {
|
||||||
header: `${t('parameters:variations')}`,
|
header: `${t('parameters:variations')}`,
|
||||||
feature: Feature.VARIATIONS,
|
feature: Feature.VARIATIONS,
|
||||||
@ -48,6 +48,19 @@ export default function UnifiedCanvasPanel() {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const unifiedCanvasImg2ImgAccordion = {
|
||||||
|
unifiedCanvasImg2Img: {
|
||||||
|
header: `${t('parameters:imageToImage')}`,
|
||||||
|
feature: undefined,
|
||||||
|
content: (
|
||||||
|
<ImageToImageStrength
|
||||||
|
label={t('parameters:img2imgStrength')}
|
||||||
|
styleClass="main-settings-block image-to-image-strength-main-option"
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<InvokeOptionsPanel>
|
<InvokeOptionsPanel>
|
||||||
<Flex flexDir="column" rowGap="0.5rem">
|
<Flex flexDir="column" rowGap="0.5rem">
|
||||||
@ -56,10 +69,7 @@ export default function UnifiedCanvasPanel() {
|
|||||||
</Flex>
|
</Flex>
|
||||||
<ProcessButtons />
|
<ProcessButtons />
|
||||||
<MainSettings />
|
<MainSettings />
|
||||||
<ImageToImageStrength
|
<ParametersAccordion accordionInfo={unifiedCanvasImg2ImgAccordion} />
|
||||||
label={t('parameters:img2imgStrength')}
|
|
||||||
styleClass="main-settings-block image-to-image-strength-main-option"
|
|
||||||
/>
|
|
||||||
<ParametersAccordion accordionInfo={unifiedCanvasAccordions} />
|
<ParametersAccordion accordionInfo={unifiedCanvasAccordions} />
|
||||||
</InvokeOptionsPanel>
|
</InvokeOptionsPanel>
|
||||||
);
|
);
|
||||||
|
@ -14,6 +14,7 @@ const initialtabsState: UIState = {
|
|||||||
shouldShowImageDetails: false,
|
shouldShowImageDetails: false,
|
||||||
shouldUseCanvasBetaLayout: false,
|
shouldUseCanvasBetaLayout: false,
|
||||||
shouldShowExistingModelsInSearch: false,
|
shouldShowExistingModelsInSearch: false,
|
||||||
|
shouldUseSliders: false,
|
||||||
addNewModelUIOption: null,
|
addNewModelUIOption: null,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -66,6 +67,9 @@ export const uiSlice = createSlice({
|
|||||||
) => {
|
) => {
|
||||||
state.shouldShowExistingModelsInSearch = action.payload;
|
state.shouldShowExistingModelsInSearch = action.payload;
|
||||||
},
|
},
|
||||||
|
setShouldUseSliders: (state, action: PayloadAction<boolean>) => {
|
||||||
|
state.shouldUseSliders = action.payload;
|
||||||
|
},
|
||||||
setAddNewModelUIOption: (state, action: PayloadAction<AddNewModelType>) => {
|
setAddNewModelUIOption: (state, action: PayloadAction<AddNewModelType>) => {
|
||||||
state.addNewModelUIOption = action.payload;
|
state.addNewModelUIOption = action.payload;
|
||||||
},
|
},
|
||||||
@ -83,6 +87,7 @@ export const {
|
|||||||
setShouldShowImageDetails,
|
setShouldShowImageDetails,
|
||||||
setShouldUseCanvasBetaLayout,
|
setShouldUseCanvasBetaLayout,
|
||||||
setShouldShowExistingModelsInSearch,
|
setShouldShowExistingModelsInSearch,
|
||||||
|
setShouldUseSliders,
|
||||||
setAddNewModelUIOption,
|
setAddNewModelUIOption,
|
||||||
} = uiSlice.actions;
|
} = uiSlice.actions;
|
||||||
|
|
||||||
|
@ -11,5 +11,6 @@ export interface UIState {
|
|||||||
shouldShowImageDetails: boolean;
|
shouldShowImageDetails: boolean;
|
||||||
shouldUseCanvasBetaLayout: boolean;
|
shouldUseCanvasBetaLayout: boolean;
|
||||||
shouldShowExistingModelsInSearch: boolean;
|
shouldShowExistingModelsInSearch: boolean;
|
||||||
|
shouldUseSliders: boolean;
|
||||||
addNewModelUIOption: AddNewModelType;
|
addNewModelUIOption: AddNewModelType;
|
||||||
}
|
}
|
||||||
|
@ -137,4 +137,7 @@
|
|||||||
// Scrollbar
|
// Scrollbar
|
||||||
--scrollbar-color: var(--accent-color);
|
--scrollbar-color: var(--accent-color);
|
||||||
--scrollbar-color-hover: var(--accent-color-bright);
|
--scrollbar-color-hover: var(--accent-color-bright);
|
||||||
|
|
||||||
|
// SubHook
|
||||||
|
--subhook-color: var(--accent-color);
|
||||||
}
|
}
|
||||||
|
@ -135,4 +135,7 @@
|
|||||||
// Scrollbar
|
// Scrollbar
|
||||||
--scrollbar-color: var(--accent-color);
|
--scrollbar-color: var(--accent-color);
|
||||||
--scrollbar-color-hover: var(--accent-color-bright);
|
--scrollbar-color-hover: var(--accent-color-bright);
|
||||||
|
|
||||||
|
// SubHook
|
||||||
|
--subhook-color: var(--accent-color);
|
||||||
}
|
}
|
||||||
|
@ -132,4 +132,7 @@
|
|||||||
// Scrollbar
|
// Scrollbar
|
||||||
--scrollbar-color: rgb(180, 180, 184);
|
--scrollbar-color: rgb(180, 180, 184);
|
||||||
--scrollbar-color-hover: rgb(150, 150, 154);
|
--scrollbar-color-hover: rgb(150, 150, 154);
|
||||||
|
|
||||||
|
// SubHook
|
||||||
|
--subhook-color: rgb(0, 0, 0);
|
||||||
}
|
}
|
||||||
|
File diff suppressed because one or more lines are too long
Loading…
x
Reference in New Issue
Block a user