New selected field movement

This commit is contained in:
micialware committed 2026-09-11 00:41:36 +03:00
1 parent 47bc83d4ae
commit 8fe4f3b8f4
3 files changed
+120 -19

No files matched your search

+115 -19
View File
@@ -6,7 +6,7 @@ use crate::data_provider::word_groups::{WordGroupDataLayer, WordGroupRepositoryI
use crate::data_provider::words::WordDataLayer;
use crate::data_provider::words::WordRepositoryInner;
use crate::navigation::Page::{Import, Word};
use crate::navigation::{NavigatedPage, Page, RootMessage};
use crate::navigation::{KeyPressedPage, NavigatedPage, Page, RootMessage};
use crate::pages::dictionary::DictionaryMessage::*;
use crate::pages::dictionary_quiz::DictionaryQuizState;
use crate::pages::import::ImportState;
@@ -27,11 +27,17 @@ use iced::widget::text_input::default;
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 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,
@@ -46,8 +52,7 @@ pub struct DictionaryState {
auto_save_queue: HashMap<EntityHandle<WordData>, DateTime<Utc>>,
displayed_words_query: Query<WordData, WordRepositoryInner, WordDataLayer>,
groups_query: Query<WordGroup, WordGroupRepositoryInner, WordGroupDataLayer>,
selected_cell: Option<(EntityHandle<WordData>, BasicWordFields)>,
hovered_cell: Option<(EntityHandle<WordData>, BasicWordFields)>,
selected_cell: Option<(EntityHandle<WordData>, BasicWordFields, usize)>,
}
#[derive(Clone)]
@@ -73,8 +78,17 @@ pub enum DictionaryMessage {
ChangeDirection,
TrySave(EntityHandle<WordData>),
GotoImport,
SelectField(EntityHandle<WordData>, BasicWordFields),
SelectField(EntityHandle<WordData>, BasicWordFields, usize),
EditField(String),
ChangeSelectedField(SelectionChangeDirection),
}
#[derive(Clone, PartialEq, Eq, Hash, Copy)]
pub enum SelectionChangeDirection {
Next,
Previous,
Forward,
Backward,
}
#[derive(Clone, PartialEq, Eq, Hash, Copy)]
@@ -84,6 +98,8 @@ pub enum BasicWordFields {
Tags,
}
const FIELDS: &[BasicWordFields] = &[Key, Value, Tags];
impl NavigatedPage<DictionaryMessage> for DictionaryState {
fn navigate(&mut self, message: &DictionaryMessage) -> Option<Page> {
if let Back = message {
@@ -281,9 +297,9 @@ impl NavigatedPage<DictionaryMessage> for DictionaryState {
}
}
GotoImport => {}
SelectField(e, f) => {
SelectField(e, f, index) => {
info!("Editing word {}", e.id);
self.selected_cell = Some((e, f));
self.selected_cell = Some((e, f, index));
return focus(iced::widget::Id::new("editor"));
}
EditField(value) => {
@@ -307,6 +323,51 @@ impl NavigatedPage<DictionaryMessage> for DictionaryState {
return self.launch_auto_save_offset(selected.0);
}
}
ChangeSelectedField(change) => {
return if let Some(selected) = self.selected_cell.clone() {
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) };
if new_index < self.displayed_words_query.len() {
return SelectField(self.displayed_words_query.get(new_index).unwrap(), selected.1, new_index);
}
SelectField(selected.0, selected.1, selected.2)
};
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;
if index < 0 {
index = (FIELDS.len() - 1) as i8;
}
if index >= FIELDS.len() as i8 {
index = 0;
}
SelectField(selected.0, FIELDS[index as usize], selected.2)
};
Task::done(RootMessage::Dictionary(match change {
Next => {
update_vertical(true)
}
Previous => {
update_vertical(false)
}
Forward => {
update_horizontal(true)
}
Backward => {
update_horizontal(false)
}
}))
} else {
Task::none()
}
}
}
Task::none()
@@ -375,7 +436,6 @@ impl DictionaryState {
displayed_words_query: words_query,
groups_query,
selected_cell: None,
hovered_cell: None,
};
result.init();
@@ -435,7 +495,6 @@ impl DictionaryState {
}
let mut selection = None;
let mut hovered = None;
if let Some(cell) = self.selected_cell.as_ref() {
if cell.0 == *word_handle {
@@ -443,12 +502,6 @@ impl DictionaryState {
}
}
if let Some(cell) = self.hovered_cell.as_ref() {
if cell.0 == *word_handle {
hovered = Some(cell.1);
}
}
let word_line_data = WordLineState {
is_included: self.included.contains(word_handle),
key: word.key.clone().into(),
@@ -456,7 +509,7 @@ impl DictionaryState {
tags: word.tags.clone().into(),
handle: *word_handle,
selection,
hover: hovered,
number: i,
};
let lazy_line = lazy(word_line_data, Self::word_line);
@@ -499,7 +552,7 @@ impl DictionaryState {
&data.key,
data.selection.is_some() && data.selection.unwrap() == BasicWordFields::Key,
))
.on_press(SelectField(data.handle, BasicWordFields::Key))
.on_press(SelectField(data.handle, BasicWordFields::Key, data.number)),
);
line = line.push(
hard_mouse_area(field(
@@ -507,7 +560,11 @@ impl DictionaryState {
&data.value,
data.selection.is_some() && data.selection.unwrap() == BasicWordFields::Value,
))
.on_press(SelectField(data.handle, BasicWordFields::Value))
.on_press(SelectField(
data.handle,
BasicWordFields::Value,
data.number,
)),
);
line = line.push(
@@ -516,7 +573,7 @@ impl DictionaryState {
&data.tags,
data.selection.is_some() && data.selection.unwrap() == BasicWordFields::Tags,
))
.on_press(SelectField(data.handle, BasicWordFields::Tags))
.on_press(SelectField(data.handle, BasicWordFields::Tags, data.number)),
);
let line_button = || {
@@ -715,6 +772,45 @@ impl DictionaryState {
}
}
impl KeyPressedPage for DictionaryState {
fn press(&mut self, message: &Event) -> Task<RootMessage> {
if let Event::KeyPressed {
key: _,
modified_key: modifier,
physical_key: pk,
location: _,
modifiers: _,
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,
)))
}
}
_ => Task::none(),
};
}
Task::none()
}
}
pub fn split_with_coma(ts: &str) -> Vec<String> {
ts.split(',')
.map(|ts| ts.to_lowercase().trim().to_string())
@@ -730,5 +826,5 @@ struct WordLineState {
tags: Box<str>,
handle: EntityHandle<WordData>,
selection: Option<BasicWordFields>,
hover: Option<BasicWordFields>,
number: usize,
}