ui: add checkbox view, move spinners creation to views, autorun option when server is disabled, refactor network tabs to hold only current instance
This commit is contained in:
parent
b91bc2f7e7
commit
d34889a801
14 changed files with 173 additions and 100 deletions
|
@ -8,6 +8,7 @@ network:
|
|||
enable: Enable
|
||||
disable: Disable
|
||||
restart: Restart
|
||||
autorun: Autorun
|
||||
disabled_server: 'Enable server or choose another connection method by pressing %{dots} on top left corner of the screen.'
|
||||
sync_status:
|
||||
server_restarting: Server is restarting
|
||||
|
@ -27,7 +28,7 @@ sync_status:
|
|||
tx_hashset_range_proofs_validation: 'Validating state (range proofs): %{percent}%'
|
||||
tx_hashset_kernels_validation: 'Validating state (kernels): %{percent}%'
|
||||
tx_hashset_save: Finalizing chain state
|
||||
body_sync: Downloading blockchain
|
||||
body_sync: Downloading blocks
|
||||
body_sync_percent: 'Downloading blocks: %{percent}%'
|
||||
shutdown: Server is shutting down
|
||||
network_node:
|
||||
|
|
|
@ -8,6 +8,7 @@ network:
|
|||
enable: Включить
|
||||
disable: Выключить
|
||||
restart: Перезапустить
|
||||
autorun: Автозапуск
|
||||
disabled_server: 'Включите сервер или выберите другой способ подключения, нажав %{dots} в левом верхнем углу экрана.'
|
||||
sync_status:
|
||||
server_restarting: Сервер перезапускается
|
||||
|
@ -27,7 +28,7 @@ sync_status:
|
|||
tx_hashset_range_proofs_validation: 'Проверка доказательств: %{percent}%'
|
||||
tx_hashset_kernels_validation: 'Проверка ядер: %{percent}%'
|
||||
tx_hashset_save: Сохранение состояния цепи
|
||||
body_sync: Загрузка блокчейна
|
||||
body_sync: Загрузка блоков
|
||||
body_sync_percent: 'Загрузка блоков: %{percent}%'
|
||||
shutdown: Выключение сервера
|
||||
network_node:
|
||||
|
|
|
@ -72,6 +72,10 @@ impl App {
|
|||
style.spacing.scroll_bar_width = 4.0;
|
||||
// Disable spacing between items.
|
||||
style.spacing.item_spacing = egui::vec2(0.0, 0.0);
|
||||
// Setup radio button/checkbox size and spacing.
|
||||
style.spacing.icon_width = 24.0;
|
||||
style.spacing.icon_width_inner = 14.0;
|
||||
style.spacing.icon_spacing = 10.0;
|
||||
|
||||
ctx.set_style(style);
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@ use crate::gui::screens::ScreenId;
|
|||
use crate::gui::views::{Modal, ModalId, ModalLocation};
|
||||
|
||||
lazy_static! {
|
||||
/// Static [Navigator] state to be accessible from anywhere.
|
||||
/// Static [`Navigator`] state to be accessible from anywhere.
|
||||
static ref NAVIGATOR_STATE: RwLock<Navigator> = RwLock::new(Navigator::default());
|
||||
}
|
||||
|
||||
|
@ -53,20 +53,20 @@ impl Default for Navigator {
|
|||
}
|
||||
|
||||
impl Navigator {
|
||||
/// Initialize navigation from provided [ScreenId].
|
||||
/// Initialize navigation from provided [`ScreenId`].
|
||||
pub fn init(from: ScreenId) {
|
||||
let mut w_nav = NAVIGATOR_STATE.write().unwrap();
|
||||
w_nav.screen_stack.clear();
|
||||
w_nav.screen_stack.insert(from);
|
||||
}
|
||||
|
||||
/// Check if provided [ScreenId] is current.
|
||||
/// Check if provided [`ScreenId`] is current.
|
||||
pub fn is_current(id: &ScreenId) -> bool {
|
||||
let r_nav = NAVIGATOR_STATE.read().unwrap();
|
||||
r_nav.screen_stack.last().unwrap() == id
|
||||
}
|
||||
|
||||
/// Navigate to screen with provided [ScreenId].
|
||||
/// Navigate to screen with provided [`ScreenId`].
|
||||
pub fn to(id: ScreenId) {
|
||||
NAVIGATOR_STATE.write().unwrap().screen_stack.insert(id);
|
||||
}
|
||||
|
@ -110,19 +110,19 @@ impl Navigator {
|
|||
}
|
||||
}
|
||||
|
||||
/// Open exit confirmation [Modal].
|
||||
/// Open exit confirmation [`Modal`].
|
||||
pub fn open_exit_modal() {
|
||||
let w_nav = NAVIGATOR_STATE.write().unwrap();
|
||||
Self::open_exit_modal_nav(w_nav);
|
||||
}
|
||||
|
||||
/// Open exit confirmation [Modal] with provided [NAVIGATOR_STATE] lock.
|
||||
/// Open exit confirmation [`Modal`] with provided [NAVIGATOR_STATE] lock.
|
||||
fn open_exit_modal_nav(mut w_nav: RwLockWriteGuard<Navigator>) {
|
||||
let m = Modal::new(ModalId::Exit, ModalLocation::Global).title(t!("modal_exit.exit"));
|
||||
w_nav.global_modal = Some(m);
|
||||
}
|
||||
|
||||
/// Open [Modal] at specified location.
|
||||
/// Open [`Modal`] at specified location.
|
||||
pub fn open_modal(modal: Modal) {
|
||||
let mut w_nav = NAVIGATOR_STATE.write().unwrap();
|
||||
match modal.location {
|
||||
|
@ -138,7 +138,7 @@ impl Navigator {
|
|||
}
|
||||
}
|
||||
|
||||
/// Check if [Modal] is open at specified location and remove it from [Navigator] if closed.
|
||||
/// Check if [`Modal`] is open at specified location and remove it from [`Navigator`] otherwise.
|
||||
pub fn is_modal_open(location: ModalLocation) -> bool {
|
||||
// Check if Modal is showing.
|
||||
{
|
||||
|
@ -176,7 +176,7 @@ impl Navigator {
|
|||
true
|
||||
}
|
||||
|
||||
/// Show [Modal] with provided location at app UI.
|
||||
/// Show [`Modal`] with provided location at app UI.
|
||||
pub fn modal_ui(ui: &mut egui::Ui,
|
||||
location: ModalLocation,
|
||||
add_content: impl FnOnce(&mut egui::Ui, &Modal)) {
|
||||
|
|
|
@ -14,8 +14,6 @@
|
|||
|
||||
use std::cmp::min;
|
||||
|
||||
use egui::{Spinner, Widget};
|
||||
|
||||
use crate::gui::{App, Colors, Navigator};
|
||||
use crate::gui::platform::PlatformCallbacks;
|
||||
use crate::gui::screens::{Account, Accounts, Screen, ScreenId};
|
||||
|
@ -80,7 +78,7 @@ impl Root {
|
|||
}
|
||||
ui.add_space(16.0);
|
||||
ui.vertical_centered(|ui| {
|
||||
Spinner::new().size(48.0).color(Colors::GOLD).ui(ui);
|
||||
View::small_loading_spinner(ui);
|
||||
ui.add_space(12.0);
|
||||
ui.label(t!("sync_status.shutdown"));
|
||||
});
|
||||
|
|
|
@ -22,14 +22,9 @@ mod modal;
|
|||
pub use modal::*;
|
||||
|
||||
mod network;
|
||||
pub use network::Network;
|
||||
pub use network::*;
|
||||
|
||||
mod network_node;
|
||||
mod network_settings;
|
||||
mod network_metrics;
|
||||
mod network_mining;
|
||||
|
||||
pub trait NetworkTab {
|
||||
fn name(&self) -> String;
|
||||
fn ui(&mut self, ui: &mut egui::Ui);
|
||||
}
|
|
@ -133,7 +133,7 @@ impl Modal {
|
|||
ui.set_min_size(ui.available_size());
|
||||
});
|
||||
|
||||
// Show main content Window at give position
|
||||
// Show main content Window at given position
|
||||
let layer_id = egui::Window::new(self.window_id(false))
|
||||
.title_bar(false)
|
||||
.resizable(false)
|
||||
|
|
|
@ -22,35 +22,36 @@ use grin_chain::SyncStatus;
|
|||
use crate::gui::{Colors, Navigator};
|
||||
use crate::gui::icons::{CARDHOLDER, DATABASE, DOTS_THREE_OUTLINE_VERTICAL, FACTORY, FADERS, GAUGE, POWER};
|
||||
use crate::gui::platform::PlatformCallbacks;
|
||||
use crate::gui::views::{NetworkTab, View};
|
||||
use crate::gui::views::network_metrics::NetworkMetrics;
|
||||
use crate::gui::views::network_mining::NetworkMining;
|
||||
use crate::gui::views::network_node::NetworkNode;
|
||||
use crate::gui::views::network_settings::NetworkSettings;
|
||||
use crate::gui::views::View;
|
||||
use crate::node::Node;
|
||||
use crate::Settings;
|
||||
|
||||
pub trait NetworkTab {
|
||||
fn get_type(&self) -> NetworkTabType;
|
||||
fn name(&self) -> String;
|
||||
fn ui(&mut self, ui: &mut egui::Ui);
|
||||
}
|
||||
|
||||
#[derive(PartialEq)]
|
||||
enum Mode {
|
||||
pub enum NetworkTabType {
|
||||
Node,
|
||||
Metrics,
|
||||
Mining,
|
||||
Tuning
|
||||
Settings
|
||||
}
|
||||
|
||||
pub struct Network {
|
||||
current_mode: Mode,
|
||||
|
||||
node_view: NetworkNode,
|
||||
metrics_view: NetworkMetrics,
|
||||
mining_view: NetworkMining,
|
||||
current_tab: Box<dyn NetworkTab>,
|
||||
}
|
||||
|
||||
impl Default for Network {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
current_mode: Mode::Node,
|
||||
node_view: NetworkNode::default(),
|
||||
metrics_view: NetworkMetrics::default(),
|
||||
mining_view: NetworkMining::default()
|
||||
current_tab: Box::new(NetworkNode::default()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -87,7 +88,7 @@ impl Network {
|
|||
.. Default::default()
|
||||
})
|
||||
.show_inside(ui, |ui| {
|
||||
self.draw_tab_content(ui);
|
||||
self.current_tab.ui(ui);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -100,44 +101,33 @@ impl Network {
|
|||
|
||||
ui.columns(4, |columns| {
|
||||
columns[0].vertical_centered_justified(|ui| {
|
||||
View::tab_button(ui, DATABASE, self.current_mode == Mode::Node, || {
|
||||
self.current_mode = Mode::Node;
|
||||
View::tab_button(ui, DATABASE,
|
||||
self.current_tab.get_type() == NetworkTabType::Node, || {
|
||||
self.current_tab = Box::new(NetworkNode::default());
|
||||
});
|
||||
});
|
||||
columns[1].vertical_centered_justified(|ui| {
|
||||
View::tab_button(ui, GAUGE, self.current_mode == Mode::Metrics, || {
|
||||
self.current_mode = Mode::Metrics;
|
||||
View::tab_button(ui, GAUGE,
|
||||
self.current_tab.get_type() == NetworkTabType::Metrics, || {
|
||||
self.current_tab = Box::new(NetworkMetrics::default());
|
||||
});
|
||||
});
|
||||
columns[2].vertical_centered_justified(|ui| {
|
||||
View::tab_button(ui, FACTORY, self.current_mode == Mode::Mining, || {
|
||||
self.current_mode = Mode::Mining;
|
||||
View::tab_button(ui, FACTORY,
|
||||
self.current_tab.get_type() == NetworkTabType::Mining, || {
|
||||
self.current_tab = Box::new(NetworkMining::default());
|
||||
});
|
||||
});
|
||||
columns[3].vertical_centered_justified(|ui| {
|
||||
View::tab_button(ui, FADERS, self.current_mode == Mode::Tuning, || {
|
||||
self.current_mode = Mode::Tuning;
|
||||
View::tab_button(ui, FADERS,
|
||||
self.current_tab.get_type() == NetworkTabType::Settings, || {
|
||||
self.current_tab = Box::new(NetworkSettings::default());
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
fn draw_tab_content(&mut self, ui: &mut egui::Ui) {
|
||||
match self.current_mode {
|
||||
Mode::Node => {
|
||||
self.node_view.ui(ui);
|
||||
}
|
||||
Mode::Metrics => {
|
||||
self.metrics_view.ui(ui);
|
||||
}
|
||||
Mode::Tuning => {
|
||||
self.node_view.ui(ui);
|
||||
}
|
||||
Mode::Mining => {}
|
||||
}
|
||||
}
|
||||
|
||||
fn draw_title(&mut self, ui: &mut egui::Ui, frame: &mut eframe::Frame) {
|
||||
StripBuilder::new(ui)
|
||||
.size(Size::exact(52.0))
|
||||
|
@ -173,21 +163,6 @@ impl Network {
|
|||
}
|
||||
|
||||
fn draw_title_text(&self, builder: StripBuilder) {
|
||||
let title_text = match &self.current_mode {
|
||||
Mode::Node => {
|
||||
self.node_view.name()
|
||||
}
|
||||
Mode::Metrics => {
|
||||
self.metrics_view.name()
|
||||
}
|
||||
Mode::Mining => {
|
||||
self.mining_view.name()
|
||||
}
|
||||
Mode::Tuning => {
|
||||
self.node_view.name()
|
||||
}
|
||||
};
|
||||
|
||||
builder
|
||||
.size(Size::remainder())
|
||||
.size(Size::exact(32.0))
|
||||
|
@ -195,7 +170,7 @@ impl Network {
|
|||
strip.cell(|ui| {
|
||||
ui.add_space(2.0);
|
||||
ui.vertical_centered(|ui| {
|
||||
ui.label(RichText::new(title_text.to_uppercase())
|
||||
ui.label(RichText::new(self.current_tab.name().to_uppercase())
|
||||
.size(18.0)
|
||||
.color(Colors::TITLE));
|
||||
});
|
||||
|
@ -233,7 +208,7 @@ impl Network {
|
|||
}
|
||||
|
||||
pub fn disabled_server_content(ui: &mut egui::Ui) {
|
||||
View::center_content(ui, 142.0, |ui| {
|
||||
View::center_content(ui, 162.0, |ui| {
|
||||
let text = t!("network.disabled_server", "dots" => DOTS_THREE_OUTLINE_VERTICAL);
|
||||
ui.label(RichText::new(text)
|
||||
.size(16.0)
|
||||
|
@ -245,6 +220,15 @@ impl Network {
|
|||
View::button(ui, format!("{} {}", POWER, t!("network.enable")), Colors::GOLD, || {
|
||||
Node::start();
|
||||
});
|
||||
|
||||
ui.add_space(4.0);
|
||||
|
||||
let autostart: bool = Settings::get_app_config().auto_start_node;
|
||||
View::checkbox(ui, autostart, t!("network.autorun"), || {
|
||||
let mut w_app_config = Settings::get_app_config_to_update();
|
||||
w_app_config.auto_start_node = !autostart;
|
||||
w_app_config.save();
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,12 +14,12 @@
|
|||
|
||||
use chrono::{DateTime, NaiveDateTime, Utc};
|
||||
use eframe::epaint::{Color32, Rounding, Stroke};
|
||||
use egui::{RichText, ScrollArea, Spinner, Widget};
|
||||
use egui::{RichText, ScrollArea};
|
||||
use grin_servers::DiffBlock;
|
||||
|
||||
use crate::gui::Colors;
|
||||
use crate::gui::icons::{AT, COINS, CUBE_TRANSPARENT, HASH, HOURGLASS_LOW, HOURGLASS_MEDIUM, TIMER};
|
||||
use crate::gui::views::{Network, NetworkTab, View};
|
||||
use crate::gui::views::{Network, NetworkTab, NetworkTabType, View};
|
||||
use crate::node::Node;
|
||||
|
||||
#[derive(Default)]
|
||||
|
@ -30,18 +30,23 @@ const BLOCK_REWARD: f64 = 60.0;
|
|||
const YEARLY_SUPPLY: f64 = ((60 * 60 * 24 * 365) + 6 * 60 * 60) as f64;
|
||||
|
||||
impl NetworkTab for NetworkMetrics {
|
||||
fn get_type(&self) -> NetworkTabType {
|
||||
NetworkTabType::Metrics
|
||||
}
|
||||
|
||||
fn name(&self) -> String {
|
||||
t!("network.metrics")
|
||||
}
|
||||
|
||||
fn ui(&mut self, ui: &mut egui::Ui) {
|
||||
let server_stats = Node::get_stats();
|
||||
// Show loading spinner when stats are not available or message when server is not enabled.
|
||||
if server_stats.is_none() || server_stats.as_ref().unwrap().diff_stats.height == 0 {
|
||||
if !Node::is_running() {
|
||||
Network::disabled_server_content(ui);
|
||||
} else {
|
||||
View::center_content(ui, 160.0, |ui| {
|
||||
Spinner::new().size(104.0).color(Colors::GOLD).ui(ui);
|
||||
View::big_loading_spinner(ui);
|
||||
ui.add_space(18.0);
|
||||
ui.label(RichText::new(t!("network_metrics.loading"))
|
||||
.size(16.0)
|
||||
|
@ -54,7 +59,7 @@ impl NetworkTab for NetworkMetrics {
|
|||
|
||||
let stats = server_stats.as_ref().unwrap();
|
||||
|
||||
// Show emission info
|
||||
// Show emission info.
|
||||
ui.vertical_centered_justified(|ui| {
|
||||
View::sub_header(ui, format!("{} {}", COINS, t!("network_metrics.emission")));
|
||||
});
|
||||
|
|
|
@ -12,19 +12,37 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
use egui::Ui;
|
||||
use crate::gui::views::NetworkTab;
|
||||
use crate::gui::Colors;
|
||||
use crate::gui::views::{Network, NetworkTab, NetworkTabType, View};
|
||||
use crate::node::Node;
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct NetworkMining;
|
||||
|
||||
impl NetworkTab for NetworkMining {
|
||||
fn get_type(&self) -> NetworkTabType {
|
||||
NetworkTabType::Mining
|
||||
}
|
||||
|
||||
fn name(&self) -> String {
|
||||
t!("network.mining")
|
||||
}
|
||||
|
||||
fn ui(&mut self, ui: &mut Ui) {
|
||||
fn ui(&mut self, ui: &mut egui::Ui) {
|
||||
let server_stats = Node::get_stats();
|
||||
// Show loading spinner when stats are not available or message when server is not enabled.
|
||||
if !server_stats.is_some() {
|
||||
if !Node::is_running() {
|
||||
Network::disabled_server_content(ui);
|
||||
} else {
|
||||
ui.centered_and_justified(|ui| {
|
||||
View::big_loading_spinner(ui);
|
||||
});
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
let stats = server_stats.as_ref().unwrap();
|
||||
|
||||
}
|
||||
}
|
|
@ -13,30 +13,35 @@
|
|||
// limitations under the License.
|
||||
|
||||
use eframe::epaint::Stroke;
|
||||
use egui::{Color32, RichText, Rounding, ScrollArea, Spinner, Widget};
|
||||
use egui::{Color32, RichText, Rounding, ScrollArea};
|
||||
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::views::{Network, NetworkTab, View};
|
||||
use crate::gui::views::{Network, NetworkTab, NetworkTabType, View};
|
||||
use crate::node::Node;
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct NetworkNode;
|
||||
|
||||
impl NetworkTab for NetworkNode {
|
||||
fn get_type(&self) -> NetworkTabType {
|
||||
NetworkTabType::Metrics
|
||||
}
|
||||
|
||||
fn name(&self) -> String {
|
||||
t!("network.node")
|
||||
}
|
||||
|
||||
fn ui(&mut self, ui: &mut egui::Ui) {
|
||||
let server_stats = Node::get_stats();
|
||||
// Show loading spinner when stats are not available or message when server is not enabled.
|
||||
if !server_stats.is_some() {
|
||||
if !Node::is_running() {
|
||||
Network::disabled_server_content(ui);
|
||||
} else {
|
||||
ui.centered_and_justified(|ui| {
|
||||
Spinner::new().size(104.0).color(Colors::GOLD).ui(ui);
|
||||
View::big_loading_spinner(ui);
|
||||
});
|
||||
}
|
||||
return;
|
||||
|
@ -83,7 +88,7 @@ impl NetworkTab for NetworkNode {
|
|||
});
|
||||
|
||||
// Show block stats
|
||||
ui.add_space(6.0);
|
||||
ui.add_space(4.0);
|
||||
ui.vertical_centered_justified(|ui| {
|
||||
View::sub_header(ui, format!("{} {}", CUBE, t!("network_node.block")));
|
||||
});
|
||||
|
@ -119,7 +124,7 @@ impl NetworkTab for NetworkNode {
|
|||
});
|
||||
|
||||
// Show data stats
|
||||
ui.add_space(6.0);
|
||||
ui.add_space(4.0);
|
||||
ui.vertical_centered_justified(|ui| {
|
||||
View::sub_header(ui, format!("{} {}", SHARE_NETWORK, t!("network_node.data")));
|
||||
});
|
||||
|
@ -167,7 +172,7 @@ impl NetworkTab for NetworkNode {
|
|||
|
||||
// Show peers stats when available
|
||||
if stats.peer_count > 0 {
|
||||
ui.add_space(6.0);
|
||||
ui.add_space(4.0);
|
||||
ui.vertical_centered_justified(|ui| {
|
||||
View::sub_header(ui, format!("{} {}", HANDSHAKE, t!("network_node.peers")));
|
||||
});
|
||||
|
|
|
@ -11,3 +11,22 @@
|
|||
// 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 crate::gui::views::{NetworkTab, NetworkTabType};
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct NetworkSettings;
|
||||
|
||||
impl NetworkTab for NetworkSettings {
|
||||
fn get_type(&self) -> NetworkTabType {
|
||||
NetworkTabType::Settings
|
||||
}
|
||||
|
||||
fn name(&self) -> String {
|
||||
t!("network.settings")
|
||||
}
|
||||
|
||||
fn ui(&mut self, ui: &mut egui::Ui) {
|
||||
|
||||
}
|
||||
}
|
|
@ -12,12 +12,13 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
use egui::{Button, PointerState, Response, RichText, Sense, Widget};
|
||||
use egui::{Button, PointerState, Response, RichText, Sense, Spinner, Widget};
|
||||
use egui::epaint::{Color32, FontId, RectShape, Rounding, Stroke};
|
||||
use egui::epaint::text::TextWrapping;
|
||||
use egui::text::{LayoutJob, TextFormat};
|
||||
|
||||
use crate::gui::Colors;
|
||||
use crate::gui::icons::{CHECK_SQUARE, SQUARE};
|
||||
|
||||
pub struct View;
|
||||
|
||||
|
@ -184,4 +185,38 @@ impl View {
|
|||
});
|
||||
});
|
||||
}
|
||||
|
||||
/// Draw big gold loading spinner.
|
||||
pub fn big_loading_spinner(ui: &mut egui::Ui) {
|
||||
Spinner::new().size(104.0).color(Colors::GOLD).ui(ui);
|
||||
}
|
||||
|
||||
/// Draw small gold loading spinner.
|
||||
pub fn small_loading_spinner(ui: &mut egui::Ui) {
|
||||
Spinner::new().size(48.0).color(Colors::GOLD).ui(ui);
|
||||
}
|
||||
|
||||
// let wt = RichText::new(text.to_uppercase()).size(18.0).color(Colors::BUTTON);
|
||||
// let br = Button::new(wt)
|
||||
// .stroke(Self::DEFAULT_STROKE)
|
||||
// .fill(fill_color)
|
||||
// .ui(ui).interact(Sense::click_and_drag());
|
||||
//
|
||||
// Self::on_button_click(ui, br, action);
|
||||
|
||||
/// Draw button that looks like checkbox with callback to change value.
|
||||
pub fn checkbox(ui: &mut egui::Ui, value: bool, text: String, cb: impl FnOnce()) {
|
||||
let text_value = match value {
|
||||
true => { format!("{} {}", CHECK_SQUARE, text)}
|
||||
false => { format!("{} {}", SQUARE, text)}
|
||||
};
|
||||
let wt = RichText::new(text_value).size(18.0).color(Colors::BUTTON);
|
||||
let br = Button::new(wt)
|
||||
.frame(false)
|
||||
.stroke(Stroke::NONE)
|
||||
.fill(Colors::TRANSPARENT)
|
||||
.ui(ui).interact(Sense::click_and_drag());
|
||||
|
||||
Self::on_button_click(ui, br, cb);
|
||||
}
|
||||
}
|
|
@ -15,7 +15,7 @@
|
|||
use std::fs::{self, File};
|
||||
use std::io::Write;
|
||||
use std::path::PathBuf;
|
||||
use std::sync::{Arc, RwLock, RwLockReadGuard};
|
||||
use std::sync::{Arc, RwLock, RwLockReadGuard, RwLockWriteGuard};
|
||||
|
||||
use grin_config::ConfigError;
|
||||
use grin_core::global::ChainTypes;
|
||||
|
@ -38,14 +38,14 @@ pub struct AppConfig {
|
|||
/// Run node server on startup.
|
||||
pub auto_start_node: bool,
|
||||
/// Chain type for node server.
|
||||
pub chain_type: ChainTypes
|
||||
pub node_chain_type: ChainTypes
|
||||
}
|
||||
|
||||
impl Default for AppConfig {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
auto_start_node: false,
|
||||
chain_type: ChainTypes::default(),
|
||||
node_chain_type: ChainTypes::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -57,12 +57,16 @@ impl AppConfig {
|
|||
let parsed = Settings::read_from_file::<AppConfig>(config_path.clone());
|
||||
if !config_path.exists() || parsed.is_err() {
|
||||
let default_config = AppConfig::default();
|
||||
Settings::write_to_file(&default_config, config_path.to_str().unwrap());
|
||||
Settings::write_to_file(&default_config, config_path);
|
||||
default_config
|
||||
} else {
|
||||
parsed.unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn save(&self) {
|
||||
Settings::write_to_file(self, Settings::get_config_path(APP_CONFIG_FILE_NAME, None));
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Settings {
|
||||
|
@ -74,7 +78,7 @@ impl Settings {
|
|||
/// Initialize settings with app and node configs from the disk.
|
||||
fn init() -> Self {
|
||||
let app_config = AppConfig::init();
|
||||
let chain_type = app_config.chain_type;
|
||||
let chain_type = app_config.node_chain_type;
|
||||
Self {
|
||||
app_config: Arc::new(RwLock::new(app_config)),
|
||||
node_config: Arc::new(RwLock::new(NodeConfig::init(&chain_type)))
|
||||
|
@ -89,6 +93,10 @@ impl Settings {
|
|||
SETTINGS_STATE.app_config.read().unwrap()
|
||||
}
|
||||
|
||||
pub fn get_app_config_to_update() -> RwLockWriteGuard<'static, AppConfig> {
|
||||
SETTINGS_STATE.app_config.write().unwrap()
|
||||
}
|
||||
|
||||
/// Get working directory path for application.
|
||||
pub fn get_working_path(chain_type: Option<&ChainTypes>) -> PathBuf {
|
||||
// Check if dir exists
|
||||
|
@ -131,9 +139,9 @@ impl Settings {
|
|||
}
|
||||
|
||||
/// Write config to a file
|
||||
pub fn write_to_file<T: Serialize>(config: &T, name: &str) {
|
||||
pub fn write_to_file<T: Serialize>(config: &T, path: PathBuf) {
|
||||
let conf_out = toml::to_string(config).unwrap();
|
||||
let mut file = File::create(name).unwrap();
|
||||
let mut file = File::create(path.to_str().unwrap()).unwrap();
|
||||
file.write_all(conf_out.as_bytes()).unwrap();
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue