mirror of
https://github.com/invoke-ai/InvokeAI
synced 2024-08-30 20:32:17 +00:00
Merge branch 'main' into feat/nodes-phase-5
This commit is contained in:
commit
71591d0bee
@ -506,12 +506,13 @@
|
|||||||
"hiresStrength": "High Res Strength",
|
"hiresStrength": "High Res Strength",
|
||||||
"imageFit": "Fit Initial Image To Output Size",
|
"imageFit": "Fit Initial Image To Output Size",
|
||||||
"codeformerFidelity": "Fidelity",
|
"codeformerFidelity": "Fidelity",
|
||||||
|
"compositingSettingsHeader": "Compositing Settings",
|
||||||
"maskAdjustmentsHeader": "Mask Adjustments",
|
"maskAdjustmentsHeader": "Mask Adjustments",
|
||||||
"maskBlur": "Mask Blur",
|
"maskBlur": "Blur",
|
||||||
"maskBlurMethod": "Mask Blur Method",
|
"maskBlurMethod": "Blur Method",
|
||||||
"coherencePassHeader": "Coherence Pass",
|
"coherencePassHeader": "Coherence Pass",
|
||||||
"coherenceSteps": "Coherence Pass Steps",
|
"coherenceSteps": "Steps",
|
||||||
"coherenceStrength": "Coherence Pass Strength",
|
"coherenceStrength": "Strength",
|
||||||
"seamLowThreshold": "Low",
|
"seamLowThreshold": "Low",
|
||||||
"seamHighThreshold": "High",
|
"seamHighThreshold": "High",
|
||||||
"scaleBeforeProcessing": "Scale Before Processing",
|
"scaleBeforeProcessing": "Scale Before Processing",
|
||||||
@ -569,6 +570,7 @@
|
|||||||
"useSlidersForAll": "Use Sliders For All Options",
|
"useSlidersForAll": "Use Sliders For All Options",
|
||||||
"showProgressInViewer": "Show Progress Images in Viewer",
|
"showProgressInViewer": "Show Progress Images in Viewer",
|
||||||
"antialiasProgressImages": "Antialias Progress Images",
|
"antialiasProgressImages": "Antialias Progress Images",
|
||||||
|
"autoChangeDimensions": "Update W/H To Model Defaults On Change",
|
||||||
"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.",
|
||||||
"resetWebUIDesc2": "If images aren't showing up in the gallery or something else isn't working, please try resetting before submitting an issue on GitHub.",
|
"resetWebUIDesc2": "If images aren't showing up in the gallery or something else isn't working, please try resetting before submitting an issue on GitHub.",
|
||||||
@ -712,7 +714,8 @@
|
|||||||
"ui": {
|
"ui": {
|
||||||
"showProgressImages": "Show Progress Images",
|
"showProgressImages": "Show Progress Images",
|
||||||
"hideProgressImages": "Hide Progress Images",
|
"hideProgressImages": "Hide Progress Images",
|
||||||
"swapSizes": "Swap Sizes"
|
"swapSizes": "Swap Sizes",
|
||||||
|
"lockRatio": "Lock Ratio"
|
||||||
},
|
},
|
||||||
"nodes": {
|
"nodes": {
|
||||||
"reloadNodeTemplates": "Reload Node Templates",
|
"reloadNodeTemplates": "Reload Node Templates",
|
||||||
|
@ -1,9 +1,12 @@
|
|||||||
import { logger } from 'app/logging/logger';
|
import { logger } from 'app/logging/logger';
|
||||||
|
import { setBoundingBoxDimensions } from 'features/canvas/store/canvasSlice';
|
||||||
import { controlNetRemoved } from 'features/controlNet/store/controlNetSlice';
|
import { controlNetRemoved } from 'features/controlNet/store/controlNetSlice';
|
||||||
import { loraRemoved } from 'features/lora/store/loraSlice';
|
import { loraRemoved } from 'features/lora/store/loraSlice';
|
||||||
import { modelSelected } from 'features/parameters/store/actions';
|
import { modelSelected } from 'features/parameters/store/actions';
|
||||||
import {
|
import {
|
||||||
modelChanged,
|
modelChanged,
|
||||||
|
setHeight,
|
||||||
|
setWidth,
|
||||||
vaeSelected,
|
vaeSelected,
|
||||||
} from 'features/parameters/store/generationSlice';
|
} from 'features/parameters/store/generationSlice';
|
||||||
import { zMainOrOnnxModel } from 'features/parameters/types/parameterSchemas';
|
import { zMainOrOnnxModel } from 'features/parameters/types/parameterSchemas';
|
||||||
@ -74,6 +77,22 @@ export const addModelSelectedListener = () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Update Width / Height / Bounding Box Dimensions on Model Change
|
||||||
|
if (
|
||||||
|
state.generation.model?.base_model !== newModel.base_model &&
|
||||||
|
state.ui.shouldAutoChangeDimensions
|
||||||
|
) {
|
||||||
|
if (['sdxl', 'sdxl-refiner'].includes(newModel.base_model)) {
|
||||||
|
dispatch(setWidth(1024));
|
||||||
|
dispatch(setHeight(1024));
|
||||||
|
dispatch(setBoundingBoxDimensions({ width: 1024, height: 1024 }));
|
||||||
|
} else {
|
||||||
|
dispatch(setWidth(512));
|
||||||
|
dispatch(setHeight(512));
|
||||||
|
dispatch(setBoundingBoxDimensions({ width: 512, height: 512 }));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
dispatch(modelChanged(newModel));
|
dispatch(modelChanged(newModel));
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
@ -6,11 +6,11 @@ import {
|
|||||||
configureStore,
|
configureStore,
|
||||||
} from '@reduxjs/toolkit';
|
} from '@reduxjs/toolkit';
|
||||||
import canvasReducer from 'features/canvas/store/canvasSlice';
|
import canvasReducer from 'features/canvas/store/canvasSlice';
|
||||||
|
import changeBoardModalReducer from 'features/changeBoardModal/store/slice';
|
||||||
import controlNetReducer from 'features/controlNet/store/controlNetSlice';
|
import controlNetReducer from 'features/controlNet/store/controlNetSlice';
|
||||||
|
import deleteImageModalReducer from 'features/deleteImageModal/store/slice';
|
||||||
import dynamicPromptsReducer from 'features/dynamicPrompts/store/dynamicPromptsSlice';
|
import dynamicPromptsReducer from 'features/dynamicPrompts/store/dynamicPromptsSlice';
|
||||||
import galleryReducer from 'features/gallery/store/gallerySlice';
|
import galleryReducer from 'features/gallery/store/gallerySlice';
|
||||||
import deleteImageModalReducer from 'features/deleteImageModal/store/slice';
|
|
||||||
import changeBoardModalReducer from 'features/changeBoardModal/store/slice';
|
|
||||||
import loraReducer from 'features/lora/store/loraSlice';
|
import loraReducer from 'features/lora/store/loraSlice';
|
||||||
import nodesReducer from 'features/nodes/store/nodesSlice';
|
import nodesReducer from 'features/nodes/store/nodesSlice';
|
||||||
import generationReducer from 'features/parameters/store/generationSlice';
|
import generationReducer from 'features/parameters/store/generationSlice';
|
||||||
|
@ -86,8 +86,8 @@ const IAICollapse = (props: IAIToggleCollapseProps) => {
|
|||||||
<Collapse in={isOpen} animateOpacity style={{ overflow: 'unset' }}>
|
<Collapse in={isOpen} animateOpacity style={{ overflow: 'unset' }}>
|
||||||
<Box
|
<Box
|
||||||
sx={{
|
sx={{
|
||||||
p: 2,
|
p: 4,
|
||||||
pt: 3,
|
pb: 4,
|
||||||
borderBottomRadius: 'base',
|
borderBottomRadius: 'base',
|
||||||
bg: 'base.150',
|
bg: 'base.150',
|
||||||
_dark: {
|
_dark: {
|
||||||
|
@ -5,16 +5,20 @@ import { stateSelector } from 'app/store/store';
|
|||||||
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 IAIDndImage from 'common/components/IAIDndImage';
|
import IAIDndImage from 'common/components/IAIDndImage';
|
||||||
|
import { setBoundingBoxDimensions } from 'features/canvas/store/canvasSlice';
|
||||||
import {
|
import {
|
||||||
TypesafeDraggableData,
|
TypesafeDraggableData,
|
||||||
TypesafeDroppableData,
|
TypesafeDroppableData,
|
||||||
} from 'features/dnd/types';
|
} from 'features/dnd/types';
|
||||||
|
import { setHeight, setWidth } from 'features/parameters/store/generationSlice';
|
||||||
|
import { activeTabNameSelector } from 'features/ui/store/uiSelectors';
|
||||||
import { memo, useCallback, useMemo, useState } from 'react';
|
import { memo, useCallback, useMemo, useState } from 'react';
|
||||||
import { FaSave, FaUndo } from 'react-icons/fa';
|
import { FaRulerVertical, FaSave, FaUndo } from 'react-icons/fa';
|
||||||
import {
|
import {
|
||||||
useAddImageToBoardMutation,
|
useAddImageToBoardMutation,
|
||||||
useChangeImageIsIntermediateMutation,
|
useChangeImageIsIntermediateMutation,
|
||||||
useGetImageDTOQuery,
|
useGetImageDTOQuery,
|
||||||
|
useRemoveImageFromBoardMutation,
|
||||||
} from 'services/api/endpoints/images';
|
} from 'services/api/endpoints/images';
|
||||||
import { PostUploadAction } from 'services/api/types';
|
import { PostUploadAction } from 'services/api/types';
|
||||||
import IAIDndImageIcon from '../../../common/components/IAIDndImageIcon';
|
import IAIDndImageIcon from '../../../common/components/IAIDndImageIcon';
|
||||||
@ -54,6 +58,7 @@ const ControlNetImagePreview = ({ isSmall, controlNet }: Props) => {
|
|||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
|
|
||||||
const { pendingControlImages, autoAddBoardId } = useAppSelector(selector);
|
const { pendingControlImages, autoAddBoardId } = useAppSelector(selector);
|
||||||
|
const activeTabName = useAppSelector(activeTabNameSelector);
|
||||||
|
|
||||||
const [isMouseOverImage, setIsMouseOverImage] = useState(false);
|
const [isMouseOverImage, setIsMouseOverImage] = useState(false);
|
||||||
|
|
||||||
@ -67,23 +72,54 @@ const ControlNetImagePreview = ({ isSmall, controlNet }: Props) => {
|
|||||||
|
|
||||||
const [changeIsIntermediate] = useChangeImageIsIntermediateMutation();
|
const [changeIsIntermediate] = useChangeImageIsIntermediateMutation();
|
||||||
const [addToBoard] = useAddImageToBoardMutation();
|
const [addToBoard] = useAddImageToBoardMutation();
|
||||||
|
const [removeFromBoard] = useRemoveImageFromBoardMutation();
|
||||||
const handleResetControlImage = useCallback(() => {
|
const handleResetControlImage = useCallback(() => {
|
||||||
dispatch(controlNetImageChanged({ controlNetId, controlImage: null }));
|
dispatch(controlNetImageChanged({ controlNetId, controlImage: null }));
|
||||||
}, [controlNetId, dispatch]);
|
}, [controlNetId, dispatch]);
|
||||||
|
|
||||||
const handleSaveControlImage = useCallback(() => {
|
const handleSaveControlImage = useCallback(async () => {
|
||||||
if (!processedControlImage) {
|
if (!processedControlImage) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
changeIsIntermediate({
|
await changeIsIntermediate({
|
||||||
imageDTO: processedControlImage,
|
imageDTO: processedControlImage,
|
||||||
is_intermediate: false,
|
is_intermediate: false,
|
||||||
});
|
}).unwrap();
|
||||||
|
|
||||||
addToBoard({ imageDTO: processedControlImage, board_id: autoAddBoardId });
|
if (autoAddBoardId !== 'none') {
|
||||||
}, [processedControlImage, autoAddBoardId, changeIsIntermediate, addToBoard]);
|
addToBoard({
|
||||||
|
imageDTO: processedControlImage,
|
||||||
|
board_id: autoAddBoardId,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
removeFromBoard({ imageDTO: processedControlImage });
|
||||||
|
}
|
||||||
|
}, [
|
||||||
|
processedControlImage,
|
||||||
|
changeIsIntermediate,
|
||||||
|
autoAddBoardId,
|
||||||
|
addToBoard,
|
||||||
|
removeFromBoard,
|
||||||
|
]);
|
||||||
|
|
||||||
|
const handleSetControlImageToDimensions = useCallback(() => {
|
||||||
|
if (!processedControlImage) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (activeTabName === 'unifiedCanvas') {
|
||||||
|
dispatch(
|
||||||
|
setBoundingBoxDimensions({
|
||||||
|
width: processedControlImage.width,
|
||||||
|
height: processedControlImage.height,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
dispatch(setWidth(processedControlImage.width));
|
||||||
|
dispatch(setHeight(processedControlImage.height));
|
||||||
|
}
|
||||||
|
}, [processedControlImage, activeTabName, dispatch]);
|
||||||
|
|
||||||
const handleMouseEnter = useCallback(() => {
|
const handleMouseEnter = useCallback(() => {
|
||||||
setIsMouseOverImage(true);
|
setIsMouseOverImage(true);
|
||||||
@ -144,21 +180,7 @@ const ControlNetImagePreview = ({ isSmall, controlNet }: Props) => {
|
|||||||
imageDTO={controlImage}
|
imageDTO={controlImage}
|
||||||
isDropDisabled={shouldShowProcessedImage || !isEnabled}
|
isDropDisabled={shouldShowProcessedImage || !isEnabled}
|
||||||
postUploadAction={postUploadAction}
|
postUploadAction={postUploadAction}
|
||||||
>
|
|
||||||
<>
|
|
||||||
<IAIDndImageIcon
|
|
||||||
onClick={handleResetControlImage}
|
|
||||||
icon={controlImage ? <FaUndo /> : undefined}
|
|
||||||
tooltip="Reset Control Image"
|
|
||||||
/>
|
/>
|
||||||
<IAIDndImageIcon
|
|
||||||
onClick={handleSaveControlImage}
|
|
||||||
icon={controlImage ? <FaSave size={16} /> : undefined}
|
|
||||||
tooltip="Save Control Image"
|
|
||||||
styleOverrides={{ marginTop: 6 }}
|
|
||||||
/>
|
|
||||||
</>
|
|
||||||
</IAIDndImage>
|
|
||||||
|
|
||||||
<Box
|
<Box
|
||||||
sx={{
|
sx={{
|
||||||
@ -179,7 +201,9 @@ const ControlNetImagePreview = ({ isSmall, controlNet }: Props) => {
|
|||||||
imageDTO={processedControlImage}
|
imageDTO={processedControlImage}
|
||||||
isUploadDisabled={true}
|
isUploadDisabled={true}
|
||||||
isDropDisabled={!isEnabled}
|
isDropDisabled={!isEnabled}
|
||||||
>
|
/>
|
||||||
|
</Box>
|
||||||
|
|
||||||
<>
|
<>
|
||||||
<IAIDndImageIcon
|
<IAIDndImageIcon
|
||||||
onClick={handleResetControlImage}
|
onClick={handleResetControlImage}
|
||||||
@ -192,9 +216,14 @@ const ControlNetImagePreview = ({ isSmall, controlNet }: Props) => {
|
|||||||
tooltip="Save Control Image"
|
tooltip="Save Control Image"
|
||||||
styleOverrides={{ marginTop: 6 }}
|
styleOverrides={{ marginTop: 6 }}
|
||||||
/>
|
/>
|
||||||
|
<IAIDndImageIcon
|
||||||
|
onClick={handleSetControlImageToDimensions}
|
||||||
|
icon={controlImage ? <FaRulerVertical size={16} /> : undefined}
|
||||||
|
tooltip="Set Control Image Dimensions To W/H"
|
||||||
|
styleOverrides={{ marginTop: 12 }}
|
||||||
|
/>
|
||||||
</>
|
</>
|
||||||
</IAIDndImage>
|
|
||||||
</Box>
|
|
||||||
{pendingControlImages.includes(controlNetId) && (
|
{pendingControlImages.includes(controlNetId) && (
|
||||||
<Flex
|
<Flex
|
||||||
sx={{
|
sx={{
|
||||||
|
@ -4,11 +4,11 @@ import { stateSelector } from 'app/store/store';
|
|||||||
import { useAppSelector } from 'app/store/storeHooks';
|
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 { memo } from 'react';
|
||||||
|
import { useFeatureStatus } from '../../system/hooks/useFeatureStatus';
|
||||||
import ParamDynamicPromptsCombinatorial from './ParamDynamicPromptsCombinatorial';
|
import ParamDynamicPromptsCombinatorial from './ParamDynamicPromptsCombinatorial';
|
||||||
import ParamDynamicPromptsToggle from './ParamDynamicPromptsEnabled';
|
import ParamDynamicPromptsToggle from './ParamDynamicPromptsEnabled';
|
||||||
import ParamDynamicPromptsMaxPrompts from './ParamDynamicPromptsMaxPrompts';
|
import ParamDynamicPromptsMaxPrompts from './ParamDynamicPromptsMaxPrompts';
|
||||||
import { useFeatureStatus } from '../../system/hooks/useFeatureStatus';
|
|
||||||
import { memo } from 'react';
|
|
||||||
|
|
||||||
const selector = createSelector(
|
const selector = createSelector(
|
||||||
stateSelector,
|
stateSelector,
|
||||||
|
@ -39,7 +39,7 @@ const ImageGalleryContent = () => {
|
|||||||
const { galleryView } = useAppSelector(selector);
|
const { galleryView } = useAppSelector(selector);
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
const { isOpen: isBoardListOpen, onToggle: onToggleBoardList } =
|
const { isOpen: isBoardListOpen, onToggle: onToggleBoardList } =
|
||||||
useDisclosure();
|
useDisclosure({ defaultIsOpen: true });
|
||||||
|
|
||||||
const handleClickImages = useCallback(() => {
|
const handleClickImages = useCallback(() => {
|
||||||
dispatch(galleryViewChanged('images'));
|
dispatch(galleryViewChanged('images'));
|
||||||
|
@ -14,8 +14,9 @@ const selector = createSelector(
|
|||||||
[stateSelector, isStagingSelector],
|
[stateSelector, isStagingSelector],
|
||||||
({ canvas, generation }, isStaging) => {
|
({ canvas, generation }, isStaging) => {
|
||||||
const { boundingBoxDimensions } = canvas;
|
const { boundingBoxDimensions } = canvas;
|
||||||
const { aspectRatio } = generation;
|
const { model, aspectRatio } = generation;
|
||||||
return {
|
return {
|
||||||
|
model,
|
||||||
boundingBoxDimensions,
|
boundingBoxDimensions,
|
||||||
isStaging,
|
isStaging,
|
||||||
aspectRatio,
|
aspectRatio,
|
||||||
@ -26,11 +27,15 @@ const selector = createSelector(
|
|||||||
|
|
||||||
const ParamBoundingBoxWidth = () => {
|
const ParamBoundingBoxWidth = () => {
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
const { boundingBoxDimensions, isStaging, aspectRatio } =
|
const { model, boundingBoxDimensions, isStaging, aspectRatio } =
|
||||||
useAppSelector(selector);
|
useAppSelector(selector);
|
||||||
|
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
|
const initial = ['sdxl', 'sdxl-refiner'].includes(model?.base_model as string)
|
||||||
|
? 1024
|
||||||
|
: 512;
|
||||||
|
|
||||||
const handleChangeHeight = (v: number) => {
|
const handleChangeHeight = (v: number) => {
|
||||||
dispatch(
|
dispatch(
|
||||||
setBoundingBoxDimensions({
|
setBoundingBoxDimensions({
|
||||||
@ -53,15 +58,15 @@ const ParamBoundingBoxWidth = () => {
|
|||||||
dispatch(
|
dispatch(
|
||||||
setBoundingBoxDimensions({
|
setBoundingBoxDimensions({
|
||||||
...boundingBoxDimensions,
|
...boundingBoxDimensions,
|
||||||
height: Math.floor(512),
|
height: Math.floor(initial),
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
if (aspectRatio) {
|
if (aspectRatio) {
|
||||||
const newWidth = roundToMultiple(512 * aspectRatio, 64);
|
const newWidth = roundToMultiple(initial * aspectRatio, 64);
|
||||||
dispatch(
|
dispatch(
|
||||||
setBoundingBoxDimensions({
|
setBoundingBoxDimensions({
|
||||||
width: newWidth,
|
width: newWidth,
|
||||||
height: Math.floor(512),
|
height: Math.floor(initial),
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -71,7 +76,7 @@ const ParamBoundingBoxWidth = () => {
|
|||||||
<IAISlider
|
<IAISlider
|
||||||
label={t('parameters.boundingBoxHeight')}
|
label={t('parameters.boundingBoxHeight')}
|
||||||
min={64}
|
min={64}
|
||||||
max={1024}
|
max={1536}
|
||||||
step={64}
|
step={64}
|
||||||
value={boundingBoxDimensions.height}
|
value={boundingBoxDimensions.height}
|
||||||
onChange={handleChangeHeight}
|
onChange={handleChangeHeight}
|
||||||
|
@ -1,17 +1,83 @@
|
|||||||
import { Flex, Spacer, Text } from '@chakra-ui/react';
|
import { Flex, Spacer, Text } from '@chakra-ui/react';
|
||||||
import { useAppDispatch } from 'app/store/storeHooks';
|
import { createSelector } from '@reduxjs/toolkit';
|
||||||
|
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||||
import IAIIconButton from 'common/components/IAIIconButton';
|
import IAIIconButton from 'common/components/IAIIconButton';
|
||||||
|
import { canvasSelector } from 'features/canvas/store/canvasSelectors';
|
||||||
import { flipBoundingBoxAxes } from 'features/canvas/store/canvasSlice';
|
import { flipBoundingBoxAxes } from 'features/canvas/store/canvasSlice';
|
||||||
|
import { generationSelector } from 'features/parameters/store/generationSelectors';
|
||||||
|
import {
|
||||||
|
setAspectRatio,
|
||||||
|
setShouldLockAspectRatio,
|
||||||
|
} from 'features/parameters/store/generationSlice';
|
||||||
|
import { useCallback } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
import { FaLock } from 'react-icons/fa';
|
||||||
import { MdOutlineSwapVert } from 'react-icons/md';
|
import { MdOutlineSwapVert } from 'react-icons/md';
|
||||||
import ParamAspectRatio from '../../Core/ParamAspectRatio';
|
import ParamAspectRatio, {
|
||||||
|
mappedAspectRatios,
|
||||||
|
} from '../../Core/ParamAspectRatio';
|
||||||
import ParamBoundingBoxHeight from './ParamBoundingBoxHeight';
|
import ParamBoundingBoxHeight from './ParamBoundingBoxHeight';
|
||||||
import ParamBoundingBoxWidth from './ParamBoundingBoxWidth';
|
import ParamBoundingBoxWidth from './ParamBoundingBoxWidth';
|
||||||
|
|
||||||
|
const sizeOptsSelector = createSelector(
|
||||||
|
[generationSelector, canvasSelector],
|
||||||
|
(generation, canvas) => {
|
||||||
|
const { shouldFitToWidthHeight, shouldLockAspectRatio } = generation;
|
||||||
|
const { boundingBoxDimensions } = canvas;
|
||||||
|
|
||||||
|
return {
|
||||||
|
shouldFitToWidthHeight,
|
||||||
|
shouldLockAspectRatio,
|
||||||
|
boundingBoxDimensions,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
export default function ParamBoundingBoxSize() {
|
export default function ParamBoundingBoxSize() {
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
|
const { shouldLockAspectRatio, boundingBoxDimensions } =
|
||||||
|
useAppSelector(sizeOptsSelector);
|
||||||
|
|
||||||
|
const handleLockRatio = useCallback(() => {
|
||||||
|
if (shouldLockAspectRatio) {
|
||||||
|
dispatch(setShouldLockAspectRatio(false));
|
||||||
|
if (
|
||||||
|
!mappedAspectRatios.includes(
|
||||||
|
boundingBoxDimensions.width / boundingBoxDimensions.height
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
dispatch(setAspectRatio(null));
|
||||||
|
} else {
|
||||||
|
dispatch(
|
||||||
|
setAspectRatio(
|
||||||
|
boundingBoxDimensions.width / boundingBoxDimensions.height
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
dispatch(setShouldLockAspectRatio(true));
|
||||||
|
dispatch(
|
||||||
|
setAspectRatio(
|
||||||
|
boundingBoxDimensions.width / boundingBoxDimensions.height
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}, [shouldLockAspectRatio, boundingBoxDimensions, dispatch]);
|
||||||
|
|
||||||
|
const handleToggleSize = useCallback(() => {
|
||||||
|
dispatch(flipBoundingBoxAxes());
|
||||||
|
dispatch(setAspectRatio(null));
|
||||||
|
if (shouldLockAspectRatio) {
|
||||||
|
dispatch(
|
||||||
|
setAspectRatio(
|
||||||
|
boundingBoxDimensions.height / boundingBoxDimensions.width
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}, [dispatch, shouldLockAspectRatio, boundingBoxDimensions]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Flex
|
<Flex
|
||||||
sx={{
|
sx={{
|
||||||
@ -20,7 +86,7 @@ export default function ParamBoundingBoxSize() {
|
|||||||
borderRadius: 4,
|
borderRadius: 4,
|
||||||
flexDirection: 'column',
|
flexDirection: 'column',
|
||||||
w: 'full',
|
w: 'full',
|
||||||
bg: 'base.150',
|
bg: 'base.100',
|
||||||
_dark: {
|
_dark: {
|
||||||
bg: 'base.750',
|
bg: 'base.750',
|
||||||
},
|
},
|
||||||
@ -47,7 +113,15 @@ export default function ParamBoundingBoxSize() {
|
|||||||
size="sm"
|
size="sm"
|
||||||
icon={<MdOutlineSwapVert />}
|
icon={<MdOutlineSwapVert />}
|
||||||
fontSize={20}
|
fontSize={20}
|
||||||
onClick={() => dispatch(flipBoundingBoxAxes())}
|
onClick={handleToggleSize}
|
||||||
|
/>
|
||||||
|
<IAIIconButton
|
||||||
|
tooltip={t('ui.lockRatio')}
|
||||||
|
aria-label={t('ui.lockRatio')}
|
||||||
|
size="sm"
|
||||||
|
icon={<FaLock />}
|
||||||
|
isChecked={shouldLockAspectRatio}
|
||||||
|
onClick={handleLockRatio}
|
||||||
/>
|
/>
|
||||||
</Flex>
|
</Flex>
|
||||||
<ParamBoundingBoxWidth />
|
<ParamBoundingBoxWidth />
|
||||||
|
@ -14,8 +14,9 @@ const selector = createSelector(
|
|||||||
[stateSelector, isStagingSelector],
|
[stateSelector, isStagingSelector],
|
||||||
({ canvas, generation }, isStaging) => {
|
({ canvas, generation }, isStaging) => {
|
||||||
const { boundingBoxDimensions } = canvas;
|
const { boundingBoxDimensions } = canvas;
|
||||||
const { aspectRatio } = generation;
|
const { model, aspectRatio } = generation;
|
||||||
return {
|
return {
|
||||||
|
model,
|
||||||
boundingBoxDimensions,
|
boundingBoxDimensions,
|
||||||
isStaging,
|
isStaging,
|
||||||
aspectRatio,
|
aspectRatio,
|
||||||
@ -26,9 +27,13 @@ const selector = createSelector(
|
|||||||
|
|
||||||
const ParamBoundingBoxWidth = () => {
|
const ParamBoundingBoxWidth = () => {
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
const { boundingBoxDimensions, isStaging, aspectRatio } =
|
const { model, boundingBoxDimensions, isStaging, aspectRatio } =
|
||||||
useAppSelector(selector);
|
useAppSelector(selector);
|
||||||
|
|
||||||
|
const initial = ['sdxl', 'sdxl-refiner'].includes(model?.base_model as string)
|
||||||
|
? 1024
|
||||||
|
: 512;
|
||||||
|
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
const handleChangeWidth = (v: number) => {
|
const handleChangeWidth = (v: number) => {
|
||||||
@ -53,14 +58,14 @@ const ParamBoundingBoxWidth = () => {
|
|||||||
dispatch(
|
dispatch(
|
||||||
setBoundingBoxDimensions({
|
setBoundingBoxDimensions({
|
||||||
...boundingBoxDimensions,
|
...boundingBoxDimensions,
|
||||||
width: Math.floor(512),
|
width: Math.floor(initial),
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
if (aspectRatio) {
|
if (aspectRatio) {
|
||||||
const newHeight = roundToMultiple(512 / aspectRatio, 64);
|
const newHeight = roundToMultiple(initial / aspectRatio, 64);
|
||||||
dispatch(
|
dispatch(
|
||||||
setBoundingBoxDimensions({
|
setBoundingBoxDimensions({
|
||||||
width: Math.floor(512),
|
width: Math.floor(initial),
|
||||||
height: newHeight,
|
height: newHeight,
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
@ -71,7 +76,7 @@ const ParamBoundingBoxWidth = () => {
|
|||||||
<IAISlider
|
<IAISlider
|
||||||
label={t('parameters.boundingBoxWidth')}
|
label={t('parameters.boundingBoxWidth')}
|
||||||
min={64}
|
min={64}
|
||||||
max={1024}
|
max={1536}
|
||||||
step={64}
|
step={64}
|
||||||
value={boundingBoxDimensions.width}
|
value={boundingBoxDimensions.width}
|
||||||
onChange={handleChangeWidth}
|
onChange={handleChangeWidth}
|
||||||
|
@ -0,0 +1,31 @@
|
|||||||
|
import { Divider, Flex } from '@chakra-ui/react';
|
||||||
|
import IAICollapse from 'common/components/IAICollapse';
|
||||||
|
import { memo } from 'react';
|
||||||
|
import { useTranslation } from 'react-i18next';
|
||||||
|
import SubParametersWrapper from '../../SubParametersWrapper';
|
||||||
|
import ParamCanvasCoherenceSteps from './CoherencePass/ParamCanvasCoherenceSteps';
|
||||||
|
import ParamCanvasCoherenceStrength from './CoherencePass/ParamCanvasCoherenceStrength';
|
||||||
|
import ParamMaskBlur from './MaskAdjustment/ParamMaskBlur';
|
||||||
|
import ParamMaskBlurMethod from './MaskAdjustment/ParamMaskBlurMethod';
|
||||||
|
|
||||||
|
const ParamCompositingSettingsCollapse = () => {
|
||||||
|
const { t } = useTranslation();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<IAICollapse label={t('parameters.compositingSettingsHeader')}>
|
||||||
|
<Flex sx={{ flexDirection: 'column', gap: 2 }}>
|
||||||
|
<SubParametersWrapper label={t('parameters.maskAdjustmentsHeader')}>
|
||||||
|
<ParamMaskBlur />
|
||||||
|
<ParamMaskBlurMethod />
|
||||||
|
</SubParametersWrapper>
|
||||||
|
<Divider />
|
||||||
|
<SubParametersWrapper label={t('parameters.coherencePassHeader')}>
|
||||||
|
<ParamCanvasCoherenceSteps />
|
||||||
|
<ParamCanvasCoherenceStrength />
|
||||||
|
</SubParametersWrapper>
|
||||||
|
</Flex>
|
||||||
|
</IAICollapse>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default memo(ParamCompositingSettingsCollapse);
|
@ -1,8 +1,9 @@
|
|||||||
import { Flex } from '@chakra-ui/react';
|
import { Divider, Flex } from '@chakra-ui/react';
|
||||||
import { memo } from 'react';
|
import { memo } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
import IAICollapse from 'common/components/IAICollapse';
|
import IAICollapse from 'common/components/IAICollapse';
|
||||||
|
import SubParametersWrapper from '../../SubParametersWrapper';
|
||||||
import ParamInfillMethod from './ParamInfillMethod';
|
import ParamInfillMethod from './ParamInfillMethod';
|
||||||
import ParamInfillTilesize from './ParamInfillTilesize';
|
import ParamInfillTilesize from './ParamInfillTilesize';
|
||||||
import ParamScaleBeforeProcessing from './ParamScaleBeforeProcessing';
|
import ParamScaleBeforeProcessing from './ParamScaleBeforeProcessing';
|
||||||
@ -15,11 +16,16 @@ const ParamInfillCollapse = () => {
|
|||||||
return (
|
return (
|
||||||
<IAICollapse label={t('parameters.infillScalingHeader')}>
|
<IAICollapse label={t('parameters.infillScalingHeader')}>
|
||||||
<Flex sx={{ gap: 2, flexDirection: 'column' }}>
|
<Flex sx={{ gap: 2, flexDirection: 'column' }}>
|
||||||
|
<SubParametersWrapper>
|
||||||
<ParamInfillMethod />
|
<ParamInfillMethod />
|
||||||
<ParamInfillTilesize />
|
<ParamInfillTilesize />
|
||||||
|
</SubParametersWrapper>
|
||||||
|
<Divider />
|
||||||
|
<SubParametersWrapper>
|
||||||
<ParamScaleBeforeProcessing />
|
<ParamScaleBeforeProcessing />
|
||||||
<ParamScaledWidth />
|
<ParamScaledWidth />
|
||||||
<ParamScaledHeight />
|
<ParamScaledHeight />
|
||||||
|
</SubParametersWrapper>
|
||||||
</Flex>
|
</Flex>
|
||||||
</IAICollapse>
|
</IAICollapse>
|
||||||
);
|
);
|
||||||
|
@ -5,16 +5,17 @@ import IAISlider from 'common/components/IAISlider';
|
|||||||
import { canvasSelector } from 'features/canvas/store/canvasSelectors';
|
import { canvasSelector } from 'features/canvas/store/canvasSelectors';
|
||||||
import { setScaledBoundingBoxDimensions } from 'features/canvas/store/canvasSlice';
|
import { setScaledBoundingBoxDimensions } from 'features/canvas/store/canvasSlice';
|
||||||
import { generationSelector } from 'features/parameters/store/generationSelectors';
|
import { generationSelector } from 'features/parameters/store/generationSelectors';
|
||||||
import { systemSelector } from 'features/system/store/systemSelectors';
|
|
||||||
import { memo } from 'react';
|
import { memo } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
const selector = createSelector(
|
const selector = createSelector(
|
||||||
[generationSelector, systemSelector, canvasSelector],
|
[generationSelector, canvasSelector],
|
||||||
(parameters, system, canvas) => {
|
(generation, canvas) => {
|
||||||
const { scaledBoundingBoxDimensions, boundingBoxScaleMethod } = canvas;
|
const { scaledBoundingBoxDimensions, boundingBoxScaleMethod } = canvas;
|
||||||
|
const { model } = generation;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
model,
|
||||||
scaledBoundingBoxDimensions,
|
scaledBoundingBoxDimensions,
|
||||||
isManual: boundingBoxScaleMethod === 'manual',
|
isManual: boundingBoxScaleMethod === 'manual',
|
||||||
};
|
};
|
||||||
@ -24,7 +25,12 @@ const selector = createSelector(
|
|||||||
|
|
||||||
const ParamScaledHeight = () => {
|
const ParamScaledHeight = () => {
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
const { isManual, scaledBoundingBoxDimensions } = useAppSelector(selector);
|
const { model, isManual, scaledBoundingBoxDimensions } =
|
||||||
|
useAppSelector(selector);
|
||||||
|
|
||||||
|
const initial = ['sdxl', 'sdxl-refiner'].includes(model?.base_model as string)
|
||||||
|
? 1024
|
||||||
|
: 512;
|
||||||
|
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
@ -41,7 +47,7 @@ const ParamScaledHeight = () => {
|
|||||||
dispatch(
|
dispatch(
|
||||||
setScaledBoundingBoxDimensions({
|
setScaledBoundingBoxDimensions({
|
||||||
...scaledBoundingBoxDimensions,
|
...scaledBoundingBoxDimensions,
|
||||||
height: Math.floor(512),
|
height: Math.floor(initial),
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
@ -51,7 +57,7 @@ const ParamScaledHeight = () => {
|
|||||||
isDisabled={!isManual}
|
isDisabled={!isManual}
|
||||||
label={t('parameters.scaledHeight')}
|
label={t('parameters.scaledHeight')}
|
||||||
min={64}
|
min={64}
|
||||||
max={1024}
|
max={1536}
|
||||||
step={64}
|
step={64}
|
||||||
value={scaledBoundingBoxDimensions.height}
|
value={scaledBoundingBoxDimensions.height}
|
||||||
onChange={handleChangeScaledHeight}
|
onChange={handleChangeScaledHeight}
|
||||||
|
@ -4,15 +4,18 @@ import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions';
|
|||||||
import IAISlider from 'common/components/IAISlider';
|
import IAISlider from 'common/components/IAISlider';
|
||||||
import { canvasSelector } from 'features/canvas/store/canvasSelectors';
|
import { canvasSelector } from 'features/canvas/store/canvasSelectors';
|
||||||
import { setScaledBoundingBoxDimensions } from 'features/canvas/store/canvasSlice';
|
import { setScaledBoundingBoxDimensions } from 'features/canvas/store/canvasSlice';
|
||||||
|
import { generationSelector } from 'features/parameters/store/generationSelectors';
|
||||||
import { memo } from 'react';
|
import { memo } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
const selector = createSelector(
|
const selector = createSelector(
|
||||||
[canvasSelector],
|
[canvasSelector, generationSelector],
|
||||||
(canvas) => {
|
(canvas, generation) => {
|
||||||
const { boundingBoxScaleMethod, scaledBoundingBoxDimensions } = canvas;
|
const { boundingBoxScaleMethod, scaledBoundingBoxDimensions } = canvas;
|
||||||
|
const { model } = generation;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
model,
|
||||||
scaledBoundingBoxDimensions,
|
scaledBoundingBoxDimensions,
|
||||||
isManual: boundingBoxScaleMethod === 'manual',
|
isManual: boundingBoxScaleMethod === 'manual',
|
||||||
};
|
};
|
||||||
@ -22,7 +25,12 @@ const selector = createSelector(
|
|||||||
|
|
||||||
const ParamScaledWidth = () => {
|
const ParamScaledWidth = () => {
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
const { isManual, scaledBoundingBoxDimensions } = useAppSelector(selector);
|
const { model, isManual, scaledBoundingBoxDimensions } =
|
||||||
|
useAppSelector(selector);
|
||||||
|
|
||||||
|
const initial = ['sdxl', 'sdxl-refiner'].includes(model?.base_model as string)
|
||||||
|
? 1024
|
||||||
|
: 512;
|
||||||
|
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
@ -39,7 +47,7 @@ const ParamScaledWidth = () => {
|
|||||||
dispatch(
|
dispatch(
|
||||||
setScaledBoundingBoxDimensions({
|
setScaledBoundingBoxDimensions({
|
||||||
...scaledBoundingBoxDimensions,
|
...scaledBoundingBoxDimensions,
|
||||||
width: Math.floor(512),
|
width: Math.floor(initial),
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
@ -49,7 +57,7 @@ const ParamScaledWidth = () => {
|
|||||||
isDisabled={!isManual}
|
isDisabled={!isManual}
|
||||||
label={t('parameters.scaledWidth')}
|
label={t('parameters.scaledWidth')}
|
||||||
min={64}
|
min={64}
|
||||||
max={1024}
|
max={1536}
|
||||||
step={64}
|
step={64}
|
||||||
value={scaledBoundingBoxDimensions.width}
|
value={scaledBoundingBoxDimensions.width}
|
||||||
onChange={handleChangeScaledWidth}
|
onChange={handleChangeScaledWidth}
|
||||||
|
@ -1,21 +0,0 @@
|
|||||||
import { Flex } from '@chakra-ui/react';
|
|
||||||
import IAICollapse from 'common/components/IAICollapse';
|
|
||||||
import { memo } from 'react';
|
|
||||||
import { useTranslation } from 'react-i18next';
|
|
||||||
import ParamMaskBlur from './ParamMaskBlur';
|
|
||||||
import ParamMaskBlurMethod from './ParamMaskBlurMethod';
|
|
||||||
|
|
||||||
const ParamMaskAdjustmentCollapse = () => {
|
|
||||||
const { t } = useTranslation();
|
|
||||||
|
|
||||||
return (
|
|
||||||
<IAICollapse label={t('parameters.maskAdjustmentsHeader')}>
|
|
||||||
<Flex sx={{ flexDirection: 'column', gap: 2 }}>
|
|
||||||
<ParamMaskBlur />
|
|
||||||
<ParamMaskBlurMethod />
|
|
||||||
</Flex>
|
|
||||||
</IAICollapse>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default memo(ParamMaskAdjustmentCollapse);
|
|
@ -1,21 +0,0 @@
|
|||||||
import { Flex } from '@chakra-ui/react';
|
|
||||||
import IAICollapse from 'common/components/IAICollapse';
|
|
||||||
import { memo } from 'react';
|
|
||||||
import { useTranslation } from 'react-i18next';
|
|
||||||
import ParamCanvasCoherenceSteps from './ParamCanvasCoherenceSteps';
|
|
||||||
import ParamCanvasCoherenceStrength from './ParamCanvasCoherenceStrength';
|
|
||||||
|
|
||||||
const ParamCanvasCoherencePassCollapse = () => {
|
|
||||||
const { t } = useTranslation();
|
|
||||||
|
|
||||||
return (
|
|
||||||
<IAICollapse label={t('parameters.coherencePassHeader')}>
|
|
||||||
<Flex sx={{ flexDirection: 'column', gap: 2, paddingBottom: 2 }}>
|
|
||||||
<ParamCanvasCoherenceSteps />
|
|
||||||
<ParamCanvasCoherenceStrength />
|
|
||||||
</Flex>
|
|
||||||
</IAICollapse>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default memo(ParamCanvasCoherencePassCollapse);
|
|
@ -2,7 +2,10 @@ import { ButtonGroup, Flex } from '@chakra-ui/react';
|
|||||||
import { RootState } from 'app/store/store';
|
import { RootState } from 'app/store/store';
|
||||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||||
import IAIButton from 'common/components/IAIButton';
|
import IAIButton from 'common/components/IAIButton';
|
||||||
import { setAspectRatio } from 'features/parameters/store/generationSlice';
|
import {
|
||||||
|
setAspectRatio,
|
||||||
|
setShouldLockAspectRatio,
|
||||||
|
} from 'features/parameters/store/generationSlice';
|
||||||
import { activeTabNameSelector } from '../../../../ui/store/uiSelectors';
|
import { activeTabNameSelector } from '../../../../ui/store/uiSelectors';
|
||||||
|
|
||||||
const aspectRatios = [
|
const aspectRatios = [
|
||||||
@ -12,6 +15,8 @@ const aspectRatios = [
|
|||||||
{ name: '1:1', value: 1 / 1 },
|
{ name: '1:1', value: 1 / 1 },
|
||||||
];
|
];
|
||||||
|
|
||||||
|
export const mappedAspectRatios = aspectRatios.map((ar) => ar.value);
|
||||||
|
|
||||||
export default function ParamAspectRatio() {
|
export default function ParamAspectRatio() {
|
||||||
const aspectRatio = useAppSelector(
|
const aspectRatio = useAppSelector(
|
||||||
(state: RootState) => state.generation.aspectRatio
|
(state: RootState) => state.generation.aspectRatio
|
||||||
@ -34,7 +39,10 @@ export default function ParamAspectRatio() {
|
|||||||
isDisabled={
|
isDisabled={
|
||||||
activeTabName === 'img2img' ? !shouldFitToWidthHeight : false
|
activeTabName === 'img2img' ? !shouldFitToWidthHeight : false
|
||||||
}
|
}
|
||||||
onClick={() => dispatch(setAspectRatio(ratio.value))}
|
onClick={() => {
|
||||||
|
dispatch(setAspectRatio(ratio.value));
|
||||||
|
dispatch(setShouldLockAspectRatio(false));
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
{ratio.name}
|
{ratio.name}
|
||||||
</IAIButton>
|
</IAIButton>
|
||||||
|
@ -11,16 +11,15 @@ import { useTranslation } from 'react-i18next';
|
|||||||
const selector = createSelector(
|
const selector = createSelector(
|
||||||
[stateSelector],
|
[stateSelector],
|
||||||
({ generation, hotkeys, config }) => {
|
({ generation, hotkeys, config }) => {
|
||||||
const { initial, min, sliderMax, inputMax, fineStep, coarseStep } =
|
const { min, sliderMax, inputMax, fineStep, coarseStep } = config.sd.height;
|
||||||
config.sd.height;
|
const { model, height } = generation;
|
||||||
const { height } = generation;
|
|
||||||
const { aspectRatio } = generation;
|
const { aspectRatio } = generation;
|
||||||
|
|
||||||
const step = hotkeys.shift ? fineStep : coarseStep;
|
const step = hotkeys.shift ? fineStep : coarseStep;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
model,
|
||||||
height,
|
height,
|
||||||
initial,
|
|
||||||
min,
|
min,
|
||||||
sliderMax,
|
sliderMax,
|
||||||
inputMax,
|
inputMax,
|
||||||
@ -37,11 +36,15 @@ type ParamHeightProps = Omit<
|
|||||||
>;
|
>;
|
||||||
|
|
||||||
const ParamHeight = (props: ParamHeightProps) => {
|
const ParamHeight = (props: ParamHeightProps) => {
|
||||||
const { height, initial, min, sliderMax, inputMax, step, aspectRatio } =
|
const { model, height, min, sliderMax, inputMax, step, aspectRatio } =
|
||||||
useAppSelector(selector);
|
useAppSelector(selector);
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
|
const initial = ['sdxl', 'sdxl-refiner'].includes(model?.base_model as string)
|
||||||
|
? 1024
|
||||||
|
: 512;
|
||||||
|
|
||||||
const handleChange = useCallback(
|
const handleChange = useCallback(
|
||||||
(v: number) => {
|
(v: number) => {
|
||||||
dispatch(setHeight(v));
|
dispatch(setHeight(v));
|
||||||
|
@ -1,22 +1,71 @@
|
|||||||
import { Flex, Spacer, Text } from '@chakra-ui/react';
|
import { Flex, Spacer, Text } from '@chakra-ui/react';
|
||||||
import { RootState } from 'app/store/store';
|
import { createSelector } from '@reduxjs/toolkit';
|
||||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||||
import IAIIconButton from 'common/components/IAIIconButton';
|
import IAIIconButton from 'common/components/IAIIconButton';
|
||||||
import { toggleSize } from 'features/parameters/store/generationSlice';
|
import { generationSelector } from 'features/parameters/store/generationSelectors';
|
||||||
|
import {
|
||||||
|
setAspectRatio,
|
||||||
|
setShouldLockAspectRatio,
|
||||||
|
toggleSize,
|
||||||
|
} from 'features/parameters/store/generationSlice';
|
||||||
|
import { useCallback } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
import { FaLock } from 'react-icons/fa';
|
||||||
import { MdOutlineSwapVert } from 'react-icons/md';
|
import { MdOutlineSwapVert } from 'react-icons/md';
|
||||||
import ParamAspectRatio from './ParamAspectRatio';
|
import { activeTabNameSelector } from '../../../../ui/store/uiSelectors';
|
||||||
|
import ParamAspectRatio, { mappedAspectRatios } from './ParamAspectRatio';
|
||||||
import ParamHeight from './ParamHeight';
|
import ParamHeight from './ParamHeight';
|
||||||
import ParamWidth from './ParamWidth';
|
import ParamWidth from './ParamWidth';
|
||||||
import { activeTabNameSelector } from '../../../../ui/store/uiSelectors';
|
|
||||||
|
const sizeOptsSelector = createSelector(
|
||||||
|
[generationSelector, activeTabNameSelector],
|
||||||
|
(generation, activeTabName) => {
|
||||||
|
const { shouldFitToWidthHeight, shouldLockAspectRatio, width, height } =
|
||||||
|
generation;
|
||||||
|
|
||||||
|
return {
|
||||||
|
activeTabName,
|
||||||
|
shouldFitToWidthHeight,
|
||||||
|
shouldLockAspectRatio,
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
export default function ParamSize() {
|
export default function ParamSize() {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
const shouldFitToWidthHeight = useAppSelector(
|
const {
|
||||||
(state: RootState) => state.generation.shouldFitToWidthHeight
|
activeTabName,
|
||||||
);
|
shouldFitToWidthHeight,
|
||||||
const activeTabName = useAppSelector(activeTabNameSelector);
|
shouldLockAspectRatio,
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
} = useAppSelector(sizeOptsSelector);
|
||||||
|
|
||||||
|
const handleLockRatio = useCallback(() => {
|
||||||
|
if (shouldLockAspectRatio) {
|
||||||
|
dispatch(setShouldLockAspectRatio(false));
|
||||||
|
if (!mappedAspectRatios.includes(width / height)) {
|
||||||
|
dispatch(setAspectRatio(null));
|
||||||
|
} else {
|
||||||
|
dispatch(setAspectRatio(width / height));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
dispatch(setShouldLockAspectRatio(true));
|
||||||
|
dispatch(setAspectRatio(width / height));
|
||||||
|
}
|
||||||
|
}, [shouldLockAspectRatio, width, height, dispatch]);
|
||||||
|
|
||||||
|
const handleToggleSize = useCallback(() => {
|
||||||
|
dispatch(toggleSize());
|
||||||
|
dispatch(setAspectRatio(null));
|
||||||
|
if (shouldLockAspectRatio) {
|
||||||
|
dispatch(setAspectRatio(height / width));
|
||||||
|
}
|
||||||
|
}, [dispatch, shouldLockAspectRatio, width, height]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Flex
|
<Flex
|
||||||
sx={{
|
sx={{
|
||||||
@ -55,7 +104,18 @@ export default function ParamSize() {
|
|||||||
isDisabled={
|
isDisabled={
|
||||||
activeTabName === 'img2img' ? !shouldFitToWidthHeight : false
|
activeTabName === 'img2img' ? !shouldFitToWidthHeight : false
|
||||||
}
|
}
|
||||||
onClick={() => dispatch(toggleSize())}
|
onClick={handleToggleSize}
|
||||||
|
/>
|
||||||
|
<IAIIconButton
|
||||||
|
tooltip={t('ui.lockRatio')}
|
||||||
|
aria-label={t('ui.lockRatio')}
|
||||||
|
size="sm"
|
||||||
|
icon={<FaLock />}
|
||||||
|
isChecked={shouldLockAspectRatio}
|
||||||
|
isDisabled={
|
||||||
|
activeTabName === 'img2img' ? !shouldFitToWidthHeight : false
|
||||||
|
}
|
||||||
|
onClick={handleLockRatio}
|
||||||
/>
|
/>
|
||||||
</Flex>
|
</Flex>
|
||||||
<Flex gap={2} alignItems="center">
|
<Flex gap={2} alignItems="center">
|
||||||
|
@ -11,15 +11,14 @@ import { useTranslation } from 'react-i18next';
|
|||||||
const selector = createSelector(
|
const selector = createSelector(
|
||||||
[stateSelector],
|
[stateSelector],
|
||||||
({ generation, hotkeys, config }) => {
|
({ generation, hotkeys, config }) => {
|
||||||
const { initial, min, sliderMax, inputMax, fineStep, coarseStep } =
|
const { min, sliderMax, inputMax, fineStep, coarseStep } = config.sd.width;
|
||||||
config.sd.width;
|
const { model, width, aspectRatio } = generation;
|
||||||
const { width, aspectRatio } = generation;
|
|
||||||
|
|
||||||
const step = hotkeys.shift ? fineStep : coarseStep;
|
const step = hotkeys.shift ? fineStep : coarseStep;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
model,
|
||||||
width,
|
width,
|
||||||
initial,
|
|
||||||
min,
|
min,
|
||||||
sliderMax,
|
sliderMax,
|
||||||
inputMax,
|
inputMax,
|
||||||
@ -33,11 +32,15 @@ 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, aspectRatio } =
|
const { model, width, min, sliderMax, inputMax, step, aspectRatio } =
|
||||||
useAppSelector(selector);
|
useAppSelector(selector);
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
|
const initial = ['sdxl', 'sdxl-refiner'].includes(model?.base_model as string)
|
||||||
|
? 1024
|
||||||
|
: 512;
|
||||||
|
|
||||||
const handleChange = useCallback(
|
const handleChange = useCallback(
|
||||||
(v: number) => {
|
(v: number) => {
|
||||||
dispatch(setWidth(v));
|
dispatch(setWidth(v));
|
||||||
|
@ -6,6 +6,7 @@ import IAISlider from 'common/components/IAISlider';
|
|||||||
import { setImg2imgStrength } from 'features/parameters/store/generationSlice';
|
import { setImg2imgStrength } from 'features/parameters/store/generationSlice';
|
||||||
import { memo, useCallback } from 'react';
|
import { memo, useCallback } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
import SubParametersWrapper from '../SubParametersWrapper';
|
||||||
|
|
||||||
const selector = createSelector(
|
const selector = createSelector(
|
||||||
[stateSelector],
|
[stateSelector],
|
||||||
@ -44,6 +45,7 @@ const ImageToImageStrength = () => {
|
|||||||
}, [dispatch, initial]);
|
}, [dispatch, initial]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
<SubParametersWrapper>
|
||||||
<IAISlider
|
<IAISlider
|
||||||
label={`${t('parameters.denoisingStrength')}`}
|
label={`${t('parameters.denoisingStrength')}`}
|
||||||
step={step}
|
step={step}
|
||||||
@ -58,6 +60,7 @@ const ImageToImageStrength = () => {
|
|||||||
withReset
|
withReset
|
||||||
sliderNumberInputProps={{ max: inputMax }}
|
sliderNumberInputProps={{ max: inputMax }}
|
||||||
/>
|
/>
|
||||||
|
</SubParametersWrapper>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -0,0 +1,39 @@
|
|||||||
|
import { Flex, Text } from '@chakra-ui/react';
|
||||||
|
import { ReactNode, memo } from 'react';
|
||||||
|
|
||||||
|
type SubParameterWrapperProps = {
|
||||||
|
children: ReactNode | ReactNode[];
|
||||||
|
label?: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
const SubParametersWrapper = (props: SubParameterWrapperProps) => (
|
||||||
|
<Flex
|
||||||
|
sx={{
|
||||||
|
flexDir: 'column',
|
||||||
|
gap: 2,
|
||||||
|
bg: 'base.100',
|
||||||
|
px: 4,
|
||||||
|
pt: 2,
|
||||||
|
pb: 4,
|
||||||
|
borderRadius: 'base',
|
||||||
|
_dark: {
|
||||||
|
bg: 'base.750',
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{props.label && (
|
||||||
|
<Text
|
||||||
|
fontSize="sm"
|
||||||
|
fontWeight="bold"
|
||||||
|
sx={{ color: 'base.600', _dark: { color: 'base.300' } }}
|
||||||
|
>
|
||||||
|
{props.label}
|
||||||
|
</Text>
|
||||||
|
)}
|
||||||
|
{props.children}
|
||||||
|
</Flex>
|
||||||
|
);
|
||||||
|
|
||||||
|
SubParametersWrapper.displayName = 'SubSettingsWrapper';
|
||||||
|
|
||||||
|
export default memo(SubParametersWrapper);
|
@ -62,6 +62,7 @@ export interface GenerationState {
|
|||||||
shouldUseCpuNoise: boolean;
|
shouldUseCpuNoise: boolean;
|
||||||
shouldShowAdvancedOptions: boolean;
|
shouldShowAdvancedOptions: boolean;
|
||||||
aspectRatio: number | null;
|
aspectRatio: number | null;
|
||||||
|
shouldLockAspectRatio: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const initialGenerationState: GenerationState = {
|
export const initialGenerationState: GenerationState = {
|
||||||
@ -101,6 +102,7 @@ export const initialGenerationState: GenerationState = {
|
|||||||
shouldUseCpuNoise: true,
|
shouldUseCpuNoise: true,
|
||||||
shouldShowAdvancedOptions: false,
|
shouldShowAdvancedOptions: false,
|
||||||
aspectRatio: null,
|
aspectRatio: null,
|
||||||
|
shouldLockAspectRatio: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
const initialState: GenerationState = initialGenerationState;
|
const initialState: GenerationState = initialGenerationState;
|
||||||
@ -272,6 +274,9 @@ export const generationSlice = createSlice({
|
|||||||
state.height = roundToMultiple(state.width / newAspectRatio, 8);
|
state.height = roundToMultiple(state.width / newAspectRatio, 8);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
setShouldLockAspectRatio: (state, action: PayloadAction<boolean>) => {
|
||||||
|
state.shouldLockAspectRatio = action.payload;
|
||||||
|
},
|
||||||
},
|
},
|
||||||
extraReducers: (builder) => {
|
extraReducers: (builder) => {
|
||||||
builder.addCase(configChanged, (state, action) => {
|
builder.addCase(configChanged, (state, action) => {
|
||||||
@ -342,6 +347,7 @@ export const {
|
|||||||
shouldUseCpuNoiseChanged,
|
shouldUseCpuNoiseChanged,
|
||||||
setShouldShowAdvancedOptions,
|
setShouldShowAdvancedOptions,
|
||||||
setAspectRatio,
|
setAspectRatio,
|
||||||
|
setShouldLockAspectRatio,
|
||||||
vaePrecisionChanged,
|
vaePrecisionChanged,
|
||||||
} = generationSlice.actions;
|
} = generationSlice.actions;
|
||||||
|
|
||||||
|
@ -3,6 +3,7 @@ import { stateSelector } from 'app/store/store';
|
|||||||
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 from 'common/components/IAISlider';
|
import IAISlider from 'common/components/IAISlider';
|
||||||
|
import SubParametersWrapper from 'features/parameters/components/Parameters/SubParametersWrapper';
|
||||||
import { memo, useCallback } from 'react';
|
import { memo, useCallback } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { setSDXLImg2ImgDenoisingStrength } from '../store/sdxlSlice';
|
import { setSDXLImg2ImgDenoisingStrength } from '../store/sdxlSlice';
|
||||||
@ -34,6 +35,7 @@ const ParamSDXLImg2ImgDenoisingStrength = () => {
|
|||||||
}, [dispatch]);
|
}, [dispatch]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
<SubParametersWrapper>
|
||||||
<IAISlider
|
<IAISlider
|
||||||
label={`${t('parameters.denoisingStrength')}`}
|
label={`${t('parameters.denoisingStrength')}`}
|
||||||
step={0.01}
|
step={0.01}
|
||||||
@ -47,6 +49,7 @@ const ParamSDXLImg2ImgDenoisingStrength = () => {
|
|||||||
withSliderMarks
|
withSliderMarks
|
||||||
withReset
|
withReset
|
||||||
/>
|
/>
|
||||||
|
</SubParametersWrapper>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -4,6 +4,7 @@ import { stateSelector } from 'app/store/store';
|
|||||||
import { useAppSelector } from 'app/store/storeHooks';
|
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 { memo } from 'react';
|
||||||
import ParamSDXLRefinerCFGScale from './SDXLRefiner/ParamSDXLRefinerCFGScale';
|
import ParamSDXLRefinerCFGScale from './SDXLRefiner/ParamSDXLRefinerCFGScale';
|
||||||
import ParamSDXLRefinerModelSelect from './SDXLRefiner/ParamSDXLRefinerModelSelect';
|
import ParamSDXLRefinerModelSelect from './SDXLRefiner/ParamSDXLRefinerModelSelect';
|
||||||
import ParamSDXLRefinerNegativeAestheticScore from './SDXLRefiner/ParamSDXLRefinerNegativeAestheticScore';
|
import ParamSDXLRefinerNegativeAestheticScore from './SDXLRefiner/ParamSDXLRefinerNegativeAestheticScore';
|
||||||
@ -12,7 +13,6 @@ import ParamSDXLRefinerScheduler from './SDXLRefiner/ParamSDXLRefinerScheduler';
|
|||||||
import ParamSDXLRefinerStart from './SDXLRefiner/ParamSDXLRefinerStart';
|
import ParamSDXLRefinerStart from './SDXLRefiner/ParamSDXLRefinerStart';
|
||||||
import ParamSDXLRefinerSteps from './SDXLRefiner/ParamSDXLRefinerSteps';
|
import ParamSDXLRefinerSteps from './SDXLRefiner/ParamSDXLRefinerSteps';
|
||||||
import ParamUseSDXLRefiner from './SDXLRefiner/ParamUseSDXLRefiner';
|
import ParamUseSDXLRefiner from './SDXLRefiner/ParamUseSDXLRefiner';
|
||||||
import { memo } from 'react';
|
|
||||||
|
|
||||||
const selector = createSelector(
|
const selector = createSelector(
|
||||||
stateSelector,
|
stateSelector,
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
import ParamDynamicPromptsCollapse from 'features/dynamicPrompts/components/ParamDynamicPromptsCollapse';
|
import ParamDynamicPromptsCollapse from 'features/dynamicPrompts/components/ParamDynamicPromptsCollapse';
|
||||||
import ParamLoraCollapse from 'features/lora/components/ParamLoraCollapse';
|
import ParamLoraCollapse from 'features/lora/components/ParamLoraCollapse';
|
||||||
|
import ParamCompositingSettingsCollapse from 'features/parameters/components/Parameters/Canvas/Compositing/ParamCompositingSettingsCollapse';
|
||||||
import ParamInfillAndScalingCollapse from 'features/parameters/components/Parameters/Canvas/InfillAndScaling/ParamInfillAndScalingCollapse';
|
import ParamInfillAndScalingCollapse from 'features/parameters/components/Parameters/Canvas/InfillAndScaling/ParamInfillAndScalingCollapse';
|
||||||
import ParamMaskAdjustmentCollapse from 'features/parameters/components/Parameters/Canvas/MaskAdjustment/ParamMaskAdjustmentCollapse';
|
|
||||||
import ParamCanvasCoherencePassCollapse from 'features/parameters/components/Parameters/Canvas/SeamPainting/ParamCanvasCoherencePassCollapse';
|
|
||||||
import ParamControlNetCollapse from 'features/parameters/components/Parameters/ControlNet/ParamControlNetCollapse';
|
import ParamControlNetCollapse from 'features/parameters/components/Parameters/ControlNet/ParamControlNetCollapse';
|
||||||
import ParamNoiseCollapse from 'features/parameters/components/Parameters/Noise/ParamNoiseCollapse';
|
import ParamNoiseCollapse from 'features/parameters/components/Parameters/Noise/ParamNoiseCollapse';
|
||||||
import ParamSeamlessCollapse from 'features/parameters/components/Parameters/Seamless/ParamSeamlessCollapse';
|
import ParamSeamlessCollapse from 'features/parameters/components/Parameters/Seamless/ParamSeamlessCollapse';
|
||||||
@ -20,9 +19,8 @@ export default function SDXLUnifiedCanvasTabParameters() {
|
|||||||
<ParamLoraCollapse />
|
<ParamLoraCollapse />
|
||||||
<ParamDynamicPromptsCollapse />
|
<ParamDynamicPromptsCollapse />
|
||||||
<ParamNoiseCollapse />
|
<ParamNoiseCollapse />
|
||||||
<ParamMaskAdjustmentCollapse />
|
|
||||||
<ParamInfillAndScalingCollapse />
|
<ParamInfillAndScalingCollapse />
|
||||||
<ParamCanvasCoherencePassCollapse />
|
<ParamCompositingSettingsCollapse />
|
||||||
<ParamSeamlessCollapse />
|
<ParamSeamlessCollapse />
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
@ -30,6 +30,7 @@ import {
|
|||||||
shouldUseWatermarkerChanged,
|
shouldUseWatermarkerChanged,
|
||||||
} from 'features/system/store/systemSlice';
|
} from 'features/system/store/systemSlice';
|
||||||
import {
|
import {
|
||||||
|
setShouldAutoChangeDimensions,
|
||||||
setShouldShowProgressInViewer,
|
setShouldShowProgressInViewer,
|
||||||
setShouldUseSliders,
|
setShouldUseSliders,
|
||||||
} from 'features/ui/store/uiSlice';
|
} from 'features/ui/store/uiSlice';
|
||||||
@ -68,7 +69,11 @@ const selector = createSelector(
|
|||||||
shouldUseWatermarker,
|
shouldUseWatermarker,
|
||||||
} = system;
|
} = system;
|
||||||
|
|
||||||
const { shouldUseSliders, shouldShowProgressInViewer } = ui;
|
const {
|
||||||
|
shouldUseSliders,
|
||||||
|
shouldShowProgressInViewer,
|
||||||
|
shouldAutoChangeDimensions,
|
||||||
|
} = ui;
|
||||||
|
|
||||||
const { shouldShowAdvancedOptions } = generation;
|
const { shouldShowAdvancedOptions } = generation;
|
||||||
|
|
||||||
@ -83,6 +88,7 @@ const selector = createSelector(
|
|||||||
shouldShowAdvancedOptions,
|
shouldShowAdvancedOptions,
|
||||||
shouldUseNSFWChecker,
|
shouldUseNSFWChecker,
|
||||||
shouldUseWatermarker,
|
shouldUseWatermarker,
|
||||||
|
shouldAutoChangeDimensions,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -158,6 +164,7 @@ const SettingsModal = ({ children, config }: SettingsModalProps) => {
|
|||||||
shouldShowAdvancedOptions,
|
shouldShowAdvancedOptions,
|
||||||
shouldUseNSFWChecker,
|
shouldUseNSFWChecker,
|
||||||
shouldUseWatermarker,
|
shouldUseWatermarker,
|
||||||
|
shouldAutoChangeDimensions,
|
||||||
} = useAppSelector(selector);
|
} = useAppSelector(selector);
|
||||||
|
|
||||||
const handleClickResetWebUI = useCallback(() => {
|
const handleClickResetWebUI = useCallback(() => {
|
||||||
@ -297,6 +304,13 @@ const SettingsModal = ({ children, config }: SettingsModalProps) => {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
<SettingSwitch
|
||||||
|
label={t('settings.autoChangeDimensions')}
|
||||||
|
isChecked={shouldAutoChangeDimensions}
|
||||||
|
onChange={(e: ChangeEvent<HTMLInputElement>) =>
|
||||||
|
dispatch(setShouldAutoChangeDimensions(e.target.checked))
|
||||||
|
}
|
||||||
|
/>
|
||||||
{shouldShowLocalizationToggle && (
|
{shouldShowLocalizationToggle && (
|
||||||
<IAIMantineSelect
|
<IAIMantineSelect
|
||||||
disabled={!isLocalizationEnabled}
|
disabled={!isLocalizationEnabled}
|
||||||
|
@ -1,9 +1,8 @@
|
|||||||
import ParamDynamicPromptsCollapse from 'features/dynamicPrompts/components/ParamDynamicPromptsCollapse';
|
import ParamDynamicPromptsCollapse from 'features/dynamicPrompts/components/ParamDynamicPromptsCollapse';
|
||||||
import ParamLoraCollapse from 'features/lora/components/ParamLoraCollapse';
|
import ParamLoraCollapse from 'features/lora/components/ParamLoraCollapse';
|
||||||
import ParamAdvancedCollapse from 'features/parameters/components/Parameters/Advanced/ParamAdvancedCollapse';
|
import ParamAdvancedCollapse from 'features/parameters/components/Parameters/Advanced/ParamAdvancedCollapse';
|
||||||
|
import ParamCompositingSettingsCollapse from 'features/parameters/components/Parameters/Canvas/Compositing/ParamCompositingSettingsCollapse';
|
||||||
import ParamInfillAndScalingCollapse from 'features/parameters/components/Parameters/Canvas/InfillAndScaling/ParamInfillAndScalingCollapse';
|
import ParamInfillAndScalingCollapse from 'features/parameters/components/Parameters/Canvas/InfillAndScaling/ParamInfillAndScalingCollapse';
|
||||||
import ParamMaskAdjustmentCollapse from 'features/parameters/components/Parameters/Canvas/MaskAdjustment/ParamMaskAdjustmentCollapse';
|
|
||||||
import ParamCanvasCoherencePassCollapse from 'features/parameters/components/Parameters/Canvas/SeamPainting/ParamCanvasCoherencePassCollapse';
|
|
||||||
import ParamControlNetCollapse from 'features/parameters/components/Parameters/ControlNet/ParamControlNetCollapse';
|
import ParamControlNetCollapse from 'features/parameters/components/Parameters/ControlNet/ParamControlNetCollapse';
|
||||||
import ParamPromptArea from 'features/parameters/components/Parameters/Prompt/ParamPromptArea';
|
import ParamPromptArea from 'features/parameters/components/Parameters/Prompt/ParamPromptArea';
|
||||||
import ParamSeamlessCollapse from 'features/parameters/components/Parameters/Seamless/ParamSeamlessCollapse';
|
import ParamSeamlessCollapse from 'features/parameters/components/Parameters/Seamless/ParamSeamlessCollapse';
|
||||||
@ -20,9 +19,8 @@ const UnifiedCanvasParameters = () => {
|
|||||||
<ParamLoraCollapse />
|
<ParamLoraCollapse />
|
||||||
<ParamDynamicPromptsCollapse />
|
<ParamDynamicPromptsCollapse />
|
||||||
<ParamSymmetryCollapse />
|
<ParamSymmetryCollapse />
|
||||||
<ParamMaskAdjustmentCollapse />
|
|
||||||
<ParamInfillAndScalingCollapse />
|
<ParamInfillAndScalingCollapse />
|
||||||
<ParamCanvasCoherencePassCollapse />
|
<ParamCompositingSettingsCollapse />
|
||||||
<ParamSeamlessCollapse />
|
<ParamSeamlessCollapse />
|
||||||
<ParamAdvancedCollapse />
|
<ParamAdvancedCollapse />
|
||||||
</>
|
</>
|
||||||
|
@ -15,6 +15,7 @@ export const initialUIState: UIState = {
|
|||||||
shouldHidePreview: false,
|
shouldHidePreview: false,
|
||||||
shouldShowProgressInViewer: true,
|
shouldShowProgressInViewer: true,
|
||||||
shouldShowEmbeddingPicker: false,
|
shouldShowEmbeddingPicker: false,
|
||||||
|
shouldAutoChangeDimensions: false,
|
||||||
favoriteSchedulers: [],
|
favoriteSchedulers: [],
|
||||||
globalContextMenuCloseTrigger: 0,
|
globalContextMenuCloseTrigger: 0,
|
||||||
panels: {},
|
panels: {},
|
||||||
@ -57,6 +58,9 @@ export const uiSlice = createSlice({
|
|||||||
toggleEmbeddingPicker: (state) => {
|
toggleEmbeddingPicker: (state) => {
|
||||||
state.shouldShowEmbeddingPicker = !state.shouldShowEmbeddingPicker;
|
state.shouldShowEmbeddingPicker = !state.shouldShowEmbeddingPicker;
|
||||||
},
|
},
|
||||||
|
setShouldAutoChangeDimensions: (state, action: PayloadAction<boolean>) => {
|
||||||
|
state.shouldAutoChangeDimensions = action.payload;
|
||||||
|
},
|
||||||
contextMenusClosed: (state) => {
|
contextMenusClosed: (state) => {
|
||||||
state.globalContextMenuCloseTrigger += 1;
|
state.globalContextMenuCloseTrigger += 1;
|
||||||
},
|
},
|
||||||
@ -84,6 +88,7 @@ export const {
|
|||||||
setShouldShowProgressInViewer,
|
setShouldShowProgressInViewer,
|
||||||
favoriteSchedulersChanged,
|
favoriteSchedulersChanged,
|
||||||
toggleEmbeddingPicker,
|
toggleEmbeddingPicker,
|
||||||
|
setShouldAutoChangeDimensions,
|
||||||
contextMenusClosed,
|
contextMenusClosed,
|
||||||
panelsChanged,
|
panelsChanged,
|
||||||
} = uiSlice.actions;
|
} = uiSlice.actions;
|
||||||
|
@ -21,6 +21,7 @@ export interface UIState {
|
|||||||
shouldHidePreview: boolean;
|
shouldHidePreview: boolean;
|
||||||
shouldShowProgressInViewer: boolean;
|
shouldShowProgressInViewer: boolean;
|
||||||
shouldShowEmbeddingPicker: boolean;
|
shouldShowEmbeddingPicker: boolean;
|
||||||
|
shouldAutoChangeDimensions: boolean;
|
||||||
favoriteSchedulers: SchedulerParam[];
|
favoriteSchedulers: SchedulerParam[];
|
||||||
globalContextMenuCloseTrigger: number;
|
globalContextMenuCloseTrigger: number;
|
||||||
panels: Record<string, string>;
|
panels: Record<string, string>;
|
||||||
|
Loading…
Reference in New Issue
Block a user