git.fiddlerwoaroof.com
clim-objc-browser.lisp
d5a8a26b
 (defpackage :clim-objc-browser
   (:use :clim-lisp :clim))
 (in-package :clim-objc-browser)
 
 (define-application-frame class-browser ()
   ((classes :initarg :classes :reader classes)
    (visible-classes :initform nil :accessor visible-classes)
    (current-class :initform nil :accessor current-class))
   (:panes (classes :application
                    :incremental-redisplay t
41bef396
                    :display-function 'display-classes
a70ac4c5
                    #+nil(:double-buffering t)
                    )
d5a8a26b
           (methods :application
                    :incremental-redisplay t
                    :display-function 'display-methods)
           (int :interactor))
   (:pointer-documentation t)
   (:layouts (default (vertically ()
                        (horizontally ()
                          classes methods)
                        int)))
   (:default-initargs
41bef396
       :classes (sort (remove-if (serapeum:op
                                   (alexandria:starts-with #\_
                                                           (objc-runtime::objc-class-get-name _)))
d5a8a26b
                                 (objc-runtime::get-classes))
                      #'string-lessp
                      :key 'objc-runtime::objc-class-get-name)))
 
 (defun reset-application-frame ()
   (setf (visible-classes clim:*application-frame*) nil
         (current-class clim:*application-frame*) nil
         (slot-value clim:*application-frame* 'classes)
         (sort (remove-if (serapeum:op (alexandria:starts-with #\_
                                                               (objc-runtime::objc-class-get-name _)))
                          (objc-runtime::get-classes))
               #'string-lessp
               :key 'objc-runtime::objc-class-get-name)))
 
 (define-presentation-type objc-class ())
 (define-presentation-method present (object (type objc-class) stream view &key)
   (declare (ignore view))
   (format stream "#[OBJC Class: ~a]"
           (objc-runtime::objc-class-get-name object)))
 
 (define-presentation-type objc-method ())
 (define-presentation-method present (object (type objc-method) stream view &key)
   (declare (ignore view))
   (format stream "@(~a)"
           (objc-runtime::get-method-name object)))
 
382ab041
 (define-presentation-translator string-to-objc-class (string objc-class class-browser
                                                              :tester ((inp) (objc-runtime:ensure-class inp))
                                                              :tester-definitive t)
     (inp)
   (format *terminal-io* "~&translating ~s to an objc-class" inp)
   (objc-runtime:ensure-class inp))
 
d5a8a26b
 (defun display-classes (frame pane)
   (updating-output (pane :unique-id (or (visible-classes frame)
                                         (classes frame))
                          :id-test 'eq)
     (loop for class in (or (visible-classes frame)
                            (classes frame))
        do
          (updating-output (pane :unique-id (cffi:pointer-address class)
                                 :id-test 'eql
                                 :cache-value class
                                 :cache-test 'eql)
            (with-output-as-presentation (pane class 'objc-class)
              (format pane "~&   ~a~%" (objc-runtime::objc-class-get-name class)))))))
 
 (defun display-methods (frame pane)
   (updating-output (pane :unique-id (current-class frame)
                          :id-test 'eq)
     (when (current-class frame)
       (loop for method in (sort (objc-runtime::get-methods (current-class frame))
                                 'string<
                                 :key 'objc-runtime::get-method-name)
          do
            (with-output-as-presentation (pane method 'objc-method)
              (format pane "   Method: ~a~%" (objc-runtime::get-method-name method)))))))
 
 (define-class-browser-command (com-get-methods :name t :menu t) ((the-class objc-class :gesture :select))
382ab041
   (if (cffi:pointerp the-class)
       (setf (current-class *application-frame*) the-class)
       (format *terminal-io* "~&The value ~s is not a pointer to a class, but a ~s" the-class (type-of the-class))))
d5a8a26b
 
 
 (define-class-browser-command (com-refresh-classes :name t :menu t) ()
   (reset-application-frame))
 
 (define-class-browser-command (com-filter-classes :name t :menu t) ((prefix string))
   (setf (visible-classes *application-frame*)
         (remove-if-not (serapeum:op
                          (alexandria:starts-with-subseq prefix _ :test #'char-equal))
                        (classes *application-frame*)
                        :key 'objc-runtime::objc-class-get-name)))
 
 (defun main ()
   (clim:run-frame-top-level
    (clim:make-application-frame 'class-browser)))