Re: intercepting keydowns
Re: intercepting keydowns
- Subject: Re: intercepting keydowns
- From: James Spencer <email@hidden>
- Date: Sat, 2 Apr 2005 22:43:22 -0600
On Apr 2, 2005, at 6:36 PM, Roland Silver wrote:
Hi Satoshi,
Thanks for your email to me and the cocoa-dev list responding to my
question about intercepting keydowns.
I followed your advice in this way:
I started an Xcode Cocoa project called EmulatorExperiment.03, and
started up Interface Builder by double-clicking MainMenu.nib. I
dragged an NSTextView into the window, created a subclass MyTextView
of NSTextView, Instantiated it, created subfiles for it, and saved the
MainMenu.nib file.
There is no reason to instantiate an instance of MyTextView as an
individual instance in the nib file. You never do anything with that
instance and it is NOT in your view hierarchy. Rather, after reading
in MyTextView.h (or creating it in IB; it sounds like you may have done
the latter from the above), simply get an Inspector for the NSTextView
that you have included in your window (you may have to double click
twice as you have put that view in a scroller so when you first click
on the view, the inspector is actually showing you the scroller),
select the Custom Class popup and in the list that appears, select
MyTextView.
Back in Xcode, I moved MyTextView.[hm] to the Classes group, and added
a keyDown override (whose declaration I got from the documentation for
NSResponder), to myTextView.m:
An aside: It doesn't matter where you move the file. The groups in
Xcode exist for your organisation. You could have left them where ever
they were including in the resources "folder" (which isn't a folder, it
is just a group again existing only for organisation purposes).
- (void)keyDown:(NSEvent *)theEvent {
NSLog(@"keyDown:theEvent = %@", theEvent);
}
figuring that if my keyDown method got called, I would see evidence of
it in the Run Log.
You will if you follow my directions above (at least I do when I run
it.)
I built the project, ran it, and successfully entered a few characters
into the text view -- but no evidence of the overriding keyDown being
called appeared in the Run Log.
Because the view you were typing into was still an NSTextView, not a
MyTextView.
I then followed your further advice by subclassing NSApplication as
MyApplication, creating files for it (but not instantiating it: IB
won't let me), and saving the MainMenu.nib file.
Concept: You wouldn't want to instantiate your application object in IB
because Cocoa creates the singleton application object and then loads
the nib. If you could somehow instantiate the application in IB, you
would end up with two application objects.
Nevertheless, you need to tell Cocoa that you want it to create an
application object of class MyApplication rather than the default
NSApplication. Cocoa is smart but it is not a mind reader and merely
including the definition of a subclass in your source files does not
tell Cocoa that that is the class you want to use. You do this by
changing the Principal Class under Properties in the Target inspector
(Get Info). (You should also change the File Owner's custom class the
same way that you changed the view's class above; in your sample code,
it really doesn't matter but if you add other outlets or actions to
MyApplication, this would permit you to make the connections. To do
this, of course, you will need to read MyApplication.h into IB.
Back in Xcode, I added a sendEvent override to MyApplication.m:
- (void)sendEvent:(NSEvent *)theEvent {
NSLog(@"sendEvent:theEvent = %@", theEvent);
}
I haven't done anything else in IB, like dragging something to
something else to establish delegation, outlets, or actions.
As before, I built the project, ran it, and successfully entered a few
characters into the text view -- but no evidence of the overriding
keyDown or sendEvent being called appeared in the Run Log:
[Session started at 2005-04-02 17:24:18 -0700.]
Executable “EmulatorExperiment.03” has exited with status 0.
Again, this makes sense because your application object (the object
whose sendEvent: is being called) is an instance of the default
NSApplication class, not MyApplication. You make the changes and your
log statement will be called.
Of course if that is ALL you do, then the only thing that your
application will do is record the log statements for sendEvent: above.
Because you don't call the super method, the event won't be processed,
the event will die in your sendEvent: override, and your text view
still won't get any events. You should stick a [super
sendEvent:theEvent]; after the NSLog() call in the application object
and, assuming you want to see the text in your text view, similarly add
a [super keyDown:theEvent]; in MyTextView.
Spence
James P. Spencer
Rochester, MN
email@hidden
"Badges?? We don't need no stinkin badges!"
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Cocoa-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden