UNDO ME WIP

This commit is contained in:
psychedelicious 2024-07-08 23:56:21 +10:00
parent c49b90e621
commit 78b4562184
11 changed files with 185 additions and 8 deletions

View File

@ -18,7 +18,7 @@ export const addEnqueueRequestedLinear = (startAppListening: AppStartListening)
const { prepend } = action.payload; const { prepend } = action.payload;
let didStartStaging = false; let didStartStaging = false;
if (!state.canvasV2.session.isStaging) { if (!state.canvasV2.session.isStaging && state.canvasV2.session.isActive) {
dispatch(sessionStartedStaging()); dispatch(sessionStartedStaging());
didStartStaging = true; didStartStaging = true;
} }

View File

@ -0,0 +1,147 @@
import { Flex, Grid, GridItem, IconButton } from '@invoke-ai/ui-library';
import { useAppSelector } from 'app/store/storeHooks';
import { memo, useCallback, useState } from 'react';
import {
PiArrowDownBold,
PiArrowDownLeftBold,
PiArrowDownRightBold,
PiArrowLeftBold,
PiArrowRightBold,
PiArrowUpBold,
PiArrowUpLeftBold,
PiArrowUpRightBold,
PiSquareBold,
} from 'react-icons/pi';
type ResizeDirection =
| 'up-left'
| 'up'
| 'up-right'
| 'left'
| 'center-out'
| 'right'
| 'down-left'
| 'down'
| 'down-right';
export const CanvasResizer = memo(() => {
const document = useAppSelector((s) => s.canvasV2.document);
const [resizeDirection, setResizeDirection] = useState<ResizeDirection>('center-out');
const setDirUpLeft = useCallback(() => {
setResizeDirection('up-left');
}, []);
const setDirUp = useCallback(() => {
setResizeDirection('up');
}, []);
const setDirUpRight = useCallback(() => {
setResizeDirection('up-right');
}, []);
const setDirLeft = useCallback(() => {
setResizeDirection('left');
}, []);
const setDirCenterOut = useCallback(() => {
setResizeDirection('center-out');
}, []);
const setDirRight = useCallback(() => {
setResizeDirection('right');
}, []);
const setDirDownLeft = useCallback(() => {
setResizeDirection('down-left');
}, []);
const setDirDown = useCallback(() => {
setResizeDirection('down');
}, []);
const setDirDownRight = useCallback(() => {
setResizeDirection('down-right');
}, []);
return (
<Flex p={2}>
<Grid gridTemplateRows="1fr 1fr 1fr" gridTemplateColumns="1fr 1fr 1fr" gap={2}>
<GridItem>
<IconButton
onClick={setDirUpLeft}
aria-label="up-left"
icon={<PiArrowUpLeftBold />}
variant={resizeDirection === 'up-left' ? 'solid' : 'ghost'}
/>
</GridItem>
<GridItem>
<IconButton
onClick={setDirUp}
aria-label="up"
icon={<PiArrowUpBold />}
variant={resizeDirection === 'up' ? 'solid' : 'ghost'}
/>
</GridItem>
<GridItem>
<IconButton
onClick={setDirUpRight}
aria-label="up-right"
icon={<PiArrowUpRightBold />}
variant={resizeDirection === 'up-right' ? 'solid' : 'ghost'}
/>
</GridItem>
<GridItem>
<IconButton
onClick={setDirLeft}
aria-label="left"
icon={<PiArrowLeftBold />}
variant={resizeDirection === 'left' ? 'solid' : 'ghost'}
/>
</GridItem>
<GridItem>
<IconButton
onClick={setDirCenterOut}
aria-label="center-out"
icon={<PiSquareBold />}
variant={resizeDirection === 'center-out' ? 'solid' : 'ghost'}
/>
</GridItem>
<GridItem>
<IconButton
onClick={setDirRight}
aria-label="right"
icon={<PiArrowRightBold />}
variant={resizeDirection === 'right' ? 'solid' : 'ghost'}
/>
</GridItem>
<GridItem>
<IconButton
onClick={setDirDownLeft}
aria-label="down-left"
icon={<PiArrowDownLeftBold />}
variant={resizeDirection === 'down-left' ? 'solid' : 'ghost'}
/>
</GridItem>
<GridItem>
<IconButton
onClick={setDirDown}
aria-label="down"
icon={<PiArrowDownBold />}
variant={resizeDirection === 'down' ? 'solid' : 'ghost'}
/>
</GridItem>
<GridItem>
<IconButton
onClick={setDirDownRight}
aria-label="down-right"
icon={<PiArrowDownRightBold />}
variant={resizeDirection === 'down-right' ? 'solid' : 'ghost'}
/>
</GridItem>
</Grid>
</Flex>
);
});
CanvasResizer.displayName = 'CanvasResizer';

View File

@ -21,6 +21,9 @@ export const ControlLayersEditor = memo(() => {
<Flex position="absolute" bottom={2} gap={2} align="center" justify="center"> <Flex position="absolute" bottom={2} gap={2} align="center" justify="center">
<StagingAreaToolbar /> <StagingAreaToolbar />
</Flex> </Flex>
{/* <Flex position="absolute" top={0} right={0} bottom={0} left={0} align="center" justify="center">
<CanvasResizer />
</Flex> */}
</Flex> </Flex>
); );
}); });

View File

@ -5,6 +5,7 @@ import { BrushWidth } from 'features/controlLayers/components/BrushWidth';
import ControlLayersSettingsPopover from 'features/controlLayers/components/ControlLayersSettingsPopover'; import ControlLayersSettingsPopover from 'features/controlLayers/components/ControlLayersSettingsPopover';
import { EraserWidth } from 'features/controlLayers/components/EraserWidth'; import { EraserWidth } from 'features/controlLayers/components/EraserWidth';
import { FillColorPicker } from 'features/controlLayers/components/FillColorPicker'; import { FillColorPicker } from 'features/controlLayers/components/FillColorPicker';
import { NewSessionButton } from 'features/controlLayers/components/NewSessionButton';
import { ResetCanvasButton } from 'features/controlLayers/components/ResetCanvasButton'; import { ResetCanvasButton } from 'features/controlLayers/components/ResetCanvasButton';
import { ToolChooser } from 'features/controlLayers/components/ToolChooser'; import { ToolChooser } from 'features/controlLayers/components/ToolChooser';
import { UndoRedoButtonGroup } from 'features/controlLayers/components/UndoRedoButtonGroup'; import { UndoRedoButtonGroup } from 'features/controlLayers/components/UndoRedoButtonGroup';
@ -32,6 +33,7 @@ export const ControlLayersToolbar = memo(() => {
<UndoRedoButtonGroup /> <UndoRedoButtonGroup />
<ControlLayersSettingsPopover /> <ControlLayersSettingsPopover />
<ResetCanvasButton /> <ResetCanvasButton />
<NewSessionButton />
<ViewerToggleMenu /> <ViewerToggleMenu />
</Flex> </Flex>
</Flex> </Flex>

View File

@ -0,0 +1,16 @@
import { Button } from '@invoke-ai/ui-library';
import { useAppDispatch } from 'app/store/storeHooks';
import { sessionStarted } from 'features/controlLayers/store/canvasV2Slice';
import { memo, useCallback } from 'react';
export const NewSessionButton = memo(() => {
const dispatch = useAppDispatch();
const onClick = useCallback(() => {
dispatch(sessionStarted());
}, [dispatch]);
return <Button onClick={onClick}>New</Button>;
});
NewSessionButton.displayName = 'NewSessionButton';

View File

@ -205,9 +205,17 @@ export class CanvasBbox {
} }
render() { render() {
const session = this.manager.stateApi.getSession();
const bbox = this.manager.stateApi.getBbox(); const bbox = this.manager.stateApi.getBbox();
const toolState = this.manager.stateApi.getToolState(); const toolState = this.manager.stateApi.getToolState();
if (!session.isActive) {
this.group.listening(false);
this.group.visible(false);
return;
}
this.group.visible(true);
this.group.listening(toolState.selected === 'bbox'); this.group.listening(toolState.selected === 'bbox');
this.rect.setAttrs({ this.rect.setAttrs({
x: bbox.rect.x, x: bbox.rect.x,

View File

@ -265,7 +265,8 @@ export class CanvasManager {
if ( if (
this.isFirstRender || this.isFirstRender ||
state.bbox !== this.prevState.bbox || state.bbox !== this.prevState.bbox ||
state.tool.selected !== this.prevState.tool.selected state.tool.selected !== this.prevState.tool.selected ||
state.session.isActive !== this.prevState.session.isActive
) { ) {
log.debug('Rendering generation bbox'); log.debug('Rendering generation bbox');
this.preview.bbox.render(); this.preview.bbox.render();

View File

@ -20,7 +20,7 @@ export class CanvasStagingArea {
} }
async render() { async render() {
const stagingArea = this.manager.stateApi.getStagingAreaState(); const stagingArea = this.manager.stateApi.getSession();
const bbox = this.manager.stateApi.getBbox(); const bbox = this.manager.stateApi.getBbox();
const shouldShowStagedImage = this.manager.stateApi.getShouldShowStagedImage(); const shouldShowStagedImage = this.manager.stateApi.getShouldShowStagedImage();
const lastProgressEvent = this.manager.stateApi.getLastProgressEvent(); const lastProgressEvent = this.manager.stateApi.getLastProgressEvent();

View File

@ -231,7 +231,7 @@ export class CanvasStateApi {
getMaskOpacity = () => { getMaskOpacity = () => {
return this.getState().settings.maskOpacity; return this.getState().settings.maskOpacity;
}; };
getStagingAreaState = () => { getSession = () => {
return this.getState().session; return this.getState().session;
}; };
getIsSelected = (id: string) => { getIsSelected = (id: string) => {

View File

@ -353,7 +353,7 @@ export function getCompositeLayerStageClone(arg: { manager: CanvasManager }): Ko
export function getGenerationMode(arg: { manager: CanvasManager }): GenerationMode { export function getGenerationMode(arg: { manager: CanvasManager }): GenerationMode {
const { manager } = arg; const { manager } = arg;
const { x, y, width, height } = manager.stateApi.getBbox(); const { x, y, width, height } = manager.stateApi.getBbox().rect;
const inpaintMaskLayer = getInpaintMaskLayerClone(arg); const inpaintMaskLayer = getInpaintMaskLayerClone(arg);
const inpaintMaskImageData = konvaNodeToImageData(inpaintMaskLayer, { x, y, width, height }); const inpaintMaskImageData = konvaNodeToImageData(inpaintMaskLayer, { x, y, width, height });
const inpaintMaskTransparency = getImageDataTransparency(inpaintMaskImageData); const inpaintMaskTransparency = getImageDataTransparency(inpaintMaskImageData);

View File

@ -1,8 +1,8 @@
import type { FormLabelProps } from '@invoke-ai/ui-library'; import type { FormLabelProps } from '@invoke-ai/ui-library';
import { Flex, FormControlGroup } from '@invoke-ai/ui-library'; import { Flex, FormControlGroup } from '@invoke-ai/ui-library';
import { CanvasResizer } from 'features/controlLayers/components/CanvasResizer';
import { ParamHeight } from 'features/parameters/components/Core/ParamHeight'; import { ParamHeight } from 'features/parameters/components/Core/ParamHeight';
import { ParamWidth } from 'features/parameters/components/Core/ParamWidth'; import { ParamWidth } from 'features/parameters/components/Core/ParamWidth';
import { AspectRatioIconPreview } from 'features/parameters/components/DocumentSize/AspectRatioIconPreview';
import { AspectRatioSelect } from 'features/parameters/components/DocumentSize/AspectRatioSelect'; import { AspectRatioSelect } from 'features/parameters/components/DocumentSize/AspectRatioSelect';
import { LockAspectRatioButton } from 'features/parameters/components/DocumentSize/LockAspectRatioButton'; import { LockAspectRatioButton } from 'features/parameters/components/DocumentSize/LockAspectRatioButton';
import { SetOptimalSizeButton } from 'features/parameters/components/DocumentSize/SetOptimalSizeButton'; import { SetOptimalSizeButton } from 'features/parameters/components/DocumentSize/SetOptimalSizeButton';
@ -24,8 +24,8 @@ export const DocumentSize = memo(() => {
<ParamHeight /> <ParamHeight />
</FormControlGroup> </FormControlGroup>
</Flex> </Flex>
<Flex w="108px" h="108px" flexShrink={0} flexGrow={0}> <Flex w="108px" h="108px" flexShrink={0} flexGrow={0} bg="base.850" alignItems="center" justifyContent="center">
<AspectRatioIconPreview /> <CanvasResizer />
</Flex> </Flex>
</Flex> </Flex>
); );