From c0211c4e370ec5fb46b90764235282d098ca21c1 Mon Sep 17 00:00:00 2001 From: Glenn Morris Date: Fri, 15 Feb 2013 19:29:39 -0800 Subject: [PATCH] Add commands for navigating multi-frame images * lisp/image.el (image-nth-frame): New, split from image-animate-timeout. (image-animate-timeout): Use image-nth-frame. * lisp/image-mode.el (image-goto-frame, image-next-frame) (image-previous-frame): New commands. (image-mode-map): Add new frame commands. * etc/NEWS: Mention this. --- etc/NEWS | 4 ++++ lisp/ChangeLog | 8 ++++++++ lisp/image-mode.el | 34 ++++++++++++++++++++++++++++++++++ lisp/image.el | 15 ++++++++++++--- 4 files changed, 58 insertions(+), 3 deletions(-) diff --git a/etc/NEWS b/etc/NEWS index 98824220cec..62d84a0788d 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -141,6 +141,10 @@ amounts of data into the ERC input. visit the next image file and the previous image file in the same directory, respectively. +*** New commands to show specific frames of multi-frame images. +`f' (`image-next-frame') and `b' (`image-previous-frame') visit the +next or previous frame. `F' (`image-goto-frame') shows a specific frame. + --- *** The command `image-mode-fit-frame' deletes other windows. When toggling, it restores the frame's previous window configuration. diff --git a/lisp/ChangeLog b/lisp/ChangeLog index d9e6a3eb5b4..e71e3d6752e 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,3 +1,11 @@ +2013-02-16 Glenn Morris + + * image.el (image-nth-frame): New, split from image-animate-timeout. + (image-animate-timeout): Use image-nth-frame. + * image-mode.el (image-goto-frame, image-next-frame) + (image-previous-frame): New commands. + (image-mode-map): Add new frame commands. + 2013-02-16 Jonas Bernoulli * emacs-lisp/tabulated-list.el (tabulated-list-print-col): diff --git a/lisp/image-mode.el b/lisp/image-mode.el index fcbea945714..e539848675c 100644 --- a/lisp/image-mode.el +++ b/lisp/image-mode.el @@ -340,6 +340,9 @@ call." (define-key map (kbd "S-SPC") 'image-scroll-down) (define-key map (kbd "DEL") 'image-scroll-down) (define-key map (kbd "RET") 'image-toggle-animation) + (define-key map "F" 'image-goto-frame) + (define-key map "f" 'image-next-frame) + (define-key map "b" 'image-previous-frame) (define-key map "n" 'image-next-file) (define-key map "p" 'image-previous-file) (define-key map [remap forward-char] 'image-forward-hscroll) @@ -627,6 +630,37 @@ Otherwise it plays once, then stops." (image-animate image index (if image-animate-loop t))))))))) +(defun image-goto-frame (n &optional relative) + "Show frame N of a multi-frame image. +Optional argument OFFSET non-nil means interpret N as relative to the +current frame. Frames are indexed from 1." + (interactive + (list (or current-prefix-arg + (read-number "Show frame number: ")))) + (let ((image (image-get-display-property)) + animation) + (cond + ((null image) + (error "No image is present")) + ((null image-current-frame) + (message "No image animation.")) + (t + (image-nth-frame image (if relative (+ n image-current-frame) (1- n))))))) + +(defun image-next-frame (&optional n) + "Switch to the next frame of a multi-frame image. +With optional argument N, switch to the Nth frame after the current one. +If N is negative, switch to the Nth frame before the current one." + (interactive "p") + (image-goto-frame n t)) + +(defun image-previous-frame (&optional n) + "Switch to the previous frame of a multi-frame image. +With optional argument N, switch to the Nth frame before the current one. +If N is negative, switch to the Nth frame after the current one." + (interactive "p") + (image-next-frame (- n))) + ;;; Switching to the next/previous image diff --git a/lisp/image.el b/lisp/image.el index e0521ad065a..b03a634d060 100644 --- a/lisp/image.el +++ b/lisp/image.el @@ -660,6 +660,17 @@ number, play until that number of seconds has elapsed." (defvar-local image-current-frame nil "The frame index of the current animated image.") +(defun image-nth-frame (image n &optional nocheck) + "Show frame N of IMAGE. +Frames are indexed from 0. Optional argument NOCHECK non-nil means +do not check N is within the range of frames present in the image." + (unless nocheck + (if (< n 0) (setq n 0) + (setq n (min n (1- (car (image-animated-p image))))))) + (plist-put (cdr image) :index n) + (setq image-current-frame n) + (force-window-update)) + ;; FIXME? The delay may not be the same for different sub-images, ;; hence we need to call image-animated-p to return it. ;; But it also returns count, so why do we bother passing that as an @@ -674,9 +685,7 @@ LIMIT determines when to stop. If t, loop forever. If nil, stop after displaying the last animation frame. Otherwise, stop after LIMIT seconds have elapsed. The minimum delay between successive frames is 0.01s." - (plist-put (cdr image) :index n) - (setq image-current-frame n) - (force-window-update) + (image-nth-frame image n t) (setq n (1+ n)) (let* ((time (float-time)) (animation (image-animated-p image)) -- 2.39.2