mirror of
https://github.com/invoke-ai/InvokeAI.git
synced 2026-02-07 23:25:03 -05:00
feat(ui): add selected entity status to HUD
This commit is contained in:
@@ -1824,7 +1824,16 @@
|
||||
"HUD": {
|
||||
"bbox": "Bbox",
|
||||
"scaledBbox": "Scaled Bbox",
|
||||
"autoSave": "Auto Save"
|
||||
"autoSave": "Auto Save",
|
||||
"entityStatus": {
|
||||
"selectedEntity": "Selected Entity",
|
||||
"filtering": "Filtering",
|
||||
"transforming": "Transforming",
|
||||
"locked": "Locked",
|
||||
"hidden": "Hidden",
|
||||
"disabled": "Disabled",
|
||||
"enabled": "Enabled"
|
||||
}
|
||||
}
|
||||
},
|
||||
"upscaling": {
|
||||
|
||||
@@ -2,26 +2,31 @@ import { Grid } from '@invoke-ai/ui-library';
|
||||
import { CanvasHUDItemAutoSave } from 'features/controlLayers/components/HUD/CanvasHUDItemAutoSave';
|
||||
import { CanvasHUDItemBbox } from 'features/controlLayers/components/HUD/CanvasHUDItemBbox';
|
||||
import { CanvasHUDItemScaledBbox } from 'features/controlLayers/components/HUD/CanvasHUDItemScaledBbox';
|
||||
import { CanvasHUDItemSelectedEntityStatus } from 'features/controlLayers/components/HUD/CanvasHUDItemSelectedEntityStatus';
|
||||
import { CanvasHUDItemSnapToGrid } from 'features/controlLayers/components/HUD/CanvasHUDItemSnapToGrid';
|
||||
import { CanvasManagerProviderGate } from 'features/controlLayers/contexts/CanvasManagerProviderGate';
|
||||
import { memo } from 'react';
|
||||
|
||||
export const CanvasHUD = memo(() => {
|
||||
return (
|
||||
<Grid
|
||||
bg="base.900"
|
||||
borderBottomEndRadius="base"
|
||||
p={2}
|
||||
gap={2}
|
||||
borderRadius="base"
|
||||
templateColumns="1fr 1fr"
|
||||
opacity={0.6}
|
||||
minW={64}
|
||||
>
|
||||
<CanvasHUDItemBbox />
|
||||
<CanvasHUDItemScaledBbox />
|
||||
<CanvasHUDItemSnapToGrid />
|
||||
<CanvasHUDItemAutoSave />
|
||||
</Grid>
|
||||
<CanvasManagerProviderGate>
|
||||
<Grid
|
||||
bg="base.900"
|
||||
borderBottomEndRadius="base"
|
||||
p={2}
|
||||
gap={2}
|
||||
borderRadius="base"
|
||||
templateColumns="1fr 1fr"
|
||||
opacity={0.6}
|
||||
minW={64}
|
||||
>
|
||||
<CanvasHUDItemBbox />
|
||||
<CanvasHUDItemScaledBbox />
|
||||
<CanvasHUDItemSnapToGrid />
|
||||
<CanvasHUDItemAutoSave />
|
||||
<CanvasHUDItemSelectedEntityStatus />
|
||||
</Grid>
|
||||
</CanvasManagerProviderGate>
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
@@ -1,14 +1,23 @@
|
||||
import { GridItem, Text } from '@invoke-ai/ui-library';
|
||||
import type { Property } from 'csstype';
|
||||
import { memo } from 'react';
|
||||
|
||||
export const CanvasHUDItem = memo(({ label, value }: { label: string; value: string | number }) => {
|
||||
type Props = {
|
||||
label: string;
|
||||
value: string | number;
|
||||
color?: Property.Color;
|
||||
};
|
||||
|
||||
export const CanvasHUDItem = memo(({ label, value, color }: Props) => {
|
||||
return (
|
||||
<>
|
||||
<GridItem>
|
||||
<Text textAlign="end">{label}: </Text>
|
||||
</GridItem>
|
||||
<GridItem fontWeight="semibold">
|
||||
<Text textAlign="end">{value}</Text>
|
||||
<Text textAlign="end" color={color}>
|
||||
{value}
|
||||
</Text>
|
||||
</GridItem>
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -0,0 +1,110 @@
|
||||
import { useStore } from '@nanostores/react';
|
||||
import { createSelector } from '@reduxjs/toolkit';
|
||||
import { useAppSelector } from 'app/store/storeHooks';
|
||||
import type { Property } from 'csstype';
|
||||
import { CanvasHUDItem } from 'features/controlLayers/components/HUD/CanvasHUDItem';
|
||||
import { useEntityAdapter } from 'features/controlLayers/hooks/useEntityAdapter';
|
||||
import { useEntityTypeIsHidden } from 'features/controlLayers/hooks/useEntityTypeIsHidden';
|
||||
import {
|
||||
selectCanvasSlice,
|
||||
selectEntityOrThrow,
|
||||
selectSelectedEntityIdentifier,
|
||||
} from 'features/controlLayers/store/selectors';
|
||||
import type { CanvasEntityIdentifier } from 'features/controlLayers/store/types';
|
||||
import { atom } from 'nanostores';
|
||||
import { memo, useMemo } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
type ContentProps = {
|
||||
entityIdentifier: CanvasEntityIdentifier;
|
||||
};
|
||||
|
||||
const $isFilteringFallback = atom(false);
|
||||
|
||||
type EntityStatus = {
|
||||
value: string;
|
||||
color?: Property.Color;
|
||||
};
|
||||
|
||||
const CanvasHUDItemSelectedEntityStatusContent = memo(({ entityIdentifier }: ContentProps) => {
|
||||
const { t } = useTranslation();
|
||||
const adapter = useEntityAdapter(entityIdentifier);
|
||||
const selectIsEnabled = useMemo(
|
||||
() => createSelector(selectCanvasSlice, (canvas) => selectEntityOrThrow(canvas, entityIdentifier).isEnabled),
|
||||
[entityIdentifier]
|
||||
);
|
||||
const selectIsLocked = useMemo(
|
||||
() => createSelector(selectCanvasSlice, (canvas) => selectEntityOrThrow(canvas, entityIdentifier).isLocked),
|
||||
[entityIdentifier]
|
||||
);
|
||||
const isEnabled = useAppSelector(selectIsEnabled);
|
||||
const isLocked = useAppSelector(selectIsLocked);
|
||||
const isHidden = useEntityTypeIsHidden(entityIdentifier.type);
|
||||
const isFiltering = useStore(adapter.filterer?.$isFiltering ?? $isFilteringFallback);
|
||||
const isTransforming = useStore(adapter.transformer.$isTransforming);
|
||||
|
||||
const status = useMemo<EntityStatus>(() => {
|
||||
if (isFiltering) {
|
||||
return {
|
||||
value: t('controlLayers.HUD.entityStatus.filtering'),
|
||||
color: 'invokeYellow.300',
|
||||
};
|
||||
}
|
||||
|
||||
if (isTransforming) {
|
||||
return {
|
||||
value: t('controlLayers.HUD.entityStatus.transforming'),
|
||||
color: 'invokeYellow.300',
|
||||
};
|
||||
}
|
||||
|
||||
if (isHidden) {
|
||||
return {
|
||||
value: t('controlLayers.HUD.entityStatus.hidden'),
|
||||
color: 'invokePurple.300',
|
||||
};
|
||||
}
|
||||
|
||||
if (isLocked) {
|
||||
return {
|
||||
value: t('controlLayers.HUD.entityStatus.locked'),
|
||||
color: 'invokeRed.300',
|
||||
};
|
||||
}
|
||||
|
||||
if (!isEnabled) {
|
||||
return {
|
||||
value: t('controlLayers.HUD.entityStatus.disabled'),
|
||||
color: 'invokeRed.300',
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
value: t('controlLayers.HUD.entityStatus.enabled'),
|
||||
};
|
||||
}, [isFiltering, isTransforming, isHidden, isLocked, isEnabled, t]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<CanvasHUDItem
|
||||
label={t('controlLayers.HUD.entityStatus.selectedEntity')}
|
||||
value={status.value}
|
||||
color={status.color}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
});
|
||||
|
||||
CanvasHUDItemSelectedEntityStatusContent.displayName = 'CanvasHUDItemSelectedEntityStatusContent';
|
||||
|
||||
export const CanvasHUDItemSelectedEntityStatus = memo(() => {
|
||||
const selectedEntityIdentifier = useAppSelector(selectSelectedEntityIdentifier);
|
||||
|
||||
if (!selectedEntityIdentifier) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return <CanvasHUDItemSelectedEntityStatusContent entityIdentifier={selectedEntityIdentifier} />;
|
||||
});
|
||||
|
||||
CanvasHUDItemSelectedEntityStatus.displayName = 'CanvasHUDItemSelectedEntityStatus';
|
||||
Reference in New Issue
Block a user