From 1987d0553c1a6d31a6b505cd8292ee99e240a105 Mon Sep 17 00:00:00 2001 From: ardocrat Date: Tue, 27 May 2025 14:28:23 +0300 Subject: [PATCH] ui: numeric keyboard input --- src/gui/views/input/keyboard.rs | 228 ++++++++++++------ src/gui/views/input/types.rs | 2 +- src/gui/views/network/setup/dandelion.rs | 8 +- src/gui/views/network/setup/node.rs | 4 +- src/gui/views/network/setup/p2p.rs | 8 +- src/gui/views/network/setup/pool.rs | 17 +- src/gui/views/network/setup/stratum.rs | 6 +- .../views/wallets/wallet/messages/request.rs | 140 +++++------ .../views/wallets/wallet/settings/common.rs | 2 +- .../views/wallets/wallet/transport/send.rs | 1 + 10 files changed, 250 insertions(+), 166 deletions(-) diff --git a/src/gui/views/input/keyboard.rs b/src/gui/views/input/keyboard.rs index 8ee47b9..79108ca 100644 --- a/src/gui/views/input/keyboard.rs +++ b/src/gui/views/input/keyboard.rs @@ -39,13 +39,13 @@ lazy_static! { /// Software keyboard content. pub struct KeyboardContent { /// Keyboard layout. - mode: KeyboardLayout + layout: KeyboardLayout } impl Default for KeyboardContent { fn default() -> Self { Self { - mode: KeyboardLayout::TEXT, + layout: KeyboardLayout::TEXT, } } } @@ -53,10 +53,13 @@ impl Default for KeyboardContent { impl KeyboardContent { /// Maximum keyboard content width. const MAX_WIDTH: f32 = 600.0; + /// Maximum numbers layout width. + const MAX_WIDTH_NUMBERS: f32 = 400.0; /// Draw keyboard content as separate [`Window`]. pub fn window_ui(&mut self, ctx: &egui::Context) { if !KeyboardContent::window_showing() { + self.layout = KeyboardLayout::TEXT; return; } let width = ctx.screen_rect().width(); @@ -78,7 +81,7 @@ impl KeyboardContent { left: View::get_left_inset(), right: View::get_right_inset(), top: 1.0, - bottom: View::get_bottom_inset() + 1.0, + bottom: View::get_bottom_inset(), }, fill: Colors::fill(), ..Default::default() @@ -88,7 +91,12 @@ impl KeyboardContent { // Calculate content width. let side_insets = View::get_left_inset() + View::get_right_inset(); let available_width = width - side_insets; - let w = f32::min(available_width, Self::MAX_WIDTH); + let w = f32::min(available_width, if self.layout == KeyboardLayout::NUMBERS { + Self::MAX_WIDTH_NUMBERS + } else { + Self::MAX_WIDTH + }); + // Draw content. View::max_width_ui(ui, w, |ui| { self.ui(ui); }); @@ -105,9 +113,17 @@ impl KeyboardContent { // Setup vertical padding inside buttons. ui.style_mut().spacing.button_padding = egui::vec2(0.0, 8.0); - let button_rect = match self.mode { + // Set numbers layout type if passed on opening. + if NUMERIC.load(Ordering::Relaxed) { + self.layout = KeyboardLayout::NUMBERS; + } else if self.layout == KeyboardLayout::NUMBERS { + self.layout = KeyboardLayout::TEXT; + } + + let button_rect = match self.layout { KeyboardLayout::TEXT => Self::text_ui(ui), KeyboardLayout::SYMBOLS => Self::symbols_ui(ui), + KeyboardLayout::NUMBERS => Self::numbers_ui(ui), }; ui.add_space(2.0); @@ -117,93 +133,159 @@ impl KeyboardContent { r.set_width(ui.available_width()); r.size() }; - let button_width = ui.available_width() / if self.mode != KeyboardLayout::SYMBOLS { - 11.0 - } else { - 10.0 + let button_width = ui.available_width() / match self.layout { + KeyboardLayout::TEXT => 11.0, + KeyboardLayout::SYMBOLS => 10.0, + KeyboardLayout::NUMBERS => 4.0, }; ui.allocate_ui_with_layout(bottom_size, Layout::right_to_left(Align::Center), |ui| { - // Enter key input. - ui.horizontal_centered(|ui| { - ui.set_max_width(button_width * 2.0 + 1.0); - Self::custom_button_ui(KEY_RETURN.to_string(), - Colors::white_or_black(false), - Some(Colors::green()), - ui, - |_| { - Self::input_event(KeyboardEvent::ENTER); - }); - }); - // Backspace key input. - ui.horizontal_centered(|ui| { - ui.set_max_width(button_width * 1.0); - Self::custom_button_ui(BACKSPACE.to_string(), - Colors::red(), - Some(Colors::fill_lite()), - ui, - |_| { - Self::input_event(KeyboardEvent::CLEAR); - }); - }); - // Space key input. - ui.horizontal_centered(|ui| { - ui.set_max_width(button_width * 4.0); - Self::custom_button_ui(" ".to_string(), Colors::inactive_text(), None, ui, |l| { - Self::input_event(KeyboardEvent::TEXT(l)); + if self.layout == KeyboardLayout::NUMBERS { + ui.horizontal_centered(|ui| { + ui.set_max_width(button_width * 2.0 + 1.0); + Self::custom_button_ui(KEY_RETURN.to_string(), + Colors::white_or_black(false), + Some(Colors::green()), + ui, + |_| { + Self::input_event(KeyboardEvent::ENTER); + }); }); - }); - if self.mode != KeyboardLayout::SYMBOLS { - // Switch to english and back. ui.horizontal_centered(|ui| { ui.set_max_width(button_width); - Self::custom_button_ui(GLOBE_SIMPLE.to_string(), - Colors::text_button(), + Self::input_button_ui("0", true, ui); + }); + ui.horizontal_centered(|ui| { + ui.set_max_width(button_width); + Self::input_button_ui(".", false, ui); + }); + } else { + // Enter key input. + ui.horizontal_centered(|ui| { + ui.set_max_width(button_width * 2.0 + 1.0); + Self::custom_button_ui(KEY_RETURN.to_string(), + Colors::white_or_black(false), + Some(Colors::green()), + ui, + |_| { + Self::input_event(KeyboardEvent::ENTER); + }); + }); + // Backspace key input. + ui.horizontal_centered(|ui| { + ui.set_max_width(button_width * 1.0); + Self::custom_button_ui(BACKSPACE.to_string(), + Colors::red(), Some(Colors::fill_lite()), ui, |_| { - AppConfig::toggle_english_keyboard() + Self::input_event(KeyboardEvent::CLEAR); }); }); - // Shift key input. + // Space key input. ui.horizontal_centered(|ui| { - ui.set_max_width(button_width); - let uppercase = UPPERCASE.load(Ordering::Relaxed); - let color = if uppercase { - Colors::yellow_dark() + ui.set_max_width(button_width * 4.0); + Self::custom_button_ui(" ".to_string(), Colors::inactive_text(), None, ui, |l| { + Self::input_event(KeyboardEvent::TEXT(l)); + }); + }); + if self.layout == KeyboardLayout::TEXT { + // Switch to english and back. + ui.horizontal_centered(|ui| { + ui.set_max_width(button_width); + Self::custom_button_ui(GLOBE_SIMPLE.to_string(), + Colors::text_button(), + Some(Colors::fill_lite()), + ui, + |_| { + AppConfig::toggle_english_keyboard() + }); + }); + // Shift key input. + ui.horizontal_centered(|ui| { + ui.set_max_width(button_width); + let uppercase = UPPERCASE.load(Ordering::Relaxed); + let color = if uppercase { + Colors::yellow_dark() + } else { + Colors::inactive_text() + }; + Self::custom_button_ui(ARROW_FAT_UP.to_string(), + color, + Some(Colors::fill_lite()), + ui, |_| { + UPPERCASE.store(!uppercase, Ordering::Relaxed); + }); + }); + } + // Switch to symbols and back. + ui.horizontal_centered(|ui| { + let label = if self.layout == KeyboardLayout::SYMBOLS { + let q = t!("keyboard.q", locale = Self::locale().as_str()); + let w = t!("keyboard.w", locale = Self::locale().as_str()); + let e = t!("keyboard.e", locale = Self::locale().as_str()); + format!("{}{}{}", q, w, e).to_uppercase() } else { - Colors::inactive_text() + "!@ツ".to_string() }; - Self::custom_button_ui(ARROW_FAT_UP.to_string(), - color, + let mut mode = self.layout.clone(); + Self::custom_button_ui(label, + Colors::text(false), Some(Colors::fill_lite()), - ui, |_| { - UPPERCASE.store(!uppercase, Ordering::Relaxed); - }); + ui, + |_| { + if self.layout == KeyboardLayout::SYMBOLS { + mode = KeyboardLayout::TEXT; + } else { + mode = KeyboardLayout::SYMBOLS; + } + }); + self.layout = mode; }); } - // Switch to symbols and back. - ui.horizontal_centered(|ui| { - let label = if self.mode == KeyboardLayout::SYMBOLS { - let q = t!("keyboard.q", locale = Self::locale().as_str()); - let w = t!("keyboard.w", locale = Self::locale().as_str()); - let e = t!("keyboard.e", locale = Self::locale().as_str()); - format!("{}{}{}", q, w, e).to_uppercase() - } else { - "?/ツ".to_string() - }; - let mut mode = self.mode.clone(); - Self::custom_button_ui(label, Colors::text(false), Some(Colors::fill_lite()), ui, |_| { - if self.mode == KeyboardLayout::SYMBOLS { - mode = KeyboardLayout::TEXT; - } else { - mode = KeyboardLayout::SYMBOLS; - } - }); - self.mode = mode; - }); }); } + /// Draw numbers content returning button [`Rect`]. + fn numbers_ui(ui: &mut egui::Ui) -> Rect { + let mut button_rect = ui.available_rect_before_wrap(); + let tl_0: Vec<&str> = vec!["1", "2", "3", "-"]; + ui.columns(tl_0.len(), |columns| { + for (index, s) in tl_0.iter().enumerate() { + let last = index == tl_0.len() - 1; + button_rect = Self::input_button_ui(s, !last, &mut columns[index]); + } + }); + ui.add_space(2.0); + + let tl_1: Vec<&str> = vec!["4", "5", "6", "+"]; + ui.columns(tl_1.len(), |columns| { + for (index, s) in tl_1.iter().enumerate() { + let last = index == tl_1.len() - 1; + Self::input_button_ui(s, !last, &mut columns[index]); + } + }); + ui.add_space(2.0); + + let tl_2: Vec<&str> = vec!["7", "8", "9", BACKSPACE]; + ui.columns(tl_2.len(), |columns| { + for (index, s) in tl_2.iter().enumerate() { + if index == tl_2.len() - 1 { + Self::custom_button_ui(BACKSPACE.to_string(), + Colors::red(), + Some(Colors::fill_lite()), + &mut columns[index], + |_| { + Self::input_event(KeyboardEvent::CLEAR); + }); + } else { + Self::input_button_ui(s, true, &mut columns[index]); + } + } + }); + + button_rect + } + /// Draw text content returning button [`Rect`]. fn text_ui(ui: &mut egui::Ui) -> Rect { let mut button_rect = ui.available_rect_before_wrap(); diff --git a/src/gui/views/input/types.rs b/src/gui/views/input/types.rs index 42dcd7a..66fa6f1 100644 --- a/src/gui/views/input/types.rs +++ b/src/gui/views/input/types.rs @@ -15,7 +15,7 @@ /// Software keyboard input type. #[derive(Clone, PartialOrd, PartialEq)] pub enum KeyboardLayout { - TEXT, SYMBOLS + TEXT, SYMBOLS, NUMBERS } /// Software keyboard input event. diff --git a/src/gui/views/network/setup/dandelion.rs b/src/gui/views/network/setup/dandelion.rs index 66feae3..4e78766 100644 --- a/src/gui/views/network/setup/dandelion.rs +++ b/src/gui/views/network/setup/dandelion.rs @@ -171,7 +171,7 @@ impl DandelionSetup { ui.add_space(8.0); // Draw epoch text edit. - let mut epoch_edit = TextEdit::new(Id::from(modal.id)).h_center(); + let mut epoch_edit = TextEdit::new(Id::from(modal.id)).h_center().numeric(); epoch_edit.ui(ui, &mut self.epoch_edit, cb); if epoch_edit.enter_pressed { on_save(self); @@ -249,7 +249,7 @@ impl DandelionSetup { ui.add_space(8.0); // Draw embargo text edit. - let mut embargo_edit = TextEdit::new(Id::from(modal.id)).h_center(); + let mut embargo_edit = TextEdit::new(Id::from(modal.id)).h_center().numeric(); embargo_edit.ui(ui, &mut self.embargo_edit, cb); if embargo_edit.enter_pressed { on_save(self); @@ -328,7 +328,7 @@ impl DandelionSetup { ui.add_space(8.0); // Draw aggregation period text edit. - let mut aggregation_edit = TextEdit::new(Id::from(modal.id)).h_center(); + let mut aggregation_edit = TextEdit::new(Id::from(modal.id)).h_center().numeric(); aggregation_edit.ui(ui, &mut self.aggregation_edit, cb); if aggregation_edit.enter_pressed { on_save(self); @@ -407,7 +407,7 @@ impl DandelionSetup { ui.add_space(8.0); // Draw stem phase probability text edit. - let mut stem_prob_edit = TextEdit::new(Id::from(modal.id)).h_center(); + let mut stem_prob_edit = TextEdit::new(Id::from(modal.id)).h_center().numeric(); stem_prob_edit.ui(ui, &mut self.stem_prob_edit, cb); if stem_prob_edit.enter_pressed { on_save(self); diff --git a/src/gui/views/network/setup/node.rs b/src/gui/views/network/setup/node.rs index 51b57eb..33beabc 100644 --- a/src/gui/views/network/setup/node.rs +++ b/src/gui/views/network/setup/node.rs @@ -304,7 +304,7 @@ impl NodeSetup { ui.add_space(6.0); // Draw API port text edit. - let mut api_port_edit = TextEdit::new(Id::from(modal.id)).h_center(); + let mut api_port_edit = TextEdit::new(Id::from(modal.id)).h_center().numeric(); api_port_edit.ui(ui, &mut self.api_port_edit, cb); if api_port_edit.enter_pressed { on_save(self); @@ -489,7 +489,7 @@ impl NodeSetup { ui.add_space(8.0); // Draw ftl value text edit. - let mut ftl_edit = TextEdit::new(Id::from(modal.id)).h_center(); + let mut ftl_edit = TextEdit::new(Id::from(modal.id)).h_center().numeric(); ftl_edit.ui(ui, &mut self.ftl_edit, cb); if ftl_edit.enter_pressed { on_save(self); diff --git a/src/gui/views/network/setup/p2p.rs b/src/gui/views/network/setup/p2p.rs index e0508df..a839499 100644 --- a/src/gui/views/network/setup/p2p.rs +++ b/src/gui/views/network/setup/p2p.rs @@ -296,7 +296,7 @@ impl P2PSetup { ui.add_space(8.0); // Draw p2p port text edit. - let mut edit = TextEdit::new(Id::from(modal.id)).h_center(); + let mut edit = TextEdit::new(Id::from(modal.id)).h_center().numeric(); edit.ui(ui, &mut self.port_edit, cb); if edit.enter_pressed { on_save(self); @@ -546,7 +546,7 @@ impl P2PSetup { ui.add_space(8.0); // Draw ban window text edit. - let mut edit = TextEdit::new(Id::from(modal.id)).h_center(); + let mut edit = TextEdit::new(Id::from(modal.id)).h_center().numeric(); edit.ui(ui, &mut self.ban_window_edit, cb); if edit.enter_pressed { on_save(self); @@ -625,7 +625,7 @@ impl P2PSetup { ui.add_space(8.0); // Draw maximum number of inbound peers text edit. - let mut edit = TextEdit::new(Id::from(modal.id)).h_center(); + let mut edit = TextEdit::new(Id::from(modal.id)).h_center().numeric(); edit.ui(ui, &mut self.max_inbound_count, cb); if edit.enter_pressed { on_save(self); @@ -703,7 +703,7 @@ impl P2PSetup { ui.add_space(8.0); // Draw maximum number of outbound peers text edit. - let mut edit = TextEdit::new(Id::from(modal.id)).h_center(); + let mut edit = TextEdit::new(Id::from(modal.id)).h_center().numeric(); edit.ui(ui, &mut self.max_outbound_count, cb); if edit.enter_pressed { on_save(self); diff --git a/src/gui/views/network/setup/pool.rs b/src/gui/views/network/setup/pool.rs index e418023..327f203 100644 --- a/src/gui/views/network/setup/pool.rs +++ b/src/gui/views/network/setup/pool.rs @@ -174,9 +174,11 @@ impl PoolSetup { ui.add_space(8.0); // Draw fee base text edit. - TextEdit::new(Id::from(modal.id)) - .h_center() - .ui(ui, &mut self.fee_base_edit, cb); + let mut edit = TextEdit::new(Id::from(modal.id)).h_center().numeric(); + edit.ui(ui, &mut self.fee_base_edit, cb); + if edit.enter_pressed { + on_save(self); + } // Show error when specified value is not valid or reminder to restart enabled node. if self.fee_base_edit.parse::().is_err() { @@ -251,7 +253,7 @@ impl PoolSetup { ui.add_space(8.0); // Draw reorg period text edit. - let mut edit = TextEdit::new(Id::from(modal.id)).h_center(); + let mut edit = TextEdit::new(Id::from(modal.id)).h_center().numeric(); edit.ui(ui, &mut self.reorg_period_edit, cb); if edit.enter_pressed { on_save(self); @@ -329,8 +331,7 @@ impl PoolSetup { ui.add_space(8.0); // Draw pool size text edit. - let mut edit = TextEdit::new(Id::from(modal.id)) - .h_center(); + let mut edit = TextEdit::new(Id::from(modal.id)).h_center().numeric(); edit.ui(ui, &mut self.pool_size_edit, cb); if edit.enter_pressed { on_save(self); @@ -410,7 +411,7 @@ impl PoolSetup { ui.add_space(8.0); // Draw stempool size text edit. - let mut edit = TextEdit::new(Id::from(modal.id)).h_center(); + let mut edit = TextEdit::new(Id::from(modal.id)).h_center().numeric(); edit.ui(ui, &mut self.stempool_size_edit, cb); if edit.enter_pressed { on_save(self); @@ -490,7 +491,7 @@ impl PoolSetup { ui.add_space(8.0); // Draw tx weight text edit. - let mut edit = TextEdit::new(Id::from(modal.id)).h_center(); + let mut edit = TextEdit::new(Id::from(modal.id)).h_center().numeric(); edit.ui(ui, &mut self.max_weight_edit, cb); if edit.enter_pressed { on_save(self); diff --git a/src/gui/views/network/setup/stratum.rs b/src/gui/views/network/setup/stratum.rs index 0893fa9..80b2e99 100644 --- a/src/gui/views/network/setup/stratum.rs +++ b/src/gui/views/network/setup/stratum.rs @@ -312,7 +312,7 @@ impl StratumSetup { ui.add_space(8.0); // Draw stratum port text edit. - let mut edit = TextEdit::new(Id::from(modal.id)).h_center(); + let mut edit = TextEdit::new(Id::from(modal.id)).h_center().numeric(); edit.ui(ui, &mut self.stratum_port_edit, cb); if edit.enter_pressed { on_save(self); @@ -397,7 +397,7 @@ impl StratumSetup { ui.add_space(8.0); // Draw attempt time text edit. - let mut edit = TextEdit::new(Id::from(modal.id)).h_center(); + let mut edit = TextEdit::new(Id::from(modal.id)).h_center().numeric(); edit.ui(ui, &mut self.attempt_time_edit, cb); if edit.enter_pressed { on_save(self); @@ -476,7 +476,7 @@ impl StratumSetup { ui.add_space(8.0); // Draw share difficulty text edit. - let mut edit = TextEdit::new(Id::from(modal.id)).h_center(); + let mut edit = TextEdit::new(Id::from(modal.id)).h_center().numeric(); edit.ui(ui, &mut self.min_share_diff_edit, cb); if edit.enter_pressed { on_save(self); diff --git a/src/gui/views/wallets/wallet/messages/request.rs b/src/gui/views/wallets/wallet/messages/request.rs index 15fba25..78ed5a8 100644 --- a/src/gui/views/wallets/wallet/messages/request.rs +++ b/src/gui/views/wallets/wallet/messages/request.rs @@ -70,6 +70,38 @@ impl MessageRequestModal { return; } + // Setup callback on continue. + let on_continue = |m: &mut MessageRequestModal| { + if m.amount_edit.is_empty() { + return; + } + if let Ok(a) = amount_from_hr_string(m.amount_edit.as_str()) { + modal.disable_closing(); + // Setup data for request. + let wallet = wallet.clone(); + let invoice = m.invoice.clone(); + let result = m.request_result.clone(); + // Send request at another thread. + m.request_loading = true; + thread::spawn(move || { + let res = if invoice { + wallet.issue_invoice(a) + } else { + wallet.send(a, None) + }; + let mut w_result = result.write(); + *w_result = Some(res); + }); + } else { + let err = if m.invoice { + t!("wallets.invoice_slatepack_err") + } else { + t!("wallets.send_slatepack_err") + }; + m.request_error = Some(err); + } + }; + ui.add_space(6.0); // Draw content on request loading. @@ -79,74 +111,6 @@ impl MessageRequestModal { } // Draw amount input content. - self.amount_input_ui(ui, wallet, modal, cb); - - // Show request creation error. - if let Some(err) = &self.request_error { - ui.add_space(12.0); - ui.vertical_centered(|ui| { - ui.label(RichText::new(err) - .size(17.0) - .color(Colors::red())); - }); - } - - ui.add_space(12.0); - - // Setup spacing between buttons. - ui.spacing_mut().item_spacing = egui::Vec2::new(8.0, 0.0); - - ui.columns(2, |columns| { - columns[0].vertical_centered_justified(|ui| { - View::button(ui, t!("modal.cancel"), Colors::white_or_black(false), || { - self.amount_edit = "".to_string(); - self.request_error = None; - modal.close(); - }); - }); - columns[1].vertical_centered_justified(|ui| { - // Button to create Slatepack message request. - View::button(ui, t!("continue"), Colors::white_or_black(false), || { - if self.amount_edit.is_empty() { - return; - } - if let Ok(a) = amount_from_hr_string(self.amount_edit.as_str()) { - modal.disable_closing(); - // Setup data for request. - let wallet = wallet.clone(); - let invoice = self.invoice.clone(); - let result = self.request_result.clone(); - // Send request at another thread. - self.request_loading = true; - thread::spawn(move || { - let res = if invoice { - wallet.issue_invoice(a) - } else { - wallet.send(a, None) - }; - let mut w_result = result.write(); - *w_result = Some(res); - }); - } else { - let err = if self.invoice { - t!("wallets.invoice_slatepack_err") - } else { - t!("wallets.send_slatepack_err") - }; - self.request_error = Some(err); - } - }); - }); - }); - ui.add_space(6.0); - } - - /// Draw amount input content. - fn amount_input_ui(&mut self, - ui: &mut egui::Ui, - wallet: &Wallet, - modal: &Modal, - cb: &dyn PlatformCallbacks) { ui.vertical_centered(|ui| { let enter_text = if self.invoice { t!("wallets.enter_amount_receive") @@ -162,10 +126,14 @@ impl MessageRequestModal { ui.add_space(8.0); // Draw request amount text input. - let mut amount_edit = TextEdit::new(Id::from(modal.id).with(wallet.get_config().id)) - .h_center(); let amount_edit_before = self.amount_edit.clone(); + let mut amount_edit = TextEdit::new(Id::from(modal.id).with(wallet.get_config().id)) + .h_center() + .numeric(); amount_edit.ui(ui, &mut self.amount_edit, cb); + if amount_edit.enter_pressed { + on_continue(self); + } // Check value if input was changed. if amount_edit_before != self.amount_edit { @@ -205,6 +173,38 @@ impl MessageRequestModal { } } } + + // Show request creation error. + if let Some(err) = &self.request_error { + ui.add_space(12.0); + ui.vertical_centered(|ui| { + ui.label(RichText::new(err) + .size(17.0) + .color(Colors::red())); + }); + } + + ui.add_space(12.0); + + // Setup spacing between buttons. + ui.spacing_mut().item_spacing = egui::Vec2::new(8.0, 0.0); + + ui.columns(2, |columns| { + columns[0].vertical_centered_justified(|ui| { + View::button(ui, t!("modal.cancel"), Colors::white_or_black(false), || { + self.amount_edit = "".to_string(); + self.request_error = None; + modal.close(); + }); + }); + columns[1].vertical_centered_justified(|ui| { + // Button to create Slatepack message request. + View::button(ui, t!("continue"), Colors::white_or_black(false), || { + on_continue(self); + }); + }); + }); + ui.add_space(6.0); } /// Draw loading request content. diff --git a/src/gui/views/wallets/wallet/settings/common.rs b/src/gui/views/wallets/wallet/settings/common.rs index 8be024b..e0fb394 100644 --- a/src/gui/views/wallets/wallet/settings/common.rs +++ b/src/gui/views/wallets/wallet/settings/common.rs @@ -332,7 +332,7 @@ impl CommonSettings { ui.add_space(8.0); // Minimum amount of confirmations text edit. - let mut min_confirmations_edit = TextEdit::new(Id::from(modal.id)).h_center(); + let mut min_confirmations_edit = TextEdit::new(Id::from(modal.id)).h_center().numeric(); min_confirmations_edit.ui(ui, &mut self.min_confirmations_edit, cb); if min_confirmations_edit.enter_pressed { on_save(self); diff --git a/src/gui/views/wallets/wallet/transport/send.rs b/src/gui/views/wallets/wallet/transport/send.rs index 394f336..f2d88af 100644 --- a/src/gui/views/wallets/wallet/transport/send.rs +++ b/src/gui/views/wallets/wallet/transport/send.rs @@ -146,6 +146,7 @@ impl TransportSendModal { let amount_edit_id = Id::from(modal.id).with("amount").with(wallet.get_config().id); let mut amount_edit = TextEdit::new(amount_edit_id) .h_center() + .numeric() .focus(Modal::first_draw()); let amount_edit_before = self.amount_edit.clone(); amount_edit.ui(ui, &mut self.amount_edit, cb);