Changeset 790
- Timestamp:
- Apr 19, 2004, 12:31:50 PM (21 years ago)
- File:
-
- 1 edited
-
trunk/ccl/examples/cocoa-editor.lisp (modified) (12 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/ccl/examples/cocoa-editor.lisp
r771 r790 322 322 (not (eql (slot-value self 'edit-count) 0))) 323 323 324 325 (define-objc-method (((:struct :<NSR>ange r) :double-click-at-index (:unsigned index))326 hemlock-text-storage)327 (block HANDLED328 (let* ((cache (hemlock-buffer-string-cache (send self 'string)))329 (buffer (if cache (buffer-cache-buffer cache))))330 (when (and buffer (string= (hi::buffer-major-mode buffer) "Lisp"))331 (let* ((hi::*buffer-gap-context* (hi::buffer-gap-context buffer)))332 (hi::with-mark ((m1 (hi::buffer-point buffer)))333 (move-hemlock-mark-to-absolute-position m1 cache index)334 (hemlock::pre-command-parse-check m1)335 (when (hemlock::valid-spot m1 nil)336 (cond ((eql (hi::next-character m1) #\()337 (hi::with-mark ((m2 m1))338 (when (hemlock::list-offset m2 1)339 (setf (pref r :<NSR>ange.location) index340 (pref r :<NSR>ange.length)341 (- (mark-absolute-position m2) index))342 (return-from HANDLED nil))))343 ((eql (hi::previous-character m1) #\))344 (hi::with-mark ((m2 m1))345 (when (hemlock::list-offset m2 -1)346 (#_NSLog #@"Length = %d"347 :unsigned348 (- (1- index) (mark-absolute-position m2)))349 (setf (pref r :<NSR>ange.location)350 (mark-absolute-position m2)351 (pref r :<NSR>ange.length)352 (- (1- index) (mark-absolute-position m2)))353 (return-from HANDLED nil)))))))))354 ;; No early exit, so call next-method355 (objc-message-send-super-stret r (super) "doubleClickAtIndex:"356 :unsigned index357 :void))))358 359 360 361 362 363 364 365 366 324 (defun textstorage-note-insertion-at-position (self pos n) 367 325 (send self … … 541 499 ;;; An abstract superclass of the main and echo-area text views. 542 500 (defclass hemlock-textstorage-text-view (ns::ns-text-view) 543 ((save-blink-color :foreign-type :id)) 501 ((blink-location :foreign-type :unsigned :accessor text-view-blink-location) 502 (blink-color-attribute :foreign-type :id :accessor text-view-blink-color) 503 (blink-enabled :foreign-type :<BOOL> :accessor text-view-blink-enabled) ) 544 504 (:metaclass ns:+ns-object)) 545 505 506 507 508 ;;; Note changes to the textview's background color; record them 509 ;;; as the value of the "temporary" foreground color (for blinking). 510 (define-objc-method ((:void :set-background-color color) 511 hemlock-textstorage-text-view) 512 (let* ((dict (text-view-blink-color self))) 513 (when (%null-ptr-p dict) 514 (setq dict (setf (text-view-blink-color self) 515 (make-objc-instance 'ns:ns-mutable-dictionary 516 :with-capacity 1)))) 517 (send dict :set-value color :for-key #@"NSColor") 518 (send-super :set-background-color color))) 519 520 ;;; Maybe cause 1 character in the textview to blink (by setting/clearing a 521 ;;; temporary attribute) in synch with the insertion point. 522 523 (define-objc-method ((:void :draw-insertion-point-in-rect (:<NSR>ect r) 524 :color color 525 :turned-on (:<BOOL> flag)) 526 hemlock-textstorage-text-view) 527 (unless (eql #$NO (text-view-blink-enabled self)) 528 (let* ((layout (send self 'layout-manager)) 529 (blink-color (text-view-blink-color self))) 530 ;; We toggle the blinked character "off" by setting its 531 ;; foreground color to the textview's background color. 532 ;; The blinked character should be "on" whenever the insertion 533 ;; point is drawn as "off" 534 (slet ((blink-range (ns-make-range (text-view-blink-location self) 1))) 535 #+debug (#_NSLog #@"Flag = %d" :<BOOL> (if flag #$YES #$NO)) 536 (if flag 537 (send layout 538 :add-temporary-attributes blink-color 539 :for-character-range blink-range) 540 (send layout 541 :remove-temporary-attribute #@"NSColor" 542 :for-character-range blink-range))))) 543 (send-super :draw-insertion-point-in-rect r 544 :color color 545 :turned-on flag)) 546 547 (defmethod disable-blink ((self hemlock-textstorage-text-view)) 548 (when (eql (text-view-blink-enabled self) #$YES) 549 (setf (text-view-blink-enabled self) #$NO) 550 (send (send self 'layout-manager) 551 :remove-temporary-attribute #@"NSColor" 552 :for-character-range (ns-make-range (text-view-blink-location self) 553 1)))) 554 555 (defmethod update-blink ((self hemlock-textstorage-text-view)) 556 (disable-blink self) 557 (let* ((d (hemlock-buffer-string-cache (send self 'string))) 558 (buffer (buffer-cache-buffer d))) 559 (when (and buffer (string= (hi::buffer-major-mode buffer) "Lisp")) 560 (let* ((hi::*buffer-gap-context* (hi::buffer-gap-context buffer)) 561 (point (hi::buffer-point buffer))) 562 #+debug (#_NSLog #@"Syntax check for blinking") 563 (hemlock::pre-command-parse-check point) 564 (when (hemlock::valid-spot point nil) 565 (cond ((eql (hi::next-character point) #\() 566 (hi::with-mark ((temp point)) 567 (when (hemlock::list-offset temp 1) 568 #+debug (#_NSLog #@"enable blink, forward") 569 (setf (text-view-blink-location self) 570 (mark-absolute-position temp) 571 (text-view-blink-enabled self) #$YES)))) 572 ((eql (hi::previous-character point) #\)) 573 (hi::with-mark ((temp point)) 574 (when (hemlock::list-offset temp -1) 575 #+debug (#_NSLog #@"enable blink, backward") 576 (setf (text-view-blink-location self) 577 (mark-absolute-position temp) 578 (text-view-blink-enabled self) #$YES)))))))))) 579 546 580 ;;; Set and display the selection at pos, whose length is len and whose 547 ;;; affinity is affinity. This should never be called from someCocoa581 ;;; affinity is affinity. This should never be called from any Cocoa 548 582 ;;; event handler; it should not call anything that'll try to set the 549 583 ;;; underlying buffer's point and/or mark. … … 552 586 :affinity (:<NSS>election<A>ffinity affinity)) 553 587 hemlock-textstorage-text-view) 588 (when (eql len 0) 589 (update-blink self)) 554 590 (slet ((range (ns-make-range pos len))) 555 591 (send-super :set-selected-range range … … 558 594 (send self :scroll-range-to-visible range))) 559 595 560 ;;; A specialized NSTextView. Some of the instance variables are intended 561 ;;; to support paren highlighting by blinking, but that doesn't work yet. 562 ;;; The NSTextView is part of the "pane" object that displays buffers. 596 ;;; A specialized NSTextView. The NSTextView is part of the "pane" 597 ;;; object that displays buffers. 563 598 (defclass hemlock-text-view (hemlock-textstorage-text-view) 564 599 ((pane :foreign-type :id :accessor text-view-pane)) … … 568 603 (defmethod text-view-buffer ((self hemlock-text-view)) 569 604 (buffer-cache-buffer (hemlock-buffer-string-cache (send (send self 'text-storage) 'string)))) 605 606 (define-objc-method (((:struct :<NSR>ange r) 607 :selection-range-for-proposed-range (:<NSR>ange proposed) 608 :granularity (:<NSS>election<G>ranularity g)) 609 hemlock-textstorage-text-view) 610 #+debug 611 (#_NSLog #@"Granularity = %d" :int g) 612 (block HANDLED 613 (let* ((index (pref proposed :<NSR>ange.location)) 614 (length (pref proposed :<NSR>ange.length))) 615 (when (and (eql 0 length) ; not extending existing selection 616 (not (eql g #$NSSelectByCharacter))) 617 (let* ((textstorage (send self 'text-storage)) 618 (cache (hemlock-buffer-string-cache (send textstorage 'string))) 619 (buffer (if cache (buffer-cache-buffer cache)))) 620 (when (and buffer (string= (hi::buffer-major-mode buffer) "Lisp")) 621 (let* ((hi::*buffer-gap-context* (hi::buffer-gap-context buffer))) 622 (hi::with-mark ((m1 (hi::buffer-point buffer))) 623 (move-hemlock-mark-to-absolute-position m1 cache index) 624 (hemlock::pre-command-parse-check m1) 625 (when (hemlock::valid-spot m1 nil) 626 (cond ((eql (hi::next-character m1) #\() 627 (hi::with-mark ((m2 m1)) 628 (when (hemlock::list-offset m2 1) 629 (setf (pref r :<NSR>ange.location) index 630 (pref r :<NSR>ange.length) 631 (- (mark-absolute-position m2) index)) 632 (return-from HANDLED nil)))) 633 ((eql (hi::previous-character m1) #\)) 634 (hi::with-mark ((m2 m1)) 635 (when (hemlock::list-offset m2 -1) 636 (setf (pref r :<NSR>ange.location) 637 (mark-absolute-position m2) 638 (pref r :<NSR>ange.length) 639 (- index (mark-absolute-position m2))) 640 (return-from HANDLED nil)))))))))))) 641 (objc-message-send-super-stret r (super) "selectionRangeForProposedRange:granularity:" 642 :<NSR>ange proposed 643 :<NSS>election<G>ranularity g) 644 #+debug 645 (#_NSLog #@"range = %@, proposed = %@, granularity = %d" 646 :address (#_NSStringFromRange r) 647 :address (#_NSStringFromRange proposed) 648 :<NSS>election<G>ranularity g))) 570 649 571 650 ;;; Translate a keyDown NSEvent to a Hemlock key-event. … … 612 691 (pass-key-down-event-to-hemlock self event)) 613 692 614 ;;; Update the underlying buffer's point. Should really set the 615 ;;; active region (in Hemlock terms) as well. 693 ;;; Update the underlying buffer's point (and "active region", if appropriate. 694 ;;; This is called in response to a mouse click or other event; it shouldn't 695 ;;; be called from the Hemlock side of things. 616 696 (define-objc-method ((:void :set-selected-range (:<NSR>ange r) 617 697 :affinity (:<NSS>election<A>ffinity affinity) … … 635 715 (#_NSLog #@"Moving point to absolute position %d" :int location) 636 716 (setf (hi::buffer-region-active buffer) nil) 637 (move-hemlock-mark-to-absolute-position point d location)) 717 (move-hemlock-mark-to-absolute-position point d location) 718 (update-blink self)) 638 719 (t 639 720 ;; We don't get much information about which end of the … … 934 1015 (defmethod hi::activate-hemlock-view ((view echo-area-view)) 935 1016 (let* ((hemlock-frame (send view 'window))) 936 #+debug 01017 #+debug 937 1018 (#_NSLog #@"Activating echo area") 938 1019 (send hemlock-frame :make-first-responder view))) … … 1169 1250 (let* ((pane (nth-value 1170 1251 1 1171 (new-hemlock-document-window))) 1172 (tv (make-scrolling-textview-for-pane pane ts container-tracks-text-view-width color)))1252 (new-hemlock-document-window)))) 1253 (make-scrolling-textview-for-pane pane ts container-tracks-text-view-width color) 1173 1254 (multiple-value-bind (height width) 1174 1255 (size-of-char-in-font (default-font)) 1175 (size-text view-containers tvheight width nrows ncols))1256 (size-text-pane pane height width nrows ncols)) 1176 1257 pane)) 1177 1258 … … 1421 1502 (send sf :width-of-string #@" ")))) 1422 1503 1423 1424 (defun get-size-for-textview (font nrows ncols) 1425 (multiple-value-bind (h w) (size-of-char-in-font font) 1426 (values (fceiling (* nrows h)) 1427 (fceiling (* ncols w))))) 1428 1429 1430 (defun size-textview-containers (tv char-height char-width nrows ncols) 1431 (let* ((height (fceiling (* nrows char-height))) 1504 1505 1506 (defun size-text-pane (pane char-height char-width nrows ncols) 1507 (let* ((tv (text-pane-text-view pane)) 1508 (height (fceiling (* nrows char-height))) 1432 1509 (width (fceiling (* ncols char-width))) 1433 (scrollview ( send (send tv 'superview) 'superview))1510 (scrollview (text-pane-scroll-view pane)) 1434 1511 (window (send scrollview 'window))) 1435 1512 (rlet ((tv-size :<NSS>ize :height height 1436 1513 :width (+ width (* 2 (send (send tv 'text-container) 1437 'line-fragment-padding)))))1514 'line-fragment-padding))))) 1438 1515 (when (send scrollview 'has-vertical-scroller) 1439 1516 (send scrollview :set-vertical-line-scroll char-height) 1440 1517 (send scrollview :set-vertical-page-scroll char-height)) 1518 (when (send scrollview 'has-horizontal-scroller) 1519 (send scrollview :set-horizontal-line-scroll char-width) 1520 (send scrollview :set-horizontal-page-scroll char-width)) 1441 1521 (slet ((sv-size 1442 1522 (send (@class ns-scroll-view) … … 1447 1527 (send scrollview 'has-vertical-scroller) 1448 1528 :border-type (send scrollview 'border-type)))) 1449 (slet ((sv-frame (send scrollview 'frame))) 1529 (slet ((pane-frame (send pane 'frame)) 1530 (margins (send pane 'content-view-margins))) 1450 1531 (incf (pref sv-size :<NSS>ize.height) 1451 (pref sv-frame :<NSR>ect.origin.y)) 1532 (+ (pref pane-frame :<NSR>ect.origin.y) 1533 (* 2 (pref margins :<NSS>ize.height)))) 1534 (incf (pref sv-size :<NSS>ize.width) 1535 (pref margins :<NSS>ize.width)) 1452 1536 (send window :set-content-size sv-size) 1453 1537 (send window :set-resize-increments … … 1594 1678 (let* ((textview (text-pane-text-view textpane))) 1595 1679 (unless (%null-ptr-p textview) 1596 (if (> n 0) 1597 (send textview :page-down nil) 1598 (send textview :page-up nil))))) 1680 (let* ((selector (if (>= n 0 ) 1681 (@selector "pageDown:") 1682 (@selector "pageUp:")))) 1683 (send textview 1684 :perform-selector-on-main-thread selector 1685 :with-object (%null-ptr) 1686 :wait-until-done t))))) 1599 1687 1600 1688 ;;; This needs to run on the main thread.
Note:
See TracChangeset
for help on using the changeset viewer.
