From 26a8912fc3d99ef39278a808dbc621515aee586c Mon Sep 17 00:00:00 2001 From: Csaba Date: Thu, 10 Oct 2024 00:23:01 +0200 Subject: [PATCH] feat(bar): add label prefix config opt This commit makes the label prefix configurable. Users can select if they want to show an icon, only text, or both text and an icon. --- komorebi-bar/src/battery.rs | 27 ++++- komorebi-bar/src/config.rs | 12 +++ komorebi-bar/src/cpu.rs | 17 +++- komorebi-bar/src/date.rs | 18 +++- komorebi-bar/src/memory.rs | 19 +++- komorebi-bar/src/network.rs | 190 ++++++++++++++++++++++++++++++------ komorebi-bar/src/storage.rs | 25 +++-- komorebi-bar/src/time.rs | 18 +++- 8 files changed, 276 insertions(+), 50 deletions(-) diff --git a/komorebi-bar/src/battery.rs b/komorebi-bar/src/battery.rs index 1b1517e07..0925b109e 100644 --- a/komorebi-bar/src/battery.rs +++ b/komorebi-bar/src/battery.rs @@ -1,3 +1,4 @@ +use crate::config::LabelPrefix; use crate::widget::BarWidget; use crate::WIDGET_SPACING; use eframe::egui::text::LayoutJob; @@ -23,6 +24,8 @@ pub struct BatteryConfig { pub enable: bool, /// Data refresh interval (default: 10 seconds) pub data_refresh_interval: Option, + /// Display label prefix + pub label_prefix: Option, } impl From for Battery { @@ -30,6 +33,7 @@ impl From for Battery { let manager = Manager::new().unwrap(); let mut last_state = String::new(); let mut state = None; + let prefix = value.label_prefix.unwrap_or(LabelPrefix::Icon); if let Ok(mut batteries) = manager.batteries() { if let Some(Ok(first)) = batteries.nth(0) { @@ -39,8 +43,13 @@ impl From for Battery { State::Discharging => state = Some(BatteryState::Discharging), _ => {} } - - last_state = format!("{percentage}%"); + + last_state = match prefix { + LabelPrefix::Text | LabelPrefix::IconAndText => { + format!("BAT: {percentage:.0}%") + } + LabelPrefix::None | LabelPrefix::Icon => format!("{percentage:.0}%"), + } } } @@ -49,6 +58,7 @@ impl From for Battery { manager, last_state, data_refresh_interval: value.data_refresh_interval.unwrap_or(10), + label_prefix: prefix, state: state.unwrap_or(BatteryState::Discharging), last_updated: Instant::now(), } @@ -65,6 +75,7 @@ pub struct Battery { manager: Manager, pub state: BatteryState, data_refresh_interval: u64, + label_prefix: LabelPrefix, last_state: String, last_updated: Instant, } @@ -86,7 +97,12 @@ impl Battery { _ => {} } - output = format!("{percentage:.0}%"); + output = match self.label_prefix { + LabelPrefix::Text | LabelPrefix::IconAndText => { + format!("BAT: {percentage:.0}%") + } + LabelPrefix::None | LabelPrefix::Icon => format!("{percentage:.0}%"), + } } } @@ -116,7 +132,10 @@ impl BarWidget for Battery { .unwrap_or_else(FontId::default); let mut layout_job = LayoutJob::simple( - emoji.to_string(), + match self.label_prefix { + LabelPrefix::Icon | LabelPrefix::IconAndText => emoji.to_string(), + LabelPrefix::None | LabelPrefix::Text => String::new(), + }, font_id.clone(), ctx.style().visuals.selection.stroke.color, 100.0, diff --git a/komorebi-bar/src/config.rs b/komorebi-bar/src/config.rs index 8d59f6fbf..cf18b707c 100644 --- a/komorebi-bar/src/config.rs +++ b/komorebi-bar/src/config.rs @@ -164,3 +164,15 @@ impl From for KomobarTheme { } } } + +#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema)] +pub enum LabelPrefix { + /// Show no prefix + None, + /// Show an icon + Icon, + /// Show text + Text, + /// Show an icon and text + IconAndText, +} diff --git a/komorebi-bar/src/cpu.rs b/komorebi-bar/src/cpu.rs index 58f77db94..aedb6b067 100644 --- a/komorebi-bar/src/cpu.rs +++ b/komorebi-bar/src/cpu.rs @@ -1,3 +1,4 @@ +use crate::config::LabelPrefix; use crate::widget::BarWidget; use crate::WIDGET_SPACING; use eframe::egui::text::LayoutJob; @@ -23,6 +24,8 @@ pub struct CpuConfig { pub enable: bool, /// Data refresh interval (default: 10 seconds) pub data_refresh_interval: Option, + /// Display label prefix + pub label_prefix: Option, } impl From for Cpu { @@ -36,6 +39,7 @@ impl From for Cpu { enable: value.enable, system, data_refresh_interval: value.data_refresh_interval.unwrap_or(10), + label_prefix: value.label_prefix.unwrap_or(LabelPrefix::IconAndText), last_updated: Instant::now(), } } @@ -45,6 +49,7 @@ pub struct Cpu { pub enable: bool, system: System, data_refresh_interval: u64, + label_prefix: LabelPrefix, last_updated: Instant, } @@ -57,7 +62,10 @@ impl Cpu { } let used = self.system.global_cpu_usage(); - format!("CPU: {:.0}%", used) + match self.label_prefix { + LabelPrefix::Text | LabelPrefix::IconAndText => format!("CPU: {:.0}%", used), + LabelPrefix::None | LabelPrefix::Icon => format!("{:.0}%", used), + } } } @@ -74,7 +82,12 @@ impl BarWidget for Cpu { .unwrap_or_else(FontId::default); let mut layout_job = LayoutJob::simple( - egui_phosphor::regular::CIRCUITRY.to_string(), + match self.label_prefix { + LabelPrefix::Icon | LabelPrefix::IconAndText => { + egui_phosphor::regular::CIRCUITRY.to_string() + } + LabelPrefix::None | LabelPrefix::Text => String::new(), + }, font_id.clone(), ctx.style().visuals.selection.stroke.color, 100.0, diff --git a/komorebi-bar/src/date.rs b/komorebi-bar/src/date.rs index 1cf449af4..9a2727c39 100644 --- a/komorebi-bar/src/date.rs +++ b/komorebi-bar/src/date.rs @@ -1,3 +1,4 @@ +use crate::config::LabelPrefix; use crate::widget::BarWidget; use crate::WIDGET_SPACING; use eframe::egui::text::LayoutJob; @@ -19,6 +20,8 @@ pub struct DateConfig { pub enable: bool, /// Set the Date format pub format: DateFormat, + /// Display label prefix + pub label_prefix: Option, } impl From for Date { @@ -26,6 +29,7 @@ impl From for Date { Self { enable: value.enable, format: value.format, + label_prefix: value.label_prefix.unwrap_or(LabelPrefix::Icon), } } } @@ -70,6 +74,7 @@ impl DateFormat { pub struct Date { pub enable: bool, pub format: DateFormat, + label_prefix: LabelPrefix, } impl Date { @@ -83,7 +88,7 @@ impl Date { impl BarWidget for Date { fn render(&mut self, ctx: &Context, ui: &mut Ui) { if self.enable { - let output = self.output(); + let mut output = self.output(); if !output.is_empty() { let font_id = ctx .style() @@ -93,12 +98,21 @@ impl BarWidget for Date { .unwrap_or_else(FontId::default); let mut layout_job = LayoutJob::simple( - egui_phosphor::regular::CALENDAR_DOTS.to_string(), + match self.label_prefix { + LabelPrefix::Icon | LabelPrefix::IconAndText => { + egui_phosphor::regular::CALENDAR_DOTS.to_string() + } + LabelPrefix::None | LabelPrefix::Text => String::new(), + }, font_id.clone(), ctx.style().visuals.selection.stroke.color, 100.0, ); + if let LabelPrefix::Text | LabelPrefix::IconAndText = self.label_prefix { + output.insert_str(0, "DATE: "); + } + layout_job.append( &output, 10.0, diff --git a/komorebi-bar/src/memory.rs b/komorebi-bar/src/memory.rs index 308f32110..f5261b804 100644 --- a/komorebi-bar/src/memory.rs +++ b/komorebi-bar/src/memory.rs @@ -1,3 +1,4 @@ +use crate::config::LabelPrefix; use crate::widget::BarWidget; use crate::WIDGET_SPACING; use eframe::egui::text::LayoutJob; @@ -23,6 +24,8 @@ pub struct MemoryConfig { pub enable: bool, /// Data refresh interval (default: 10 seconds) pub data_refresh_interval: Option, + /// Display label prefix + pub label_prefix: Option, } impl From for Memory { @@ -36,6 +39,7 @@ impl From for Memory { enable: value.enable, system, data_refresh_interval: value.data_refresh_interval.unwrap_or(10), + label_prefix: value.label_prefix.unwrap_or(LabelPrefix::IconAndText), last_updated: Instant::now(), } } @@ -45,6 +49,7 @@ pub struct Memory { pub enable: bool, system: System, data_refresh_interval: u64, + label_prefix: LabelPrefix, last_updated: Instant, } @@ -58,7 +63,12 @@ impl Memory { let used = self.system.used_memory(); let total = self.system.total_memory(); - format!("RAM: {}%", (used * 100) / total) + match self.label_prefix { + LabelPrefix::Text | LabelPrefix::IconAndText => { + format!("RAM: {}%", (used * 100) / total) + } + LabelPrefix::None | LabelPrefix::Icon => format!("{}%", (used * 100) / total), + } } } @@ -75,7 +85,12 @@ impl BarWidget for Memory { .unwrap_or_else(FontId::default); let mut layout_job = LayoutJob::simple( - egui_phosphor::regular::MEMORY.to_string(), + match self.label_prefix { + LabelPrefix::Icon | LabelPrefix::IconAndText => { + egui_phosphor::regular::MEMORY.to_string() + } + LabelPrefix::None | LabelPrefix::Text => String::new(), + }, font_id.clone(), ctx.style().visuals.selection.stroke.color, 100.0, diff --git a/komorebi-bar/src/network.rs b/komorebi-bar/src/network.rs index 910b5f7b8..6f41fcb73 100644 --- a/komorebi-bar/src/network.rs +++ b/komorebi-bar/src/network.rs @@ -1,3 +1,4 @@ +use crate::config::LabelPrefix; use crate::widget::BarWidget; use crate::WIDGET_SPACING; use eframe::egui::text::LayoutJob; @@ -30,6 +31,8 @@ pub struct NetworkConfig { pub network_activity_fill_characters: Option, /// Data refresh interval (default: 10 seconds) pub data_refresh_interval: Option, + /// Display label prefix + pub label_prefix: Option, } impl From for Network { @@ -42,6 +45,8 @@ impl From for Network { let mut default_interface = String::new(); + let prefix = value.label_prefix.unwrap_or(LabelPrefix::Icon); + if let Ok(interface) = netdev::get_default_interface() { if let Some(friendly_name) = interface.friendly_name { default_interface.clone_from(&friendly_name); @@ -50,13 +55,32 @@ impl From for Network { networks_total_data_transmitted.refresh(); for (interface_name, data) in &networks_total_data_transmitted { if friendly_name.eq(interface_name) { - last_state_data.push(format!( - "{} {} / {} {}", - egui_phosphor::regular::ARROW_FAT_DOWN, - to_pretty_bytes(data.total_received(), 1), - egui_phosphor::regular::ARROW_FAT_UP, - to_pretty_bytes(data.total_transmitted(), 1), - )) + last_state_data.push(match prefix { + LabelPrefix::None => format!( + "{} | {}", + to_pretty_bytes(data.total_received(), 1), + to_pretty_bytes(data.total_transmitted(), 1), + ), + LabelPrefix::Icon => format!( + "{} {} | {} {}", + egui_phosphor::regular::ARROW_FAT_DOWN, + to_pretty_bytes(data.total_received(), 1), + egui_phosphor::regular::ARROW_FAT_UP, + to_pretty_bytes(data.total_transmitted(), 1), + ), + LabelPrefix::Text => format!( + "\u{2211}DOWN: {} | \u{2211}UP: {}", + to_pretty_bytes(data.total_received(), 1), + to_pretty_bytes(data.total_transmitted(), 1), + ), + LabelPrefix::IconAndText => format!( + "{} \u{2211}DOWN: {} | {} \u{2211}UP: {}", + egui_phosphor::regular::ARROW_FAT_DOWN, + to_pretty_bytes(data.total_received(), 1), + egui_phosphor::regular::ARROW_FAT_UP, + to_pretty_bytes(data.total_transmitted(), 1), + ), + }) } } } @@ -65,14 +89,40 @@ impl From for Network { networks_network_activity.refresh(); for (interface_name, data) in &networks_network_activity { if friendly_name.eq(interface_name) { - last_state_transmitted.push(format!( - "{} {: >width$}/s {} {: >width$}/s", - egui_phosphor::regular::ARROW_FAT_DOWN, - to_pretty_bytes(data.received(), 1), - egui_phosphor::regular::ARROW_FAT_UP, - to_pretty_bytes(data.transmitted(), 1), - width = value.network_activity_fill_characters.unwrap_or_default(), - )) + last_state_transmitted.push(match prefix { + LabelPrefix::None => format!( + "{: >width$}/s | {: >width$}/s", + to_pretty_bytes(data.received(), 1), + to_pretty_bytes(data.transmitted(), 1), + width = + value.network_activity_fill_characters.unwrap_or_default(), + ), + LabelPrefix::Icon => format!( + "{} {: >width$}/s | {} {: >width$}/s", + egui_phosphor::regular::ARROW_FAT_DOWN, + to_pretty_bytes(data.received(), 1), + egui_phosphor::regular::ARROW_FAT_UP, + to_pretty_bytes(data.transmitted(), 1), + width = + value.network_activity_fill_characters.unwrap_or_default(), + ), + LabelPrefix::Text => format!( + "DOWN: {: >width$}/s | UP: {: >width$}/s", + to_pretty_bytes(data.received(), 1), + to_pretty_bytes(data.transmitted(), 1), + width = + value.network_activity_fill_characters.unwrap_or_default(), + ), + LabelPrefix::IconAndText => format!( + "{} DOWN: {: >width$}/s | {} UP: {: >width$}/s", + egui_phosphor::regular::ARROW_FAT_DOWN, + to_pretty_bytes(data.received(), 1), + egui_phosphor::regular::ARROW_FAT_UP, + to_pretty_bytes(data.transmitted(), 1), + width = + value.network_activity_fill_characters.unwrap_or_default(), + ), + }) } } } @@ -85,6 +135,7 @@ impl From for Network { networks_network_activity, default_interface, data_refresh_interval: value.data_refresh_interval.unwrap_or(10), + label_prefix: prefix, show_total_data_transmitted: value.show_total_data_transmitted, show_network_activity: value.show_network_activity, network_activity_fill_characters: value @@ -105,6 +156,7 @@ pub struct Network { networks_total_data_transmitted: Networks, networks_network_activity: Networks, data_refresh_interval: u64, + label_prefix: LabelPrefix, default_interface: String, last_state_total_data_transmitted: Vec, last_state_network_activity: Vec, @@ -138,14 +190,62 @@ impl Network { self.networks_network_activity.refresh(); for (interface_name, data) in &self.networks_network_activity { if friendly_name.eq(interface_name) { - outputs.push(format!( - "{} {: >width$}/s {} {: >width$}/s", - egui_phosphor::regular::ARROW_FAT_DOWN, - to_pretty_bytes(data.received(), self.data_refresh_interval), - egui_phosphor::regular::ARROW_FAT_UP, - to_pretty_bytes(data.transmitted(), self.data_refresh_interval), - width = self.network_activity_fill_characters, - )) + outputs.push(match self.label_prefix { + LabelPrefix::None => format!( + "{: >width$}/s | {: >width$}/s", + to_pretty_bytes( + data.received(), + self.data_refresh_interval + ), + to_pretty_bytes( + data.transmitted(), + self.data_refresh_interval + ), + width = self.network_activity_fill_characters, + ), + LabelPrefix::Icon => format!( + "{} {: >width$}/s | {} {: >width$}/s", + egui_phosphor::regular::ARROW_FAT_DOWN, + to_pretty_bytes( + data.received(), + self.data_refresh_interval + ), + egui_phosphor::regular::ARROW_FAT_UP, + to_pretty_bytes( + data.transmitted(), + self.data_refresh_interval + ), + width = self.network_activity_fill_characters, + ), + LabelPrefix::Text => format!( + "DOWN: {: >width$}/s | UP: {: >width$}/s", + to_pretty_bytes( + data.received(), + self.data_refresh_interval + ), + to_pretty_bytes( + data.transmitted(), + self.data_refresh_interval + ), + width = self.network_activity_fill_characters, + ), + LabelPrefix::IconAndText => { + format!( + "{} DOWN: {: >width$}/s | {} UP: {: >width$}/s", + egui_phosphor::regular::ARROW_FAT_DOWN, + to_pretty_bytes( + data.received(), + self.data_refresh_interval + ), + egui_phosphor::regular::ARROW_FAT_UP, + to_pretty_bytes( + data.transmitted(), + self.data_refresh_interval + ), + width = self.network_activity_fill_characters, + ) + } + }) } } } @@ -176,13 +276,32 @@ impl Network { for (interface_name, data) in &self.networks_total_data_transmitted { if friendly_name.eq(interface_name) { - outputs.push(format!( - "{} {} / {} {}", - egui_phosphor::regular::ARROW_FAT_DOWN, - to_pretty_bytes(data.total_received(), 1), - egui_phosphor::regular::ARROW_FAT_UP, - to_pretty_bytes(data.total_transmitted(), 1), - )) + outputs.push(match self.label_prefix { + LabelPrefix::None => format!( + "{} | {}", + to_pretty_bytes(data.total_received(), 1), + to_pretty_bytes(data.total_transmitted(), 1), + ), + LabelPrefix::Icon => format!( + "{} {} | {} {}", + egui_phosphor::regular::ARROW_FAT_DOWN, + to_pretty_bytes(data.total_received(), 1), + egui_phosphor::regular::ARROW_FAT_UP, + to_pretty_bytes(data.total_transmitted(), 1), + ), + LabelPrefix::Text => format!( + "\u{2211}DOWN: {} | \u{2211}UP: {}", + to_pretty_bytes(data.total_received(), 1), + to_pretty_bytes(data.total_transmitted(), 1), + ), + LabelPrefix::IconAndText => format!( + "{} \u{2211}DOWN: {} | {} \u{2211}UP: {}", + egui_phosphor::regular::ARROW_FAT_DOWN, + to_pretty_bytes(data.total_received(), 1), + egui_phosphor::regular::ARROW_FAT_UP, + to_pretty_bytes(data.total_transmitted(), 1), + ), + }) } } } @@ -227,12 +346,21 @@ impl BarWidget for Network { .unwrap_or_else(FontId::default); let mut layout_job = LayoutJob::simple( - egui_phosphor::regular::WIFI_HIGH.to_string(), + match self.label_prefix { + LabelPrefix::Icon | LabelPrefix::IconAndText => { + egui_phosphor::regular::WIFI_HIGH.to_string() + } + LabelPrefix::None | LabelPrefix::Text => String::new(), + }, font_id.clone(), ctx.style().visuals.selection.stroke.color, 100.0, ); + if let LabelPrefix::Text | LabelPrefix::IconAndText = self.label_prefix { + self.default_interface.insert_str(0, "NET: "); + } + layout_job.append( &self.default_interface, 10.0, diff --git a/komorebi-bar/src/storage.rs b/komorebi-bar/src/storage.rs index f2d9e1e1e..c81f66da8 100644 --- a/komorebi-bar/src/storage.rs +++ b/komorebi-bar/src/storage.rs @@ -1,3 +1,4 @@ +use crate::config::LabelPrefix; use crate::widget::BarWidget; use crate::WIDGET_SPACING; use eframe::egui::text::LayoutJob; @@ -22,6 +23,8 @@ pub struct StorageConfig { pub enable: bool, /// Data refresh interval (default: 10 seconds) pub data_refresh_interval: Option, + /// Display label prefix + pub label_prefix: Option, } impl From for Storage { @@ -30,6 +33,7 @@ impl From for Storage { enable: value.enable, disks: Disks::new_with_refreshed_list(), data_refresh_interval: value.data_refresh_interval.unwrap_or(10), + label_prefix: value.label_prefix.unwrap_or(LabelPrefix::IconAndText), last_updated: Instant::now(), } } @@ -39,6 +43,7 @@ pub struct Storage { pub enable: bool, disks: Disks, data_refresh_interval: u64, + label_prefix: LabelPrefix, last_updated: Instant, } @@ -57,12 +62,13 @@ impl Storage { let total = disk.total_space(); let available = disk.available_space(); let used = total - available; - - disks.push(format!( - "{} {}%", - mount.to_string_lossy(), - (used * 100) / total - )) + + disks.push(match self.label_prefix { + LabelPrefix::Text | LabelPrefix::IconAndText => { + format!("{} {}%", mount.to_string_lossy(), (used * 100) / total) + } + LabelPrefix::None | LabelPrefix::Icon => format!("{}%", (used * 100) / total), + }) } disks.sort(); @@ -84,7 +90,12 @@ impl BarWidget for Storage { for output in self.output() { let mut layout_job = LayoutJob::simple( - egui_phosphor::regular::HARD_DRIVES.to_string(), + match self.label_prefix { + LabelPrefix::Icon | LabelPrefix::IconAndText => { + egui_phosphor::regular::HARD_DRIVES.to_string() + } + LabelPrefix::None | LabelPrefix::Text => String::new(), + }, font_id.clone(), ctx.style().visuals.selection.stroke.color, 100.0, diff --git a/komorebi-bar/src/time.rs b/komorebi-bar/src/time.rs index 85b5db8b5..37f4160e1 100644 --- a/komorebi-bar/src/time.rs +++ b/komorebi-bar/src/time.rs @@ -1,3 +1,4 @@ +use crate::config::LabelPrefix; use crate::widget::BarWidget; use crate::WIDGET_SPACING; use eframe::egui::text::LayoutJob; @@ -18,6 +19,8 @@ pub struct TimeConfig { pub enable: bool, /// Set the Time format pub format: TimeFormat, + /// Display label prefix + pub label_prefix: Option, } impl From for Time { @@ -25,6 +28,7 @@ impl From for Time { Self { enable: value.enable, format: value.format, + label_prefix: value.label_prefix.unwrap_or(LabelPrefix::Icon), } } } @@ -61,6 +65,7 @@ impl TimeFormat { pub struct Time { pub enable: bool, pub format: TimeFormat, + label_prefix: LabelPrefix, } impl Time { @@ -74,7 +79,7 @@ impl Time { impl BarWidget for Time { fn render(&mut self, ctx: &Context, ui: &mut Ui) { if self.enable { - let output = self.output(); + let mut output = self.output(); if !output.is_empty() { let font_id = ctx .style() @@ -84,12 +89,21 @@ impl BarWidget for Time { .unwrap_or_else(FontId::default); let mut layout_job = LayoutJob::simple( - egui_phosphor::regular::CLOCK.to_string(), + match self.label_prefix { + LabelPrefix::Icon | LabelPrefix::IconAndText => { + egui_phosphor::regular::CLOCK.to_string() + } + LabelPrefix::None | LabelPrefix::Text => String::new(), + }, font_id.clone(), ctx.style().visuals.selection.stroke.color, 100.0, ); + if let LabelPrefix::Text | LabelPrefix::IconAndText = self.label_prefix { + output.insert_str(0, "TIME: "); + } + layout_job.append( &output, 10.0,