ui: node content max width

This commit is contained in:
ardocrat 2024-04-22 17:37:58 +03:00
parent cd89b879c6
commit 4b98ce364e
5 changed files with 273 additions and 238 deletions

View file

@ -16,7 +16,7 @@ use egui::{Margin, RichText, ScrollArea, Stroke};
use crate::AppConfig; use crate::AppConfig;
use crate::gui::Colors; 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::platform::PlatformCallbacks;
use crate::gui::views::{ConnectionsContent, NetworkMetrics, NetworkMining, NetworkNode, NetworkSettings, Root, TitlePanel, View}; use crate::gui::views::{ConnectionsContent, NetworkMetrics, NetworkMining, NetworkNode, NetworkSettings, Root, TitlePanel, View};
use crate::gui::views::network::types::{NetworkTab, NetworkTabType}; use crate::gui::views::network::types::{NetworkTab, NetworkTabType};
@ -64,7 +64,12 @@ impl NetworkContent {
..Default::default() ..Default::default()
}) })
.show_animated_inside(ui, !show_connections, |ui| { .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. // Show current node tab content.
@ -89,6 +94,7 @@ impl NetworkContent {
..Default::default() ..Default::default()
}) })
.show_inside(ui, |ui| { .show_inside(ui, |ui| {
// Draw node tab content.
self.node_tab_content.ui(ui, frame, cb); self.node_tab_content.ui(ui, frame, cb);
}); });
}); });
@ -148,7 +154,7 @@ impl NetworkContent {
/// Draw tab buttons in the bottom of the screen. /// Draw tab buttons in the bottom of the screen.
fn tabs_ui(&mut self, ui: &mut egui::Ui) { fn tabs_ui(&mut self, ui: &mut egui::Ui) {
ui.scope(|ui| { ui.vertical_centered(|ui| {
// Setup spacing between tabs. // Setup spacing between tabs.
ui.style_mut().spacing.item_spacing = egui::vec2(4.0, 0.0); ui.style_mut().spacing.item_spacing = egui::vec2(4.0, 0.0);
// Setup vertical padding inside tab button. // Setup vertical padding inside tab button.
@ -213,7 +219,7 @@ impl NetworkContent {
} }
}, |ui, frame| { }, |ui, frame| {
if !Root::is_dual_panel_mode(ui) { if !Root::is_dual_panel_mode(ui) {
View::title_button(ui, CARDHOLDER, || { View::title_button(ui, BRIEFCASE, || {
Root::toggle_network_panel(); Root::toggle_network_panel();
}); });
} }

View file

@ -13,12 +13,12 @@
// limitations under the License. // limitations under the License.
use egui::{RichText, Rounding, ScrollArea, vec2}; use egui::{RichText, Rounding, ScrollArea, vec2};
use grin_servers::DiffBlock; use grin_servers::{DiffBlock, ServerStats};
use crate::gui::Colors; use crate::gui::Colors;
use crate::gui::icons::{AT, COINS, CUBE_TRANSPARENT, HASH, HOURGLASS_LOW, HOURGLASS_MEDIUM, TIMER}; use crate::gui::icons::{AT, COINS, CUBE_TRANSPARENT, HASH, HOURGLASS_LOW, HOURGLASS_MEDIUM, TIMER};
use crate::gui::platform::PlatformCallbacks; 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::gui::views::network::types::{NetworkTab, NetworkTabType};
use crate::node::Node; use crate::node::Node;
@ -56,91 +56,103 @@ impl NetworkTab for NetworkMetrics {
return; return;
} }
let stats = server_stats.as_ref().unwrap();
ui.add_space(1.0); ui.add_space(1.0);
ui.vertical_centered(|ui| {
// Show emission info. View::max_width_ui(ui, Root::SIDE_PANEL_WIDTH * 1.3, |ui| {
View::sub_title(ui, format!("{} {}", COINS, t!("network_metrics.emission"))); let stats = server_stats.as_ref().unwrap();
ui.columns(3, |columns| { // Show emission and difficulty info.
let supply = stats.header_stats.height as f64 * BLOCK_REWARD; info_ui(ui, stats);
let rate = (YEARLY_SUPPLY * 100.0) / supply; // Show difficulty adjustment window blocks.
blocks_ui(ui, stats);
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]);
});
});
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; 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. /// Draw block difficulty item.
fn block_item_ui(ui: &mut egui::Ui, db: &DiffBlock, rounding: Rounding) { fn block_item_ui(ui: &mut egui::Ui, db: &DiffBlock, rounding: Rounding) {
let mut rect = ui.available_rect_before_wrap(); let mut rect = ui.available_rect_before_wrap();

View file

@ -19,7 +19,7 @@ use grin_servers::WorkerStats;
use crate::gui::Colors; 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::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::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::setup::StratumSetup;
use crate::gui::views::network::types::{NetworkTab, NetworkTabType}; use crate::gui::views::network::types::{NetworkTab, NetworkTabType};
use crate::node::{Node, NodeConfig}; use crate::node::{Node, NodeConfig};
@ -73,7 +73,11 @@ impl NetworkTab for NetworkMining {
.auto_shrink([false; 2]) .auto_shrink([false; 2])
.show(ui, |ui| { .show(ui, |ui| {
ui.add_space(1.0); 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; return;
} }

View file

@ -18,7 +18,7 @@ use grin_servers::PeerStats;
use crate::gui::Colors; use crate::gui::Colors;
use crate::gui::icons::{AT, CUBE, DEVICES, FLOW_ARROW, HANDSHAKE, PACKAGE, PLUGS_CONNECTED, SHARE_NETWORK}; use crate::gui::icons::{AT, CUBE, DEVICES, FLOW_ARROW, HANDSHAKE, PACKAGE, PLUGS_CONNECTED, SHARE_NETWORK};
use crate::gui::platform::PlatformCallbacks; 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::gui::views::network::types::{NetworkTab, NetworkTabType};
use crate::node::Node; use crate::node::Node;
@ -45,140 +45,150 @@ impl NetworkTab for NetworkNode {
return; return;
} }
let stats = server_stats.as_ref().unwrap();
ScrollArea::vertical() ScrollArea::vertical()
.id_source("integrated_node") .id_source("integrated_node")
.auto_shrink([false; 2]) .auto_shrink([false; 2])
.show(ui, |ui| { .show(ui, |ui| {
ui.add_space(2.0); ui.add_space(2.0);
ui.vertical_centered(|ui| {
// Show header info. View::max_width_ui(ui, Root::SIDE_PANEL_WIDTH * 1.3, |ui| {
View::sub_title(ui, format!("{} {}", FLOW_ARROW, t!("network_node.header"))); // Show node stats content.
ui.columns(2, |columns| { node_stats_ui(ui);
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 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. /// Draw connected peer info item.
fn peer_item_ui(ui: &mut egui::Ui, peer: &PeerStats, rounding: Rounding) { fn peer_item_ui(ui: &mut egui::Ui, peer: &PeerStats, rounding: Rounding) {
let mut rect = ui.available_rect_before_wrap(); let mut rect = ui.available_rect_before_wrap();

View file

@ -17,7 +17,7 @@ use egui::{RichText, ScrollArea};
use crate::gui::Colors; use crate::gui::Colors;
use crate::gui::icons::ARROW_COUNTER_CLOCKWISE; use crate::gui::icons::ARROW_COUNTER_CLOCKWISE;
use crate::gui::platform::PlatformCallbacks; 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::setup::{DandelionSetup, NodeSetup, P2PSetup, PoolSetup, StratumSetup};
use crate::gui::views::network::types::{NetworkTab, NetworkTabType}; use crate::gui::views::network::types::{NetworkTab, NetworkTabType};
use crate::gui::views::types::{ModalContainer, ModalPosition}; use crate::gui::views::types::{ModalContainer, ModalPosition};
@ -89,44 +89,47 @@ impl NetworkTab for NetworkSettings {
.auto_shrink([false; 2]) .auto_shrink([false; 2])
.show(ui, |ui| { .show(ui, |ui| {
ui.add_space(1.0); 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. ui.add_space(6.0);
self.node.ui(ui, frame, cb); View::horizontal_line(ui, Colors::STROKE);
ui.add_space(4.0);
ui.add_space(6.0); // Draw P2P server setup section.
View::horizontal_line(ui, Colors::STROKE); self.p2p.ui(ui, frame, cb);
ui.add_space(4.0);
// Draw P2P server setup section. ui.add_space(6.0);
self.p2p.ui(ui, frame, cb); View::horizontal_line(ui, Colors::STROKE);
ui.add_space(4.0);
ui.add_space(6.0); // Draw Stratum server setup section.
View::horizontal_line(ui, Colors::STROKE); self.stratum.ui(ui, frame, cb);
ui.add_space(4.0);
// Draw Stratum server setup section. ui.add_space(6.0);
self.stratum.ui(ui, frame, cb); View::horizontal_line(ui, Colors::STROKE);
ui.add_space(4.0);
ui.add_space(6.0); // Draw pool setup section.
View::horizontal_line(ui, Colors::STROKE); self.pool.ui(ui, frame, cb);
ui.add_space(4.0);
// Draw pool setup section. ui.add_space(6.0);
self.pool.ui(ui, frame, cb); View::horizontal_line(ui, Colors::STROKE);
ui.add_space(4.0);
ui.add_space(6.0); // Draw Dandelion server setup section.
View::horizontal_line(ui, Colors::STROKE); self.dandelion.ui(ui, frame, cb);
ui.add_space(4.0);
// Draw Dandelion server setup section. ui.add_space(6.0);
self.dandelion.ui(ui, frame, cb); View::horizontal_line(ui, Colors::STROKE);
ui.add_space(6.0);
ui.add_space(6.0); // Draw reset settings content.
View::horizontal_line(ui, Colors::STROKE); reset_settings_ui(ui);
ui.add_space(6.0); });
});
// Draw reset settings content.
reset_settings_ui(ui);
}); });
} }
} }