@@ -19,13 +19,13 @@ pub struct MouseArea<
19
19
Renderer = crate :: Renderer ,
20
20
> {
21
21
content : Element < ' a , Message , Theme , Renderer > ,
22
- on_press : Option < Message > ,
23
- on_release : Option < Message > ,
24
- on_double_click : Option < Message > ,
25
- on_right_press : Option < Message > ,
26
- on_right_release : Option < Message > ,
27
- on_middle_press : Option < Message > ,
28
- on_middle_release : Option < Message > ,
22
+ on_press : Option < Reaction < ' a , Message > > ,
23
+ on_release : Option < Reaction < ' a , Message > > ,
24
+ on_double_click : Option < Reaction < ' a , Message > > ,
25
+ on_right_press : Option < Reaction < ' a , Message > > ,
26
+ on_right_release : Option < Reaction < ' a , Message > > ,
27
+ on_middle_press : Option < Reaction < ' a , Message > > ,
28
+ on_middle_release : Option < Reaction < ' a , Message > > ,
29
29
on_scroll : Option < Box < dyn Fn ( mouse:: ScrollDelta ) -> Message + ' a > > ,
30
30
on_enter : Option < Message > ,
31
31
on_move : Option < Box < dyn Fn ( Point ) -> Message + ' a > > ,
@@ -37,14 +37,34 @@ impl<'a, Message, Theme, Renderer> MouseArea<'a, Message, Theme, Renderer> {
37
37
/// The message to emit on a left button press.
38
38
#[ must_use]
39
39
pub fn on_press ( mut self , message : Message ) -> Self {
40
- self . on_press = Some ( message) ;
40
+ self . on_press = Some ( Reaction :: Message ( message) ) ;
41
+ self
42
+ }
43
+
44
+ /// The closure to create the message to emit on a left button press.
45
+ #[ must_use]
46
+ pub fn on_press_position < F > ( mut self , on_press : F ) -> Self
47
+ where
48
+ F : ' a + Fn ( Point ) -> Message
49
+ {
50
+ self . on_press = Some ( Reaction :: MessageWithPosition ( Box :: new ( on_press) ) ) ;
41
51
self
42
52
}
43
53
44
54
/// The message to emit on a left button release.
45
55
#[ must_use]
46
56
pub fn on_release ( mut self , message : Message ) -> Self {
47
- self . on_release = Some ( message) ;
57
+ self . on_release = Some ( Reaction :: Message ( message) ) ;
58
+ self
59
+ }
60
+
61
+ /// The closure to create the message to emit on a left button release with the position.
62
+ #[ must_use]
63
+ pub fn on_release_position < F > ( mut self , on_release : F ) -> Self
64
+ where
65
+ F : ' a + Fn ( Point ) -> Message
66
+ {
67
+ self . on_release = Some ( Reaction :: MessageWithPosition ( Box :: new ( on_release) ) ) ;
48
68
self
49
69
}
50
70
@@ -60,35 +80,85 @@ impl<'a, Message, Theme, Renderer> MouseArea<'a, Message, Theme, Renderer> {
60
80
/// [`on_release`]: Self::on_release
61
81
#[ must_use]
62
82
pub fn on_double_click ( mut self , message : Message ) -> Self {
63
- self . on_double_click = Some ( message) ;
83
+ self . on_double_click = Some ( Reaction :: Message ( message) ) ;
84
+ self
85
+ }
86
+
87
+ /// The closure to create the message to emit on a double click.
88
+ #[ must_use]
89
+ pub fn on_double_click_position < F > ( mut self , on_double_click : F ) -> Self
90
+ where
91
+ F : ' a + Fn ( Point ) -> Message
92
+ {
93
+ self . on_double_click = Some ( Reaction :: MessageWithPosition ( Box :: new ( on_double_click) ) ) ;
64
94
self
65
95
}
66
96
67
97
/// The message to emit on a right button press.
68
98
#[ must_use]
69
99
pub fn on_right_press ( mut self , message : Message ) -> Self {
70
- self . on_right_press = Some ( message) ;
100
+ self . on_right_press = Some ( Reaction :: Message ( message) ) ;
101
+ self
102
+ }
103
+
104
+ /// The closure to create the message to emit on a right button press.
105
+ #[ must_use]
106
+ pub fn on_right_press_position < F > ( mut self , on_right_press : F ) -> Self
107
+ where
108
+ F : ' a + Fn ( Point ) -> Message
109
+ {
110
+ self . on_right_press = Some ( Reaction :: MessageWithPosition ( Box :: new ( on_right_press) ) ) ;
71
111
self
72
112
}
73
113
74
114
/// The message to emit on a right button release.
75
115
#[ must_use]
76
116
pub fn on_right_release ( mut self , message : Message ) -> Self {
77
- self . on_right_release = Some ( message) ;
117
+ self . on_right_release = Some ( Reaction :: Message ( message) ) ;
118
+ self
119
+ }
120
+
121
+ /// The closure to create the message to emit on a right button release.
122
+ #[ must_use]
123
+ pub fn on_right_release_position < F > ( mut self , on_right_release : F ) -> Self
124
+ where
125
+ F : ' a + Fn ( Point ) -> Message
126
+ {
127
+ self . on_right_release = Some ( Reaction :: MessageWithPosition ( Box :: new ( on_right_release) ) ) ;
78
128
self
79
129
}
80
130
81
131
/// The message to emit on a middle button press.
82
132
#[ must_use]
83
133
pub fn on_middle_press ( mut self , message : Message ) -> Self {
84
- self . on_middle_press = Some ( message) ;
134
+ self . on_middle_press = Some ( Reaction :: Message ( message) ) ;
135
+ self
136
+ }
137
+
138
+ /// The closure to create the message to emit on a middle button press.
139
+ #[ must_use]
140
+ pub fn on_middle_press_position < F > ( mut self , on_middle_press : F ) -> Self
141
+ where
142
+ F : ' a + Fn ( Point ) -> Message
143
+ {
144
+ self . on_middle_press = Some ( Reaction :: MessageWithPosition ( Box :: new ( on_middle_press) ) ) ;
85
145
self
86
146
}
87
147
88
148
/// The message to emit on a middle button release.
89
149
#[ must_use]
90
150
pub fn on_middle_release ( mut self , message : Message ) -> Self {
91
- self . on_middle_release = Some ( message) ;
151
+ self . on_middle_release = Some ( Reaction :: Message ( message) ) ;
152
+ self
153
+ }
154
+
155
+ /// The closure to create the message to emit on a middle button release.
156
+ #[ must_use]
157
+ pub fn on_middle_release_position < F > ( mut self , on_middle_release : F ) -> Self
158
+ where
159
+ F : ' a + Fn ( Point ) -> Message
160
+ {
161
+ self . on_middle_release = Some ( Reaction :: MessageWithPosition ( Box :: new ( on_middle_release) ) ) ;
92
162
self
93
163
}
94
164
@@ -370,21 +440,23 @@ fn update<Message: Clone, Theme, Renderer>(
370
440
match event {
371
441
Event :: Mouse ( mouse:: Event :: ButtonPressed ( mouse:: Button :: Left ) )
372
442
| Event :: Touch ( touch:: Event :: FingerPressed { .. } ) => {
373
- if let Some ( message) = widget. on_press . as_ref ( ) {
374
- shell. publish ( message. clone ( ) ) ;
375
- shell. capture_event ( ) ;
443
+ if let Some ( reaction) = widget. on_press . as_ref ( ) {
444
+ if let Some ( message) = reaction. react_maybe ( cursor_position) {
445
+ shell. publish ( message) ;
446
+ shell. capture_event ( ) ;
447
+ }
376
448
}
377
449
378
450
if let Some ( position) = cursor_position {
379
- if let Some ( message ) = widget. on_double_click . as_ref ( ) {
451
+ if let Some ( reaction ) = widget. on_double_click . as_ref ( ) {
380
452
let new_click = mouse:: Click :: new (
381
453
position,
382
454
mouse:: Button :: Left ,
383
455
state. previous_click ,
384
456
) ;
385
457
386
458
if new_click. kind ( ) == mouse:: click:: Kind :: Double {
387
- shell. publish ( message . clone ( ) ) ;
459
+ shell. publish ( reaction . react ( position ) ) ;
388
460
}
389
461
390
462
state. previous_click = Some ( new_click) ;
@@ -397,30 +469,40 @@ fn update<Message: Clone, Theme, Renderer>(
397
469
}
398
470
Event :: Mouse ( mouse:: Event :: ButtonReleased ( mouse:: Button :: Left ) )
399
471
| Event :: Touch ( touch:: Event :: FingerLifted { .. } ) => {
400
- if let Some ( message) = widget. on_release . as_ref ( ) {
401
- shell. publish ( message. clone ( ) ) ;
472
+ if let Some ( reaction) = widget. on_release . as_ref ( ) {
473
+ if let Some ( message) = reaction. react_maybe ( cursor_position) {
474
+ shell. publish ( message) ;
475
+ }
402
476
}
403
477
}
404
478
Event :: Mouse ( mouse:: Event :: ButtonPressed ( mouse:: Button :: Right ) ) => {
405
- if let Some ( message) = widget. on_right_press . as_ref ( ) {
406
- shell. publish ( message. clone ( ) ) ;
407
- shell. capture_event ( ) ;
479
+ if let Some ( reaction) = widget. on_right_press . as_ref ( ) {
480
+ if let Some ( message) = reaction. react_maybe ( cursor_position) {
481
+ shell. publish ( message. clone ( ) ) ;
482
+ shell. capture_event ( ) ;
483
+ }
408
484
}
409
485
}
410
486
Event :: Mouse ( mouse:: Event :: ButtonReleased ( mouse:: Button :: Right ) ) => {
411
- if let Some ( message) = widget. on_right_release . as_ref ( ) {
412
- shell. publish ( message. clone ( ) ) ;
487
+ if let Some ( reaction) = widget. on_right_release . as_ref ( ) {
488
+ if let Some ( message) = reaction. react_maybe ( cursor_position) {
489
+ shell. publish ( message) ;
490
+ }
413
491
}
414
492
}
415
493
Event :: Mouse ( mouse:: Event :: ButtonPressed ( mouse:: Button :: Middle ) ) => {
416
- if let Some ( message) = widget. on_middle_press . as_ref ( ) {
417
- shell. publish ( message. clone ( ) ) ;
418
- shell. capture_event ( ) ;
494
+ if let Some ( reaction) = widget. on_middle_press . as_ref ( ) {
495
+ if let Some ( message) = reaction. react_maybe ( cursor_position) {
496
+ shell. publish ( message. clone ( ) ) ;
497
+ shell. capture_event ( ) ;
498
+ }
419
499
}
420
500
}
421
501
Event :: Mouse ( mouse:: Event :: ButtonReleased ( mouse:: Button :: Middle ) ) => {
422
- if let Some ( message) = widget. on_middle_release . as_ref ( ) {
423
- shell. publish ( message. clone ( ) ) ;
502
+ if let Some ( reaction) = widget. on_middle_release . as_ref ( ) {
503
+ if let Some ( message) = reaction. react_maybe ( cursor_position) {
504
+ shell. publish ( message) ;
505
+ }
424
506
}
425
507
}
426
508
Event :: Mouse ( mouse:: Event :: WheelScrolled { delta } ) => {
@@ -432,3 +514,29 @@ fn update<Message: Clone, Theme, Renderer>(
432
514
_ => { }
433
515
}
434
516
}
517
+
518
+ enum Reaction < ' a , Message > {
519
+ Message ( Message ) ,
520
+ MessageWithPosition ( Box < dyn Fn ( Point ) -> Message + ' a > ) ,
521
+ }
522
+
523
+ impl < Message > Reaction < ' _ , Message >
524
+ where
525
+ Message : Clone ,
526
+ {
527
+ pub ( crate ) fn react_maybe ( & self , position : Option < Point > ) -> Option < Message > {
528
+ let position = position?;
529
+
530
+ Some ( match self {
531
+ Self :: Message ( message) => message. clone ( ) ,
532
+ Self :: MessageWithPosition ( creator) => ( creator) ( position) ,
533
+ } )
534
+ }
535
+
536
+ pub ( crate ) fn react ( & self , position : Point ) -> Message {
537
+ match self {
538
+ Self :: Message ( message) => message. clone ( ) ,
539
+ Self :: MessageWithPosition ( creator) => ( creator) ( position) ,
540
+ }
541
+ }
542
+ }
0 commit comments