From 36c267246bc7c5c2e5526c259bf460c1ad3e97e8 Mon Sep 17 00:00:00 2001 From: Csaba Date: Thu, 14 Nov 2024 23:17:39 +0100 Subject: [PATCH] correct spacing on komorebi and network widgets (WIP) --- komorebi-bar/src/battery.rs | 2 +- komorebi-bar/src/cpu.rs | 2 +- komorebi-bar/src/date.rs | 2 +- komorebi-bar/src/komorebi.rs | 312 +++++++++++++++++------------------ komorebi-bar/src/media.rs | 2 +- komorebi-bar/src/memory.rs | 2 +- komorebi-bar/src/network.rs | 122 ++++++++------ komorebi-bar/src/render.rs | 23 +-- komorebi-bar/src/storage.rs | 3 +- komorebi-bar/src/time.rs | 2 +- 10 files changed, 242 insertions(+), 230 deletions(-) diff --git a/komorebi-bar/src/battery.rs b/komorebi-bar/src/battery.rs index 9df24727..4f72513c 100644 --- a/komorebi-bar/src/battery.rs +++ b/komorebi-bar/src/battery.rs @@ -147,7 +147,7 @@ impl BarWidget for Battery { TextFormat::simple(font_id, ctx.style().visuals.text_color()), ); - config.apply_on_widget(true, ui, |ui| { + config.apply_on_widget(true, true, ui, |ui| { ui.add( Label::new(layout_job) .selectable(false) diff --git a/komorebi-bar/src/cpu.rs b/komorebi-bar/src/cpu.rs index 626cfda3..04747d8c 100644 --- a/komorebi-bar/src/cpu.rs +++ b/komorebi-bar/src/cpu.rs @@ -99,7 +99,7 @@ impl BarWidget for Cpu { TextFormat::simple(font_id, ctx.style().visuals.text_color()), ); - config.apply_on_widget(true, ui, |ui| { + config.apply_on_widget(true, true, ui, |ui| { if ui .add( Label::new(layout_job) diff --git a/komorebi-bar/src/date.rs b/komorebi-bar/src/date.rs index f228c6e5..689d3f95 100644 --- a/komorebi-bar/src/date.rs +++ b/komorebi-bar/src/date.rs @@ -119,7 +119,7 @@ impl BarWidget for Date { TextFormat::simple(font_id, ctx.style().visuals.text_color()), ); - config.apply_on_widget(true, ui, |ui| { + config.apply_on_widget(true, true, ui, |ui| { if ui .add( Label::new(WidgetText::LayoutJob(layout_job.clone())) diff --git a/komorebi-bar/src/komorebi.rs b/komorebi-bar/src/komorebi.rs index 746376e2..34b5324b 100644 --- a/komorebi-bar/src/komorebi.rs +++ b/komorebi-bar/src/komorebi.rs @@ -124,12 +124,30 @@ pub struct Komorebi { impl BarWidget for Komorebi { fn render(&mut self, ctx: &Context, ui: &mut Ui, mut config: RenderConfig) { let mut komorebi_notification_state = self.komorebi_notification_state.borrow_mut(); + let mut enable_widget: [bool; 4] = [self.workspaces.enable, false, false, false]; - if self.workspaces.enable { + if let Some(layout) = self.layout { + enable_widget[1] = layout.enable; + } + + if let Some(configuration_switcher) = &self.configuration_switcher { + enable_widget[2] = configuration_switcher.enable; + } + + if let Some(focused_window) = self.focused_window { + if focused_window.enable { + let titles = &komorebi_notification_state.focused_container_information.0; + enable_widget[3] = !titles.is_empty(); + } + } + + let last_enabled_widget_index = enable_widget.iter().rposition(|&x| x); + + if enable_widget[0] { let mut update = None; // NOTE: There should always be at least one workspace. - config.apply_on_widget(false, ui, |ui| { + config.apply_on_widget(false, last_enabled_widget_index == Some(0), ui, |ui| { for (i, (ws, should_show)) in komorebi_notification_state.workspaces.iter().enumerate() { @@ -194,60 +212,49 @@ impl BarWidget for Komorebi { } } - if let Some(layout) = self.layout { - if layout.enable { - config.apply_on_widget(true, ui, |ui| { - if ui - .add( - Label::new(komorebi_notification_state.layout.to_string()) - .selectable(false) - .sense(Sense::click()), - ) - .clicked() - { - match komorebi_notification_state.layout { - KomorebiLayout::Default(_) => { - if komorebi_client::send_message(&SocketMessage::CycleLayout( - CycleDirection::Next, - )) - .is_err() - { - tracing::error!( - "could not send message to komorebi: CycleLayout" - ); - } + if enable_widget[1] { + config.apply_on_widget(true, last_enabled_widget_index == Some(1), ui, |ui| { + if ui + .add( + Label::new(komorebi_notification_state.layout.to_string()) + .selectable(false) + .sense(Sense::click()), + ) + .clicked() + { + match komorebi_notification_state.layout { + KomorebiLayout::Default(_) => { + if komorebi_client::send_message(&SocketMessage::CycleLayout( + CycleDirection::Next, + )) + .is_err() + { + tracing::error!("could not send message to komorebi: CycleLayout"); } - KomorebiLayout::Floating => { - if komorebi_client::send_message(&SocketMessage::ToggleTiling) - .is_err() - { - tracing::error!( - "could not send message to komorebi: ToggleTiling" - ); - } - } - KomorebiLayout::Paused => { - if komorebi_client::send_message(&SocketMessage::TogglePause) - .is_err() - { - tracing::error!( - "could not send message to komorebi: TogglePause" - ); - } - } - KomorebiLayout::Custom => {} } + KomorebiLayout::Floating => { + if komorebi_client::send_message(&SocketMessage::ToggleTiling).is_err() + { + tracing::error!("could not send message to komorebi: ToggleTiling"); + } + } + KomorebiLayout::Paused => { + if komorebi_client::send_message(&SocketMessage::TogglePause).is_err() { + tracing::error!("could not send message to komorebi: TogglePause"); + } + } + KomorebiLayout::Custom => {} } - }); - } + } + }); } - if let Some(configuration_switcher) = &self.configuration_switcher { - if configuration_switcher.enable { - for (name, location) in configuration_switcher.configurations.iter() { - let path = PathBuf::from(location); - if path.is_file() { - config.apply_on_widget(true, ui,|ui|{ + if enable_widget[2] { + let configuration_switcher = self.configuration_switcher.as_ref().unwrap(); + for (name, location) in configuration_switcher.configurations.iter() { + let path = PathBuf::from(location); + if path.is_file() { + config.apply_on_widget(true, last_enabled_widget_index == Some(2), ui,|ui|{ if ui .add(Label::new(name).selectable(false).sense(Sense::click())) .clicked() @@ -295,126 +302,117 @@ impl BarWidget for Komorebi { } } }}); - } } } } - if let Some(focused_window) = self.focused_window { - if focused_window.enable { - let titles = &komorebi_notification_state.focused_container_information.0; + if enable_widget[3] { + let focused_window = self.focused_window.unwrap(); + let titles = &komorebi_notification_state.focused_container_information.0; + config.apply_on_widget(true, last_enabled_widget_index == Some(4), ui, |ui| { + let icons = &komorebi_notification_state.focused_container_information.1; + let focused_window_idx = + komorebi_notification_state.focused_container_information.2; - if !titles.is_empty() { - config.apply_on_widget(true, ui, |ui| { - let icons = &komorebi_notification_state.focused_container_information.1; - let focused_window_idx = - komorebi_notification_state.focused_container_information.2; + let iter = titles.iter().zip(icons.iter()); - let iter = titles.iter().zip(icons.iter()); + for (i, (title, icon)) in iter.enumerate() { + if focused_window.show_icon { + if let Some(img) = icon { + ui.add( + Image::from(&img_to_texture(ctx, img)) + .maintain_aspect_ratio(true) + .max_height(15.0), + ); + } + } - for (i, (title, icon)) in iter.enumerate() { - if focused_window.show_icon { - if let Some(img) = icon { - ui.add( - Image::from(&img_to_texture(ctx, img)) - .maintain_aspect_ratio(true) - .max_height(15.0), - ); - } + if i == focused_window_idx { + let font_id = ctx + .style() + .text_styles + .get(&TextStyle::Body) + .cloned() + .unwrap_or_else(FontId::default); + + let layout_job = LayoutJob::simple( + title.to_string(), + font_id.clone(), + komorebi_notification_state + .stack_accent + .unwrap_or(ctx.style().visuals.selection.stroke.color), + 100.0, + ); + + if titles.len() > 1 { + let available_height = ui.available_height(); + let mut custom_ui = CustomUi(ui); + custom_ui.add_sized_left_to_right( + Vec2::new( + MAX_LABEL_WIDTH.load(Ordering::SeqCst) as f32, + available_height, + ), + Label::new(layout_job).selectable(false).truncate(), + ); + } else { + let available_height = ui.available_height(); + let mut custom_ui = CustomUi(ui); + custom_ui.add_sized_left_to_right( + Vec2::new( + MAX_LABEL_WIDTH.load(Ordering::SeqCst) as f32, + available_height, + ), + Label::new(title).selectable(false).truncate(), + ); + } + } else { + let available_height = ui.available_height(); + let mut custom_ui = CustomUi(ui); + + if custom_ui + .add_sized_left_to_right( + Vec2::new( + MAX_LABEL_WIDTH.load(Ordering::SeqCst) as f32, + available_height, + ), + Label::new(title) + .selectable(false) + .sense(Sense::click()) + .truncate(), + ) + .clicked() + { + if komorebi_client::send_message(&SocketMessage::MouseFollowsFocus( + false, + )) + .is_err() + { + tracing::error!( + "could not send message to komorebi: MouseFollowsFocus" + ); } - if i == focused_window_idx { - let font_id = ctx - .style() - .text_styles - .get(&TextStyle::Body) - .cloned() - .unwrap_or_else(FontId::default); - - let layout_job = LayoutJob::simple( - title.to_string(), - font_id.clone(), - komorebi_notification_state - .stack_accent - .unwrap_or(ctx.style().visuals.selection.stroke.color), - 100.0, + if komorebi_client::send_message(&SocketMessage::FocusStackWindow(i)) + .is_err() + { + tracing::error!( + "could not send message to komorebi: FocusStackWindow" ); + } - if titles.len() > 1 { - let available_height = ui.available_height(); - let mut custom_ui = CustomUi(ui); - custom_ui.add_sized_left_to_right( - Vec2::new( - MAX_LABEL_WIDTH.load(Ordering::SeqCst) as f32, - available_height, - ), - Label::new(layout_job).selectable(false).truncate(), - ); - } else { - let available_height = ui.available_height(); - let mut custom_ui = CustomUi(ui); - custom_ui.add_sized_left_to_right( - Vec2::new( - MAX_LABEL_WIDTH.load(Ordering::SeqCst) as f32, - available_height, - ), - Label::new(title).selectable(false).truncate(), - ); - } - } else { - let available_height = ui.available_height(); - let mut custom_ui = CustomUi(ui); - - if custom_ui - .add_sized_left_to_right( - Vec2::new( - MAX_LABEL_WIDTH.load(Ordering::SeqCst) as f32, - available_height, - ), - Label::new(title) - .selectable(false) - .sense(Sense::click()) - .truncate(), - ) - .clicked() - { - if komorebi_client::send_message( - &SocketMessage::MouseFollowsFocus(false), - ) - .is_err() - { - tracing::error!( - "could not send message to komorebi: MouseFollowsFocus" - ); - } - - if komorebi_client::send_message( - &SocketMessage::FocusStackWindow(i), - ) - .is_err() - { - tracing::error!( - "could not send message to komorebi: FocusStackWindow" - ); - } - - if komorebi_client::send_message( - &SocketMessage::MouseFollowsFocus( - komorebi_notification_state.mouse_follows_focus, - ), - ) - .is_err() - { - tracing::error!( - "could not send message to komorebi: MouseFollowsFocus" - ); - } - } + if komorebi_client::send_message(&SocketMessage::MouseFollowsFocus( + komorebi_notification_state.mouse_follows_focus, + )) + .is_err() + { + tracing::error!( + "could not send message to komorebi: MouseFollowsFocus" + ); } } - }); + } } - } + }); } } } diff --git a/komorebi-bar/src/media.rs b/komorebi-bar/src/media.rs index 14c1713f..1895db20 100644 --- a/komorebi-bar/src/media.rs +++ b/komorebi-bar/src/media.rs @@ -102,7 +102,7 @@ impl BarWidget for Media { TextFormat::simple(font_id, ctx.style().visuals.text_color()), ); - config.apply_on_widget(true, ui, |ui| { + config.apply_on_widget(true, true, ui, |ui| { let available_height = ui.available_height(); let mut custom_ui = CustomUi(ui); diff --git a/komorebi-bar/src/memory.rs b/komorebi-bar/src/memory.rs index 13561214..ac424302 100644 --- a/komorebi-bar/src/memory.rs +++ b/komorebi-bar/src/memory.rs @@ -102,7 +102,7 @@ impl BarWidget for Memory { TextFormat::simple(font_id, ctx.style().visuals.text_color()), ); - config.apply_on_widget(true, ui, |ui| { + config.apply_on_widget(true, true, ui, |ui| { if ui .add( Label::new(layout_job) diff --git a/komorebi-bar/src/network.rs b/komorebi-bar/src/network.rs index 3ef10dc6..991ab2eb 100644 --- a/komorebi-bar/src/network.rs +++ b/komorebi-bar/src/network.rs @@ -318,71 +318,83 @@ impl Network { impl BarWidget for Network { fn render(&mut self, ctx: &Context, ui: &mut Ui, mut config: RenderConfig) { - if self.show_total_data_transmitted { - for output in self.total_data_transmitted() { - config.apply_on_widget(true, ui, |ui| { - ui.add(Label::new(output).selectable(false)); - }); - } - } - - if self.show_network_activity { - for output in self.network_activity() { - config.apply_on_widget(true, ui, |ui| { - ui.add(Label::new(output).selectable(false)); - }); - } - } + let mut enable_widget: [bool; 3] = [ + self.show_total_data_transmitted, + self.show_network_activity, + false, + ]; if self.enable { self.default_interface(); if !self.default_interface.is_empty() { - let font_id = ctx - .style() - .text_styles - .get(&TextStyle::Body) - .cloned() - .unwrap_or_else(FontId::default); + enable_widget[2] = true; + } + } - let mut layout_job = LayoutJob::simple( - 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, - ); + let last_enabled_widget_index = enable_widget.iter().rposition(|&x| x); - if let LabelPrefix::Text | LabelPrefix::IconAndText = self.label_prefix { - self.default_interface.insert_str(0, "NET: "); - } - - layout_job.append( - &self.default_interface, - 10.0, - TextFormat::simple(font_id, ctx.style().visuals.text_color()), - ); - - config.apply_on_widget(true, ui, |ui| { - if ui - .add( - Label::new(layout_job) - .selectable(false) - .sense(Sense::click()), - ) - .clicked() - { - if let Err(error) = Command::new("cmd.exe").args(["/C", "ncpa"]).spawn() { - eprintln!("{}", error) - } - } + if enable_widget[0] { + for output in self.total_data_transmitted() { + config.apply_on_widget(true, last_enabled_widget_index == Some(0), ui, |ui| { + ui.add(Label::new(output).selectable(false)); }); } } + + if enable_widget[1] { + for output in self.network_activity() { + config.apply_on_widget(true, last_enabled_widget_index == Some(1), ui, |ui| { + ui.add(Label::new(output).selectable(false)); + }); + } + } + + if enable_widget[2] { + let font_id = ctx + .style() + .text_styles + .get(&TextStyle::Body) + .cloned() + .unwrap_or_else(FontId::default); + + let mut layout_job = LayoutJob::simple( + 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, + TextFormat::simple(font_id, ctx.style().visuals.text_color()), + ); + + config.apply_on_widget(true, last_enabled_widget_index == Some(2), ui, |ui| { + if ui + .add( + Label::new(layout_job) + .selectable(false) + .sense(Sense::click()), + ) + .clicked() + { + if let Err(error) = Command::new("cmd.exe").args(["/C", "ncpa"]).spawn() { + eprintln!("{}", error) + } + } + }); + } } } diff --git a/komorebi-bar/src/render.rs b/komorebi-bar/src/render.rs index d6efcbcb..c2608351 100644 --- a/komorebi-bar/src/render.rs +++ b/komorebi-bar/src/render.rs @@ -86,19 +86,20 @@ impl RenderConfig { pub fn apply_on_widget( &mut self, - use_spacing: bool, - // TODO: this should remove the margin on the last widget on the left side and the first widget on the right side - // This is complex, since the last/first widget can have multiple "sections", like komorebi, network, ... - // This and the same setting on RenderConfig needs to be combined. - //no_spacing: Option, + more_inner_margin: bool, + is_last_widget: bool, ui: &mut Ui, add_contents: impl FnOnce(&mut Ui) -> R, ) -> InnerResponse { + // since a widget can call this multiple times, it is necessary to know the last time + // in order to add widget spacing correctly + self.no_spacing = self.no_spacing && is_last_widget; + if let Grouping::Widget(config) = self.grouping { - return self.define_group(use_spacing, config, ui, add_contents); + return self.define_group(more_inner_margin, config, ui, add_contents); } - self.fallback_widget_group(use_spacing, ui, add_contents) + self.fallback_widget_group(more_inner_margin, ui, add_contents) } fn fallback_group(ui: &mut Ui, add_contents: impl FnOnce(&mut Ui) -> R) -> InnerResponse { @@ -110,13 +111,13 @@ impl RenderConfig { fn fallback_widget_group( &mut self, - use_spacing: bool, + more_inner_margin: bool, ui: &mut Ui, add_contents: impl FnOnce(&mut Ui) -> R, ) -> InnerResponse { Frame::none() .outer_margin(self.widget_outer_margin()) - .inner_margin(match use_spacing { + .inner_margin(match more_inner_margin { true => Margin::symmetric(5.0, 0.0), false => Margin::same(0.0), }) @@ -125,14 +126,14 @@ impl RenderConfig { fn define_group( &mut self, - use_spacing: bool, + more_inner_margin: bool, config: GroupingConfig, ui: &mut Ui, add_contents: impl FnOnce(&mut Ui) -> R, ) -> InnerResponse { Frame::none() .outer_margin(self.widget_outer_margin()) - .inner_margin(match use_spacing { + .inner_margin(match more_inner_margin { true => Margin::symmetric(8.0, 3.0), false => Margin::symmetric(3.0, 3.0), }) diff --git a/komorebi-bar/src/storage.rs b/komorebi-bar/src/storage.rs index e52c8b0d..045f8832 100644 --- a/komorebi-bar/src/storage.rs +++ b/komorebi-bar/src/storage.rs @@ -107,7 +107,8 @@ impl BarWidget for Storage { TextFormat::simple(font_id.clone(), ctx.style().visuals.text_color()), ); - config.apply_on_widget(true, ui, |ui| { + // TODO: WIP + config.apply_on_widget(true, false, ui, |ui| { if ui .add( Label::new(layout_job) diff --git a/komorebi-bar/src/time.rs b/komorebi-bar/src/time.rs index 897b3252..e5b53128 100644 --- a/komorebi-bar/src/time.rs +++ b/komorebi-bar/src/time.rs @@ -110,7 +110,7 @@ impl BarWidget for Time { TextFormat::simple(font_id, ctx.style().visuals.text_color()), ); - config.apply_on_widget(true, ui, |ui| { + config.apply_on_widget(true, true, ui, |ui| { if ui .add( Label::new(layout_job)