fw2601
fw2601

Reputation: 83

Draw into a NSView via mouse event

i am new to programming, objective-c (and stackoverflow). I'm learning and moving forward very slowly ;) but then I ran into a problem, which google couldn't solve. I have a single window and a NSview and then added a mouse event that should draw the coordinates into my view, but it doesn't. The funny thing is: it is drawn when the mouse moves over the window buttons of my apps window...

- (void)drawRect:(NSRect)dirtyRect {
   NSPoint imagePos = NSMakePoint(0, 0);
   NSImage *aImage = [NSImage imageNamed:@"mw_bg01.png"];
   [aImage dissolveToPoint:imagePos fraction:1.0];
}
- (void)mouseDown:(NSEvent*)theEvent;{
   mouseLoc = [NSEvent mouseLocation];
   mousePosX = mouseLoc.x;mousePosY = mouseLoc.y;
   NSString* mouseString = [NSString stringWithFormat:@"%d", mousePosX];
   NSPoint textPoint = NSMakePoint(5, 5);
   NSMutableDictionary *textAttrib = [[NSMutableDictionary alloc] init];
   [textAttrib setObject:[NSFont fontWithName:@"Helvetica Light" size:10]
               forKey:NSFontAttributeName];
   [textAttrib setObject:[NSColor grayColor] forKey:NSForegroundColorAttributeName];
   [mouseString drawAtPoint:textPoint withAttributes:textAttrib];
}

I don't know how to go on, any suggestions? Thanks!

Upvotes: 3

Views: 1712

Answers (1)

Andrew Madsen
Andrew Madsen

Reputation: 21373

You shouldn't do drawing in the -mouseDown: method. Rather, you must do all your drawing in -drawRect: (or methods that you call from -drawRect:). Try something like this:

@interface MyView ()
    @property NSPoint lastMousePoint;
@end

@implementation MyView

- (void)drawLastMousePoint
{
    NSString *mouseString = NSStringFromPoint(self.lastMousePoint);
    NSPoint textPoint = NSMakePoint(5, 5);
    NSMutableDictionary *textAttrib = [[NSMutableDictionary alloc] init];
    [textAttrib setObject:[NSFont fontWithName:@"Helvetica Light" size:10]
                forKey:NSFontAttributeName];
    [textAttrib setObject:[NSColor grayColor] forKey:NSForegroundColorAttributeName];
    [mouseString drawAtPoint:textPoint withAttributes:textAttrib];
}

- (void)drawRect:(NSRect)dirtyRect 
{
    NSPoint imagePos = NSMakePoint(0, 0);
    NSImage *aImage = [NSImage imageNamed:@"mw_bg01.png"];
    [aImage dissolveToPoint:imagePos fraction:1.0];

    [self drawLastMousePoint];
}

- (void)mouseDown:(NSEvent*)theEvent;
{
    self.lastMousePoint = [theEvent locationInWindow];
    [self setNeedsDisplay:YES];
}

@end

When you get a mouse down event, you simply store the location of the mouse down. The drawing is done in -drawLastMousePoint which you call in your -drawRect: method. Since you know you need to redraw anytime the mouse is clicked, you call -setNeedsDisplay: to inform the view that it needs to be redrawn. Note that the redraw doesn't happen immediately, rather, it will happen the next time through the run loop. In other words, you're saying "hey, something changed, and I need to draw my view's contents again. Please call -drawRect: again as soon as possible!"

One other note: +[NSEvent mouseLocation] is really designed for getting the current mouse location outside the event stream. Typically, in a -mouseDown: method, you call -locationInWindow on the NSEvent passed as the argument to the method. If you need to convert to local/view coordinates, you should call [self convertPoint:[theEvent locationInWindow] fromView:nil];.

Upvotes: 5

Related Questions