An applicaiton and simulator for a bike lighting system #245
|
@ -3783,6 +3783,7 @@ dependencies = [
|
||||||
"glib",
|
"glib",
|
||||||
"gtk4",
|
"gtk4",
|
||||||
"libadwaita",
|
"libadwaita",
|
||||||
|
"lights-core",
|
||||||
"pango",
|
"pango",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
@ -1,14 +1,72 @@
|
||||||
pub fn add(left: usize, right: usize) -> usize {
|
use std::time::Duration;
|
||||||
left + right
|
|
||||||
|
mod patterns;
|
||||||
|
pub use patterns::*;
|
||||||
|
|
||||||
|
mod types;
|
||||||
|
pub use types::{DashboardPattern, Pattern, RGB};
|
||||||
|
|
||||||
|
pub trait UI {
|
||||||
|
fn update_lights(&self, dashboard_lights: DashboardPattern, lights: Pattern);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
pub trait Animation {
|
||||||
mod tests {
|
fn tick(&self, frame: Duration) -> (DashboardPattern, Pattern);
|
||||||
use super::*;
|
}
|
||||||
|
|
||||||
#[test]
|
pub struct DefaultAnimation {}
|
||||||
fn it_works() {
|
|
||||||
let result = add(2, 2);
|
impl Animation for DefaultAnimation {
|
||||||
assert_eq!(result, 4);
|
fn tick(&self, _: Duration) -> (DashboardPattern, Pattern) {
|
||||||
|
(PRIDE_DASHBOARD, PRIDE)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub enum Event {
|
||||||
|
Brake,
|
||||||
|
BrakeRelease,
|
||||||
|
LeftBlinker,
|
||||||
|
LeftBlinkerRelease,
|
||||||
|
NextPattern,
|
||||||
|
PreviousPattern,
|
||||||
|
RightBlinker,
|
||||||
|
RightBlinkerRelease,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub enum State {
|
||||||
|
Pattern(u8),
|
||||||
|
Brake,
|
||||||
|
LeftBlinker,
|
||||||
|
RightBlinker,
|
||||||
|
BrakeLeftBlinker,
|
||||||
|
BrakeRightBlinker,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct App {
|
||||||
|
ui: Box<dyn UI>,
|
||||||
|
state: State,
|
||||||
|
current_animation: Box<dyn Animation>,
|
||||||
|
dashboard_lights: DashboardPattern,
|
||||||
|
lights: Pattern,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl App {
|
||||||
|
pub fn new(ui: Box<dyn UI>) -> Self {
|
||||||
|
Self {
|
||||||
|
ui,
|
||||||
|
state: State::Pattern(0),
|
||||||
|
current_animation: Box::new(DefaultAnimation {}),
|
||||||
|
dashboard_lights: OFF_DASHBOARD,
|
||||||
|
lights: OFF,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn tick(&mut self, frame: Duration) {
|
||||||
|
let (dashboard, lights) = self.current_animation.tick(frame);
|
||||||
|
self.dashboard_lights = dashboard.clone();
|
||||||
|
self.lights = lights.clone();
|
||||||
|
self.ui.update_lights(dashboard, lights);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,671 @@
|
||||||
|
use crate::RGB;
|
||||||
|
|
||||||
|
pub type DashboardPattern = [RGB; 3];
|
||||||
|
pub type Pattern = [RGB; 60];
|
||||||
|
|
||||||
|
pub const OFF_DASHBOARD: DashboardPattern = [
|
||||||
|
RGB { r: 0, g: 0, b: 0 },
|
||||||
|
RGB { r: 0, g: 0, b: 0 },
|
||||||
|
RGB { r: 0, g: 0, b: 0 },
|
||||||
|
];
|
||||||
|
|
||||||
|
pub const OFF: Pattern = [
|
||||||
|
RGB { r: 0, g: 0, b: 0 },
|
||||||
|
RGB { r: 0, g: 0, b: 0 },
|
||||||
|
RGB { r: 0, g: 0, b: 0 },
|
||||||
|
RGB { r: 0, g: 0, b: 0 },
|
||||||
|
RGB { r: 0, g: 0, b: 0 },
|
||||||
|
RGB { r: 0, g: 0, b: 0 },
|
||||||
|
RGB { r: 0, g: 0, b: 0 },
|
||||||
|
RGB { r: 0, g: 0, b: 0 },
|
||||||
|
RGB { r: 0, g: 0, b: 0 },
|
||||||
|
RGB { r: 0, g: 0, b: 0 },
|
||||||
|
RGB { r: 0, g: 0, b: 0 },
|
||||||
|
RGB { r: 0, g: 0, b: 0 },
|
||||||
|
RGB { r: 0, g: 0, b: 0 },
|
||||||
|
RGB { r: 0, g: 0, b: 0 },
|
||||||
|
RGB { r: 0, g: 0, b: 0 },
|
||||||
|
RGB { r: 0, g: 0, b: 0 },
|
||||||
|
RGB { r: 0, g: 0, b: 0 },
|
||||||
|
RGB { r: 0, g: 0, b: 0 },
|
||||||
|
RGB { r: 0, g: 0, b: 0 },
|
||||||
|
RGB { r: 0, g: 0, b: 0 },
|
||||||
|
RGB { r: 0, g: 0, b: 0 },
|
||||||
|
RGB { r: 0, g: 0, b: 0 },
|
||||||
|
RGB { r: 0, g: 0, b: 0 },
|
||||||
|
RGB { r: 0, g: 0, b: 0 },
|
||||||
|
RGB { r: 0, g: 0, b: 0 },
|
||||||
|
RGB { r: 0, g: 0, b: 0 },
|
||||||
|
RGB { r: 0, g: 0, b: 0 },
|
||||||
|
RGB { r: 0, g: 0, b: 0 },
|
||||||
|
RGB { r: 0, g: 0, b: 0 },
|
||||||
|
RGB { r: 0, g: 0, b: 0 },
|
||||||
|
RGB { r: 0, g: 0, b: 0 },
|
||||||
|
RGB { r: 0, g: 0, b: 0 },
|
||||||
|
RGB { r: 0, g: 0, b: 0 },
|
||||||
|
RGB { r: 0, g: 0, b: 0 },
|
||||||
|
RGB { r: 0, g: 0, b: 0 },
|
||||||
|
RGB { r: 0, g: 0, b: 0 },
|
||||||
|
RGB { r: 0, g: 0, b: 0 },
|
||||||
|
RGB { r: 0, g: 0, b: 0 },
|
||||||
|
RGB { r: 0, g: 0, b: 0 },
|
||||||
|
RGB { r: 0, g: 0, b: 0 },
|
||||||
|
RGB { r: 0, g: 0, b: 0 },
|
||||||
|
RGB { r: 0, g: 0, b: 0 },
|
||||||
|
RGB { r: 0, g: 0, b: 0 },
|
||||||
|
RGB { r: 0, g: 0, b: 0 },
|
||||||
|
RGB { r: 0, g: 0, b: 0 },
|
||||||
|
RGB { r: 0, g: 0, b: 0 },
|
||||||
|
RGB { r: 0, g: 0, b: 0 },
|
||||||
|
RGB { r: 0, g: 0, b: 0 },
|
||||||
|
RGB { r: 0, g: 0, b: 0 },
|
||||||
|
RGB { r: 0, g: 0, b: 0 },
|
||||||
|
RGB { r: 0, g: 0, b: 0 },
|
||||||
|
RGB { r: 0, g: 0, b: 0 },
|
||||||
|
RGB { r: 0, g: 0, b: 0 },
|
||||||
|
RGB { r: 0, g: 0, b: 0 },
|
||||||
|
RGB { r: 0, g: 0, b: 0 },
|
||||||
|
RGB { r: 0, g: 0, b: 0 },
|
||||||
|
RGB { r: 0, g: 0, b: 0 },
|
||||||
|
RGB { r: 0, g: 0, b: 0 },
|
||||||
|
RGB { r: 0, g: 0, b: 0 },
|
||||||
|
RGB { r: 0, g: 0, b: 0 },
|
||||||
|
];
|
||||||
|
|
||||||
|
pub const PRIDE_DASHBOARD: DashboardPattern = [
|
||||||
|
RGB { r: 228, g: 3, b: 3 },
|
||||||
|
RGB {
|
||||||
|
r: 255,
|
||||||
|
g: 237,
|
||||||
|
b: 0,
|
||||||
|
},
|
||||||
|
RGB {
|
||||||
|
r: 115,
|
||||||
|
g: 41,
|
||||||
|
b: 130,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
pub const PRIDE: Pattern = [
|
||||||
|
RGB { r: 228, g: 3, b: 3 },
|
||||||
|
RGB { r: 228, g: 3, b: 3 },
|
||||||
|
RGB { r: 228, g: 3, b: 3 },
|
||||||
|
RGB { r: 228, g: 3, b: 3 },
|
||||||
|
RGB { r: 228, g: 3, b: 3 },
|
||||||
|
RGB { r: 228, g: 3, b: 3 },
|
||||||
|
RGB { r: 228, g: 3, b: 3 },
|
||||||
|
RGB { r: 228, g: 3, b: 3 },
|
||||||
|
RGB { r: 228, g: 3, b: 3 },
|
||||||
|
RGB { r: 228, g: 3, b: 3 },
|
||||||
|
RGB {
|
||||||
|
r: 255,
|
||||||
|
g: 140,
|
||||||
|
b: 0,
|
||||||
|
},
|
||||||
|
RGB {
|
||||||
|
r: 255,
|
||||||
|
g: 140,
|
||||||
|
b: 0,
|
||||||
|
},
|
||||||
|
RGB {
|
||||||
|
r: 255,
|
||||||
|
g: 140,
|
||||||
|
b: 0,
|
||||||
|
},
|
||||||
|
RGB {
|
||||||
|
r: 255,
|
||||||
|
g: 140,
|
||||||
|
b: 0,
|
||||||
|
},
|
||||||
|
RGB {
|
||||||
|
r: 255,
|
||||||
|
g: 140,
|
||||||
|
b: 0,
|
||||||
|
},
|
||||||
|
RGB {
|
||||||
|
r: 255,
|
||||||
|
g: 140,
|
||||||
|
b: 0,
|
||||||
|
},
|
||||||
|
RGB {
|
||||||
|
r: 255,
|
||||||
|
g: 140,
|
||||||
|
b: 0,
|
||||||
|
},
|
||||||
|
RGB {
|
||||||
|
r: 255,
|
||||||
|
g: 140,
|
||||||
|
b: 0,
|
||||||
|
},
|
||||||
|
RGB {
|
||||||
|
r: 255,
|
||||||
|
g: 140,
|
||||||
|
b: 0,
|
||||||
|
},
|
||||||
|
RGB {
|
||||||
|
r: 255,
|
||||||
|
g: 140,
|
||||||
|
b: 0,
|
||||||
|
},
|
||||||
|
RGB {
|
||||||
|
r: 255,
|
||||||
|
g: 237,
|
||||||
|
b: 0,
|
||||||
|
},
|
||||||
|
RGB {
|
||||||
|
r: 255,
|
||||||
|
g: 237,
|
||||||
|
b: 0,
|
||||||
|
},
|
||||||
|
RGB {
|
||||||
|
r: 255,
|
||||||
|
g: 237,
|
||||||
|
b: 0,
|
||||||
|
},
|
||||||
|
RGB {
|
||||||
|
r: 255,
|
||||||
|
g: 237,
|
||||||
|
b: 0,
|
||||||
|
},
|
||||||
|
RGB {
|
||||||
|
r: 255,
|
||||||
|
g: 237,
|
||||||
|
b: 0,
|
||||||
|
},
|
||||||
|
RGB {
|
||||||
|
r: 255,
|
||||||
|
g: 237,
|
||||||
|
b: 0,
|
||||||
|
},
|
||||||
|
RGB {
|
||||||
|
r: 255,
|
||||||
|
g: 237,
|
||||||
|
b: 0,
|
||||||
|
},
|
||||||
|
RGB {
|
||||||
|
r: 255,
|
||||||
|
g: 237,
|
||||||
|
b: 0,
|
||||||
|
},
|
||||||
|
RGB {
|
||||||
|
r: 255,
|
||||||
|
g: 237,
|
||||||
|
b: 0,
|
||||||
|
},
|
||||||
|
RGB {
|
||||||
|
r: 255,
|
||||||
|
g: 237,
|
||||||
|
b: 0,
|
||||||
|
},
|
||||||
|
RGB {
|
||||||
|
r: 0,
|
||||||
|
g: 128,
|
||||||
|
b: 38,
|
||||||
|
},
|
||||||
|
RGB {
|
||||||
|
r: 0,
|
||||||
|
g: 128,
|
||||||
|
b: 38,
|
||||||
|
},
|
||||||
|
RGB {
|
||||||
|
r: 0,
|
||||||
|
g: 128,
|
||||||
|
b: 38,
|
||||||
|
},
|
||||||
|
RGB {
|
||||||
|
r: 0,
|
||||||
|
g: 128,
|
||||||
|
b: 38,
|
||||||
|
},
|
||||||
|
RGB {
|
||||||
|
r: 0,
|
||||||
|
g: 128,
|
||||||
|
b: 38,
|
||||||
|
},
|
||||||
|
RGB {
|
||||||
|
r: 0,
|
||||||
|
g: 128,
|
||||||
|
b: 38,
|
||||||
|
},
|
||||||
|
RGB {
|
||||||
|
r: 0,
|
||||||
|
g: 128,
|
||||||
|
b: 38,
|
||||||
|
},
|
||||||
|
RGB {
|
||||||
|
r: 0,
|
||||||
|
g: 128,
|
||||||
|
b: 38,
|
||||||
|
},
|
||||||
|
RGB {
|
||||||
|
r: 0,
|
||||||
|
g: 128,
|
||||||
|
b: 38,
|
||||||
|
},
|
||||||
|
RGB {
|
||||||
|
r: 0,
|
||||||
|
g: 128,
|
||||||
|
b: 38,
|
||||||
|
},
|
||||||
|
RGB {
|
||||||
|
r: 36,
|
||||||
|
g: 64,
|
||||||
|
b: 142,
|
||||||
|
},
|
||||||
|
RGB {
|
||||||
|
r: 36,
|
||||||
|
g: 64,
|
||||||
|
b: 142,
|
||||||
|
},
|
||||||
|
RGB {
|
||||||
|
r: 36,
|
||||||
|
g: 64,
|
||||||
|
b: 142,
|
||||||
|
},
|
||||||
|
RGB {
|
||||||
|
r: 36,
|
||||||
|
g: 64,
|
||||||
|
b: 142,
|
||||||
|
},
|
||||||
|
RGB {
|
||||||
|
r: 36,
|
||||||
|
g: 64,
|
||||||
|
b: 142,
|
||||||
|
},
|
||||||
|
RGB {
|
||||||
|
r: 36,
|
||||||
|
g: 64,
|
||||||
|
b: 142,
|
||||||
|
},
|
||||||
|
RGB {
|
||||||
|
r: 36,
|
||||||
|
g: 64,
|
||||||
|
b: 142,
|
||||||
|
},
|
||||||
|
RGB {
|
||||||
|
r: 36,
|
||||||
|
g: 64,
|
||||||
|
b: 142,
|
||||||
|
},
|
||||||
|
RGB {
|
||||||
|
r: 36,
|
||||||
|
g: 64,
|
||||||
|
b: 142,
|
||||||
|
},
|
||||||
|
RGB {
|
||||||
|
r: 36,
|
||||||
|
g: 64,
|
||||||
|
b: 142,
|
||||||
|
},
|
||||||
|
RGB {
|
||||||
|
r: 115,
|
||||||
|
g: 41,
|
||||||
|
b: 130,
|
||||||
|
},
|
||||||
|
RGB {
|
||||||
|
r: 115,
|
||||||
|
g: 41,
|
||||||
|
b: 130,
|
||||||
|
},
|
||||||
|
RGB {
|
||||||
|
r: 115,
|
||||||
|
g: 41,
|
||||||
|
b: 130,
|
||||||
|
},
|
||||||
|
RGB {
|
||||||
|
r: 115,
|
||||||
|
g: 41,
|
||||||
|
b: 130,
|
||||||
|
},
|
||||||
|
RGB {
|
||||||
|
r: 115,
|
||||||
|
g: 41,
|
||||||
|
b: 130,
|
||||||
|
},
|
||||||
|
RGB {
|
||||||
|
r: 115,
|
||||||
|
g: 41,
|
||||||
|
b: 130,
|
||||||
|
},
|
||||||
|
RGB {
|
||||||
|
r: 115,
|
||||||
|
g: 41,
|
||||||
|
b: 130,
|
||||||
|
},
|
||||||
|
RGB {
|
||||||
|
r: 115,
|
||||||
|
g: 41,
|
||||||
|
b: 130,
|
||||||
|
},
|
||||||
|
RGB {
|
||||||
|
r: 115,
|
||||||
|
g: 41,
|
||||||
|
b: 130,
|
||||||
|
},
|
||||||
|
RGB {
|
||||||
|
r: 115,
|
||||||
|
g: 41,
|
||||||
|
b: 130,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
pub const TRANS_PRIDE_DASHBOARD: DashboardPattern = [
|
||||||
|
RGB {
|
||||||
|
r: 91,
|
||||||
|
g: 206,
|
||||||
|
b: 250,
|
||||||
|
},
|
||||||
|
RGB {
|
||||||
|
r: 255,
|
||||||
|
g: 255,
|
||||||
|
b: 255,
|
||||||
|
},
|
||||||
|
RGB {
|
||||||
|
r: 245,
|
||||||
|
g: 169,
|
||||||
|
b: 184,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
pub const TRANS_PRIDE: Pattern = [
|
||||||
|
RGB {
|
||||||
|
r: 91,
|
||||||
|
g: 206,
|
||||||
|
b: 250,
|
||||||
|
},
|
||||||
|
RGB {
|
||||||
|
r: 91,
|
||||||
|
g: 206,
|
||||||
|
b: 250,
|
||||||
|
},
|
||||||
|
RGB {
|
||||||
|
r: 91,
|
||||||
|
g: 206,
|
||||||
|
b: 250,
|
||||||
|
},
|
||||||
|
RGB {
|
||||||
|
r: 91,
|
||||||
|
g: 206,
|
||||||
|
b: 250,
|
||||||
|
},
|
||||||
|
RGB {
|
||||||
|
r: 91,
|
||||||
|
g: 206,
|
||||||
|
b: 250,
|
||||||
|
},
|
||||||
|
RGB {
|
||||||
|
r: 91,
|
||||||
|
g: 206,
|
||||||
|
b: 250,
|
||||||
|
},
|
||||||
|
RGB {
|
||||||
|
r: 91,
|
||||||
|
g: 206,
|
||||||
|
b: 250,
|
||||||
|
},
|
||||||
|
RGB {
|
||||||
|
r: 91,
|
||||||
|
g: 206,
|
||||||
|
b: 250,
|
||||||
|
},
|
||||||
|
RGB {
|
||||||
|
r: 91,
|
||||||
|
g: 206,
|
||||||
|
b: 250,
|
||||||
|
},
|
||||||
|
RGB {
|
||||||
|
r: 91,
|
||||||
|
g: 206,
|
||||||
|
b: 250,
|
||||||
|
},
|
||||||
|
RGB {
|
||||||
|
r: 91,
|
||||||
|
g: 206,
|
||||||
|
b: 250,
|
||||||
|
},
|
||||||
|
RGB {
|
||||||
|
r: 91,
|
||||||
|
g: 206,
|
||||||
|
b: 250,
|
||||||
|
},
|
||||||
|
RGB {
|
||||||
|
r: 245,
|
||||||
|
g: 169,
|
||||||
|
b: 184,
|
||||||
|
},
|
||||||
|
RGB {
|
||||||
|
r: 245,
|
||||||
|
g: 169,
|
||||||
|
b: 184,
|
||||||
|
},
|
||||||
|
RGB {
|
||||||
|
r: 245,
|
||||||
|
g: 169,
|
||||||
|
b: 184,
|
||||||
|
},
|
||||||
|
RGB {
|
||||||
|
r: 245,
|
||||||
|
g: 169,
|
||||||
|
b: 184,
|
||||||
|
},
|
||||||
|
RGB {
|
||||||
|
r: 245,
|
||||||
|
g: 169,
|
||||||
|
b: 184,
|
||||||
|
},
|
||||||
|
RGB {
|
||||||
|
r: 245,
|
||||||
|
g: 169,
|
||||||
|
b: 184,
|
||||||
|
},
|
||||||
|
RGB {
|
||||||
|
r: 245,
|
||||||
|
g: 169,
|
||||||
|
b: 184,
|
||||||
|
},
|
||||||
|
RGB {
|
||||||
|
r: 245,
|
||||||
|
g: 169,
|
||||||
|
b: 184,
|
||||||
|
},
|
||||||
|
RGB {
|
||||||
|
r: 245,
|
||||||
|
g: 169,
|
||||||
|
b: 184,
|
||||||
|
},
|
||||||
|
RGB {
|
||||||
|
r: 245,
|
||||||
|
g: 169,
|
||||||
|
b: 184,
|
||||||
|
},
|
||||||
|
RGB {
|
||||||
|
r: 245,
|
||||||
|
g: 169,
|
||||||
|
b: 184,
|
||||||
|
},
|
||||||
|
RGB {
|
||||||
|
r: 245,
|
||||||
|
g: 169,
|
||||||
|
b: 184,
|
||||||
|
},
|
||||||
|
RGB {
|
||||||
|
r: 255,
|
||||||
|
g: 255,
|
||||||
|
b: 255,
|
||||||
|
},
|
||||||
|
RGB {
|
||||||
|
r: 255,
|
||||||
|
g: 255,
|
||||||
|
b: 255,
|
||||||
|
},
|
||||||
|
RGB {
|
||||||
|
r: 255,
|
||||||
|
g: 255,
|
||||||
|
b: 255,
|
||||||
|
},
|
||||||
|
RGB {
|
||||||
|
r: 255,
|
||||||
|
g: 255,
|
||||||
|
b: 255,
|
||||||
|
},
|
||||||
|
RGB {
|
||||||
|
r: 255,
|
||||||
|
g: 255,
|
||||||
|
b: 255,
|
||||||
|
},
|
||||||
|
RGB {
|
||||||
|
r: 255,
|
||||||
|
g: 255,
|
||||||
|
b: 255,
|
||||||
|
},
|
||||||
|
RGB {
|
||||||
|
r: 255,
|
||||||
|
g: 255,
|
||||||
|
b: 255,
|
||||||
|
},
|
||||||
|
RGB {
|
||||||
|
r: 255,
|
||||||
|
g: 255,
|
||||||
|
b: 255,
|
||||||
|
},
|
||||||
|
RGB {
|
||||||
|
r: 255,
|
||||||
|
g: 255,
|
||||||
|
b: 255,
|
||||||
|
},
|
||||||
|
RGB {
|
||||||
|
r: 255,
|
||||||
|
g: 255,
|
||||||
|
b: 255,
|
||||||
|
},
|
||||||
|
RGB {
|
||||||
|
r: 255,
|
||||||
|
g: 255,
|
||||||
|
b: 255,
|
||||||
|
},
|
||||||
|
RGB {
|
||||||
|
r: 255,
|
||||||
|
g: 255,
|
||||||
|
b: 255,
|
||||||
|
},
|
||||||
|
RGB {
|
||||||
|
r: 245,
|
||||||
|
g: 169,
|
||||||
|
b: 184,
|
||||||
|
},
|
||||||
|
RGB {
|
||||||
|
r: 245,
|
||||||
|
g: 169,
|
||||||
|
b: 184,
|
||||||
|
},
|
||||||
|
RGB {
|
||||||
|
r: 245,
|
||||||
|
g: 169,
|
||||||
|
b: 184,
|
||||||
|
},
|
||||||
|
RGB {
|
||||||
|
r: 245,
|
||||||
|
g: 169,
|
||||||
|
b: 184,
|
||||||
|
},
|
||||||
|
RGB {
|
||||||
|
r: 245,
|
||||||
|
g: 169,
|
||||||
|
b: 184,
|
||||||
|
},
|
||||||
|
RGB {
|
||||||
|
r: 245,
|
||||||
|
g: 169,
|
||||||
|
b: 184,
|
||||||
|
},
|
||||||
|
RGB {
|
||||||
|
r: 245,
|
||||||
|
g: 169,
|
||||||
|
b: 184,
|
||||||
|
},
|
||||||
|
RGB {
|
||||||
|
r: 245,
|
||||||
|
g: 169,
|
||||||
|
b: 184,
|
||||||
|
},
|
||||||
|
RGB {
|
||||||
|
r: 245,
|
||||||
|
g: 169,
|
||||||
|
b: 184,
|
||||||
|
},
|
||||||
|
RGB {
|
||||||
|
r: 245,
|
||||||
|
g: 169,
|
||||||
|
b: 184,
|
||||||
|
},
|
||||||
|
RGB {
|
||||||
|
r: 245,
|
||||||
|
g: 169,
|
||||||
|
b: 184,
|
||||||
|
},
|
||||||
|
RGB {
|
||||||
|
r: 245,
|
||||||
|
g: 169,
|
||||||
|
b: 184,
|
||||||
|
},
|
||||||
|
RGB {
|
||||||
|
r: 91,
|
||||||
|
g: 206,
|
||||||
|
b: 250,
|
||||||
|
},
|
||||||
|
RGB {
|
||||||
|
r: 91,
|
||||||
|
g: 206,
|
||||||
|
b: 250,
|
||||||
|
},
|
||||||
|
RGB {
|
||||||
|
r: 91,
|
||||||
|
g: 206,
|
||||||
|
b: 250,
|
||||||
|
},
|
||||||
|
RGB {
|
||||||
|
r: 91,
|
||||||
|
g: 206,
|
||||||
|
b: 250,
|
||||||
|
},
|
||||||
|
RGB {
|
||||||
|
r: 91,
|
||||||
|
g: 206,
|
||||||
|
b: 250,
|
||||||
|
},
|
||||||
|
RGB {
|
||||||
|
r: 91,
|
||||||
|
g: 206,
|
||||||
|
b: 250,
|
||||||
|
},
|
||||||
|
RGB {
|
||||||
|
r: 91,
|
||||||
|
g: 206,
|
||||||
|
b: 250,
|
||||||
|
},
|
||||||
|
RGB {
|
||||||
|
r: 91,
|
||||||
|
g: 206,
|
||||||
|
b: 250,
|
||||||
|
},
|
||||||
|
RGB {
|
||||||
|
r: 91,
|
||||||
|
g: 206,
|
||||||
|
b: 250,
|
||||||
|
},
|
||||||
|
RGB {
|
||||||
|
r: 91,
|
||||||
|
g: 206,
|
||||||
|
b: 250,
|
||||||
|
},
|
||||||
|
RGB {
|
||||||
|
r: 91,
|
||||||
|
g: 206,
|
||||||
|
b: 250,
|
||||||
|
},
|
||||||
|
RGB {
|
||||||
|
r: 91,
|
||||||
|
g: 206,
|
||||||
|
b: 250,
|
||||||
|
},
|
||||||
|
];
|
|
@ -0,0 +1,9 @@
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct RGB {
|
||||||
|
pub r: u8,
|
||||||
|
pub g: u8,
|
||||||
|
pub b: u8,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub type DashboardPattern = [RGB; 3];
|
||||||
|
pub type Pattern = [RGB; 60];
|
|
@ -12,4 +12,5 @@ fixed = { version = "1" }
|
||||||
gio = { version = "0.18" }
|
gio = { version = "0.18" }
|
||||||
glib = { version = "0.18" }
|
glib = { version = "0.18" }
|
||||||
gtk = { version = "0.7", package = "gtk4", features = [ "v4_8" ] }
|
gtk = { version = "0.7", package = "gtk4", features = [ "v4_8" ] }
|
||||||
|
lights-core = { path = "../core" }
|
||||||
pango = { version = "*" }
|
pango = { version = "*" }
|
||||||
|
|
|
@ -1,19 +1,19 @@
|
||||||
use adw::prelude::*;
|
use adw::prelude::*;
|
||||||
use glib::Object;
|
use glib::{Object, Sender};
|
||||||
use gtk::subclass::prelude::*;
|
use gtk::subclass::prelude::*;
|
||||||
|
use lights_core::{App, DashboardPattern, Pattern, RGB, UI};
|
||||||
use std::{cell::RefCell, env, rc::Rc};
|
use std::{cell::RefCell, env, rc::Rc};
|
||||||
|
|
||||||
const WIDTH: i32 = 640;
|
const WIDTH: i32 = 640;
|
||||||
const HEIGHT: i32 = 480;
|
const HEIGHT: i32 = 480;
|
||||||
|
|
||||||
pub struct RGB {
|
pub struct Update {
|
||||||
pub r: u8,
|
dashboard: DashboardPattern,
|
||||||
pub g: u8,
|
lights: Pattern,
|
||||||
pub b: u8,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct DashboardLightsPrivate {
|
pub struct DashboardLightsPrivate {
|
||||||
lights: Rc<RefCell<[RGB; 3]>>,
|
lights: Rc<RefCell<DashboardPattern>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[glib::object_subclass]
|
#[glib::object_subclass]
|
||||||
|
@ -55,9 +55,9 @@ impl DashboardLights {
|
||||||
let lights = s.imp().lights.borrow();
|
let lights = s.imp().lights.borrow();
|
||||||
for i in 0..3 {
|
for i in 0..3 {
|
||||||
context.set_source_rgb(
|
context.set_source_rgb(
|
||||||
lights[i].r as f64,
|
lights[i].r as f64 / 256.,
|
||||||
lights[i].g as f64,
|
lights[i].g as f64 / 256.,
|
||||||
lights[i].b as f64,
|
lights[i].b as f64 / 256.,
|
||||||
);
|
);
|
||||||
context.rectangle(start + 100. * i as f64, 10., 80., 80.);
|
context.rectangle(start + 100. * i as f64, 10., 80., 80.);
|
||||||
let _ = context.fill();
|
let _ = context.fill();
|
||||||
|
@ -75,7 +75,7 @@ impl DashboardLights {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct BikeLightsPrivate {
|
pub struct BikeLightsPrivate {
|
||||||
lights: Rc<RefCell<[RGB; 60]>>,
|
lights: Rc<RefCell<Pattern>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[glib::object_subclass]
|
#[glib::object_subclass]
|
||||||
|
@ -173,18 +173,18 @@ impl BikeLights {
|
||||||
let lights = s.imp().lights.borrow();
|
let lights = s.imp().lights.borrow();
|
||||||
for i in 0..30 {
|
for i in 0..30 {
|
||||||
context.set_source_rgb(
|
context.set_source_rgb(
|
||||||
lights[i].r as f64,
|
lights[i].r as f64 / 256.,
|
||||||
lights[i].g as f64,
|
lights[i].g as f64 / 256.,
|
||||||
lights[i].b as f64,
|
lights[i].b as f64 / 256.,
|
||||||
);
|
);
|
||||||
context.rectangle(5. + 20. * i as f64, 5., 15., 15.);
|
context.rectangle(5. + 20. * i as f64, 5., 15., 15.);
|
||||||
let _ = context.fill();
|
let _ = context.fill();
|
||||||
}
|
}
|
||||||
for i in 0..30 {
|
for i in 0..30 {
|
||||||
context.set_source_rgb(
|
context.set_source_rgb(
|
||||||
lights[i + 30].r as f64,
|
lights[i + 30].r as f64 / 256.,
|
||||||
lights[i + 30].g as f64,
|
lights[i + 30].g as f64 / 256.,
|
||||||
lights[i + 30].b as f64,
|
lights[i + 30].b as f64 / 256.,
|
||||||
);
|
);
|
||||||
context.rectangle(5. + 20. * i as f64, 30., 15., 15.);
|
context.rectangle(5. + 20. * i as f64, 30., 15., 15.);
|
||||||
let _ = context.fill();
|
let _ = context.fill();
|
||||||
|
@ -201,14 +201,42 @@ impl BikeLights {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct GTKUI {
|
||||||
|
tx: Rc<RefCell<Option<Sender<Update>>>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl UI for GTKUI {
|
||||||
|
fn update_lights(&self, dashboard_lights: DashboardPattern, lights: Pattern) {
|
||||||
|
if let Some(tx) = self.tx.borrow().as_ref() {
|
||||||
|
tx.send(Update {
|
||||||
|
dashboard: dashboard_lights,
|
||||||
|
lights,
|
||||||
|
})
|
||||||
|
.unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let app = adw::Application::builder()
|
let adw_app = adw::Application::builder()
|
||||||
.application_id("com.luminescent-dreams.bike-light-simulator")
|
.application_id("com.luminescent-dreams.bike-light-simulator")
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
app.connect_activate(move |app| {
|
adw_app.connect_activate(move |adw_app| {
|
||||||
|
let (tx, rx) = gtk::glib::MainContext::channel::<Update>(gtk::glib::Priority::DEFAULT);
|
||||||
|
|
||||||
|
std::thread::spawn(move || {
|
||||||
|
let mut bike_app = App::new(Box::new(GTKUI {
|
||||||
|
tx: Rc::new(RefCell::new(Some(tx))),
|
||||||
|
}));
|
||||||
|
loop {
|
||||||
|
bike_app.tick(std::time::Duration::from_millis(0));
|
||||||
|
std::thread::sleep(std::time::Duration::from_millis(100));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
let window = adw::ApplicationWindow::builder()
|
let window = adw::ApplicationWindow::builder()
|
||||||
.application(app)
|
.application(adw_app)
|
||||||
.default_width(WIDTH)
|
.default_width(WIDTH)
|
||||||
.default_height(HEIGHT)
|
.default_height(HEIGHT)
|
||||||
.build();
|
.build();
|
||||||
|
@ -226,47 +254,6 @@ fn main() {
|
||||||
let brake_button = gtk::Button::builder().label("Brakes").build();
|
let brake_button = gtk::Button::builder().label("Brakes").build();
|
||||||
let right_button = gtk::Button::builder().label("R").build();
|
let right_button = gtk::Button::builder().label("R").build();
|
||||||
|
|
||||||
left_button.connect_clicked({
|
|
||||||
let dashboard_lights = dashboard_lights.clone();
|
|
||||||
move |_| {
|
|
||||||
dashboard_lights.set_lights([
|
|
||||||
RGB {
|
|
||||||
r: 128,
|
|
||||||
g: 128,
|
|
||||||
b: 0,
|
|
||||||
},
|
|
||||||
RGB { r: 0, g: 0, b: 0 },
|
|
||||||
RGB { r: 0, g: 0, b: 0 },
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
brake_button.connect_clicked({
|
|
||||||
let dashboard_lights = dashboard_lights.clone();
|
|
||||||
move |_| {
|
|
||||||
dashboard_lights.set_lights([
|
|
||||||
RGB { r: 128, g: 0, b: 0 },
|
|
||||||
RGB { r: 128, g: 0, b: 0 },
|
|
||||||
RGB { r: 128, g: 0, b: 0 },
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
right_button.connect_clicked({
|
|
||||||
let dashboard_lights = dashboard_lights.clone();
|
|
||||||
move |_| {
|
|
||||||
dashboard_lights.set_lights([
|
|
||||||
RGB { r: 0, g: 0, b: 0 },
|
|
||||||
RGB { r: 0, g: 0, b: 0 },
|
|
||||||
RGB {
|
|
||||||
r: 128,
|
|
||||||
g: 128,
|
|
||||||
b: 0,
|
|
||||||
},
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
controls.append(&left_button);
|
controls.append(&left_button);
|
||||||
controls.append(&brake_button);
|
controls.append(&brake_button);
|
||||||
controls.append(&right_button);
|
controls.append(&right_button);
|
||||||
|
@ -286,10 +273,20 @@ fn main() {
|
||||||
layout.append(&dashboard_lights);
|
layout.append(&dashboard_lights);
|
||||||
layout.append(&bike_lights);
|
layout.append(&bike_lights);
|
||||||
|
|
||||||
|
rx.attach(None, {
|
||||||
|
let dashboard_lights = dashboard_lights.clone();
|
||||||
|
let bike_lights = bike_lights.clone();
|
||||||
|
move |Update { dashboard, lights }| {
|
||||||
|
dashboard_lights.set_lights(dashboard);
|
||||||
|
bike_lights.set_lights(lights);
|
||||||
|
glib::ControlFlow::Continue
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
window.set_content(Some(&layout));
|
window.set_content(Some(&layout));
|
||||||
window.present();
|
window.present();
|
||||||
});
|
});
|
||||||
|
|
||||||
let args: Vec<String> = env::args().collect();
|
let args: Vec<String> = env::args().collect();
|
||||||
ApplicationExtManual::run_with_args(&app, &args);
|
ApplicationExtManual::run_with_args(&adw_app, &args);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue