Apple Developer Connection
Member Login Log In | Not a Member? Contact ADC

< Previous PageNext Page > Hide TOC

Handling Mouse Clicks

One of the earliest things to consider in handling mouse-down events is whether the receiving NSView object should become the first responder, which means that it will be the first candidate for subsequent key events and action messages. Views that handle graphic elements that the user can select—drawing shapes or text, for example—should typically accept first responder status on a mouse-down event by overriding the acceptsFirstResponder method to return YES, as discussed in “Preparing a Custom View for Receiving Events.”

By default, a mouse-down event in a window that isn’t the key window simply brings the window forward and makes it key; the event isn’t sent to the NSView object over which the mouse click occurs. The NSView can claim an initial mouse-down event, however, by overriding acceptsFirstMouse: to return YES. The argument of this method is the mouse-down event that occurred in the non-key window, which the view object can examine to determine whether it wants to receive the mouse event and potentially become first responder. You want the default behavior of this method in, for example, a control that affects the selected object in a window. However, in certain cases it’s appropriate to override this behavior, such as for controls that should receive mouseDown: messages even when the window is inactive. Examples of controls that support this click-through behavior are the title-bar buttons of a window.

In your implementation of an NSResponder mouse-event method, often the first thing you might do is examine the passed-in NSEvent object to decide if this is an event you want to handle. If it is an event that you handle, then you may need to extract information from the NSEvent object to help you handle it. Specifically, you can get the following information from the NSEvent object:

Many view objects in the Application Kit (such as controls and menu items) change their appearance in response to mouse-down events, sometimes only until the subsequent mouse-up event. Doing this provides visual confirmation to the user that their action is effective or that the clicked object is now selected. Listing 4-1 shows a simple example of this.

Listing 4-1  Simple handling of mouse click—changing view’s appearance

- (void)mouseDown:(NSEvent *)theEvent {
    [self setFrameColor:[NSColor redColor]];
    [self setNeedsDisplay:YES];
}
 
- (void)mouseUp:(NSEvent *)theEvent {
    [self setFrameColor:[NSColor greenColor]];
    [self setNeedsDisplay:YES];
}
 
- (void)drawRect:(NSRect)rect {
    [[self frameColor] set];
    NSRectFill(rect);
}

But many view objects, particularly controls and cells, do more than simply change their appearance in response to mouse clicks. One common paradigm is for the clicked view to send an action message to a target object (where both action and target are settable properties of the view). As shown in Listing 4-2, the view typically sends the message on mouseUp: rather than mouseDown:, thus giving users an opportunity to change their minds mid-click.

Listing 4-2  Simple handling of mouse click—sending an action message

- (void)mouseDown:(NSEvent *)theEvent {
    [self setFrameColor:[NSColor redColor]];
    [self setNeedsDisplay:YES];
}
 
- (void)mouseUp:(NSEvent *)theEvent {
    [self setFrameColor:[NSColor greenColor]];
    [self setNeedsDisplay:YES];
    [NSApp sendAction:[self action] to:[self target] from:self];
}
 
- (SEL)action {return action; }
 
- (void)setAction:(SEL)newAction {
    action = newAction;
}
 
- (id)target { return target; }
 
- (void)setTarget:(id)newTarget {
    target = newTarget;
}

Listing 4-3 gives a more complex, real-world example. (It’s from the example project for the Sketch application.) This implementation of mouseDown: determines if users double-clicked a graphical object and, if they did, enables the editing of that object. Otherwise, if a palette object is selected, it creates an instance of that object at the location of the mouse click.

Listing 4-3  Handling a mouse-down event—Sketch application

- (void)mouseDown:(NSEvent *)theEvent {
    Class theClass = [[SKTToolPaletteController sharedToolPaletteController] currentGraphicClass];
    if ([self editingGraphic]) {
        [self endEditing];
    }
    if ([theEvent clickCount] > 1) {
        NSPoint curPoint = [self convertPoint:[theEvent locationInWindow] fromView:nil];
        SKTGraphic *graphic = [self graphicUnderPoint:curPoint];
        if (graphic && [graphic isEditable]) {
            [self startEditingGraphic:graphic withEvent:theEvent];
            return;
        }
    }
    if (theClass) {
        [self clearSelection];
        [self createGraphicOfClass:theClass withEvent:theEvent];
    } else {
        [self selectAndTrackMouseWithEvent:theEvent];
    }
}

The classes of the Application Kit that implement controls manage this target-action behavior for you.



< Previous PageNext Page > Hide TOC


Last updated: 2007-03-16




Did this document help you?
Yes: Tell us what works for you.

It’s good, but: Report typos, inaccuracies, and so forth.

It wasn’t helpful: Tell us what would have helped.
Get information on Apple products.
Visit the Apple Store online or at retail locations.
1-800-MY-APPLE

Copyright © 2007 Apple Inc.
All rights reserved. | Terms of use | Privacy Notice