[Openmcl-devel] Questions about Cocoa app development]
mikel evins
mevins at mac.com
Sun Jan 27 12:00:53 PST 2008
On Jan 26, 2008, at 1:50 AM, Didier Verna wrote:
>
> Hi Mikel,
>
> thank you for the detailed answer.
>
> mikel evins <mevins at mac.com> wrote:
>
>> As for interacting with your application, well, you can build a
>> Listener into it. Feel free to send suggestions for how you'd like it
>> to work.
>
> At a first glance, having a window -> listenener menu option
> implemented directly by build-application (optionally with an option
> to
> turn it off) would be nice.
>
> Also, I have done a few tests and noticed that if you create a simple
> nib file without a window (just a MainMenu), you do get the listener
> in
> your app. Only when you add a window does the listener go away. How's
> that implemented ?
Unintentionally. :-)
By default, an NSApplication instance sends
applicationOpenUntitledFile: to its delegate, which causes a new
window to be created. If your nib doesn't have a window that is
defined as the key target, that message is being handled by Clozure
CL's classes, which respond by opening a Listener if one is not
already open.
If you want your window to be opened instead, create one in your main
nibfile.
If you want no window to open at launch, implement an application
delegate and define its applicationShouldOpenUntitledFile: method to
return NO.
>>> 2/ How do you execute specific Lisp code when the application
>>> starts,
>>> both before and after the GUI is setup ?
>>>
>>
>> One Cocoa-flavored way to do it is to create an application delegate
>> and implement the methods applicationWillFinishLaunching: and
>> applicationDidFinishLaunching:. You can implement these in Lisp and
>> have them evaluate arbitrary Lisp forms. Apple documentation of these
>> and other delegate methods is here:
>
> OK, I've done a test with a menu-only nib file, but I can't get this
> to work. Here's my code (trivial, really):
>
> (defvar *test* nil)
>
> (defclass app-delegate (ns:ns-object)
> ()
> (:metaclass ns:+ns-object))
>
> (objc:defmethod (#/test: :void)
> ((self app-delegate) sender)
> (declare (ignore sender))
> (setf *test* 0)
> (format t "Test~%"))
>
> (objc:defmethod (#/applicationWillFinishLaunching: :void)
> ((self app-delegate) notification)
> (declare (ignore notification))
> (setf *test* 1)
> (format t "Will finish launching~%"))
>
> (objc:defmethod (#/applicationDidFinishLaunching: :void)
> ((self app-delegate) notification)
> (declare (ignore notification))
> (setf *test* 2)
> (format t "Did finish launching~%"))
>
> I've made connections to the app-delegate in the nib file (the
> delegate
> field of the Application itself, and the test action from the Help
> menu
> option). However, only the help button seems to work. Am I doing
> something wrong ?
No, we are.
BUILD-APPLICATION saves an image that uses Clozure CL's application
classes and its Cocoa startup code. The code for START-COCOA-
APPLICATION in cocoa-ide/cocoa-window.lisp sets the application
delegate for you. Unfortunately, if you use BUILD-APPLICATION to build
your app, there's no handy way to tell START-COCOA-APPLICATION you
want to use a particular delegate class. This is a bug, and I have
filed a bug report. I'll fix it when I can.
In the meantime, try these as workarounds:
File-based:
First, define this method in your source file:
(defmethod application-init-file ((app cocoa-application))
"home:init-file")
For "home:init-file" substitute any suitable pathname.
Then, put the lisp forms you want evaluated in the file at that path.
Function-based:
Put the forms you want evaluated in a definition like this:
(defmethod initialize-instance ::after ((app cocoa-application) &rest
initargs &key &allow-other-keys)
[your code goes here])
You can always try redefining START-COCOA-APPLICATION as well, though
that's probably not for the faint of heart.
--me
More information about the Openmcl-devel
mailing list