Before button global styling

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