@@ -17,7 +17,7 @@ use iced::{
17
17
widget:: {
18
18
text:: LineHeight ,
19
19
text_input:: { self , cursor, Value } ,
20
- Column , Container , Row , Text , TextInput ,
20
+ Column , Container , Row , Text ,
21
21
} ,
22
22
Alignment , Background , Border , Color , Element , Event , Length , Padding , Pixels , Point ,
23
23
Rectangle , Shadow , Size ,
@@ -37,6 +37,7 @@ pub use crate::{
37
37
StyleFn ,
38
38
} ,
39
39
} ;
40
+ use crate :: widgets:: typed_input:: TypedInput ;
40
41
41
42
/// The default padding
42
43
const DEFAULT_PADDING : f32 = 5.0 ;
81
82
/// The text size of the [`NumberInput`].
82
83
size : Option < f32 > ,
83
84
/// The underlying element of the [`NumberInput`].
84
- content : TextInput < ' a , Message , Theme , Renderer > ,
85
+ content : TypedInput < ' a , T , Message , Theme , Renderer > ,
85
86
/// The ``on_change`` event of the [`NumberInput`].
86
87
on_change : Box < dyn Fn ( T ) -> Message > ,
87
88
/// The style of the [`NumberInput`].
@@ -116,9 +117,6 @@ where
116
117
T : ' static ,
117
118
{
118
119
let padding = DEFAULT_PADDING ;
119
- let convert_to_num = move |s : String | {
120
- on_changed ( T :: from_str ( & s) . unwrap_or ( if s. is_empty ( ) { T :: zero ( ) } else { value } ) )
121
- } ;
122
120
123
121
Self {
124
122
value,
@@ -127,8 +125,7 @@ where
127
125
max : Self :: set_max ( bounds. end_bound ( ) ) ,
128
126
padding,
129
127
size : None ,
130
- content : TextInput :: new ( "" , format ! ( "{value}" ) . as_str ( ) )
131
- . on_input ( convert_to_num)
128
+ content : TypedInput :: new ( value, on_changed)
132
129
. padding ( padding)
133
130
. width ( Length :: Fixed ( 127.0 ) )
134
131
. class ( Theme :: default_input ( ) ) ,
@@ -346,7 +343,7 @@ where
346
343
. shrink ( padding) ;
347
344
let content = self
348
345
. content
349
- . layout ( & mut tree. children [ 0 ] , renderer, & limits, None ) ;
346
+ . layout ( & mut tree. children [ 0 ] , renderer, & limits) ;
350
347
let limits2 = Limits :: new ( Size :: new ( 0.0 , 0.0 ) , content. size ( ) ) ;
351
348
let txt_size = self . size . unwrap_or_else ( || renderer. default_size ( ) . 0 ) ;
352
349
@@ -456,10 +453,15 @@ where
456
453
457
454
let child = state. children . get_mut ( 0 ) . expect ( "fail to get child" ) ;
458
455
let text_input = child
456
+ . children
457
+ . get_mut ( 0 )
458
+ . expect ( "fail to get text input" )
459
459
. state
460
460
. downcast_mut :: < text_input:: State < Renderer :: Paragraph > > ( ) ;
461
461
let modifiers = state. state . downcast_mut :: < ModifierState > ( ) ;
462
462
463
+ let current_text = self . content . text ( ) . to_string ( ) ;
464
+
463
465
let mut forward_to_text = |event, shell, child, clipboard| {
464
466
self . content . on_event (
465
467
child, event, content, cursor, renderer, clipboard, shell, viewport,
@@ -485,39 +487,43 @@ where
485
487
forward_to_text ( event, shell, child, clipboard)
486
488
} else if text == "\u{8} " {
487
489
// Backspace
488
- if T :: zero ( ) . eq ( & self . value ) {
489
- event:: Status :: Ignored
490
- } else {
491
- let mut new_val = self . value . to_string ( ) ;
492
- match text_input. cursor ( ) . state ( & Value :: new ( & new_val) ) {
493
- cursor:: State :: Index ( idx)
494
- if idx >= 1 && idx <= new_val. len ( ) =>
495
- {
496
- _ = new_val. remove ( idx - 1 ) ;
497
- }
498
- cursor:: State :: Selection { start, end }
499
- if start <= new_val. len ( ) && end <= new_val. len ( ) =>
500
- {
501
- new_val. replace_range ( start. min ( end) ..start. max ( end) , "" ) ;
502
- }
503
- _ => return event:: Status :: Ignored ,
490
+ if current_text == T :: zero ( ) . to_string ( ) {
491
+ return event:: Status :: Ignored ;
492
+ }
493
+ let mut new_val = current_text;
494
+ match text_input. cursor ( ) . state ( & Value :: new ( & new_val) ) {
495
+ cursor:: State :: Index ( idx)
496
+ if idx >= 1 && idx <= new_val. len ( ) =>
497
+ {
498
+ _ = new_val. remove ( idx - 1 ) ;
504
499
}
505
-
506
- if new_val. is_empty ( ) {
507
- new_val = T :: zero ( ) . to_string ( ) ;
500
+ cursor:: State :: Selection { start, end }
501
+ if start <= new_val. len ( ) && end <= new_val. len ( ) =>
502
+ {
503
+ new_val. replace_range ( start. min ( end) ..start. max ( end) , "" ) ;
508
504
}
505
+ _ => return event:: Status :: Ignored ,
506
+ }
509
507
510
- match T :: from_str ( & new_val) {
511
- Ok ( val)
512
- if ( self . min ..self . max ) . contains ( & val)
513
- && val != self . value =>
514
- {
515
- self . value = val;
516
- forward_to_text ( event, shell, child, clipboard)
517
- }
518
- Ok ( _) => event:: Status :: Captured ,
519
- _ => event:: Status :: Ignored ,
508
+ if new_val. is_empty ( ) {
509
+ new_val = T :: zero ( ) . to_string ( ) ;
510
+ }
511
+
512
+ match T :: from_str ( & new_val) {
513
+ Ok ( val)
514
+ if ( self . min ..self . max ) . contains ( & val)
515
+ && val != self . value =>
516
+ {
517
+ self . value = val;
518
+ forward_to_text ( event, shell, child, clipboard)
520
519
}
520
+ Ok ( val)
521
+ if ( self . min ..self . max ) . contains ( & val) =>
522
+ {
523
+ forward_to_text ( event, shell, child, clipboard)
524
+ }
525
+ Ok ( _) => event:: Status :: Captured ,
526
+ _ => event:: Status :: Ignored ,
521
527
}
522
528
} else {
523
529
let input = if text == "\u{16} " {
@@ -526,15 +532,15 @@ where
526
532
Some ( paste) => paste,
527
533
None => return event:: Status :: Ignored ,
528
534
}
529
- } else if text. parse :: < i64 > ( ) . is_err ( ) && text != "-" {
535
+ } else if text. parse :: < i64 > ( ) . is_err ( ) && text != "-" && text != "." {
530
536
return event:: Status :: Ignored ;
531
537
} else {
532
538
text. to_string ( )
533
539
} ;
534
540
535
541
let input = input. trim ( ) ;
536
542
537
- let mut new_val = self . value . to_string ( ) ;
543
+ let mut new_val = current_text ;
538
544
match text_input. cursor ( ) . state ( & Value :: new ( & new_val) ) {
539
545
cursor:: State :: Index ( idx) if idx <= new_val. len ( ) => {
540
546
new_val. insert_str ( idx, input) ;
@@ -554,7 +560,11 @@ where
554
560
self . value = val;
555
561
forward_to_text ( event, shell, child, clipboard)
556
562
}
557
- Ok ( _) => event:: Status :: Captured ,
563
+ Ok ( val)
564
+ if ( self . min ..self . max ) . contains ( & val) =>
565
+ forward_to_text ( event, shell, child, clipboard) ,
566
+ Ok ( _) =>
567
+ event:: Status :: Captured ,
558
568
_ => event:: Status :: Ignored ,
559
569
}
560
570
}
@@ -569,7 +579,9 @@ where
569
579
event:: Status :: Captured
570
580
}
571
581
keyboard:: Key :: Named (
572
- keyboard:: key:: Named :: ArrowLeft | keyboard:: key:: Named :: ArrowRight ,
582
+ keyboard:: key:: Named :: ArrowLeft | keyboard:: key:: Named :: ArrowRight |
583
+ keyboard:: key:: Named :: Home |
584
+ keyboard:: key:: Named :: End ,
573
585
) => forward_to_text ( event, shell, child, clipboard) ,
574
586
_ => event:: Status :: Ignored ,
575
587
} ,
@@ -661,7 +673,7 @@ where
661
673
state : & Tree ,
662
674
renderer : & mut Renderer ,
663
675
theme : & Theme ,
664
- _style : & renderer:: Style ,
676
+ style : & renderer:: Style ,
665
677
layout : Layout < ' _ > ,
666
678
cursor : Cursor ,
667
679
viewport : & Rectangle ,
@@ -684,9 +696,9 @@ where
684
696
& state. children [ 0 ] ,
685
697
renderer,
686
698
theme,
699
+ style,
687
700
content_layout,
688
701
cursor,
689
- None ,
690
702
viewport,
691
703
) ;
692
704
let is_decrease_disabled = self . value <= self . min || self . min == self . max ;
0 commit comments