This commit is contained in:
2026-09-13 14:37:59 +01:00
parent b81eb967ee
commit 74f59be3f8
11 changed files with 87 additions and 37 deletions
+25 -1
View File
@@ -4,7 +4,31 @@ use toml::Table;
#[derive(Serialize, Deserialize)] #[derive(Serialize, Deserialize)]
pub struct BarbarConfig { pub struct BarbarConfig {
pub monitor: Option<String>, pub monitor: Option<String>,
pub ups: Option<i32>, // Updates per second pub ups: Option<i32>, // Updates per second
pub order: ModuleOrder,
pub modules: Option<Table>, // 'clock': [clock settings] pub modules: Option<Table>, // 'clock': [clock settings]
pub services: Option<Table>, // 'clockticker': [clockticker settings] pub services: Option<Table>, // 'clockticker': [clockticker settings]
} }
#[derive(serde::Deserialize, Serialize, Clone, Copy, Debug)]
#[serde(rename_all = "lowercase")]
pub enum Modules {
Clock,
Weather,
}
impl Modules {
pub fn to_string(&self) -> &str {
match self {
Modules::Clock => "clock",
Modules::Weather => "weather",
}
}
}
#[derive(Deserialize, Serialize, Clone)]
pub struct ModuleOrder {
pub left: Vec<Modules>,
pub middle: Vec<Modules>,
pub right: Vec<Modules>,
}
+2 -4
View File
@@ -11,11 +11,9 @@ mod module;
mod service; mod service;
mod wire; mod wire;
pub use config::BarbarConfig; pub use config::{BarbarConfig, Modules};
pub use effect::ModuleEffect; pub use effect::ModuleEffect;
pub use messages::{ClockKind, ClockMsg, ClockPayload}; pub use messages::*;
pub use messages::modules::WeatherKind;
pub use messages::services::WeatherResponse;
pub use module::BarModule; pub use module::BarModule;
pub use service::Service; pub use service::Service;
pub use wire::{Endpoint, Inbox, Namespace, Target, Wire}; pub use wire::{Endpoint, Inbox, Namespace, Target, Wire};
+2 -2
View File
@@ -3,5 +3,5 @@
mod clock; mod clock;
mod weather; mod weather;
pub use clock::ClockMsg; pub use clock::*;
pub use weather::WeatherKind; pub use weather::*;
+2 -2
View File
@@ -3,5 +3,5 @@
mod datetime; mod datetime;
mod weather; mod weather;
pub use datetime::{ClockKind, ClockPayload}; pub use datetime::*;
pub use weather::{WeatherKind, WeatherPayload, WeatherResponse}; pub use weather::*;
@@ -5,11 +5,11 @@ use serde::Deserialize;
use crate::Service; use crate::Service;
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)] #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
pub enum WeatherKind { pub enum WeatherMsg {
State, State,
} }
impl WeatherKind { impl WeatherMsg {
pub fn key(self) -> Service { pub fn key(self) -> Service {
Service(match self { Service(match self {
Self::State => "weather.state", Self::State => "weather.state",
@@ -19,7 +19,7 @@ impl WeatherKind {
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct WeatherPayload { pub struct WeatherPayload {
pub kind: WeatherKind, pub kind: WeatherMsg,
pub payload: Arc<dyn Any + Send + Sync>, pub payload: Arc<dyn Any + Send + Sync>,
} }
+3 -3
View File
@@ -2,7 +2,7 @@ use std::collections::{BTreeMap, BTreeSet};
use iced::window; use iced::window;
use common::{BarModule, Inbox, Service}; use common::{BarModule, Inbox, Modules, Service};
use toml::Table; use toml::Table;
/// Application state: module registry, routing, popup bookkeeping. /// Application state: module registry, routing, popup bookkeeping.
@@ -12,7 +12,7 @@ pub(crate) struct Bar {
/// Module registry keyed by stable module id. /// Module registry keyed by stable module id.
pub(crate) modules: BTreeMap<&'static str, Box<dyn BarModule>>, pub(crate) modules: BTreeMap<&'static str, Box<dyn BarModule>>,
/// Left, Middle, Right ; Module Order /// Left, Middle, Right ; Module Order
pub(crate) order: (Vec<String>, Vec<String>, Vec<String>), pub(crate) order: (Vec<Modules>, Vec<Modules>, Vec<Modules>),
/// Surface id of the open popup. /// Surface id of the open popup.
pub(crate) popup_id: Option<window::Id>, pub(crate) popup_id: Option<window::Id>,
/// Fan-out routing table: module id -> services it wants. /// Fan-out routing table: module id -> services it wants.
@@ -25,7 +25,7 @@ pub(crate) struct Bar {
impl Bar { impl Bar {
pub(crate) fn new( pub(crate) fn new(
modules_config_table: &Table, modules_config_table: &Table,
modules_order: (Vec<String>, Vec<String>, Vec<String>), modules_order: (Vec<Modules>, Vec<Modules>, Vec<Modules>),
) -> Self { ) -> Self {
// Registry owns construction: adding a module never edits this file. // Registry owns construction: adding a module never edits this file.
let modules: BTreeMap<&'static str, Box<dyn BarModule>> = let modules: BTreeMap<&'static str, Box<dyn BarModule>> =
+12 -1
View File
@@ -47,9 +47,19 @@ fn main() -> Result<(), iced_layershell::Error> {
}; };
let modules = config.modules.clone().unwrap_or_default(); let modules = config.modules.clone().unwrap_or_default();
let order = config.order;
daemon( daemon(
move || Bar::new(&modules), move || {
Bar::new(
&modules,
(
order.left.clone(),
order.middle.clone(),
order.right.clone(),
),
)
},
subscription::namespace, subscription::namespace,
update::update, update::update,
view::view, view::view,
@@ -62,6 +72,7 @@ fn main() -> Result<(), iced_layershell::Error> {
exclusive_zone: BAR_HEIGHT as i32, exclusive_zone: BAR_HEIGHT as i32,
anchor: Anchor::Top | Anchor::Left | Anchor::Right, anchor: Anchor::Top | Anchor::Left | Anchor::Right,
start_mode, start_mode,
keyboard_interactivity: iced_layershell::reexport::KeyboardInteractivity::None,
..Default::default() ..Default::default()
}, },
..Default::default() ..Default::default()
+30 -9
View File
@@ -1,3 +1,4 @@
use common::Wire;
use iced::widget::{container, row, text}; use iced::widget::{container, row, text};
use iced::{window, Alignment, Element, Length, Theme}; use iced::{window, Alignment, Element, Length, Theme};
@@ -15,16 +16,36 @@ pub(crate) fn view(bar: &Bar, id: window::Id) -> Element<'_, Message> {
/// Each module renders itself; the bar lays them out in a row. /// Each module renders itself; the bar lays them out in a row.
fn bar_view(bar: &Bar) -> Element<'_, Message> { fn bar_view(bar: &Bar) -> Element<'_, Message> {
let mut children: Vec<Element<Message>> = Vec::new(); // for (i, (_, module)) in bar.modules.iter().enumerate() {
// children.push(module.view(None).map(|w| Message::Event(Msg::Wire(w))));
// if i < bar.modules.len() - 1 {
// children.push(text("|").size(14).into());
// }
// }
let left = row(bar
.order
.0
.iter()
.map(|x| {
bar.modules
.get(x.to_string())
.unwrap()
.view(None)
.map(|w| Message::Event(Msg::Wire(w)))
})
.collect::<Vec<Element<Message>>>());
let middle = row(bar
.order
.1
.iter()
.map(|x| bar.modules.get(x.to_string()).unwrap().view(None)));
let right = row(bar
.order
.2
.iter()
.map(|x| bar.modules.get(x.to_string()).unwrap().view(None)));
for (i, (_, module)) in bar.modules.iter().enumerate() { container(left.width(Length::Fill).align_y(Alignment::Center))
children.push(module.view(None).map(|w| Message::Event(Msg::Wire(w))));
if i < bar.modules.len() - 1 {
children.push(text("|").size(14).into());
}
}
container(row(children).width(Length::Fill).align_y(Alignment::Center))
.padding(8) .padding(8)
.align_x(Alignment::Center) .align_x(Alignment::Center)
.into() .into()
+2 -2
View File
@@ -1,6 +1,6 @@
use std::error::Error; use std::error::Error;
use common::{BarModule, Endpoint, ModuleEffect, Service, WeatherKind, Wire}; use common::{BarModule, Endpoint, ModuleEffect, Service, WeatherKind, WeatherMsg, Wire};
use iced::{ use iced::{
widget::{container, mouse_area, text}, widget::{container, mouse_area, text},
Element, Task, Element, Task,
@@ -43,7 +43,7 @@ impl BarModule for WeatherModule {
/// Route keys this module subscribes to. /// Route keys this module subscribes to.
fn services(&self) -> Vec<Service> { fn services(&self) -> Vec<Service> {
vec![] vec![WeatherMsg::State.key()]
} }
/// Optional: read `module.weather` from the config table. /// Optional: read `module.weather` from the config table.
+2 -10
View File
@@ -8,7 +8,7 @@
use std::collections::HashMap; use std::collections::HashMap;
use chrono::{DateTime, Local, Timelike}; use chrono::{DateTime, Local, Timelike};
use iced::futures::{channel::mpsc, SinkExt, StreamExt}; use iced::futures::{channel::mpsc, SinkExt};
use iced::Subscription; use iced::Subscription;
use common::{ClockKind, ClockPayload, Endpoint, Inbox, Wire}; use common::{ClockKind, ClockPayload, Endpoint, Inbox, Wire};
@@ -17,20 +17,12 @@ use common::{ClockKind, ClockPayload, Endpoint, Inbox, Wire};
pub const NAMESPACE: &str = "clock."; pub const NAMESPACE: &str = "clock.";
/// Drives the clock, publishing only the kind modules last asked for. /// Drives the clock, publishing only the kind modules last asked for.
#[derive(Default)]
pub struct ClockTicker { pub struct ClockTicker {
last: DateTime<Local>, last: DateTime<Local>,
// want: ClockKind, // want: ClockKind,
} }
impl Default for ClockTicker {
fn default() -> Self {
Self {
last: DateTime::default(),
// want: ClockKind::Seconds,
}
}
}
impl ClockTicker { impl ClockTicker {
pub fn new() -> Self { pub fn new() -> Self {
Self::default() Self::default()
+4
View File
@@ -1,4 +1,8 @@
monitor = "DP-2" monitor = "DP-2"
[order]
left = ["weather", "clock"]
middle = []
right = ["clock"]
[modules.clock] [modules.clock]
format = true format = true