From 0dc6780da655df7172bfcbc53f23719bd58a3490 Mon Sep 17 00:00:00 2001 From: alex-ds13 <145657253+alex-ds13@users.noreply.github.com> Date: Wed, 18 Dec 2024 11:24:49 +0000 Subject: [PATCH] fix(bar): normalize areas of widgets This commit changes the way each of the 3 parts of potential widgets (left, center and right) is created so that they are all done on the same way and look the same. It is using `Area` with different anchors for each part which makes the widgets actually center vertically properly. This created an issue with the `Bar` grouping. To fix it we've made the `Bar` grouping change the outer panel frame instead of creating an actual group. This has the side effect (or maybe feature!) of losing the background of the outer frame. Meaning this outer frame will now have the look of the `Bar` grouping only. Currently it is using a fixed outer margin but this can be changed in the future to a config option. --- komorebi-bar/src/bar.rs | 114 +++++++++++++++++++++---------------- komorebi-bar/src/render.rs | 49 ++++++++++------ 2 files changed, 98 insertions(+), 65 deletions(-) diff --git a/komorebi-bar/src/bar.rs b/komorebi-bar/src/bar.rs index e1f14f2b..a248191d 100644 --- a/komorebi-bar/src/bar.rs +++ b/komorebi-bar/src/bar.rs @@ -17,7 +17,6 @@ use crate::MONITOR_LEFT; use crate::MONITOR_RIGHT; use crate::MONITOR_TOP; use crossbeam_channel::Receiver; -use eframe::egui::Align; use eframe::egui::Align2; use eframe::egui::Area; use eframe::egui::CentralPanel; @@ -29,7 +28,6 @@ use eframe::egui::FontFamily; use eframe::egui::FontId; use eframe::egui::Frame; use eframe::egui::Id; -use eframe::egui::Layout; use eframe::egui::Margin; use eframe::egui::Rgba; use eframe::egui::Style; @@ -356,8 +354,6 @@ impl Komobar { }); } - right_widgets.reverse(); - self.left_widgets = left_widgets; self.center_widgets = center_widgets; self.right_widgets = right_widgets; @@ -494,55 +490,75 @@ impl eframe::App for Komobar { let mut render_config = self.render_config.borrow_mut(); - CentralPanel::default().frame(frame).show(ctx, |ui| { + let frame = render_config.change_frame_on_bar(frame, &ctx.style()); + + CentralPanel::default().frame(frame).show(ctx, |_| { // Apply grouping logic for the bar as a whole - render_config.clone().apply_on_bar(ui, |ui| { - ui.horizontal_centered(|ui| { - // Left-aligned widgets layout - ui.with_layout(Layout::left_to_right(Align::Center), |ui| { - let mut render_conf = render_config.clone(); - render_conf.alignment = Some(Alignment::Left); + if !self.left_widgets.is_empty() { + // Left-aligned widgets layout + Area::new(Id::new("left_panel")) + .anchor( + Align2::LEFT_CENTER, + [self.config.widget_spacing.unwrap_or(10.0), 0.0], + ) // Align in the left center of the window + .show(ctx, |ui| { + Frame::none().show(ui, |ui| { + ui.horizontal_centered(|ui| { + let mut render_conf = render_config.clone(); + render_conf.alignment = Some(Alignment::Left); - render_config.apply_on_alignment(ui, |ui| { - for w in &mut self.left_widgets { - w.render(ctx, ui, &mut render_conf); - } - }); - }); - - // Right-aligned widgets layout - ui.with_layout(Layout::right_to_left(Align::Center), |ui| { - let mut render_conf = render_config.clone(); - render_conf.alignment = Some(Alignment::Right); - - render_config.apply_on_alignment(ui, |ui| { - for w in &mut self.right_widgets { - w.render(ctx, ui, &mut render_conf); - } - }); - }); - - if !self.center_widgets.is_empty() { - // Floating center widgets - Area::new(Id::new("center_panel")) - .anchor(Align2::CENTER_CENTER, [0.0, 0.0]) // Align in the center of the window - .show(ctx, |ui| { - Frame::none().show(ui, |ui| { - ui.horizontal_centered(|ui| { - let mut render_conf = render_config.clone(); - render_conf.alignment = Some(Alignment::Center); - - render_config.apply_on_alignment(ui, |ui| { - for w in &mut self.center_widgets { - w.render(ctx, ui, &mut render_conf); - } - }); - }); + render_config.apply_on_alignment(ui, |ui| { + for w in &mut self.left_widgets { + w.render(ctx, ui, &mut render_conf); + } }); }); - } - }) - }) + }); + }); + } + + if !self.right_widgets.is_empty() { + // Right-aligned widgets layout + Area::new(Id::new("right_panel")) + .anchor( + Align2::RIGHT_CENTER, + [-self.config.widget_spacing.unwrap_or(10.0), 0.0], + ) // Align in the right center of the window + .show(ctx, |ui| { + Frame::none().show(ui, |ui| { + ui.horizontal_centered(|ui| { + let mut render_conf = render_config.clone(); + render_conf.alignment = Some(Alignment::Right); + + render_config.apply_on_alignment(ui, |ui| { + for w in &mut self.right_widgets { + w.render(ctx, ui, &mut render_conf); + } + }); + }); + }); + }); + } + + if !self.center_widgets.is_empty() { + // Floating center widgets + Area::new(Id::new("center_panel")) + .anchor(Align2::CENTER_CENTER, [0.0, 0.0]) // Align in the center of the window + .show(ctx, |ui| { + Frame::none().show(ui, |ui| { + ui.horizontal_centered(|ui| { + let mut render_conf = render_config.clone(); + render_conf.alignment = Some(Alignment::Center); + + render_config.apply_on_alignment(ui, |ui| { + for w in &mut self.center_widgets { + w.render(ctx, ui, &mut render_conf); + } + }); + }); + }); + }); + } }); } } diff --git a/komorebi-bar/src/render.rs b/komorebi-bar/src/render.rs index bc12705f..64ef91af 100644 --- a/komorebi-bar/src/render.rs +++ b/komorebi-bar/src/render.rs @@ -16,6 +16,7 @@ use serde::Deserialize; use serde::Serialize; use std::sync::atomic::AtomicUsize; use std::sync::atomic::Ordering; +use std::sync::Arc; static SHOW_KOMOREBI_LAYOUT_OPTIONS: AtomicUsize = AtomicUsize::new(0); @@ -107,18 +108,28 @@ impl RenderConfig { } } - pub fn apply_on_bar( + pub fn change_frame_on_bar( &mut self, - ui: &mut Ui, - add_contents: impl FnOnce(&mut Ui) -> R, - ) -> InnerResponse { + frame: Frame, + ui_style: &Arc, + ) -> Frame { self.alignment = None; if let Grouping::Bar(config) = self.grouping { - return self.define_group(None, config, ui, add_contents); + return self.define_group_frame( + //TODO: this outer margin can be a config + Some(Margin { + left: 10.0, + right: 10.0, + top: 6.0, + bottom: 6.0, + }), + config, + ui_style, + ); } - Self::fallback_group(ui, add_contents) + frame } pub fn apply_on_alignment( @@ -180,16 +191,26 @@ impl RenderConfig { ui: &mut Ui, add_contents: impl FnOnce(&mut Ui) -> R, ) -> InnerResponse { - Frame::group(ui.style_mut()) + self.define_group_frame(outer_margin, config, ui.style()) + .show(ui, add_contents) + } + + pub fn define_group_frame( + &mut self, + outer_margin: Option, + config: GroupingConfig, + ui_style: &Arc, + ) -> Frame { + Frame::group(ui_style) .outer_margin(outer_margin.unwrap_or(Margin::ZERO)) .inner_margin(match self.more_inner_margin { true => Margin::symmetric(6.0, 1.0), false => Margin::symmetric(1.0, 1.0), }) - .stroke(ui.style().visuals.widgets.noninteractive.bg_stroke) + .stroke(ui_style.visuals.widgets.noninteractive.bg_stroke) .rounding(match config.rounding { Some(rounding) => rounding.into(), - None => ui.style().visuals.widgets.noninteractive.rounding, + None => ui_style.visuals.widgets.noninteractive.rounding, }) .fill( self.background_color @@ -221,8 +242,7 @@ impl RenderConfig { blur: 3.0, offset: Vec2::new(1.0, 1.0), spread: 2.0, - color: ui - .style() + color: ui_style .visuals .selection .stroke @@ -233,8 +253,7 @@ impl RenderConfig { blur: 3.0, offset: Vec2::new(0.0, 0.0), spread: 2.0, - color: ui - .style() + color: ui_style .visuals .selection .stroke @@ -245,8 +264,7 @@ impl RenderConfig { blur: 0.0, offset: Vec2::new(1.0, 1.0), spread: 2.0, - color: ui - .style() + color: ui_style .visuals .selection .stroke @@ -256,7 +274,6 @@ impl RenderConfig { }, None => Shadow::NONE, }) - .show(ui, add_contents) } fn widget_outer_margin(&mut self, ui: &mut Ui) -> Margin {