views:

40

answers:

1

I have an NSTableView in my application with data being drawn in for both the X and Y axes (ie, every row is matched with every column.) I've got the data populating the cells the way I'd like, but it looks terrible with the columns stretched out horizontally.

I would like to turn the NSTextFieldCell on its side, so that the text is written vertically instead of horizontally. I realize that I'm probably going to have to subclass the NSTextFieldCell, but I'm not sure which functions I'm going to need to override in order to accomplish what I want to do.

What functions in NSTextFieldCell draw the text itself? Is there any built-in way to draw text vertically instead of horizontally?

A: 

Well, it took a lot of digging to figure this one out, but I eventually came across the NSAffineTransform object, which apparently can be used to shift the entire coordinate system with respect to the application. Once I had figured that out, I subclassed NSTextViewCell and overrode the -drawInteriorWithFrame:inView: function to rotate the coordinate system around before drawing the text.

- (void)drawInteriorWithFrame:(NSRect)cellFrame inView:(NSView *)controlView {
    // Save the current graphics state so we can return to it later
    NSGraphicsContext *context = [NSGraphicsContext currentContext];
    [context saveGraphicsState];

    // Create an object that will allow us to shift the origin to the center
    NSSize originShift = NSMakeSize(cellFrame.origin.x + cellFrame.size.width / 2.0,
                                    cellFrame.origin.y + cellFrame.size.height / 2.0);

    // Rotate the coordinate system
    NSAffineTransform* transform = [NSAffineTransform transform];
    [transform translateXBy: originShift.width yBy: originShift.height]; // Move origin to center of cell
    [transform rotateByDegrees:270]; // Rotate 90 deg CCW
    [transform translateXBy: -originShift.width yBy: -originShift.height]; // Move origin back
    [transform concat]; // Set the changes to the current NSGraphicsContext

    // Create a new frame that matches the cell's position & size in the new coordinate system
    NSRect newFrame = NSMakeRect(cellFrame.origin.x-(cellFrame.size.height-cellFrame.size.width)/2,
                                 cellFrame.origin.y+(cellFrame.size.height-cellFrame.size.width)/2,
                                 cellFrame.size.height, cellFrame.size.width);

    // Draw the text just like we normally would, but in the new coordinate system
    [super drawInteriorWithFrame:newFrame inView:controlView];

    // Restore the original coordinate system so that other cells can draw properly
    [context restoreGraphicsState];
}

I now have an NSTextCell that draws its contents sideways! By changing the row height, I can give it enough room to look good.

Nate Thorn