use winit::keyboard::{Key, NamedKey};
use crate::{
EventQueue, GlobalEvent, PlaybackType,
coordinates::{CharPosition, CharRect, FONT_SIZE16, PixelRect},
draw_buffer::DrawBuffer,
pages::PagesEnum,
};
use super::{Dialog, DialogResponse};
enum Action {
Menu(Menu),
Page(PagesEnum),
Playback(PlaybackType),
// const data. Allows Recursing this inside the GlobalEvent
Event(fn() -> GlobalEvent),
// TODO: should be removed when it's all implemented
NotYetImplemented,
}
// Main missing, because it cant be opened from a menu
#[derive(Clone, Copy)]
enum Menu {
File,
Playback,
Sample,
Instrument,
Settings,
}
pub struct PageMenu {
name: &'static str,
rect: CharRect,
selected: u8,
pressed: bool,
buttons: &'static [(&'static str, Action)],
#[cfg(feature = "accesskit")]
node_id: accesskit::NodeId,
}
impl PageMenu {
const BACKGROUND_COLOR: u8 = 2;
const TOPLEFT_COLOR: u8 = 3;
const BOTRIGHT_COLOR: u8 = 1;
const fn new(
name: &'static str,
pos: CharPosition,
width: u8,
buttons: &'static [(&'static str, Action)],
#[cfg(feature = "accesskit")] node_id: accesskit::NodeId,
) -> Self {
let rect = CharRect::new(
pos.y(),
// TODO: const trait
pos.y() + 5 + (3 * buttons.len() as u8),
pos.x(),
pos.x() + width + 3,
);
Self {
name,
rect,
selected: 0,
pressed: false,
buttons,
#[cfg(feature = "accesskit")]
node_id,
}
}
fn draw_button_corners(rect: CharRect, draw_buffer: &mut DrawBuffer) {
// let framebuffer = &mut draw_buffer.framebuffer;
let pixel_rect = PixelRect::from(rect);
// draw top right corner
for y in 0..FONT_SIZE16 {
for x in y..FONT_SIZE16 {
draw_buffer.set(
pixel_rect.top() + y,
pixel_rect.right() - FONT_SIZE16 + x + 1,
Self::BOTRIGHT_COLOR,
);
}
}
// draw botleft corner
for y in 0..FONT_SIZE16 {
for x in 0..(FONT_SIZE16 - y) {
draw_buffer.set(
pixel_rect.bot() - y,
pixel_rect.left() + x,
Self::BOTRIGHT_COLOR,
);
}
}
}
fn draw(&self, has_child: bool, draw_buffer: &mut DrawBuffer) {
let top_left = self.rect.top_left();
let top = top_left.y();
let left = top_left.x();
draw_buffer.draw_rect(Self::BACKGROUND_COLOR, self.rect);
draw_buffer.draw_string(self.name, top_left + CharPosition::new(7, 2), 3, 2);
// self.draw_outer_box(draw_buffer);
draw_buffer.draw_out_border(self.rect, Self::TOPLEFT_COLOR, Self::TOPLEFT_COLOR, 2);
draw_buffer.draw_out_border(
CharRect::new(
self.rect.top() + 1,
self.rect.bot() - 1,
self.rect.left() + 1,
self.rect.right() - 1,
),
Self::BOTRIGHT_COLOR,
Self::BOTRIGHT_COLOR,
1,
);
for (num, (name, _)) in self.buttons.iter().enumerate() {
let num = u8::try_from(num).unwrap();
let text_color = match self.selected == num {
true => 11,
false => 0,
};
draw_buffer.draw_string(
name,
top_left + CharPosition::new(4, (3 * num) + 5),
text_color,
Self::BACKGROUND_COLOR,
);
let top = top + (3 * num) + 4;
let (top_left, bot_right) = match (self.pressed || has_child) && self.selected == num {
true => (Self::BOTRIGHT_COLOR, Self::TOPLEFT_COLOR),
false => (Self::TOPLEFT_COLOR, Self::BOTRIGHT_COLOR),
};
let rect = CharRect::new(top, top + 2, left + 2, left + self.rect.width() - 2);
draw_buffer.draw_out_border(rect, top_left, bot_right, 1);
Self::draw_button_corners(rect, draw_buffer);
}
}
fn process_input(
&mut self,
key_event: &winit::event::KeyEvent,
events: &mut EventQueue<'_>,
) -> (DialogResponse, Option