feat(ui): update entity list menu

This commit is contained in:
psychedelicious 2024-08-23 17:10:32 +10:00
parent a4f8671f86
commit aefb2339bb
5 changed files with 84 additions and 60 deletions

View File

@ -1652,6 +1652,7 @@
"autoSave": "Auto-save to Gallery",
"resetCanvas": "Reset Canvas",
"resetAll": "Reset All",
"deleteAll": "Delete All",
"clearCaches": "Clear Caches",
"recalculateRects": "Recalculate Rects",
"clipToBbox": "Clip Strokes to Bbox",

View File

@ -1,57 +0,0 @@
import { IconButton, Menu, MenuButton, MenuItem, MenuList } from '@invoke-ai/ui-library';
import { useAppDispatch } from 'app/store/storeHooks';
import { useDefaultControlAdapter, useDefaultIPAdapter } from 'features/controlLayers/hooks/useLayerControlAdapter';
import {
controlLayerAdded,
inpaintMaskAdded,
ipaAdded,
rasterLayerAdded,
rgAdded,
} from 'features/controlLayers/store/canvasV2Slice';
import { memo, useCallback } from 'react';
import { useTranslation } from 'react-i18next';
import { PiPlusBold } from 'react-icons/pi';
export const AddLayerButton = memo(() => {
const { t } = useTranslation();
const dispatch = useAppDispatch();
const defaultControlAdapter = useDefaultControlAdapter();
const defaultIPAdapter = useDefaultIPAdapter();
const addInpaintMask = useCallback(() => {
dispatch(inpaintMaskAdded());
}, [dispatch]);
const addRegionalGuidance = useCallback(() => {
dispatch(rgAdded());
}, [dispatch]);
const addRasterLayer = useCallback(() => {
dispatch(rasterLayerAdded({ isSelected: true }));
}, [dispatch]);
const addControlLayer = useCallback(() => {
dispatch(controlLayerAdded({ isSelected: true, overrides: { controlAdapter: defaultControlAdapter } }));
}, [defaultControlAdapter, dispatch]);
const addIPAdapter = useCallback(() => {
dispatch(ipaAdded({ ipAdapter: defaultIPAdapter }));
}, [defaultIPAdapter, dispatch]);
return (
<Menu>
<MenuButton
as={IconButton}
aria-label={t('controlLayers.addLayer')}
icon={<PiPlusBold />}
variant="link"
data-testid="control-layers-add-layer-menu-button"
alignSelf="stretch"
/>
<MenuList>
<MenuItem onClick={addInpaintMask}>{t('controlLayers.inpaintMask', { count: 1 })}</MenuItem>
<MenuItem onClick={addRegionalGuidance}>{t('controlLayers.regionalGuidance', { count: 1 })}</MenuItem>
<MenuItem onClick={addRasterLayer}>{t('controlLayers.rasterLayer', { count: 1 })}</MenuItem>
<MenuItem onClick={addControlLayer}>{t('controlLayers.controlLayer', { count: 1 })}</MenuItem>
<MenuItem onClick={addIPAdapter}>{t('controlLayers.ipAdapter', { count: 1 })}</MenuItem>
</MenuList>
</Menu>
);
});
AddLayerButton.displayName = 'AddLayerButton';

View File

@ -0,0 +1,80 @@
import { IconButton, Menu, MenuButton, MenuDivider, MenuItem, MenuList } from '@invoke-ai/ui-library';
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
import { useDefaultControlAdapter, useDefaultIPAdapter } from 'features/controlLayers/hooks/useLayerControlAdapter';
import {
allEntitiesDeleted,
controlLayerAdded,
inpaintMaskAdded,
ipaAdded,
rasterLayerAdded,
rgAdded,
} from 'features/controlLayers/store/canvasV2Slice';
import { selectEntityCount } from 'features/controlLayers/store/selectors';
import { memo, useCallback } from 'react';
import { useTranslation } from 'react-i18next';
import { PiDotsThreeOutlineFill, PiPlusBold, PiTrashSimpleBold } from 'react-icons/pi';
export const CanvasEntityListMenu = memo(() => {
const { t } = useTranslation();
const dispatch = useAppDispatch();
const hasEntities = useAppSelector((s) => {
const count = selectEntityCount(s);
return count > 0;
});
const defaultControlAdapter = useDefaultControlAdapter();
const defaultIPAdapter = useDefaultIPAdapter();
const addInpaintMask = useCallback(() => {
dispatch(inpaintMaskAdded());
}, [dispatch]);
const addRegionalGuidance = useCallback(() => {
dispatch(rgAdded());
}, [dispatch]);
const addRasterLayer = useCallback(() => {
dispatch(rasterLayerAdded({ isSelected: true }));
}, [dispatch]);
const addControlLayer = useCallback(() => {
dispatch(controlLayerAdded({ isSelected: true, overrides: { controlAdapter: defaultControlAdapter } }));
}, [defaultControlAdapter, dispatch]);
const addIPAdapter = useCallback(() => {
dispatch(ipaAdded({ ipAdapter: defaultIPAdapter }));
}, [defaultIPAdapter, dispatch]);
const deleteAll = useCallback(() => {
dispatch(allEntitiesDeleted());
}, [dispatch]);
return (
<Menu>
<MenuButton
as={IconButton}
aria-label={t('accessibility.menu')}
icon={<PiDotsThreeOutlineFill />}
variant="link"
data-testid="control-layers-add-layer-menu-button"
alignSelf="stretch"
/>
<MenuList>
<MenuItem icon={<PiPlusBold />} onClick={addInpaintMask}>
{t('controlLayers.inpaintMask', { count: 1 })}
</MenuItem>
<MenuItem icon={<PiPlusBold />} onClick={addRegionalGuidance}>
{t('controlLayers.regionalGuidance', { count: 1 })}
</MenuItem>
<MenuItem icon={<PiPlusBold />} onClick={addRasterLayer}>
{t('controlLayers.rasterLayer', { count: 1 })}
</MenuItem>
<MenuItem icon={<PiPlusBold />} onClick={addControlLayer}>
{t('controlLayers.controlLayer', { count: 1 })}
</MenuItem>
<MenuItem icon={<PiPlusBold />} onClick={addIPAdapter}>
{t('controlLayers.ipAdapter', { count: 1 })}
</MenuItem>
<MenuDivider />
<MenuItem onClick={deleteAll} icon={<PiTrashSimpleBold />} color="error.300" isDisabled={!hasEntities}>
{t('controlLayers.deleteAll', { count: 1 })}
</MenuItem>
</MenuList>
</Menu>
);
});
CanvasEntityListMenu.displayName = 'CanvasEntityListMenu';

View File

@ -439,7 +439,6 @@ export const {
invertScrollChanged,
toolChanged,
toolBufferChanged,
allEntitiesDeleted,
clipToBboxChanged,
canvasReset,
settingsDynamicGridToggled,
@ -460,6 +459,7 @@ export const {
entityArrangedBackwardOne,
entityArrangedToBack,
entityOpacityChanged,
allEntitiesDeleted,
allEntitiesOfTypeIsHiddenToggled,
// bbox
bboxChanged,

View File

@ -3,7 +3,7 @@ import { Box, Flex, Spacer, Tab, TabList, TabPanel, TabPanels, Tabs } from '@inv
import { useStore } from '@nanostores/react';
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
import { overlayScrollbarsParams } from 'common/components/OverlayScrollbars/constants';
import { AddLayerButton } from 'features/controlLayers/components/AddLayerButton';
import { CanvasEntityListMenu } from 'features/controlLayers/components/CanvasEntityListMenu';
import { CanvasPanelContent } from 'features/controlLayers/components/CanvasPanelContent';
import { $isPreviewVisible } from 'features/controlLayers/store/canvasV2Slice';
import { selectEntityCount } from 'features/controlLayers/store/selectors';
@ -102,7 +102,7 @@ const ParametersPanelTextToImage = () => {
{controlLayersTitle}
</Tab>
<Spacer />
<AddLayerButton />
<CanvasEntityListMenu />
</TabList>
<TabPanels w="full" h="full">
<TabPanel p={0} w="full" h="full">