fmstl
This commit is contained in:
@@ -4,7 +4,31 @@ use toml::Table;
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct BarbarConfig {
|
||||
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 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>,
|
||||
}
|
||||
|
||||
@@ -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};
|
||||
|
||||
@@ -3,5 +3,5 @@
|
||||
mod clock;
|
||||
mod weather;
|
||||
|
||||
pub use clock::ClockMsg;
|
||||
pub use weather::WeatherKind;
|
||||
pub use clock::*;
|
||||
pub use weather::*;
|
||||
|
||||
@@ -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>,
|
||||
}
|
||||
|
||||
|
||||
@@ -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
@@ -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
@@ -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()
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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()
|
||||
|
||||
Reference in New Issue
Block a user