Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting an NSImage from an NSProgressIndicator

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.

like image 390
lfalin Avatar asked Nov 04 '08 16:11

lfalin


2 Answers

I've used AMIndeterminateProgressIndicatorCell for indeterminate progress indicators in cells. It's not a true NSProgressIndicator, as it does it's own drawing, but it's a pretty good replica, IMO.

alt text
(source: harmless.de)

like image 138
Dave Dribin Avatar answered Oct 24 '22 09:10

Dave Dribin


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];
like image 36
Brian Webster Avatar answered Oct 24 '22 09:10

Brian Webster