Updated word display #19

Merged
micialware merged 13 commits from updated-word-display into master 2026-09-13 17:42:58 +03:00
3 changed files with 127 additions and 123 deletions
Showing only changes of commit adb6388ee2 - Show all commits

No files matched your search

-6
View File
@@ -21,7 +21,6 @@ use crate::pages::repetition_settings::{RepetitionSettingsMessage, RepetitionSet
use crate::pages::repetitions::{RepetitionsMessage, RepetitionsState};
use crate::pages::selector::{SelectorMessage, SelectorState};
use crate::pages::sync::{SyncMessage, SyncState};
use crate::pages::word::{WordMessage, WordState};
use crate::pages::writing::{WritingMessage, WritingState};
use crate::state_navigate_handle;
use crate::state_update;
@@ -56,7 +55,6 @@ pub enum RootMessage {
Randomizer(RandomizerMessage),
Repetitions(RepetitionsMessage),
Repetition(RepetitionMessage),
Word(WordMessage),
Sync(SyncMessage),
History(HistoryMessage),
RepetitionSettings(RepetitionSettingsMessage),
@@ -78,7 +76,6 @@ pub enum Page {
Randomizer(RandomizerState),
Repetitions(RepetitionsState),
Repetition(RepetitionState),
Word(WordState),
Sync(SyncState),
History(HistoryState),
RepetitionSettings(RepetitionSettingsState),
@@ -182,7 +179,6 @@ impl ScreenState {
Randomizer,
Repetitions,
Repetition,
Word,
Sync,
History,
RepetitionSettings,
@@ -206,7 +202,6 @@ impl ScreenState {
Randomizer,
Repetitions,
Repetition,
Word,
Sync,
History,
RepetitionSettings,
@@ -227,7 +222,6 @@ impl ScreenState {
Randomizer,
Repetitions,
Repetition,
Word,
Sync,
History,
RepetitionSettings,
+121 -100
View File
@@ -1,16 +1,18 @@
use crate::app::AppState;
use crate::data::Id;
use crate::data::entities::{EntityHandle, WordData, WordGroup};
use crate::data::repositories::{Query, Repository};
use crate::data::Id;
use crate::data_provider::word_groups::{WordGroupDataLayer, WordGroupRepositoryInner};
use crate::data_provider::words::WordDataLayer;
use crate::data_provider::words::WordRepositoryInner;
use crate::navigation::Page::{Import, Word};
use crate::navigation::Page::Import;
use crate::navigation::{KeyPressedPage, NavigatedPage, Page, RootMessage};
use crate::pages::dictionary::BasicWordFields::*;
use crate::pages::dictionary::DictionaryMessage::*;
use crate::pages::dictionary::SelectionChangeDirection::*;
use crate::pages::dictionary_quiz::DictionaryQuizState;
use crate::pages::import::ImportState;
use crate::pages::word::WordState;
use crate::pages::word::{WordEditor, WordMessage};
use crate::push_error_task;
use crate::styling::*;
use crate::widgets::hard_mouse_area::hard_mouse_area;
@@ -22,22 +24,20 @@ use iced::widget::button::Style;
use iced::widget::button::{danger, text};
use iced::widget::operation::focus;
use iced::widget::space::horizontal;
use iced::widget::text_input::Status::Active;
use iced::widget::text_input::default;
use iced::widget::text_input::Status::Active;
use iced::widget::*;
use iced::{Border, Color, Shadow, Task};
use iced_core::Length::Fill;
use iced_core::keyboard;
use iced_core::keyboard::Event;
use iced_core::keyboard::Key::Named;
use iced_core::keyboard::key::Physical::Code;
use iced_core::keyboard::{Event, Modifiers};
use iced_core::keyboard::Key::Named;
use iced_core::Length::{Fill, FillPortion};
use log::info;
use rand::random_range;
use std::ops::Add;
use std::sync::Arc;
use std::time::{Duration, Instant};
use crate::pages::dictionary::BasicWordFields::*;
use crate::pages::dictionary::SelectionChangeDirection::*;
pub struct DictionaryState {
state: AppState,
@@ -53,6 +53,7 @@ pub struct DictionaryState {
displayed_words_query: Query<WordData, WordRepositoryInner, WordDataLayer>,
groups_query: Query<WordGroup, WordGroupRepositoryInner, WordGroupDataLayer>,
selected_cell: Option<(EntityHandle<WordData>, BasicWordFields, usize)>,
word_editor: Option<WordEditor>,
}
#[derive(Clone)]
@@ -61,7 +62,8 @@ pub enum DictionaryMessage {
SetTags(EntityHandle<WordData>, String),
SetKey(EntityHandle<WordData>, String),
SetValue(EntityHandle<WordData>, String),
WordAction(EntityHandle<WordData>),
ExtendedEdit(EntityHandle<WordData>),
DeleteWord(EntityHandle<WordData>),
NewWord,
Include(EntityHandle<WordData>, bool),
IncludeTag(String, bool),
@@ -81,6 +83,7 @@ pub enum DictionaryMessage {
SelectField(EntityHandle<WordData>, BasicWordFields, usize),
EditField(String),
ChangeSelectedField(SelectionChangeDirection),
EditorAction(WordMessage),
}
#[derive(Clone, PartialEq, Eq, Hash, Copy)]
@@ -122,11 +125,7 @@ impl NavigatedPage<DictionaryMessage> for DictionaryState {
self.state.clone(),
)));
}
if let WordAction(handle) = message
&& handle.real()
{
return Some(Word(WordState::new(*handle, self.state.clone())));
}
if let GotoImport = message {
return Some(Import(ImportState::new(self.state.clone())));
}
@@ -186,14 +185,8 @@ impl NavigatedPage<DictionaryMessage> for DictionaryState {
return self.launch_auto_save_offset(i);
}
WordAction(i) => {
let mut dictionary = self.state.dictionary.write();
if let Err(err) = dictionary.delete(i) {
return push_error_task!(err);
}
self.displayed_words_query.load(&dictionary);
ExtendedEdit(i) => {
self.word_editor = Some(WordEditor::new(i, self.state.clone()));
}
Include(i, b) => {
if b {
@@ -308,13 +301,13 @@ impl NavigatedPage<DictionaryMessage> for DictionaryState {
let mut dictionary = self.state.dictionary.write();
let word = dictionary.get_mut_static(selected.0).unwrap();
match selected.1 {
BasicWordFields::Key => {
Key => {
word.key = value;
}
BasicWordFields::Value => {
Value => {
word.value = value;
}
BasicWordFields::Tags => {
Tags => {
word.key = value;
}
}
@@ -324,14 +317,22 @@ impl NavigatedPage<DictionaryMessage> for DictionaryState {
}
}
ChangeSelectedField(change) => {
return if let Some(selected) = self.selected_cell.clone() {
return if let Some(selected) = self.selected_cell {
let update_vertical = move |mut dir: bool| {
if self.reverse_list {
dir = !dir;
}
let new_index = if dir { selected.2.saturating_add(1) } else { selected.2.saturating_sub(1) };
let new_index = if dir {
selected.2.saturating_add(1)
} else {
selected.2.saturating_sub(1)
};
if new_index < self.displayed_words_query.len() {
return SelectField(self.displayed_words_query.get(new_index).unwrap(), selected.1, new_index);
return SelectField(
self.displayed_words_query.get(new_index).unwrap(),
selected.1,
new_index,
);
}
SelectField(selected.0, selected.1, selected.2)
@@ -340,7 +341,8 @@ impl NavigatedPage<DictionaryMessage> for DictionaryState {
let update_horizontal = move |dir: bool| {
let current = selected.1;
let delta = if dir { 1 } else { -1 };
let mut index = FIELDS.iter().position(|&f| f == current).unwrap() as i8 + delta;
let mut index =
FIELDS.iter().position(|&f| f == current).unwrap() as i8 + delta;
if index < 0 {
index = (FIELDS.len() - 1) as i8;
}
@@ -351,22 +353,26 @@ impl NavigatedPage<DictionaryMessage> for DictionaryState {
};
Task::done(RootMessage::Dictionary(match change {
Next => {
update_vertical(true)
}
Previous => {
update_vertical(false)
}
Forward => {
update_horizontal(true)
}
Backward => {
update_horizontal(false)
}
Next => update_vertical(true),
Previous => update_vertical(false),
Forward => update_horizontal(true),
Backward => update_horizontal(false),
}))
} else {
Task::none()
};
}
DeleteWord(i) => {
let mut dictionary = self.state.dictionary.write();
if let Err(err) = dictionary.delete(i) {
return push_error_task!(err);
}
self.displayed_words_query.load(&dictionary);
}
EditorAction(action) => {
self.word_editor.as_mut().unwrap().update(action);
}
}
@@ -379,37 +385,15 @@ impl NavigatedPage<DictionaryMessage> for DictionaryState {
iced::widget::column![
self.groups_panel(),
row![horizontal().width(8), self.words_list(),],
{
let mut display = "".to_string();
if let Some(selected) = self.selected_cell.as_ref() {
let mut dictionary = self.state.dictionary.write();
let word = dictionary.get_mut_static(selected.0).unwrap();
match selected.1 {
BasicWordFields::Key => {
display = word.key.clone();
}
BasicWordFields::Value => {
display = word.value.clone();
}
BasicWordFields::Tags => {
display = word.tags.clone();
}
}
}
text_input("", display.as_str())
.width(Fill)
.id(iced::widget::Id::new("editor"))
.on_input(EditField)
},
self.selection_editor(),
row![
self.add_word_button(),
horizontal().width(Fill),
button("Импорт").style(text).on_press(GotoImport),
]
]
.spacing(5),
self.filters(),
.spacing(5).width(FillPortion(4)),
self.right_panel(),
]
.spacing(DEFAULT_SPACING)
.into(),
@@ -436,6 +420,7 @@ impl DictionaryState {
displayed_words_query: words_query,
groups_query,
selected_cell: None,
word_editor: None,
};
result.init();
@@ -496,11 +481,11 @@ impl DictionaryState {
let mut selection = None;
if let Some(cell) = self.selected_cell.as_ref() {
if cell.0 == *word_handle {
if let Some(cell) = self.selected_cell.as_ref()
&& cell.0 == *word_handle
{
selection = Some(cell.1);
}
}
let word_line_data = WordLineState {
is_included: self.included.contains(word_handle),
@@ -540,7 +525,7 @@ impl DictionaryState {
default_style.border.radius = 0.0.into();
if selected {
default_style.border.color = x.extended_palette().secondary.base.color;
default_style.border.width = 3.0_f32.into();
default_style.border.width = 3.0_f32;
}
default_style
})
@@ -550,36 +535,32 @@ impl DictionaryState {
hard_mouse_area(field(
"Слово",
&data.key,
data.selection.is_some() && data.selection.unwrap() == BasicWordFields::Key,
data.selection.is_some() && data.selection.unwrap() == Key,
))
.on_press(SelectField(data.handle, BasicWordFields::Key, data.number)),
.on_press(SelectField(data.handle, Key, data.number)),
);
line = line.push(
hard_mouse_area(field(
"Перевод",
&data.value,
data.selection.is_some() && data.selection.unwrap() == BasicWordFields::Value,
data.selection.is_some() && data.selection.unwrap() == Value,
))
.on_press(SelectField(
data.handle,
BasicWordFields::Value,
data.number,
)),
.on_press(SelectField(data.handle, Value, data.number)),
);
line = line.push(
hard_mouse_area(field(
"Теги",
&data.tags,
data.selection.is_some() && data.selection.unwrap() == BasicWordFields::Tags,
data.selection.is_some() && data.selection.unwrap() == Tags,
))
.on_press(SelectField(data.handle, BasicWordFields::Tags, data.number)),
.on_press(SelectField(data.handle, Tags, data.number)),
);
let line_button = || {
if !data.handle.real() {
return button("-")
.on_press(WordAction(data.handle))
.on_press(ExtendedEdit(data.handle))
.style(|_x: &Theme, _status: button::Status| Style {
background: None,
text_color: Color::BLACK,
@@ -591,13 +572,21 @@ impl DictionaryState {
}
button("")
.on_press(WordAction(data.handle))
.on_press(ExtendedEdit(data.handle))
.style(button::primary)
.width(15)
};
line.push(line_button()).push(space().width(10))
}
fn right_panel(&self) -> iced::Element<'_, DictionaryMessage> {
if let Some(editor) = &self.word_editor {
container(editor.view().map(EditorAction)).width(FillPortion(3)).into()
} else {
self.filters()
}
}
fn filters(&self) -> iced::Element<'_, DictionaryMessage> {
let dict = &self.state.dictionary.read();
@@ -619,7 +608,7 @@ impl DictionaryState {
.on_press(GotoTest)
.width(Fill),
]
.width(250)
.width(FillPortion(1))
.spacing(DEFAULT_SPACING)
.into()
}
@@ -719,6 +708,31 @@ impl DictionaryState {
info!("Time {}", time.elapsed().as_micros());
}
fn selection_editor(&self) -> iced::Element<'_, DictionaryMessage> {
let mut display = "".to_string();
if let Some(selected) = self.selected_cell.as_ref() {
let mut dictionary = self.state.dictionary.write();
let word = dictionary.get_mut_static(selected.0).unwrap();
match selected.1 {
Key => {
display = word.key.clone();
}
Value => {
display = word.value.clone();
}
Tags => {
display = word.tags.clone();
}
}
}
text_input("", display.as_str())
.width(Fill)
.id(iced::widget::Id::new("editor"))
.on_input(EditField)
.into()
}
fn groups_panel(&self) -> iced::Element<'_, DictionaryMessage> {
let mut row = Row::new();
row = row.push(button("+").style(text).on_press(CreateGroup));
@@ -779,29 +793,36 @@ impl KeyPressedPage for DictionaryState {
modified_key: modifier,
physical_key: pk,
location: _,
modifiers: _,
modifiers: mods,
text: _,
repeat: _,
} = message
&& let Code(code) = pk
{
return match code {
keyboard::key::Code::ArrowDown => Task::done(RootMessage::Dictionary(
ChangeSelectedField(SelectionChangeDirection::Next),
)),
keyboard::key::Code::ArrowUp => Task::done(RootMessage::Dictionary(
ChangeSelectedField(SelectionChangeDirection::Previous),
)),
keyboard::key::Code::Tab => {
if let Named(keyboard::key::Named::Alt) = modifier {
Task::done(RootMessage::Dictionary(ChangeSelectedField(
SelectionChangeDirection::Backward,
)))
} else {
Task::done(RootMessage::Dictionary(ChangeSelectedField(
SelectionChangeDirection::Forward,
)))
keyboard::key::Code::ArrowDown => {
Task::done(RootMessage::Dictionary(ChangeSelectedField(Next)))
}
keyboard::key::Code::ArrowUp => {
Task::done(RootMessage::Dictionary(ChangeSelectedField(Previous)))
}
keyboard::key::Code::Tab => {
return if *mods == Modifiers::CTRL && let Some(selected) = self.selected_cell {
Task::done(RootMessage::Dictionary(ExtendedEdit(selected.0)))
} else if let Named(keyboard::key::Named::Alt) = modifier {
Task::done(RootMessage::Dictionary(ChangeSelectedField(Backward)))
} else {
Task::done(RootMessage::Dictionary(ChangeSelectedField(Forward)))
}
}
keyboard::key::Code::Escape => {
if self.word_editor.is_some() {
self.word_editor = None;
}else if self.selected_cell.is_some() {
self.selected_cell = None;
}
Task::none()
}
_ => Task::none(),
};
+6 -17
View File
@@ -8,22 +8,13 @@ use iced::widget::button::danger;
use iced::widget::{button, column, row, space, text, text_input};
use iced::{Element, Fill, Task};
pub struct WordState {
pub struct WordEditor {
state: AppState,
handle: EntityHandle<WordData>,
}
impl NavigatedPage<WordMessage> for WordState {
fn navigate(&mut self, message: &WordMessage) -> Option<Page> {
if let Back = message {
Some(PreviousPage)
} else {
None
}
}
fn navigated(&mut self) {}
fn update(&mut self, message: WordMessage) -> Task<RootMessage> {
impl WordEditor {
pub(crate) fn update(&mut self, message: WordMessage) {
// match message {
// Back => {}
// Save => {
@@ -60,10 +51,9 @@ impl NavigatedPage<WordMessage> for WordState {
// self.word.additional.remove(key.as_str());
// }
// }
Task::none()
}
fn view(&self) -> Element<'_, WordMessage> {
pub(crate) fn view(&self) -> Element<'_, WordMessage> {
// let mut fast_add = row![];
// if !self.word.additional.contains_key("reading") {
// fast_add = fast_add.push(
@@ -129,13 +119,13 @@ impl NavigatedPage<WordMessage> for WordState {
}
}
impl WordState {
impl WordEditor {
pub fn new(handle: EntityHandle<WordData>, state: AppState) -> Self {
Self { state, handle }
}
}
impl WordState {
impl WordEditor {
fn get_view_for_more(&self, value: (&String, &String)) -> Element<'_, WordMessage> {
match value.0.as_str() {
"reading" => self.reading_field(value.1),
@@ -180,7 +170,6 @@ impl WordState {
#[derive(Debug, Clone)]
pub enum WordMessage {
Save,
Back,
Delete,
SetTags(String),
SetKey(String),