views:

604

answers:

2

I need to put the image from an NSProgressIndicator into an NSOutlineView Cell. I have written up code that does this for a determinate indicator and it works just great:

NSProgressIndicator *progressIndicator = [[NSProgressIndicator alloc] initWithFrame:NSMakeRect(0, 0, 16, 16)];
[progressIndicator setStyle:NSProgressIndicatorSpinningStyle];    
[progressIndicator setIndeterminate:NO];
[progressIndicator setMaxValue:100.0];
[progressIndicator setDoubleValue:somePercentage];    

NSImage *updateImage = [[NSImage alloc] initWithData:[progressIndicator dataWithPDFInsideRect:[progressIndicator frame]]];
[progressIndicator release];


return [updateImage autorelease];

I have tried to modify the code to also give me indeterminate indicator images. However for the indeterminate case, I always get a blank 16x16 image. (I have confirmed this by writing the image to a file in each case, the determinate case gives me the progress indicator image, the indeterminate case is always 16x16 white square).

The modified code is:

if(self.lengthUnknown)
{
    NSProgressIndicator *progressIndicator = [[NSProgressIndicator alloc] initWithFrame:NSMakeRect(0, 0, 16, 16)];
    [progressIndicator setStyle:NSProgressIndicatorSpinningStyle];    
    [progressIndicator setIndeterminate:YES];

    NSImage *updateImage = [[NSImage alloc] initWithData:[progressIndicator dataWithPDFInsideRect:[progressIndicator frame]]];
    [progressIndicator release];


    return [updateImage autorelease];
}
else
{
 // Same code as the first listing, this case works fine
}

Do indeterminate progress indicators use some type of drawing that causes -dataWithPDFInsideRect: to be unable to capture their image?


More information: I tried setting the progress indicator to not use threaded animation as well as trying to grab the contents through NSImage's lockFocus method as suggested below but neither of those attempts made a difference.

The progress indicator cell code that Dave mentions below (AMIndeterminateProgressIndicatorCell) is a great workaround, but I would still like to know why I can't use the same technique that works with the determinate mode.

+4  A: 
Dave Dribin
+2  A: 

Progress indicators do use a background thread to keep their animation drawing even if the main thread is busy doing something else, so it's possible that's what's causing the problem. You might try calling setUsesThreadedAnimation:NO on the progress indicator before doing your drawing to see if that makes a difference.

Another tact would be to create a blank NSImage, and then call the progress indicator's drawRect: method to render its contents into the image buffer. That would look something like:

NSProgressIndicator* progressIndicator;
NSImage* image = [[NSImage alloc] initWithSize:[progressIndicator bounds].size];
[image lockFocus];
[progressIndicator drawRect:[progressIndicator bounds]];
[image unlockFocus];
Brian Webster