Set up a bunch of animations and some state transitions!
This commit is contained in:
parent
06aedc34bb
commit
0bb5e62f96
|
@ -1,28 +1,213 @@
|
||||||
use std::time::Duration;
|
|
||||||
|
|
||||||
mod patterns;
|
mod patterns;
|
||||||
pub use patterns::*;
|
pub use patterns::*;
|
||||||
|
|
||||||
mod types;
|
mod types;
|
||||||
pub use types::{DashboardPattern, Pattern, RGB};
|
pub use types::{DashboardPattern, Pattern, RGB};
|
||||||
|
|
||||||
|
pub const FPS: u8 = 30;
|
||||||
|
|
||||||
pub trait UI {
|
pub trait UI {
|
||||||
fn check_event(&self) -> Option<Event>;
|
fn check_event(&self) -> Option<Event>;
|
||||||
fn update_lights(&self, dashboard_lights: DashboardPattern, lights: Pattern);
|
fn update_lights(&self, dashboard_lights: DashboardPattern, lights: Pattern);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait Animation {
|
pub trait Animation {
|
||||||
fn tick(&self, time: std::time::Instant) -> (DashboardPattern, Pattern);
|
fn tick(&mut self, time: std::time::Instant) -> (DashboardPattern, Pattern);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct DefaultAnimation {}
|
pub struct DefaultAnimation {}
|
||||||
|
|
||||||
impl Animation for DefaultAnimation {
|
impl Animation for DefaultAnimation {
|
||||||
fn tick(&self, time: std::time::Instant) -> (DashboardPattern, Pattern) {
|
fn tick(&mut self, _: std::time::Instant) -> (DashboardPattern, Pattern) {
|
||||||
(PRIDE_DASHBOARD, PRIDE)
|
(PRIDE_DASHBOARD, PRIDE)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct Fade {
|
||||||
|
starting_dashboard: DashboardPattern,
|
||||||
|
starting_lights: Pattern,
|
||||||
|
|
||||||
|
start_time: std::time::Instant,
|
||||||
|
dashboard_slope: Vec<RGB<f64>>,
|
||||||
|
body_slope: Vec<RGB<f64>>,
|
||||||
|
frames: u8,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Fade {
|
||||||
|
fn new(
|
||||||
|
dashboard: DashboardPattern,
|
||||||
|
lights: Pattern,
|
||||||
|
ending_dashboard: DashboardPattern,
|
||||||
|
ending_lights: Pattern,
|
||||||
|
frames: u8,
|
||||||
|
time: std::time::Instant,
|
||||||
|
) -> Self {
|
||||||
|
let mut dashboard_slope = Vec::new();
|
||||||
|
let mut body_slope = Vec::new();
|
||||||
|
for i in 0..3 {
|
||||||
|
let slope = RGB {
|
||||||
|
r: (ending_dashboard[i].r as f64 - dashboard[i].r as f64) / frames as f64,
|
||||||
|
g: (ending_dashboard[i].g as f64 - dashboard[i].g as f64) / frames as f64,
|
||||||
|
b: (ending_dashboard[i].b as f64 - dashboard[i].b as f64) / frames as f64,
|
||||||
|
};
|
||||||
|
dashboard_slope.push(slope);
|
||||||
|
}
|
||||||
|
|
||||||
|
for i in 0..60 {
|
||||||
|
let slope = RGB {
|
||||||
|
r: (ending_lights[i].r as f64 - lights[i].r as f64) / frames as f64,
|
||||||
|
g: (ending_lights[i].g as f64 - lights[i].g as f64) / frames as f64,
|
||||||
|
b: (ending_lights[i].b as f64 - lights[i].b as f64) / frames as f64,
|
||||||
|
};
|
||||||
|
body_slope.push(slope);
|
||||||
|
}
|
||||||
|
|
||||||
|
println!("dashboard slope: {:?}", dashboard_slope);
|
||||||
|
|
||||||
|
Self {
|
||||||
|
starting_dashboard: dashboard,
|
||||||
|
starting_lights: lights,
|
||||||
|
start_time: time,
|
||||||
|
dashboard_slope,
|
||||||
|
body_slope,
|
||||||
|
frames,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Animation for Fade {
|
||||||
|
fn tick(&mut self, time: std::time::Instant) -> (DashboardPattern, Pattern) {
|
||||||
|
let mut frames: u8 = ((time - self.start_time).as_millis() as f64 / FPS as f64) as u8;
|
||||||
|
if frames > self.frames {
|
||||||
|
frames = self.frames
|
||||||
|
}
|
||||||
|
let mut dashboard_pattern: DashboardPattern = OFF_DASHBOARD;
|
||||||
|
let mut body_pattern: Pattern = OFF;
|
||||||
|
|
||||||
|
let apply = |value: f64, frames: f64, slope: f64| -> f64 { value + frames * slope };
|
||||||
|
|
||||||
|
for i in 0..3 {
|
||||||
|
dashboard_pattern[i].r = apply(
|
||||||
|
self.starting_dashboard[i].r as f64,
|
||||||
|
frames as f64,
|
||||||
|
self.dashboard_slope[i].r as f64,
|
||||||
|
) as u8;
|
||||||
|
dashboard_pattern[i].g = apply(
|
||||||
|
self.starting_dashboard[i].g as f64,
|
||||||
|
frames as f64,
|
||||||
|
self.dashboard_slope[i].g as f64,
|
||||||
|
) as u8;
|
||||||
|
dashboard_pattern[i].b = apply(
|
||||||
|
self.starting_dashboard[i].b as f64,
|
||||||
|
frames as f64,
|
||||||
|
self.dashboard_slope[i].b as f64,
|
||||||
|
) as u8;
|
||||||
|
}
|
||||||
|
|
||||||
|
for i in 0..60 {
|
||||||
|
body_pattern[i].r = apply(
|
||||||
|
self.starting_lights[i].r as f64,
|
||||||
|
frames as f64,
|
||||||
|
self.body_slope[i].r as f64,
|
||||||
|
) as u8;
|
||||||
|
body_pattern[i].g = apply(
|
||||||
|
self.starting_lights[i].g as f64,
|
||||||
|
frames as f64,
|
||||||
|
self.body_slope[i].g as f64,
|
||||||
|
) as u8;
|
||||||
|
body_pattern[i].b = apply(
|
||||||
|
self.starting_lights[i].b as f64,
|
||||||
|
frames as f64,
|
||||||
|
self.body_slope[i].b as f64,
|
||||||
|
) as u8;
|
||||||
|
}
|
||||||
|
|
||||||
|
(dashboard_pattern, body_pattern)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum FadeDirection {
|
||||||
|
FadeIn,
|
||||||
|
FadeOut,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct LeftBlinker {
|
||||||
|
fade_in: Fade,
|
||||||
|
fade_out: Fade,
|
||||||
|
direction: FadeDirection,
|
||||||
|
|
||||||
|
start_time: std::time::Instant,
|
||||||
|
frames: u8,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl LeftBlinker {
|
||||||
|
fn new(
|
||||||
|
starting_dashboard: DashboardPattern,
|
||||||
|
starting_body: Pattern,
|
||||||
|
time: std::time::Instant,
|
||||||
|
) -> Self {
|
||||||
|
let mut ending_dashboard = starting_dashboard.clone();
|
||||||
|
ending_dashboard[0].r = LEFT_DASHBOARD[0].r;
|
||||||
|
ending_dashboard[0].g = LEFT_DASHBOARD[0].g;
|
||||||
|
ending_dashboard[0].b = LEFT_DASHBOARD[0].b;
|
||||||
|
|
||||||
|
let mut ending_body = starting_body.clone();
|
||||||
|
for i in 0..30 {
|
||||||
|
ending_body[i].r = LEFT[i].r;
|
||||||
|
ending_body[i].g = LEFT[i].g;
|
||||||
|
ending_body[i].b = LEFT[i].b;
|
||||||
|
}
|
||||||
|
|
||||||
|
LeftBlinker {
|
||||||
|
fade_in: Fade::new(
|
||||||
|
starting_dashboard.clone(),
|
||||||
|
starting_body.clone(),
|
||||||
|
ending_dashboard.clone(),
|
||||||
|
ending_body.clone(),
|
||||||
|
LEFT_FRAMES,
|
||||||
|
time,
|
||||||
|
),
|
||||||
|
fade_out: Fade::new(
|
||||||
|
ending_dashboard.clone(),
|
||||||
|
ending_body.clone(),
|
||||||
|
starting_dashboard.clone(),
|
||||||
|
starting_body.clone(),
|
||||||
|
LEFT_FRAMES,
|
||||||
|
time,
|
||||||
|
),
|
||||||
|
direction: FadeDirection::FadeIn,
|
||||||
|
start_time: time,
|
||||||
|
frames: LEFT_FRAMES,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Animation for LeftBlinker {
|
||||||
|
fn tick(&mut self, time: std::time::Instant) -> (DashboardPattern, Pattern) {
|
||||||
|
let frames: u8 = ((time - self.start_time).as_millis() as f64 / FPS as f64) as u8;
|
||||||
|
if frames > self.frames {
|
||||||
|
match self.direction {
|
||||||
|
FadeDirection::FadeIn => {
|
||||||
|
self.direction = FadeDirection::FadeOut;
|
||||||
|
self.fade_out.start_time = time;
|
||||||
|
}
|
||||||
|
FadeDirection::FadeOut => {
|
||||||
|
self.direction = FadeDirection::FadeIn;
|
||||||
|
self.fade_in.start_time = time;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self.start_time = time;
|
||||||
|
}
|
||||||
|
println!("anim: {:?} {}", self.direction, frames);
|
||||||
|
|
||||||
|
match self.direction {
|
||||||
|
FadeDirection::FadeIn => self.fade_in.tick(time),
|
||||||
|
FadeDirection::FadeOut => self.fade_out.tick(time),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub enum Event {
|
pub enum Event {
|
||||||
Brake,
|
Brake,
|
||||||
|
@ -33,7 +218,7 @@ pub enum Event {
|
||||||
RightBlinker,
|
RightBlinker,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone, PartialEq)]
|
||||||
pub enum State {
|
pub enum State {
|
||||||
Pattern(u8),
|
Pattern(u8),
|
||||||
Brake,
|
Brake,
|
||||||
|
@ -46,6 +231,7 @@ pub enum State {
|
||||||
pub struct App {
|
pub struct App {
|
||||||
ui: Box<dyn UI>,
|
ui: Box<dyn UI>,
|
||||||
state: State,
|
state: State,
|
||||||
|
home_state: State,
|
||||||
current_animation: Box<dyn Animation>,
|
current_animation: Box<dyn Animation>,
|
||||||
dashboard_lights: DashboardPattern,
|
dashboard_lights: DashboardPattern,
|
||||||
lights: Pattern,
|
lights: Pattern,
|
||||||
|
@ -56,17 +242,103 @@ impl App {
|
||||||
Self {
|
Self {
|
||||||
ui,
|
ui,
|
||||||
state: State::Pattern(0),
|
state: State::Pattern(0),
|
||||||
|
home_state: State::Pattern(0),
|
||||||
current_animation: Box::new(DefaultAnimation {}),
|
current_animation: Box::new(DefaultAnimation {}),
|
||||||
dashboard_lights: OFF_DASHBOARD,
|
dashboard_lights: OFF_DASHBOARD,
|
||||||
lights: OFF,
|
lights: OFF,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn update_state(&mut self, time: std::time::Instant) {
|
||||||
|
match self.state {
|
||||||
|
State::Pattern(0) => {
|
||||||
|
self.current_animation = Box::new(Fade::new(
|
||||||
|
self.dashboard_lights.clone(),
|
||||||
|
self.lights.clone(),
|
||||||
|
PRIDE_DASHBOARD,
|
||||||
|
PRIDE,
|
||||||
|
DEFAULT_FRAMES,
|
||||||
|
time,
|
||||||
|
))
|
||||||
|
}
|
||||||
|
State::Pattern(1) => {
|
||||||
|
self.current_animation = Box::new(Fade::new(
|
||||||
|
self.dashboard_lights.clone(),
|
||||||
|
self.lights.clone(),
|
||||||
|
TRANS_PRIDE_DASHBOARD,
|
||||||
|
TRANS_PRIDE,
|
||||||
|
DEFAULT_FRAMES,
|
||||||
|
time,
|
||||||
|
))
|
||||||
|
}
|
||||||
|
State::Pattern(_) => {}
|
||||||
|
State::Brake => {
|
||||||
|
self.current_animation = Box::new(Fade::new(
|
||||||
|
self.dashboard_lights.clone(),
|
||||||
|
self.lights.clone(),
|
||||||
|
BRAKE_DASHBOARD,
|
||||||
|
BRAKES,
|
||||||
|
BRAKE_FRAMES,
|
||||||
|
time,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
State::LeftBlinker => {
|
||||||
|
self.current_animation = Box::new(LeftBlinker::new(
|
||||||
|
self.dashboard_lights.clone(),
|
||||||
|
self.lights.clone(),
|
||||||
|
time,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
State::RightBlinker => (),
|
||||||
|
State::BrakeLeftBlinker => (),
|
||||||
|
State::BrakeRightBlinker => (),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn tick(&mut self, time: std::time::Instant) {
|
pub fn tick(&mut self, time: std::time::Instant) {
|
||||||
match self.ui.check_event() {
|
match self.ui.check_event() {
|
||||||
Some(event) => println!("event received: {:?}", event),
|
Some(event) => {
|
||||||
None => (),
|
match event {
|
||||||
|
Event::Brake => {
|
||||||
|
if self.state == State::Brake {
|
||||||
|
self.state = self.home_state.clone();
|
||||||
|
} else {
|
||||||
|
self.state = State::Brake;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Event::BrakeRelease => self.state = State::Pattern(0),
|
||||||
|
Event::LeftBlinker => match self.state {
|
||||||
|
State::Brake => self.state = State::BrakeLeftBlinker,
|
||||||
|
State::BrakeLeftBlinker => self.state = State::Brake,
|
||||||
|
State::LeftBlinker => self.state = self.home_state.clone(),
|
||||||
|
_ => self.state = State::LeftBlinker,
|
||||||
|
},
|
||||||
|
Event::NextPattern => match self.state {
|
||||||
|
State::Pattern(i) => {
|
||||||
|
let next = i + 1;
|
||||||
|
self.state = State::Pattern(if next > 1 { 0 } else { next });
|
||||||
|
self.home_state = self.state.clone();
|
||||||
|
}
|
||||||
|
_ => (),
|
||||||
|
},
|
||||||
|
Event::PreviousPattern => match self.state {
|
||||||
|
State::Pattern(i) => {
|
||||||
|
if i == 0 {
|
||||||
|
self.state = State::Pattern(1);
|
||||||
|
} else {
|
||||||
|
self.state = State::Pattern(i - 1);
|
||||||
|
}
|
||||||
|
self.home_state = self.state.clone();
|
||||||
|
}
|
||||||
|
_ => (),
|
||||||
|
},
|
||||||
|
Event::RightBlinker => {}
|
||||||
|
}
|
||||||
|
self.update_state(time);
|
||||||
|
}
|
||||||
|
None => {}
|
||||||
};
|
};
|
||||||
|
|
||||||
let (dashboard, lights) = self.current_animation.tick(time);
|
let (dashboard, lights) = self.current_animation.tick(time);
|
||||||
self.dashboard_lights = dashboard.clone();
|
self.dashboard_lights = dashboard.clone();
|
||||||
self.lights = lights.clone();
|
self.lights = lights.clone();
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use crate::RGB;
|
use crate::RGB;
|
||||||
|
|
||||||
pub type DashboardPattern = [RGB; 3];
|
pub type DashboardPattern = [RGB<u8>; 3];
|
||||||
pub type Pattern = [RGB; 60];
|
pub type Pattern = [RGB<u8>; 60];
|
||||||
|
|
||||||
pub const OFF_DASHBOARD: DashboardPattern = [
|
pub const OFF_DASHBOARD: DashboardPattern = [
|
||||||
RGB { r: 0, g: 0, b: 0 },
|
RGB { r: 0, g: 0, b: 0 },
|
||||||
|
@ -72,17 +72,19 @@ pub const OFF: Pattern = [
|
||||||
RGB { r: 0, g: 0, b: 0 },
|
RGB { r: 0, g: 0, b: 0 },
|
||||||
];
|
];
|
||||||
|
|
||||||
|
pub const DEFAULT_FRAMES: u8 = 30;
|
||||||
|
|
||||||
pub const PRIDE_DASHBOARD: DashboardPattern = [
|
pub const PRIDE_DASHBOARD: DashboardPattern = [
|
||||||
RGB { r: 228, g: 3, b: 3 },
|
RGB { r: 228, g: 3, b: 3 },
|
||||||
RGB {
|
RGB {
|
||||||
r: 255,
|
r: 0,
|
||||||
g: 237,
|
g: 128,
|
||||||
b: 0,
|
b: 38,
|
||||||
},
|
},
|
||||||
RGB {
|
RGB {
|
||||||
r: 115,
|
r: 36,
|
||||||
g: 41,
|
g: 64,
|
||||||
b: 130,
|
b: 142,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
@ -669,3 +671,269 @@ pub const TRANS_PRIDE: Pattern = [
|
||||||
b: 250,
|
b: 250,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
pub const BRAKE_FRAMES: u8 = 15;
|
||||||
|
|
||||||
|
pub const BRAKE_DASHBOARD: DashboardPattern = [
|
||||||
|
RGB { r: 128, g: 0, b: 0 },
|
||||||
|
RGB { r: 128, g: 0, b: 0 },
|
||||||
|
RGB { r: 128, g: 0, b: 0 },
|
||||||
|
];
|
||||||
|
|
||||||
|
pub const BRAKES: Pattern = [
|
||||||
|
RGB { r: 128, g: 0, b: 0 },
|
||||||
|
RGB { r: 128, g: 0, b: 0 },
|
||||||
|
RGB { r: 128, g: 0, b: 0 },
|
||||||
|
RGB { r: 128, g: 0, b: 0 },
|
||||||
|
RGB { r: 128, g: 0, b: 0 },
|
||||||
|
RGB { r: 128, g: 0, b: 0 },
|
||||||
|
RGB { r: 128, g: 0, b: 0 },
|
||||||
|
RGB { r: 128, g: 0, b: 0 },
|
||||||
|
RGB { r: 128, g: 0, b: 0 },
|
||||||
|
RGB { r: 128, g: 0, b: 0 },
|
||||||
|
RGB { r: 128, g: 0, b: 0 },
|
||||||
|
RGB { r: 128, g: 0, b: 0 },
|
||||||
|
RGB { r: 128, g: 0, b: 0 },
|
||||||
|
RGB { r: 128, g: 0, b: 0 },
|
||||||
|
RGB { r: 128, g: 0, b: 0 },
|
||||||
|
RGB { r: 128, g: 0, b: 0 },
|
||||||
|
RGB { r: 128, g: 0, b: 0 },
|
||||||
|
RGB { r: 128, g: 0, b: 0 },
|
||||||
|
RGB { r: 128, g: 0, b: 0 },
|
||||||
|
RGB { r: 128, g: 0, b: 0 },
|
||||||
|
RGB { r: 128, g: 0, b: 0 },
|
||||||
|
RGB { r: 128, g: 0, b: 0 },
|
||||||
|
RGB { r: 128, g: 0, b: 0 },
|
||||||
|
RGB { r: 128, g: 0, b: 0 },
|
||||||
|
RGB { r: 128, g: 0, b: 0 },
|
||||||
|
RGB { r: 128, g: 0, b: 0 },
|
||||||
|
RGB { r: 128, g: 0, b: 0 },
|
||||||
|
RGB { r: 128, g: 0, b: 0 },
|
||||||
|
RGB { r: 128, g: 0, b: 0 },
|
||||||
|
RGB { r: 128, g: 0, b: 0 },
|
||||||
|
RGB { r: 128, g: 0, b: 0 },
|
||||||
|
RGB { r: 128, g: 0, b: 0 },
|
||||||
|
RGB { r: 128, g: 0, b: 0 },
|
||||||
|
RGB { r: 128, g: 0, b: 0 },
|
||||||
|
RGB { r: 128, g: 0, b: 0 },
|
||||||
|
RGB { r: 128, g: 0, b: 0 },
|
||||||
|
RGB { r: 128, g: 0, b: 0 },
|
||||||
|
RGB { r: 128, g: 0, b: 0 },
|
||||||
|
RGB { r: 128, g: 0, b: 0 },
|
||||||
|
RGB { r: 128, g: 0, b: 0 },
|
||||||
|
RGB { r: 128, g: 0, b: 0 },
|
||||||
|
RGB { r: 128, g: 0, b: 0 },
|
||||||
|
RGB { r: 128, g: 0, b: 0 },
|
||||||
|
RGB { r: 128, g: 0, b: 0 },
|
||||||
|
RGB { r: 128, g: 0, b: 0 },
|
||||||
|
RGB { r: 128, g: 0, b: 0 },
|
||||||
|
RGB { r: 128, g: 0, b: 0 },
|
||||||
|
RGB { r: 128, g: 0, b: 0 },
|
||||||
|
RGB { r: 128, g: 0, b: 0 },
|
||||||
|
RGB { r: 128, g: 0, b: 0 },
|
||||||
|
RGB { r: 128, g: 0, b: 0 },
|
||||||
|
RGB { r: 128, g: 0, b: 0 },
|
||||||
|
RGB { r: 128, g: 0, b: 0 },
|
||||||
|
RGB { r: 128, g: 0, b: 0 },
|
||||||
|
RGB { r: 128, g: 0, b: 0 },
|
||||||
|
RGB { r: 128, g: 0, b: 0 },
|
||||||
|
RGB { r: 128, g: 0, b: 0 },
|
||||||
|
RGB { r: 128, g: 0, b: 0 },
|
||||||
|
RGB { r: 128, g: 0, b: 0 },
|
||||||
|
RGB { r: 128, g: 0, b: 0 },
|
||||||
|
];
|
||||||
|
|
||||||
|
pub const LEFT_FRAMES: u8 = 15;
|
||||||
|
|
||||||
|
pub const LEFT_DASHBOARD: DashboardPattern = [
|
||||||
|
RGB {
|
||||||
|
r: 255,
|
||||||
|
g: 191,
|
||||||
|
b: 0,
|
||||||
|
},
|
||||||
|
RGB { r: 0, g: 0, b: 0 },
|
||||||
|
RGB { r: 0, g: 0, b: 0 },
|
||||||
|
];
|
||||||
|
|
||||||
|
pub const LEFT: Pattern = [
|
||||||
|
RGB {
|
||||||
|
r: 255,
|
||||||
|
g: 191,
|
||||||
|
b: 0,
|
||||||
|
},
|
||||||
|
RGB {
|
||||||
|
r: 255,
|
||||||
|
g: 191,
|
||||||
|
b: 0,
|
||||||
|
},
|
||||||
|
RGB {
|
||||||
|
r: 255,
|
||||||
|
g: 191,
|
||||||
|
b: 0,
|
||||||
|
},
|
||||||
|
RGB {
|
||||||
|
r: 255,
|
||||||
|
g: 191,
|
||||||
|
b: 0,
|
||||||
|
},
|
||||||
|
RGB {
|
||||||
|
r: 255,
|
||||||
|
g: 191,
|
||||||
|
b: 0,
|
||||||
|
},
|
||||||
|
RGB {
|
||||||
|
r: 255,
|
||||||
|
g: 191,
|
||||||
|
b: 0,
|
||||||
|
},
|
||||||
|
RGB {
|
||||||
|
r: 255,
|
||||||
|
g: 191,
|
||||||
|
b: 0,
|
||||||
|
},
|
||||||
|
RGB {
|
||||||
|
r: 255,
|
||||||
|
g: 191,
|
||||||
|
b: 0,
|
||||||
|
},
|
||||||
|
RGB {
|
||||||
|
r: 255,
|
||||||
|
g: 191,
|
||||||
|
b: 0,
|
||||||
|
},
|
||||||
|
RGB {
|
||||||
|
r: 255,
|
||||||
|
g: 191,
|
||||||
|
b: 0,
|
||||||
|
},
|
||||||
|
RGB {
|
||||||
|
r: 255,
|
||||||
|
g: 191,
|
||||||
|
b: 0,
|
||||||
|
},
|
||||||
|
RGB {
|
||||||
|
r: 255,
|
||||||
|
g: 191,
|
||||||
|
b: 0,
|
||||||
|
},
|
||||||
|
RGB {
|
||||||
|
r: 255,
|
||||||
|
g: 191,
|
||||||
|
b: 0,
|
||||||
|
},
|
||||||
|
RGB {
|
||||||
|
r: 255,
|
||||||
|
g: 191,
|
||||||
|
b: 0,
|
||||||
|
},
|
||||||
|
RGB {
|
||||||
|
r: 255,
|
||||||
|
g: 191,
|
||||||
|
b: 0,
|
||||||
|
},
|
||||||
|
RGB {
|
||||||
|
r: 255,
|
||||||
|
g: 191,
|
||||||
|
b: 0,
|
||||||
|
},
|
||||||
|
RGB {
|
||||||
|
r: 255,
|
||||||
|
g: 191,
|
||||||
|
b: 0,
|
||||||
|
},
|
||||||
|
RGB {
|
||||||
|
r: 255,
|
||||||
|
g: 191,
|
||||||
|
b: 0,
|
||||||
|
},
|
||||||
|
RGB {
|
||||||
|
r: 255,
|
||||||
|
g: 191,
|
||||||
|
b: 0,
|
||||||
|
},
|
||||||
|
RGB {
|
||||||
|
r: 255,
|
||||||
|
g: 191,
|
||||||
|
b: 0,
|
||||||
|
},
|
||||||
|
RGB {
|
||||||
|
r: 255,
|
||||||
|
g: 191,
|
||||||
|
b: 0,
|
||||||
|
},
|
||||||
|
RGB {
|
||||||
|
r: 255,
|
||||||
|
g: 191,
|
||||||
|
b: 0,
|
||||||
|
},
|
||||||
|
RGB {
|
||||||
|
r: 255,
|
||||||
|
g: 191,
|
||||||
|
b: 0,
|
||||||
|
},
|
||||||
|
RGB {
|
||||||
|
r: 255,
|
||||||
|
g: 191,
|
||||||
|
b: 0,
|
||||||
|
},
|
||||||
|
RGB {
|
||||||
|
r: 255,
|
||||||
|
g: 191,
|
||||||
|
b: 0,
|
||||||
|
},
|
||||||
|
RGB {
|
||||||
|
r: 255,
|
||||||
|
g: 191,
|
||||||
|
b: 0,
|
||||||
|
},
|
||||||
|
RGB {
|
||||||
|
r: 255,
|
||||||
|
g: 191,
|
||||||
|
b: 0,
|
||||||
|
},
|
||||||
|
RGB {
|
||||||
|
r: 255,
|
||||||
|
g: 191,
|
||||||
|
b: 0,
|
||||||
|
},
|
||||||
|
RGB {
|
||||||
|
r: 255,
|
||||||
|
g: 191,
|
||||||
|
b: 0,
|
||||||
|
},
|
||||||
|
RGB {
|
||||||
|
r: 255,
|
||||||
|
g: 191,
|
||||||
|
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 },
|
||||||
|
];
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
#[derive(Clone)]
|
#[derive(Clone, Default, Debug)]
|
||||||
pub struct RGB {
|
pub struct RGB<T> {
|
||||||
pub r: u8,
|
pub r: T,
|
||||||
pub g: u8,
|
pub g: T,
|
||||||
pub b: u8,
|
pub b: T,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type DashboardPattern = [RGB; 3];
|
pub type DashboardPattern = [RGB<u8>; 3];
|
||||||
pub type Pattern = [RGB; 60];
|
pub type Pattern = [RGB<u8>; 60];
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use adw::prelude::*;
|
use adw::prelude::*;
|
||||||
use glib::{Object, Sender};
|
use glib::{Object, Sender};
|
||||||
use gtk::subclass::prelude::*;
|
use gtk::subclass::prelude::*;
|
||||||
use lights_core::{App, DashboardPattern, Event, Pattern, RGB, UI};
|
use lights_core::{App, DashboardPattern, Event, Pattern, FPS, RGB, UI};
|
||||||
use std::{
|
use std::{
|
||||||
cell::RefCell,
|
cell::RefCell,
|
||||||
env,
|
env,
|
||||||
|
@ -73,7 +73,7 @@ impl DashboardLights {
|
||||||
s
|
s
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_lights(&self, lights: [RGB; 3]) {
|
pub fn set_lights(&self, lights: [RGB<u8>; 3]) {
|
||||||
*self.imp().lights.borrow_mut() = lights;
|
*self.imp().lights.borrow_mut() = lights;
|
||||||
self.queue_draw();
|
self.queue_draw();
|
||||||
}
|
}
|
||||||
|
@ -200,7 +200,7 @@ impl BikeLights {
|
||||||
s
|
s
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_lights(&self, lights: [RGB; 60]) {
|
pub fn set_lights(&self, lights: [RGB<u8>; 60]) {
|
||||||
*self.imp().lights.borrow_mut() = lights;
|
*self.imp().lights.borrow_mut() = lights;
|
||||||
self.queue_draw();
|
self.queue_draw();
|
||||||
}
|
}
|
||||||
|
@ -247,7 +247,7 @@ fn main() {
|
||||||
}));
|
}));
|
||||||
loop {
|
loop {
|
||||||
bike_app.tick(std::time::Instant::now());
|
bike_app.tick(std::time::Instant::now());
|
||||||
std::thread::sleep(std::time::Duration::from_millis(100));
|
std::thread::sleep(std::time::Duration::from_millis(1000 / (FPS as u64)));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -303,6 +303,20 @@ fn main() {
|
||||||
let previous_pattern = gtk::Button::builder().label("Previous").build();
|
let previous_pattern = gtk::Button::builder().label("Previous").build();
|
||||||
let next_pattern = gtk::Button::builder().label("Next").build();
|
let next_pattern = gtk::Button::builder().label("Next").build();
|
||||||
|
|
||||||
|
previous_pattern.connect_clicked({
|
||||||
|
let event_tx = event_tx.clone();
|
||||||
|
move |_| {
|
||||||
|
let _ = event_tx.send(Event::PreviousPattern);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
next_pattern.connect_clicked({
|
||||||
|
let event_tx = event_tx.clone();
|
||||||
|
move |_| {
|
||||||
|
let _ = event_tx.send(Event::NextPattern);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
pattern_controls.append(&previous_pattern);
|
pattern_controls.append(&previous_pattern);
|
||||||
pattern_controls.append(&next_pattern);
|
pattern_controls.append(&next_pattern);
|
||||||
layout.append(&pattern_controls);
|
layout.append(&pattern_controls);
|
||||||
|
|
Loading…
Reference in New Issue