Changeset 6788


Ignore:
Timestamp:
Jul 6, 2007, 12:00:19 PM (17 years ago)
Author:
Gary Byers
Message:

Move towards multiple typeout panels.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/ide-1.0/ccl/examples/cocoa-typeout.lisp

    r6765 r6788  
    55
    66;;
    7 ;; the typeout panel is just an ns-panel containing a scroll-view
     7;; a typeout window is just an ns-window containing a scroll-view
    88;; which contains a text-view. The text is read only.
    99;;
    10 ;; There is only one panel which is created with the first invocation
    11 ;; of the 'shared-panel class method. The panel is bound to the
    12 ;; variable ccl::*typeout-panel*
    13 ;;
    14 ;; the panel is implicitly bound to a stream, and text written to
     10;; the window is implicitly bound to a stream, and text written to
    1511;; the stream is written into the text-view object. The stream is
    1612;; available via the function (ccl::typeout-stream)
    1713;;
    18 ;; the panel width is set to 600 pixels, which is fine since hemlock
    19 ;; looks like it wants to wrap the documentation at 80 characters
    20 ;; anyway. In the long run this window should use a variable size font
    21 ;; and maybe compute the width as 80 times the width of the letter W.
    22 ;;
    23 ;; I'll revisit this after the preferences are more defined.
    24 ;;
     14
    2515;; @class typeout-view
    2616;;
    2717(defclass typeout-view (ns:ns-view)
    2818  ((scroll-view :foreign-type :id :reader typeout-view-scroll-view)
    29    (text-view :foreign-type :id :reader typeout-view-text-view)
    30    (text-storage :foreign-type :id :reader typeout-view-text-storage))
     19   (text-view :foreign-type :id :reader typeout-view-text-view))
    3120  (:metaclass ns:+ns-object))
     21
     22(defclass typeout-text-view (ns:ns-text-view)
     23    ()
     24  (:metaclass ns:+ns-object))
     25
     26(objc:defmethod (#/clearAll: :void) ((self typeout-text-view))
     27  (#/selectAll: self +null-ptr+)
     28  (#/delete: self +null-ptr+))
     29
     30(objc:defmethod (#/insertText: :void) ((self typeout-text-view) text)
     31  (#/setEditable: self t)
     32  (call-next-method text)
     33  (#/setEditable: self nil))
     34
    3235
    3336(objc:defmethod #/initWithFrame: ((self typeout-view) (frame :<NSR>ect))
     
    3841    (#/setBorderType: scrollview #$NSBezelBorder)
    3942    (#/setHasVerticalScroller: scrollview t)
    40     (#/setHasHorizontalScroller: scrollview nil)
     43    (#/setHasHorizontalScroller: scrollview t)
    4144    (#/setRulersVisible: scrollview nil)
    42     (#/setAutoresizingMask: scrollview #$NSViewHeightSizable)
     45    (#/setAutoresizingMask: scrollview (logior #$NSViewWidthSizable #$NSViewHeightSizable))
    4346    (#/setAutoresizesSubviews: scroll-content t)
    4447    (#/addSubview: self scrollview)
     
    4649    (let* ((contentsize (#/contentSize scrollview)))
    4750      (ns:with-ns-rect (text-frame 0 0 (ns:ns-size-width contentsize) (ns:ns-size-height contentsize))
    48         (let* ((text-view (make-instance 'ns:ns-text-view
    49                                          :with-frame text-frame))
    50                (text-storage (#/textStorage text-view)))
     51        (let* ((text-view (make-instance 'typeout-text-view
     52                                         :with-frame text-frame)))
    5153          (#/setEditable: text-view nil)
    52           (setf (slot-value self 'text-storage) text-storage)
     54          (#/setHorizontallyResizable: text-view t)
     55          (#/setAutoresizingMask: text-view #$NSViewWidthSizable)
     56          (#/setTypingAttributes: text-view (create-text-attributes
     57                                  :font (default-font :name *default-font-name* :size *default-font-size*)
     58                                  :line-break-mode :char))
    5359          (#/setDocumentView: scrollview text-view)
     60          (ns:with-ns-size (container-size 1.0f7 1.0f7)
     61          (let* ((layout (#/layoutManager text-view))
     62                 (container (make-instance 'ns:ns-text-container
     63                                           :with-container-size container-size)))
     64            (#/setWidthTracksTextView: container t)
     65            (#/setHeightTracksTextView: container nil)
     66            (#/addTextContainer: layout container)))
     67       
    5468          (setf (slot-value self 'text-view) text-view)))))
    5569  self)
     
    5872;; @class typeout-panel
    5973;;
    60 (defloadvar *typeout-panel* nil)
     74(defloadvar *typeout-window* nil)
    6175
    62 (defclass typeout-panel (ns:ns-panel)
    63     ((typeout-view :foreign-type :id :accessor typeout-panel-typeout-view))
     76(defclass typeout-window (ns:ns-window)
     77    ((typeout-view :foreign-type :id :accessor typeout-window-typeout-view))
    6478  (:metaclass ns:+ns-object))
    6579
    66 (objc:defmethod #/sharedPanel ((self +typeout-panel))
    67    (cond (*typeout-panel*)
     80(defloadvar *typeout-windows* ())
     81(defstatic *typeout-windows-lock* (make-lock))
     82
     83(defun get-typeout-window (title)
     84  (with-lock-grabbed (*typeout-windows-lock*)
     85    (when *typeout-windows*
     86      (let* ((w (pop *typeout-windows*)))
     87        (set-window-title w title)
     88        w))))
     89
     90(objc:defmethod #/typeoutWindowWithTitle: ((self +typeout-window) title)
     91  (let* ((panel (new-cocoa-window :class self
     92                                  :title title
     93                                  :width 600
     94                                  :activate nil)))
     95    (#/setReleasedWhenClosed: panel nil)
     96    (let* ((view (make-instance 'typeout-view :with-frame (#/bounds (#/contentView panel)))))
     97      (#/setAutoresizingMask: view (logior
     98                                    #$NSViewWidthSizable
     99                                    #$NSViewHeightSizable))
     100      (#/setContentView: panel view)
     101      (#/setNeedsDisplay: view t)
     102      (setf (slot-value panel 'typeout-view) view)
     103      panel)))
     104
     105(objc:defmethod #/sharedPanel ((self +typeout-window))
     106   (cond (*typeout-window*)
    68107         (t
    69           (let* ((panel (new-cocoa-window :class self
    70                                           :title "Typeout"
    71                                           :width 600
    72                                           :activate nil)))
    73             (ns:with-ns-size (size 600 10000)
    74                              (#/setMaxSize: panel size)
    75                              (setf (ns:ns-size-height size) 1)
    76                              (#/setMinSize: panel size))
    77             (let* ((view (make-instance 'typeout-view :with-frame (#/bounds (#/contentView panel)))))
    78               (#/setContentView: panel view)
    79               (#/setNeedsDisplay: view t)
    80               (setf (slot-value panel 'typeout-view) view)
    81               (setq *typeout-panel* panel))))))
    82 
    83 (objc:defmethod #/init ((self typeout-panel))
    84   (let* ((class (class-of self)))
    85     (#/dealloc self)
    86     (#/sharedPanel class)))
     108          (setq *typeout-window* (#/typeoutWindowWithTitle: self "Typeout")))))
    87109
    88110
    89 (objc:defmethod (#/show :void) ((self typeout-panel))
    90   (#/orderFront: self +null-ptr+))
    91111
    92 (defloadvar *typeout-attributes* nil)
     112(objc:defmethod (#/close :void) ((self typeout-window))
     113  (call-next-method)
     114  (unless (eql self *typeout-window*)
     115    (with-lock-grabbed (*typeout-windows-lock*)
     116      (push (%inc-ptr self 0) *typeout-windows*))))
     117
     118
     119
     120(objc:defmethod (#/show :void) ((self typeout-window))
     121  (#/makeKeyAndOrderFront: self +null-ptr+))
     122
    93123
    94124(defclass typeout-stream (fundamental-character-output-stream)
    95   ((text-storage :initform nil :accessor typeout-stream-text-storage)
    96    (line-number :initform 0 :accessor typeout-stream-line-number)
    97    (line-position :initform 0 :accessor typeout-stream-line-position)))
     125  ((string-stream :initform (make-string-output-stream))
     126   (window :initform (#/sharedPanel typeout-window) :initarg :window)))
    98127
    99128(defun prepare-typeout-stream (stream)
    100   (let ((panel (#/sharedPanel typeout-panel)))
    101     (unless (typeout-stream-text-storage stream)
    102       (setf (typeout-stream-text-storage stream) (typeout-view-text-storage (typeout-panel-typeout-view panel))))
    103     (unless *typeout-attributes*
    104       (setf *typeout-attributes* (create-text-attributes
    105                                   :font (default-font :name *default-font-name* :size *default-font-size*)
    106                                   :line-break-mode :word)))
    107     (#/show panel)))
     129  (declare (ignorable stream))
     130  (with-slots (window) stream
     131    (#/show window)))
    108132
    109133
     
    115139(defmethod stream-write-char ((stream typeout-stream) char)
    116140  (prepare-typeout-stream stream)
    117   ;;
    118   ;;  convert tabs to spaces.
    119   ;;
    120   (if (eq char #\tab)
    121       (return-from stream-write-char
    122         (progn
    123           (format stream "(make-string (- 8 (mod ~A 8)) :initial-element #\space)~%" (typeout-stream-line-position stream))
    124           (stream-write-string stream (make-string (- 8 (mod (typeout-stream-line-position stream) 8))
    125                                                    :initial-element #\space)))))
    126 
    127   ;;
    128   ;;  Maybe convert non-printable characters to something else?
    129   ;;  This is a problem for the editor, but probably not here.
    130 
    131   ;;
    132   ;;  adjust the line and column #s accordingly
    133   ;;
    134   (if (eq char #\newline)
    135       (progn
    136         (incf (typeout-stream-line-number stream))
    137         (setf (typeout-stream-line-position stream) 0))
    138     (incf (typeout-stream-line-position stream)))
    139 
    140   ;;
    141   ;;  print the character by converting it to a string and appending
    142   ;;  it to the text-storage buffer.
    143   ;;
    144   (let* ((the-typeout-view (typeout-panel-typeout-view *typeout-panel*))
    145          (text-storage (slot-value the-typeout-view 'text-storage))
    146          (str (make-string 1 :initial-element char))
    147          (attr-str (make-instance 'ns:ns-attributed-string
    148                                   :with-string str
    149                                   :attributes *typeout-attributes*)))
    150     (#/appendAttributedString: text-storage attr-str)))
     141  (write-char char (slot-value stream 'string-stream)))
    151142
    152143(defmethod stream-write-string ((stream typeout-stream) string &optional (start 0) end)
    153144  (prepare-typeout-stream stream)
    154   (let* ((str (if start
    155                   (subseq string start end)
    156                 string))
    157          (attr-str (make-instance 'ns:ns-attributed-string
    158                                   :with-string str
    159                                   :attributes *typeout-attributes*))
    160          (the-typeout-view (typeout-panel-typeout-view *typeout-panel*))
    161          (text-storage (slot-value the-typeout-view 'text-storage)))
    162     (setf (typeout-stream-line-position stream) (length string))
    163     (#/appendAttributedString: text-storage attr-str)))
     145  (write-string (if (and (eql start 0) (or (null end) (eql end (length string))))
     146                    string
     147                    (subseq string start end))
     148                (slot-value stream 'string-stream)))
    164149
     150 
    165151(defmethod stream-fresh-line ((stream typeout-stream))
    166152  (prepare-typeout-stream stream)
    167   (stream-write-char stream #\newline))
     153  (fresh-line (slot-value stream 'string-stream)))
    168154
    169155(defmethod stream-line-column ((stream typeout-stream))
    170   (typeout-stream-line-position stream))
     156  (stream-line-column (slot-value stream 'string-stream)))
    171157
    172158(defmethod stream-clear-output ((stream typeout-stream))
    173159  (prepare-typeout-stream stream)
    174   (let* ((the-typeout-view (typeout-panel-typeout-view *typeout-panel*))
    175          (text-storage (slot-value the-typeout-view 'text-storage))
    176          (len (#/length text-storage)))
    177     (declare (type ns:ns-text-storage text-storage))
     160  (let* ((window (slot-value stream 'window))
     161         (the-typeout-view (typeout-window-typeout-view window))
     162         (text-view (slot-value the-typeout-view 'text-view))
     163         (string-stream (slot-value stream 'string-stream)))
     164    (get-output-stream-string string-stream)
    178165    (#/performSelectorOnMainThread:withObject:waitUntilDone:
    179      text-storage
    180      (@selector #/beginEditing)
     166     text-view
     167     (@selector #/clearAll:)
    181168     +null-ptr+
    182      t)
    183     (#/deleteCharactersInRange: text-storage (ns:make-ns-range 0 len))))
     169     t)))
    184170
    185171(defmethod stream-force-output ((stream typeout-stream))
    186   (let* ((the-typeout-view (typeout-panel-typeout-view *typeout-panel*))
    187          (text-storage (slot-value the-typeout-view 'text-storage)))
     172  (let* ((window (slot-value stream 'window))
     173         (the-typeout-view (typeout-window-typeout-view window))
     174         (text-view (slot-value the-typeout-view 'text-view)))
    188175    (#/performSelectorOnMainThread:withObject:waitUntilDone:
    189      text-storage
    190      (@selector #/endEditing)
    191      +null-ptr+
     176     text-view
     177     (@selector #/insertText:)
     178     (%make-nsstring (get-output-stream-string (slot-value stream 'string-stream)))
    192179     t)))
    193180 
    194181
     182(defloadvar *typeout-stream* nil)
    195183
    196 (defloadvar *typeout-stream* (make-instance 'typeout-stream))
     184(defun typeout-stream (&optional title)
     185  (if (null title)
     186    (or *typeout-stream*
     187        (setq *typeout-stream* (make-instance 'typeout-stream)))
     188    (make-instance 'typeout-stream :window (#/typeoutWindowWithTitle: typeout-window (%make-nsstring (format nil "~a" title))))))
    197189
    198 (defun typeout-stream ()
    199   *typeout-stream*)
    200 
Note: See TracChangeset for help on using the changeset viewer.