On Dec 10, 2008, at 2:44 AM, Graham Cox wrote:

I need to draw outside of the usual drawRect: method (no really, I do!)

The reason is that I have a custom cell that is used in a table/ outline view that draws a colour swatch. When clicked it pops up a menu of colours so the user can choose another colour. While tracking the menu, the cell shows the colour in the menu that the mouse is over. When the mouse is released, the cell sends the chosen colour to the table's datasource as usual.

The drawing of the colour while tracking the menu needs to take place outside the drawRect: mechanism. Why? Because the host view is a table, and I need to avoid it reloading the cell from the datasource while I'm tracking the menu. If I invalidate the table view, it will redraw the entire row. That would be OK if I could rely on it to draw only my row, but in some circumstances I have found that it doesn't, but redraws the whole table (for example after editing a text cell, for some reason any setNeedsDisplayInRect: on a small part of the table causes the whole table to reload).

There are various reasons why this happens; for one, the focus ring may bleed into the rect that was invalidated. But, as you have noticed, you should not rely on invalidating just a small portion and hoping only that portion should redraw.

I think it is still correct to invalidate your cell's rect, and have the table redraw (potentially redrawing everything).

,,,......
Maybe it s a graphics context problem? I have tried always setting the current context to the view's window but that stops it from ever working (which may be a clue). Anyone spot anything I'm doing or not doing here?

Also, if you feel tempted to advise me not to do it this way, believe me, I have exhaustively investigated that route, which has proven even more problematic, because there's insufficient fine control over what the tableview itself does in its own drawRect: method. So far this approach is the cleanest by far.

I think you should try another approach. Go back to invalidating the rect of the cell that you want to redraw. Essentially, you want one cell to maintain specific state while you are doing something else. There is one easy approach to do this, which is to maintain a copy of the cell while you are showing your special menu, and use that cell to draw *just* that one particular row/column.

General steps:
1. Save off the row/column
2. Copy the cell at that row/column when showing your menu
3. Always return that copied cell from the delegate method:
- (NSCell *)tableView:(NSTableView *)tableView dataCellForTableColumn: (NSTableColumn *)tableColumn row:(NSInteger)row AVAILABLE_MAC_OS_X_VERSION_10_5_AND_LATER;
   else, return [tableColumn dataCell].
4. Don't update the properties for that row/column in -willdisplaycell
5. Update the colors of that copied cell when your menu changes state
6. Drop the copied cell when your menu goes away.

Another approach would be something similar to this great example:

        <http://developer.apple.com/samplecode/PhotoSearch/>

.corbin
_______________________________________________

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to [EMAIL PROTECTED]

Reply via email to