1
1
import { CompositeNumberInput , Flex , FormControl , FormLabel , Select , Switch } from '@invoke-ai/ui-library' ;
2
2
import { useAppDispatch } from 'app/store/storeHooks' ;
3
+ import { roundDownToMultiple , roundUpToMultiple } from 'common/util/roundDownToMultiple' ;
3
4
import { useIntegerField } from 'features/nodes/components/flow/nodes/Invocation/fields/IntegerField/useIntegerField' ;
4
5
import { useInputFieldInstance } from 'features/nodes/hooks/useInputFieldInstance' ;
5
6
import { fieldIntegerValueChanged } from 'features/nodes/store/nodesSlice' ;
@@ -9,7 +10,7 @@ import type { NodeFieldIntegerSettings } from 'features/nodes/types/workflow';
9
10
import { zNumberComponent } from 'features/nodes/types/workflow' ;
10
11
import { constrainNumber } from 'features/nodes/util/constrainNumber' ;
11
12
import type { ChangeEvent } from 'react' ;
12
- import { memo , useCallback } from 'react' ;
13
+ import { memo , useCallback , useMemo } from 'react' ;
13
14
import { useTranslation } from 'react-i18next' ;
14
15
15
16
type Props = {
@@ -64,32 +65,42 @@ const SettingMin = memo(({ id, config, nodeId, fieldName, fieldTemplate }: Props
64
65
const dispatch = useAppDispatch ( ) ;
65
66
const field = useInputFieldInstance < IntegerFieldInputInstance > ( nodeId , fieldName ) ;
66
67
67
- const floatField = useIntegerField ( nodeId , fieldName , fieldTemplate ) ;
68
+ const integerField = useIntegerField ( nodeId , fieldName , fieldTemplate ) ;
68
69
69
70
const onToggleSetting = useCallback ( ( ) => {
70
71
const newConfig : NodeFieldIntegerSettings = {
71
72
...config ,
72
- min : config . min !== undefined ? undefined : floatField . min ,
73
+ min : config . min !== undefined ? undefined : integerField . min ,
73
74
} ;
75
+
74
76
dispatch ( formElementNodeFieldDataChanged ( { id, changes : { settings : newConfig } } ) ) ;
75
- } , [ config , dispatch , floatField . min , id ] ) ;
77
+ } , [ config , dispatch , integerField . min , id ] ) ;
76
78
77
79
const onChange = useCallback (
78
- ( v : number ) => {
80
+ ( min : number ) => {
79
81
const newConfig : NodeFieldIntegerSettings = {
80
82
...config ,
81
- min : v ,
83
+ min,
82
84
} ;
83
-
84
85
dispatch ( formElementNodeFieldDataChanged ( { id, changes : { settings : newConfig } } ) ) ;
85
86
86
87
// We may need to update the value if it is outside the new min/max range
87
- const constrained = constrainNumber ( field . value , { ... floatField } , newConfig ) ;
88
+ const constrained = constrainNumber ( field . value , integerField , newConfig ) ;
88
89
if ( field . value !== constrained ) {
89
90
dispatch ( fieldIntegerValueChanged ( { nodeId, fieldName, value : constrained } ) ) ;
90
91
}
91
92
} ,
92
- [ config , dispatch , field . value , fieldName , floatField , id , nodeId ]
93
+ [ config , dispatch , id , field , integerField , nodeId , fieldName ]
94
+ ) ;
95
+
96
+ const constraintMin = useMemo (
97
+ ( ) => roundUpToMultiple ( integerField . min , integerField . step ) ,
98
+ [ integerField . min , integerField . step ]
99
+ ) ;
100
+
101
+ const constraintMax = useMemo (
102
+ ( ) => ( config . max ?? integerField . max ) - integerField . step ,
103
+ [ config . max , integerField . max , integerField . step ]
93
104
) ;
94
105
95
106
return (
@@ -101,10 +112,11 @@ const SettingMin = memo(({ id, config, nodeId, fieldName, fieldTemplate }: Props
101
112
< CompositeNumberInput
102
113
w = "full"
103
114
isDisabled = { config . min === undefined }
104
- value = { config . min === undefined ? ( `${ floatField . min } (inherited)` as unknown as number ) : config . min }
115
+ value = { config . min ?? ( `${ integerField . min } (inherited)` as unknown as number ) }
105
116
onChange = { onChange }
106
- min = { floatField . min }
107
- max = { ( config . max ?? floatField . max ) - 1 }
117
+ min = { constraintMin }
118
+ max = { constraintMax }
119
+ step = { integerField . step }
108
120
/>
109
121
</ FormControl >
110
122
) ;
@@ -116,32 +128,42 @@ const SettingMax = memo(({ id, config, nodeId, fieldName, fieldTemplate }: Props
116
128
const dispatch = useAppDispatch ( ) ;
117
129
const field = useInputFieldInstance < IntegerFieldInputInstance > ( nodeId , fieldName ) ;
118
130
119
- const floatField = useIntegerField ( nodeId , fieldName , fieldTemplate ) ;
131
+ const integerField = useIntegerField ( nodeId , fieldName , fieldTemplate ) ;
120
132
121
133
const onToggleSetting = useCallback ( ( ) => {
122
134
const newConfig : NodeFieldIntegerSettings = {
123
135
...config ,
124
- max : config . max !== undefined ? undefined : floatField . max ,
136
+ max : config . max !== undefined ? undefined : integerField . max ,
125
137
} ;
126
138
dispatch ( formElementNodeFieldDataChanged ( { id, changes : { settings : newConfig } } ) ) ;
127
- } , [ config , dispatch , floatField . max , id ] ) ;
139
+ } , [ config , dispatch , integerField . max , id ] ) ;
128
140
129
141
const onChange = useCallback (
130
- ( v : number ) => {
142
+ ( max : number ) => {
131
143
const newConfig : NodeFieldIntegerSettings = {
132
144
...config ,
133
- max : v ,
145
+ max,
134
146
} ;
135
147
136
148
dispatch ( formElementNodeFieldDataChanged ( { id, changes : { settings : newConfig } } ) ) ;
137
149
138
150
// We may need to update the value if it is outside the new min/max range
139
- const constrained = constrainNumber ( field . value , floatField , newConfig ) ;
151
+ const constrained = constrainNumber ( field . value , integerField , newConfig ) ;
140
152
if ( field . value !== constrained ) {
141
153
dispatch ( fieldIntegerValueChanged ( { nodeId, fieldName, value : constrained } ) ) ;
142
154
}
143
155
} ,
144
- [ config , dispatch , field . value , fieldName , floatField , id , nodeId ]
156
+ [ config , dispatch , field . value , fieldName , integerField , id , nodeId ]
157
+ ) ;
158
+
159
+ const constraintMin = useMemo (
160
+ ( ) => ( config . min ?? integerField . min ) + integerField . step ,
161
+ [ config . min , integerField . min , integerField . step ]
162
+ ) ;
163
+
164
+ const constraintMax = useMemo (
165
+ ( ) => roundDownToMultiple ( integerField . max , integerField . step ) ,
166
+ [ integerField . max , integerField . step ]
145
167
) ;
146
168
147
169
return (
@@ -153,10 +175,11 @@ const SettingMax = memo(({ id, config, nodeId, fieldName, fieldTemplate }: Props
153
175
< CompositeNumberInput
154
176
w = "full"
155
177
isDisabled = { config . max === undefined }
156
- value = { config . max === undefined ? ( `${ floatField . max } (inherited)` as unknown as number ) : config . max }
178
+ value = { config . max ?? ( `${ integerField . max } (inherited)` as unknown as number ) }
157
179
onChange = { onChange }
158
- min = { ( config . min ?? floatField . min ) + 1 }
159
- max = { floatField . max }
180
+ min = { constraintMin }
181
+ max = { constraintMax }
182
+ step = { integerField . step }
160
183
/>
161
184
</ FormControl >
162
185
) ;
0 commit comments