Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Respond to mouse events in text field in view-based table view

I have text fields inside a custom view inside an NSOutlineView. Editing one of these cells requires a single click, a pause, and another single click. The first single click selects the table view row, and the second single click draws the cursor in the field. Double-clicking the cell, which lets you edit in a cell-based table view, only selects the row.

The behavior I want: one click to change the selection and edit.

What do I need to override to obtain this behavior?

I've read some other posts:

  • The NSTextField flyweight pattern wouldn't seem to apply to view-based table views, where the cell views are all instantiated from nibs.
  • I tried subclassing NSTextField like this solution describes, but my overridden mouseDown method is not called. Overridden awakeFromNib and viewWillDraw (mentioned in this post) are called. Of course mouseDown is called if I put the text field somewhere outside a table view.

By comparison, a NSSegmentedControl in my cell view changes its value without first selecting the row.


Here's the working solution adapted from the accepted response:

In outline view subclass:

-(void)mouseDown:(NSEvent *)theEvent {     [super mouseDown:theEvent];      // Forward the click to the row's cell view     NSPoint selfPoint = [self convertPoint:theEvent.locationInWindow fromView:nil];     NSInteger row = [self rowAtPoint:selfPoint];     if (row>=0) [(CellViewSubclass *)[self viewAtColumn:0 row:row makeIfNecessary:NO]             mouseDownForTextFields:theEvent]; } 

In table cell view subclass:

// Respond to clicks within text fields only, because other clicks will be duplicates of events passed to mouseDown - (void)mouseDownForTextFields:(NSEvent *)theEvent {     // If shift or command are being held, we're selecting rows, so ignore     if ((NSCommandKeyMask | NSShiftKeyMask) & [theEvent modifierFlags]) return;     NSPoint selfPoint = [self convertPoint:theEvent.locationInWindow fromView:nil];     for (NSView *subview in [self subviews])         if ([subview isKindOfClass:[NSTextField class]])             if (NSPointInRect(selfPoint, [subview frame]))                 [[self window] makeFirstResponder:subview]; } 
like image 523
paulmelnikow Avatar asked Aug 18 '11 00:08

paulmelnikow


1 Answers

Had the same problem. After much struggle, it magically worked when I selected None as against the default Regular (other option is Source List) for the Highlight option of the table view in IB!

Another option is the solution at https://stackoverflow.com/a/13579469/804616, which appears to be more specific but a little hacky compared to this.

like image 183
trss Avatar answered Sep 23 '22 12:09

trss