1. Welcome to the new MacRumors forums. See our announcement and read our FAQ

Drawing Cocoa Circles... Easy Enough, Right?

Discussion in 'Mac Programming' started by Littleodie914, Aug 16, 2007.

  1. macrumors 68000


    Hey guys, I've been wrestling with this problem for a while now, and I can't seem to come up with a solution. I've got a subclassed TableView that has a special column for drawing circles, based on the color assigned to the "parent data" of the table. (See Pic 1 for details.)

    The problem is, when I switch over to a different parent, like to the blue subject, any tasks I add will have the same peach color, *until* I exceed the number of earlier-created subjects. Confusing I know, but here's an example:

    I've got the situation seen below. I switch over to the blue subject, and create a task. It's peach. Create a second, it's still peach. Create a third, however, and they all turn blue. When I go back to the peach subject after creating that third blue task, The original two peach-colored "Thing 1" and "Thing 2" objects have turned blue as well!

    Here's what I'm using, in a subclassed NSTextFieldCell:

    NSColor *taskParentColor = [NSUnarchiver unarchiveObjectWithData:[[currentObject valueForKey:@"parentSubject"] valueForKey:@"color"]];
    [taskParentColor set];
    NSBezierPath* thePath3 = [NSBezierPath bezierPath];
    NSRect bounds3 = NSMakeRect(cellFrame.origin.x + (cellFrame.size.width / 2) - 5, cellFrame.origin.y + 3, 10, 10);
    [thePath3 appendBezierPathWithOvalInRect:bounds3];
    [thePath3 fill];
    I'm assuming there's something wrong with the way I'm drawing the circle, but I'm not that familiar with custom graphics. Here's to hoping you guys know a bit more than me! :) As always, thanks so much for your help!

    Attached Files:

  2. Moderator emeritus


    What's currentObject?

    I believe you can bind directly to the NSCell in the nib. So you could create a statusColor method in your object, and bind that to the cell. Then use that color directly, something like:

    NSColor *taskParentColor = [[self objectValue] valueForKey:@"statusColor"];
  3. Moderator emeritus


    Here's a mini project that demonstrates a custom cell and bindings. Almost everything is done in the nib.

    Hope this helps.
  4. macrumors 68000


    currentObject is the object in the TaskController (NSArrayController for the tableview) at the current index (row) the table is displaying.

    Edit: Yea, I see how that example works, thanks a lot for it. :) I think my way kind of works the same. Instead of actually binding to the color, it's just getting the color when it's asked to draw itself. So currentObject has a parent, the "Subject". The subject has a key "color", so when a task is being drawn, it's getting the archived color of its parent, and drawing that in the first column. I know it's at least *getting* the colors, since they show up, they just update oddly.

    Here's the source, if you want to check it out: (I know I've got a few other kinks to work out ;) )
  5. Moderator emeritus


    How are you updating it?

    Why are you archiving the color object?
  6. macrumors 68000


    Somehow, (it was a while back, I don't remember) I have an observer set up for when the subject changes, and in that code I'm calling [taskTableView reloadData] on the table.

    And I'm using a Core Data model, so to store it as "Binary" (since there's no "Color" option) I have to archive the NSColor object.
  7. macrumors 68000


    I also just noticed, after messing with it for a bit, that if you click on a task then off it, somewhere randomly on the table, (to deselect the task) a few times, it will switch back and forth between the right and wrong colors. :confused:

    This is just getting weirder and weirder!

    Edit: So what seems to be happening, after a few more NSLog's, is the currently-drawn item isn't always reporting the correct parent subject. How exactly is drawing updated when using Core Bindings with a Core Data model for a TableView?
  8. macrumors 6502

    Your custom cell should be fairly simple. Try setting up an internal variable for the cell color with setter and getter methods and get the color from that variable when drawing. You shouldn't need to access the datasource from the cell.

    The easiest place to assign the color is in the NSTableView Delegate methods. Try setting the color here:
    - (void)tableView:(NSTableView *)aTableView willDisplayCell:(id)aCell forTableColumn:(NSTableColumn *)aTableColumn row:(int)rowIndex
    Only one datacell exists for each table column. The datacell needs to be configured each time it is used to draw a cell in a table. You will probably find that when re-sorting the table then clicking around, the last item in the table is the one that starts overriding the other cells.

    If you're using bindings, think about using value transformers as opposed to adding to your data model.

    I'm still new to a lot of this, so please correct me if I missed anything.

    Luke Gladding


Share This Page