Merge branch 'main' into sdxl-support

This commit is contained in:
Lincoln Stein 2023-07-10 18:51:03 -04:00 committed by GitHub
commit d8ebbd258a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 233 additions and 99 deletions

View File

@ -1,22 +1,16 @@
import sqlite3
import threading
from abc import ABC, abstractmethod from abc import ABC, abstractmethod
from datetime import datetime from datetime import datetime
from typing import Generic, Optional, TypeVar, cast from typing import Generic, Optional, TypeVar, cast
import sqlite3
import threading
from pydantic import BaseModel, Field from pydantic import BaseModel, Field
from pydantic.generics import GenericModel from pydantic.generics import GenericModel
from invokeai.app.models.image import ImageCategory, ResourceOrigin
from invokeai.app.models.metadata import ImageMetadata from invokeai.app.models.metadata import ImageMetadata
from invokeai.app.models.image import (
ImageCategory,
ResourceOrigin,
)
from invokeai.app.services.models.image_record import ( from invokeai.app.services.models.image_record import (
ImageRecord, ImageRecord, ImageRecordChanges, deserialize_image_record)
ImageRecordChanges,
deserialize_image_record,
)
T = TypeVar("T", bound=BaseModel) T = TypeVar("T", bound=BaseModel)
@ -162,7 +156,6 @@ class SqliteImageRecordStorage(ImageRecordStorageBase):
node_id TEXT, node_id TEXT,
metadata TEXT, metadata TEXT,
is_intermediate BOOLEAN DEFAULT FALSE, is_intermediate BOOLEAN DEFAULT FALSE,
board_id TEXT,
created_at DATETIME NOT NULL DEFAULT(STRFTIME('%Y-%m-%d %H:%M:%f', 'NOW')), created_at DATETIME NOT NULL DEFAULT(STRFTIME('%Y-%m-%d %H:%M:%f', 'NOW')),
-- Updated via trigger -- Updated via trigger
updated_at DATETIME NOT NULL DEFAULT(STRFTIME('%Y-%m-%d %H:%M:%f', 'NOW')), updated_at DATETIME NOT NULL DEFAULT(STRFTIME('%Y-%m-%d %H:%M:%f', 'NOW')),

View File

@ -528,7 +528,8 @@
"hidePreview": "Hide Preview", "hidePreview": "Hide Preview",
"showPreview": "Show Preview", "showPreview": "Show Preview",
"controlNetControlMode": "Control Mode", "controlNetControlMode": "Control Mode",
"clipSkip": "Clip Skip" "clipSkip": "Clip Skip",
"aspectRatio": "Ratio"
}, },
"settings": { "settings": {
"models": "Models", "models": "Models",
@ -671,6 +672,7 @@
}, },
"ui": { "ui": {
"showProgressImages": "Show Progress Images", "showProgressImages": "Show Progress Images",
"hideProgressImages": "Hide Progress Images" "hideProgressImages": "Hide Progress Images",
"swapSizes": "Swap Sizes"
} }
} }

View File

@ -53,13 +53,15 @@ const GalleryImage = (props: HoverableImageProps) => {
const handleClick = useCallback( const handleClick = useCallback(
(e: MouseEvent<HTMLDivElement>) => { (e: MouseEvent<HTMLDivElement>) => {
if (e.shiftKey) { // multiselect disabled for now
dispatch(imageRangeEndSelected(props.imageDTO.image_name)); // if (e.shiftKey) {
} else if (e.ctrlKey || e.metaKey) { // dispatch(imageRangeEndSelected(props.imageDTO.image_name));
dispatch(imageSelectionToggled(props.imageDTO.image_name)); // } else if (e.ctrlKey || e.metaKey) {
} else { // dispatch(imageSelectionToggled(props.imageDTO.image_name));
// } else {
// dispatch(imageSelected(props.imageDTO.image_name));
// }
dispatch(imageSelected(props.imageDTO.image_name)); dispatch(imageSelected(props.imageDTO.image_name));
}
}, },
[dispatch, props.imageDTO.image_name] [dispatch, props.imageDTO.image_name]
); );
@ -121,6 +123,7 @@ const GalleryImage = (props: HoverableImageProps) => {
// withResetIcon // removed bc it's too easy to accidentally delete images // withResetIcon // removed bc it's too easy to accidentally delete images
isDropDisabled={true} isDropDisabled={true}
isUploadDisabled={true} isUploadDisabled={true}
thumbnail={true}
/> />
</Box> </Box>
)} )}

View File

@ -1,49 +1,32 @@
import { MenuItem, MenuList } from '@chakra-ui/react';
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
import { memo, useCallback, useContext } from 'react';
import {
FaExpand,
FaFolder,
FaFolderPlus,
FaShare,
FaTrash,
} from 'react-icons/fa';
import { ContextMenu, ContextMenuProps } from 'chakra-ui-contextmenu';
import {
resizeAndScaleCanvas,
setInitialCanvasImage,
} from 'features/canvas/store/canvasSlice';
import { setActiveTab } from 'features/ui/store/uiSlice';
import { useTranslation } from 'react-i18next';
import { ExternalLinkIcon } from '@chakra-ui/icons'; import { ExternalLinkIcon } from '@chakra-ui/icons';
import { IoArrowUndoCircleOutline } from 'react-icons/io5'; import { MenuItem, MenuList } from '@chakra-ui/react';
import { createSelector } from '@reduxjs/toolkit'; import { createSelector } from '@reduxjs/toolkit';
import { useFeatureStatus } from 'features/system/hooks/useFeatureStatus';
import { useRecallParameters } from 'features/parameters/hooks/useRecallParameters';
import { initialImageSelected } from 'features/parameters/store/actions';
import { sentImageToCanvas, sentImageToImg2Img } from '../store/actions';
import { useAppToaster } from 'app/components/Toaster'; import { useAppToaster } from 'app/components/Toaster';
import { AddImageToBoardContext } from '../../../app/contexts/AddImageToBoardContext'; import { stateSelector } from 'app/store/store';
import { useRemoveImageFromBoardMutation } from 'services/api/endpoints/boardImages'; import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
import { ImageDTO } from 'services/api/types'; import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions';
import { RootState, stateSelector } from 'app/store/store'; import { ContextMenu, ContextMenuProps } from 'chakra-ui-contextmenu';
import { import {
imagesAddedToBatch, imagesAddedToBatch,
selectionAddedToBatch, selectionAddedToBatch,
} from 'features/batch/store/batchSlice'; } from 'features/batch/store/batchSlice';
import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions'; import {
resizeAndScaleCanvas,
setInitialCanvasImage,
} from 'features/canvas/store/canvasSlice';
import { imageToDeleteSelected } from 'features/imageDeletion/store/imageDeletionSlice'; import { imageToDeleteSelected } from 'features/imageDeletion/store/imageDeletionSlice';
import { useRecallParameters } from 'features/parameters/hooks/useRecallParameters';
const selector = createSelector( import { initialImageSelected } from 'features/parameters/store/actions';
[stateSelector, (state: RootState, imageDTO: ImageDTO) => imageDTO], import { useFeatureStatus } from 'features/system/hooks/useFeatureStatus';
({ gallery, batch }, imageDTO) => { import { setActiveTab } from 'features/ui/store/uiSlice';
const selectionCount = gallery.selection.length; import { memo, useCallback, useContext, useMemo } from 'react';
const isInBatch = batch.imageNames.includes(imageDTO.image_name); import { useTranslation } from 'react-i18next';
import { FaExpand, FaFolder, FaShare, FaTrash } from 'react-icons/fa';
return { selectionCount, isInBatch }; import { IoArrowUndoCircleOutline } from 'react-icons/io5';
}, import { useRemoveImageFromBoardMutation } from 'services/api/endpoints/boardImages';
defaultSelectorOptions import { ImageDTO } from 'services/api/types';
); import { AddImageToBoardContext } from '../../../app/contexts/AddImageToBoardContext';
import { sentImageToCanvas, sentImageToImg2Img } from '../store/actions';
type Props = { type Props = {
image: ImageDTO; image: ImageDTO;
@ -51,9 +34,21 @@ type Props = {
}; };
const ImageContextMenu = ({ image, children }: Props) => { const ImageContextMenu = ({ image, children }: Props) => {
const { selectionCount, isInBatch } = useAppSelector((state) => const selector = useMemo(
selector(state, image) () =>
createSelector(
[stateSelector],
({ gallery, batch }) => {
const selectionCount = gallery.selection.length;
const isInBatch = batch.imageNames.includes(image.image_name);
return { selectionCount, isInBatch };
},
defaultSelectorOptions
),
[image.image_name]
); );
const { selectionCount, isInBatch } = useAppSelector(selector);
const dispatch = useAppDispatch(); const dispatch = useAppDispatch();
const { t } = useTranslation(); const { t } = useTranslation();

View File

@ -8,7 +8,7 @@ import {
selectImagesById, selectImagesById,
} from 'features/gallery/store/gallerySlice'; } from 'features/gallery/store/gallerySlice';
import { clamp, isEqual } from 'lodash-es'; import { clamp, isEqual } from 'lodash-es';
import { useCallback, useState } from 'react'; import { memo, useCallback, useState } from 'react';
import { useHotkeys } from 'react-hotkeys-hook'; import { useHotkeys } from 'react-hotkeys-hook';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { FaAngleDoubleRight, FaAngleLeft, FaAngleRight } from 'react-icons/fa'; import { FaAngleDoubleRight, FaAngleLeft, FaAngleRight } from 'react-icons/fa';
@ -227,4 +227,4 @@ const NextPrevImageButtons = () => {
); );
}; };
export default NextPrevImageButtons; export default memo(NextPrevImageButtons);

View File

@ -0,0 +1,37 @@
import { ButtonGroup, Flex } from '@chakra-ui/react';
import { RootState } from 'app/store/store';
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
import IAIButton from 'common/components/IAIButton';
import { setAspectRatio } from 'features/ui/store/uiSlice';
const aspectRatios = [
{ name: 'Free', value: null },
{ name: 'Portrait', value: 0.67 / 1 },
{ name: 'Wide', value: 16 / 9 },
{ name: 'Square', value: 1 / 1 },
];
export default function ParamAspectRatio() {
const aspectRatio = useAppSelector(
(state: RootState) => state.ui.aspectRatio
);
const dispatch = useAppDispatch();
return (
<Flex gap={2} flexGrow={1}>
<ButtonGroup isAttached>
{aspectRatios.map((ratio) => (
<IAIButton
key={ratio.name}
size="sm"
isChecked={aspectRatio === ratio.value}
onClick={() => dispatch(setAspectRatio(ratio.value))}
>
{ratio.name}
</IAIButton>
))}
</ButtonGroup>
</Flex>
);
}

View File

@ -2,19 +2,22 @@ import { createSelector } from '@reduxjs/toolkit';
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks'; import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions'; import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions';
import IAISlider, { IAIFullSliderProps } from 'common/components/IAISlider'; import IAISlider, { IAIFullSliderProps } from 'common/components/IAISlider';
import { roundToMultiple } from 'common/util/roundDownToMultiple';
import { generationSelector } from 'features/parameters/store/generationSelectors'; import { generationSelector } from 'features/parameters/store/generationSelectors';
import { setHeight } from 'features/parameters/store/generationSlice'; import { setHeight, setWidth } from 'features/parameters/store/generationSlice';
import { configSelector } from 'features/system/store/configSelectors'; import { configSelector } from 'features/system/store/configSelectors';
import { hotkeysSelector } from 'features/ui/store/hotkeysSlice'; import { hotkeysSelector } from 'features/ui/store/hotkeysSlice';
import { uiSelector } from 'features/ui/store/uiSelectors';
import { memo, useCallback } from 'react'; import { memo, useCallback } from 'react';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
const selector = createSelector( const selector = createSelector(
[generationSelector, hotkeysSelector, configSelector], [generationSelector, hotkeysSelector, configSelector, uiSelector],
(generation, hotkeys, config) => { (generation, hotkeys, config, ui) => {
const { initial, min, sliderMax, inputMax, fineStep, coarseStep } = const { initial, min, sliderMax, inputMax, fineStep, coarseStep } =
config.sd.height; config.sd.height;
const { height } = generation; const { height } = generation;
const { aspectRatio } = ui;
const step = hotkeys.shift ? fineStep : coarseStep; const step = hotkeys.shift ? fineStep : coarseStep;
@ -25,6 +28,7 @@ const selector = createSelector(
sliderMax, sliderMax,
inputMax, inputMax,
step, step,
aspectRatio,
}; };
}, },
defaultSelectorOptions defaultSelectorOptions
@ -36,7 +40,7 @@ type ParamHeightProps = Omit<
>; >;
const ParamHeight = (props: ParamHeightProps) => { const ParamHeight = (props: ParamHeightProps) => {
const { height, initial, min, sliderMax, inputMax, step } = const { height, initial, min, sliderMax, inputMax, step, aspectRatio } =
useAppSelector(selector); useAppSelector(selector);
const dispatch = useAppDispatch(); const dispatch = useAppDispatch();
const { t } = useTranslation(); const { t } = useTranslation();
@ -44,13 +48,21 @@ const ParamHeight = (props: ParamHeightProps) => {
const handleChange = useCallback( const handleChange = useCallback(
(v: number) => { (v: number) => {
dispatch(setHeight(v)); dispatch(setHeight(v));
if (aspectRatio) {
const newWidth = roundToMultiple(v * aspectRatio, 8);
dispatch(setWidth(newWidth));
}
}, },
[dispatch] [dispatch, aspectRatio]
); );
const handleReset = useCallback(() => { const handleReset = useCallback(() => {
dispatch(setHeight(initial)); dispatch(setHeight(initial));
}, [dispatch, initial]); if (aspectRatio) {
const newWidth = roundToMultiple(initial * aspectRatio, 8);
dispatch(setWidth(newWidth));
}
}, [dispatch, initial, aspectRatio]);
return ( return (
<IAISlider <IAISlider

View File

@ -0,0 +1,64 @@
import { Flex, Spacer, Text } from '@chakra-ui/react';
import { RootState } from 'app/store/store';
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
import IAIIconButton from 'common/components/IAIIconButton';
import { toggleSize } from 'features/parameters/store/generationSlice';
import { useTranslation } from 'react-i18next';
import { MdOutlineSwapVert } from 'react-icons/md';
import ParamAspectRatio from './ParamAspectRatio';
import ParamHeight from './ParamHeight';
import ParamWidth from './ParamWidth';
export default function ParamSize() {
const { t } = useTranslation();
const dispatch = useAppDispatch();
const shouldFitToWidthHeight = useAppSelector(
(state: RootState) => state.generation.shouldFitToWidthHeight
);
return (
<Flex
sx={{
gap: 2,
p: 4,
borderRadius: 4,
flexDirection: 'column',
w: 'full',
bg: 'base.150',
_dark: {
bg: 'base.750',
},
}}
>
<Flex alignItems="center" gap={2}>
<Text
sx={{
fontSize: 'sm',
width: 'full',
color: 'base.700',
_dark: {
color: 'base.300',
},
}}
>
{t('parameters.aspectRatio')}
</Text>
<Spacer />
<ParamAspectRatio />
<IAIIconButton
tooltip={t('ui.swapSizes')}
aria-label={t('ui.swapSizes')}
size="sm"
icon={<MdOutlineSwapVert />}
fontSize={20}
onClick={() => dispatch(toggleSize())}
/>
</Flex>
<Flex gap={2} alignItems="center">
<Flex gap={2} flexDirection="column" width="full">
<ParamWidth isDisabled={!shouldFitToWidthHeight} />
<ParamHeight isDisabled={!shouldFitToWidthHeight} />
</Flex>
</Flex>
</Flex>
);
}

View File

@ -2,19 +2,22 @@ import { createSelector } from '@reduxjs/toolkit';
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks'; import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions'; import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions';
import IAISlider, { IAIFullSliderProps } from 'common/components/IAISlider'; import IAISlider, { IAIFullSliderProps } from 'common/components/IAISlider';
import { roundToMultiple } from 'common/util/roundDownToMultiple';
import { generationSelector } from 'features/parameters/store/generationSelectors'; import { generationSelector } from 'features/parameters/store/generationSelectors';
import { setWidth } from 'features/parameters/store/generationSlice'; import { setHeight, setWidth } from 'features/parameters/store/generationSlice';
import { configSelector } from 'features/system/store/configSelectors'; import { configSelector } from 'features/system/store/configSelectors';
import { hotkeysSelector } from 'features/ui/store/hotkeysSlice'; import { hotkeysSelector } from 'features/ui/store/hotkeysSlice';
import { uiSelector } from 'features/ui/store/uiSelectors';
import { memo, useCallback } from 'react'; import { memo, useCallback } from 'react';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
const selector = createSelector( const selector = createSelector(
[generationSelector, hotkeysSelector, configSelector], [generationSelector, hotkeysSelector, configSelector, uiSelector],
(generation, hotkeys, config) => { (generation, hotkeys, config, ui) => {
const { initial, min, sliderMax, inputMax, fineStep, coarseStep } = const { initial, min, sliderMax, inputMax, fineStep, coarseStep } =
config.sd.width; config.sd.width;
const { width } = generation; const { width } = generation;
const { aspectRatio } = ui;
const step = hotkeys.shift ? fineStep : coarseStep; const step = hotkeys.shift ? fineStep : coarseStep;
@ -25,6 +28,7 @@ const selector = createSelector(
sliderMax, sliderMax,
inputMax, inputMax,
step, step,
aspectRatio,
}; };
}, },
defaultSelectorOptions defaultSelectorOptions
@ -33,7 +37,7 @@ const selector = createSelector(
type ParamWidthProps = Omit<IAIFullSliderProps, 'label' | 'value' | 'onChange'>; type ParamWidthProps = Omit<IAIFullSliderProps, 'label' | 'value' | 'onChange'>;
const ParamWidth = (props: ParamWidthProps) => { const ParamWidth = (props: ParamWidthProps) => {
const { width, initial, min, sliderMax, inputMax, step } = const { width, initial, min, sliderMax, inputMax, step, aspectRatio } =
useAppSelector(selector); useAppSelector(selector);
const dispatch = useAppDispatch(); const dispatch = useAppDispatch();
const { t } = useTranslation(); const { t } = useTranslation();
@ -41,13 +45,21 @@ const ParamWidth = (props: ParamWidthProps) => {
const handleChange = useCallback( const handleChange = useCallback(
(v: number) => { (v: number) => {
dispatch(setWidth(v)); dispatch(setWidth(v));
if (aspectRatio) {
const newHeight = roundToMultiple(v / aspectRatio, 8);
dispatch(setHeight(newHeight));
}
}, },
[dispatch] [dispatch, aspectRatio]
); );
const handleReset = useCallback(() => { const handleReset = useCallback(() => {
dispatch(setWidth(initial)); dispatch(setWidth(initial));
}, [dispatch, initial]); if (aspectRatio) {
const newHeight = roundToMultiple(initial / aspectRatio, 8);
dispatch(setHeight(newHeight));
}
}, [dispatch, initial, aspectRatio]);
return ( return (
<IAISlider <IAISlider

View File

@ -78,7 +78,7 @@ export default function InvokeButton(props: InvokeButton) {
aria-label={t('parameters.invoke')} aria-label={t('parameters.invoke')}
type="submit" type="submit"
icon={<FaPlay />} icon={<FaPlay />}
isDisabled={!isReady} isDisabled={!isReady || isProcessing}
onClick={handleInvoke} onClick={handleInvoke}
tooltip={t('parameters.invoke')} tooltip={t('parameters.invoke')}
tooltipProps={{ placement: 'top' }} tooltipProps={{ placement: 'top' }}
@ -95,7 +95,7 @@ export default function InvokeButton(props: InvokeButton) {
<IAIButton <IAIButton
aria-label={t('parameters.invoke')} aria-label={t('parameters.invoke')}
type="submit" type="submit"
isDisabled={!isReady} isDisabled={!isReady || isProcessing}
onClick={handleInvoke} onClick={handleInvoke}
colorScheme="accent" colorScheme="accent"
id="invoke-button" id="invoke-button"

View File

@ -1,8 +1,12 @@
import type { PayloadAction } from '@reduxjs/toolkit'; import type { PayloadAction } from '@reduxjs/toolkit';
import { createSlice } from '@reduxjs/toolkit'; import { createSlice } from '@reduxjs/toolkit';
import { DEFAULT_SCHEDULER_NAME } from 'app/constants'; import { DEFAULT_SCHEDULER_NAME } from 'app/constants';
import { roundToMultiple } from 'common/util/roundDownToMultiple';
import { configChanged } from 'features/system/store/configSlice'; import { configChanged } from 'features/system/store/configSlice';
import { setShouldShowAdvancedOptions } from 'features/ui/store/uiSlice'; import {
setAspectRatio,
setShouldShowAdvancedOptions,
} from 'features/ui/store/uiSlice';
import { clamp } from 'lodash-es'; import { clamp } from 'lodash-es';
import { ImageDTO } from 'services/api/types'; import { ImageDTO } from 'services/api/types';
import { clipSkipMap } from '../components/Parameters/Advanced/ParamClipSkip'; import { clipSkipMap } from '../components/Parameters/Advanced/ParamClipSkip';
@ -139,6 +143,11 @@ export const generationSlice = createSlice({
setWidth: (state, action: PayloadAction<number>) => { setWidth: (state, action: PayloadAction<number>) => {
state.width = action.payload; state.width = action.payload;
}, },
toggleSize: (state) => {
const [width, height] = [state.width, state.height];
state.width = height;
state.height = width;
},
setScheduler: (state, action: PayloadAction<SchedulerParam>) => { setScheduler: (state, action: PayloadAction<SchedulerParam>) => {
state.scheduler = action.payload; state.scheduler = action.payload;
}, },
@ -262,6 +271,12 @@ export const generationSlice = createSlice({
const advancedOptionsStatus = action.payload; const advancedOptionsStatus = action.payload;
if (!advancedOptionsStatus) state.clipSkip = 0; if (!advancedOptionsStatus) state.clipSkip = 0;
}); });
builder.addCase(setAspectRatio, (state, action) => {
const ratio = action.payload;
if (ratio) {
state.height = roundToMultiple(state.width / ratio, 8);
}
});
}, },
}); });
@ -271,7 +286,9 @@ export const {
resetParametersState, resetParametersState,
resetSeed, resetSeed,
setCfgScale, setCfgScale,
setWidth,
setHeight, setHeight,
toggleSize,
setImg2imgStrength, setImg2imgStrength,
setInfillMethod, setInfillMethod,
setIterations, setIterations,
@ -292,7 +309,6 @@ export const {
setThreshold, setThreshold,
setTileSize, setTileSize,
setVariationAmount, setVariationAmount,
setWidth,
setShouldUseSymmetry, setShouldUseSymmetry,
setHorizontalSymmetrySteps, setHorizontalSymmetrySteps,
setVerticalSymmetrySteps, setVerticalSymmetrySteps,

View File

@ -4,11 +4,10 @@ import { useAppSelector } from 'app/store/storeHooks';
import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions'; import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions';
import IAICollapse from 'common/components/IAICollapse'; import IAICollapse from 'common/components/IAICollapse';
import ParamCFGScale from 'features/parameters/components/Parameters/Core/ParamCFGScale'; import ParamCFGScale from 'features/parameters/components/Parameters/Core/ParamCFGScale';
import ParamHeight from 'features/parameters/components/Parameters/Core/ParamHeight';
import ParamIterations from 'features/parameters/components/Parameters/Core/ParamIterations'; import ParamIterations from 'features/parameters/components/Parameters/Core/ParamIterations';
import ParamModelandVAEandScheduler from 'features/parameters/components/Parameters/Core/ParamModelandVAEandScheduler'; import ParamModelandVAEandScheduler from 'features/parameters/components/Parameters/Core/ParamModelandVAEandScheduler';
import ParamSize from 'features/parameters/components/Parameters/Core/ParamSize';
import ParamSteps from 'features/parameters/components/Parameters/Core/ParamSteps'; import ParamSteps from 'features/parameters/components/Parameters/Core/ParamSteps';
import ParamWidth from 'features/parameters/components/Parameters/Core/ParamWidth';
import ImageToImageFit from 'features/parameters/components/Parameters/ImageToImage/ImageToImageFit'; import ImageToImageFit from 'features/parameters/components/Parameters/ImageToImage/ImageToImageFit';
import ImageToImageStrength from 'features/parameters/components/Parameters/ImageToImage/ImageToImageStrength'; import ImageToImageStrength from 'features/parameters/components/Parameters/ImageToImage/ImageToImageStrength';
import ParamSeedFull from 'features/parameters/components/Parameters/Seed/ParamSeedFull'; import ParamSeedFull from 'features/parameters/components/Parameters/Seed/ParamSeedFull';
@ -47,15 +46,14 @@ const ImageToImageTabCoreParameters = () => {
> >
{shouldUseSliders ? ( {shouldUseSliders ? (
<> <>
<ParamIterations />
<ParamSteps />
<ParamCFGScale />
<ParamModelandVAEandScheduler /> <ParamModelandVAEandScheduler />
<Box pt={2}> <Box pt={2}>
<ParamSeedFull /> <ParamSeedFull />
</Box> </Box>
<ParamIterations /> <ParamSize />
<ParamSteps />
<ParamCFGScale />
<ParamWidth isDisabled={!shouldFitToWidthHeight} />
<ParamHeight isDisabled={!shouldFitToWidthHeight} />
</> </>
) : ( ) : (
<> <>
@ -68,8 +66,7 @@ const ImageToImageTabCoreParameters = () => {
<Box pt={2}> <Box pt={2}>
<ParamSeedFull /> <ParamSeedFull />
</Box> </Box>
<ParamWidth isDisabled={!shouldFitToWidthHeight} /> <ParamSize />
<ParamHeight isDisabled={!shouldFitToWidthHeight} />
</> </>
)} )}
<ImageToImageStrength /> <ImageToImageStrength />

View File

@ -5,11 +5,10 @@ import { useAppSelector } from 'app/store/storeHooks';
import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions'; import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions';
import IAICollapse from 'common/components/IAICollapse'; import IAICollapse from 'common/components/IAICollapse';
import ParamCFGScale from 'features/parameters/components/Parameters/Core/ParamCFGScale'; import ParamCFGScale from 'features/parameters/components/Parameters/Core/ParamCFGScale';
import ParamHeight from 'features/parameters/components/Parameters/Core/ParamHeight';
import ParamIterations from 'features/parameters/components/Parameters/Core/ParamIterations'; import ParamIterations from 'features/parameters/components/Parameters/Core/ParamIterations';
import ParamModelandVAEandScheduler from 'features/parameters/components/Parameters/Core/ParamModelandVAEandScheduler'; import ParamModelandVAEandScheduler from 'features/parameters/components/Parameters/Core/ParamModelandVAEandScheduler';
import ParamSize from 'features/parameters/components/Parameters/Core/ParamSize';
import ParamSteps from 'features/parameters/components/Parameters/Core/ParamSteps'; import ParamSteps from 'features/parameters/components/Parameters/Core/ParamSteps';
import ParamWidth from 'features/parameters/components/Parameters/Core/ParamWidth';
import ParamSeedFull from 'features/parameters/components/Parameters/Seed/ParamSeedFull'; import ParamSeedFull from 'features/parameters/components/Parameters/Seed/ParamSeedFull';
import { memo } from 'react'; import { memo } from 'react';
@ -43,15 +42,14 @@ const TextToImageTabCoreParameters = () => {
> >
{shouldUseSliders ? ( {shouldUseSliders ? (
<> <>
<ParamIterations />
<ParamSteps />
<ParamCFGScale />
<ParamModelandVAEandScheduler /> <ParamModelandVAEandScheduler />
<Box pt={2}> <Box pt={2}>
<ParamSeedFull /> <ParamSeedFull />
</Box> </Box>
<ParamIterations /> <ParamSize />
<ParamSteps />
<ParamCFGScale />
<ParamWidth />
<ParamHeight />
</> </>
) : ( ) : (
<> <>
@ -64,8 +62,7 @@ const TextToImageTabCoreParameters = () => {
<Box pt={2}> <Box pt={2}>
<ParamSeedFull /> <ParamSeedFull />
</Box> </Box>
<ParamWidth /> <ParamSize />
<ParamHeight />
</> </>
)} )}
</Flex> </Flex>

View File

@ -44,13 +44,13 @@ const UnifiedCanvasCoreParameters = () => {
> >
{shouldUseSliders ? ( {shouldUseSliders ? (
<> <>
<ParamIterations />
<ParamSteps />
<ParamCFGScale />
<ParamModelandVAEandScheduler /> <ParamModelandVAEandScheduler />
<Box pt={2}> <Box pt={2}>
<ParamSeedFull /> <ParamSeedFull />
</Box> </Box>
<ParamIterations />
<ParamSteps />
<ParamCFGScale />
<ParamBoundingBoxWidth /> <ParamBoundingBoxWidth />
<ParamBoundingBoxHeight /> <ParamBoundingBoxHeight />
</> </>

View File

@ -21,6 +21,7 @@ export const initialUIState: UIState = {
shouldShowProgressInViewer: true, shouldShowProgressInViewer: true,
shouldShowEmbeddingPicker: false, shouldShowEmbeddingPicker: false,
shouldShowAdvancedOptions: false, shouldShowAdvancedOptions: false,
aspectRatio: null,
favoriteSchedulers: [], favoriteSchedulers: [],
}; };
@ -104,6 +105,9 @@ export const uiSlice = createSlice({
setShouldShowAdvancedOptions: (state, action: PayloadAction<boolean>) => { setShouldShowAdvancedOptions: (state, action: PayloadAction<boolean>) => {
state.shouldShowAdvancedOptions = action.payload; state.shouldShowAdvancedOptions = action.payload;
}, },
setAspectRatio: (state, action: PayloadAction<number | null>) => {
state.aspectRatio = action.payload;
},
}, },
extraReducers(builder) { extraReducers(builder) {
builder.addCase(initialImageChanged, (state) => { builder.addCase(initialImageChanged, (state) => {
@ -132,6 +136,7 @@ export const {
favoriteSchedulersChanged, favoriteSchedulersChanged,
toggleEmbeddingPicker, toggleEmbeddingPicker,
setShouldShowAdvancedOptions, setShouldShowAdvancedOptions,
setAspectRatio,
} = uiSlice.actions; } = uiSlice.actions;
export default uiSlice.reducer; export default uiSlice.reducer;

View File

@ -29,5 +29,6 @@ export interface UIState {
shouldShowProgressInViewer: boolean; shouldShowProgressInViewer: boolean;
shouldShowEmbeddingPicker: boolean; shouldShowEmbeddingPicker: boolean;
shouldShowAdvancedOptions: boolean; shouldShowAdvancedOptions: boolean;
aspectRatio: number | null;
favoriteSchedulers: SchedulerParam[]; favoriteSchedulers: SchedulerParam[];
} }