mirror of
https://github.com/invoke-ai/InvokeAI
synced 2024-08-30 20:32:17 +00:00
feat(ui): add toggle for clipToBbox
This commit is contained in:
parent
488ca87787
commit
ce8a7bc178
@ -11,7 +11,7 @@ import {
|
||||
} from '@invoke-ai/ui-library';
|
||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||
import { MaskOpacity } from 'features/controlLayers/components/MaskOpacity';
|
||||
import { invertScrollChanged } from 'features/controlLayers/store/canvasV2Slice';
|
||||
import { clipToBboxChanged, invertScrollChanged } from 'features/controlLayers/store/canvasV2Slice';
|
||||
import type { ChangeEvent } from 'react';
|
||||
import { memo, useCallback } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
@ -20,11 +20,16 @@ import { RiSettings4Fill } from 'react-icons/ri';
|
||||
const ControlLayersSettingsPopover = () => {
|
||||
const { t } = useTranslation();
|
||||
const dispatch = useAppDispatch();
|
||||
const clipToBbox = useAppSelector((s) => s.canvasV2.settings.clipToBbox);
|
||||
const invertScroll = useAppSelector((s) => s.canvasV2.tool.invertScroll);
|
||||
const onChangeInvertScroll = useCallback(
|
||||
(e: ChangeEvent<HTMLInputElement>) => dispatch(invertScrollChanged(e.target.checked)),
|
||||
[dispatch]
|
||||
);
|
||||
const onChangeClipToBbox = useCallback(
|
||||
(e: ChangeEvent<HTMLInputElement>) => dispatch(clipToBboxChanged(e.target.checked)),
|
||||
[dispatch]
|
||||
);
|
||||
return (
|
||||
<Popover isLazy>
|
||||
<PopoverTrigger>
|
||||
@ -38,6 +43,10 @@ const ControlLayersSettingsPopover = () => {
|
||||
<FormLabel flexGrow={1}>{t('unifiedCanvas.invertBrushSizeScrollDirection')}</FormLabel>
|
||||
<Checkbox isChecked={invertScroll} onChange={onChangeInvertScroll} />
|
||||
</FormControl>
|
||||
<FormControl w="full">
|
||||
<FormLabel flexGrow={1}>{t('unifiedCanvas.clipToBbox')}</FormLabel>
|
||||
<Checkbox isChecked={clipToBbox} onChange={onChangeClipToBbox} />
|
||||
</FormControl>
|
||||
</Flex>
|
||||
</PopoverBody>
|
||||
</PopoverContent>
|
||||
|
@ -53,6 +53,7 @@ type Arg = {
|
||||
setSpaceKey: (val: boolean) => void;
|
||||
getDocument: () => CanvasV2State['document'];
|
||||
getBbox: () => CanvasV2State['bbox'];
|
||||
getSettings: () => CanvasV2State['settings'];
|
||||
onBrushLineAdded: (arg: BrushLineAddedArg, entityType: CanvasEntity['type']) => void;
|
||||
onEraserLineAdded: (arg: EraserLineAddedArg, entityType: CanvasEntity['type']) => void;
|
||||
onPointAddedToLine: (arg: PointAddedToLineArg, entityType: CanvasEntity['type']) => void;
|
||||
@ -155,6 +156,7 @@ export const setStageEventHandlers = ({
|
||||
setSpaceKey,
|
||||
getDocument,
|
||||
getBbox,
|
||||
getSettings,
|
||||
onBrushLineAdded,
|
||||
onEraserLineAdded,
|
||||
onPointAddedToLine,
|
||||
@ -203,6 +205,17 @@ export const setStageEventHandlers = ({
|
||||
|
||||
if (toolState.selected === 'brush') {
|
||||
const bbox = getBbox();
|
||||
const settings = getSettings();
|
||||
|
||||
const clip = settings.clipToBbox
|
||||
? {
|
||||
x: bbox.x,
|
||||
y: bbox.y,
|
||||
width: bbox.width,
|
||||
height: bbox.height,
|
||||
}
|
||||
: null;
|
||||
|
||||
if (e.evt.shiftKey) {
|
||||
const lastAddedPoint = getLastAddedPoint();
|
||||
// Create a straight line if holding shift
|
||||
@ -218,12 +231,7 @@ export const setStageEventHandlers = ({
|
||||
],
|
||||
color: getCurrentFill(),
|
||||
width: toolState.brush.width,
|
||||
clip: {
|
||||
x: bbox.x,
|
||||
y: bbox.y,
|
||||
width: bbox.width,
|
||||
height: bbox.height,
|
||||
},
|
||||
clip,
|
||||
},
|
||||
selectedEntity.type
|
||||
);
|
||||
@ -240,12 +248,7 @@ export const setStageEventHandlers = ({
|
||||
],
|
||||
color: getCurrentFill(),
|
||||
width: toolState.brush.width,
|
||||
clip: {
|
||||
x: bbox.x,
|
||||
y: bbox.y,
|
||||
width: bbox.width,
|
||||
height: bbox.height,
|
||||
},
|
||||
clip,
|
||||
},
|
||||
selectedEntity.type
|
||||
);
|
||||
@ -255,6 +258,16 @@ export const setStageEventHandlers = ({
|
||||
|
||||
if (toolState.selected === 'eraser') {
|
||||
const bbox = getBbox();
|
||||
const settings = getSettings();
|
||||
|
||||
const clip = settings.clipToBbox
|
||||
? {
|
||||
x: bbox.x,
|
||||
y: bbox.y,
|
||||
width: bbox.width,
|
||||
height: bbox.height,
|
||||
}
|
||||
: null;
|
||||
if (e.evt.shiftKey) {
|
||||
// Create a straight line if holding shift
|
||||
const lastAddedPoint = getLastAddedPoint();
|
||||
@ -269,12 +282,7 @@ export const setStageEventHandlers = ({
|
||||
pos.y - selectedEntity.y,
|
||||
],
|
||||
width: toolState.eraser.width,
|
||||
clip: {
|
||||
x: bbox.x,
|
||||
y: bbox.y,
|
||||
width: bbox.width,
|
||||
height: bbox.height,
|
||||
},
|
||||
clip,
|
||||
},
|
||||
selectedEntity.type
|
||||
);
|
||||
@ -290,12 +298,7 @@ export const setStageEventHandlers = ({
|
||||
pos.y - selectedEntity.y,
|
||||
],
|
||||
width: toolState.eraser.width,
|
||||
clip: {
|
||||
x: bbox.x,
|
||||
y: bbox.y,
|
||||
width: bbox.width,
|
||||
height: bbox.height,
|
||||
},
|
||||
clip,
|
||||
},
|
||||
selectedEntity.type
|
||||
);
|
||||
@ -402,6 +405,16 @@ export const setStageEventHandlers = ({
|
||||
);
|
||||
} else {
|
||||
const bbox = getBbox();
|
||||
const settings = getSettings();
|
||||
|
||||
const clip = settings.clipToBbox
|
||||
? {
|
||||
x: bbox.x,
|
||||
y: bbox.y,
|
||||
width: bbox.width,
|
||||
height: bbox.height,
|
||||
}
|
||||
: null;
|
||||
// Start a new line
|
||||
onBrushLineAdded(
|
||||
{
|
||||
@ -414,12 +427,7 @@ export const setStageEventHandlers = ({
|
||||
],
|
||||
width: toolState.brush.width,
|
||||
color: getCurrentFill(),
|
||||
clip: {
|
||||
x: bbox.x,
|
||||
y: bbox.y,
|
||||
width: bbox.width,
|
||||
height: bbox.height,
|
||||
},
|
||||
clip,
|
||||
},
|
||||
selectedEntity.type
|
||||
);
|
||||
@ -441,6 +449,16 @@ export const setStageEventHandlers = ({
|
||||
);
|
||||
} else {
|
||||
const bbox = getBbox();
|
||||
const settings = getSettings();
|
||||
|
||||
const clip = settings.clipToBbox
|
||||
? {
|
||||
x: bbox.x,
|
||||
y: bbox.y,
|
||||
width: bbox.width,
|
||||
height: bbox.height,
|
||||
}
|
||||
: null;
|
||||
// Start a new line
|
||||
onEraserLineAdded(
|
||||
{
|
||||
@ -452,12 +470,7 @@ export const setStageEventHandlers = ({
|
||||
pos.y - selectedEntity.y,
|
||||
],
|
||||
width: toolState.eraser.width,
|
||||
clip: {
|
||||
x: bbox.x,
|
||||
y: bbox.y,
|
||||
width: bbox.width,
|
||||
height: bbox.height,
|
||||
},
|
||||
clip,
|
||||
},
|
||||
selectedEntity.type
|
||||
);
|
||||
|
@ -33,8 +33,6 @@ const getControlAdapter = (manager: KonvaNodeManager, entity: ControlAdapterEnti
|
||||
listening: false,
|
||||
});
|
||||
const konvaObjectGroup = createObjectGroup(konvaLayer, CA_LAYER_OBJECT_GROUP_NAME);
|
||||
konvaLayer.add(konvaObjectGroup);
|
||||
manager.stage.add(konvaLayer);
|
||||
return manager.add(entity.id, konvaLayer, konvaObjectGroup);
|
||||
};
|
||||
|
||||
|
@ -3,8 +3,8 @@ import type { Store } from '@reduxjs/toolkit';
|
||||
import { logger } from 'app/logging/logger';
|
||||
import { $isDebugging } from 'app/store/nanostores/isDebugging';
|
||||
import type { RootState } from 'app/store/store';
|
||||
import { KonvaNodeManager } from 'features/controlLayers/konva/nodeManager';
|
||||
import { setStageEventHandlers } from 'features/controlLayers/konva/events';
|
||||
import { KonvaNodeManager } from 'features/controlLayers/konva/nodeManager';
|
||||
import { arrangeEntities } from 'features/controlLayers/konva/renderers/arrange';
|
||||
import { renderBackgroundLayer } from 'features/controlLayers/konva/renderers/background';
|
||||
import { updateBboxes } from 'features/controlLayers/konva/renderers/bbox';
|
||||
@ -209,6 +209,7 @@ export const initializeRenderer = (
|
||||
const getBbox = () => getState().canvasV2.bbox;
|
||||
const getDocument = () => getState().canvasV2.document;
|
||||
const getToolState = () => getState().canvasV2.tool;
|
||||
const getSettings = () => getState().canvasV2.settings;
|
||||
|
||||
// Read-write state, ephemeral interaction state
|
||||
let isDrawing = false;
|
||||
@ -268,6 +269,7 @@ export const initializeRenderer = (
|
||||
setStageAttrs: $stageAttrs.set,
|
||||
getDocument,
|
||||
getBbox,
|
||||
getSettings,
|
||||
onBrushLineAdded,
|
||||
onEraserLineAdded,
|
||||
onPointAddedToLine,
|
||||
|
@ -184,6 +184,7 @@ export const {
|
||||
allEntitiesDeleted,
|
||||
scaledBboxChanged,
|
||||
bboxScaleMethodChanged,
|
||||
clipToBboxChanged,
|
||||
// layers
|
||||
layerAdded,
|
||||
layerRecalled,
|
||||
|
@ -5,4 +5,7 @@ export const settingsReducers = {
|
||||
maskOpacityChanged: (state, action: PayloadAction<number>) => {
|
||||
state.settings.maskOpacity = action.payload;
|
||||
},
|
||||
clipToBboxChanged: (state, action: PayloadAction<boolean>) => {
|
||||
state.settings.clipToBbox = action.payload;
|
||||
},
|
||||
} satisfies SliceCaseReducers<CanvasV2State>;
|
||||
|
Loading…
Reference in New Issue
Block a user