Files
jap_learn/src/main.rs
T

104 lines
2.2 KiB
Rust
Raw Normal View History

2026-02-10 17:25:39 +03:00
#![windows_subsystem = "windows"]
2026-02-10 11:28:12 +03:00
mod lang;
2026-02-10 12:12:16 +03:00
mod quiz;
mod selector;
2026-02-10 17:04:48 +03:00
mod writing;
2026-02-10 11:28:12 +03:00
2026-02-10 12:12:16 +03:00
use crate::quiz::*;
use crate::selector::*;
2026-02-10 17:04:48 +03:00
use crate::Page::{Quiz, Selector, Writing};
2026-02-10 12:12:16 +03:00
use iced::widget::text;
use iced::Element;
2026-02-10 17:04:48 +03:00
use crate::writing::{WritingMessage, WritingState};
2026-02-10 11:28:12 +03:00
fn main() -> iced::Result {
iced::application("A kana learn app", ScreenState::update, ScreenState::view).run()
}
#[derive(Debug, Clone)]
pub enum RootMessage {
Selector(SelectorMessage),
Quiz(QuizMessage),
2026-02-10 17:04:48 +03:00
Writing(WritingMessage),
2026-02-10 11:28:12 +03:00
}
enum Page {
Selector(SelectorState),
Quiz(QuizState),
2026-02-10 17:04:48 +03:00
Writing(WritingState),
2026-02-10 11:28:12 +03:00
Back,
}
impl Default for Page {
fn default() -> Self {
Selector(SelectorState::default())
}
}
pub struct ScreenState {
stack: Vec<Page>,
}
impl Default for ScreenState {
fn default() -> Self {
ScreenState {
stack: vec![Page::default()],
}
}
}
impl ScreenState {
pub fn update(&mut self, message: RootMessage) {
2026-02-10 17:04:48 +03:00
state_update!(message, self.stack, Selector, Quiz, Writing);
2026-02-10 11:28:12 +03:00
}
pub fn view(&self) -> Element<'_, RootMessage> {
2026-02-10 17:04:48 +03:00
view_navigation!(self.stack, Quiz, Selector, Writing)
2026-02-10 11:28:12 +03:00
}
}
2026-02-10 12:12:16 +03:00
#[macro_export]
macro_rules! view_navigation {
($stack:expr, $($e:ident), *) => {
match &$stack.last().unwrap() {
$(
$e(s) => s.view().map(RootMessage::$e),
)*
_ => text!("").into(),
2026-02-10 11:28:12 +03:00
}
}
}
2026-02-10 12:12:16 +03:00
#[macro_export]
macro_rules! state_update {
($message:expr, $stack:expr, $($e:ident), *) => {
match $message {
$(
RootMessage::$e(msg) => {
if let $e(s) = $stack.last_mut().unwrap() {
message_navigation!(msg, $stack, s)
2026-02-10 11:28:12 +03:00
}
}
2026-02-10 12:12:16 +03:00
)*
2026-02-10 11:28:12 +03:00
}
}
}
2026-02-10 12:12:16 +03:00
#[macro_export]
macro_rules! message_navigation {
($msg:expr, $stack:expr, $state:expr) => {
if let Some(new_page) = $state.navigate(&$msg) {
if let Page::Back = new_page {
$stack.pop();
return;
2026-02-10 11:28:12 +03:00
}
2026-02-10 12:12:16 +03:00
$stack.push(new_page);
} else {
$state.update($msg);
2026-02-10 11:28:12 +03:00
}
2026-02-10 12:12:16 +03:00
};
}
2026-02-10 11:28:12 +03:00
2026-02-10 12:12:16 +03:00
trait NavigatedPage<T> {
fn navigate(&self, message: &T) -> Option<Page>;
2026-02-10 11:28:12 +03:00
}