diff --git a/src/main.rs b/src/main.rs index fb91200..6dfbac8 100644 --- a/src/main.rs +++ b/src/main.rs @@ -49,7 +49,7 @@ fn run( .expect("Cannot add font"), }; - let beo = ui::Beo::new(); + let mut beo = ui::Beo::new(); for app in &beo.apps { println!(">> {}", app.name()); } @@ -81,6 +81,7 @@ fn run( match hw_event { Some(ev) => { println!("HW Event: {:?}", ev); + beo.accept_event(ev); } None => {} } @@ -153,7 +154,7 @@ fn run( let dpi_factor = window.scale_factor(); let size = window.inner_size(); canvas.set_size(size.width, size.height, dpi_factor as f32); - canvas.clear_rect(0, 0, size.width, size.height, Color::rgbf(0.9, 0.9, 0.9)); + canvas.clear_rect(0, 0, size.width, size.height, Color::rgbf(0., 0., 0.)); let elapsed = start.elapsed().as_secs_f32(); let now = Instant::now(); @@ -162,7 +163,8 @@ fn run( perf.update(dt); - draw_main_menu(&mut canvas, &fonts, &beo); + //draw_main_menu(&mut canvas, &fonts, &beo); + beo.draw(&mut canvas, &fonts); let mut paint = Paint::color(Color::hex("B7410E")); paint.set_font(&[fonts.bold]); @@ -227,48 +229,6 @@ fn run( }); } -fn draw_main_menu(canvas: &mut Canvas, fonts: &Fonts, beo: &ui::Beo) { - let canvas_width = canvas.width(); - let canvas_height = canvas.height(); - - // circle is centered on the right side of the screen - let main_menu_circle = roundy_math::VirtualCircle { - center: roundy_math::Point { - x: canvas_width as f64, - y: canvas_height as f64 / 2.0 + 10., - }, - //radius: canvas_width as f64 - 30.0, - radius: 400.0, - }; - - let canvas_size = roundy_math::Point { - x: canvas_width as f64, - y: canvas_height as f64, - }; - - let pts = main_menu_circle.get_equidistant_points(8, canvas_size); - for i in 0..pts.len() { - //println!(">>> {:?}", pts[i]); - let mut paint = Paint::color(Color::hex("B7410E")); - paint.set_font(&[fonts.bold]); - paint.set_text_baseline(Baseline::Top); - let _ = canvas.fill_text(pts[i].x as f32, pts[i].y as f32, format!("XX {i}"), &paint); - } - - /* - let mut y = 40.0; - for app in &beo.apps { - println!("{}", app.name()); - let mut paint = Paint::color(Color::hex("B7410E")); - paint.set_font(&[fonts.bold]); - paint.set_text_baseline(Baseline::Top); - paint.set_text_align(Align::Right); - let _ = canvas.fill_text(50.0, y, app.name(), &paint); - y += 20.0; - } - */ -} - fn draw_baselines( canvas: &mut Canvas, fonts: &Fonts, diff --git a/src/roundy_math.rs b/src/roundy_math.rs index 8e68c9d..a36ad2d 100644 --- a/src/roundy_math.rs +++ b/src/roundy_math.rs @@ -1,14 +1,13 @@ - #[derive(Debug)] pub struct Point { - pub x: f64, - pub y: f64, + pub x: f32, + pub y: f32, } pub struct VirtualCircle { pub center: Point, // radius of the circle in pixels - pub radius: f64, + pub radius: f32, } impl VirtualCircle { @@ -40,12 +39,12 @@ impl VirtualCircle { let mut points = Vec::new(); // Calculate the angle step to distribute points evenly - let angle_step = (intersection_angles.1 - intersection_angles.0) / (n as f64); + let angle_step = (intersection_angles.1 - intersection_angles.0) / (n as f32); //println!("angle step: {}", angle_step); // Generate the points for i in 0..n { - let theta = intersection_angles.0 + angle_step * (i as f64 + 0.5); + let theta = intersection_angles.0 + angle_step * (i as f32 + 0.5); let x = theta.sin() * self.radius + viewport_size.x; let y = theta.cos() * self.radius + viewport_size.y - self.center.y; points.push(Point { x, y }); @@ -53,4 +52,10 @@ impl VirtualCircle { points } + + pub fn get_x_on_circle(&self, y: f32) -> f32 { + // Given an x coordinate, return the y coordinate so that it lies on the circle + let x = self.center.x - (self.radius.powf(2.) - (y - self.center.y).powf(2.)).sqrt(); + x as f32 + } } diff --git a/src/ui.rs b/src/ui.rs index 26c8c1d..68e1bcd 100644 --- a/src/ui.rs +++ b/src/ui.rs @@ -1,5 +1,84 @@ +use femtovg::{Baseline, Canvas, Color, Paint, Path, Renderer}; + +use crate::{hid::Beo5Event, Fonts}; + +use crate::roundy_math; + pub struct Beo { pub apps: Vec>, + pub laser_pct: f32, +} + +impl Beo { + pub fn new() -> Beo { + Beo { + apps: get_apps(), + laser_pct: 0.0, + } + } + + pub fn accept_event(&mut self, event: Beo5Event) { + match event { + Beo5Event::LaserPosition(pct) => { + self.laser_pct = pct; + println!("Laser moved to {}%", pct * 100.); + } + _ => { + // TODO: pass event to current app + } + } + } + + pub fn draw(&self, canvas: &mut Canvas, fonts: &Fonts) { + self.draw_main_menu(canvas, fonts); + } + + fn draw_main_menu(&self, canvas: &mut Canvas, fonts: &Fonts) { + let canvas_width = canvas.width(); + let canvas_height = canvas.height(); + + // circle is centered on the right side of the screen + let main_menu_circle = roundy_math::VirtualCircle { + center: roundy_math::Point { + x: canvas_width as f32, + y: canvas_height as f32 / 2.0, + }, + radius: canvas_width as f32 - 30.0, + }; + + let canvas_size = roundy_math::Point { + x: canvas_width as f32, + y: canvas_height as f32, + }; + + // draw the main apps in the circle + let pts = main_menu_circle.get_equidistant_points(8, canvas_size); + for i in 0..pts.len() { + let mut paint = Paint::color(Color::hex("B7410E")); + paint.set_font(&[fonts.bold]); + paint.set_text_baseline(Baseline::Top); + let _ = canvas.fill_text(pts[i].x as f32, pts[i].y as f32, format!("XX {i}"), &paint); + } + + // draw the laser + let bg = Paint::linear_gradient( + 10., + canvas_height as f32 * self.laser_pct, + 20., + canvas_height as f32 * self.laser_pct + 20., + Color::rgba(255, 0, 0, 32), + Color::rgba(0, 0, 0, 16), + ); + + let ellipse_color = Paint::color(Color::hex("5C89D1")); + let mut path = Path::new(); + let ey = canvas_height as f32 * self.laser_pct; + let ex = main_menu_circle.get_x_on_circle(ey); + println!("ex: {}, ey: {}", ex, ey); + + path.ellipse(ex, ey, 10., 20.); + canvas.fill_path(&path, &ellipse_color); + } } pub trait App { @@ -19,12 +98,6 @@ impl App for Radio { } } -impl Beo { - pub fn new() -> Beo { - Beo { apps: get_apps() } - } -} - fn get_apps() -> Vec> { vec![Box::new(Spotify {}), Box::new(Radio {})] }