| [13631] | 1 | ;; ns-object-utils.lisp
|
|---|
| 2 | #|
|
|---|
| 3 | The MIT license.
|
|---|
| 4 |
|
|---|
| 5 | Copyright (c) 2010 Paul L. Krueger
|
|---|
| 6 |
|
|---|
| 7 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software
|
|---|
| 8 | and associated documentation files (the "Software"), to deal in the Software without restriction,
|
|---|
| 9 | including without limitation the rights to use, copy, modify, merge, publish, distribute,
|
|---|
| 10 | sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
|
|---|
| 11 | furnished to do so, subject to the following conditions:
|
|---|
| 12 |
|
|---|
| 13 | The above copyright notice and this permission notice shall be included in all copies or substantial
|
|---|
| 14 | portions of the Software.
|
|---|
| 15 |
|
|---|
| 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
|
|---|
| 17 | LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
|---|
| 18 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
|---|
| 19 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
|---|
| 20 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|---|
| 21 |
|
|---|
| 22 | |#
|
|---|
| 23 |
|
|---|
| 24 |
|
|---|
| 25 | ;; These are useful for manipulating various types of NSObjects using lisp
|
|---|
| 26 |
|
|---|
| 27 | (eval-when (:compile-toplevel :load-toplevel :execute)
|
|---|
| 28 | (require :ns-string-utils)
|
|---|
| 29 | (require :date)
|
|---|
| 30 | (require :decimal))
|
|---|
| 31 |
|
|---|
| 32 |
|
|---|
| 33 | (defpackage :interface-utilities
|
|---|
| 34 | (:nicknames :iu)
|
|---|
| 35 | (:export
|
|---|
| 36 | lisp-to-ns-object
|
|---|
| 37 | lisp-ptr-wrapper
|
|---|
| 38 | lpw-lisp-ptr
|
|---|
| 39 | lpw-depth
|
|---|
| 40 | lpw-parent
|
|---|
| 41 | make-ptr-wrapper
|
|---|
| 42 | ns-to-lisp-object
|
|---|
| 43 | print-ns-object))
|
|---|
| 44 |
|
|---|
| 45 | (in-package :iu)
|
|---|
| 46 |
|
|---|
| 47 | (defun print-ns-object (ns-obj)
|
|---|
| 48 | ;; default print methods for objects truncate strings at 1024 characters for some reason
|
|---|
| 49 | ;; this function doesn't
|
|---|
| 50 | (if (ccl::objc-object-p ns-obj)
|
|---|
| 51 | (format t "~a" (ns-to-lisp-string (#/description ns-obj)))
|
|---|
| 52 | (format t "~s" ns-obj)))
|
|---|
| 53 |
|
|---|
| 54 | (defun ns-to-lisp-object (old-lisp-obj ns-obj &optional (ns-format nil))
|
|---|
| 55 | ;; convert an arbitrary NSObject object to an appropriate lisp object.
|
|---|
| 56 | ;; Often done so that it can replace the old-lisp-obj when edited
|
|---|
| 57 | ;; An empty string @"" returns nil if old-lisp-obj is not a string
|
|---|
| 58 | (cond ((ccl::objc-object-p old-lisp-obj)
|
|---|
| 59 | ;; the old value was an NSObject so just return the new value
|
|---|
| 60 | ns-obj)
|
|---|
| 61 | ((typep ns-obj 'lisp-ptr-wrapper)
|
|---|
| 62 | ;; just strip the wrapper and return the original object
|
|---|
| 63 | (lpw-lisp-ptr ns-obj))
|
|---|
| 64 | ((typep ns-obj 'ns:ns-decimal)
|
|---|
| 65 | (if (floatp old-lisp-obj)
|
|---|
| 66 | ;; convert the decimal to a float
|
|---|
| 67 | (#/doubleValue ns-obj)
|
|---|
| 68 | ;; otherwise convert it to an appropriate lisp integer with assumed
|
|---|
| 69 | ;; decimals (see ip;Utilities;decimal.lisp)
|
|---|
| 70 | (if (eq (first ns-format) :decimal)
|
|---|
| 71 | (lisp-from-ns-decimal ns-obj :decimals (second ns-format))
|
|---|
| 72 | (lisp-from-ns-decimal ns-obj))))
|
|---|
| 73 | ((typep ns-obj 'ns:ns-number)
|
|---|
| 74 | (read-from-string (ns-to-lisp-string (#/descriptionWithLocale: ns-obj (%null-ptr)))
|
|---|
| 75 | nil nil))
|
|---|
| 76 | ((typep ns-obj 'ns:ns-date)
|
|---|
| 77 | (ns-to-lisp-date ns-obj))
|
|---|
| 78 | (t
|
|---|
| 79 | (let ((str (ns-to-lisp-string ns-obj)))
|
|---|
| 80 | (if (stringp old-lisp-obj)
|
|---|
| 81 | str
|
|---|
| 82 | (read-from-string str nil nil))))))
|
|---|
| 83 |
|
|---|
| 84 | (defun lisp-to-ns-object (lisp-obj &optional (ns-format nil))
|
|---|
| 85 | ;; convert an arbitrary lisp object to an appropriate NSObject so
|
|---|
| 86 | ;; that it can be displayed someplace
|
|---|
| 87 | (cond ((ccl::objc-object-p lisp-obj)
|
|---|
| 88 | ;; it's already an NSObject so just return it
|
|---|
| 89 | lisp-obj)
|
|---|
| 90 | ((eq ns-format :date)
|
|---|
| 91 | ;; assume lisp-obj is an integer representing a lisp date
|
|---|
| 92 | (lisp-to-ns-date lisp-obj))
|
|---|
| 93 | ((and (consp ns-format) (eq (first ns-format) :decimal))
|
|---|
| 94 | (cond ((typep lisp-obj 'fixnum)
|
|---|
| 95 | (lisp-to-ns-decimal lisp-obj :decimals (second ns-format)))
|
|---|
| 96 | ((typep lisp-obj 'number)
|
|---|
| 97 | (lisp-to-ns-decimal (round (* (expt 10 (second ns-format)) lisp-obj))
|
|---|
| 98 | :decimals (second ns-format)))
|
|---|
| 99 | (t
|
|---|
| 100 | (lisp-to-ns-decimal 0 :decimals (second ns-format)))))
|
|---|
| 101 | ((integerp lisp-obj)
|
|---|
| 102 | (#/numberWithInt: ns:ns-number lisp-obj))
|
|---|
| 103 | ((typep lisp-obj 'double-float)
|
|---|
| 104 | (#/numberWithDouble: ns:ns-number lisp-obj))
|
|---|
| 105 | ((floatp lisp-obj)
|
|---|
| 106 | (#/numberWithFloat: ns:ns-number lisp-obj))
|
|---|
| 107 | ((null lisp-obj)
|
|---|
| 108 | #@"")
|
|---|
| 109 | (t
|
|---|
| 110 | (lisp-to-temp-nsstring (if (stringp lisp-obj)
|
|---|
| 111 | lisp-obj
|
|---|
| 112 | (format nil "~s" lisp-obj))))))
|
|---|
| 113 |
|
|---|
| 114 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|---|
| 115 | ;; lisp-ptr-wrapper
|
|---|
| 116 | ;;
|
|---|
| 117 | ;; This is a simple class that encapsulates a pointer to a lisp object so we can pass this
|
|---|
| 118 | ;; off to an Objective-C view and know what it points to when we get it back later.
|
|---|
| 119 |
|
|---|
| 120 | (defclass lisp-ptr-wrapper (ns:ns-object)
|
|---|
| 121 | ((lpw-lisp-ptr :accessor lpw-lisp-ptr)
|
|---|
| 122 | (lpw-depth :accessor lpw-depth)
|
|---|
| 123 | (lpw-parent :accessor lpw-parent))
|
|---|
| 124 | (:metaclass ns:+ns-object))
|
|---|
| 125 |
|
|---|
| 126 | (defun make-ptr-wrapper (ptr &key (depth 1) (parent nil))
|
|---|
| 127 | (let ((lpw (make-instance 'lisp-ptr-wrapper)))
|
|---|
| 128 | (setf (lpw-lisp-ptr lpw) ptr)
|
|---|
| 129 | (setf (lpw-depth lpw) depth)
|
|---|
| 130 | (setf (lpw-parent lpw) parent)
|
|---|
| 131 | lpw))
|
|---|
| 132 |
|
|---|
| 133 |
|
|---|
| 134 | (provide :ns-object-utils)
|
|---|