Require help-macro, not help-screen.
[bpt/emacs.git] / lisp / scroll-bar.el
CommitLineData
aae56ea7 1;;; scroll-bar.el --- window system-independent scroll bar support.
6d62a90e
JB
2
3;;; Copyright (C) 1993 Free Software Foundation, Inc.
4
5;; Maintainer: FSF
6;; Keywords: hardware
7
8;;; This file is part of GNU Emacs.
9
10;;; GNU Emacs is free software; you can redistribute it and/or modify
11;;; it under the terms of the GNU General Public License as published by
12;;; the Free Software Foundation; either version 2, or (at your option)
13;;; any later version.
14
15;;; GNU Emacs is distributed in the hope that it will be useful,
16;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18;;; GNU General Public License for more details.
19
20;;; You should have received a copy of the GNU General Public License
21;;; along with GNU Emacs; see the file COPYING. If not, write to
22;;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
23
76550a57
ER
24;;; Code:
25
d9ecc911
ER
26;;; Commentary:
27
28;; Window-system-independent bindings of mouse clicks on the scroll bar.
29;; Presently emulates the scroll-bar behavior of xterm.
30;;; Code:
31
dbc4e1c1
JB
32(require 'mouse)
33
6d62a90e
JB
34\f
35;;;; Utilities.
36
bf3c8a70 37(defun scroll-bar-scale (num-denom whole)
6d62a90e 38 "Given a pair (NUM . DENOM) and WHOLE, return (/ (* NUM WHOLE) DENOM).
bf3c8a70
JB
39This is handy for scaling a position on a scroll bar into real units,
40like buffer positions. If SCROLL-BAR-POS is the (PORTION . WHOLE) pair
41from a scroll bar event, then (scroll-bar-scale SCROLL-BAR-POS
6d62a90e 42\(buffer-size)) is the position in the current buffer corresponding to
bf3c8a70 43that scroll bar position."
6d62a90e
JB
44 ;; We multiply before we divide to maintain precision.
45 ;; We use floating point because the product of a large buffer size
bf3c8a70 46 ;; with a large scroll bar portion can easily overflow a lisp int.
6d62a90e
JB
47 (truncate (/ (* (float (car num-denom)) whole) (cdr num-denom))))
48
49\f
fe48f821
JB
50;;;; Helpful functions for enabling and disabling scroll bars.
51(defvar scroll-bar-mode nil)
52
53(defun scroll-bar-mode (flag)
54 "Toggle display of vertical scroll bars on each frame.
55This command applies to all frames that exist and frames to be
56created in the future.
57With a numeric argument, if the argument is negative,
58turn off scroll bars; otherwise, turn on scroll bars."
59 (interactive "P")
60 (setq scroll-bar-mode (if (null flag) (not scroll-bar-mode)
61 (or (not (numberp flag)) (>= flag 0))))
62 (mapcar
63 (function
64 (lambda (param-name)
65 (let ((parameter (assq param-name default-frame-alist)))
66 (if (consp parameter)
67 (setcdr parameter scroll-bar-mode)
68 (setq default-frame-alist
69 (cons (cons param-name scroll-bar-mode)
70 default-frame-alist))))))
bf3c8a70 71 '(vertical-scroll-bars horizontal-scroll-bars))
fe48f821
JB
72 (let ((frames (frame-list)))
73 (while frames
74 (modify-frame-parameters
75 (car frames)
bf3c8a70
JB
76 (list (cons 'vertical-scroll-bars scroll-bar-mode)
77 (cons 'horizontal-scroll-bars scroll-bar-mode)))
fe48f821
JB
78 (setq frames (cdr frames)))))
79\f
bf3c8a70 80;;;; Buffer navigation using the scroll bar.
6d62a90e 81
bf3c8a70
JB
82(defun scroll-bar-set-window-start (event)
83 "Set the window start according to where the scroll bar is dragged.
84EVENT should be a scroll bar click or drag event."
6d62a90e 85 (interactive "e")
dbc4e1c1 86 (let* ((end-position (event-end event))
6d62a90e
JB
87 (window (nth 0 end-position))
88 (portion-whole (nth 2 end-position)))
89 (save-excursion
90 (set-buffer (window-buffer window))
91 (save-excursion
bf3c8a70 92 (goto-char (scroll-bar-scale portion-whole (buffer-size)))
6d62a90e
JB
93 (beginning-of-line)
94 (set-window-start window (point))))))
95
bf3c8a70
JB
96(defun scroll-bar-scroll-down (event)
97 "Scroll the window's top line down to the location of the scroll bar click.
98EVENT should be a scroll bar click."
6d62a90e
JB
99 (interactive "e")
100 (let ((old-selected-window (selected-window)))
101 (unwind-protect
102 (progn
dbc4e1c1 103 (let* ((end-position (event-end event))
6d62a90e
JB
104 (window (nth 0 end-position))
105 (portion-whole (nth 2 end-position)))
106 (select-window window)
107 (scroll-down
bf3c8a70 108 (scroll-bar-scale portion-whole (1- (window-height))))))
6d62a90e
JB
109 (select-window old-selected-window))))
110
bf3c8a70
JB
111(defun scroll-bar-scroll-up (event)
112 "Scroll the line next to the scroll bar click to the top of the window.
113EVENT should be a scroll bar click."
6d62a90e
JB
114 (interactive "e")
115 (let ((old-selected-window (selected-window)))
116 (unwind-protect
117 (progn
dbc4e1c1 118 (let* ((end-position (event-end event))
6d62a90e
JB
119 (window (nth 0 end-position))
120 (portion-whole (nth 2 end-position)))
121 (select-window window)
122 (scroll-up
bf3c8a70 123 (scroll-bar-scale portion-whole (1- (window-height))))))
6d62a90e
JB
124 (select-window old-selected-window))))
125
126\f
127;;;; Bindings.
128
129;;; For now, we'll set things up to work like xterm.
bf3c8a70
JB
130(global-set-key [vertical-scroll-bar mouse-1] 'scroll-bar-scroll-up)
131(global-set-key [vertical-scroll-bar drag-mouse-1] 'scroll-bar-scroll-up)
6d62a90e 132
bf3c8a70
JB
133(global-set-key [vertical-scroll-bar mouse-2] 'scroll-bar-set-window-start)
134(global-set-key [vertical-scroll-bar drag-mouse-2] 'scroll-bar-set-window-start)
6d62a90e 135
bf3c8a70
JB
136(global-set-key [vertical-scroll-bar mouse-3] 'scroll-bar-scroll-down)
137(global-set-key [vertical-scroll-bar drag-mouse-3] 'scroll-bar-scroll-down)
6d62a90e
JB
138
139\f
dc14eed2 140(provide 'scroll-bar)
6d62a90e 141
bf3c8a70 142;;; scroll-bar.el ends here