Something went wrong. Try again.
This repository has no description
Something went wrong. Try again.
8.5 kB · 253 lines
Rust
at main
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254mod help_page;pub mod order_list;pub mod pattern;mod sample_list;mod song_directory_config_page;
use help_page::HelpPage;use order_list::{OrderListPage, OrderListPageEvent};use pattern::{PatternPage, PatternPageEvent};use sample_list::SampleList;use song_directory_config_page::{SDCChange, SongDirectoryConfigPage};use winit::{ event::{KeyEvent, Modifiers}, event_loop::EventLoopProxy, keyboard::{Key, NamedKey},};
use crate::{ EventQueue, GlobalEvent, coordinates::{CharPosition, CharRect, WINDOW_SIZE_CHARS}, draw_buffer::DrawBuffer, pages::sample_list::SampleListEvent,};
pub trait Page { fn draw(&mut self, draw_buffer: &mut DrawBuffer); fn draw_constant(&mut self, draw_buffer: &mut DrawBuffer);
fn process_key_event( &mut self, modifiers: &Modifiers, key_event: &KeyEvent, // please give me reborrowing for custom structs rustc :3 events: &mut EventQueue<'_>, ) -> PageResponse;
#[cfg(feature = "accesskit")] fn build_tree( &self, tree: &mut Vec<(accesskit::NodeId, accesskit::Node)>, ) -> crate::AccessResponse;}
pub enum PageResponse { RequestRedraw, None,}
#[derive(Clone, Copy, PartialEq, Eq, Debug)]pub enum PagesEnum { Help, SongDirectoryConfig, Pattern, OrderList, SampleList,}
#[derive(Debug, Clone)]pub enum PageEvent { Sdc(SDCChange), Pattern(PatternPageEvent), OrderList(OrderListPageEvent), SampleList(SampleListEvent),}
impl PageEvent { fn get_page(&self) -> PagesEnum { match self { PageEvent::Sdc(_) => PagesEnum::SongDirectoryConfig, PageEvent::Pattern(_) => PagesEnum::Pattern, PageEvent::OrderList(_) => PagesEnum::OrderList, PageEvent::SampleList(_) => PagesEnum::SampleList, } }}
pub struct AllPages { help: HelpPage, song_directory_config: SongDirectoryConfigPage, pattern: PatternPage, order_list: OrderListPage, sample_list: SampleList,
const_draw_needed: bool, current: PagesEnum,}
impl AllPages { pub fn new(proxy: EventLoopProxy<GlobalEvent>) -> Self { AllPages { help: HelpPage::new(), song_directory_config: SongDirectoryConfigPage::new(), pattern: PatternPage::new(proxy.clone()), current: PagesEnum::SongDirectoryConfig, order_list: OrderListPage::new(), const_draw_needed: true, sample_list: SampleList::new(proxy), } }
fn get_title(&self) -> &'static str { match self.current { PagesEnum::Help => "Help", PagesEnum::SongDirectoryConfig => "Song Variables & Directory Configuration (F12)", PagesEnum::Pattern => "Pattern Editor (F2)", PagesEnum::OrderList => match self.order_list.mode() { order_list::Mode::Volume => "Order List and Channel Volume (F11)", order_list::Mode::Panning => "Order List and Panning (F11)", }, PagesEnum::SampleList => "Sample List (F3)", } }
fn get_page(&self) -> &dyn Page { match self.current { PagesEnum::Help => &self.help, PagesEnum::SongDirectoryConfig => &self.song_directory_config, PagesEnum::Pattern => &self.pattern, PagesEnum::OrderList => &self.order_list, PagesEnum::SampleList => &self.sample_list, } }
fn get_page_mut(&mut self) -> &mut dyn Page { match self.current { PagesEnum::Help => &mut self.help, PagesEnum::SongDirectoryConfig => &mut self.song_directory_config, PagesEnum::Pattern => &mut self.pattern, PagesEnum::OrderList => &mut self.order_list, PagesEnum::SampleList => &mut self.sample_list, } }
/// requests a redraw if it is needed pub fn switch_page(&mut self, next_page: PagesEnum) -> PageResponse { if next_page != self.current { // when switching to the OrderListPage, reset to the pan mode if next_page == PagesEnum::OrderList { self.order_list.reset_mode(); } self.current = next_page; self.request_draw_const(); PageResponse::RequestRedraw } else { PageResponse::None } }
pub fn request_draw_const(&mut self) { self.const_draw_needed = true; }
pub fn draw(&mut self, draw_buffer: &mut DrawBuffer) { if self.const_draw_needed { self.draw_constant(draw_buffer); } self.get_page_mut().draw(draw_buffer); }
pub fn draw_constant(&mut self, draw_buffer: &mut DrawBuffer) { // draw page title let title = self.get_title(); let title_len = u8::try_from(title.len()).expect("title doesn't fit on the page"); let middle = WINDOW_SIZE_CHARS.0 / 2; let str_start = middle - (title_len / 2); draw_buffer.draw_string(title, CharPosition::new(str_start, 11), 0, 2); const DOTTED: [u8; 8] = [0, 0, 0, 0b01010101, 0, 0, 0, 0]; draw_buffer.draw_rect(2, CharRect::new(11, 11, str_start - 1, str_start - 1)); draw_buffer.draw_rect( 2, CharRect::new(11, 11, str_start + title_len, str_start + title_len), ); for x in 1..=(str_start - 2) { draw_buffer.draw_char(DOTTED, CharPosition::new(x, 11), 1, 2); } for x in (str_start + title_len + 1)..=(WINDOW_SIZE_CHARS.0 - 2) { draw_buffer.draw_char(DOTTED, CharPosition::new(x, 11), 1, 2); } // draw page const self.get_page_mut().draw_constant(draw_buffer); self.const_draw_needed = false; }
// add key_events for changing pages here pub fn process_key_event( &mut self, modifiers: &Modifiers, key_event: &KeyEvent, events: &mut EventQueue<'_>, ) -> PageResponse { if key_event.state.is_pressed() && modifiers.state().is_empty() { if key_event.logical_key == Key::Named(NamedKey::F1) { self.switch_page(PagesEnum::Help); return PageResponse::RequestRedraw; } else if key_event.logical_key == Key::Named(NamedKey::F2) { self.switch_page(PagesEnum::Pattern); return PageResponse::RequestRedraw; } else if key_event.logical_key == Key::Named(NamedKey::F11) { if self.current == PagesEnum::OrderList { self.order_list.switch_mode(); self.request_draw_const(); return PageResponse::RequestRedraw; } else { self.switch_page(PagesEnum::OrderList); return PageResponse::RequestRedraw; } } else if key_event.logical_key == Key::Named(NamedKey::F12) { self.switch_page(PagesEnum::SongDirectoryConfig); return PageResponse::RequestRedraw; } else if key_event.logical_key == Key::Named(NamedKey::F3) { self.switch_page(PagesEnum::SampleList); return PageResponse::RequestRedraw; } }
self.get_page_mut() .process_key_event(modifiers, key_event, events) }
pub fn process_page_event( &mut self, event: PageEvent, events: &mut EventQueue<'_>, ) -> PageResponse { let page = event.get_page(); let response = match event { PageEvent::Sdc(change) => self.song_directory_config.ui_change(change), PageEvent::Pattern(event) => self.pattern.process_event(event, events), PageEvent::OrderList(event) => self.order_list.process_event(event), PageEvent::SampleList(event) => self.sample_list.process_event(event, events), };
// if the page isn't shown a redraw isn't necessary if page == self.current { response } else { PageResponse::None } }
#[cfg(feature = "accesskit")] pub fn build_tree( &self, tree: &mut Vec<(accesskit::NodeId, accesskit::Node)>, ) -> crate::AccessResponse { self.get_page().build_tree(tree) }
#[cfg(feature = "accesskit")] pub fn process_accesskit_event(&mut self, _event: accesskit::ActionRequest) -> PageResponse { todo!() }}