create hook for managing entity type enabledness for given base model and update usage

This commit is contained in:
Mary Hipp
2025-03-17 14:58:32 -04:00
committed by psychedelicious
parent 9846229e52
commit 8837932bad
6 changed files with 80 additions and 27 deletions

View File

@@ -1,5 +1,4 @@
import { Button, Flex, Heading } from '@invoke-ai/ui-library';
import { useAppSelector } from 'app/store/storeHooks';
import { InformationalPopover } from 'common/components/InformationalPopover/InformationalPopover';
import {
useAddControlLayer,
@@ -9,7 +8,7 @@ import {
useAddRegionalGuidance,
useAddRegionalReferenceImage,
} from 'features/controlLayers/hooks/addLayerHooks';
import { selectIsSD3 } from 'features/controlLayers/store/paramsSlice';
import { useIsEntityTypeEnabled } from 'features/controlLayers/hooks/useIsEntityTypeEnabled';
import { memo } from 'react';
import { useTranslation } from 'react-i18next';
import { PiPlusBold } from 'react-icons/pi';
@@ -22,7 +21,7 @@ export const CanvasAddEntityButtons = memo(() => {
const addControlLayer = useAddControlLayer();
const addGlobalReferenceImage = useAddGlobalReferenceImage();
const addRegionalReferenceImage = useAddRegionalReferenceImage();
const isSD3 = useAppSelector(selectIsSD3);
const { isReferenceImageEnabled, isRegionalGuidanceEnabled, isControlLayerEnabled } = useIsEntityTypeEnabled();
return (
<Flex w="full" h="full" justifyContent="center" gap={4}>
@@ -36,7 +35,7 @@ export const CanvasAddEntityButtons = memo(() => {
justifyContent="flex-start"
leftIcon={<PiPlusBold />}
onClick={addGlobalReferenceImage}
isDisabled={isSD3}
isDisabled={!isReferenceImageEnabled}
>
{t('controlLayers.globalReferenceImage')}
</Button>
@@ -62,7 +61,7 @@ export const CanvasAddEntityButtons = memo(() => {
justifyContent="flex-start"
leftIcon={<PiPlusBold />}
onClick={addRegionalGuidance}
isDisabled={isSD3}
isDisabled={!isRegionalGuidanceEnabled}
>
{t('controlLayers.regionalGuidance')}
</Button>
@@ -74,7 +73,7 @@ export const CanvasAddEntityButtons = memo(() => {
justifyContent="flex-start"
leftIcon={<PiPlusBold />}
onClick={addRegionalReferenceImage}
isDisabled={isSD3}
isDisabled={!isRegionalGuidanceEnabled}
>
{t('controlLayers.regionalReferenceImage')}
</Button>
@@ -89,7 +88,7 @@ export const CanvasAddEntityButtons = memo(() => {
justifyContent="flex-start"
leftIcon={<PiPlusBold />}
onClick={addControlLayer}
isDisabled={isSD3}
isDisabled={!isControlLayerEnabled}
>
{t('controlLayers.controlLayer')}
</Button>

View File

@@ -1,5 +1,4 @@
import { IconButton, Menu, MenuButton, MenuGroup, MenuItem, MenuList } from '@invoke-ai/ui-library';
import { useAppSelector } from 'app/store/storeHooks';
import {
useAddControlLayer,
useAddGlobalReferenceImage,
@@ -9,7 +8,7 @@ import {
useAddRegionalReferenceImage,
} from 'features/controlLayers/hooks/addLayerHooks';
import { useCanvasIsBusy } from 'features/controlLayers/hooks/useCanvasIsBusy';
import { selectIsSD3 } from 'features/controlLayers/store/paramsSlice';
import { useIsEntityTypeEnabled } from 'features/controlLayers/hooks/useIsEntityTypeEnabled';
import { memo } from 'react';
import { useTranslation } from 'react-i18next';
import { PiPlusBold } from 'react-icons/pi';
@@ -23,7 +22,7 @@ export const EntityListGlobalActionBarAddLayerMenu = memo(() => {
const addRegionalReferenceImage = useAddRegionalReferenceImage();
const addRasterLayer = useAddRasterLayer();
const addControlLayer = useAddControlLayer();
const isSD3 = useAppSelector(selectIsSD3);
const { isReferenceImageEnabled, isRegionalGuidanceEnabled, isControlLayerEnabled } = useIsEntityTypeEnabled();
return (
<Menu>
@@ -40,7 +39,7 @@ export const EntityListGlobalActionBarAddLayerMenu = memo(() => {
/>
<MenuList>
<MenuGroup title={t('controlLayers.global')}>
<MenuItem icon={<PiPlusBold />} onClick={addGlobalReferenceImage} isDisabled={isSD3}>
<MenuItem icon={<PiPlusBold />} onClick={addGlobalReferenceImage} isDisabled={!isReferenceImageEnabled}>
{t('controlLayers.globalReferenceImage')}
</MenuItem>
</MenuGroup>
@@ -48,15 +47,15 @@ export const EntityListGlobalActionBarAddLayerMenu = memo(() => {
<MenuItem icon={<PiPlusBold />} onClick={addInpaintMask}>
{t('controlLayers.inpaintMask')}
</MenuItem>
<MenuItem icon={<PiPlusBold />} onClick={addRegionalGuidance} isDisabled={isSD3}>
<MenuItem icon={<PiPlusBold />} onClick={addRegionalGuidance} isDisabled={!isRegionalGuidanceEnabled}>
{t('controlLayers.regionalGuidance')}
</MenuItem>
<MenuItem icon={<PiPlusBold />} onClick={addRegionalReferenceImage} isDisabled={isSD3}>
<MenuItem icon={<PiPlusBold />} onClick={addRegionalReferenceImage} isDisabled={!isRegionalGuidanceEnabled}>
{t('controlLayers.regionalReferenceImage')}
</MenuItem>
</MenuGroup>
<MenuGroup title={t('controlLayers.layer_other')}>
<MenuItem icon={<PiPlusBold />} onClick={addControlLayer} isDisabled={isSD3}>
<MenuItem icon={<PiPlusBold />} onClick={addControlLayer} isDisabled={!isControlLayerEnabled}>
{t('controlLayers.controlLayer')}
</MenuItem>
<MenuItem icon={<PiPlusBold />} onClick={addRasterLayer}>

View File

@@ -0,0 +1,57 @@
import { useAppSelector } from 'app/store/storeHooks';
import { selectIsCogView4, selectIsSD3 } from 'features/controlLayers/store/paramsSlice';
import type { CanvasEntityType } from 'features/controlLayers/store/types';
import { useCallback, useMemo } from 'react';
export const useIsEntityTypeEnabled = () => {
const isSD3 = useAppSelector(selectIsSD3);
const isCogView4 = useAppSelector(selectIsCogView4);
const isEntityTypeEnabled = useCallback(
(layerType: CanvasEntityType) => {
switch (layerType) {
case 'reference_image':
return !isSD3 && !isCogView4;
case 'regional_guidance':
return !isSD3 && !isCogView4;
case 'control_layer':
return !isSD3 && !isCogView4;
case 'inpaint_mask':
return true;
case 'raster_layer':
return true;
default:
break;
}
},
[isSD3, isCogView4]
);
const isReferenceImageEnabled = useMemo(() => {
return isEntityTypeEnabled('reference_image');
}, [isEntityTypeEnabled]);
const isRegionalGuidanceEnabled = useMemo(() => {
return isEntityTypeEnabled('regional_guidance');
}, [isEntityTypeEnabled]);
const isRasterLayerEnabled = useMemo(() => {
return isEntityTypeEnabled('raster_layer');
}, [isEntityTypeEnabled]);
const isControlLayerEnabled = useMemo(() => {
return isEntityTypeEnabled('control_layer');
}, [isEntityTypeEnabled]);
const isInpaintMaskEnabled = useMemo(() => {
return isEntityTypeEnabled('inpaint_mask');
}, [isEntityTypeEnabled]);
return {
isReferenceImageEnabled,
isRegionalGuidanceEnabled,
isRasterLayerEnabled,
isControlLayerEnabled,
isInpaintMaskEnabled,
};
};

View File

@@ -379,6 +379,7 @@ export const selectBase = createParamsSelector((params) => params.model?.base);
export const selectIsSDXL = createParamsSelector((params) => params.model?.base === 'sdxl');
export const selectIsFLUX = createParamsSelector((params) => params.model?.base === 'flux');
export const selectIsSD3 = createParamsSelector((params) => params.model?.base === 'sd-3');
export const selectIsCogView4 = createParamsSelector((params) => params.model?.base === 'cogview4');
export const selectModel = createParamsSelector((params) => params.model);
export const selectModelKey = createParamsSelector((params) => params.model?.key);

View File

@@ -1,9 +1,8 @@
import { Menu, MenuButton, MenuItem, MenuList } from '@invoke-ai/ui-library';
import { useAppStore } from 'app/store/nanostores/store';
import { useAppSelector } from 'app/store/storeHooks';
import { SubMenuButtonContent, useSubMenu } from 'common/hooks/useSubMenu';
import { useCanvasIsBusySafe } from 'features/controlLayers/hooks/useCanvasIsBusy';
import { selectIsSD3 } from 'features/controlLayers/store/paramsSlice';
import { useIsEntityTypeEnabled } from 'features/controlLayers/hooks/useIsEntityTypeEnabled';
import { useImageViewer } from 'features/gallery/components/ImageViewer/useImageViewer';
import { useImageDTOContext } from 'features/gallery/contexts/ImageDTOContext';
import { newCanvasFromImage } from 'features/imageActions/actions';
@@ -20,7 +19,7 @@ export const ImageMenuItemNewCanvasFromImageSubMenu = memo(() => {
const imageDTO = useImageDTOContext();
const imageViewer = useImageViewer();
const isBusy = useCanvasIsBusySafe();
const isSD3 = useAppSelector(selectIsSD3);
const { isControlLayerEnabled } = useIsEntityTypeEnabled();
const onClickNewCanvasWithRasterLayerFromImage = useCallback(() => {
const { dispatch, getState } = store;
@@ -90,14 +89,14 @@ export const ImageMenuItemNewCanvasFromImageSubMenu = memo(() => {
<MenuItem
icon={<PiFileBold />}
onClickCapture={onClickNewCanvasWithControlLayerFromImage}
isDisabled={isBusy || isSD3}
isDisabled={isBusy || !isControlLayerEnabled}
>
{t('controlLayers.asControlLayer')}
</MenuItem>
<MenuItem
icon={<PiFileBold />}
onClickCapture={onClickNewCanvasWithControlLayerFromImageWithResize}
isDisabled={isBusy || isSD3}
isDisabled={isBusy || !isControlLayerEnabled}
>
{t('controlLayers.asControlLayerResize')}
</MenuItem>

View File

@@ -1,10 +1,9 @@
import { Menu, MenuButton, MenuItem, MenuList } from '@invoke-ai/ui-library';
import { useAppStore } from 'app/store/nanostores/store';
import { useAppSelector } from 'app/store/storeHooks';
import { SubMenuButtonContent, useSubMenu } from 'common/hooks/useSubMenu';
import { NewLayerIcon } from 'features/controlLayers/components/common/icons';
import { useCanvasIsBusySafe } from 'features/controlLayers/hooks/useCanvasIsBusy';
import { selectIsFLUX, selectIsSD3 } from 'features/controlLayers/store/paramsSlice';
import { useIsEntityTypeEnabled } from 'features/controlLayers/hooks/useIsEntityTypeEnabled';
import { useImageViewer } from 'features/gallery/components/ImageViewer/useImageViewer';
import { useImageDTOContext } from 'features/gallery/contexts/ImageDTOContext';
import { sentImageToCanvas } from 'features/gallery/store/actions';
@@ -22,8 +21,7 @@ export const ImageMenuItemNewLayerFromImageSubMenu = memo(() => {
const imageDTO = useImageDTOContext();
const imageViewer = useImageViewer();
const isBusy = useCanvasIsBusySafe();
const isFLUX = useAppSelector(selectIsFLUX);
const isSD3 = useAppSelector(selectIsSD3);
const { isRegionalGuidanceEnabled, isControlLayerEnabled, isReferenceImageEnabled } = useIsEntityTypeEnabled();
const onClickNewRasterLayerFromImage = useCallback(() => {
const { dispatch, getState } = store;
@@ -116,14 +114,14 @@ export const ImageMenuItemNewLayerFromImageSubMenu = memo(() => {
<MenuItem
icon={<NewLayerIcon />}
onClickCapture={onClickNewRegionalGuidanceFromImage}
isDisabled={isBusy || isFLUX || isSD3}
isDisabled={isBusy || !isRegionalGuidanceEnabled}
>
{t('controlLayers.regionalGuidance')}
</MenuItem>
<MenuItem
icon={<NewLayerIcon />}
onClickCapture={onClickNewControlLayerFromImage}
isDisabled={isBusy || isSD3}
isDisabled={isBusy || !isControlLayerEnabled}
>
{t('controlLayers.controlLayer')}
</MenuItem>
@@ -133,14 +131,14 @@ export const ImageMenuItemNewLayerFromImageSubMenu = memo(() => {
<MenuItem
icon={<NewLayerIcon />}
onClickCapture={onClickNewRegionalReferenceImageFromImage}
isDisabled={isBusy}
isDisabled={isBusy || !isRegionalGuidanceEnabled}
>
{t('controlLayers.referenceImageRegional')}
</MenuItem>
<MenuItem
icon={<NewLayerIcon />}
onClickCapture={onClickNewGlobalReferenceImageFromImage}
isDisabled={isBusy}
isDisabled={isBusy || !isReferenceImageEnabled}
>
{t('controlLayers.referenceImageGlobal')}
</MenuItem>