Changeset 869
- Timestamp:
- Aug 30, 2004, 3:20:12 PM (20 years ago)
- File:
-
- 1 edited
-
trunk/ccl/examples/cocoa-editor.lisp (modified) (25 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/ccl/examples/cocoa-editor.lisp
r856 r869 9 9 10 10 (eval-when (:compile-toplevel :execute) 11 (pushnew :all-in-cocoa-thread *features*) 11 12 (use-interface-dir :cocoa)) 12 13 … … 157 158 158 159 160 (defun adjust-buffer-cache-for-insertion (display pos n) 161 (if (buffer-cache-workline display) 162 (let* ((hi::*buffer-gap-context* (hi::buffer-gap-context (buffer-cache-buffer display)))) 163 (if (> (buffer-cache-workline-offset display) pos) 164 (incf (buffer-cache-workline-offset display) n) 165 (when (>= (+ (buffer-cache-workline-offset display) 166 (buffer-cache-workline-length display)) 167 pos) 168 (setf (buffer-cache-workline-length display) 169 (hi::line-length (buffer-cache-workline display))))) 170 (incf (buffer-cache-buflen display) n)) 171 (reset-buffer-cache display))) 172 173 174 175 159 176 ;;; Update the cache so that it's describing the current absolute 160 177 ;;; position. 178 161 179 (defun update-line-cache-for-index (cache index) 162 180 (let* ((buffer (buffer-cache-buffer cache)) … … 179 197 (buffer-cache-workline-length cache) len)) 180 198 (return (values line idx)))) 181 (setq moved t)199 (setq moved t) 182 200 (if (< index pos) 183 201 (setq line (hi::line-previous line) … … 242 260 243 261 262 244 263 ;;; Return the character at the specified index (as a :unichar.) 264 245 265 (define-objc-method ((:unichar :character-at-index (unsigned index)) 246 266 hemlock-buffer-string) 267 #+debug 268 (#_NSLog #@"Character at index: %d" :unsigned index) 247 269 (char-code (hemlock-char-at-index (hemlock-buffer-string-cache self) index))) 248 270 249 271 272 (define-objc-method ((:void :get-characters (:address buffer) :range (:<NSR>ange r)) 273 hemlock-buffer-string) 274 (let* ((cache (hemlock-buffer-string-cache self)) 275 (index (pref r :<NSR>ange.location)) 276 (length (pref r :<NSR>ange.length)) 277 (hi::*buffer-gap-context* 278 (hi::buffer-gap-context (buffer-cache-buffer cache)))) 279 #+debug 280 (#_NSLog #@"get characters: %d/%d" 281 :unsigned index 282 :unsigned length) 283 (multiple-value-bind (line idx) (update-line-cache-for-index cache index) 284 (let* ((len (hemlock::line-length line))) 285 (do* ((i 0 (1+ i)) 286 (p 0 (+ p 2))) 287 ((= i length)) 288 (cond ((< idx len) 289 (setf (%get-unsigned-word buffer p) 290 (char-code (hemlock::line-character line idx))) 291 (incf idx)) 292 (t 293 (setf (%get-unsigned-word buffer p) 294 (char-code #\Newline) 295 line (hi::line-next line) 296 len (hi::line-length line) 297 idx 0)))))))) 298 299 (define-objc-method ((:void :get-line-start ((:* :unsigned) startptr) 300 :end ((:* :unsigned) endptr) 301 :contents-end ((:* :unsigned) contents-endptr) 302 :for-range (:<NSR>ange r)) 303 hemlock-buffer-string) 304 (let* ((cache (hemlock-buffer-string-cache self)) 305 (index (pref r :<NSR>ange.location)) 306 (length (pref r :<NSR>ange.length)) 307 (hi::*buffer-gap-context* 308 (hi::buffer-gap-context (buffer-cache-buffer cache)))) 309 #+debug 0 310 (#_NSLog #@"get line start: %d/%d" 311 :unsigned index 312 :unsigned length) 313 (update-line-cache-for-index cache index) 314 (unless (%null-ptr-p startptr) 315 ;; Index of the first character in the line which contains 316 ;; the start of the range. 317 (setf (pref startptr :unsigned) 318 (buffer-cache-workline-offset cache))) 319 (unless (%null-ptr-p endptr) 320 ;; Index of the newline which terminates the line which 321 ;; contains the start of the range. 322 (setf (pref endptr :unsigned) 323 (+ (buffer-cache-workline-offset cache) 324 (buffer-cache-workline-length cache)))) 325 (unless (%null-ptr-p contents-endptr) 326 ;; Index of the newline which terminates the line which 327 ;; contains the start of the range. 328 (unless (zerop length) 329 (update-line-cache-for-index cache (+ index length))) 330 (setf (pref contents-endptr :unsigned) 331 (1+ (+ (buffer-cache-workline-offset cache) 332 (buffer-cache-workline-length cache))))))) 333 334 250 335 ;;; Return an NSData object representing the bytes in the string. If 251 336 ;;; the underlying buffer uses #\linefeed as a line terminator, we can … … 260 345 (external-format (if buffer (hi::buffer-external-format buffer ))) 261 346 (raw-length (if buffer (hemlock-buffer-length buffer) 0))) 262 347 (hi::%set-buffer-modified buffer nil) 263 348 (if (eql 0 raw-length) 264 349 (make-objc-instance 'ns:ns-mutable-data :with-length 0) … … 317 402 (:metaclass ns:+ns-object)) 318 403 404 (define-objc-method ((:unsigned :line-break-before-index (:unsigned index) 405 :within-range (:<NSR>ange r)) 406 hemlock-text-storage) 407 (#_NSLog #@"Line break before index: %d within range: %@" 408 :unsigned index 409 :id (#_NSStringFromRange r)) 410 (send-super :line-break-before-index index :within-range r)) 411 412 319 413 320 414 ;;; Return true iff we're inside a "beginEditing/endEditing" pair … … 412 506 :effective-range ((* :<NSR>ange) rangeptr)) 413 507 hemlock-text-storage) 508 #+debug 509 (#_NSLog #@"Attributes at index: %d" :unsigned index) 414 510 (let* ((buffer-cache (hemlock-buffer-string-cache (slot-value self 'string))) 415 511 (buffer (buffer-cache-buffer buffer-cache)) … … 472 568 (let* ((layouts (send textstorage 'layout-managers))) 473 569 (unless (%null-ptr-p layouts) 474 (dotimes (i (send layouts'count))570 (dotimes (i (send (the ns:ns-array layouts) 'count)) 475 571 (let* ((layout (send layouts :object-at-index i)) 476 572 (containers (send layout 'text-containers))) 477 573 (unless (%null-ptr-p containers) 478 (dotimes (j (send containers'count))574 (dotimes (j (send (the ns:ns-array containers) 'count)) 479 575 (let* ((container (send containers :object-at-index j)) 480 576 (tv (send container 'text-view))) … … 530 626 531 627 532 628 (def-cocoa-default *layout-text-in-background* :int 1 "When non-zero, do text layout when idle.") 629 630 (define-objc-method ((:void :layout-manager layout 631 :did-complete-layout-for-text-container cont 632 :at-end (:<BOOL> flag)) 633 hemlock-textstorage-text-view) 634 (declare (ignore cont)) 635 (when (zerop *layout-text-in-background*) 636 (send layout :set-delegate (%null-ptr)) 637 (send layout :set-background-layout-enabled nil))) 638 533 639 ;;; Note changes to the textview's background color; record them 534 640 ;;; as the value of the "temporary" foreground color (for blinking). … … 545 651 :turned-on (:<BOOL> flag)) 546 652 hemlock-textstorage-text-view) 547 (unless ( eql #$NO (text-view-blink-enabled self))548 ( let* ((layout (send self 'layout-manager))549 (container (send self 'text-container))550 (blink-color (text-view-blink-color self)))551 ;; We toggle the blinked character "off" by setting its552 ;; foreground color to the textview's background color.553 ;; The blinked character should be "on" whenever the insertion554 ;; point is drawn as "off"555 (slet ((glyph-range556 (send layout557 :glyph-range-for-character-range558 (ns-make-range (text-view-blink-location self) 1)559 :actual-character-range (%null-ptr))))560 #+debug (#_NSLog #@"Flag = %d, location = %d" :<BOOL> (if flag #$YES #$NO) :int (text-view-blink-location self))561 (if flag653 (unless (send (send self 'text-storage) 'editing-in-progress) 654 (unless (eql #$NO (text-view-blink-enabled self)) 655 (let* ((layout (send self 'layout-manager)) 656 (container (send self 'text-container)) 657 (blink-color (text-view-blink-color self))) 658 ;; We toggle the blinked character "off" by setting its 659 ;; foreground color to the textview's background color. 660 ;; The blinked character should be "on" whenever the insertion 661 ;; point is drawn as "off" 662 (slet ((glyph-range 663 (send layout 664 :glyph-range-for-character-range 665 (ns-make-range (text-view-blink-location self) 1) 666 :actual-character-range (%null-ptr)))) 667 #+debug (#_NSLog #@"Flag = %d, location = %d" :<BOOL> (if flag #$YES #$NO) :int (text-view-blink-location self)) 562 668 (slet ((rect (send layout 563 669 :bounding-rect-for-glyph-range glyph-range 564 670 :in-text-container container))) 565 (send blink-color'set)671 (send (the ns:ns-color blink-color) 'set) 566 672 (#_NSRectFill rect)) 567 (send layout 568 :draw-glyphs-for-glyph-range glyph-range 569 :at-point (send self 'text-container-origin))) 570 ))) 571 (send-super :draw-insertion-point-in-rect r 572 :color color 573 :turned-on flag)) 673 (if flag 674 (send layout 675 :draw-glyphs-for-glyph-range glyph-range 676 :at-point (send self 'text-container-origin))) 677 ))) 678 (send-super :draw-insertion-point-in-rect r 679 :color color 680 :turned-on flag))) 574 681 575 682 (defmethod disable-blink ((self hemlock-textstorage-text-view)) 576 683 (when (eql (text-view-blink-enabled self) #$YES) 577 684 (setf (text-view-blink-enabled self) #$NO) 578 (unwind-protect 579 (progn 580 (send self 'lock-focus) 581 (let* ((layout (send self 'layout-manager))) 582 (slet ((glyph-range (send layout 583 :glyph-range-for-character-range 584 (ns-make-range (text-view-blink-location self) 585 1) 586 :actual-character-range (%null-ptr)))) 587 (send layout 588 :draw-glyphs-for-glyph-range glyph-range 589 :at-point (send self 'text-container-origin))))) 590 (send self 'unlock-focus)))) 685 ;; Force the blinked character to be redrawn. Let the text 686 ;; system do the drawing. 687 (let* ((layout (send self 'layout-manager))) 688 (send layout :invalidate-display-for-character-range 689 (ns-make-range (text-view-blink-location self) 1))))) 591 690 592 691 (defmethod update-blink ((self hemlock-textstorage-text-view)) … … 692 791 (n (if (%null-ptr-p unmodchars) 693 792 0 694 (send unmodchars'length)))793 (send (the ns:ns-string unmodchars) 'length))) 695 794 (c (if (eql n 1) 696 795 (send unmodchars :character-at-index 0)))) … … 1029 1128 :text-container container) 1030 1129 'autorelease))) 1130 (send layout :set-delegate tv) 1031 1131 (send tv :set-min-size (ns-make-size 1032 1132 0.0f0 … … 1088 1188 ((textstorage :foreign-type :id)) 1089 1189 (:metaclass ns:+ns-object)) 1190 1191 (define-objc-method ((:void close) echo-area-document) 1192 (let* ((ts (slot-value self 'textstorage))) 1193 (unless (%null-ptr-p ts) 1194 (setf (slot-value self 'textstorage) (%null-ptr)) 1195 (close-hemlock-textstorage ts)))) 1090 1196 1091 1197 (define-objc-method ((:void :update-change-count (:<NSD>ocument<C>hange<T>ype change)) echo-area-document) … … 1292 1398 (setf (slot-value self 'command-thread) nil) 1293 1399 (process-kill proc))) 1400 (let* ((buf (hemlock-frame-echo-area-buffer self)) 1401 (echo-doc (if buf (hi::buffer-document buf)))) 1402 (when echo-doc 1403 (setf (hemlock-frame-echo-area-buffer self) nil) 1404 (send echo-doc 'close))) 1405 (release-canonical-nsobject self) 1294 1406 (send-super 'close)) 1295 1407 … … 1312 1424 pane))))) 1313 1425 1314 1315 1316 1426 1317 1427 … … 1335 1445 (defun %nsstring-to-mark (nsstring mark) 1336 1446 "returns external-format of string" 1337 (let* ((string-len (send nsstring'length))1447 (let* ((string-len (send (the ns:ns-string nsstring) 'length)) 1338 1448 (line-start 0) 1339 1449 (first-line-terminator ()) … … 1440 1550 (frame (send pane 'window)) 1441 1551 (buffer (text-view-buffer (text-pane-text-view pane)))) 1442 (setf (slot-value frame 'echo-area-view)1443 (make-echo-area-for-window frame (hi::buffer-gap-context buffer) color))1552 (setf (slot-value frame 'echo-area-view) 1553 (make-echo-area-for-window frame (hi::buffer-gap-context buffer) color)) 1444 1554 (setf (slot-value frame 'command-thread) 1445 1555 (process-run-function (format nil "Hemlock window thread") … … 1470 1580 1471 1581 (defun hi::document-begin-editing (document) 1582 #-all-in-cocoa-thread 1583 (send (slot-value document 'textstorage) 'begin-editing) 1584 #+all-in-cocoa-thread 1472 1585 (send (slot-value document 'textstorage) 1473 1586 :perform-selector-on-main-thread … … 1479 1592 1480 1593 (defun hi::document-end-editing (document) 1594 #-all-in-cocoa-thread 1595 (send (slot-value document 'textstorage) 'end-editing) 1596 #+all-in-cocoa-thread 1481 1597 (send (slot-value document 'textstorage) 1482 1598 :perform-selector-on-main-thread … … 1509 1625 (%get-ptr paramptrs (ash 1 target::word-shift)) 1510 1626 number-for-n) 1511 (let* ((params (make-objc-instance 'ns:ns-array 1512 :with-objects paramptrs 1513 :count 2))) 1627 (let* ((params 1628 (send (send (@class "NSArray") 'alloc) 1629 :init-with-objects paramptrs 1630 :count 2))) 1514 1631 (send textstorage 1515 1632 :perform-selector-on-main-thread … … 1558 1675 (format t "~&insert: pos = ~d, n = ~d" pos n) 1559 1676 (let* ((display (hemlock-buffer-string-cache (send textstorage 'string)))) 1560 (reset-buffer-cache display) 1677 ;(reset-buffer-cache display) 1678 (adjust-buffer-cache-for-insertion display pos n) 1561 1679 (update-line-cache-for-index display pos)) 1680 #-all-in-cocoa-thread 1681 (textstorage-note-insertion-at-position textstorage pos n) 1682 #+all-in-cocoa-thread 1562 1683 (perform-edit-change-notification textstorage 1563 1684 (@selector "noteInsertion:") … … 1574 1695 :int (mark-absolute-position mark) 1575 1696 :int n) 1697 #-all-in-cocoa-thread 1698 (send textstorage 1699 :edited (logior #$NSTextStorageEditedCharacters 1700 #$NSTextStorageEditedAttributes) 1701 :range (ns-make-range (mark-absolute-position mark) n) 1702 :change-in-length 0) 1703 #+all-in-cocoa-thread 1576 1704 (perform-edit-change-notification textstorage 1577 1705 (@selector "noteModification:") … … 1585 1713 (textstorage (if document (slot-value document 'textstorage)))) 1586 1714 (when textstorage 1715 #-all-in-cocoa-thread 1716 (let* ((pos (mark-absolute-position mark))) 1717 (send textstorage 1718 :edited #$NSTextStorageEditedCharacters 1719 :range (ns-make-range pos n) 1720 :change-in-length (- n)) 1721 (let* ((display (hemlock-buffer-string-cache (send textstorage 'string)))) 1722 (reset-buffer-cache display) 1723 (update-line-cache-for-index display pos))) 1724 #+all-in-cocoa-thread 1587 1725 (perform-edit-change-notification textstorage 1588 1726 (@selector "noteDeletion:") 1589 1727 (mark-absolute-position mark) 1590 1728 (abs n)))))) 1729 1591 1730 (defun hi::set-document-modified (document flag) 1592 1731 (send document … … 1648 1787 (:metaclass ns:+ns-object)) 1649 1788 1650 1651 1789 1790 1791 (define-objc-method ((:void :_window-will-close notification) 1792 hemlock-editor-window-controller) 1793 #+debug 1794 (let* ((w (send notification 'object))) 1795 (#_NSLog #@"Window controller: window will close: %@" :id w)) 1796 (send-super :_window-will-close notification)) 1652 1797 1653 1798 ;;; The HemlockEditorDocument class. … … 1800 1945 1801 1946 (define-objc-method ((:void close) hemlock-editor-document) 1947 #+debug 1948 (#_NSLog #@"Document close: %@" :id self) 1802 1949 (let* ((textstorage (slot-value self 'textstorage))) 1803 (setf (slot-value self 'textstorage) (%null-ptr))1804 1950 (unless (%null-ptr-p textstorage) 1951 (setf (slot-value self 'textstorage) (%null-ptr)) 1805 1952 (for-each-textview-using-storage 1806 1953 textstorage 1807 #'(lambda (tv) (send tv :set-string #@""))) 1954 #'(lambda (tv) 1955 (let* ((layout (send tv 'layout-manager))) 1956 (send layout :set-background-layout-enabled nil)))) 1808 1957 (close-hemlock-textstorage textstorage))) 1809 (send-super 'close))1958 (send-super 'close)) 1810 1959 1811 1960
Note:
See TracChangeset
for help on using the changeset viewer.
