mirror of
https://github.com/invoke-ai/InvokeAI.git
synced 2026-04-23 03:00:31 -04:00
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:
committed by
psychedelicious
parent
fd2da6446a
commit
0303ebad50
@@ -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>
|
||||
);
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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';
|
||||
@@ -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 />
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -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 />
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -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 />
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -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 />
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -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';
|
||||
@@ -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 />
|
||||
|
||||
@@ -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';
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user