Fixes inpainting + code cleanup

This commit is contained in:
psychedelicious 2022-11-12 00:06:26 +11:00 committed by blessedcoolant
parent 00385240e7
commit e21e901fa2
31 changed files with 715 additions and 762 deletions

View File

@ -698,22 +698,24 @@ class InvokeAIWebServer:
So we need to convert each into a PIL Image. So we need to convert each into a PIL Image.
""" """
init_img_url = generation_parameters["init_img"]
truncated_outpaint_mask_b64 = generation_parameters["init_mask"][:64] truncated_outpaint_mask_b64 = generation_parameters["init_mask"][:64]
init_img_url = generation_parameters["init_img"] init_img_url = generation_parameters["init_img"]
init_img_url = generation_parameters["init_img"]
init_img_path = self.get_image_path_from_url(init_img_url) init_img_path = self.get_image_path_from_url(init_img_url)
original_image = Image.open(init_img_path) original_image = Image.open(init_img_path)
rgba_image = original_image.convert("RGBA") rgba_image = original_image.convert("RGBA")
# copy a region from it which we will inpaint # copy a region from it which we will inpaint
cropped_init_image = copy_image_from_bounding_box( cropped_init_image = copy_image_from_bounding_box(
rgba_image, **generation_parameters["bounding_box"] rgba_image, **generation_parameters["bounding_box"]
) )
original_bounding_box = generation_parameters["bounding_box"].copy()
generation_parameters["init_img"] = cropped_init_image generation_parameters["init_img"] = cropped_init_image
# Convert mask dataURL to an image and convert to greyscale # Convert mask dataURL to an image and convert to greyscale

File diff suppressed because one or more lines are too long

593
frontend/dist/assets/index.ece4fb83.js vendored Normal file

File diff suppressed because one or more lines are too long

View File

@ -7,6 +7,7 @@
<title>InvokeAI - A Stable Diffusion Toolkit</title> <title>InvokeAI - A Stable Diffusion Toolkit</title>
<link rel="shortcut icon" type="icon" href="./assets/favicon.0d253ced.ico" /> <link rel="shortcut icon" type="icon" href="./assets/favicon.0d253ced.ico" />
<<<<<<< refs/remotes/upstream/development <<<<<<< refs/remotes/upstream/development
<<<<<<< refs/remotes/upstream/development
<<<<<<< refs/remotes/upstream/development <<<<<<< refs/remotes/upstream/development
<script type="module" crossorigin src="./assets/index.a8ba2a6c.js"></script> <script type="module" crossorigin src="./assets/index.a8ba2a6c.js"></script>
<link rel="stylesheet" href="./assets/index.40a72c80.css"> <link rel="stylesheet" href="./assets/index.40a72c80.css">
@ -15,6 +16,9 @@
======= =======
<script type="module" crossorigin src="./assets/index.a06633cf.js"></script> <script type="module" crossorigin src="./assets/index.a06633cf.js"></script>
>>>>>>> Builds fresh bundle >>>>>>> Builds fresh bundle
=======
<script type="module" crossorigin src="./assets/index.ece4fb83.js"></script>
>>>>>>> Fixes inpainting + code cleanup
<link rel="stylesheet" href="./assets/index.a44a1287.css"> <link rel="stylesheet" href="./assets/index.a44a1287.css">
>>>>>>> Builds fresh bundle >>>>>>> Builds fresh bundle
</head> </head>

View File

@ -1,9 +1,6 @@
import { useEffect } from 'react';
import ProgressBar from 'features/system/ProgressBar'; import ProgressBar from 'features/system/ProgressBar';
import SiteHeader from 'features/system/SiteHeader'; import SiteHeader from 'features/system/SiteHeader';
import Console from 'features/system/Console'; import Console from 'features/system/Console';
import { useAppDispatch } from './store';
import { requestSystemConfig } from './socketio/actions';
import { keepGUIAlive } from './utils'; import { keepGUIAlive } from './utils';
import InvokeTabs from 'features/tabs/InvokeTabs'; import InvokeTabs from 'features/tabs/InvokeTabs';
import ImageUploader from 'common/components/ImageUploader'; import ImageUploader from 'common/components/ImageUploader';
@ -80,8 +77,6 @@ const appSelector = createSelector(
); );
const App = () => { const App = () => {
const dispatch = useAppDispatch();
const { shouldShowGalleryButton, shouldShowOptionsPanelButton } = const { shouldShowGalleryButton, shouldShowOptionsPanelButton } =
useAppSelector(appSelector); useAppSelector(appSelector);

View File

@ -17,7 +17,6 @@ import {
modelChangeRequested, modelChangeRequested,
setIsProcessing, setIsProcessing,
} from 'features/system/systemSlice'; } from 'features/system/systemSlice';
import { inpaintingImageElementRef } from 'features/canvas/IAICanvas';
import { InvokeTabName } from 'features/tabs/InvokeTabs'; import { InvokeTabName } from 'features/tabs/InvokeTabs';
import * as InvokeAI from 'app/invokeai'; import * as InvokeAI from 'app/invokeai';
import { RootState } from 'app/store'; import { RootState } from 'app/store';
@ -57,9 +56,9 @@ const makeSocketIOEmitters = (
if (['inpainting', 'outpainting'].includes(generationMode)) { if (['inpainting', 'outpainting'].includes(generationMode)) {
const baseCanvasImage = baseCanvasImageSelector(getState()); const baseCanvasImage = baseCanvasImageSelector(getState());
const imageUrl = baseCanvasImage?.url; const imageUrl = baseCanvasImage?.image.url;
if (!inpaintingImageElementRef.current || !imageUrl) { if (!imageUrl) {
dispatch( dispatch(
addLogEntry({ addLogEntry({
timestamp: dateFormat(new Date(), 'isoDateTime'), timestamp: dateFormat(new Date(), 'isoDateTime'),
@ -72,9 +71,6 @@ const makeSocketIOEmitters = (
} }
frontendToBackendParametersConfig.imageToProcessUrl = imageUrl; frontendToBackendParametersConfig.imageToProcessUrl = imageUrl;
// frontendToBackendParametersConfig.maskImageElement =
// inpaintingImageElementRef.current;
} else if (!['txt2img', 'img2img'].includes(generationMode)) { } else if (!['txt2img', 'img2img'].includes(generationMode)) {
if (!galleryState.currentImage?.url) return; if (!galleryState.currentImage?.url) return;

View File

@ -32,12 +32,14 @@ import {
setInitialImage, setInitialImage,
setMaskPath, setMaskPath,
} from 'features/options/optionsSlice'; } from 'features/options/optionsSlice';
import { requestImages, requestNewImages, requestSystemConfig } from './actions'; import {
requestImages,
requestNewImages,
requestSystemConfig,
} from './actions';
import { import {
addImageToOutpaintingSesion, addImageToOutpaintingSesion,
clearImageToInpaint,
setImageToInpaint, setImageToInpaint,
setImageToOutpaint,
} from 'features/canvas/canvasSlice'; } from 'features/canvas/canvasSlice';
import { tabMap } from 'features/tabs/InvokeTabs'; import { tabMap } from 'features/tabs/InvokeTabs';
@ -312,16 +314,11 @@ const makeSocketIOListeners = (
// remove references to image in options // remove references to image in options
const { initialImage, maskPath } = getState().options; const { initialImage, maskPath } = getState().options;
const { inpainting, outpainting } = getState().canvas;
if (initialImage?.url === url || initialImage === url) { if (initialImage?.url === url || initialImage === url) {
dispatch(clearInitialImage()); dispatch(clearInitialImage());
} }
// if (imageToInpaint?.url === url) {
// dispatch(clearImageToInpaint());
// }
if (maskPath === url) { if (maskPath === url) {
dispatch(setMaskPath('')); dispatch(setMaskPath(''));
} }

View File

@ -1,5 +1,4 @@
import { Heading } from '@chakra-ui/react'; import { Heading } from '@chakra-ui/react';
import { KeyboardEvent } from 'react';
import { useHotkeys } from 'react-hotkeys-hook'; import { useHotkeys } from 'react-hotkeys-hook';
type ImageUploadOverlayProps = { type ImageUploadOverlayProps = {

View File

@ -1,15 +1,13 @@
// lib // lib
import { MutableRefObject, useEffect, useRef, useState } from 'react'; import { MutableRefObject, useRef } from 'react';
import Konva from 'konva'; import Konva from 'konva';
import { Layer, Stage } from 'react-konva'; import { Layer, Stage } from 'react-konva';
import { Image as KonvaImage } from 'react-konva';
import { Stage as StageType } from 'konva/lib/Stage'; import { Stage as StageType } from 'konva/lib/Stage';
// app // app
import { useAppDispatch, useAppSelector } from 'app/store'; import { useAppSelector } from 'app/store';
import { import {
baseCanvasImageSelector, baseCanvasImageSelector,
clearImageToInpaint,
currentCanvasSelector, currentCanvasSelector,
outpaintingCanvasSelector, outpaintingCanvasSelector,
} from 'features/canvas/canvasSlice'; } from 'features/canvas/canvasSlice';
@ -18,8 +16,7 @@ import {
import IAICanvasMaskLines from './IAICanvasMaskLines'; import IAICanvasMaskLines from './IAICanvasMaskLines';
import IAICanvasBrushPreview from './IAICanvasBrushPreview'; import IAICanvasBrushPreview from './IAICanvasBrushPreview';
import { Vector2d } from 'konva/lib/types'; import { Vector2d } from 'konva/lib/types';
import IAICanvasBoundingBoxPreview from './IAICanvasBoundingBoxPreview'; import IAICanvasBoundingBox from './IAICanvasBoundingBox';
import { useToast } from '@chakra-ui/react';
import useCanvasHotkeys from './hooks/useCanvasHotkeys'; import useCanvasHotkeys from './hooks/useCanvasHotkeys';
import _ from 'lodash'; import _ from 'lodash';
import { createSelector } from '@reduxjs/toolkit'; import { createSelector } from '@reduxjs/toolkit';
@ -32,7 +29,7 @@ import useCanvasMouseMove from './hooks/useCanvasMouseMove';
import useCanvasMouseEnter from './hooks/useCanvasMouseEnter'; import useCanvasMouseEnter from './hooks/useCanvasMouseEnter';
import useCanvasMouseOut from './hooks/useCanvasMouseOut'; import useCanvasMouseOut from './hooks/useCanvasMouseOut';
import useCanvasDragMove from './hooks/useCanvasDragMove'; import useCanvasDragMove from './hooks/useCanvasDragMove';
import IAICanvasOutpaintingObjects from './IAICanvasOutpaintingObjects'; import IAICanvasObjectRenderer from './IAICanvasObjectRenderer';
import IAICanvasGrid from './IAICanvasGrid'; import IAICanvasGrid from './IAICanvasGrid';
import IAICanvasIntermediateImage from './IAICanvasIntermediateImage'; import IAICanvasIntermediateImage from './IAICanvasIntermediateImage';
import IAICanvasStatusText from './IAICanvasStatusText'; import IAICanvasStatusText from './IAICanvasStatusText';
@ -46,18 +43,14 @@ const canvasSelector = createSelector(
], ],
(currentCanvas, outpaintingCanvas, baseCanvasImage, activeTabName) => { (currentCanvas, outpaintingCanvas, baseCanvasImage, activeTabName) => {
const { const {
shouldInvertMask,
isMaskEnabled, isMaskEnabled,
shouldShowCheckboardTransparency,
stageScale, stageScale,
shouldShowBoundingBox, shouldShowBoundingBox,
shouldLockBoundingBox,
isTransformingBoundingBox, isTransformingBoundingBox,
isMouseOverBoundingBox, isMouseOverBoundingBox,
isMovingBoundingBox, isMovingBoundingBox,
stageDimensions, stageDimensions,
stageCoordinates, stageCoordinates,
isMoveStageKeyHeld,
tool, tool,
isMovingStage, isMovingStage,
} = currentCanvas; } = currentCanvas;
@ -71,7 +64,7 @@ const canvasSelector = createSelector(
stageCursor = undefined; stageCursor = undefined;
} else if (isMouseOverBoundingBox) { } else if (isMouseOverBoundingBox) {
stageCursor = 'move'; stageCursor = 'move';
} else { } else if (activeTabName === 'outpainting') {
if (isMovingStage) { if (isMovingStage) {
stageCursor = 'grabbing'; stageCursor = 'grabbing';
} else { } else {
@ -83,22 +76,15 @@ const canvasSelector = createSelector(
} }
return { return {
shouldInvertMask,
isMaskEnabled,
shouldShowCheckboardTransparency,
stageScale,
shouldShowBoundingBox,
shouldLockBoundingBox,
shouldShowGrid,
isTransformingBoundingBox,
isModifyingBoundingBox: isTransformingBoundingBox || isMovingBoundingBox,
stageCursor,
isMouseOverBoundingBox,
stageDimensions,
stageCoordinates,
isMoveStageKeyHeld,
activeTabName, activeTabName,
baseCanvasImage, isMaskEnabled,
isModifyingBoundingBox: isTransformingBoundingBox || isMovingBoundingBox,
shouldShowBoundingBox,
shouldShowGrid,
stageCoordinates,
stageCursor,
stageDimensions,
stageScale,
tool, tool,
}; };
}, },
@ -112,45 +98,32 @@ const canvasSelector = createSelector(
// Use a closure allow other components to use these things... not ideal... // Use a closure allow other components to use these things... not ideal...
export let stageRef: MutableRefObject<StageType | null>; export let stageRef: MutableRefObject<StageType | null>;
export let canvasImageLayerRef: MutableRefObject<Konva.Layer | null>; export let canvasImageLayerRef: MutableRefObject<Konva.Layer | null>;
export let inpaintingImageElementRef: MutableRefObject<HTMLImageElement | null>;
const IAICanvas = () => { const IAICanvas = () => {
const dispatch = useAppDispatch();
const { const {
shouldInvertMask, activeTabName,
isMaskEnabled, isMaskEnabled,
shouldShowCheckboardTransparency,
stageScale,
shouldShowBoundingBox,
isModifyingBoundingBox, isModifyingBoundingBox,
shouldShowBoundingBox,
shouldShowGrid,
stageCoordinates,
stageCursor, stageCursor,
stageDimensions, stageDimensions,
stageCoordinates, stageScale,
shouldShowGrid,
activeTabName,
baseCanvasImage,
tool, tool,
} = useAppSelector(canvasSelector); } = useAppSelector(canvasSelector);
useCanvasHotkeys(); useCanvasHotkeys();
const toast = useToast();
// set the closure'd refs // set the closure'd refs
stageRef = useRef<StageType>(null); stageRef = useRef<StageType>(null);
canvasImageLayerRef = useRef<Konva.Layer>(null); canvasImageLayerRef = useRef<Konva.Layer>(null);
inpaintingImageElementRef = useRef<HTMLImageElement>(null);
const lastCursorPositionRef = useRef<Vector2d>({ x: 0, y: 0 }); const lastCursorPositionRef = useRef<Vector2d>({ x: 0, y: 0 });
// Use refs for values that do not affect rendering, other values in redux // Use refs for values that do not affect rendering, other values in redux
const didMouseMoveRef = useRef<boolean>(false); const didMouseMoveRef = useRef<boolean>(false);
// Load the image into this
const [canvasBgImage, setCanvasBgImage] = useState<HTMLImageElement | null>(
null
);
const handleWheel = useCanvasWheel(stageRef); const handleWheel = useCanvasWheel(stageRef);
const handleMouseDown = useCanvasMouseDown(stageRef); const handleMouseDown = useCanvasMouseDown(stageRef);
const handleMouseUp = useCanvasMouseUp(stageRef, didMouseMoveRef); const handleMouseUp = useCanvasMouseUp(stageRef, didMouseMoveRef);
@ -164,29 +137,6 @@ const IAICanvas = () => {
const { handleDragStart, handleDragMove, handleDragEnd } = const { handleDragStart, handleDragMove, handleDragEnd } =
useCanvasDragMove(); useCanvasDragMove();
// Load the image and set the options panel width & height
useEffect(() => {
if (baseCanvasImage) {
const image = new Image();
image.onload = () => {
inpaintingImageElementRef.current = image;
setCanvasBgImage(image);
};
image.onerror = () => {
toast({
title: 'Unable to Load Image',
description: `Image ${baseCanvasImage.url} failed to load`,
status: 'error',
isClosable: true,
});
dispatch(clearImageToInpaint());
};
image.src = baseCanvasImage.url;
} else {
setCanvasBgImage(null);
}
}, [baseCanvasImage, dispatch, stageScale, toast]);
return ( return (
<div className="inpainting-canvas-container"> <div className="inpainting-canvas-container">
<div className="inpainting-canvas-wrapper"> <div className="inpainting-canvas-wrapper">
@ -209,36 +159,31 @@ const IAICanvas = () => {
onDragMove={handleDragMove} onDragMove={handleDragMove}
onDragEnd={handleDragEnd} onDragEnd={handleDragEnd}
onWheel={handleWheel} onWheel={handleWheel}
listening={ listening={tool === 'move' && !isModifyingBoundingBox}
tool === 'move' &&
!isModifyingBoundingBox &&
activeTabName === 'outpainting'
}
draggable={ draggable={
tool === 'move' && tool === 'move' &&
!isModifyingBoundingBox && !isModifyingBoundingBox &&
activeTabName === 'outpainting' activeTabName === 'outpainting'
} }
> >
<Layer visible={shouldShowGrid}> <Layer id={'grid'} visible={shouldShowGrid}>
<IAICanvasGrid /> <IAICanvasGrid />
</Layer> </Layer>
<Layer <Layer
id={'image-layer'} id={'image'}
ref={canvasImageLayerRef} ref={canvasImageLayerRef}
listening={false} listening={false}
imageSmoothingEnabled={false} imageSmoothingEnabled={false}
> >
<IAICanvasOutpaintingObjects /> <IAICanvasObjectRenderer />
<IAICanvasIntermediateImage /> <IAICanvasIntermediateImage />
</Layer> </Layer>
<Layer id={'mask-layer'} visible={isMaskEnabled} listening={false}> <Layer id={'mask'} visible={isMaskEnabled} listening={false}>
<IAICanvasMaskLines visible={true} listening={false} /> <IAICanvasMaskLines visible={true} listening={false} />
<IAICanvasMaskCompositer listening={false} /> <IAICanvasMaskCompositer listening={false} />
{canvasBgImage && ( {/* {canvasBgImage && (
<> <>
<KonvaImage <KonvaImage
image={canvasBgImage} image={canvasBgImage}
@ -256,10 +201,10 @@ const IAICanvas = () => {
} }
/> />
</> </>
)} )} */}
</Layer> </Layer>
<Layer id={'preview-layer'}> <Layer id={'tool'}>
<IAICanvasBoundingBoxPreview visible={shouldShowBoundingBox} /> <IAICanvasBoundingBox visible={shouldShowBoundingBox} />
<IAICanvasBrushPreview <IAICanvasBrushPreview
visible={tool !== 'move'} visible={tool !== 'move'}
listening={false} listening={false}

View File

@ -1,6 +1,5 @@
import { createSelector } from '@reduxjs/toolkit'; import { createSelector } from '@reduxjs/toolkit';
import Konva from 'konva'; import Konva from 'konva';
import { Context } from 'konva/lib/Context';
import { KonvaEventObject } from 'konva/lib/Node'; import { KonvaEventObject } from 'konva/lib/Node';
import { Box } from 'konva/lib/shapes/Transformer'; import { Box } from 'konva/lib/shapes/Transformer';
import { Vector2d } from 'konva/lib/types'; import { Vector2d } from 'konva/lib/types';
@ -33,7 +32,6 @@ const boundingBoxPreviewSelector = createSelector(
boundingBoxDimensions, boundingBoxDimensions,
stageDimensions, stageDimensions,
stageScale, stageScale,
shouldLockBoundingBox,
isDrawing, isDrawing,
isTransformingBoundingBox, isTransformingBoundingBox,
isMovingBoundingBox, isMovingBoundingBox,
@ -52,7 +50,6 @@ const boundingBoxPreviewSelector = createSelector(
shouldDarkenOutsideBoundingBox, shouldDarkenOutsideBoundingBox,
isMovingBoundingBox, isMovingBoundingBox,
isTransformingBoundingBox, isTransformingBoundingBox,
shouldLockBoundingBox,
stageDimensions, stageDimensions,
stageScale, stageScale,
baseCanvasImage, baseCanvasImage,
@ -72,9 +69,7 @@ const boundingBoxPreviewSelector = createSelector(
type IAICanvasBoundingBoxPreviewProps = GroupConfig; type IAICanvasBoundingBoxPreviewProps = GroupConfig;
const IAICanvasBoundingBoxPreview = ( const IAICanvasBoundingBox = (props: IAICanvasBoundingBoxPreviewProps) => {
props: IAICanvasBoundingBoxPreviewProps
) => {
const { ...rest } = props; const { ...rest } = props;
const dispatch = useAppDispatch(); const dispatch = useAppDispatch();
@ -86,7 +81,6 @@ const IAICanvasBoundingBoxPreview = (
shouldDarkenOutsideBoundingBox, shouldDarkenOutsideBoundingBox,
isMovingBoundingBox, isMovingBoundingBox,
isTransformingBoundingBox, isTransformingBoundingBox,
shouldLockBoundingBox,
stageCoordinates, stageCoordinates,
stageDimensions, stageDimensions,
stageScale, stageScale,
@ -104,7 +98,7 @@ const IAICanvasBoundingBoxPreview = (
if (!transformerRef.current || !shapeRef.current) return; if (!transformerRef.current || !shapeRef.current) return;
transformerRef.current.nodes([shapeRef.current]); transformerRef.current.nodes([shapeRef.current]);
transformerRef.current.getLayer()?.batchDraw(); transformerRef.current.getLayer()?.batchDraw();
}, [shouldLockBoundingBox]); }, []);
const scaledStep = 64 * stageScale; const scaledStep = 64 * stageScale;
@ -264,7 +258,6 @@ const IAICanvasBoundingBoxPreview = (
[scaledStep] [scaledStep]
); );
// OK
const boundBoxFunc = useCallback( const boundBoxFunc = useCallback(
(oldBoundBox: Box, newBoundBox: Box) => { (oldBoundBox: Box, newBoundBox: Box) => {
/** /**
@ -341,10 +334,10 @@ const IAICanvasBoundingBoxPreview = (
dragBoundFunc={ dragBoundFunc={
activeTabName === 'inpainting' ? dragBoundFunc : undefined activeTabName === 'inpainting' ? dragBoundFunc : undefined
} }
listening={!isDrawing && tool === 'move'}
draggable={true} draggable={true}
fillEnabled={tool === 'move'} fillEnabled={tool === 'move'}
height={boundingBoxDimensions.height} height={boundingBoxDimensions.height}
listening={!isDrawing && tool === 'move'}
onDragEnd={handleEndedModifying} onDragEnd={handleEndedModifying}
onDragMove={handleOnDragMove} onDragMove={handleOnDragMove}
onMouseDown={handleStartedMoving} onMouseDown={handleStartedMoving}
@ -387,4 +380,4 @@ const IAICanvasBoundingBoxPreview = (
); );
}; };
export default IAICanvasBoundingBoxPreview; export default IAICanvasBoundingBox;

View File

@ -15,7 +15,6 @@ import IAIPopover from 'common/components/IAIPopover';
import IAIColorPicker from 'common/components/IAIColorPicker'; import IAIColorPicker from 'common/components/IAIColorPicker';
import IAISlider from 'common/components/IAISlider'; import IAISlider from 'common/components/IAISlider';
import { Flex } from '@chakra-ui/react'; import { Flex } from '@chakra-ui/react';
import IAINumberInput from 'common/components/IAINumberInput';
export const selector = createSelector( export const selector = createSelector(
[currentCanvasSelector, outpaintingCanvasSelector, activeTabNameSelector], [currentCanvasSelector, outpaintingCanvasSelector, activeTabNameSelector],

View File

@ -2,7 +2,7 @@ import IAICanvasBrushControl from './IAICanvasControls/IAICanvasBrushControl';
import IAICanvasEraserControl from './IAICanvasControls/IAICanvasEraserControl'; import IAICanvasEraserControl from './IAICanvasControls/IAICanvasEraserControl';
import IAICanvasUndoControl from './IAICanvasControls/IAICanvasUndoButton'; import IAICanvasUndoControl from './IAICanvasControls/IAICanvasUndoButton';
import IAICanvasRedoControl from './IAICanvasControls/IAICanvasRedoButton'; import IAICanvasRedoControl from './IAICanvasControls/IAICanvasRedoButton';
import { Button, ButtonGroup } from '@chakra-ui/react'; import { ButtonGroup } from '@chakra-ui/react';
import IAICanvasMaskClear from './IAICanvasControls/IAICanvasMaskControls/IAICanvasMaskClear'; import IAICanvasMaskClear from './IAICanvasControls/IAICanvasMaskControls/IAICanvasMaskClear';
import IAICanvasMaskVisibilityControl from './IAICanvasControls/IAICanvasMaskControls/IAICanvasMaskVisibilityControl'; import IAICanvasMaskVisibilityControl from './IAICanvasControls/IAICanvasMaskControls/IAICanvasMaskVisibilityControl';
import IAICanvasMaskInvertControl from './IAICanvasControls/IAICanvasMaskControls/IAICanvasMaskInvertControl'; import IAICanvasMaskInvertControl from './IAICanvasControls/IAICanvasMaskControls/IAICanvasMaskInvertControl';
@ -11,8 +11,6 @@ import IAICanvasShowHideBoundingBoxControl from './IAICanvasControls/IAICanvasSh
import ImageUploaderIconButton from 'common/components/ImageUploaderIconButton'; import ImageUploaderIconButton from 'common/components/ImageUploaderIconButton';
import { createSelector } from '@reduxjs/toolkit'; import { createSelector } from '@reduxjs/toolkit';
import { import {
currentCanvasSelector,
GenericCanvasState,
outpaintingCanvasSelector, outpaintingCanvasSelector,
OutpaintingCanvasState, OutpaintingCanvasState,
uploadOutpaintingMergedImage, uploadOutpaintingMergedImage,
@ -23,7 +21,6 @@ import { OptionsState } from 'features/options/optionsSlice';
import _ from 'lodash'; import _ from 'lodash';
import IAICanvasImageEraserControl from './IAICanvasControls/IAICanvasImageEraserControl'; import IAICanvasImageEraserControl from './IAICanvasControls/IAICanvasImageEraserControl';
import { canvasImageLayerRef } from './IAICanvas'; import { canvasImageLayerRef } from './IAICanvas';
import { uploadImage } from 'app/socketio/actions';
import IAIIconButton from 'common/components/IAIIconButton'; import IAIIconButton from 'common/components/IAIIconButton';
import { FaSave } from 'react-icons/fa'; import { FaSave } from 'react-icons/fa';
@ -56,12 +53,7 @@ export const canvasControlsSelector = createSelector(
const IAICanvasControls = () => { const IAICanvasControls = () => {
const dispatch = useAppDispatch(); const dispatch = useAppDispatch();
const { const { activeTabName } = useAppSelector(canvasControlsSelector);
activeTabName,
boundingBoxCoordinates,
boundingBoxDimensions,
stageScale,
} = useAppSelector(canvasControlsSelector);
return ( return (
<div className="inpainting-settings"> <div className="inpainting-settings">

View File

@ -1,7 +1,6 @@
import { createSelector } from '@reduxjs/toolkit'; import { createSelector } from '@reduxjs/toolkit';
import { useAppSelector } from 'app/store'; import { useAppSelector } from 'app/store';
import { RectConfig } from 'konva/lib/shapes/Rect'; import { RectConfig } from 'konva/lib/shapes/Rect';
import _ from 'lodash';
import { Rect } from 'react-konva'; import { Rect } from 'react-konva';
import { import {
currentCanvasSelector, currentCanvasSelector,
@ -24,7 +23,6 @@ export const canvasMaskCompositerSelector = createSelector(
stageDimensions, stageDimensions,
stageScale, stageScale,
maskColorString: rgbaColorToString(maskColor), maskColorString: rgbaColorToString(maskColor),
maskOpacity: maskColor.a,
}; };
} }
); );
@ -116,13 +114,8 @@ const getColoredSVG = (color: string) => {
const IAICanvasMaskCompositer = (props: IAICanvasMaskCompositerProps) => { const IAICanvasMaskCompositer = (props: IAICanvasMaskCompositerProps) => {
const { ...rest } = props; const { ...rest } = props;
const { const { maskColorString, stageCoordinates, stageDimensions, stageScale } =
maskColorString, useAppSelector(canvasMaskCompositerSelector);
maskOpacity,
stageCoordinates,
stageDimensions,
stageScale,
} = useAppSelector(canvasMaskCompositerSelector);
const [fillPatternImage, setFillPatternImage] = const [fillPatternImage, setFillPatternImage] =
useState<HTMLImageElement | null>(null); useState<HTMLImageElement | null>(null);

View File

@ -1,9 +1,9 @@
import { createSelector } from '@reduxjs/toolkit'; import { createSelector } from '@reduxjs/toolkit';
import { RootState, useAppSelector } from 'app/store'; import { useAppSelector } from 'app/store';
import _ from 'lodash'; import _ from 'lodash';
import { Group, Line } from 'react-konva'; import { Group, Line } from 'react-konva';
import { import {
CanvasState, currentCanvasSelector,
isCanvasBaseImage, isCanvasBaseImage,
isCanvasBaseLine, isCanvasBaseLine,
} from './canvasSlice'; } from './canvasSlice';
@ -11,14 +11,9 @@ import IAICanvasImage from './IAICanvasImage';
import { rgbaColorToString } from './util/colorToString'; import { rgbaColorToString } from './util/colorToString';
const selector = createSelector( const selector = createSelector(
[(state: RootState) => state.canvas], [currentCanvasSelector],
(canvas: CanvasState) => { (currentCanvas) => {
return { return currentCanvas.objects;
objects:
canvas.currentCanvas === 'outpainting'
? canvas.outpainting.objects
: undefined,
};
}, },
{ {
memoizeOptions: { memoizeOptions: {
@ -27,8 +22,8 @@ const selector = createSelector(
} }
); );
const IAICanvasOutpaintingObjects = () => { const IAICanvasObjectRenderer = () => {
const { objects } = useAppSelector(selector); const objects = useAppSelector(selector);
if (!objects) return null; if (!objects) return null;
@ -62,4 +57,4 @@ const IAICanvasOutpaintingObjects = () => {
); );
}; };
export default IAICanvasOutpaintingObjects; export default IAICanvasObjectRenderer;

View File

@ -5,14 +5,10 @@ import { activeTabNameSelector } from 'features/options/optionsSelectors';
import { import {
baseCanvasImageSelector, baseCanvasImageSelector,
CanvasState, CanvasState,
currentCanvasSelector,
GenericCanvasState,
setStageDimensions, setStageDimensions,
setStageScale, setStageScale,
} from 'features/canvas/canvasSlice'; } from 'features/canvas/canvasSlice';
import { createSelector } from '@reduxjs/toolkit'; import { createSelector } from '@reduxjs/toolkit';
import * as InvokeAI from 'app/invokeai';
import { first } from 'lodash';
const canvasResizerSelector = createSelector( const canvasResizerSelector = createSelector(
(state: RootState) => state.canvas, (state: RootState) => state.canvas,
@ -39,13 +35,12 @@ const IAICanvasResizer = () => {
useLayoutEffect(() => { useLayoutEffect(() => {
window.setTimeout(() => { window.setTimeout(() => {
if (!ref.current || !baseCanvasImage) return; if (!ref.current || !baseCanvasImage) return;
const { width: imageWidth, height: imageHeight } = baseCanvasImage.image;
const width = ref.current.clientWidth; const { clientWidth, clientHeight } = ref.current;
const height = ref.current.clientHeight;
const scale = Math.min( const scale = Math.min(
1, 1,
Math.min(width / baseCanvasImage.width, height / baseCanvasImage.height) Math.min(clientWidth / imageWidth, clientHeight / imageHeight)
); );
dispatch(setStageScale(scale)); dispatch(setStageScale(scale));
@ -53,15 +48,15 @@ const IAICanvasResizer = () => {
if (activeTabName === 'inpainting') { if (activeTabName === 'inpainting') {
dispatch( dispatch(
setStageDimensions({ setStageDimensions({
width: Math.floor(baseCanvasImage.width * scale), width: Math.floor(imageWidth * scale),
height: Math.floor(baseCanvasImage.height * scale), height: Math.floor(imageHeight * scale),
}) })
); );
} else if (activeTabName === 'outpainting') { } else if (activeTabName === 'outpainting') {
dispatch( dispatch(
setStageDimensions({ setStageDimensions({
width: Math.floor(width), width: Math.floor(clientWidth),
height: Math.floor(height), height: Math.floor(clientHeight),
}) })
); );
} }

View File

@ -11,7 +11,6 @@ import * as InvokeAI from 'app/invokeai';
import _ from 'lodash'; import _ from 'lodash';
import { roundDownToMultiple } from 'common/util/roundDownToMultiple'; import { roundDownToMultiple } from 'common/util/roundDownToMultiple';
import { RootState } from 'app/store'; import { RootState } from 'app/store';
import { activeTabNameSelector } from 'features/options/optionsSelectors';
import { MutableRefObject } from 'react'; import { MutableRefObject } from 'react';
import Konva from 'konva'; import Konva from 'konva';
@ -137,7 +136,7 @@ const initialGenericCanvasState: GenericCanvasState = {
tool: 'brush', tool: 'brush',
brushColor: { r: 90, g: 90, b: 255, a: 1 }, brushColor: { r: 90, g: 90, b: 255, a: 1 },
brushSize: 50, brushSize: 50,
maskColor: { r: 255, g: 90, b: 90, a: 0.5 }, maskColor: { r: 255, g: 90, b: 90, a: 1 },
eraserSize: 50, eraserSize: 50,
stageDimensions: { width: 0, height: 0 }, stageDimensions: { width: 0, height: 0 },
stageCoordinates: { x: 0, y: 0 }, stageCoordinates: { x: 0, y: 0 },
@ -351,7 +350,16 @@ export const canvasSlice = createSlice({
state.inpainting.boundingBoxDimensions = newDimensions; state.inpainting.boundingBoxDimensions = newDimensions;
state.inpainting.boundingBoxCoordinates = newCoordinates; state.inpainting.boundingBoxCoordinates = newCoordinates;
state.inpainting.imageToInpaint = action.payload; // state.inpainting.imageToInpaint = action.payload;
state.inpainting.objects = [
{
kind: 'image',
layer: 'base',
x: 0,
y: 0,
image: action.payload,
},
];
state.doesCanvasNeedScaling = true; state.doesCanvasNeedScaling = true;
}, },
setStageDimensions: (state, action: PayloadAction<Dimensions>) => { setStageDimensions: (state, action: PayloadAction<Dimensions>) => {
@ -567,19 +575,19 @@ export const canvasSlice = createSlice({
lastLine.points.push(...action.payload); lastLine.points.push(...action.payload);
}, },
undo: (state) => { undo: (state) => {
if (state.outpainting.objects.length === 0) return; if (state[state.currentCanvas].objects.length === 0) return;
const newObjects = state.outpainting.pastObjects.pop(); const newObjects = state[state.currentCanvas].pastObjects.pop();
if (!newObjects) return; if (!newObjects) return;
state.outpainting.futureObjects.unshift(state.outpainting.objects); state[state.currentCanvas].futureObjects.unshift(state[state.currentCanvas].objects);
state.outpainting.objects = newObjects; state[state.currentCanvas].objects = newObjects;
}, },
redo: (state) => { redo: (state) => {
if (state.outpainting.futureObjects.length === 0) return; if (state[state.currentCanvas].futureObjects.length === 0) return;
const newObjects = state.outpainting.futureObjects.shift(); const newObjects = state[state.currentCanvas].futureObjects.shift();
if (!newObjects) return; if (!newObjects) return;
state.outpainting.pastObjects.push(state.outpainting.objects); state[state.currentCanvas].pastObjects.push(state[state.currentCanvas].objects);
state.outpainting.objects = newObjects; state[state.currentCanvas].objects = newObjects;
}, },
setShouldShowGrid: (state, action: PayloadAction<boolean>) => { setShouldShowGrid: (state, action: PayloadAction<boolean>) => {
state.outpainting.shouldShowGrid = action.payload; state.outpainting.shouldShowGrid = action.payload;
@ -748,17 +756,8 @@ export const inpaintingCanvasSelector = (
): InpaintingCanvasState => state.canvas.inpainting; ): InpaintingCanvasState => state.canvas.inpainting;
export const baseCanvasImageSelector = createSelector( export const baseCanvasImageSelector = createSelector(
[(state: RootState) => state.canvas, activeTabNameSelector], [currentCanvasSelector],
(canvas: CanvasState, activeTabName) => { (currentCanvas) => {
if (activeTabName === 'inpainting') { return currentCanvas.objects.find(isCanvasBaseImage);
return canvas.inpainting.imageToInpaint;
} else if (activeTabName === 'outpainting') {
const firstImageObject = canvas.outpainting.objects.find(
(obj) => obj.kind === 'image'
);
if (firstImageObject && firstImageObject.kind === 'image') {
return firstImageObject.image;
}
}
} }
); );

View File

@ -2,26 +2,20 @@ import { createSelector } from '@reduxjs/toolkit';
import _ from 'lodash'; import _ from 'lodash';
import { useHotkeys } from 'react-hotkeys-hook'; import { useHotkeys } from 'react-hotkeys-hook';
import { activeTabNameSelector } from 'features/options/optionsSelectors'; import { activeTabNameSelector } from 'features/options/optionsSelectors';
import { OptionsState } from 'features/options/optionsSlice';
import { import {
CanvasTool, CanvasTool,
setShouldShowBoundingBox, setShouldShowBoundingBox,
setTool, setTool,
toggleShouldLockBoundingBox, toggleShouldLockBoundingBox,
} from 'features/canvas/canvasSlice'; } from 'features/canvas/canvasSlice';
import { RootState, useAppDispatch, useAppSelector } from 'app/store'; import { useAppDispatch, useAppSelector } from 'app/store';
import { currentCanvasSelector, GenericCanvasState } from '../canvasSlice'; import { currentCanvasSelector } from '../canvasSlice';
import { useRef } from 'react'; import { useRef } from 'react';
const inpaintingCanvasHotkeysSelector = createSelector( const inpaintingCanvasHotkeysSelector = createSelector(
[ [currentCanvasSelector, activeTabNameSelector],
(state: RootState) => state.options, (currentCanvas, activeTabName) => {
currentCanvasSelector,
activeTabNameSelector,
],
(options: OptionsState, currentCanvas: GenericCanvasState, activeTabName) => {
const { const {
isMaskEnabled,
cursorPosition, cursorPosition,
shouldLockBoundingBox, shouldLockBoundingBox,
shouldShowBoundingBox, shouldShowBoundingBox,
@ -30,7 +24,6 @@ const inpaintingCanvasHotkeysSelector = createSelector(
return { return {
activeTabName, activeTabName,
isMaskEnabled,
isCursorOnCanvas: Boolean(cursorPosition), isCursorOnCanvas: Boolean(cursorPosition),
shouldLockBoundingBox, shouldLockBoundingBox,
shouldShowBoundingBox, shouldShowBoundingBox,
@ -46,8 +39,9 @@ const inpaintingCanvasHotkeysSelector = createSelector(
const useInpaintingCanvasHotkeys = () => { const useInpaintingCanvasHotkeys = () => {
const dispatch = useAppDispatch(); const dispatch = useAppDispatch();
const { isMaskEnabled, activeTabName, shouldShowBoundingBox, tool } = const { activeTabName, shouldShowBoundingBox, tool } = useAppSelector(
useAppSelector(inpaintingCanvasHotkeysSelector); inpaintingCanvasHotkeysSelector
);
const previousToolRef = useRef<CanvasTool | null>(null); const previousToolRef = useRef<CanvasTool | null>(null);
// Toggle lock bounding box // Toggle lock bounding box

View File

@ -1,5 +1,4 @@
import { useAppDispatch } from 'app/store'; import { useAppDispatch } from 'app/store';
import _ from 'lodash';
import { useCallback } from 'react'; import { useCallback } from 'react';
import { setCursorPosition, setIsDrawing } from '../canvasSlice'; import { setCursorPosition, setIsDrawing } from '../canvasSlice';

View File

@ -21,7 +21,7 @@ import IAIIconButton from 'common/components/IAIIconButton';
import UpscaleOptions from 'features/options/AdvancedOptions/Upscale/UpscaleOptions'; import UpscaleOptions from 'features/options/AdvancedOptions/Upscale/UpscaleOptions';
import FaceRestoreOptions from 'features/options/AdvancedOptions/FaceRestore/FaceRestoreOptions'; import FaceRestoreOptions from 'features/options/AdvancedOptions/FaceRestore/FaceRestoreOptions';
import { useHotkeys } from 'react-hotkeys-hook'; import { useHotkeys } from 'react-hotkeys-hook';
import { ButtonGroup, Link, useClipboard, useToast } from '@chakra-ui/react'; import { ButtonGroup, Link, useToast } from '@chakra-ui/react';
import { import {
FaAsterisk, FaAsterisk,
FaCode, FaCode,

View File

@ -1,4 +1,4 @@
import { IconButton, Image, Spinner } from '@chakra-ui/react'; import { IconButton, Image } from '@chakra-ui/react';
import { useState } from 'react'; import { useState } from 'react';
import { FaAngleLeft, FaAngleRight } from 'react-icons/fa'; import { FaAngleLeft, FaAngleRight } from 'react-icons/fa';
import { RootState, useAppDispatch, useAppSelector } from 'app/store'; import { RootState, useAppDispatch, useAppSelector } from 'app/store';

View File

@ -1,5 +1,5 @@
import React from 'react'; import React from 'react';
import { RootState, useAppDispatch, useAppSelector } from 'app/store'; import { useAppDispatch, useAppSelector } from 'app/store';
import IAICheckbox from 'common/components/IAICheckbox'; import IAICheckbox from 'common/components/IAICheckbox';
import { import {
currentCanvasSelector, currentCanvasSelector,

View File

@ -1,12 +1,10 @@
import React from 'react'; import React from 'react';
import IAISlider from 'common/components/IAISlider'; import IAISlider from 'common/components/IAISlider';
import { RootState, useAppDispatch, useAppSelector } from 'app/store'; import { useAppDispatch, useAppSelector } from 'app/store';
import { createSelector } from '@reduxjs/toolkit'; import { createSelector } from '@reduxjs/toolkit';
import { import {
currentCanvasSelector, currentCanvasSelector,
GenericCanvasState,
// InpaintingState,
setBoundingBoxDimensions, setBoundingBoxDimensions,
} from 'features/canvas/canvasSlice'; } from 'features/canvas/canvasSlice';
@ -15,7 +13,7 @@ import _ from 'lodash';
const boundingBoxDimensionsSelector = createSelector( const boundingBoxDimensionsSelector = createSelector(
currentCanvasSelector, currentCanvasSelector,
(currentCanvas: GenericCanvasState) => { (currentCanvas) => {
const { stageDimensions, boundingBoxDimensions, shouldLockBoundingBox } = const { stageDimensions, boundingBoxDimensions, shouldLockBoundingBox } =
currentCanvas; currentCanvas;
return { return {

View File

@ -1,16 +1,15 @@
import React from 'react'; import React from 'react';
import { RootState, useAppDispatch, useAppSelector } from 'app/store'; import { useAppDispatch, useAppSelector } from 'app/store';
import IAICheckbox from 'common/components/IAICheckbox'; import IAICheckbox from 'common/components/IAICheckbox';
import { import {
currentCanvasSelector, currentCanvasSelector,
GenericCanvasState,
setShouldLockBoundingBox, setShouldLockBoundingBox,
} from 'features/canvas/canvasSlice'; } from 'features/canvas/canvasSlice';
import { createSelector } from '@reduxjs/toolkit'; import { createSelector } from '@reduxjs/toolkit';
const boundingBoxLockSelector = createSelector( const boundingBoxLockSelector = createSelector(
currentCanvasSelector, currentCanvasSelector,
(currentCanvas: GenericCanvasState) => currentCanvas.shouldLockBoundingBox (currentCanvas) => currentCanvas.shouldLockBoundingBox
); );
export default function BoundingBoxLock() { export default function BoundingBoxLock() {

View File

@ -1,17 +1,16 @@
import React from 'react'; import React from 'react';
import { BiHide, BiShow } from 'react-icons/bi'; import { BiHide, BiShow } from 'react-icons/bi';
import { RootState, useAppDispatch, useAppSelector } from 'app/store'; import { useAppDispatch, useAppSelector } from 'app/store';
import IAIIconButton from 'common/components/IAIIconButton'; import IAIIconButton from 'common/components/IAIIconButton';
import { import {
currentCanvasSelector, currentCanvasSelector,
GenericCanvasState,
setShouldShowBoundingBox, setShouldShowBoundingBox,
} from 'features/canvas/canvasSlice'; } from 'features/canvas/canvasSlice';
import { createSelector } from '@reduxjs/toolkit'; import { createSelector } from '@reduxjs/toolkit';
const boundingBoxVisibilitySelector = createSelector( const boundingBoxVisibilitySelector = createSelector(
currentCanvasSelector, currentCanvasSelector,
(currentCanvas: GenericCanvasState) => currentCanvas.shouldShowBoundingBox (currentCanvas) => currentCanvas.shouldShowBoundingBox
); );
export default function BoundingBoxVisibility() { export default function BoundingBoxVisibility() {

View File

@ -1,9 +1,5 @@
import React, { ChangeEvent } from 'react'; import React, { ChangeEvent } from 'react';
import { import { useAppDispatch, useAppSelector } from '../../../../app/store';
RootState,
useAppDispatch,
useAppSelector,
} from '../../../../app/store';
import _ from 'lodash'; import _ from 'lodash';
import { createSelector } from '@reduxjs/toolkit'; import { createSelector } from '@reduxjs/toolkit';
import IAISwitch from '../../../../common/components/IAISwitch'; import IAISwitch from '../../../../common/components/IAISwitch';

View File

@ -1,5 +1,4 @@
import { Image, useToast } from '@chakra-ui/react'; import { Image, useToast } from '@chakra-ui/react';
import { SyntheticEvent } from 'react';
import { RootState, useAppDispatch, useAppSelector } from 'app/store'; import { RootState, useAppDispatch, useAppSelector } from 'app/store';
import ImageUploaderIconButton from 'common/components/ImageUploaderIconButton'; import ImageUploaderIconButton from 'common/components/ImageUploaderIconButton';
import { clearInitialImage } from 'features/options/optionsSlice'; import { clearInitialImage } from 'features/options/optionsSlice';

View File

@ -1,5 +1,4 @@
import { createSelector } from '@reduxjs/toolkit'; import { createSelector } from '@reduxjs/toolkit';
// import IAICanvas from 'features/canvas/IAICanvas';
import IAICanvasControls from 'features/canvas/IAICanvasControls'; import IAICanvasControls from 'features/canvas/IAICanvasControls';
import IAICanvasResizer from 'features/canvas/IAICanvasResizer'; import IAICanvasResizer from 'features/canvas/IAICanvasResizer';
import _ from 'lodash'; import _ from 'lodash';
@ -9,23 +8,25 @@ import ImageUploadButton from 'common/components/ImageUploaderButton';
import CurrentImageDisplay from 'features/gallery/CurrentImageDisplay'; import CurrentImageDisplay from 'features/gallery/CurrentImageDisplay';
import { OptionsState } from 'features/options/optionsSlice'; import { OptionsState } from 'features/options/optionsSlice';
import { import {
baseCanvasImageSelector,
CanvasState, CanvasState,
setDoesCanvasNeedScaling, setDoesCanvasNeedScaling,
} from 'features/canvas/canvasSlice'; } from 'features/canvas/canvasSlice';
import IAICanvas from 'features/canvas/IAICanvas'; import IAICanvas from 'features/canvas/IAICanvas';
const inpaintingDisplaySelector = createSelector( const inpaintingDisplaySelector = createSelector(
[(state: RootState) => state.canvas, (state: RootState) => state.options], [
(canvas: CanvasState, options: OptionsState) => { baseCanvasImageSelector,
const { (state: RootState) => state.canvas,
doesCanvasNeedScaling, (state: RootState) => state.options,
inpainting: { imageToInpaint }, ],
} = canvas; (baseCanvasImage, canvas: CanvasState, options: OptionsState) => {
const { doesCanvasNeedScaling } = canvas;
const { showDualDisplay } = options; const { showDualDisplay } = options;
return { return {
doesCanvasNeedScaling, doesCanvasNeedScaling,
showDualDisplay, showDualDisplay,
imageToInpaint, baseCanvasImage,
}; };
}, },
{ {
@ -37,7 +38,7 @@ const inpaintingDisplaySelector = createSelector(
const InpaintingDisplay = () => { const InpaintingDisplay = () => {
const dispatch = useAppDispatch(); const dispatch = useAppDispatch();
const { showDualDisplay, doesCanvasNeedScaling, imageToInpaint } = const { showDualDisplay, doesCanvasNeedScaling, baseCanvasImage } =
useAppSelector(inpaintingDisplaySelector); useAppSelector(inpaintingDisplaySelector);
useLayoutEffect(() => { useLayoutEffect(() => {
@ -49,7 +50,7 @@ const InpaintingDisplay = () => {
return () => window.removeEventListener('resize', resizeCallback); return () => window.removeEventListener('resize', resizeCallback);
}, [dispatch]); }, [dispatch]);
const inpaintingComponent = imageToInpaint ? ( const inpaintingComponent = baseCanvasImage ? (
<div className="inpainting-main-area"> <div className="inpainting-main-area">
<IAICanvasControls /> <IAICanvasControls />
<div className="inpainting-canvas-area"> <div className="inpainting-canvas-area">

View File

@ -4,7 +4,6 @@ import React, { ReactElement } from 'react';
import { useHotkeys } from 'react-hotkeys-hook'; import { useHotkeys } from 'react-hotkeys-hook';
import { RootState, useAppDispatch, useAppSelector } from 'app/store'; import { RootState, useAppDispatch, useAppSelector } from 'app/store';
import NodesWIP from 'common/components/WorkInProgress/NodesWIP'; import NodesWIP from 'common/components/WorkInProgress/NodesWIP';
import OutpaintingWIP from 'common/components/WorkInProgress/OutpaintingWIP';
import { PostProcessingWIP } from 'common/components/WorkInProgress/PostProcessingWIP'; import { PostProcessingWIP } from 'common/components/WorkInProgress/PostProcessingWIP';
import ImageToImageIcon from 'common/icons/ImageToImageIcon'; import ImageToImageIcon from 'common/icons/ImageToImageIcon';
import InpaintIcon from 'common/icons/InpaintIcon'; import InpaintIcon from 'common/icons/InpaintIcon';
@ -19,13 +18,9 @@ import {
} from 'features/options/optionsSlice'; } from 'features/options/optionsSlice';
import ImageToImageWorkarea from './ImageToImage'; import ImageToImageWorkarea from './ImageToImage';
import InpaintingWorkarea from './Inpainting/InpaintingWorkarea'; import InpaintingWorkarea from './Inpainting/InpaintingWorkarea';
// import { setDoesCanvasNeedScaling } from './Inpainting/inpaintingSlice';
import TextToImageWorkarea from './TextToImage'; import TextToImageWorkarea from './TextToImage';
import Lightbox from 'features/lightbox/Lightbox'; import Lightbox from 'features/lightbox/Lightbox';
import { import { setDoesCanvasNeedScaling } from 'features/canvas/canvasSlice';
setCurrentCanvas,
setDoesCanvasNeedScaling,
} from 'features/canvas/canvasSlice';
import OutpaintingWorkarea from './Outpainting/OutpaintingWorkarea'; import OutpaintingWorkarea from './Outpainting/OutpaintingWorkarea';
import { setShouldShowGallery } from 'features/gallery/gallerySlice'; import { setShouldShowGallery } from 'features/gallery/gallerySlice';

View File

@ -19,7 +19,6 @@ const workareaSelector = createSelector(
return { return {
showDualDisplay, showDualDisplay,
shouldPinOptionsPanel, shouldPinOptionsPanel,
activeTabName,
isLightBoxOpen, isLightBoxOpen,
shouldShowDualDisplayButton: ['inpainting'].includes(activeTabName), shouldShowDualDisplayButton: ['inpainting'].includes(activeTabName),
}; };
@ -37,7 +36,6 @@ const InvokeWorkarea = (props: InvokeWorkareaProps) => {
const { optionsPanel, children, styleClass } = props; const { optionsPanel, children, styleClass } = props;
const { const {
showDualDisplay, showDualDisplay,
activeTabName,
isLightBoxOpen, isLightBoxOpen,
shouldShowDualDisplayButton, shouldShowDualDisplayButton,
} = useAppSelector(workareaSelector); } = useAppSelector(workareaSelector);

View File

@ -1,34 +1,26 @@
import { createSelector } from '@reduxjs/toolkit'; import { createSelector } from '@reduxjs/toolkit';
// import IAICanvas from 'features/canvas/IAICanvas'; // import IAICanvas from 'features/canvas/IAICanvas';
import IAICanvasControls from 'features/canvas/IAICanvasControls';
import IAICanvasResizer from 'features/canvas/IAICanvasResizer'; import IAICanvasResizer from 'features/canvas/IAICanvasResizer';
import _ from 'lodash'; import _ from 'lodash';
import { useLayoutEffect } from 'react'; import { useLayoutEffect } from 'react';
import { RootState, useAppDispatch, useAppSelector } from 'app/store'; import { RootState, useAppDispatch, useAppSelector } from 'app/store';
import ImageUploadButton from 'common/components/ImageUploaderButton'; import ImageUploadButton from 'common/components/ImageUploaderButton';
import CurrentImageDisplay from 'features/gallery/CurrentImageDisplay';
import { OptionsState } from 'features/options/optionsSlice';
import { import {
CanvasState, CanvasState,
currentCanvasSelector,
GenericCanvasState,
OutpaintingCanvasState,
setDoesCanvasNeedScaling, setDoesCanvasNeedScaling,
} from 'features/canvas/canvasSlice'; } from 'features/canvas/canvasSlice';
import IAICanvas from 'features/canvas/IAICanvas'; import IAICanvas from 'features/canvas/IAICanvas';
import IAICanvasOutpaintingControls from 'features/canvas/IAICanvasOutpaintingControls'; import IAICanvasOutpaintingControls from 'features/canvas/IAICanvasOutpaintingControls';
const outpaintingDisplaySelector = createSelector( const outpaintingDisplaySelector = createSelector(
[(state: RootState) => state.canvas, (state: RootState) => state.options], [(state: RootState) => state.canvas],
(canvas: CanvasState, options: OptionsState) => { (canvas: CanvasState) => {
const { const {
doesCanvasNeedScaling, doesCanvasNeedScaling,
outpainting: { objects }, outpainting: { objects },
} = canvas; } = canvas;
const { showDualDisplay } = options;
return { return {
doesCanvasNeedScaling, doesCanvasNeedScaling,
showDualDisplay,
doesOutpaintingHaveObjects: objects.length > 0, doesOutpaintingHaveObjects: objects.length > 0,
}; };
}, },
@ -41,8 +33,9 @@ const outpaintingDisplaySelector = createSelector(
const OutpaintingDisplay = () => { const OutpaintingDisplay = () => {
const dispatch = useAppDispatch(); const dispatch = useAppDispatch();
const { showDualDisplay, doesCanvasNeedScaling, doesOutpaintingHaveObjects } = const { doesCanvasNeedScaling, doesOutpaintingHaveObjects } = useAppSelector(
useAppSelector(outpaintingDisplaySelector); outpaintingDisplaySelector
);
useLayoutEffect(() => { useLayoutEffect(() => {
const resizeCallback = _.debounce( const resizeCallback = _.debounce(