diff --git a/Cargo.toml b/Cargo.toml index 9ff4ee1..3d105a4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,8 +7,11 @@ authors = ["candifloss "] readme = "README.md" [dependencies] +dirs = "6.0.0" i-slint-backend-winit = { version = "1.14.1", features = ["x11"] } +serde = { version = "1.0.228", features = ["derive"] } slint = { version = "1.14.1", features = ["backend-winit"] } +toml = "0.9.8" [build-dependencies] slint-build = "1.14.1" diff --git a/src/config.rs b/src/config.rs new file mode 100644 index 0000000..c168992 --- /dev/null +++ b/src/config.rs @@ -0,0 +1,51 @@ +use dirs::config_dir; +use serde::Deserialize; +use std::{fs, path::PathBuf}; + +#[derive(Debug, Clone, Deserialize)] +pub struct Config { + pub bar_width: i32, + pub bar_height: i32, + pub default_font_family: String, + pub default_font_size: i32, +} + +// Default values for the config. +impl Default for Config { + fn default() -> Self { + Self { + bar_width: 1366, + bar_height: 27, + default_font_family: "IosevkaTermSlab Nerd Font Mono".to_string(), + default_font_size: 14, + } + } +} + +impl Config { + /// Load config from ~/.config/candywidgets/chocobar/chocobar.toml + /// Falls back to defaults if file is missing or broken. + pub fn load() -> Self { + let path = config_path(); + + // If file doesn't exist: return defaults. + if !path.exists() { + return Config::default(); + } + + // Read file; on failure return defaults. + let Ok(data) = fs::read_to_string(&path) else { + return Config::default(); + }; + + // Parse TOML; if invalid, use defaults. + let parsed: Result = toml::from_str(&data); + parsed.unwrap_or_default() + } +} + +/// Config directory. Default: ~/.config/candywidgets/chocobar/chocobar.toml +fn config_path() -> PathBuf { + let base = config_dir().unwrap_or_else(|| PathBuf::from(".")); + base.join("candywidgets/chocobar/chocobar.toml") +} diff --git a/src/main.rs b/src/main.rs index 8601bec..25058d3 100644 --- a/src/main.rs +++ b/src/main.rs @@ -5,11 +5,22 @@ use i_slint_backend_winit::{ window::WindowAttributes, }, }; -use slint::{LogicalPosition, LogicalSize}; +use slint::{LogicalPosition, LogicalSize, SharedString}; +mod config; mod widgets; +use config::Config; slint::include_modules!(); fn main() -> Result<(), Box> { + // Load config + let conf = Config::load(); + + // Bar dimensions. + let bar_height = conf.bar_height; + let bar_width = conf.bar_width; + let def_font_size = conf.default_font_size; + let def_font_fam = conf.default_font_family; + // Closure that adjusts winit WindowAttributes before Slint creates the window. let window_attrs = |attrs: WindowAttributes| { // Mark the X11 window as a DOCK so the WM treats it as a top bar/panel. @@ -24,15 +35,13 @@ fn main() -> Result<(), Box> { // Activate this customized backend for all Slint window creation and events. slint::platform::set_platform(Box::new(backend))?; - // Bar dimensions. - let bar_height = 27; - let bar_width = 1366; - // Create the Slint UI component. let ui = TopBar::new()?; // Set component properties. ui.set_bar_width(bar_width); ui.set_bar_height(bar_height); + ui.set_def_font_size(def_font_size); + ui.set_def_font_fam(SharedString::from(def_font_fam)); // Install all widget callbacks widgets::install_callbacks(&ui); diff --git a/ui/topbar.slint b/ui/topbar.slint index 8291351..f3acd3a 100644 --- a/ui/topbar.slint +++ b/ui/topbar.slint @@ -4,6 +4,8 @@ export component TopBar inherits Window { in property bar_width; in property bar_height; + in property def_font_size; + in property def_font_fam; callback show_clock(); @@ -14,8 +16,8 @@ export component TopBar inherits Window { no-frame: true; x: 0px; y: 0px; - default-font-family: "IosevkaTermSlab Nerd Font Mono"; - default-font-size: 14px; + default-font-family: def_font_fam; + default-font-size: def_font_size *1px; Rectangle { x: 0px;