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)))
|