From 44e36068a37945ca91bfaafba96efe77bdb3df26 Mon Sep 17 00:00:00 2001 From: darkfi Date: Thu, 19 Dec 2024 14:28:05 +0100 Subject: [PATCH] wallet: editbox delete selection --- bin/darkwallet/src/ui/editbox/editable.rs | 27 +++++++++++++++--- bin/darkwallet/src/ui/editbox/mod.rs | 34 +++++++++++++++++++++-- 2 files changed, 54 insertions(+), 7 deletions(-) diff --git a/bin/darkwallet/src/ui/editbox/editable.rs b/bin/darkwallet/src/ui/editbox/editable.rs index 11a647ec1d3a..fc75457cd6ce 100644 --- a/bin/darkwallet/src/ui/editbox/editable.rs +++ b/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) -> String { let mut text = String::new(); for (i, glyph) in glyphs.iter().enumerate() { diff --git a/bin/darkwallet/src/ui/editbox/mod.rs b/bin/darkwallet/src/ui/editbox/mod.rs index 3b780a6e28bf..bd0b9b0ebf4e 100644 --- a/bin/darkwallet/src/ui/editbox/mod.rs +++ b/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;