1#![allow(unused)]
2#![allow(dead_code)]
3use {
4 std::{cell::Cell, ops::Deref},
5 crate::{
6 makepad_micro_serde::*,
7 makepad_live_tokenizer::{LiveErrorOrigin, live_error_origin},
8 makepad_live_compiler::{
9 LivePropType,
10 LiveType,
11 LiveTypeField,
12 LiveFieldKind,
13 LiveNode,
14 LiveId,
15 LiveModuleId,
16 LiveTypeInfo,
17 LiveNodeSliceApi
18 },
19 live_traits::{LiveNew, LiveHook, LiveRegister, LiveHookDeref, LiveApplyValue, LiveApply,LiveApplyReset, Apply},
20 makepad_derive_live::*,
21 makepad_math::*,
22 makepad_live_id::{FromLiveId, live_id, live_id_num},
23 event::{
24 event::{Event, Hit}
25 },
26 window::WindowId,
27 cx::Cx,
28 event::xr::XrHand,
29 area::Area,
30 },
31};
32
33#[derive(Clone, Copy, Debug, Default, SerBin, DeBin, SerJson, DeJson, Eq, PartialEq)]
37pub struct KeyModifiers {
38 pub shift: bool,
39 pub control: bool,
40 pub alt: bool,
41 pub logo: bool
42}
43
44impl KeyModifiers{
45 pub fn is_primary(&self) -> bool {
50 #[cfg(target_vendor = "apple")] {
51 self.logo
52 }
53 #[cfg(not(target_vendor = "apple"))] {
54 self.control
55 }
56 }
57
58 fn any(&self)->bool{
59 self.shift || self.control || self.alt || self.logo
60 }
61}
62
63
64bitflags::bitflags! {
65 #[derive(Copy, Clone, Debug, Default, PartialEq, Eq)]
71 #[doc(alias = "click")]
72 pub struct MouseButton: u32 {
73 #[doc(alias("left", "left-click"))]
75 const PRIMARY = 1 << 0;
76 #[doc(alias("right", "right-click"))]
78 const SECONDARY = 1 << 1;
79 #[doc(alias("scroll", "wheel"))]
81 const MIDDLE = 1 << 2;
82 const BACK = 1 << 3;
84 const FORWARD = 1 << 4;
86
87 const _ = !0;
89 }
90}
91impl MouseButton {
92 pub fn is_primary(&self) -> bool {
94 self.contains(MouseButton::PRIMARY)
95 }
96 pub fn is_secondary(&self) -> bool {
98 self.contains(MouseButton::SECONDARY)
99 }
100 pub fn is_middle(&self) -> bool {
102 self.contains(MouseButton::MIDDLE)
103 }
104 pub fn is_back(&self) -> bool {
106 self.contains(MouseButton::BACK)
107 }
108 pub fn is_forward(&self) -> bool {
110 self.contains(MouseButton::FORWARD)
111 }
112 pub fn is_other_button(&self, n: u8) -> bool {
122 self.bits() & (1 << n) != 0
123 }
124 pub fn from_raw_button(raw: usize) -> MouseButton {
134 MouseButton::from_bits_retain(1 << raw)
135 }
136}
137
138
139#[derive(Clone, Debug)]
140pub struct MouseDownEvent {
141 pub abs: DVec2,
142 pub button: MouseButton,
143 pub window_id: WindowId,
144 pub modifiers: KeyModifiers,
145 pub handled: Cell<Area>,
146 pub time: f64,
147}
148
149
150#[derive(Clone, Debug)]
151pub struct MouseMoveEvent {
152 pub abs: DVec2,
153 pub window_id: WindowId,
154 pub modifiers: KeyModifiers,
155 pub time: f64,
156 pub handled: Cell<Area>,
157}
158
159#[derive(Clone, Debug)]
160pub struct MouseUpEvent {
161 pub abs: DVec2,
162 pub button: MouseButton,
163 pub window_id: WindowId,
164 pub modifiers: KeyModifiers,
165 pub time: f64
166}
167
168#[derive(Clone, Debug)]
169pub struct MouseLeaveEvent {
170 pub abs: DVec2,
171 pub window_id: WindowId,
172 pub modifiers: KeyModifiers,
173 pub time: f64,
174 pub handled: Cell<Area>,
175}
176
177#[derive(Clone, Debug)]
178pub struct ScrollEvent {
179 pub window_id: WindowId,
180 pub scroll: DVec2,
181 pub abs: DVec2,
182 pub modifiers: KeyModifiers,
183 pub handled_x: Cell<bool>,
184 pub handled_y: Cell<bool>,
185 pub is_mouse: bool,
186 pub time: f64
187}
188
189#[derive(Clone, Debug)]
190pub struct LongPressEvent {
191 pub window_id: WindowId,
192 pub abs: DVec2,
193 pub uid: u64,
194 pub time: f64,
195}
196
197#[derive(Clone, Copy, Debug)]
200pub enum TouchState {
201 Start,
202 Stop,
203 Move,
204 Stable
205}
206
207#[derive(Clone, Debug)]
208pub struct TouchPoint {
209 pub state: TouchState,
210 pub abs: DVec2,
211 pub time: f64,
212 pub uid: u64,
213 pub rotation_angle: f64,
214 pub force: f64,
215 pub radius: DVec2,
216 pub handled: Cell<Area>,
217 pub sweep_lock: Cell<Area>,
218}
219
220#[derive(Clone, Debug)]
221pub struct TouchUpdateEvent {
222 pub time: f64,
223 pub window_id: WindowId,
224 pub modifiers: KeyModifiers,
225 pub touches: Vec<TouchPoint>,
226}
227
228
229#[derive(Clone, Copy, Default, Debug, Live)]
233#[live_ignore]
234pub struct Margin {
235 #[live] pub left: f64,
236 #[live] pub top: f64,
237 #[live] pub right: f64,
238 #[live] pub bottom: f64
239}
240impl LiveRegister for Margin{}
241
242impl LiveHook for Margin {
243 fn skip_apply(&mut self, _cx: &mut Cx, _apply: &mut Apply, index: usize, nodes: &[LiveNode]) -> Option<usize> {
244 if let Some(v) = nodes[index].value.as_float() {
245 *self = Self {left: v, top: v, right: v, bottom: v};
246 Some(index + 1)
247 }
248 else {
249 None
250 }
251 }
252}
253
254impl Margin {
255 pub fn left_top(&self) -> DVec2 {
256 dvec2(self.left, self.top)
257 }
258 pub fn right_bottom(&self) -> DVec2 {
259 dvec2(self.right, self.bottom)
260 }
261 pub fn size(&self) -> DVec2 {
262 dvec2(self.left + self.right, self.top + self.bottom)
263 }
264 pub fn width(&self) -> f64 {
265 self.left + self.right
266 }
267 pub fn height(&self) -> f64 {
268 self.top + self.bottom
269 }
270
271 pub fn rect_contains_with_margin(pos: DVec2, rect: &Rect, margin: &Option<Margin>) -> bool {
272 if let Some(margin) = margin {
273 return
274 pos.x >= rect.pos.x - margin.left
275 && pos.x <= rect.pos.x + rect.size.x + margin.right
276 && pos.y >= rect.pos.y - margin.top
277 && pos.y <= rect.pos.y + rect.size.y + margin.bottom;
278 }
279 else {
280 return rect.contains(pos);
281 }
282 }
283}
284
285pub const TAP_COUNT_TIME: f64 = 0.5;
288pub const TAP_COUNT_DISTANCE: f64 = 5.0;
289
290#[derive(Clone, Debug, Default, Eq, Hash, Copy, PartialEq, FromLiveId)]
291pub struct DigitId(pub LiveId);
292
293#[derive(Default, Clone)]
294pub struct CxDigitCapture {
295 digit_id: DigitId,
296 has_long_press_occurred: bool,
297 pub area: Area,
298 pub sweep_area: Area,
299 pub switch_capture: Option<Area>,
300 pub time: f64,
301 pub abs_start: DVec2,
302}
303
304#[derive(Default, Clone)]
305pub struct CxDigitTap {
306 digit_id: DigitId,
307 last_pos: DVec2,
308 last_time: f64,
309 count: u32
310}
311
312#[derive(Default, Clone)]
313pub struct CxDigitHover {
314 digit_id: DigitId,
315 new_area: Area,
316 area: Area,
317}
318
319#[derive(Default, Clone)]
320pub struct CxFingers {
321 pub first_mouse_button: Option<(MouseButton, WindowId)>,
322 captures: Vec<CxDigitCapture>,
323 tap: CxDigitTap,
324 hovers: Vec<CxDigitHover>,
325 sweep_lock: Option<Area>,
326}
327
328impl CxFingers {
329 pub (crate) fn find_digit_for_captured_area(&self, area: Area) -> Option<DigitId> {
349 if let Some(digit) = self.captures.iter().find( | d | d.area == area) {
350 return Some(digit.digit_id)
351 }
352 None
353 }
354
355 pub (crate) fn update_area(&mut self, old_area: Area, new_area: Area) {
356 for hover in &mut self.hovers {
357 if hover.area == old_area {
358 hover.area = new_area;
359 }
360 }
361 for capture in &mut self.captures {
362 if capture.area == old_area {
363 capture.area = new_area;
364 }
365 if capture.sweep_area == old_area {
366 capture.sweep_area = new_area;
367 }
368 }
369 if self.sweep_lock == Some(old_area) {
370 self.sweep_lock = Some(new_area);
371 }
372 }
373
374 pub (crate) fn new_hover_area(&mut self, digit_id: DigitId, new_area: Area) {
375 for hover in &mut self.hovers {
376 if hover.digit_id == digit_id {
377 hover.new_area = new_area;
378 return
379 }
380 }
381 self.hovers.push(CxDigitHover {
382 digit_id,
383 area: Area::Empty,
384 new_area: new_area,
385 })
386 }
387
388 pub (crate) fn find_hover_area(&self, digit: DigitId) -> Area {
389 for hover in &self.hovers {
390 if hover.digit_id == digit {
391 return hover.area
392 }
393 }
394 Area::Empty
395 }
396
397 pub (crate) fn cycle_hover_area(&mut self, digit_id: DigitId) {
398 if let Some(hover) = self.hovers.iter_mut().find( | v | v.digit_id == digit_id) {
399 hover.area = hover.new_area;
400 hover.new_area = Area::Empty;
401 }
402 }
403
404 pub (crate) fn capture_digit(&mut self, digit_id: DigitId, area: Area, sweep_area: Area, time: f64, abs_start: DVec2) {
405 self.captures.push(CxDigitCapture {
413 sweep_area,
414 digit_id,
415 area,
416 time,
417 abs_start,
418 has_long_press_occurred: false,
419 switch_capture: None
420 })
421 }
423
424 pub (crate) fn uncapture_area(&mut self, area: Area){
425 self.captures.retain(|v| v.area != area);
426 }
427
428 pub (crate) fn find_digit_capture(&mut self, digit_id: DigitId) -> Option<&mut CxDigitCapture> {
429 self.captures.iter_mut().find( | v | v.digit_id == digit_id)
430 }
431
432
433 pub (crate) fn find_area_capture(&mut self, area: Area) -> Option<&mut CxDigitCapture> {
434 self.captures.iter_mut().find( | v | v.area == area)
435 }
436
437 pub fn is_area_captured(&self, area: Area) -> bool {
438 self.captures.iter().find( | v | v.area == area).is_some()
439 }
440
441 pub fn any_areas_captured(&self) -> bool {
442 self.captures.len() > 0
443 }
444
445 pub (crate) fn release_digit(&mut self, digit_id: DigitId) {
446 while let Some(index) = self.captures.iter_mut().position( | v | v.digit_id == digit_id) {
447 self.captures.remove(index);
448 }
449 }
450
451 pub (crate) fn remove_hover(&mut self, digit_id: DigitId) {
452 while let Some(index) = self.hovers.iter_mut().position( | v | v.digit_id == digit_id) {
453 self.hovers.remove(index);
454 }
455 }
456
457 pub (crate) fn tap_count(&self) -> u32 {
458 self.tap.count
459 }
460
461 pub (crate) fn process_tap_count(&mut self, pos: DVec2, time: f64) -> u32 {
462 if (time - self.tap.last_time) < TAP_COUNT_TIME
465 && pos.distance(&self.tap.last_pos) < TAP_COUNT_DISTANCE
466 {
467 self.tap.count += 1;
468 }
469 else {
470 self.tap.count = 1;
471 }
472 self.tap.last_pos = pos;
473 self.tap.last_time = time;
474 return self.tap.count
475 }
476
477 pub (crate) fn process_touch_update_start(&mut self, time: f64, touches: &[TouchPoint]) {
478 for touch in touches {
479 if let TouchState::Start = touch.state {
480 self.process_tap_count(touch.abs, time);
481 }
482 }
483 }
484
485 pub (crate) fn process_touch_update_end(&mut self, touches: &[TouchPoint]) {
486 for touch in touches {
487 let digit_id = live_id_num!(touch, touch.uid).into();
488 match touch.state {
489 TouchState::Stop => {
490 self.release_digit(digit_id);
491 self.remove_hover(digit_id);
492 }
493 TouchState::Start | TouchState::Move | TouchState::Stable => {
494 self.cycle_hover_area(digit_id);
495 }
496 }
497 }
498 self.switch_captures();
499 }
500
501 pub (crate) fn mouse_down(&mut self, button: MouseButton, window_id: WindowId) {
502 if self.first_mouse_button.is_none() {
503 self.first_mouse_button = Some((button, window_id));
504 }
505 }
506
507 pub (crate) fn switch_captures(&mut self) {
508 for capture in &mut self.captures {
509 if let Some(area) = capture.switch_capture {
510 capture.area = area;
511 capture.switch_capture = None;
512 }
513 }
514 }
515
516 pub (crate) fn mouse_up(&mut self, button: MouseButton) {
517 match self.first_mouse_button {
518 Some((fmb, _)) if fmb == button => {
519 self.first_mouse_button = None;
520 let digit_id = live_id!(mouse).into();
521 self.release_digit(digit_id);
522 }
523 _ => { }
524 }
525 }
526
527 pub (crate) fn test_sweep_lock(&mut self, sweep_area: Area) -> bool {
528 if let Some(lock) = self.sweep_lock {
529 if lock != sweep_area {
530 return true
531 }
532 }
533 false
534 }
535
536 pub fn sweep_lock(&mut self, area: Area) {
537 if self.sweep_lock.is_none() {
538 self.sweep_lock = Some(area);
539 }
540 }
541
542 pub fn sweep_unlock(&mut self, area: Area) {
543 if self.sweep_lock == Some(area) {
544 self.sweep_lock = None;
545 }
546 }
547
548}
549
550#[derive(Clone, Debug)]
551pub enum DigitDevice {
552 Mouse {
553 button: MouseButton,
554 },
555 Touch {
556 uid: u64
557 },
558 XrHand{
559 is_left: bool,
560 index: usize
561 },
562 XrController{
563 }
564}
565
566impl DigitDevice {
567 pub fn is_touch(&self) -> bool { matches!(self, Self::Touch {..}) }
569 pub fn is_mouse(&self) -> bool { matches!(self, Self::Mouse {..}) }
571 pub fn is_xr_hand(&self) -> bool { matches!(self, Self::XrHand {..}) }
573 pub fn is_xr_controller(&self) -> bool { matches!(self, Self::XrController {..}) }
574 pub fn has_hovers(&self) -> bool { matches!(self, Self::Mouse {..} | Self::XrController {..}| Self::XrHand {..}) }
576 pub fn mouse_button(&self) -> Option<MouseButton> {
578 if let Self::Mouse {button} = self {
579 Some(*button)
580 } else {
581 None
582 }
583 }
584 pub fn touch_uid(&self) -> Option<u64> {
586 if let Self::Touch {uid} = self {
587 Some(*uid)
588 } else {
589 None
590 }
591 }
592 pub fn is_primary_hit(&self) -> bool {
594 match self {
595 DigitDevice::Mouse { button } => button.is_primary(),
596 DigitDevice::Touch {..} => true,
597 DigitDevice::XrHand {..} => true,
598 DigitDevice::XrController {..} => true,
599 }
600 }
601 }
603
604#[derive(Clone, Debug)]
605pub struct FingerDownEvent {
606 pub window_id: WindowId,
607 pub abs: DVec2,
608
609 pub digit_id: DigitId,
610 pub device: DigitDevice,
611
612 pub tap_count: u32,
613 pub modifiers: KeyModifiers,
614 pub time: f64,
615 pub rect: Rect,
616}
617impl Deref for FingerDownEvent {
618 type Target = DigitDevice;
619 fn deref(&self) -> &DigitDevice {
620 &self.device
621 }
622}
623impl FingerDownEvent {
624 pub fn mod_control(&self) -> bool {self.modifiers.control}
625 pub fn mod_alt(&self) -> bool {self.modifiers.alt}
626 pub fn mod_shift(&self) -> bool {self.modifiers.shift}
627 pub fn mod_logo(&self) -> bool {self.modifiers.logo}
628}
629
630#[derive(Clone, Debug)]
631pub struct FingerMoveEvent {
632 pub window_id: WindowId,
633 pub abs: DVec2,
634 pub digit_id: DigitId,
635 pub device: DigitDevice,
636
637 pub tap_count: u32,
638 pub modifiers: KeyModifiers,
639 pub time: f64,
640
641 pub abs_start: DVec2,
642 pub rect: Rect,
643 pub is_over: bool,
644}
645impl Deref for FingerMoveEvent {
646 type Target = DigitDevice;
647 fn deref(&self) -> &DigitDevice {
648 &self.device
649 }
650}
651impl FingerMoveEvent {
652 pub fn move_distance(&self) -> f64 {
653 ((self.abs_start.x - self.abs.x).powf(2.) + (self.abs_start.y - self.abs.y).powf(2.)).sqrt()
654 }
655}
656
657#[derive(Clone, Debug)]
658pub struct FingerUpEvent {
659 pub window_id: WindowId,
660 pub abs: DVec2,
662 pub abs_start: DVec2,
664 pub capture_time: f64,
666 pub time: f64,
668
669 pub digit_id: DigitId,
670 pub device: DigitDevice,
671 pub has_long_press_occurred: bool,
674
675 pub tap_count: u32,
676 pub modifiers: KeyModifiers,
677 pub rect: Rect,
678 pub is_over: bool,
680 pub is_sweep: bool,
681}
682impl Deref for FingerUpEvent {
683 type Target = DigitDevice;
684 fn deref(&self) -> &DigitDevice {
685 &self.device
686 }
687}
688impl FingerUpEvent {
689 pub fn was_tap(&self) -> bool {
691 if self.has_long_press_occurred {
692 return false;
693 }
694 self.time - self.capture_time < TAP_COUNT_TIME
695 && (self.abs_start - self.abs).length() < TAP_COUNT_DISTANCE
696 }
697}
698
699#[derive(Clone, Debug)]
700pub struct FingerLongPressEvent {
701 pub window_id: WindowId,
702 pub abs: DVec2,
704 pub capture_time: f64,
706 pub time: f64,
708
709 pub digit_id: DigitId,
710 pub device: DigitDevice,
711 pub rect: Rect,
712}
713
714#[derive(Clone, Debug, Default, PartialEq)]
715pub enum HoverState {
716 In,
717 #[default]
718 Over,
719 Out
720}
721
722#[derive(Clone, Debug)]
723pub struct FingerHoverEvent {
724 pub window_id: WindowId,
725 pub abs: DVec2,
726 pub digit_id: DigitId,
727 pub device: DigitDevice,
728 pub modifiers: KeyModifiers,
729 pub time: f64,
730 pub rect: Rect,
731}
732
733#[derive(Clone, Debug)]
734pub struct FingerScrollEvent {
735 pub window_id: WindowId,
736 pub digit_id: DigitId,
737 pub abs: DVec2,
738 pub scroll: DVec2,
739 pub device: DigitDevice,
740 pub modifiers: KeyModifiers,
741 pub time: f64,
742 pub rect: Rect,
743}
744
745#[derive(Clone, Debug, Default)]
756pub struct HitOptions {
757 pub margin: Option<Margin>,
758 pub sweep_area: Area,
759 pub capture_overload: bool,
760}
761
762impl HitOptions {
763 pub fn new() -> Self {
764 Self::default()
765 }
766
767 pub fn with_sweep_area(self, area: Area) -> Self {
768 Self {
769 sweep_area: area,
770 ..self
771 }
772 }
773 pub fn with_margin(self, margin: Margin) -> Self {
774 Self {
775 margin: Some(margin),
776 ..self
777 }
778 }
779 pub fn with_capture_overload(self, capture_overload:bool) -> Self {
780 Self {
781 capture_overload,
782 ..self
783 }
784 }
785}
786
787impl Event{
788 pub fn unhandle(&self, cx:&mut Cx, area:&Area){
789 match self{
790 Event::TouchUpdate(e)=>{
791 for t in &e.touches {
792 if let TouchState::Start = t.state{
793 if t.handled.get() == *area{
794 t.handled.set(Area::Empty);
795 }
796 cx.fingers.uncapture_area(*area);
797 }
798 }
799 }
800 Event::MouseDown(fd)=>{
801 if fd.handled.get() == *area{
802 fd.handled.set(Area::Empty);
803 }
804 cx.fingers.uncapture_area(*area);
805 }
806 _=>()
807 }
808 }
809}
810
811impl Event {
812
813 pub fn hits(&self, cx: &mut Cx, area: Area) -> Hit {
814 self.hits_with_options(cx, area, HitOptions::default())
815 }
816
817 pub fn hits_with_test<F>(&self, cx: &mut Cx, area: Area, hit_test:F) -> Hit
818 where F: Fn(DVec2, &Rect, &Option<Margin>)->bool{
819 self.hits_with_options_and_test(cx, area, HitOptions::new(), hit_test)
820 }
821
822 pub fn hits_with_sweep_area(&self, cx: &mut Cx, area: Area, sweep_area: Area) -> Hit {
823 self.hits_with_options(cx, area, HitOptions::new().with_sweep_area(sweep_area))
824 }
825
826 pub fn hits_with_capture_overload(&self, cx: &mut Cx, area: Area, capture_overload: bool) -> Hit {
827 self.hits_with_options(cx, area, HitOptions::new().with_capture_overload(capture_overload))
828 }
829
830 pub fn hits_with_options(&self, cx: &mut Cx, area: Area, options: HitOptions) -> Hit {
831 self.hits_with_options_and_test(cx, area, options, |abs, rect, margin|{
832 Margin::rect_contains_with_margin(abs, rect, margin)
833 })
834 }
835
836 pub fn hits_with_options_and_test<F>(&self, cx: &mut Cx, area: Area, options: HitOptions, hit_test:F) -> Hit
837 where F: Fn(DVec2, &Rect, &Option<Margin>)->bool
838 {
839 if !area.is_valid(cx) {
840 return Hit::Nothing
841 }
842 match self {
843 Event::KeyFocus(kf) => {
844 if area == kf.prev {
845 return Hit::KeyFocusLost(kf.clone())
846 }
847 else if area == kf.focus {
848 return Hit::KeyFocus(kf.clone())
849 }
850 },
851 Event::KeyDown(kd) => {
852 if cx.keyboard.has_key_focus(area) {
853 return Hit::KeyDown(kd.clone())
854 }
855 },
856 Event::KeyUp(ku) => {
857 if cx.keyboard.has_key_focus(area) {
858 return Hit::KeyUp(ku.clone())
859 }
860 },
861 Event::TextInput(ti) => {
862 if cx.keyboard.has_key_focus(area) {
863 return Hit::TextInput(ti.clone())
864 }
865 },
866 Event::TextCopy(tc) => {
867 if cx.keyboard.has_key_focus(area) {
868 return Hit::TextCopy(tc.clone());
869 }
870 },
871 Event::TextCut(tc) => {
872 if cx.keyboard.has_key_focus(area) {
873 return Hit::TextCut(tc.clone());
874 }
875 },
876 Event::Scroll(e) => {
877 if cx.fingers.test_sweep_lock(options.sweep_area) {
878 return Hit::Nothing
880 }
881 let digit_id = live_id!(mouse).into();
882
883 let rect = area.clipped_rect(&cx);
884 if hit_test(e.abs, &rect, &options.margin) {
885 let device = DigitDevice::Mouse {
886 button: MouseButton::PRIMARY,
887 };
888 return Hit::FingerScroll(FingerScrollEvent {
889 abs: e.abs,
890 rect,
891 window_id: e.window_id,
892 digit_id,
893 device,
894 modifiers: e.modifiers,
895 time: e.time,
896 scroll: e.scroll
897 })
898 }
899 },
900 Event::TouchUpdate(e) => {
901 if cx.fingers.test_sweep_lock(options.sweep_area) {
902 return Hit::Nothing
904 }
905 for t in &e.touches {
906 let digit_id = live_id_num!(touch, t.uid).into();
907 let device = DigitDevice::Touch { uid: t.uid };
908
909 match t.state {
910 TouchState::Start => {
911 if cx.fingers.find_digit_for_captured_area(area).is_some() {
913 let rect = area.clipped_rect(&cx);
914 return Hit::FingerDown(FingerDownEvent {
915 window_id: e.window_id,
916 abs: t.abs,
917 digit_id,
918 device,
919 tap_count: cx.fingers.tap_count(),
920 modifiers: e.modifiers,
921 time: e.time,
922 rect,
923 });
924 }
925
926 if !options.capture_overload && !t.handled.get().is_empty() {
927 continue;
928 }
929
930 if cx.fingers.find_area_capture(area).is_some(){
931 continue;
932 }
933
934 let rect = area.clipped_rect(&cx);
935 if !hit_test(t.abs, &rect, &options.margin) {
936 continue;
937 }
938
939 cx.fingers.capture_digit(digit_id, area, options.sweep_area, e.time, t.abs);
940
941 t.handled.set(area);
942 return Hit::FingerDown(FingerDownEvent {
943 window_id: e.window_id,
944 abs: t.abs,
945 digit_id,
946 device,
947 tap_count: cx.fingers.tap_count(),
948 modifiers: e.modifiers,
949 time: e.time,
950 rect,
951 });
952 }
953 TouchState::Stop => {
954 let tap_count = cx.fingers.tap_count();
955 let rect = area.clipped_rect(&cx);
956 if let Some(capture) = cx.fingers.find_area_capture(area) {
957 return Hit::FingerUp(FingerUpEvent {
958 abs_start: capture.abs_start,
959 rect,
960 window_id: e.window_id,
961 abs: t.abs,
962 digit_id,
963 device,
964 has_long_press_occurred: capture.has_long_press_occurred,
965 tap_count,
966 capture_time: capture.time,
967 modifiers: e.modifiers,
968 time: e.time,
969 is_over: rect.contains(t.abs),
970 is_sweep: false,
971 });
972 }
973 }
974 TouchState::Move => {
975 let tap_count = cx.fingers.tap_count();
976 let rect = area.clipped_rect(&cx);
978
979 if !options.sweep_area.is_empty() {
981 if let Some(capture) = cx.fingers.find_digit_capture(digit_id) {
982 if capture.switch_capture.is_none()
983 && hit_test(t.abs, &rect, &options.margin)
984 {
985 if t.handled.get().is_empty() {
986 t.handled.set(area);
987 if capture.area == area {
988 return Hit::FingerMove(FingerMoveEvent {
989 window_id: e.window_id,
990 abs: t.abs,
991 digit_id,
992 device,
993 tap_count,
994 modifiers: e.modifiers,
995 time: e.time,
996 abs_start: capture.abs_start,
997 rect,
998 is_over: true,
999 });
1000 }
1001 else if capture.sweep_area == options.sweep_area { capture.switch_capture = Some(area);
1003 return Hit::FingerDown(FingerDownEvent {
1004 window_id: e.window_id,
1005 abs: t.abs,
1006 digit_id,
1007 device,
1008 tap_count: cx.fingers.tap_count(),
1009 modifiers: e.modifiers,
1010 time: e.time,
1011 rect,
1012 });
1013 }
1014 }
1015 }
1016 else if capture.area == area { if capture.switch_capture.is_none() {
1018 capture.switch_capture = Some(Area::Empty);
1019 }
1020 return Hit::FingerUp(FingerUpEvent {
1021 abs_start: capture.abs_start,
1022 rect,
1023 window_id: e.window_id,
1024 abs: t.abs,
1025 digit_id,
1026 device,
1027 has_long_press_occurred: capture.has_long_press_occurred,
1028 tap_count,
1029 capture_time: capture.time,
1030 modifiers: e.modifiers,
1031 time: e.time,
1032 is_sweep: true,
1033 is_over: false,
1034 });
1035 }
1036 }
1037 }
1038 else if let Some(capture) = cx.fingers.find_area_capture(area) {
1039 return Hit::FingerMove(FingerMoveEvent {
1040 window_id: e.window_id,
1041 abs: t.abs,
1042 digit_id,
1043 device,
1044 tap_count,
1045 modifiers: e.modifiers,
1046 time: e.time,
1047 abs_start: capture.abs_start,
1048 rect,
1049 is_over: hit_test(t.abs, &rect, &options.margin),
1050 })
1051 }
1052 }
1053 TouchState::Stable => {}
1054 }
1055 }
1056 }
1057 Event::MouseMove(e) => { if cx.fingers.test_sweep_lock(options.sweep_area) {
1059 return Hit::Nothing
1061 }
1062
1063 let digit_id = live_id!(mouse).into();
1064
1065 let tap_count = cx.fingers.tap_count();
1066 let hover_last = cx.fingers.find_hover_area(digit_id);
1067 let rect = area.clipped_rect(&cx);
1068
1069 if let Some((button, _window_id)) = cx.fingers.first_mouse_button {
1070 let device = DigitDevice::Mouse {
1071 button,
1072 };
1073 if !options.sweep_area.is_empty() {
1075 if let Some(capture) = cx.fingers.find_digit_capture(digit_id) {
1076 if capture.switch_capture.is_none()
1077 && hit_test(e.abs, &rect, &options.margin) {
1078 if e.handled.get().is_empty() {
1079 e.handled.set(area);
1080 if capture.area == area {
1081 return Hit::FingerMove(FingerMoveEvent {
1082 window_id: e.window_id,
1083 abs: e.abs,
1084 digit_id,
1085 device,
1086 tap_count,
1087 modifiers: e.modifiers,
1088 time: e.time,
1089 abs_start: capture.abs_start,
1090 rect,
1091 is_over: true,
1092 })
1093 }
1094 else if capture.sweep_area == options.sweep_area { capture.switch_capture = Some(area);
1096 cx.fingers.new_hover_area(digit_id, area);
1097 return Hit::FingerDown(FingerDownEvent {
1098 window_id: e.window_id,
1099 abs: e.abs,
1100 digit_id,
1101 device,
1102 tap_count: cx.fingers.tap_count(),
1103 modifiers: e.modifiers,
1104 time: e.time,
1105 rect,
1106 })
1107 }
1108 }
1109 }
1110 else if capture.area == area { if capture.switch_capture.is_none() {
1112 capture.switch_capture = Some(Area::Empty);
1113 }
1114 return Hit::FingerUp(FingerUpEvent {
1115 abs_start: capture.abs_start,
1116 rect,
1117 window_id: e.window_id,
1118 abs: e.abs,
1119 digit_id,
1120 device,
1121 has_long_press_occurred: capture.has_long_press_occurred,
1122 tap_count,
1123 capture_time: capture.time,
1124 modifiers: e.modifiers,
1125 time: e.time,
1126 is_sweep: true,
1127 is_over: false,
1128 });
1129
1130 }
1131 }
1132 }
1133 else if let Some(capture) = cx.fingers.find_area_capture(area) {
1134 let event = Hit::FingerMove(FingerMoveEvent {
1135 window_id: e.window_id,
1136 abs: e.abs,
1137 digit_id,
1138 device,
1139 tap_count,
1140 modifiers: e.modifiers,
1141 time: e.time,
1142 abs_start: capture.abs_start,
1143 rect,
1144 is_over: hit_test(e.abs, &rect, &options.margin),
1145 });
1146 cx.fingers.new_hover_area(digit_id, area);
1147 return event
1148 }
1149 }
1150 else {
1151 let device = DigitDevice::Mouse {
1152 button: MouseButton::PRIMARY,
1153 };
1154
1155 let handled_area = e.handled.get();
1156
1157 let fhe = FingerHoverEvent {
1158 window_id: e.window_id,
1159 abs: e.abs,
1160 digit_id,
1161 device,
1162 modifiers: e.modifiers,
1163 time: e.time,
1164 rect,
1165 };
1166
1167 if hover_last == area {
1168
1169 if (handled_area.is_empty() || handled_area == area) && hit_test(e.abs, &rect, &options.margin) {
1170 e.handled.set(area);
1171 cx.fingers.new_hover_area(digit_id, area);
1172 return Hit::FingerHoverOver(fhe)
1173 }
1174 else {
1175 return Hit::FingerHoverOut(fhe)
1176 }
1177 }
1178 else {
1179 if (handled_area.is_empty() || handled_area == area) && hit_test(e.abs, &rect, &options.margin) {
1180 cx.fingers.new_hover_area(digit_id, area);
1182 e.handled.set(area);
1183 return Hit::FingerHoverIn(fhe)
1184 }
1185 }
1186 }
1187 },
1188 Event::MouseDown(e) => {
1189
1190 let digit_id = live_id!(mouse).into();
1191
1192 let device = DigitDevice::Mouse {
1193 button: e.button,
1194 };
1195
1196 if cx.fingers.find_digit_for_captured_area(area).is_some() {
1198 let rect = area.clipped_rect(&cx);
1199 return Hit::FingerDown(FingerDownEvent {
1200 window_id: e.window_id,
1201 abs: e.abs,
1202 digit_id,
1203 device,
1204 tap_count: cx.fingers.tap_count(),
1205 modifiers: e.modifiers,
1206 time: e.time,
1207 rect,
1208 })
1209 }
1210
1211 if cx.fingers.test_sweep_lock(options.sweep_area) {
1212 return Hit::Nothing
1214 }
1215
1216
1217 if !options.capture_overload && !e.handled.get().is_empty() {
1218 return Hit::Nothing
1219 }
1220
1221 if cx.fingers.first_mouse_button.is_some() && cx.fingers.first_mouse_button.unwrap().0 != e.button{
1222 return Hit::Nothing
1223 }
1224
1225 let rect = area.clipped_rect(&cx);
1226 if !hit_test(e.abs, &rect, &options.margin) {
1227 return Hit::Nothing
1228 }
1229
1230
1231 if cx.fingers.find_digit_for_captured_area(area).is_some() {
1232 return Hit::Nothing;
1233 }
1234
1235 cx.fingers.capture_digit(digit_id, area, options.sweep_area, e.time, e.abs);
1236 e.handled.set(area);
1237 cx.fingers.new_hover_area(digit_id, area);
1238 return Hit::FingerDown(FingerDownEvent {
1239 window_id: e.window_id,
1240 abs: e.abs,
1241 digit_id,
1242 device,
1243 tap_count: cx.fingers.tap_count(),
1244 modifiers: e.modifiers,
1245 time: e.time,
1246 rect,
1247 })
1248 },
1249 Event::MouseUp(e) => {
1250 if cx.fingers.test_sweep_lock(options.sweep_area) {
1251 return Hit::Nothing
1253 }
1254
1255 if cx.fingers.first_mouse_button.is_some() && cx.fingers.first_mouse_button.unwrap().0 != e.button {
1256 return Hit::Nothing
1257 }
1258
1259 let digit_id = live_id!(mouse).into();
1260
1261 let device = DigitDevice::Mouse {
1262 button: e.button,
1263 };
1264 let tap_count = cx.fingers.tap_count();
1265 let rect = area.clipped_rect(&cx);
1266
1267 if let Some(capture) = cx.fingers.find_area_capture(area) {
1268 let is_over = hit_test(e.abs, &rect, &options.margin);
1269 let event = Hit::FingerUp(FingerUpEvent {
1270 abs_start: capture.abs_start,
1271 rect,
1272 window_id: e.window_id,
1273 abs: e.abs,
1274 digit_id,
1275 device,
1276 has_long_press_occurred: capture.has_long_press_occurred,
1277 tap_count,
1278 capture_time: capture.time,
1279 modifiers: e.modifiers,
1280 time: e.time,
1281 is_over,
1282 is_sweep: false,
1283 });
1284 if is_over {
1285 cx.fingers.new_hover_area(digit_id, area);
1286 }
1287 return event
1288 }
1289 },
1290 Event::MouseLeave(e) => {
1291 if cx.fingers.test_sweep_lock(options.sweep_area) {
1292 return Hit::Nothing;
1294 }
1295 let device = DigitDevice::Mouse { button: MouseButton::empty() };
1296 let digit_id = live_id!(mouse).into();
1297 let rect = area.clipped_rect(&cx);
1298 let hover_last = cx.fingers.find_hover_area(digit_id);
1299 let handled_area = e.handled.get();
1300
1301 let fhe = FingerHoverEvent {
1302 window_id: e.window_id,
1303 abs: e.abs,
1304 digit_id,
1305 device,
1306 modifiers: e.modifiers,
1307 time: e.time,
1308 rect,
1309 };
1310 if hover_last == area {
1311 return Hit::FingerHoverOut(fhe);
1312 }
1313 },
1314 Event::LongPress(e) => {
1315 if cx.fingers.test_sweep_lock(options.sweep_area) {
1316 log!("Skipping LongPress Hit, sweep_area: {:?}", options.sweep_area);
1317 return Hit::Nothing
1318 }
1319
1320 let rect = area.clipped_rect(&cx);
1321 if let Some(capture) = cx.fingers.find_area_capture(area) {
1322 capture.has_long_press_occurred = true;
1323 let digit_id = live_id_num!(touch, e.uid).into();
1328 let device = DigitDevice::Touch {
1329 uid: e.uid,
1330 };
1331 return Hit::FingerLongPress(FingerLongPressEvent {
1332 window_id: e.window_id,
1333 abs: e.abs,
1334 capture_time: capture.time,
1335 time: e.time,
1336 digit_id,
1337 device,
1338 rect,
1339 });
1340 }
1341 },
1342 Event::DesignerPick(e) => {
1343
1344 let rect = area.clipped_rect(&cx);
1345 if !hit_test(e.abs, &rect, &options.margin) {
1346 return Hit::Nothing
1347 }
1348 return Hit::DesignerPick(e.clone())
1351 },
1352 Event::XrLocal(e)=>{
1353 return e.hits_with_options_and_test(cx, area, options, hit_test)
1354 },
1355 _ => ()
1356 };
1357 Hit::Nothing
1358 }
1359}