mirror of
https://github.com/invoke-ai/InvokeAI.git
synced 2026-04-23 03:00:31 -04:00
simplify adjustments type to optional not null
This commit is contained in:
committed by
psychedelicious
parent
32c2d3f740
commit
5991067fd9
@@ -20,6 +20,7 @@ import {
|
||||
rasterLayerAdjustmentsSimpleUpdated,
|
||||
} from 'features/controlLayers/store/canvasSlice';
|
||||
import { selectEntity } from 'features/controlLayers/store/selectors';
|
||||
import { makeDefaultRasterLayerAdjustments } from 'features/controlLayers/store/util';
|
||||
import React, { memo, useCallback } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { PiCaretDownBold } from 'react-icons/pi';
|
||||
@@ -66,10 +67,15 @@ export const RasterLayerAdjustmentsPanel = memo(() => {
|
||||
|
||||
const onToggleEnabled = useCallback(
|
||||
(v: boolean) => {
|
||||
// Only toggle the enabled state; preserve current mode/collapsed so users can A/B compare
|
||||
dispatch(rasterLayerAdjustmentsSet({ entityIdentifier, adjustments: { enabled: v } }));
|
||||
const current = layer?.adjustments ?? makeDefaultRasterLayerAdjustments(mode);
|
||||
dispatch(
|
||||
rasterLayerAdjustmentsSet({
|
||||
entityIdentifier,
|
||||
adjustments: { ...current, enabled: v },
|
||||
})
|
||||
);
|
||||
},
|
||||
[dispatch, entityIdentifier]
|
||||
[dispatch, entityIdentifier, layer?.adjustments, mode]
|
||||
);
|
||||
|
||||
const onReset = useCallback(() => {
|
||||
@@ -98,26 +104,25 @@ export const RasterLayerAdjustmentsPanel = memo(() => {
|
||||
}, [dispatch, entityIdentifier]);
|
||||
|
||||
const onToggleCollapsed = useCallback(() => {
|
||||
const current = layer?.adjustments ?? makeDefaultRasterLayerAdjustments(mode);
|
||||
dispatch(
|
||||
rasterLayerAdjustmentsSet({
|
||||
entityIdentifier,
|
||||
adjustments: { collapsed: !collapsed },
|
||||
adjustments: { ...current, collapsed: !collapsed },
|
||||
})
|
||||
);
|
||||
}, [dispatch, entityIdentifier, collapsed]);
|
||||
}, [dispatch, entityIdentifier, collapsed, layer?.adjustments, mode]);
|
||||
|
||||
const onSetMode = useCallback(
|
||||
(nextMode: 'simple' | 'curves') => {
|
||||
if (!layer?.adjustments) {
|
||||
return;
|
||||
}
|
||||
if (nextMode === mode) {
|
||||
return;
|
||||
}
|
||||
const current = layer?.adjustments ?? makeDefaultRasterLayerAdjustments(nextMode);
|
||||
dispatch(
|
||||
rasterLayerAdjustmentsSet({
|
||||
entityIdentifier,
|
||||
adjustments: { mode: nextMode },
|
||||
adjustments: { ...current, mode: nextMode },
|
||||
})
|
||||
);
|
||||
},
|
||||
@@ -215,12 +220,35 @@ export const RasterLayerAdjustmentsPanel = memo(() => {
|
||||
|
||||
{!collapsed && mode === 'simple' && (
|
||||
<>
|
||||
<AdjustmentSliderRow label={t('controlLayers.adjustments.brightness')} value={simple.brightness} onChange={onBrightness} />
|
||||
<AdjustmentSliderRow label={t('controlLayers.adjustments.contrast')} value={simple.contrast} onChange={onContrast} />
|
||||
<AdjustmentSliderRow label={t('controlLayers.adjustments.saturation')} value={simple.saturation} onChange={onSaturation} />
|
||||
<AdjustmentSliderRow label={t('controlLayers.adjustments.temperature')} value={simple.temperature} onChange={onTemperature} />
|
||||
<AdjustmentSliderRow
|
||||
label={t('controlLayers.adjustments.brightness')}
|
||||
value={simple.brightness}
|
||||
onChange={onBrightness}
|
||||
/>
|
||||
<AdjustmentSliderRow
|
||||
label={t('controlLayers.adjustments.contrast')}
|
||||
value={simple.contrast}
|
||||
onChange={onContrast}
|
||||
/>
|
||||
<AdjustmentSliderRow
|
||||
label={t('controlLayers.adjustments.saturation')}
|
||||
value={simple.saturation}
|
||||
onChange={onSaturation}
|
||||
/>
|
||||
<AdjustmentSliderRow
|
||||
label={t('controlLayers.adjustments.temperature')}
|
||||
value={simple.temperature}
|
||||
onChange={onTemperature}
|
||||
/>
|
||||
<AdjustmentSliderRow label={t('controlLayers.adjustments.tint')} value={simple.tint} onChange={onTint} />
|
||||
<AdjustmentSliderRow label={t('controlLayers.adjustments.sharpness')} value={simple.sharpness} onChange={onSharpness} min={0} max={1} step={0.01} />
|
||||
<AdjustmentSliderRow
|
||||
label={t('controlLayers.adjustments.sharpness')}
|
||||
value={simple.sharpness}
|
||||
onChange={onSharpness}
|
||||
min={0}
|
||||
max={1}
|
||||
step={0.01}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import { Flex, Text, Box } from '@invoke-ai/ui-library';
|
||||
import { Box, Flex, Text } from '@invoke-ai/ui-library';
|
||||
import { createSelector } from '@reduxjs/toolkit';
|
||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||
import { useEntityAdapterContext } from 'features/controlLayers/contexts/EntityAdapterContext';
|
||||
import { useEntityIdentifierContext } from 'features/controlLayers/contexts/EntityIdentifierContext';
|
||||
import { rasterLayerAdjustmentsCurvesUpdated } from 'features/controlLayers/store/canvasSlice';
|
||||
import { selectEntity, selectCanvasSlice } from 'features/controlLayers/store/selectors';
|
||||
import { createSelector } from '@reduxjs/toolkit';
|
||||
import { selectCanvasSlice, selectEntity } from 'features/controlLayers/store/selectors';
|
||||
import React, { memo, useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
@@ -307,8 +307,7 @@ export const RasterLayerCurvesEditor = memo(() => {
|
||||
const adapter = useEntityAdapterContext<'raster_layer'>('raster_layer');
|
||||
const { t } = useTranslation();
|
||||
const selectLayer = useMemo(
|
||||
() =>
|
||||
createSelector(selectCanvasSlice, (canvas) => selectEntity(canvas, entityIdentifier)),
|
||||
() => createSelector(selectCanvasSlice, (canvas) => selectEntity(canvas, entityIdentifier)),
|
||||
[entityIdentifier]
|
||||
);
|
||||
const layer = useAppSelector(selectLayer);
|
||||
|
||||
@@ -3,6 +3,7 @@ import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||
import { useEntityIdentifierContext } from 'features/controlLayers/contexts/EntityIdentifierContext';
|
||||
import { rasterLayerAdjustmentsReset, rasterLayerAdjustmentsSet } from 'features/controlLayers/store/canvasSlice';
|
||||
import type { CanvasRasterLayerState } from 'features/controlLayers/store/types';
|
||||
import { makeDefaultRasterLayerAdjustments } from 'features/controlLayers/store/util';
|
||||
import { memo, useCallback } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { PiSlidersHorizontalBold } from 'react-icons/pi';
|
||||
@@ -22,7 +23,7 @@ export const RasterLayerMenuItemsAdjustments = memo(() => {
|
||||
dispatch(
|
||||
rasterLayerAdjustmentsSet({
|
||||
entityIdentifier,
|
||||
adjustments: { enabled: true, collapsed: false, mode: 'simple' },
|
||||
adjustments: makeDefaultRasterLayerAdjustments('simple'),
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
@@ -96,6 +96,8 @@ import {
|
||||
initialFLUXRedux,
|
||||
initialIPAdapter,
|
||||
initialT2IAdapter,
|
||||
makeDefaultRasterLayerAdjustments,
|
||||
type RasterLayerAdjustments,
|
||||
} from './util';
|
||||
|
||||
const slice = createSlice({
|
||||
@@ -109,10 +111,7 @@ const slice = createSlice({
|
||||
action: PayloadAction<
|
||||
EntityIdentifierPayload<
|
||||
{
|
||||
adjustments:
|
||||
| NonNullable<CanvasRasterLayerState['adjustments']>
|
||||
| { enabled?: boolean; collapsed?: boolean; mode?: 'simple' | 'curves' }
|
||||
| null;
|
||||
adjustments: RasterLayerAdjustments | null;
|
||||
},
|
||||
'raster_layer'
|
||||
>
|
||||
@@ -124,43 +123,13 @@ const slice = createSlice({
|
||||
return;
|
||||
}
|
||||
if (adjustments === null) {
|
||||
layer.adjustments = null;
|
||||
delete layer.adjustments;
|
||||
return;
|
||||
}
|
||||
if (layer.adjustments === null) {
|
||||
layer.adjustments = {
|
||||
version: 1,
|
||||
enabled: true,
|
||||
collapsed: false,
|
||||
mode: 'simple',
|
||||
simple: { brightness: 0, contrast: 0, saturation: 0, temperature: 0, tint: 0, sharpness: 0 },
|
||||
curves: {
|
||||
master: [
|
||||
[0, 0],
|
||||
[255, 255],
|
||||
],
|
||||
r: [
|
||||
[0, 0],
|
||||
[255, 255],
|
||||
],
|
||||
g: [
|
||||
[0, 0],
|
||||
[255, 255],
|
||||
],
|
||||
b: [
|
||||
[0, 0],
|
||||
[255, 255],
|
||||
],
|
||||
},
|
||||
};
|
||||
}
|
||||
if (typeof adjustments === 'object' && adjustments !== null && 'version' in adjustments) {
|
||||
layer.adjustments = merge(layer.adjustments, adjustments as NonNullable<CanvasRasterLayerState['adjustments']>);
|
||||
} else {
|
||||
// Shallow toggles only
|
||||
const partial = adjustments as { enabled?: boolean; collapsed?: boolean; mode?: 'simple' | 'curves' };
|
||||
layer.adjustments = merge(layer.adjustments, partial);
|
||||
if (!layer.adjustments) {
|
||||
layer.adjustments = makeDefaultRasterLayerAdjustments(adjustments.mode ?? 'simple');
|
||||
}
|
||||
layer.adjustments = merge(layer.adjustments, adjustments);
|
||||
},
|
||||
rasterLayerAdjustmentsReset: (state, action: PayloadAction<EntityIdentifierPayload<void, 'raster_layer'>>) => {
|
||||
const { entityIdentifier } = action.payload;
|
||||
@@ -168,14 +137,14 @@ const slice = createSlice({
|
||||
if (!layer) {
|
||||
return;
|
||||
}
|
||||
layer.adjustments = null;
|
||||
delete layer.adjustments;
|
||||
},
|
||||
rasterLayerAdjustmentsSimpleUpdated: (
|
||||
state,
|
||||
action: PayloadAction<
|
||||
EntityIdentifierPayload<
|
||||
{
|
||||
simple: Partial<NonNullable<NonNullable<CanvasRasterLayerState['adjustments']>['simple']>>;
|
||||
simple: Partial<RasterLayerAdjustments['simple']>;
|
||||
},
|
||||
'raster_layer'
|
||||
>
|
||||
@@ -187,32 +156,7 @@ const slice = createSlice({
|
||||
return;
|
||||
}
|
||||
if (!layer.adjustments) {
|
||||
// initialize baseline
|
||||
layer.adjustments = {
|
||||
version: 1,
|
||||
enabled: true,
|
||||
collapsed: false,
|
||||
mode: 'simple',
|
||||
simple: { brightness: 0, contrast: 0, saturation: 0, temperature: 0, tint: 0, sharpness: 0 },
|
||||
curves: {
|
||||
master: [
|
||||
[0, 0],
|
||||
[255, 255],
|
||||
],
|
||||
r: [
|
||||
[0, 0],
|
||||
[255, 255],
|
||||
],
|
||||
g: [
|
||||
[0, 0],
|
||||
[255, 255],
|
||||
],
|
||||
b: [
|
||||
[0, 0],
|
||||
[255, 255],
|
||||
],
|
||||
},
|
||||
};
|
||||
layer.adjustments = makeDefaultRasterLayerAdjustments('simple');
|
||||
}
|
||||
layer.adjustments.simple = merge(layer.adjustments.simple, simple);
|
||||
},
|
||||
@@ -234,32 +178,7 @@ const slice = createSlice({
|
||||
return;
|
||||
}
|
||||
if (!layer.adjustments) {
|
||||
// initialize baseline
|
||||
layer.adjustments = {
|
||||
version: 1,
|
||||
enabled: true,
|
||||
collapsed: false,
|
||||
mode: 'curves',
|
||||
simple: { brightness: 0, contrast: 0, saturation: 0, temperature: 0, tint: 0, sharpness: 0 },
|
||||
curves: {
|
||||
master: [
|
||||
[0, 0],
|
||||
[255, 255],
|
||||
],
|
||||
r: [
|
||||
[0, 0],
|
||||
[255, 255],
|
||||
],
|
||||
g: [
|
||||
[0, 0],
|
||||
[255, 255],
|
||||
],
|
||||
b: [
|
||||
[0, 0],
|
||||
[255, 255],
|
||||
],
|
||||
},
|
||||
};
|
||||
layer.adjustments = makeDefaultRasterLayerAdjustments('curves');
|
||||
}
|
||||
layer.adjustments.curves[channel] = points;
|
||||
},
|
||||
|
||||
@@ -383,7 +383,7 @@ const zCanvasRasterLayerState = zCanvasEntityBase.extend({
|
||||
position: zCoordinate,
|
||||
opacity: zOpacity,
|
||||
objects: z.array(zCanvasObjectState),
|
||||
// Optional per-layer color adjustments (simple + curves). When null/undefined, no adjustments are applied.
|
||||
// Optional per-layer color adjustments (simple + curves). When undefined, no adjustments are applied.
|
||||
adjustments: z
|
||||
.object({
|
||||
version: z.literal(1),
|
||||
@@ -407,8 +407,7 @@ const zCanvasRasterLayerState = zCanvasEntityBase.extend({
|
||||
b: z.array(z.tuple([z.number().int().min(0).max(255), z.number().int().min(0).max(255)])).min(2),
|
||||
}),
|
||||
})
|
||||
.optional()
|
||||
.nullable(),
|
||||
.optional(),
|
||||
});
|
||||
export type CanvasRasterLayerState = z.infer<typeof zCanvasRasterLayerState>;
|
||||
|
||||
|
||||
@@ -118,6 +118,34 @@ export const initialControlLoRA: ControlLoRAConfig = {
|
||||
weight: 0.75,
|
||||
};
|
||||
|
||||
export type RasterLayerAdjustments = NonNullable<CanvasRasterLayerState['adjustments']>;
|
||||
|
||||
export const makeDefaultRasterLayerAdjustments = (mode: 'simple' | 'curves' = 'simple'): RasterLayerAdjustments => ({
|
||||
version: 1,
|
||||
enabled: true,
|
||||
collapsed: false,
|
||||
mode,
|
||||
simple: { brightness: 0, contrast: 0, saturation: 0, temperature: 0, tint: 0, sharpness: 0 },
|
||||
curves: {
|
||||
master: [
|
||||
[0, 0],
|
||||
[255, 255],
|
||||
],
|
||||
r: [
|
||||
[0, 0],
|
||||
[255, 255],
|
||||
],
|
||||
g: [
|
||||
[0, 0],
|
||||
[255, 255],
|
||||
],
|
||||
b: [
|
||||
[0, 0],
|
||||
[255, 255],
|
||||
],
|
||||
},
|
||||
});
|
||||
|
||||
export const getReferenceImageState = (id: string, overrides?: PartialDeep<RefImageState>): RefImageState => {
|
||||
const entityState: RefImageState = {
|
||||
id,
|
||||
@@ -187,7 +215,7 @@ export const getRasterLayerState = (
|
||||
objects: [],
|
||||
opacity: 1,
|
||||
position: { x: 0, y: 0 },
|
||||
adjustments: null,
|
||||
adjustments: undefined,
|
||||
};
|
||||
merge(entityState, overrides);
|
||||
return entityState;
|
||||
|
||||
Reference in New Issue
Block a user