Before button global styling
This commit is contained in:
Generated
+16
-1
@@ -765,7 +765,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "173852283a9a57a3cbe365d86e74dc428a09c50421477d5ad6fe9d9509e37737"
|
||||
dependencies = [
|
||||
"bitflags 2.10.0",
|
||||
"fontdb",
|
||||
"fontdb 0.23.0",
|
||||
"harfrust",
|
||||
"linebender_resource_handle",
|
||||
"log",
|
||||
@@ -1200,6 +1200,19 @@ dependencies = [
|
||||
"ttf-parser",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fontdb"
|
||||
version = "0.24.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2660c5e9157bf76d2db1294e4a9feba604ef610819a3b591088d0d8392a3290f"
|
||||
dependencies = [
|
||||
"fontconfig-parser",
|
||||
"log",
|
||||
"memmap2",
|
||||
"slotmap",
|
||||
"tinyvec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "foreign-types"
|
||||
version = "0.3.2"
|
||||
@@ -2097,8 +2110,10 @@ dependencies = [
|
||||
"chrono",
|
||||
"criterion",
|
||||
"dirs",
|
||||
"fontdb 0.24.0",
|
||||
"hex",
|
||||
"iced",
|
||||
"iced_core",
|
||||
"rand",
|
||||
"reqwest",
|
||||
"rhai",
|
||||
|
||||
+2
-1
@@ -5,6 +5,7 @@ edition = "2024"
|
||||
|
||||
[dependencies]
|
||||
iced = { version = "0.14.0", features = ["tokio"]}
|
||||
iced_core = "0.14.0"
|
||||
rand = "0.10.1"
|
||||
dirs = "6.0.0"
|
||||
serde = { version = "1.0.228", features = ["derive"] }
|
||||
@@ -18,7 +19,7 @@ sha2 = "0.11.0"
|
||||
tokio = { version = "1.50.0", features = ["rt", "rt-multi-thread", "macros"] }
|
||||
hex = "0.4.3"
|
||||
zstd = "0.13.3"
|
||||
|
||||
fontdb = "0.24.0"
|
||||
[dev-dependencies]
|
||||
criterion = "0.8.2"
|
||||
|
||||
|
||||
+7
-5
@@ -5,8 +5,7 @@ use crate::dictionary::DictionaryMessage::{
|
||||
use crate::dictionary_test::DictionaryQuizState;
|
||||
use crate::lang::{WordData, WordGroup};
|
||||
use crate::word::WordState;
|
||||
use crate::Page::Word;
|
||||
use crate::{AppState, NavigatedPage, Page, RootMessage, DEFAULT_SPACING};
|
||||
use crate::{AppState, RootMessage };
|
||||
use chrono::{DateTime, TimeDelta, Utc};
|
||||
use iced::alignment::Vertical::Center;
|
||||
use iced::widget::button::Style;
|
||||
@@ -22,6 +21,9 @@ use std::path::PathBuf;
|
||||
use std::sync::{Arc, Mutex};
|
||||
use std::time::{Duration, Instant};
|
||||
use DictionaryMessage::Back;
|
||||
use crate::navigation::{NavigatedPage, Page};
|
||||
use crate::navigation::Page::Word;
|
||||
use crate::styling::*;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct DictionaryState {
|
||||
@@ -347,21 +349,21 @@ impl DictionaryState {
|
||||
|
||||
line = line.push(
|
||||
text_input("Слово", &word.key)
|
||||
.size(20)
|
||||
.size(ACCENT_FONT_SIZE)
|
||||
.width(Length::Fill)
|
||||
.on_input(move |string| DictionaryMessage::SetKey(i, string))
|
||||
.on_submit(DictionaryMessage::SubmitWord(i)),
|
||||
);
|
||||
line = line.push(
|
||||
text_input("Перевод", &word.value)
|
||||
.size(20)
|
||||
.size(ACCENT_FONT_SIZE)
|
||||
.width(Length::Fill)
|
||||
.on_input(move |string| DictionaryMessage::SetValue(i, string))
|
||||
.on_submit(DictionaryMessage::SubmitWord(i)),
|
||||
);
|
||||
line = line.push(
|
||||
text_input("Тэги", &word.tags)
|
||||
.size(20)
|
||||
.size(ACCENT_FONT_SIZE)
|
||||
.width(Length::Fill)
|
||||
.on_input(move |string| DictionaryMessage::SetTags(i, string))
|
||||
.on_submit(DictionaryMessage::SubmitWord(i)),
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
use crate::dictionary::{split_with_coma};
|
||||
use crate::quiz::Score;
|
||||
use crate::Page::PreviousPage;
|
||||
use crate::{RootMessage, DEFAULT_SPACING};
|
||||
use crate::{NavigatedPage, Page};
|
||||
use crate::{RootMessage};
|
||||
use iced::border::Radius;
|
||||
use iced::widget::container::Style;
|
||||
use iced::widget::{button, container, row, space, text, text_input, Row};
|
||||
@@ -10,6 +8,9 @@ use iced::Background::Color;
|
||||
use iced::{alignment, Border, Element, Fill, Task, Theme};
|
||||
use rand::prelude::SliceRandom;
|
||||
use crate::lang::WordData;
|
||||
use crate::navigation::{NavigatedPage, Page};
|
||||
use crate::navigation::Page::PreviousPage;
|
||||
use crate::styling::*;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct DictionaryQuizState {
|
||||
@@ -84,7 +85,7 @@ impl DictionaryQuizState {
|
||||
} else {
|
||||
String::new()
|
||||
}
|
||||
).size(20).align_y(alignment::Vertical::Center),
|
||||
).size(ACCENT_FONT_SIZE).align_y(alignment::Vertical::Center),
|
||||
]
|
||||
.align_x(alignment::Horizontal::Center)
|
||||
.spacing(5),
|
||||
|
||||
+4
-2
@@ -1,12 +1,14 @@
|
||||
use crate::data_provider::history::{HistoryItem, get_history_of_set};
|
||||
use crate::lang::WordData;
|
||||
use crate::{AppState, DEFAULT_SPACING, NavigatedPage, Page, RootMessage};
|
||||
use crate::{AppState, RootMessage};
|
||||
use HistoryMessage::Back;
|
||||
use iced::alignment::Horizontal::Center;
|
||||
use iced::widget::space::horizontal;
|
||||
use iced::widget::*;
|
||||
use iced::{Element, Fill, FillPortion, Left, Task};
|
||||
use std::sync::{Arc, Mutex};
|
||||
use crate::navigation::{NavigatedPage, Page};
|
||||
use crate::styling::*;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct HistoryState {
|
||||
@@ -47,7 +49,7 @@ impl HistoryState {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn update(&mut self, message: HistoryMessage) -> Task<RootMessage> {
|
||||
pub fn update(&mut self, _: HistoryMessage) -> Task<RootMessage> {
|
||||
Task::none()
|
||||
}
|
||||
|
||||
|
||||
+15
-174
@@ -1,4 +1,4 @@
|
||||
#![windows_subsystem = "windows"]
|
||||
// #![windows_subsystem = "windows"]
|
||||
mod data_provider;
|
||||
mod dictionary;
|
||||
mod dictionary_test;
|
||||
@@ -12,47 +12,37 @@ mod sync;
|
||||
mod word;
|
||||
mod writing;
|
||||
mod history;
|
||||
pub mod navigation;
|
||||
pub mod styling;
|
||||
|
||||
use crate::data_provider::card_sets::load_sets;
|
||||
use crate::data_provider::settings::get_setting;
|
||||
use crate::data_provider::words::{load_word_groups, load_words};
|
||||
use crate::dictionary::{app_data_dir, DictionaryMessage, DictionaryState};
|
||||
use crate::dictionary_test::{DictionaryQuizMessage, DictionaryQuizState};
|
||||
use crate::dictionary::app_data_dir;
|
||||
use crate::lang::{WordData, WordGroup};
|
||||
use crate::navigation::{AppSettings, RootMessage, ScreenState};
|
||||
use crate::quiz::*;
|
||||
use crate::randomizer::randomizer::{RandomizerMessage, RandomizerState};
|
||||
use crate::repetition::{RepetitionMessage, RepetitionState};
|
||||
use crate::repetitions::{CardSetSettings, RepetitionsMessage, RepetitionsState};
|
||||
use crate::selector::*;
|
||||
use crate::sync::{SyncMessage, SyncState};
|
||||
use crate::word::{WordMessage, WordState};
|
||||
use crate::writing::{WritingMessage, WritingState};
|
||||
use crate::Page::{Dictionary, DictionaryQuiz, History, Quiz, Randomizer, Repetition, Repetitions, Selector, Sync, Word, Writing};
|
||||
use crate::repetitions::CardSetSettings;
|
||||
use crate::RootMessage::Keyboard;
|
||||
use iced::keyboard::Event;
|
||||
use iced::widget::text;
|
||||
use iced::{keyboard, Element, Program, Subscription, Theme};
|
||||
use iced::{Font, Task};
|
||||
use fontdb::Database;
|
||||
use iced::{keyboard, Program, Subscription, Theme};
|
||||
use iced::Font;
|
||||
use rusqlite::Connection;
|
||||
use std::sync::{Arc, Mutex};
|
||||
use crate::data_provider::sqlite::create_db;
|
||||
use crate::history::{HistoryMessage, HistoryState};
|
||||
|
||||
const DEFAULT_SPACING: f32 = 10.0;
|
||||
|
||||
const USER_FONT: Font = Font::with_name("Noto Sans JP");
|
||||
|
||||
fn main() -> iced::Result {
|
||||
|
||||
iced::application(ScreenState::boot, ScreenState::update, ScreenState::view)
|
||||
.subscription(subscription)
|
||||
.title("Kana learn app")
|
||||
// .settings(iced::Settings{
|
||||
// default_text_size: iced::Pixels(18.0),
|
||||
// ..iced::Settings::default()
|
||||
// })
|
||||
.settings(iced::Settings{
|
||||
default_text_size: iced::Pixels(18.0),
|
||||
..iced::Settings::default()
|
||||
})
|
||||
.font(include_bytes!("../noto.ttf"))
|
||||
.default_font(USER_FONT)
|
||||
|
||||
.theme(Theme::GruvboxDark)
|
||||
.run()
|
||||
}
|
||||
@@ -61,40 +51,7 @@ fn subscription(_state: &ScreenState) -> Subscription<RootMessage> {
|
||||
keyboard::listen().map(|e| Keyboard(e))
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub enum RootMessage {
|
||||
Selector(SelectorMessage),
|
||||
Quiz(QuizMessage),
|
||||
Writing(WritingMessage),
|
||||
Dictionary(DictionaryMessage),
|
||||
DictionaryQuiz(DictionaryQuizMessage),
|
||||
Randomizer(RandomizerMessage),
|
||||
Repetitions(RepetitionsMessage),
|
||||
Repetition(RepetitionMessage),
|
||||
Word(WordMessage),
|
||||
Sync(SyncMessage),
|
||||
History(HistoryMessage),
|
||||
Keyboard(Event),
|
||||
}
|
||||
|
||||
pub enum Page {
|
||||
Selector(SelectorState),
|
||||
Quiz(QuizState),
|
||||
Writing(WritingState),
|
||||
Dictionary(DictionaryState),
|
||||
DictionaryQuiz(DictionaryQuizState),
|
||||
Randomizer(RandomizerState),
|
||||
Repetitions(RepetitionsState),
|
||||
Repetition(RepetitionState),
|
||||
Word(WordState),
|
||||
Sync(SyncState),
|
||||
History(HistoryState),
|
||||
PreviousPage,
|
||||
}
|
||||
|
||||
pub struct ScreenState {
|
||||
stack: Vec<Page>,
|
||||
}
|
||||
|
||||
pub struct AppState {
|
||||
pub dictionary: Vec<WordData>,
|
||||
@@ -121,16 +78,7 @@ impl AppState {
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for ScreenState {
|
||||
fn default() -> Self {
|
||||
let mut state = AppState::new();
|
||||
fill_state(&mut state);
|
||||
let state = Arc::new(Mutex::new(state));
|
||||
ScreenState {
|
||||
stack: vec![Selector(SelectorState::new(state.clone()))],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fn fill_state(state: &mut AppState) {
|
||||
let list = load_words(&state.connection);
|
||||
@@ -149,110 +97,3 @@ fn load_settings(connection: &Connection) -> AppSettings {
|
||||
AppSettings { key }
|
||||
}
|
||||
|
||||
impl ScreenState {
|
||||
pub fn boot() -> (ScreenState, Task<RootMessage>) {
|
||||
create_db();
|
||||
(ScreenState::default(), Task::none())
|
||||
}
|
||||
pub fn update(&mut self, message: RootMessage) -> Task<RootMessage> {
|
||||
if let Keyboard(e) = message {
|
||||
return self.handle_keyboard(e);
|
||||
}
|
||||
|
||||
state_update!(
|
||||
message,
|
||||
self.stack,
|
||||
Selector,
|
||||
Quiz,
|
||||
Writing,
|
||||
Dictionary,
|
||||
DictionaryQuiz,
|
||||
Randomizer,
|
||||
Repetitions,
|
||||
Repetition,
|
||||
Word,
|
||||
Sync,
|
||||
History
|
||||
);
|
||||
Task::none()
|
||||
}
|
||||
pub fn view(&self) -> Element<'_, RootMessage> {
|
||||
view_navigation!(
|
||||
self.stack,
|
||||
Quiz,
|
||||
Selector,
|
||||
Writing,
|
||||
Dictionary,
|
||||
DictionaryQuiz,
|
||||
Randomizer,
|
||||
Repetitions,
|
||||
Repetition,
|
||||
Word,
|
||||
Sync,
|
||||
History
|
||||
)
|
||||
}
|
||||
|
||||
fn handle_keyboard(&mut self, message: Event) -> Task<RootMessage> {
|
||||
let page = self.stack.last_mut().unwrap();
|
||||
match page {
|
||||
Repetition(page) => page.press(&message),
|
||||
_ => Task::none(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct AppSettings {
|
||||
key: Option<String>,
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! view_navigation {
|
||||
($stack:expr, $($e:ident), *) => {
|
||||
match &$stack.last().unwrap() {
|
||||
$(
|
||||
$e(s) => s.view().map(RootMessage::$e),
|
||||
)*
|
||||
_ => text!("").into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[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)
|
||||
}
|
||||
}
|
||||
)*
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! message_navigation {
|
||||
($msg:expr, $stack:expr, $state:expr) => {
|
||||
if let Some(new_page) = $state.navigate(&$msg) {
|
||||
if let Page::PreviousPage = new_page {
|
||||
$stack.pop();
|
||||
return Task::none();
|
||||
}
|
||||
$stack.push(new_page);
|
||||
} else {
|
||||
return $state.update($msg);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
trait NavigatedPage<T> {
|
||||
fn navigate(&self, message: &T) -> Option<Page>;
|
||||
}
|
||||
|
||||
pub trait KeyPressedPage {
|
||||
fn press(&mut self, message: &Event) -> Task<RootMessage>;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,179 @@
|
||||
use crate::message_navigation;
|
||||
use crate::state_update;
|
||||
use crate::view_navigation;
|
||||
use std::sync::{Arc, Mutex};
|
||||
use iced::{Element, Task};
|
||||
use iced::keyboard::Event;
|
||||
use crate::{fill_state, AppState };
|
||||
use crate::data_provider::sqlite::create_db;
|
||||
use crate::dictionary::{DictionaryMessage, DictionaryState};
|
||||
use crate::dictionary_test::{DictionaryQuizMessage, DictionaryQuizState};
|
||||
use crate::history::{HistoryMessage, HistoryState};
|
||||
use crate::navigation::Page::*;
|
||||
use crate::navigation::RootMessage::Keyboard;
|
||||
use crate::quiz::{QuizMessage, QuizState};
|
||||
use crate::randomizer::randomizer::{RandomizerMessage, RandomizerState};
|
||||
use crate::repetition::{RepetitionMessage, RepetitionState};
|
||||
use crate::repetitions::{RepetitionsMessage, RepetitionsState};
|
||||
use crate::selector::{SelectorMessage, SelectorState};
|
||||
use crate::sync::{SyncMessage, SyncState};
|
||||
use crate::word::{WordMessage, WordState};
|
||||
use crate::writing::{WritingMessage, WritingState};
|
||||
|
||||
|
||||
impl Default for ScreenState {
|
||||
fn default() -> Self {
|
||||
let mut state = AppState::new();
|
||||
fill_state(&mut state);
|
||||
let state = Arc::new(Mutex::new(state));
|
||||
ScreenState {
|
||||
stack: vec![Page::Selector(SelectorState::new(state.clone()))],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub enum RootMessage {
|
||||
Selector(SelectorMessage),
|
||||
Quiz(QuizMessage),
|
||||
Writing(WritingMessage),
|
||||
Dictionary(DictionaryMessage),
|
||||
DictionaryQuiz(DictionaryQuizMessage),
|
||||
Randomizer(RandomizerMessage),
|
||||
Repetitions(RepetitionsMessage),
|
||||
Repetition(RepetitionMessage),
|
||||
Word(WordMessage),
|
||||
Sync(SyncMessage),
|
||||
History(HistoryMessage),
|
||||
Keyboard(Event),
|
||||
}
|
||||
|
||||
pub enum Page {
|
||||
Selector(SelectorState),
|
||||
Quiz(QuizState),
|
||||
Writing(WritingState),
|
||||
Dictionary(DictionaryState),
|
||||
DictionaryQuiz(DictionaryQuizState),
|
||||
Randomizer(RandomizerState),
|
||||
Repetitions(RepetitionsState),
|
||||
Repetition(RepetitionState),
|
||||
Word(WordState),
|
||||
Sync(SyncState),
|
||||
History(HistoryState),
|
||||
PreviousPage,
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
pub struct ScreenState {
|
||||
stack: Vec<Page>,
|
||||
}
|
||||
|
||||
impl ScreenState {
|
||||
pub fn boot() -> (ScreenState, Task<RootMessage>) {
|
||||
create_db();
|
||||
(ScreenState::default(), Task::none())
|
||||
}
|
||||
pub fn update(&mut self, message: RootMessage) -> Task<RootMessage> {
|
||||
if let Keyboard(e) = message {
|
||||
return self.handle_keyboard(e);
|
||||
}
|
||||
|
||||
state_update!(
|
||||
message,
|
||||
self.stack,
|
||||
Selector,
|
||||
Quiz,
|
||||
Writing,
|
||||
Dictionary,
|
||||
DictionaryQuiz,
|
||||
Randomizer,
|
||||
Repetitions,
|
||||
Repetition,
|
||||
Word,
|
||||
Sync,
|
||||
History
|
||||
);
|
||||
Task::none()
|
||||
}
|
||||
pub fn view(&self) -> Element<'_, RootMessage> {
|
||||
view_navigation!(
|
||||
self.stack,
|
||||
Quiz,
|
||||
Selector,
|
||||
Writing,
|
||||
Dictionary,
|
||||
DictionaryQuiz,
|
||||
Randomizer,
|
||||
Repetitions,
|
||||
Repetition,
|
||||
Word,
|
||||
Sync,
|
||||
History
|
||||
)
|
||||
}
|
||||
|
||||
fn handle_keyboard(&mut self, message: Event) -> Task<RootMessage> {
|
||||
let page = self.stack.last_mut().unwrap();
|
||||
match page {
|
||||
Page::Repetition(page) => page.press(&message),
|
||||
_ => Task::none(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct AppSettings {
|
||||
pub(crate) key: Option<String>,
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! view_navigation {
|
||||
($stack:expr, $($e:ident), *) => {
|
||||
match &$stack.last().unwrap() {
|
||||
$(
|
||||
$e(s) => s.view().map(RootMessage::$e),
|
||||
)*
|
||||
_ => iced::widget::space().into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[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)
|
||||
}
|
||||
}
|
||||
)*
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! message_navigation {
|
||||
($msg:expr, $stack:expr, $state:expr) => {
|
||||
if let Some(new_page) = $state.navigate(&$msg) {
|
||||
if let Page::PreviousPage = new_page {
|
||||
$stack.pop();
|
||||
return Task::none();
|
||||
}
|
||||
$stack.push(new_page);
|
||||
} else {
|
||||
return $state.update($msg);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
pub trait NavigatedPage<T> {
|
||||
fn navigate(&self, message: &T) -> Option<Page>;
|
||||
}
|
||||
|
||||
pub trait KeyPressedPage {
|
||||
fn press(&mut self, message: &Event) -> Task<RootMessage>;
|
||||
}
|
||||
+4
-2
@@ -1,9 +1,11 @@
|
||||
use crate::lang::KanaSet;
|
||||
use crate::Page::PreviousPage;
|
||||
use crate::{NavigatedPage, Page, RootMessage, DEFAULT_SPACING, USER_FONT};
|
||||
use crate::{ RootMessage, USER_FONT};
|
||||
use iced::widget::*;
|
||||
use iced::{alignment, Element, Fill, Task};
|
||||
use rand::seq::SliceRandom;
|
||||
use crate::navigation::{NavigatedPage, Page};
|
||||
use crate::navigation::Page::PreviousPage;
|
||||
use crate::styling::*;
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct QuizState {
|
||||
|
||||
+2
-1
@@ -1,10 +1,11 @@
|
||||
|
||||
pub mod randomizer {
|
||||
use crate::randomizer::randomizer::RandomizerMessage::{Back, Start, Edit};
|
||||
use crate::{NavigatedPage, Page, RootMessage};
|
||||
use crate::{RootMessage};
|
||||
use iced::widget::{button, container, text_editor};
|
||||
use iced::Task;
|
||||
use rand::prelude::SliceRandom;
|
||||
use crate::navigation::{NavigatedPage, Page};
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct RandomizerState {
|
||||
|
||||
+9
-6
@@ -1,16 +1,19 @@
|
||||
use crate::data_provider::voice::get_voice;
|
||||
use crate::lang::{CardSet, CardStatistics, WordData, WordOpenMode};
|
||||
use crate::repetitions::CardSetSettings;
|
||||
use crate::Page::PreviousPage;
|
||||
use crate::{AppState, KeyPressedPage, NavigatedPage, Page, RootMessage, DEFAULT_SPACING};
|
||||
use crate::{AppState, RootMessage};
|
||||
use iced::alignment::Horizontal::Center;
|
||||
use iced::keyboard::key::Physical::Code;
|
||||
use iced::widget::{button, column, container, row, rule, space, text, Column};
|
||||
use iced::{alignment, keyboard, Element, Fill, Left, Task};
|
||||
use iced::{alignment, keyboard, Element, Fill, Left, Task, Theme};
|
||||
use rodio::MixerDeviceSink;
|
||||
use std::collections::HashSet;
|
||||
use std::sync::{Arc, Mutex};
|
||||
use iced::widget::text::Style;
|
||||
use tokio::task::spawn_blocking;
|
||||
use crate::navigation::{KeyPressedPage, NavigatedPage, Page};
|
||||
use crate::navigation::Page::PreviousPage;
|
||||
use crate::styling::*;
|
||||
|
||||
pub struct RepetitionState {
|
||||
pub settings: CardSetSettings,
|
||||
@@ -128,7 +131,7 @@ impl RepetitionState {
|
||||
container(self.answer_bar())
|
||||
.width(Fill)
|
||||
.align_x(Center)
|
||||
.height(60),
|
||||
.height(80),
|
||||
text!(
|
||||
"Затронуто слов {}, {}%",
|
||||
self.opened.len(),
|
||||
@@ -182,12 +185,12 @@ impl RepetitionState {
|
||||
|
||||
fn answer_bar(&self) -> Element<'_, RepetitionMessage> {
|
||||
if !self.open {
|
||||
return space().into();
|
||||
return text!("Нажмите Пробел для открытия карточки").style(|theme: &Theme| {Style{ color: Some(theme.palette().text.scale_alpha(0.3)) }}).into();
|
||||
}
|
||||
|
||||
column![
|
||||
text!("{} очков", self.current_statistic.calculated_score().round() as i32),
|
||||
row![
|
||||
|
||||
button("Не получилось").on_press(RepetitionMessage::Answer(WordOpenMode::None)),
|
||||
button("Трудно").on_press(RepetitionMessage::Answer(WordOpenMode::Hard)),
|
||||
button("Нормально").on_press(RepetitionMessage::Answer(WordOpenMode::Ok)),
|
||||
|
||||
+14
-9
@@ -2,16 +2,18 @@ use crate::data_provider::card_sets::{delete_set, update_card_set};
|
||||
use crate::data_provider::card_stats::load_stats_of_set;
|
||||
use crate::lang::{SetOrderMode, WordData};
|
||||
use crate::repetition::RepetitionState;
|
||||
use crate::Page::{History, PreviousPage, Repetition};
|
||||
use crate::{AppState, NavigatedPage, Page, RootMessage, DEFAULT_SPACING};
|
||||
use iced::widget::button::danger;
|
||||
use crate::{AppState, RootMessage};
|
||||
use iced::widget::button::{danger, Status};
|
||||
pub use iced::widget::button::{Catalog, Style};
|
||||
use iced::widget::container::bordered_box;
|
||||
use iced::widget::{button, column, container, radio, row, scrollable, space, text, text_input, Column};
|
||||
use iced::{Border, Center, Element, Fill, Left, Length, Shadow, Task, Theme};
|
||||
use iced::{color, Background, Border, Center, Color, Element, Fill, Left, Length, Shadow, Task, Theme};
|
||||
use rhai::{Engine, Scope};
|
||||
use std::sync::{Arc, Mutex};
|
||||
use crate::history::HistoryState;
|
||||
use crate::navigation::{NavigatedPage, Page};
|
||||
use crate::navigation::Page::{History, PreviousPage, Repetition};
|
||||
use crate::styling::*;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct RepetitionsState {
|
||||
@@ -134,7 +136,6 @@ impl RepetitionsState {
|
||||
self.launch_button()
|
||||
]
|
||||
.align_y(Center)
|
||||
.padding(10)
|
||||
.spacing(DEFAULT_SPACING)
|
||||
.width(Fill)
|
||||
.height(Fill)
|
||||
@@ -148,7 +149,7 @@ impl RepetitionsState {
|
||||
}
|
||||
|
||||
fn launch_button(&self) -> Element<'_, RepetitionsMessage> {
|
||||
if let Some(_) = self.selected_set {
|
||||
if let Some(set) = self.selected_set && self.state.lock().unwrap().card_sets[set].id != 0 {
|
||||
return button(text!("▷").height(Fill).center())
|
||||
.height(200)
|
||||
.on_press(RepetitionsMessage::GoToRepetition)
|
||||
@@ -235,14 +236,18 @@ impl RepetitionsState {
|
||||
column = column.push(
|
||||
button(text!("{}", set.name.clone()))
|
||||
.on_press_with(move || RepetitionsMessage::SelectSet(i.clone()))
|
||||
.style(move |_x: &Theme, _status| Style {
|
||||
background: None,
|
||||
.style(move |_x: &Theme, status : Status| Style {
|
||||
background: if status == Status::Hovered {Some(Background::Color(Color::WHITE.scale_alpha(0.1)))} else { None },
|
||||
text_color: if self.correct_filters[i.clone()] {
|
||||
_x.palette().primary
|
||||
} else {
|
||||
_x.palette().warning
|
||||
},
|
||||
border: Border::default(),
|
||||
border: Border{
|
||||
color: Default::default(),
|
||||
width: 0.0,
|
||||
radius: 8.0.into(),
|
||||
},
|
||||
shadow: Shadow::default(),
|
||||
snap: false,
|
||||
}),
|
||||
|
||||
+4
-2
@@ -5,10 +5,12 @@ use crate::randomizer::randomizer::RandomizerState;
|
||||
use crate::repetitions::RepetitionsState;
|
||||
use crate::selector::SelectorMessage::ChangeMode;
|
||||
use crate::writing::WritingState;
|
||||
use crate::Page::{Quiz, Writing};
|
||||
use crate::{AppState, NavigatedPage, Page, QuizState, RootMessage, DEFAULT_SPACING};
|
||||
use crate::{AppState, QuizState, RootMessage};
|
||||
use iced::widget::*;
|
||||
use iced::{alignment, Element, Task};
|
||||
use crate::navigation::{NavigatedPage, Page};
|
||||
use crate::navigation::Page::{Quiz, Writing};
|
||||
use crate::styling::*;
|
||||
use crate::sync::SyncState;
|
||||
|
||||
pub struct SelectorState {
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
use iced::border::Radius;
|
||||
use iced::widget::button::{primary, Status};
|
||||
use iced::widget::button::danger;
|
||||
|
||||
use iced::widget::{button, Button};
|
||||
use iced::Element;
|
||||
use iced_core::{Background, Border, Theme};
|
||||
use crate::repetitions::Style;
|
||||
|
||||
pub const DEFAULT_SPACING: f32 = 16.0;
|
||||
pub const ACCENT_FONT_SIZE: f32 = 22.0;
|
||||
const BUTTON_RADIUS: f32 = 8.0;
|
||||
|
||||
|
||||
pub fn jl_button(theme: &Theme, status: Status) -> Style {
|
||||
let mut style = primary(theme, status);
|
||||
style.border = Border
|
||||
{
|
||||
color: Default::default(),
|
||||
width: 0.0,
|
||||
radius: Radius::new(BUTTON_RADIUS),
|
||||
};
|
||||
style
|
||||
}
|
||||
+10
-6
@@ -1,16 +1,20 @@
|
||||
use crate::data_provider::settings::{delete_settings, set_setting};
|
||||
use crate::dictionary::app_data_dir;
|
||||
use crate::sync::SyncMessage::NextAnimation;
|
||||
use crate::Page::PreviousPage;
|
||||
use crate::{fill_state, AppState, NavigatedPage, Page, RootMessage, DEFAULT_SPACING};
|
||||
use crate::{fill_state, AppState, RootMessage};
|
||||
use iced::widget::button::danger;
|
||||
use iced::widget::container::rounded_box;
|
||||
use iced::widget::{button, column, container, progress_bar, row, space, text};
|
||||
use iced::{Center, Element, Fill, Font, Left, Task};
|
||||
use iced::widget::{button, column, container, progress_bar, row, scrollable, space, text};
|
||||
use iced::{Center, Element, Fill, Font, Left, Length, Task};
|
||||
use std::io;
|
||||
use std::sync::{Arc, Mutex};
|
||||
use std::time::Duration;
|
||||
use iced::border::width;
|
||||
use iced::widget::operation::scroll_to;
|
||||
use zstd::{Decoder, Encoder, DEFAULT_COMPRESSION_LEVEL};
|
||||
use crate::navigation::{NavigatedPage, Page};
|
||||
use crate::navigation::Page::PreviousPage;
|
||||
use crate::styling::*;
|
||||
|
||||
const API_URL: &str = "https://learning.micialware.ru/";
|
||||
/*const API_URL: &str = "http://localhost:8089/";*/
|
||||
@@ -181,7 +185,7 @@ impl SyncState {
|
||||
column![
|
||||
text!("Ваш ключ синхронизации"),
|
||||
container(
|
||||
container(text!("{}", key).size(20).font(Font::MONOSPACE)).padding(3)
|
||||
container(text!("{}", key).size(ACCENT_FONT_SIZE).font(Font::MONOSPACE)).padding(3)
|
||||
)
|
||||
|
||||
.style(rounded_box),
|
||||
@@ -208,7 +212,7 @@ impl SyncState {
|
||||
}
|
||||
.spacing(DEFAULT_SPACING)
|
||||
.align_x(Center)
|
||||
.width(300)
|
||||
.width(Length::Shrink)
|
||||
.into()
|
||||
}
|
||||
|
||||
|
||||
+4
-2
@@ -1,11 +1,13 @@
|
||||
use crate::data_provider::words::{delete_word, update_word};
|
||||
use crate::lang::WordData;
|
||||
use crate::Page::PreviousPage;
|
||||
use crate::{AppState, NavigatedPage, Page, RootMessage, DEFAULT_SPACING};
|
||||
use crate::{AppState, RootMessage};
|
||||
use iced::widget::button::danger;
|
||||
use iced::widget::{button, column, container, row, rule, scrollable, space, text, text_input};
|
||||
use iced::{Element, Fill, Task};
|
||||
use std::sync::{Arc, Mutex};
|
||||
use crate::navigation::{NavigatedPage, Page};
|
||||
use crate::navigation::Page::PreviousPage;
|
||||
use crate::styling::*;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct WordState {
|
||||
|
||||
+4
-2
@@ -1,9 +1,11 @@
|
||||
use crate::lang::KanaSet;
|
||||
use crate::Page::PreviousPage;
|
||||
use crate::{NavigatedPage, Page, RootMessage, DEFAULT_SPACING};
|
||||
use crate::{ RootMessage};
|
||||
use iced::widget::*;
|
||||
use iced::{alignment, Element, Fill, Task};
|
||||
use rand::seq::SliceRandom;
|
||||
use crate::navigation::{NavigatedPage, Page};
|
||||
use crate::navigation::Page::PreviousPage;
|
||||
use crate::styling::*;
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct WritingState {
|
||||
|
||||
Reference in New Issue
Block a user