Changeset 790


Ignore:
Timestamp:
Apr 19, 2004, 12:31:50 PM (21 years ago)
Author:
Gary Byers
Message:

Lots of changes/fixes: selection, view-size, scrolling, paren-matching, etc.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/ccl/examples/cocoa-editor.lisp

    r771 r790  
    322322  (not (eql (slot-value self 'edit-count) 0)))
    323323
    324 
    325 (define-objc-method (((:struct :<NSR>ange r) :double-click-at-index (:unsigned index))
    326                      hemlock-text-storage)
    327   (block HANDLED
    328     (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) index
    340                                (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                                   :unsigned
    348                                   (- (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-method
    355       (objc-message-send-super-stret r (super) "doubleClickAtIndex:"
    356                                      :unsigned index
    357                                      :void))))
    358            
    359 
    360      
    361 
    362 
    363    
    364    
    365 
    366324(defun textstorage-note-insertion-at-position (self pos n)
    367325  (send self
     
    541499;;; An abstract superclass of the main and echo-area text views.
    542500(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) )
    544504  (:metaclass ns:+ns-object))
    545505
     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
    546580;;; Set and display the selection at pos, whose length is len and whose
    547 ;;; affinity is affinity.  This should never be called from some Cocoa
     581;;; affinity is affinity.  This should never be called from any Cocoa
    548582;;; event handler; it should not call anything that'll try to set the
    549583;;; underlying buffer's point and/or mark.
     
    552586                            :affinity (:<NSS>election<A>ffinity affinity))
    553587                     hemlock-textstorage-text-view)
     588  (when (eql len 0)
     589    (update-blink self))
    554590  (slet ((range (ns-make-range pos len)))
    555591    (send-super :set-selected-range range
     
    558594    (send self :scroll-range-to-visible range)))
    559595 
    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.
    563598(defclass hemlock-text-view (hemlock-textstorage-text-view)
    564599    ((pane :foreign-type :id :accessor text-view-pane))
     
    568603(defmethod text-view-buffer ((self hemlock-text-view))
    569604  (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)))
    570649
    571650;;; Translate a keyDown NSEvent to a Hemlock key-event.
     
    612691  (pass-key-down-event-to-hemlock self event))
    613692
    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.
    616696(define-objc-method ((:void :set-selected-range (:<NSR>ange r)
    617697                            :affinity (:<NSS>election<A>ffinity affinity)
     
    635715             (#_NSLog #@"Moving point to absolute position %d" :int location)
    636716             (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))
    638719            (t
    639720             ;; We don't get much information about which end of the
     
    9341015(defmethod hi::activate-hemlock-view ((view echo-area-view))
    9351016  (let* ((hemlock-frame (send view 'window)))
    936     #+debug 0
     1017    #+debug
    9371018    (#_NSLog #@"Activating echo area")
    9381019    (send hemlock-frame :make-first-responder view)))
     
    11691250  (let* ((pane (nth-value
    11701251                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)
    11731254    (multiple-value-bind (height width)
    11741255        (size-of-char-in-font (default-font))
    1175       (size-textview-containers tv height width nrows ncols))
     1256      (size-text-pane pane height width nrows ncols))
    11761257    pane))
    11771258
     
    14211502            (send sf :width-of-string #@" "))))
    14221503         
    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)))
    14321509         (width (fceiling (* ncols char-width)))
    1433          (scrollview (send (send tv 'superview) 'superview))
     1510         (scrollview (text-pane-scroll-view pane))
    14341511         (window (send scrollview 'window)))
    14351512    (rlet ((tv-size :<NSS>ize :height height
    14361513                    :width (+ width (* 2 (send (send tv 'text-container)
    1437                       'line-fragment-padding)))))
     1514                                               'line-fragment-padding)))))
    14381515      (when (send scrollview 'has-vertical-scroller)
    14391516        (send scrollview :set-vertical-line-scroll char-height)
    14401517        (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))
    14411521      (slet ((sv-size
    14421522              (send (@class ns-scroll-view)
     
    14471527                    (send scrollview 'has-vertical-scroller)
    14481528                    :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)))
    14501531          (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))
    14521536          (send window :set-content-size sv-size)
    14531537          (send window :set-resize-increments
     
    15941678  (let* ((textview (text-pane-text-view textpane)))
    15951679    (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)))))
    15991687
    16001688;;; This needs to run on the main thread.
Note: See TracChangeset for help on using the changeset viewer.