diff --git a/src/app/panels/middle/common/header_tab.rs b/src/app/panels/middle/common/header_tab.rs index f287ce1..e84f0fb 100644 --- a/src/app/panels/middle/common/header_tab.rs +++ b/src/app/panels/middle/common/header_tab.rs @@ -1,7 +1,12 @@ -use egui::{Hyperlink, Image, Separator, TextStyle, TextWrapMode, Ui}; -use log::debug; +use egui::{Hyperlink, Image, Label, Separator, TextStyle, TextWrapMode, Ui}; use crate::SPACE; +// prevent compiling if no elements are added to a header. No need for a header then. +const fn check_header_element(is_logo_none: bool, is_links_empty: bool, is_subtitle_none: bool) { + if is_logo_none && is_links_empty && is_subtitle_none { + panic!("header_tab must be used with at least one element"); + } +} /// logo first, first hyperlink will be the header, description under. /// will take care of centering widgets if boerder weight is more than 0. #[allow(clippy::needless_range_loop)] @@ -10,58 +15,66 @@ pub fn header_tab( logo: Option, // text, link, hover text links: &[(&str, &str, &str)], - subtitle: Option, + subtitle: Option<&str>, one_line_center: bool, ) { - // width - logo and links and separators divided by double the size of logo (can't know width of links). + check_header_element(logo.is_none(), links.is_empty(), subtitle.is_none()); ui.style_mut().wrap_mode = Some(TextWrapMode::Extend); ui.style_mut().override_text_style = Some(TextStyle::Heading); ui.add_space(SPACE); if one_line_center { - let height = 64.0; - let nb_links = links.len(); - let border_weight = ((ui.available_width() - - ((height * 4.0 * nb_links as f32) + if logo.is_some() { height * 2.0 } else { 0.0 })) - / (height * 2.0)) - .max(0.0) as usize; - // nb_columns add logo if exist plus number of links with separator for each + number of column for border space - let nb_columns = if logo.is_some() { 1 } else { 0 } + (links.len() * 2) + border_weight * 2; - ui.columns(nb_columns, |col| { - // first column for left border - for n in 0..(border_weight) { - col[n].vertical_centered(|ui| ui.add_space(0.0)); - debug!("left side space: {}", n); + ui.spacing_mut().item_spacing.x = 0.0; + let height_logo = 64.0; + let width_links = links + .iter() + .map(|x| x.0.len() as f32 * ui.text_style_height(&TextStyle::Heading) / 2.0) + .collect::>(); + let width_subtitle = subtitle.unwrap_or_default().len() as f32 + * ui.text_style_height(&TextStyle::Body) + / 2.0; + let nb_txt = links.len() + if subtitle.is_some() { 1 } else { 0 }; + // width of separator depends of width of ui and number of texts + let width_separator = (ui.available_width() / ui.text_style_height(&TextStyle::Heading) + * 4.0) + / nb_txt as f32; + // width available - logo and separator - total width of txt - separator for each text then divided by two + let border_width = (((ui.available_width() + - if logo.is_some() { + height_logo + width_separator + } else { + 0.0 } - // jump first column, stop less 2, because begin at 0 and end with space column. - let mut nb_col = border_weight; + - width_links.iter().sum::() + - width_subtitle + - (nb_txt as f32 * width_separator)) + + width_separator) + / 2.0) + .max(0.0); + ui.horizontal(|ui| { + ui.add_space(border_width); if let Some(logo) = logo { - debug!("logo: {}", nb_col); - col[nb_col].vertical_centered(|ui| ui.add_sized([height, height], logo)); - nb_col += 1; + ui.add_sized([height_logo, height_logo], logo); + ui.add_sized( + [width_separator, height_logo], + Separator::default().vertical().spacing(width_separator), + ); } - for link in links { - debug!("separator: {}", nb_col); - col[nb_col].vertical_centered(|ui| { + for (count, link) in links.iter().enumerate() { + ui.add_sized( + // [width_links[count], height_logo], + [0.0, height_logo], + Hyperlink::from_label_and_url(link.0, link.1), + ); + if count != (links.len() - 1) || subtitle.is_some() { ui.add_sized( - [height / 8.0, height], - Separator::default().vertical().spacing(height / 8.0), - ) - }); - nb_col += 1; - - debug!("link: {}", nb_col); - col[nb_col].vertical_centered(|ui| { - ui.add_sized( - [ui.available_width(), height], - Hyperlink::from_label_and_url(link.0, link.1), + [0.0, height_logo], + Separator::default().vertical().spacing(width_separator), ); - }); - nb_col += 1; + } } - - for n in nb_col..(nb_col + border_weight) { - debug!("right side border space: {}", n); - col[n].vertical_centered(|ui| ui.add_space(0.0)); + if let Some(desc) = subtitle { + ui.style_mut().override_text_style = Some(TextStyle::Body); + ui.add_sized([0.0, height_logo], Label::new(desc)); } }); } else { @@ -73,11 +86,11 @@ pub fn header_tab( for link in links { ui.hyperlink_to(link.0, link.1); } - ui.style_mut().override_text_style = Some(TextStyle::Body); + if let Some(desc) = subtitle { + ui.style_mut().override_text_style = Some(TextStyle::Body); + ui.label(desc); + } }); } - if let Some(desc) = subtitle { - ui.label(desc); - } ui.add_space(SPACE); } diff --git a/src/app/panels/middle/node.rs b/src/app/panels/middle/node.rs index b282dd2..6efa76d 100644 --- a/src/app/panels/middle/node.rs +++ b/src/app/panels/middle/node.rs @@ -1,10 +1,11 @@ use crate::app::panels::middle::common::console::{console, input_args_field, start_options_field}; +use crate::app::panels::middle::common::header_tab::header_tab; use crate::app::panels::middle::common::state_edit_field::{path_db_field, slider_state_field}; use crate::app::panels::middle::{rpc_bind_field, rpc_port_field, zmq_bind_field, zmq_port_field}; use crate::{ NODE_ARGUMENTS, NODE_DNS_BLOCKLIST, NODE_DNS_CHECKPOINT, NODE_INPUT, NODE_PRUNNING, NODE_URL, }; -use egui::{Label, TextStyle}; +use egui::TextStyle; use std::sync::{Arc, Mutex}; use log::debug; @@ -26,14 +27,13 @@ impl Node { ui: &mut egui::Ui, ) { ui.style_mut().override_text_style = Some(TextStyle::Body); - ui.vertical_centered(|ui| { - ui.add_space(SPACE); - ui.style_mut().override_text_style = Some(TextStyle::Heading); - ui.hyperlink_to("Monerod", NODE_URL); - ui.style_mut().override_text_style = None; - ui.add(Label::new("C++ Monero Node")); - ui.add_space(SPACE); - }); + header_tab( + ui, + None, + &[("Monerod", NODE_URL, "")], + Some("C++ Monero Node"), + true, + ); // console output for log debug!("Node Tab | Rendering [Console]"); egui::ScrollArea::vertical().show(ui, |ui| { diff --git a/src/app/panels/middle/xmrig_proxy.rs b/src/app/panels/middle/xmrig_proxy.rs index 1af1ef8..34a781d 100644 --- a/src/app/panels/middle/xmrig_proxy.rs +++ b/src/app/panels/middle/xmrig_proxy.rs @@ -1,9 +1,10 @@ -use egui::{Checkbox, Label, TextStyle, Ui, vec2}; +use egui::{Checkbox, TextStyle, Ui, vec2}; use std::sync::{Arc, Mutex}; use log::debug; use crate::app::panels::middle::common::console::{console, input_args_field, start_options_field}; +use crate::app::panels::middle::common::header_tab::header_tab; use crate::app::panels::middle::common::list_poolnode::list_poolnode; use crate::disk::state::XmrigProxy; use crate::helper::Process; @@ -29,14 +30,13 @@ impl XmrigProxy { buffer: &mut String, ui: &mut egui::Ui, ) { - ui.vertical_centered(|ui| { - ui.add_space(SPACE); - ui.style_mut().override_text_style = Some(TextStyle::Heading); - ui.hyperlink_to("XMRig-Proxy", XMRIG_PROXY_URL); - ui.style_mut().override_text_style = Some(TextStyle::Body); - ui.add(Label::new("High performant proxy for your miners")); - ui.add_space(SPACE); - }); + header_tab( + ui, + None, + &[("XMRig-Proxy", XMRIG_PROXY_URL, "")], + Some("High performant proxy for your miners"), + true, + ); // console output for log debug!("Xmrig-Proxy Tab | Rendering [Console]"); egui::ScrollArea::vertical().show(ui, |ui| {