// // PSActivityIndicator.m // Perforce // // Created by Adam Czubernat on 07/11/2013. // Copyright (c) 2013 Perforce Software, Inc. All rights reserved. // #import "PSActivityIndicator.h" #define PSActivityIndicatorFinsNumber 12 @interface PSActivityIndicator () { NSColor *color; CALayer *fin; } - (void)makeLayers; - (void)makeAnimation; @end @implementation PSActivityIndicator - (void)viewDidMoveToWindow { [fin removeAnimationForKey:@"finAnimation"]; if (self.window) [self makeLayers]; } - (void)viewDidHide { [fin removeAnimationForKey:@"finAnimation"]; } - (void)viewDidUnhide { [fin removeAnimationForKey:@"finAnimation"]; [self makeAnimation]; } #pragma mark - Private - (void)makeLayers { CAReplicatorLayer *replicator = [CAReplicatorLayer layer]; self.layer = replicator; self.wantsLayer = YES; CGFloat size = fminf(self.bounds.size.width, self.bounds.size.height); CGFloat thickness = size * 0.08f; CGFloat deltaAngle = (2.0*M_PI)/(PSActivityIndicatorFinsNumber); fin = [CALayer layer]; [fin setFrame:(CGRect) { (size - thickness) * 0.5f, 0.0f, thickness, size * 0.25f }]; CGColorRef colorRef = CGColorCreateFromColor(color ?: [NSColor blackColor]); [fin setBackgroundColor:colorRef]; CGColorRelease(colorRef); [fin setCornerRadius:thickness * 0.5f]; [fin setOpacity:0.25f]; [replicator setFrame:self.bounds]; [replicator setAnchorPoint:(CGPoint) { 0.5f, 0.5f }]; [replicator addSublayer:fin]; [replicator setInstanceCount:PSActivityIndicatorFinsNumber]; [replicator setInstanceTransform:CATransform3DMakeRotation(-deltaAngle, 0.0f, 0.0f, 1.0f)]; [replicator setInstanceDelay:1.0f / PSActivityIndicatorFinsNumber]; [replicator addSublayer:fin]; [self makeAnimation]; } - (void)makeAnimation { CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"opacity"]; [animation setRemovedOnCompletion:NO]; [animation setRepeatCount:HUGE_VALF]; [animation setFromValue:[NSNumber numberWithFloat:1.0]]; [animation setToValue:[NSNumber numberWithFloat:0.0]]; [animation setDuration:1.0f]; [fin addAnimation:animation forKey:@"finAnimation"]; } #pragma mark - Public - (void)setColor:(NSColor *)aColor { color = aColor ?: [NSColor blackColor]; CGColorRef colorRef = CGColorCreateFromColor(color); [fin setBackgroundColor:colorRef]; CGColorRelease(colorRef); } - (NSColor *)color { return color; } @end