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) |
