Skip to content

Commit 1e9e780

Browse files
Attila Csehpsychedelicious
authored andcommitted
Add toggle for bbox with hotkey
1 parent e65f936 commit 1e9e780

File tree

7 files changed

+61
-1
lines changed

7 files changed

+61
-1
lines changed

invokeai/frontend/web/public/locales/en.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2180,7 +2180,8 @@
21802180
"rgReferenceImagesNotSupported": "regional Reference Images not supported for selected base model",
21812181
"rgAutoNegativeNotSupported": "Auto-Negative not supported for selected base model",
21822182
"rgNoRegion": "no region drawn",
2183-
"fluxFillIncompatibleWithControlLoRA": "Control LoRA is not compatible with FLUX Fill"
2183+
"fluxFillIncompatibleWithControlLoRA": "Control LoRA is not compatible with FLUX Fill",
2184+
"bboxHidden": "Bounding box is hidden"
21842185
},
21852186
"errors": {
21862187
"unableToFindImage": "Unable to find image",
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import { Alert, AlertIcon, AlertTitle } from '@invoke-ai/ui-library';
2+
import { useStore } from '@nanostores/react';
3+
import { useCanvasManager } from 'features/controlLayers/contexts/CanvasManagerProviderGate';
4+
import { memo } from 'react';
5+
import { useTranslation } from 'react-i18next';
6+
7+
export const CanvasAlertsBboxVisibility = memo(() => {
8+
const { t } = useTranslation();
9+
const canvasManager = useCanvasManager();
10+
const isBboxHidden = useStore(canvasManager.tool.tools.bbox.$isBboxHidden);
11+
12+
if (!isBboxHidden) {
13+
return null;
14+
}
15+
16+
return (
17+
<Alert status="warning" borderRadius="base" fontSize="sm" shadow="md" w="fit-content">
18+
<AlertIcon />
19+
<AlertTitle>{t('controlLayers.warnings.bboxHidden')}</AlertTitle>
20+
</Alert>
21+
);
22+
});
23+
24+
CanvasAlertsBboxVisibility.displayName = 'CanvasAlertsBboxVisibility';

invokeai/frontend/web/src/features/controlLayers/components/Toolbar/CanvasToolbar.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import { useCanvasEntityQuickSwitchHotkey } from 'features/controlLayers/hooks/u
1515
import { useCanvasFilterHotkey } from 'features/controlLayers/hooks/useCanvasFilterHotkey';
1616
import { useCanvasInvertMaskHotkey } from 'features/controlLayers/hooks/useCanvasInvertMaskHotkey';
1717
import { useCanvasResetLayerHotkey } from 'features/controlLayers/hooks/useCanvasResetLayerHotkey';
18+
import { useCanvasToggleBboxHotkey } from 'features/controlLayers/hooks/useCanvasToggleBboxHotkey';
1819
import { useCanvasToggleNonRasterLayersHotkey } from 'features/controlLayers/hooks/useCanvasToggleNonRasterLayersHotkey';
1920
import { useCanvasTransformHotkey } from 'features/controlLayers/hooks/useCanvasTransformHotkey';
2021
import { useCanvasUndoRedoHotkeys } from 'features/controlLayers/hooks/useCanvasUndoRedoHotkeys';
@@ -31,6 +32,7 @@ export const CanvasToolbar = memo(() => {
3132
useCanvasFilterHotkey();
3233
useCanvasInvertMaskHotkey();
3334
useCanvasToggleNonRasterLayersHotkey();
35+
useCanvasToggleBboxHotkey();
3436

3537
return (
3638
<Flex w="full" gap={2} alignItems="center" px={2}>
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import { useCanvasManager } from 'features/controlLayers/contexts/CanvasManagerProviderGate';
2+
import { useRegisteredHotkeys } from 'features/system/components/HotkeysModal/useHotkeyData';
3+
import { useCallback } from 'react';
4+
5+
export const useCanvasToggleBboxHotkey = () => {
6+
const canvasManager = useCanvasManager();
7+
8+
const handleToggleBboxVisibility = useCallback(() => {
9+
canvasManager.tool.tools.bbox.toggleBboxVisibility();
10+
}, [canvasManager]);
11+
12+
useRegisteredHotkeys({
13+
id: 'toggleBbox',
14+
category: 'canvas',
15+
callback: handleToggleBboxVisibility,
16+
dependencies: [handleToggleBboxVisibility],
17+
});
18+
};

invokeai/frontend/web/src/features/controlLayers/konva/CanvasTool/CanvasBboxToolModule.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,11 @@ export class CanvasBboxToolModule extends CanvasModuleBase {
6666
*/
6767
$aspectRatioBuffer = atom(1);
6868

69+
/**
70+
* Buffer to store the visibility of the bbox.
71+
*/
72+
$isBboxHidden = atom(false);
73+
6974
constructor(parent: CanvasToolModule) {
7075
super();
7176
this.id = getPrefixedId(this.type);
@@ -191,6 +196,9 @@ export class CanvasBboxToolModule extends CanvasModuleBase {
191196

192197
// Update on busy state changes
193198
this.subscriptions.add(this.manager.$isBusy.listen(this.render));
199+
200+
// Listen for stage changes to update the bbox's visibility
201+
this.subscriptions.add(this.$isBboxHidden.listen((isHidden) => this.konva.group.visible(!isHidden)));
194202
}
195203

196204
// This is a noop. The cursor is changed when the cursor enters or leaves the bbox.
@@ -478,4 +486,8 @@ export class CanvasBboxToolModule extends CanvasModuleBase {
478486
this.subscriptions.clear();
479487
this.konva.group.destroy();
480488
};
489+
490+
toggleBboxVisibility = () => {
491+
this.$isBboxHidden.set(!this.$isBboxHidden.get());
492+
};
481493
}

invokeai/frontend/web/src/features/system/components/HotkeysModal/useHotkeyData.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,7 @@ export const useHotkeyData = (): HotkeysData => {
126126
addHotkey('canvas', 'cancelSegmentAnything', ['esc']);
127127
addHotkey('canvas', 'toggleNonRasterLayers', ['shift+h']);
128128
addHotkey('canvas', 'fitBboxToMasks', ['shift+b']);
129+
addHotkey('canvas', 'toggleBbox', ['shift+o']);
129130

130131
// Workflows
131132
addHotkey('workflows', 'addNode', ['shift+a', 'space']);

invokeai/frontend/web/src/features/ui/layouts/CanvasWorkspacePanel.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { ContextMenu, Divider, Flex, IconButton, Menu, MenuButton, MenuList } from '@invoke-ai/ui-library';
22
import { useAppSelector } from 'app/store/storeHooks';
3+
import { CanvasAlertsBboxVisibility } from 'features/controlLayers/components/CanvasAlerts/CanvasAlertsBboxVisibility';
34
import { CanvasAlertsInvocationProgress } from 'features/controlLayers/components/CanvasAlerts/CanvasAlertsInvocationProgress';
45
import { CanvasAlertsPreserveMask } from 'features/controlLayers/components/CanvasAlerts/CanvasAlertsPreserveMask';
56
import { CanvasAlertsSaveAllImagesToGallery } from 'features/controlLayers/components/CanvasAlerts/CanvasAlertsSaveAllImagesToGallery';
@@ -92,6 +93,7 @@ export const CanvasWorkspacePanel = memo(() => {
9293
<CanvasAlertsSelectedEntityStatus />
9394
<CanvasAlertsPreserveMask />
9495
<CanvasAlertsInvocationProgress />
96+
<CanvasAlertsBboxVisibility />
9597
</Flex>
9698
<Flex position="absolute" top={1} insetInlineEnd={1}>
9799
<Menu>

0 commit comments

Comments
 (0)