Преглед изворни кода

wallet: editbox delete selection

darkfi пре 1 година
родитељ
комит
44e36068a3
2 измењених фајлова са 54 додато и 7 уклоњено
  1. 23 4
      bin/darkwallet/src/ui/editbox/editable.rs
  2. 31 3
      bin/darkwallet/src/ui/editbox/mod.rs

+ 23 - 4
bin/darkwallet/src/ui/editbox/editable.rs

@@ -55,8 +55,8 @@ impl ComposingText {
     fn clear(&mut self) -> String {
         self.region_start = 0;
         self.region_end = 0;
-        let final_text = std::mem::take(&mut self.compose_text) + &self.commit_text;
-        self.commit_text.clear();
+        let final_text =
+            std::mem::take(&mut self.commit_text) + &std::mem::take(&mut self.compose_text);
         final_text
     }
 
@@ -229,10 +229,11 @@ impl Editable {
     // set cursor
 
     /// Reset any composition in progress
-    fn end_compose(&mut self) {
+    pub fn end_compose(&mut self) {
         #[cfg(target_os = "android")]
         crate::android::cancel_composition();
 
+        debug!(target: "ui::editbox", "end_compose() [editable={self:?}]");
         let final_text = self.composer.clear();
         self.before_text += &final_text;
     }
@@ -242,11 +243,16 @@ impl Editable {
             self.before_text.clone() + &self.composer.commit_text + &self.composer.compose_text;
         text
     }
-    fn get_text(&self) -> String {
+    pub fn get_text(&self) -> String {
         let text = self.get_text_before() + &self.after_text;
         text
     }
 
+    pub fn set_text(&mut self, before: String, after: String) {
+        self.before_text = before;
+        self.after_text = after;
+    }
+
     pub fn compose(&mut self, suggest_text: &str, is_commit: bool) {
         //composer.activate_or_cont(self.cursor_pos.get() as usize);
         self.composer.compose(suggest_text.to_string());
@@ -342,6 +348,19 @@ impl Editable {
     }
 }
 
+impl std::fmt::Debug for Editable {
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        write!(
+            f,
+            "({}, {}, {}, {})",
+            self.before_text,
+            self.composer.commit_text,
+            self.composer.compose_text,
+            self.after_text
+        )
+    }
+}
+
 fn glyphs_to_string(glyphs: &Vec<Glyph>) -> String {
     let mut text = String::new();
     for (i, glyph) in glyphs.iter().enumerate() {

+ 31 - 3
bin/darkwallet/src/ui/editbox/mod.rs

@@ -774,14 +774,40 @@ impl EditBox {
 
     fn delete(&self, before: usize, after: usize) {
         let mut editable = self.editable.lock().unwrap();
-        let mut select = self.select.lock().unwrap();
+        let selection = std::mem::take(&mut *self.select.lock().unwrap());
 
-        if select.is_empty() {
+        if selection.is_empty() {
             editable.delete(before, after);
             return
         }
 
-        // How do we preserve the cursor pos after deleting text?
+        let sel = selection.first().unwrap();
+        let cursor_pos = std::cmp::min(sel.start, sel.end);
+
+        let render = editable.render();
+        let mut before_text = String::new();
+        let mut after_text = String::new();
+        'next: for (pos, glyph) in render.glyphs.iter().enumerate() {
+            for select in &selection {
+                let start = std::cmp::min(select.start, select.end);
+                let end = std::cmp::max(select.start, select.end);
+
+                if start <= pos && pos < end {
+                    continue 'next
+                }
+            }
+            if pos <= cursor_pos {
+                before_text += &glyph.substr;
+            } else {
+                after_text += &glyph.substr;
+            }
+        }
+
+        editable.set_text(before_text, after_text);
+
+        self.is_phone_select.store(false, Ordering::Relaxed);
+        // Reshow cursor (if hidden)
+        self.hide_cursor.store(false, Ordering::Relaxed);
     }
 
     fn adjust_cursor(&self, has_shift: bool, move_cursor: impl Fn(&mut Editable)) {
@@ -818,6 +844,8 @@ impl EditBox {
 
         {
             let mut editable = self.editable.lock().unwrap();
+            editable.end_compose();
+
             let rendered = editable.render();
             // Adjust with scroll here too
             let x = x - rect.x;