ui: simplify rounding around list items

This commit is contained in:
ardocrat 2023-07-29 19:08:06 +03:00
parent 3f0d8facac
commit b6e55b0762
5 changed files with 62 additions and 120 deletions

View file

@ -13,7 +13,7 @@
// limitations under the License. // limitations under the License.
use chrono::{DateTime, NaiveDateTime, Utc}; use chrono::{DateTime, NaiveDateTime, Utc};
use egui::{RichText, Rounding, ScrollArea, Stroke, vec2}; use egui::{RichText, Rounding, ScrollArea, vec2};
use grin_servers::DiffBlock; use grin_servers::DiffBlock;
use crate::gui::Colors; use crate::gui::Colors;
@ -135,34 +135,24 @@ impl NetworkTab for NetworkMetrics {
blocks_size, blocks_size,
|ui, row_range| { |ui, row_range| {
for index in 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(); let db = stats.diff_stats.last_blocks.get(index).unwrap();
let rounding = if blocks_size == 1 { block_item_ui(ui, db, View::item_rounding(index, blocks_size))
[true, true]
} else if index == 0 {
[true, false]
} else if index == blocks_size - 1 {
[false, true]
} else {
[false, false]
};
block_item_ui(ui, db, rounding)
} }
}, },
); );
} }
fn on_modal_ui(&mut self, ui: &mut egui::Ui, modal: &Modal, cb: &dyn PlatformCallbacks) {} fn on_modal_ui(&mut self, _: &mut egui::Ui, _: &Modal, _: &dyn PlatformCallbacks) {}
} }
const BLOCK_ITEM_HEIGHT: f32 = 77.0; const BLOCK_ITEM_HEIGHT: f32 = 77.0;
/// Draw block difficulty item. /// Draw block difficulty item.
fn block_item_ui(ui: &mut egui::Ui, db: &DiffBlock, rounding: [bool; 2]) { fn block_item_ui(ui: &mut egui::Ui, db: &DiffBlock, rounding: Rounding) {
// Add space before the first item.
if rounding[0] {
ui.add_space(4.0);
}
let mut rect = ui.available_rect_before_wrap(); let mut rect = ui.available_rect_before_wrap();
rect.set_height(BLOCK_ITEM_HEIGHT); rect.set_height(BLOCK_ITEM_HEIGHT);
ui.allocate_ui_at_rect(rect, |ui| { ui.allocate_ui_at_rect(rect, |ui| {
@ -171,17 +161,7 @@ fn block_item_ui(ui: &mut egui::Ui, db: &DiffBlock, rounding: [bool; 2]) {
ui.vertical(|ui| { ui.vertical(|ui| {
// Draw round background. // Draw round background.
rect.min += vec2(8.0, 0.0); rect.min += vec2(8.0, 0.0);
ui.painter().rect( ui.painter().rect(rect, rounding, Colors::WHITE, View::ITEM_STROKE);
rect,
Rounding {
nw: if rounding[0] { 8.0 } else { 0.0 },
ne: if rounding[0] { 8.0 } else { 0.0 },
sw: if rounding[1] { 8.0 } else { 0.0 },
se: if rounding[1] { 8.0 } else { 0.0 },
},
Colors::WHITE,
Stroke { width: 1.0, color: Colors::ITEM_STROKE }
);
ui.add_space(2.0); ui.add_space(2.0);

View file

@ -13,12 +13,12 @@
// limitations under the License. // limitations under the License.
use chrono::{DateTime, NaiveDateTime, Utc}; use chrono::{DateTime, NaiveDateTime, Utc};
use egui::{RichText, Rounding, ScrollArea, Stroke}; use egui::{RichText, Rounding, ScrollArea};
use grin_chain::SyncStatus; use grin_chain::SyncStatus;
use grin_servers::WorkerStats; 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_NOTCH_MINUS, FOLDER_NOTCH_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::{Modal, Network, View}; use crate::gui::views::{Modal, Network, View};
use crate::gui::views::network::setup::StratumSetup; use crate::gui::views::network::setup::StratumSetup;
@ -174,17 +174,12 @@ impl NetworkTab for NetworkMining {
workers_size, workers_size,
|ui, row_range| { |ui, row_range| {
for index in row_range { for index in row_range {
// Add space before the first item.
if index == 0 {
ui.add_space(4.0);
}
let worker = stratum_stats.worker_stats.get(index).unwrap(); let worker = stratum_stats.worker_stats.get(index).unwrap();
let rounding = if workers_size == 1 { worker_item_ui(ui, worker, View::item_rounding(index, workers_size));
[true, true]
} else if index == 0 {
[true, false]
} else if index == workers_size - 1 {
[false, true]
} else {
[false, false]
};
worker_item_ui(ui, worker, rounding)
} }
}, },
); );
@ -217,28 +212,13 @@ impl NetworkTab for NetworkMining {
const WORKER_ITEM_HEIGHT: f32 = 76.0; const WORKER_ITEM_HEIGHT: f32 = 76.0;
/// Draw worker statistics item. /// Draw worker statistics item.
fn worker_item_ui(ui: &mut egui::Ui, ws: &WorkerStats, rounding: [bool; 2]) { fn worker_item_ui(ui: &mut egui::Ui, ws: &WorkerStats, rounding: Rounding) {
// Add space before the first item.
if rounding[0] {
ui.add_space(4.0);
}
ui.horizontal_wrapped(|ui| { ui.horizontal_wrapped(|ui| {
ui.vertical_centered_justified(|ui| { ui.vertical_centered_justified(|ui| {
// Draw round background. // Draw round background.
let mut rect = ui.available_rect_before_wrap(); let mut rect = ui.available_rect_before_wrap();
rect.set_height(WORKER_ITEM_HEIGHT); rect.set_height(WORKER_ITEM_HEIGHT);
ui.painter().rect( ui.painter().rect(rect, rounding, Colors::WHITE, View::ITEM_STROKE);
rect,
Rounding {
nw: if rounding[0] { 8.0 } else { 0.0 },
ne: if rounding[0] { 8.0 } else { 0.0 },
sw: if rounding[1] { 8.0 } else { 0.0 },
se: if rounding[1] { 8.0 } else { 0.0 },
},
Colors::WHITE,
Stroke { width: 1.0, color: Colors::ITEM_STROKE }
);
ui.add_space(2.0); ui.add_space(2.0);
ui.horizontal(|ui| { ui.horizontal(|ui| {
@ -266,14 +246,14 @@ fn worker_item_ui(ui: &mut egui::Ui, ws: &WorkerStats, rounding: [bool; 2]) {
ui.add_space(6.0); ui.add_space(6.0);
// Draw accepted shares. // Draw accepted shares.
let accepted_text = format!("{} {}", FOLDER_NOTCH_PLUS, ws.num_accepted); let accepted_text = format!("{} {}", FOLDER_SIMPLE_PLUS, ws.num_accepted);
ui.heading(RichText::new(accepted_text) ui.heading(RichText::new(accepted_text)
.color(Colors::GREEN) .color(Colors::GREEN)
.size(16.0)); .size(16.0));
ui.add_space(6.0); ui.add_space(6.0);
// Draw rejected shares. // Draw rejected shares.
let rejected_text = format!("{} {}", FOLDER_NOTCH_MINUS, ws.num_rejected); let rejected_text = format!("{} {}", FOLDER_SIMPLE_MINUS, ws.num_rejected);
ui.heading(RichText::new(rejected_text) ui.heading(RichText::new(rejected_text)
.color(Colors::RED) .color(Colors::RED)
.size(16.0)); .size(16.0));

View file

@ -165,45 +165,29 @@ impl NetworkTab for NetworkNode {
// Show peer stats when available. // Show peer stats when available.
if stats.peer_count > 0 { if stats.peer_count > 0 {
View::sub_title(ui, format!("{} {}", HANDSHAKE, t!("network_node.peers"))); View::sub_title(ui, format!("{} {}", HANDSHAKE, t!("network_node.peers")));
for (index, ps) in stats.peer_stats.iter().enumerate() { let peers = &stats.peer_stats;
let rounding = if stats.peer_count == 1 { for (index, ps) in peers.iter().enumerate() {
[true, true] peer_item_ui(ui, ps, View::item_rounding(index, peers.len()));
} else if index == 0 { // Add space after the last item.
[true, false] if index == peers.len() - 1 {
} else if index == &stats.peer_stats.len() - 1 { ui.add_space(5.0);
[false, true] }
} else {
[false, false]
};
ui.vertical_centered(|ui| {
peer_item_ui(ui, ps, rounding);
});
} }
} }
}); });
} }
fn on_modal_ui(&mut self, ui: &mut egui::Ui, modal: &Modal, cb: &dyn PlatformCallbacks) {} fn on_modal_ui(&mut self, _: &mut egui::Ui, _: &Modal, _: &dyn PlatformCallbacks) {}
} }
/// Draw connected peer info item. /// Draw connected peer info item.
fn peer_item_ui(ui: &mut egui::Ui, peer: &PeerStats, rounding: [bool; 2]) { 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();
rect.set_height(77.0); rect.set_height(77.0);
ui.allocate_ui_at_rect(rect, |ui| { ui.allocate_ui_at_rect(rect, |ui| {
ui.vertical(|ui| { ui.vertical(|ui| {
// Draw round background. // Draw round background.
ui.painter().rect( ui.painter().rect(rect, rounding, Colors::WHITE, View::ITEM_STROKE);
rect,
Rounding {
nw: if rounding[0] { 8.0 } else { 0.0 },
ne: if rounding[0] { 8.0 } else { 0.0 },
sw: if rounding[1] { 8.0 } else { 0.0 },
se: if rounding[1] { 8.0 } else { 0.0 },
},
Colors::WHITE,
Stroke { width: 1.0, color: Colors::ITEM_STROKE }
);
ui.add_space(2.0); ui.add_space(2.0);
@ -233,9 +217,4 @@ fn peer_item_ui(ui: &mut egui::Ui, peer: &PeerStats, rounding: [bool; 2]) {
ui.add_space(2.0); ui.add_space(2.0);
}); });
}); });
// Add space after the last item.
if rounding[1] {
ui.add_space(5.0);
}
} }

View file

@ -12,13 +12,13 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
use egui::{Id, RichText, Rounding, Stroke, TextStyle, Ui, Widget}; use egui::{Id, RichText, Rounding, TextStyle, Ui, Widget};
use egui_extras::{Size, StripBuilder}; use egui_extras::{Size, StripBuilder};
use grin_core::global::ChainTypes; use grin_core::global::ChainTypes;
use crate::AppConfig; use crate::AppConfig;
use crate::gui::Colors; use crate::gui::Colors;
use crate::gui::icons::{HANDSHAKE, PLUG, TRASH, GLOBE_SIMPLE, PLUS_CIRCLE, ARROW_FAT_LINES_UP, ARROW_FAT_LINES_DOWN, ARROW_FAT_LINE_UP, PROHIBIT_INSET, CLIPBOARD_TEXT}; use crate::gui::icons::{ARROW_FAT_LINE_UP, ARROW_FAT_LINES_DOWN, ARROW_FAT_LINES_UP, CLIPBOARD_TEXT, COMPUTER_TOWER, GLOBE_SIMPLE, HANDSHAKE, PLUG, PLUS_CIRCLE, PROHIBIT_INSET, TRASH};
use crate::gui::platform::PlatformCallbacks; use crate::gui::platform::PlatformCallbacks;
use crate::gui::views::{Modal, ModalPosition, View}; use crate::gui::views::{Modal, ModalPosition, View};
use crate::gui::views::network::settings::NetworkSettings; use crate::gui::views::network::settings::NetworkSettings;
@ -301,7 +301,7 @@ impl P2PSetup {
/// Draw peer list content based on provided [`PeerType`]. /// Draw peer list content based on provided [`PeerType`].
fn peer_list_ui(&mut self, ui: &mut Ui, peer_type: &PeerType, cb: &dyn PlatformCallbacks) { fn peer_list_ui(&mut self, ui: &mut Ui, peer_type: &PeerType, cb: &dyn PlatformCallbacks) {
let peer_list = match peer_type { let peers = match peer_type {
PeerType::DefaultSeed => { PeerType::DefaultSeed => {
if AppConfig::chain_type() == ChainTypes::Testnet { if AppConfig::chain_type() == ChainTypes::Testnet {
self.default_test_seeds.clone() self.default_test_seeds.clone()
@ -314,26 +314,17 @@ impl P2PSetup {
PeerType::Denied => NodeConfig::get_denied_peers(), PeerType::Denied => NodeConfig::get_denied_peers(),
PeerType::Preferred => NodeConfig::get_preferred_peers() PeerType::Preferred => NodeConfig::get_preferred_peers()
}; };
for (index, peer) in peer_list.iter().enumerate() { for (index, peer) in peers.iter().enumerate() {
let rounding = if peer_list.len() == 1 {
[true, true]
} else if index == 0 {
[true, false]
} else if index == peer_list.len() - 1 {
[false, true]
} else {
[false, false]
};
ui.horizontal_wrapped(|ui| { ui.horizontal_wrapped(|ui| {
// Draw peer list item. // Draw peer list item.
Self::peer_item_ui(ui, peer, peer_type, rounding); Self::peer_item_ui(ui, peer, peer_type, View::item_rounding(index, peers.len()));
}); });
} }
if peer_type != &PeerType::DefaultSeed { if peer_type != &PeerType::DefaultSeed {
// Draw description. // Draw description.
if peer_type != &PeerType::CustomSeed { if peer_type != &PeerType::CustomSeed {
if !peer_list.is_empty() { if !peers.is_empty() {
ui.add_space(12.0); ui.add_space(12.0);
} }
let desc = match peer_type { let desc = match peer_type {
@ -482,22 +473,12 @@ impl P2PSetup {
} }
/// Draw peer list item. /// Draw peer list item.
fn peer_item_ui(ui: &mut Ui, peer_addr: &String, peer_type: &PeerType, rounding: [bool; 2]) { fn peer_item_ui(ui: &mut Ui, peer_addr: &String, peer_type: &PeerType, rounding: Rounding) {
// Draw round background. // Draw round background.
let mut rect = ui.available_rect_before_wrap(); let mut rect = ui.available_rect_before_wrap();
rect.min += egui::emath::vec2(6.0, 0.0); rect.min += egui::emath::vec2(6.0, 0.0);
rect.set_height(42.0); rect.set_height(42.0);
ui.painter().rect( ui.painter().rect(rect, rounding, Colors::WHITE, View::ITEM_STROKE);
rect,
Rounding {
nw: if rounding[0] { 6.0 } else { 0.0 },
ne: if rounding[0] { 6.0 } else { 0.0 },
sw: if rounding[1] { 6.0 } else { 0.0 },
se: if rounding[1] { 6.0 } else { 0.0 },
},
Colors::WHITE,
Stroke { width: 1.0, color: Colors::ITEM_STROKE }
);
StripBuilder::new(ui) StripBuilder::new(ui)
.size(Size::exact(42.0)) .size(Size::exact(42.0))
@ -512,10 +493,10 @@ impl P2PSetup {
strip.cell(|ui| { strip.cell(|ui| {
ui.horizontal_centered(|ui| { ui.horizontal_centered(|ui| {
// Draw peer address. // Draw peer address.
let peer_text = format!("{} {}", GLOBE_SIMPLE, &peer_addr); let peer_text = format!("{} {}", COMPUTER_TOWER, &peer_addr);
ui.label(RichText::new(peer_text) ui.label(RichText::new(peer_text)
.color(Colors::TEXT_BUTTON) .color(Colors::TEXT_BUTTON)
.size(17.0)); .size(16.0));
}); });
}); });
if peer_type != &PeerType::DefaultSeed { if peer_type != &PeerType::DefaultSeed {

View file

@ -28,6 +28,8 @@ pub struct View;
impl View { impl View {
/// Default stroke around views. /// Default stroke around views.
pub const DEFAULT_STROKE: Stroke = Stroke { width: 1.0, color: Colors::STROKE }; pub const DEFAULT_STROKE: Stroke = Stroke { width: 1.0, color: Colors::STROKE };
/// Stroke around list items.
pub const ITEM_STROKE: Stroke = Stroke { width: 1.0, color: Colors::ITEM_STROKE };
/// Callback on Enter key press event. /// Callback on Enter key press event.
pub fn on_enter_key(ui: &mut egui::Ui, cb: impl FnOnce()) { pub fn on_enter_key(ui: &mut egui::Ui, cb: impl FnOnce()) {
@ -194,6 +196,26 @@ impl View {
}); });
} }
/// Calculate list item rounding based on item index.
pub fn item_rounding(index: usize, len: usize) -> Rounding {
let rounding = if len == 1 {
[true, true]
} else if index == 0 {
[true, false]
} else if index == len - 1 {
[false, true]
} else {
[false, false]
};
Rounding {
nw: if rounding[0] { 8.0 } else { 0.0 },
ne: if rounding[0] { 8.0 } else { 0.0 },
sw: if rounding[1] { 8.0 } else { 0.0 },
se: if rounding[1] { 8.0 } else { 0.0 },
}
}
/// Draw rounded box with some value and label in the middle, /// Draw rounded box with some value and label in the middle,
/// where is r = (top_left, top_right, bottom_left, bottom_right). /// where is r = (top_left, top_right, bottom_left, bottom_right).
/// | VALUE | /// | VALUE |