apply new style

This commit is contained in:
micialware committed 2026-09-15 22:09:06 +03:00
1 parent b1902b35cb
commit 1847d4f44f
14 files changed
+144 -89

No files matched your search

+1 -1
View File
@@ -1,5 +1,6 @@
use crate::data::repositories::Repository; use crate::data::repositories::Repository;
use crate::data_provider::card_states::CardStateRepository; use crate::data_provider::card_states::CardStateRepository;
use crate::data_provider::custom_fields::CustomFieldRepository;
use crate::data_provider::decks::DeckRepository; use crate::data_provider::decks::DeckRepository;
use crate::data_provider::history::HistoryRepository; use crate::data_provider::history::HistoryRepository;
use crate::data_provider::settings::get_setting; use crate::data_provider::settings::get_setting;
@@ -17,7 +18,6 @@ use log::info;
use parking_lot::{Mutex, RwLock}; use parking_lot::{Mutex, RwLock};
use rusqlite::Connection; use rusqlite::Connection;
use std::sync::Arc; use std::sync::Arc;
use crate::data_provider::custom_fields::CustomFieldRepository;
pub const USER_FONT: Font = Font::with_name("Noto Sans JP"); pub const USER_FONT: Font = Font::with_name("Noto Sans JP");
+11 -5
View File
@@ -1,21 +1,21 @@
use std::collections::HashMap;
use crate::app::AppState; use crate::app::AppState;
use crate::core::srs::OrderModule::{Fsrs, RandomSRS, SemiRandomSRS, WorstWordsSRS}; use crate::core::srs::OrderModule::{Fsrs, RandomSRS, SemiRandomSRS, WorstWordsSRS};
use crate::core::srs::{ use crate::core::srs::{
FsrsModule, OrderMode, OrderModule, RandomSRSModule, SRSModule, SemiRandomSRSModule, FsrsModule, OrderMode, OrderModule, RandomSRSModule, SRSModule, SemiRandomSRSModule,
WordOpenMode, WorstWordsSRSModule, WordOpenMode, WorstWordsSRSModule,
}; };
use crate::data::Id;
use crate::data::entities::*; use crate::data::entities::*;
use crate::data::repositories::Repository; use crate::data::repositories::Repository;
use crate::data_provider::card_states::CardStateRepositoryInner; use crate::data_provider::card_states::CardStateRepositoryInner;
use crate::notification::MaybeError; use crate::notification::MaybeError;
use chrono::Utc; use chrono::Utc;
use litemap::LiteMap;
use log::info; use log::info;
use rhai::{Engine, Scope}; use rhai::{Engine, Scope};
use std::collections::HashMap;
use std::sync::Arc; use std::sync::Arc;
use std::time::Instant; use std::time::Instant;
use litemap::LiteMap;
use crate::data::Id;
#[derive(Clone)] #[derive(Clone)]
pub struct DeckData { pub struct DeckData {
@@ -28,7 +28,7 @@ pub struct DeckData {
settings: DeckSettings, settings: DeckSettings,
} }
struct DisplayStyle{ struct DisplayStyle {
properties: LiteMap<String, String>, properties: LiteMap<String, String>,
} }
@@ -162,7 +162,13 @@ impl DeckData {
if let Ok(ast) = ast { if let Ok(ast) = ast {
let groups = state.word_groups.read().iter().cloned().collect::<Vec<_>>(); let groups = state.word_groups.read().iter().cloned().collect::<Vec<_>>();
let dictionary = &state.dictionary.read(); let dictionary = &state.dictionary.read();
let fields : HashMap<Id, String> = HashMap::from_iter(state.custom_fields.read().iter().map(|f| (f.id, f.identifier.clone()))); let fields: HashMap<Id, String> = HashMap::from_iter(
state
.custom_fields
.read()
.iter()
.map(|f| (f.id, f.identifier.clone())),
);
let query = dictionary.query_par(Arc::new(move |word| { let query = dictionary.query_par(Arc::new(move |word| {
let mut more = rhai::Map::new(); let mut more = rhai::Map::new();
for kv in &word.additional { for kv in &word.additional {
+2 -2
View File
@@ -1,5 +1,5 @@
use crate::core::srs::{WordOpenMode, FADE_PER_DAY, MAX_SCORE}; use crate::core::srs::{FADE_PER_DAY, MAX_SCORE, WordOpenMode};
use crate::data::{Id, INVALID_ID}; use crate::data::{INVALID_ID, Id};
use crate::data_provider::history::HistoryRepositoryInner; use crate::data_provider::history::HistoryRepositoryInner;
use chrono::{DateTime, Local, NaiveDate, Utc}; use chrono::{DateTime, Local, NaiveDate, Utc};
use fsrs::MemoryState; use fsrs::MemoryState;
+7 -8
View File
@@ -1,11 +1,11 @@
use crate::helpers::into_result; use crate::helpers::into_result;
use crate::notification::NotificationData; use crate::notification::NotificationData;
use crate::notification::NotificationData::IncorrectAnkiFile; use crate::notification::NotificationData::IncorrectAnkiFile;
use crate::pages::import::AnkiSchema;
use log::info; use log::info;
use rusqlite::Connection; use rusqlite::Connection;
use serde_json::Value; use serde_json::Value;
use std::collections::BTreeMap; use std::collections::BTreeMap;
use crate::pages::import::AnkiSchema;
#[derive(Clone)] #[derive(Clone)]
pub struct ImportData(pub(crate) Vec<ImportGroup>); pub struct ImportData(pub(crate) Vec<ImportGroup>);
@@ -26,14 +26,13 @@ pub struct ImportNote {
pub fields: Vec<String>, pub fields: Vec<String>,
} }
pub fn load_groups(connection: &Connection, schema: AnkiSchema) -> Result<ImportData, NotificationData> { pub fn load_groups(
connection: &Connection,
schema: AnkiSchema,
) -> Result<ImportData, NotificationData> {
match schema { match schema {
AnkiSchema::Old => { AnkiSchema::Old => load_old_schema(connection),
load_old_schema(connection) AnkiSchema::Beta => load_new_schema(connection),
}
AnkiSchema::Beta => {
load_new_schema(connection)
}
} }
} }
+20 -10
View File
@@ -1,6 +1,6 @@
use crate::data::Id;
use crate::data::entities::WordData; use crate::data::entities::WordData;
use crate::data::repositories::{DataRepository, DataRepositoryInner}; use crate::data::repositories::{DataRepository, DataRepositoryInner};
use crate::data::Id;
use crate::data_provider::{SqliteDbLayer, TableAccessQuerySet}; use crate::data_provider::{SqliteDbLayer, TableAccessQuerySet};
use litemap::LiteMap; use litemap::LiteMap;
use rusqlite::{Error, Params, Row}; use rusqlite::{Error, Params, Row};
@@ -70,24 +70,34 @@ fn additional_to_string(map: &LiteMap<Id, String>) -> String {
} }
fn additional_from_string_temp(data: String) -> LiteMap<Id, String> { fn additional_from_string_temp(data: String) -> LiteMap<Id, String> {
let pre_map: LiteMap<String, String> = serde_json::from_str(data.as_str()).unwrap();
let pre_map : LiteMap<String, String> = serde_json::from_str(data.as_str()).unwrap(); LiteMap::from(
LiteMap::from(pre_map.iter().map(|(k, v)| (match k.as_str() { pre_map
"reading" => Id(1), .iter()
"description" => Id(2), .map(|(k, v)| {
"context" => Id(3), (
&_ => Id(0) }, v.to_string())).collect()) match k.as_str() {
"reading" => Id(1),
"description" => Id(2),
"context" => Id(3),
&_ => Id(0),
},
v.to_string(),
)
})
.collect(),
)
} }
fn additional_from_string(data: String) -> LiteMap<Id, String> { fn additional_from_string(data: String) -> LiteMap<Id, String> {
if data.is_empty() { if data.is_empty() {
return LiteMap::new() return LiteMap::new();
} }
let parts = data.split('').collect::<Vec<&str>>(); let parts = data.split('').collect::<Vec<&str>>();
let chunks = parts.chunks(2).collect::<Vec<&[&str]>>(); let chunks = parts.chunks(2).collect::<Vec<&[&str]>>();
let mut map = LiteMap::with_capacity(parts.len()); let mut map = LiteMap::with_capacity(parts.len());
for part in &chunks { for part in &chunks {
let id : Id = part[0].parse().unwrap(); let id: Id = part[0].parse().unwrap();
let value: String = part[1].to_string(); let value: String = part[1].to_string();
map.insert(id, value); map.insert(id, value);
} }
+46 -25
View File
@@ -1,7 +1,7 @@
use crate::app::AppState; use crate::app::AppState;
use crate::data::Id;
use crate::data::entities::{EntityHandle, WordData, WordGroup}; use crate::data::entities::{EntityHandle, WordData, WordGroup};
use crate::data::repositories::{Query, Repository}; use crate::data::repositories::{Query, Repository};
use crate::data::Id;
use crate::data_provider::word_groups::{WordGroupDataLayer, WordGroupRepositoryInner}; use crate::data_provider::word_groups::{WordGroupDataLayer, WordGroupRepositoryInner};
use crate::data_provider::words::WordDataLayer; use crate::data_provider::words::WordDataLayer;
use crate::data_provider::words::WordRepositoryInner; use crate::data_provider::words::WordRepositoryInner;
@@ -13,10 +13,10 @@ use crate::pages::dictionary::SelectionChangeDirection::*;
use crate::pages::dictionary_quiz::DictionaryQuizState; use crate::pages::dictionary_quiz::DictionaryQuizState;
use crate::pages::import::ImportState; use crate::pages::import::ImportState;
use crate::pages::word::{WordEditor, WordMessage}; use crate::pages::word::{WordEditor, WordMessage};
use crate::push_error_task;
use crate::styling::*; use crate::styling::*;
use crate::widgets::hard_mouse_area::hard_mouse_area; use crate::widgets::hard_mouse_area::hard_mouse_area;
use crate::{jl_button, push_error}; use crate::{jl_button, push_error};
use crate::{jl_text_input, push_error_task};
use chrono::{DateTime, TimeDelta, Utc}; use chrono::{DateTime, TimeDelta, Utc};
use hashbrown::{HashMap, HashSet}; use hashbrown::{HashMap, HashSet};
use iced::alignment::Vertical::Center; use iced::alignment::Vertical::Center;
@@ -24,15 +24,16 @@ use iced::widget::button::Style;
use iced::widget::button::{danger, text}; use iced::widget::button::{danger, text};
use iced::widget::operation::focus; use iced::widget::operation::focus;
use iced::widget::space::horizontal; use iced::widget::space::horizontal;
use iced::widget::text_input::default;
use iced::widget::text_input::Status::Active; use iced::widget::text_input::Status::Active;
use iced::widget::text_input::default;
use iced::widget::*; use iced::widget::*;
use iced::{Border, Color, Shadow, Task}; use iced::{Border, Color, Shadow, Task};
use iced_core::Length::{Fill, FillPortion};
use iced_core::border::Radius;
use iced_core::keyboard; use iced_core::keyboard;
use iced_core::keyboard::Key::Named;
use iced_core::keyboard::key::Physical::Code; use iced_core::keyboard::key::Physical::Code;
use iced_core::keyboard::{Event, Modifiers}; use iced_core::keyboard::{Event, Modifiers};
use iced_core::keyboard::Key::Named;
use iced_core::Length::{Fill, FillPortion};
use log::info; use log::info;
use rand::random_range; use rand::random_range;
use std::ops::Add; use std::ops::Add;
@@ -81,7 +82,7 @@ pub enum DictionaryMessage {
EditField(String), EditField(String),
ChangeSelectedField(SelectionChangeDirection), ChangeSelectedField(SelectionChangeDirection),
EditorAction(WordMessage), EditorAction(WordMessage),
ExtendedWordEdited ExtendedWordEdited,
} }
#[derive(Clone, PartialEq, Eq, Hash, Copy)] #[derive(Clone, PartialEq, Eq, Hash, Copy)]
@@ -253,7 +254,9 @@ impl NavigatedPage<DictionaryMessage> for DictionaryState {
let _ = dictionary.save(&mut handle); let _ = dictionary.save(&mut handle);
if reload_query { if reload_query {
self.displayed_words_query.load(&dictionary); self.displayed_words_query.load(&dictionary);
if let Some(selected) = self.selected_cell && selected.0 == original { if let Some(selected) = self.selected_cell
&& selected.0 == original
{
self.selected_cell = Some((handle, selected.1, selected.2)); self.selected_cell = Some((handle, selected.1, selected.2));
if self.word_editor.is_some() { if self.word_editor.is_some() {
self.word_editor = Some(self.editor_for_word(handle)); self.word_editor = Some(self.editor_for_word(handle));
@@ -267,7 +270,10 @@ impl NavigatedPage<DictionaryMessage> for DictionaryState {
GotoImport => {} GotoImport => {}
SelectField(e, f, index) => { SelectField(e, f, index) => {
info!("Editing word {}", e.id); info!("Editing word {}", e.id);
if self.word_editor.is_some() && let Some(selected) = &self.selected_cell && selected.0 != e { if self.word_editor.is_some()
&& let Some(selected) = &self.selected_cell
&& selected.0 != e
{
self.word_editor = Some(self.editor_for_word(e)); self.word_editor = Some(self.editor_for_word(e));
} }
self.selected_cell = Some((e, f, index)); self.selected_cell = Some((e, f, index));
@@ -349,18 +355,16 @@ impl NavigatedPage<DictionaryMessage> for DictionaryState {
} }
self.displayed_words_query.load(&dictionary); self.displayed_words_query.load(&dictionary);
self.selected_cell = None; self.selected_cell = None;
self.word_editor = None; self.word_editor = None;
} }
EditorAction(action) => { EditorAction(action) => {
let result = self.word_editor.as_mut().unwrap().update(action); let result = self.word_editor.as_mut().unwrap().update(action);
if let Some(result) = result { if let Some(result) = result {
match result { match result {
DeleteWord(_) | DeleteWord(_) | ExtendedWordEdited => {
ExtendedWordEdited => {
return Task::done(RootMessage::Dictionary(result)); return Task::done(RootMessage::Dictionary(result));
}, }
_ => {} _ => {}
} }
@@ -387,7 +391,8 @@ impl NavigatedPage<DictionaryMessage> for DictionaryState {
button("Импорт").style(text).on_press(GotoImport), button("Импорт").style(text).on_press(GotoImport),
] ]
] ]
.spacing(5).width(FillPortion(4)), .spacing(5)
.width(FillPortion(4)),
self.right_panel(), self.right_panel(),
] ]
.spacing(DEFAULT_SPACING) .spacing(DEFAULT_SPACING)
@@ -425,7 +430,9 @@ impl DictionaryState {
} }
fn editor_for_word(&self, handle: EntityHandle<WordData>) -> WordEditor<DictionaryMessage> { fn editor_for_word(&self, handle: EntityHandle<WordData>) -> WordEditor<DictionaryMessage> {
WordEditor::new(handle, self.state.clone()).on_delete(DeleteWord(handle)).on_edit(ExtendedWordEdited) WordEditor::new(handle, self.state.clone())
.on_delete(DeleteWord(handle))
.on_edit(ExtendedWordEdited)
} }
fn init(&mut self) { fn init(&mut self) {
@@ -580,7 +587,9 @@ impl DictionaryState {
fn right_panel(&self) -> iced::Element<'_, DictionaryMessage> { fn right_panel(&self) -> iced::Element<'_, DictionaryMessage> {
if let Some(editor) = &self.word_editor { if let Some(editor) = &self.word_editor {
container(editor.view().map(EditorAction)).width(FillPortion(3)).into() container(editor.view().map(EditorAction))
.width(FillPortion(3))
.into()
} else { } else {
self.filters() self.filters()
} }
@@ -590,7 +599,7 @@ impl DictionaryState {
let dict = &self.state.dictionary.read(); let dict = &self.state.dictionary.read();
iced::widget::column![ iced::widget::column![
text_input("Поиск", &self.search) jl_text_input!("Поиск", &self.search)
.on_input(Search) .on_input(Search)
.width(Fill), .width(Fill),
text!("Всего слов: {}", dict.len()), text!("Всего слов: {}", dict.len()),
@@ -709,6 +718,7 @@ impl DictionaryState {
fn selection_editor(&self) -> iced::Element<'_, DictionaryMessage> { fn selection_editor(&self) -> iced::Element<'_, DictionaryMessage> {
let mut display = "".to_string(); let mut display = "".to_string();
let mut editable = false;
if let Some(selected) = self.selected_cell.as_ref() { if let Some(selected) = self.selected_cell.as_ref() {
let mut dictionary = self.state.dictionary.write(); let mut dictionary = self.state.dictionary.write();
let word = dictionary.get_mut_static(selected.0).unwrap(); let word = dictionary.get_mut_static(selected.0).unwrap();
@@ -724,12 +734,21 @@ impl DictionaryState {
display = word.tags.clone(); display = word.tags.clone();
} }
} }
editable = true;
} }
text_input("", display.as_str()) let mut field = jl_text_input!("", display.as_str())
.width(Fill) .width(Fill)
.id(iced::widget::Id::new("editor")) .id(iced::widget::Id::new("editor"))
.on_input(EditField) .style(|theme, status| {
.into() let mut default = default(theme, status);
default.border.radius = Radius::new(0);
default
});
if editable {
field = field.on_input(EditField)
}
field.into()
} }
fn groups_panel(&self) -> iced::Element<'_, DictionaryMessage> { fn groups_panel(&self) -> iced::Element<'_, DictionaryMessage> {
@@ -754,7 +773,7 @@ impl DictionaryState {
scrollable(row).width(Fill).horizontal(), scrollable(row).width(Fill).horizontal(),
row![ row![
jl_button!("⇳").on_press(ChangeDirection), jl_button!("⇳").on_press(ChangeDirection),
text_input("Название группы слов", &group.name) jl_text_input!("Название группы слов", &group.name)
.on_input(EditGroup) .on_input(EditGroup)
.width(250) .width(250)
.on_submit(SaveGroup), .on_submit(SaveGroup),
@@ -806,18 +825,20 @@ impl KeyPressedPage for DictionaryState {
Task::done(RootMessage::Dictionary(ChangeSelectedField(Previous))) Task::done(RootMessage::Dictionary(ChangeSelectedField(Previous)))
} }
keyboard::key::Code::Tab => { keyboard::key::Code::Tab => {
return if *mods == Modifiers::CTRL && let Some(selected) = self.selected_cell { return if *mods == Modifiers::CTRL
&& let Some(selected) = self.selected_cell
{
Task::done(RootMessage::Dictionary(ExtendedEdit(selected.0))) Task::done(RootMessage::Dictionary(ExtendedEdit(selected.0)))
} else if let Named(keyboard::key::Named::Alt) = modifier { } else if let Named(keyboard::key::Named::Alt) = modifier {
Task::done(RootMessage::Dictionary(ChangeSelectedField(Backward))) Task::done(RootMessage::Dictionary(ChangeSelectedField(Backward)))
} else { } else {
Task::done(RootMessage::Dictionary(ChangeSelectedField(Forward))) Task::done(RootMessage::Dictionary(ChangeSelectedField(Forward)))
} };
} }
keyboard::key::Code::Escape => { keyboard::key::Code::Escape => {
if self.word_editor.is_some() { if self.word_editor.is_some() {
self.word_editor = None; self.word_editor = None;
}else if self.selected_cell.is_some() { } else if self.selected_cell.is_some() {
self.selected_cell = None; self.selected_cell = None;
} }
+2 -2
View File
@@ -1,7 +1,6 @@
use crate::app::AppState; use crate::app::AppState;
use crate::data::entities::{EntityHandle, WordData}; use crate::data::entities::{EntityHandle, WordData};
use crate::data::repositories::Repository; use crate::data::repositories::Repository;
use crate::jl_button;
use crate::navigation::Page::PreviousPage; use crate::navigation::Page::PreviousPage;
use crate::navigation::RootMessage; use crate::navigation::RootMessage;
use crate::navigation::*; use crate::navigation::*;
@@ -9,6 +8,7 @@ use crate::pages::dictionary::split_with_coma;
use crate::pages::dictionary_quiz::DictionaryQuizMessage::*; use crate::pages::dictionary_quiz::DictionaryQuizMessage::*;
use crate::pages::quiz::Score; use crate::pages::quiz::Score;
use crate::styling::*; use crate::styling::*;
use crate::{jl_button, jl_text_input};
use iced::Background::Color; use iced::Background::Color;
use iced::border::Radius; use iced::border::Radius;
use iced::widget::container::Style; use iced::widget::container::Style;
@@ -76,7 +76,7 @@ impl NavigatedPage<DictionaryQuizMessage> for DictionaryQuizState {
] ]
.align_x(alignment::Horizontal::Center) .align_x(alignment::Horizontal::Center)
.spacing(5), .spacing(5),
text_input("Перевод", &self.answer) jl_text_input!("Перевод", &self.answer)
.size(28) .size(28)
.width(250) .width(250)
.on_input(AnswerChanged) .on_input(AnswerChanged)
+10 -5
View File
@@ -9,9 +9,9 @@ use crate::navigation::{NavigatedPage, Page, RootMessage};
use crate::notification::NotificationData::{CompressError, OpenFileError}; use crate::notification::NotificationData::{CompressError, OpenFileError};
use crate::notification::{MaybeError, NotificationData}; use crate::notification::{MaybeError, NotificationData};
use crate::pages::import::ImportMessage::*; use crate::pages::import::ImportMessage::*;
use crate::push_error;
use crate::styling::*; use crate::styling::*;
use crate::{jl_button, push_error_task}; use crate::{jl_button, push_error_task};
use crate::{jl_text_input, push_error};
use iced::widget::button::danger; use iced::widget::button::danger;
use iced::widget::container::success; use iced::widget::container::success;
use iced::widget::{ use iced::widget::{
@@ -269,7 +269,7 @@ impl ImportState {
self.available_properties(), self.available_properties(),
button("Добавить напрямую").on_press(SetupDirect), button("Добавить напрямую").on_press(SetupDirect),
row![ row![
text_input("Пользовательское поле", &self.custom_property_name) jl_text_input!("Пользовательское поле", &self.custom_property_name)
.on_input(EditCustomProperty), .on_input(EditCustomProperty),
button("Установить привязку").on_press(SetupCustomProperty) button("Установить привязку").on_press(SetupCustomProperty)
] ]
@@ -297,7 +297,7 @@ impl ImportState {
.on_toggle(SwitchSkipEmpty), .on_toggle(SwitchSkipEmpty),
column![ column![
text!("Разделитель при множественном объединении"), text!("Разделитель при множественном объединении"),
text_input("", &self.separator).on_input(EditSeparator) jl_text_input!("", &self.separator).on_input(EditSeparator)
] ]
] ]
.spacing(DEFAULT_SPACING) .spacing(DEFAULT_SPACING)
@@ -582,7 +582,11 @@ impl ImportState {
.iter() .iter()
.map(|field| field.identifier.clone()) .map(|field| field.identifier.clone())
.collect(); .collect();
current_fields.append(&mut vec!["key".to_string(), "value".to_string(), "tags".to_string()]); current_fields.append(&mut vec![
"key".to_string(),
"value".to_string(),
"tags".to_string(),
]);
for (field, _) in import_group { for (field, _) in import_group {
if current_fields.contains(field) { if current_fields.contains(field) {
continue; continue;
@@ -600,5 +604,6 @@ impl ImportState {
} }
pub enum AnkiSchema { pub enum AnkiSchema {
Old, Beta Old,
Beta,
} }
+2 -2
View File
@@ -1,10 +1,10 @@
use crate::app::USER_FONT; use crate::app::USER_FONT;
use crate::core::kana_set::KanaSet; use crate::core::kana_set::KanaSet;
use crate::jl_button;
use crate::navigation::Page::PreviousPage; use crate::navigation::Page::PreviousPage;
use crate::navigation::{NavigatedPage, Page, RootMessage}; use crate::navigation::{NavigatedPage, Page, RootMessage};
use crate::pages::quiz::QuizMessage::*; use crate::pages::quiz::QuizMessage::*;
use crate::styling::*; use crate::styling::*;
use crate::{jl_button, jl_text_input};
use iced::widget::*; use iced::widget::*;
use iced::{Element, Fill, Task, alignment}; use iced::{Element, Fill, Task, alignment};
use rand::seq::SliceRandom; use rand::seq::SliceRandom;
@@ -77,7 +77,7 @@ impl NavigatedPage<QuizMessage> for QuizState {
] ]
.align_y(alignment::Vertical::Center) .align_y(alignment::Vertical::Center)
.spacing(20), .spacing(20),
text_input("Романдзи", &self.current_roman) jl_text_input!("Романдзи", &self.current_roman)
.size(28) .size(28)
.width(150) .width(150)
.on_input(ContentChanged), .on_input(ContentChanged),
+5 -5
View File
@@ -2,12 +2,12 @@ use crate::app::AppState;
use crate::core::deck::DeckData; use crate::core::deck::DeckData;
use crate::data::entities::{DeckSettings, EntityHandle}; use crate::data::entities::{DeckSettings, EntityHandle};
use crate::data::repositories::{BatchedRepository, Repository}; use crate::data::repositories::{BatchedRepository, Repository};
use crate::jl_button;
use crate::navigation::Page::PreviousPage; use crate::navigation::Page::PreviousPage;
use crate::navigation::{NavigatedPage, Page, RootMessage}; use crate::navigation::{NavigatedPage, Page, RootMessage};
use crate::notification::MaybeError; use crate::notification::MaybeError;
use crate::pages::repetition_settings::RepetitionSettingsMessage::*; use crate::pages::repetition_settings::RepetitionSettingsMessage::*;
use crate::styling::*; use crate::styling::*;
use crate::{jl_button, jl_text_input};
use crate::{push_error, push_error_task}; use crate::{push_error, push_error_task};
use iced::widget::button::danger; use iced::widget::button::danger;
use iced::widget::space::horizontal; use iced::widget::space::horizontal;
@@ -143,22 +143,22 @@ impl NavigatedPage<RepetitionSettingsMessage> for RepetitionSettingsState {
column![ column![
column![ column![
text!("Название набора"), text!("Название набора"),
text_input("", &self.settings_data.name).on_input(SetName), jl_text_input!("", &self.settings_data.name).on_input(SetName),
] ]
.spacing(QUARTER_SPACING), .spacing(QUARTER_SPACING),
column![ column![
text!("Передняя сторона"), text!("Передняя сторона"),
text_input("", &self.settings_data.forward).on_input(SetForward), jl_text_input!("", &self.settings_data.forward).on_input(SetForward),
] ]
.spacing(QUARTER_SPACING), .spacing(QUARTER_SPACING),
column![ column![
text!("Задняя сторона"), text!("Задняя сторона"),
text_input("", &self.settings_data.backward).on_input(SetBackward), jl_text_input!("", &self.settings_data.backward).on_input(SetBackward),
] ]
.spacing(QUARTER_SPACING), .spacing(QUARTER_SPACING),
column![ column![
text!("Фильтр"), text!("Фильтр"),
text_input("", &self.settings_data.filter) jl_text_input!("", &self.settings_data.filter)
.style(|x, status| { .style(|x, status| {
let mut primary = Theme::default()(x, status); let mut primary = Theme::default()(x, status);
if !self.correct_filter { if !self.correct_filter {
+5 -5
View File
@@ -3,7 +3,6 @@ use crate::core::deck::DeckData;
use crate::core::srs::{AppendMode, OrderMode}; use crate::core::srs::{AppendMode, OrderMode};
use crate::data::entities::{CardState, DeckSettings, EntityHandle, WordData}; use crate::data::entities::{CardState, DeckSettings, EntityHandle, WordData};
use crate::data::repositories::{BatchedRepository, Repository}; use crate::data::repositories::{BatchedRepository, Repository};
use crate::jl_button;
use crate::navigation::Page::{History, PreviousPage, Repetition, RepetitionSettings}; use crate::navigation::Page::{History, PreviousPage, Repetition, RepetitionSettings};
use crate::navigation::{NavigatedPage, Page, RootMessage}; use crate::navigation::{NavigatedPage, Page, RootMessage};
use crate::notification::MaybeError; use crate::notification::MaybeError;
@@ -14,6 +13,7 @@ use crate::pages::repetitions::RepetitionsMessage::*;
use crate::push_error; use crate::push_error;
use crate::push_error_task; use crate::push_error_task;
use crate::styling::*; use crate::styling::*;
use crate::{jl_button, jl_text_input};
use chrono::{Days, Local, Utc}; use chrono::{Days, Local, Utc};
use hashbrown::HashSet; use hashbrown::HashSet;
pub use iced::widget::button::{Catalog, Style}; pub use iced::widget::button::{Catalog, Style};
@@ -303,7 +303,7 @@ impl RepetitionsState {
column![ column![
text!("Название набора"), text!("Название набора"),
row![ row![
text_input("", &deck.name).on_input(SetName), jl_text_input!("", &deck.name).on_input(SetName),
button(svg(Handle::from_memory(SETTINGS_ICON))) button(svg(Handle::from_memory(SETTINGS_ICON)))
.width(43) .width(43)
.on_press(GoToSettings), .on_press(GoToSettings),
@@ -316,17 +316,17 @@ impl RepetitionsState {
column![ column![
column![ column![
text!("Передняя сторона"), text!("Передняя сторона"),
text_input("", &deck.forward).on_input(SetForward), jl_text_input!("", &deck.forward).on_input(SetForward),
] ]
.spacing(QUARTER_SPACING), .spacing(QUARTER_SPACING),
column![ column![
text!("Задняя сторона"), text!("Задняя сторона"),
text_input("", &deck.backward).on_input(SetBackward), jl_text_input!("", &deck.backward).on_input(SetBackward),
] ]
.spacing(QUARTER_SPACING), .spacing(QUARTER_SPACING),
column![ column![
text!("Фильтр"), text!("Фильтр"),
text_input("", &deck.filter).on_input(SetFilter), jl_text_input!("", &deck.filter).on_input(SetFilter),
jl_button!("Проверить фильтр").on_press(TryFilter), jl_button!("Проверить фильтр").on_press(TryFilter),
self.count_view(deck), self.count_view(deck),
] ]
+17 -12
View File
@@ -2,6 +2,7 @@ use crate::app::AppState;
use crate::data::Id; use crate::data::Id;
use crate::data::entities::{CustomField, EntityHandle, WordData}; use crate::data::entities::{CustomField, EntityHandle, WordData};
use crate::data::repositories::Repository; use crate::data::repositories::Repository;
use crate::jl_text_input;
use crate::pages::word::WordMessage::*; use crate::pages::word::WordMessage::*;
use crate::styling::*; use crate::styling::*;
use iced::widget::button::danger; use iced::widget::button::danger;
@@ -65,23 +66,29 @@ impl<Message> WordEditor<Message> {
} }
let mut col = iced::widget::column![ let mut col = iced::widget::column![
column![text!("Ключ"), text_input("key", &word.key).on_input(SetKey),] column![
.spacing(QUARTER_SPACING), text!("Ключ"),
jl_text_input!("key", &word.key).on_input(SetKey),
]
.spacing(QUARTER_SPACING),
column![ column![
text!("Значение"), text!("Значение"),
text_input("value", &word.value).on_input(SetValue), jl_text_input!("value", &word.value).on_input(SetValue),
] ]
.spacing(QUARTER_SPACING), .spacing(QUARTER_SPACING),
column![ column![
text!("Теги"), text!("Теги"),
text_input("tags", &word.tags).on_input(SetTags), jl_text_input!("tags", &word.tags).on_input(SetTags),
] ]
.spacing(QUARTER_SPACING), .spacing(QUARTER_SPACING),
rule::horizontal(2), rule::horizontal(2),
scrollable(fast_add.padding(Padding{ scrollable(fast_add.padding(Padding {
top: 0.0,
right: 0.0,
top: 0.0 , right: 0.0 , bottom: 4.0 , left: 0.0 , })).horizontal(), bottom: 4.0,
left: 0.0,
}))
.horizontal(),
]; ];
for more in &word.additional { for more in &word.additional {
@@ -140,12 +147,10 @@ impl<Message> WordEditor<Message> {
column![ column![
text!("{}", name), text!("{}", name),
row![ row![
text_input(name, value) jl_text_input!(name, value)
.on_input(move |string| SetAdditional(id, string)) .on_input(move |string| SetAdditional(id, string))
.width(Fill), .width(Fill),
button("-") button("-").on_press(RemoveAdditional(id)).style(danger),
.on_press(RemoveAdditional(id))
.style(danger),
] ]
.spacing(QUARTER_SPACING), .spacing(QUARTER_SPACING),
] ]
+7 -4
View File
@@ -10,7 +10,7 @@ pub const HALF_SPACING: f32 = DEFAULT_SPACING / 2.0;
pub const QUARTER_SPACING: f32 = DEFAULT_SPACING / 4.0; pub const QUARTER_SPACING: f32 = DEFAULT_SPACING / 4.0;
pub const DEFAULT_SPACING: f32 = 16.0; pub const DEFAULT_SPACING: f32 = 16.0;
pub const ACCENT_FONT_SIZE: f32 = 22.0; pub const ACCENT_FONT_SIZE: f32 = 22.0;
pub const BUTTON_RADIUS: f32 = 8.0; pub const BUTTON_RADIUS: f32 = 6.0;
pub const SETTINGS_ICON: &[u8] = include_bytes!("../settings_icon.svg"); pub const SETTINGS_ICON: &[u8] = include_bytes!("../settings_icon.svg");
@@ -24,7 +24,10 @@ pub fn jl_button_style(theme: &Theme, status: Status) -> Style {
style style
} }
pub fn jl_text_input_style(theme: &Theme, status: iced::widget::text_input::Status) -> iced::widget::text_input::Style { pub fn jl_text_input_style(
theme: &Theme,
status: iced::widget::text_input::Status,
) -> iced::widget::text_input::Style {
let mut style = iced::widget::text_input::default(theme, status); let mut style = iced::widget::text_input::default(theme, status);
style.border.radius = Radius::new(BUTTON_RADIUS); style.border.radius = Radius::new(BUTTON_RADIUS);
style style
@@ -45,8 +48,8 @@ macro_rules! jl_button {
#[macro_export] #[macro_export]
macro_rules! jl_text_input { macro_rules! jl_text_input {
($content:expr) => { ($placeholder:expr, $content:expr) => {
iced::widget::text_input($content).style($crate::styling::jl_text_input_style) iced::widget::text_input($placeholder, $content).style($crate::styling::jl_text_input_style)
}; };
} }
+9 -3
View File
@@ -215,7 +215,9 @@ where
shell: &mut Shell<'_, Message>, shell: &mut Shell<'_, Message>,
viewport: &Rectangle, viewport: &Rectangle,
) { ) {
if self.on_move.is_none() && let Event::Mouse(mouse::Event::CursorMoved {..}) = event { if self.on_move.is_none()
&& let Event::Mouse(mouse::Event::CursorMoved { .. }) = event
{
self.content.as_widget_mut().update( self.content.as_widget_mut().update(
&mut tree.children[0], &mut tree.children[0],
event, event,
@@ -228,7 +230,9 @@ where
); );
} }
if self.on_enter.is_none() && let Event::Mouse(mouse::Event::CursorEntered {..}) = event { if self.on_enter.is_none()
&& let Event::Mouse(mouse::Event::CursorEntered { .. }) = event
{
self.content.as_widget_mut().update( self.content.as_widget_mut().update(
&mut tree.children[0], &mut tree.children[0],
event, event,
@@ -240,7 +244,9 @@ where
viewport, viewport,
); );
} }
if self.on_exit.is_none() && let Event::Mouse(mouse::Event::CursorLeft {..}) = event { if self.on_exit.is_none()
&& let Event::Mouse(mouse::Event::CursorLeft { .. }) = event
{
self.content.as_widget_mut().update( self.content.as_widget_mut().update(
&mut tree.children[0], &mut tree.children[0],
event, event,