org-pic.el 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. ;;; Modified picture mode with extra functions and bindings
  2. ;; BUGS: The mouse stuff does not really work reliable
  3. ;; What it really needs:
  4. ;; Picture areas should always start with ":"
  5. ;; Automatic recognize the region and use the right commands, also
  6. ;; extending the region.
  7. ;; Picture mode
  8. ;; ------------
  9. ;; Simple ASCII drawings can be made in picture-mode. You can toggle
  10. ;; picture mode with `C-c C-c' (unless you have turned it off with the
  11. ;; variable `org-enable-picture-mode'). See the picture-mode
  12. ;; documentation for details. Some additional bindings are provided by
  13. ;; org-mode:
  14. ;;
  15. ;; M-up M-7 M-8 M-9 \
  16. ;; M-left M-right M-u M-o } Draw lines in keypad-like directions
  17. ;; M-down M-j M-k M-o /
  18. ;;
  19. ;; M-- Draw line from mark to point, set mark at end.
  20. ;; S-mouse1 Freehand drawing with the mouse.
  21. ;;
  22. (defcustom org-enable-picture-mode t
  23. "Non-nil means, C-c C-c switches to picture mode.
  24. When nil, this command is disabled."
  25. :group 'org
  26. :type 'boolean)
  27. (defun org-edit-picture ()
  28. "Switch to picture mode and save the value of `transient-mark-mode'.
  29. Turn transient-mark-mode off while in picture-mode."
  30. (interactive)
  31. (if (not org-enable-picture-mode)
  32. (error
  33. "Set variable `org-enable-picture-mode' to allow picture-mode."))
  34. ;; FIXME: This is not XEmacs compatible yet
  35. (set (make-local-variable 'org-transient-mark-mode)
  36. transient-mark-mode)
  37. (set (make-local-variable 'org-cursor-color)
  38. (frame-parameter nil 'cursor-color))
  39. (set (make-local-variable 'transient-mark-mode) nil)
  40. (set-cursor-color "red")
  41. (picture-mode)
  42. (message (substitute-command-keys
  43. "Type \\[org-picture-mode-exit] in this buffer to return it to Org mode.")))
  44. (defun org-picture-mode-exit (&optional arg)
  45. "Turn off picture mode and restore `transient-mark-mode'."
  46. (interactive "P")
  47. (if (local-variable-p 'org-transient-mark-mode)
  48. (setq transient-mark-mode org-transient-mark-mode))
  49. (if (local-variable-p 'org-cursor-color)
  50. (set-cursor-color org-cursor-color))
  51. (if (fboundp 'deactivate-mark) (deactivate-mark))
  52. (if (fboundp 'zmacs-deactivate-region) (zmacs-deactivate-region))
  53. (picture-mode-exit))
  54. (eval-after-load "picture"
  55. ' (progn
  56. (define-key picture-mode-map [(meta left)] (lambda (arg) (interactive "p") (org-picture-draw 4 arg)))
  57. (define-key picture-mode-map [(meta right)] (lambda (arg) (interactive "p") (org-picture-draw 6 arg)))
  58. (define-key picture-mode-map [(meta up)] (lambda (arg) (interactive "p") (org-picture-draw 8 arg)))
  59. (define-key picture-mode-map [(meta down)] (lambda (arg) (interactive "p") (org-picture-draw 2 arg)))
  60. (define-key picture-mode-map [(meta shift left)] (lambda (arg) (interactive "p") (org-picture-draw 7 arg)))
  61. (define-key picture-mode-map [(meta shift right)] (lambda (arg) (interactive "p") (org-picture-draw 3 arg)))
  62. (define-key picture-mode-map [(meta shift up)] (lambda (arg) (interactive "p") (org-picture-draw 9 arg)))
  63. (define-key picture-mode-map [(meta shift down)] (lambda (arg) (interactive "p") (org-picture-draw 1 arg)))
  64. (define-key picture-mode-map [(meta ?j)] (lambda (arg) (interactive "p") (org-picture-draw 1 arg)))
  65. (define-key picture-mode-map [(meta ?k)] (lambda (arg) (interactive "p") (org-picture-draw 2 arg)))
  66. (define-key picture-mode-map [(meta ?l)] (lambda (arg) (interactive "p") (org-picture-draw 3 arg)))
  67. (define-key picture-mode-map [(meta ?u)] (lambda (arg) (interactive "p") (org-picture-draw 4 arg)))
  68. (define-key picture-mode-map [(meta ?o)] (lambda (arg) (interactive "p") (org-picture-draw 6 arg)))
  69. (define-key picture-mode-map [(meta ?7)] (lambda (arg) (interactive "p") (org-picture-draw 7 arg)))
  70. (define-key picture-mode-map [(meta ?8)] (lambda (arg) (interactive "p") (org-picture-draw 8 arg)))
  71. (define-key picture-mode-map [(meta ?9)] (lambda (arg) (interactive "p") (org-picture-draw 9 arg)))
  72. (define-key picture-mode-map [(meta ?-)] 'org-picture-draw-line)
  73. (define-key picture-mode-map [mouse-2] 'org-picture-mouse-line-to-here)
  74. (define-key picture-mode-map [mouse-1] 'org-picture-mouse-set-point)
  75. (define-key picture-mode-map [(shift down-mouse-1)] 'org-picture-draw-with-mouse)
  76. (define-key picture-mode-map "\C-c\C-c" 'org-picture-mode-exit)))
  77. (defun org-picture-draw (dir arg)
  78. "Draw ARG character into the direction given by DIR."
  79. (cond
  80. ((equal dir 1)
  81. (picture-movement-sw)
  82. (setq last-command-event ?/) (picture-self-insert arg))
  83. ((equal dir 2)
  84. (picture-movement-down)
  85. (setq last-command-event ?|) (picture-self-insert arg))
  86. ((equal dir 3)
  87. (picture-movement-se)
  88. (setq last-command-event ?\\) (picture-self-insert arg))
  89. ((equal dir 4)
  90. (picture-movement-left)
  91. (setq last-command-event ?-) (picture-self-insert arg))
  92. ((equal dir 5))
  93. ((equal dir 6)
  94. (picture-movement-right)
  95. (setq last-command-event ?-) (picture-self-insert arg))
  96. ((equal dir 7)
  97. (picture-movement-nw)
  98. (setq last-command-event ?\\) (picture-self-insert arg))
  99. ((equal dir 8)
  100. (picture-movement-up)
  101. (setq last-command-event ?|) (picture-self-insert arg))
  102. ((equal dir 9)
  103. (picture-movement-ne)
  104. (setq last-command-event ?/) (picture-self-insert arg)))
  105. (picture-movement-right))
  106. (defun org-picture-draw-line (&optional beg end)
  107. "Draw a line from mark to point."
  108. (interactive)
  109. (unless (and beg end)
  110. (setq beg (mark 'force)
  111. end (point)))
  112. (let (x1 x2 y1 y2 n i Dx Dy dx dy char lp x y x1a y1a lastx lasty)
  113. (goto-char beg)
  114. (setq x1 (current-column) y1 (count-lines (point-min) (point)))
  115. (if (bolp) (setq y1 (1+ y1)))
  116. (goto-char end)
  117. (setq x2 (current-column) y2 (count-lines (point-min) (point)))
  118. (if (bolp) (setq y2 (1+ y2)))
  119. (setq Dx (- x2 x1) Dy (- y2 y1)
  120. n (+ (abs Dx) (abs Dy))
  121. n (sqrt (+ (* Dx Dx) (* Dy Dy)))
  122. n (max (abs Dx) (abs Dy))
  123. n (max (abs Dx) (abs Dy))
  124. dx (/ (float Dx) (float n)) dy (/ (float Dy) (float n)))
  125. (setq x1a (floor (+ x1 (* 1. dx) .5))
  126. y1a (floor (+ y1 (* 1. dy) .5)))
  127. ;; Do the loop
  128. (setq i -1)
  129. (setq lastx x1a lasty y1a)
  130. (while (< i n)
  131. (setq i (1+ i)
  132. x (floor (+ x1 (* (float i) dx) .5))
  133. y (floor (+ y1 (* (float i) dy) .5)))
  134. (setq char (cond ((= lastx x) ?|) ((= lasty y) ?-)
  135. ((> (* (- x lastx) (- y lasty)) 0) ?\\)
  136. (t ?/))
  137. lastx x lasty y)
  138. (goto-line y)
  139. (move-to-column x t)
  140. (setq last-command-event char)
  141. (setq lp (point))
  142. (picture-self-insert 1))
  143. (goto-char lp)
  144. (set-mark lp)))
  145. (defun org-picture-mouse-line-to-here (ev)
  146. "Draw a line from point to the click position."
  147. (interactive "e")
  148. (let* ((beg (move-marker (make-marker) (point))))
  149. (org-picture-mouse-set-point ev)
  150. (org-picture-draw-line beg (point))
  151. (move-marker beg nil)))
  152. ;; Draw with the mouse
  153. (defun org-picture-mouse-set-point (ev)
  154. "Mouse-set-point, but force position."
  155. (interactive "e")
  156. (let* ((colrow (posn-col-row (event-end ev)))
  157. (col (car colrow)) (line (cdr colrow))
  158. (realline (1+ (+ (count-lines (point-min) (window-start)) line))))
  159. (goto-line realline)
  160. (while (and (eobp)
  161. (not (> (count-lines (point-min) (point-max)) realline)))
  162. (newline))
  163. (goto-line realline)
  164. (move-to-column col t)))
  165. (defun org-picture-draw-with-mouse (ev)
  166. "Use the mouse like a brush and paint stars where it goes."
  167. (interactive "e")
  168. (let (lastcr cr)
  169. (track-mouse
  170. (catch 'exit
  171. (while t
  172. (setq e (read-event))
  173. (if (not (eq (car e) 'mouse-movement)) (throw 'exit nil))
  174. (setq cr (posn-col-row (event-end e)))
  175. (when (not (equal cr lastcr))
  176. (setq lastcr cr)
  177. (org-picture-mouse-set-point e)
  178. (setq last-command-event ?*)
  179. (save-excursion
  180. (picture-self-insert 1))))))))