Compare commits
No commits in common. "7d6413c91d026bf801fcdee3d978818076edb81d" and "8b53114d0dd88c3d32d5954f85bd0d4196150dcc" have entirely different histories.
7d6413c91d
...
8b53114d0d
|
@ -165,12 +165,6 @@ version = "1.1.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
|
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "az"
|
|
||||||
version = "1.2.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "7b7e4c2464d97fe331d41de9d5db0def0a96f4d823b8b32a2efd503578988973"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "backtrace"
|
name = "backtrace"
|
||||||
version = "0.3.69"
|
version = "0.3.69"
|
||||||
|
@ -966,18 +960,6 @@ version = "1.2.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8fcfdc7a0362c9f4444381a9e697c79d435fe65b52a37466fc2c1184cee9edc6"
|
checksum = "8fcfdc7a0362c9f4444381a9e697c79d435fe65b52a37466fc2c1184cee9edc6"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "fixed"
|
|
||||||
version = "1.24.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "02c69ce7e7c0f17aa18fdd9d0de39727adb9c6281f2ad12f57cbe54ae6e76e7d"
|
|
||||||
dependencies = [
|
|
||||||
"az",
|
|
||||||
"bytemuck",
|
|
||||||
"half",
|
|
||||||
"typenum",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "flate2"
|
name = "flate2"
|
||||||
version = "1.0.27"
|
version = "1.0.27"
|
||||||
|
@ -2173,10 +2155,6 @@ dependencies = [
|
||||||
"vcpkg",
|
"vcpkg",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "lights-core"
|
|
||||||
version = "0.1.0"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "linux-raw-sys"
|
name = "linux-raw-sys"
|
||||||
version = "0.4.8"
|
version = "0.4.8"
|
||||||
|
@ -3627,20 +3605,6 @@ version = "0.3.7"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe"
|
checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "simulator"
|
|
||||||
version = "0.1.0"
|
|
||||||
dependencies = [
|
|
||||||
"cairo-rs",
|
|
||||||
"fixed",
|
|
||||||
"gio",
|
|
||||||
"glib",
|
|
||||||
"gtk4",
|
|
||||||
"libadwaita",
|
|
||||||
"lights-core",
|
|
||||||
"pango",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "siphasher"
|
name = "siphasher"
|
||||||
version = "0.2.3"
|
version = "0.2.3"
|
||||||
|
|
|
@ -2,8 +2,6 @@
|
||||||
resolver = "2"
|
resolver = "2"
|
||||||
members = [
|
members = [
|
||||||
"authdb",
|
"authdb",
|
||||||
"bike-lights/core",
|
|
||||||
"bike-lights/simulator",
|
|
||||||
"changeset",
|
"changeset",
|
||||||
"config",
|
"config",
|
||||||
"config-derive",
|
"config-derive",
|
||||||
|
|
|
@ -1,8 +0,0 @@
|
||||||
[package]
|
|
||||||
name = "lights-core"
|
|
||||||
version = "0.1.0"
|
|
||||||
edition = "2021"
|
|
||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
|
||||||
|
|
||||||
[dependencies]
|
|
|
@ -1,347 +0,0 @@
|
||||||
mod patterns;
|
|
||||||
pub use patterns::*;
|
|
||||||
|
|
||||||
mod types;
|
|
||||||
pub use types::{DashboardPattern, Pattern, RGB};
|
|
||||||
|
|
||||||
pub const FPS: u8 = 30;
|
|
||||||
|
|
||||||
pub trait UI {
|
|
||||||
fn check_event(&self) -> Option<Event>;
|
|
||||||
fn update_lights(&self, dashboard_lights: DashboardPattern, lights: Pattern);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub trait Animation {
|
|
||||||
fn tick(&mut self, time: std::time::Instant) -> (DashboardPattern, Pattern);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct DefaultAnimation {}
|
|
||||||
|
|
||||||
impl Animation for DefaultAnimation {
|
|
||||||
fn tick(&mut self, _: std::time::Instant) -> (DashboardPattern, Pattern) {
|
|
||||||
(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)]
|
|
||||||
pub enum Event {
|
|
||||||
Brake,
|
|
||||||
BrakeRelease,
|
|
||||||
LeftBlinker,
|
|
||||||
NextPattern,
|
|
||||||
PreviousPattern,
|
|
||||||
RightBlinker,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, PartialEq)]
|
|
||||||
pub enum State {
|
|
||||||
Pattern(u8),
|
|
||||||
Brake,
|
|
||||||
LeftBlinker,
|
|
||||||
RightBlinker,
|
|
||||||
BrakeLeftBlinker,
|
|
||||||
BrakeRightBlinker,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct App {
|
|
||||||
ui: Box<dyn UI>,
|
|
||||||
state: State,
|
|
||||||
home_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),
|
|
||||||
home_state: State::Pattern(0),
|
|
||||||
current_animation: Box::new(DefaultAnimation {}),
|
|
||||||
dashboard_lights: OFF_DASHBOARD,
|
|
||||||
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) {
|
|
||||||
match self.ui.check_event() {
|
|
||||||
Some(event) => {
|
|
||||||
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);
|
|
||||||
self.dashboard_lights = dashboard.clone();
|
|
||||||
self.lights = lights.clone();
|
|
||||||
self.ui.update_lights(dashboard, lights);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,939 +0,0 @@
|
||||||
use crate::RGB;
|
|
||||||
|
|
||||||
pub type DashboardPattern = [RGB<u8>; 3];
|
|
||||||
pub type Pattern = [RGB<u8>; 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 DEFAULT_FRAMES: u8 = 30;
|
|
||||||
|
|
||||||
pub const PRIDE_DASHBOARD: DashboardPattern = [
|
|
||||||
RGB { r: 228, g: 3, b: 3 },
|
|
||||||
RGB {
|
|
||||||
r: 0,
|
|
||||||
g: 128,
|
|
||||||
b: 38,
|
|
||||||
},
|
|
||||||
RGB {
|
|
||||||
r: 36,
|
|
||||||
g: 64,
|
|
||||||
b: 142,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
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,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
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 +0,0 @@
|
||||||
#[derive(Clone, Default, Debug)]
|
|
||||||
pub struct RGB<T> {
|
|
||||||
pub r: T,
|
|
||||||
pub g: T,
|
|
||||||
pub b: T,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub type DashboardPattern = [RGB<u8>; 3];
|
|
||||||
pub type Pattern = [RGB<u8>; 60];
|
|
|
@ -1,16 +0,0 @@
|
||||||
[package]
|
|
||||||
name = "simulator"
|
|
||||||
version = "0.1.0"
|
|
||||||
edition = "2021"
|
|
||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
|
||||||
|
|
||||||
[dependencies]
|
|
||||||
adw = { version = "0.5", package = "libadwaita", features = [ "v1_2" ] }
|
|
||||||
cairo-rs = { version = "0.18" }
|
|
||||||
fixed = { version = "1" }
|
|
||||||
gio = { version = "0.18" }
|
|
||||||
glib = { version = "0.18" }
|
|
||||||
gtk = { version = "0.7", package = "gtk4", features = [ "v4_8" ] }
|
|
||||||
lights-core = { path = "../core" }
|
|
||||||
pango = { version = "*" }
|
|
|
@ -1,343 +0,0 @@
|
||||||
use adw::prelude::*;
|
|
||||||
use glib::{Object, Sender};
|
|
||||||
use gtk::subclass::prelude::*;
|
|
||||||
use lights_core::{App, DashboardPattern, Event, Pattern, FPS, RGB, UI};
|
|
||||||
use std::{
|
|
||||||
cell::RefCell,
|
|
||||||
env,
|
|
||||||
rc::Rc,
|
|
||||||
sync::mpsc::{Receiver, TryRecvError},
|
|
||||||
};
|
|
||||||
|
|
||||||
const WIDTH: i32 = 640;
|
|
||||||
const HEIGHT: i32 = 480;
|
|
||||||
|
|
||||||
pub struct Update {
|
|
||||||
dashboard: DashboardPattern,
|
|
||||||
lights: Pattern,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct DashboardLightsPrivate {
|
|
||||||
lights: Rc<RefCell<DashboardPattern>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[glib::object_subclass]
|
|
||||||
impl ObjectSubclass for DashboardLightsPrivate {
|
|
||||||
const NAME: &'static str = "DashboardLights";
|
|
||||||
type Type = DashboardLights;
|
|
||||||
type ParentType = gtk::DrawingArea;
|
|
||||||
|
|
||||||
fn new() -> Self {
|
|
||||||
Self {
|
|
||||||
lights: Rc::new(RefCell::new([
|
|
||||||
RGB { r: 0, g: 0, b: 0 },
|
|
||||||
RGB { r: 0, g: 0, b: 0 },
|
|
||||||
RGB { r: 0, g: 0, b: 0 },
|
|
||||||
])),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ObjectImpl for DashboardLightsPrivate {}
|
|
||||||
impl WidgetImpl for DashboardLightsPrivate {}
|
|
||||||
impl DrawingAreaImpl for DashboardLightsPrivate {}
|
|
||||||
|
|
||||||
glib::wrapper! {
|
|
||||||
pub struct DashboardLights(ObjectSubclass<DashboardLightsPrivate>) @extends gtk::DrawingArea, gtk::Widget;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl DashboardLights {
|
|
||||||
pub fn new() -> Self {
|
|
||||||
let s: Self = Object::builder().build();
|
|
||||||
|
|
||||||
s.set_width_request(WIDTH);
|
|
||||||
s.set_height_request(100);
|
|
||||||
|
|
||||||
s.set_draw_func({
|
|
||||||
let s = s.clone();
|
|
||||||
move |_, context, width, _| {
|
|
||||||
let start = width as f64 / 2. - 150.;
|
|
||||||
let lights = s.imp().lights.borrow();
|
|
||||||
for i in 0..3 {
|
|
||||||
context.set_source_rgb(
|
|
||||||
lights[i].r as f64 / 256.,
|
|
||||||
lights[i].g as f64 / 256.,
|
|
||||||
lights[i].b as f64 / 256.,
|
|
||||||
);
|
|
||||||
context.rectangle(start + 100. * i as f64, 10., 80., 80.);
|
|
||||||
let _ = context.fill();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
s
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn set_lights(&self, lights: [RGB<u8>; 3]) {
|
|
||||||
*self.imp().lights.borrow_mut() = lights;
|
|
||||||
self.queue_draw();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct BikeLightsPrivate {
|
|
||||||
lights: Rc<RefCell<Pattern>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[glib::object_subclass]
|
|
||||||
impl ObjectSubclass for BikeLightsPrivate {
|
|
||||||
const NAME: &'static str = "BikeLights";
|
|
||||||
type Type = BikeLights;
|
|
||||||
type ParentType = gtk::DrawingArea;
|
|
||||||
|
|
||||||
fn new() -> Self {
|
|
||||||
Self {
|
|
||||||
lights: Rc::new(RefCell::new([
|
|
||||||
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 },
|
|
||||||
])),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ObjectImpl for BikeLightsPrivate {}
|
|
||||||
impl WidgetImpl for BikeLightsPrivate {}
|
|
||||||
impl DrawingAreaImpl for BikeLightsPrivate {}
|
|
||||||
|
|
||||||
glib::wrapper! {
|
|
||||||
pub struct BikeLights(ObjectSubclass<BikeLightsPrivate>) @extends gtk::DrawingArea, gtk::Widget;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl BikeLights {
|
|
||||||
pub fn new() -> Self {
|
|
||||||
let s: Self = Object::builder().build();
|
|
||||||
|
|
||||||
s.set_width_request(WIDTH);
|
|
||||||
s.set_height_request(200);
|
|
||||||
|
|
||||||
s.set_draw_func({
|
|
||||||
let s = s.clone();
|
|
||||||
move |_, context, _, _| {
|
|
||||||
let lights = s.imp().lights.borrow();
|
|
||||||
for i in 0..30 {
|
|
||||||
context.set_source_rgb(
|
|
||||||
lights[i].r as f64 / 256.,
|
|
||||||
lights[i].g as f64 / 256.,
|
|
||||||
lights[i].b as f64 / 256.,
|
|
||||||
);
|
|
||||||
context.rectangle(5. + 20. * i as f64, 5., 15., 15.);
|
|
||||||
let _ = context.fill();
|
|
||||||
}
|
|
||||||
for i in 0..30 {
|
|
||||||
context.set_source_rgb(
|
|
||||||
lights[i + 30].r as f64 / 256.,
|
|
||||||
lights[i + 30].g as f64 / 256.,
|
|
||||||
lights[i + 30].b as f64 / 256.,
|
|
||||||
);
|
|
||||||
context.rectangle(5. + 20. * i as f64, 30., 15., 15.);
|
|
||||||
let _ = context.fill();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
s
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn set_lights(&self, lights: [RGB<u8>; 60]) {
|
|
||||||
*self.imp().lights.borrow_mut() = lights;
|
|
||||||
self.queue_draw();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct GTKUI {
|
|
||||||
tx: Sender<Update>,
|
|
||||||
rx: Receiver<Event>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl UI for GTKUI {
|
|
||||||
fn check_event(&self) -> Option<Event> {
|
|
||||||
match self.rx.try_recv() {
|
|
||||||
Ok(event) => Some(event),
|
|
||||||
Err(TryRecvError::Empty) => None,
|
|
||||||
Err(TryRecvError::Disconnected) => None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn update_lights(&self, dashboard_lights: DashboardPattern, lights: Pattern) {
|
|
||||||
self.tx
|
|
||||||
.send(Update {
|
|
||||||
dashboard: dashboard_lights,
|
|
||||||
lights,
|
|
||||||
})
|
|
||||||
.unwrap();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
let adw_app = adw::Application::builder()
|
|
||||||
.application_id("com.luminescent-dreams.bike-light-simulator")
|
|
||||||
.build();
|
|
||||||
|
|
||||||
adw_app.connect_activate(move |adw_app| {
|
|
||||||
let (update_tx, update_rx) =
|
|
||||||
gtk::glib::MainContext::channel::<Update>(gtk::glib::Priority::DEFAULT);
|
|
||||||
let (event_tx, event_rx) = std::sync::mpsc::channel();
|
|
||||||
|
|
||||||
std::thread::spawn(move || {
|
|
||||||
let mut bike_app = App::new(Box::new(GTKUI {
|
|
||||||
tx: update_tx,
|
|
||||||
rx: event_rx,
|
|
||||||
}));
|
|
||||||
loop {
|
|
||||||
bike_app.tick(std::time::Instant::now());
|
|
||||||
std::thread::sleep(std::time::Duration::from_millis(1000 / (FPS as u64)));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
let window = adw::ApplicationWindow::builder()
|
|
||||||
.application(adw_app)
|
|
||||||
.default_width(WIDTH)
|
|
||||||
.default_height(HEIGHT)
|
|
||||||
.build();
|
|
||||||
let layout = gtk::Box::builder()
|
|
||||||
.orientation(gtk::Orientation::Vertical)
|
|
||||||
.build();
|
|
||||||
let controls = gtk::Box::builder()
|
|
||||||
.orientation(gtk::Orientation::Horizontal)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
let dashboard_lights = DashboardLights::new();
|
|
||||||
let bike_lights = BikeLights::new();
|
|
||||||
|
|
||||||
let left_button = gtk::Button::builder().label("L").build();
|
|
||||||
let brake_button = gtk::Button::builder().label("Brakes").build();
|
|
||||||
let right_button = gtk::Button::builder().label("R").build();
|
|
||||||
|
|
||||||
left_button.connect_clicked({
|
|
||||||
let event_tx = event_tx.clone();
|
|
||||||
move |_| {
|
|
||||||
let _ = event_tx.send(Event::LeftBlinker);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
brake_button.connect_clicked({
|
|
||||||
let event_tx = event_tx.clone();
|
|
||||||
move |_| {
|
|
||||||
let _ = event_tx.send(Event::Brake);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
right_button.connect_clicked({
|
|
||||||
let event_tx = event_tx.clone();
|
|
||||||
move |_| {
|
|
||||||
let _ = event_tx.send(Event::RightBlinker);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
controls.append(&left_button);
|
|
||||||
controls.append(&brake_button);
|
|
||||||
controls.append(&right_button);
|
|
||||||
layout.append(&controls);
|
|
||||||
|
|
||||||
let pattern_controls = gtk::Box::builder()
|
|
||||||
.orientation(gtk::Orientation::Horizontal)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
let previous_pattern = gtk::Button::builder().label("Previous").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(&next_pattern);
|
|
||||||
layout.append(&pattern_controls);
|
|
||||||
|
|
||||||
layout.append(&dashboard_lights);
|
|
||||||
layout.append(&bike_lights);
|
|
||||||
|
|
||||||
update_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.present();
|
|
||||||
});
|
|
||||||
|
|
||||||
let args: Vec<String> = env::args().collect();
|
|
||||||
ApplicationExtManual::run_with_args(&adw_app, &args);
|
|
||||||
}
|
|
Loading…
Reference in New Issue