effing works

Signed-off-by: Frank Villaro-Dixon <frank@villaro-dixon.eu>
This commit is contained in:
Frank Villaro-Dixon 2024-05-09 01:15:58 +02:00
parent fa132e2230
commit 91172deddd
4 changed files with 170 additions and 50 deletions

View file

@ -2,9 +2,9 @@ pub struct BeoApps {
pub apps: Vec<Box<dyn App>>,
}
struct MainMenu {
pub last_id: usize,
pub default_id: usize,
pub struct MainMenu {
// Can either be the default, or the current
pub selected_id: usize,
pub names: Vec<String>,
}
@ -21,6 +21,7 @@ impl AppBase {
pub trait App {
fn base(&self) -> &AppBase;
fn base_mut(&mut self) -> &mut AppBase;
// fn main_menu(&self) -> &MainMenu;
}
@ -34,12 +35,15 @@ impl Spotify {
base: AppBase {
name: "Spotify".to_string(),
main_menu: MainMenu {
last_id: 0,
default_id: 0,
selected_id: 0,
names: vec![
"Playlists".to_string(),
"Artists".to_string(),
"Albums".to_string(),
"Songs".to_string(),
"Genres".to_string(),
"New Releases".to_string(),
"Charts".to_string(),
],
},
},
@ -51,6 +55,9 @@ impl App for Spotify {
fn base(&self) -> &AppBase {
&self.base
}
fn base_mut(&mut self) -> &mut AppBase {
&mut self.base
}
}
// Similar implementations for other apps like Radio and Settings
@ -64,8 +71,7 @@ impl Radio {
base: AppBase {
name: "Radio".to_string(),
main_menu: MainMenu {
last_id: 0,
default_id: 0,
selected_id: 0,
names: vec![
"Favorites".to_string(),
"Local".to_string(),
@ -81,6 +87,9 @@ impl App for Radio {
fn base(&self) -> &AppBase {
&self.base
}
fn base_mut(&mut self) -> &mut AppBase {
&mut self.base
}
}
struct Settings {
@ -93,8 +102,7 @@ impl Settings {
base: AppBase {
name: "Settings".to_string(),
main_menu: MainMenu {
last_id: 0,
default_id: 0,
selected_id: 0,
names: vec![
"Display".to_string(),
"Sound".to_string(),
@ -110,6 +118,9 @@ impl App for Settings {
fn base(&self) -> &AppBase {
&self.base
}
fn base_mut(&mut self) -> &mut AppBase {
&mut self.base
}
}
pub fn get_beo_apps() -> BeoApps {

View file

@ -133,23 +133,25 @@ impl Beo5Device {
_ => {}
}
}
evdev::InputEventKind::Switch(switch) => {
/*
evdev::InputEventKind::Key(switch) => {
match switch {
evdev::SwitchType::LE=> {
evdev::Key::BTN_DPAD_RIGHT => {
if ev.value() == 1 {
return Beo5Event::RightButtonPressed;
return Some(Beo5Event::RightButtonPressed);
} else {
return Beo5Event::RightButtonReleased;
return Some(Beo5Event::RightButtonReleased);
}
}
evdev::Switch::SW_LEFT => {
evdev::Key::BTN_DPAD_LEFT => {
if ev.value() == 1 {
return Beo5Event::LeftButtonPressed;
} else {
return Beo5Event::LeftButtonReleased;
if ev.value() == 1 {
return Some(Beo5Event::LeftButtonPressed);
} else {
return Some(Beo5Event::LeftButtonReleased);
}
}
}
/*
evdev::Switch::SW_GO => {
if ev.value() == 1 {
return Beo5Event::GoButtonPressed;
@ -164,12 +166,12 @@ impl Beo5Device {
return Beo5Event::PowerButtonReleased;
}
}
*/
// Shouldn't be any other switches
_ => {
panic!("Unknown switch event: {ev:?}")
}
}
*/
}
_ => {} //SYN et al
}

View file

@ -13,9 +13,13 @@ use winit::{
mod helpers;
use helpers::PerfGraph;
// XXX rename to smth else
struct Fonts {
sans: FontId,
bold: FontId,
app_title: Paint,
app_menu: Paint,
app_menu_selected: Paint,
}
fn main() {
@ -41,13 +45,36 @@ fn run(
surface: glutin::surface::Surface<glutin::surface::WindowSurface>,
window: Window,
) {
let font_bold = canvas
.add_font_mem(&resource!("assets/Roboto-Bold.ttf"))
.expect("Cannot add font");
let font_sans = canvas
.add_font_mem(&resource!("assets/Roboto-Regular.ttf"))
.expect("Cannot add font");
let mut app_title = Paint::color(Color::hex("FFFFFF"));
app_title.set_font(&[font_bold]);
app_title.set_text_baseline(Baseline::Top);
app_title.set_text_align(Align::Center);
app_title.set_font_size(20.);
let mut app_menu = Paint::color(Color::hex("F0F0FF"));
app_menu.set_font(&[font_sans]);
app_menu.set_text_baseline(Baseline::Top);
app_menu.set_text_align(Align::Center);
app_menu.set_font_size(14.);
let mut app_menu_selected = Paint::color(Color::hex("F0F0FF"));
app_menu_selected.set_font(&[font_bold]);
app_menu_selected.set_text_baseline(Baseline::Top);
app_menu_selected.set_text_align(Align::Center);
app_menu_selected.set_font_size(14.);
let fonts = Fonts {
sans: canvas
.add_font_mem(&resource!("assets/Roboto-Regular.ttf"))
.expect("Cannot add font"),
bold: canvas
.add_font_mem(&resource!("assets/Roboto-Bold.ttf"))
.expect("Cannot add font"),
sans: font_sans,
bold: font_bold,
app_title,
app_menu,
app_menu_selected,
};
let apps = get_beo_apps();

130
src/ui.rs
View file

@ -6,9 +6,14 @@ use crate::apps::{App, BeoApps};
use crate::roundy_math;
pub struct BeoUi {
pub beo_apps: BeoApps,
pub current_app_id: Option<usize>,
pub laser_pct: f32,
beo_apps: BeoApps,
current_app_id: Option<usize>,
// Basically the id of the current menu. However it is float, because
// it's UI and it will move smoothly on the screen.
// XXX for items in menu
//displayed_menu_item_id: Option<f32>,
laser_pct: f32, // XXX this could be removed as only used when laser moved, could be given to fn directly
}
const CANVAS_HEIGHT: f32 = 768.;
@ -36,6 +41,18 @@ impl BeoUi {
self.laser_pct = pct;
self.choose_app_from_laser_pct();
}
Beo5Event::LeftButtonPressed => {
println!("Left button pressed");
if let Some(selected_app) = self.current_app_mut() {
selected_app.base_mut().main_menu.selected_id += 1;
}
}
Beo5Event::RightButtonPressed => {
println!("Right button pressed");
if let Some(selected_app) = self.current_app_mut() {
selected_app.base_mut().main_menu.selected_id -= 1;
}
}
_ => {
// TODO: pass event to current app
}
@ -44,18 +61,9 @@ impl BeoUi {
pub fn draw<T: Renderer>(&self, canvas: &mut Canvas<T>, fonts: &Fonts) {
self.draw_main_menu(canvas, fonts);
if let Some(selected_app) = self.current_app() {
let mut paint_title = Paint::color(Color::hex("FFFFFF"));
paint_title.set_font(&[fonts.bold]);
paint_title.set_text_baseline(Baseline::Top);
paint_title.set_text_align(Align::Center);
paint_title.set_font_size(20.);
let _ = canvas.fill_text(
CANVAS_WIDTH / 2.,
10.,
selected_app.base().name(),
&paint_title,
);
self.draw_app(canvas, fonts, selected_app);
}
}
@ -75,7 +83,6 @@ impl BeoUi {
if delta < LASER_EPS_MATCH {
self.current_app_id = Some(i);
return;
//Some(&self.beo_apps.apps[i]);
}
}
self.current_app_id = None;
@ -84,6 +91,9 @@ impl BeoUi {
fn current_app(&self) -> Option<&Box<dyn App>> {
self.current_app_id.map(|id| &self.beo_apps.apps[id])
}
fn current_app_mut(&mut self) -> Option<&mut Box<dyn App>> {
self.current_app_id.map(|id| &mut self.beo_apps.apps[id])
}
fn draw_main_menu<T: Renderer>(&self, canvas: &mut Canvas<T>, fonts: &Fonts) {
let canvas_width = canvas.width();
@ -103,10 +113,11 @@ impl BeoUi {
y: canvas_height as f32,
};
let apps = &self.beo_apps.apps;
// draw the main apps in the circle
let apps = &self.beo_apps.apps;
let pts = main_menu_circle.get_equidistant_points(apps.len(), canvas_size);
// XXX To be taken from global struct
let mut paint_normal = Paint::color(Color::hex("B7410E"));
paint_normal.set_font(&[fonts.sans]);
paint_normal.set_text_baseline(Baseline::Top);
@ -115,15 +126,16 @@ impl BeoUi {
paint_selected.set_font(&[fonts.bold]);
paint_selected.set_text_baseline(Baseline::Top);
let mut i = 0;
for app in apps {
//if self.current_app == Some(app) {
// let _ =
// canvas.fill_text(pts[i].x, pts[i].y, apps[i].base().name(), &paint_selected);
//} else {
let _ = canvas.fill_text(pts[i].x, pts[i].y, app.base().name(), &paint_normal);
// }
i += 1;
for appid in 0..apps.len() {
let paint;
if self.current_app_id == Some(appid) {
paint = &paint_selected;
} else {
paint = &paint_normal;
}
let app = &apps[appid];
let _ = canvas.fill_text(pts[appid].x, pts[appid].y, app.base().name(), paint);
}
// draw the laser
@ -135,4 +147,72 @@ impl BeoUi {
path.ellipse(ex + 15., ey, 30., 10.);
canvas.fill_path(&path, &ellipse_color);
}
fn draw_app<T: Renderer>(&self, canvas: &mut Canvas<T>, fonts: &Fonts, app: &Box<dyn App>) {
/*
let biggest_menu_name = app
.base()
.main_menu
.names
.iter()
.max_by_key(|x| x.len())
.unwrap();
let menu_separated_px = biggest_menu_name.len() as f32 * 8.;
*/
let num_menu_elements_before = 1;
let num_menu_elements_after = 2;
// That means max 1 + >1< + 2 = 4 elements in total
// Minimum aronud 3: 0 + >1< + 2
let current_menu_id = app.base().main_menu.selected_id;
let menu_elements = &app.base().main_menu.names;
// Calculate indices for slices
let start_before =
(current_menu_id as isize - num_menu_elements_before as isize).max(0) as usize;
let end_before = current_menu_id;
let start_after = current_menu_id + 1;
let end_after =
((current_menu_id + 1 + num_menu_elements_after).min(menu_elements.len())) as usize;
// Safely getting slices using clamping
let menu_elems_before = &menu_elements[start_before..end_before];
let menu_elem_selected = &menu_elements[current_menu_id];
let menu_elems_after = &menu_elements[start_after..end_after];
//println!("menu_elems_before: {:?}", menu_elems_before);
//println!("current_menu: {:?}", menu_elem_selected);
//println!("menu_elems_after: {:?}", menu_elems_after);
let mut toti = 0.;
for i in 0..menu_elems_before.len() {
let _ = canvas.fill_text(
toti * 100. + 50.,
CANVAS_HEIGHT - 80.,
&menu_elems_before[i],
&fonts.app_menu,
);
toti += 1.;
}
let _ = canvas.fill_text(
toti * 100. + 50.,
CANVAS_HEIGHT - 80.,
&menu_elem_selected,
&fonts.app_menu_selected,
);
toti += 1.;
for i in 0..menu_elems_after.len() {
let _ = canvas.fill_text(
toti * 100. + 50.,
CANVAS_HEIGHT - 80.,
&menu_elems_after[i],
&fonts.app_menu,
);
toti += 1.;
}
}
}