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:
@ -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,39 +77,44 @@ const InitialImagePreview = () => {
|
||||
}}
|
||||
onDrop={handleDrop}
|
||||
>
|
||||
{initialImage?.url && (
|
||||
<Box
|
||||
sx={{
|
||||
height: 'full',
|
||||
width: 'full',
|
||||
opacity: isImageToImageEnabled ? 1 : 0.5,
|
||||
filter: isImageToImageEnabled ? 'none' : 'auto',
|
||||
blur: '5px',
|
||||
position: 'relative',
|
||||
}}
|
||||
>
|
||||
<Image
|
||||
sx={{
|
||||
fit: 'contain',
|
||||
borderRadius: 'base',
|
||||
}}
|
||||
src={getUrl(initialImage?.url)}
|
||||
onError={onError}
|
||||
onLoad={() => {
|
||||
setIsLoaded(true);
|
||||
}}
|
||||
fallback={
|
||||
<Flex
|
||||
sx={{ h: 36, alignItems: 'center', justifyContent: 'center' }}
|
||||
>
|
||||
<Spinner color="grey" w="5rem" h="5rem" />
|
||||
</Flex>
|
||||
}
|
||||
/>
|
||||
{isLoaded && <ImageToImageOverlay image={initialImage} />}
|
||||
</Box>
|
||||
)}
|
||||
{!initialImage?.url && <SelectImagePlaceholder />}
|
||||
<Flex
|
||||
sx={{
|
||||
height: 'full',
|
||||
width: 'full',
|
||||
opacity: isImageToImageEnabled ? 1 : 0.5,
|
||||
filter: isImageToImageEnabled ? 'none' : 'auto',
|
||||
blur: '5px',
|
||||
position: 'relative',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
}}
|
||||
>
|
||||
{initialImage?.url && (
|
||||
<>
|
||||
<Image
|
||||
sx={{
|
||||
objectFit: 'contain',
|
||||
borderRadius: 'base',
|
||||
maxHeight: 'full',
|
||||
}}
|
||||
src={getUrl(initialImage?.url)}
|
||||
onError={onError}
|
||||
onLoad={() => {
|
||||
setIsLoaded(true);
|
||||
}}
|
||||
fallback={
|
||||
<Flex
|
||||
sx={{ h: 36, alignItems: 'center', justifyContent: 'center' }}
|
||||
>
|
||||
<Spinner color="grey" w="5rem" h="5rem" />
|
||||
</Flex>
|
||||
}
|
||||
/>
|
||||
{isLoaded && <ImageToImageOverlay image={initialImage} />}
|
||||
</>
|
||||
)}
|
||||
{!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))
|
||||
|
Reference in New Issue
Block a user