PageRenderTime 52ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 0ms

/src/textdrawing.sc

https://bitbucket.org/bunny351/ezd
Scala | 730 lines | 691 code | 39 blank | 0 comment | 8 complexity | 224c5c8bebed0a0ba13b86a1673ff2df MD5 | raw file
  1. ;;; ezd - easy drawing for X11 displays.
  2. ;;;
  3. ;;; The procedures in this module implement TEXT-DRAWINGs. A TEXT-DRAWING is
  4. ;;; a drawing that displays a document. Like any other drawing, it may be
  5. ;;; displayed in multiple windows.
  6. ;* Copyright 1990-1993 Digital Equipment Corporation
  7. ;* All Rights Reserved
  8. ;*
  9. ;* Permission to use, copy, and modify this software and its documentation is
  10. ;* hereby granted only under the following terms and conditions. Both the
  11. ;* above copyright notice and this permission notice must appear in all copies
  12. ;* of the software, derivative works or modified versions, and any portions
  13. ;* thereof, and both notices must appear in supporting documentation.
  14. ;*
  15. ;* Users of this software agree to the terms and conditions set forth herein,
  16. ;* and hereby grant back to Digital a non-exclusive, unrestricted, royalty-free
  17. ;* right and license under any changes, enhancements or extensions made to the
  18. ;* core functions of the software, including but not limited to those affording
  19. ;* compatibility with other hardware or software environments, but excluding
  20. ;* applications which incorporate this software. Users further agree to use
  21. ;* their best efforts to return to Digital any such changes, enhancements or
  22. ;* extensions that they make and inform Digital of noteworthy uses of this
  23. ;* software. Correspondence should be provided to Digital at:
  24. ;*
  25. ;* Director of Licensing
  26. ;* Western Research Laboratory
  27. ;* Digital Equipment Corporation
  28. ;* 250 University Avenue
  29. ;* Palo Alto, California 94301
  30. ;*
  31. ;* This software may be distributed (but not offered for sale or transferred
  32. ;* for compensation) to third parties, provided such third parties agree to
  33. ;* abide by the terms and conditions of this notice.
  34. ;*
  35. ;* THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
  36. ;* WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
  37. ;* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
  38. ;* CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
  39. ;* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
  40. ;* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
  41. ;* ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  42. ;* SOFTWARE.
  43. (module textdrawing (with jtextree mouseedit ezd))
  44. (include "struct.sch")
  45. (include "match.sch")
  46. (include "jtextree.sch")
  47. (include "mouseedit.sch")
  48. (include "commands.sch")
  49. (include "ginfo.sch")
  50. (include "ezd.sch")
  51. (include "display.sch")
  52. (include "drawing.sch")
  53. (include "window.sch")
  54. (include "view.sch")
  55. (include "events.sch")
  56. (include "interact.sch")
  57. (include "xternal.sch")
  58. ;;; The basic data structure used is a TEXT-DRAWING containing the following
  59. ;;; fields:
  60. ;;;
  61. ;;; NAME name of the drawing
  62. ;;; WIDTH width of a text line in pixels
  63. ;;; TEXT-COLOR color to draw text in
  64. ;;; TEXT-STIPPLE stipple to draw text with
  65. ;;; FONT text font to use
  66. ;;; CUSOR-COLOR color to draw the cursor in
  67. ;;; HIGHLIGHT-COLOR color to draw the highlighted area in
  68. ;;; HIGHLIGHT-STIPPLE stipple to draw the highlight in
  69. ;;; OPTIONS list of any of UNJUSTIFIED or READ-ONLY.
  70. ;;; BEGIN-HIGHLIGHT marker for the begining of the highlight
  71. ;;; END-HIGHLIGHT marker for the end of the highlight
  72. ;;; DXFS font's xfontstruct
  73. ;;; ROW-HEIGHT height of each row of text
  74. ;;; CURSOR-FONT font to display the "^" cursor in
  75. ;;; CURSOR marker for the cursor
  76. ;;; TEXT-DELTA-X delta x from origin position to draw text
  77. ;;; CURSOR-DELTA-Y delta y from character position to draw cursor
  78. ;;; VIEWS list of triples of window, first and last lines
  79. ;;; VISIBLE-LINES ordered list of visible line ranges, where
  80. ;;; each range is a list of first and last lines
  81. ;;; JTEXTREE JTEXTREE that holds the text
  82. (define-structure TEXT-DRAWING
  83. name
  84. width
  85. text-color
  86. text-stipple
  87. font
  88. cursor-color
  89. highlight-color
  90. highlight-stipple
  91. options
  92. (begin-highlight (make-marker 'begin 0 -1))
  93. (end-highlight (make-marker 'end 0 -1))
  94. (dxfs (display-font->xfontstruct *display* font))
  95. (row-height (+ (xfontstruct-ascent (text-drawing-dxfs self))
  96. (xfontstruct-descent (text-drawing-dxfs self))))
  97. (cursor-font "8x13bold")
  98. (cursor (make-marker 'cursor 0 -1))
  99. (text-delta-x (let* ((fs (display-font->xfontstruct *display*
  100. (text-drawing-cursor-font self)))
  101. (cs (cadddr (xtextextents fs "^" 1))))
  102. (quotient (xcharstruct-width cs) 2)))
  103. (cursor-delta-y (xfontstruct-ascent (text-drawing-dxfs self)))
  104. (views '())
  105. (visible-lines '())
  106. (jtextree (let ((jtextree (make-jtextree)))
  107. (text-drawing-width! self width)
  108. (jtextree-width! jtextree
  109. (and (not (memq 'UNJUSTIFIED options))
  110. (- width (* (text-drawing-text-delta-x self) 2))))
  111. (jtextree-font! jtextree (text-drawing-dxfs self))
  112. (if (not text-color)
  113. (text-drawing-text-color! self 'black))
  114. (if (not highlight-color)
  115. (text-drawing-highlight-color! self 'gray95))
  116. (jtextree-markers! jtextree
  117. (list (text-drawing-begin-highlight self)
  118. (text-drawing-end-highlight self)
  119. (text-drawing-cursor self)))
  120. (ezd '(save-drawing)
  121. `(set-drawing ,name)
  122. '(object text-drawing
  123. (fill-rectangle 0 0 1000000 1000000 clear))
  124. '(object highlight)
  125. '(object cursor)
  126. `(when * visible
  127. ,(lambda () (text-drawing-visible self)))
  128. `(when * set-attributes
  129. ,(lambda () (text-drawing-set-attributes self)))
  130. `(when * get-attributes
  131. ,(lambda () (text-drawing-get-attributes self)))
  132. '(restore-drawing))
  133. (mouse-edit-init name 'text-drawing options)
  134. jtextree)))
  135. ;;; Each view of a TEXT-DRAWING is represented by a TEXT-VIEW record with the
  136. ;;; following fields.
  137. ;;;
  138. ;;; WINDOW window-name
  139. ;;; X overlay position in pixels in the window
  140. ;;; Y
  141. ;;; WIDTH
  142. ;;; HEIGHT
  143. ;;; FIRST first line visible
  144. ;;; LAST last line visible
  145. ;;; SLIDER name of the slider drawing associated with the view
  146. (define-structure TEXT-VIEW
  147. window
  148. x
  149. y
  150. width
  151. height
  152. first
  153. last
  154. (slider #f))
  155. (define-in-line-structure-access TEXT-VIEW window x y width height first last
  156. slider)
  157. ;;; A TEXT-DRAWING is created by the following ezd command.
  158. (define (TEXT-DRAWING-OPTION? x) (memq x '(read-only unjustified)))
  159. (define-ezd-command
  160. `(text-drawing ,symbol? ,positive-number? (optional POINTS)
  161. (optional ,color?) (optional ,stipple?) (optional ,string?)
  162. (optional ,color?) (optional ,color?) (optional ,stipple?)
  163. (repeat ,text-drawing-option?))
  164. "(text-drawing name width [points] [color] [stipple] [\"font\"] [cursor-color [highlight-color] [highlight-stipple]] [READ-ONLY] [UNJUSTIFIED])"
  165. (lambda (name width points color stipple font cursor highlight
  166. highlight-stipple options)
  167. (make-text-drawing name (if points (points->pixels width) width)
  168. color stipple font cursor highlight highlight-stipple
  169. options)))
  170. ;;; When a portion of the TEXT-DRAWING is displayed in a view, ezd notifies
  171. ;;; the drawing by sending it a VISIBLE event. Origin changes are also visible
  172. ;;; here and will result in changes to any sliders as needed.
  173. (define (TEXT-DRAWING-VISIBLE self)
  174. (let ((row-height (text-drawing-row-height self))
  175. (jt (text-drawing-jtextree self)))
  176. ;;; Turn the current event into a text-view iff it's not null.
  177. (define (MAKE-VIEW old)
  178. (let ((x (list-ref *user-event-misc* 0))
  179. (y (list-ref *user-event-misc* 1))
  180. (width (list-ref *user-event-misc* 2))
  181. (height (list-ref *user-event-misc* 3)))
  182. (if y
  183. (let ((first (quotient (+ y (- row-height 1))
  184. row-height))
  185. (last (quotient
  186. (- (+ y height) (- row-height 1))
  187. row-height)))
  188. (if (>= last first)
  189. (if old
  190. (let ((slider (text-view-slider old))
  191. (was-range (- (text-view-last
  192. old)
  193. (text-view-first
  194. old)
  195. -1))
  196. (is-range (- last first -1)))
  197. (text-view-width! old width)
  198. (text-view-height! old height)
  199. (text-view-first! old first)
  200. (text-view-last! old last)
  201. (if (and slider
  202. (not (eq? was-range
  203. is-range)))
  204. (ezd `(set-attributes
  205. ,slider
  206. slider
  207. (value ,first)
  208. (indicator-size
  209. ,is-range))))
  210. old)
  211. (make-text-view *user-event-window*
  212. x y width height first last))
  213. #f))
  214. (begin (if (and old (text-view-slider old))
  215. (ezd `(delete-view ,*user-event-window*
  216. ,(text-view-slider old))))
  217. #f))))
  218. ;;; Correct the views list.
  219. (text-drawing-views! self
  220. (let loop ((views (text-drawing-views self)))
  221. (if (pair? views)
  222. (if (eq? *user-event-window*
  223. (text-view-window (car views)))
  224. (let ((view (make-view (car views))))
  225. (if view
  226. (cons view (cdr views))
  227. (loop (cdr views))))
  228. (cons (car views) (loop (cdr views))))
  229. (let ((view (make-view #f)))
  230. (if view (list view) '())))))
  231. (text-drawing-compute-visible-lines self)))
  232. ;;; When a view is added or deleted, or a view is scrolled, the following
  233. ;;; procedure is called to recompute (and redraw) the lines visible in the
  234. ;;; drawing.
  235. (define (TEXT-DRAWING-COMPUTE-VISIBLE-LINES self)
  236. (let ((was-visible (text-drawing-visible-lines self))
  237. (row-height (text-drawing-row-height self)))
  238. ;;; Deleted lines from the drawing.
  239. (define (DELETED-LINES f l)
  240. (ezd '(save-drawing)
  241. `(set-drawing ,(text-drawing-name self)))
  242. (do ((i f (+ i 1)))
  243. ((> i l))
  244. (ezd `(object ,(string->symbol (format "T~s" i)))))
  245. (ezd '(restore-drawing)))
  246. ;;; 1. Recompute the visible lines.
  247. (text-drawing-visible-lines! self
  248. (let loop ((views (text-drawing-views self)) (lines '()))
  249. (if (pair? views)
  250. (loop (cdr views)
  251. (let loop ((first (text-view-first (car views)))
  252. (last (text-view-last (car views)))
  253. (lines lines))
  254. (if (pair? lines)
  255. (let ((fl (caar lines))
  256. (ll (cadar lines)))
  257. (cond ((< last fl)
  258. (cons `(,first ,last) lines))
  259. ((> first ll)
  260. (cons (car lines)
  261. (loop first last
  262. (cdr lines))))
  263. (else (loop (min first fl)
  264. (max last ll)
  265. (cdr lines)))))
  266. `((,first ,last)))))
  267. lines)))
  268. ;;; 2. Display newly visible lines, delete no longer visible lines.
  269. (let loop ((was was-visible) (is (text-drawing-visible-lines self)))
  270. (cond ((and (pair? was) (pair? is))
  271. (let ((was-f (caar was))
  272. (was-l (cadar was))
  273. (is-f (caar is))
  274. (is-l (cadar is)))
  275. (cond ((eq? was-f is-f)
  276. (cond ((< was-l is-l)
  277. (loop (cdr was)
  278. (cons `(,(+ was-l 1) ,is-l)
  279. (cdr is))))
  280. ((> was-l is-l)
  281. (loop (cons `(,(+ is-l 1) ,was-l)
  282. (cdr was))
  283. (cdr is)))
  284. (else (loop (cdr was) (cdr is)))))
  285. ((< was-l is-f)
  286. (deleted-lines was-f was-l)
  287. (loop (cdr was) is))
  288. ((< is-l was-f)
  289. (text-drawing-draw-lines self is-f is-l)
  290. (loop was (cdr is)))
  291. ((< was-f is-f)
  292. (loop `((,was-f ,(- is-f 1))
  293. (,is-f ,was-l)
  294. ,@(cdr was))
  295. is))
  296. (else (loop was
  297. `((,is-f ,(- was-f 1))
  298. (,was-f ,is-l)
  299. ,@(cdr is)))))))
  300. ((pair? is)
  301. (text-drawing-draw-lines self (caar is) (cadar is))
  302. (loop was (cdr is)))
  303. ((pair? was)
  304. (deleted-lines (caar was) (cadar was))
  305. (loop (cdr was) is))))))
  306. ;;; Lines of text existing in the document and visible in some view are drawn
  307. ;;; by the following procedure.
  308. (define (TEXT-DRAWING-DRAW-LINES self first last)
  309. (let ((row-height (text-drawing-row-height self))
  310. (xpad (text-drawing-text-delta-x self))
  311. (color (text-drawing-text-color self))
  312. (stipple (if (text-drawing-text-stipple self)
  313. (list (text-drawing-text-stipple self))
  314. '()))
  315. (font (if (text-drawing-font self)
  316. (list (text-drawing-font self))
  317. '()))
  318. (jt (text-drawing-jtextree self)))
  319. (ezd '(save-drawing)
  320. `(set-drawing ,(text-drawing-name self)))
  321. (let loop ((i first) (visible (text-drawing-visible-lines self)))
  322. (if (and (pair? visible) (<= i last))
  323. (let ((f (caar visible))
  324. (l (cadar visible)))
  325. (cond ((< i f) (loop f visible))
  326. ((> i l) (loop i (cdr visible)))
  327. (else (ezd `(object ,(string->symbol
  328. (format "T~s" i))
  329. (text ,xpad
  330. ,(* row-height i)
  331. ,(jtextree-expanded-text
  332. jt i)
  333. ,color
  334. ,@stipple
  335. ,@font)))
  336. (loop (+ i 1) visible))))))
  337. (ezd '(restore-drawing))))
  338. ;;; Information can be extracted from the TEXT-DRAWING object via ezd's
  339. ;;; attribute mechanism. The following attributes may be read:
  340. ;;;
  341. ;;; WIDTH width in pixels
  342. ;;; TEXT-COLOR
  343. ;;; TEXT-STIPPLE
  344. ;;; FONT
  345. ;;; CURSOR-COLOR
  346. ;;; HIGHLIGHT-COLOR
  347. ;;; HIGHLIGHT-STIPPLE
  348. ;;; OPTIONS
  349. ;;; ROW-HEIGHT height in pixels of each row
  350. ;;; CURSOR list of cursor line and char
  351. ;;; HIGHLIGHT line/character position or #f
  352. ;;; LINES # of lines in the document
  353. ;;; (TEXT-LINE x) contents of text line x
  354. ;;; (VIEW window) first, last & slider for the view or #f.
  355. ;;; (XY->LINE-CHAR-TEXT x y) convert drawing coordinate to line/character
  356. ;;; position and contents of line.
  357. ;;;
  358. ;;; ATTRIBUTES list of all attributes that can be either read or set.
  359. (define (TEXT-DRAWING-GET-ATTRIBUTES self)
  360. (map (lambda (a)
  361. (cond ((eq? a 'WIDTH)
  362. (text-drawing-width self))
  363. ((eq? a 'TEXT-COLOR)
  364. (text-drawing-text-color self))
  365. ((eq? a 'TEXT-STIPPLE)
  366. (text-drawing-text-stipple self))
  367. ((eq? a 'FONT)
  368. (text-drawing-font self))
  369. ((eq? a 'CURSOR-COLOR)
  370. (text-drawing-cursor-color self))
  371. ((eq? a 'HIGHLIGHT-COLOR)
  372. (text-drawing-highlight-color self))
  373. ((eq? a 'HIGHLIGHT-STIPPLE)
  374. (text-drawing-highlight-stipple self))
  375. ((eq? a 'OPTIONS)
  376. (text-drawing-options self))
  377. ((eq? a 'ROW-HEIGHT)
  378. (text-drawing-row-height self))
  379. ((eq? a 'CURSOR)
  380. (if (marker-line (text-drawing-cursor self))
  381. (list (marker-line (text-drawing-cursor self))
  382. (marker-char (text-drawing-cursor self)))
  383. #f))
  384. ((eq? a 'HIGHLIGHT)
  385. (if (marker-line (text-drawing-begin-highlight self))
  386. (list (marker-line
  387. (text-drawing-begin-highlight self))
  388. (marker-char
  389. (text-drawing-begin-highlight self))
  390. (marker-line
  391. (text-drawing-end-highlight self))
  392. (marker-char
  393. (text-drawing-end-highlight self)))
  394. #f))
  395. ((eq? a 'LINES)
  396. (jtextree-lines (text-drawing-jtextree self)))
  397. ((match? (TEXT-LINE non-negative?) a)
  398. (jtextree-text (text-drawing-jtextree self) (cadr a)))
  399. ((match? (VIEW symbol?) a)
  400. (let loop ((tvl (text-drawing-views self)))
  401. (if (pair? tvl)
  402. (let ((tv (car tvl)))
  403. (if (eq? (cadr a) (text-view-window tv))
  404. (list (text-view-first tv)
  405. (text-view-last tv)
  406. (text-view-slider tv))
  407. (loop (cdr tvl))))
  408. #f)))
  409. ((match? (XY->LINE-CHAR-TEXT non-negative?
  410. non-negative?) a)
  411. (let* ((jt (text-drawing-jtextree self))
  412. (line (min (quotient (caddr a)
  413. (text-drawing-row-height self))
  414. (jtextree-lines jt)))
  415. (char (pixel->texti-jtextree jt line
  416. (- (cadr a)
  417. (text-drawing-text-delta-x self))))
  418. (text (jtextree-text jt line)))
  419. (list line char text)))
  420. ((eq? a 'ATTRIBUTES)
  421. '(width text-color text-stipple font cursor-color
  422. highlight-color highlight-stipple options
  423. row-height cursor highlight lines text-line
  424. xy->line-char-text insert delete view
  425. scroll delete-view delete-object attributes))
  426. (else (ezd-error 'TEXT-DRAWING "Invalid attribute: ~s"
  427. a))))
  428. *user-event-misc*))
  429. ;;; A TEXT-DRAWING is changed by setting its attributes. The following
  430. ;;; attributes may be set:
  431. ;;;
  432. ;;; (INSERT "string") insert text at the end of the document.
  433. ;;; (INSERT line char "string")
  434. ;;; insert text before the specified line and
  435. ;;; character positions. Note that line and
  436. ;;; character indices begin at 0.
  437. ;;;
  438. ;;; (DELETE line0 char0 line1 char1)
  439. ;;; deletes a range of text, including the end
  440. ;;; points.
  441. ;;; (DELETE line char END) delete from starting position through the
  442. ;;; end of the document.
  443. ;;;
  444. ;;; (CURSOR) turns off cursor display
  445. ;;; (CURSOR line char) sets the cursor position
  446. ;;;
  447. ;;; (HIGHLIGHT) turns off the highlight
  448. ;;; (HIGHLIGHT line0 char0 line0 char1)
  449. ;;; highlights a range of text including the end
  450. ;;; points.
  451. ;;;
  452. ;;; (VIEW window x y width height slider-width)
  453. ;;; create a view in that window of the designated
  454. ;;; size. If slider-width is non-zero, then that
  455. ;;; much area of the view will be allocated for a
  456. ;;; slider.
  457. ;;;
  458. ;;; (SCROLL window line) scroll the view in the designated window so
  459. ;;; that the designated line is the first line
  460. ;;; visible.
  461. ;;;
  462. ;;; (DELETE-VIEW window) delete a view
  463. ;;;
  464. ;;; (DELETE-OBJECT) delete the drawing
  465. ;;;
  466. ;;; (MOUSE-EDIT) indicates changes are coming from the mouse
  467. ;;; based editor so it need not be initialized.
  468. (define (TEXT-DRAWING-SET-ATTRIBUTES self)
  469. (let* ((jt (text-drawing-jtextree self))
  470. (was-lines (jtextree-lines jt))
  471. (mouse-edit #f))
  472. (DEFINE (SET-CURSOR l c)
  473. (let ((cursor (text-drawing-cursor self)))
  474. (marker-line! cursor l)
  475. (marker-char! cursor c)
  476. (marker-changed! cursor #t)))
  477. (define (SET-HIGHLIGHT line0 char0 line1 char1)
  478. (let ((begin-highlight (text-drawing-begin-highlight self))
  479. (end-highlight (text-drawing-end-highlight self)))
  480. (marker-line! begin-highlight line0)
  481. (marker-char! begin-highlight char0)
  482. (marker-changed! begin-highlight #t)
  483. (marker-line! end-highlight line1)
  484. (marker-char! end-highlight char1)
  485. (marker-changed! end-highlight #t)))
  486. (for-each
  487. (lambda (a)
  488. (cond ((match? (INSERT string?) a)
  489. (insert-jtextree jt (jtextree-lines jt) 0
  490. (cadr a) #t))
  491. ((match? (INSERT non-negative? non-negative?
  492. string?) a)
  493. (insert-jtextree jt (cadr a) (caddr a) (cadddr a)
  494. #t))
  495. ((match? (DELETE non-negative? non-negative?
  496. non-negative? non-negative?)
  497. a)
  498. (delete-jtextree jt (list-ref a 1) (list-ref a 2)
  499. (list-ref a 3) (list-ref a 4) #t))
  500. ((match? (DELETE non-negative? non-negative?
  501. (lambda (x) (eq? x 'END)))
  502. a)
  503. (delete-jtextree jt (list-ref a 1) (list-ref a 2)
  504. (jtextree-lines jt) 0 #t))
  505. ((match? (CURSOR) a)
  506. (set-cursor 0 -1))
  507. ((match? (CURSOR non-negative? non-negative?) a)
  508. (set-cursor (cadr a) (caddr a)))
  509. ((match? (HIGHLIGHT) a)
  510. (set-highlight 0 -1 0 -1))
  511. ((match? (HIGHLIGHT non-negative? non-negative?
  512. non-negative? non-negative?) a)
  513. (set-highlight (list-ref a 1) (list-ref a 2)
  514. (list-ref a 3) (list-ref a 4)))
  515. ((match? (VIEW window-exists? non-negative?
  516. non-negative? non-negative?
  517. non-negative? non-negative?) a)
  518. (text-drawing-new-view self (list-ref a 1)
  519. (list-ref a 2) (list-ref a 3) (list-ref a 4)
  520. (list-ref a 5) (list-ref a 6)))
  521. ((match? (SCROLL window-exists? non-negative?) a)
  522. (text-view-scroll self (cadr a) (caddr a)))
  523. ((match? (DELETE-VIEW symbol?) a)
  524. (ezd `(delete-view ,(cadr a)
  525. ,(text-drawing-name self))))
  526. ((equal? '(DELETE-OBJECT) a)
  527. (for-each
  528. (lambda (tv)
  529. (ezd `(delete-view
  530. ,(text-view-window tv)
  531. ,(text-drawing-name self))))
  532. (text-drawing-views self))
  533. (ezd `(save-drawing)
  534. `(set-drawing ,(text-drawing-name self))
  535. '(clear)
  536. '(restore-drawing)))
  537. ((equal? '(MOUSE-EDIT) a)
  538. (set! mouse-edit #t))
  539. (else (ezd-error 'TEXT-DRAWING
  540. "Invalid attribute: ~s" a))))
  541. *user-event-misc*)
  542. (if (not mouse-edit)
  543. (mouse-edit-init (text-drawing-name self) 'text-drawing
  544. (text-drawing-options self)))
  545. (text-drawing-update-display self was-lines)))
  546. ;;; After changes have been made to the display by changing attributes, the
  547. ;;; following procedure is called to update the display.
  548. (define (TEXT-DRAWING-UPDATE-DISPLAY self was-lines)
  549. (let* ((jt (text-drawing-jtextree self))
  550. (first (jtextree-first-changed jt))
  551. (last (jtextree-last-changed jt))
  552. (is-lines (jtextree-lines jt))
  553. (row-height (text-drawing-row-height self))
  554. (text-delta-x (text-drawing-text-delta-x self))
  555. (highlight-color (text-drawing-highlight-color self))
  556. (highlight-stipple (if (text-drawing-highlight-stipple self)
  557. `(,(text-drawing-highlight-stipple
  558. self))
  559. '()))
  560. (cursor (text-drawing-cursor self))
  561. (begin-highlight (text-drawing-begin-highlight self))
  562. (end-highlight (text-drawing-end-highlight self)))
  563. (ezd '(save-drawing)
  564. `(set-drawing ,(text-drawing-name self)))
  565. ;;; 1. Redraw changed text lines.
  566. (if first (text-drawing-draw-lines self first
  567. (if (eq? is-lines was-lines)
  568. last
  569. (max last was-lines))))
  570. ;;; 2. Change maximum and value on sliders on text size change.
  571. (if (not (eq? is-lines was-lines))
  572. (for-each
  573. (lambda (tv)
  574. (if (text-view-slider tv)
  575. (let* ((slider (text-view-slider tv))
  576. (value (car (get-attributes slider 'slider
  577. 'value)))
  578. (max-value (max 0
  579. (- is-lines
  580. (- (text-view-last tv)
  581. (text-view-first
  582. tv))
  583. 1))))
  584. (if (< max-value value)
  585. (text-view-scroll self
  586. (text-view-window tv)
  587. max-value))
  588. (set-attributes slider 'slider
  589. `(value ,(min value max-value))
  590. `(max-value ,max-value)))))
  591. (text-drawing-views self)))
  592. ;;; 3. Redraw the cursor.
  593. (if (marker-changed cursor)
  594. (if (>= (marker-char cursor) 0)
  595. (ezd `(object cursor
  596. (text ,(texti->pixel-jtextree jt
  597. (marker-line cursor)
  598. (marker-char cursor))
  599. ,(+ (* row-height (marker-line cursor))
  600. (text-drawing-cursor-delta-y self))
  601. "^"
  602. ,(or (text-drawing-cursor-color self)
  603. (text-drawing-text-color self))
  604. ,(text-drawing-cursor-font self))))
  605. (ezd `(object cursor))))
  606. ;;; 4. Redraw the highlighted area.
  607. (if (or (marker-changed begin-highlight)
  608. (marker-changed end-highlight))
  609. (if (and (>= (marker-char begin-highlight) 0)
  610. (>= (marker-char end-highlight) 0))
  611. (let* ((line0 (marker-line begin-highlight))
  612. (char0 (marker-char begin-highlight))
  613. (xchar0 (texti->pixel-jtextree jt line0 char0))
  614. (line1 (marker-line end-highlight))
  615. (char1 (marker-char end-highlight))
  616. (xchar1 (texti->pixel-jtextree jt line1
  617. (+ 1 char1)))
  618. (width1 (texti->pixel-jtextree jt line1
  619. 1000000)))
  620. (define (DRAW i)
  621. `(fill-rectangle
  622. ,(+ text-delta-x
  623. (if (eq? i line0) xchar0 0))
  624. ,(* row-height i)
  625. ,(- (texti->pixel-jtextree jt i
  626. 1000000)
  627. (if (eq? i line0) xchar0 0)
  628. (if (eq? i line1)
  629. (- width1 xchar1)
  630. 0))
  631. ,row-height
  632. ,highlight-color
  633. ,@highlight-stipple))
  634. (ezd `(object highlight
  635. ,@(let loop ((i line0))
  636. (if (<= i line1)
  637. (cons (draw i) (loop (+ i 1)))
  638. '())))))
  639. (ezd '(object highlight))))
  640. (ezd '(restore-drawing))
  641. (clear-changes-jtextree jt)))
  642. ;;; A new text view is created when the following procedure is called by
  643. ;;; TEXT-DRAWING-SET-ATTRIBUTES.
  644. (define (TEXT-DRAWING-NEW-VIEW self window x y width height slider)
  645. (let* ((drawing (text-drawing-name self))
  646. (slider-name (string->symbol (string-append (symbol->string window)
  647. "-" (symbol->string drawing)
  648. "-SLIDER")))
  649. (lines (quotient height
  650. (text-drawing-row-height self)))
  651. (document-lines (jtextree-lines (text-drawing-jtextree self))))
  652. (ezd `(overlay ,window ,drawing ,(+ x slider) ,y ,(- width slider)
  653. ,height))
  654. (for-each
  655. (lambda (tv)
  656. (when (eq? (text-view-window tv) window)
  657. (text-view-x! tv (+ x slider))
  658. (text-view-y! tv y)))
  659. (text-drawing-views self))
  660. (when (positive? slider)
  661. (ezd '(save-drawing)
  662. `(set-drawing ,slider-name)
  663. `(overlay ,window ,slider-name ,x ,y ,slider ,height)
  664. `(origin ,window ,slider-name ,x ,y)
  665. `(slider slider 0 0 ,slider ,height ,lines 0
  666. ,(max 0 (- document-lines lines)) 0 ,(- lines 1)
  667. (ezd `(set-attributes
  668. ,,(list 'quote drawing) text-drawing
  669. (scroll ,,(list 'quote window)
  670. ,(car *user-event-misc*))))
  671. ,(text-drawing-text-color self) s8))
  672. (for-each
  673. (lambda (tv)
  674. (if (eq? (text-view-window tv) window)
  675. (text-view-slider! tv slider-name)))
  676. (text-drawing-views self)))
  677. (ezd `(origin ,window ,drawing ,(+ x slider) ,y))))
  678. ;;; A TEXT-VIEW is scrolled by the following procedure that is called from
  679. ;;; TEXT-DRAWING-SET-ATTRIBUTES.
  680. (define (TEXT-VIEW-SCROLL self window line)
  681. (let* ((new-first (inexact->exact (round line)))
  682. (row-height (text-drawing-row-height self)))
  683. (for-each
  684. (lambda (tv)
  685. (when (and (eq? (text-view-window tv) window)
  686. (not (eq? (text-view-first tv) new-first)))
  687. (ezd `(origin ,window ,(text-drawing-name self)
  688. ,(text-view-x tv)
  689. ,(+ (text-view-y tv)
  690. (* (- row-height) new-first))))))
  691. (text-drawing-views self))))