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)