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
+24
View File
@@ -5,6 +5,30 @@ use toml::Table;
pub struct BarbarConfig {
pub monitor: Option<String>,
pub ups: Option<i32>, // Updates per second
pub order: ModuleOrder,
pub modules: Option<Table>, // 'clock': [clock 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 wire;
pub use config::BarbarConfig;
pub use config::{BarbarConfig, Modules};
pub use effect::ModuleEffect;
pub use messages::{ClockKind, ClockMsg, ClockPayload};
pub use messages::modules::WeatherKind;
pub use messages::services::WeatherResponse;
pub use messages::*;
pub use module::BarModule;
pub use service::Service;
pub use wire::{Endpoint, Inbox, Namespace, Target, Wire};
+2 -2
View File
@@ -3,5 +3,5 @@
mod clock;
mod weather;
pub use clock::ClockMsg;
pub use weather::WeatherKind;
pub use clock::*;
pub use weather::*;
+2 -2
View File
@@ -3,5 +3,5 @@
mod datetime;
mod weather;
pub use datetime::{ClockKind, ClockPayload};
pub use weather::{WeatherKind, WeatherPayload, WeatherResponse};
pub use datetime::*;
pub use weather::*;
@@ -5,11 +5,11 @@ use serde::Deserialize;
use crate::Service;
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
pub enum WeatherKind {
pub enum WeatherMsg {
State,
}
impl WeatherKind {
impl WeatherMsg {
pub fn key(self) -> Service {
Service(match self {
Self::State => "weather.state",
@@ -19,7 +19,7 @@ impl WeatherKind {
#[derive(Clone, Debug)]
pub struct WeatherPayload {
pub kind: WeatherKind,
pub kind: WeatherMsg,
pub payload: Arc<dyn Any + Send + Sync>,
}
+3 -3
View File
@@ -2,7 +2,7 @@ use std::collections::{BTreeMap, BTreeSet};
use iced::window;
use common::{BarModule, Inbox, Service};
use common::{BarModule, Inbox, Modules, Service};
use toml::Table;
/// Application state: module registry, routing, popup bookkeeping.
@@ -12,7 +12,7 @@ pub(crate) struct Bar {
/// Module registry keyed by stable module id.
pub(crate) modules: BTreeMap<&'static str, Box<dyn BarModule>>,
/// 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.
pub(crate) popup_id: Option<window::Id>,
/// Fan-out routing table: module id -> services it wants.
@@ -25,7 +25,7 @@ pub(crate) struct Bar {
impl Bar {
pub(crate) fn new(
modules_config_table: &Table,
modules_order: (Vec<String>, Vec<String>, Vec<String>),
modules_order: (Vec<Modules>, Vec<Modules>, Vec<Modules>),
) -> Self {
// Registry owns construction: adding a module never edits this file.
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 order = config.order;
daemon(
move || Bar::new(&modules),
move || {
Bar::new(
&modules,
(
order.left.clone(),
order.middle.clone(),
order.right.clone(),
),
)
},
subscription::namespace,
update::update,
view::view,
@@ -62,6 +72,7 @@ fn main() -> Result<(), iced_layershell::Error> {
exclusive_zone: BAR_HEIGHT as i32,
anchor: Anchor::Top | Anchor::Left | Anchor::Right,
start_mode,
keyboard_interactivity: iced_layershell::reexport::KeyboardInteractivity::None,
..Default::default()
},
..Default::default()
+30 -9
View File
@@ -1,3 +1,4 @@
use common::Wire;
use iced::widget::{container, row, text};
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.
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() {
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))
container(left.width(Length::Fill).align_y(Alignment::Center))
.padding(8)
.align_x(Alignment::Center)
.into()
+2 -2
View File
@@ -1,6 +1,6 @@
use std::error::Error;
use common::{BarModule, Endpoint, ModuleEffect, Service, WeatherKind, Wire};
use common::{BarModule, Endpoint, ModuleEffect, Service, WeatherKind, WeatherMsg, Wire};
use iced::{
widget::{container, mouse_area, text},
Element, Task,
@@ -43,7 +43,7 @@ impl BarModule for WeatherModule {
/// Route keys this module subscribes to.
fn services(&self) -> Vec<Service> {
vec![]
vec![WeatherMsg::State.key()]
}
/// Optional: read `module.weather` from the config table.
+2 -10
View File
@@ -8,7 +8,7 @@
use std::collections::HashMap;
use chrono::{DateTime, Local, Timelike};
use iced::futures::{channel::mpsc, SinkExt, StreamExt};
use iced::futures::{channel::mpsc, SinkExt};
use iced::Subscription;
use common::{ClockKind, ClockPayload, Endpoint, Inbox, Wire};
@@ -17,20 +17,12 @@ use common::{ClockKind, ClockPayload, Endpoint, Inbox, Wire};
pub const NAMESPACE: &str = "clock.";
/// Drives the clock, publishing only the kind modules last asked for.
#[derive(Default)]
pub struct ClockTicker {
last: DateTime<Local>,
// want: ClockKind,
}
impl Default for ClockTicker {
fn default() -> Self {
Self {
last: DateTime::default(),
// want: ClockKind::Seconds,
}
}
}
impl ClockTicker {
pub fn new() -> Self {
Self::default()
+4
View File
@@ -1,4 +1,8 @@
monitor = "DP-2"
[order]
left = ["weather", "clock"]
middle = []
right = ["clock"]
[modules.clock]
format = true