mirror of
https://github.com/invoke-ai/InvokeAI.git
synced 2026-02-14 05:04:56 -05:00
Add option to save all staging images to gallery in canvas mode
Co-authored-by: kent <kent@invoke.ai>
This commit is contained in:
committed by
psychedelicious
parent
e6c67cc00f
commit
ef135f9923
@@ -1962,6 +1962,7 @@
|
|||||||
"recalculateRects": "Recalculate Rects",
|
"recalculateRects": "Recalculate Rects",
|
||||||
"clipToBbox": "Clip Strokes to Bbox",
|
"clipToBbox": "Clip Strokes to Bbox",
|
||||||
"outputOnlyMaskedRegions": "Output Only Generated Regions",
|
"outputOnlyMaskedRegions": "Output Only Generated Regions",
|
||||||
|
"saveAllStagingImagesToGallery": "Save All Staging Images to Gallery",
|
||||||
"addLayer": "Add Layer",
|
"addLayer": "Add Layer",
|
||||||
"duplicate": "Duplicate",
|
"duplicate": "Duplicate",
|
||||||
"moveToFront": "Move to Front",
|
"moveToFront": "Move to Front",
|
||||||
@@ -2330,6 +2331,9 @@
|
|||||||
"label": "Preserve Masked Region",
|
"label": "Preserve Masked Region",
|
||||||
"alert": "Preserving Masked Region"
|
"alert": "Preserving Masked Region"
|
||||||
},
|
},
|
||||||
|
"saveAllStagingImagesToGallery": {
|
||||||
|
"alert": "Saving All Staging Images to Gallery"
|
||||||
|
},
|
||||||
"isolatedStagingPreview": "Isolated Staging Preview",
|
"isolatedStagingPreview": "Isolated Staging Preview",
|
||||||
"isolatedPreview": "Isolated Preview",
|
"isolatedPreview": "Isolated Preview",
|
||||||
"isolatedLayerPreview": "Isolated Layer Preview",
|
"isolatedLayerPreview": "Isolated Layer Preview",
|
||||||
|
|||||||
@@ -0,0 +1,23 @@
|
|||||||
|
import { Alert, AlertIcon, AlertTitle } from '@invoke-ai/ui-library';
|
||||||
|
import { useAppSelector } from 'app/store/storeHooks';
|
||||||
|
import { selectSaveAllStagingImagesToGallery } from 'features/controlLayers/store/canvasSettingsSlice';
|
||||||
|
import { memo } from 'react';
|
||||||
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
|
export const CanvasAlertsSaveAllStagingImagesToGallery = memo(() => {
|
||||||
|
const { t } = useTranslation();
|
||||||
|
const saveAllStagingImagesToGallery = useAppSelector(selectSaveAllStagingImagesToGallery);
|
||||||
|
|
||||||
|
if (!saveAllStagingImagesToGallery) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Alert status="info" borderRadius="base" fontSize="sm" shadow="md" w="fit-content">
|
||||||
|
<AlertIcon />
|
||||||
|
<AlertTitle>{t('controlLayers.settings.saveAllStagingImagesToGallery.alert')}</AlertTitle>
|
||||||
|
</Alert>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
CanvasAlertsSaveAllStagingImagesToGallery.displayName = 'CanvasAlertsSaveAllStagingImagesToGallery';
|
||||||
@@ -26,6 +26,7 @@ import { CanvasSettingsPreserveMaskCheckbox } from 'features/controlLayers/compo
|
|||||||
import { CanvasSettingsPressureSensitivityCheckbox } from 'features/controlLayers/components/Settings/CanvasSettingsPressureSensitivity';
|
import { CanvasSettingsPressureSensitivityCheckbox } from 'features/controlLayers/components/Settings/CanvasSettingsPressureSensitivity';
|
||||||
import { CanvasSettingsRecalculateRectsButton } from 'features/controlLayers/components/Settings/CanvasSettingsRecalculateRectsButton';
|
import { CanvasSettingsRecalculateRectsButton } from 'features/controlLayers/components/Settings/CanvasSettingsRecalculateRectsButton';
|
||||||
import { CanvasSettingsRuleOfThirdsSwitch } from 'features/controlLayers/components/Settings/CanvasSettingsRuleOfThirdsGuideSwitch';
|
import { CanvasSettingsRuleOfThirdsSwitch } from 'features/controlLayers/components/Settings/CanvasSettingsRuleOfThirdsGuideSwitch';
|
||||||
|
import { CanvasSettingsSaveAllStagingImagesToGalleryCheckbox } from 'features/controlLayers/components/Settings/CanvasSettingsSaveAllStagingImagesToGalleryCheckbox';
|
||||||
import { CanvasSettingsShowHUDSwitch } from 'features/controlLayers/components/Settings/CanvasSettingsShowHUDSwitch';
|
import { CanvasSettingsShowHUDSwitch } from 'features/controlLayers/components/Settings/CanvasSettingsShowHUDSwitch';
|
||||||
import { CanvasSettingsShowProgressOnCanvas } from 'features/controlLayers/components/Settings/CanvasSettingsShowProgressOnCanvasSwitch';
|
import { CanvasSettingsShowProgressOnCanvas } from 'features/controlLayers/components/Settings/CanvasSettingsShowProgressOnCanvasSwitch';
|
||||||
import { memo } from 'react';
|
import { memo } from 'react';
|
||||||
@@ -61,6 +62,7 @@ export const CanvasSettingsPopover = memo(() => {
|
|||||||
<CanvasSettingsPreserveMaskCheckbox />
|
<CanvasSettingsPreserveMaskCheckbox />
|
||||||
<CanvasSettingsClipToBboxCheckbox />
|
<CanvasSettingsClipToBboxCheckbox />
|
||||||
<CanvasSettingsOutputOnlyMaskedRegionsCheckbox />
|
<CanvasSettingsOutputOnlyMaskedRegionsCheckbox />
|
||||||
|
<CanvasSettingsSaveAllStagingImagesToGalleryCheckbox />
|
||||||
</Flex>
|
</Flex>
|
||||||
|
|
||||||
<Divider />
|
<Divider />
|
||||||
|
|||||||
@@ -0,0 +1,25 @@
|
|||||||
|
import { Checkbox, FormControl, FormLabel } from '@invoke-ai/ui-library';
|
||||||
|
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||||
|
import {
|
||||||
|
selectSaveAllStagingImagesToGallery,
|
||||||
|
settingsSaveAllStagingImagesToGalleryToggled,
|
||||||
|
} from 'features/controlLayers/store/canvasSettingsSlice';
|
||||||
|
import { memo, useCallback } from 'react';
|
||||||
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
|
export const CanvasSettingsSaveAllStagingImagesToGalleryCheckbox = memo(() => {
|
||||||
|
const { t } = useTranslation();
|
||||||
|
const dispatch = useAppDispatch();
|
||||||
|
const saveAllStagingImagesToGallery = useAppSelector(selectSaveAllStagingImagesToGallery);
|
||||||
|
const onChange = useCallback(() => {
|
||||||
|
dispatch(settingsSaveAllStagingImagesToGalleryToggled());
|
||||||
|
}, [dispatch]);
|
||||||
|
return (
|
||||||
|
<FormControl w="full">
|
||||||
|
<FormLabel flexGrow={1}>{t('controlLayers.saveAllStagingImagesToGallery')}</FormLabel>
|
||||||
|
<Checkbox isChecked={saveAllStagingImagesToGallery} onChange={onChange} />
|
||||||
|
</FormControl>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
CanvasSettingsSaveAllStagingImagesToGalleryCheckbox.displayName = 'CanvasSettingsSaveAllStagingImagesToGalleryCheckbox';
|
||||||
@@ -77,6 +77,10 @@ type CanvasSettingsState = {
|
|||||||
* Whether to show the rule of thirds composition guide overlay on the canvas.
|
* Whether to show the rule of thirds composition guide overlay on the canvas.
|
||||||
*/
|
*/
|
||||||
ruleOfThirds: boolean;
|
ruleOfThirds: boolean;
|
||||||
|
/**
|
||||||
|
* Whether to save all staging images to the gallery instead of keeping them as intermediate images.
|
||||||
|
*/
|
||||||
|
saveAllStagingImagesToGallery: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
const initialState: CanvasSettingsState = {
|
const initialState: CanvasSettingsState = {
|
||||||
@@ -97,6 +101,7 @@ const initialState: CanvasSettingsState = {
|
|||||||
isolatedLayerPreview: true,
|
isolatedLayerPreview: true,
|
||||||
pressureSensitivity: true,
|
pressureSensitivity: true,
|
||||||
ruleOfThirds: false,
|
ruleOfThirds: false,
|
||||||
|
saveAllStagingImagesToGallery: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
export const canvasSettingsSlice = createSlice({
|
export const canvasSettingsSlice = createSlice({
|
||||||
@@ -154,6 +159,9 @@ export const canvasSettingsSlice = createSlice({
|
|||||||
settingsRuleOfThirdsToggled: (state) => {
|
settingsRuleOfThirdsToggled: (state) => {
|
||||||
state.ruleOfThirds = !state.ruleOfThirds;
|
state.ruleOfThirds = !state.ruleOfThirds;
|
||||||
},
|
},
|
||||||
|
settingsSaveAllStagingImagesToGalleryToggled: (state) => {
|
||||||
|
state.saveAllStagingImagesToGallery = !state.saveAllStagingImagesToGallery;
|
||||||
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -175,6 +183,7 @@ export const {
|
|||||||
settingsIsolatedLayerPreviewToggled,
|
settingsIsolatedLayerPreviewToggled,
|
||||||
settingsPressureSensitivityToggled,
|
settingsPressureSensitivityToggled,
|
||||||
settingsRuleOfThirdsToggled,
|
settingsRuleOfThirdsToggled,
|
||||||
|
settingsSaveAllStagingImagesToGalleryToggled,
|
||||||
} = canvasSettingsSlice.actions;
|
} = canvasSettingsSlice.actions;
|
||||||
|
|
||||||
/* eslint-disable-next-line @typescript-eslint/no-explicit-any */
|
/* eslint-disable-next-line @typescript-eslint/no-explicit-any */
|
||||||
@@ -209,3 +218,6 @@ export const selectIsolatedStagingPreview = createCanvasSettingsSelector((settin
|
|||||||
export const selectIsolatedLayerPreview = createCanvasSettingsSelector((settings) => settings.isolatedLayerPreview);
|
export const selectIsolatedLayerPreview = createCanvasSettingsSelector((settings) => settings.isolatedLayerPreview);
|
||||||
export const selectPressureSensitivity = createCanvasSettingsSelector((settings) => settings.pressureSensitivity);
|
export const selectPressureSensitivity = createCanvasSettingsSelector((settings) => settings.pressureSensitivity);
|
||||||
export const selectRuleOfThirds = createCanvasSettingsSelector((settings) => settings.ruleOfThirds);
|
export const selectRuleOfThirds = createCanvasSettingsSelector((settings) => settings.ruleOfThirds);
|
||||||
|
export const selectSaveAllStagingImagesToGallery = createCanvasSettingsSelector(
|
||||||
|
(settings) => settings.saveAllStagingImagesToGallery
|
||||||
|
);
|
||||||
|
|||||||
@@ -55,9 +55,7 @@ export const ModelInstallQueue = memo(() => {
|
|||||||
<Box layerStyle="first" p={3} borderRadius="base" w="full" h="full">
|
<Box layerStyle="first" p={3} borderRadius="base" w="full" h="full">
|
||||||
<ScrollableContent>
|
<ScrollableContent>
|
||||||
<Flex flexDir="column-reverse" gap="2" w="full">
|
<Flex flexDir="column-reverse" gap="2" w="full">
|
||||||
{data?.map((model) => (
|
{data?.map((model) => <ModelInstallQueueItem key={model.id} installJob={model} />)}
|
||||||
<ModelInstallQueueItem key={model.id} installJob={model} />
|
|
||||||
))}
|
|
||||||
</Flex>
|
</Flex>
|
||||||
</ScrollableContent>
|
</ScrollableContent>
|
||||||
</Box>
|
</Box>
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { createSelector } from '@reduxjs/toolkit';
|
import { createSelector } from '@reduxjs/toolkit';
|
||||||
import type { RootState } from 'app/store/store';
|
import type { RootState } from 'app/store/store';
|
||||||
import { getPrefixedId } from 'features/controlLayers/konva/util';
|
import { getPrefixedId } from 'features/controlLayers/konva/util';
|
||||||
|
import { selectSaveAllStagingImagesToGallery } from 'features/controlLayers/store/canvasSettingsSlice';
|
||||||
import {
|
import {
|
||||||
selectImg2imgStrength,
|
selectImg2imgStrength,
|
||||||
selectMainModelConfig,
|
selectMainModelConfig,
|
||||||
@@ -44,8 +45,11 @@ export const selectCanvasOutputFields = (state: RootState) => {
|
|||||||
// Advanced session means working on canvas - images are not saved to gallery or added to a board.
|
// Advanced session means working on canvas - images are not saved to gallery or added to a board.
|
||||||
// Simple session means working in YOLO mode - images are saved to gallery & board.
|
// Simple session means working in YOLO mode - images are saved to gallery & board.
|
||||||
const tab = selectActiveTab(state);
|
const tab = selectActiveTab(state);
|
||||||
const is_intermediate = tab === 'canvas';
|
const saveAllStagingImagesToGallery = selectSaveAllStagingImagesToGallery(state);
|
||||||
const board = tab === 'canvas' ? undefined : getBoardField(state);
|
|
||||||
|
// If we're on canvas and the save all staging images setting is enabled, save to gallery
|
||||||
|
const is_intermediate = tab === 'canvas' && !saveAllStagingImagesToGallery;
|
||||||
|
const board = tab === 'canvas' && !saveAllStagingImagesToGallery ? undefined : getBoardField(state);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
is_intermediate,
|
is_intermediate,
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import { ContextMenu, Divider, Flex, IconButton, Menu, MenuButton, MenuList } fr
|
|||||||
import { useAppSelector } from 'app/store/storeHooks';
|
import { useAppSelector } from 'app/store/storeHooks';
|
||||||
import { CanvasAlertsInvocationProgress } from 'features/controlLayers/components/CanvasAlerts/CanvasAlertsInvocationProgress';
|
import { CanvasAlertsInvocationProgress } from 'features/controlLayers/components/CanvasAlerts/CanvasAlertsInvocationProgress';
|
||||||
import { CanvasAlertsPreserveMask } from 'features/controlLayers/components/CanvasAlerts/CanvasAlertsPreserveMask';
|
import { CanvasAlertsPreserveMask } from 'features/controlLayers/components/CanvasAlerts/CanvasAlertsPreserveMask';
|
||||||
|
import { CanvasAlertsSaveAllStagingImagesToGallery } from 'features/controlLayers/components/CanvasAlerts/CanvasAlertsSaveAllStagingImagesToGallery';
|
||||||
import { CanvasAlertsSelectedEntityStatus } from 'features/controlLayers/components/CanvasAlerts/CanvasAlertsSelectedEntityStatus';
|
import { CanvasAlertsSelectedEntityStatus } from 'features/controlLayers/components/CanvasAlerts/CanvasAlertsSelectedEntityStatus';
|
||||||
import { CanvasBusySpinner } from 'features/controlLayers/components/CanvasBusySpinner';
|
import { CanvasBusySpinner } from 'features/controlLayers/components/CanvasBusySpinner';
|
||||||
import { CanvasContextMenuGlobalMenuItems } from 'features/controlLayers/components/CanvasContextMenu/CanvasContextMenuGlobalMenuItems';
|
import { CanvasContextMenuGlobalMenuItems } from 'features/controlLayers/components/CanvasContextMenu/CanvasContextMenuGlobalMenuItems';
|
||||||
@@ -88,6 +89,7 @@ export const CanvasWorkspacePanel = memo(() => {
|
|||||||
{showHUD && <CanvasHUD />}
|
{showHUD && <CanvasHUD />}
|
||||||
<CanvasAlertsSelectedEntityStatus />
|
<CanvasAlertsSelectedEntityStatus />
|
||||||
<CanvasAlertsPreserveMask />
|
<CanvasAlertsPreserveMask />
|
||||||
|
<CanvasAlertsSaveAllStagingImagesToGallery />
|
||||||
<CanvasAlertsInvocationProgress />
|
<CanvasAlertsInvocationProgress />
|
||||||
</Flex>
|
</Flex>
|
||||||
<Flex position="absolute" top={1} insetInlineEnd={1}>
|
<Flex position="absolute" top={1} insetInlineEnd={1}>
|
||||||
|
|||||||
Reference in New Issue
Block a user