@@ -7,44 +7,56 @@ import { useCanvasManager } from 'features/controlLayers/contexts/CanvasManagerP
77import { useEntityIdentifierContext } from 'features/controlLayers/contexts/EntityIdentifierContext' ;
88import {
99 rasterLayerAdjustmentsCancel ,
10+ rasterLayerAdjustmentsCollapsedToggled ,
11+ rasterLayerAdjustmentsEnabledToggled ,
12+ rasterLayerAdjustmentsModeChanged ,
1013 rasterLayerAdjustmentsReset ,
1114 rasterLayerAdjustmentsSet ,
1215} from 'features/controlLayers/store/canvasSlice' ;
1316import { selectCanvasSlice , selectEntity } from 'features/controlLayers/store/selectors' ;
14- import { makeDefaultRasterLayerAdjustments } from 'features/controlLayers/store/util' ;
1517import React , { memo , useCallback , useMemo } from 'react' ;
1618import { useTranslation } from 'react-i18next' ;
1719import { PiArrowCounterClockwiseBold , PiCaretDownBold , PiCheckBold , PiTrashBold } from 'react-icons/pi' ;
1820
1921export const RasterLayerAdjustmentsPanel = memo ( ( ) => {
22+ const { t } = useTranslation ( ) ;
2023 const dispatch = useAppDispatch ( ) ;
2124 const entityIdentifier = useEntityIdentifierContext < 'raster_layer' > ( ) ;
2225 const canvasManager = useCanvasManager ( ) ;
23- const selectAdjustments = useMemo ( ( ) => {
24- return createSelector ( selectCanvasSlice , ( canvas ) => selectEntity ( canvas , entityIdentifier ) ?. adjustments ) ;
26+
27+ const selectHasAdjustments = useMemo ( ( ) => {
28+ return createSelector ( selectCanvasSlice , ( canvas ) => Boolean ( selectEntity ( canvas , entityIdentifier ) ?. adjustments ) ) ;
2529 } , [ entityIdentifier ] ) ;
2630
27- const adjustments = useAppSelector ( selectAdjustments ) ;
28- const { t } = useTranslation ( ) ;
31+ const hasAdjustments = useAppSelector ( selectHasAdjustments ) ;
2932
30- const hasAdjustments = Boolean ( adjustments ) ;
31- const enabled = Boolean ( adjustments ?. enabled ) ;
32- const collapsed = Boolean ( adjustments ?. collapsed ) ;
33- const mode = adjustments ?. mode ?? 'simple' ;
34-
35- const onToggleEnabled = useCallback (
36- ( e : React . ChangeEvent < HTMLInputElement > ) => {
37- const v = e . target . checked ;
38- const current = adjustments ?? makeDefaultRasterLayerAdjustments ( mode ) ;
39- dispatch (
40- rasterLayerAdjustmentsSet ( {
41- entityIdentifier,
42- adjustments : { ...current , enabled : v } ,
43- } )
44- ) ;
45- } ,
46- [ dispatch , entityIdentifier , adjustments , mode ]
47- ) ;
33+ const selectMode = useMemo ( ( ) => {
34+ return createSelector (
35+ selectCanvasSlice ,
36+ ( canvas ) => selectEntity ( canvas , entityIdentifier ) ?. adjustments ?. mode ?? 'simple'
37+ ) ;
38+ } , [ entityIdentifier ] ) ;
39+ const mode = useAppSelector ( selectMode ) ;
40+
41+ const selectEnabled = useMemo ( ( ) => {
42+ return createSelector (
43+ selectCanvasSlice ,
44+ ( canvas ) => selectEntity ( canvas , entityIdentifier ) ?. adjustments ?. enabled ?? false
45+ ) ;
46+ } , [ entityIdentifier ] ) ;
47+ const enabled = useAppSelector ( selectEnabled ) ;
48+
49+ const selectCollapsed = useMemo ( ( ) => {
50+ return createSelector (
51+ selectCanvasSlice ,
52+ ( canvas ) => selectEntity ( canvas , entityIdentifier ) ?. adjustments ?. collapsed ?? false
53+ ) ;
54+ } , [ entityIdentifier ] ) ;
55+ const collapsed = useAppSelector ( selectCollapsed ) ;
56+
57+ const onToggleEnabled = useCallback ( ( ) => {
58+ dispatch ( rasterLayerAdjustmentsEnabledToggled ( { entityIdentifier } ) ) ;
59+ } , [ dispatch , entityIdentifier ] ) ;
4860
4961 const onReset = useCallback ( ( ) => {
5062 // Reset values to defaults but keep adjustments present; preserve enabled/collapsed/mode
@@ -57,34 +69,18 @@ export const RasterLayerAdjustmentsPanel = memo(() => {
5769 } , [ dispatch , entityIdentifier ] ) ;
5870
5971 const onToggleCollapsed = useCallback ( ( ) => {
60- const current = adjustments ?? makeDefaultRasterLayerAdjustments ( mode ) ;
61- dispatch (
62- rasterLayerAdjustmentsSet ( {
63- entityIdentifier,
64- adjustments : { ...current , collapsed : ! collapsed } ,
65- } )
66- ) ;
67- } , [ dispatch , entityIdentifier , collapsed , adjustments , mode ] ) ;
68-
69- const onSetMode = useCallback (
70- ( nextMode : 'simple' | 'curves' ) => {
71- if ( nextMode === mode ) {
72- return ;
73- }
74- const current = adjustments ?? makeDefaultRasterLayerAdjustments ( nextMode ) ;
75- dispatch (
76- rasterLayerAdjustmentsSet ( {
77- entityIdentifier,
78- adjustments : { ...current , mode : nextMode } ,
79- } )
80- ) ;
81- } ,
82- [ dispatch , entityIdentifier , adjustments , mode ]
72+ dispatch ( rasterLayerAdjustmentsCollapsedToggled ( { entityIdentifier } ) ) ;
73+ } , [ dispatch , entityIdentifier ] ) ;
74+
75+ const onClickModeSimple = useCallback (
76+ ( ) => dispatch ( rasterLayerAdjustmentsModeChanged ( { entityIdentifier, mode : 'simple' } ) ) ,
77+ [ dispatch , entityIdentifier ]
8378 ) ;
8479
85- // Memoized click handlers to avoid inline arrow functions in JSX
86- const onClickModeSimple = useCallback ( ( ) => onSetMode ( 'simple' ) , [ onSetMode ] ) ;
87- const onClickModeCurves = useCallback ( ( ) => onSetMode ( 'curves' ) , [ onSetMode ] ) ;
80+ const onClickModeCurves = useCallback (
81+ ( ) => dispatch ( rasterLayerAdjustmentsModeChanged ( { entityIdentifier, mode : 'curves' } ) ) ,
82+ [ dispatch , entityIdentifier ]
83+ ) ;
8884
8985 const onFinish = useCallback ( async ( ) => {
9086 // Bake current visual into layer pixels, then clear adjustments
@@ -137,7 +133,7 @@ export const RasterLayerAdjustmentsPanel = memo(() => {
137133 aria-label = { t ( 'controlLayers.adjustments.cancel' ) }
138134 size = "md"
139135 onClick = { onCancel }
140- isDisabled = { ! adjustments }
136+ isDisabled = { ! hasAdjustments }
141137 colorScheme = "red"
142138 icon = { < PiTrashBold /> }
143139 variant = "ghost"
@@ -146,15 +142,15 @@ export const RasterLayerAdjustmentsPanel = memo(() => {
146142 aria-label = { t ( 'controlLayers.adjustments.reset' ) }
147143 size = "md"
148144 onClick = { onReset }
149- isDisabled = { ! adjustments }
145+ isDisabled = { ! hasAdjustments }
150146 icon = { < PiArrowCounterClockwiseBold /> }
151147 variant = "ghost"
152148 />
153149 < IconButton
154150 aria-label = { t ( 'controlLayers.adjustments.finish' ) }
155151 size = "md"
156152 onClick = { onFinish }
157- isDisabled = { ! adjustments }
153+ isDisabled = { ! hasAdjustments }
158154 colorScheme = "green"
159155 icon = { < PiCheckBold /> }
160156 variant = "ghost"
0 commit comments