| Index | Submit class | Submit snippet | Submission feed | List |

PWLevelIndicator

Language: Objective-C, Author: Collin Henderson
License: Public domain

I noticed that the current star rating level indicator style really sucks. So I took it upon myself to make a custom star rater. You can easily change around the images, and size (you have to do this in the .m file though.) The images that come with it look nice for a polished (or unified as some people call it) window like in iTunes.

PWLevelIndicator source preview

#import "PWLevelIndicator.h"

@implementation PWLevelIndicatorCell


- (void)drawWithFrame:(NSRect)cellFrame inView:(NSView *)controlView{

unsigned starCount = (unsigned)roundf([self floatValue]);

NSSize starSize = cellFrame.size;
starSize.width /= 5.0;

[starImg setSize:starSize];
[dotImg setSize:starSize];

NSRect starRect = NSMakeRect(0.0, 0.0, starSize.width, starSize.height);
NSRect imgRect = starRect;

if (starCount) {
unsigned starIndex;
for (starIndex = 0; starIndex < starCount; starIndex++) {
starRect.origin.x = starIndex * starSize.width;
[starImg drawInRect:starRect fromRect:imgRect operation:NSCompositeSourceOver fraction:1.0];
}
}
if ( (starCount < 5) ) {

unsigned starIndex;
for (starIndex = starCount; starIndex < 5; starIndex++) {
starRect.origin.x = starIndex * starSize.width;
[dotImg drawAtPoint:starRect.origin fromRect:imgRect operation:NSCompositeSourceOver fraction:1.0];
}
}
}

-(void)setImage:(NSImage *)image{
if (starImg != image) {
if (starImg != nil) [starImg release];
starImg = [image copy];
[starImg setScalesWhenResized:YES];
}
}

-(void)setDotImage:(NSImage *)dotImage{
if (dotImg != dotImage) {
if (dotImg != nil) [dotImg release];
dotImg = [dotImage copy];
[dotImg setScalesWhenResized:YES];
}
}

- (void) dealloc {
if (starImg != nil) [starImg release];
if (dotImg != nil) [dotImg release];
[super dealloc];
}

@end

@implementation PWLevelIndicator


+ (Class)cellClass{
return [PWLevelIndicatorCell class];
}

- (id) initWithCoder:(NSCoder *)aDecoder{
self = [super initWithCoder:aDecoder];
if (self != nil) {
[self setCell:[[[PWLevelIndicatorCell alloc] initWithLevelIndicatorStyle:NSRatingLevelIndicatorStyle] autorelease]];
NSRect liFrame = [self frame];
liFrame.size.width = 90.0; // new width
liFrame.size.height = 17.0; // new height
[self setFrame:liFrame];
[[self cell] setImage:[NSImage imageNamed:@"star_on.png"]];
[[self cell] setDotImage:[NSImage imageNamed:@"star_off.png"]];
}
return self;

}

- (id) initWithFrame:(NSRect)frameRect {
self = [super initWithFrame:frameRect];
if (self != nil) {
[self setCell:[[[PWLevelIndicatorCell alloc] initWithLevelIndicatorStyle:NSRatingLevelIndicatorStyle] autorelease]];
[[self cell] setImage:[NSImage imageNamed:@"star_on.png"]];
[[self cell] setDotImage:[NSImage imageNamed:@"star_off.png"]];
}
return self;
}


@end

PWLevelIndicator header preview


/* PWLevelIndicator.h */

#import <Cocoa/Cocoa.h>

@interface PWLevelIndicatorCell : NSLevelIndicatorCell{
NSImage *starImg;
NSImage *dotImg;
}

-(void)setDotImage:(NSImage *)dotImage;

@end

@interface PWLevelIndicator : NSLevelIndicator{
}
@end
Download Archive

Compatible with:


Comments

Hank McShane says:

I like the looks of this but I can't drag across the star images to change the rating. Any ideas what could be wrong?

bob says:

if (starImg != nil) [starImg release];

should be written as

[starImg release];

sending a message to nil has no effect

Name

Website

Do you hate spammers? (Answer "Yes")