diff --git a/invokeai/frontend/web/public/locales/en.json b/invokeai/frontend/web/public/locales/en.json index cf1b9aedef..726ce2e008 100644 --- a/invokeai/frontend/web/public/locales/en.json +++ b/invokeai/frontend/web/public/locales/en.json @@ -1682,6 +1682,8 @@ "controlLayer": "Control Layer", "inpaintMask": "Inpaint Mask", "regionalGuidance": "Regional Guidance", + "canvasAsRasterLayer": "$t(controlLayers.canvas) as $t(controlLayers.rasterLayer)", + "canvasAsControlLayer": "$t(controlLayers.canvas) as $t(controlLayers.controlLayer)", "referenceImage": "Reference Image", "regionalReferenceImage": "Regional Reference Image", "globalReferenceImage": "Global Reference Image", @@ -1894,6 +1896,7 @@ "include": "Include", "exclude": "Exclude", "neutral": "Neutral", + "apply": "Apply", "reset": "Reset", "saveAs": "Save As", "cancel": "Cancel", diff --git a/invokeai/frontend/web/src/features/controlLayers/components/CanvasAlerts/CanvasAlertsPreserveMask.tsx b/invokeai/frontend/web/src/features/controlLayers/components/CanvasAlerts/CanvasAlertsPreserveMask.tsx index bdfeabd1c7..7178c3d123 100644 --- a/invokeai/frontend/web/src/features/controlLayers/components/CanvasAlerts/CanvasAlertsPreserveMask.tsx +++ b/invokeai/frontend/web/src/features/controlLayers/components/CanvasAlerts/CanvasAlertsPreserveMask.tsx @@ -13,7 +13,7 @@ export const CanvasAlertsPreserveMask = memo(() => { } return ( - + {t('controlLayers.settings.preserveMask.alert')} diff --git a/invokeai/frontend/web/src/features/controlLayers/components/CanvasAlerts/CanvasAlertsSelectedEntityStatus.tsx b/invokeai/frontend/web/src/features/controlLayers/components/CanvasAlerts/CanvasAlertsSelectedEntityStatus.tsx index 6ba087af8e..47bbf36ebd 100644 --- a/invokeai/frontend/web/src/features/controlLayers/components/CanvasAlerts/CanvasAlertsSelectedEntityStatus.tsx +++ b/invokeai/frontend/web/src/features/controlLayers/components/CanvasAlerts/CanvasAlertsSelectedEntityStatus.tsx @@ -98,7 +98,7 @@ const CanvasAlertsSelectedEntityStatusContent = memo(({ entityIdentifier, adapte } return ( - + {alert.title} diff --git a/invokeai/frontend/web/src/features/controlLayers/components/CanvasAlerts/CanvasAlertsSendingTo.tsx b/invokeai/frontend/web/src/features/controlLayers/components/CanvasAlerts/CanvasAlertsSendingTo.tsx index 16791ee7e6..96d388c70a 100644 --- a/invokeai/frontend/web/src/features/controlLayers/components/CanvasAlerts/CanvasAlertsSendingTo.tsx +++ b/invokeai/frontend/web/src/features/controlLayers/components/CanvasAlerts/CanvasAlertsSendingTo.tsx @@ -132,7 +132,6 @@ const AlertWrapper = ({ fontSize="sm" shadow="md" w="fit-content" - alignSelf="flex-end" > diff --git a/invokeai/frontend/web/src/features/controlLayers/components/CanvasContextMenu/CanvasContextMenuSelectedEntityMenuItems.tsx b/invokeai/frontend/web/src/features/controlLayers/components/CanvasContextMenu/CanvasContextMenuSelectedEntityMenuItems.tsx index 6f70f5b799..57dac5cbb5 100644 --- a/invokeai/frontend/web/src/features/controlLayers/components/CanvasContextMenu/CanvasContextMenuSelectedEntityMenuItems.tsx +++ b/invokeai/frontend/web/src/features/controlLayers/components/CanvasContextMenu/CanvasContextMenuSelectedEntityMenuItems.tsx @@ -1,3 +1,4 @@ +import { MenuGroup } from '@invoke-ai/ui-library'; import { useAppSelector } from 'app/store/storeHooks'; import { ControlLayerMenuItems } from 'features/controlLayers/components/ControlLayer/ControlLayerMenuItems'; import { InpaintMaskMenuItems } from 'features/controlLayers/components/InpaintMask/InpaintMaskMenuItems'; @@ -8,7 +9,9 @@ import { EntityIdentifierContext, useEntityIdentifierContext, } from 'features/controlLayers/contexts/EntityIdentifierContext'; +import { useEntityTypeString } from 'features/controlLayers/hooks/useEntityTypeString'; import { selectSelectedEntityIdentifier } from 'features/controlLayers/store/selectors'; +import type { PropsWithChildren } from 'react'; import { memo } from 'react'; import type { Equals } from 'tsafe'; import { assert } from 'tsafe'; @@ -46,9 +49,20 @@ export const CanvasContextMenuSelectedEntityMenuItems = memo(() => { return ( - + + + ); }); CanvasContextMenuSelectedEntityMenuItems.displayName = 'CanvasContextMenuSelectedEntityMenuItems'; + +const CanvasContextMenuSelectedEntityMenuGroup = memo((props: PropsWithChildren) => { + const entityIdentifier = useEntityIdentifierContext(); + const title = useEntityTypeString(entityIdentifier.type); + + return {props.children}; +}); + +CanvasContextMenuSelectedEntityMenuGroup.displayName = 'CanvasContextMenuSelectedEntityMenuGroup'; diff --git a/invokeai/frontend/web/src/features/controlLayers/components/CanvasMainPanelContent.tsx b/invokeai/frontend/web/src/features/controlLayers/components/CanvasMainPanelContent.tsx index 1e8dccfd39..b66c0d8367 100644 --- a/invokeai/frontend/web/src/features/controlLayers/components/CanvasMainPanelContent.tsx +++ b/invokeai/frontend/web/src/features/controlLayers/components/CanvasMainPanelContent.tsx @@ -71,12 +71,16 @@ export const CanvasMainPanelContent = memo(() => { > - {showHUD && ( - - - - )} - + + {showHUD && } diff --git a/invokeai/frontend/web/src/features/controlLayers/components/ControlLayer/ControlLayerMenuItems.tsx b/invokeai/frontend/web/src/features/controlLayers/components/ControlLayer/ControlLayerMenuItems.tsx index ab77f238bc..e7e5a45d71 100644 --- a/invokeai/frontend/web/src/features/controlLayers/components/ControlLayer/ControlLayerMenuItems.tsx +++ b/invokeai/frontend/web/src/features/controlLayers/components/ControlLayer/ControlLayerMenuItems.tsx @@ -27,11 +27,10 @@ export const ControlLayerMenuItems = memo(() => { + + - - - ); }); diff --git a/invokeai/frontend/web/src/features/controlLayers/components/Filters/Filter.tsx b/invokeai/frontend/web/src/features/controlLayers/components/Filters/Filter.tsx index 4143b113ca..6aace17412 100644 --- a/invokeai/frontend/web/src/features/controlLayers/components/Filters/Filter.tsx +++ b/invokeai/frontend/web/src/features/controlLayers/components/Filters/Filter.tsx @@ -8,6 +8,7 @@ import { MenuItem, MenuList, Spacer, + Spinner, } from '@invoke-ai/ui-library'; import { useStore } from '@nanostores/react'; import { useAppSelector } from 'app/store/storeHooks'; @@ -25,7 +26,7 @@ import { IMAGE_FILTERS } from 'features/controlLayers/store/filters'; import { useRegisteredHotkeys } from 'features/system/components/HotkeysModal/useHotkeyData'; import { memo, useCallback, useMemo, useRef } from 'react'; import { useTranslation } from 'react-i18next'; -import { PiArrowsCounterClockwiseBold, PiFloppyDiskBold, PiPlayFill, PiXBold } from 'react-icons/pi'; +import { PiCaretDownBold } from 'react-icons/pi'; const FilterContent = memo( ({ adapter }: { adapter: CanvasEntityAdapterRasterLayer | CanvasEntityAdapterControlLayer }) => { @@ -115,39 +116,41 @@ const FilterContent = memo( + } - isLoading={isProcessing} loadingText={t('controlLayers.selectObject.saveAs')} variant="ghost" - isDisabled={!isValid || !hasProcessed} + isDisabled={isProcessing || !isValid || !hasProcessed} + rightIcon={} > {t('controlLayers.selectObject.saveAs')} - - {t('controlLayers.replaceCurrent')} - {t('controlLayers.newInpaintMask')} @@ -162,12 +165,7 @@ const FilterContent = memo( - diff --git a/invokeai/frontend/web/src/features/controlLayers/components/InpaintMask/InpaintMaskMenuItems.tsx b/invokeai/frontend/web/src/features/controlLayers/components/InpaintMask/InpaintMaskMenuItems.tsx index d8dc481d72..0e0005df80 100644 --- a/invokeai/frontend/web/src/features/controlLayers/components/InpaintMask/InpaintMaskMenuItems.tsx +++ b/invokeai/frontend/web/src/features/controlLayers/components/InpaintMask/InpaintMaskMenuItems.tsx @@ -20,10 +20,9 @@ export const InpaintMaskMenuItems = memo(() => { - - - + + ); }); diff --git a/invokeai/frontend/web/src/features/controlLayers/components/RasterLayer/RasterLayerMenuItems.tsx b/invokeai/frontend/web/src/features/controlLayers/components/RasterLayer/RasterLayerMenuItems.tsx index 212720e064..30a96866f4 100644 --- a/invokeai/frontend/web/src/features/controlLayers/components/RasterLayer/RasterLayerMenuItems.tsx +++ b/invokeai/frontend/web/src/features/controlLayers/components/RasterLayer/RasterLayerMenuItems.tsx @@ -25,11 +25,10 @@ export const RasterLayerMenuItems = memo(() => { + + - - - ); }); diff --git a/invokeai/frontend/web/src/features/controlLayers/components/RegionalGuidance/RegionalGuidanceMenuItems.tsx b/invokeai/frontend/web/src/features/controlLayers/components/RegionalGuidance/RegionalGuidanceMenuItems.tsx index 745730a420..79b3f6dffe 100644 --- a/invokeai/frontend/web/src/features/controlLayers/components/RegionalGuidance/RegionalGuidanceMenuItems.tsx +++ b/invokeai/frontend/web/src/features/controlLayers/components/RegionalGuidance/RegionalGuidanceMenuItems.tsx @@ -25,10 +25,9 @@ export const RegionalGuidanceMenuItems = memo(() => { - - - + + ); }); diff --git a/invokeai/frontend/web/src/features/controlLayers/components/SelectObject/SelectObject.tsx b/invokeai/frontend/web/src/features/controlLayers/components/SelectObject/SelectObject.tsx index 72be4daccf..5fb3cc7dca 100644 --- a/invokeai/frontend/web/src/features/controlLayers/components/SelectObject/SelectObject.tsx +++ b/invokeai/frontend/web/src/features/controlLayers/components/SelectObject/SelectObject.tsx @@ -10,6 +10,7 @@ import { MenuItem, MenuList, Spacer, + Spinner, Text, Tooltip, UnorderedList, @@ -29,7 +30,7 @@ import { useRegisteredHotkeys } from 'features/system/components/HotkeysModal/us import type { PropsWithChildren } from 'react'; import { memo, useCallback, useRef } from 'react'; import { Trans, useTranslation } from 'react-i18next'; -import { PiArrowsCounterClockwiseBold, PiFloppyDiskBold, PiInfoBold, PiPlayFill, PiXBold } from 'react-icons/pi'; +import { PiCaretDownBold, PiInfoBold } from 'react-icons/pi'; const SelectObjectContent = memo( ({ adapter }: { adapter: CanvasEntityAdapterRasterLayer | CanvasEntityAdapterControlLayer }) => { @@ -42,10 +43,6 @@ const SelectObjectContent = memo( const hasImageState = useStore(adapter.segmentAnything.$hasImageState); const autoProcess = useAppSelector(selectAutoProcess); - const replaceCurrent = useCallback(() => { - adapter.segmentAnything.apply(); - }, [adapter.segmentAnything]); - const saveAsInpaintMask = useCallback(() => { adapter.segmentAnything.saveAs('inpaint_mask'); }, [adapter.segmentAnything]); @@ -115,58 +112,59 @@ const SelectObjectContent = memo( + } - isLoading={isProcessing} loadingText={t('controlLayers.selectObject.saveAs')} variant="ghost" - isDisabled={!hasImageState} + isDisabled={isProcessing || !hasImageState} + rightIcon={} > {t('controlLayers.selectObject.saveAs')} - - {t('controlLayers.replaceCurrent')} - - + {t('controlLayers.newInpaintMask')} - + {t('controlLayers.newRegionalGuidance')} - + {t('controlLayers.newControlLayer')} - + {t('controlLayers.newRasterLayer')}