Skip to content

Instantly share code, notes, and snippets.

@angerman
Created March 6, 2009 04:46
Show Gist options
  • Save angerman/74762 to your computer and use it in GitHub Desktop.
Save angerman/74762 to your computer and use it in GitHub Desktop.
/* -*- coding: utf-8 -*-
*
* Starrater with a revised version from boucher from 280North
*/
@import <AppKit/CPControl.j>
@import <AppKit/CPImage.j>
var starEmpty = [[CPImage alloc] initWithContentsOfFile: "Resources/StarRater/empty.gif" size: CPSizeMake(25, 25)],
starSet = [[CPImage alloc] initWithContentsOfFile: "Resources/StarRater/set.gif" size: CPSizeMake(25, 25)],
starActive = [[CPImage alloc] initWithContentsOfFile: "Resources/StarRater/active.gif" size: CPSizeMake(25, 25)],
loaded;
@implementation StarRatingView : CPControl
{
int numberOfStars @accessors;
int activeValue;
BOOL isActive;
}
- (id)initWithFrame:(CGRect)aFrame
{
if (self = [super initWithFrame:aFrame])
{
numberOfStars = 6;
if(loaded)
return self;
if([starEmpty loadStatus] != CPImageLoadStatusCompleted)
[[CPNotificationCenter defaultCenter] addObserver:self selector:@selector(imageDidLoad:) name:CPImageDidLoadNotification object:starEmpty];
if([starSet loadStatus] != CPImageLoadStatusCompleted)
[[CPNotificationCenter defaultCenter] addObserver:self selector:@selector(imageDidLoad:) name:CPImageDidLoadNotification object:starSet];
if([starActive loadStatus] != CPImageLoadStatusCompleted)
[[CPNotificationCenter defaultCenter] addObserver:self selector:@selector(imageDidLoad:) name:CPImageDidLoadNotification object:starActive];
[self checkLoaded];
}
return self;
}
- (void)viewWillMoveToWindow:(CPWindow)aWindow
{
[aWindow setAcceptsMouseMovedEvents:YES];
}
// This will be called whenever we setNeedsDisplay to YES
- (void)drawRect:(CGRect)aRect
{
if(!loaded)
return;
var context = [[CPGraphicsContext currentContext] graphicsPort],
bounds = [self bounds],
starWidth = bounds.size.width / numberOfStars,
starHeight = bounds.size.height,
value = [self intValue];
for (var i=0; i<numberOfStars; i++)
{
if (isActive && activeValue > i)
CGContextDrawImage(context, CGRectMake(starWidth*i, 0, starWidth, starHeight), starActive);
else
{
if (value > i)
CGContextDrawImage(context, CGRectMake(starWidth*i, 0, starWidth, starHeight), starSet);
else if (value <= i)
CGContextDrawImage(context, CGRectMake(starWidth*i, 0, starWidth, starHeight), starEmpty);
}
}
}
-(void)imageDidLoad:(CPNotification)aNotification
{
[[CPNotificationCenter defaultCenter] removeObserver:self name:CPImageDidLoadNotification object:[aNotification object]];
[self checkLoaded];
}
- (void)checkLoaded
{
loaded = [starEmpty loadStatus] == CPImageLoadStatusCompleted && [starSet loadStatus] == CPImageLoadStatusCompleted && [starActive loadStatus] == CPImageLoadStatusCompleted;
if(loaded)
[self setNeedsDisplay:YES];
}
- (void)mouseEntered:(CPEvent)anEvent
{
isActive = YES;
[self setNeedsDisplay:YES];
}
- (void)mouseExited:(CPEvent)anEvent
{
isActive = NO;
[self setNeedsDisplay:YES];
}
- (void)mouseMoved:(CPEvent)anEvent
{
var offset = [self convertPoint:[anEvent locationInWindow] fromView:nil].x,
bounds = [self bounds],
starWidth = bounds.size.width / numberOfStars,
activeValue = CEIL(offset/starWidth);
[self setNeedsDisplay:YES];
}
- (void)mouseDown:(CPEvent)anEvent
{
[self setIntValue:activeValue];
activeValue = 0;
[super mouseDown:anEvent];
[self setNeedsDisplay:YES];
}
- (void)sizeToFit
{
[self setFrameSize:CGSizeMake(numberOfStars*25, 25)];
}
@end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment