feat(ui): wip img2img layouting

This commit is contained in:
psychedelicious
2023-05-08 12:51:40 +10:00
parent 5365f42a04
commit 864f4bb4af
25 changed files with 338 additions and 110 deletions

View File

@ -1,6 +1,6 @@
import { isEqual } from 'lodash-es';
import ResizableDrawer from './common/ResizableDrawer/ResizableDrawer';
import GenerateParameters from './tabs/Create/GenerateParameters';
import CreateBaseSettings from './tabs/Create/CreateBaseSettings';
import { createSelector } from '@reduxjs/toolkit';
import { activeTabNameSelector, uiSelector } from '../store/uiSelectors';
import { lightboxSelector } from 'features/lightbox/store/lightboxSelectors';
@ -13,16 +13,26 @@ import { memo } from 'react';
import { Flex } from '@chakra-ui/react';
import InvokeAILogoComponent from 'features/system/components/InvokeAILogoComponent';
import PinParametersPanelButton from './PinParametersPanelButton';
import { Panel, PanelGroup } from 'react-resizable-panels';
import CreateSidePanelPinned from './tabs/Create/CreateSidePanelPinned';
import CreateTextParameters from './tabs/Create/CreateBaseSettings';
import ResizeHandle from './tabs/ResizeHandle';
import CreateImageSettings from './tabs/Create/CreateImageSettings';
const selector = createSelector(
[uiSelector, activeTabNameSelector, lightboxSelector],
(ui, activeTabName, lightbox) => {
const { shouldPinParametersPanel, shouldShowParametersPanel } = ui;
const {
shouldPinParametersPanel,
shouldShowParametersPanel,
shouldShowImageParameters,
} = ui;
const { isLightboxOpen } = lightbox;
return {
shouldPinParametersPanel,
shouldShowParametersPanel,
shouldShowImageParameters,
};
},
{
@ -34,8 +44,11 @@ const selector = createSelector(
const CreateParametersPanel = () => {
const dispatch = useAppDispatch();
const { shouldPinParametersPanel, shouldShowParametersPanel } =
useAppSelector(selector);
const {
shouldPinParametersPanel,
shouldShowParametersPanel,
shouldShowImageParameters,
} = useAppSelector(selector);
const handleClosePanel = () => {
dispatch(setShouldShowParametersPanel(false));
@ -53,13 +66,7 @@ const CreateParametersPanel = () => {
onClose={handleClosePanel}
minWidth={500}
>
<Flex
flexDir="column"
position="relative"
h={{ base: 600, xl: 'full' }}
w={{ sm: 'full', lg: '100vw', xl: 'full' }}
paddingRight={{ base: 8, xl: 0 }}
>
<Flex flexDir="column" position="relative" h="full" w="full">
<Flex
paddingTop={1.5}
paddingBottom={4}
@ -69,7 +76,37 @@ const CreateParametersPanel = () => {
<InvokeAILogoComponent />
<PinParametersPanelButton />
</Flex>
<GenerateParameters />
<PanelGroup
autoSaveId="createTab_floatingParameters"
direction="horizontal"
style={{ height: '100%', width: '100%' }}
>
<>
<Panel
id="createTab_textParameters"
order={0}
defaultSize={25}
minSize={25}
style={{ position: 'relative' }}
>
<CreateTextParameters />
</Panel>
{shouldShowImageParameters && (
<>
<ResizeHandle />
<Panel
id="createTab_imageParameters"
order={1}
defaultSize={25}
minSize={25}
style={{ position: 'relative' }}
>
<CreateImageSettings />
</Panel>
</>
)}
</>
</PanelGroup>
</Flex>
</ResizableDrawer>
);

View File

@ -39,13 +39,13 @@ import { configSelector } from 'features/system/store/configSelectors';
import { isEqual } from 'lodash-es';
import AnimatedImageToImagePanel from 'features/parameters/components/AnimatedImageToImagePanel';
import Scrollable from './common/Scrollable';
import GenerateParameters from './tabs/Create/GenerateParameters';
import CreateBaseSettings from './tabs/Create/CreateBaseSettings';
import PinParametersPanelButton from './PinParametersPanelButton';
import ParametersSlide from './common/ParametersSlide';
import ImageGalleryPanel from 'features/gallery/components/ImageGalleryPanel';
import { Panel, PanelGroup, PanelResizeHandle } from 'react-resizable-panels';
import ImageGalleryContent from 'features/gallery/components/ImageGalleryContent';
import CreateTabContent from './tabs/Create/GenerateContent';
import CreateTabContent from './tabs/Create/CreateContent';
import ParametersPanel from './ParametersPanel';
import { OverlayScrollbarsComponent } from 'overlayscrollbars-react';
import CreateTab from './tabs/Create/CreateTab';

View File

@ -40,7 +40,7 @@ import { PARAMETERS_PANEL_WIDTH } from 'theme/util/constants';
import OverlayScrollable from '../../common/OverlayScrollable';
import AnimatedImageToImagePanel from 'features/parameters/components/AnimatedImageToImagePanel';
const GenerateParameters = () => {
const CreateBaseSettings = () => {
const { t } = useTranslation();
const generateAccordionItems: ParametersAccordionItems = useMemo(
@ -102,23 +102,22 @@ const GenerateParameters = () => {
<PromptInput />
<NegativePromptInput />
<ProcessButtons />
<ImageToImageToggle />
<Flex
sx={{
flexDirection: 'column',
gap: 2,
bg: 'base.800',
p: 4,
pb: 6,
borderRadius: 'base',
}}
>
<MainSettings />
</Flex>
<ImageToImageToggle />
<ParametersAccordion accordionItems={generateAccordionItems} />
</Flex>
</OverlayScrollable>
);
};
export default memo(GenerateParameters);
export default memo(CreateBaseSettings);

View File

@ -10,10 +10,16 @@ const CreateTabContent = () => {
width: '100%',
height: '100%',
borderRadius: 'base',
bg: 'base.850',
// bg: 'base.850',
}}
>
<Flex sx={{ p: 4, width: '100%', height: '100%' }}>
<Flex
sx={{
// p: 2,
width: '100%',
height: '100%',
}}
>
<CurrentImageDisplay />
</Flex>
</Box>

View File

@ -0,0 +1,53 @@
import { memo } from 'react';
import OverlayScrollable from '../../common/OverlayScrollable';
import ImageToImageSettings from 'features/parameters/components/AdvancedParameters/ImageToImage/ImageToImageSettings';
import {
Box,
ButtonGroup,
Collapse,
Flex,
Heading,
HStack,
Image,
Spacer,
useDisclosure,
VStack,
} from '@chakra-ui/react';
import { motion } from 'framer-motion';
import IAIButton from 'common/components/IAIButton';
import ImageFit from 'features/parameters/components/AdvancedParameters/ImageToImage/ImageFit';
import ImageToImageStrength from 'features/parameters/components/AdvancedParameters/ImageToImage/ImageToImageStrength';
import IAIIconButton from 'common/components/IAIIconButton';
import { useTranslation } from 'react-i18next';
import { useState } from 'react';
import { FaUndo, FaUpload } from 'react-icons/fa';
import ImagePromptHeading from 'common/components/ImageToImageSettingsHeader';
import InitialImagePreview from 'features/parameters/components/AdvancedParameters/ImageToImage/InitialImagePreview';
const CreateImageSettings = () => {
return (
<OverlayScrollable>
<Flex
sx={{
gap: 2,
flexDirection: 'column',
h: 'full',
w: 'full',
position: 'absolute',
borderRadius: 'base',
// bg: 'base.850',
// p: 2,
}}
>
<ImagePromptHeading />
<InitialImagePreview />
<ImageToImageStrength />
<ImageFit />
</Flex>
</OverlayScrollable>
);
};
export default memo(CreateImageSettings);

View File

@ -0,0 +1,69 @@
import { createSelector } from '@reduxjs/toolkit';
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
import { uiSelector } from 'features/ui/store/uiSelectors';
import { memo } from 'react';
import { Panel } from 'react-resizable-panels';
import CreateTextParameters from './CreateBaseSettings';
import PinParametersPanelButton from '../../PinParametersPanelButton';
import ResizeHandle from '../ResizeHandle';
import ImageToImageSettings from 'features/parameters/components/AdvancedParameters/ImageToImage/ImageToImageSettings';
import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions';
import CreateImageSettings from './CreateImageSettings';
const selector = createSelector(
uiSelector,
(ui) => {
const {
shouldPinParametersPanel,
shouldShowParametersPanel,
shouldShowImageParameters,
} = ui;
return {
shouldPinParametersPanel,
shouldShowParametersPanel,
shouldShowImageParameters,
};
},
defaultSelectorOptions
);
const CreateSidePanelPinned = () => {
const dispatch = useAppDispatch();
const {
shouldPinParametersPanel,
shouldShowParametersPanel,
shouldShowImageParameters,
} = useAppSelector(selector);
return (
<>
<Panel
order={0}
defaultSize={25}
minSize={25}
style={{ position: 'relative' }}
>
<CreateTextParameters />
<PinParametersPanelButton
sx={{ position: 'absolute', top: 0, insetInlineEnd: 0 }}
/>
</Panel>
{shouldShowImageParameters && (
<>
<ResizeHandle />
<Panel
order={1}
defaultSize={25}
minSize={25}
style={{ position: 'relative' }}
>
<CreateImageSettings />
</Panel>
</>
)}
<ResizeHandle />
</>
);
};
export default memo(CreateSidePanelPinned);

View File

@ -1,17 +1,20 @@
import { Portal, TabPanel } from '@chakra-ui/react';
import { memo } from 'react';
import { Panel, PanelGroup, PanelResizeHandle } from 'react-resizable-panels';
import GenerateParameters from './GenerateParameters';
import CreateBaseSettings from './CreateBaseSettings';
import PinParametersPanelButton from '../../PinParametersPanelButton';
import ImageGalleryContent from 'features/gallery/components/ImageGalleryContent';
import { createSelector } from '@reduxjs/toolkit';
import { uiSelector } from 'features/ui/store/uiSelectors';
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
import { requestCanvasRescale } from 'features/canvas/store/thunks/requestCanvasScale';
import CreateTabContent from './GenerateContent';
import CreateTabContent from './CreateContent';
import ResizeHandle from '../ResizeHandle';
import AnimatedImageToImagePanel from 'features/parameters/components/AnimatedImageToImagePanel';
import ImageToImageSettings from 'features/parameters/components/AdvancedParameters/ImageToImage/ImageToImageSettings';
import CreateSidePanelPinned from './CreateSidePanelPinned';
import CreateTextParameters from './CreateBaseSettings';
import CreateImageSettings from './CreateImageSettings';
const selector = createSelector(uiSelector, (ui) => {
const {
@ -19,6 +22,7 @@ const selector = createSelector(uiSelector, (ui) => {
shouldShowGallery,
shouldPinParametersPanel,
shouldShowParametersPanel,
shouldShowImageParameters,
} = ui;
return {
@ -26,6 +30,7 @@ const selector = createSelector(uiSelector, (ui) => {
shouldShowGallery,
shouldPinParametersPanel,
shouldShowParametersPanel,
shouldShowImageParameters,
};
});
@ -36,44 +41,49 @@ const CreateTab = () => {
shouldShowGallery,
shouldPinParametersPanel,
shouldShowParametersPanel,
shouldShowImageParameters,
} = useAppSelector(selector);
return (
<PanelGroup
autoSaveId="createTab_pinned"
direction="horizontal"
style={{ height: '100%', width: '100%' }}
>
{shouldPinParametersPanel && shouldShowParametersPanel && (
<>
<Panel
id="createTab_textParameters"
order={0}
defaultSize={30}
minSize={20}
defaultSize={25}
minSize={25}
style={{ position: 'relative' }}
>
<GenerateParameters />
<CreateTextParameters />
<PinParametersPanelButton
sx={{ position: 'absolute', top: 0, insetInlineEnd: 0 }}
/>
</Panel>
<ResizeHandle />
</>
)}
{shouldPinParametersPanel && shouldShowParametersPanel && (
<>
<Panel
order={0}
defaultSize={30}
minSize={20}
style={{ position: 'relative' }}
>
<ImageToImageSettings />
</Panel>
{shouldShowImageParameters && (
<>
<ResizeHandle />
<Panel
id="createTab_imageParameters"
order={1}
defaultSize={25}
minSize={25}
style={{ position: 'relative' }}
>
<CreateImageSettings />
</Panel>
</>
)}
<ResizeHandle />
</>
)}
<Panel
order={1}
id="createTab_content"
order={2}
minSize={30}
onResize={() => {
dispatch(requestCanvasRescale());
@ -84,7 +94,7 @@ const CreateTab = () => {
{shouldPinGallery && shouldShowGallery && (
<>
<ResizeHandle />
<Panel order={2} defaultSize={10} minSize={10}>
<Panel id="createTab_gallery" order={3} defaultSize={10} minSize={10}>
<ImageGalleryContent />
</Panel>
</>

View File

@ -1,8 +1,8 @@
import { Box, Flex } from '@chakra-ui/react';
import { useAppSelector } from 'app/store/storeHooks';
import { memo } from 'react';
import CreateTabContent from './GenerateContent';
import GenerateParameters from './GenerateParameters';
import CreateTabContent from './CreateContent';
import CreateBaseSettings from './CreateBaseSettings';
import PinParametersPanelButton from '../../PinParametersPanelButton';
import { RootState } from 'app/store/store';
import Scrollable from '../../common/Scrollable';
@ -35,7 +35,7 @@ const GenerateWorkspace = () => {
}}
>
<Scrollable>
<GenerateParameters />
<CreateBaseSettings />
</Scrollable>
<PinParametersPanelButton
sx={{ position: 'absolute', top: 0, insetInlineEnd: 0 }}
@ -44,7 +44,7 @@ const GenerateWorkspace = () => {
</Flex>
) : (
<ParametersSlide>
<GenerateParameters />
<CreateBaseSettings />
</ParametersSlide>
)}
<CreateTabContent />

View File

@ -37,6 +37,7 @@ const NodesTab = () => {
return (
<PanelGroup
autoSaveId="nodesTab"
direction="horizontal"
style={{ height: '100%', width: '100%' }}
>

View File

@ -8,7 +8,7 @@ const ResizeHandle = () => {
<Flex
sx={{ w: 6, h: 'full', justifyContent: 'center', alignItems: 'center' }}
>
<Box sx={{ w: 0.5, h: 'calc(100% - 1rem)', py: 4, bg: 'base.800' }} />
<Box sx={{ w: 0.5, h: 'calc(100% - 4px)', bg: 'base.850' }} />
</Flex>
</PanelResizeHandle>
);

View File

@ -42,6 +42,7 @@ const UnifiedCanvasTab = () => {
return (
<PanelGroup
autoSaveId="canvasTab"
direction="horizontal"
style={{ height: '100%', width: '100%' }}
>

View File

@ -24,6 +24,7 @@ export const initialUIState: UIState = {
floatingProgressImageRect: { x: 0, y: 0, width: 0, height: 0 },
shouldShowProgressImages: false,
shouldAutoShowProgressImages: false,
shouldShowImageParameters: false,
};
export const uiSlice = createSlice({
@ -136,6 +137,12 @@ export const uiSlice = createSlice({
) => {
state.shouldAutoShowProgressImages = action.payload;
},
shouldShowImageParametersChanged: (
state,
action: PayloadAction<boolean>
) => {
state.shouldShowImageParameters = action.payload;
},
},
});
@ -163,6 +170,7 @@ export const {
floatingProgressImageResized,
setShouldShowProgressImages,
setShouldAutoShowProgressImages,
shouldShowImageParametersChanged,
} = uiSlice.actions;
export default uiSlice.reducer;

View File

@ -32,4 +32,5 @@ export interface UIState {
floatingProgressImageRect: Rect;
shouldShowProgressImages: boolean;
shouldAutoShowProgressImages: boolean;
shouldShowImageParameters: boolean;
}