Browse code
Wire up the buttons in the nib file.
Ed L authored on 10/01/2018 08:15:50
Showing 3 changed files
Showing 3 changed files
... | ... |
@@ -11,9 +11,12 @@ |
11 | 11 |
</connections> |
12 | 12 |
</customObject> |
13 | 13 |
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/> |
14 |
- <customObject id="-3" userLabel="Application"/> |
|
14 |
+ <customObject id="-3" userLabel="Application" customClass="NSObject"/> |
|
15 | 15 |
<customObject id="Voe-Tx-rLC" customClass="AppDelegate"> |
16 | 16 |
<connections> |
17 |
+ <outlet property="actionButton" destination="tsC-6t-n8w" id="1do-fU-4Vq"/> |
|
18 |
+ <outlet property="alertButton" destination="B58-6z-vcj" id="sNy-nL-OXG"/> |
|
19 |
+ <outlet property="profitButton" destination="kpz-zw-hNc" id="eR3-2l-bVP"/> |
|
17 | 20 |
<outlet property="window" destination="QvC-M9-y7g" id="gIp-Ho-8D9"/> |
18 | 21 |
</connections> |
19 | 22 |
</customObject> |
... | ... |
@@ -685,6 +688,7 @@ |
685 | 688 |
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/> |
686 | 689 |
<rect key="contentRect" x="335" y="390" width="130" height="127"/> |
687 | 690 |
<rect key="screenRect" x="0.0" y="0.0" width="1680" height="1050"/> |
691 |
+ <value key="minSize" type="size" width="130" height="127"/> |
|
688 | 692 |
<view key="contentView" wantsLayer="YES" id="EiT-Mj-1SZ"> |
689 | 693 |
<rect key="frame" x="0.0" y="0.0" width="130" height="127"/> |
690 | 694 |
<autoresizingMask key="autoresizingMask"/> |
... | ... |
@@ -698,6 +702,9 @@ |
698 | 702 |
</button> |
699 | 703 |
<button identifier="QButton" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="B58-6z-vcj"> |
700 | 704 |
<rect key="frame" x="14" y="46" width="102" height="32"/> |
705 |
+ <constraints> |
|
706 |
+ <constraint firstAttribute="height" constant="21" id="4bY-Mh-ivB"/> |
|
707 |
+ </constraints> |
|
701 | 708 |
<buttonCell key="cell" type="push" title="???" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="fM6-sP-hqC"> |
702 | 709 |
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/> |
703 | 710 |
<font key="font" metaFont="system"/> |
... | ... |
@@ -712,21 +719,21 @@ |
712 | 719 |
</button> |
713 | 720 |
</subviews> |
714 | 721 |
<constraints> |
715 |
- <constraint firstItem="kpz-zw-hNc" firstAttribute="leading" secondItem="EiT-Mj-1SZ" secondAttribute="leading" constant="20" id="FUw-ts-Dvv"/> |
|
716 |
- <constraint firstItem="kpz-zw-hNc" firstAttribute="top" secondItem="B58-6z-vcj" secondAttribute="bottom" constant="12" id="Mo0-Fq-Ekv"/> |
|
717 |
- <constraint firstAttribute="trailing" secondItem="B58-6z-vcj" secondAttribute="trailing" constant="20" id="PrU-3Q-xbT"/> |
|
718 |
- <constraint firstItem="B58-6z-vcj" firstAttribute="top" secondItem="tsC-6t-n8w" secondAttribute="bottom" constant="12" id="R99-fb-R0a"/> |
|
719 |
- <constraint firstAttribute="trailing" secondItem="kpz-zw-hNc" secondAttribute="trailing" constant="20" id="cXz-s9-bm0"/> |
|
720 |
- <constraint firstItem="tsC-6t-n8w" firstAttribute="top" secondItem="EiT-Mj-1SZ" secondAttribute="top" constant="20" id="fgb-wQ-bYz"/> |
|
721 |
- <constraint firstItem="tsC-6t-n8w" firstAttribute="leading" secondItem="EiT-Mj-1SZ" secondAttribute="leading" constant="20" id="gkO-dz-KSN"/> |
|
722 |
- <constraint firstAttribute="trailing" secondItem="tsC-6t-n8w" secondAttribute="trailing" constant="20" id="kvv-3f-CPP"/> |
|
723 |
- <constraint firstItem="B58-6z-vcj" firstAttribute="leading" secondItem="EiT-Mj-1SZ" secondAttribute="leading" constant="20" id="pxX-yN-nxG"/> |
|
724 |
- <constraint firstItem="B58-6z-vcj" firstAttribute="width" secondItem="tsC-6t-n8w" secondAttribute="width" id="raD-LI-R65"/> |
|
725 |
- <constraint firstItem="kpz-zw-hNc" firstAttribute="width" secondItem="B58-6z-vcj" secondAttribute="width" id="sko-eC-fdc"/> |
|
726 |
- <constraint firstAttribute="bottom" secondItem="kpz-zw-hNc" secondAttribute="bottom" constant="20" id="zFb-Pu-3aJ"/> |
|
722 |
+ <constraint firstItem="kpz-zw-hNc" firstAttribute="leading" secondItem="B58-6z-vcj" secondAttribute="leading" id="5b9-mG-fdb"/> |
|
723 |
+ <constraint firstAttribute="trailing" secondItem="tsC-6t-n8w" secondAttribute="trailing" constant="20" id="698-FB-H88"/> |
|
724 |
+ <constraint firstItem="tsC-6t-n8w" firstAttribute="top" secondItem="EiT-Mj-1SZ" secondAttribute="top" constant="20" id="AU4-Qz-TKg"/> |
|
725 |
+ <constraint firstItem="B58-6z-vcj" firstAttribute="leading" secondItem="tsC-6t-n8w" secondAttribute="leading" id="FPZ-ws-33F"/> |
|
726 |
+ <constraint firstItem="B58-6z-vcj" firstAttribute="top" secondItem="tsC-6t-n8w" secondAttribute="bottom" constant="12" id="MRa-zq-5sy"/> |
|
727 |
+ <constraint firstItem="kpz-zw-hNc" firstAttribute="width" secondItem="B58-6z-vcj" secondAttribute="width" id="Nvf-uM-pjC"/> |
|
728 |
+ <constraint firstAttribute="bottom" secondItem="tsC-6t-n8w" secondAttribute="bottom" constant="86" id="OOB-Ll-lhm"/> |
|
729 |
+ <constraint firstItem="B58-6z-vcj" firstAttribute="width" secondItem="tsC-6t-n8w" secondAttribute="width" id="S8Y-hC-OzM"/> |
|
730 |
+ <constraint firstItem="kpz-zw-hNc" firstAttribute="top" secondItem="B58-6z-vcj" secondAttribute="bottom" constant="12" id="SpV-Go-sxH"/> |
|
731 |
+ <constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="kpz-zw-hNc" secondAttribute="trailing" constant="20" symbolic="YES" id="bgf-3t-GzH"/> |
|
732 |
+ <constraint firstItem="tsC-6t-n8w" firstAttribute="leading" secondItem="EiT-Mj-1SZ" secondAttribute="leading" constant="20" id="xdm-k8-1Yj"/> |
|
733 |
+ <constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="B58-6z-vcj" secondAttribute="trailing" constant="20" symbolic="YES" id="ygs-9c-Ai1"/> |
|
727 | 734 |
</constraints> |
728 | 735 |
</view> |
729 |
- <point key="canvasLocation" x="-36" y="44.5"/> |
|
736 |
+ <point key="canvasLocation" x="-36" y="48.5"/> |
|
730 | 737 |
</window> |
731 | 738 |
</objects> |
732 | 739 |
</document> |
... | ... |
@@ -90,46 +90,88 @@ |
90 | 90 |
,(coerce h 'double-float))) |
91 | 91 |
'(:struct objc-runtime:ns-rect))) |
92 | 92 |
|
93 |
-(defun show-alert (message) |
|
93 |
+(defun show-alert (message &optional (informative-text "Informative Text!")) |
|
94 | 94 |
(let ((alert [[#@NSAlert @(alloc)] @(init)])) |
95 |
- [alert @(setMessageText:) :pointer @"message"] |
|
96 |
- [alert @(setInformativeText:) :pointer @"Informative text."] |
|
95 |
+ [alert @(setMessageText:) :pointer (objc-runtime::make-nsstring message)] |
|
96 |
+ [alert @(setInformativeText:) :pointer (objc-runtime::make-nsstring informative-text)] |
|
97 | 97 |
[alert @(addButtonWithTitle:) :pointer @"OK"] |
98 | 98 |
[alert @(addButtonWithTitle:) :pointer @"Cancel"] |
99 | 99 |
[alert @(runModal)])) |
100 | 100 |
|
101 |
-(cffi:defcallback button-action :void ((a :pointer) (b :pointer) (sender :pointer)) |
|
101 |
+(cffi:defcallback do-things-action :void ((a :pointer) (b :pointer) (sender :pointer)) |
|
102 |
+ (declare (ignore a b sender)) |
|
103 |
+ (show-alert "Starting Swank" |
|
104 |
+ "Loading Quicklisp from ~/quicklisp/setup.lisp + starting swank") |
|
105 |
+ |
|
106 |
+ (load "~/quicklisp/setup.lisp") |
|
107 |
+ (funcall (intern "QUICKLOAD" (find-package :QL)) :swank) |
|
108 |
+ (funcall (intern "CREATE-SERVER" (find-package :swank)) :port 5060 :dont-close t) |
|
109 |
+ |
|
110 |
+ (show-alert "Started swank on 5060")) |
|
111 |
+ |
|
112 |
+(cffi:defcallback alert-action :void ((a :pointer) (b :pointer) (sender :pointer)) |
|
102 | 113 |
(declare (ignore a b sender)) |
103 | 114 |
(show-alert "Hello There!")) |
104 | 115 |
|
105 |
-(defun make-button-delegate (button) |
|
116 |
+(cffi:defcallback profit-action :void ((a :pointer) (b :pointer) (sender :pointer)) |
|
117 |
+ (declare (ignore a b sender)) |
|
118 |
+ (show-alert "That Was Profitable!")) |
|
119 |
+ |
|
120 |
+(defun make-button-delegate (button cb) |
|
106 | 121 |
(let ((my-class (objc-runtime::objc-allocate-class-pair #@NSObject "ButtonDel" 0))) |
107 | 122 |
(with-selectors ((do-magic "doMagic:") (set-target "setTarget:") (set-action "setAction:") |
108 | 123 |
alloc init) |
109 |
- (objc-runtime::class-add-method my-class do-magic (cffi:callback button-action) |
|
110 |
- "v@:@") |
|
124 |
+ (objc-runtime::class-add-method my-class do-magic cb "v@:@") |
|
111 | 125 |
(fw.lu:prog1-bind (result [[my-class alloc] init]) |
112 | 126 |
[button set-target :pointer result] |
113 | 127 |
[button set-action :pointer do-magic])))) |
114 | 128 |
|
129 |
+(defun make-app-delegate-class (outlets) |
|
130 |
+ (let ((app-delegate-class (objc-runtime::objc-allocate-class-pair |
|
131 |
+ #@NSObject "AppDelegate" 0))) |
|
132 |
+ (objc-runtime::add-pointer-ivar app-delegate-class "window") |
|
133 |
+ (objc-runtime::add-pointer-ivar app-delegate-class "delegate") |
|
134 |
+ |
|
135 |
+ (loop for outlet in outlets do |
|
136 |
+ (objc-runtime::add-pointer-ivar app-delegate-class outlet)) |
|
137 |
+ |
|
138 |
+ app-delegate-class)) |
|
139 |
+ |
|
140 |
+(defun load-nib (name) |
|
141 |
+ ;; find and activate the nib |
|
142 |
+ (let* ((bundle [#@NSBundle @(mainBundle)]) |
|
143 |
+ (nib [[#@NSNib @(alloc)] @(initWithNibNamed:bundle:) |
|
144 |
+ :pointer (objc-runtime::make-nsstring name) |
|
145 |
+ :pointer bundle])) |
|
146 |
+ (cffi:with-foreign-object (p :pointer) |
|
147 |
+ ;; TODO: is dropping p a problem here? The docs say something relevant. |
|
148 |
+ ;; must investigate. |
|
149 |
+ [nib @(instantiateWithOwner:topLevelObjects:) |
|
150 |
+ :pointer objc-runtime::ns-app |
|
151 |
+ :pointer p]))) |
|
152 |
+ |
|
115 | 153 |
(defun main () |
116 | 154 |
(trivial-main-thread:with-body-in-main-thread (:blocking t) |
117 |
- [#@NSAutoReleasePool @(new) ] |
|
118 |
- [#@NSApplication @(sharedApplication) ] |
|
155 |
+ [#@NSAutoReleasePool @(new)] |
|
156 |
+ [#@NSApplication @(sharedApplication)] |
|
119 | 157 |
[objc-runtime::ns-app @(setActivationPolicy:) :int 0] |
120 | 158 |
|
121 |
- (let ((app-delegate (objc-runtime::objc-allocate-class-pair |
|
122 |
- #@NSObject "AppDelegate" 0))) |
|
123 |
- (objc-runtime::add-pointer-ivar app-delegate "window") |
|
124 |
- (objc-runtime::add-pointer-ivar app-delegate "delegate")) |
|
125 |
- |
|
126 |
- (let* ((bundle [#@NSBundle @(mainBundle)]) |
|
127 |
- (nib [[#@NSNib @(alloc)] @(initWithNibNamed:bundle:) |
|
128 |
- :pointer @"MainMenu" |
|
129 |
- :pointer bundle])) |
|
130 |
- (cffi:with-foreign-object (p :pointer) |
|
131 |
- [nib @(instantiateWithOwner:topLevelObjects:) |
|
132 |
- :pointer objc-runtime::ns-app |
|
133 |
- :pointer p])) |
|
159 |
+ ;; Setup the app delegate class. We register this one because it's useful |
|
160 |
+ ;; When debugging via something like lldb |
|
161 |
+ (objc-runtime::objc-register-class-pair |
|
162 |
+ (make-app-delegate-class '("actionButton" |
|
163 |
+ "alertButton" |
|
164 |
+ "profitButton"))) |
|
165 |
+ |
|
166 |
+ (load-nib "MainMenu") |
|
167 |
+ |
|
168 |
+ (let ((app-delegate [objc-runtime::ns-app @(delegate)])) |
|
169 |
+ (make-button-delegate (value-for-key app-delegate "actionButton") |
|
170 |
+ (cffi:callback do-things-action)) |
|
171 |
+ (make-button-delegate (value-for-key app-delegate "alertButton") |
|
172 |
+ (cffi:callback alert-action)) |
|
173 |
+ (make-button-delegate (value-for-key app-delegate "profitButton") |
|
174 |
+ (cffi:callback profit-action))) |
|
175 |
+ |
|
134 | 176 |
[objc-runtime::ns-app @(activateIgnoringOtherApps:) :boolean t] |
135 |
- [objc-runtime::ns-app @(run) ])) |
|
177 |
+ [objc-runtime::ns-app @(run)])) |