unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
* Image-mode enhancements (post-release)
@ 2007-05-23 17:54 Chong Yidong
  2007-05-23 18:47 ` David Kastrup
  2007-05-23 22:44 ` Kevin Ryde
  0 siblings, 2 replies; 7+ messages in thread
From: Chong Yidong @ 2007-05-23 17:54 UTC (permalink / raw)
  To: emacs-devel

One important enhancement I would like to get into Emacs 23 (and maybe
Emacs 22.2 too) is image scrolling for image-mode.  Currently, images
that are wider or taller than the Emacs window aren't handled very
well; you can scroll up and down using next-line and previous-line,
but not sideways (and, annoyingly, scrolling to the bottom of such
images loops back to the top).

The following patch implements the necessary image-scrolling
functions, and remaps the normal navigation keybindings (forward-char,
previous-line, scroll-up, etc.) to use these functions when image-mode
is displaying the image as an image.

One other useful feature which is not currently implemented would be
to resize the image to fit the Emacs window if it is too large, and to
provide a way to toggle between the full-sized and window-fitted
versions of the image (Firefox has a similar feature).

Comments are welcome.

*** emacs/lisp/image-mode.el.~1.22.~	2007-05-21 18:43:47.000000000 -0400
--- emacs/lisp/image-mode.el	2007-05-23 13:45:59.000000000 -0400
***************
*** 43,53 ****
  ;;;###autoload (push '("\\.p[bpgn]m\\'" . image-mode) auto-mode-alist)
  ;;;###autoload (push '("\\.x[bp]m\\'"   . image-mode-maybe) auto-mode-alist)
  
  (defvar image-mode-map
    (let ((map (make-sparse-keymap)))
      (define-key map "\C-c\C-c" 'image-toggle-display)
      map)
!   "Major mode keymap for Image mode.")
  
  ;;;###autoload
  (defun image-mode ()
--- 43,204 ----
  ;;;###autoload (push '("\\.p[bpgn]m\\'" . image-mode) auto-mode-alist)
  ;;;###autoload (push '("\\.x[bp]m\\'"   . image-mode-maybe) auto-mode-alist)
  
+ ;;; Image scrolling functions
+ 
+ (defun image-forward-hscroll (&optional n)
+   "Scroll image in current window to the left by N character widths.
+ Stop if the right edge of the image is reached."
+   (interactive "p")
+   (cond ((= n 0) nil)
+ 	((< n 0)
+ 	 (set-window-hscroll (selected-window)
+ 			     (max 0 (+ (window-hscroll) n))))
+ 	(t
+ 	 (let* ((image (get-text-property 1 'display))
+ 		(edges (window-inside-edges))
+ 		(win-width (- (nth 2 edges) (nth 0 edges)))
+ 		(img-width (ceiling (car (image-size image)))))
+ 	   (set-window-hscroll (selected-window)
+ 			       (min (max 0 (- img-width win-width))
+ 				    (+ n (window-hscroll))))))))
+ 
+ (defun image-backward-hscroll (&optional n)
+   "Scroll image in current window to the right by N character widths.
+ Stop if the left edge of the image is reached."
+   (interactive "p")
+   (image-forward-hscroll (- n)))
+ 
+ (defun image-next-line (&optional n)
+   "Scroll image in current window upward by N lines.
+ Stop if the bottom edge of the image is reached."
+   (interactive "p")
+   (cond ((= n 0) nil)
+ 	((< n 0)
+ 	 (set-window-vscroll (selected-window)
+ 			     (max 0 (+ (window-vscroll) n))))
+ 	(t
+ 	 (let* ((image (get-text-property 1 'display))
+ 		(edges (window-inside-edges))
+ 		(win-height (- (nth 3 edges) (nth 1 edges)))
+ 		(img-height (ceiling (cdr (image-size image)))))
+ 	   (set-window-vscroll (selected-window)
+ 			       (min (max 0 (- img-height win-height))
+ 				    (+ n (window-vscroll))))))))
+ 
+ (defun image-previous-line (&optional n)
+   "Scroll image in current window downward by N lines.
+ Stop if the top edge of the image is reached."
+   (interactive "p")
+   (image-next-line (- n)))
+ 
+ (defun image-scroll-up (&optional n)
+   "Scroll image in current window upward by N lines.
+ Stop if the bottom edge of the image is reached.
+ If ARG is omitted or nil, scroll upward by a near full screen.
+ A near full screen is `next-screen-context-lines' less than a full screen.
+ Negative ARG means scroll downward.
+ If ARG is the atom `-', scroll downward by nearly full screen.
+ When calling from a program, supply as argument a number, nil, or `-'."
+   (interactive "P")
+   (cond ((null n)
+ 	 (let* ((edges (window-inside-edges))
+ 		(win-height (- (nth 3 edges) (nth 1 edges))))
+ 	   (image-next-line
+ 	    (max 0 (- win-height next-screen-context-lines)))))
+ 	((eq n '-)
+ 	 (let* ((edges (window-inside-edges))
+ 		(win-height (- (nth 3 edges) (nth 1 edges))))
+ 	   (image-next-line
+ 	    (min 0 (- next-screen-context-lines win-height)))))
+ 	(t (image-next-line (prefix-numeric-value n)))))
+ 
+ (defun image-scroll-down (&optional n)
+   "Scroll image in current window downward by N lines
+ Stop if the top edge of the image is reached.
+ If ARG is omitted or nil, scroll downward by a near full screen.
+ A near full screen is `next-screen-context-lines' less than a full screen.
+ Negative ARG means scroll upward.
+ If ARG is the atom `-', scroll upward by nearly full screen.
+ When calling from a program, supply as argument a number, nil, or `-'."
+   (interactive "P")
+   (cond ((null n)
+ 	 (let* ((edges (window-inside-edges))
+ 		(win-height (- (nth 3 edges) (nth 1 edges))))
+ 	   (image-next-line
+ 	    (min 0 (- next-screen-context-lines win-height)))))
+ 	((eq n '-)
+ 	 (let* ((edges (window-inside-edges))
+ 		(win-height (- (nth 3 edges) (nth 1 edges))))
+ 	   (image-next-line
+ 	    (max 0 (- win-height next-screen-context-lines)))))
+ 	(t (image-next-line (- (prefix-numeric-value n))))))
+ 
+ (defun image-bol (arg)
+   "Scroll horizontally to the left edge of the image in the current window.
+ With argument ARG not nil or 1, move forward ARG - 1 lines first,
+ stopping if the top or bottom edge of the image is reached."
+   (interactive "p")
+   (and arg
+        (/= (setq arg (prefix-numeric-value arg)) 1)
+        (image-next-line (- arg 1)))
+   (set-window-hscroll (selected-window) 0))
+ 
+ (defun image-eol (arg)
+   "Scroll horizontally to the right edge of the image in the current window.
+ With argument ARG not nil or 1, move forward ARG - 1 lines first,
+ stopping if the top or bottom edge of the image is reached."
+   (interactive "p")
+   (and arg
+        (/= (setq arg (prefix-numeric-value arg)) 1)
+        (image-next-line (- arg 1)))
+   (let* ((image (get-text-property 1 'display))
+ 	 (edges (window-inside-edges))
+ 	 (win-width (- (nth 2 edges) (nth 0 edges)))
+ 	 (img-width (ceiling (car (image-size image)))))
+     (set-window-hscroll (selected-window)
+ 			(max 0 (- img-width win-width)))))
+ 
+ (defun image-bob ()
+   "Scroll to the top-left corner of the image in the current window."
+   (interactive)
+   (set-window-hscroll (selected-window) 0)
+   (set-window-vscroll (selected-window) 0))
+ 
+ (defun image-eob ()
+   "Scroll to the bottom-right corner of the image in the current window."
+   (interactive)
+   (let* ((image (get-text-property 1 'display))
+ 	 (edges (window-inside-edges))
+ 	 (win-width (- (nth 2 edges) (nth 0 edges)))
+ 	 (img-width (ceiling (car (image-size image))))
+ 	 (win-height (- (nth 3 edges) (nth 1 edges)))
+ 	 (img-height (ceiling (cdr (image-size image)))))
+     (set-window-hscroll (selected-window) (max 0 (- img-width win-width)))
+     (set-window-vscroll (selected-window) (max 0 (- img-height win-height)))))
+ 
+ ;;; Image Mode setup
+ 
  (defvar image-mode-map
    (let ((map (make-sparse-keymap)))
      (define-key map "\C-c\C-c" 'image-toggle-display)
+     (define-key map [remap forward-char] 'image-forward-hscroll)
+     (define-key map [remap backward-char] 'image-backward-hscroll)
+     (define-key map [remap previous-line] 'image-previous-line)
+     (define-key map [remap next-line] 'image-next-line)
+     (define-key map [remap scroll-up] 'image-scroll-up)
+     (define-key map [remap scroll-down] 'image-scroll-down)
+     (define-key map [remap move-beginning-of-line] 'image-bol)
+     (define-key map [remap move-end-of-line] 'image-eol)
+     (define-key map [remap beginning-of-buffer] 'image-bob)
+     (define-key map [remap end-of-buffer] 'image-eob)
+     map)
+   "Major mode keymap for viewing images in Image mode.")
+ 
+ (defvar image-mode-text-map
+   (let ((map (make-sparse-keymap)))
+     (define-key map "\C-c\C-c" 'image-toggle-display)
      map)
!   "Major mode keymap for viewing images as text in Image mode.")
  
  ;;;###autoload
  (defun image-mode ()
***************
*** 58,70 ****
    (kill-all-local-variables)
    (setq mode-name "Image")
    (setq major-mode 'image-mode)
-   (use-local-map image-mode-map)
    (add-hook 'change-major-mode-hook 'image-toggle-display-text nil t)
    (if (and (display-images-p)
  	   (not (get-text-property (point-min) 'display)))
        (image-toggle-display)
      ;; Set next vars when image is already displayed but local
      ;; variables were cleared by kill-all-local-variables
      (setq cursor-type nil truncate-lines t))
    (run-mode-hooks 'image-mode-hook)
    (if (display-images-p)
--- 209,221 ----
    (kill-all-local-variables)
    (setq mode-name "Image")
    (setq major-mode 'image-mode)
    (add-hook 'change-major-mode-hook 'image-toggle-display-text nil t)
    (if (and (display-images-p)
  	   (not (get-text-property (point-min) 'display)))
        (image-toggle-display)
      ;; Set next vars when image is already displayed but local
      ;; variables were cleared by kill-all-local-variables
+     (use-local-map image-mode-map)
      (setq cursor-type nil truncate-lines t))
    (run-mode-hooks 'image-mode-hook)
    (if (display-images-p)
***************
*** 140,145 ****
--- 291,298 ----
  	(set-buffer-modified-p modified)
  	(kill-local-variable 'cursor-type)
  	(kill-local-variable 'truncate-lines)
+ 	(kill-local-variable 'auto-hscroll-mode)
+ 	(use-local-map image-mode-text-map)
  	(if (called-interactively-p)
  	    (message "Repeat this command to go back to displaying the image")))
      ;; Turn the image data into a real image, but only if the whole file
***************
*** 161,172 ****
  	       nil t)))
  	   (props
  	    `(display ,image
! 		      intangible ,image
! 		      rear-nonsticky (display intangible)
! 		      ;; This a cheap attempt to make the whole buffer
! 		      ;; read-only when we're visiting the file (as
! 		      ;; opposed to just inserting it).
! 		      read-only t front-sticky (read-only)))
  	   (inhibit-read-only t)
  	   (buffer-undo-list t)
  	   (modified (buffer-modified-p)))
--- 314,322 ----
  	       nil t)))
  	   (props
  	    `(display ,image
! 	      intangible ,image
! 	      rear-nonsticky (display intangible)
! 	      read-only t front-sticky (read-only)))
  	   (inhibit-read-only t)
  	   (buffer-undo-list t)
  	   (modified (buffer-modified-p)))
***************
*** 179,184 ****
--- 329,337 ----
        ;; This just makes the arrow displayed in the right fringe
        ;; area look correct when the image is wider than the window.
        (setq truncate-lines t)
+       ;; Allow navigation of large images
+       (set (make-local-variable 'auto-hscroll-mode) nil)
+       (use-local-map image-mode-map)
        (if (called-interactively-p)
  	  (message "Repeat this command to go back to displaying the file as text")))))

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Image-mode enhancements (post-release)
  2007-05-23 17:54 Image-mode enhancements (post-release) Chong Yidong
@ 2007-05-23 18:47 ` David Kastrup
  2007-05-23 19:48   ` Chong Yidong
                     ` (2 more replies)
  2007-05-23 22:44 ` Kevin Ryde
  1 sibling, 3 replies; 7+ messages in thread
From: David Kastrup @ 2007-05-23 18:47 UTC (permalink / raw)
  To: Chong Yidong; +Cc: emacs-devel

Chong Yidong <cyd@stupidchicken.com> writes:

> One important enhancement I would like to get into Emacs 23 (and maybe
> Emacs 22.2 too) is image scrolling for image-mode.  Currently, images
> that are wider or taller than the Emacs window aren't handled very
> well; you can scroll up and down using next-line and previous-line,
> but not sideways (and, annoyingly, scrolling to the bottom of such
> images loops back to the top).
>
> The following patch implements the necessary image-scrolling
> functions, and remaps the normal navigation keybindings
> (forward-char, previous-line, scroll-up, etc.) to use these
> functions when image-mode is displaying the image as an image.

Since there are a number of modes apart from image-mode that can embed
images, some technique that did not require special commands would be
preferable.  If we have done everything that can be reasonably
expected to be done on such buffers, we can still consider creating
special commands for image-mode.

> One other useful feature which is not currently implemented would be
> to resize the image to fit the Emacs window if it is too large, and
> to provide a way to toggle between the full-sized and window-fitted
> versions of the image (Firefox has a similar feature).

tumme (or whatever it is called now) has a mode like that.

-- 
David Kastrup, Kriemhildstr. 15, 44793 Bochum

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Image-mode enhancements (post-release)
  2007-05-23 18:47 ` David Kastrup
@ 2007-05-23 19:48   ` Chong Yidong
  2007-05-23 19:53   ` Mathias Dahl
  2007-05-23 23:46   ` Richard Stallman
  2 siblings, 0 replies; 7+ messages in thread
From: Chong Yidong @ 2007-05-23 19:48 UTC (permalink / raw)
  To: David Kastrup; +Cc: emacs-devel

David Kastrup <dak@gnu.org> writes:

> Since there are a number of modes apart from image-mode that can embed
> images, some technique that did not require special commands would be
> preferable.  If we have done everything that can be reasonably
> expected to be done on such buffers, we can still consider creating
> special commands for image-mode.

Emacs already supports for scrolling tall embedded images, which is
implemented in line-move-partial.  It is much more convenient to
create special commands for image-mode because in image-mode, there is
exactly one image in the buffer, and nothing else.

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Image-mode enhancements (post-release)
  2007-05-23 18:47 ` David Kastrup
  2007-05-23 19:48   ` Chong Yidong
@ 2007-05-23 19:53   ` Mathias Dahl
  2007-05-23 23:46   ` Richard Stallman
  2 siblings, 0 replies; 7+ messages in thread
From: Mathias Dahl @ 2007-05-23 19:53 UTC (permalink / raw)
  To: David Kastrup; +Cc: Chong Yidong, emacs-devel

> > One other useful feature which is not currently implemented would be
> > to resize the image to fit the Emacs window if it is too large, and
> > to provide a way to toggle between the full-sized and window-fitted
> > versions of the image (Firefox has a similar feature).
>
> tumme (or whatever it is called now) has a mode like that.

And here it is:

(defun image-dired-display-image (file &optional original-size)
  "Display image FILE in image buffer.
Use this when you want to display the image, semi sized, in a new
window.  The image is sized to fit the display window (using a
temporary file, don't worry).  Because of this, it will not be as
quick as opening it directly, but on most modern systems it
should feel snappy enough.

If optional argument ORIGINAL-SIZE is non-nil, display image in its
original size."
...

/Mathias

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Image-mode enhancements (post-release)
  2007-05-23 17:54 Image-mode enhancements (post-release) Chong Yidong
  2007-05-23 18:47 ` David Kastrup
@ 2007-05-23 22:44 ` Kevin Ryde
  1 sibling, 0 replies; 7+ messages in thread
From: Kevin Ryde @ 2007-05-23 22:44 UTC (permalink / raw)
  To: emacs-devel

Chong Yidong <cyd@stupidchicken.com> writes:
>
> One important enhancement I would like to get into Emacs 23 (and maybe
> Emacs 22.2 too) is image scrolling for image-mode.  Currently, images
> that are wider or taller than the Emacs window aren't handled very
> well; you can scroll up and down using next-line and previous-line,
> but not sideways (and, annoyingly, scrolling to the bottom of such
> images loops back to the top).

Tinkering with text bits after the image (see other message) I noticed
even freakier is when there's text after the image, and the image height
is greater than the window, if you try to C-n down it keeps getting
recentred back to the top (where I had hoped it would at least go to the
next text line).  You have to hold down C-n and hope your keyboard is
faster than the redisplay!  (Or go M-> of course.)

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Image-mode enhancements (post-release)
  2007-05-23 18:47 ` David Kastrup
  2007-05-23 19:48   ` Chong Yidong
  2007-05-23 19:53   ` Mathias Dahl
@ 2007-05-23 23:46   ` Richard Stallman
  2007-05-24  6:57     ` David Kastrup
  2 siblings, 1 reply; 7+ messages in thread
From: Richard Stallman @ 2007-05-23 23:46 UTC (permalink / raw)
  To: David Kastrup; +Cc: cyd, emacs-devel

    Since there are a number of modes apart from image-mode that can embed
    images, some technique that did not require special commands would be
    preferable.

Do you mean, some low-level scrolling mechanism that could be used?
It seems a bit hard to design one.  I think we may as well install
this simple feature for now.

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Image-mode enhancements (post-release)
  2007-05-23 23:46   ` Richard Stallman
@ 2007-05-24  6:57     ` David Kastrup
  0 siblings, 0 replies; 7+ messages in thread
From: David Kastrup @ 2007-05-24  6:57 UTC (permalink / raw)
  To: rms; +Cc: cyd, emacs-devel

Richard Stallman <rms@gnu.org> writes:

>     Since there are a number of modes apart from image-mode that can embed
>     images, some technique that did not require special commands would be
>     preferable.
>
> Do you mean, some low-level scrolling mechanism that could be used?
> It seems a bit hard to design one.

Actually, we are not half bad at the moment.  The idea is that when
moving the cursor to the calculated position would require
recentering, then instead vscroll/hscroll are used.

This works best (though not yet optimal) when going forward
vertically.  The equivalent functionality horizontally is not there
yet, and backward movements are somewhat less optimal.

> I think we may as well install this simple feature for now.

-- 
David Kastrup

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2007-05-24  6:57 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-05-23 17:54 Image-mode enhancements (post-release) Chong Yidong
2007-05-23 18:47 ` David Kastrup
2007-05-23 19:48   ` Chong Yidong
2007-05-23 19:53   ` Mathias Dahl
2007-05-23 23:46   ` Richard Stallman
2007-05-24  6:57     ` David Kastrup
2007-05-23 22:44 ` Kevin Ryde

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).