From d9bd1b1b86ed0567f571e9468d07363c53bc7bd1 Mon Sep 17 00:00:00 2001 From: Mikhail Mitrofanov Date: Sat, 1 Aug 2026 13:04:18 +0300 Subject: [PATCH] Before button global styling --- Cargo.lock | 17 +++- Cargo.toml | 3 +- src/dictionary.rs | 12 +-- src/dictionary_test.rs | 9 +- src/history.rs | 6 +- src/main.rs | 191 ++++------------------------------------- src/navigation.rs | 179 ++++++++++++++++++++++++++++++++++++++ src/quiz.rs | 6 +- src/randomizer.rs | 3 +- src/repetition.rs | 15 ++-- src/repetitions.rs | 23 +++-- src/selector.rs | 6 +- src/styling.rs | 24 ++++++ src/sync.rs | 16 ++-- src/word.rs | 6 +- src/writing.rs | 6 +- 16 files changed, 304 insertions(+), 218 deletions(-) create mode 100644 src/navigation.rs create mode 100644 src/styling.rs diff --git a/Cargo.lock b/Cargo.lock index d4c511d..45dc57e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -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", diff --git a/Cargo.toml b/Cargo.toml index 552253b..ba71ca0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -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" diff --git a/src/dictionary.rs b/src/dictionary.rs index ad549f7..d63963c 100644 --- a/src/dictionary.rs +++ b/src/dictionary.rs @@ -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)), diff --git a/src/dictionary_test.rs b/src/dictionary_test.rs index 52eeb58..254037f 100644 --- a/src/dictionary_test.rs +++ b/src/dictionary_test.rs @@ -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), diff --git a/src/history.rs b/src/history.rs index e41cfb7..c2ec250 100644 --- a/src/history.rs +++ b/src/history.rs @@ -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 { + pub fn update(&mut self, _: HistoryMessage) -> Task { Task::none() } diff --git a/src/main.rs b/src/main.rs index 5035bb6..93e11f5 100644 --- a/src/main.rs +++ b/src/main.rs @@ -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::data_provider::words::{load_word_groups, load_words}; +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 { 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, -} pub struct AppState { pub dictionary: Vec, @@ -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) { - create_db(); - (ScreenState::default(), Task::none()) - } - pub fn update(&mut self, message: RootMessage) -> Task { - 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 { - let page = self.stack.last_mut().unwrap(); - match page { - Repetition(page) => page.press(&message), - _ => Task::none(), - } - } -} - -pub struct AppSettings { - key: Option, -} - -#[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 { - fn navigate(&self, message: &T) -> Option; -} - -pub trait KeyPressedPage { - fn press(&mut self, message: &Event) -> Task; -} diff --git a/src/navigation.rs b/src/navigation.rs new file mode 100644 index 0000000..f192fa4 --- /dev/null +++ b/src/navigation.rs @@ -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, +} + +impl ScreenState { + pub fn boot() -> (ScreenState, Task) { + create_db(); + (ScreenState::default(), Task::none()) + } + pub fn update(&mut self, message: RootMessage) -> Task { + 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 { + let page = self.stack.last_mut().unwrap(); + match page { + Page::Repetition(page) => page.press(&message), + _ => Task::none(), + } + } +} + +pub struct AppSettings { + pub(crate) key: Option, +} + +#[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 { + fn navigate(&self, message: &T) -> Option; +} + +pub trait KeyPressedPage { + fn press(&mut self, message: &Event) -> Task; +} diff --git a/src/quiz.rs b/src/quiz.rs index 3425618..cdd623b 100644 --- a/src/quiz.rs +++ b/src/quiz.rs @@ -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 { diff --git a/src/randomizer.rs b/src/randomizer.rs index 5290609..3a2fdfa 100644 --- a/src/randomizer.rs +++ b/src/randomizer.rs @@ -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 { diff --git a/src/repetition.rs b/src/repetition.rs index 5f78643..c5d02d4 100644 --- a/src/repetition.rs +++ b/src/repetition.rs @@ -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)), diff --git a/src/repetitions.rs b/src/repetitions.rs index 4cc268e..ea6886c 100644 --- a/src/repetitions.rs +++ b/src/repetitions.rs @@ -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, }), diff --git a/src/selector.rs b/src/selector.rs index 75f1d3e..e4283c9 100644 --- a/src/selector.rs +++ b/src/selector.rs @@ -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 { diff --git a/src/styling.rs b/src/styling.rs new file mode 100644 index 0000000..6f44aef --- /dev/null +++ b/src/styling.rs @@ -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 +} \ No newline at end of file diff --git a/src/sync.rs b/src/sync.rs index 6b36e2e..bbeaf8b 100644 --- a/src/sync.rs +++ b/src/sync.rs @@ -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() } diff --git a/src/word.rs b/src/word.rs index 08fea52..3c29736 100644 --- a/src/word.rs +++ b/src/word.rs @@ -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 { diff --git a/src/writing.rs b/src/writing.rs index 376c75d..252ea62 100644 --- a/src/writing.rs +++ b/src/writing.rs @@ -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 {