* term/x-win.el: Require `scroll-bar', not `scrollbar'.
[bpt/emacs.git] / lisp / scroll-bar.el
CommitLineData
6d62a90e
JB
1;;; scrollbar.el -- window system-independent scrollbar support.
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
dbc4e1c1
JB
24(require 'mouse)
25
6d62a90e
JB
26\f
27;;;; Utilities.
28
29(defun scrollbar-scale (num-denom whole)
30 "Given a pair (NUM . DENOM) and WHOLE, return (/ (* NUM WHOLE) DENOM).
31This is handy for scaling a position on a scrollbar into real units,
32like buffer positions. If SCROLLBAR-POS is the (PORTION . WHOLE) pair
33from a scrollbar event, then (scrollbar-scale SCROLLBAR-POS
34\(buffer-size)) is the position in the current buffer corresponding to
35that scrollbar position."
36 ;; We multiply before we divide to maintain precision.
37 ;; We use floating point because the product of a large buffer size
38 ;; with a large scrollbar portion can easily overflow a lisp int.
39 (truncate (/ (* (float (car num-denom)) whole) (cdr num-denom))))
40
41\f
fe48f821
JB
42;;;; Helpful functions for enabling and disabling scroll bars.
43(defvar scroll-bar-mode nil)
44
45(defun scroll-bar-mode (flag)
46 "Toggle display of vertical scroll bars on each frame.
47This command applies to all frames that exist and frames to be
48created in the future.
49With a numeric argument, if the argument is negative,
50turn off scroll bars; otherwise, turn on scroll bars."
51 (interactive "P")
52 (setq scroll-bar-mode (if (null flag) (not scroll-bar-mode)
53 (or (not (numberp flag)) (>= flag 0))))
54 (mapcar
55 (function
56 (lambda (param-name)
57 (let ((parameter (assq param-name default-frame-alist)))
58 (if (consp parameter)
59 (setcdr parameter scroll-bar-mode)
60 (setq default-frame-alist
61 (cons (cons param-name scroll-bar-mode)
62 default-frame-alist))))))
63 '(vertical-scrollbars horizontal-scrollbars))
64 (let ((frames (frame-list)))
65 (while frames
66 (modify-frame-parameters
67 (car frames)
68 (list (cons 'vertical-scrollbars scroll-bar-mode)
69 (cons 'horizontal-scrollbars scroll-bar-mode)))
70 (setq frames (cdr frames)))))
71\f
6d62a90e
JB
72;;;; Buffer navigation using the scrollbar.
73
74(defun scrollbar-set-window-start (event)
75 "Set the window start according to where the scrollbar is dragged.
76EVENT should be a scrollbar click or drag event."
77 (interactive "e")
dbc4e1c1 78 (let* ((end-position (event-end event))
6d62a90e
JB
79 (window (nth 0 end-position))
80 (portion-whole (nth 2 end-position)))
81 (save-excursion
82 (set-buffer (window-buffer window))
83 (save-excursion
84 (goto-char (scrollbar-scale portion-whole (buffer-size)))
85 (beginning-of-line)
86 (set-window-start window (point))))))
87
88(defun scrollbar-scroll-down (event)
89 "Scroll the window's top line down to the location of the scrollbar click.
90EVENT should be a scrollbar click."
91 (interactive "e")
92 (let ((old-selected-window (selected-window)))
93 (unwind-protect
94 (progn
dbc4e1c1 95 (let* ((end-position (event-end event))
6d62a90e
JB
96 (window (nth 0 end-position))
97 (portion-whole (nth 2 end-position)))
98 (select-window window)
99 (scroll-down
100 (scrollbar-scale portion-whole (1- (window-height))))))
101 (select-window old-selected-window))))
102
103(defun scrollbar-scroll-up (event)
104 "Scroll the line next to the scrollbar click to the top of the window.
105EVENT should be a scrollbar click."
106 (interactive "e")
107 (let ((old-selected-window (selected-window)))
108 (unwind-protect
109 (progn
dbc4e1c1 110 (let* ((end-position (event-end event))
6d62a90e
JB
111 (window (nth 0 end-position))
112 (portion-whole (nth 2 end-position)))
113 (select-window window)
114 (scroll-up
115 (scrollbar-scale portion-whole (1- (window-height))))))
116 (select-window old-selected-window))))
117
118\f
119;;;; Bindings.
120
121;;; For now, we'll set things up to work like xterm.
122(global-set-key [vertical-scrollbar mouse-1] 'scrollbar-scroll-up)
123(global-set-key [vertical-scrollbar drag-mouse-1] 'scrollbar-scroll-up)
124
125(global-set-key [vertical-scrollbar mouse-2] 'scrollbar-set-window-start)
126(global-set-key [vertical-scrollbar drag-mouse-2] 'scrollbar-set-window-start)
127
128(global-set-key [vertical-scrollbar mouse-3] 'scrollbar-scroll-down)
129(global-set-key [vertical-scrollbar drag-mouse-3] 'scrollbar-scroll-down)
130
131\f
132(provide 'scrollbar)
133
134;;; scrollbar.el ends here