fix(iced): add viewer keyboard navigation and wire lazy loading
This commit is contained in:
@@ -519,6 +519,9 @@ pub enum Message {
|
|||||||
ViewerOpenFile(std::path::PathBuf),
|
ViewerOpenFile(std::path::PathBuf),
|
||||||
ViewerRefresh,
|
ViewerRefresh,
|
||||||
ViewerFullscreen(bool),
|
ViewerFullscreen(bool),
|
||||||
|
ViewerPrev,
|
||||||
|
ViewerNext,
|
||||||
|
ViewerEnter,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Convert a FilterType enum to the engine's string filter ID.
|
/// Convert a FilterType enum to the engine's string filter ID.
|
||||||
@@ -3350,10 +3353,36 @@ impl HcieIcedApp {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Message::ViewerPrev => {
|
||||||
|
if self.viewer_active {
|
||||||
|
self.viewer_state.prev_image();
|
||||||
|
self.viewer_state.load_preview();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Message::ViewerNext => {
|
||||||
|
if self.viewer_active {
|
||||||
|
self.viewer_state.next_image();
|
||||||
|
self.viewer_state.load_preview();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Message::ViewerEnter => {
|
||||||
|
if self.viewer_active && !self.viewer_state.images.is_empty() {
|
||||||
|
let path = self.viewer_state.images[self.viewer_state.active_image_idx].clone();
|
||||||
|
return Task::perform(async move {}, move |_| Message::ViewerOpenFile(path.clone()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Message::NoOp => {}
|
Message::NoOp => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Lazy-load thumbnails when viewer is active (max LAZY_LOAD_BUDGET per frame)
|
||||||
|
if self.viewer_active {
|
||||||
|
let batch = crate::viewer::thumbnail_grid::next_load_batch(&self.viewer_state);
|
||||||
|
for path in batch {
|
||||||
|
self.viewer_state.load_thumbnail(&path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Task::none()
|
Task::none()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3584,13 +3613,20 @@ impl HcieIcedApp {
|
|||||||
iced::keyboard::Key::Character(ref c) if c.as_str() == "i" && ctrl && shift => {
|
iced::keyboard::Key::Character(ref c) if c.as_str() == "i" && ctrl && shift => {
|
||||||
Some(Message::SelectInverse)
|
Some(Message::SelectInverse)
|
||||||
}
|
}
|
||||||
// Escape = close menu, cancel dialog, deselect, or cancel crop
|
// Arrow keys — viewer navigation or no-op
|
||||||
iced::keyboard::Key::Named(iced::keyboard::key::Named::Escape) => {
|
iced::keyboard::Key::Named(iced::keyboard::key::Named::ArrowLeft) => {
|
||||||
Some(Message::MenuClose) // Crop cancel handled in update()
|
Some(Message::ViewerPrev)
|
||||||
}
|
}
|
||||||
// Enter = confirm crop
|
iced::keyboard::Key::Named(iced::keyboard::key::Named::ArrowRight) => {
|
||||||
|
Some(Message::ViewerNext)
|
||||||
|
}
|
||||||
|
// Escape = exit viewer, close menu, cancel dialog, deselect, or cancel crop
|
||||||
|
iced::keyboard::Key::Named(iced::keyboard::key::Named::Escape) => {
|
||||||
|
Some(Message::ViewerToggle)
|
||||||
|
}
|
||||||
|
// Enter = open file in viewer, or confirm crop
|
||||||
iced::keyboard::Key::Named(iced::keyboard::key::Named::Enter) => {
|
iced::keyboard::Key::Named(iced::keyboard::key::Named::Enter) => {
|
||||||
Some(Message::CropConfirm) // Crop confirm handled in update()
|
Some(Message::ViewerEnter)
|
||||||
}
|
}
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user