Discussion:
keyboard input from NSTableView
Thomas Waters
2001-03-20 04:49:26 UTC
Permalink
Sorry for the newbie question, but I've been searching, honest!

Can someone send me, or point me to a simple example that traps keyboard input from a NSTableView?

Specifically, I want to capture the Return key, so that the user can move up and down the table rows with the arrow keys and press Return to "do it".

I'm not really understanding how to hook things up in IB to make this happen.

What I've tried so far is setting a class of mine to be the delegate of the NSTableView, and I was hoping it would call my keyDown: message, but that didn't work.

Thanks.

Tom

---------------------------------
Tom Waters
Hired Gun
Java/Swing, ObjectiveC/Cocoa

___________________________________________________
GO.com Mail
Get Your Free, Private E-mail at http://mail.go.com
John C. Randolph
2001-03-20 04:57:54 UTC
Permalink
Post by Thomas Waters
Sorry for the newbie question, but I've been searching, honest!
Can someone send me, or point me to a simple example that traps
keyboard input from a NSTableView?
Specifically, I want to capture the Return key, so that the user can
move up and down the table rows with the arrow keys and press Return to
"do it".
I'm not really understanding how to hook things up in IB to make this
happen.
What I've tried so far is setting a class of mine to be the delegate of
the NSTableView, and I was hoping it would call my keyDown: message,
but that didn't work.
You should be able to do what you want by implementing the text delegate
methods in the table view's delegate.

-jcr
Thomas Waters
2001-03-20 18:47:40 UTC
Permalink
I'm not sure if I've done the correct thing here, but I've got it working.

I'm posting my solution in hopes that it might help the others who emailed me saying "me too!", and/or so the experts can correct my solution. (It seems there are many ways to do the same thing here...)

My object structure is as follows: (all hooked up in IB)

NSTableView
dataSource -> MyDataSource
delegate -> MyDataSource

MyDataSource
outlets:
theTableView -> NSTableView

Previously, I had assumed that MyDataSource:keyDown would get called because MyDataSource was set as the delegate, which didn't work, and prompted my first message...

I read the docs on input event distribution and decided MyDataSource should also be an NSResponder... so I changed it to subclass NSResponder and told the NSTableView that it was the nextResponder.

Now keyDown is being called and all is well, yet I still feel this might not be the correct idiom to be using.

@interface MyDataSource : NSResponder
{
IBOutlet id theTableView; // the tableView instance.
}
@end

@implementation MyDataSource
- (void)awakeFromNib
{
[theTableView setNextResponder: self];
}
- (void)keyDown:(NSEvent *)theEvent
{
printf("key pressed: %s\n", [[theEvent description] cString]);
}
// ... <snipped dataSource implementation here...>
@end






-----Original Message-----
From: "John C. Randolph"<***@idiom.com>
To: "Thomas Waters"<***@go.com>
Cc: "John C. Randolph"<***@idiom.com>, macosx-***@omnigroup.com
Date: Mon Mar 19 22:57:48 PST 2001
Subject: Re: keyboard input from NSTableView
Post by John C. Randolph
Post by Thomas Waters
Sorry for the newbie question, but I've been searching, honest!
Can someone send me, or point me to a simple example that traps
keyboard input from a NSTableView?
Specifically, I want to capture the Return key, so that the user can
move up and down the table rows with the arrow keys and press Return to
"do it".
I'm not really understanding how to hook things up in IB to make this
happen.
What I've tried so far is setting a class of mine to be the delegate of
the NSTableView, and I was hoping it would call my keyDown: message,
but that didn't work.
You should be able to do what you want by implementing the text delegate
methods in the table view's delegate.
-jcr
___________________________________________________
GO.com Mail
Get Your Free, Private E-mail at http://mail.go.com
Tai Luxon
2001-03-22 23:38:00 UTC
Permalink
I want the delete key to delete the selected row(s) in my
NSTableView. What is the best way to get this done? I want to have a
method in my document controller class handle the deletion, but I'm
not sure how to make it get called when the user presses the delete
key.

I can't use Tom's method (below) of inserting my controller into the
responder chain because my controller class is already subclassing
NSDocument.

I don't believe John's method (at the bottom) is really relevant
because the text delegate methods won't get invoked when delete is
pressed.

I also want to handle a double-click on a row, so I was going to set
my controller class as the target for the NSTableView and use
-setDoubleAction: to hook up the target-action behavior.
Unfortunately there is no -setKeyDownAction: that I can use. It looks
like my best bet would be to use [tableView sendActionOn:
NSKeyDownMask]. Will that work and if so, how do I keep the other
NSTableView keyboard behavior (such as the arrow keys moving the
selection)? (BTW, when you have a control send actions on multiple
events, do they all have to go to one target? Is there any way to
make different actions invoke methods on different targets?)

... time passes...

Well, I just tried [tableView sendActionOn: NSKeyDownMask] and my
method gets called when I click my mouse in the table view, not when
I press a key. [tableView sendActionOn: NSAnyEventMask] didn't make
my method get called on a key press either. I also realized that even
if it gets called on a key down, I won't have the event so won't be
able to determine if it was the delete key that was pressed. So back
to square one.

I would rather not subclass NSTableView just to implement the delete.
Maybe I could insert a custom subclass on NSResponder into the
responder chain for the express purpose of calling my method on a
delete key down, but that seems kinda awkward. Is there a clean way
to do this?

Thanks.

- Tai
Post by Thomas Waters
I'm not sure if I've done the correct thing here, but I've got it working.
I'm posting my solution in hopes that it might help the others who
emailed me saying "me too!", and/or so the experts can correct my
solution. (It seems there are many ways to do the same thing
here...)
My object structure is as follows: (all hooked up in IB)
NSTableView
dataSource -> MyDataSource
delegate -> MyDataSource
MyDataSource
theTableView -> NSTableView
Previously, I had assumed that MyDataSource:keyDown would get called
because MyDataSource was set as the delegate, which didn't work, and
prompted my first message...
I read the docs on input event distribution and decided MyDataSource
should also be an NSResponder... so I changed it to subclass
NSResponder and told the NSTableView that it was the nextResponder.
Now keyDown is being called and all is well, yet I still feel this
might not be the correct idiom to be using.
@interface MyDataSource : NSResponder
{
IBOutlet id theTableView; // the tableView instance.
}
@end
@implementation MyDataSource
- (void)awakeFromNib
{
[theTableView setNextResponder: self];
}
- (void)keyDown:(NSEvent *)theEvent
{
printf("key pressed: %s\n", [[theEvent description] cString]);
}
// ... <snipped dataSource implementation here...>
@end
-----Original Message-----
Date: Mon Mar 19 22:57:48 PST 2001
Subject: Re: keyboard input from NSTableView
Post by John C. Randolph
Post by Thomas Waters
Sorry for the newbie question, but I've been searching, honest!
Can someone send me, or point me to a simple example that traps
keyboard input from a NSTableView?
Specifically, I want to capture the Return key, so that the user can
move up and down the table rows with the arrow keys and press Return to
"do it".
I'm not really understanding how to hook things up in IB to make this
happen.
What I've tried so far is setting a class of mine to be the delegate of
the NSTableView, and I was hoping it would call my keyDown: message,
but that didn't work.
You should be able to do what you want by implementing the text delegate
methods in the table view's delegate.
-jcr
___________________________________________________
GO.com Mail
Get Your Free, Private E-mail at http://mail.go.com
_______________________________________________
MacOSX-dev mailing list
http://www.omnigroup.com/mailman/listinfo/macosx-dev
--------------------------------------------------------------------
Tai Luxon
***@falcon.calpoly.edu
http://www.bluecanoe.com/TIE/
--------------------------------------------------------------------
Vince DeMarco
2001-03-22 23:56:04 UTC
Permalink
I want the delete key to delete the selected row(s) in my NSTableView.
What is the best way to get this done? I want to have a method in my
document controller class handle the deletion, but I'm not sure how to
make it get called when the user presses the delete key.
I can't use Tom's method (below) of inserting my controller into the
responder chain because my controller class is already subclassing
NSDocument.
I don't believe John's method (at the bottom) is really relevant
because the text delegate methods won't get invoked when delete is
pressed.
I also want to handle a double-click on a row, so I was going to set my
controller class as the target for the NSTableView and use
-setDoubleAction: to hook up the target-action behavior. Unfortunately
there is no -setKeyDownAction: that I can use. It looks like my best
bet would be to use [tableView sendActionOn: NSKeyDownMask]. Will that
work and if so, how do I keep the other NSTableView keyboard behavior
(such as the arrow keys moving the selection)? (BTW, when you have a
control send actions on multiple events, do they all have to go to one
target? Is there any way to make different actions invoke methods on
different targets?)
... time passes...
Well, I just tried [tableView sendActionOn: NSKeyDownMask] and my
method gets called when I click my mouse in the table view, not when I
press a key. [tableView sendActionOn: NSAnyEventMask] didn't make my
method get called on a key press either. I also realized that even if
it gets called on a key down, I won't have the event so won't be able
to determine if it was the delete key that was pressed. So back to
square one.
I would rather not subclass NSTableView just to implement the delete.
Maybe I could insert a custom subclass on NSResponder into the
responder chain for the express purpose of calling my method on a
delete key down, but that seems kinda awkward. Is there a clean way to
do this?
Whats wrong with subclassing??

Try this

The code below addes another method to the TableViewDataSource to tell
it to delete a particular row.

----------

#import <AppKit/AppKit.h>


@interface MyTableView : NSTableView
{
BOOL _dataSourceDeleteRow;
}

@end

@interface NSObject(MyTableViewDataSource)
- (void)tableView:(NSTableView *)tableView deleteRow:(int)row;
@end

----------

#import "MyTableView.h"

@implementation MyTableView

- (void)setDataSource:(id)anObject
{
[super setDataSource:anObject];

_dataSourceDeleteRow = [anObject
respondsToSelector:@selector(tableView:deleteRow:)];
}

- (void)keyDown:(NSEvent *)theEvent
{
NSString *keyString;
unichar keyChar;

keyString = [theEvent charactersIgnoringModifiers];
keyChar = [keyString characterAtIndex:0];

switch(keyChar){
case 0177: /* Delete key */
case NSDeleteFunctionKey:
case NSDeleteCharFunctionKey:
if (_dataSourceDeleteRow && ([self selectedRow] != -1) ){
[[self dataSource] tableView:self deleteRow:[self
selectedRow]];
}
break;
default:
[super keyDown:theEvent];
}
}

@end

Loading...