-
-
- : }
- />
-
-
- :
- }
- />
-
-
- : }
- />
-
-
+
{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';