1
1
import { Button , ButtonGroup , Flex , IconButton , Switch , Text } from '@invoke-ai/ui-library' ;
2
+ import { createSelector } from '@reduxjs/toolkit' ;
2
3
import { useAppDispatch , useAppSelector } from 'app/store/storeHooks' ;
3
4
import { RasterLayerCurvesAdjustmentsEditor } from 'features/controlLayers/components/RasterLayer/RasterLayerCurvesAdjustmentsEditor' ;
4
5
import { RasterLayerSimpleAdjustmentsEditor } from 'features/controlLayers/components/RasterLayer/RasterLayerSimpleAdjustmentsEditor' ;
@@ -10,36 +11,40 @@ import {
10
11
rasterLayerAdjustmentsSet ,
11
12
rasterLayerAdjustmentsSimpleUpdated ,
12
13
} from 'features/controlLayers/store/canvasSlice' ;
13
- import { selectEntity } from 'features/controlLayers/store/selectors' ;
14
+ import { selectCanvasSlice , selectEntity } from 'features/controlLayers/store/selectors' ;
14
15
import { makeDefaultRasterLayerAdjustments } from 'features/controlLayers/store/util' ;
15
- import React , { memo , useCallback } from 'react' ;
16
+ import React , { memo , useCallback , useMemo } from 'react' ;
16
17
import { useTranslation } from 'react-i18next' ;
17
18
import { PiArrowCounterClockwiseBold , PiCaretDownBold , PiCheckBold , PiTrashBold } from 'react-icons/pi' ;
18
19
19
20
export const RasterLayerAdjustmentsPanel = memo ( ( ) => {
20
21
const dispatch = useAppDispatch ( ) ;
21
22
const entityIdentifier = useEntityIdentifierContext < 'raster_layer' > ( ) ;
22
23
const canvasManager = useCanvasManager ( ) ;
23
- const layer = useAppSelector ( ( s ) => selectEntity ( s . canvas . present , entityIdentifier ) ) ;
24
+ const selectAdjustments = useMemo ( ( ) => {
25
+ return createSelector ( selectCanvasSlice , ( canvas ) => selectEntity ( canvas , entityIdentifier ) ?. adjustments ) ;
26
+ } , [ entityIdentifier ] ) ;
27
+
28
+ const adjustments = useAppSelector ( selectAdjustments ) ;
24
29
const { t } = useTranslation ( ) ;
25
30
26
- const hasAdjustments = Boolean ( layer ?. adjustments ) ;
27
- const enabled = Boolean ( layer ?. adjustments ?. enabled ) ;
28
- const collapsed = Boolean ( layer ?. adjustments ?. collapsed ) ;
29
- const mode = layer ?. adjustments ?. mode ?? 'simple' ;
31
+ const hasAdjustments = Boolean ( adjustments ) ;
32
+ const enabled = Boolean ( adjustments ?. enabled ) ;
33
+ const collapsed = Boolean ( adjustments ?. collapsed ) ;
34
+ const mode = adjustments ?. mode ?? 'simple' ;
30
35
31
36
const onToggleEnabled = useCallback (
32
37
( e : React . ChangeEvent < HTMLInputElement > ) => {
33
38
const v = e . target . checked ;
34
- const current = layer ?. adjustments ?? makeDefaultRasterLayerAdjustments ( mode ) ;
39
+ const current = adjustments ?? makeDefaultRasterLayerAdjustments ( mode ) ;
35
40
dispatch (
36
41
rasterLayerAdjustmentsSet ( {
37
42
entityIdentifier,
38
43
adjustments : { ...current , enabled : v } ,
39
44
} )
40
45
) ;
41
46
} ,
42
- [ dispatch , entityIdentifier , layer ?. adjustments , mode ]
47
+ [ dispatch , entityIdentifier , adjustments , mode ]
43
48
) ;
44
49
45
50
const onReset = useCallback ( ( ) => {
@@ -73,29 +78,29 @@ export const RasterLayerAdjustmentsPanel = memo(() => {
73
78
} , [ dispatch , entityIdentifier ] ) ;
74
79
75
80
const onToggleCollapsed = useCallback ( ( ) => {
76
- const current = layer ?. adjustments ?? makeDefaultRasterLayerAdjustments ( mode ) ;
81
+ const current = adjustments ?? makeDefaultRasterLayerAdjustments ( mode ) ;
77
82
dispatch (
78
83
rasterLayerAdjustmentsSet ( {
79
84
entityIdentifier,
80
85
adjustments : { ...current , collapsed : ! collapsed } ,
81
86
} )
82
87
) ;
83
- } , [ dispatch , entityIdentifier , collapsed , layer ?. adjustments , mode ] ) ;
88
+ } , [ dispatch , entityIdentifier , collapsed , adjustments , mode ] ) ;
84
89
85
90
const onSetMode = useCallback (
86
91
( nextMode : 'simple' | 'curves' ) => {
87
92
if ( nextMode === mode ) {
88
93
return ;
89
94
}
90
- const current = layer ?. adjustments ?? makeDefaultRasterLayerAdjustments ( nextMode ) ;
95
+ const current = adjustments ?? makeDefaultRasterLayerAdjustments ( nextMode ) ;
91
96
dispatch (
92
97
rasterLayerAdjustmentsSet ( {
93
98
entityIdentifier,
94
99
adjustments : { ...current , mode : nextMode } ,
95
100
} )
96
101
) ;
97
102
} ,
98
- [ dispatch , entityIdentifier , layer ?. adjustments , mode ]
103
+ [ dispatch , entityIdentifier , adjustments , mode ]
99
104
) ;
100
105
101
106
// Memoized click handlers to avoid inline arrow functions in JSX
@@ -125,7 +130,7 @@ export const RasterLayerAdjustmentsPanel = memo(() => {
125
130
126
131
return (
127
132
< >
128
- < Flex px = { 4 } alignItems = "center" gap = { 3 } mt = { 2 } mb = { 2 } >
133
+ < Flex p = { 2 } alignItems = "center" gap = { 2 } >
129
134
< IconButton
130
135
aria-label = { collapsed ? t ( 'controlLayers.adjustments.expand' ) : t ( 'controlLayers.adjustments.collapse' ) }
131
136
size = "sm"
@@ -141,18 +146,10 @@ export const RasterLayerAdjustmentsPanel = memo(() => {
141
146
Adjustments
142
147
</ Text >
143
148
< ButtonGroup size = "sm" isAttached variant = "outline" >
144
- < Button
145
- onClick = { onClickModeSimple }
146
- isActive = { mode === 'simple' }
147
- colorScheme = { mode === 'simple' ? 'invokeBlue' : undefined }
148
- >
149
+ < Button onClick = { onClickModeSimple } colorScheme = { mode === 'simple' ? 'invokeBlue' : undefined } >
149
150
{ t ( 'controlLayers.adjustments.simple' ) }
150
151
</ Button >
151
- < Button
152
- onClick = { onClickModeCurves }
153
- isActive = { mode === 'curves' }
154
- colorScheme = { mode === 'curves' ? 'invokeBlue' : undefined }
155
- >
152
+ < Button onClick = { onClickModeCurves } colorScheme = { mode === 'curves' ? 'invokeBlue' : undefined } >
156
153
{ t ( 'controlLayers.adjustments.curves' ) }
157
154
</ Button >
158
155
</ ButtonGroup >
@@ -161,7 +158,7 @@ export const RasterLayerAdjustmentsPanel = memo(() => {
161
158
aria-label = { t ( 'controlLayers.adjustments.cancel' ) }
162
159
size = "md"
163
160
onClick = { onCancel }
164
- isDisabled = { ! layer ?. adjustments }
161
+ isDisabled = { ! adjustments }
165
162
colorScheme = "red"
166
163
icon = { < PiTrashBold /> }
167
164
variant = "ghost"
@@ -170,15 +167,15 @@ export const RasterLayerAdjustmentsPanel = memo(() => {
170
167
aria-label = { t ( 'controlLayers.adjustments.reset' ) }
171
168
size = "md"
172
169
onClick = { onReset }
173
- isDisabled = { ! layer ?. adjustments }
170
+ isDisabled = { ! adjustments }
174
171
icon = { < PiArrowCounterClockwiseBold /> }
175
172
variant = "ghost"
176
173
/>
177
174
< IconButton
178
175
aria-label = { t ( 'controlLayers.adjustments.finish' ) }
179
176
size = "md"
180
177
onClick = { onFinish }
181
- isDisabled = { ! layer ?. adjustments }
178
+ isDisabled = { ! adjustments }
182
179
colorScheme = "green"
183
180
icon = { < PiCheckBold /> }
184
181
variant = "ghost"
0 commit comments