diff --git a/data/gtk/help_overlay.ui b/data/gtk/help_overlay.ui index 9a5c3e6..dd4d60a 100644 --- a/data/gtk/help_overlay.ui +++ b/data/gtk/help_overlay.ui @@ -102,6 +102,18 @@ Right + + + First Image + win.first + + + + + Last Image + win.last + + diff --git a/src/application.rs b/src/application.rs index 164481f..9abda2f 100644 --- a/src/application.rs +++ b/src/application.rs @@ -180,8 +180,10 @@ impl LpApplication { self.set_accels_for_action("win.toggle-fullscreen", &["F11"]); self.set_accels_for_action("win.set-background", &["F8"]); - self.set_accels_for_action("win.previous", &["Left"]); - self.set_accels_for_action("win.next", &["Right"]); + self.set_accels_for_action("win.previous", &["Left", "Page_Down"]); + self.set_accels_for_action("win.next", &["Right", "Page_Up"]); + self.set_accels_for_action("win.first", &["Home"]); + self.set_accels_for_action("win.last", &["End"]); self.set_accels_for_action("win.zoom-to(1.0)", &["1", "KP_1", "1", "KP_1"]); self.set_accels_for_action("win.zoom-to(2.0)", &["2", "KP_2", "2", "KP_2"]); diff --git a/src/file_model.rs b/src/file_model.rs index e701c3d..f3b2dc0 100644 --- a/src/file_model.rs +++ b/src/file_model.rs @@ -207,6 +207,16 @@ impl LpFileModel { .collect() } + /// Return first path + pub fn first(&self) -> Option { + self.imp().files.borrow().first().cloned() + } + + /// Returns last path + pub fn last(&self) -> Option { + self.imp().files.borrow().last().cloned() + } + /// Currently sorts by name fn sort(files: &mut IndexSet) { files.sort_by(|x, y| util::compare_by_name(x, y)); diff --git a/src/util.rs b/src/util.rs index 22a9ec3..3c94ac7 100644 --- a/src/util.rs +++ b/src/util.rs @@ -123,3 +123,15 @@ pub async fn spawn( .spawn(async_global_executor::spawn_blocking(f))? .await) } + +#[derive(Debug, Clone, Copy)] +pub enum Position { + First, + Last, +} + +#[derive(Debug, Clone, Copy)] +pub enum Direction { + Back, + Forward, +} diff --git a/src/widgets/image_view.rs b/src/widgets/image_view.rs index cb2bafe..9ce9dfb 100644 --- a/src/widgets/image_view.rs +++ b/src/widgets/image_view.rs @@ -21,6 +21,7 @@ use crate::deps::*; use crate::file_model::LpFileModel; use crate::i18n::*; use crate::thumbnail::Thumbnail; +use crate::util::{Direction, Position}; use crate::widgets::{LpImage, LpImagePage, LpSlidingView}; use adw::prelude::*; @@ -270,12 +271,11 @@ impl LpImageView { } /// Move forward or backwards - pub fn navigate(&self, direction: adw::NavigationDirection) { + pub fn navigate(&self, direction: Direction) { if let Some(current_path) = self.current_path() { let new_path = match direction { - adw::NavigationDirection::Forward => self.model().after(¤t_path), - adw::NavigationDirection::Back => self.model().before(¤t_path), - _ => unimplemented!("Navigation direction should only be back or forward."), + Direction::Forward => self.model().after(¤t_path), + Direction::Back => self.model().before(¤t_path), }; if let Some(new_path) = new_path { @@ -284,6 +284,18 @@ impl LpImageView { } } + /// Jump to position + pub fn jump(&self, position: Position) { + let new_path = match position { + Position::First => self.model().first(), + Position::Last => self.model().last(), + }; + + if let Some(new_path) = new_path { + self.navigate_to_path(&new_path); + } + } + /// Used for drag and drop fn navigate_to_path(&self, new_path: &Path) { let sliding_view = self.sliding_view(); diff --git a/src/window.rs b/src/window.rs index f0a7911..8bcd8ba 100644 --- a/src/window.rs +++ b/src/window.rs @@ -30,7 +30,7 @@ use std::cell::RefCell; use std::path::{Path, PathBuf}; use crate::config; -use crate::util; +use crate::util::{self, Direction, Position}; use crate::widgets::{LpImage, LpImagePage, LpImageView, LpPropertiesView}; mod imp { @@ -99,15 +99,19 @@ mod imp { }); klass.install_action("win.next", None, move |win, _, _| { - win.imp() - .image_view - .navigate(adw::NavigationDirection::Forward); + win.imp().image_view.navigate(Direction::Forward); }); klass.install_action("win.previous", None, move |win, _, _| { - win.imp() - .image_view - .navigate(adw::NavigationDirection::Back); + win.imp().image_view.navigate(Direction::Back); + }); + + klass.install_action("win.first", None, move |win, _, _| { + win.imp().image_view.jump(Position::First); + }); + + klass.install_action("win.last", None, move |win, _, _| { + win.imp().image_view.jump(Position::Last); }); klass.install_action("win.zoom-out", None, move |win, _, _| {