diff --git a/frontend/src/features/system/HotkeysModal/HotkeysModal.scss b/frontend/src/features/system/HotkeysModal/HotkeysModal.scss index 3a8902a7d9..0a216b5c4b 100644 --- a/frontend/src/features/system/HotkeysModal/HotkeysModal.scss +++ b/frontend/src/features/system/HotkeysModal/HotkeysModal.scss @@ -1,6 +1,8 @@ @use '../../../styles/Mixins/' as *; .hotkeys-modal { + width: 36rem !important; + max-width: 36rem !important; display: grid; padding: 1rem; background-color: var(--settings-modal-bg) !important; @@ -17,8 +19,14 @@ } } +.hotkeys-modal-button { + display: flex; + align-items: center; + justify-content: space-between; +} + .hotkeys-modal-items { - max-height: 32rem; + max-height: 36rem; overflow-y: scroll; @include HideScrollbar; diff --git a/frontend/src/features/system/HotkeysModal/HotkeysModal.tsx b/frontend/src/features/system/HotkeysModal/HotkeysModal.tsx index e3cfe8f51a..a1dad4216d 100644 --- a/frontend/src/features/system/HotkeysModal/HotkeysModal.tsx +++ b/frontend/src/features/system/HotkeysModal/HotkeysModal.tsx @@ -1,6 +1,7 @@ import { Accordion, AccordionButton, + AccordionIcon, AccordionItem, AccordionPanel, Modal, @@ -181,8 +182,13 @@ export default function HotkeysModal({ children }: HotkeysModalProps) { hotkey: 'Ctrl+Shift+Z, Ctrl+Y', }, { - title: 'Move Bounding Box', - desc: 'Hold to move bounding box', + title: 'Lock Bounding Box', + desc: 'Locks the bounding box', + hotkey: 'M', + }, + { + title: 'Quick Toggle Lock Bounding Box', + desc: 'Hold to toggle locking the bounding box', hotkey: 'Space', }, { @@ -225,8 +231,9 @@ export default function HotkeysModal({ children }: HotkeysModalProps) {
- +

App Hotkeys

+
{renderHotkeyModalItems(appHotkeys)} @@ -234,8 +241,9 @@ export default function HotkeysModal({ children }: HotkeysModalProps) {
- +

General Hotkeys

+
{renderHotkeyModalItems(generalHotkeys)} @@ -243,8 +251,9 @@ export default function HotkeysModal({ children }: HotkeysModalProps) {
- +

Gallery Hotkeys

+
{renderHotkeyModalItems(galleryHotkeys)} @@ -252,8 +261,9 @@ export default function HotkeysModal({ children }: HotkeysModalProps) {
- +

Inpainting Hotkeys

+
{renderHotkeyModalItems(inpaintingHotkeys)} diff --git a/frontend/src/features/tabs/Inpainting/InpaintingCanvas.tsx b/frontend/src/features/tabs/Inpainting/InpaintingCanvas.tsx index ad34bbaf2b..16d7af8b72 100644 --- a/frontend/src/features/tabs/Inpainting/InpaintingCanvas.tsx +++ b/frontend/src/features/tabs/Inpainting/InpaintingCanvas.tsx @@ -220,8 +220,17 @@ const InpaintingCanvas = () => { return (
- {!shouldShowMask &&
Mask Hidden (H)
} - {shouldInvertMask &&
Mask Inverted (Shift+M)
} + {!shouldShowMask && ( +
Mask Hidden (H)
+ )} + {shouldInvertMask && ( +
Mask Inverted (Shift+M)
+ )} + {!shouldLockBoundingBox && ( +
+ Transforming Bounding Box (M) +
+ )}
{canvasBgImage && ( diff --git a/frontend/src/features/tabs/Inpainting/InpaintingControls.tsx b/frontend/src/features/tabs/Inpainting/InpaintingControls.tsx index 569db6b684..02a1d06b38 100644 --- a/frontend/src/features/tabs/Inpainting/InpaintingControls.tsx +++ b/frontend/src/features/tabs/Inpainting/InpaintingControls.tsx @@ -23,6 +23,7 @@ import { setShouldShowMask, setShouldInvertMask, setNeedsRepaint, + toggleShouldLockBoundingBox, } from './inpaintingSlice'; import { MdInvertColors, MdInvertColorsOff } from 'react-icons/md'; @@ -144,6 +145,19 @@ const InpaintingControls = () => { [activeTabName, shouldShowMask] ); + // Toggle lock bounding box + useHotkeys( + 'm', + (e: KeyboardEvent) => { + e.preventDefault(); + dispatch(toggleShouldLockBoundingBox()); + }, + { + enabled: activeTabName === 'inpainting' && shouldShowMask, + }, + [activeTabName, shouldShowMask] + ); + // Undo useHotkeys( 'cmd+z, control+z', diff --git a/frontend/src/features/tabs/Inpainting/components/InpaintingBoundingBoxPreview.tsx b/frontend/src/features/tabs/Inpainting/components/InpaintingBoundingBoxPreview.tsx index fb2150d087..cf4da44c01 100644 --- a/frontend/src/features/tabs/Inpainting/components/InpaintingBoundingBoxPreview.tsx +++ b/frontend/src/features/tabs/Inpainting/components/InpaintingBoundingBoxPreview.tsx @@ -87,66 +87,6 @@ export const InpaintingBoundingBoxPreviewOverlay = () => { ); }; -// /** -// * Draws marching ants around the mask. Unused. -// */ -// const _InpaintingBoundingBoxPreviewMarchingAnts = () => { -// const { boundingBoxCoordinate, boundingBoxDimensions } = useAppSelector( -// boundingBoxPreviewSelector -// ); - -// const blackStrokeRectRef = useRef(null); -// const whiteStrokeRectRef = useRef(null); - -// useEffect(() => { -// const blackStrokeRect = blackStrokeRectRef.current; -// const whiteStrokeRect = whiteStrokeRectRef.current; - -// const anim = new Konva.Animation((frame) => { -// if (!frame) return; -// blackStrokeRect?.dashOffset( -// -1 * (Math.floor(frame.time / MARCHING_ANTS_SPEED) % 16) -// ); -// whiteStrokeRect?.dashOffset( -// -1 * ((Math.floor(frame.time / MARCHING_ANTS_SPEED) % 16) + 4) -// ); -// }); - -// anim.start(); - -// return () => { -// anim.stop(); -// }; -// }, []); - -// return ( -// -// -// -// -// ); -// }; - const InpaintingBoundingBoxPreview = () => { const dispatch = useAppDispatch(); const { @@ -326,15 +266,14 @@ const InpaintingBoundingBoxPreview = () => { strokeWidth={strokeWidth} listening={!shouldLockBoundingBox} onMouseEnter={(e) => { - // style stage container: const container = e?.target?.getStage()?.container(); if (!container) return; - container.style.cursor = 'move'; + container.style.cursor = shouldLockBoundingBox ? 'none' : 'move'; }} onMouseLeave={(e) => { const container = e?.target?.getStage()?.container(); if (!container) return; - container.style.cursor = 'default'; + container.style.cursor = shouldLockBoundingBox ? 'none' : 'default'; }} draggable={!shouldLockBoundingBox} onDragMove={handleOnDragMove} diff --git a/frontend/src/features/tabs/Inpainting/components/KeyboardEventManager.tsx b/frontend/src/features/tabs/Inpainting/components/KeyboardEventManager.tsx index 3c5b421c6a..ac0cfd55aa 100644 --- a/frontend/src/features/tabs/Inpainting/components/KeyboardEventManager.tsx +++ b/frontend/src/features/tabs/Inpainting/components/KeyboardEventManager.tsx @@ -12,7 +12,6 @@ import { InpaintingState, setIsDrawing, setShouldLockBoundingBox, - setShouldShowBrush, toggleTool, } from '../inpaintingSlice'; @@ -91,10 +90,8 @@ const KeyboardEventManager = () => { case ' ': { if (e.type === 'keydown') { dispatch(setIsDrawing(false)); - dispatch(setShouldLockBoundingBox(false)); - } else { - dispatch(setShouldLockBoundingBox(true)); } + dispatch(setShouldLockBoundingBox(!shouldLockBoundingBox)); break; } } diff --git a/frontend/src/features/tabs/Inpainting/inpaintingSlice.ts b/frontend/src/features/tabs/Inpainting/inpaintingSlice.ts index dd8cfe1b15..2a5ec73ee1 100644 --- a/frontend/src/features/tabs/Inpainting/inpaintingSlice.ts +++ b/frontend/src/features/tabs/Inpainting/inpaintingSlice.ts @@ -36,11 +36,9 @@ export interface InpaintingState { canvasDimensions: Dimensions; boundingBoxDimensions: Dimensions; boundingBoxCoordinate: Vector2d; - isMovingBoundingBox: boolean; boundingBoxPreviewFill: RgbaColor; shouldShowBoundingBox: boolean; shouldShowBoundingBoxFill: boolean; - isTransformingBoundingBox: boolean; lines: MaskLine[]; pastLines: MaskLine[][]; futureLines: MaskLine[][]; @@ -68,7 +66,6 @@ const initialInpaintingState: InpaintingState = { boundingBoxPreviewFill: { r: 0, g: 0, b: 0, a: 0.7 }, shouldShowBoundingBox: false, shouldShowBoundingBoxFill: false, - isTransformingBoundingBox: false, cursorPosition: null, lines: [], pastLines: [], @@ -78,7 +75,6 @@ const initialInpaintingState: InpaintingState = { shouldShowCheckboardTransparency: false, shouldShowBrush: true, shouldShowBrushPreview: false, - isMovingBoundingBox: false, needsRepaint: false, isDrawing: false, stageScale: 1, @@ -289,24 +285,6 @@ export const inpaintingSlice = createSlice({ }, setBoundingBoxCoordinate: (state, action: PayloadAction) => { state.boundingBoxCoordinate = action.payload; - // const { x, y } = action.payload; - - // const maxX = - // state.canvasDimensions.width - state.boundingBoxDimensions.width; - - // const maxY = - // state.canvasDimensions.height - state.boundingBoxDimensions.height; - - // const clampedX = _.clamp(x, 0, maxX); - // const clampedY = _.clamp(y, 0, maxY); - - // state.boundingBoxCoordinate = { x: clampedX, y: clampedY }; - }, - setIsMovingBoundingBox: (state, action: PayloadAction) => { - state.isMovingBoundingBox = action.payload; - }, - toggleIsMovingBoundingBox: (state) => { - state.isMovingBoundingBox = !state.isMovingBoundingBox; }, setBoundingBoxPreviewFill: (state, action: PayloadAction) => { state.boundingBoxPreviewFill = action.payload; @@ -321,9 +299,6 @@ export const inpaintingSlice = createSlice({ setShouldShowBoundingBoxFill: (state, action: PayloadAction) => { state.shouldShowBoundingBoxFill = action.payload; }, - setIsTransformingBoundingBox: (state, action: PayloadAction) => { - state.isTransformingBoundingBox = action.payload; - }, setIsDrawing: (state, action: PayloadAction) => { state.isDrawing = action.payload; }, @@ -343,6 +318,9 @@ export const inpaintingSlice = createSlice({ setShouldLockBoundingBox: (state, action: PayloadAction) => { state.shouldLockBoundingBox = action.payload; }, + toggleShouldLockBoundingBox: (state) => { + state.shouldLockBoundingBox = !state.shouldLockBoundingBox; + }, }, }); @@ -364,14 +342,11 @@ export const { setImageToInpaint, setBoundingBoxDimensions, setBoundingBoxCoordinate, - setIsMovingBoundingBox, setBoundingBoxPreviewFill, setNeedsRepaint, setStageScale, toggleTool, - toggleIsMovingBoundingBox, setShouldShowBoundingBoxFill, - setIsTransformingBoundingBox, setIsDrawing, setShouldShowBrush, setShouldShowBoundingBox, @@ -379,6 +354,7 @@ export const { setShouldUseInpaintReplace, setInpaintReplace, setShouldLockBoundingBox, + toggleShouldLockBoundingBox, } = inpaintingSlice.actions; export default inpaintingSlice.reducer;