diff --git a/invokeai/frontend/web/src/app/types/invokeai.ts b/invokeai/frontend/web/src/app/types/invokeai.ts index 8658b9dcb7..faee66a9a9 100644 --- a/invokeai/frontend/web/src/app/types/invokeai.ts +++ b/invokeai/frontend/web/src/app/types/invokeai.ts @@ -43,6 +43,16 @@ export type SDFeature = | 'vae' | 'hrf'; +export type NumericalParameterConfig = { + initial: number; + sliderMin: number; + sliderMax: number; + numberInputMin: number; + numberInputMax: number; + fineStep: number; + coarseStep: number; +}; + /** * Configuration options for the InvokeAI UI. * Distinct from system settings which may be changed inside the app. @@ -66,69 +76,32 @@ export type AppConfig = { defaultModel?: string; disabledControlNetModels: string[]; disabledControlNetProcessors: (keyof typeof CONTROLNET_PROCESSORS)[]; - iterations: { - initial: number; - min: number; - sliderMax: number; - inputMax: number; - fineStep: number; - coarseStep: number; - }; - width: { - initial: number; - min: number; - sliderMax: number; - inputMax: number; - fineStep: number; - coarseStep: number; - }; - height: { - initial: number; - min: number; - sliderMax: number; - inputMax: number; - fineStep: number; - coarseStep: number; - }; - steps: { - initial: number; - min: number; - sliderMax: number; - inputMax: number; - fineStep: number; - coarseStep: number; - }; - guidance: { - initial: number; - min: number; - sliderMax: number; - inputMax: number; - fineStep: number; - coarseStep: number; - }; - img2imgStrength: { - initial: number; - min: number; - sliderMax: number; - inputMax: number; - fineStep: number; - coarseStep: number; - }; - hrfStrength: { - initial: number; - min: number; - sliderMax: number; - inputMax: number; - fineStep: number; - coarseStep: number; - }; + // Core parameters + iterations: NumericalParameterConfig; + width: NumericalParameterConfig; // initial value comes from model + height: NumericalParameterConfig; // initial value comes from model + steps: NumericalParameterConfig; + guidance: NumericalParameterConfig; + cfgRescaleMultiplier: NumericalParameterConfig; + img2imgStrength: NumericalParameterConfig; + // Canvas + boundingBoxHeight: NumericalParameterConfig; // initial value comes from model + boundingBoxWidth: NumericalParameterConfig; // initial value comes from model + scaledBoundingBoxHeight: NumericalParameterConfig; // initial value comes from model + scaledBoundingBoxWidth: NumericalParameterConfig; // initial value comes from model + canvasCoherenceStrength: NumericalParameterConfig; + canvasCoherenceSteps: NumericalParameterConfig; + infillTileSize: NumericalParameterConfig; + infillPatchmatchDownscaleSize: NumericalParameterConfig; + // Misc advanced + clipSkip: NumericalParameterConfig; // slider and input max are ignored for this, because the values depend on the model + maskBlur: NumericalParameterConfig; + hrfStrength: NumericalParameterConfig; dynamicPrompts: { - maxPrompts: { - initial: number; - min: number; - sliderMax: number; - inputMax: number; - }; + maxPrompts: NumericalParameterConfig; + }; + ca: { + weight: NumericalParameterConfig; }; }; }; diff --git a/invokeai/frontend/web/src/features/controlAdapters/components/parameters/ParamControlAdapterWeight.tsx b/invokeai/frontend/web/src/features/controlAdapters/components/parameters/ParamControlAdapterWeight.tsx index 11f0dca36c..65a70d78de 100644 --- a/invokeai/frontend/web/src/features/controlAdapters/components/parameters/ParamControlAdapterWeight.tsx +++ b/invokeai/frontend/web/src/features/controlAdapters/components/parameters/ParamControlAdapterWeight.tsx @@ -1,4 +1,4 @@ -import { useAppDispatch } from 'app/store/storeHooks'; +import { useAppDispatch, useAppSelector } from 'app/store/storeHooks'; import { InvControl } from 'common/components/InvControl/InvControl'; import { InvControlGroup } from 'common/components/InvControl/InvControlGroup'; import { InvNumberInput } from 'common/components/InvNumberInput/InvNumberInput'; @@ -17,10 +17,22 @@ type ParamControlAdapterWeightProps = { const formatValue = (v: number) => v.toFixed(2); const ParamControlAdapterWeight = ({ id }: ParamControlAdapterWeightProps) => { + const { t } = useTranslation(); + const dispatch = useAppDispatch(); const isEnabled = useControlAdapterIsEnabled(id); const weight = useControlAdapterWeight(id); - const dispatch = useAppDispatch(); - const { t } = useTranslation(); + const initial = useAppSelector((s) => s.config.sd.ca.weight.initial); + const sliderMin = useAppSelector((s) => s.config.sd.ca.weight.sliderMin); + const sliderMax = useAppSelector((s) => s.config.sd.ca.weight.sliderMax); + const numberInputMin = useAppSelector( + (s) => s.config.sd.ca.weight.numberInputMin + ); + const numberInputMax = useAppSelector( + (s) => s.config.sd.ca.weight.numberInputMax + ); + const coarseStep = useAppSelector((s) => s.config.sd.ca.weight.coarseStep); + const fineStep = useAppSelector((s) => s.config.sd.ca.weight.fineStep); + const onChange = useCallback( (weight: number) => { dispatch(controlAdapterWeightChanged({ id, weight })); @@ -43,23 +55,23 @@ const ParamControlAdapterWeight = ({ id }: ParamControlAdapterWeightProps) => { diff --git a/invokeai/frontend/web/src/features/dynamicPrompts/components/ParamDynamicPromptsMaxPrompts.tsx b/invokeai/frontend/web/src/features/dynamicPrompts/components/ParamDynamicPromptsMaxPrompts.tsx index 97fd6950db..c4b69d49e4 100644 --- a/invokeai/frontend/web/src/features/dynamicPrompts/components/ParamDynamicPromptsMaxPrompts.tsx +++ b/invokeai/frontend/web/src/features/dynamicPrompts/components/ParamDynamicPromptsMaxPrompts.tsx @@ -7,12 +7,17 @@ import { useTranslation } from 'react-i18next'; const ParamDynamicPromptsMaxPrompts = () => { const maxPrompts = useAppSelector((s) => s.dynamicPrompts.maxPrompts); - const min = useAppSelector((s) => s.config.sd.dynamicPrompts.maxPrompts.min); + const sliderMin = useAppSelector( + (s) => s.config.sd.dynamicPrompts.maxPrompts.sliderMin + ); const sliderMax = useAppSelector( (s) => s.config.sd.dynamicPrompts.maxPrompts.sliderMax ); - const inputMax = useAppSelector( - (s) => s.config.sd.dynamicPrompts.maxPrompts.inputMax + const numberInputMin = useAppSelector( + (s) => s.config.sd.dynamicPrompts.maxPrompts.numberInputMin + ); + const numberInputMax = useAppSelector( + (s) => s.config.sd.dynamicPrompts.maxPrompts.numberInputMax ); const initial = useAppSelector( (s) => s.config.sd.dynamicPrompts.maxPrompts.initial @@ -36,14 +41,15 @@ const ParamDynamicPromptsMaxPrompts = () => { renderInfoPopoverInPortal={false} > ); diff --git a/invokeai/frontend/web/src/features/hrf/components/ParamHrfStrength.tsx b/invokeai/frontend/web/src/features/hrf/components/ParamHrfStrength.tsx index b05c6a8ed8..a41e096148 100644 --- a/invokeai/frontend/web/src/features/hrf/components/ParamHrfStrength.tsx +++ b/invokeai/frontend/web/src/features/hrf/components/ParamHrfStrength.tsx @@ -8,8 +8,14 @@ import { useTranslation } from 'react-i18next'; const ParamHrfStrength = () => { const hrfStrength = useAppSelector((s) => s.hrf.hrfStrength); const initial = useAppSelector((s) => s.config.sd.hrfStrength.initial); - const min = useAppSelector((s) => s.config.sd.hrfStrength.min); + const sliderMin = useAppSelector((s) => s.config.sd.hrfStrength.sliderMin); const sliderMax = useAppSelector((s) => s.config.sd.hrfStrength.sliderMax); + const numberInputMin = useAppSelector( + (s) => s.config.sd.hrfStrength.numberInputMin + ); + const numberInputMax = useAppSelector( + (s) => s.config.sd.hrfStrength.numberInputMax + ); const coarseStep = useAppSelector((s) => s.config.sd.hrfStrength.coarseStep); const fineStep = useAppSelector((s) => s.config.sd.hrfStrength.fineStep); const dispatch = useAppDispatch(); @@ -25,7 +31,7 @@ const ParamHrfStrength = () => { return ( { onChange={onChange} marks withNumberInput + numberInputMin={numberInputMin} + numberInputMax={numberInputMax} /> ); diff --git a/invokeai/frontend/web/src/features/parameters/components/Advanced/ParamCFGRescaleMultiplier.tsx b/invokeai/frontend/web/src/features/parameters/components/Advanced/ParamCFGRescaleMultiplier.tsx index a1e65b5ea9..e9d37d6f97 100644 --- a/invokeai/frontend/web/src/features/parameters/components/Advanced/ParamCFGRescaleMultiplier.tsx +++ b/invokeai/frontend/web/src/features/parameters/components/Advanced/ParamCFGRescaleMultiplier.tsx @@ -9,6 +9,28 @@ const ParamCFGRescaleMultiplier = () => { const cfgRescaleMultiplier = useAppSelector( (s) => s.generation.cfgRescaleMultiplier ); + const initial = useAppSelector( + (s) => s.config.sd.cfgRescaleMultiplier.initial + ); + const sliderMin = useAppSelector( + (s) => s.config.sd.cfgRescaleMultiplier.sliderMin + ); + const sliderMax = useAppSelector( + (s) => s.config.sd.cfgRescaleMultiplier.sliderMax + ); + const numberInputMin = useAppSelector( + (s) => s.config.sd.cfgRescaleMultiplier.numberInputMin + ); + const numberInputMax = useAppSelector( + (s) => s.config.sd.cfgRescaleMultiplier.numberInputMax + ); + const coarseStep = useAppSelector( + (s) => s.config.sd.cfgRescaleMultiplier.coarseStep + ); + const fineStep = useAppSelector( + (s) => s.config.sd.cfgRescaleMultiplier.fineStep + ); + const dispatch = useAppDispatch(); const { t } = useTranslation(); @@ -24,12 +46,14 @@ const ParamCFGRescaleMultiplier = () => { > diff --git a/invokeai/frontend/web/src/features/parameters/components/Advanced/ParamClipSkip.tsx b/invokeai/frontend/web/src/features/parameters/components/Advanced/ParamClipSkip.tsx index 4588f34165..5ed2470471 100644 --- a/invokeai/frontend/web/src/features/parameters/components/Advanced/ParamClipSkip.tsx +++ b/invokeai/frontend/web/src/features/parameters/components/Advanced/ParamClipSkip.tsx @@ -8,7 +8,13 @@ import { useTranslation } from 'react-i18next'; const ParamClipSkip = () => { const clipSkip = useAppSelector((s) => s.generation.clipSkip); - + const initial = useAppSelector((s) => s.config.sd.clipSkip.initial); + const sliderMin = useAppSelector((s) => s.config.sd.clipSkip.sliderMin); + const numberInputMin = useAppSelector( + (s) => s.config.sd.clipSkip.numberInputMin + ); + const coarseStep = useAppSelector((s) => s.config.sd.clipSkip.coarseStep); + const fineStep = useAppSelector((s) => s.config.sd.clipSkip.fineStep); const { model } = useAppSelector((s) => s.generation); const dispatch = useAppDispatch(); @@ -43,12 +49,15 @@ const ParamClipSkip = () => { diff --git a/invokeai/frontend/web/src/features/parameters/components/Canvas/BoundingBox/ParamBoundingBoxHeight.tsx b/invokeai/frontend/web/src/features/parameters/components/Canvas/BoundingBox/ParamBoundingBoxHeight.tsx index e072f93953..0636320092 100644 --- a/invokeai/frontend/web/src/features/parameters/components/Canvas/BoundingBox/ParamBoundingBoxHeight.tsx +++ b/invokeai/frontend/web/src/features/parameters/components/Canvas/BoundingBox/ParamBoundingBoxHeight.tsx @@ -2,21 +2,34 @@ import { useAppSelector } from 'app/store/storeHooks'; import { InvControl } from 'common/components/InvControl/InvControl'; import { InvSlider } from 'common/components/InvSlider/InvSlider'; import { isStagingSelector } from 'features/canvas/store/canvasSelectors'; -import { - CANVAS_GRID_SIZE_COARSE, - CANVAS_GRID_SIZE_FINE, -} from 'features/canvas/store/constants'; import { useImageSizeContext } from 'features/parameters/components/ImageSize/ImageSizeContext'; import { selectOptimalDimension } from 'features/parameters/store/generationSlice'; import { memo, useCallback } from 'react'; import { useTranslation } from 'react-i18next'; -const ParamBoundingBoxWidth = () => { - const isStaging = useAppSelector(isStagingSelector); - const initial = useAppSelector(selectOptimalDimension); - const ctx = useImageSizeContext(); +const ParamBoundingBoxHeight = () => { const { t } = useTranslation(); - + const ctx = useImageSizeContext(); + const isStaging = useAppSelector(isStagingSelector); + const optimalDimension = useAppSelector(selectOptimalDimension); + const sliderMin = useAppSelector( + (s) => s.config.sd.boundingBoxHeight.sliderMin + ); + const sliderMax = useAppSelector( + (s) => s.config.sd.boundingBoxHeight.sliderMax + ); + const numberInputMin = useAppSelector( + (s) => s.config.sd.boundingBoxHeight.numberInputMin + ); + const numberInputMax = useAppSelector( + (s) => s.config.sd.boundingBoxHeight.numberInputMax + ); + const coarseStep = useAppSelector( + (s) => s.config.sd.boundingBoxHeight.coarseStep + ); + const fineStep = useAppSelector( + (s) => s.config.sd.boundingBoxHeight.fineStep + ); const onChange = useCallback( (v: number) => { ctx.heightChanged(v); @@ -27,19 +40,20 @@ const ParamBoundingBoxWidth = () => { return ( ); }; -export default memo(ParamBoundingBoxWidth); +export default memo(ParamBoundingBoxHeight); diff --git a/invokeai/frontend/web/src/features/parameters/components/Canvas/BoundingBox/ParamBoundingBoxWidth.tsx b/invokeai/frontend/web/src/features/parameters/components/Canvas/BoundingBox/ParamBoundingBoxWidth.tsx index b0af01d67f..442b999ae0 100644 --- a/invokeai/frontend/web/src/features/parameters/components/Canvas/BoundingBox/ParamBoundingBoxWidth.tsx +++ b/invokeai/frontend/web/src/features/parameters/components/Canvas/BoundingBox/ParamBoundingBoxWidth.tsx @@ -2,21 +2,32 @@ import { useAppSelector } from 'app/store/storeHooks'; import { InvControl } from 'common/components/InvControl/InvControl'; import { InvSlider } from 'common/components/InvSlider/InvSlider'; import { isStagingSelector } from 'features/canvas/store/canvasSelectors'; -import { - CANVAS_GRID_SIZE_COARSE, - CANVAS_GRID_SIZE_FINE, -} from 'features/canvas/store/constants'; import { useImageSizeContext } from 'features/parameters/components/ImageSize/ImageSizeContext'; import { selectOptimalDimension } from 'features/parameters/store/generationSlice'; import { memo, useCallback } from 'react'; import { useTranslation } from 'react-i18next'; const ParamBoundingBoxWidth = () => { - const isStaging = useAppSelector(isStagingSelector); - const initial = useAppSelector(selectOptimalDimension); - const ctx = useImageSizeContext(); const { t } = useTranslation(); - + const ctx = useImageSizeContext(); + const isStaging = useAppSelector(isStagingSelector); + const optimalDimension = useAppSelector(selectOptimalDimension); + const sliderMin = useAppSelector( + (s) => s.config.sd.boundingBoxWidth.sliderMin + ); + const sliderMax = useAppSelector( + (s) => s.config.sd.boundingBoxWidth.sliderMax + ); + const numberInputMin = useAppSelector( + (s) => s.config.sd.boundingBoxWidth.numberInputMin + ); + const numberInputMax = useAppSelector( + (s) => s.config.sd.boundingBoxWidth.numberInputMax + ); + const coarseStep = useAppSelector( + (s) => s.config.sd.boundingBoxWidth.coarseStep + ); + const fineStep = useAppSelector((s) => s.config.sd.boundingBoxWidth.fineStep); const onChange = useCallback( (v: number) => { ctx.widthChanged(v); @@ -27,15 +38,16 @@ const ParamBoundingBoxWidth = () => { return ( diff --git a/invokeai/frontend/web/src/features/parameters/components/Canvas/Compositing/CoherencePass/ParamCanvasCoherenceSteps.tsx b/invokeai/frontend/web/src/features/parameters/components/Canvas/Compositing/CoherencePass/ParamCanvasCoherenceSteps.tsx index a8a79e6112..a8b6df44b7 100644 --- a/invokeai/frontend/web/src/features/parameters/components/Canvas/Compositing/CoherencePass/ParamCanvasCoherenceSteps.tsx +++ b/invokeai/frontend/web/src/features/parameters/components/Canvas/Compositing/CoherencePass/ParamCanvasCoherenceSteps.tsx @@ -10,6 +10,28 @@ const ParamCanvasCoherenceSteps = () => { const canvasCoherenceSteps = useAppSelector( (s) => s.generation.canvasCoherenceSteps ); + const initial = useAppSelector( + (s) => s.config.sd.canvasCoherenceSteps.initial + ); + const sliderMin = useAppSelector( + (s) => s.config.sd.canvasCoherenceSteps.sliderMin + ); + const sliderMax = useAppSelector( + (s) => s.config.sd.canvasCoherenceSteps.sliderMax + ); + const numberInputMin = useAppSelector( + (s) => s.config.sd.canvasCoherenceSteps.numberInputMin + ); + const numberInputMax = useAppSelector( + (s) => s.config.sd.canvasCoherenceSteps.numberInputMax + ); + const coarseStep = useAppSelector( + (s) => s.config.sd.canvasCoherenceSteps.coarseStep + ); + const fineStep = useAppSelector( + (s) => s.config.sd.canvasCoherenceSteps.fineStep + ); + const { t } = useTranslation(); const handleChange = useCallback( @@ -25,14 +47,16 @@ const ParamCanvasCoherenceSteps = () => { feature="compositingCoherenceSteps" > diff --git a/invokeai/frontend/web/src/features/parameters/components/Canvas/Compositing/MaskAdjustment/ParamMaskBlur.tsx b/invokeai/frontend/web/src/features/parameters/components/Canvas/Compositing/MaskAdjustment/ParamMaskBlur.tsx index 7a7086e9aa..2c22f5bf46 100644 --- a/invokeai/frontend/web/src/features/parameters/components/Canvas/Compositing/MaskAdjustment/ParamMaskBlur.tsx +++ b/invokeai/frontend/web/src/features/parameters/components/Canvas/Compositing/MaskAdjustment/ParamMaskBlur.tsx @@ -6,9 +6,20 @@ import { memo, useCallback } from 'react'; import { useTranslation } from 'react-i18next'; const ParamMaskBlur = () => { + const { t } = useTranslation(); const dispatch = useAppDispatch(); const maskBlur = useAppSelector((s) => s.generation.maskBlur); - const { t } = useTranslation(); + const initial = useAppSelector((s) => s.config.sd.maskBlur.initial); + const sliderMin = useAppSelector((s) => s.config.sd.maskBlur.sliderMin); + const sliderMax = useAppSelector((s) => s.config.sd.maskBlur.sliderMax); + const numberInputMin = useAppSelector( + (s) => s.config.sd.maskBlur.numberInputMin + ); + const numberInputMax = useAppSelector( + (s) => s.config.sd.maskBlur.numberInputMax + ); + const coarseStep = useAppSelector((s) => s.config.sd.maskBlur.coarseStep); + const fineStep = useAppSelector((s) => s.config.sd.maskBlur.fineStep); const handleChange = useCallback( (v: number) => { @@ -20,14 +31,17 @@ const ParamMaskBlur = () => { return ( ); diff --git a/invokeai/frontend/web/src/features/parameters/components/Canvas/InfillAndScaling/ParamInfillPatchmatchDownscaleSize.tsx b/invokeai/frontend/web/src/features/parameters/components/Canvas/InfillAndScaling/ParamInfillPatchmatchDownscaleSize.tsx index ddef55f3cc..7817d3b1ca 100644 --- a/invokeai/frontend/web/src/features/parameters/components/Canvas/InfillAndScaling/ParamInfillPatchmatchDownscaleSize.tsx +++ b/invokeai/frontend/web/src/features/parameters/components/Canvas/InfillAndScaling/ParamInfillPatchmatchDownscaleSize.tsx @@ -11,6 +11,27 @@ const ParamInfillPatchmatchDownscaleSize = () => { const infillPatchmatchDownscaleSize = useAppSelector( (s) => s.generation.infillPatchmatchDownscaleSize ); + const initial = useAppSelector( + (s) => s.config.sd.infillPatchmatchDownscaleSize.initial + ); + const sliderMin = useAppSelector( + (s) => s.config.sd.infillPatchmatchDownscaleSize.sliderMin + ); + const sliderMax = useAppSelector( + (s) => s.config.sd.infillPatchmatchDownscaleSize.sliderMax + ); + const numberInputMin = useAppSelector( + (s) => s.config.sd.infillPatchmatchDownscaleSize.numberInputMin + ); + const numberInputMax = useAppSelector( + (s) => s.config.sd.infillPatchmatchDownscaleSize.numberInputMax + ); + const coarseStep = useAppSelector( + (s) => s.config.sd.infillPatchmatchDownscaleSize.coarseStep + ); + const fineStep = useAppSelector( + (s) => s.config.sd.infillPatchmatchDownscaleSize.fineStep + ); const { t } = useTranslation(); @@ -27,12 +48,16 @@ const ParamInfillPatchmatchDownscaleSize = () => { label={t('parameters.patchmatchDownScaleSize')} > diff --git a/invokeai/frontend/web/src/features/parameters/components/Canvas/InfillAndScaling/ParamInfillTilesize.tsx b/invokeai/frontend/web/src/features/parameters/components/Canvas/InfillAndScaling/ParamInfillTilesize.tsx index 09c215036f..d0da0c99de 100644 --- a/invokeai/frontend/web/src/features/parameters/components/Canvas/InfillAndScaling/ParamInfillTilesize.tsx +++ b/invokeai/frontend/web/src/features/parameters/components/Canvas/InfillAndScaling/ParamInfillTilesize.tsx @@ -8,6 +8,20 @@ import { useTranslation } from 'react-i18next'; const ParamInfillTileSize = () => { const dispatch = useAppDispatch(); const infillTileSize = useAppSelector((s) => s.generation.infillTileSize); + const initial = useAppSelector((s) => s.config.sd.infillTileSize.initial); + const sliderMin = useAppSelector((s) => s.config.sd.infillTileSize.sliderMin); + const sliderMax = useAppSelector((s) => s.config.sd.infillTileSize.sliderMax); + const numberInputMin = useAppSelector( + (s) => s.config.sd.infillTileSize.numberInputMin + ); + const numberInputMax = useAppSelector( + (s) => s.config.sd.infillTileSize.numberInputMax + ); + const coarseStep = useAppSelector( + (s) => s.config.sd.infillTileSize.coarseStep + ); + const fineStep = useAppSelector((s) => s.config.sd.infillTileSize.fineStep); + const infillMethod = useAppSelector((s) => s.generation.infillMethod); const { t } = useTranslation(); @@ -25,12 +39,15 @@ const ParamInfillTileSize = () => { label={t('parameters.tileSize')} > diff --git a/invokeai/frontend/web/src/features/parameters/components/Canvas/InfillAndScaling/ParamScaledHeight.tsx b/invokeai/frontend/web/src/features/parameters/components/Canvas/InfillAndScaling/ParamScaledHeight.tsx index 68c4971e23..9a7c0e7c3d 100644 --- a/invokeai/frontend/web/src/features/parameters/components/Canvas/InfillAndScaling/ParamScaledHeight.tsx +++ b/invokeai/frontend/web/src/features/parameters/components/Canvas/InfillAndScaling/ParamScaledHeight.tsx @@ -2,15 +2,12 @@ import { useAppDispatch, useAppSelector } from 'app/store/storeHooks'; import { InvControl } from 'common/components/InvControl/InvControl'; import { InvSlider } from 'common/components/InvSlider/InvSlider'; import { setScaledBoundingBoxDimensions } from 'features/canvas/store/canvasSlice'; -import { - CANVAS_GRID_SIZE_COARSE, - CANVAS_GRID_SIZE_FINE, -} from 'features/canvas/store/constants'; import { selectOptimalDimension } from 'features/parameters/store/generationSlice'; import { memo, useCallback } from 'react'; import { useTranslation } from 'react-i18next'; const ParamScaledHeight = () => { + const { t } = useTranslation(); const dispatch = useAppDispatch(); const optimalDimension = useAppSelector(selectOptimalDimension); const isManual = useAppSelector( @@ -19,8 +16,24 @@ const ParamScaledHeight = () => { const height = useAppSelector( (s) => s.canvas.scaledBoundingBoxDimensions.height ); - - const { t } = useTranslation(); + const sliderMin = useAppSelector( + (s) => s.config.sd.scaledBoundingBoxHeight.sliderMin + ); + const sliderMax = useAppSelector( + (s) => s.config.sd.scaledBoundingBoxHeight.sliderMax + ); + const numberInputMin = useAppSelector( + (s) => s.config.sd.scaledBoundingBoxHeight.numberInputMin + ); + const numberInputMax = useAppSelector( + (s) => s.config.sd.scaledBoundingBoxHeight.numberInputMax + ); + const coarseStep = useAppSelector( + (s) => s.config.sd.scaledBoundingBoxHeight.coarseStep + ); + const fineStep = useAppSelector( + (s) => s.config.sd.scaledBoundingBoxHeight.fineStep + ); const onChange = useCallback( (height: number) => { @@ -29,23 +42,20 @@ const ParamScaledHeight = () => { [dispatch] ); - const onReset = useCallback(() => { - dispatch(setScaledBoundingBoxDimensions({ height: optimalDimension })); - }, [dispatch, optimalDimension]); - return ( ); diff --git a/invokeai/frontend/web/src/features/parameters/components/Canvas/InfillAndScaling/ParamScaledWidth.tsx b/invokeai/frontend/web/src/features/parameters/components/Canvas/InfillAndScaling/ParamScaledWidth.tsx index 0b23cb127d..3c0fef3204 100644 --- a/invokeai/frontend/web/src/features/parameters/components/Canvas/InfillAndScaling/ParamScaledWidth.tsx +++ b/invokeai/frontend/web/src/features/parameters/components/Canvas/InfillAndScaling/ParamScaledWidth.tsx @@ -2,17 +2,13 @@ import { useAppDispatch, useAppSelector } from 'app/store/storeHooks'; import { InvControl } from 'common/components/InvControl/InvControl'; import { InvSlider } from 'common/components/InvSlider/InvSlider'; import { setScaledBoundingBoxDimensions } from 'features/canvas/store/canvasSlice'; -import { - CANVAS_GRID_SIZE_COARSE, - CANVAS_GRID_SIZE_FINE, -} from 'features/canvas/store/constants'; import { selectOptimalDimension } from 'features/parameters/store/generationSlice'; import { memo, useCallback } from 'react'; import { useTranslation } from 'react-i18next'; const ParamScaledWidth = () => { - const dispatch = useAppDispatch(); const { t } = useTranslation(); + const dispatch = useAppDispatch(); const optimalDimension = useAppSelector(selectOptimalDimension); const isManual = useAppSelector( (s) => s.canvas.boundingBoxScaleMethod === 'manual' @@ -20,7 +16,24 @@ const ParamScaledWidth = () => { const width = useAppSelector( (s) => s.canvas.scaledBoundingBoxDimensions.width ); - + const sliderMin = useAppSelector( + (s) => s.config.sd.scaledBoundingBoxWidth.sliderMin + ); + const sliderMax = useAppSelector( + (s) => s.config.sd.scaledBoundingBoxWidth.sliderMax + ); + const numberInputMin = useAppSelector( + (s) => s.config.sd.scaledBoundingBoxWidth.numberInputMin + ); + const numberInputMax = useAppSelector( + (s) => s.config.sd.scaledBoundingBoxWidth.numberInputMax + ); + const coarseStep = useAppSelector( + (s) => s.config.sd.scaledBoundingBoxWidth.coarseStep + ); + const fineStep = useAppSelector( + (s) => s.config.sd.scaledBoundingBoxWidth.fineStep + ); const onChange = useCallback( (width: number) => { dispatch(setScaledBoundingBoxDimensions({ width })); @@ -28,23 +41,20 @@ const ParamScaledWidth = () => { [dispatch] ); - const onReset = useCallback(() => { - dispatch(setScaledBoundingBoxDimensions({ width: optimalDimension })); - }, [dispatch, optimalDimension]); - return ( ); diff --git a/invokeai/frontend/web/src/features/parameters/components/Core/ParamCFGScale.tsx b/invokeai/frontend/web/src/features/parameters/components/Core/ParamCFGScale.tsx index 07b0d5931c..e4d73d42b8 100644 --- a/invokeai/frontend/web/src/features/parameters/components/Core/ParamCFGScale.tsx +++ b/invokeai/frontend/web/src/features/parameters/components/Core/ParamCFGScale.tsx @@ -7,17 +7,22 @@ import { useTranslation } from 'react-i18next'; const ParamCFGScale = () => { const cfgScale = useAppSelector((s) => s.generation.cfgScale); - const min = useAppSelector((s) => s.config.sd.guidance.min); - const inputMax = useAppSelector((s) => s.config.sd.guidance.inputMax); + const sliderMin = useAppSelector((s) => s.config.sd.guidance.sliderMin); const sliderMax = useAppSelector((s) => s.config.sd.guidance.sliderMax); + const numberInputMin = useAppSelector( + (s) => s.config.sd.guidance.numberInputMin + ); + const numberInputMax = useAppSelector( + (s) => s.config.sd.guidance.numberInputMax + ); const coarseStep = useAppSelector((s) => s.config.sd.guidance.coarseStep); const fineStep = useAppSelector((s) => s.config.sd.guidance.fineStep); const initial = useAppSelector((s) => s.config.sd.guidance.initial); const dispatch = useAppDispatch(); const { t } = useTranslation(); const marks = useMemo( - () => [min, Math.floor(sliderMax / 2), sliderMax], - [sliderMax, min] + () => [sliderMin, Math.floor(sliderMax / 2), sliderMax], + [sliderMax, sliderMin] ); const onChange = useCallback( (v: number) => dispatch(setCfgScale(v)), @@ -29,14 +34,15 @@ const ParamCFGScale = () => { ); diff --git a/invokeai/frontend/web/src/features/parameters/components/Core/ParamHeight.tsx b/invokeai/frontend/web/src/features/parameters/components/Core/ParamHeight.tsx index 9d46c5845b..9c4914416d 100644 --- a/invokeai/frontend/web/src/features/parameters/components/Core/ParamHeight.tsx +++ b/invokeai/frontend/web/src/features/parameters/components/Core/ParamHeight.tsx @@ -1,6 +1,5 @@ import { useAppSelector } from 'app/store/storeHooks'; import { InvControl } from 'common/components/InvControl/InvControl'; -import { InvNumberInput } from 'common/components/InvNumberInput/InvNumberInput'; import { InvSlider } from 'common/components/InvSlider/InvSlider'; import { useImageSizeContext } from 'features/parameters/components/ImageSize/ImageSizeContext'; import { selectOptimalDimension } from 'features/parameters/store/generationSlice'; @@ -11,9 +10,14 @@ export const ParamHeight = memo(() => { const { t } = useTranslation(); const ctx = useImageSizeContext(); const optimalDimension = useAppSelector(selectOptimalDimension); - const min = useAppSelector((s) => s.config.sd.height.min); + const sliderMin = useAppSelector((s) => s.config.sd.height.sliderMin); const sliderMax = useAppSelector((s) => s.config.sd.height.sliderMax); - const inputMax = useAppSelector((s) => s.config.sd.height.inputMax); + const numberInputMin = useAppSelector( + (s) => s.config.sd.height.numberInputMin + ); + const numberInputMax = useAppSelector( + (s) => s.config.sd.height.numberInputMax + ); const coarseStep = useAppSelector((s) => s.config.sd.height.coarseStep); const fineStep = useAppSelector((s) => s.config.sd.height.fineStep); @@ -25,8 +29,8 @@ export const ParamHeight = memo(() => { ); const marks = useMemo( - () => [min, optimalDimension, sliderMax], - [min, optimalDimension, sliderMax] + () => [sliderMin, optimalDimension, sliderMax], + [sliderMin, optimalDimension, sliderMax] ); return ( @@ -35,20 +39,14 @@ export const ParamHeight = memo(() => { value={ctx.height} defaultValue={optimalDimension} onChange={onChange} - min={min} + min={sliderMin} max={sliderMax} step={coarseStep} fineStep={fineStep} marks={marks} - /> - ); diff --git a/invokeai/frontend/web/src/features/parameters/components/Core/ParamSteps.tsx b/invokeai/frontend/web/src/features/parameters/components/Core/ParamSteps.tsx index f79113e998..961d4502d3 100644 --- a/invokeai/frontend/web/src/features/parameters/components/Core/ParamSteps.tsx +++ b/invokeai/frontend/web/src/features/parameters/components/Core/ParamSteps.tsx @@ -1,26 +1,28 @@ import { useAppDispatch, useAppSelector } from 'app/store/storeHooks'; import { InvControl } from 'common/components/InvControl/InvControl'; import { InvSlider } from 'common/components/InvSlider/InvSlider'; -import { - clampSymmetrySteps, - setSteps, -} from 'features/parameters/store/generationSlice'; +import { setSteps } from 'features/parameters/store/generationSlice'; import { memo, useCallback, useMemo } from 'react'; import { useTranslation } from 'react-i18next'; const ParamSteps = () => { const steps = useAppSelector((s) => s.generation.steps); const initial = useAppSelector((s) => s.config.sd.steps.initial); - const min = useAppSelector((s) => s.config.sd.steps.min); + const sliderMin = useAppSelector((s) => s.config.sd.steps.sliderMin); const sliderMax = useAppSelector((s) => s.config.sd.steps.sliderMax); - const inputMax = useAppSelector((s) => s.config.sd.steps.inputMax); + 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( - () => [min, Math.floor(sliderMax / 2), sliderMax], - [sliderMax, min] + () => [sliderMin, Math.floor(sliderMax / 2), sliderMax], + [sliderMax, sliderMin] ); const onChange = useCallback( (v: number) => { @@ -29,24 +31,20 @@ const ParamSteps = () => { [dispatch] ); - const onBlur = useCallback(() => { - dispatch(clampSymmetrySteps()); - }, [dispatch]); - return ( ); diff --git a/invokeai/frontend/web/src/features/parameters/components/Core/ParamWidth.tsx b/invokeai/frontend/web/src/features/parameters/components/Core/ParamWidth.tsx index 99537a668f..889f3777df 100644 --- a/invokeai/frontend/web/src/features/parameters/components/Core/ParamWidth.tsx +++ b/invokeai/frontend/web/src/features/parameters/components/Core/ParamWidth.tsx @@ -1,6 +1,5 @@ import { useAppSelector } from 'app/store/storeHooks'; import { InvControl } from 'common/components/InvControl/InvControl'; -import { InvNumberInput } from 'common/components/InvNumberInput/InvNumberInput'; import { InvSlider } from 'common/components/InvSlider/InvSlider'; import { useImageSizeContext } from 'features/parameters/components/ImageSize/ImageSizeContext'; import { selectOptimalDimension } from 'features/parameters/store/generationSlice'; @@ -11,9 +10,14 @@ export const ParamWidth = memo(() => { const { t } = useTranslation(); const ctx = useImageSizeContext(); const optimalDimension = useAppSelector(selectOptimalDimension); - const min = useAppSelector((s) => s.config.sd.width.min); + const sliderMin = useAppSelector((s) => s.config.sd.width.sliderMin); const sliderMax = useAppSelector((s) => s.config.sd.width.sliderMax); - const inputMax = useAppSelector((s) => s.config.sd.width.inputMax); + const numberInputMin = useAppSelector( + (s) => s.config.sd.width.numberInputMin + ); + const numberInputMax = useAppSelector( + (s) => s.config.sd.width.numberInputMax + ); const coarseStep = useAppSelector((s) => s.config.sd.width.coarseStep); const fineStep = useAppSelector((s) => s.config.sd.width.fineStep); @@ -25,8 +29,8 @@ export const ParamWidth = memo(() => { ); const marks = useMemo( - () => [min, optimalDimension, sliderMax], - [min, optimalDimension, sliderMax] + () => [sliderMin, optimalDimension, sliderMax], + [sliderMin, optimalDimension, sliderMax] ); return ( @@ -35,20 +39,14 @@ export const ParamWidth = memo(() => { value={ctx.width} onChange={onChange} defaultValue={optimalDimension} - min={min} + min={sliderMin} max={sliderMax} step={coarseStep} fineStep={fineStep} marks={marks} - /> - ); diff --git a/invokeai/frontend/web/src/features/parameters/components/ImageToImage/ImageToImageStrength.tsx b/invokeai/frontend/web/src/features/parameters/components/ImageToImage/ImageToImageStrength.tsx index b7d211da29..b661cc051f 100644 --- a/invokeai/frontend/web/src/features/parameters/components/ImageToImage/ImageToImageStrength.tsx +++ b/invokeai/frontend/web/src/features/parameters/components/ImageToImage/ImageToImageStrength.tsx @@ -10,11 +10,18 @@ const marks = [0, 0.5, 1]; const ImageToImageStrength = () => { const img2imgStrength = useAppSelector((s) => s.generation.img2imgStrength); const initial = useAppSelector((s) => s.config.sd.img2imgStrength.initial); - const min = useAppSelector((s) => s.config.sd.img2imgStrength.min); + const sliderMin = useAppSelector( + (s) => s.config.sd.img2imgStrength.sliderMin + ); const sliderMax = useAppSelector( (s) => s.config.sd.img2imgStrength.sliderMax ); - const inputMax = useAppSelector((s) => s.config.sd.img2imgStrength.inputMax); + const numberInputMin = useAppSelector( + (s) => s.config.sd.img2imgStrength.numberInputMin + ); + const numberInputMax = useAppSelector( + (s) => s.config.sd.img2imgStrength.numberInputMax + ); const coarseStep = useAppSelector( (s) => s.config.sd.img2imgStrength.coarseStep ); @@ -35,14 +42,15 @@ const ImageToImageStrength = () => { ); diff --git a/invokeai/frontend/web/src/features/parameters/components/Symmetry/ParamSymmetryHorizontal.tsx b/invokeai/frontend/web/src/features/parameters/components/Symmetry/ParamSymmetryHorizontal.tsx deleted file mode 100644 index c4daf8a366..0000000000 --- a/invokeai/frontend/web/src/features/parameters/components/Symmetry/ParamSymmetryHorizontal.tsx +++ /dev/null @@ -1,42 +0,0 @@ -import { useAppDispatch, useAppSelector } from 'app/store/storeHooks'; -import { InvControl } from 'common/components/InvControl/InvControl'; -import { InvSlider } from 'common/components/InvSlider/InvSlider'; -import { setHorizontalSymmetrySteps } from 'features/parameters/store/generationSlice'; -import { memo, useCallback } from 'react'; -import { useTranslation } from 'react-i18next'; - -const ParamSymmetryHorizontal = () => { - const horizontalSymmetrySteps = useAppSelector( - (s) => s.generation.horizontalSymmetrySteps - ); - - const steps = useAppSelector((s) => s.generation.steps); - - const dispatch = useAppDispatch(); - - const { t } = useTranslation(); - - const handleChange = useCallback( - (v: number) => { - dispatch(setHorizontalSymmetrySteps(v)); - }, - [dispatch] - ); - - return ( - - - - ); -}; - -export default memo(ParamSymmetryHorizontal); diff --git a/invokeai/frontend/web/src/features/parameters/components/Symmetry/ParamSymmetryToggle.tsx b/invokeai/frontend/web/src/features/parameters/components/Symmetry/ParamSymmetryToggle.tsx deleted file mode 100644 index e408af90e5..0000000000 --- a/invokeai/frontend/web/src/features/parameters/components/Symmetry/ParamSymmetryToggle.tsx +++ /dev/null @@ -1,28 +0,0 @@ -import { useAppDispatch, useAppSelector } from 'app/store/storeHooks'; -import { InvControl } from 'common/components/InvControl/InvControl'; -import { InvSwitch } from 'common/components/InvSwitch/wrapper'; -import { setShouldUseSymmetry } from 'features/parameters/store/generationSlice'; -import type { ChangeEvent } from 'react'; -import { memo, useCallback } from 'react'; - -const ParamSymmetryToggle = () => { - const shouldUseSymmetry = useAppSelector( - (s) => s.generation.shouldUseSymmetry - ); - - const dispatch = useAppDispatch(); - const handleChange = useCallback( - (e: ChangeEvent) => { - dispatch(setShouldUseSymmetry(e.target.checked)); - }, - [dispatch] - ); - - return ( - - - - ); -}; - -export default memo(ParamSymmetryToggle); diff --git a/invokeai/frontend/web/src/features/parameters/components/Symmetry/ParamSymmetryVertical.tsx b/invokeai/frontend/web/src/features/parameters/components/Symmetry/ParamSymmetryVertical.tsx deleted file mode 100644 index f6f2dc150d..0000000000 --- a/invokeai/frontend/web/src/features/parameters/components/Symmetry/ParamSymmetryVertical.tsx +++ /dev/null @@ -1,42 +0,0 @@ -import { useAppDispatch, useAppSelector } from 'app/store/storeHooks'; -import { InvControl } from 'common/components/InvControl/InvControl'; -import { InvSlider } from 'common/components/InvSlider/InvSlider'; -import { setVerticalSymmetrySteps } from 'features/parameters/store/generationSlice'; -import { memo, useCallback } from 'react'; -import { useTranslation } from 'react-i18next'; - -const ParamSymmetryVertical = () => { - const verticalSymmetrySteps = useAppSelector( - (s) => s.generation.verticalSymmetrySteps - ); - - const steps = useAppSelector((s) => s.generation.steps); - - const dispatch = useAppDispatch(); - - const { t } = useTranslation(); - - const handleChange = useCallback( - (v: number) => { - dispatch(setVerticalSymmetrySteps(v)); - }, - [dispatch] - ); - - return ( - - - - ); -}; - -export default memo(ParamSymmetryVertical); diff --git a/invokeai/frontend/web/src/features/parameters/store/generationSlice.ts b/invokeai/frontend/web/src/features/parameters/store/generationSlice.ts index 8efad67954..0c97e16e21 100644 --- a/invokeai/frontend/web/src/features/parameters/store/generationSlice.ts +++ b/invokeai/frontend/web/src/features/parameters/store/generationSlice.ts @@ -35,7 +35,6 @@ export const initialGenerationState: GenerationState = { img2imgStrength: 0.75, infillMethod: 'patchmatch', iterations: 1, - perlin: 0, positivePrompt: '', negativePrompt: '', scheduler: 'euler', @@ -45,19 +44,12 @@ export const initialGenerationState: GenerationState = { canvasCoherenceSteps: 20, canvasCoherenceStrength: 0.3, seed: 0, - seedWeights: '', shouldFitToWidthHeight: true, - shouldGenerateVariations: false, shouldRandomizeSeed: true, steps: 50, - threshold: 0, infillTileSize: 32, infillPatchmatchDownscaleSize: 1, - variationAmount: 0.1, width: 512, - shouldUseSymmetry: false, - horizontalSymmetrySteps: 0, - verticalSymmetrySteps: 0, model: null, vae: null, vaePrecision: 'fp32', @@ -85,18 +77,6 @@ export const generationSlice = createSlice({ setSteps: (state, action: PayloadAction) => { state.steps = action.payload; }, - clampSymmetrySteps: (state) => { - state.horizontalSymmetrySteps = clamp( - state.horizontalSymmetrySteps, - 0, - state.steps - ); - state.verticalSymmetrySteps = clamp( - state.verticalSymmetrySteps, - 0, - state.steps - ); - }, setCfgScale: (state, action: PayloadAction) => { state.cfgScale = action.payload; }, @@ -106,12 +86,6 @@ export const generationSlice = createSlice({ ) => { state.cfgRescaleMultiplier = action.payload; }, - setThreshold: (state, action: PayloadAction) => { - state.threshold = action.payload; - }, - setPerlin: (state, action: PayloadAction) => { - state.perlin = action.payload; - }, setScheduler: (state, action: PayloadAction) => { state.scheduler = action.payload; }, @@ -134,17 +108,6 @@ export const generationSlice = createSlice({ resetSeed: (state) => { state.seed = -1; }, - setShouldGenerateVariations: (state, action: PayloadAction) => { - state.shouldGenerateVariations = action.payload; - }, - setVariationAmount: (state, action: PayloadAction) => { - state.variationAmount = action.payload; - }, - setSeedWeights: (state, action: PayloadAction) => { - state.seedWeights = action.payload; - state.shouldGenerateVariations = true; - state.variationAmount = 0; - }, resetParametersState: (state) => { return { ...state, @@ -190,15 +153,6 @@ export const generationSlice = createSlice({ ) => { state.infillPatchmatchDownscaleSize = action.payload; }, - setShouldUseSymmetry: (state, action: PayloadAction) => { - state.shouldUseSymmetry = action.payload; - }, - setHorizontalSymmetrySteps: (state, action: PayloadAction) => { - state.horizontalSymmetrySteps = action.payload; - }, - setVerticalSymmetrySteps: (state, action: PayloadAction) => { - state.verticalSymmetrySteps = action.payload; - }, initialImageChanged: (state, action: PayloadAction) => { const { image_name, width, height } = action.payload; state.initialImage = { imageName: image_name, width, height }; @@ -282,7 +236,6 @@ export const generationSlice = createSlice({ }); export const { - clampSymmetrySteps, clearInitialImage, resetParametersState, resetSeed, @@ -291,7 +244,6 @@ export const { setImg2imgStrength, setInfillMethod, setIterations, - setPerlin, setPositivePrompt, setNegativePrompt, setScheduler, @@ -301,18 +253,11 @@ export const { setCanvasCoherenceSteps, setCanvasCoherenceStrength, setSeed, - setSeedWeights, setShouldFitToWidthHeight, - setShouldGenerateVariations, setShouldRandomizeSeed, setSteps, - setThreshold, setInfillTileSize, setInfillPatchmatchDownscaleSize, - setVariationAmount, - setShouldUseSymmetry, - setHorizontalSymmetrySteps, - setVerticalSymmetrySteps, initialImageChanged, modelChanged, vaeSelected, diff --git a/invokeai/frontend/web/src/features/parameters/store/types.ts b/invokeai/frontend/web/src/features/parameters/store/types.ts index cd42fb1340..118e91bbe1 100644 --- a/invokeai/frontend/web/src/features/parameters/store/types.ts +++ b/invokeai/frontend/web/src/features/parameters/store/types.ts @@ -26,7 +26,6 @@ export interface GenerationState { infillMethod: string; initialImage?: { imageName: string; width: number; height: number }; iterations: number; - perlin: number; positivePrompt: ParameterPositivePrompt; negativePrompt: ParameterNegativePrompt; scheduler: ParameterScheduler; @@ -36,19 +35,12 @@ export interface GenerationState { canvasCoherenceSteps: number; canvasCoherenceStrength: ParameterStrength; seed: ParameterSeed; - seedWeights: string; shouldFitToWidthHeight: boolean; - shouldGenerateVariations: boolean; shouldRandomizeSeed: boolean; steps: ParameterSteps; - threshold: number; infillTileSize: number; infillPatchmatchDownscaleSize: number; - variationAmount: number; width: ParameterWidth; - shouldUseSymmetry: boolean; - horizontalSymmetrySteps: number; - verticalSymmetrySteps: number; model: ParameterModel | null; vae: ParameterVAEModel | null; vaePrecision: ParameterPrecision; diff --git a/invokeai/frontend/web/src/features/queue/hooks/useQueueBack.ts b/invokeai/frontend/web/src/features/queue/hooks/useQueueBack.ts index 0a2582f56b..7698372584 100644 --- a/invokeai/frontend/web/src/features/queue/hooks/useQueueBack.ts +++ b/invokeai/frontend/web/src/features/queue/hooks/useQueueBack.ts @@ -1,7 +1,6 @@ import { enqueueRequested } from 'app/store/actions'; import { useAppDispatch, useAppSelector } from 'app/store/storeHooks'; import { useIsReadyToEnqueue } from 'common/hooks/useIsReadyToEnqueue'; -import { clampSymmetrySteps } from 'features/parameters/store/generationSlice'; import { activeTabNameSelector } from 'features/ui/store/uiSelectors'; import { useCallback, useMemo } from 'react'; import { useEnqueueBatchMutation } from 'services/api/endpoints/queue'; @@ -18,7 +17,6 @@ export const useQueueBack = () => { if (isDisabled) { return; } - dispatch(clampSymmetrySteps()); dispatch(enqueueRequested({ tabName, prepend: false })); }, [dispatch, isDisabled, tabName]); diff --git a/invokeai/frontend/web/src/features/queue/hooks/useQueueFront.ts b/invokeai/frontend/web/src/features/queue/hooks/useQueueFront.ts index ddc8d16c58..d39ac96566 100644 --- a/invokeai/frontend/web/src/features/queue/hooks/useQueueFront.ts +++ b/invokeai/frontend/web/src/features/queue/hooks/useQueueFront.ts @@ -1,7 +1,6 @@ import { enqueueRequested } from 'app/store/actions'; import { useAppDispatch, useAppSelector } from 'app/store/storeHooks'; import { useIsReadyToEnqueue } from 'common/hooks/useIsReadyToEnqueue'; -import { clampSymmetrySteps } from 'features/parameters/store/generationSlice'; import { useFeatureStatus } from 'features/system/hooks/useFeatureStatus'; import { activeTabNameSelector } from 'features/ui/store/uiSelectors'; import { useCallback, useMemo } from 'react'; @@ -24,7 +23,6 @@ export const useQueueFront = () => { if (isDisabled) { return; } - dispatch(clampSymmetrySteps()); dispatch(enqueueRequested({ tabName, prepend: true })); }, [dispatch, isDisabled, tabName]); diff --git a/invokeai/frontend/web/src/features/sdxl/components/SDXLRefiner/ParamSDXLRefinerCFGScale.tsx b/invokeai/frontend/web/src/features/sdxl/components/SDXLRefiner/ParamSDXLRefinerCFGScale.tsx index 56cbcf8e1b..c60d77458c 100644 --- a/invokeai/frontend/web/src/features/sdxl/components/SDXLRefiner/ParamSDXLRefinerCFGScale.tsx +++ b/invokeai/frontend/web/src/features/sdxl/components/SDXLRefiner/ParamSDXLRefinerCFGScale.tsx @@ -9,15 +9,20 @@ const ParamSDXLRefinerCFGScale = () => { const { t } = useTranslation(); const dispatch = useAppDispatch(); const refinerCFGScale = useAppSelector((s) => s.sdxl.refinerCFGScale); - const min = useAppSelector((s) => s.config.sd.guidance.min); - const inputMax = useAppSelector((s) => s.config.sd.guidance.inputMax); + const sliderMin = useAppSelector((s) => s.config.sd.guidance.sliderMin); const sliderMax = useAppSelector((s) => s.config.sd.guidance.sliderMax); + const numberInputMin = useAppSelector( + (s) => s.config.sd.guidance.numberInputMin + ); + const numberInputMax = useAppSelector( + (s) => s.config.sd.guidance.numberInputMax + ); const coarseStep = useAppSelector((s) => s.config.sd.guidance.coarseStep); const fineStep = useAppSelector((s) => s.config.sd.guidance.fineStep); const initial = useAppSelector((s) => s.config.sd.guidance.initial); const marks = useMemo( - () => [min, Math.floor(sliderMax / 2), sliderMax], - [sliderMax, min] + () => [sliderMin, Math.floor(sliderMax / 2), sliderMax], + [sliderMax, sliderMin] ); const onChange = useCallback( @@ -30,13 +35,14 @@ const ParamSDXLRefinerCFGScale = () => { diff --git a/invokeai/frontend/web/src/features/sdxl/components/SDXLRefiner/ParamSDXLRefinerSteps.tsx b/invokeai/frontend/web/src/features/sdxl/components/SDXLRefiner/ParamSDXLRefinerSteps.tsx index 9d6180fa54..a787d7e328 100644 --- a/invokeai/frontend/web/src/features/sdxl/components/SDXLRefiner/ParamSDXLRefinerSteps.tsx +++ b/invokeai/frontend/web/src/features/sdxl/components/SDXLRefiner/ParamSDXLRefinerSteps.tsx @@ -10,15 +10,20 @@ const ParamSDXLRefinerSteps = () => { const dispatch = useAppDispatch(); const refinerSteps = useAppSelector((s) => s.sdxl.refinerSteps); const initial = useAppSelector((s) => s.config.sd.steps.initial); - const min = useAppSelector((s) => s.config.sd.steps.min); + const sliderMin = useAppSelector((s) => s.config.sd.steps.sliderMin); const sliderMax = useAppSelector((s) => s.config.sd.steps.sliderMax); - const inputMax = useAppSelector((s) => s.config.sd.steps.inputMax); + 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 marks = useMemo( - () => [min, Math.floor(sliderMax / 2), sliderMax], - [sliderMax, min] + () => [sliderMin, Math.floor(sliderMax / 2), sliderMax], + [sliderMax, sliderMin] ); const onChange = useCallback( @@ -33,14 +38,15 @@ const ParamSDXLRefinerSteps = () => { ); diff --git a/invokeai/frontend/web/src/features/system/store/configSlice.ts b/invokeai/frontend/web/src/features/system/store/configSlice.ts index 3264883c2b..fad698ef51 100644 --- a/invokeai/frontend/web/src/features/system/store/configSlice.ts +++ b/invokeai/frontend/web/src/features/system/store/configSlice.ts @@ -1,9 +1,23 @@ import type { PayloadAction } from '@reduxjs/toolkit'; import { createSlice } from '@reduxjs/toolkit'; import type { RootState } from 'app/store/store'; -import type { AppConfig, PartialAppConfig } from 'app/types/invokeai'; +import type { + AppConfig, + NumericalParameterConfig, + PartialAppConfig, +} from 'app/types/invokeai'; import { merge } from 'lodash-es'; +const baseDimensionConfig: NumericalParameterConfig = { + initial: 512, // determined by model selection, unused in practice + sliderMin: 64, + sliderMax: 1536, + numberInputMin: 64, + numberInputMax: 4096, + fineStep: 8, + coarseStep: 64, +}; + export const initialConfigState: AppConfig = { shouldUpdateImagesOnConnect: false, shouldFetchMetadataFromApi: false, @@ -24,66 +38,138 @@ export const initialConfigState: AppConfig = { disabledControlNetProcessors: [], iterations: { initial: 1, - min: 1, + sliderMin: 1, sliderMax: 1000, - inputMax: 10000, + numberInputMin: 1, + numberInputMax: 10000, fineStep: 1, coarseStep: 1, }, - width: { - initial: 512, - min: 64, - sliderMax: 1536, - inputMax: 4096, - fineStep: 8, - coarseStep: 64, - }, - height: { - initial: 512, - min: 64, - sliderMax: 1536, - inputMax: 4096, - fineStep: 8, - coarseStep: 64, - }, + width: { ...baseDimensionConfig }, + height: { ...baseDimensionConfig }, + boundingBoxWidth: { ...baseDimensionConfig }, + boundingBoxHeight: { ...baseDimensionConfig }, + scaledBoundingBoxWidth: { ...baseDimensionConfig }, + scaledBoundingBoxHeight: { ...baseDimensionConfig }, steps: { initial: 30, - min: 1, + sliderMin: 1, sliderMax: 100, - inputMax: 500, + numberInputMin: 1, + numberInputMax: 500, fineStep: 1, coarseStep: 1, }, guidance: { initial: 7, - min: 1, + sliderMin: 1, sliderMax: 20, - inputMax: 200, + numberInputMin: 1, + numberInputMax: 200, fineStep: 0.1, coarseStep: 0.5, }, img2imgStrength: { initial: 0.7, - min: 0, + sliderMin: 0, sliderMax: 1, - inputMax: 1, + numberInputMin: 0, + numberInputMax: 1, + fineStep: 0.01, + coarseStep: 0.05, + }, + canvasCoherenceStrength: { + initial: 0.3, + sliderMin: 0, + sliderMax: 1, + numberInputMin: 0, + numberInputMax: 1, fineStep: 0.01, coarseStep: 0.05, }, hrfStrength: { initial: 0.45, - min: 0, + sliderMin: 0, sliderMax: 1, - inputMax: 1, + numberInputMin: 0, + numberInputMax: 1, fineStep: 0.01, coarseStep: 0.05, }, + canvasCoherenceSteps: { + initial: 20, + sliderMin: 1, + sliderMax: 100, + numberInputMin: 1, + numberInputMax: 999, + fineStep: 1, + coarseStep: 1, + }, + cfgRescaleMultiplier: { + initial: 0, + sliderMin: 0, + sliderMax: 0.99, + numberInputMin: 0, + numberInputMax: 0.99, + fineStep: 0.05, + coarseStep: 0.1, + }, + clipSkip: { + initial: 0, + sliderMin: 0, + sliderMax: 12, // determined by model selection, unused in practice + numberInputMin: 0, + numberInputMax: 12, // determined by model selection, unused in practice + fineStep: 1, + coarseStep: 1, + }, + infillPatchmatchDownscaleSize: { + initial: 1, + sliderMin: 1, + sliderMax: 10, + numberInputMin: 1, + numberInputMax: 10, + fineStep: 1, + coarseStep: 1, + }, + infillTileSize: { + initial: 32, + sliderMin: 16, + sliderMax: 64, + numberInputMin: 16, + numberInputMax: 256, + fineStep: 1, + coarseStep: 1, + }, + maskBlur: { + initial: 16, + sliderMin: 0, + sliderMax: 64, + numberInputMin: 0, + numberInputMax: 512, + fineStep: 1, + coarseStep: 1, + }, + ca: { + weight: { + initial: 1, + sliderMin: 0, + sliderMax: 2, + numberInputMin: -1, + numberInputMax: 2, + fineStep: 0.01, + coarseStep: 0.05, + }, + }, dynamicPrompts: { maxPrompts: { initial: 100, - min: 1, + sliderMin: 1, sliderMax: 1000, - inputMax: 10000, + numberInputMin: 1, + numberInputMax: 10000, + fineStep: 1, + coarseStep: 10, }, }, },