Skip to content

Commit 33c92ec

Browse files
blessedcoolantpsychedelicious
authored andcommitted
Expose Snap Threshold and Move Snap Settings to BBox Panel
1 parent d80844a commit 33c92ec

File tree

5 files changed

+74
-30
lines changed

5 files changed

+74
-30
lines changed

frontend/src/features/canvas/components/IAICanvasToolbar/IAICanvasBoundingBox.tsx

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ const boundingBoxPreviewSelector = createSelector(
3636
tool,
3737
stageCoordinates,
3838
shouldSnapToGrid,
39+
gridSnapThreshold,
3940
} = canvas;
4041

4142
return {
@@ -49,6 +50,7 @@ const boundingBoxPreviewSelector = createSelector(
4950
stageDimensions,
5051
stageScale,
5152
shouldSnapToGrid,
53+
gridSnapThreshold,
5254
tool,
5355
stageCoordinates,
5456
boundingBoxStrokeWidth: (isMouseOverBoundingBox ? 8 : 1) / stageScale,
@@ -80,6 +82,7 @@ const IAICanvasBoundingBox = (props: IAICanvasBoundingBoxPreviewProps) => {
8082
stageDimensions,
8183
stageScale,
8284
shouldSnapToGrid,
85+
gridSnapThreshold,
8386
tool,
8487
boundingBoxStrokeWidth,
8588
hitStrokeWidth,
@@ -111,8 +114,8 @@ const IAICanvasBoundingBox = (props: IAICanvasBoundingBoxPreviewProps) => {
111114
const dragX = e.target.x();
112115
const dragY = e.target.y();
113116

114-
const newX = roundToMultiple(dragX, 64);
115-
const newY = roundToMultiple(dragY, 64);
117+
const newX = roundToMultiple(dragX, gridSnapThreshold);
118+
const newY = roundToMultiple(dragY, gridSnapThreshold);
116119

117120
e.target.x(newX);
118121
e.target.y(newY);
@@ -124,7 +127,7 @@ const IAICanvasBoundingBox = (props: IAICanvasBoundingBoxPreviewProps) => {
124127
})
125128
);
126129
},
127-
[dispatch, shouldSnapToGrid]
130+
[dispatch, shouldSnapToGrid, gridSnapThreshold]
128131
);
129132

130133
const handleOnTransform = useCallback(() => {

frontend/src/features/canvas/components/IAICanvasToolbar/IAICanvasSettingsButtonPopover.tsx

Lines changed: 0 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import {
77
setShouldShowCanvasDebugInfo,
88
setShouldShowGrid,
99
setShouldShowIntermediates,
10-
setShouldSnapToGrid,
1110
} from 'features/canvas/store/canvasSlice';
1211
import { useAppDispatch, useAppSelector } from 'app/store';
1312
import _ from 'lodash';
@@ -18,8 +17,6 @@ import IAICheckbox from 'common/components/IAICheckbox';
1817
import { canvasSelector } from 'features/canvas/store/canvasSelectors';
1918
import EmptyTempFolderButtonModal from 'features/system/components/ClearTempFolderButtonModal';
2019
import ClearCanvasHistoryButtonModal from '../ClearCanvasHistoryButtonModal';
21-
import { ChangeEvent } from 'react';
22-
import { useHotkeys } from 'react-hotkeys-hook';
2320

2421
export const canvasControlsSelector = createSelector(
2522
[canvasSelector],
@@ -60,24 +57,8 @@ const IAICanvasSettingsButtonPopover = () => {
6057
shouldShowCanvasDebugInfo,
6158
shouldShowGrid,
6259
shouldShowIntermediates,
63-
shouldSnapToGrid,
6460
} = useAppSelector(canvasControlsSelector);
6561

66-
useHotkeys(
67-
['n'],
68-
() => {
69-
dispatch(setShouldSnapToGrid(!shouldSnapToGrid));
70-
},
71-
{
72-
enabled: true,
73-
preventDefault: true,
74-
},
75-
[shouldSnapToGrid]
76-
);
77-
78-
const handleChangeShouldSnapToGrid = (e: ChangeEvent<HTMLInputElement>) =>
79-
dispatch(setShouldSnapToGrid(e.target.checked));
80-
8162
return (
8263
<IAIPopover
8364
trigger="hover"
@@ -102,11 +83,6 @@ const IAICanvasSettingsButtonPopover = () => {
10283
isChecked={shouldShowGrid}
10384
onChange={(e) => dispatch(setShouldShowGrid(e.target.checked))}
10485
/>
105-
<IAICheckbox
106-
label="Snap to Grid"
107-
isChecked={shouldSnapToGrid}
108-
onChange={handleChangeShouldSnapToGrid}
109-
/>
11086
<IAICheckbox
11187
label="Darken Outside Selection"
11288
isChecked={shouldDarkenOutsideBoundingBox}

frontend/src/features/canvas/store/canvasSlice.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ const initialCanvasState: CanvasState = {
8282
shouldShowStagingImage: true,
8383
shouldShowStagingOutline: true,
8484
shouldSnapToGrid: true,
85+
gridSnapThreshold: 64,
8586
shouldUseInpaintReplace: false,
8687
stageCoordinates: { x: 0, y: 0 },
8788
stageDimensions: { width: 0, height: 0 },
@@ -452,6 +453,9 @@ export const canvasSlice = createSlice({
452453
setShouldSnapToGrid: (state, action: PayloadAction<boolean>) => {
453454
state.shouldSnapToGrid = action.payload;
454455
},
456+
setGridSnapThreshold: (state, action: PayloadAction<number>) => {
457+
state.gridSnapThreshold = action.payload;
458+
},
455459
setShouldAutoSave: (state, action: PayloadAction<boolean>) => {
456460
state.shouldAutoSave = action.payload;
457461
},
@@ -825,6 +829,7 @@ export const {
825829
setShouldShowStagingImage,
826830
setShouldShowStagingOutline,
827831
setShouldSnapToGrid,
832+
setGridSnapThreshold,
828833
setShouldUseInpaintReplace,
829834
setStageCoordinates,
830835
setStageDimensions,

frontend/src/features/canvas/store/canvasTypes.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,7 @@ export interface CanvasState {
129129
shouldShowStagingImage: boolean;
130130
shouldShowStagingOutline: boolean;
131131
shouldSnapToGrid: boolean;
132+
gridSnapThreshold: number;
132133
shouldUseInpaintReplace: boolean;
133134
stageCoordinates: Vector2d;
134135
stageDimensions: Dimensions;

frontend/src/features/options/components/AdvancedOptions/Canvas/BoundingBoxSettings/BoundingBoxSettings.tsx

Lines changed: 62 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,30 @@
1+
import { ChangeEvent } from 'react';
12
import { Box, Flex } from '@chakra-ui/react';
23
import { createSelector } from '@reduxjs/toolkit';
34
import { useAppDispatch, useAppSelector } from 'app/store';
45
import IAISlider from 'common/components/IAISlider';
56
import { canvasSelector } from 'features/canvas/store/canvasSelectors';
6-
import { setBoundingBoxDimensions } from 'features/canvas/store/canvasSlice';
7+
import {
8+
setBoundingBoxDimensions,
9+
setGridSnapThreshold,
10+
setShouldSnapToGrid,
11+
} from 'features/canvas/store/canvasSlice';
712
import _ from 'lodash';
13+
import IAICheckbox from 'common/components/IAICheckbox';
14+
import { useHotkeys } from 'react-hotkeys-hook';
815

916
const selector = createSelector(
1017
canvasSelector,
1118
(canvas) => {
12-
const { boundingBoxDimensions, boundingBoxScaleMethod: boundingBoxScale } = canvas;
19+
const {
20+
boundingBoxDimensions,
21+
boundingBoxScaleMethod: boundingBoxScale,
22+
shouldSnapToGrid,
23+
gridSnapThreshold,
24+
} = canvas;
1325
return {
26+
shouldSnapToGrid,
27+
gridSnapThreshold,
1428
boundingBoxDimensions,
1529
boundingBoxScale,
1630
};
@@ -24,7 +38,8 @@ const selector = createSelector(
2438

2539
const BoundingBoxSettings = () => {
2640
const dispatch = useAppDispatch();
27-
const { boundingBoxDimensions } = useAppSelector(selector);
41+
const { boundingBoxDimensions, shouldSnapToGrid, gridSnapThreshold } =
42+
useAppSelector(selector);
2843

2944
const handleChangeWidth = (v: number) => {
3045
dispatch(
@@ -62,6 +77,29 @@ const BoundingBoxSettings = () => {
6277
);
6378
};
6479

80+
const handleChangeShouldSnapToGrid = (e: ChangeEvent<HTMLInputElement>) =>
81+
dispatch(setShouldSnapToGrid(e.target.checked));
82+
83+
const handleChangeGridSnapThreshold = (v: number) => {
84+
dispatch(setGridSnapThreshold(v));
85+
};
86+
87+
const handleResetGridSnapThreshold = () => {
88+
dispatch(setGridSnapThreshold(64));
89+
};
90+
91+
useHotkeys(
92+
['n'],
93+
() => {
94+
dispatch(setShouldSnapToGrid(!shouldSnapToGrid));
95+
},
96+
{
97+
enabled: true,
98+
preventDefault: true,
99+
},
100+
[shouldSnapToGrid]
101+
);
102+
65103
return (
66104
<Flex direction="column" gap="1rem">
67105
<IAISlider
@@ -90,6 +128,27 @@ const BoundingBoxSettings = () => {
90128
withInput
91129
withReset
92130
/>
131+
<IAICheckbox
132+
label="Snap Bounding Box to Grid (N)"
133+
isChecked={shouldSnapToGrid}
134+
onChange={handleChangeShouldSnapToGrid}
135+
/>
136+
<IAISlider
137+
label={'Snap Threshold'}
138+
min={2}
139+
max={256}
140+
step={2}
141+
value={gridSnapThreshold}
142+
onChange={handleChangeGridSnapThreshold}
143+
handleReset={handleResetGridSnapThreshold}
144+
isSliderDisabled={!shouldSnapToGrid}
145+
isInputDisabled={!shouldSnapToGrid}
146+
isResetDisabled={!shouldSnapToGrid}
147+
sliderNumberInputProps={{ max: 4096 }}
148+
withSliderMarks
149+
withInput
150+
withReset
151+
/>
93152
</Flex>
94153
);
95154
};

0 commit comments

Comments
 (0)