@@ -23,7 +23,7 @@ export class DialogManager {
2323 log . debug ( `Clicked on value area: ${ valueAreaKey } ` ) ;
2424
2525 // Determine the type and current value based on the control key
26- let valueType , currentValue , propertyName , minValue = 0.01 ;
26+ let valueType , currentValue , propertyName , minValue = 0.01 , integerOnly = false ;
2727
2828 if ( valueAreaKey === 'scaleValueArea' ) {
2929 valueType = 'Scale Factor' ;
@@ -42,23 +42,32 @@ export class DialogManager {
4242 currentValue = this . rm . node . properties . snapValue ;
4343 propertyName = 'snapValue' ;
4444 minValue = 1 ;
45+ integerOnly = true ;
4546 } else if ( valueAreaKey === 'widthValueArea' ) {
4647 valueType = 'Width' ;
4748 currentValue = this . rm . widthWidget ? this . rm . widthWidget . value : this . rm . node . properties . valueX ;
4849 propertyName = 'width' ;
4950 minValue = 64 ;
51+ integerOnly = true ;
5052 } else if ( valueAreaKey === 'heightValueArea' ) {
5153 valueType = 'Height' ;
5254 currentValue = this . rm . heightWidget ? this . rm . heightWidget . value : this . rm . node . properties . valueY ;
5355 propertyName = 'height' ;
5456 minValue = 64 ;
57+ integerOnly = true ;
58+ } else if ( valueAreaKey === 'batchSizeValueArea' ) {
59+ valueType = 'Batch Size' ;
60+ currentValue = this . rm . batchSizeWidget ? this . rm . batchSizeWidget . value : 1 ;
61+ propertyName = 'batch_size' ;
62+ minValue = 1 ;
63+ integerOnly = true ;
5564 } else {
5665 log . debug ( `Unknown value area key: ${ valueAreaKey } ` ) ;
5766 return ;
5867 }
5968
6069 log . debug ( `Opening dialog for ${ valueType } with current value: ${ currentValue } ` ) ;
61- this . createCustomInputDialog ( valueType , currentValue , propertyName , minValue , e ) ;
70+ this . createCustomInputDialog ( valueType , currentValue , propertyName , minValue , integerOnly , e ) ;
6271 }
6372
6473 /**
@@ -67,9 +76,10 @@ export class DialogManager {
6776 * @param {number } currentValue - The current value
6877 * @param {string } propertyName - The property name to update
6978 * @param {number } minValue - Minimum allowed value
79+ * @param {boolean } integerOnly - Whether to allow only integer values
7080 * @param {Event } e - The mouse event for positioning
7181 */
72- createCustomInputDialog ( valueType , currentValue , propertyName , minValue , e ) {
82+ createCustomInputDialog ( valueType , currentValue , propertyName , minValue , integerOnly , e ) {
7383 this . inputDialogActive = true ;
7484 log . debug ( `Creating dialog for ${ valueType } , current: ${ currentValue } ` ) ;
7585
@@ -103,11 +113,12 @@ export class DialogManager {
103113 dialog . style . top = `${ Math . max ( 10 , Math . min ( y , window . innerHeight - 200 ) ) } px` ;
104114
105115 // Create dialog content
116+ const inputStep = integerOnly ? '1' : '0.01' ;
106117 dialog . innerHTML = `
107118 <div style="color: #fff; font-size: 16px; font-weight: bold; margin-bottom: 15px; text-align: center;">Set Custom ${ valueType } </div>
108119 <div style="margin-bottom: 10px;">
109120 <label style="color: #ccc; font-size: 12px; display: block; margin-bottom: 5px;">Current: ${ this . formatValueForDisplay ( currentValue , valueType ) } </label>
110- <input type="${ valueType === 'Scale Factor' ? 'text' : 'number' } " id="customValueInput" value="${ currentValue } " step="${ valueType === 'Width' || valueType === 'Height' ? '1' : '0.01' } " min="${ minValue } "
121+ <input type="${ valueType === 'Scale Factor' ? 'text' : 'number' } " id="customValueInput" value="${ currentValue } " step="${ inputStep } " min="${ minValue } "
111122 style="width: 100%; padding: 8px; border: 1px solid #555; border-radius: 4px; background: #333; color: #fff; font-size: 14px; box-sizing: border-box;">
112123 </div>
113124 <div id="validationMessage" style="color: #f55; font-size: 11px; margin-bottom: 5px; min-height: 15px;"></div>
@@ -131,6 +142,37 @@ export class DialogManager {
131142 infoMsg . textContent = 'Tip: Use /2 for 0.5x, /4 for 0.25x, etc.' ;
132143 }
133144
145+ // Block decimal characters for integer-only inputs
146+ if ( integerOnly ) {
147+ input . addEventListener ( 'keydown' , ( e ) => {
148+ // Allow: backspace, delete, tab, escape, enter, arrows, home, end
149+ const allowedKeys = [ 'Backspace' , 'Delete' , 'Tab' , 'Escape' , 'Enter' , 'ArrowLeft' , 'ArrowRight' , 'ArrowUp' , 'ArrowDown' , 'Home' , 'End' ] ;
150+
151+ // Block: decimal point, comma, e, E, +, - (except for navigation)
152+ const blockedChars = [ '.' , ',' , 'e' , 'E' , '+' , '-' ] ;
153+
154+ if ( allowedKeys . includes ( e . key ) ) {
155+ return ; // Allow these keys
156+ }
157+
158+ // Allow Ctrl/Cmd combinations (copy, paste, select all, etc.)
159+ if ( e . ctrlKey || e . metaKey ) {
160+ return ;
161+ }
162+
163+ // Block decimal and scientific notation characters
164+ if ( blockedChars . includes ( e . key ) ) {
165+ e . preventDefault ( ) ;
166+ return ;
167+ }
168+
169+ // Allow only digits 0-9
170+ if ( ! / ^ \d $ / . test ( e . key ) ) {
171+ e . preventDefault ( ) ;
172+ }
173+ } ) ;
174+ }
175+
134176 // Focus and select input
135177 setTimeout ( ( ) => { input . focus ( ) ; input . select ( ) ; } , 50 ) ;
136178
@@ -146,6 +188,10 @@ export class DialogManager {
146188 validationMsg . textContent = errorMsg ;
147189 applyBtn . disabled = true ; applyBtn . style . opacity = '0.5' ;
148190 return false ;
191+ } else if ( integerOnly && ! Number . isInteger ( value ) ) {
192+ validationMsg . textContent = 'Value must be a whole number' ;
193+ applyBtn . disabled = true ; applyBtn . style . opacity = '0.5' ;
194+ return false ;
149195 } else {
150196 validationMsg . textContent = '' ;
151197 applyBtn . disabled = false ; applyBtn . style . opacity = '1' ;
@@ -243,6 +289,12 @@ export class DialogManager {
243289 const newHeight = Math . round ( value ) ;
244290 const currentWidth = this . rm . widthWidget ? this . rm . widthWidget . value : props . valueX ;
245291 this . rm . setDimensions ( currentWidth , newHeight ) ;
292+ } else if ( propertyName === 'batch_size' ) {
293+ const newBatchSize = Math . max ( 1 , Math . min ( 4096 , Math . round ( value ) ) ) ;
294+ props . batch_size = newBatchSize ;
295+ if ( this . rm . batchSizeWidget ) {
296+ this . rm . batchSizeWidget . value = newBatchSize ;
297+ }
246298 }
247299
248300 this . closeCustomInputDialog ( ) ;
@@ -266,6 +318,8 @@ export class DialogManager {
266318 return value . toFixed ( 1 ) + 'MP' ;
267319 } else if ( valueType === 'Width' || valueType === 'Height' ) {
268320 return value . toString ( ) + 'px' ;
321+ } else if ( valueType === 'Batch Size' ) {
322+ return value . toString ( ) ;
269323 } else {
270324 return value . toString ( ) ;
271325 }
0 commit comments