remove copy/save from layer UX and add it to layer context menu and action bar where appropriate; remove copy/save from IP adapter layers

This commit is contained in:
Mary Hipp
2024-09-17 18:58:53 -04:00
committed by psychedelicious
parent fd2da6446a
commit 0303ebad50
11 changed files with 63 additions and 54 deletions

View File

@@ -1,6 +1,6 @@
import { MenuGroup } from '@invoke-ai/ui-library';
import { useAppSelector } from 'app/store/storeHooks';
import { CanvasEntityMenuItemsCopy } from 'features/controlLayers/components/common/CanvasEntityMenuItemsCopy';
import { CanvasEntityMenuItemsCopyToClipboard } from 'features/controlLayers/components/common/CanvasEntityMenuItemsCopyToClipboard';
import { CanvasEntityMenuItemsDelete } from 'features/controlLayers/components/common/CanvasEntityMenuItemsDelete';
import { CanvasEntityMenuItemsFilter } from 'features/controlLayers/components/common/CanvasEntityMenuItemsFilter';
import { CanvasEntityMenuItemsSave } from 'features/controlLayers/components/common/CanvasEntityMenuItemsSave';
@@ -11,7 +11,11 @@ import {
} from 'features/controlLayers/contexts/EntityIdentifierContext';
import { useEntityTitle } from 'features/controlLayers/hooks/useEntityTitle';
import { selectSelectedEntityIdentifier } from 'features/controlLayers/store/selectors';
import { isFilterableEntityIdentifier, isTransformableEntityIdentifier } from 'features/controlLayers/store/types';
import {
isFilterableEntityIdentifier,
isSaveableEntityIdentifier,
isTransformableEntityIdentifier,
} from 'features/controlLayers/store/types';
import { memo } from 'react';
const CanvasContextMenuSelectedEntityMenuItemsContent = memo(() => {
@@ -22,8 +26,8 @@ const CanvasContextMenuSelectedEntityMenuItemsContent = memo(() => {
<MenuGroup title={title}>
{isFilterableEntityIdentifier(entityIdentifier) && <CanvasEntityMenuItemsFilter />}
{isTransformableEntityIdentifier(entityIdentifier) && <CanvasEntityMenuItemsTransform />}
<CanvasEntityMenuItemsCopy />
<CanvasEntityMenuItemsSave />
{isSaveableEntityIdentifier(entityIdentifier) && <CanvasEntityMenuItemsCopyToClipboard />}
{isSaveableEntityIdentifier(entityIdentifier) && <CanvasEntityMenuItemsSave />}
<CanvasEntityMenuItemsDelete />
</MenuGroup>
);

View File

@@ -7,6 +7,8 @@ import { EntityListSelectedEntityActionBarOpacity } from 'features/controlLayers
import { EntityListSelectedEntityActionBarTransformButton } from 'features/controlLayers/components/CanvasEntityList/EntityListSelectedEntityActionBarTransformButton';
import { memo } from 'react';
import { EntityListSelectedEntityActionBarSaveToAssetsButton } from './EntityListSelectedEntityActionBarSaveToAssetsButton';
export const EntityListSelectedEntityActionBar = memo(() => {
return (
<Flex w="full" gap={2} alignItems="center" ps={1}>
@@ -16,6 +18,7 @@ export const EntityListSelectedEntityActionBar = memo(() => {
<Flex h="full">
<EntityListSelectedEntityActionBarFilterButton />
<EntityListSelectedEntityActionBarTransformButton />
<EntityListSelectedEntityActionBarSaveToAssetsButton />
<EntityListSelectedEntityActionBarDuplicateButton />
<EntityListGlobalActionBarAddLayerMenu />
</Flex>

View File

@@ -1,34 +1,44 @@
import { IconButton } from '@invoke-ai/ui-library';
import { useAppSelector } from 'app/store/storeHooks';
import { useEntityAdapterSafe } from 'features/controlLayers/contexts/EntityAdapterContext';
import { useEntityIdentifierContext } from 'features/controlLayers/contexts/EntityIdentifierContext';
import { useCanvasIsBusy } from 'features/controlLayers/hooks/useCanvasIsBusy';
import { useSaveLayerToAssets } from 'features/controlLayers/hooks/useSaveLayerToAssets';
import { selectSelectedEntityIdentifier } from 'features/controlLayers/store/selectors';
import { isSaveableEntityIdentifier } from 'features/controlLayers/store/types';
import { memo, useCallback } from 'react';
import { useTranslation } from 'react-i18next';
import { PiFloppyDiskBold } from 'react-icons/pi';
export const CanvasEntitySaveToAssets = memo(() => {
export const EntityListSelectedEntityActionBarSaveToAssetsButton = memo(() => {
const { t } = useTranslation();
const entityIdentifier = useEntityIdentifierContext();
const adapter = useEntityAdapterSafe(entityIdentifier);
const isBusy = useCanvasIsBusy();
const selectedEntityIdentifier = useAppSelector(selectSelectedEntityIdentifier);
const adapter = useEntityAdapterSafe(selectedEntityIdentifier);
const saveLayerToAssets = useSaveLayerToAssets();
const onClick = useCallback(() => {
saveLayerToAssets(adapter);
}, [saveLayerToAssets, adapter]);
if (!selectedEntityIdentifier) {
return null;
}
if (!isSaveableEntityIdentifier(selectedEntityIdentifier)) {
return null;
}
return (
<IconButton
onClick={onClick}
isDisabled={!selectedEntityIdentifier || isBusy}
size="sm"
aria-label={t('controlLayers.saveLayerToAssets')}
tooltip={t('controlLayers.saveLayerToAssets')}
variant="link"
alignSelf="stretch"
aria-label={t('controlLayers.saveLayerToAssets')}
tooltip={t('controlLayers.saveLayerToAssets')}
icon={<PiFloppyDiskBold />}
onClick={onClick}
isDisabled={isBusy}
/>
);
});
CanvasEntitySaveToAssets.displayName = 'CanvasEntitySaveToAssets';
EntityListSelectedEntityActionBarSaveToAssetsButton.displayName = 'EntityListSelectedEntityActionBarSaveToAssetsButton';

View File

@@ -1,8 +1,10 @@
import { MenuDivider } from '@invoke-ai/ui-library';
import { CanvasEntityMenuItemsArrange } from 'features/controlLayers/components/common/CanvasEntityMenuItemsArrange';
import { CanvasEntityMenuItemsCopyToClipboard } from 'features/controlLayers/components/common/CanvasEntityMenuItemsCopyToClipboard';
import { CanvasEntityMenuItemsDelete } from 'features/controlLayers/components/common/CanvasEntityMenuItemsDelete';
import { CanvasEntityMenuItemsDuplicate } from 'features/controlLayers/components/common/CanvasEntityMenuItemsDuplicate';
import { CanvasEntityMenuItemsFilter } from 'features/controlLayers/components/common/CanvasEntityMenuItemsFilter';
import { CanvasEntityMenuItemsSave } from 'features/controlLayers/components/common/CanvasEntityMenuItemsSave';
import { CanvasEntityMenuItemsTransform } from 'features/controlLayers/components/common/CanvasEntityMenuItemsTransform';
import { ControlLayerMenuItemsConvertControlToRaster } from 'features/controlLayers/components/ControlLayer/ControlLayerMenuItemsConvertControlToRaster';
import { ControlLayerMenuItemsTransparencyEffect } from 'features/controlLayers/components/ControlLayer/ControlLayerMenuItemsTransparencyEffect';
@@ -19,6 +21,8 @@ export const ControlLayerMenuItems = memo(() => {
<CanvasEntityMenuItemsArrange />
<MenuDivider />
<CanvasEntityMenuItemsDuplicate />
<CanvasEntityMenuItemsCopyToClipboard />
<CanvasEntityMenuItemsSave />
<CanvasEntityMenuItemsDelete />
</>
);

View File

@@ -1,7 +1,9 @@
import { MenuDivider } from '@invoke-ai/ui-library';
import { CanvasEntityMenuItemsArrange } from 'features/controlLayers/components/common/CanvasEntityMenuItemsArrange';
import { CanvasEntityMenuItemsCopyToClipboard } from 'features/controlLayers/components/common/CanvasEntityMenuItemsCopyToClipboard';
import { CanvasEntityMenuItemsDelete } from 'features/controlLayers/components/common/CanvasEntityMenuItemsDelete';
import { CanvasEntityMenuItemsDuplicate } from 'features/controlLayers/components/common/CanvasEntityMenuItemsDuplicate';
import { CanvasEntityMenuItemsSave } from 'features/controlLayers/components/common/CanvasEntityMenuItemsSave';
import { CanvasEntityMenuItemsTransform } from 'features/controlLayers/components/common/CanvasEntityMenuItemsTransform';
import { memo } from 'react';
@@ -13,6 +15,8 @@ export const InpaintMaskMenuItems = memo(() => {
<CanvasEntityMenuItemsArrange />
<MenuDivider />
<CanvasEntityMenuItemsDuplicate />
<CanvasEntityMenuItemsCopyToClipboard />
<CanvasEntityMenuItemsSave />
<CanvasEntityMenuItemsDelete />
</>
);

View File

@@ -1,8 +1,10 @@
import { MenuDivider } from '@invoke-ai/ui-library';
import { CanvasEntityMenuItemsArrange } from 'features/controlLayers/components/common/CanvasEntityMenuItemsArrange';
import { CanvasEntityMenuItemsCopyToClipboard } from 'features/controlLayers/components/common/CanvasEntityMenuItemsCopyToClipboard';
import { CanvasEntityMenuItemsDelete } from 'features/controlLayers/components/common/CanvasEntityMenuItemsDelete';
import { CanvasEntityMenuItemsDuplicate } from 'features/controlLayers/components/common/CanvasEntityMenuItemsDuplicate';
import { CanvasEntityMenuItemsFilter } from 'features/controlLayers/components/common/CanvasEntityMenuItemsFilter';
import { CanvasEntityMenuItemsSave } from 'features/controlLayers/components/common/CanvasEntityMenuItemsSave';
import { CanvasEntityMenuItemsTransform } from 'features/controlLayers/components/common/CanvasEntityMenuItemsTransform';
import { RasterLayerMenuItemsConvertRasterToControl } from 'features/controlLayers/components/RasterLayer/RasterLayerMenuItemsConvertRasterToControl';
import { memo } from 'react';
@@ -17,6 +19,8 @@ export const RasterLayerMenuItems = memo(() => {
<CanvasEntityMenuItemsArrange />
<MenuDivider />
<CanvasEntityMenuItemsDuplicate />
<CanvasEntityMenuItemsCopyToClipboard />
<CanvasEntityMenuItemsSave />
<CanvasEntityMenuItemsDelete />
</>
);

View File

@@ -1,7 +1,9 @@
import { MenuDivider } from '@invoke-ai/ui-library';
import { CanvasEntityMenuItemsArrange } from 'features/controlLayers/components/common/CanvasEntityMenuItemsArrange';
import { CanvasEntityMenuItemsCopyToClipboard } from 'features/controlLayers/components/common/CanvasEntityMenuItemsCopyToClipboard';
import { CanvasEntityMenuItemsDelete } from 'features/controlLayers/components/common/CanvasEntityMenuItemsDelete';
import { CanvasEntityMenuItemsDuplicate } from 'features/controlLayers/components/common/CanvasEntityMenuItemsDuplicate';
import { CanvasEntityMenuItemsSave } from 'features/controlLayers/components/common/CanvasEntityMenuItemsSave';
import { CanvasEntityMenuItemsTransform } from 'features/controlLayers/components/common/CanvasEntityMenuItemsTransform';
import { RegionalGuidanceMenuItemsAddPromptsAndIPAdapter } from 'features/controlLayers/components/RegionalGuidance/RegionalGuidanceMenuItemsAddPromptsAndIPAdapter';
import { RegionalGuidanceMenuItemsAutoNegative } from 'features/controlLayers/components/RegionalGuidance/RegionalGuidanceMenuItemsAutoNegative';
@@ -18,6 +20,8 @@ export const RegionalGuidanceMenuItems = memo(() => {
<CanvasEntityMenuItemsArrange />
<MenuDivider />
<CanvasEntityMenuItemsDuplicate />
<CanvasEntityMenuItemsCopyToClipboard />
<CanvasEntityMenuItemsSave />
<CanvasEntityMenuItemsDelete />
</>
);

View File

@@ -1,34 +0,0 @@
import { IconButton } from '@invoke-ai/ui-library';
import { useEntityAdapterSafe } from 'features/controlLayers/contexts/EntityAdapterContext';
import { useEntityIdentifierContext } from 'features/controlLayers/contexts/EntityIdentifierContext';
import { useCanvasIsBusy } from 'features/controlLayers/hooks/useCanvasIsBusy';
import { useCopyLayerToClipboard } from 'features/controlLayers/hooks/useCopyLayerToClipboard';
import { memo, useCallback } from 'react';
import { useTranslation } from 'react-i18next';
import { PiCopyBold } from 'react-icons/pi';
export const CanvasEntityCopyToClipboard = memo(() => {
const { t } = useTranslation();
const entityIdentifier = useEntityIdentifierContext();
const adapter = useEntityAdapterSafe(entityIdentifier);
const isBusy = useCanvasIsBusy();
const copyLayerToClipboard = useCopyLayerToClipboard();
const onClick = useCallback(() => {
copyLayerToClipboard(adapter);
}, [copyLayerToClipboard, adapter]);
return (
<IconButton
size="sm"
aria-label={t('unifiedCanvas.copyToClipboard')}
tooltip={t('unifiedCanvas.copyToClipboard')}
variant="link"
alignSelf="stretch"
icon={<PiCopyBold />}
onClick={onClick}
isDisabled={isBusy}
/>
);
});
CanvasEntityCopyToClipboard.displayName = 'CanvasEntityCopyToClipboard';

View File

@@ -6,16 +6,11 @@ import { CanvasEntityIsLockedToggle } from 'features/controlLayers/components/co
import { useEntityIdentifierContext } from 'features/controlLayers/contexts/EntityIdentifierContext';
import { memo } from 'react';
import { CanvasEntityCopyToClipboard } from './CanvasEntityCopyToClipboard';
import { CanvasEntitySaveToAssets } from './CanvasEntitySaveToAssets';
export const CanvasEntityHeaderCommonActions = memo(() => {
const entityIdentifier = useEntityIdentifierContext();
return (
<Flex alignSelf="stretch">
<CanvasEntitySaveToAssets />
<CanvasEntityCopyToClipboard />
<CanvasEntityIsBookmarkedForQuickSwitchToggle />
{entityIdentifier.type !== 'reference_image' && <CanvasEntityIsLockedToggle />}
<CanvasEntityEnabledToggle />

View File

@@ -7,7 +7,7 @@ import { memo, useCallback } from 'react';
import { useTranslation } from 'react-i18next';
import { PiCopyBold } from 'react-icons/pi';
export const CanvasEntityMenuItemsCopy = memo(() => {
export const CanvasEntityMenuItemsCopyToClipboard = memo(() => {
const { t } = useTranslation();
const entityIdentifier = useEntityIdentifierContext();
const adapter = useEntityAdapterSafe(entityIdentifier);
@@ -25,4 +25,4 @@ export const CanvasEntityMenuItemsCopy = memo(() => {
);
});
CanvasEntityMenuItemsCopy.displayName = 'CanvasEntityMenuItemsCopy';
CanvasEntityMenuItemsCopyToClipboard.displayName = 'CanvasEntityMenuItemsCopyToClipboard';

View File

@@ -384,6 +384,21 @@ export function isTransformableEntityIdentifier(
);
}
export function isSaveableEntityIdentifier(
entityIdentifier: CanvasEntityIdentifier
): entityIdentifier is
| CanvasEntityIdentifier<'raster_layer'>
| CanvasEntityIdentifier<'control_layer'>
| CanvasEntityIdentifier<'inpaint_mask'>
| CanvasEntityIdentifier<'regional_guidance'> {
return (
isRasterLayerEntityIdentifier(entityIdentifier) ||
isControlLayerEntityIdentifier(entityIdentifier) ||
isInpaintMaskEntityIdentifier(entityIdentifier) ||
isRegionalGuidanceEntityIdentifier(entityIdentifier)
);
}
export function isRenderableEntity(entity: CanvasEntityState): entity is CanvasRenderableEntityState {
return isRenderableEntityType(entity.type);
}