diff --git a/bin/darkwallet/src/main.rs b/bin/darkwallet/src/main.rs index 108c4f4f9..b8af1b326 100644 --- a/bin/darkwallet/src/main.rs +++ b/bin/darkwallet/src/main.rs @@ -133,6 +133,18 @@ fn main() { } }); async_runtime.push_task(ev_relay_task); + let ev_sub = event_pub.subscribe_char(); + let ev_relay_task = ex.spawn(async move { + debug!(target: "main", "event relayer started"); + loop { + let Ok((key, mods, repeat)) = ev_sub.receive().await else { + debug!(target: "main", "Event relayer closed"); + break + }; + debug!(target: "main", "char event: {:?} {:?} {}", key, mods, repeat); + } + }); + async_runtime.push_task(ev_relay_task); //let stage = gfx2::Stage::new(method_rep, event_pub); gfx2::run_gui(async_runtime, method_rep, event_pub); diff --git a/bin/darkwallet/src/text2.rs b/bin/darkwallet/src/text2.rs index 5924f00f9..98df959b4 100644 --- a/bin/darkwallet/src/text2.rs +++ b/bin/darkwallet/src/text2.rs @@ -270,6 +270,7 @@ impl TextShaper { } pub async fn shape(&self, text: String, font_size: f32) -> Vec { + //debug!(target: "text", "shape('{}', {})", text, font_size); // Lock font faces // Freetype faces are not threadsafe let mut faces = self.font_faces.lock().await; @@ -337,7 +338,7 @@ impl TextShaper { let mut prev_cluster = 0; //for (i, (position, info)) in positions.iter().zip(infos).enumerate() { - for (i, (position, info)) in + 'iter_glyphs: for (i, (position, info)) in glyph_pos_iter.iter().zip(glyph_infos_iter.iter()).enumerate() { let glyph_id = info.codepoint as u32; @@ -373,21 +374,26 @@ impl TextShaper { face_idx, }; //debug!(target: "text", "cache_key: {:?}", cache_key); - if let Some(sprite) = cache.get(&cache_key) { - let Some(sprite) = sprite.upgrade() else { break }; + 'load_sprite: { + if let Some(sprite) = cache.get(&cache_key) { + let Some(sprite) = sprite.upgrade() else { + break 'load_sprite; + }; - let glyph = Glyph { - glyph_id, - substr: String::new(), - sprite, - x_offset, - y_offset, - x_advance, - y_advance, - }; + //debug!(target: "text", "found glyph!"); + let glyph = Glyph { + glyph_id, + substr: String::new(), + sprite, + x_offset, + y_offset, + x_advance, + y_advance, + }; - glyphs.push(glyph); - continue + glyphs.push(glyph); + continue 'iter_glyphs; + } } let mut flags = ft::face::LoadFlag::DEFAULT; @@ -467,6 +473,7 @@ impl TextShaper { y_advance, }; + //debug!(target: "text", "pushing glyph..."); glyphs.push(glyph); } diff --git a/bin/darkwallet/src/ui/editbox.rs b/bin/darkwallet/src/ui/editbox.rs index 7eee7f30d..de3139b0f 100644 --- a/bin/darkwallet/src/ui/editbox.rs +++ b/bin/darkwallet/src/ui/editbox.rs @@ -22,13 +22,6 @@ use crate::{ use super::{eval_rect, get_parent_rect, read_rect, DrawUpdate, OnModify, Stoppable}; -// First refactor the event system -// Each event should have its own unique pipe -// Advantages: -// - less overhead when publishing msgs to ppl who dont need them -// - more advanced locking of streams when widgets capture input -// also add capturing and make use of it with editbox. - const CURSOR_WIDTH: f32 = 4.; #[derive(Debug, Clone, Eq, Hash, PartialEq)] @@ -37,6 +30,10 @@ enum PressedKey { Key(KeyCode), } +/// On key press (repeat=false), we immediately process the event. +/// Then there's a delay (repeat=true) and then for every step time +/// while key press events are being sent, we allow an event. +/// This ensures smooth typing in the editbox. struct PressedKeysSmoothRepeat { /// When holding keys, we track from start and last sent time. /// This is useful for initial delay and smooth scrolling. @@ -179,7 +176,7 @@ impl EditBox { .await; // testing - //window::show_keyboard(true); + window::show_keyboard(true); let self_ = Arc::new_cyclic(|me: &Weak| { // Start a task monitoring for key down events @@ -302,7 +299,7 @@ impl EditBox { }; // First filter for only single digit keys - let disallowed_keys = ['\r', '\u{8}', '\u{7f}', '\t']; + let disallowed_keys = ['\r', '\u{8}', '\u{7f}', '\t', '\n']; if disallowed_keys.contains(&key) { return } @@ -384,6 +381,27 @@ impl EditBox { async fn handle_key(&self, key: &KeyCode, mods: &KeyMods) { debug!(target: "ui::editbox", "handle_key({:?}, {:?})", key, mods); + match key { + //KeyCode::Left, + //KeyCode::Right, + //KeyCode::Up, + //KeyCode::Down, + //KeyCode::Enter, + KeyCode::Kp0 => self.insert_char('0').await, + KeyCode::Kp1 => self.insert_char('1').await, + KeyCode::Kp2 => self.insert_char('2').await, + KeyCode::Kp3 => self.insert_char('3').await, + KeyCode::Kp4 => self.insert_char('4').await, + KeyCode::Kp5 => self.insert_char('5').await, + KeyCode::Kp6 => self.insert_char('6').await, + KeyCode::Kp7 => self.insert_char('7').await, + KeyCode::Kp8 => self.insert_char('8').await, + KeyCode::Kp9 => self.insert_char('9').await, + KeyCode::KpDecimal => self.insert_char('.').await, + KeyCode::Enter | KeyCode::KpEnter => self.send_event().await, + //KeyCode::Backspace, + _ => {} + } } async fn redraw(&self) { @@ -465,6 +483,16 @@ impl EditBox { )], }) } + + async fn send_event(&self) { + let text = self.text.get(); + debug!(target: "ui::editbox", "sending text {}", text); + + // This should probably be unset instead + self.text.set(String::new()); + self.cursor_pos.set(0); + self.redraw().await; + } } impl Stoppable for EditBox { @@ -496,4 +524,5 @@ static ALLOWED_KEYCODES: &'static [KeyCode] = &[ KeyCode::Kp9, KeyCode::KpDecimal, KeyCode::KpEnter, + KeyCode::Backspace, ];