Writing test page
This commit is contained in:
+10
-4
@@ -180,6 +180,14 @@ impl KanaSet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn next(&mut self) -> (String, String) {
|
pub fn next(&mut self) -> (String, String) {
|
||||||
|
let current_set = self.list();
|
||||||
|
|
||||||
|
let mut rand = rand::rng();
|
||||||
|
let index: u32 = rand.random();
|
||||||
|
current_set[index as usize % current_set.len()].clone()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn list(&self) -> Vec<(String, String)> {
|
||||||
let mut current_set: Vec<(String, String)> = Vec::new();
|
let mut current_set: Vec<(String, String)> = Vec::new();
|
||||||
|
|
||||||
for i in 0..10 {
|
for i in 0..10 {
|
||||||
@@ -189,10 +197,8 @@ impl KanaSet {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut rand = rand::rng();
|
current_set
|
||||||
let index: u32 = rand.random();
|
|
||||||
current_set[index as usize % current_set.len()].clone()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+7
-3
@@ -1,12 +1,14 @@
|
|||||||
mod lang;
|
mod lang;
|
||||||
mod quiz;
|
mod quiz;
|
||||||
mod selector;
|
mod selector;
|
||||||
|
mod writing;
|
||||||
|
|
||||||
use crate::quiz::*;
|
use crate::quiz::*;
|
||||||
use crate::selector::*;
|
use crate::selector::*;
|
||||||
use crate::Page::{Quiz, Selector};
|
use crate::Page::{Quiz, Selector, Writing};
|
||||||
use iced::widget::text;
|
use iced::widget::text;
|
||||||
use iced::Element;
|
use iced::Element;
|
||||||
|
use crate::writing::{WritingMessage, WritingState};
|
||||||
|
|
||||||
fn main() -> iced::Result {
|
fn main() -> iced::Result {
|
||||||
iced::application("A kana learn app", ScreenState::update, ScreenState::view).run()
|
iced::application("A kana learn app", ScreenState::update, ScreenState::view).run()
|
||||||
@@ -16,11 +18,13 @@ fn main() -> iced::Result {
|
|||||||
pub enum RootMessage {
|
pub enum RootMessage {
|
||||||
Selector(SelectorMessage),
|
Selector(SelectorMessage),
|
||||||
Quiz(QuizMessage),
|
Quiz(QuizMessage),
|
||||||
|
Writing(WritingMessage),
|
||||||
}
|
}
|
||||||
|
|
||||||
enum Page {
|
enum Page {
|
||||||
Selector(SelectorState),
|
Selector(SelectorState),
|
||||||
Quiz(QuizState),
|
Quiz(QuizState),
|
||||||
|
Writing(WritingState),
|
||||||
Back,
|
Back,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -44,11 +48,11 @@ impl Default for ScreenState {
|
|||||||
|
|
||||||
impl ScreenState {
|
impl ScreenState {
|
||||||
pub fn update(&mut self, message: RootMessage) {
|
pub fn update(&mut self, message: RootMessage) {
|
||||||
state_update!(message, self.stack, Selector, Quiz);
|
state_update!(message, self.stack, Selector, Quiz, Writing);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn view(&self) -> Element<'_, RootMessage> {
|
pub fn view(&self) -> Element<'_, RootMessage> {
|
||||||
view_navigation!(self.stack, Quiz, Selector)
|
view_navigation!(self.stack, Quiz, Selector, Writing)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+19
-5
@@ -1,17 +1,21 @@
|
|||||||
use crate::lang::{KanaSet, KanaType};
|
use crate::lang::{KanaSet, KanaType};
|
||||||
use crate::Page::Quiz;
|
use crate::selector::SelectorMessage::ChangeMode;
|
||||||
|
use crate::writing::WritingState;
|
||||||
|
use crate::Page::{Quiz, Writing};
|
||||||
use crate::{NavigatedPage, Page, QuizState};
|
use crate::{NavigatedPage, Page, QuizState};
|
||||||
use iced::widget::{button, checkbox, container, text, Column, Row};
|
use iced::widget::*;
|
||||||
use iced::{alignment, Element, Font};
|
use iced::{alignment, Element, Font};
|
||||||
|
|
||||||
pub struct SelectorState {
|
pub struct SelectorState {
|
||||||
pub set: KanaSet,
|
pub set: KanaSet,
|
||||||
|
is_writing: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for SelectorState {
|
impl Default for SelectorState {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
set: KanaSet::hiragana(),
|
set: KanaSet::hiragana(),
|
||||||
|
is_writing: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -21,14 +25,20 @@ pub enum SelectorMessage {
|
|||||||
Change,
|
Change,
|
||||||
Goto,
|
Goto,
|
||||||
Check(usize, bool),
|
Check(usize, bool),
|
||||||
|
ChangeMode(bool),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl NavigatedPage<SelectorMessage> for SelectorState {
|
impl NavigatedPage<SelectorMessage> for SelectorState {
|
||||||
fn navigate(&self, message: &SelectorMessage) -> Option<Page> {
|
fn navigate(&self, message: &SelectorMessage) -> Option<Page> {
|
||||||
if let SelectorMessage::Goto = message {
|
if let SelectorMessage::Goto = message {
|
||||||
let mut quiz = QuizState::new();
|
return if self.is_writing {
|
||||||
quiz.set = self.set.clone();
|
let writing = WritingState::new(&self.set);
|
||||||
return Some(Quiz(quiz));
|
Some(Writing(writing))
|
||||||
|
} else {
|
||||||
|
let mut quiz = QuizState::new();
|
||||||
|
quiz.set = self.set.clone();
|
||||||
|
Some(Quiz(quiz))
|
||||||
|
};
|
||||||
}
|
}
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
@@ -43,6 +53,7 @@ impl SelectorState {
|
|||||||
},
|
},
|
||||||
SelectorMessage::Goto => {}
|
SelectorMessage::Goto => {}
|
||||||
SelectorMessage::Check(i, b) => self.set.include_map[i] = b,
|
SelectorMessage::Check(i, b) => self.set.include_map[i] = b,
|
||||||
|
ChangeMode(b) => self.is_writing = b,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -51,6 +62,9 @@ impl SelectorState {
|
|||||||
iced::widget::column![
|
iced::widget::column![
|
||||||
button("Переключить").on_press(SelectorMessage::Change),
|
button("Переключить").on_press(SelectorMessage::Change),
|
||||||
self.rows_selector(),
|
self.rows_selector(),
|
||||||
|
toggler(self.is_writing)
|
||||||
|
.label("Режим письма")
|
||||||
|
.on_toggle(ChangeMode),
|
||||||
button("К тесту").on_press(SelectorMessage::Goto),
|
button("К тесту").on_press(SelectorMessage::Goto),
|
||||||
]
|
]
|
||||||
.spacing(10),
|
.spacing(10),
|
||||||
|
|||||||
+107
@@ -0,0 +1,107 @@
|
|||||||
|
use crate::lang::KanaSet;
|
||||||
|
use crate::Page::Back;
|
||||||
|
use crate::{NavigatedPage, Page};
|
||||||
|
use iced::widget::*;
|
||||||
|
use iced::{alignment, Element, Fill, Font};
|
||||||
|
use rand::seq::SliceRandom;
|
||||||
|
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
pub struct WritingState {
|
||||||
|
kana: String,
|
||||||
|
set: Vec<(String, String)>,
|
||||||
|
original_set: Vec<(String, String)>,
|
||||||
|
kana_total: String,
|
||||||
|
roman_total: String,
|
||||||
|
is_help: bool,
|
||||||
|
next_text: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl NavigatedPage<WritingMessage> for WritingState {
|
||||||
|
fn navigate(&self, message: &WritingMessage) -> Option<Page> {
|
||||||
|
if let WritingMessage::Back = message {
|
||||||
|
Some(Back)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WritingState {
|
||||||
|
pub(crate) fn new(set: &KanaSet) -> WritingState {
|
||||||
|
let mut list = set.list();
|
||||||
|
list.shuffle(&mut rand::rng());
|
||||||
|
WritingState {
|
||||||
|
kana: "".to_string(),
|
||||||
|
set: list.clone(),
|
||||||
|
original_set: list,
|
||||||
|
kana_total: "".to_string(),
|
||||||
|
roman_total: "".to_string(),
|
||||||
|
is_help: false,
|
||||||
|
next_text: "Дальше".to_string(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WritingState {
|
||||||
|
pub fn update(&mut self, message: WritingMessage) {
|
||||||
|
match message {
|
||||||
|
WritingMessage::Back => todo!(),
|
||||||
|
WritingMessage::Next => self.next(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn next(&mut self) {
|
||||||
|
if self.set.is_empty() {
|
||||||
|
self.kana = "".to_string();
|
||||||
|
self.roman_total = "".to_string();
|
||||||
|
self.kana_total = "".to_string();
|
||||||
|
|
||||||
|
self.set = self.original_set.clone();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let current = self.set.pop().unwrap();
|
||||||
|
self.kana_total += &*format!("{} ", ¤t.0).to_string();
|
||||||
|
self.roman_total += &*format!("{} ", ¤t.1.clone()).to_string();
|
||||||
|
self.kana = current.1;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn view(&self) -> Element<'_, WritingMessage> {
|
||||||
|
container(
|
||||||
|
iced::widget::column![
|
||||||
|
text!("{}", self.roman_total).size(24),
|
||||||
|
text!("{}", self.kana).size(48),
|
||||||
|
self.answers(),
|
||||||
|
row![
|
||||||
|
button(text!("{}", self.next_text)).on_press(WritingMessage::Next),
|
||||||
|
button("Закончить").on_press(WritingMessage::Back),
|
||||||
|
]
|
||||||
|
.spacing(10)
|
||||||
|
]
|
||||||
|
.spacing(10)
|
||||||
|
.align_x(alignment::Horizontal::Center),
|
||||||
|
)
|
||||||
|
.center_x(Fill)
|
||||||
|
.into()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn answers(&self) -> Element<'_, WritingMessage> {
|
||||||
|
if self.set.is_empty() {
|
||||||
|
text!("{}", self.kana_total).font(Font::with_name("AppleGothic")).size(36).into()
|
||||||
|
} else {
|
||||||
|
vertical_space().height(36).into()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub enum WritingMessage {
|
||||||
|
Next,
|
||||||
|
Back,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Default, Debug, Clone)]
|
||||||
|
pub struct Score {
|
||||||
|
total: i32,
|
||||||
|
correct: i32,
|
||||||
|
fail: i32,
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user