Blog

Hovering Buttons in an NSTableView

Aug 11, 2007 — Whitney Young (Updated Feb 6, 2008)

iTunes, Mail, and the Finder all have buttons that are displayed in a table view on the right hand side of the cell. When you hover over these buttons, the image used changes to indicate that it's a button. There is really no easy way to add this functionality to your own custom cell. Searching for others who tried to do the same sort of thing pulled up one thread on the coca-dev mailing list with no conclusion to the person's issue.

I just finished adding hoverable buttons to Senuti's source list, and it was very tricky. Here's what I did.

  • Created an NSWindow subclass for custom event dispatching
  • Created an NSTableView subclass for custom event dispatching
  • Created a custom NSCell to handle event notification from the table view

So the cell needs to respond to mouseMoved: events. NSButtonCell does that, you think, but NSButtonCell doesn't receive the events in an NSTableView. So that's what the NSTableView subclass is for. It handles mouse events and dispatches them to the cell. The cell isn't really part of any control, though, and is reused throughout the rows of the table. Therefore, calling the table delegate method, tableView:willDisplayCell:forTableColumn:row:, before sending messages to the cell was necessary. The cell then responds and lets the table view know whether or not it needs to redraw that cell.

And of course, you have to have the table view become the firstResponder in order to receive mouseMoved: events. If it does become the firstResponder, though, then whenever the mouse enters the table view, focus will change to that view. That's not a good thing. That's where the NSWindow subclass comes into play. Each mouseMoved: event tracked in the window is forwarded to a list of additional responders. The table view adds and removes itself from the additional responders list when the mouse enters/exits.

All that's left to do is draw the button image, and update when the mouse enters/leaves/clicks in the button area. Since this post doesn't go into much detail, the implementation of what I did is all available under the GPL. SEButtonImageTextCell, SEEventTable, and SEEventWindow.

1 Comment Tags: Apple, Cocoa, Code, GPL, Objective-C, OS X, Senuti