| [13390] | 1 | ;;; package-view.lisp
|
|---|
| 2 |
|
|---|
| 3 | #|
|
|---|
| 4 | The MIT license.
|
|---|
| 5 |
|
|---|
| 6 | Copyright (c) 2010 Paul L. Krueger
|
|---|
| 7 |
|
|---|
| 8 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software
|
|---|
| 9 | and associated documentation files (the "Software"), to deal in the Software without restriction,
|
|---|
| 10 | including without limitation the rights to use, copy, modify, merge, publish, distribute,
|
|---|
| 11 | sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
|
|---|
| 12 | furnished to do so, subject to the following conditions:
|
|---|
| 13 |
|
|---|
| 14 | The above copyright notice and this permission notice shall be included in all copies or substantial
|
|---|
| 15 | portions of the Software.
|
|---|
| 16 |
|
|---|
| 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
|
|---|
| 18 | LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
|---|
| 19 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
|---|
| 20 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
|---|
| 21 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|---|
| 22 |
|
|---|
| 23 | |#
|
|---|
| 24 |
|
|---|
| [13646] | 25 | (eval-when (:compile-toplevel :load-toplevel :execute)
|
|---|
| 26 | (require :nib))
|
|---|
| [13390] | 27 |
|
|---|
| 28 | (defpackage :package-view
|
|---|
| 29 | (:nicknames :pv)
|
|---|
| 30 | (:use :ccl :common-lisp)
|
|---|
| 31 | (:export test-package))
|
|---|
| 32 |
|
|---|
| 33 | (in-package :pv)
|
|---|
| 34 |
|
|---|
| 35 | ;;; Sample lisp/Cocoa interface that uses a NIB file defined with interface builder;
|
|---|
| 36 | ;;; A definition is provided for the "SpeechController" class that was specified to interface builder
|
|---|
| 37 | ;;; as the class of the NIB file owner.
|
|---|
| 38 | ;;; We manually create an instance of SpeechController and specify it as the owner for the NIB file.
|
|---|
| 39 |
|
|---|
| 40 | (defclass package-view-controller (ns:ns-object)
|
|---|
| 41 | ((package-table :foreign-type :id :accessor package-table)
|
|---|
| 42 | (use-table :foreign-type :id :accessor use-table)
|
|---|
| 43 | (used-by-table :foreign-type :id :accessor used-by-table)
|
|---|
| 44 | (current-package :accessor current-package :initform nil)
|
|---|
| 45 | (current-nicknames :accessor current-nicknames :initform nil)
|
|---|
| 46 | (all-packages :accessor all-packages :initform nil)
|
|---|
| 47 | (current-package-use-list :accessor current-package-use-list :initform nil)
|
|---|
| 48 | (current-package-used-by-list :accessor current-package-used-by-list :initform nil)
|
|---|
| 49 | (window-controller :accessor window-controller :initform nil))
|
|---|
| 50 | (:metaclass ns:+ns-object))
|
|---|
| 51 |
|
|---|
| 52 | (defmethod initialize-instance :after ((self package-view-controller)
|
|---|
| 53 | &key &allow-other-keys)
|
|---|
| 54 | (let ((pkgs (list-all-packages)))
|
|---|
| 55 | (setf (all-packages self) (make-array (list (list-length pkgs))
|
|---|
| 56 | :initial-contents pkgs)))
|
|---|
| 57 | (let ((nib-name (ccl::%make-nsstring
|
|---|
| 58 | (namestring (truename "ip:PackageView;packageview.nib")))))
|
|---|
| 59 | (setf (window-controller self)
|
|---|
| 60 | (make-instance ns:ns-window-controller
|
|---|
| 61 | :with-window-nib-path nib-name
|
|---|
| 62 | :owner self))
|
|---|
| 63 | ;; Now make the controller load the nib file and make the window visible
|
|---|
| 64 | (#/window (window-controller self))
|
|---|
| 65 | (#/release nib-name))
|
|---|
| 66 | ;; we do the following so that ccl:terminate will be called before we are garbage
|
|---|
| 67 | ;; collected and we can release the window-controller that we created
|
|---|
| 68 | (ccl:terminate-when-unreachable self))
|
|---|
| 69 |
|
|---|
| 70 | (defmethod ccl:terminate ((self package-view-controller))
|
|---|
| 71 | (#/release (window-controller self)))
|
|---|
| 72 |
|
|---|
| 73 | ;; Initialization methods called when the nib file is loaded
|
|---|
| 74 | ;; These initialize links from this package-view-controller to the text-views we defined
|
|---|
| 75 | ;; to display things. Names correspond to the outlet names we defined for the
|
|---|
| 76 | ;; PackageViewController class as file-owner in IB.
|
|---|
| 77 |
|
|---|
| 78 | (objc:defmethod (#/setPackageTable: :void)
|
|---|
| 79 | ((self package-view-controller) (tab :id))
|
|---|
| 80 | (setf (package-table self) tab)
|
|---|
| 81 | ;; Table may already have initialized before this link was set. Tell it to reload
|
|---|
| 82 | ;; just in case.
|
|---|
| 83 | (#/reloadData tab))
|
|---|
| 84 |
|
|---|
| 85 | (objc:defmethod (#/setUseTable: :void)
|
|---|
| 86 | ((self package-view-controller) (tab :id))
|
|---|
| 87 | (setf (use-table self) tab)
|
|---|
| 88 | ;; Table may already have initialized before this link was set. Tell it to reload
|
|---|
| 89 | ;; just in case
|
|---|
| 90 | (#/reloadData tab))
|
|---|
| 91 |
|
|---|
| 92 | (objc:defmethod (#/setUseByTable: :void)
|
|---|
| 93 | ((self package-view-controller) (tab :id))
|
|---|
| 94 | (setf (used-by-table self) tab)
|
|---|
| 95 | ;; Table may already have initialized before this link was set. Tell it to reload just in case
|
|---|
| 96 | (#/reloadData tab))
|
|---|
| 97 |
|
|---|
| 98 | ;; Methods called because we linked this class (as file owner) via the data-source outlet for
|
|---|
| 99 | ;; our text views in IB
|
|---|
| 100 |
|
|---|
| 101 | (objc:defmethod (#/numberOfRowsInTableView: #>NSInteger)
|
|---|
| 102 | ((self package-view-controller) (tab :id))
|
|---|
| 103 | (cond ((eql tab (package-table self))
|
|---|
| 104 | (array-dimension (all-packages self) 0))
|
|---|
| 105 | ((eql tab (use-table self))
|
|---|
| 106 | (if (current-package-use-list self)
|
|---|
| 107 | (array-dimension (current-package-use-list self) 0)
|
|---|
| 108 | 0))
|
|---|
| 109 | ((eql tab (used-by-table self))
|
|---|
| 110 | (if (current-package-used-by-list self)
|
|---|
| 111 | (array-dimension (current-package-used-by-list self) 0)
|
|---|
| 112 | 0))
|
|---|
| 113 | (t
|
|---|
| 114 | ;; We can get called before the links are initialized. If so, return 0
|
|---|
| 115 | 0)))
|
|---|
| 116 |
|
|---|
| 117 | (objc:defmethod (#/tableView:objectValueForTableColumn:row: :id)
|
|---|
| 118 | ((self package-view-controller)
|
|---|
| 119 | (tab :id)
|
|---|
| 120 | (col :id)
|
|---|
| 121 | (row #>NSInteger))
|
|---|
| 122 | (let ((ret-str nil))
|
|---|
| 123 | (cond ((eql tab (package-table self))
|
|---|
| 124 | (let ((col-id (ccl::lisp-string-from-nsstring (#/identifier col))))
|
|---|
| 125 | (setf ret-str (ccl::%make-nsstring
|
|---|
| 126 | (if (string= col-id "1")
|
|---|
| 127 | (package-name (svref (all-packages self) row))
|
|---|
| 128 | (format nil
|
|---|
| 129 | "~{~a~^,~}"
|
|---|
| 130 | (package-nicknames
|
|---|
| 131 | (svref (all-packages self) row))))))))
|
|---|
| 132 | ((eql tab (use-table self))
|
|---|
| 133 | (setf ret-str (ccl::%make-nsstring
|
|---|
| 134 | (if (current-package-use-list self)
|
|---|
| 135 | (package-name (svref (current-package-use-list self) row))
|
|---|
| 136 | ""))))
|
|---|
| 137 | ((eql tab (used-by-table self))
|
|---|
| 138 | (setf ret-str (ccl::%make-nsstring
|
|---|
| 139 | (if (current-package-used-by-list self)
|
|---|
| 140 | (package-name (svref (current-package-used-by-list self) row))
|
|---|
| 141 | ""))))
|
|---|
| 142 | (t
|
|---|
| 143 | (error "~s is not a linked view (~s, ~s, or ~s)"
|
|---|
| 144 | tab
|
|---|
| 145 | (package-table self)
|
|---|
| 146 | (use-table self)
|
|---|
| 147 | (used-by-table self))))
|
|---|
| 148 | (#/autorelease ret-str)
|
|---|
| 149 | ret-str))
|
|---|
| 150 |
|
|---|
| 151 | ;; Methods called because we linked this class (as file owner) via the text-view delegate outlets in IB
|
|---|
| 152 |
|
|---|
| 153 |
|
|---|
| 154 | (objc:defmethod (#/tableViewSelectionDidChange: :void)
|
|---|
| 155 | ((self package-view-controller) (notif :id))
|
|---|
| 156 | (let ((tab (#/object notif)))
|
|---|
| 157 | (when (eql tab (package-table self))
|
|---|
| 158 | ;; change the other two tables to reflect the package selected
|
|---|
| 159 | (let* ((pkg (svref (all-packages self) (#/selectedRow (package-table self))))
|
|---|
| 160 | (pkgs-used (package-use-list pkg))
|
|---|
| 161 | (pkgs-using (package-used-by-list pkg)))
|
|---|
| 162 | (setf (current-package-use-list self)
|
|---|
| 163 | (make-array (list (list-length pkgs-used)) :initial-contents pkgs-used))
|
|---|
| 164 | (setf (current-package-used-by-list self)
|
|---|
| 165 | (make-array (list (list-length pkgs-using)) :initial-contents pkgs-using))
|
|---|
| 166 | (#/reloadData (use-table self))
|
|---|
| 167 | (#/reloadData (used-by-table self))))))
|
|---|
| 168 |
|
|---|
| 169 |
|
|---|
| 170 | ;; Methods called because we linked this class (as file owner) via the Window delegate outlet in IB
|
|---|
| 171 |
|
|---|
| 172 | ;; test by
|
|---|
| 173 | (defun test-package ()
|
|---|
| 174 | (make-instance 'package-view-controller))
|
|---|
| 175 |
|
|---|
| 176 | (provide :package-view)
|
|---|