mirror of
https://github.com/invoke-ai/InvokeAI
synced 2024-08-30 20:32:17 +00:00
feat(ui): disable most interaction while filtering
This commit is contained in:
parent
799688514b
commit
bb3ad8c2f1
@ -11,8 +11,8 @@ import { PiCheckBold, PiShootingStarBold, PiXBold } from 'react-icons/pi';
|
|||||||
export const Filter = memo(() => {
|
export const Filter = memo(() => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const canvasManager = useCanvasManager();
|
const canvasManager = useCanvasManager();
|
||||||
const adapter = useStore(canvasManager.filter.$adapter);
|
|
||||||
const config = useStore(canvasManager.filter.$config);
|
const config = useStore(canvasManager.filter.$config);
|
||||||
|
const isFiltering = useStore(canvasManager.filter.$isFiltering);
|
||||||
const isProcessing = useStore(canvasManager.filter.$isProcessing);
|
const isProcessing = useStore(canvasManager.filter.$isProcessing);
|
||||||
|
|
||||||
const previewFilter = useCallback(() => {
|
const previewFilter = useCallback(() => {
|
||||||
@ -41,7 +41,7 @@ export const Filter = memo(() => {
|
|||||||
[canvasManager.filter.$config]
|
[canvasManager.filter.$config]
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!adapter) {
|
if (!isFiltering) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import { IconButton } from '@invoke-ai/ui-library';
|
import { IconButton } from '@invoke-ai/ui-library';
|
||||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||||
|
import { useIsFiltering } from 'features/controlLayers/hooks/useIsFiltering';
|
||||||
import { useIsTransforming } from 'features/controlLayers/hooks/useIsTransforming';
|
import { useIsTransforming } from 'features/controlLayers/hooks/useIsTransforming';
|
||||||
import { toolChanged } from 'features/controlLayers/store/canvasV2Slice';
|
import { toolChanged } from 'features/controlLayers/store/canvasV2Slice';
|
||||||
import { memo, useCallback, useMemo } from 'react';
|
import { memo, useCallback, useMemo } from 'react';
|
||||||
@ -10,12 +11,13 @@ import { PiBoundingBoxBold } from 'react-icons/pi';
|
|||||||
export const ToolBboxButton = memo(() => {
|
export const ToolBboxButton = memo(() => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
|
const isFiltering = useIsFiltering();
|
||||||
const isTransforming = useIsTransforming();
|
const isTransforming = useIsTransforming();
|
||||||
const isStaging = useAppSelector((s) => s.canvasV2.session.isStaging);
|
const isStaging = useAppSelector((s) => s.canvasV2.session.isStaging);
|
||||||
const isSelected = useAppSelector((s) => s.canvasV2.tool.selected === 'bbox');
|
const isSelected = useAppSelector((s) => s.canvasV2.tool.selected === 'bbox');
|
||||||
const isDisabled = useMemo(() => {
|
const isDisabled = useMemo(() => {
|
||||||
return isTransforming || isStaging;
|
return isTransforming || isFiltering || isStaging;
|
||||||
}, [isStaging, isTransforming]);
|
}, [isFiltering, isStaging, isTransforming]);
|
||||||
|
|
||||||
const onClick = useCallback(() => {
|
const onClick = useCallback(() => {
|
||||||
dispatch(toolChanged('bbox'));
|
dispatch(toolChanged('bbox'));
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import { IconButton } from '@invoke-ai/ui-library';
|
import { IconButton } from '@invoke-ai/ui-library';
|
||||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||||
|
import { useIsFiltering } from 'features/controlLayers/hooks/useIsFiltering';
|
||||||
import { useIsTransforming } from 'features/controlLayers/hooks/useIsTransforming';
|
import { useIsTransforming } from 'features/controlLayers/hooks/useIsTransforming';
|
||||||
import { toolChanged } from 'features/controlLayers/store/canvasV2Slice';
|
import { toolChanged } from 'features/controlLayers/store/canvasV2Slice';
|
||||||
import { isDrawableEntityType } from 'features/controlLayers/store/types';
|
import { isDrawableEntityType } from 'features/controlLayers/store/types';
|
||||||
@ -11,6 +12,7 @@ import { PiPaintBrushBold } from 'react-icons/pi';
|
|||||||
export const ToolBrushButton = memo(() => {
|
export const ToolBrushButton = memo(() => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
|
const isFiltering = useIsFiltering();
|
||||||
const isTransforming = useIsTransforming();
|
const isTransforming = useIsTransforming();
|
||||||
const isStaging = useAppSelector((s) => s.canvasV2.session.isStaging);
|
const isStaging = useAppSelector((s) => s.canvasV2.session.isStaging);
|
||||||
const isSelected = useAppSelector((s) => s.canvasV2.tool.selected === 'brush');
|
const isSelected = useAppSelector((s) => s.canvasV2.tool.selected === 'brush');
|
||||||
@ -22,8 +24,8 @@ export const ToolBrushButton = memo(() => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const isDisabled = useMemo(() => {
|
const isDisabled = useMemo(() => {
|
||||||
return isTransforming || isStaging || !isDrawingToolAllowed;
|
return isTransforming || isFiltering || isStaging || !isDrawingToolAllowed;
|
||||||
}, [isDrawingToolAllowed, isStaging, isTransforming]);
|
}, [isDrawingToolAllowed, isFiltering, isStaging, isTransforming]);
|
||||||
|
|
||||||
const onClick = useCallback(() => {
|
const onClick = useCallback(() => {
|
||||||
dispatch(toolChanged('brush'));
|
dispatch(toolChanged('brush'));
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { ButtonGroup } from '@invoke-ai/ui-library';
|
import { ButtonGroup } from '@invoke-ai/ui-library';
|
||||||
import { ToolBboxButton } from 'features/controlLayers/components/Tool/ToolBboxButton';
|
import { ToolBboxButton } from 'features/controlLayers/components/Tool/ToolBboxButton';
|
||||||
import { ToolBrushButton } from 'features/controlLayers/components/Tool/ToolBrushButton';
|
import { ToolBrushButton } from 'features/controlLayers/components/Tool/ToolBrushButton';
|
||||||
import { ToolColorPickerButton } from 'features/controlLayers/components/Tool/ToolEyeDropperButton';
|
import { ToolColorPickerButton } from 'features/controlLayers/components/Tool/ToolColorPickerButton';
|
||||||
import { ToolMoveButton } from 'features/controlLayers/components/Tool/ToolMoveButton';
|
import { ToolMoveButton } from 'features/controlLayers/components/Tool/ToolMoveButton';
|
||||||
import { ToolRectButton } from 'features/controlLayers/components/Tool/ToolRectButton';
|
import { ToolRectButton } from 'features/controlLayers/components/Tool/ToolRectButton';
|
||||||
import { useCanvasDeleteLayerHotkey } from 'features/controlLayers/hooks/useCanvasDeleteLayerHotkey';
|
import { useCanvasDeleteLayerHotkey } from 'features/controlLayers/hooks/useCanvasDeleteLayerHotkey';
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import { IconButton } from '@invoke-ai/ui-library';
|
import { IconButton } from '@invoke-ai/ui-library';
|
||||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||||
|
import { useIsFiltering } from 'features/controlLayers/hooks/useIsFiltering';
|
||||||
import { useIsTransforming } from 'features/controlLayers/hooks/useIsTransforming';
|
import { useIsTransforming } from 'features/controlLayers/hooks/useIsTransforming';
|
||||||
import { toolChanged } from 'features/controlLayers/store/canvasV2Slice';
|
import { toolChanged } from 'features/controlLayers/store/canvasV2Slice';
|
||||||
import { memo, useCallback, useMemo } from 'react';
|
import { memo, useCallback, useMemo } from 'react';
|
||||||
@ -10,13 +11,14 @@ import { PiEyedropperBold } from 'react-icons/pi';
|
|||||||
export const ToolColorPickerButton = memo(() => {
|
export const ToolColorPickerButton = memo(() => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
|
const isFiltering = useIsFiltering();
|
||||||
const isTransforming = useIsTransforming();
|
const isTransforming = useIsTransforming();
|
||||||
const isSelected = useAppSelector((s) => s.canvasV2.tool.selected === 'colorPicker');
|
const isSelected = useAppSelector((s) => s.canvasV2.tool.selected === 'colorPicker');
|
||||||
const isStaging = useAppSelector((s) => s.canvasV2.session.isStaging);
|
const isStaging = useAppSelector((s) => s.canvasV2.session.isStaging);
|
||||||
|
|
||||||
const isDisabled = useMemo(() => {
|
const isDisabled = useMemo(() => {
|
||||||
return isTransforming || isStaging;
|
return isTransforming || isFiltering || isStaging;
|
||||||
}, [isStaging, isTransforming]);
|
}, [isFiltering, isStaging, isTransforming]);
|
||||||
|
|
||||||
const onClick = useCallback(() => {
|
const onClick = useCallback(() => {
|
||||||
dispatch(toolChanged('colorPicker'));
|
dispatch(toolChanged('colorPicker'));
|
@ -1,5 +1,6 @@
|
|||||||
import { IconButton } from '@invoke-ai/ui-library';
|
import { IconButton } from '@invoke-ai/ui-library';
|
||||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||||
|
import { useIsFiltering } from 'features/controlLayers/hooks/useIsFiltering';
|
||||||
import { useIsTransforming } from 'features/controlLayers/hooks/useIsTransforming';
|
import { useIsTransforming } from 'features/controlLayers/hooks/useIsTransforming';
|
||||||
import { toolChanged } from 'features/controlLayers/store/canvasV2Slice';
|
import { toolChanged } from 'features/controlLayers/store/canvasV2Slice';
|
||||||
import { isDrawableEntityType } from 'features/controlLayers/store/types';
|
import { isDrawableEntityType } from 'features/controlLayers/store/types';
|
||||||
@ -11,6 +12,7 @@ import { PiEraserBold } from 'react-icons/pi';
|
|||||||
export const ToolEraserButton = memo(() => {
|
export const ToolEraserButton = memo(() => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
|
const isFiltering = useIsFiltering();
|
||||||
const isTransforming = useIsTransforming();
|
const isTransforming = useIsTransforming();
|
||||||
const isStaging = useAppSelector((s) => s.canvasV2.session.isStaging);
|
const isStaging = useAppSelector((s) => s.canvasV2.session.isStaging);
|
||||||
const isSelected = useAppSelector((s) => s.canvasV2.tool.selected === 'eraser');
|
const isSelected = useAppSelector((s) => s.canvasV2.tool.selected === 'eraser');
|
||||||
@ -21,8 +23,8 @@ export const ToolEraserButton = memo(() => {
|
|||||||
return isDrawableEntityType(s.canvasV2.selectedEntityIdentifier.type);
|
return isDrawableEntityType(s.canvasV2.selectedEntityIdentifier.type);
|
||||||
});
|
});
|
||||||
const isDisabled = useMemo(() => {
|
const isDisabled = useMemo(() => {
|
||||||
return isTransforming || isStaging || !isDrawingToolAllowed;
|
return isTransforming || isFiltering || isStaging || !isDrawingToolAllowed;
|
||||||
}, [isDrawingToolAllowed, isStaging, isTransforming]);
|
}, [isDrawingToolAllowed, isFiltering, isStaging, isTransforming]);
|
||||||
|
|
||||||
const onClick = useCallback(() => {
|
const onClick = useCallback(() => {
|
||||||
dispatch(toolChanged('eraser'));
|
dispatch(toolChanged('eraser'));
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import { IconButton } from '@invoke-ai/ui-library';
|
import { IconButton } from '@invoke-ai/ui-library';
|
||||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||||
|
import { useIsFiltering } from 'features/controlLayers/hooks/useIsFiltering';
|
||||||
import { useIsTransforming } from 'features/controlLayers/hooks/useIsTransforming';
|
import { useIsTransforming } from 'features/controlLayers/hooks/useIsTransforming';
|
||||||
import { toolChanged } from 'features/controlLayers/store/canvasV2Slice';
|
import { toolChanged } from 'features/controlLayers/store/canvasV2Slice';
|
||||||
import { isDrawableEntityType } from 'features/controlLayers/store/types';
|
import { isDrawableEntityType } from 'features/controlLayers/store/types';
|
||||||
@ -11,6 +12,7 @@ import { PiCursorBold } from 'react-icons/pi';
|
|||||||
export const ToolMoveButton = memo(() => {
|
export const ToolMoveButton = memo(() => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
|
const isFiltering = useIsFiltering();
|
||||||
const isTransforming = useIsTransforming();
|
const isTransforming = useIsTransforming();
|
||||||
const isSelected = useAppSelector((s) => s.canvasV2.tool.selected === 'move');
|
const isSelected = useAppSelector((s) => s.canvasV2.tool.selected === 'move');
|
||||||
const isStaging = useAppSelector((s) => s.canvasV2.session.isStaging);
|
const isStaging = useAppSelector((s) => s.canvasV2.session.isStaging);
|
||||||
@ -21,8 +23,8 @@ export const ToolMoveButton = memo(() => {
|
|||||||
return isDrawableEntityType(s.canvasV2.selectedEntityIdentifier.type);
|
return isDrawableEntityType(s.canvasV2.selectedEntityIdentifier.type);
|
||||||
});
|
});
|
||||||
const isDisabled = useMemo(() => {
|
const isDisabled = useMemo(() => {
|
||||||
return isTransforming || isStaging || !isDrawingToolAllowed;
|
return isTransforming || isFiltering || isStaging || !isDrawingToolAllowed;
|
||||||
}, [isDrawingToolAllowed, isStaging, isTransforming]);
|
}, [isDrawingToolAllowed, isFiltering, isStaging, isTransforming]);
|
||||||
|
|
||||||
const onClick = useCallback(() => {
|
const onClick = useCallback(() => {
|
||||||
dispatch(toolChanged('move'));
|
dispatch(toolChanged('move'));
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import { IconButton } from '@invoke-ai/ui-library';
|
import { IconButton } from '@invoke-ai/ui-library';
|
||||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||||
|
import { useIsFiltering } from 'features/controlLayers/hooks/useIsFiltering';
|
||||||
import { useIsTransforming } from 'features/controlLayers/hooks/useIsTransforming';
|
import { useIsTransforming } from 'features/controlLayers/hooks/useIsTransforming';
|
||||||
import { toolChanged } from 'features/controlLayers/store/canvasV2Slice';
|
import { toolChanged } from 'features/controlLayers/store/canvasV2Slice';
|
||||||
import { isDrawableEntityType } from 'features/controlLayers/store/types';
|
import { isDrawableEntityType } from 'features/controlLayers/store/types';
|
||||||
@ -12,6 +13,7 @@ export const ToolRectButton = memo(() => {
|
|||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
const isSelected = useAppSelector((s) => s.canvasV2.tool.selected === 'rect');
|
const isSelected = useAppSelector((s) => s.canvasV2.tool.selected === 'rect');
|
||||||
|
const isFiltering = useIsFiltering();
|
||||||
const isTransforming = useIsTransforming();
|
const isTransforming = useIsTransforming();
|
||||||
const isStaging = useAppSelector((s) => s.canvasV2.session.isStaging);
|
const isStaging = useAppSelector((s) => s.canvasV2.session.isStaging);
|
||||||
const isDrawingToolAllowed = useAppSelector((s) => {
|
const isDrawingToolAllowed = useAppSelector((s) => {
|
||||||
@ -22,8 +24,8 @@ export const ToolRectButton = memo(() => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const isDisabled = useMemo(() => {
|
const isDisabled = useMemo(() => {
|
||||||
return isTransforming || isStaging || !isDrawingToolAllowed;
|
return isTransforming || isFiltering || isStaging || !isDrawingToolAllowed;
|
||||||
}, [isDrawingToolAllowed, isStaging, isTransforming]);
|
}, [isDrawingToolAllowed, isFiltering, isStaging, isTransforming]);
|
||||||
|
|
||||||
const onClick = useCallback(() => {
|
const onClick = useCallback(() => {
|
||||||
dispatch(toolChanged('rect'));
|
dispatch(toolChanged('rect'));
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import { IconButton } from '@invoke-ai/ui-library';
|
import { IconButton } from '@invoke-ai/ui-library';
|
||||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||||
|
import { useIsFiltering } from 'features/controlLayers/hooks/useIsFiltering';
|
||||||
import { useIsTransforming } from 'features/controlLayers/hooks/useIsTransforming';
|
import { useIsTransforming } from 'features/controlLayers/hooks/useIsTransforming';
|
||||||
import { toolChanged } from 'features/controlLayers/store/canvasV2Slice';
|
import { toolChanged } from 'features/controlLayers/store/canvasV2Slice';
|
||||||
import { memo, useCallback, useMemo } from 'react';
|
import { memo, useCallback, useMemo } from 'react';
|
||||||
@ -11,11 +12,12 @@ export const ToolViewButton = memo(() => {
|
|||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
const isTransforming = useIsTransforming();
|
const isTransforming = useIsTransforming();
|
||||||
|
const isFiltering = useIsFiltering();
|
||||||
const isStaging = useAppSelector((s) => s.canvasV2.session.isStaging);
|
const isStaging = useAppSelector((s) => s.canvasV2.session.isStaging);
|
||||||
const isSelected = useAppSelector((s) => s.canvasV2.tool.selected === 'view');
|
const isSelected = useAppSelector((s) => s.canvasV2.tool.selected === 'view');
|
||||||
const isDisabled = useMemo(() => {
|
const isDisabled = useMemo(() => {
|
||||||
return isTransforming || isStaging;
|
return isTransforming || isFiltering || isStaging;
|
||||||
}, [isStaging, isTransforming]);
|
}, [isFiltering, isStaging, isTransforming]);
|
||||||
const onClick = useCallback(() => {
|
const onClick = useCallback(() => {
|
||||||
dispatch(toolChanged('view'));
|
dispatch(toolChanged('view'));
|
||||||
}, [dispatch]);
|
}, [dispatch]);
|
||||||
|
@ -0,0 +1,8 @@
|
|||||||
|
import { useStore } from '@nanostores/react';
|
||||||
|
import { useCanvasManager } from 'features/controlLayers/contexts/CanvasManagerProviderGate';
|
||||||
|
|
||||||
|
export const useIsFiltering = () => {
|
||||||
|
const canvasManager = useCanvasManager();
|
||||||
|
const isFiltering = useStore(canvasManager.filter.$isFiltering);
|
||||||
|
return isFiltering;
|
||||||
|
};
|
@ -4,7 +4,7 @@ import type { CanvasManager } from 'features/controlLayers/konva/CanvasManager';
|
|||||||
import { getPrefixedId } from 'features/controlLayers/konva/util';
|
import { getPrefixedId } from 'features/controlLayers/konva/util';
|
||||||
import type { CanvasEntityIdentifier, CanvasImageState, FilterConfig } from 'features/controlLayers/store/types';
|
import type { CanvasEntityIdentifier, CanvasImageState, FilterConfig } from 'features/controlLayers/store/types';
|
||||||
import { IMAGE_FILTERS, imageDTOToImageObject } from 'features/controlLayers/store/types';
|
import { IMAGE_FILTERS, imageDTOToImageObject } from 'features/controlLayers/store/types';
|
||||||
import { atom } from 'nanostores';
|
import { atom, computed } from 'nanostores';
|
||||||
import type { Logger } from 'roarr';
|
import type { Logger } from 'roarr';
|
||||||
import { getImageDTO } from 'services/api/endpoints/images';
|
import { getImageDTO } from 'services/api/endpoints/images';
|
||||||
import type { BatchConfig, ImageDTO, S } from 'services/api/types';
|
import type { BatchConfig, ImageDTO, S } from 'services/api/types';
|
||||||
@ -23,6 +23,7 @@ export class CanvasFilterModule {
|
|||||||
imageState: CanvasImageState | null = null;
|
imageState: CanvasImageState | null = null;
|
||||||
|
|
||||||
$adapter = atom<CanvasLayerAdapter | null>(null);
|
$adapter = atom<CanvasLayerAdapter | null>(null);
|
||||||
|
$isFiltering = computed(this.$adapter, (adapter) => Boolean(adapter));
|
||||||
$isProcessing = atom<boolean>(false);
|
$isProcessing = atom<boolean>(false);
|
||||||
$config = atom<FilterConfig>(IMAGE_FILTERS.canny_image_processor.buildDefaults());
|
$config = atom<FilterConfig>(IMAGE_FILTERS.canny_image_processor.buildDefaults());
|
||||||
|
|
||||||
@ -46,6 +47,7 @@ export class CanvasFilterModule {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.$adapter.set(entity.adapter);
|
this.$adapter.set(entity.adapter);
|
||||||
|
this.manager.stateApi.setTool('view');
|
||||||
};
|
};
|
||||||
|
|
||||||
previewFilter = async () => {
|
previewFilter = async () => {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user