]> code.delx.au - gnu-emacs/blobdiff - lisp/mouse-drag.el
* lisp/progmodes/ruby-mode.el (ruby-move-to-block): Improve
[gnu-emacs] / lisp / mouse-drag.el
index f1d56eccc667c0861396fbcdc74cb4078c2b92c5..3a29e05c8b192c19f28e4265ab0d754c2204cd67 100644 (file)
@@ -1,17 +1,16 @@
 ;;; mouse-drag.el --- use mouse-2 to do a new style of scrolling
 
 ;;; mouse-drag.el --- use mouse-2 to do a new style of scrolling
 
-;; Copyright (C) 1996, 1997, 2001, 2002, 2003, 2004,
-;;   2005, 2006, 2007 Free Software Foundation, Inc.
+;; Copyright (C) 1996-1997, 2001-2013 Free Software Foundation, Inc.
 
 ;; Author: John Heidemann <johnh@ISI.EDU>
 ;; Keywords: mouse
 
 ;; This file is part of GNU Emacs.
 
 
 ;; Author: John Heidemann <johnh@ISI.EDU>
 ;; Keywords: mouse
 
 ;; This file is part of GNU Emacs.
 
-;; GNU Emacs is free software; you can redistribute it and/or modify
+;; GNU Emacs is free software: you can redistribute it and/or modify
 ;; it under the terms of the GNU General Public License as published by
 ;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation; either version 3, or (at your option)
-;; any later version.
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
 
 ;; GNU Emacs is distributed in the hope that it will be useful,
 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
 
 ;; GNU Emacs is distributed in the hope that it will be useful,
 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
 ;; GNU General Public License for more details.
 
 ;; You should have received a copy of the GNU General Public License
 ;; GNU General Public License for more details.
 
 ;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs; see the file COPYING.  If not, write to the
-;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-;; Boston, MA 02110-1301, USA.
+;; along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.
 
 ;;; Commentary:
 
 
 ;;; Commentary:
 
-;;; What is ``mouse-drag.el''?
-;;;
-;;; Doesn't that scroll bar seem far away when you want to scroll?
-;;; This module overloads mouse-2 to do ``throw'' scrolling.  You
-;;; click and drag.  The distance you move from your original click
-;;; turns into a scroll amount.  The scroll amount is scaled
-;;; exponentially to make both large moves and short adjustments easy.
-;;; What this boils down to is that you can easily scroll around the
-;;; buffer without much mouse movement.  Finally, clicks which aren't
-;;; drags are passed off to the old mouse-2 binding, so old mouse-2
-;;; operations (find-file in dired-mode, yanking in most other modes)
-;;; still work.
-;;;
-;;; There is an alternative way to scroll, ``drag'' scrolling.  You
-;;; can click on a character and then drag it around, scrolling the
-;;; buffer with you.  The character always stays under the mouse.
-;;; Compared to throw-scrolling, this approach provides direct
-;;; manipulation (nice) but requires more mouse movement
-;;; (unfortunate).  It is offered as an alternative for those who
-;;; prefer it.
-;;;
-;;; If you like mouse-drag, you should also check out mouse-copy
-;;; for ``one-click text copy and move''.
-;;;
-;;; To use mouse-drag, place the following in your .emacs file:
-;;;    (require 'mouse-drag)
-;;; -and either-
-;;;     (global-set-key [down-mouse-2] 'mouse-drag-throw)
-;;; -or-
-;;;     (global-set-key [down-mouse-2] 'mouse-drag-drag)
-;;;
-;;;
-;;;
-;;; Options:
-;;;
-;;; - reverse the throw-scroll direction with \\[mouse-throw-with-scroll-bar]
-;;; - work around a bug with \\[mouse-extras-work-around-drag-bug]
-;;; - auto-enable horizontal scrolling with
-;;;   \\[mouse-drag-electric-col-scrolling]
-;;;
-;;;
-;;; History and related work:
-;;;
-;;; One-click copying and moving was inspired by lemacs-19.8.
-;;; Throw-scrolling was inspired by MacPaint's ``hand'' and by Tk's
-;;; mouse-2 scrolling.  The package mouse-scroll.el by Tom Wurgler
-;;; <twurgler@goodyear.com> is similar to mouse-drag-throw, but
-;;; doesn't pass clicks through.
-;;;
-;;; These functions have been tested in emacs version 19.30,
-;;; and this package has run in the past on 19.25-19.29.
-;;;
-;;; Originally mouse-drag was part of a larger package.
-;;; As of 11 July 96 the scrolling functions were split out
-;;; in preparation for incorporation into (the future) emacs-19.32.
-;;;
-;;;
-;;; Thanks:
-;;;
-;;; Thanks to Kai Grossjohann
-;;; <grossjoh@dusty.informatik.uni-dortmund.de> for reporting bugs, to
-;;; Tom Wurgler <twurgler@goodyear.com> for reporting bugs and
-;;; suggesting fixes, and to Joel Graber <jgraber@ti.com> for
-;;; prompting me to do drag-scrolling and for an initial
-;;; implementation of horizontal drag-scrolling.
-;;;
-;;;    -johnh@isi.edu, 11-Jul-96
-;;;
-;;;
-;;; What's new with mouse-drag 2.24?
-;;;
-;;; - mouse-drag-electric-col-scrolling (default: on)
-;;;   auto-enables horizontal scrolling when clicks on wrapped
-;;;   lines occur
-\f
+;; What is ``mouse-drag.el''?
+;;
+;; Doesn't that scroll bar seem far away when you want to scroll?
+;; This module overloads mouse-2 to do ``throw'' scrolling.  You
+;; click and drag.  The distance you move from your original click
+;; turns into a scroll amount.  The scroll amount is scaled
+;; exponentially to make both large moves and short adjustments easy.
+;; What this boils down to is that you can easily scroll around the
+;; buffer without much mouse movement.  Finally, clicks which aren't
+;; drags are passed off to the old mouse-2 binding, so old mouse-2
+;; operations (find-file in dired-mode, yanking in most other modes)
+;; still work.
+;;
+;; There is an alternative way to scroll, ``drag'' scrolling.  You
+;; can click on a character and then drag it around, scrolling the
+;; buffer with you.  The character always stays under the mouse.
+;; Compared to throw-scrolling, this approach provides direct
+;; manipulation (nice) but requires more mouse movement
+;; (unfortunate).  It is offered as an alternative for those who
+;; prefer it.
+;;
+;; If you like mouse-drag, you should also check out mouse-copy
+;; for ``one-click text copy and move''.
+;;
+;; To use mouse-drag, place the following in your init file:
+;; -either-
+;;     (global-set-key [down-mouse-2] 'mouse-drag-throw)
+;; -or-
+;;     (global-set-key [down-mouse-2] 'mouse-drag-drag)
+;;
+;;
+;;
+;; Options:
+;;
+;; - reverse the throw-scroll direction with \\[mouse-throw-with-scroll-bar]
+;; - work around a bug with \\[mouse-extras-work-around-drag-bug]
+;; - auto-enable horizontal scrolling with
+;;   \\[mouse-drag-electric-col-scrolling]
+;;
+;;
+;; History and related work:
+;;
+;; One-click copying and moving was inspired by lemacs-19.8.
+;; Throw-scrolling was inspired by MacPaint's ``hand'' and by Tk's
+;; mouse-2 scrolling.  The package mouse-scroll.el by Tom Wurgler
+;; <twurgler@goodyear.com> is similar to mouse-drag-throw, but
+;; doesn't pass clicks through.
+;;
+;; These functions have been tested in emacs version 19.30,
+;; and this package has run in the past on 19.25-19.29.
+;;
+;; Originally mouse-drag was part of a larger package.
+;; As of 11 July 96 the scrolling functions were split out
+;; in preparation for incorporation into (the future) emacs-19.32.
+;;
+;; Thanks:
+;;
+;; Thanks to Kai Grossjohann
+;; <grossjoh@dusty.informatik.uni-dortmund.de> for reporting bugs, to
+;; Tom Wurgler <twurgler@goodyear.com> for reporting bugs and
+;; suggesting fixes, and to Joel Graber <jgraber@ti.com> for
+;; prompting me to do drag-scrolling and for an initial
+;; implementation of horizontal drag-scrolling.
+;;
+;;    -johnh@isi.edu, 11-Jul-96
+;;
+;;
+;; What's new with mouse-drag 2.24?
+;;
+;; - mouse-drag-electric-col-scrolling (default: on)
+;;   auto-enables horizontal scrolling when clicks on wrapped
+;;   lines occur
+
+;; TODO:
+;; - For mouse-drag-throw, we should try and place some visual indicator
+;;   of the original mouse position (like Firefox does).
+
 ;;; Code:
 
 ;;
 ;;; Code:
 
 ;;
@@ -142,11 +141,11 @@ Keep the cursor on the screen as needed."
       ((start-col-row (posn-col-row start-posn))
        (end-col-row (posn-col-row end-posn)))
     (and
       ((start-col-row (posn-col-row start-posn))
        (end-col-row (posn-col-row end-posn)))
     (and
-;; We no longer exclude things by time.
-;;     (< (- (posn-timestamp end-posn) (posn-timestamp start-posn))
-;;     (if (numberp double-click-time)
-;;         (* 2 double-click-time)   ;; stretch it a little
-;;       999999)) ;; non-numeric => check by position alone
+     ;; ;; We no longer exclude things by time.
+     ;; (< (- (posn-timestamp end-posn) (posn-timestamp start-posn))
+     ;;    (if (numberp double-click-time)
+     ;;        (* 2 double-click-time) ;; stretch it a little
+     ;;      999999)) ;; non-numeric => check by position alone
      (= (car start-col-row) (car end-col-row))
      (= (cdr start-col-row) (cdr end-col-row)))))
 
      (= (car start-col-row) (car end-col-row))
      (= (cdr start-col-row) (cdr end-col-row)))))
 
@@ -158,28 +157,35 @@ Keep the cursor on the screen as needed."
 Basically, we check for existing horizontal scrolling."
   (or truncate-lines
       (> (window-hscroll (selected-window)) 0)
 Basically, we check for existing horizontal scrolling."
   (or truncate-lines
       (> (window-hscroll (selected-window)) 0)
-      (< (window-width) (frame-width))
+      (not (window-full-width-p))
       (and
        mouse-drag-electric-col-scrolling
        (save-excursion  ;; on a long line?
         (let
       (and
        mouse-drag-electric-col-scrolling
        (save-excursion  ;; on a long line?
         (let
-            ((beg (progn (beginning-of-line) (point)))
+            ((beg (line-beginning-position))
              (end (progn (end-of-line) (point))))
           (if (> (- end beg) (window-width))
               (setq truncate-lines t)
             nil))))))
 
 (defvar mouse-throw-with-scroll-bar nil
              (end (progn (end-of-line) (point))))
           (if (> (- end beg) (window-width))
               (setq truncate-lines t)
             nil))))))
 
 (defvar mouse-throw-with-scroll-bar nil
-  "*Set direction of mouse-throwing.
+  "Set direction of mouse-throwing.
 If nil, the text moves in the direction the mouse moves.
 If t, the scroll bar moves in the direction the mouse moves.")
 If nil, the text moves in the direction the mouse moves.
 If t, the scroll bar moves in the direction the mouse moves.")
-(defconst mouse-throw-magnifier-with-scroll-bar
-      [-16 -8 -4 -2 -1 0 0 0  1  2  4  8  16])
-(defconst mouse-throw-magnifier-with-mouse-movement
-      [ 16  8  4  2  1 0 0 0 -1 -2 -4 -8 -16])
 (defconst mouse-throw-magnifier-min -6)
 (defconst mouse-throw-magnifier-max 6)
 (defconst mouse-throw-magnifier-min -6)
 (defconst mouse-throw-magnifier-max 6)
+(defconst mouse-throw-magnifier-base 1.5)
+
+(defun mouse-drag-scroll-delta (mouse-delta)
+  ;; Limit the exponential explosion.
+  (setq mouse-delta
+        (max mouse-throw-magnifier-min
+             (min mouse-throw-magnifier-max mouse-delta)))
+  (* (round (exp (* (log mouse-throw-magnifier-base) (abs mouse-delta))))
+     (if (< mouse-delta 0) -1 1)
+     (if mouse-throw-with-scroll-bar 1 -1)))
 
 
+;;;###autoload
 (defun mouse-drag-throw (start-event)
   "\"Throw\" the page according to a mouse drag.
 
 (defun mouse-drag-throw (start-event)
   "\"Throw\" the page according to a mouse drag.
 
@@ -188,7 +194,7 @@ from the original mouse click to the current mouse location.  Try it;
 you'll like it.  It's easier to observe than to explain.
 
 If the mouse is clicked and released in the same place of time we
 you'll like it.  It's easier to observe than to explain.
 
 If the mouse is clicked and released in the same place of time we
-assume that the user didn't want to scdebugroll but wanted to whatever
+assume that the user didn't want to scroll but wanted to whatever
 mouse-2 used to do, so we pass it through.
 
 Throw scrolling was inspired (but is not identical to) the \"hand\"
 mouse-2 used to do, so we pass it through.
 
 Throw scrolling was inspired (but is not identical to) the \"hand\"
@@ -208,13 +214,10 @@ To test this function, evaluate:
         (start-row (cdr (posn-col-row start-posn)))
         (start-col (car (posn-col-row start-posn)))
         (old-selected-window (selected-window))
         (start-row (cdr (posn-col-row start-posn)))
         (start-col (car (posn-col-row start-posn)))
         (old-selected-window (selected-window))
-        event end row mouse-delta scroll-delta
+        event end row scroll-delta
         have-scrolled
         have-scrolled
-        window-last-row
-        col mouse-col-delta window-last-col
+        col
         (scroll-col-delta 0)
         (scroll-col-delta 0)
-        adjusted-mouse-col-delta
-        adjusted-mouse-delta
         ;; be conservative about allowing horizontal scrolling
         (col-scrolling-p (mouse-drag-should-do-col-scrolling)))
     (select-window start-window)
         ;; be conservative about allowing horizontal scrolling
         (col-scrolling-p (mouse-drag-should-do-col-scrolling)))
     (select-window start-window)
@@ -226,35 +229,11 @@ To test this function, evaluate:
                     col (car (posn-col-row end)))
               (or (mouse-movement-p event)
                   (eq (car-safe event) 'switch-frame)))
                     col (car (posn-col-row end)))
               (or (mouse-movement-p event)
                   (eq (car-safe event) 'switch-frame)))
-       (if (eq start-window (posn-window end))
-           (progn
-             (setq mouse-delta (- start-row row)
-                   adjusted-mouse-delta
-                   (- (cond
-                       ((<= mouse-delta mouse-throw-magnifier-min)
-                        mouse-throw-magnifier-min)
-                       ((>= mouse-delta mouse-throw-magnifier-max)
-                        mouse-throw-magnifier-max)
-                       (t mouse-delta))
-                      mouse-throw-magnifier-min)
-                   scroll-delta (aref (if mouse-throw-with-scroll-bar
-                                          mouse-throw-magnifier-with-scroll-bar
-                                        mouse-throw-magnifier-with-mouse-movement)
-                                      adjusted-mouse-delta))
-             (if col-scrolling-p
-                 (setq mouse-col-delta (- start-col col)
-                       adjusted-mouse-col-delta
-                       (- (cond
-                           ((<= mouse-col-delta mouse-throw-magnifier-min)
-                            mouse-throw-magnifier-min)
-                           ((>= mouse-col-delta mouse-throw-magnifier-max)
-                            mouse-throw-magnifier-max)
-                           (t mouse-col-delta))
-                          mouse-throw-magnifier-min)
-                       scroll-col-delta (aref (if mouse-throw-with-scroll-bar
-                                                  mouse-throw-magnifier-with-scroll-bar
-                                                mouse-throw-magnifier-with-mouse-movement)
-                                              adjusted-mouse-col-delta)))))
+       (when (eq start-window (posn-window end))
+          (when col-scrolling-p
+            (setq scroll-col-delta (mouse-drag-scroll-delta (- start-col col))))
+          (setq scroll-delta (mouse-drag-scroll-delta (- start-row row))))
+
        (if (or (/= 0 scroll-delta)
                (/= 0 scroll-col-delta))
            (progn
        (if (or (/= 0 scroll-delta)
                (/= 0 scroll-col-delta))
            (progn
@@ -270,6 +249,7 @@ To test this function, evaluate:
     ;; Now restore the old window.
     (select-window old-selected-window)))
 
     ;; Now restore the old window.
     (select-window old-selected-window)))
 
+;;;###autoload
 (defun mouse-drag-drag (start-event)
   "\"Drag\" the page according to a mouse drag.
 
 (defun mouse-drag-drag (start-event)
   "\"Drag\" the page according to a mouse drag.
 
@@ -292,10 +272,10 @@ To test this function, evaluate:
         (start-row (cdr (posn-col-row start-posn)))
         (start-col (car (posn-col-row start-posn)))
         (old-selected-window (selected-window))
         (start-row (cdr (posn-col-row start-posn)))
         (start-col (car (posn-col-row start-posn)))
         (old-selected-window (selected-window))
-        event end row mouse-delta scroll-delta
+        event end row scroll-delta
         have-scrolled
         window-last-row
         have-scrolled
         window-last-row
-        col mouse-col-delta window-last-col
+        col window-last-col
         (scroll-col-delta 0)
         ;; be conservative about allowing horizontal scrolling
         (col-scrolling-p (mouse-drag-should-do-col-scrolling)))
         (scroll-col-delta 0)
         ;; be conservative about allowing horizontal scrolling
         (col-scrolling-p (mouse-drag-should-do-col-scrolling)))
@@ -342,5 +322,4 @@ To test this function, evaluate:
 
 (provide 'mouse-drag)
 
 
 (provide 'mouse-drag)
 
-;;; arch-tag: e47354ff-82f5-42c4-b3dc-88dd9c04b770
 ;;; mouse-drag.el ends here
 ;;; mouse-drag.el ends here