Welcome to the MacNN Forums.

If this is your first visit, be sure to check out the FAQ by clicking the link above. You may have to register before you can post: click the register link above to proceed. To start viewing messages, select the forum that you want to visit from the selection below.

You are here: MacNN Forums > Software - Troubleshooting and Discussion > Developer Center > alternating table row colors ala 'iTunes'

alternating table row colors ala 'iTunes'
Thread Tools
Mac Enthusiast
Join Date: Oct 2001
Status: Offline
Reply With Quote
May 21, 2002, 05:55 PM
 
I've managed to achieve alternating row colors as iTunes does it. I've even managed to get the little gray lines between columns by turning the table background to gray and adjusting the cell size to allow the gray background to peek through. This however makes another problem much more noticeable. The problem is, how do i get the alternating row colors to fill the table, not just populated cells? It looks kinda dorky with alternating lt blue and white columns for cells with data, and then gray underneath for the rest of the space in the table? Im guessing I need to subclass NSTableView, but this is something I only know about in theory. I've never subclassed anything before. What do you all think? Is there some more obvious way I have overlooked? If I need to subclass, would someone walk me through the process?
3R1C
     
Junior Member
Join Date: Jul 2001
Location: Mos Eisley Cantina
Status: Offline
Reply With Quote
May 21, 2002, 06:18 PM
 
There's may be an easier way, but you can subclass NSCell and override the drawInteriorWithFrame function. Then in this function, you can draw a gray background and do whatever else you want.

Of course, you'll need to tell the appropriate NSTableColumn objects to use your subclass instead of the plain vanilla NSCell. Do this with NSTableColumn's setDataCell message.
     
Fresh-Faced Recruit
Join Date: Jan 2000
Location: Los Altos, CA, USA
Status: Offline
Reply With Quote
May 22, 2002, 02:09 AM
 
I just figured this out last week...

This assumes you have subclassed NSTableView which includes a class variable

NSColor *oddRowColor

and that your NSTableView backgroundColor is the color you want the even rows background to be.

override drawRect: with something like:

- (void) drawRectNSRect) r{
NSRect rowRect, nextRect;
NSSize cellSpacing;
int countRows;
float height;
BOOL isOddRow;
[super drawRect:r];
// draw remaining lines in blank area
countRows = [[self dataSource] numberOfRowsInTableView:self];
rowRect = [self rectOfRow:countRows-1];
cellSpacing = [self intercellSpacing];
height = [self rowHeight]+cellSpacing.height;
nextRect.origin.x = r.origin.x;
nextRect.origin.y = rowRect.origin.y+height;
nextRect.size.width = r.size.width;
nextRect.size.height=height;
if (countRows==0) {
isOddRow = TRUE;
nextRect.origin.y = 0;
}
else
isOddRow = ((countRows%2)==0); // next row is odd if last row is even
while (nextRect.origin.y<(r.origin.y+r.size.heigh t)) {
if (isOddRow)
[oddRowColor set];
else
[[self backgroundColor] set];
[NSBezierPath fillRect:nextRect];
isOddRow = !isOddRow;
nextRect.origin.y+=height;
}
}
     
3R1C  (op)
Mac Enthusiast
Join Date: Oct 2001
Status: Offline
Reply With Quote
May 22, 2002, 04:34 AM
 
Wow. I cant believe that I was actually able to get what you posted to work! not because its hard, but because I'm a newbie who has never 'subclassed'. Anyway, enough self-wonder. Worked like a charm. I suppose it is a trade off tho. I lose the grey column separators. If you ever figure that one out, post it and i'll see if I can screw it up.
3R1C
     
Fresh-Faced Recruit
Join Date: Jan 2000
Location: Los Altos, CA, USA
Status: Offline
Reply With Quote
May 22, 2002, 03:03 PM
 
I'll leave that as an excersize for you

A couple of areas that I would start off with in order to accomplish this (there may be other ways):

override

- (void)drawGridInClipRect: (NSRect)r

and iterate through the columns (NSArray *tcs = [self tableColumns], then loop through & do the drawing within the clipped rectangle)

[ 05-22-2002: Message edited by: Brad Brack ]
     
Fresh-Faced Recruit
Join Date: May 2002
Status: Offline
Reply With Quote
May 22, 2002, 03:18 PM
 
Originally posted by 3R1C:
I lose the grey column separators.
Are you still doing setIntercellSpacing? or does this override that?
Love,
The Surfer
     
3R1C  (op)
Mac Enthusiast
Join Date: Oct 2001
Status: Offline
Reply With Quote
May 22, 2002, 10:49 PM
 
Im not doing the intercell spacing anymore, because the color that will show thru is one of the two alternating row colors, not gray as in iTunes. Also that wont work because the column lines will only be visible on rows which have data instead of all the way to the bottom of the table. My ignorance on these matters is only eclipsed by my tenacity. I shall find a way (probably with everyones help).
3R1C
     
Dedicated MacNNer
Join Date: Jan 2001
Location: Virginia, US
Status: Offline
Reply With Quote
May 25, 2002, 02:36 PM
 
You can do this without subclassing too by implementing the -tableView:willDisplayCell:forTableColumn:row: delegate method. Something like this:

<BLOCKQUOTE><font size="1"face="Geneva, Verdana, Arial">code:</font><HR><pre><font size=1 face=courier>
- (void)tableViewNSTableView *)tableView willDisplayCellid)cell forTableColumnNSTableColumn *)tableColumn rowint)row
{
NSColor *oddRowColor, *evenRowColor; <font color = brown>//assume these exist</font>

if ([cell isKindOfClass:[NSTextFieldCell class]]) {
NSColor *color = (row & <font color = blue>1</font>)? oddRowColor : evenRowColor;
[cell setBackgroundColor:color];
[cell setDrawsBackground:YES]; <font color = brown>// just being safe</font>
}
}
</font>[/code]

The cells are always NSTextFieldCells BTW unless you change them programmatically.
     
3R1C  (op)
Mac Enthusiast
Join Date: Oct 2001
Status: Offline
Reply With Quote
May 25, 2002, 08:03 PM
 
This is how I was doing it before, but this method doesnt do the alternating row colors such that they will continue to the end of the table regardless of how many rows the table has. This causes the balance of the table to keep the table background color.
3R1C
     
Fresh-Faced Recruit
Join Date: Jan 2000
Location: Los Altos, CA, USA
Status: Offline
Reply With Quote
May 26, 2002, 12:25 PM
 
right, and the code above from my last post ONLY fills in the remaining area. (it's assumed you already have methods in place to put background colors in the rows drawn)
I've found some outstanding issues which need to be addressed too-
• if you plan to have drag & drop enabled in this table view, you'll need to add additional code to take care of highlighting (putting borders around) the appropriate row or entire table view
• you may need to do something special if you allow for column selection
     
3R1C  (op)
Mac Enthusiast
Join Date: Oct 2001
Status: Offline
Reply With Quote
May 26, 2002, 06:14 PM
 
&lt;sheepish apology&gt; My bad. DOH! &lt;/sheepish apology&gt;
3R1C
     
Fresh-Faced Recruit
Join Date: May 2002
Status: Offline
Reply With Quote
May 26, 2002, 07:15 PM
 
</font><blockquote><font size="1" face="Geneva, Verdana, Arial, sans-serif">quote:</font><hr /><font size="1" face="Geneva, Verdana, Arial, sans-serif">Originally posted by lindberg:
</font><blockquote><font size="1" face="Geneva, Verdana, Arial, sans-serif">code:</font><hr /><pre style="font-size:x-small; font-family: monospace;">NSColor *color = (row &amp; 1)? oddRowColor : evenRowColor; </pre><hr /></blockquote><font size="1" face="Geneva, Verdana, Arial, sans-serif"></font><hr /></blockquote><font size="1" face="Geneva, Verdana, Arial, sans-serif">Could you please explain what you are doing here? Obviously, you are setting color to one of the two bg colors, but how, exactly, is this accomplished? Specifically, how do the '&' and '?' characters translate to "pick one of &lt;oddRowColor : evenRowColor&gt;"?

Here's my uneducated guess:
color = (BOOL)? YESresult : NOresult;

If that's right, what does '& 1' do? I would have done something like:
</font><blockquote><font size="1" face="Geneva, Verdana, Arial, sans-serif">code:</font><hr /><pre style="font-size:x-small; font-family: monospace;">NSColor *color = (row % 2)? oddRowColor : evenRowColor; </pre><hr /></blockquote><font size="1" face="Geneva, Verdana, Arial, sans-serif">Also, is this sort of construct only valid for variable definition? And does it have to be done while declaring, or can you say:
</font><blockquote><font size="1" face="Geneva, Verdana, Arial, sans-serif">code:</font><hr /><pre style="font-size:x-small; font-family: monospace;">NSColor *color;
// Do some other stuff
color = (row &amp; 1)? oddRowColor : evenRowColor; </pre><hr /></blockquote><font size="1" face="Geneva, Verdana, Arial, sans-serif">Sorry about the noob questions, but I am trying to learn Cocoa without knowing anything about C. <img border="0" title="" alt="[Wink]" src="wink.gif" /> I was reading a book on C++, but then I realized I was barking up the wrong branch. I guess I'll have to check out a good C book from Safari.
Love,
The Surfer
     
Clinically Insane
Join Date: Oct 2001
Location: San Diego, CA, USA
Status: Offline
Reply With Quote
May 26, 2002, 10:06 PM
 
The ? operator is a way of doing an evaluation in the middle of another statement. These statements are equivalent:
</font><blockquote><font size="1" face="Geneva, Verdana, Arial, sans-serif">code:</font><hr /><pre style="font-size:x-small; font-family: monospace;">a = (x &lt; 2) ? y : z;

if (x &lt; 2)
{
a = y;
}
else
{
a = z;
}</pre><hr /></blockquote><font size="1" face="Geneva, Verdana, Arial, sans-serif">In both cases, it decides whether x is less than 2 and gives a the value or either y or z.

The & operator is a bitwise operator. It operates on the actual bits that represent a number, rather than the number those bits represent. In this case, you're checking the rightmost bit. If it's 1, you know it's an odd number. (See <a href="http://www.iota-six.co.uk/c/17_bitwi.htm" target="_blank">here</a> for a good explanation of the bitwise operators and what they do.)
Your row % 2 solution would have the same effect, but bitwise operations tend to be much faster than arithmetic ones.

As for where things work--you've got a compiler. Write some code and figure it out. You'll probably find a few places where things don't, but OS X is stable enough to stand a few program crashes. And the actual practice writing code is invaluable--that's where you'll really learn.
Chuck
___
"Instead of either 'multi-talented' or 'multitalented' use 'bisexual'."
     
Fresh-Faced Recruit
Join Date: May 2002
Status: Offline
Reply With Quote
May 27, 2002, 01:53 AM
 
Hey thanks, Chuckit!

Looks like I had the right idea after all. Thanks for the link on bitwise operators. I've been wondering how they work. I almost had to ask why the '&' only checked the last bit of row , but then I realized it's because 1 == ...00001

Handy, and they're faster to boot. MOD is probably one of the slowest ops, I guess.
Love,
The Surfer
     
Dedicated MacNNer
Join Date: Jan 2001
Location: Virginia, US
Status: Offline
Reply With Quote
May 27, 2002, 10:48 PM
 
Thanks for explaining things Chuckit :-)

I probably should have used

NSColor *color = ((row % 2) == 0)? evenRowColor : oddRowColor;

in the example to be more explicit, but the (num & 1) trick is just an ingrained habit. To be honest, a decent optimizing compiler should convert the %2 code into the efficient form, and even if not you'll never notice the speed difference in this case anyways. So if it's more clear to you using the "(num % 2)" form, then by all means do that.

But, I guess it's been the fodder for more discussion, which is always good :-)
     
Junior Member
Join Date: Nov 2001
Location: Indiana
Status: Offline
Reply With Quote
May 28, 2002, 10:14 AM
 
Okay, I set out to make a iTunes-esq NSTableView as well...I had the intercell spacing trick and the willDisplayCell, stuff, blah, blah, blah. But then I read this thread and thought I'd take it a little further. What I came up with was a class that would do the alternating color spacing, have nice gridlines in both the filled data, and the extra space. It even allows selection and still looks decent...

But there are a few problems, so I thought I should just throw it out here for public consumption, as it'll probably help someone and a few of you guys can help me out:

When resizing columns the grid lines go all to hell for some reason, and the when the gridline intersects with a selected row there are sometimes "artifacts", which may just be optical illusions, but in any case it would look nicer if we could kill the grid lines at intersection with selected rows.

WARNING: This code is (probably) horrible. It was a hack of a hack of hack of some code I got from earlier in the thread and my own code I've been using in Neo.app. I'm also about ready to go take a long, long nap.

Here it is: <a href="http://elwww.cc.purdue.edu/~mthole/neo/CustomTableView.m" target="_blank">CustomTableView.m</a>

Can anyone make anything better with that?

- Michael Thole
     
Fresh-Faced Recruit
Join Date: May 2002
Status: Offline
Reply With Quote
May 28, 2002, 06:36 PM
 
</font><blockquote><font size="1" face="Geneva, Verdana, Arial, sans-serif">quote:</font><hr /><font size="1" face="Geneva, Verdana, Arial, sans-serif">Originally posted by lindberg:
<strong>But, I guess it's been the fodder for more discussion, which is always good :-)</strong></font><hr /></blockquote><font size="1" face="Geneva, Verdana, Arial, sans-serif">The two main reasons I lurk here is to offer advice and find tricks like that.

Like I said, I don't really know anything about C. Just some basics I picked up when I started "Learning to Program in C++" and what I've gleaned from examining other people's implementations. Thanks again.

And now, back to your regularly scheduled thread...
Love,
The Surfer
     
   
Thread Tools
Forum Links
Forum Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On
Top
Privacy Policy
All times are GMT -5. The time now is 03:03 PM.
All contents of these forums © 1995-2011 MacNN. All rights reserved.
Branding + Design: www.gesamtbild.com
vBulletin v.3.8.7 © 2000-2011, Jelsoft Enterprises Ltd., Content Relevant URLs by vBSEO 3.3.2