mirror of
https://github.com/invoke-ai/InvokeAI
synced 2024-08-30 20:32:17 +00:00
feat(ui): rp ui styling/layout
This commit is contained in:
parent
ea527f5fe1
commit
9276ecfd02
@ -1516,11 +1516,12 @@
|
|||||||
"moveForward": "Move Forward",
|
"moveForward": "Move Forward",
|
||||||
"moveBackward": "Move Backward",
|
"moveBackward": "Move Backward",
|
||||||
"brushSize": "Brush Size",
|
"brushSize": "Brush Size",
|
||||||
"regionalPrompts": "Regional Prompts",
|
"regionalPrompts": "Regional Prompts BETA",
|
||||||
"enableRegionalPrompts": "Enable $t(regionalPrompts.regionalPrompts)",
|
"enableRegionalPrompts": "Enable $t(regionalPrompts.regionalPrompts)",
|
||||||
"layerOpacity": "Layer Opacity",
|
"layerOpacity": "Layer Opacity",
|
||||||
"autoNegative": "Auto Negative",
|
"autoNegative": "Auto Negative",
|
||||||
"toggleVisibility": "Toggle Layer Visibility",
|
"toggleVisibility": "Toggle Layer Visibility",
|
||||||
"resetRegion": "Reset Region"
|
"resetRegion": "Reset Region",
|
||||||
|
"debugLayers": "Debug Layers"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,23 @@
|
|||||||
|
import { IconButton } from '@invoke-ai/ui-library';
|
||||||
|
import { getRegionalPromptLayerBlobs } from 'features/regionalPrompts/util/getLayerBlobs';
|
||||||
|
import { memo } from 'react';
|
||||||
|
import { useTranslation } from 'react-i18next';
|
||||||
|
import { PiBugBold } from 'react-icons/pi';
|
||||||
|
|
||||||
|
const debugBlobs = () => {
|
||||||
|
getRegionalPromptLayerBlobs(undefined, true);
|
||||||
|
};
|
||||||
|
export const DebugLayersButton = memo(() => {
|
||||||
|
const { t } = useTranslation();
|
||||||
|
return (
|
||||||
|
<IconButton
|
||||||
|
colorScheme="warning"
|
||||||
|
aria-label={t('regionalPrompts.debugLayers')}
|
||||||
|
tooltip={t('regionalPrompts.debugLayers')}
|
||||||
|
icon={<PiBugBold />}
|
||||||
|
onClick={debugBlobs}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
DebugLayersButton.displayName = 'DebugLayersButton';
|
@ -1,10 +1,11 @@
|
|||||||
/* eslint-disable i18next/no-literal-string */
|
/* eslint-disable i18next/no-literal-string */
|
||||||
import { Button, ButtonGroup, Flex } from '@invoke-ai/ui-library';
|
import { Flex, Spacer } from '@invoke-ai/ui-library';
|
||||||
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
|
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
|
||||||
import { useAppSelector } from 'app/store/storeHooks';
|
import { useAppSelector } from 'app/store/storeHooks';
|
||||||
import ScrollableContent from 'common/components/OverlayScrollbars/ScrollableContent';
|
import ScrollableContent from 'common/components/OverlayScrollbars/ScrollableContent';
|
||||||
import { AddLayerButton } from 'features/regionalPrompts/components/AddLayerButton';
|
import { AddLayerButton } from 'features/regionalPrompts/components/AddLayerButton';
|
||||||
import { BrushSize } from 'features/regionalPrompts/components/BrushSize';
|
import { BrushSize } from 'features/regionalPrompts/components/BrushSize';
|
||||||
|
import { DebugLayersButton } from 'features/regionalPrompts/components/DebugLayersButton';
|
||||||
import { DeleteAllLayersButton } from 'features/regionalPrompts/components/DeleteAllLayersButton';
|
import { DeleteAllLayersButton } from 'features/regionalPrompts/components/DeleteAllLayersButton';
|
||||||
import { PromptLayerOpacity } from 'features/regionalPrompts/components/PromptLayerOpacity';
|
import { PromptLayerOpacity } from 'features/regionalPrompts/components/PromptLayerOpacity';
|
||||||
import { RPEnabledSwitch } from 'features/regionalPrompts/components/RPEnabledSwitch';
|
import { RPEnabledSwitch } from 'features/regionalPrompts/components/RPEnabledSwitch';
|
||||||
@ -13,7 +14,6 @@ import { StageComponent } from 'features/regionalPrompts/components/StageCompone
|
|||||||
import { ToolChooser } from 'features/regionalPrompts/components/ToolChooser';
|
import { ToolChooser } from 'features/regionalPrompts/components/ToolChooser';
|
||||||
import { UndoRedoButtonGroup } from 'features/regionalPrompts/components/UndoRedoButtonGroup';
|
import { UndoRedoButtonGroup } from 'features/regionalPrompts/components/UndoRedoButtonGroup';
|
||||||
import { isRPLayer, selectRegionalPromptsSlice } from 'features/regionalPrompts/store/regionalPromptsSlice';
|
import { isRPLayer, selectRegionalPromptsSlice } from 'features/regionalPrompts/store/regionalPromptsSlice';
|
||||||
import { getRegionalPromptLayerBlobs } from 'features/regionalPrompts/util/getLayerBlobs';
|
|
||||||
import { memo } from 'react';
|
import { memo } from 'react';
|
||||||
|
|
||||||
const selectRPLayerIdsReversed = createMemoizedSelector(selectRegionalPromptsSlice, (regionalPrompts) =>
|
const selectRPLayerIdsReversed = createMemoizedSelector(selectRegionalPromptsSlice, (regionalPrompts) =>
|
||||||
@ -23,21 +23,16 @@ const selectRPLayerIdsReversed = createMemoizedSelector(selectRegionalPromptsSli
|
|||||||
.reverse()
|
.reverse()
|
||||||
);
|
);
|
||||||
|
|
||||||
const debugBlobs = () => {
|
|
||||||
getRegionalPromptLayerBlobs(undefined, true);
|
|
||||||
};
|
|
||||||
|
|
||||||
export const RegionalPromptsEditor = memo(() => {
|
export const RegionalPromptsEditor = memo(() => {
|
||||||
const rpLayerIdsReversed = useAppSelector(selectRPLayerIdsReversed);
|
const rpLayerIdsReversed = useAppSelector(selectRPLayerIdsReversed);
|
||||||
return (
|
return (
|
||||||
<Flex gap={4} w="full" h="full">
|
<Flex gap={4} w="full" h="full">
|
||||||
<Flex flexDir="column" gap={4} minW={430}>
|
<Flex flexDir="column" gap={4} minW={430}>
|
||||||
<Flex gap={3}>
|
<Flex gap={3} w="full" justifyContent="space-between">
|
||||||
<ButtonGroup isAttached={false}>
|
<DebugLayersButton />
|
||||||
<Button onClick={debugBlobs}>🐛</Button>
|
|
||||||
<AddLayerButton />
|
<AddLayerButton />
|
||||||
<DeleteAllLayersButton />
|
<DeleteAllLayersButton />
|
||||||
</ButtonGroup>
|
<Spacer />
|
||||||
<UndoRedoButtonGroup />
|
<UndoRedoButtonGroup />
|
||||||
<ToolChooser />
|
<ToolChooser />
|
||||||
</Flex>
|
</Flex>
|
||||||
|
@ -2,9 +2,11 @@ import { ButtonGroup, IconButton } from '@invoke-ai/ui-library';
|
|||||||
import { useStore } from '@nanostores/react';
|
import { useStore } from '@nanostores/react';
|
||||||
import { $tool } from 'features/regionalPrompts/store/regionalPromptsSlice';
|
import { $tool } from 'features/regionalPrompts/store/regionalPromptsSlice';
|
||||||
import { useCallback } from 'react';
|
import { useCallback } from 'react';
|
||||||
|
import { useTranslation } from 'react-i18next';
|
||||||
import { PiArrowsOutCardinalBold, PiEraserBold, PiPaintBrushBold } from 'react-icons/pi';
|
import { PiArrowsOutCardinalBold, PiEraserBold, PiPaintBrushBold } from 'react-icons/pi';
|
||||||
|
|
||||||
export const ToolChooser: React.FC = () => {
|
export const ToolChooser: React.FC = () => {
|
||||||
|
const { t } = useTranslation();
|
||||||
const tool = useStore($tool);
|
const tool = useStore($tool);
|
||||||
const setToolToBrush = useCallback(() => {
|
const setToolToBrush = useCallback(() => {
|
||||||
$tool.set('brush');
|
$tool.set('brush');
|
||||||
@ -19,19 +21,22 @@ export const ToolChooser: React.FC = () => {
|
|||||||
return (
|
return (
|
||||||
<ButtonGroup isAttached>
|
<ButtonGroup isAttached>
|
||||||
<IconButton
|
<IconButton
|
||||||
aria-label="Brush tool"
|
aria-label={t('unifiedCanvas.brush')}
|
||||||
|
tooltip={t('unifiedCanvas.brush')}
|
||||||
icon={<PiPaintBrushBold />}
|
icon={<PiPaintBrushBold />}
|
||||||
variant={tool === 'brush' ? 'solid' : 'outline'}
|
variant={tool === 'brush' ? 'solid' : 'outline'}
|
||||||
onClick={setToolToBrush}
|
onClick={setToolToBrush}
|
||||||
/>
|
/>
|
||||||
<IconButton
|
<IconButton
|
||||||
aria-label="Eraser tool"
|
aria-label={t('unifiedCanvas.eraser')}
|
||||||
|
tooltip={t('unifiedCanvas.eraser')}
|
||||||
icon={<PiEraserBold />}
|
icon={<PiEraserBold />}
|
||||||
variant={tool === 'eraser' ? 'solid' : 'outline'}
|
variant={tool === 'eraser' ? 'solid' : 'outline'}
|
||||||
onClick={setToolToEraser}
|
onClick={setToolToEraser}
|
||||||
/>
|
/>
|
||||||
<IconButton
|
<IconButton
|
||||||
aria-label="Move tool"
|
aria-label={t('unifiedCanvas.move')}
|
||||||
|
tooltip={t('unifiedCanvas.move')}
|
||||||
icon={<PiArrowsOutCardinalBold />}
|
icon={<PiArrowsOutCardinalBold />}
|
||||||
variant={tool === 'move' ? 'solid' : 'outline'}
|
variant={tool === 'move' ? 'solid' : 'outline'}
|
||||||
onClick={setToolToMove}
|
onClick={setToolToMove}
|
||||||
|
@ -4,9 +4,11 @@ import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
|||||||
import { redoRegionalPrompts, undoRegionalPrompts } from 'features/regionalPrompts/store/regionalPromptsSlice';
|
import { redoRegionalPrompts, undoRegionalPrompts } from 'features/regionalPrompts/store/regionalPromptsSlice';
|
||||||
import { memo, useCallback } from 'react';
|
import { memo, useCallback } from 'react';
|
||||||
import { useHotkeys } from 'react-hotkeys-hook';
|
import { useHotkeys } from 'react-hotkeys-hook';
|
||||||
|
import { useTranslation } from 'react-i18next';
|
||||||
import { PiArrowClockwiseBold, PiArrowCounterClockwiseBold } from 'react-icons/pi';
|
import { PiArrowClockwiseBold, PiArrowCounterClockwiseBold } from 'react-icons/pi';
|
||||||
|
|
||||||
export const UndoRedoButtonGroup = memo(() => {
|
export const UndoRedoButtonGroup = memo(() => {
|
||||||
|
const { t } = useTranslation();
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
|
|
||||||
const mayUndo = useAppSelector((s) => s.regionalPrompts.past.length > 0);
|
const mayUndo = useAppSelector((s) => s.regionalPrompts.past.length > 0);
|
||||||
@ -23,8 +25,20 @@ export const UndoRedoButtonGroup = memo(() => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<ButtonGroup>
|
<ButtonGroup>
|
||||||
<IconButton aria-label="undo" onClick={undo} icon={<PiArrowCounterClockwiseBold />} isDisabled={!mayUndo} />
|
<IconButton
|
||||||
<IconButton aria-label="redo" onClick={redo} icon={<PiArrowClockwiseBold />} isDisabled={!mayRedo} />
|
aria-label={t('unifiedCanvas.undo')}
|
||||||
|
tooltip={t('unifiedCanvas.undo')}
|
||||||
|
onClick={undo}
|
||||||
|
icon={<PiArrowCounterClockwiseBold />}
|
||||||
|
isDisabled={!mayUndo}
|
||||||
|
/>
|
||||||
|
<IconButton
|
||||||
|
aria-label={t('unifiedCanvas.redo')}
|
||||||
|
tooltip={t('unifiedCanvas.redo')}
|
||||||
|
onClick={redo}
|
||||||
|
icon={<PiArrowClockwiseBold />}
|
||||||
|
isDisabled={!mayRedo}
|
||||||
|
/>
|
||||||
</ButtonGroup>
|
</ButtonGroup>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
Loading…
x
Reference in New Issue
Block a user