mirror of
https://github.com/invoke-ai/InvokeAI
synced 2024-08-30 20:32:17 +00:00
feat(ui): support image dnd to canvas
This commit is contained in:
parent
2c77563dcc
commit
7bd94eac0e
@ -30,6 +30,7 @@ import {
|
||||
} from './canvasTypes';
|
||||
import { ImageDTO } from 'services/api';
|
||||
import { sessionCanceled } from 'services/thunks/session';
|
||||
import { setShouldUseCanvasBetaLayout } from 'features/ui/store/uiSlice';
|
||||
|
||||
export const initialLayerState: CanvasLayerState = {
|
||||
objects: [],
|
||||
@ -851,6 +852,10 @@ export const canvasSlice = createSlice({
|
||||
state.layerState.stagingArea = initialLayerState.stagingArea;
|
||||
}
|
||||
});
|
||||
|
||||
builder.addCase(setShouldUseCanvasBetaLayout, (state, action) => {
|
||||
state.doesCanvasNeedScaling = true;
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
|
@ -1,72 +0,0 @@
|
||||
import { createSelector } from '@reduxjs/toolkit';
|
||||
// import IAICanvas from 'features/canvas/components/IAICanvas';
|
||||
import { Box, Flex } from '@chakra-ui/react';
|
||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||
import IAICanvas from 'features/canvas/components/IAICanvas';
|
||||
import IAICanvasResizer from 'features/canvas/components/IAICanvasResizer';
|
||||
import { canvasSelector } from 'features/canvas/store/canvasSelectors';
|
||||
|
||||
import { isEqual } from 'lodash-es';
|
||||
import { useLayoutEffect } from 'react';
|
||||
import UnifiedCanvasToolbarBeta from './UnifiedCanvasToolbarBeta';
|
||||
import UnifiedCanvasToolSettingsBeta from './UnifiedCanvasToolSettingsBeta';
|
||||
import { requestCanvasRescale } from 'features/canvas/store/thunks/requestCanvasScale';
|
||||
|
||||
const selector = createSelector(
|
||||
[canvasSelector],
|
||||
(canvas) => {
|
||||
const { doesCanvasNeedScaling } = canvas;
|
||||
return {
|
||||
doesCanvasNeedScaling,
|
||||
};
|
||||
},
|
||||
{
|
||||
memoizeOptions: {
|
||||
resultEqualityCheck: isEqual,
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
const UnifiedCanvasContentBeta = () => {
|
||||
const dispatch = useAppDispatch();
|
||||
|
||||
const { doesCanvasNeedScaling } = useAppSelector(selector);
|
||||
|
||||
useLayoutEffect(() => {
|
||||
dispatch(requestCanvasRescale());
|
||||
const resizeCallback = () => {
|
||||
dispatch(requestCanvasRescale());
|
||||
};
|
||||
|
||||
window.addEventListener('resize', resizeCallback);
|
||||
|
||||
return () => window.removeEventListener('resize', resizeCallback);
|
||||
}, [dispatch]);
|
||||
|
||||
return (
|
||||
<Box
|
||||
sx={{
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
borderRadius: 'base',
|
||||
bg: 'base.850',
|
||||
}}
|
||||
>
|
||||
<Flex
|
||||
flexDirection="row"
|
||||
width="100%"
|
||||
height="100%"
|
||||
columnGap={4}
|
||||
padding={4}
|
||||
>
|
||||
<UnifiedCanvasToolbarBeta />
|
||||
<Flex width="100%" height="100%" flexDirection="column" rowGap={4}>
|
||||
<UnifiedCanvasToolSettingsBeta />
|
||||
{doesCanvasNeedScaling ? <IAICanvasResizer /> : <IAICanvas />}
|
||||
</Flex>
|
||||
</Flex>
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
export default UnifiedCanvasContentBeta;
|
@ -1,34 +1,58 @@
|
||||
import { Box, Flex } from '@chakra-ui/react';
|
||||
import { createSelector } from '@reduxjs/toolkit';
|
||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||
import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions';
|
||||
import IAICanvas from 'features/canvas/components/IAICanvas';
|
||||
import IAICanvasResizer from 'features/canvas/components/IAICanvasResizer';
|
||||
import IAICanvasToolbar from 'features/canvas/components/IAICanvasToolbar/IAICanvasToolbar';
|
||||
import { canvasSelector } from 'features/canvas/store/canvasSelectors';
|
||||
import { requestCanvasRescale } from 'features/canvas/store/thunks/requestCanvasScale';
|
||||
import { isEqual } from 'lodash-es';
|
||||
import { uiSelector } from 'features/ui/store/uiSelectors';
|
||||
|
||||
import { memo, useLayoutEffect } from 'react';
|
||||
import { memo, useCallback, useLayoutEffect } from 'react';
|
||||
import UnifiedCanvasToolbarBeta from './UnifiedCanvasBeta/UnifiedCanvasToolbarBeta';
|
||||
import UnifiedCanvasToolSettingsBeta from './UnifiedCanvasBeta/UnifiedCanvasToolSettingsBeta';
|
||||
import { ImageDTO } from 'services/api';
|
||||
import { setInitialCanvasImage } from 'features/canvas/store/canvasSlice';
|
||||
import { useDroppable } from '@dnd-kit/core';
|
||||
import IAIDropOverlay from 'common/components/IAIDropOverlay';
|
||||
|
||||
const selector = createSelector(
|
||||
[canvasSelector],
|
||||
(canvas) => {
|
||||
[canvasSelector, uiSelector],
|
||||
(canvas, ui) => {
|
||||
const { doesCanvasNeedScaling } = canvas;
|
||||
const { shouldUseCanvasBetaLayout } = ui;
|
||||
return {
|
||||
doesCanvasNeedScaling,
|
||||
shouldUseCanvasBetaLayout,
|
||||
};
|
||||
},
|
||||
{
|
||||
memoizeOptions: {
|
||||
resultEqualityCheck: isEqual,
|
||||
},
|
||||
}
|
||||
defaultSelectorOptions
|
||||
);
|
||||
|
||||
const UnifiedCanvasContent = () => {
|
||||
const dispatch = useAppDispatch();
|
||||
|
||||
const { doesCanvasNeedScaling } = useAppSelector(selector);
|
||||
const { doesCanvasNeedScaling, shouldUseCanvasBetaLayout } =
|
||||
useAppSelector(selector);
|
||||
|
||||
const onDrop = useCallback(
|
||||
(droppedImage: ImageDTO) => {
|
||||
dispatch(setInitialCanvasImage(droppedImage));
|
||||
},
|
||||
[dispatch]
|
||||
);
|
||||
|
||||
const {
|
||||
isOver,
|
||||
setNodeRef: setDroppableRef,
|
||||
active,
|
||||
} = useDroppable({
|
||||
id: 'unifiedCanvas',
|
||||
data: {
|
||||
handleDrop: onDrop,
|
||||
},
|
||||
});
|
||||
|
||||
useLayoutEffect(() => {
|
||||
dispatch(requestCanvasRescale());
|
||||
@ -42,14 +66,55 @@ const UnifiedCanvasContent = () => {
|
||||
return () => window.removeEventListener('resize', resizeCallback);
|
||||
}, [dispatch]);
|
||||
|
||||
if (shouldUseCanvasBetaLayout) {
|
||||
return (
|
||||
<Box
|
||||
ref={setDroppableRef}
|
||||
sx={{
|
||||
w: 'full',
|
||||
h: 'full',
|
||||
borderRadius: 'base',
|
||||
bg: 'base.850',
|
||||
p: 4,
|
||||
}}
|
||||
>
|
||||
<Flex
|
||||
sx={{
|
||||
w: 'full',
|
||||
h: 'full',
|
||||
gap: 4,
|
||||
}}
|
||||
>
|
||||
<UnifiedCanvasToolbarBeta />
|
||||
<Flex
|
||||
sx={{
|
||||
flexDir: 'column',
|
||||
w: 'full',
|
||||
h: 'full',
|
||||
gap: 4,
|
||||
position: 'relative',
|
||||
}}
|
||||
>
|
||||
<UnifiedCanvasToolSettingsBeta />
|
||||
<Box sx={{ w: 'full', h: 'full', position: 'relative' }}>
|
||||
{doesCanvasNeedScaling ? <IAICanvasResizer /> : <IAICanvas />}
|
||||
{active && <IAIDropOverlay isOver={isOver} />}
|
||||
</Box>
|
||||
</Flex>
|
||||
</Flex>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<Box
|
||||
ref={setDroppableRef}
|
||||
sx={{
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
padding: 4,
|
||||
w: 'full',
|
||||
h: 'full',
|
||||
borderRadius: 'base',
|
||||
bg: 'base.850',
|
||||
p: 4,
|
||||
}}
|
||||
>
|
||||
<Flex
|
||||
@ -57,8 +122,8 @@ const UnifiedCanvasContent = () => {
|
||||
flexDirection: 'column',
|
||||
alignItems: 'center',
|
||||
gap: 4,
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
w: 'full',
|
||||
h: 'full',
|
||||
}}
|
||||
>
|
||||
<IAICanvasToolbar />
|
||||
@ -68,11 +133,14 @@ const UnifiedCanvasContent = () => {
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
gap: 4,
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
w: 'full',
|
||||
h: 'full',
|
||||
}}
|
||||
>
|
||||
{doesCanvasNeedScaling ? <IAICanvasResizer /> : <IAICanvas />}
|
||||
<Box sx={{ w: 'full', h: 'full', position: 'relative' }}>
|
||||
{doesCanvasNeedScaling ? <IAICanvasResizer /> : <IAICanvas />}
|
||||
{active && <IAIDropOverlay isOver={isOver} />}
|
||||
</Box>
|
||||
</Flex>
|
||||
</Flex>
|
||||
</Box>
|
||||
|
@ -1,34 +1,16 @@
|
||||
import { Flex } from '@chakra-ui/react';
|
||||
import { memo } from 'react';
|
||||
import { createSelector } from '@reduxjs/toolkit';
|
||||
import { uiSelector } from 'features/ui/store/uiSelectors';
|
||||
import { useAppSelector } from 'app/store/storeHooks';
|
||||
import UnifiedCanvasContent from './UnifiedCanvasContent';
|
||||
import UnifiedCanvasParameters from './UnifiedCanvasParameters';
|
||||
import UnifiedCanvasContentBeta from './UnifiedCanvasBeta/UnifiedCanvasContentBeta';
|
||||
import ParametersPinnedWrapper from '../../ParametersPinnedWrapper';
|
||||
|
||||
const selector = createSelector(uiSelector, (ui) => {
|
||||
const { shouldUseCanvasBetaLayout } = ui;
|
||||
|
||||
return {
|
||||
shouldUseCanvasBetaLayout,
|
||||
};
|
||||
});
|
||||
|
||||
const UnifiedCanvasTab = () => {
|
||||
const { shouldUseCanvasBetaLayout } = useAppSelector(selector);
|
||||
|
||||
return (
|
||||
<Flex sx={{ gap: 4, w: 'full', h: 'full' }}>
|
||||
<ParametersPinnedWrapper>
|
||||
<UnifiedCanvasParameters />
|
||||
</ParametersPinnedWrapper>
|
||||
{shouldUseCanvasBetaLayout ? (
|
||||
<UnifiedCanvasContentBeta />
|
||||
) : (
|
||||
<UnifiedCanvasContent />
|
||||
)}
|
||||
<UnifiedCanvasContent />
|
||||
</Flex>
|
||||
);
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user