Rhys Lewis
Rhys Lewis

Reputation: 453

How to replicate Mac OSX system graphic?

I'm looking to add functionality to my Mac OSX app to display a graphic like the one in the attached link (that Mac OSX displays for remaining space available on your hard drive) when a series of variables are passed values.

For example, if I had 5 variables, A to E with the following values/percentages (A=50, B=20, C=15, D=10, E=5), I would like to learn how to display those values graphically in this format where the size of the color bar is proportional to the value, and a legend is also displayed.

Any sample code that anyone could provide would be greatly appreciated.

Upvotes: 1

Views: 156

Answers (2)

Rhys Lewis
Rhys Lewis

Reputation: 453

SOLVED: In the end I decided to learn how to use quartz to do some drawing. It has been very rewarding as I've achieved the desired result of proportionally scaled bars that alter size as the input variables change. It's very customisable too.

To anyone else that would like to learn how to do this, I'd highly recommend this tutorial.

Upvotes: 2

SIGKILL
SIGKILL

Reputation: 400

There are many different way to achieve this. I would start by using a NSBox object and give it the right shape. Next I would programmatically create an image that shows the different colors and mask it with another image to cut out all the edges. Then i would create a NSImageView inside the box and display the masked image there. I can add some code if you want.

EDIT:

Some code.

I've tried it using a simple static picture that is made up of 2 colors and a transparent rest. I just add it to the outlet like so:

-(void) awakeFromNib{
     NSImage* img = [self maskImage:[NSImage imageNamed:@"Static image from Bundle"] withMask:[NSImage imageNamed:@"Static image mask"]];
    [imgView setImage:img];

}

And the maskImage:withMask: method looks like this:

- (NSImage*) maskImage:(NSImage *)image withMask:(NSImage *)maskImage {
     CGImageSourceRef sourceRef = CGImageSourceCreateWithData((__bridge CFDataRef)[maskImage TIFFRepresentation], NULL);
     CGImageRef maskRef = CGImageSourceCreateImageAtIndex(sourceRef, 0, NULL);

     sourceRef = CGImageSourceCreateWithData((__bridge CFDataRef)[image TIFFRepresentation], NULL);
     CGImageRef imageRef = CGImageSourceCreateImageAtIndex(sourceRef, 0, NULL);


     CGImageRef mask = CGImageMaskCreate(CGImageGetWidth(maskRef),
                                    CGImageGetHeight(maskRef),
                                    CGImageGetBitsPerComponent(maskRef),
                                    CGImageGetBitsPerPixel(maskRef),
                                    CGImageGetBytesPerRow(maskRef),
                                    CGImageGetDataProvider(maskRef), NULL, false);

     CGImageRef masked = CGImageCreateWithMask(imageRef, mask);
     return [[NSImage alloc] initWithCGImage:masked size:NSZeroSize];

}

For the mask image I used a simple black and white photoshop picture of the size of the NSBox object and blacked out everything that should become transparent. The only problem with this method is the shadows of the NSBox are not rendered. To achieve this you need to create a gradient in your mask. This should be actually pretty straight forward.

I have been using these pictures: http://postimage.org/gallery/ertbeca/

Source image: http://postimage.org/image/pdgs4abop/ Mask image: http://postimage.org/image/54teikcdl/

And it ended up looking like this: http://postimage.org/image/s8tvb5fop/

Hope that helps.

Upvotes: 0

Related Questions