diff --git a/src/gui/views/network/content.rs b/src/gui/views/network/content.rs index 34ab8f5..0f876ff 100644 --- a/src/gui/views/network/content.rs +++ b/src/gui/views/network/content.rs @@ -16,7 +16,7 @@ use egui::{Margin, RichText, ScrollArea, Stroke}; use crate::AppConfig; use crate::gui::Colors; -use crate::gui::icons::{CARDHOLDER, DATABASE, DOTS_THREE_OUTLINE_VERTICAL, FACTORY, FADERS, GAUGE, PLUS_CIRCLE, POWER}; +use crate::gui::icons::{BRIEFCASE, CARDHOLDER, DATABASE, DOTS_THREE_OUTLINE_VERTICAL, FACTORY, FADERS, GAUGE, PLUS_CIRCLE, POWER}; use crate::gui::platform::PlatformCallbacks; use crate::gui::views::{ConnectionsContent, NetworkMetrics, NetworkMining, NetworkNode, NetworkSettings, Root, TitlePanel, View}; use crate::gui::views::network::types::{NetworkTab, NetworkTabType}; @@ -64,7 +64,12 @@ impl NetworkContent { ..Default::default() }) .show_animated_inside(ui, !show_connections, |ui| { - self.tabs_ui(ui); + ui.vertical_centered(|ui| { + View::max_width_ui(ui, Root::SIDE_PANEL_WIDTH * 1.3, |ui| { + // Show tabs content. + self.tabs_ui(ui); + }); + }); }); // Show current node tab content. @@ -89,6 +94,7 @@ impl NetworkContent { ..Default::default() }) .show_inside(ui, |ui| { + // Draw node tab content. self.node_tab_content.ui(ui, frame, cb); }); }); @@ -148,7 +154,7 @@ impl NetworkContent { /// Draw tab buttons in the bottom of the screen. fn tabs_ui(&mut self, ui: &mut egui::Ui) { - ui.scope(|ui| { + ui.vertical_centered(|ui| { // Setup spacing between tabs. ui.style_mut().spacing.item_spacing = egui::vec2(4.0, 0.0); // Setup vertical padding inside tab button. @@ -213,7 +219,7 @@ impl NetworkContent { } }, |ui, frame| { if !Root::is_dual_panel_mode(ui) { - View::title_button(ui, CARDHOLDER, || { + View::title_button(ui, BRIEFCASE, || { Root::toggle_network_panel(); }); } diff --git a/src/gui/views/network/metrics.rs b/src/gui/views/network/metrics.rs index f184ae8..7453f3a 100644 --- a/src/gui/views/network/metrics.rs +++ b/src/gui/views/network/metrics.rs @@ -13,12 +13,12 @@ // limitations under the License. use egui::{RichText, Rounding, ScrollArea, vec2}; -use grin_servers::DiffBlock; +use grin_servers::{DiffBlock, ServerStats}; use crate::gui::Colors; use crate::gui::icons::{AT, COINS, CUBE_TRANSPARENT, HASH, HOURGLASS_LOW, HOURGLASS_MEDIUM, TIMER}; use crate::gui::platform::PlatformCallbacks; -use crate::gui::views::{NetworkContent, View}; +use crate::gui::views::{NetworkContent, Root, View}; use crate::gui::views::network::types::{NetworkTab, NetworkTabType}; use crate::node::Node; @@ -56,91 +56,103 @@ impl NetworkTab for NetworkMetrics { return; } - let stats = server_stats.as_ref().unwrap(); - ui.add_space(1.0); - - // Show emission info. - View::sub_title(ui, format!("{} {}", COINS, t!("network_metrics.emission"))); - ui.columns(3, |columns| { - let supply = stats.header_stats.height as f64 * BLOCK_REWARD; - let rate = (YEARLY_SUPPLY * 100.0) / supply; - - columns[0].vertical_centered(|ui| { - View::rounded_box(ui, - format!("{}ツ", BLOCK_REWARD), - t!("network_metrics.reward"), - [true, false, true, false]); - }); - columns[1].vertical_centered(|ui| { - View::rounded_box(ui, - format!("{:.2}%", rate), - t!("network_metrics.inflation"), - [false, false, false, false]); - }); - columns[2].vertical_centered(|ui| { - View::rounded_box(ui, - supply.to_string(), - t!("network_metrics.supply"), - [false, true, false, true]); + ui.vertical_centered(|ui| { + View::max_width_ui(ui, Root::SIDE_PANEL_WIDTH * 1.3, |ui| { + let stats = server_stats.as_ref().unwrap(); + // Show emission and difficulty info. + info_ui(ui, stats); + // Show difficulty adjustment window blocks. + blocks_ui(ui, stats); }); }); - ui.add_space(5.0); - - // Show difficulty adjustment window info. - let difficulty_title = t!( - "network_metrics.difficulty_window", - "size" => stats.diff_stats.window_size - ); - View::sub_title(ui, format!("{} {}", HOURGLASS_MEDIUM, difficulty_title)); - ui.columns(3, |columns| { - columns[0].vertical_centered(|ui| { - View::rounded_box(ui, - stats.diff_stats.height.to_string(), - t!("network_node.height"), - [true, false, true, false]); - }); - columns[1].vertical_centered(|ui| { - View::rounded_box(ui, - format!("{}s", stats.diff_stats.average_block_time), - t!("network_metrics.block_time"), - [false, false, false, false]); - }); - columns[2].vertical_centered(|ui| { - View::rounded_box(ui, - stats.diff_stats.average_difficulty.to_string(), - t!("network_node.difficulty"), - [false, true, false, true]); - }); - }); - ui.add_space(4.0); - - // Show difficulty adjustment window blocks. - let blocks_size = stats.diff_stats.last_blocks.len(); - ScrollArea::vertical() - .id_source("difficulty_scroll") - .auto_shrink([false; 2]) - .stick_to_bottom(true) - .show_rows( - ui, - BLOCK_ITEM_HEIGHT - 1.0, - blocks_size, - |ui, row_range| { - for index in row_range { - // Add space before the first item. - if index == 0 { - ui.add_space(4.0); - } - let db = stats.diff_stats.last_blocks.get(index).unwrap(); - block_item_ui(ui, db, View::item_rounding(index, blocks_size, false)); - } - }, - ); } } const BLOCK_ITEM_HEIGHT: f32 = 77.0; +/// Draw emission and difficulty info. +fn info_ui(ui: &mut egui::Ui, stats: &ServerStats) { + // Show emission info. + View::sub_title(ui, format!("{} {}", COINS, t!("network_metrics.emission"))); + ui.columns(3, |columns| { + let supply = stats.header_stats.height as f64 * BLOCK_REWARD; + let rate = (YEARLY_SUPPLY * 100.0) / supply; + + columns[0].vertical_centered(|ui| { + View::rounded_box(ui, + format!("{}ツ", BLOCK_REWARD), + t!("network_metrics.reward"), + [true, false, true, false]); + }); + columns[1].vertical_centered(|ui| { + View::rounded_box(ui, + format!("{:.2}%", rate), + t!("network_metrics.inflation"), + [false, false, false, false]); + }); + columns[2].vertical_centered(|ui| { + View::rounded_box(ui, + supply.to_string(), + t!("network_metrics.supply"), + [false, true, false, true]); + }); + }); + ui.add_space(5.0); + + // Show difficulty adjustment window info. + let difficulty_title = t!( + "network_metrics.difficulty_window", + "size" => stats.diff_stats.window_size + ); + View::sub_title(ui, format!("{} {}", HOURGLASS_MEDIUM, difficulty_title)); + ui.columns(3, |columns| { + columns[0].vertical_centered(|ui| { + View::rounded_box(ui, + stats.diff_stats.height.to_string(), + t!("network_node.height"), + [true, false, true, false]); + }); + columns[1].vertical_centered(|ui| { + View::rounded_box(ui, + format!("{}s", stats.diff_stats.average_block_time), + t!("network_metrics.block_time"), + [false, false, false, false]); + }); + columns[2].vertical_centered(|ui| { + View::rounded_box(ui, + stats.diff_stats.average_difficulty.to_string(), + t!("network_node.difficulty"), + [false, true, false, true]); + }); + }); +} + +/// Draw difficulty adjustment window blocks content. +fn blocks_ui(ui: &mut egui::Ui, stats: &ServerStats) { + let blocks_size = stats.diff_stats.last_blocks.len(); + ui.add_space(4.0); + ScrollArea::vertical() + .id_source("difficulty_scroll") + .auto_shrink([false; 2]) + .stick_to_bottom(true) + .show_rows( + ui, + BLOCK_ITEM_HEIGHT - 1.0, + blocks_size, + |ui, row_range| { + for index in row_range { + // Add space before the first item. + if index == 0 { + ui.add_space(4.0); + } + let db = stats.diff_stats.last_blocks.get(index).unwrap(); + block_item_ui(ui, db, View::item_rounding(index, blocks_size, false)); + } + }, + ); +} + /// Draw block difficulty item. fn block_item_ui(ui: &mut egui::Ui, db: &DiffBlock, rounding: Rounding) { let mut rect = ui.available_rect_before_wrap(); diff --git a/src/gui/views/network/mining.rs b/src/gui/views/network/mining.rs index eaa0f4f..812f6f3 100644 --- a/src/gui/views/network/mining.rs +++ b/src/gui/views/network/mining.rs @@ -19,7 +19,7 @@ use grin_servers::WorkerStats; use crate::gui::Colors; use crate::gui::icons::{BARBELL, CLOCK_AFTERNOON, CPU, CUBE, FADERS, FOLDER_DASHED, FOLDER_SIMPLE_MINUS, FOLDER_SIMPLE_PLUS, HARD_DRIVES, PLUGS, PLUGS_CONNECTED, POLYGON}; use crate::gui::platform::PlatformCallbacks; -use crate::gui::views::{NetworkContent, View}; +use crate::gui::views::{NetworkContent, Root, View}; use crate::gui::views::network::setup::StratumSetup; use crate::gui::views::network::types::{NetworkTab, NetworkTabType}; use crate::node::{Node, NodeConfig}; @@ -73,7 +73,11 @@ impl NetworkTab for NetworkMining { .auto_shrink([false; 2]) .show(ui, |ui| { ui.add_space(1.0); - self.stratum_server_setup.ui(ui, frame, cb); + ui.vertical_centered(|ui| { + View::max_width_ui(ui, Root::SIDE_PANEL_WIDTH * 1.3, |ui| { + self.stratum_server_setup.ui(ui, frame, cb); + }); + }); }); return; } diff --git a/src/gui/views/network/node.rs b/src/gui/views/network/node.rs index e99d929..7ed5659 100644 --- a/src/gui/views/network/node.rs +++ b/src/gui/views/network/node.rs @@ -18,7 +18,7 @@ use grin_servers::PeerStats; use crate::gui::Colors; use crate::gui::icons::{AT, CUBE, DEVICES, FLOW_ARROW, HANDSHAKE, PACKAGE, PLUGS_CONNECTED, SHARE_NETWORK}; use crate::gui::platform::PlatformCallbacks; -use crate::gui::views::{NetworkContent, View}; +use crate::gui::views::{NetworkContent, Root, View}; use crate::gui::views::network::types::{NetworkTab, NetworkTabType}; use crate::node::Node; @@ -45,140 +45,150 @@ impl NetworkTab for NetworkNode { return; } - let stats = server_stats.as_ref().unwrap(); - ScrollArea::vertical() .id_source("integrated_node") .auto_shrink([false; 2]) .show(ui, |ui| { ui.add_space(2.0); - - // Show header info. - View::sub_title(ui, format!("{} {}", FLOW_ARROW, t!("network_node.header"))); - ui.columns(2, |columns| { - columns[0].vertical_centered(|ui| { - View::rounded_box(ui, - stats.header_stats.last_block_h.to_string(), - t!("network_node.hash"), - [true, false, false, false]); - }); - columns[1].vertical_centered(|ui| { - View::rounded_box(ui, - stats.header_stats.height.to_string(), - t!("network_node.height"), - [false, true, false, false]); + ui.vertical_centered(|ui| { + View::max_width_ui(ui, Root::SIDE_PANEL_WIDTH * 1.3, |ui| { + // Show node stats content. + node_stats_ui(ui); }); }); - ui.columns(2, |columns| { - columns[0].vertical_centered(|ui| { - View::rounded_box(ui, - stats.header_stats.total_difficulty.to_string(), - t!("network_node.difficulty"), - [false, false, true, false]); - }); - columns[1].vertical_centered(|ui| { - let h_ts = stats.header_stats.latest_timestamp.timestamp(); - let h_time = View::format_time(h_ts); - View::rounded_box(ui, - h_time, - t!("network_node.time"), - [false, false, false, true]); - }); - }); - ui.add_space(5.0); - - // Show block info. - View::sub_title(ui, format!("{} {}", CUBE, t!("network_node.block"))); - ui.columns(2, |columns| { - columns[0].vertical_centered(|ui| { - View::rounded_box(ui, - stats.chain_stats.last_block_h.to_string(), - t!("network_node.hash"), - [true, false, false, false]); - }); - columns[1].vertical_centered(|ui| { - View::rounded_box(ui, - stats.chain_stats.height.to_string(), - t!("network_node.height"), - [false, true, false, false]); - }); - }); - ui.columns(2, |columns| { - columns[0].vertical_centered(|ui| { - View::rounded_box(ui, - stats.chain_stats.total_difficulty.to_string(), - t!("network_node.difficulty"), - [false, false, true, false]); - }); - columns[1].vertical_centered(|ui| { - let b_ts = stats.chain_stats.latest_timestamp.timestamp(); - let b_time = View::format_time(b_ts); - View::rounded_box(ui, - b_time, - t!("network_node.time"), - [false, false, false, true]); - }); - }); - ui.add_space(5.0); - - // Show data info. - View::sub_title(ui, format!("{} {}", SHARE_NETWORK, t!("network_node.data"))); - ui.columns(2, |columns| { - columns[0].vertical_centered(|ui| { - let tx_stat = match &stats.tx_stats { - None => "0 (0)".to_string(), - Some(tx) => format!("{} ({})", tx.tx_pool_size, tx.tx_pool_kernels) - }; - View::rounded_box(ui, - tx_stat, - t!("network_node.main_pool"), - [true, false, false, false]); - }); - columns[1].vertical_centered(|ui| { - let stem_tx_stat = match &stats.tx_stats { - None => "0 (0)".to_string(), - Some(stx) => format!("{} ({})", - stx.stem_pool_size, - stx.stem_pool_kernels) - }; - View::rounded_box(ui, - stem_tx_stat, - t!("network_node.stem_pool"), - [false, true, false, false]); - }); - }); - ui.columns(2, |columns| { - columns[0].vertical_centered(|ui| { - View::rounded_box(ui, - stats.disk_usage_gb.to_string(), - t!("network_node.size"), - [false, false, true, false]); - }); - columns[1].vertical_centered(|ui| { - View::rounded_box(ui, - stats.peer_count.to_string(), - t!("network_node.peers"), - [false, false, false, true]); - }); - }); - ui.add_space(5.0); - - // Show peer stats when available. - if stats.peer_count > 0 { - View::sub_title(ui, format!("{} {}", HANDSHAKE, t!("network_node.peers"))); - let peers = &stats.peer_stats; - for (index, ps) in peers.iter().enumerate() { - peer_item_ui(ui, ps, View::item_rounding(index, peers.len(), false)); - // Add space after the last item. - if index == peers.len() - 1 { - ui.add_space(5.0); - } - } - } }); } } +/// Draw node statistics content. +fn node_stats_ui(ui: &mut egui::Ui) { + let server_stats = Node::get_stats(); + let stats = server_stats.as_ref().unwrap(); + + // Show header info. + View::sub_title(ui, format!("{} {}", FLOW_ARROW, t!("network_node.header"))); + ui.columns(2, |columns| { + columns[0].vertical_centered(|ui| { + View::rounded_box(ui, + stats.header_stats.last_block_h.to_string(), + t!("network_node.hash"), + [true, false, false, false]); + }); + columns[1].vertical_centered(|ui| { + View::rounded_box(ui, + stats.header_stats.height.to_string(), + t!("network_node.height"), + [false, true, false, false]); + }); + }); + ui.columns(2, |columns| { + columns[0].vertical_centered(|ui| { + View::rounded_box(ui, + stats.header_stats.total_difficulty.to_string(), + t!("network_node.difficulty"), + [false, false, true, false]); + }); + columns[1].vertical_centered(|ui| { + let h_ts = stats.header_stats.latest_timestamp.timestamp(); + let h_time = View::format_time(h_ts); + View::rounded_box(ui, + h_time, + t!("network_node.time"), + [false, false, false, true]); + }); + }); + ui.add_space(5.0); + + // Show block info. + View::sub_title(ui, format!("{} {}", CUBE, t!("network_node.block"))); + ui.columns(2, |columns| { + columns[0].vertical_centered(|ui| { + View::rounded_box(ui, + stats.chain_stats.last_block_h.to_string(), + t!("network_node.hash"), + [true, false, false, false]); + }); + columns[1].vertical_centered(|ui| { + View::rounded_box(ui, + stats.chain_stats.height.to_string(), + t!("network_node.height"), + [false, true, false, false]); + }); + }); + ui.columns(2, |columns| { + columns[0].vertical_centered(|ui| { + View::rounded_box(ui, + stats.chain_stats.total_difficulty.to_string(), + t!("network_node.difficulty"), + [false, false, true, false]); + }); + columns[1].vertical_centered(|ui| { + let b_ts = stats.chain_stats.latest_timestamp.timestamp(); + let b_time = View::format_time(b_ts); + View::rounded_box(ui, + b_time, + t!("network_node.time"), + [false, false, false, true]); + }); + }); + ui.add_space(5.0); + + // Show data info. + View::sub_title(ui, format!("{} {}", SHARE_NETWORK, t!("network_node.data"))); + ui.columns(2, |columns| { + columns[0].vertical_centered(|ui| { + let tx_stat = match &stats.tx_stats { + None => "0 (0)".to_string(), + Some(tx) => format!("{} ({})", tx.tx_pool_size, tx.tx_pool_kernels) + }; + View::rounded_box(ui, + tx_stat, + t!("network_node.main_pool"), + [true, false, false, false]); + }); + columns[1].vertical_centered(|ui| { + let stem_tx_stat = match &stats.tx_stats { + None => "0 (0)".to_string(), + Some(stx) => format!("{} ({})", + stx.stem_pool_size, + stx.stem_pool_kernels) + }; + View::rounded_box(ui, + stem_tx_stat, + t!("network_node.stem_pool"), + [false, true, false, false]); + }); + }); + ui.columns(2, |columns| { + columns[0].vertical_centered(|ui| { + View::rounded_box(ui, + stats.disk_usage_gb.to_string(), + t!("network_node.size"), + [false, false, true, false]); + }); + columns[1].vertical_centered(|ui| { + View::rounded_box(ui, + stats.peer_count.to_string(), + t!("network_node.peers"), + [false, false, false, true]); + }); + }); + ui.add_space(5.0); + + // Show peer stats when available. + if stats.peer_count > 0 { + View::sub_title(ui, format!("{} {}", HANDSHAKE, t!("network_node.peers"))); + let peers = &stats.peer_stats; + for (index, ps) in peers.iter().enumerate() { + peer_item_ui(ui, ps, View::item_rounding(index, peers.len(), false)); + // Add space after the last item. + if index == peers.len() - 1 { + ui.add_space(5.0); + } + } + } +} + /// Draw connected peer info item. fn peer_item_ui(ui: &mut egui::Ui, peer: &PeerStats, rounding: Rounding) { let mut rect = ui.available_rect_before_wrap(); diff --git a/src/gui/views/network/settings.rs b/src/gui/views/network/settings.rs index 13c8403..01cd485 100644 --- a/src/gui/views/network/settings.rs +++ b/src/gui/views/network/settings.rs @@ -17,7 +17,7 @@ use egui::{RichText, ScrollArea}; use crate::gui::Colors; use crate::gui::icons::ARROW_COUNTER_CLOCKWISE; use crate::gui::platform::PlatformCallbacks; -use crate::gui::views::{Modal, View}; +use crate::gui::views::{Modal, Root, View}; use crate::gui::views::network::setup::{DandelionSetup, NodeSetup, P2PSetup, PoolSetup, StratumSetup}; use crate::gui::views::network::types::{NetworkTab, NetworkTabType}; use crate::gui::views::types::{ModalContainer, ModalPosition}; @@ -89,44 +89,47 @@ impl NetworkTab for NetworkSettings { .auto_shrink([false; 2]) .show(ui, |ui| { ui.add_space(1.0); + ui.vertical_centered(|ui| { + View::max_width_ui(ui, Root::SIDE_PANEL_WIDTH * 1.3, |ui| { + // Draw node setup section. + self.node.ui(ui, frame, cb); - // Draw node setup section. - self.node.ui(ui, frame, cb); + ui.add_space(6.0); + View::horizontal_line(ui, Colors::STROKE); + ui.add_space(4.0); - ui.add_space(6.0); - View::horizontal_line(ui, Colors::STROKE); - ui.add_space(4.0); + // Draw P2P server setup section. + self.p2p.ui(ui, frame, cb); - // Draw P2P server setup section. - self.p2p.ui(ui, frame, cb); + ui.add_space(6.0); + View::horizontal_line(ui, Colors::STROKE); + ui.add_space(4.0); - ui.add_space(6.0); - View::horizontal_line(ui, Colors::STROKE); - ui.add_space(4.0); + // Draw Stratum server setup section. + self.stratum.ui(ui, frame, cb); - // Draw Stratum server setup section. - self.stratum.ui(ui, frame, cb); + ui.add_space(6.0); + View::horizontal_line(ui, Colors::STROKE); + ui.add_space(4.0); - ui.add_space(6.0); - View::horizontal_line(ui, Colors::STROKE); - ui.add_space(4.0); + // Draw pool setup section. + self.pool.ui(ui, frame, cb); - // Draw pool setup section. - self.pool.ui(ui, frame, cb); + ui.add_space(6.0); + View::horizontal_line(ui, Colors::STROKE); + ui.add_space(4.0); - ui.add_space(6.0); - View::horizontal_line(ui, Colors::STROKE); - ui.add_space(4.0); + // Draw Dandelion server setup section. + self.dandelion.ui(ui, frame, cb); - // Draw Dandelion server setup section. - self.dandelion.ui(ui, frame, cb); + ui.add_space(6.0); + View::horizontal_line(ui, Colors::STROKE); + ui.add_space(6.0); - ui.add_space(6.0); - View::horizontal_line(ui, Colors::STROKE); - ui.add_space(6.0); - - // Draw reset settings content. - reset_settings_ui(ui); + // Draw reset settings content. + reset_settings_ui(ui); + }); + }); }); } }