#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)] pub enum Page { #[default] Main, Patterns, Engine, Help, Dict, Options, } impl Page { /// All pages for iteration pub const ALL: &'static [Page] = &[ Page::Main, Page::Patterns, Page::Engine, Page::Help, Page::Dict, Page::Options, ]; /// Grid dimensions (cols, rows) pub const GRID_SIZE: (i8, i8) = (3, 2); /// Grid position (col, row) for each page /// Layout: /// col 0 col 1 col 2 /// row 0 Dict Patterns Options /// row 1 Help Sequencer Engine pub const fn grid_pos(self) -> (i8, i8) { match self { Page::Dict => (0, 0), Page::Help => (0, 1), Page::Patterns => (1, 0), Page::Main => (1, 1), Page::Options => (2, 0), Page::Engine => (2, 1), } } /// Find page at grid position, if any pub fn at_pos(col: i8, row: i8) -> Option { Self::ALL.iter().copied().find(|p| p.grid_pos() == (col, row)) } /// Display name for the page pub const fn name(self) -> &'static str { match self { Page::Main => "Sequencer", Page::Patterns => "Patterns", Page::Engine => "Engine", Page::Help => "Help", Page::Dict => "Dict", Page::Options => "Options", } } pub fn left(&mut self) { let (col, row) = self.grid_pos(); for offset in 1..=Self::GRID_SIZE.0 { let new_col = (col - offset).rem_euclid(Self::GRID_SIZE.0); if let Some(page) = Self::at_pos(new_col, row) { *self = page; return; } } } pub fn right(&mut self) { let (col, row) = self.grid_pos(); for offset in 1..=Self::GRID_SIZE.0 { let new_col = (col + offset).rem_euclid(Self::GRID_SIZE.0); if let Some(page) = Self::at_pos(new_col, row) { *self = page; return; } } } pub fn up(&mut self) { let (col, row) = self.grid_pos(); if let Some(page) = Self::at_pos(col, row - 1) { *self = page; } } pub fn down(&mut self) { let (col, row) = self.grid_pos(); if let Some(page) = Self::at_pos(col, row + 1) { *self = page; } } }