Trying to draw custom selection on NSTableView subclass

Discussion in 'Mac Programming' started by chris-morrison, Oct 29, 2010.

  1. macrumors newbie

    Joined:
    May 19, 2010
    #1
    Hi all,

    I am implementing my own subclass of NSTableView which has a gradient selection marker like iTunes or iMovie.

    I have got all my subclasses set up and I have prepared the image for the selection marker, but I have hit a maddening brick wall.

    I am using the following code to draw my custom selection in my NSTableView subclass.

    Code:
    - (void)highlightSelectionInClipRect:(NSRect)clipRect
    {
        if ([self selectedRow] == -1) return;
        
        if (__useDarkProLook)
        {
            [self lockFocus];
            
            NSImage *selImage = [NSImage imageNamed:@"TableViewSelection.tiff"];
            [selImage setFlipped:[self isFlipped]];
            NSIndexSet *selectedRowIndexes = [self selectedRowIndexes];
            NSInteger currentIndex = [selectedRowIndexes firstIndex];
            
            while (currentIndex != NSNotFound)
            {
                NSRect rowRect = [self rectOfRow:currentIndex];
                
                if (!NSIsEmptyRect(rowRect))
                {
                    NSLog(@"Drawing selection for %llu (%f, %f, %f, %f)", currentIndex, rowRect.origin.x, rowRect.origin.y, rowRect.size.width, rowRect.size.height);
                    
                    [selImage drawInRect:rowRect fromRect:rowRect operation:NSCompositeSourceOver fraction:1.0];
                }
                
                currentIndex = [selectedRowIndexes indexGreaterThanIndex:currentIndex];
            }
            
            [self unlockFocus];
        }
        
        [super highlightSelectionInClipRect:clipRect];
    }
    
    - (id)_highlightColorForCell:(NSCell *)cell;
    {
        if (__useDarkProLook) return nil;
        
        return [super _highlightColorForCell:cell];
    }
    
    When I load some data into my table view and click on the first item my selection is drawn perfectly.

    However, when I click on any of the other items nothing happens apart from a slight change of the color of the text. I can only seem to draw the selection on the first item.

    I have tried absolutely everything and I cannot get past this stumbling block.

    Has anyone else experienced this or have any idea what I have missed?

    Regards,

    Chris
     
  2. macrumors 68030

    jared_kipe

    Joined:
    Dec 8, 2003
    Location:
    Seattle
    #2
    First off, set a breakpoint or put in an NSLog to see if your method is getting called every time you select a row. Perhaps selectedRow isn't changing?
     
  3. thread starter macrumors newbie

    Joined:
    May 19, 2010
    #3
    There is an NSLog before the line to draw the image, the method is being called (with the correct index).

    Below is the output to the console in Xcode when I click on eight items in the table view one after the other.

    Code:
    2010-10-29 15:23:44.179 MyApp[30065:5703] Drawing selection for 0 (0.000000, 0.000000, 418.000000, 20.000000)
    2010-10-29 15:23:46.419 MyApp[30065:5703] Drawing selection for 1 (0.000000, 20.000000, 418.000000, 20.000000)
    2010-10-29 15:23:47.843 MyApp[30065:5b07] Drawing selection for 2 (0.000000, 40.000000, 418.000000, 20.000000)
    2010-10-29 15:23:49.099 MyApp[30065:5b07] Drawing selection for 3 (0.000000, 60.000000, 418.000000, 20.000000)
    2010-10-29 15:23:50.275 MyApp[30065:5b07] Drawing selection for 4 (0.000000, 80.000000, 418.000000, 20.000000)
    2010-10-29 15:23:52.331 MyApp[30065:5b07] Drawing selection for 5 (0.000000, 100.000000, 418.000000, 20.000000)
    2010-10-29 15:23:53.459 MyApp[30065:5703] Drawing selection for 6 (0.000000, 120.000000, 418.000000, 20.000000)
    2010-10-29 15:23:54.299 MyApp[30065:5b07] Drawing selection for 7 (0.000000, 140.000000, 418.000000, 20.000000)
    
     
  4. Moderator emeritus

    robbieduncan

    Joined:
    Jul 24, 2002
    Location:
    London
    #4
    What is the clip rect you are being passed? Have you considered the possibility that you should not be working out the row position, rather you should just fill the supplied rect with the highlight image and the table view will deal with it being in the correct place on screen?

    Edit: it appears that I'm wrong on that...
     
  5. macrumors 65816

    Bernard SG

    Joined:
    Jul 3, 2010
    #5
    Clear your view at the start of your "While" loop?
     
  6. thread starter macrumors newbie

    Joined:
    May 19, 2010
    #6
    Could you elaborate a bit on that on that please.
     
  7. macrumors 68030

    jared_kipe

    Joined:
    Dec 8, 2003
    Location:
    Seattle
    #7
    Does it work properly the FIRST time you click it (as in any row) or just the First row?? Does it deselect properly?
     
  8. thread starter macrumors newbie

    Joined:
    May 19, 2010
    #8
    It selects and deselects correctly however many times you click on the very first row only.
     
  9. macrumors 603

    Joined:
    Aug 9, 2009
    #9
    Did you read any code samples before writing your code?
    If so, what URLs?

    Did you pattern your code after a specific example?
    Which one?

    If none of the above, consider looking up some examples.


    What does your code draw after highlightSelectionInClipRect: has returned?
    The ref doc says "This method is invoked before drawRow:clipRect:." so post any override of that, and post the delegate's cell-drawing code.

    Logically, if something is drawn after highlightSelectionInClipRect returns, then that drawn content will appear instead of anything drawn by highlightSelectionInClipRect.
     
  10. macrumors 68000

    Sydde

    Joined:
    Aug 17, 2009
    #10
    Look here:
    Code:
    [selImage drawInRect:rowRect [U][COLOR="DarkRed"]fromRect:[B]rowRect[/B][/COLOR][/U] operation:NSCompositeSourceOver fraction:1.0];
    hint: try NSZeroRect
     
  11. thread starter macrumors newbie

    Joined:
    May 19, 2010
    #11
  12. thread starter macrumors newbie

    Joined:
    May 19, 2010
    #12
    Trying to draw custom selection on NSTableView subclass Reply to Thread SOLVED

    That seems to have done the trick. Thank you.
     
  13. macrumors 68030

    jared_kipe

    Joined:
    Dec 8, 2003
    Location:
    Seattle
    #13
    Good one, it's trying to draw part of the image that isn't there (in the image coordinate space)

    However, I'm not sure you intend to draw the whole image. Maybe something like

    maybe make a new rect with (0.0, 0.0, rowRect.size.width, rowRect.size.height)
     
  14. macrumors 68000

    Sydde

    Joined:
    Aug 17, 2009
    #14
    He did say "gradient", so I guessed it was a stretchable tiny image (or ought to be). But your point is well taken: chris-morrison would be well advised to read the docs for NSImage so that he understands what the fix did.
     
  15. macrumors 68030

    jared_kipe

    Joined:
    Dec 8, 2003
    Location:
    Seattle
    #15
    I didn't notice, I was coming from the POV that it was working for the first bar, so the smaller change would be to ask the image to display the size that it was originally displaying (and apparently working).
     
  16. thread starter macrumors newbie

    Joined:
    May 19, 2010
    #16
    I have studied the NSImage docs with a bit more acumen and it is now clear what was going wrong.

    We live and learn.

    Thank you everyone for your help.

    Chris
     

Share This Page