X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: fbb9d,9f7f5f518828cbc6 X-Google-Attributes: gidfbb9d,public X-Google-ArrivalTime: 1995-02-01 10:25:30 PST Path: nntp.gmd.de!Germany.EU.net!EU.net!howland.reston.ans.net!news.sprintlink.net!sashimi.wwa.com!not-for-mail From: flee@cse.psu.edu (Felix Lee) Newsgroups: rec.arts.ascii Subject: Code: Emacs-mouse drawing code Date: 1 Feb 1995 12:25:30 -0600 Organization: Penn State Comp Sci & Eng Lines: 184 Sender: boba@gagme.wwa.com Approved: boba@wwa.com Message-ID: <3gojmq$614@gagme.wwa.com> References: <3gnbll$1rs@gagme.wwa.com> NNTP-Posting-Host: gagme.wwa.com > Could someone repost the code to drawing ascii with emacs and the mouse? ;;;; $Id: mdraw.el,v 1.10 1994/08/30 14:15:21 flee Exp $ ;;;; Backpointer: ftp.cse.psu.edu:/pub/flee/mdraw.el ;;; Brush drawing with the mouse. ;;; 1. Byte-compile and load this file. ;;; 2. Edit a buffer and enter picture mode. (M-x edit-picture) ;;; 3. Hold shift and a mouse button to draw with a brush. ;;; By default: ;;; button 1 is a 1x1 "X" brush ;;; button 2 is a 2x2 diamond-pattern brush ;;; button 3 is a 1x2 " " brush (ie, an eraser) ;;; The brushes are actually rectangles stored in registers 1, 2, and 3. ;;; So, you can set a brush by selecting a rectangle of text and using ;;; copy-rectangle-to-register ("C-x r r") to the appropriate register. ;;; As a shortcut, you can use "C-c 1", "C-c 2", etc. ;;; XXX could use some better default brushes.. (require 'picture) (provide 'mdraw) (define-key picture-mode-map [S-down-mouse-1] 'flee/draw-at-mouse-1) (define-key picture-mode-map [S-down-mouse-2] 'flee/draw-at-mouse-2) (define-key picture-mode-map [S-down-mouse-3] 'flee/draw-at-mouse-3) (define-key picture-mode-map "\C-c1" 'flee/shortcut-to-register-1) (define-key picture-mode-map "\C-c2" 'flee/shortcut-to-register-2) (define-key picture-mode-map "\C-c3" 'flee/shortcut-to-register-3) ;;; Set the default brushes. (defvar flee/default-brush-1 '("X")) (defvar flee/default-brush-2 '("/\\" "\\/")) (defvar flee/default-brush-3 '(" ")) (or (get-register ?1) (set-register ?1 flee/default-brush-1)) (or (get-register ?2) (set-register ?2 flee/default-brush-2)) (or (get-register ?3) (set-register ?3 flee/default-brush-3)) (defun flee/draw-at-mouse-1 () (interactive) (flee/internal-draw-at-mouse (flee/get-register-rectangle ?1))) (defun flee/draw-at-mouse-2 () (interactive) (flee/internal-draw-at-mouse (flee/get-register-rectangle ?2))) (defun flee/draw-at-mouse-3 () (interactive) (flee/internal-draw-at-mouse (flee/get-register-rectangle ?3))) (defun flee/internal-draw-at-mouse (rectangle) (let ( (event nil) (position nil) (starting-window (selected-window)) ) (track-mouse (while (mouse-movement-p (setq event (read-event))) (setq position (event-start event)) ;; Is position within the text area of the drawing window? (if (and (numberp (posn-point position)) (eq (posn-window position) starting-window)) (progn (flee/move-to-position position) (save-excursion (flee/insert-rectangle rectangle)))) )) )) (defun flee/get-register-rectangle (name) ;; Returns the register NAME as a rectangle. Signals an error if it ;; isn't a rectangle. (let ( (value (get-register name)) ) (cond ;; If it's a cons, emacs vaguely guarantees it's a rectangle. ( (consp value) value) ;; XXX Could try coercing a string to a rectangle, but a ;; multi-line string would have to be broken up or else the ;; result is garbage. ( t (error "Register %c is not a rectangle." name) ) ))) (defun flee/move-to-position (position) "Move to POSITION, which is an event position, inserting space and newlines if necessary." ;; XXX This assumes that truncate-lines is t. (goto-char (window-start)) (let ( (row (cdr (posn-col-row position))) (indent-tabs-mode nil) ) (setq row (forward-line row)) (or (bolp) (insert ?\n)) (while (< 0 row) (insert ?\n) (setq row (1- row))) (move-to-column (+ (car (posn-col-row position)) (window-hscroll)) 'force) )) ;; Slightly different version than in picture-mode.el. Mainly, never ;; uses tabs. (defun move-to-column-force (column) "Move to column COLUMN in current line. Differs from `move-to-column' in that it creates or modifies whitespace if necessary to attain exactly the specified column." (let ( (indent-tabs-mode nil) ) (move-to-column (max 0 column) 'force))) (defun flee/insert-rectangle (rectangle) "Overlay RECTANGLE with upper left corner at point." (let ( (indent-tabs-mode nil) (width nil) ) (while rectangle (setq width (length (car rectangle))) (picture-forward-column width) (delete-char (- width)) (insert (car rectangle)) (forward-char (- width)) (picture-move-down 1) (setq rectangle (cdr rectangle))) )) ;;; for debugging (define-key picture-mode-map [C-S-down-mouse-1] 'flee/track-at-mouse) (defun flee/track-at-mouse () (interactive) (let ( (event nil) (position nil) (window (selected-window)) ) (track-mouse (while (mouse-movement-p (setq event (read-event))) (setq position (event-start event)) (message "coord: %s point: %s" (posn-col-row position) (posn-point position)) )) )) ;;; obsolete, but a little faster than painting with " ", because it's ;;; specialcased. (defun flee/erase-at-mouse () (interactive) (let ( (event nil) (position nil) (window (selected-window)) ) (track-mouse (while (mouse-movement-p (setq event (read-event))) (setq position (event-start event)) (if (and (eq window (posn-window position)) (numberp (posn-point position))) (progn (flee/move-to-position position) (if (not (eolp)) (save-excursion (delete-char 1) (insert ? ))))) )) )) (defun flee/shortcut-to-register-1 () (interactive) (copy-rectangle-to-register ?1 (point) (mark) )) (defun flee/shortcut-to-register-2 () (interactive) (copy-rectangle-to-register ?2 (point) (mark))) (defun flee/shortcut-to-register-3 () (interactive) (copy-rectangle-to-register ?3 (point) (mark)))