diff options
| author | Glenn Morris | 2013-08-15 23:33:08 -0700 |
|---|---|---|
| committer | Glenn Morris | 2013-08-15 23:33:08 -0700 |
| commit | 3a2ddc2d1824a17319fa053655fce4861c6cbb18 (patch) | |
| tree | 2fedfdcadfedd9c7b78ea37e4bf431c432498fa9 | |
| parent | bd805d5baef783126eaf1c290e0e4fb4d95774d3 (diff) | |
| download | emacs-3a2ddc2d1824a17319fa053655fce4861c6cbb18.tar.gz emacs-3a2ddc2d1824a17319fa053655fce4861c6cbb18.zip | |
Add functions to change the speed of animated images
* lisp/image-mode.el (image-mode-map): Add menu items to reverse,
increase, decrease, reset animation speed.
(image--set-speed, image-increase-speed, image-decrease-speed)
(image-reverse-speed, image-reset-speed): New functions.
(image-mode-map): Add bindings for speed commands.
* lisp/image.el (image-animate-get-speed, image-animate-set-speed):
New functions.
(image-animate-timeout): Respect image :speed property.
* etc/NEWS: Mention this.
| -rw-r--r-- | etc/NEWS | 4 | ||||
| -rw-r--r-- | lisp/ChangeLog | 12 | ||||
| -rw-r--r-- | lisp/image-mode.el | 69 | ||||
| -rw-r--r-- | lisp/image.el | 36 |
4 files changed, 111 insertions, 10 deletions
| @@ -347,6 +347,8 @@ directory, respectively. | |||
| 347 | `f' (`image-next-frame') and `b' (`image-previous-frame') visit the | 347 | `f' (`image-next-frame') and `b' (`image-previous-frame') visit the |
| 348 | next or previous frame. `F' (`image-goto-frame') shows a specific frame. | 348 | next or previous frame. `F' (`image-goto-frame') shows a specific frame. |
| 349 | 349 | ||
| 350 | *** New commands to speed up, slow down, or reverse animation. | ||
| 351 | |||
| 350 | --- | 352 | --- |
| 351 | *** The command `image-mode-fit-frame' deletes other windows. | 353 | *** The command `image-mode-fit-frame' deletes other windows. |
| 352 | When toggling, it restores the frame's previous window configuration. | 354 | When toggling, it restores the frame's previous window configuration. |
| @@ -683,6 +685,8 @@ Emacs uses `image-default-frame-delay'. | |||
| 683 | *** New functions `image-current-frame' and `image-show-frame' for getting | 685 | *** New functions `image-current-frame' and `image-show-frame' for getting |
| 684 | and setting the current frame of a multi-frame image. | 686 | and setting the current frame of a multi-frame image. |
| 685 | 687 | ||
| 688 | *** You can change the speed of animated images. | ||
| 689 | |||
| 686 | ** Changes in encoding and decoding of text | 690 | ** Changes in encoding and decoding of text |
| 687 | 691 | ||
| 688 | --- | 692 | --- |
diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 9119b34d52c..cad6788f0e8 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog | |||
| @@ -1,3 +1,15 @@ | |||
| 1 | 2013-08-16 Glenn Morris <rgm@gnu.org> | ||
| 2 | |||
| 3 | * image-mode.el (image-mode-map): Add menu items to reverse, | ||
| 4 | increase, decrease, reset animation speed. | ||
| 5 | (image--set-speed, image-increase-speed, image-decrease-speed) | ||
| 6 | (image-reverse-speed, image-reset-speed): New functions. | ||
| 7 | (image-mode-map): Add bindings for speed commands. | ||
| 8 | |||
| 9 | * image.el (image-animate-get-speed, image-animate-set-speed): | ||
| 10 | New functions. | ||
| 11 | (image-animate-timeout): Respect image :speed property. | ||
| 12 | |||
| 1 | 2013-08-15 Stefan Monnier <monnier@iro.umontreal.ca> | 13 | 2013-08-15 Stefan Monnier <monnier@iro.umontreal.ca> |
| 2 | 14 | ||
| 3 | * emacs-lisp/debug.el (debugger-setup-buffer): Put point on the | 15 | * emacs-lisp/debug.el (debugger-setup-buffer): Put point on the |
diff --git a/lisp/image-mode.el b/lisp/image-mode.el index 30dfd045b46..f9bbbcdb1ab 100644 --- a/lisp/image-mode.el +++ b/lisp/image-mode.el | |||
| @@ -354,6 +354,10 @@ call." | |||
| 354 | (define-key map "b" 'image-previous-frame) | 354 | (define-key map "b" 'image-previous-frame) |
| 355 | (define-key map "n" 'image-next-file) | 355 | (define-key map "n" 'image-next-file) |
| 356 | (define-key map "p" 'image-previous-file) | 356 | (define-key map "p" 'image-previous-file) |
| 357 | (define-key map "a+" 'image-increase-speed) | ||
| 358 | (define-key map "a-" 'image-decrease-speed) | ||
| 359 | (define-key map "a0" 'image-reset-speed) | ||
| 360 | (define-key map "ar" 'image-reverse-speed) | ||
| 357 | (define-key map [remap forward-char] 'image-forward-hscroll) | 361 | (define-key map [remap forward-char] 'image-forward-hscroll) |
| 358 | (define-key map [remap backward-char] 'image-backward-hscroll) | 362 | (define-key map [remap backward-char] 'image-backward-hscroll) |
| 359 | (define-key map [remap right-char] 'image-forward-hscroll) | 363 | (define-key map [remap right-char] 'image-forward-hscroll) |
| @@ -412,7 +416,23 @@ call." | |||
| 412 | (image-toggle-animation))) | 416 | (image-toggle-animation))) |
| 413 | :style toggle :selected image-animate-loop | 417 | :style toggle :selected image-animate-loop |
| 414 | :active image-multi-frame | 418 | :active image-multi-frame |
| 415 | :help "Animate images once, or forever?"] | 419 | :help "Animate images once, or forever?"] |
| 420 | ["Reverse Animation" image-reverse-speed | ||
| 421 | :style toggle :selected (let ((image (image-get-display-property))) | ||
| 422 | (and image (< | ||
| 423 | (image-animate-get-speed image) | ||
| 424 | 0))) | ||
| 425 | :active image-multi-frame | ||
| 426 | :help "Reverse direction of this image's animation?"] | ||
| 427 | ["Speed Up Animation" image-increase-speed | ||
| 428 | :active image-multi-frame | ||
| 429 | :help "Speed up this image's animation"] | ||
| 430 | ["Slow Down Animation" image-decrease-speed | ||
| 431 | :active image-multi-frame | ||
| 432 | :help "Slow down this image's animation"] | ||
| 433 | ["Reset Animation Speed" image-reset-speed | ||
| 434 | :active image-multi-frame | ||
| 435 | :help "Reset the speed of this image's animation"] | ||
| 416 | ["Next Frame" image-next-frame :active image-multi-frame | 436 | ["Next Frame" image-next-frame :active image-multi-frame |
| 417 | :help "Show the next frame of this image"] | 437 | :help "Show the next frame of this image"] |
| 418 | ["Previous Frame" image-previous-frame :active image-multi-frame | 438 | ["Previous Frame" image-previous-frame :active image-multi-frame |
| @@ -437,7 +457,10 @@ call." | |||
| 437 | (defun image-mode () | 457 | (defun image-mode () |
| 438 | "Major mode for image files. | 458 | "Major mode for image files. |
| 439 | You can use \\<image-mode-map>\\[image-toggle-display] | 459 | You can use \\<image-mode-map>\\[image-toggle-display] |
| 440 | to toggle between display as an image and display as text." | 460 | to toggle between display as an image and display as text. |
| 461 | |||
| 462 | Key bindings: | ||
| 463 | \\{image-mode-map}" | ||
| 441 | (interactive) | 464 | (interactive) |
| 442 | (condition-case err | 465 | (condition-case err |
| 443 | (progn | 466 | (progn |
| @@ -703,6 +726,48 @@ Otherwise it plays once, then stops." | |||
| 703 | (image-animate image index | 726 | (image-animate image index |
| 704 | (if image-animate-loop t))))))))) | 727 | (if image-animate-loop t))))))))) |
| 705 | 728 | ||
| 729 | (defun image--set-speed (speed &optional multiply) | ||
| 730 | "Set speed of an animated image to SPEED. | ||
| 731 | If MULTIPLY is non-nil, treat SPEED as a multiplication factor. | ||
| 732 | If SPEED is `reset', reset the magnitude of the speed to 1." | ||
| 733 | (let ((image (image-get-display-property))) | ||
| 734 | (cond | ||
| 735 | ((null image) | ||
| 736 | (error "No image is present")) | ||
| 737 | ((null image-multi-frame) | ||
| 738 | (message "No image animation.")) | ||
| 739 | (t | ||
| 740 | (if (eq speed 'reset) | ||
| 741 | (setq speed (if (< (image-animate-get-speed image) 0) | ||
| 742 | -1 1) | ||
| 743 | multiply nil)) | ||
| 744 | (image-animate-set-speed image speed multiply) | ||
| 745 | ;; FIXME Hack to refresh an active image. | ||
| 746 | (when (image-animate-timer image) | ||
| 747 | (image-toggle-animation) | ||
| 748 | (image-toggle-animation)) | ||
| 749 | (message "Image speed is now %s" (image-animate-get-speed image)))))) | ||
| 750 | |||
| 751 | (defun image-increase-speed () | ||
| 752 | "Increase the speed of current animated image by a factor of 2." | ||
| 753 | (interactive) | ||
| 754 | (image--set-speed 2 t)) | ||
| 755 | |||
| 756 | (defun image-decrease-speed () | ||
| 757 | "Decrease the speed of current animated image by a factor of 2." | ||
| 758 | (interactive) | ||
| 759 | (image--set-speed 0.5 t)) | ||
| 760 | |||
| 761 | (defun image-reverse-speed () | ||
| 762 | "Reverse the animation of the current image." | ||
| 763 | (interactive) | ||
| 764 | (image--set-speed -1 t)) | ||
| 765 | |||
| 766 | (defun image-reset-speed () | ||
| 767 | "Reset the animation speed of the current image." | ||
| 768 | (interactive) | ||
| 769 | (image--set-speed 'reset)) | ||
| 770 | |||
| 706 | (defun image-goto-frame (n &optional relative) | 771 | (defun image-goto-frame (n &optional relative) |
| 707 | "Show frame N of a multi-frame image. | 772 | "Show frame N of a multi-frame image. |
| 708 | Optional argument OFFSET non-nil means interpret N as relative to the | 773 | Optional argument OFFSET non-nil means interpret N as relative to the |
diff --git a/lisp/image.el b/lisp/image.el index d213c5d6d79..6c15a7d0b96 100644 --- a/lisp/image.el +++ b/lisp/image.el | |||
| @@ -687,6 +687,19 @@ do not check N is within the range of frames present in the image." | |||
| 687 | (plist-put (cdr image) :index n) | 687 | (plist-put (cdr image) :index n) |
| 688 | (force-window-update)) | 688 | (force-window-update)) |
| 689 | 689 | ||
| 690 | (defun image-animate-get-speed (image) | ||
| 691 | "Return the speed factor for animating IMAGE." | ||
| 692 | (or (plist-get (cdr image) :speed) 1)) | ||
| 693 | |||
| 694 | (defun image-animate-set-speed (image value &optional multiply) | ||
| 695 | "Set the speed factor for animating IMAGE to VALUE. | ||
| 696 | With optional argument MULTIPLY non-nil, treat VALUE as a | ||
| 697 | multiplication factor for the current value." | ||
| 698 | (plist-put (cdr image) :speed | ||
| 699 | (if multiply | ||
| 700 | (* value (image-animate-get-speed image)) | ||
| 701 | value))) | ||
| 702 | |||
| 690 | ;; FIXME? The delay may not be the same for different sub-images, | 703 | ;; FIXME? The delay may not be the same for different sub-images, |
| 691 | ;; hence we need to call image-multi-frame-p to return it. | 704 | ;; hence we need to call image-multi-frame-p to return it. |
| 692 | ;; But it also returns count, so why do we bother passing that as an | 705 | ;; But it also returns count, so why do we bother passing that as an |
| @@ -700,21 +713,28 @@ TIME-ELAPSED is the total time that has elapsed since | |||
| 700 | LIMIT determines when to stop. If t, loop forever. If nil, stop | 713 | LIMIT determines when to stop. If t, loop forever. If nil, stop |
| 701 | after displaying the last animation frame. Otherwise, stop | 714 | after displaying the last animation frame. Otherwise, stop |
| 702 | after LIMIT seconds have elapsed. | 715 | after LIMIT seconds have elapsed. |
| 703 | The minimum delay between successive frames is `image-minimum-frame-delay'." | 716 | The minimum delay between successive frames is `image-minimum-frame-delay'. |
| 717 | |||
| 718 | If the image has a non-nil :speed property, it acts as a multiplier | ||
| 719 | for the animation speed. A negative value means to animate in reverse." | ||
| 704 | (image-show-frame image n t) | 720 | (image-show-frame image n t) |
| 705 | (setq n (1+ n)) | 721 | (let* ((speed (image-animate-get-speed image)) |
| 706 | (let* ((time (float-time)) | 722 | (time (float-time)) |
| 707 | (animation (image-multi-frame-p image)) | 723 | (animation (image-multi-frame-p image)) |
| 708 | ;; Subtract off the time we took to load the image from the | 724 | ;; Subtract off the time we took to load the image from the |
| 709 | ;; stated delay time. | 725 | ;; stated delay time. |
| 710 | (delay (max (+ (or (cdr animation) image-default-frame-delay) | 726 | (delay (max (+ (* (or (cdr animation) image-default-frame-delay) |
| 727 | (/ 1 (abs speed))) | ||
| 711 | time (- (float-time))) | 728 | time (- (float-time))) |
| 712 | image-minimum-frame-delay)) | 729 | image-minimum-frame-delay)) |
| 713 | done) | 730 | done) |
| 714 | (if (>= n count) | 731 | (setq n (if (< speed 0) |
| 715 | (if limit | 732 | (1- n) |
| 716 | (setq n 0) | 733 | (1+ n))) |
| 717 | (setq done t))) | 734 | (if limit |
| 735 | (cond ((>= n count) (setq n 0)) | ||
| 736 | ((< n 0) (setq n (1- count)))) | ||
| 737 | (and (or (>= n count) (< n 0)) (setq done t))) | ||
| 718 | (setq time-elapsed (+ delay time-elapsed)) | 738 | (setq time-elapsed (+ delay time-elapsed)) |
| 719 | (if (numberp limit) | 739 | (if (numberp limit) |
| 720 | (setq done (>= time-elapsed limit))) | 740 | (setq done (>= time-elapsed limit))) |