From 327c435e8fff14e785dbdd1cba356d55adca7d2d Mon Sep 17 00:00:00 2001 From: darkfi Date: Wed, 10 Jul 2024 12:48:07 +0200 Subject: [PATCH] wallet: editbox bugfix, split regen_glyphs() from redraw() --- bin/darkwallet/src/gfx2.rs | 1 + bin/darkwallet/src/ui/editbox.rs | 49 +++++++++++++++++++++++++++++--- 2 files changed, 46 insertions(+), 4 deletions(-) diff --git a/bin/darkwallet/src/gfx2.rs b/bin/darkwallet/src/gfx2.rs index f626e7239..322949a4e 100644 --- a/bin/darkwallet/src/gfx2.rs +++ b/bin/darkwallet/src/gfx2.rs @@ -58,6 +58,7 @@ impl Vertex { } } +#[derive(Debug)] pub struct Point { pub x: f32, pub y: f32, diff --git a/bin/darkwallet/src/ui/editbox.rs b/bin/darkwallet/src/ui/editbox.rs index 3bc06ab83..4bb775c82 100644 --- a/bin/darkwallet/src/ui/editbox.rs +++ b/bin/darkwallet/src/ui/editbox.rs @@ -197,6 +197,7 @@ impl EditBox { // testing window::show_keyboard(true); + // Must do this whenever the text changes let glyphs = text_shaper.shape(text.get(), font_size.get()).await; let self_ = Arc::new_cyclic(|me: &Weak| { @@ -285,7 +286,8 @@ impl EditBox { //on_modify.when_change(scroll.prop(), redraw); //on_modify.when_change(cursor_pos.prop(), redraw); on_modify.when_change(font_size.prop(), redraw); - on_modify.when_change(text.prop(), redraw); + // We must also reshape text + //on_modify.when_change(text.prop(), redraw); on_modify.when_change(text_color.prop(), redraw); on_modify.when_change(cursor_color.prop(), redraw); on_modify.when_change(hi_bg_color.prop(), redraw); @@ -339,6 +341,12 @@ impl EditBox { Pimpl::EditBox(self_) } + /// This MUST be called whenever the text property is changed. + async fn regen_glyphs(&self) { + let glyphs = self.text_shaper.shape(self.text.get(), self.font_size.get()).await; + *self.glyphs.lock().unwrap() = glyphs; + } + /// Called whenever the text or any text property changes. /// Not related to cursor, text highlighting or bounding (clip) rects. async fn regen_mesh(&self, mut clip: Rectangle) -> TextRenderInfo { @@ -640,6 +648,7 @@ impl EditBox { let mut focus_changed = false; let Some(rect) = self.get_cached_world_rect().await else { return }; + // clicking inside box will: // 1. make it active // 2. begin selection @@ -815,6 +824,7 @@ impl EditBox { // meh lets pretend it doesn't exist for now. self.cursor_pos.set(cursor_pos + 1); + self.regen_glyphs().await; self.apply_cursor_scrolling(); self.redraw().await; } @@ -936,6 +946,7 @@ impl EditBox { self.text.set(text); }; + self.regen_glyphs().await; self.apply_cursor_scrolling(); self.redraw().await; } @@ -962,17 +973,50 @@ impl EditBox { self.cursor_pos.set(cursor_pos - 1); }; + self.regen_glyphs().await; self.apply_cursor_scrolling(); self.redraw().await; } KeyCode::Home => { + let cursor_pos = self.cursor_pos.get(); + + if !mods.shift { + self.selected.set_null(0).unwrap(); + self.selected.set_null(1).unwrap(); + } else if self.selected.is_null(0).unwrap() { + assert!(self.selected.is_null(1).unwrap()); + self.selected.set_u32(0, cursor_pos).unwrap(); + } + self.cursor_pos.set(0); + + // Update selection + if mods.shift { + self.selected.set_u32(1, cursor_pos).unwrap(); + } + self.apply_cursor_scrolling(); self.redraw().await; } KeyCode::End => { + let cursor_pos = self.cursor_pos.get(); + + if !mods.shift { + self.selected.set_null(0).unwrap(); + self.selected.set_null(1).unwrap(); + } else if self.selected.is_null(0).unwrap() { + assert!(self.selected.is_null(1).unwrap()); + self.selected.set_u32(0, cursor_pos).unwrap(); + } + let glyphs_len = self.glyphs.lock().unwrap().len(); self.cursor_pos.set(glyphs_len as u32); + + // Update selection + if mods.shift { + self.selected.set_u32(1, cursor_pos).unwrap(); + } + self.apply_cursor_scrolling(); self.redraw().await; } @@ -1136,9 +1180,6 @@ impl EditBox { // draw will recalc this when it's None let old = std::mem::replace(&mut *self.render_info.lock().unwrap(), None); - let glyphs = self.text_shaper.shape(self.text.get(), self.font_size.get()).await; - *self.glyphs.lock().unwrap() = glyphs; - let sg = self.sg.lock().await; let node = sg.get_node(self.node_id).unwrap();