mirror of
https://github.com/invoke-ai/InvokeAI
synced 2024-08-30 20:32:17 +00:00
feat(ui): wip img2img layouting
This commit is contained in:
parent
5365f42a04
commit
864f4bb4af
@ -102,7 +102,8 @@
|
||||
"generate": "Generate",
|
||||
"openInNewTab": "Open in New Tab",
|
||||
"dontAskMeAgain": "Don't ask me again",
|
||||
"areYouSure": "Are you sure?"
|
||||
"areYouSure": "Are you sure?",
|
||||
"imagePrompt": "Image Prompt"
|
||||
},
|
||||
"gallery": {
|
||||
"generations": "Generations",
|
||||
|
@ -0,0 +1,7 @@
|
||||
import { isEqual } from 'lodash-es';
|
||||
|
||||
export const defaultSelectorOptions = {
|
||||
memoizeOptions: {
|
||||
resultEqualityCheck: isEqual,
|
||||
},
|
||||
};
|
@ -14,6 +14,7 @@ const ImageToImageOverlay = ({ image }: ImageToImageOverlayProps) => {
|
||||
w: 'full',
|
||||
h: 'full',
|
||||
position: 'absolute',
|
||||
pointerEvents: 'none',
|
||||
}}
|
||||
>
|
||||
<Flex
|
||||
|
@ -7,7 +7,7 @@ import { useAppDispatch } from 'app/store/storeHooks';
|
||||
import { useCallback } from 'react';
|
||||
import { clearInitialImage } from 'features/parameters/store/generationSlice';
|
||||
|
||||
const ImageToImageSettingsHeader = () => {
|
||||
const ImagePromptHeading = () => {
|
||||
const dispatch = useAppDispatch();
|
||||
const { t } = useTranslation();
|
||||
|
||||
@ -18,7 +18,7 @@ const ImageToImageSettingsHeader = () => {
|
||||
return (
|
||||
<Flex w="full" alignItems="center">
|
||||
<Text size="sm" fontWeight={500} color="base.300">
|
||||
Image to Image
|
||||
{t('parameters.initialImage')}
|
||||
</Text>
|
||||
<Spacer />
|
||||
<ButtonGroup>
|
||||
@ -38,4 +38,4 @@ const ImageToImageSettingsHeader = () => {
|
||||
);
|
||||
};
|
||||
|
||||
export default ImageToImageSettingsHeader;
|
||||
export default ImagePromptHeading;
|
||||
|
@ -410,7 +410,7 @@ const CurrentImageButtons = (props: CurrentImageButtonsProps) => {
|
||||
}}
|
||||
{...props}
|
||||
>
|
||||
<ButtonGroup isAttached={true}>
|
||||
<ButtonGroup size="sm" isAttached={true}>
|
||||
<IAIPopover
|
||||
triggerComponent={
|
||||
<IAIIconButton
|
||||
@ -497,7 +497,7 @@ const CurrentImageButtons = (props: CurrentImageButtonsProps) => {
|
||||
)}
|
||||
</ButtonGroup>
|
||||
|
||||
<ButtonGroup isAttached={true}>
|
||||
<ButtonGroup size="sm" isAttached={true}>
|
||||
<IAIIconButton
|
||||
icon={<FaQuoteRight />}
|
||||
tooltip={`${t('parameters.usePrompt')} (P)`}
|
||||
@ -528,7 +528,7 @@ const CurrentImageButtons = (props: CurrentImageButtonsProps) => {
|
||||
</ButtonGroup>
|
||||
|
||||
{(isUpscalingEnabled || isFaceRestoreEnabled) && (
|
||||
<ButtonGroup isAttached={true}>
|
||||
<ButtonGroup size="sm" isAttached={true}>
|
||||
{isFaceRestoreEnabled && (
|
||||
<IAIPopover
|
||||
triggerComponent={
|
||||
@ -593,7 +593,7 @@ const CurrentImageButtons = (props: CurrentImageButtonsProps) => {
|
||||
</ButtonGroup>
|
||||
)}
|
||||
|
||||
<ButtonGroup isAttached={true}>
|
||||
<ButtonGroup size="sm" isAttached={true}>
|
||||
<IAIIconButton
|
||||
icon={<FaCode />}
|
||||
tooltip={`${t('parameters.info')} (I)`}
|
||||
@ -603,6 +603,7 @@ const CurrentImageButtons = (props: CurrentImageButtonsProps) => {
|
||||
/>
|
||||
</ButtonGroup>
|
||||
|
||||
<ButtonGroup size="sm" isAttached={true}>
|
||||
<IAIIconButton
|
||||
onClick={handleInitiateDelete}
|
||||
icon={<FaTrash />}
|
||||
@ -611,6 +612,7 @@ const CurrentImageButtons = (props: CurrentImageButtonsProps) => {
|
||||
isDisabled={!image || !isConnected}
|
||||
colorScheme="error"
|
||||
/>
|
||||
</ButtonGroup>
|
||||
</Flex>
|
||||
{image && (
|
||||
<DeleteImageModal
|
||||
|
@ -179,7 +179,17 @@ const ImageGalleryContent = () => {
|
||||
}, [dispatch, currentCategory]);
|
||||
|
||||
return (
|
||||
<Flex flexDirection="column" w="full" h="full" gap={4}>
|
||||
<Flex
|
||||
sx={{
|
||||
gap: 2,
|
||||
flexDirection: 'column',
|
||||
h: 'full',
|
||||
w: 'full',
|
||||
borderRadius: 'base',
|
||||
// bg: 'base.850',
|
||||
// p: 2,
|
||||
}}
|
||||
>
|
||||
<Flex
|
||||
ref={resizeObserverRef}
|
||||
alignItems="center"
|
||||
|
@ -21,13 +21,13 @@ import { useTranslation } from 'react-i18next';
|
||||
import InitialImagePreview from './InitialImagePreview';
|
||||
import { useState } from 'react';
|
||||
import { FaUndo, FaUpload } from 'react-icons/fa';
|
||||
import ImageToImageSettingsHeader from 'common/components/ImageToImageSettingsHeader';
|
||||
import ImagePromptHeading from 'common/components/ImageToImageSettingsHeader';
|
||||
|
||||
export default function ImageToImageSettings() {
|
||||
const { t } = useTranslation();
|
||||
return (
|
||||
<VStack gap={2} w="full" alignItems="stretch">
|
||||
<ImageToImageSettingsHeader />
|
||||
<ImagePromptHeading />
|
||||
<InitialImagePreview />
|
||||
<ImageToImageStrength />
|
||||
<ImageFit />
|
||||
|
@ -1,34 +1,50 @@
|
||||
import { Flex } from '@chakra-ui/react';
|
||||
import { createSelector } from '@reduxjs/toolkit';
|
||||
import { RootState } from 'app/store/store';
|
||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||
import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions';
|
||||
import IAISwitch from 'common/components/IAISwitch';
|
||||
import { generationSelector } from 'features/parameters/store/generationSelectors';
|
||||
import { isImageToImageEnabledChanged } from 'features/parameters/store/generationSlice';
|
||||
import { uiSelector } from 'features/ui/store/uiSelectors';
|
||||
import { shouldShowImageParametersChanged } from 'features/ui/store/uiSlice';
|
||||
import { ChangeEvent } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
const selector = createSelector(
|
||||
[uiSelector, generationSelector],
|
||||
(ui, generation) => {
|
||||
const { isImageToImageEnabled } = generation;
|
||||
const { shouldShowImageParameters } = ui;
|
||||
return {
|
||||
isImageToImageEnabled,
|
||||
shouldShowImageParameters,
|
||||
};
|
||||
},
|
||||
defaultSelectorOptions
|
||||
);
|
||||
|
||||
export default function ImageToImageToggle() {
|
||||
const isImageToImageEnabled = useAppSelector(
|
||||
(state: RootState) => state.generation.isImageToImageEnabled
|
||||
);
|
||||
const { isImageToImageEnabled, shouldShowImageParameters } =
|
||||
useAppSelector(selector);
|
||||
|
||||
const { t } = useTranslation();
|
||||
|
||||
const dispatch = useAppDispatch();
|
||||
|
||||
const handleChange = (e: ChangeEvent<HTMLInputElement>) =>
|
||||
dispatch(isImageToImageEnabledChanged(e.target.checked));
|
||||
dispatch(shouldShowImageParametersChanged(e.target.checked));
|
||||
|
||||
return (
|
||||
<Flex background="base.800" py={1.5} px={4} borderRadius={4}>
|
||||
<Flex py={1.5} px={4} borderRadius={4}>
|
||||
<IAISwitch
|
||||
label={t('common.img2img')}
|
||||
isChecked={isImageToImageEnabled}
|
||||
label={t('parameters.initialImage')}
|
||||
isChecked={shouldShowImageParameters}
|
||||
width="full"
|
||||
onChange={handleChange}
|
||||
justifyContent="space-between"
|
||||
formLabelProps={{
|
||||
fontWeight: 'bold',
|
||||
color: 'base.200',
|
||||
fontWeight: 400,
|
||||
}}
|
||||
/>
|
||||
</Flex>
|
||||
|
@ -70,7 +70,6 @@ const InitialImagePreview = () => {
|
||||
return (
|
||||
<Flex
|
||||
sx={{
|
||||
height: 'full',
|
||||
width: 'full',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
@ -78,8 +77,7 @@ const InitialImagePreview = () => {
|
||||
}}
|
||||
onDrop={handleDrop}
|
||||
>
|
||||
{initialImage?.url && (
|
||||
<Box
|
||||
<Flex
|
||||
sx={{
|
||||
height: 'full',
|
||||
width: 'full',
|
||||
@ -87,12 +85,17 @@ const InitialImagePreview = () => {
|
||||
filter: isImageToImageEnabled ? 'none' : 'auto',
|
||||
blur: '5px',
|
||||
position: 'relative',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
}}
|
||||
>
|
||||
{initialImage?.url && (
|
||||
<>
|
||||
<Image
|
||||
sx={{
|
||||
fit: 'contain',
|
||||
objectFit: 'contain',
|
||||
borderRadius: 'base',
|
||||
maxHeight: 'full',
|
||||
}}
|
||||
src={getUrl(initialImage?.url)}
|
||||
onError={onError}
|
||||
@ -108,9 +111,10 @@ const InitialImagePreview = () => {
|
||||
}
|
||||
/>
|
||||
{isLoaded && <ImageToImageOverlay image={initialImage} />}
|
||||
</Box>
|
||||
</>
|
||||
)}
|
||||
{!initialImage?.url && <SelectImagePlaceholder />}
|
||||
</Flex>
|
||||
{!isImageToImageEnabled && (
|
||||
<Flex
|
||||
sx={{
|
||||
|
@ -29,6 +29,8 @@ import { MdCancel, MdCancelScheduleSend } from 'react-icons/md';
|
||||
|
||||
import { sessionCanceled } from 'services/thunks/session';
|
||||
import { BiChevronDown } from 'react-icons/bi';
|
||||
import { FaChevronDown } from 'react-icons/fa';
|
||||
import { ChevronDownIcon } from '@chakra-ui/icons';
|
||||
|
||||
const cancelButtonSelector = createSelector(
|
||||
systemSelector,
|
||||
@ -135,13 +137,12 @@ const CancelButton = (
|
||||
colorScheme="error"
|
||||
{...rest}
|
||||
/>
|
||||
|
||||
<Menu closeOnSelect={false}>
|
||||
<MenuButton
|
||||
as={IAIIconButton}
|
||||
tooltip={t('parameters.cancel.setType')}
|
||||
aria-label={t('parameters.cancel.setType')}
|
||||
icon={<BiChevronDown />}
|
||||
icon={<ChevronDownIcon w="1em" h="1em" />}
|
||||
paddingX={0}
|
||||
paddingY={0}
|
||||
colorScheme="error"
|
||||
|
@ -4,6 +4,8 @@ import { activeTabNameSelector } from 'features/ui/store/uiSelectors';
|
||||
import CancelButton from './CancelButton';
|
||||
import InvokeButton from './InvokeButton';
|
||||
import LoopbackButton from './Loopback';
|
||||
import IAICheckbox from 'common/components/IAICheckbox';
|
||||
import IAISwitch from 'common/components/IAISwitch';
|
||||
|
||||
/**
|
||||
* Buttons to start and cancel image generation.
|
||||
|
@ -55,7 +55,6 @@ const ProgressImagePreview = () => {
|
||||
|
||||
return (
|
||||
<>
|
||||
{' '}
|
||||
<IAIIconButton
|
||||
onClick={() =>
|
||||
dispatch(setShouldShowProgressImages(!showProgressWindow))
|
||||
|
@ -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>
|
||||
);
|
||||
|
@ -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';
|
||||
|
@ -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);
|
@ -10,10 +10,16 @@ const CreateTabContent = () => {
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
borderRadius: 'base',
|
||||
bg: 'base.850',
|
||||
// bg: 'base.850',
|
||||
}}
|
||||
>
|
||||
<Flex
|
||||
sx={{
|
||||
// p: 2,
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
}}
|
||||
>
|
||||
<Flex sx={{ p: 4, width: '100%', height: '100%' }}>
|
||||
<CurrentImageDisplay />
|
||||
</Flex>
|
||||
</Box>
|
@ -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);
|
@ -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);
|
@ -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 && (
|
||||
{shouldShowImageParameters && (
|
||||
<>
|
||||
<ResizeHandle />
|
||||
<Panel
|
||||
order={0}
|
||||
defaultSize={30}
|
||||
minSize={20}
|
||||
id="createTab_imageParameters"
|
||||
order={1}
|
||||
defaultSize={25}
|
||||
minSize={25}
|
||||
style={{ position: 'relative' }}
|
||||
>
|
||||
<ImageToImageSettings />
|
||||
<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>
|
||||
</>
|
||||
|
@ -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 />
|
||||
|
@ -37,6 +37,7 @@ const NodesTab = () => {
|
||||
|
||||
return (
|
||||
<PanelGroup
|
||||
autoSaveId="nodesTab"
|
||||
direction="horizontal"
|
||||
style={{ height: '100%', width: '100%' }}
|
||||
>
|
||||
|
@ -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>
|
||||
);
|
||||
|
@ -42,6 +42,7 @@ const UnifiedCanvasTab = () => {
|
||||
|
||||
return (
|
||||
<PanelGroup
|
||||
autoSaveId="canvasTab"
|
||||
direction="horizontal"
|
||||
style={{ height: '100%', width: '100%' }}
|
||||
>
|
||||
|
@ -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;
|
||||
|
@ -32,4 +32,5 @@ export interface UIState {
|
||||
floatingProgressImageRect: Rect;
|
||||
shouldShowProgressImages: boolean;
|
||||
shouldAutoShowProgressImages: boolean;
|
||||
shouldShowImageParameters: boolean;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user