Skip to content

Instantly share code, notes, and snippets.

@boucher
Forked from angerman/gist:74762
Created March 6, 2009 04:53
Show Gist options
  • Save boucher/74764 to your computer and use it in GitHub Desktop.
Save boucher/74764 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)];
@implementation StarRatingView : CPControl
{
int numberOfStars @accessors;
int activeValue;
BOOL isActive;
}
- (id)initWithFrame:(CGRect)aFrame
{
if (self = [super initWithFrame:aFrame])
{
numberOfStars = 6;
}
return self;
}
- (void)viewWillMoveToWindow:(CPWindow)aWindow
{
[aWindow setAcceptsMouseMovedEvents:YES];
}
// This will be called whenever we setNeedsDisplay to YES
- (void)drawRect:(CGRect)aRect
{
if(![self checkLoaded])
setTimeout(function(){[self setNeedsDisplay:YES]});
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)checkLoaded
{
return [starEmpty loadStatus] == CPImageLoadStatusCompleted && [starSet loadStatus] == CPImageLoadStatusCompleted && [starActive loadStatus] == CPImageLoadStatusCompleted;
}
- (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];
[super mouseDown:anEvent];
}
- (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