Skip to content

feat(ui): add toggle for bbox with hotkey #8385

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion invokeai/frontend/web/public/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -2180,7 +2180,8 @@
"rgReferenceImagesNotSupported": "regional Reference Images not supported for selected base model",
"rgAutoNegativeNotSupported": "Auto-Negative not supported for selected base model",
"rgNoRegion": "no region drawn",
"fluxFillIncompatibleWithControlLoRA": "Control LoRA is not compatible with FLUX Fill"
"fluxFillIncompatibleWithControlLoRA": "Control LoRA is not compatible with FLUX Fill",
"bboxHidden": "Bounding box is hidden"
},
"errors": {
"unableToFindImage": "Unable to find image",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { Alert, AlertIcon, AlertTitle } from '@invoke-ai/ui-library';
import { useStore } from '@nanostores/react';
import { useCanvasManager } from 'features/controlLayers/contexts/CanvasManagerProviderGate';
import { memo } from 'react';
import { useTranslation } from 'react-i18next';

export const CanvasAlertsBboxVisibility = memo(() => {
const { t } = useTranslation();
const canvasManager = useCanvasManager();
const isBboxHidden = useStore(canvasManager.tool.tools.bbox.$isBboxHidden);

if (!isBboxHidden) {
return null;
}

return (
<Alert status="warning" borderRadius="base" fontSize="sm" shadow="md" w="fit-content">
<AlertIcon />
<AlertTitle>{t('controlLayers.warnings.bboxHidden')}</AlertTitle>
</Alert>
);
});

CanvasAlertsBboxVisibility.displayName = 'CanvasAlertsBboxVisibility';
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { useCanvasEntityQuickSwitchHotkey } from 'features/controlLayers/hooks/u
import { useCanvasFilterHotkey } from 'features/controlLayers/hooks/useCanvasFilterHotkey';
import { useCanvasInvertMaskHotkey } from 'features/controlLayers/hooks/useCanvasInvertMaskHotkey';
import { useCanvasResetLayerHotkey } from 'features/controlLayers/hooks/useCanvasResetLayerHotkey';
import { useCanvasToggleBboxHotkey } from 'features/controlLayers/hooks/useCanvasToggleBboxHotkey';
import { useCanvasToggleNonRasterLayersHotkey } from 'features/controlLayers/hooks/useCanvasToggleNonRasterLayersHotkey';
import { useCanvasTransformHotkey } from 'features/controlLayers/hooks/useCanvasTransformHotkey';
import { useCanvasUndoRedoHotkeys } from 'features/controlLayers/hooks/useCanvasUndoRedoHotkeys';
Expand All @@ -31,6 +32,7 @@ export const CanvasToolbar = memo(() => {
useCanvasFilterHotkey();
useCanvasInvertMaskHotkey();
useCanvasToggleNonRasterLayersHotkey();
useCanvasToggleBboxHotkey();

return (
<Flex w="full" gap={2} alignItems="center" px={2}>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { useCanvasManager } from 'features/controlLayers/contexts/CanvasManagerProviderGate';
import { useRegisteredHotkeys } from 'features/system/components/HotkeysModal/useHotkeyData';
import { useCallback } from 'react';

export const useCanvasToggleBboxHotkey = () => {
const canvasManager = useCanvasManager();

const handleToggleBboxVisibility = useCallback(() => {
canvasManager.tool.tools.bbox.toggleBboxVisibility();
}, [canvasManager]);

useRegisteredHotkeys({
id: 'toggleBbox',
category: 'canvas',
callback: handleToggleBboxVisibility,
dependencies: [handleToggleBboxVisibility],
});
};
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,11 @@ export class CanvasBboxToolModule extends CanvasModuleBase {
*/
$aspectRatioBuffer = atom(1);

/**
* Buffer to store the visibility of the bbox.
*/
$isBboxHidden = atom(false);

constructor(parent: CanvasToolModule) {
super();
this.id = getPrefixedId(this.type);
Expand Down Expand Up @@ -191,6 +196,9 @@ export class CanvasBboxToolModule extends CanvasModuleBase {

// Update on busy state changes
this.subscriptions.add(this.manager.$isBusy.listen(this.render));

// Listen for stage changes to update the bbox's visibility
this.subscriptions.add(this.$isBboxHidden.listen(this.render));
}

// This is a noop. The cursor is changed when the cursor enters or leaves the bbox.
Expand All @@ -206,13 +214,15 @@ export class CanvasBboxToolModule extends CanvasModuleBase {
};

/**
* Renders the bbox. The bbox is only visible when the tool is set to 'bbox'.
* Renders the bbox.
*/
render = () => {
const tool = this.manager.tool.$tool.get();

const { x, y, width, height } = this.manager.stateApi.runSelector(selectBbox).rect;

this.konva.group.visible(!this.$isBboxHidden.get());

// We need to reach up to the preview layer to enable/disable listening so that the bbox can be interacted with.
// If the mangaer is busy, we disable listening so the bbox cannot be interacted with.
this.konva.group.listening(tool === 'bbox' && !this.manager.$isBusy.get());
Expand Down Expand Up @@ -478,4 +488,8 @@ export class CanvasBboxToolModule extends CanvasModuleBase {
this.subscriptions.clear();
this.konva.group.destroy();
};

toggleBboxVisibility = () => {
this.$isBboxHidden.set(!this.$isBboxHidden.get());
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ export const useHotkeyData = (): HotkeysData => {
addHotkey('canvas', 'cancelSegmentAnything', ['esc']);
addHotkey('canvas', 'toggleNonRasterLayers', ['shift+h']);
addHotkey('canvas', 'fitBboxToMasks', ['shift+b']);
addHotkey('canvas', 'toggleBbox', ['shift+o']);

// Workflows
addHotkey('workflows', 'addNode', ['shift+a', 'space']);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { ContextMenu, Divider, Flex, IconButton, Menu, MenuButton, MenuList } from '@invoke-ai/ui-library';
import { useAppSelector } from 'app/store/storeHooks';
import { CanvasAlertsBboxVisibility } from 'features/controlLayers/components/CanvasAlerts/CanvasAlertsBboxVisibility';
import { CanvasAlertsInvocationProgress } from 'features/controlLayers/components/CanvasAlerts/CanvasAlertsInvocationProgress';
import { CanvasAlertsPreserveMask } from 'features/controlLayers/components/CanvasAlerts/CanvasAlertsPreserveMask';
import { CanvasAlertsSaveAllImagesToGallery } from 'features/controlLayers/components/CanvasAlerts/CanvasAlertsSaveAllImagesToGallery';
Expand Down Expand Up @@ -92,6 +93,7 @@ export const CanvasWorkspacePanel = memo(() => {
<CanvasAlertsSelectedEntityStatus />
<CanvasAlertsPreserveMask />
<CanvasAlertsInvocationProgress />
<CanvasAlertsBboxVisibility />
</Flex>
<Flex position="absolute" top={1} insetInlineEnd={1}>
<Menu>
Expand Down