improve look of adapters buttons in initial page

This commit is contained in:
GyulyVGC
2025-12-18 23:53:54 +01:00
parent 1b75284afb
commit f61fb26cc1
4 changed files with 97 additions and 100 deletions

View File

@@ -1,7 +1,7 @@
use std::ops::Range; use std::ops::Range;
use iced::Element; use iced::Element;
use iced::widget::Column; use iced::widget::{Column, Space};
use plotters::prelude::*; use plotters::prelude::*;
use plotters_iced::{Chart, ChartBuilder, ChartWidget, DrawingBackend}; use plotters_iced::{Chart, ChartBuilder, ChartWidget, DrawingBackend};
@@ -49,7 +49,11 @@ pub fn update_charts_data(&mut self, packets: u128) {
} }
pub fn view(&self) -> Element<'_, Message, StyleType> { pub fn view(&self) -> Element<'_, Message, StyleType> {
Column::new().height(40).push(ChartWidget::new(self)).into() Column::new()
.height(45)
.push(Space::with_height(5))
.push(ChartWidget::new(self))
.into()
} }
pub fn change_style(&mut self, style: StyleType) { pub fn change_style(&mut self, style: StyleType) {

View File

@@ -9,7 +9,7 @@
use crate::gui::styles::button::ButtonType; use crate::gui::styles::button::ButtonType;
use crate::gui::styles::container::ContainerType; use crate::gui::styles::container::ContainerType;
use crate::gui::styles::scrollbar::ScrollbarType; use crate::gui::styles::scrollbar::ScrollbarType;
use crate::gui::styles::style_constants::{FONT_SIZE_SUBTITLE, FONT_SIZE_TITLE}; use crate::gui::styles::style_constants::{FONT_SIZE_FOOTER, FONT_SIZE_SUBTITLE, FONT_SIZE_TITLE};
use crate::gui::styles::text::TextType; use crate::gui::styles::text::TextType;
use crate::gui::styles::types::gradient_type::GradientType; use crate::gui::styles::types::gradient_type::GradientType;
use crate::gui::types::export_pcap::ExportPcap; use crate::gui::types::export_pcap::ExportPcap;
@@ -17,9 +17,8 @@
use crate::gui::types::message::Message; use crate::gui::types::message::Message;
use crate::gui::types::settings::Settings; use crate::gui::types::settings::Settings;
use crate::networking::types::capture_context::{CaptureSource, CaptureSourcePicklist}; use crate::networking::types::capture_context::{CaptureSource, CaptureSourcePicklist};
use crate::translations::translations::{ use crate::networking::types::my_device::MyDevice;
address_translation, addresses_translation, network_adapter_translation, start_translation, use crate::translations::translations::{network_adapter_translation, start_translation};
};
use crate::translations::translations_3::{ use crate::translations::translations_3::{
directory_translation, export_capture_translation, file_name_translation, directory_translation, export_capture_translation, file_name_translation,
}; };
@@ -138,7 +137,7 @@ fn get_col_data_source(
let mut col = Column::new() let mut col = Column::new()
.align_x(Alignment::Center) .align_x(Alignment::Center)
.padding(Padding::new(10.0).top(30)) .padding(Padding::new(10.0).top(30).bottom(0))
.spacing(30) .spacing(30)
.height(Length::Fill) .height(Length::Fill)
.width(FillPortion(1)) .width(FillPortion(1))
@@ -156,7 +155,7 @@ fn get_col_data_source(
match &sniffer.conf.capture_source_picklist { match &sniffer.conf.capture_source_picklist {
CaptureSourcePicklist::Device => { CaptureSourcePicklist::Device => {
col = col.push(get_col_adapter(sniffer, font, language)); col = col.push(get_col_adapter(sniffer, font));
} }
CaptureSourcePicklist::File => { CaptureSourcePicklist::File => {
col = col.push(get_col_import_pcap( col = col.push(get_col_import_pcap(
@@ -171,72 +170,22 @@ fn get_col_data_source(
col col
} }
fn get_col_adapter( fn get_col_adapter(sniffer: &Sniffer, font: Font) -> Column<'_, Message, StyleType> {
sniffer: &Sniffer,
font: Font,
language: Language,
) -> Column<'_, Message, StyleType> {
let mut dev_str_list = vec![];
// TODO: do not iterate here
for (my_dev, _) in &sniffer.preview_charts {
let mut title = String::new();
#[allow(unused_mut)]
let mut subtitle: Option<&String> = None;
let name = my_dev.get_name();
match my_dev.get_desc() {
None => {
title.push_str(name);
}
Some(description) => {
#[cfg(not(target_os = "windows"))]
{
let _ = writeln!(title, "{name}");
subtitle = Some(description);
}
#[cfg(target_os = "windows")]
title.push_str(description);
}
}
let mut addrs_str = String::new();
let num_addresses = my_dev.get_addresses().len();
match num_addresses {
0 => {}
1 => {
let _ = write!(addrs_str, "{}:", address_translation(language));
}
_ => {
let _ = write!(addrs_str, "{}:", addresses_translation(language));
}
}
for addr in my_dev.get_addresses() {
let address_string = addr.addr.to_string();
let _ = write!(addrs_str, "\n {address_string}");
}
dev_str_list.push((name, title, subtitle, addrs_str));
}
Column::new() Column::new()
.spacing(5) .spacing(5)
.height(Length::Fill) .height(Length::Fill)
.push(if dev_str_list.is_empty() { .push(if sniffer.preview_charts.is_empty() {
Into::<iced::Element<Message, StyleType>>::into(center( Into::<iced::Element<Message, StyleType>>::into(center(
Icon::get_hourglass(sniffer.dots_pulse.0.len()).size(60), Icon::get_hourglass(sniffer.dots_pulse.0.len()).size(60),
)) ))
} else { } else {
Scrollable::with_direction( Scrollable::with_direction(
dev_str_list.into_iter().fold( sniffer.preview_charts.iter().fold(
Column::new().padding(Padding::ZERO.right(13)).spacing(5), Column::new().padding(Padding::ZERO.right(13)).spacing(5),
|scroll_adapters, (name, title, subtitle, addrs)| { |scroll_adapters, (my_dev, chart)| {
let addrs_text = if addrs.is_empty() { let name = my_dev.get_name();
None let addresses_row = get_addresses_row(my_dev, font);
} else { let (title, subtitle) = get_adapter_title_subtitle(my_dev);
Some(Text::new(addrs).font(font))
};
let my_device_chart = sniffer
.preview_charts
.iter()
.find(|(dev, _)| dev.get_name().eq(name));
scroll_adapters.push( scroll_adapters.push(
Button::new( Button::new(
Column::new() Column::new()
@@ -248,16 +197,14 @@ fn get_col_adapter(
.size(FONT_SIZE_SUBTITLE), .size(FONT_SIZE_SUBTITLE),
) )
.push_maybe(subtitle.map(|sub| Text::new(sub).font(font))) .push_maybe(subtitle.map(|sub| Text::new(sub).font(font)))
.push_maybe(addrs_text) .push_maybe(addresses_row)
.push_maybe(my_device_chart.and_then(|(_, c)| { .push_maybe(if chart.max_packets > 0.0 {
if c.max_packets > 0.0 { Some(chart.view())
Some(c.view()) } else {
} else { None
None }),
}
})),
) )
.padding([20, 30]) .padding(15)
.width(Length::Fill) .width(Length::Fill)
.class( .class(
if let CaptureSource::Device(device) = &sniffer.capture_source { if let CaptureSource::Device(device) = &sniffer.capture_source {
@@ -280,6 +227,45 @@ fn get_col_adapter(
}) })
} }
fn get_addresses_row(my_dev: &MyDevice, font: Font) -> Option<Row<'_, Message, StyleType>> {
let addresses = my_dev.get_addresses();
if addresses.is_empty() {
return None;
}
let mut row = Row::new().spacing(5);
for addr in my_dev.get_addresses() {
let address_string = addr.addr.to_string();
row = row.push(
Container::new(Text::new(address_string).size(FONT_SIZE_FOOTER).font(font))
.padding(Padding::new(5.0).left(10).right(10))
.class(ContainerType::AdapterAddress),
);
}
Some(row)
}
fn get_adapter_title_subtitle(my_dev: &MyDevice) -> (String, Option<String>) {
let mut title = String::new();
#[allow(unused_mut)]
let mut subtitle: Option<String> = None;
let name = my_dev.get_name();
match my_dev.get_desc() {
None => {
title.push_str(name);
}
Some(description) => {
#[cfg(not(target_os = "windows"))]
{
let _ = writeln!(title, "{name}");
subtitle = Some(description.to_owned());
}
#[cfg(target_os = "windows")]
title.push_str(description.to_owned());
}
}
(title, subtitle)
}
fn get_col_import_pcap<'a>( fn get_col_import_pcap<'a>(
language: Language, language: Language,
font: Font, font: Font,

View File

@@ -24,6 +24,7 @@ pub enum ContainerType {
Highlighted, Highlighted,
HighlightedOnHeader, HighlightedOnHeader,
ModalBackground, ModalBackground,
AdapterAddress,
} }
impl ContainerType { impl ContainerType {
@@ -61,6 +62,10 @@ fn appearance(&self, style: &StyleType) -> Style {
a: 0.9, a: 0.9,
..Color::BLACK ..Color::BLACK
}), }),
ContainerType::AdapterAddress => Background::Color(Color {
a: if ext.is_nightly { 0.4 } else { 0.7 },
..ext.buttons_color
}),
}), }),
border: Border { border: Border {
radius: match self { radius: match self {
@@ -68,6 +73,7 @@ fn appearance(&self, style: &StyleType) -> Style {
ContainerType::Modal => Radius::new(0).bottom(BORDER_ROUNDED_RADIUS), ContainerType::Modal => Radius::new(0).bottom(BORDER_ROUNDED_RADIUS),
ContainerType::Tooltip => 7.0.into(), ContainerType::Tooltip => 7.0.into(),
ContainerType::Badge ContainerType::Badge
| ContainerType::AdapterAddress
| ContainerType::BadgeInfo | ContainerType::BadgeInfo
| ContainerType::Highlighted | ContainerType::Highlighted
| ContainerType::HighlightedOnHeader => 100.0.into(), | ContainerType::HighlightedOnHeader => 100.0.into(),
@@ -84,6 +90,7 @@ fn appearance(&self, style: &StyleType) -> Style {
_ => BORDER_WIDTH, _ => BORDER_WIDTH,
}, },
color: match self { color: match self {
ContainerType::AdapterAddress => colors.primary,
ContainerType::Palette => Color::BLACK, ContainerType::Palette => Color::BLACK,
ContainerType::BadgeInfo => colors.secondary, ContainerType::BadgeInfo => colors.secondary,
ContainerType::Modal => ext.buttons_color, ContainerType::Modal => ext.buttons_color,

View File

@@ -142,32 +142,32 @@ pub fn address_translation(language: Language) -> &'static str {
} }
} }
pub fn addresses_translation(language: Language) -> &'static str { // pub fn addresses_translation(language: Language) -> &'static str {
match language { // match language {
Language::EN => "Addresses", // Language::EN => "Addresses",
Language::IT => "Indirizzi", // Language::IT => "Indirizzi",
Language::FR => "Adresses", // Language::FR => "Adresses",
Language::ES => "Direcciones", // Language::ES => "Direcciones",
Language::PL | Language::CS => "Adresy", // Language::PL | Language::CS => "Adresy",
Language::DE | Language::NL => "Adressen", // Language::DE | Language::NL => "Adressen",
Language::UK => "Адреси", // Language::UK => "Адреси",
Language::ZH => "网络地址", // Language::ZH => "网络地址",
Language::ZH_TW => "網路位址", // Language::ZH_TW => "網路位址",
Language::RO => "Adrese", // Language::RO => "Adrese",
Language::KO => "주소", // Language::KO => "주소",
Language::TR => "Adresler", // Language::TR => "Adresler",
Language::RU => "Адреса", // Language::RU => "Адреса",
Language::PT => "Endereços", // Language::PT => "Endereços",
Language::EL => "Διευθύνσεις", // Language::EL => "Διευθύνσεις",
// Language::FA => "نشانی ها", // // Language::FA => "نشانی ها",
Language::SV => "Adresser", // Language::SV => "Adresser",
Language::FI => "Osoitteet", // Language::FI => "Osoitteet",
Language::JA => "アドレス", // Language::JA => "アドレス",
Language::UZ => "Manzillar", // Language::UZ => "Manzillar",
Language::VI => "Danh sách địa chỉ", // Language::VI => "Danh sách địa chỉ",
Language::ID => "Alamat", // Language::ID => "Alamat",
} // }
} // }
// pub fn ip_version_translation(language: Language) -> &'static str { // pub fn ip_version_translation(language: Language) -> &'static str {
// match language { // match language {