views:

143

answers:

1

Hey everyone, I'm a newbie and I have what I anticipate will be a pretty easy question to answer. In order to learn a bit about event handling and drawing, I'm attempting to write a program that draws a black rectangle that increases in length every time the user hits the 'c' key. So far it just draws a black rectangle on a blue background without responding to keystrokes. Here is what I have so far:

Input.h

#import <Cocoa/Cocoa.h>


@interface Input : NSView {

 int length;

}

- (void)keyDown:(NSEvent *)theEvent;
@end

Input.m

#import "Input.h"


@implementation Input

- (id)initWithFrame:(NSRect)frame {
    self = [super initWithFrame:frame];

 length = 10;

    if (self) {
        // Initialization code here.
    }
    return self;
}

- (void)drawRect:(NSRect)dirtyRect {
 //set variables
 NSRect r1;
 NSBezierPath *bp;

    // set background color
 [[NSColor blueColor] set];
 NSRectFill(dirtyRect);

 //set color to black & draw r1
 [[NSColor blackColor] set];
 r1 = NSMakeRect(1, 1, length, 10);
 bp = [NSBezierPath bezierPathWithRect:r1];
 [bp fill];


}

- (void)keyDown:(NSEvent *)theEvent
{
    NSString *key = [theEvent characters];

    if ( [key isEqualToString:@"c"] ) {
        length += 10;
    }
}

@end

I copied the keyDown method from Cocoa in a Nutshell, by the way. Needless to say, I don't really understand it. Do I have to make connections in IB in order to get the program to recognize keystrokes? Basically, I would love it if somebody could help me to get this program to work, because as of yet I have not gotten anything to respond to keystrokes.

And here's Cocoa in a Nutshell

+1  A: 

IIRC, to receive keystrokes your view needs to become first responder. It should work if you add something like these methods:

- (BOOL) acceptsFirstResponder
{
    return YES;
}
- (BOOL) resignFirstResponder
{
    return YES;
}
- (BOOL) becomeFirstResponder
{
    return YES;
}

(You can do other stuff in them too, of course, if appropriate.)

Update: You also need to mark your view as needing to be redrawn. Add:

[self setNeedsDisplay:YES];

To your event handler. And it's probably a good idea to add a log message at the beginning as well, so that you can see whether the method is getting called:

NSLog(@"keyDown [%@]", [theEvent characters]);
walkytalky
Wow, thanks for the timely response; I really didn't expect anyone to get back that quickly.I added those methods to Input.m, but I'm afraid it still isn't working :(. I feel like this should be something so basic, yet it seems I've hit a wall. Any other ideas or suggestions?And again, thanks a lot.
Arthur Skirvin
See the update above. If that fails, and the message isn't get logged, then we'll have to dig a bit deeper.
walkytalky
Alright! You're the man. Thanks A LOT. That was frustrating as heck. The setNeedsDisplay method did the trick. I don't know why, but I was under the impression that the view was being actively redrawn. Again, thanks for taking time to help out a beginner.
Arthur Skirvin