mirror of
https://github.com/invoke-ai/InvokeAI
synced 2024-08-30 20:32:17 +00:00
feat(ui): support image objects on raster layers
Just the UI and internal state, not rendering yet.
This commit is contained in:
parent
cefd9a027c
commit
5c0676bcc2
@ -10,6 +10,7 @@ import {
|
||||
import {
|
||||
caLayerImageChanged,
|
||||
iiLayerImageChanged,
|
||||
imageAdded,
|
||||
ipaLayerImageChanged,
|
||||
rgLayerIPAdapterImageChanged,
|
||||
} from 'features/controlLayers/store/controlLayersSlice';
|
||||
@ -161,6 +162,24 @@ export const addImageDroppedListener = (startAppListening: AppStartListening) =>
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Image dropped on Raster layer
|
||||
*/
|
||||
if (
|
||||
overData.actionType === 'ADD_RASTER_LAYER_IMAGE' &&
|
||||
activeData.payloadType === 'IMAGE_DTO' &&
|
||||
activeData.payload.imageDTO
|
||||
) {
|
||||
const { layerId } = overData.context;
|
||||
dispatch(
|
||||
imageAdded({
|
||||
layerId,
|
||||
imageDTO: activeData.payload.imageDTO,
|
||||
})
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Image dropped on Canvas
|
||||
*/
|
||||
|
@ -11,6 +11,7 @@ type Props = PropsWithChildren<{
|
||||
export const LayerWrapper = memo(({ onClick, borderColor, children }: Props) => {
|
||||
return (
|
||||
<Flex
|
||||
position="relative"
|
||||
gap={2}
|
||||
onClick={onClick}
|
||||
bg={borderColor}
|
||||
|
@ -1,5 +1,6 @@
|
||||
import { Flex, Spacer, useDisclosure } from '@invoke-ai/ui-library';
|
||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||
import IAIDroppable from 'common/components/IAIDroppable';
|
||||
import { LayerDeleteButton } from 'features/controlLayers/components/LayerCommon/LayerDeleteButton';
|
||||
import { LayerMenu } from 'features/controlLayers/components/LayerCommon/LayerMenu';
|
||||
import { LayerOpacity } from 'features/controlLayers/components/LayerCommon/LayerOpacity';
|
||||
@ -8,7 +9,8 @@ import { LayerIsEnabledToggle } from 'features/controlLayers/components/LayerCom
|
||||
import { LayerWrapper } from 'features/controlLayers/components/LayerCommon/LayerWrapper';
|
||||
import { layerSelected, selectLayerOrThrow } from 'features/controlLayers/store/controlLayersSlice';
|
||||
import { isRasterLayer } from 'features/controlLayers/store/types';
|
||||
import { memo, useCallback } from 'react';
|
||||
import type { RasterLayerImageDropData } from 'features/dnd/types';
|
||||
import { memo, useCallback, useMemo } from 'react';
|
||||
|
||||
type Props = {
|
||||
layerId: string;
|
||||
@ -24,6 +26,15 @@ export const RasterLayer = memo(({ layerId }: Props) => {
|
||||
}, [dispatch, layerId]);
|
||||
const { isOpen, onToggle } = useDisclosure({ defaultIsOpen: true });
|
||||
|
||||
const droppableData = useMemo(() => {
|
||||
const _droppableData: RasterLayerImageDropData = {
|
||||
id: layerId,
|
||||
actionType: 'ADD_RASTER_LAYER_IMAGE',
|
||||
context: { layerId },
|
||||
};
|
||||
return _droppableData;
|
||||
}, [layerId]);
|
||||
|
||||
return (
|
||||
<LayerWrapper onClick={onClick} borderColor={isSelected ? 'base.400' : 'base.800'}>
|
||||
<Flex gap={3} alignItems="center" p={3} cursor="pointer" onDoubleClick={onToggle}>
|
||||
@ -39,6 +50,7 @@ export const RasterLayer = memo(({ layerId }: Props) => {
|
||||
PLACEHOLDER
|
||||
</Flex>
|
||||
)}
|
||||
<IAIDroppable data={droppableData} />
|
||||
</LayerWrapper>
|
||||
);
|
||||
});
|
||||
|
@ -8,6 +8,7 @@ import {
|
||||
getBrushLineId,
|
||||
getCALayerId,
|
||||
getEraserLineId,
|
||||
getImageObjectId,
|
||||
getIPALayerId,
|
||||
getRasterLayerId,
|
||||
getRectId,
|
||||
@ -48,6 +49,7 @@ import { v4 as uuidv4 } from 'uuid';
|
||||
import type {
|
||||
AddBrushLineArg,
|
||||
AddEraserLineArg,
|
||||
AddImageObjectArg,
|
||||
AddPointToLineArg,
|
||||
AddRectShapeArg,
|
||||
ControlAdapterLayer,
|
||||
@ -715,7 +717,7 @@ export const controlLayersSlice = createSlice({
|
||||
return;
|
||||
}
|
||||
const layer = selectLayerOrThrow(state, layerId, isRGOrRasterlayer);
|
||||
const id = getRectId(layer.id, rectUuid);
|
||||
const id = getRectShapeId(layer.id, rectUuid);
|
||||
layer.objects.push({
|
||||
type: 'rect_shape',
|
||||
id,
|
||||
@ -732,6 +734,25 @@ export const controlLayersSlice = createSlice({
|
||||
},
|
||||
prepare: (payload: AddRectShapeArg) => ({ payload: { ...payload, rectUuid: uuidv4() } }),
|
||||
},
|
||||
imageAdded: {
|
||||
reducer: (state, action: PayloadAction<AddImageObjectArg & { imageUuid: string }>) => {
|
||||
const { layerId, imageUuid, imageDTO } = action.payload;
|
||||
const layer = selectLayerOrThrow(state, layerId, isRasterLayer);
|
||||
const id = getImageObjectId(layer.id, imageUuid);
|
||||
const { width, height, image_name: name } = imageDTO;
|
||||
layer.objects.push({
|
||||
type: 'image',
|
||||
id,
|
||||
x: 0,
|
||||
y: 0,
|
||||
width,
|
||||
height,
|
||||
image: { width, height, name },
|
||||
});
|
||||
layer.bboxNeedsUpdate = true;
|
||||
},
|
||||
prepare: (payload: AddImageObjectArg) => ({ payload: { ...payload, imageUuid: uuidv4() } }),
|
||||
},
|
||||
//#endregion
|
||||
|
||||
//#region Globals
|
||||
@ -897,6 +918,7 @@ export const {
|
||||
eraserLineAdded,
|
||||
linePointsAdded,
|
||||
rectAdded,
|
||||
imageAdded,
|
||||
rgLayerMaskImageUploaded,
|
||||
rgLayerAutoNegativeChanged,
|
||||
rgLayerIPAdapterAdded,
|
||||
|
@ -20,6 +20,7 @@ import {
|
||||
zParameterStrength,
|
||||
} from 'features/parameters/types/parameterSchemas';
|
||||
import type { IRect } from 'konva/lib/types';
|
||||
import type { ImageDTO } from 'services/api/types';
|
||||
import { z } from 'zod';
|
||||
|
||||
const zTool = z.enum(['brush', 'eraser', 'move', 'rect']);
|
||||
@ -273,7 +274,8 @@ export type ControlLayersState = {
|
||||
export type AddEraserLineArg = { layerId: string; points: [number, number, number, number] };
|
||||
export type AddBrushLineArg = AddEraserLineArg & { color: RgbaColor };
|
||||
export type AddPointToLineArg = { layerId: string; point: [number, number] };
|
||||
export type AddRectShapeArg = { layerId: string; rect: IRect; color: RgbaColor }; //#region Type guards
|
||||
export type AddRectShapeArg = { layerId: string; rect: IRect; color: RgbaColor };
|
||||
export type AddImageObjectArg = { layerId: string; imageDTO: ImageDTO };
|
||||
|
||||
//#region Type guards
|
||||
export const isLine = (obj: AnyLayerObject): obj is BrushLine | EraserLine => {
|
||||
|
@ -58,6 +58,13 @@ export type IILayerImageDropData = BaseDropData & {
|
||||
};
|
||||
};
|
||||
|
||||
export type RasterLayerImageDropData = BaseDropData & {
|
||||
actionType: 'ADD_RASTER_LAYER_IMAGE';
|
||||
context: {
|
||||
layerId: string;
|
||||
};
|
||||
};
|
||||
|
||||
export type CanvasInitialImageDropData = BaseDropData & {
|
||||
actionType: 'SET_CANVAS_INITIAL_IMAGE';
|
||||
};
|
||||
|
@ -33,6 +33,8 @@ export const isValidDrop = (overData?: TypesafeDroppableData | null, activeData?
|
||||
return payloadType === 'IMAGE_DTO';
|
||||
case 'SELECT_FOR_COMPARE':
|
||||
return payloadType === 'IMAGE_DTO';
|
||||
case 'ADD_RASTER_LAYER_IMAGE':
|
||||
return payloadType === 'IMAGE_DTO';
|
||||
case 'ADD_TO_BOARD': {
|
||||
// If the board is the same, don't allow the drop
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user