Mercurial > hg > xemacs
comparison shared/motion.el @ 0:107d592c5f4a
DICE versions, used by pers/common, recursive, I think/hope
author | Henry S. Thompson <ht@inf.ed.ac.uk> |
---|---|
date | Mon, 08 Feb 2021 11:44:37 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:107d592c5f4a |
---|---|
1 ;;; Copyright (C) 1990 Alan M. Carroll | |
2 ;;; | |
3 ;;; This file is for use with Epoch, a modified version of GNU Emacs. | |
4 ;;; Requires Epoch 3.2 or later. | |
5 ;;; | |
6 ;;; This code is distributed in the hope that it will be useful, | |
7 ;;; bute WITHOUT ANY WARRANTY. No author or distributor accepts | |
8 ;;; responsibility to anyone for the consequences of using this code | |
9 ;;; or for whether it serves any particular purpose or works at all, | |
10 ;;; unless explicitly stated in a written agreement. | |
11 ;;; | |
12 ;;; Everyone is granted permission to copy, modify and redistribute | |
13 ;;; this code, but only under the conditions described in the | |
14 ;;; GNU Emacs General Public License, except the original author nor his | |
15 ;;; agents are bound by the License in their use of this code. | |
16 ;;; (These special rights for the author in no way restrict the rights of | |
17 ;;; others given in the License or this prologue) | |
18 ;;; A copy of this license is supposed to have been given to you along | |
19 ;;; with Epoch so you can know your rights and responsibilities. | |
20 ;;; It should be in a file named COPYING. Among other things, the | |
21 ;;; copyright notice and this notice must be preserved on all copies. | |
22 ;;; | |
23 (provide 'motion) | |
24 (require 'button) | |
25 (require 'mouse) | |
26 ;;; | |
27 ;;; version tohandle mouse stuff | |
28 ;;; | |
29 ;;; [cjl] now use primitive epoch::move-button when possible. | |
30 ;;; | |
31 (defvar horizontal-drag-inc 5 "Number of columns to scroll when the pointer is to the left or right of the window") | |
32 (defvar vertical-drag-inc 2 "Number of lines to scroll when the pointer is above or below the edge of the window") | |
33 | |
34 (defvar mouse::downp nil "State variable for mouse dragging internals") | |
35 (defvar mouse::last-point -1 "Last location of a motion event") | |
36 | |
37 (make-variable-buffer-local 'drag-button) | |
38 (make-variable-buffer-local 'mouse-down-marker) | |
39 | |
40 (defvar motion::attribute (reserve-attribute) "Attribute for drag buttons") | |
41 (setq epoch::buttons-modify-buffer nil) | |
42 | |
43 (defvar motion::style nil "style used by drag buttons") | |
44 | |
45 ;; | |
46 ;; Set window-setup-hook to call motion::init(), which sets default | |
47 ;; style for button dragging | |
48 ;; | |
49 (epoch-add-setup-hook 'motion::init) | |
50 (defun motion::init () | |
51 (and (not motion::style) (setq motion::style (make-style))) | |
52 (set-style-foreground motion::style (foreground)) | |
53 (set-style-background motion::style (background)) | |
54 (set-style-underline motion::style (foreground)) | |
55 (set-attribute-style motion::attribute motion::style) | |
56 ;; enable the handler | |
57 (push-event 'motion 'motion::handler) | |
58 ;; set up hints on all the current screens | |
59 (dolist (s (screen-list t)) (epoch::set-motion-hints t s)) | |
60 ;; enable hints on future screens | |
61 (push '(motion-hints t) epoch::screen-properties) | |
62 ) | |
63 | |
64 (setq-default drag-button nil) | |
65 (setq-default mouse-down-marker nil) | |
66 | |
67 ;;; ------------------------------------------------------------------------ | |
68 (defun set-mouse-marker (&optional location) | |
69 (if (null mouse-down-marker) | |
70 (setq mouse-down-marker (make-marker)) | |
71 ) | |
72 (set-marker mouse-down-marker (or location (point))) | |
73 ) | |
74 ;;; -------------------------------------------------------------------------- | |
75 ;;; generic arg is a list of ( POINT BUFFER WINDOW SCREEN ) | |
76 ;;; | |
77 (defun end-mouse-drag (arg) | |
78 (setq mouse::last-point -1) ;always do this cleanup | |
79 (when mouse::downp | |
80 (setq mouse::downp nil) | |
81 (mouse::copy-button drag-button) | |
82 (if (buttonp drag-button) | |
83 (if (<= (point) (button-start drag-button)) | |
84 (progn | |
85 (push-mark (button-end drag-button) t) | |
86 (goto-char (button-start drag-button)) | |
87 ) | |
88 ;; ELSE point is past drag button start | |
89 (progn | |
90 (push-mark (button-start drag-button) t) | |
91 (goto-char (button-end drag-button)) | |
92 ) | |
93 ) | |
94 ) | |
95 ) | |
96 ) | |
97 | |
98 (defun start-mouse-drag (arg) | |
99 (when arg | |
100 (setq mouse::downp 'start) | |
101 (mouse::set-point arg) | |
102 (set-mouse-marker) | |
103 (setq mouse::last-point (point)) | |
104 (if drag-button | |
105 (progn (delete-button drag-button) (setq drag-button nil) ) | |
106 ) | |
107 ) | |
108 ) | |
109 | |
110 (defun extend-mouse-drag (arg) | |
111 (setq mouse::downp 'extend) | |
112 (let | |
113 ( | |
114 (m1 (and drag-button (button-start drag-button))) | |
115 (m2 (and drag-button (button-end drag-button))) | |
116 (spot (car arg)) ;point of the mouse click. | |
117 ) | |
118 (if (null m1) (setq m1 0)) | |
119 (if (null m2) (setq m2 0)) | |
120 (cond | |
121 ((or (null drag-button) (null mouse-down-marker)) | |
122 (setq drag-button (add-button (point) spot motion::attribute) ) | |
123 (set-mouse-marker) | |
124 ) | |
125 ((<= spot m1) | |
126 (setq drag-button (move-button drag-button spot m2) ) | |
127 (set-mouse-marker m2) | |
128 ) | |
129 ((>= spot m2) | |
130 (setq drag-button (move-button drag-button m1 spot) ) | |
131 (set-mouse-marker m1) | |
132 ) | |
133 ((<= mouse-down-marker spot) | |
134 (setq drag-button (move-button drag-button m1 spot) ) | |
135 (set-mouse-marker m1) | |
136 ) | |
137 (t | |
138 (setq drag-button (move-button drag-button spot m2) ) | |
139 (set-mouse-marker m2) | |
140 ) | |
141 ) | |
142 (epoch::redisplay-screen) | |
143 (setq mouse::last-point (point)) | |
144 ) | |
145 ) | |
146 | |
147 ;;; ------------------------------------------------------------------------ | |
148 ;;; Define the handler | |
149 ;;; | |
150 (defun motion::handler (type value scr) | |
151 (if (null mouse-down-marker) (set-mouse-marker)) | |
152 (if (and (boundp 'mouse::downp) mouse::downp) | |
153 (mouse-sweep-update) | |
154 ) | |
155 ) | |
156 ;;; | |
157 (defun mouse-sweep-update() | |
158 (let* | |
159 (x y pos drag-m1 drag-m2 pnt orig-m1 orig-m2 | |
160 (out-of-bounds t) | |
161 (epoch::event-handler-abort nil) | |
162 (w (selected-window)) | |
163 (w-edges (window-edges w)) | |
164 (left (car w-edges)) | |
165 (top (elt w-edges 1)) | |
166 (right (- (elt w-edges 2) (+ 2 left))) | |
167 (bottom (- (elt w-edges 3) (+ 2 top))) | |
168 ever | |
169 ) | |
170 (if drag-button | |
171 (progn (setq orig-m1 (or (button-start drag-button) -1)) | |
172 (setq orig-m2 (or (button-end drag-button) -1))) | |
173 (progn (setq orig-m1 mouse-down-marker) | |
174 (setq orig-m2 (point)))) | |
175 (while | |
176 (and | |
177 out-of-bounds | |
178 (setq pos (query-mouse)) | |
179 (/= 0 (logand mouse-any-mask (elt pos 2))) | |
180 ) | |
181 ;;convert to window relative co-ordinates | |
182 (setq x (- (car pos) left)) | |
183 (setq y (- (elt pos 1) top)) | |
184 (setq out-of-bounds | |
185 (not (and (<= 0 y) (<= y bottom) (<= 0 x) (<= x right))) | |
186 ) | |
187 | |
188 ;; scrolling conditions | |
189 (condition-case errno | |
190 (progn | |
191 (if (< y 0) (scroll-down vertical-drag-inc)) | |
192 (if (> y bottom) (scroll-up vertical-drag-inc)) | |
193 ) | |
194 (error ) ;nothing, just catch it | |
195 ) | |
196 (if (< x 0) (scroll-right horizontal-drag-inc)) | |
197 (if (> x right) (scroll-left horizontal-drag-inc)) | |
198 (setq y (max 0 (min bottom y))) | |
199 (setq x (max 0 (min right x))) | |
200 | |
201 (setq pnt (car (epoch::coords-to-point (+ x left) (+ y top)))) | |
202 (when (/= mouse::last-point pnt) | |
203 (if (> mouse-down-marker pnt) | |
204 (progn | |
205 (setq drag-m1 pnt) | |
206 (setq drag-m2 (marker-position mouse-down-marker)) | |
207 ) | |
208 (progn | |
209 (setq drag-m1 (marker-position mouse-down-marker)) | |
210 (setq drag-m2 pnt) | |
211 ) | |
212 ) | |
213 ;; don't move for trivial reasons | |
214 (when (or ever (/= drag-m1 orig-m1) (/= drag-m2 orig-m2)) | |
215 (setq ever t) | |
216 (if (not drag-button) | |
217 (setq drag-button | |
218 (add-button mouse-down-marker | |
219 (point) motion::attribute ) | |
220 ) | |
221 ) | |
222 (move-button drag-button drag-m1 drag-m2) | |
223 (epoch::redisplay-screen) | |
224 ) | |
225 ) | |
226 (setq mouse::last-point pnt) | |
227 ) | |
228 ) | |
229 ) | |
230 ;;; ------------------------------------------------------------------------ | |
231 ;;; Code for selecting lines using motion events. Assumes that the line is | |
232 ;;; left unmarked on button up | |
233 ;;; | |
234 (defvar mouse::line-button nil "Button for selected line") | |
235 ;;; | |
236 (defun mouse-select-line-start (arg) | |
237 (mouse::set-point arg) ;go there | |
238 (setq mouse::last-point (point)) | |
239 (let ( bol ) | |
240 (save-excursion | |
241 (beginning-of-line) | |
242 (setq bol (point)) | |
243 (end-of-line) | |
244 (setq mouse::line-button (add-button bol (point) motion::attribute)) | |
245 ) | |
246 ) | |
247 (push-event 'motion 'mouse-select-line-update) | |
248 ) | |
249 ;;; | |
250 (defun mouse-select-line-end (arg) | |
251 (setq mouse::last-point -1) | |
252 (when mouse::line-button (delete-button mouse::line-button)) | |
253 (pop-event 'motion) | |
254 ) | |
255 ;;; | |
256 (defun mouse-select-line-update (type value scr) | |
257 (let* | |
258 ( | |
259 y | |
260 pos | |
261 bol | |
262 (out-of-bounds t) | |
263 (epoch::event-handler-abort nil) | |
264 (w-edges (window-edges (selected-window))) | |
265 (top (elt w-edges 1)) | |
266 (bottom (- (elt w-edges 3) (+ 2 top))) | |
267 max-vscroll | |
268 ) | |
269 (while | |
270 (and | |
271 out-of-bounds | |
272 (setq pos (query-mouse)) | |
273 (/= 0 (logand mouse-any-mask (elt pos 2))) | |
274 ) | |
275 ;;convert to window relative co-ordinates | |
276 (setq y (- (elt pos 1) top)) | |
277 (setq out-of-bounds (not (and (<= 0 y) (<= y bottom)))) | |
278 | |
279 ;; Scrolling hard, because of possibly shrink-wrapped windows. | |
280 ;; set max-vscroll to be the most we could scroll down and not have | |
281 ;; empty lines at the bottom | |
282 (save-excursion | |
283 (move-to-window-line bottom) ;go to the last line in the window | |
284 (setq max-vscroll | |
285 (- vertical-drag-inc (forward-line vertical-drag-inc)) | |
286 ) | |
287 (if (and (> max-vscroll 0) (eobp) (= 0 (current-column))) | |
288 (decf max-vscroll) | |
289 ) | |
290 ) | |
291 (condition-case errno | |
292 (progn | |
293 (if (< y 0) (scroll-down vertical-drag-inc)) | |
294 (if (> y bottom) (scroll-up (min max-vscroll vertical-drag-inc))) | |
295 ) | |
296 ;; CONDITIONS | |
297 (error) ;nothing, just want to catch it | |
298 ) | |
299 (setq y (max 0 (min bottom y))) | |
300 | |
301 ;;move to the new point | |
302 (move-to-window-line y) | |
303 (beginning-of-line) (setq bol (point)) | |
304 (end-of-line) | |
305 (when (/= mouse::last-point (point)) | |
306 (move-button mouse::line-button bol (point)) | |
307 (epoch::redisplay-screen) | |
308 ) | |
309 (setq mouse::last-point (point)) | |
310 ) | |
311 ) | |
312 ) | |
313 ;;; -------------------------------------------------------------------------- | |
314 ;;; install all our variouse handlers | |
315 (global-set-mouse mouse-left mouse-down 'start-mouse-drag) | |
316 (global-set-mouse mouse-left mouse-up 'end-mouse-drag) | |
317 (global-set-mouse mouse-right mouse-down 'extend-mouse-drag) | |
318 (global-set-mouse mouse-right mouse-up 'end-mouse-drag) | |
319 (global-set-mouse mouse-middle mouse-down 'mouse::paste-cut-buffer) |