Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NSView receiving click events thru a NSTextView

I have a NSTextView, non-editable, non-selectable, in a NSView. I need the NSView to receive click events when the text view is clicked - basically I need the click events to act as though the text view doesn't even exist. Obviously I would just use the

textView:clickedOnCell:inRect:atIndex:

text view delegate method, but I need to capture the click event, to detect double-clicks and things like that.

like image 874
Chris Avatar asked Aug 20 '11 16:08

Chris


2 Answers

In the view that contains the text view, override the hitTest: method to return self. The mouse events will then be sent to the container view.

Caveat

I've since found that hitTest: will be called for click and mouse-tracking events anywhere in the window, even for events that wouldn't naturally be anywhere near the container view. If there are other views in the window, your hitTest: method will turn the container view into a black hole that causes all of those events to gravitate into itself, never to be seen by any other views.

The fix for that is to test whether the event is within your view before swallowing it. If it is, return self; if it isn't, return nil.

The simplest way to do that is to call super's implementation, which will return the view or any subview of itself if the point is within the view, and then just return self if that method returned non-nil. If it returned nil, then you return nil, too.

A less-simple but possibly more efficient method would be to convert the point from the window's coordinate system to the view's, then use NSPointInRect to test whether the point is within the view's bounds.

like image 80
Peter Hosey Avatar answered Nov 06 '22 07:11

Peter Hosey


Just to put Peter's fantastic description into code:

- (NSView *)hitTest:(NSPoint)aPoint
{
    NSView *result = [super hitTest:aPoint];
    if (result)
    {
        result = self;
    }
    return result;
}
like image 44
Adam Fox Avatar answered Nov 06 '22 06:11

Adam Fox