mirror of
https://github.com/LGUG2Z/komorebi.git
synced 2026-04-25 10:08:33 +02:00
widget rounding based on grouping, atomic background color, simplified config, style on grouping
This commit is contained in:
@@ -1,3 +1,4 @@
|
|||||||
|
use crate::config::Color32Ext;
|
||||||
use crate::config::KomobarConfig;
|
use crate::config::KomobarConfig;
|
||||||
use crate::config::KomobarTheme;
|
use crate::config::KomobarTheme;
|
||||||
use crate::config::Position;
|
use crate::config::Position;
|
||||||
@@ -9,6 +10,7 @@ use crate::process_hwnd;
|
|||||||
use crate::widget::BarWidget;
|
use crate::widget::BarWidget;
|
||||||
use crate::widget::RenderConfig;
|
use crate::widget::RenderConfig;
|
||||||
use crate::widget::WidgetConfig;
|
use crate::widget::WidgetConfig;
|
||||||
|
use crate::BACKGROUND_COLOR;
|
||||||
use crate::BAR_HEIGHT;
|
use crate::BAR_HEIGHT;
|
||||||
use crate::MAX_LABEL_WIDTH;
|
use crate::MAX_LABEL_WIDTH;
|
||||||
use crate::MONITOR_LEFT;
|
use crate::MONITOR_LEFT;
|
||||||
@@ -194,8 +196,6 @@ impl Komobar {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.render_config.replace(config.into());
|
|
||||||
|
|
||||||
match config.theme {
|
match config.theme {
|
||||||
Some(theme) => {
|
Some(theme) => {
|
||||||
apply_theme(ctx, theme, self.bg_color.clone());
|
apply_theme(ctx, theme, self.bg_color.clone());
|
||||||
@@ -244,13 +244,30 @@ impl Komobar {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(background) = self.config.background {
|
// apply rounding to the widgets
|
||||||
let theme_color = *self.bg_color.borrow();
|
if let Some(Grouping::Bar(config) | Grouping::Side(config) | Grouping::Widget(config)) =
|
||||||
|
&config.grouping
|
||||||
self.bg_color
|
{
|
||||||
.replace(background.to_color32_or(Some(theme_color)));
|
if let Some(rounding) = config.rounding {
|
||||||
|
ctx.style_mut(|style| {
|
||||||
|
style.visuals.widgets.noninteractive.rounding = rounding.into();
|
||||||
|
style.visuals.widgets.inactive.rounding = rounding.into();
|
||||||
|
style.visuals.widgets.hovered.rounding = rounding.into();
|
||||||
|
style.visuals.widgets.active.rounding = rounding.into();
|
||||||
|
style.visuals.widgets.open.rounding = rounding.into();
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self.render_config.replace(config.into());
|
||||||
|
|
||||||
|
let theme_color = *self.bg_color.borrow();
|
||||||
|
|
||||||
|
BACKGROUND_COLOR.store(theme_color.to_u32(), Ordering::SeqCst);
|
||||||
|
|
||||||
|
self.bg_color
|
||||||
|
.replace(theme_color.try_apply_alpha(self.config.transparency_alpha));
|
||||||
|
|
||||||
if let Some(font_size) = &config.font_size {
|
if let Some(font_size) = &config.font_size {
|
||||||
tracing::info!("attempting to set custom font size: {font_size}");
|
tracing::info!("attempting to set custom font size: {font_size}");
|
||||||
Self::set_font_size(ctx, *font_size);
|
Self::set_font_size(ctx, *font_size);
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ use eframe::egui::Color32;
|
|||||||
use eframe::egui::Pos2;
|
use eframe::egui::Pos2;
|
||||||
use eframe::egui::TextBuffer;
|
use eframe::egui::TextBuffer;
|
||||||
use eframe::egui::Vec2;
|
use eframe::egui::Vec2;
|
||||||
use komorebi_client::Colour;
|
|
||||||
use komorebi_client::KomorebiTheme;
|
use komorebi_client::KomorebiTheme;
|
||||||
use komorebi_client::Rect;
|
use komorebi_client::Rect;
|
||||||
use schemars::JsonSchema;
|
use schemars::JsonSchema;
|
||||||
@@ -32,8 +31,8 @@ pub struct KomobarConfig {
|
|||||||
pub max_label_width: Option<f32>,
|
pub max_label_width: Option<f32>,
|
||||||
/// Theme
|
/// Theme
|
||||||
pub theme: Option<KomobarTheme>,
|
pub theme: Option<KomobarTheme>,
|
||||||
/// Background color
|
/// Alpha value for the color transparency [[0-255]] (default: 200)
|
||||||
pub background: Option<AlphaColour>,
|
pub transparency_alpha: Option<u8>,
|
||||||
/// Visual grouping for widgets
|
/// Visual grouping for widgets
|
||||||
pub grouping: Option<Grouping>,
|
pub grouping: Option<Grouping>,
|
||||||
/// Left side widgets (ordered left-to-right)
|
/// Left side widgets (ordered left-to-right)
|
||||||
@@ -198,29 +197,36 @@ pub enum LabelPrefix {
|
|||||||
IconAndText,
|
IconAndText,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema)]
|
pub trait Color32Ext {
|
||||||
pub struct AlphaColour {
|
fn to_u32(&self) -> u32;
|
||||||
/// Color
|
fn from_u32(color: u32) -> Self;
|
||||||
pub color: Option<Colour>,
|
fn try_apply_alpha(self, transparency_alpha: Option<u8>) -> Self;
|
||||||
/// Alpha value for the color transparency [[0-255]] (default: 200)
|
|
||||||
pub transparency_alpha: Option<u8>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AlphaColour {
|
impl Color32Ext for Color32 {
|
||||||
/// Returns an Rgb or Rgba color using the alpha, and default_color or Rgb(0,0,0)
|
/// Converts Color32 to u32 (ARGB format)
|
||||||
pub fn to_color32_or(self, default_color: Option<Color32>) -> Color32 {
|
fn to_u32(&self) -> u32 {
|
||||||
let color = match self.color {
|
((self.a() as u32) << 24)
|
||||||
Some(color) => color.into(),
|
| ((self.r() as u32) << 16)
|
||||||
None => match default_color {
|
| ((self.g() as u32) << 8)
|
||||||
Some(color) => color,
|
| (self.b() as u32)
|
||||||
None => Color32::from_rgb(0, 0, 0),
|
}
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
if let Some(alpha) = self.transparency_alpha {
|
/// Converts u32 back to Color32 (ARGB format)
|
||||||
return Color32::from_rgba_unmultiplied(color.r(), color.g(), color.b(), alpha);
|
fn from_u32(color: u32) -> Self {
|
||||||
|
let a = ((color >> 24) & 0xFF) as u8;
|
||||||
|
let r = ((color >> 16) & 0xFF) as u8;
|
||||||
|
let g = ((color >> 8) & 0xFF) as u8;
|
||||||
|
let b = (color & 0xFF) as u8;
|
||||||
|
Color32::from_rgba_premultiplied(r, g, b, a)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Tries to apply the alpha value to the Color32
|
||||||
|
fn try_apply_alpha(self, transparency_alpha: Option<u8>) -> Self {
|
||||||
|
if let Some(alpha) = transparency_alpha {
|
||||||
|
return Color32::from_rgba_unmultiplied(self.r(), self.g(), self.b(), alpha);
|
||||||
}
|
}
|
||||||
|
|
||||||
color
|
self
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,19 +1,17 @@
|
|||||||
use crate::config::AlphaColour;
|
use crate::config::Color32Ext;
|
||||||
use crate::config::Position;
|
use crate::BACKGROUND_COLOR;
|
||||||
use eframe::egui::Color32;
|
use eframe::egui::Color32;
|
||||||
use eframe::egui::Frame;
|
use eframe::egui::Frame;
|
||||||
use eframe::egui::InnerResponse;
|
use eframe::egui::InnerResponse;
|
||||||
use eframe::egui::Margin;
|
use eframe::egui::Margin;
|
||||||
use eframe::egui::Rounding;
|
use eframe::egui::Rounding;
|
||||||
use eframe::egui::Shadow;
|
use eframe::egui::Shadow;
|
||||||
use eframe::egui::Stroke;
|
|
||||||
use eframe::egui::Ui;
|
use eframe::egui::Ui;
|
||||||
use eframe::egui::Vec2;
|
use eframe::egui::Vec2;
|
||||||
use komorebi_client::Colour;
|
|
||||||
use komorebi_client::Rect;
|
|
||||||
use schemars::JsonSchema;
|
use schemars::JsonSchema;
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
|
use std::sync::atomic::Ordering;
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema)]
|
#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema)]
|
||||||
#[serde(tag = "kind")]
|
#[serde(tag = "kind")]
|
||||||
@@ -36,21 +34,8 @@ impl Grouping {
|
|||||||
) -> InnerResponse<R> {
|
) -> InnerResponse<R> {
|
||||||
match self {
|
match self {
|
||||||
Self::Bar(config) => Self::define_frame(ui, config).show(ui, add_contents),
|
Self::Bar(config) => Self::define_frame(ui, config).show(ui, add_contents),
|
||||||
|
Self::Side(_) => Self::default_response(ui, add_contents),
|
||||||
Self::Widget(_) => Self::default_response(ui, add_contents),
|
Self::Widget(_) => Self::default_response(ui, add_contents),
|
||||||
Self::Side(_) => Self::default_response(ui, add_contents),
|
|
||||||
Self::None => Self::default_response(ui, add_contents),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn apply_on_widget<R>(
|
|
||||||
&mut self,
|
|
||||||
ui: &mut Ui,
|
|
||||||
add_contents: impl FnOnce(&mut Ui) -> R,
|
|
||||||
) -> InnerResponse<R> {
|
|
||||||
match self {
|
|
||||||
Self::Bar(_) => Self::default_response(ui, add_contents),
|
|
||||||
Self::Widget(config) => Self::define_frame(ui, config).show(ui, add_contents),
|
|
||||||
Self::Side(_) => Self::default_response(ui, add_contents),
|
|
||||||
Self::None => Self::default_response(ui, add_contents),
|
Self::None => Self::default_response(ui, add_contents),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -62,36 +47,49 @@ impl Grouping {
|
|||||||
) -> InnerResponse<R> {
|
) -> InnerResponse<R> {
|
||||||
match self {
|
match self {
|
||||||
Self::Bar(_) => Self::default_response(ui, add_contents),
|
Self::Bar(_) => Self::default_response(ui, add_contents),
|
||||||
Self::Widget(_) => Self::default_response(ui, add_contents),
|
|
||||||
Self::Side(config) => Self::define_frame(ui, config).show(ui, add_contents),
|
Self::Side(config) => Self::define_frame(ui, config).show(ui, add_contents),
|
||||||
|
Self::Widget(_) => Self::default_response(ui, add_contents),
|
||||||
|
Self::None => Self::default_response(ui, add_contents),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn apply_on_widget<R>(
|
||||||
|
&mut self,
|
||||||
|
ui: &mut Ui,
|
||||||
|
add_contents: impl FnOnce(&mut Ui) -> R,
|
||||||
|
) -> InnerResponse<R> {
|
||||||
|
match self {
|
||||||
|
Self::Bar(_) => Self::default_response(ui, add_contents),
|
||||||
|
Self::Side(_) => Self::default_response(ui, add_contents),
|
||||||
|
Self::Widget(config) => Self::define_frame(ui, config).show(ui, add_contents),
|
||||||
Self::None => Self::default_response(ui, add_contents),
|
Self::None => Self::default_response(ui, add_contents),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn define_frame(ui: &mut Ui, config: &mut GroupingConfig) -> Frame {
|
fn define_frame(ui: &mut Ui, config: &mut GroupingConfig) -> Frame {
|
||||||
Frame::none()
|
Frame::none()
|
||||||
.fill(match config.fill {
|
.outer_margin(Margin::same(0.0))
|
||||||
Some(color) => color.to_color32_or(None),
|
.inner_margin(Margin::symmetric(3.0, 3.0))
|
||||||
None => Color32::TRANSPARENT,
|
.stroke(ui.style().visuals.widgets.noninteractive.bg_stroke)
|
||||||
})
|
|
||||||
.outer_margin(match config.outer_margin {
|
|
||||||
Some(margin) => Self::rect_to_margin(margin),
|
|
||||||
None => Margin::symmetric(0.0, 0.0),
|
|
||||||
})
|
|
||||||
.inner_margin(match config.inner_margin {
|
|
||||||
Some(margin) => Self::rect_to_margin(margin),
|
|
||||||
None => Margin::symmetric(5.0, 2.0),
|
|
||||||
})
|
|
||||||
.rounding(match config.rounding {
|
.rounding(match config.rounding {
|
||||||
Some(rounding) => rounding.into(),
|
Some(rounding) => rounding.into(),
|
||||||
None => Rounding::same(5.0),
|
None => ui.style().visuals.widgets.noninteractive.rounding,
|
||||||
})
|
})
|
||||||
.stroke(match config.stroke {
|
.fill(
|
||||||
Some(line) => line.into(),
|
Color32::from_u32(BACKGROUND_COLOR.load(Ordering::SeqCst))
|
||||||
None => ui.style().visuals.widgets.noninteractive.bg_stroke,
|
.try_apply_alpha(config.transparency_alpha),
|
||||||
})
|
)
|
||||||
.shadow(match config.shadow {
|
.shadow(match config.style {
|
||||||
Some(shadow) => shadow.into(),
|
Some(style) => match style {
|
||||||
|
// new styles can be added if needed
|
||||||
|
GroupingStyle::Default => Shadow::NONE,
|
||||||
|
GroupingStyle::DefaultWithShadow => Shadow {
|
||||||
|
blur: 4.0,
|
||||||
|
offset: Vec2::new(1.0, 1.0),
|
||||||
|
spread: 3.0,
|
||||||
|
color: Color32::BLACK.try_apply_alpha(config.transparency_alpha),
|
||||||
|
},
|
||||||
|
},
|
||||||
None => Shadow::NONE,
|
None => Shadow::NONE,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -105,43 +103,19 @@ impl Grouping {
|
|||||||
response: ui.response().clone(),
|
response: ui.response().clone(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn rect_to_margin(rect: Rect) -> Margin {
|
|
||||||
Margin {
|
|
||||||
left: rect.left as f32,
|
|
||||||
right: rect.right as f32,
|
|
||||||
top: rect.top as f32,
|
|
||||||
bottom: rect.bottom as f32,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema)]
|
#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema)]
|
||||||
pub struct GroupingConfig {
|
pub struct GroupingConfig {
|
||||||
pub fill: Option<AlphaColour>,
|
pub style: Option<GroupingStyle>,
|
||||||
|
pub transparency_alpha: Option<u8>,
|
||||||
pub rounding: Option<RoundingConfig>,
|
pub rounding: Option<RoundingConfig>,
|
||||||
pub outer_margin: Option<Rect>,
|
|
||||||
pub inner_margin: Option<Rect>,
|
|
||||||
pub stroke: Option<Line>,
|
|
||||||
pub shadow: Option<BoxShadow>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema)]
|
#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema)]
|
||||||
pub struct Line {
|
pub enum GroupingStyle {
|
||||||
pub width: Option<f32>,
|
Default,
|
||||||
pub color: Option<Colour>,
|
DefaultWithShadow,
|
||||||
}
|
|
||||||
|
|
||||||
impl From<Line> for Stroke {
|
|
||||||
fn from(value: Line) -> Self {
|
|
||||||
Self {
|
|
||||||
width: value.width.unwrap_or(1.0),
|
|
||||||
color: match value.color {
|
|
||||||
Some(color) => color.into(),
|
|
||||||
None => Color32::from_rgb(0, 0, 0),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema)]
|
#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema)]
|
||||||
@@ -166,40 +140,3 @@ impl From<RoundingConfig> for Rounding {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema)]
|
|
||||||
pub struct BoxShadow {
|
|
||||||
/// Move the shadow by this much.
|
|
||||||
///
|
|
||||||
/// For instance, a value of `[1.0, 2.0]` will move the shadow 1 point to the right and 2 points down,
|
|
||||||
/// causing a drop-shadow effect.
|
|
||||||
pub offset: Option<Position>,
|
|
||||||
|
|
||||||
/// The width of the blur, i.e. the width of the fuzzy penumbra.
|
|
||||||
///
|
|
||||||
/// A value of 0.0 means a sharp shadow.
|
|
||||||
pub blur: Option<f32>,
|
|
||||||
|
|
||||||
/// Expand the shadow in all directions by this much.
|
|
||||||
pub spread: Option<f32>,
|
|
||||||
|
|
||||||
/// Color of the opaque center of the shadow.
|
|
||||||
pub color: Option<AlphaColour>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<BoxShadow> for Shadow {
|
|
||||||
fn from(value: BoxShadow) -> Self {
|
|
||||||
Shadow {
|
|
||||||
offset: match value.offset {
|
|
||||||
Some(offset) => offset.into(),
|
|
||||||
None => Vec2::ZERO,
|
|
||||||
},
|
|
||||||
blur: value.blur.unwrap_or(0.0),
|
|
||||||
spread: value.spread.unwrap_or(0.0),
|
|
||||||
color: match value.color {
|
|
||||||
Some(color) => color.to_color32_or(None),
|
|
||||||
None => Color32::TRANSPARENT,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ use std::io::BufReader;
|
|||||||
use std::io::Read;
|
use std::io::Read;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::sync::atomic::AtomicI32;
|
use std::sync::atomic::AtomicI32;
|
||||||
|
use std::sync::atomic::AtomicU32;
|
||||||
use std::sync::atomic::Ordering;
|
use std::sync::atomic::Ordering;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
@@ -45,6 +46,7 @@ use windows::Win32::UI::WindowsAndMessaging::GetWindowThreadProcessId;
|
|||||||
|
|
||||||
pub static WIDGET_SPACING: f32 = 10.0;
|
pub static WIDGET_SPACING: f32 = 10.0;
|
||||||
|
|
||||||
|
pub static BACKGROUND_COLOR: AtomicU32 = AtomicU32::new(0);
|
||||||
pub static MAX_LABEL_WIDTH: AtomicI32 = AtomicI32::new(400);
|
pub static MAX_LABEL_WIDTH: AtomicI32 = AtomicI32::new(400);
|
||||||
pub static MONITOR_LEFT: AtomicI32 = AtomicI32::new(0);
|
pub static MONITOR_LEFT: AtomicI32 = AtomicI32::new(0);
|
||||||
pub static MONITOR_TOP: AtomicI32 = AtomicI32::new(0);
|
pub static MONITOR_TOP: AtomicI32 = AtomicI32::new(0);
|
||||||
@@ -267,10 +269,7 @@ fn main() -> color_eyre::Result<()> {
|
|||||||
|
|
||||||
let viewport_builder = ViewportBuilder::default()
|
let viewport_builder = ViewportBuilder::default()
|
||||||
.with_decorations(false)
|
.with_decorations(false)
|
||||||
.with_transparent(match config.background {
|
.with_transparent(config.transparency_alpha.is_some())
|
||||||
None => false,
|
|
||||||
Some(color) => color.transparency_alpha.is_some(),
|
|
||||||
})
|
|
||||||
.with_taskbar(false);
|
.with_taskbar(false);
|
||||||
|
|
||||||
let native_options = eframe::NativeOptions {
|
let native_options = eframe::NativeOptions {
|
||||||
|
|||||||
Reference in New Issue
Block a user