Răsfoiți Sursa

wallet: editbox phone touchscreen highlighting text

darkfi 2 ani în urmă
părinte
comite
baf83715e6
2 a modificat fișierele cu 143 adăugiri și 70 ștergeri
  1. 94 68
      bin/darkwallet/src/gfx2.rs
  2. 49 2
      bin/darkwallet/src/ui/editbox.rs

+ 94 - 68
bin/darkwallet/src/gfx2.rs

@@ -342,11 +342,8 @@ pub enum GraphicsMethod {
 pub type GraphicsEventPublisherPtr = Arc<GraphicsEventPublisher>;
 
 pub struct GraphicsEventPublisher {
-    lock_key_down: SyncMutex<Option<SubscriptionId>>,
-    key_down: PublisherPtr<(KeyCode, KeyMods, bool)>,
-
-    lock_key_up: SyncMutex<Option<SubscriptionId>>,
-    key_up: PublisherPtr<(KeyCode, KeyMods)>,
+    lock_resize: SyncMutex<Option<SubscriptionId>>,
+    resize: PublisherPtr<(f32, f32)>,
 
     lock_mouse_move: SyncMutex<Option<SubscriptionId>>,
     mouse_move: PublisherPtr<(f32, f32)>,
@@ -360,21 +357,24 @@ pub struct GraphicsEventPublisher {
     lock_mouse_btn_up: SyncMutex<Option<SubscriptionId>>,
     mouse_btn_up: PublisherPtr<(MouseButton, f32, f32)>,
 
-    lock_resize: SyncMutex<Option<SubscriptionId>>,
-    resize: PublisherPtr<(f32, f32)>,
-
     lock_char: SyncMutex<Option<SubscriptionId>>,
     chr: PublisherPtr<(char, KeyMods, bool)>,
+
+    lock_key_down: SyncMutex<Option<SubscriptionId>>,
+    key_down: PublisherPtr<(KeyCode, KeyMods, bool)>,
+
+    lock_key_up: SyncMutex<Option<SubscriptionId>>,
+    key_up: PublisherPtr<(KeyCode, KeyMods)>,
+
+    lock_touch: SyncMutex<Option<SubscriptionId>>,
+    touch: PublisherPtr<(TouchPhase, u64, f32, f32)>,
 }
 
 impl GraphicsEventPublisher {
     pub fn new() -> Arc<Self> {
         Arc::new(Self {
-            lock_key_down: SyncMutex::new(None),
-            key_down: Publisher::new(),
-
-            lock_key_up: SyncMutex::new(None),
-            key_up: Publisher::new(),
+            lock_resize: SyncMutex::new(None),
+            resize: Publisher::new(),
 
             lock_mouse_move: SyncMutex::new(None),
             mouse_move: Publisher::new(),
@@ -388,26 +388,25 @@ impl GraphicsEventPublisher {
             lock_mouse_btn_up: SyncMutex::new(None),
             mouse_btn_up: Publisher::new(),
 
-            lock_resize: SyncMutex::new(None),
-            resize: Publisher::new(),
-
             lock_char: SyncMutex::new(None),
             chr: Publisher::new(),
-        })
-    }
 
-    fn lock_key_down(&self, sub_id: SubscriptionId) {
-        *self.lock_key_down.lock().unwrap() = Some(sub_id);
-    }
-    fn unlock_key_down(&self) {
-        *self.lock_key_down.lock().unwrap() = None;
+            lock_key_down: SyncMutex::new(None),
+            key_down: Publisher::new(),
+
+            lock_key_up: SyncMutex::new(None),
+            key_up: Publisher::new(),
+
+            lock_touch: SyncMutex::new(None),
+            touch: Publisher::new(),
+        })
     }
 
-    fn lock_key_up(&self, sub_id: SubscriptionId) {
-        *self.lock_key_up.lock().unwrap() = Some(sub_id);
+    fn lock_resize(&self, sub_id: SubscriptionId) {
+        *self.lock_resize.lock().unwrap() = Some(sub_id);
     }
-    fn unlock_key_up(&self) {
-        *self.lock_key_up.lock().unwrap() = None;
+    fn unlock_resize(&self) {
+        *self.lock_resize.lock().unwrap() = None;
     }
 
     fn lock_mouse_move(&self, sub_id: SubscriptionId) {
@@ -438,13 +437,6 @@ impl GraphicsEventPublisher {
         *self.lock_mouse_btn_up.lock().unwrap() = None;
     }
 
-    fn lock_resize(&self, sub_id: SubscriptionId) {
-        *self.lock_resize.lock().unwrap() = Some(sub_id);
-    }
-    fn unlock_resize(&self) {
-        *self.lock_resize.lock().unwrap() = None;
-    }
-
     fn lock_char(&self, sub_id: SubscriptionId) {
         *self.lock_char.lock().unwrap() = Some(sub_id);
     }
@@ -452,24 +444,35 @@ impl GraphicsEventPublisher {
         *self.lock_char.lock().unwrap() = None;
     }
 
-    fn notify_key_down(&self, key: KeyCode, mods: KeyMods, repeat: bool) {
-        let ev = (key, mods, repeat);
+    fn lock_key_down(&self, sub_id: SubscriptionId) {
+        *self.lock_key_down.lock().unwrap() = Some(sub_id);
+    }
+    fn unlock_key_down(&self) {
+        *self.lock_key_down.lock().unwrap() = None;
+    }
 
-        let locked = self.lock_key_down.lock().unwrap().clone();
-        if let Some(locked) = locked {
-            self.key_down.notify_with_include(ev, &[locked]);
-        } else {
-            self.key_down.notify(ev);
-        }
+    fn lock_key_up(&self, sub_id: SubscriptionId) {
+        *self.lock_key_up.lock().unwrap() = Some(sub_id);
+    }
+    fn unlock_key_up(&self) {
+        *self.lock_key_up.lock().unwrap() = None;
     }
-    fn notify_key_up(&self, key: KeyCode, mods: KeyMods) {
-        let ev = (key, mods);
 
-        let locked = self.lock_key_up.lock().unwrap().clone();
+    fn lock_touch(&self, sub_id: SubscriptionId) {
+        *self.lock_touch.lock().unwrap() = Some(sub_id);
+    }
+    fn unlock_touch(&self) {
+        *self.lock_touch.lock().unwrap() = None;
+    }
+
+    fn notify_resize(&self, w: f32, h: f32) {
+        let ev = (w, h);
+
+        let locked = self.lock_resize.lock().unwrap().clone();
         if let Some(locked) = locked {
-            self.key_up.notify_with_include(ev, &[locked]);
+            self.resize.notify_with_include(ev, &[locked]);
         } else {
-            self.key_up.notify(ev);
+            self.resize.notify(ev);
         }
     }
 
@@ -483,7 +486,6 @@ impl GraphicsEventPublisher {
             self.mouse_move.notify(ev);
         }
     }
-
     fn notify_mouse_wheel(&self, x: f32, y: f32) {
         let ev = (x, y);
 
@@ -494,7 +496,6 @@ impl GraphicsEventPublisher {
             self.mouse_wheel.notify(ev);
         }
     }
-
     fn notify_mouse_btn_down(&self, button: MouseButton, x: f32, y: f32) {
         let ev = (button, x, y);
 
@@ -505,7 +506,6 @@ impl GraphicsEventPublisher {
             self.mouse_btn_down.notify(ev);
         }
     }
-
     fn notify_mouse_btn_up(&self, button: MouseButton, x: f32, y: f32) {
         let ev = (button, x, y);
 
@@ -517,16 +517,6 @@ impl GraphicsEventPublisher {
         }
     }
 
-    fn notify_resize(&self, w: f32, h: f32) {
-        let ev = (w, h);
-
-        let locked = self.lock_resize.lock().unwrap().clone();
-        if let Some(locked) = locked {
-            self.resize.notify_with_include(ev, &[locked]);
-        } else {
-            self.resize.notify(ev);
-        }
-    }
     fn notify_char(&self, chr: char, mods: KeyMods, repeat: bool) {
         let ev = (chr, mods, repeat);
 
@@ -538,11 +528,40 @@ impl GraphicsEventPublisher {
         }
     }
 
-    pub fn subscribe_key_down(&self) -> Subscription<(KeyCode, KeyMods, bool)> {
-        self.key_down.clone().subscribe()
+    fn notify_key_down(&self, key: KeyCode, mods: KeyMods, repeat: bool) {
+        let ev = (key, mods, repeat);
+
+        let locked = self.lock_key_down.lock().unwrap().clone();
+        if let Some(locked) = locked {
+            self.key_down.notify_with_include(ev, &[locked]);
+        } else {
+            self.key_down.notify(ev);
+        }
     }
-    pub fn subscribe_key_up(&self) -> Subscription<(KeyCode, KeyMods)> {
-        self.key_up.clone().subscribe()
+    fn notify_key_up(&self, key: KeyCode, mods: KeyMods) {
+        let ev = (key, mods);
+
+        let locked = self.lock_key_up.lock().unwrap().clone();
+        if let Some(locked) = locked {
+            self.key_up.notify_with_include(ev, &[locked]);
+        } else {
+            self.key_up.notify(ev);
+        }
+    }
+
+    fn notify_touch(&self, phase: TouchPhase, id: u64, x: f32, y: f32) {
+        let ev = (phase, id, x, y);
+
+        let locked = self.lock_touch.lock().unwrap().clone();
+        if let Some(locked) = locked {
+            self.touch.notify_with_include(ev, &[locked]);
+        } else {
+            self.touch.notify(ev);
+        }
+    }
+
+    pub fn subscribe_resize(&self) -> Subscription<(f32, f32)> {
+        self.resize.clone().subscribe()
     }
     pub fn subscribe_mouse_move(&self) -> Subscription<(f32, f32)> {
         self.mouse_move.clone().subscribe()
@@ -556,12 +575,18 @@ impl GraphicsEventPublisher {
     pub fn subscribe_mouse_btn_up(&self) -> Subscription<(MouseButton, f32, f32)> {
         self.mouse_btn_up.clone().subscribe()
     }
-    pub fn subscribe_resize(&self) -> Subscription<(f32, f32)> {
-        self.resize.clone().subscribe()
-    }
     pub fn subscribe_char(&self) -> Subscription<(char, KeyMods, bool)> {
         self.chr.clone().subscribe()
     }
+    pub fn subscribe_key_down(&self) -> Subscription<(KeyCode, KeyMods, bool)> {
+        self.key_down.clone().subscribe()
+    }
+    pub fn subscribe_key_up(&self) -> Subscription<(KeyCode, KeyMods)> {
+        self.key_up.clone().subscribe()
+    }
+    pub fn subscribe_touch(&self) -> Subscription<(TouchPhase, u64, f32, f32)> {
+        self.touch.clone().subscribe()
+    }
 }
 
 struct Stage {
@@ -795,8 +820,9 @@ impl EventHandler for Stage {
         self.event_pub.notify_key_up(keycode, mods);
     }
 
+    /// The id corresponds to multi-touch. Multiple touch events have different ids.
     fn touch_event(&mut self, phase: TouchPhase, id: u64, x: f32, y: f32) {
-        debug!(target: "gfx", "touch_event({:?}, {}, {}, {})", phase, id, x, y);
+        self.event_pub.notify_touch(phase, id, x, y);
     }
 
     fn quit_requested_event(&mut self) {

+ 49 - 2
bin/darkwallet/src/ui/editbox.rs

@@ -1,4 +1,4 @@
-use miniquad::{window, BufferId, KeyCode, KeyMods, MouseButton, TextureId};
+use miniquad::{window, BufferId, KeyCode, KeyMods, MouseButton, TextureId, TouchPhase};
 use rand::{rngs::OsRng, Rng};
 use std::{
     collections::HashMap,
@@ -245,6 +245,14 @@ impl EditBox {
                 }
             });
 
+            let ev_sub = event_pub.subscribe_touch();
+            let me2 = me.clone();
+            let touch_task = ex.spawn(async move {
+                loop {
+                    Self::process_touch(&me2, &ev_sub).await;
+                }
+            });
+
             let mut on_modify = OnModify::new(ex, node_name, node_id, me.clone());
             on_modify.when_change(is_focused.prop(), Self::change_focus);
 
@@ -255,6 +263,7 @@ impl EditBox {
                 mouse_btn_down_task,
                 mouse_btn_up_task,
                 mouse_move_task,
+                touch_task,
             ];
             tasks.append(&mut on_modify.tasks);
 
@@ -549,6 +558,24 @@ impl EditBox {
         self_.handle_mouse_move(mouse_x, mouse_y).await;
     }
 
+    async fn process_touch(me: &Weak<Self>, ev_sub: &Subscription<(TouchPhase, u64, f32, f32)>) {
+        let Ok((phase, id, touch_x, touch_y)) = ev_sub.receive().await else {
+            debug!(target: "ui::editbox", "Event relayer closed");
+            return
+        };
+
+        let Some(self_) = me.upgrade() else {
+            // Should not happen
+            panic!("self destroyed before touch_task was stopped!");
+        };
+
+        if !self_.is_active.get() {
+            return
+        }
+
+        self_.handle_touch(phase, id, touch_x, touch_y).await;
+    }
+
     async fn change_focus(self: Arc<Self>) {
         if !self.is_active.get() {
             return
@@ -611,7 +638,11 @@ impl EditBox {
             self.redraw().await;
         }
     }
-    fn handle_mouse_btn_up(&self, button: MouseButton, x: f32, y: f32) {
+    fn handle_mouse_btn_up(&self, btn: MouseButton, x: f32, y: f32) {
+        if btn != MouseButton::Left {
+            return
+        }
+
         // releasing mouse button will end selection
         self.mouse_btn_held.store(false, Ordering::Relaxed);
     }
@@ -635,6 +666,22 @@ impl EditBox {
         self.redraw().await;
     }
 
+    async fn handle_touch(&self, phase: TouchPhase, id: u64, touch_x: f32, touch_y: f32) {
+        // Ignore multi-touch
+        if id != 0 {
+            return
+        }
+        // Simulate mouse events
+        match phase {
+            TouchPhase::Started => {
+                self.handle_mouse_btn_down(MouseButton::Left, touch_x, touch_y).await
+            }
+            TouchPhase::Moved => self.handle_mouse_move(touch_x, touch_y).await,
+            TouchPhase::Ended => self.handle_mouse_btn_up(MouseButton::Left, touch_x, touch_y),
+            TouchPhase::Cancelled => {}
+        }
+    }
+
     /// Used when clicking the text. Given the x coord of the mouse, it finds the index
     /// of the closest glyph to that x coord.
     fn find_closest_glyph_idx(&self, x: f32, rect: &Rectangle) -> u32 {