Splitting kana set
This commit is contained in:
1 parent
36e5693564
commit
c74a0eb311
25 files changed
+389
-354
No files matched your search
@@ -0,0 +1,224 @@
|
||||
use crate::navigation::RootMessage;
|
||||
use crate::pages::dictionary::split_with_coma;
|
||||
use crate::pages::dictionary_quiz::DictionaryQuizMessage::*;
|
||||
use crate::lang::WordData;
|
||||
use crate::navigation::Page::PreviousPage;
|
||||
use crate::navigation::*;
|
||||
use crate::pages::quiz::Score;
|
||||
use crate::styling::*;
|
||||
use iced::Background::Color;
|
||||
use iced::border::Radius;
|
||||
use iced::widget::container::Style;
|
||||
use iced::widget::{Row, button, container, row, space, text, text_input};
|
||||
use iced::{Border, Element, Fill, Task, Theme, alignment};
|
||||
use rand::prelude::SliceRandom;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct DictionaryQuizState {
|
||||
words: Vec<WordData>,
|
||||
current_set: Vec<WordData>,
|
||||
answer: String,
|
||||
view: String,
|
||||
correct: String,
|
||||
score: Score,
|
||||
is_help: bool,
|
||||
reverse: bool,
|
||||
laps: u32,
|
||||
no_typing: bool,
|
||||
}
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum DictionaryQuizMessage {
|
||||
Back,
|
||||
AnswerChanged(String),
|
||||
SubmitAnswer,
|
||||
Appeal,
|
||||
}
|
||||
|
||||
impl NavigatedPage<DictionaryQuizMessage> for DictionaryQuizState {
|
||||
fn navigate(&mut self, message: &DictionaryQuizMessage) -> Option<Page> {
|
||||
match message {
|
||||
Back => Some(PreviousPage),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
fn navigated(&mut self) {}
|
||||
|
||||
fn update(&mut self, message: DictionaryQuizMessage) -> Task<RootMessage> {
|
||||
match message {
|
||||
Back => {}
|
||||
AnswerChanged(c) => self.answer = c.clone(),
|
||||
SubmitAnswer => self.submit(),
|
||||
Appeal => self.appeal_answer(),
|
||||
}
|
||||
Task::none()
|
||||
}
|
||||
|
||||
fn view(&self) -> Element<'_, DictionaryQuizMessage> {
|
||||
container(
|
||||
iced::widget::column![
|
||||
self.laps(),
|
||||
iced::widget::column![
|
||||
text!("{}", self.view).size(54),
|
||||
text!(
|
||||
"{}",
|
||||
if self.is_help {
|
||||
self.correct.clone()
|
||||
} else {
|
||||
String::new()
|
||||
}
|
||||
)
|
||||
.size(ACCENT_FONT_SIZE)
|
||||
.align_y(alignment::Vertical::Center),
|
||||
]
|
||||
.align_x(alignment::Horizontal::Center)
|
||||
.spacing(5),
|
||||
text_input("Перевод", &self.answer)
|
||||
.size(28)
|
||||
.width(250)
|
||||
.on_input(AnswerChanged)
|
||||
.on_submit(SubmitAnswer),
|
||||
row![
|
||||
text!("{}", self.score.total.to_string()).size(25),
|
||||
text!("{}", self.score.correct.to_string())
|
||||
.size(25)
|
||||
.color(iced::Color::from_rgb8(60, 170, 60)),
|
||||
text!("{}", self.score.fail.to_string())
|
||||
.color(iced::Color::from_rgb8(255, 79, 0))
|
||||
.size(25),
|
||||
]
|
||||
.spacing(DEFAULT_SPACING),
|
||||
row![
|
||||
button("Закончить").style(jl_button).on_press(Back),
|
||||
self.appeal_button()
|
||||
]
|
||||
.spacing(DEFAULT_SPACING),
|
||||
]
|
||||
.spacing(DEFAULT_SPACING)
|
||||
.align_x(alignment::Horizontal::Center),
|
||||
)
|
||||
.center_y(Fill)
|
||||
.center_x(Fill)
|
||||
.into()
|
||||
}
|
||||
}
|
||||
|
||||
impl DictionaryQuizState {
|
||||
pub fn new(words: Vec<WordData>, reverse: bool, no_typing: bool) -> DictionaryQuizState {
|
||||
DictionaryQuizState {
|
||||
words,
|
||||
current_set: Vec::new(),
|
||||
answer: "".to_string(),
|
||||
view: "---".to_string(),
|
||||
correct: "".to_string(),
|
||||
score: Default::default(),
|
||||
is_help: false,
|
||||
reverse,
|
||||
laps: 0,
|
||||
no_typing,
|
||||
}
|
||||
}
|
||||
|
||||
fn submit(&mut self) {
|
||||
if self.view == "---" {
|
||||
self.show_next();
|
||||
return;
|
||||
}
|
||||
|
||||
if self.no_typing {
|
||||
self.no_type_submit();
|
||||
} else {
|
||||
self.default_submit();
|
||||
}
|
||||
}
|
||||
|
||||
fn no_type_submit(&mut self) {
|
||||
if self.is_help {
|
||||
self.is_help = false;
|
||||
self.score.total += 1;
|
||||
self.show_next()
|
||||
} else {
|
||||
self.is_help = true;
|
||||
}
|
||||
}
|
||||
|
||||
fn default_submit(&mut self) {
|
||||
if !self.is_help {
|
||||
self.score.total += 1;
|
||||
}
|
||||
if self.answer.to_lowercase() == self.correct.to_lowercase()
|
||||
|| split_with_coma(self.correct.to_lowercase().as_str()).contains(&self.answer.to_lowercase())
|
||||
{
|
||||
if !self.is_help {
|
||||
self.score.correct += 1;
|
||||
}
|
||||
self.show_next()
|
||||
} else {
|
||||
self.score.fail += 1;
|
||||
self.is_help = true;
|
||||
}
|
||||
}
|
||||
|
||||
fn update_set(&mut self) {
|
||||
self.current_set.append(&mut self.words.clone());
|
||||
self.current_set.shuffle(&mut rand::rng());
|
||||
if self.score.total != 0 {
|
||||
self.laps += 1;
|
||||
}
|
||||
}
|
||||
|
||||
fn show_next(&mut self) {
|
||||
self.is_help = false;
|
||||
self.answer = String::new();
|
||||
|
||||
let next: WordData = match self.current_set.pop() {
|
||||
Some(word) => word,
|
||||
None => {
|
||||
self.update_set();
|
||||
self.current_set.pop().expect("Empty set")
|
||||
}
|
||||
};
|
||||
|
||||
if self.reverse {
|
||||
self.view = next.value.clone();
|
||||
self.correct = next.key.clone();
|
||||
} else {
|
||||
self.view = next.key.clone();
|
||||
self.correct = next.value.clone();
|
||||
}
|
||||
}
|
||||
|
||||
fn laps(&self) -> Element<'_, DictionaryQuizMessage> {
|
||||
let mut col = Row::new();
|
||||
for _ in 0..self.laps {
|
||||
col = col.push(iced::widget::container(space().height(15).width(15)).style(
|
||||
|x: &Theme| Style {
|
||||
text_color: None,
|
||||
background: Some(Color(x.palette().primary)),
|
||||
border: Border {
|
||||
color: Default::default(),
|
||||
width: 0.0,
|
||||
radius: Radius::new(5),
|
||||
},
|
||||
shadow: Default::default(),
|
||||
snap: false,
|
||||
},
|
||||
));
|
||||
}
|
||||
col.spacing(DEFAULT_SPACING).into()
|
||||
}
|
||||
|
||||
fn appeal_button(&self) -> Element<'_, DictionaryQuizMessage> {
|
||||
if self.is_help && !self.no_typing {
|
||||
return button("Апелляция").style(jl_button).on_press(Appeal).into();
|
||||
}
|
||||
space().into()
|
||||
}
|
||||
|
||||
fn appeal_answer(&mut self) {
|
||||
self.score.correct += 1;
|
||||
self.score.fail -= 1;
|
||||
self.answer = self.correct.clone();
|
||||
self.show_next()
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user