diff --git a/frontend/src/features/options/AdvancedOptions/Inpainting/BoundingBoxSettings.tsx b/frontend/src/features/options/AdvancedOptions/Inpainting/BoundingBoxSettings.tsx index fec9f5411c..ca87426e8d 100644 --- a/frontend/src/features/options/AdvancedOptions/Inpainting/BoundingBoxSettings.tsx +++ b/frontend/src/features/options/AdvancedOptions/Inpainting/BoundingBoxSettings.tsx @@ -113,7 +113,7 @@ const BoundingBoxSettings = () => {

Inpaint Box

- {/* : @@ -121,7 +121,7 @@ const BoundingBoxSettings = () => { onClick={handleShowBoundingBox} background={'none'} padding={0} - /> */} + />
diff --git a/frontend/src/features/system/HotkeysModal/HotkeysModal.tsx b/frontend/src/features/system/HotkeysModal/HotkeysModal.tsx index d16899dbbd..aa6b79ead5 100644 --- a/frontend/src/features/system/HotkeysModal/HotkeysModal.tsx +++ b/frontend/src/features/system/HotkeysModal/HotkeysModal.tsx @@ -194,12 +194,12 @@ export default function HotkeysModal({ children }: HotkeysModalProps) { { title: 'Lock Bounding Box', desc: 'Locks the bounding box', - hotkey: 'M', + hotkey: 'Shift+Q', }, { title: 'Quick Toggle Lock Bounding Box', desc: 'Hold to toggle locking the bounding box', - hotkey: 'Space', + hotkey: 'Q', }, { title: 'Expand Inpainting Area', diff --git a/frontend/src/features/tabs/Inpainting/InpaintingCanvas.tsx b/frontend/src/features/tabs/Inpainting/InpaintingCanvas.tsx index 4544d578f7..3b8adc1322 100644 --- a/frontend/src/features/tabs/Inpainting/InpaintingCanvas.tsx +++ b/frontend/src/features/tabs/Inpainting/InpaintingCanvas.tsx @@ -38,6 +38,7 @@ import { Icon, IconButton, Tooltip, useToast } from '@chakra-ui/react'; import { FaLock, FaUnlock } from 'react-icons/fa'; import { MdInvertColors, MdInvertColorsOff } from 'react-icons/md'; import { BiHide, BiShow } from 'react-icons/bi'; +import InpaintingCanvasStatusIcons from './InpaintingCanvasStatusIcons'; // Use a closure allow other components to use these things... not ideal... export let stageRef: MutableRefObject; @@ -243,39 +244,7 @@ const InpaintingCanvas = () => { return (
-
-
- : } - /> -
-
- : - } - /> -
-
- : } - /> -
-
+ {canvasBgImage && ( { /> )} - {shouldShowMask && ( - - {shouldShowBoundingBoxFill && shouldShowBoundingBox && ( - - )} - - {!isMouseOverBoundingBox && !isModifyingBoundingBox && ( - - )} - - )} + + {shouldShowBoundingBoxFill && shouldShowBoundingBox && ( + + )} + {shouldShowBoundingBox && } + + {!isMouseOverBoundingBox && !isModifyingBoundingBox && ( + + )} + )} diff --git a/frontend/src/features/tabs/Inpainting/InpaintingCanvasStatusIcons.scss b/frontend/src/features/tabs/Inpainting/InpaintingCanvasStatusIcons.scss new file mode 100644 index 0000000000..30c54dea19 --- /dev/null +++ b/frontend/src/features/tabs/Inpainting/InpaintingCanvasStatusIcons.scss @@ -0,0 +1,31 @@ +.inpainting-alerts { + position: absolute; + top: 0; + left: 0; + display: flex; + z-index: 2; + margin: 0.25rem; + padding: 0.25rem; + pointer-events: none; + background-color: var(--text-color); + opacity: 0.7; + border-radius: 0.5rem; + + button { + svg { + fill: var(--background-color); + } + + &[data-selected='true'] { + svg { + fill: var(--accent-color-hover); + } + } + + &[data-alert='true'] { + svg { + fill: var(--destructive-color-hover); + } + } + } +} diff --git a/frontend/src/features/tabs/Inpainting/InpaintingCanvasStatusIcons.tsx b/frontend/src/features/tabs/Inpainting/InpaintingCanvasStatusIcons.tsx new file mode 100644 index 0000000000..e6edddfb72 --- /dev/null +++ b/frontend/src/features/tabs/Inpainting/InpaintingCanvasStatusIcons.tsx @@ -0,0 +1,81 @@ +const inpaintingCanvasStatusIconsSelector = createSelector( + (state: RootState) => state.inpainting, + (inpainting: InpaintingState) => { + const { + shouldShowMask, + shouldInvertMask, + shouldLockBoundingBox, + shouldShowBoundingBox, + } = inpainting; + + return { + shouldShowMask, + shouldInvertMask, + shouldLockBoundingBox, + shouldShowBoundingBox, + }; + } +); + +import { IconButton } from '@chakra-ui/react'; +import { createSelector } from '@reduxjs/toolkit'; +import { BiHide, BiShow } from 'react-icons/bi'; +import { BsBoundingBox } from 'react-icons/bs'; +import { FaLock, FaUnlock } from 'react-icons/fa'; +import { MdInvertColors, MdInvertColorsOff } from 'react-icons/md'; +import { RootState, useAppSelector } from '../../../app/store'; +import { InpaintingState } from './inpaintingSlice'; + +const InpaintingCanvasStatusIcons = () => { + const { + shouldShowMask, + shouldInvertMask, + shouldLockBoundingBox, + shouldShowBoundingBox, + } = useAppSelector(inpaintingCanvasStatusIconsSelector); + + return ( +
+
+ : } + /> +
+
+ : } + /> +
+
+ : } + /> +
+
+ } + /> +
+
+ ); +}; + +export default InpaintingCanvasStatusIcons; diff --git a/frontend/src/features/tabs/Inpainting/InpaintingControls.tsx b/frontend/src/features/tabs/Inpainting/InpaintingControls.tsx index 49a9229d74..f3386a3bc6 100644 --- a/frontend/src/features/tabs/Inpainting/InpaintingControls.tsx +++ b/frontend/src/features/tabs/Inpainting/InpaintingControls.tsx @@ -154,7 +154,7 @@ const InpaintingControls = () => { // Toggle lock bounding box useHotkeys( - 'm', + 'shift+q', (e: KeyboardEvent) => { e.preventDefault(); dispatch(toggleShouldLockBoundingBox()); diff --git a/frontend/src/features/tabs/Inpainting/components/InpaintingGrid.tsx b/frontend/src/features/tabs/Inpainting/components/InpaintingGrid.tsx new file mode 100644 index 0000000000..e69de29bb2 diff --git a/frontend/src/features/tabs/Inpainting/components/KeyboardEventManager.tsx b/frontend/src/features/tabs/Inpainting/components/KeyboardEventManager.tsx index 9bb00de1a8..84db2fb61c 100644 --- a/frontend/src/features/tabs/Inpainting/components/KeyboardEventManager.tsx +++ b/frontend/src/features/tabs/Inpainting/components/KeyboardEventManager.tsx @@ -24,13 +24,18 @@ const keyboardEventManagerSelector = createSelector( activeTabNameSelector, ], (options: OptionsState, inpainting: InpaintingState, activeTabName) => { - const { shouldShowMask, cursorPosition, shouldLockBoundingBox } = - inpainting; + const { + shouldShowMask, + cursorPosition, + shouldLockBoundingBox, + shouldShowBoundingBox, + } = inpainting; return { activeTabName, shouldShowMask, isCursorOnCanvas: Boolean(cursorPosition), shouldLockBoundingBox, + shouldShowBoundingBox, }; }, { @@ -47,6 +52,7 @@ const KeyboardEventManager = () => { activeTabName, isCursorOnCanvas, shouldLockBoundingBox, + shouldShowBoundingBox, } = useAppSelector(keyboardEventManagerSelector); const wasLastEventOverCanvas = useRef(false); @@ -55,7 +61,7 @@ const KeyboardEventManager = () => { useEffect(() => { const listener = (e: KeyboardEvent) => { if ( - !['x', ' '].includes(e.key) || + !['x', 'q'].includes(e.key) || activeTabName !== 'inpainting' || !shouldShowMask ) { @@ -93,8 +99,8 @@ const KeyboardEventManager = () => { dispatch(toggleTool()); break; } - case ' ': { - if (!shouldShowMask) break; + case 'q': { + if (!shouldShowMask || !shouldShowBoundingBox) break; dispatch(setIsSpacebarHeld(e.type === 'keydown')); dispatch(setShouldLockBoundingBox(e.type !== 'keydown')); break; @@ -118,6 +124,7 @@ const KeyboardEventManager = () => { shouldShowMask, isCursorOnCanvas, shouldLockBoundingBox, + shouldShowBoundingBox, ]); return null; diff --git a/frontend/src/styles/index.scss b/frontend/src/styles/index.scss index fd5a9e7dc1..11d932e9d9 100644 --- a/frontend/src/styles/index.scss +++ b/frontend/src/styles/index.scss @@ -39,8 +39,9 @@ @use '../features/tabs/InvokeOptionsPanel.scss'; @use '../features/tabs/TextToImage/TextToImage.scss'; @use '../features/tabs/ImageToImage/ImageToImage.scss'; -@use '../features/tabs/Inpainting/Inpainting.scss'; @use '../features/tabs/FloatingButton.scss'; +@use '../features/tabs/Inpainting/Inpainting.scss'; +@use '../features/tabs/Inpainting/InpaintingCanvasStatusIcons.scss'; // Component Shared @use '../common/components/IAINumberInput.scss';