mirror of
https://github.com/invoke-ai/InvokeAI
synced 2024-08-30 20:32:17 +00:00
feat(ui): add + buttons to entity categories
This commit is contained in:
parent
0098c33f81
commit
085cc82926
@ -1684,27 +1684,34 @@
|
|||||||
"addPositivePrompt": "Add $t(common.positivePrompt)",
|
"addPositivePrompt": "Add $t(common.positivePrompt)",
|
||||||
"addNegativePrompt": "Add $t(common.negativePrompt)",
|
"addNegativePrompt": "Add $t(common.negativePrompt)",
|
||||||
"addIPAdapter": "Add $t(common.ipAdapter)",
|
"addIPAdapter": "Add $t(common.ipAdapter)",
|
||||||
|
"addRasterLayer": "Add $t(controlLayers.rasterLayer)",
|
||||||
|
"addControlLayer": "Add $t(controlLayers.controlLayer)",
|
||||||
|
"addInpaintMask": "Add $t(controlLayers.inpaintMask)",
|
||||||
|
"addRegionalGuidance": "Add $t(controlLayers.regionalGuidance)",
|
||||||
"regionalGuidanceLayer": "$t(controlLayers.regionalGuidance) $t(unifiedCanvas.layer)",
|
"regionalGuidanceLayer": "$t(controlLayers.regionalGuidance) $t(unifiedCanvas.layer)",
|
||||||
"raster": "Raster",
|
"raster": "Raster",
|
||||||
"rasterLayer_one": "Raster Layer",
|
"rasterLayer": "Raster Layer",
|
||||||
"controlLayer_one": "Control Layer",
|
"controlLayer": "Control Layer",
|
||||||
"inpaintMask_one": "Inpaint Mask",
|
"inpaintMask": "Inpaint Mask",
|
||||||
"regionalGuidance_one": "Regional Guidance",
|
"regionalGuidance": "Regional Guidance",
|
||||||
"ipAdapter_one": "IP Adapter",
|
"ipAdapter": "IP Adapter",
|
||||||
"rasterLayer_other": "Raster Layers",
|
"rasterLayer_withCount_one": "$t(controlLayers.rasterLayer)",
|
||||||
"controlLayer_other": "Control Layers",
|
"controlLayer_withCount_one": "$t(controlLayers.controlLayer)",
|
||||||
"inpaintMask_other": "Inpaint Masks",
|
"inpaintMask_withCount_one": "$t(controlLayers.inpaintMask)",
|
||||||
"regionalGuidance_other": "Regional Guidance",
|
"regionalGuidance_withCount_one": "$t(controlLayers.regionalGuidance)",
|
||||||
"ipAdapter_other": "IP Adapters",
|
"ipAdapter_withCount_one": "$t(controlLayers.ipAdapter)",
|
||||||
|
"rasterLayer_withCount_other": "Raster Layers",
|
||||||
|
"controlLayer_withCount_other": "Control Layers",
|
||||||
|
"inpaintMask_withCount_other": "Inpaint Masks",
|
||||||
|
"regionalGuidance_withCount_other": "Regional Guidance",
|
||||||
|
"ipAdapter_withCount_other": "IP Adapters",
|
||||||
"opacity": "Opacity",
|
"opacity": "Opacity",
|
||||||
"regionalGuidance_withCount_hidden": "Regional Guidance ({{count}} hidden)",
|
"regionalGuidance_withCount_hidden": "Regional Guidance ({{count}} hidden)",
|
||||||
"controlAdapters_withCount_hidden": "Control Adapters ({{count}} hidden)",
|
|
||||||
"controlLayers_withCount_hidden": "Control Layers ({{count}} hidden)",
|
"controlLayers_withCount_hidden": "Control Layers ({{count}} hidden)",
|
||||||
"rasterLayers_withCount_hidden": "Raster Layers ({{count}} hidden)",
|
"rasterLayers_withCount_hidden": "Raster Layers ({{count}} hidden)",
|
||||||
"ipAdapters_withCount_hidden": "IP Adapters ({{count}} hidden)",
|
"ipAdapters_withCount_hidden": "IP Adapters ({{count}} hidden)",
|
||||||
"inpaintMasks_withCount_hidden": "Inpaint Masks ({{count}} hidden)",
|
"inpaintMasks_withCount_hidden": "Inpaint Masks ({{count}} hidden)",
|
||||||
"regionalGuidance_withCount_visible": "Regional Guidance ({{count}})",
|
"regionalGuidance_withCount_visible": "Regional Guidance ({{count}})",
|
||||||
"controlAdapters_withCount_visible": "Control Adapters ({{count}})",
|
|
||||||
"controlLayers_withCount_visible": "Control Layers ({{count}})",
|
"controlLayers_withCount_visible": "Control Layers ({{count}})",
|
||||||
"rasterLayers_withCount_visible": "Raster Layers ({{count}})",
|
"rasterLayers_withCount_visible": "Raster Layers ({{count}})",
|
||||||
"ipAdapters_withCount_visible": "IP Adapters ({{count}})",
|
"ipAdapters_withCount_visible": "IP Adapters ({{count}})",
|
||||||
|
@ -34,19 +34,19 @@ export const CanvasAddEntityButtons = memo(() => {
|
|||||||
<Flex flexDir="column" w="full" h="full" alignItems="center" justifyContent="center">
|
<Flex flexDir="column" w="full" h="full" alignItems="center" justifyContent="center">
|
||||||
<ButtonGroup orientation="vertical" isAttached={false}>
|
<ButtonGroup orientation="vertical" isAttached={false}>
|
||||||
<Button variant="ghost" justifyContent="flex-start" leftIcon={<PiPlusBold />} onClick={addInpaintMask}>
|
<Button variant="ghost" justifyContent="flex-start" leftIcon={<PiPlusBold />} onClick={addInpaintMask}>
|
||||||
{t('controlLayers.inpaintMask', { count: 1 })}
|
{t('controlLayers.inpaintMask')}
|
||||||
</Button>
|
</Button>
|
||||||
<Button variant="ghost" justifyContent="flex-start" leftIcon={<PiPlusBold />} onClick={addRegionalGuidance}>
|
<Button variant="ghost" justifyContent="flex-start" leftIcon={<PiPlusBold />} onClick={addRegionalGuidance}>
|
||||||
{t('controlLayers.regionalGuidance', { count: 1 })}
|
{t('controlLayers.regionalGuidance')}
|
||||||
</Button>
|
</Button>
|
||||||
<Button variant="ghost" justifyContent="flex-start" leftIcon={<PiPlusBold />} onClick={addRasterLayer}>
|
<Button variant="ghost" justifyContent="flex-start" leftIcon={<PiPlusBold />} onClick={addRasterLayer}>
|
||||||
{t('controlLayers.rasterLayer', { count: 1 })}
|
{t('controlLayers.rasterLayer')}
|
||||||
</Button>
|
</Button>
|
||||||
<Button variant="ghost" justifyContent="flex-start" leftIcon={<PiPlusBold />} onClick={addControlLayer}>
|
<Button variant="ghost" justifyContent="flex-start" leftIcon={<PiPlusBold />} onClick={addControlLayer}>
|
||||||
{t('controlLayers.controlLayer', { count: 1 })}
|
{t('controlLayers.controlLayer')}
|
||||||
</Button>
|
</Button>
|
||||||
<Button variant="ghost" justifyContent="flex-start" leftIcon={<PiPlusBold />} onClick={addIPAdapter}>
|
<Button variant="ghost" justifyContent="flex-start" leftIcon={<PiPlusBold />} onClick={addIPAdapter}>
|
||||||
{t('controlLayers.ipAdapter', { count: 1 })}
|
{t('controlLayers.ipAdapter')}
|
||||||
</Button>
|
</Button>
|
||||||
</ButtonGroup>
|
</ButtonGroup>
|
||||||
</Flex>
|
</Flex>
|
||||||
|
@ -33,19 +33,19 @@ export const CanvasEntityListMenuItems = memo(() => {
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<MenuItem icon={<PiPlusBold />} onClick={addInpaintMask}>
|
<MenuItem icon={<PiPlusBold />} onClick={addInpaintMask}>
|
||||||
{t('controlLayers.inpaintMask', { count: 1 })}
|
{t('controlLayers.inpaintMask')}
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
<MenuItem icon={<PiPlusBold />} onClick={addRegionalGuidance}>
|
<MenuItem icon={<PiPlusBold />} onClick={addRegionalGuidance}>
|
||||||
{t('controlLayers.regionalGuidance', { count: 1 })}
|
{t('controlLayers.regionalGuidance')}
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
<MenuItem icon={<PiPlusBold />} onClick={addRasterLayer}>
|
<MenuItem icon={<PiPlusBold />} onClick={addRasterLayer}>
|
||||||
{t('controlLayers.rasterLayer', { count: 1 })}
|
{t('controlLayers.rasterLayer')}
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
<MenuItem icon={<PiPlusBold />} onClick={addControlLayer}>
|
<MenuItem icon={<PiPlusBold />} onClick={addControlLayer}>
|
||||||
{t('controlLayers.controlLayer', { count: 1 })}
|
{t('controlLayers.controlLayer')}
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
<MenuItem icon={<PiPlusBold />} onClick={addIPAdapter}>
|
<MenuItem icon={<PiPlusBold />} onClick={addIPAdapter}>
|
||||||
{t('controlLayers.ipAdapter', { count: 1 })}
|
{t('controlLayers.ipAdapter')}
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
@ -0,0 +1,70 @@
|
|||||||
|
import { IconButton } from '@invoke-ai/ui-library';
|
||||||
|
import { useAppDispatch } from 'app/store/storeHooks';
|
||||||
|
import {
|
||||||
|
controlLayerAdded,
|
||||||
|
inpaintMaskAdded,
|
||||||
|
ipaAdded,
|
||||||
|
rasterLayerAdded,
|
||||||
|
rgAdded,
|
||||||
|
} from 'features/controlLayers/store/canvasSlice';
|
||||||
|
import type { CanvasEntityIdentifier } from 'features/controlLayers/store/types';
|
||||||
|
import { memo, useCallback, useMemo } from 'react';
|
||||||
|
import { useTranslation } from 'react-i18next';
|
||||||
|
import { PiPlusBold } from 'react-icons/pi';
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
type: CanvasEntityIdentifier['type'];
|
||||||
|
};
|
||||||
|
|
||||||
|
export const CanvasEntityAddOfTypeButton = memo(({ type }: Props) => {
|
||||||
|
const { t } = useTranslation();
|
||||||
|
const dispatch = useAppDispatch();
|
||||||
|
const onClick = useCallback(() => {
|
||||||
|
switch (type) {
|
||||||
|
case 'inpaint_mask':
|
||||||
|
dispatch(inpaintMaskAdded({ isSelected: true }));
|
||||||
|
break;
|
||||||
|
case 'regional_guidance':
|
||||||
|
dispatch(rgAdded({ isSelected: true }));
|
||||||
|
break;
|
||||||
|
case 'raster_layer':
|
||||||
|
dispatch(rasterLayerAdded({ isSelected: true }));
|
||||||
|
break;
|
||||||
|
case 'control_layer':
|
||||||
|
dispatch(controlLayerAdded({ isSelected: true }));
|
||||||
|
break;
|
||||||
|
case 'ip_adapter':
|
||||||
|
dispatch(ipaAdded({ isSelected: true }));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}, [dispatch, type]);
|
||||||
|
|
||||||
|
const label = useMemo(() => {
|
||||||
|
switch (type) {
|
||||||
|
case 'inpaint_mask':
|
||||||
|
return t('controlLayers.addInpaintMask');
|
||||||
|
case 'regional_guidance':
|
||||||
|
return t('controlLayers.addRegionalGuidance');
|
||||||
|
case 'raster_layer':
|
||||||
|
return t('controlLayers.addRasterLayer');
|
||||||
|
case 'control_layer':
|
||||||
|
return t('controlLayers.addControlLayer');
|
||||||
|
case 'ip_adapter':
|
||||||
|
return t('controlLayers.addIPAdapter');
|
||||||
|
}
|
||||||
|
}, [type, t]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<IconButton
|
||||||
|
size="sm"
|
||||||
|
aria-label={label}
|
||||||
|
tooltip={label}
|
||||||
|
variant="link"
|
||||||
|
icon={<PiPlusBold />}
|
||||||
|
onClick={onClick}
|
||||||
|
alignSelf="stretch"
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
CanvasEntityAddOfTypeButton.displayName = 'CanvasEntityAddOfTypeButton';
|
@ -1,6 +1,7 @@
|
|||||||
import type { SystemStyleObject } from '@invoke-ai/ui-library';
|
import type { SystemStyleObject } from '@invoke-ai/ui-library';
|
||||||
import { Button, Collapse, Flex, Icon, Spacer, Text } from '@invoke-ai/ui-library';
|
import { Button, Collapse, Flex, Icon, Spacer, Text } from '@invoke-ai/ui-library';
|
||||||
import { useBoolean } from 'common/hooks/useBoolean';
|
import { useBoolean } from 'common/hooks/useBoolean';
|
||||||
|
import { CanvasEntityAddOfTypeButton } from 'features/controlLayers/components/common/CanvasEntityAddOfTypeButton';
|
||||||
import { CanvasEntityTypeIsHiddenToggle } from 'features/controlLayers/components/common/CanvasEntityTypeIsHiddenToggle';
|
import { CanvasEntityTypeIsHiddenToggle } from 'features/controlLayers/components/common/CanvasEntityTypeIsHiddenToggle';
|
||||||
import { useEntityTypeTitle } from 'features/controlLayers/hooks/useEntityTypeTitle';
|
import { useEntityTypeTitle } from 'features/controlLayers/hooks/useEntityTypeTitle';
|
||||||
import type { CanvasEntityIdentifier } from 'features/controlLayers/store/types';
|
import type { CanvasEntityIdentifier } from 'features/controlLayers/store/types';
|
||||||
@ -53,6 +54,7 @@ export const CanvasEntityGroupList = memo(({ isSelected, type, children }: Props
|
|||||||
</Text>
|
</Text>
|
||||||
<Spacer />
|
<Spacer />
|
||||||
</Flex>
|
</Flex>
|
||||||
|
<CanvasEntityAddOfTypeButton type={type} />
|
||||||
{type !== 'ip_adapter' && <CanvasEntityTypeIsHiddenToggle type={type} />}
|
{type !== 'ip_adapter' && <CanvasEntityTypeIsHiddenToggle type={type} />}
|
||||||
</Flex>
|
</Flex>
|
||||||
<Collapse in={collapse.isTrue}>
|
<Collapse in={collapse.isTrue}>
|
||||||
|
@ -29,15 +29,15 @@ export const useEntityTitle = (entityIdentifier: CanvasEntityIdentifier) => {
|
|||||||
|
|
||||||
const parts: string[] = [];
|
const parts: string[] = [];
|
||||||
if (entityIdentifier.type === 'inpaint_mask') {
|
if (entityIdentifier.type === 'inpaint_mask') {
|
||||||
parts.push(t('controlLayers.inpaintMask', { count: 1 }));
|
parts.push(t('controlLayers.inpaintMask'));
|
||||||
} else if (entityIdentifier.type === 'control_layer') {
|
} else if (entityIdentifier.type === 'control_layer') {
|
||||||
parts.push(t('controlLayers.controlLayer', { count: 1 }));
|
parts.push(t('controlLayers.controlLayer'));
|
||||||
} else if (entityIdentifier.type === 'raster_layer') {
|
} else if (entityIdentifier.type === 'raster_layer') {
|
||||||
parts.push(t('controlLayers.rasterLayer', { count: 1 }));
|
parts.push(t('controlLayers.rasterLayer'));
|
||||||
} else if (entityIdentifier.type === 'ip_adapter') {
|
} else if (entityIdentifier.type === 'ip_adapter') {
|
||||||
parts.push(t('common.ipAdapter', { count: 1 }));
|
parts.push(t('common.ipAdapter'));
|
||||||
} else if (entityIdentifier.type === 'regional_guidance') {
|
} else if (entityIdentifier.type === 'regional_guidance') {
|
||||||
parts.push(t('controlLayers.regionalGuidance', { count: 1 }));
|
parts.push(t('controlLayers.regionalGuidance'));
|
||||||
} else {
|
} else {
|
||||||
assert(false, 'Unexpected entity type');
|
assert(false, 'Unexpected entity type');
|
||||||
}
|
}
|
||||||
|
@ -8,15 +8,15 @@ export const useEntityTypeString = (type: CanvasEntityIdentifier['type']): strin
|
|||||||
const typeString = useMemo(() => {
|
const typeString = useMemo(() => {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case 'control_layer':
|
case 'control_layer':
|
||||||
return t('controlLayers.controlLayer', { count: 0 });
|
return t('controlLayers.controlLayer');
|
||||||
case 'raster_layer':
|
case 'raster_layer':
|
||||||
return t('controlLayers.rasterLayer', { count: 0 });
|
return t('controlLayers.rasterLayer');
|
||||||
case 'inpaint_mask':
|
case 'inpaint_mask':
|
||||||
return t('controlLayers.inpaintMask', { count: 0 });
|
return t('controlLayers.inpaintMask');
|
||||||
case 'regional_guidance':
|
case 'regional_guidance':
|
||||||
return t('controlLayers.regionalGuidance', { count: 0 });
|
return t('controlLayers.regionalGuidance');
|
||||||
case 'ip_adapter':
|
case 'ip_adapter':
|
||||||
return t('controlLayers.ipAdapter', { count: 0 });
|
return t('controlLayers.ipAdapter');
|
||||||
default:
|
default:
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user