small medium large xlarge

Generic-user-small
31 Jul 2011, 14:12
Paul Hancock (3 posts)

I implemented the shopping list project and have a question about the cellFrame coordinate system. In the project, in order to locate the coordinate to draw the strikethrough line for purchased items, Tim uses the code

CGFloat middleY = cellFrame.origin.y + cellFrame.size.height / 2;

This works well, but when I started changing the divisor to put the line, say, 1/3 the way up the cell rather than in the middle, I discovered that the cellFrame coordinate system starts at the TOP left, not the BOTTOM left. For example, the code

CGFloat middleY = cellFrame.origin.y;                         // draws the line at the TOP of the cellFrame
CGFloat middleY = cellFrame.origin.y + cellFrame.size.height; // draws the line at the BOTTOM of the cellFrame

I was under the impression that all coordinate origins were in the bottom left. What am I missing here?

Generic-user-small
31 Jul 2011, 14:54
Tim Isted (105 posts)

Thank you for asking this question - it’s pointed out something that I really should have mentioned very explicitly in the book when moving from plain NSView to drawing in NSTableView cells.

Any NSView has an isFlipped property. This is used to flip the coordinate system used for drawing in the view; the norm is bottom-left, flipped is top-left.

A flipped, top-left origin makes sense in many situations, and in particular in anything that draws repeated information from the top down, like an NSTableView. The table view, therefore, returns YES from isFlipped and uses a flipped coordinate system, meaning that when each of its NSCells does its drawing, the coordinates are still flipped.

If you’re in a position where you’re not sure whether the coordinates are flipped, just query the view. E.g.:

- (void)drawInteriorWithFrame:(NSRect)cellFrame inView:(NSView *)controlView
{
    [super drawInteriorWithFrame:cellFrame inView:controlView];
    
    if( [controlView isFlipped] ) {
        // treat origin as top left
    } else {
        // treat origin as bottom left
    }
    ...

I should have pointed out this flipped coordinate system in the book in the section “Subclassing NSTableViewCell,” where I show the output of logging the cell frames (p.308 in P1.0). You can see each Y coordinate is increasing:

{{129, 1}, {334, 17}}
{{129, 20}, {334, 17}}
{{129, 39}, {334, 17}}

where the first cell is at the top, but has a Y coordinate of 1 - the containing tableview’s coordinate system is flipped.

You must be logged in to comment