mirror of
https://github.com/jwinterm/grim.git
synced 2026-10-17 14:21:24 +02:00
ui: settings content at separate panel
This commit is contained in:
+4
-2
@@ -59,8 +59,10 @@ impl<Platform: PlatformCallbacks> App<Platform> {
|
||||
if View::is_desktop() {
|
||||
self.platform.set_context(ctx);
|
||||
}
|
||||
// Check connections availability.
|
||||
ExternalConnection::check(None, ctx);
|
||||
// Check connections availability at dual panel mode.
|
||||
if Content::is_dual_panel_mode(ctx) && AppConfig::show_connections_network_panel() {
|
||||
ExternalConnection::check(None, ctx);
|
||||
}
|
||||
// Setup visuals.
|
||||
crate::setup_visuals(ctx);
|
||||
}
|
||||
|
||||
+16
-129
@@ -12,31 +12,35 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
use egui::os::OperatingSystem;
|
||||
use egui::RichText;
|
||||
use lazy_static::lazy_static;
|
||||
use std::fs;
|
||||
use std::sync::atomic::{AtomicBool, Ordering};
|
||||
use egui::os::OperatingSystem;
|
||||
use egui::{Align, Layout, RichText, StrokeKind};
|
||||
use lazy_static::lazy_static;
|
||||
|
||||
use crate::gui::Colors;
|
||||
use crate::gui::icons::FILE_X;
|
||||
use crate::gui::platform::PlatformCallbacks;
|
||||
use crate::gui::views::{Modal, View};
|
||||
use crate::gui::views::network::NetworkContent;
|
||||
use crate::gui::views::types::{ModalContainer, ModalPosition};
|
||||
use crate::gui::views::wallets::WalletsContent;
|
||||
use crate::gui::views::{Modal, View};
|
||||
use crate::gui::Colors;
|
||||
use crate::node::Node;
|
||||
use crate::{AppConfig, Settings};
|
||||
use crate::gui::icons::{CHECK, CHECK_FAT, FILE_X};
|
||||
use crate::gui::views::network::NetworkContent;
|
||||
use crate::gui::views::wallets::WalletsContent;
|
||||
|
||||
lazy_static! {
|
||||
/// Global state to check if [`NetworkContent`] panel is open.
|
||||
static ref NETWORK_PANEL_OPEN: AtomicBool = AtomicBool::new(false);
|
||||
|
||||
/// Global state to check if [`NetworkContent`] panel is open.
|
||||
static ref SETTINGS_PANEL_OPEN: AtomicBool = AtomicBool::new(false);
|
||||
}
|
||||
|
||||
/// Contains main ui content, handles side panel state.
|
||||
pub struct Content {
|
||||
/// Side panel [`NetworkContent`] content.
|
||||
network: NetworkContent,
|
||||
|
||||
/// Central panel [`WalletsContent`] content.
|
||||
pub wallets: WalletsContent,
|
||||
|
||||
@@ -70,7 +74,6 @@ impl Default for Content {
|
||||
first_draw: true,
|
||||
allowed_modal_ids: vec![
|
||||
Self::EXIT_CONFIRMATION_MODAL,
|
||||
Self::SETTINGS_MODAL,
|
||||
ANDROID_INTEGRATED_NODE_WARNING_MODAL,
|
||||
CRASH_REPORT_MODAL
|
||||
],
|
||||
@@ -89,7 +92,6 @@ impl ModalContainer for Content {
|
||||
cb: &dyn PlatformCallbacks) {
|
||||
match modal.id {
|
||||
Self::EXIT_CONFIRMATION_MODAL => self.exit_modal_content(ui, modal, cb),
|
||||
Self::SETTINGS_MODAL => self.settings_modal_ui(ui),
|
||||
ANDROID_INTEGRATED_NODE_WARNING_MODAL => self.android_warning_modal_ui(ui),
|
||||
CRASH_REPORT_MODAL => self.crash_report_modal_ui(ui, cb),
|
||||
_ => {}
|
||||
@@ -100,8 +102,6 @@ impl ModalContainer for Content {
|
||||
impl Content {
|
||||
/// Identifier for exit confirmation [`Modal`].
|
||||
pub const EXIT_CONFIRMATION_MODAL: &'static str = "exit_confirmation_modal";
|
||||
/// Identifier for wallet opening [`Modal`].
|
||||
pub const SETTINGS_MODAL: &'static str = "settings_modal";
|
||||
|
||||
/// Default width of side panel at application UI.
|
||||
pub const SIDE_PANEL_WIDTH: f32 = 400.0;
|
||||
@@ -114,7 +114,10 @@ impl Content {
|
||||
self.current_modal_ui(ui, cb);
|
||||
|
||||
let dual_panel = Self::is_dual_panel_mode(ui.ctx());
|
||||
let (is_panel_open, panel_width) = network_panel_state_width(ui.ctx(), dual_panel);
|
||||
let (is_panel_open, mut panel_width) = network_panel_state_width(ui.ctx(), dual_panel);
|
||||
if self.network.showing_settings() {
|
||||
panel_width = ui.available_width();
|
||||
}
|
||||
|
||||
// Show network content.
|
||||
egui::SidePanel::left("network_panel")
|
||||
@@ -244,122 +247,6 @@ impl Content {
|
||||
}
|
||||
}
|
||||
|
||||
/// Draw creating wallet name/password input [`Modal`] content.
|
||||
pub fn settings_modal_ui(&mut self, ui: &mut egui::Ui) {
|
||||
ui.add_space(6.0);
|
||||
|
||||
// Show theme selection.
|
||||
Self::theme_selection_ui(ui);
|
||||
|
||||
ui.add_space(8.0);
|
||||
View::horizontal_line(ui, Colors::item_stroke());
|
||||
ui.add_space(6.0);
|
||||
|
||||
ui.vertical_centered(|ui| {
|
||||
ui.label(RichText::new(format!("{}:", t!("language")))
|
||||
.size(16.0)
|
||||
.color(Colors::gray())
|
||||
);
|
||||
});
|
||||
ui.add_space(8.0);
|
||||
|
||||
// Draw available list of languages to select.
|
||||
let locales = rust_i18n::available_locales!();
|
||||
for (index, locale) in locales.iter().enumerate() {
|
||||
Self::language_item_ui(locale, ui, index, locales.len());
|
||||
}
|
||||
|
||||
ui.add_space(8.0);
|
||||
|
||||
// Show button to close modal.
|
||||
ui.vertical_centered_justified(|ui| {
|
||||
View::button(ui, t!("close"), Colors::white_or_black(false), || {
|
||||
Modal::close();
|
||||
});
|
||||
});
|
||||
ui.add_space(6.0);
|
||||
}
|
||||
|
||||
/// Draw theme selection content.
|
||||
fn theme_selection_ui(ui: &mut egui::Ui) {
|
||||
ui.vertical_centered(|ui| {
|
||||
ui.label(RichText::new(t!("theme")).size(16.0).color(Colors::gray()));
|
||||
});
|
||||
|
||||
let saved_use_dark = AppConfig::dark_theme().unwrap_or(false);
|
||||
let mut selected_use_dark = saved_use_dark;
|
||||
|
||||
ui.add_space(8.0);
|
||||
ui.columns(2, |columns| {
|
||||
columns[0].vertical_centered(|ui| {
|
||||
View::radio_value(ui, &mut selected_use_dark, false, t!("light"));
|
||||
});
|
||||
columns[1].vertical_centered(|ui| {
|
||||
View::radio_value(ui, &mut selected_use_dark, true, t!("dark"));
|
||||
})
|
||||
});
|
||||
ui.add_space(8.0);
|
||||
|
||||
if saved_use_dark != selected_use_dark {
|
||||
AppConfig::set_dark_theme(selected_use_dark);
|
||||
crate::setup_visuals(ui.ctx());
|
||||
}
|
||||
}
|
||||
|
||||
/// Draw language selection item content.
|
||||
fn language_item_ui(locale: &str, ui: &mut egui::Ui, index: usize, len: usize) {
|
||||
// Setup layout size.
|
||||
let mut rect = ui.available_rect_before_wrap();
|
||||
rect.set_height(50.0);
|
||||
|
||||
// Draw round background.
|
||||
let bg_rect = rect.clone();
|
||||
let item_rounding = View::item_rounding(index, len, false);
|
||||
ui.painter().rect(bg_rect,
|
||||
item_rounding,
|
||||
Colors::fill(),
|
||||
View::item_stroke(),
|
||||
StrokeKind::Middle);
|
||||
|
||||
ui.allocate_ui_with_layout(rect.size(), Layout::right_to_left(Align::Center), |ui| {
|
||||
// Draw button to select language.
|
||||
let is_current = if let Some(lang) = AppConfig::locale() {
|
||||
lang == locale
|
||||
} else {
|
||||
rust_i18n::locale() == locale
|
||||
};
|
||||
if !is_current {
|
||||
View::item_button(ui, View::item_rounding(index, len, true), CHECK, None, || {
|
||||
rust_i18n::set_locale(locale);
|
||||
AppConfig::save_locale(locale);
|
||||
Modal::close();
|
||||
});
|
||||
} else {
|
||||
ui.add_space(14.0);
|
||||
ui.label(RichText::new(CHECK_FAT).size(20.0).color(Colors::green()));
|
||||
ui.add_space(14.0);
|
||||
}
|
||||
|
||||
let layout_size = ui.available_size();
|
||||
ui.allocate_ui_with_layout(layout_size, Layout::left_to_right(Align::Center), |ui| {
|
||||
ui.add_space(12.0);
|
||||
ui.vertical(|ui| {
|
||||
// Draw language name.
|
||||
ui.add_space(12.0);
|
||||
let color = if is_current {
|
||||
Colors::title(false)
|
||||
} else {
|
||||
Colors::gray()
|
||||
};
|
||||
ui.label(RichText::new(t!("lang_name", locale = locale))
|
||||
.size(17.0)
|
||||
.color(color));
|
||||
ui.add_space(3.0);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/// Draw content for integrated node warning [`Modal`] on Android.
|
||||
fn android_warning_modal_ui(&mut self, ui: &mut egui::Ui) {
|
||||
ui.add_space(6.0);
|
||||
|
||||
@@ -27,8 +27,8 @@ mod content;
|
||||
pub use content::*;
|
||||
|
||||
pub mod network;
|
||||
|
||||
pub mod wallets;
|
||||
pub mod settings;
|
||||
|
||||
mod camera;
|
||||
pub use camera::*;
|
||||
|
||||
@@ -17,11 +17,12 @@ use egui::scroll_area::ScrollBarVisibility;
|
||||
|
||||
use crate::AppConfig;
|
||||
use crate::gui::Colors;
|
||||
use crate::gui::icons::{ARROWS_COUNTER_CLOCKWISE, BRIEFCASE, DATABASE, DOTS_THREE_OUTLINE_VERTICAL, FACTORY, FADERS, GAUGE, POWER};
|
||||
use crate::gui::icons::{ARROWS_COUNTER_CLOCKWISE, ARROW_LEFT, BRIEFCASE, DATABASE, DOTS_THREE_OUTLINE_VERTICAL, FACTORY, FADERS, GAUGE, GEAR, POWER};
|
||||
use crate::gui::platform::PlatformCallbacks;
|
||||
use crate::gui::views::{Content, TitlePanel, View};
|
||||
use crate::gui::views::network::{ConnectionsContent, NetworkMetrics, NetworkMining, NetworkNode, NetworkSettings};
|
||||
use crate::gui::views::network::types::{NodeTab, NodeTabType};
|
||||
use crate::gui::views::settings::SettingsContent;
|
||||
use crate::gui::views::types::{LinePosition, TitleContentType, TitleType};
|
||||
use crate::node::{Node, NodeConfig, NodeError};
|
||||
use crate::wallet::ExternalConnection;
|
||||
@@ -32,6 +33,9 @@ pub struct NetworkContent {
|
||||
node_tab_content: Box<dyn NodeTab>,
|
||||
/// Connections content.
|
||||
connections: ConnectionsContent,
|
||||
|
||||
/// Application settings content.
|
||||
settings_content: Option<SettingsContent>,
|
||||
}
|
||||
|
||||
impl Default for NetworkContent {
|
||||
@@ -39,12 +43,14 @@ impl Default for NetworkContent {
|
||||
Self {
|
||||
node_tab_content: Box::new(NetworkNode::default()),
|
||||
connections: ConnectionsContent::default(),
|
||||
settings_content: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl NetworkContent {
|
||||
pub fn ui(&mut self, ui: &mut egui::Ui, cb: &dyn PlatformCallbacks) {
|
||||
let show_settings = self.showing_settings();
|
||||
let show_connections = AppConfig::show_connections_network_panel();
|
||||
let dual_panel = Content::is_dual_panel_mode(ui.ctx());
|
||||
|
||||
@@ -52,8 +58,8 @@ impl NetworkContent {
|
||||
self.title_ui(ui, dual_panel, show_connections);
|
||||
|
||||
// Show integrated node tabs content.
|
||||
if !show_connections {
|
||||
egui::TopBottomPanel::bottom("node_tabs")
|
||||
if !show_connections && !show_settings {
|
||||
egui::TopBottomPanel::bottom("network_tabs_content")
|
||||
.min_height(0.5)
|
||||
.resizable(false)
|
||||
.frame(egui::Frame {
|
||||
@@ -83,14 +89,14 @@ impl NetworkContent {
|
||||
});
|
||||
}
|
||||
|
||||
// Show integrated node tab content.
|
||||
egui::SidePanel::right("node_tab_content")
|
||||
// Show settings or integrated node content.
|
||||
egui::SidePanel::right("network_side_content")
|
||||
.resizable(false)
|
||||
.exact_width(ui.available_width())
|
||||
.frame(egui::Frame {
|
||||
..Default::default()
|
||||
})
|
||||
.show_animated_inside(ui, !show_connections, |ui| {
|
||||
.show_animated_inside(ui, show_settings || !show_connections, |ui| {
|
||||
egui::CentralPanel::default()
|
||||
.frame(egui::Frame {
|
||||
inner_margin: Margin {
|
||||
@@ -103,7 +109,11 @@ impl NetworkContent {
|
||||
})
|
||||
.show_inside(ui, |ui| {
|
||||
let rect = ui.available_rect_before_wrap();
|
||||
if self.node_tab_content.get_type() != NodeTabType::Settings {
|
||||
if let Some(c) = &mut self.settings_content {
|
||||
View::max_width_ui(ui, Content::SIDE_PANEL_WIDTH * 1.3, |ui| {
|
||||
c.ui(ui);
|
||||
});
|
||||
} else if self.node_tab_content.get_type() != NodeTabType::Settings {
|
||||
View::max_width_ui(ui, Content::SIDE_PANEL_WIDTH * 1.3, |ui| {
|
||||
let node_err = Node::get_error();
|
||||
if let Some(err) = node_err {
|
||||
@@ -192,6 +202,11 @@ impl NetworkContent {
|
||||
}
|
||||
}
|
||||
|
||||
/// Check if application settings content is showing.
|
||||
pub fn showing_settings(&self) -> bool {
|
||||
self.settings_content.is_some()
|
||||
}
|
||||
|
||||
/// Draw tab buttons at bottom of the screen.
|
||||
fn tabs_ui(&mut self, ui: &mut egui::Ui) {
|
||||
ui.vertical_centered(|ui| {
|
||||
@@ -229,11 +244,15 @@ impl NetworkContent {
|
||||
|
||||
/// Draw title content.
|
||||
fn title_ui(&mut self, ui: &mut egui::Ui, dual_panel: bool, show_connections: bool) {
|
||||
let show_settings = self.showing_settings();
|
||||
|
||||
// Setup values for title panel.
|
||||
let title_text = self.node_tab_content.get_type().title();
|
||||
let subtitle_text = Node::get_sync_status_text();
|
||||
let not_syncing = Node::not_syncing();
|
||||
let title_content = if !show_connections {
|
||||
let title_content = if show_settings {
|
||||
TitleContentType::Title(t!("settings"))
|
||||
} else if !show_connections {
|
||||
TitleContentType::WithSubTitle(title_text, subtitle_text, !not_syncing)
|
||||
} else {
|
||||
TitleContentType::Title(t!("network.connections"))
|
||||
@@ -241,16 +260,24 @@ impl NetworkContent {
|
||||
|
||||
// Draw title panel.
|
||||
TitlePanel::new(Id::from("network_title_panel")).ui(TitleType::Single(title_content), |ui| {
|
||||
if !show_connections {
|
||||
if show_settings {
|
||||
View::title_button_big(ui, ARROW_LEFT, |_| {
|
||||
self.settings_content = None;
|
||||
});
|
||||
} else if !show_connections {
|
||||
View::title_button_big(ui, DOTS_THREE_OUTLINE_VERTICAL, |ui| {
|
||||
AppConfig::toggle_show_connections_network_panel();
|
||||
if AppConfig::show_connections_network_panel() {
|
||||
ExternalConnection::check(None, ui.ctx());
|
||||
}
|
||||
});
|
||||
} else if !dual_panel {
|
||||
View::title_button_big(ui, GEAR, |_| {
|
||||
self.settings_content = Some(SettingsContent::default());
|
||||
});
|
||||
}
|
||||
}, |ui| {
|
||||
if !dual_panel {
|
||||
if !dual_panel && !show_settings {
|
||||
View::title_button_big(ui, BRIEFCASE, |_| {
|
||||
Content::toggle_network_panel();
|
||||
});
|
||||
|
||||
@@ -0,0 +1,145 @@
|
||||
// Copyright 2025 The Grim Developers
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
use eframe::emath::Align;
|
||||
use eframe::epaint::StrokeKind;
|
||||
use egui::{Layout, RichText};
|
||||
use crate::AppConfig;
|
||||
use crate::gui::Colors;
|
||||
use crate::gui::icons::{CHECK, CHECK_FAT};
|
||||
use crate::gui::views::{Modal, View};
|
||||
|
||||
/// Application settings content.
|
||||
pub struct SettingsContent {
|
||||
|
||||
}
|
||||
|
||||
|
||||
impl Default for SettingsContent {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl SettingsContent {
|
||||
/// Draw settings content.
|
||||
pub fn ui(&mut self, ui: &mut egui::Ui) {
|
||||
ui.add_space(6.0);
|
||||
|
||||
// Show theme selection.
|
||||
Self::theme_selection_ui(ui);
|
||||
|
||||
ui.add_space(8.0);
|
||||
View::horizontal_line(ui, Colors::item_stroke());
|
||||
ui.add_space(6.0);
|
||||
|
||||
ui.vertical_centered(|ui| {
|
||||
ui.label(RichText::new(format!("{}:", t!("language")))
|
||||
.size(16.0)
|
||||
.color(Colors::gray())
|
||||
);
|
||||
});
|
||||
ui.add_space(8.0);
|
||||
|
||||
// Draw available list of languages to select.
|
||||
let locales = rust_i18n::available_locales!();
|
||||
for (index, locale) in locales.iter().enumerate() {
|
||||
Self::language_item_ui(locale, ui, index, locales.len());
|
||||
}
|
||||
}
|
||||
|
||||
/// Draw theme selection content.
|
||||
fn theme_selection_ui(ui: &mut egui::Ui) {
|
||||
ui.vertical_centered(|ui| {
|
||||
ui.label(RichText::new(t!("theme")).size(16.0).color(Colors::gray()));
|
||||
});
|
||||
|
||||
let saved_use_dark = AppConfig::dark_theme().unwrap_or(false);
|
||||
let mut selected_use_dark = saved_use_dark;
|
||||
|
||||
ui.add_space(8.0);
|
||||
ui.columns(2, |columns| {
|
||||
columns[0].vertical_centered(|ui| {
|
||||
View::radio_value(ui, &mut selected_use_dark, false, t!("light"));
|
||||
});
|
||||
columns[1].vertical_centered(|ui| {
|
||||
View::radio_value(ui, &mut selected_use_dark, true, t!("dark"));
|
||||
})
|
||||
});
|
||||
ui.add_space(8.0);
|
||||
|
||||
if saved_use_dark != selected_use_dark {
|
||||
AppConfig::set_dark_theme(selected_use_dark);
|
||||
crate::setup_visuals(ui.ctx());
|
||||
}
|
||||
|
||||
ui.add_space(6.0);
|
||||
}
|
||||
|
||||
/// Draw language selection item content.
|
||||
fn language_item_ui(locale: &str, ui: &mut egui::Ui, index: usize, len: usize) {
|
||||
// Setup layout size.
|
||||
let mut rect = ui.available_rect_before_wrap();
|
||||
rect.set_height(50.0);
|
||||
|
||||
// Draw round background.
|
||||
let bg_rect = rect.clone();
|
||||
let item_rounding = View::item_rounding(index, len, false);
|
||||
ui.painter().rect(bg_rect,
|
||||
item_rounding,
|
||||
Colors::fill(),
|
||||
View::item_stroke(),
|
||||
StrokeKind::Middle);
|
||||
|
||||
ui.allocate_ui_with_layout(rect.size(), Layout::right_to_left(Align::Center), |ui| {
|
||||
// Draw button to select language.
|
||||
let is_current = if let Some(lang) = AppConfig::locale() {
|
||||
lang == locale
|
||||
} else {
|
||||
rust_i18n::locale() == locale
|
||||
};
|
||||
if !is_current {
|
||||
View::item_button(ui, View::item_rounding(index, len, true), CHECK, None, || {
|
||||
rust_i18n::set_locale(locale);
|
||||
AppConfig::save_locale(locale);
|
||||
Modal::close();
|
||||
});
|
||||
} else {
|
||||
ui.add_space(14.0);
|
||||
ui.label(RichText::new(CHECK_FAT).size(20.0).color(Colors::green()));
|
||||
ui.add_space(14.0);
|
||||
}
|
||||
|
||||
let layout_size = ui.available_size();
|
||||
ui.allocate_ui_with_layout(layout_size, Layout::left_to_right(Align::Center), |ui| {
|
||||
ui.add_space(12.0);
|
||||
ui.vertical(|ui| {
|
||||
// Draw language name.
|
||||
ui.add_space(12.0);
|
||||
let color = if is_current {
|
||||
Colors::title(false)
|
||||
} else {
|
||||
Colors::gray()
|
||||
};
|
||||
ui.label(RichText::new(t!("lang_name", locale = locale))
|
||||
.size(17.0)
|
||||
.color(color));
|
||||
ui.add_space(3.0);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
// Copyright 2025 The Grim Developers
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
mod content;
|
||||
pub use content::*;
|
||||
@@ -21,6 +21,7 @@ use crate::gui::Colors;
|
||||
use crate::gui::icons::{ARROW_LEFT, CARET_RIGHT, COMPUTER_TOWER, FOLDER_OPEN, FOLDER_PLUS, GEAR, GLOBE, GLOBE_SIMPLE, LOCK_KEY, PLUS, SIDEBAR_SIMPLE, SUITCASE};
|
||||
use crate::gui::platform::PlatformCallbacks;
|
||||
use crate::gui::views::{Modal, Content, TitlePanel, View};
|
||||
use crate::gui::views::settings::SettingsContent;
|
||||
use crate::gui::views::types::{ModalContainer, ModalPosition, LinePosition, TitleContentType, TitleType};
|
||||
use crate::gui::views::wallets::creation::WalletCreation;
|
||||
use crate::gui::views::wallets::modals::{AddWalletModal, OpenWalletModal, WalletConnectionModal, WalletsModal};
|
||||
@@ -49,6 +50,9 @@ pub struct WalletsContent {
|
||||
/// Wallet creation content.
|
||||
creation_content: Option<WalletCreation>,
|
||||
|
||||
/// Settings content.
|
||||
settings_content: Option<SettingsContent>,
|
||||
|
||||
/// Flag to show [`Wallet`] list at dual panel mode.
|
||||
show_wallets_at_dual_panel: bool,
|
||||
|
||||
@@ -70,6 +74,7 @@ impl Default for WalletsContent {
|
||||
conn_selection_content: None,
|
||||
wallet_content: None,
|
||||
creation_content: None,
|
||||
settings_content: None,
|
||||
show_wallets_at_dual_panel: AppConfig::show_wallets_at_dual_panel(),
|
||||
modal_ids: vec![
|
||||
ADD_WALLET_MODAL,
|
||||
@@ -100,7 +105,7 @@ impl ModalContainer for WalletsContent {
|
||||
);
|
||||
});
|
||||
}
|
||||
if self.creation_content.is_some() {
|
||||
if self.creating_wallet() {
|
||||
self.add_wallet_modal_content = None;
|
||||
}
|
||||
},
|
||||
@@ -147,11 +152,12 @@ impl WalletsContent {
|
||||
pub fn ui(&mut self, ui: &mut egui::Ui, cb: &dyn PlatformCallbacks) {
|
||||
self.current_modal_ui(ui, cb);
|
||||
|
||||
let showing_settings = self.showing_settings();
|
||||
let creating_wallet = self.creating_wallet();
|
||||
let showing_wallet = self.showing_wallet() && !creating_wallet;
|
||||
let showing_wallet = self.showing_wallet() && !creating_wallet && !showing_settings;
|
||||
let dual_panel = Self::is_dual_panel_mode(ui);
|
||||
let content_width = ui.available_width();
|
||||
let list_hidden = creating_wallet || self.wallets.list().is_empty()
|
||||
let list_hidden = showing_settings || creating_wallet || self.wallets.list().is_empty()
|
||||
|| (showing_wallet && self.wallet_content.as_ref().unwrap().qr_scan_content.is_some())
|
||||
|| (dual_panel && showing_wallet && !self.show_wallets_at_dual_panel)
|
||||
|| (!dual_panel && showing_wallet);
|
||||
@@ -253,7 +259,13 @@ impl WalletsContent {
|
||||
..Default::default()
|
||||
})
|
||||
.show_inside(ui, |ui| {
|
||||
if self.creation_content.is_some() {
|
||||
if self.showing_settings() {
|
||||
if let Some(c) = &mut self.settings_content {
|
||||
View::max_width_ui(ui, Content::SIDE_PANEL_WIDTH * 1.3, |ui| {
|
||||
c.ui(ui);
|
||||
});
|
||||
}
|
||||
} else if self.creating_wallet() {
|
||||
let creation = self.creation_content.as_mut().unwrap();
|
||||
let pass = creation.pass.clone();
|
||||
let mut created = false;
|
||||
@@ -306,6 +318,11 @@ impl WalletsContent {
|
||||
self.creation_content.is_some()
|
||||
}
|
||||
|
||||
/// Check if application settings are showing.
|
||||
pub fn showing_settings(&self) -> bool {
|
||||
self.settings_content.is_some()
|
||||
}
|
||||
|
||||
/// Handle data from deeplink or opened file.
|
||||
pub fn on_data(&mut self, ui: &mut egui::Ui, data: Option<String>) {
|
||||
let wallets_size = self.wallets.list().len();
|
||||
@@ -349,7 +366,11 @@ impl WalletsContent {
|
||||
|
||||
/// Handle Back key event returning `false` when event was handled.
|
||||
pub fn on_back(&mut self, cb: &dyn PlatformCallbacks) -> bool {
|
||||
if self.creation_content.is_some() {
|
||||
if self.showing_settings() {
|
||||
// Close settings.
|
||||
self.settings_content = None;
|
||||
return false;
|
||||
} else if self.creating_wallet() {
|
||||
// Close wallet creation.
|
||||
let creation = self.creation_content.as_mut().unwrap();
|
||||
if creation.on_back() {
|
||||
@@ -380,6 +401,7 @@ impl WalletsContent {
|
||||
show_wallet: bool,
|
||||
cb: &dyn PlatformCallbacks) {
|
||||
let show_list = self.show_wallets_at_dual_panel;
|
||||
let showing_settings = self.showing_settings();
|
||||
let creating_wallet = self.creating_wallet();
|
||||
let qr_scan = {
|
||||
let mut scan = false;
|
||||
@@ -390,7 +412,7 @@ impl WalletsContent {
|
||||
};
|
||||
// Setup title.
|
||||
let title_content = if show_wallet && (!dual_panel
|
||||
|| (dual_panel && !show_list)) && !creating_wallet {
|
||||
|| (dual_panel && !show_list)) && !creating_wallet && !showing_settings {
|
||||
let wallet_content = self.wallet_content.as_ref().unwrap();
|
||||
let wallet_tab_type = wallet_content.current_tab.get_type();
|
||||
let title_text = if qr_scan {
|
||||
@@ -405,14 +427,17 @@ impl WalletsContent {
|
||||
TitleType::Single(TitleContentType::WithSubTitle(title_text, subtitle_text, false))
|
||||
}
|
||||
} else {
|
||||
let title_text = if qr_scan {
|
||||
let title_text = if showing_settings {
|
||||
t!("settings")
|
||||
} else if qr_scan {
|
||||
t!("scan_qr")
|
||||
} else if creating_wallet {
|
||||
t!("wallets.add")
|
||||
} else {
|
||||
t!("wallets.title")
|
||||
};
|
||||
let dual_title = !qr_scan && !creating_wallet && show_wallet && dual_panel;
|
||||
let dual_title = !showing_settings && !qr_scan && !creating_wallet &&
|
||||
show_wallet && dual_panel;
|
||||
if dual_title {
|
||||
let wallet_content = self.wallet_content.as_ref().unwrap();
|
||||
let wallet_tab_type = wallet_content.current_tab.get_type();
|
||||
@@ -430,8 +455,14 @@ impl WalletsContent {
|
||||
};
|
||||
|
||||
// Draw title panel.
|
||||
let mut show_settings = false;
|
||||
let showing_settings = self.showing_settings();
|
||||
TitlePanel::new(Id::new("wallets_title_panel")).ui(title_content, |ui| {
|
||||
if show_wallet && !dual_panel {
|
||||
if self.showing_settings() {
|
||||
View::title_button_big(ui, ARROW_LEFT, |_| {
|
||||
self.settings_content = None;
|
||||
});
|
||||
} else if show_wallet && !dual_panel {
|
||||
View::title_button_big(ui, ARROW_LEFT, |_| {
|
||||
let wallet_qr_scan = self.wallet_content
|
||||
.as_ref()
|
||||
@@ -445,7 +476,7 @@ impl WalletsContent {
|
||||
}
|
||||
self.wallet_content = None;
|
||||
});
|
||||
} else if self.creation_content.is_some() {
|
||||
} else if self.creating_wallet() {
|
||||
let mut close = false;
|
||||
if let Some(creation) = self.creation_content.as_mut() {
|
||||
View::title_button_big(ui, ARROW_LEFT, |_| {
|
||||
@@ -478,16 +509,18 @@ impl WalletsContent {
|
||||
View::title_button_big(ui, GLOBE, |_| {
|
||||
Content::toggle_network_panel();
|
||||
});
|
||||
};
|
||||
}
|
||||
}, |ui| {
|
||||
View::title_button_big(ui, GEAR, |_| {
|
||||
// Show settings modal.
|
||||
Modal::new(Content::SETTINGS_MODAL)
|
||||
.position(ModalPosition::CenterTop)
|
||||
.title(t!("settings"))
|
||||
.show();
|
||||
});
|
||||
if !showing_settings {
|
||||
View::title_button_big(ui, GEAR, |_| {
|
||||
// Show application settings.
|
||||
show_settings = true;
|
||||
});
|
||||
}
|
||||
}, ui);
|
||||
if show_settings {
|
||||
self.settings_content = Some(SettingsContent::default());
|
||||
}
|
||||
}
|
||||
|
||||
/// Draw list of wallets.
|
||||
|
||||
Reference in New Issue
Block a user