views:

266

answers:

2

I am wanting to change the text background color on a tableview's cell when it is hovered upon, similar to how AddressBook "highlights" the label of a contact's element when you mouseover the label names. However I cannot figure out how to accomplish...

detecting a mouseover on a particular NSCell and... After detecting the cell his hovered upon, highlighting the text in that cell (not highlighting the entire row as if the user selected that row)

As NSCell is not a subclass of NSView this seems to be a very difficult task.

Any example of this or explanation on how this might be done would be greatly appreciated.

Thanks!

+2  A: 

Overall, it's not a simple task as you noticed.

To track the mouse in an NSCell, subclass NSCell and override

-[NSCell startTrackingAt:inView:]   

and

-[NSCell stopTracking:at:inView:mouseIsUp:]      

Once you've detected the mouse is tracking inside a cell, you can find out which cell you are in the table with [tableView rowAtPoint:point] and [tableView columnAtPoint:point], and then find your frame with [tableView frameOfCellAtColumn:column row:row] Then, you can change the way your cell is drawn by changing some property of the cell or changing the way it's drawn directly by overriding drawInteriorWithFrame:inView:.

Here's documentation on subclassing NSCell: http://developer.apple.com/mac/library/documentation/cocoa/conceptual/ControlCell/Tasks/SubclassingNSCell.html

Ken Aspeslagh
Thanks for the info! For some reason my startTrakingAt:inView: or stopTracing:at:inView:mouseIsUp methods are not being called... i know my table does not support selection as I don't want the user to be able to select a row... i'm wondering if this is effecting that.
Wigwam
Are you sure your subclass is being used in the table?
Ken Aspeslagh
That is to say, did you make the column's cell an instance of your custom subclass?
Peter Hosey
A: 

I actually got it working using another method. I got it from the example posted here... http://www.cocoadev.com/index.pl?NSTableViewRollover

Instead of using NSCell's tracking mechanism, I am tracking mouseEntered/mouseExited and mouseMoved within my subclassed NSTableView.

  1. When the tableview awakeFromNib method is called, I create a trackingRect from the visible portion of the tableview

  2. I have a BOOL ivar that is set to YES when the mouse is within the tracking area(mouseEntered) and NO when it is not (mouseExited)

  3. Within the mouseMoved method, I determine the current row the mouse cursor is on and set it to an NSInteger ivar and then call the tableview's setNeedsDisplayInRect: passing the rect of the row that the mouse is on.

  4. I also override resetCursorRects to remove the old tracking rect and add a new one...this method is called when the tableview is scrolled upon so that it's tracking the latest visible rect.

  5. Finally in my tableview's delegate, I determine the selected row (by retrieving the row index from the NSInteger ivar of the table view and change the cell's text color (or anything you want) if the currently drawn cell matches the row the mouse cursor is on. All this is done in the delegate method: tableView:(NSTableView *)aTableView willDisplayCell:(id)aCell forTableColumn:(NSTableColumn *)aTableColumn row:(NSInteger)rowIndex

I hope this helps others, as this was a bit tricky. It is also probably important to make sure that tableview is the firstResponder when the view loads, just makes things a bit more streamlined and cleaner.

Btw, is there a way to make a specific control in a view always be the firstResponder with nothing else possible as being the firstResponder? Even a method such as the iPhones... viewWillAppear method will help as I could set the first responder each time the view is visible...but i'm not aware of such a method on the Mac.

Wigwam