#import "PLYAnimationDelegate.h"
#import "PLYView.h"
@interface PLYView ()
@property (nonatomic, assign) CGRect trueFrame;
@end
@implementation PLYView
- (instancetype)init {
if ((self = [super init])) {
self.opaque = NO;
}
return self;
}
- (CGRect)trueFrame {
CGRect frame = self.bounds;
NSAssert(frame.origin.x == 0.0, @"Can't calculate true frame when origin is non-zero.");
NSAssert(frame.origin.y == 0.0, @"Can't calculate true frame when origin is non-zero.");
frame.origin.x = self.center.x - frame.size.width / 2.0;
frame.origin.y = self.center.y - frame.size.height / 2.0;
return frame;
}
- (void)setTrueFrame:(CGRect)frame {
frame.origin.x += frame.size.width / 2.0;
frame.origin.y += frame.size.height / 2.0;
self.center = frame.origin;
frame.origin.x = 0.0;
frame.origin.y = 0.0;
self.bounds = frame;
}
- (void)updateLayout {
for (UIView *view in self.subviews)
[view setNeedsLayout];
if (self.layout == nil)
return;
CGRect oldFrame = self.trueFrame;
CGRect newFrame = [self.layout fetch];
if (CGRectEqualToRect(oldFrame, newFrame))
return;
self.trueFrame = newFrame;
}
- (void)layoutSubviews {
[super layoutSubviews];
[self updateLayout];
CGRect bounds = [self convertRect:self.frame toView:nil];
[self.onLayout callWithArgument:[[PLYLayoutEvent alloc] initWithFrame:bounds]];
}
- (void)setOpaqueBackgroundColor:(UIColor *)color {
_opaqueBackgroundColor = color;
[self setNeedsDisplay];
}
- (CGPoint)resolvePoint:(PLYPoint)point {
CGPoint result = CGPointZero;
if (point.x.kind == PLYDimensionKindPixels)
result.x = point.x.value;
else if (point.x.kind == PLYDimensionKindPercentage)
result.x = point.x.value * self.bounds.size.width;
if (point.y.kind == PLYDimensionKindPixels)
result.y = point.y.value;
else if (point.y.kind == PLYDimensionKindPercentage)
result.y = point.y.value * self.bounds.size.height;
return result;
}
- (void)drawRect:(CGRect)dirtyRect {
const CGFloat kappa = 4 * (sqrt(2.0) - 1.0) / 3.0;
CGPoint tl = [self resolvePoint:self.cornerRadii.topLeft];
CGPoint tr = [self resolvePoint:self.cornerRadii.topRight];
CGPoint br = [self resolvePoint:self.cornerRadii.bottomLeft];
CGPoint bl = [self resolvePoint:self.cornerRadii.bottomRight];
UIBezierPath *path = [UIBezierPath bezierPath];
[path moveToPoint:CGPointMake(tl.x, 0.0)];
[path addLineToPoint:CGPointMake(self.bounds.size.width - tr.x, 0.0)];
[path addCurveToPoint:CGPointMake(self.bounds.size.width, tr.y)
controlPoint1:CGPointMake(self.bounds.size.width - tr.x + tr.x * kappa, 0.0)
controlPoint2:CGPointMake(self.bounds.size.width, tr.y - tr.y * kappa)];
[path addLineToPoint:CGPointMake(self.bounds.size.width, self.bounds.size.height - br.y)];
[path addCurveToPoint:CGPointMake(self.bounds.size.width - br.x, self.bounds.size.height)
controlPoint1:CGPointMake(self.bounds.size.width, self.bounds.size.height - br.y + br.y * kappa)
controlPoint2:CGPointMake(self.bounds.size.width - br.x + br.x * kappa, self.bounds.size.height)];
[path addLineToPoint:CGPointMake(bl.x, self.bounds.size.height)];
[path addCurveToPoint:CGPointMake(0.0, self.bounds.size.height - bl.y)
controlPoint1:CGPointMake(bl.x - bl.x * kappa, self.bounds.size.height)
controlPoint2:CGPointMake(0.0, self.bounds.size.height - bl.y + bl.y * kappa)];
[path addLineToPoint:CGPointMake(0.0, tl.y)];
[path addCurveToPoint:CGPointMake(tl.x, 0.0)
controlPoint1:CGPointMake(0.0, tl.y - tl.y * kappa)
controlPoint2:CGPointMake(tl.x - tl.x * kappa, 0.0)];
[path closePath];
[self.opaqueBackgroundColor setFill];
[path fill];
}
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
[super touchesBegan:touches withEvent:event];
[self.onPointerDown callWithArgument:nil];
}
- (void)touchesCancelled:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
[super touchesCancelled:touches withEvent:event];
[self.onPointerCancel callWithArgument:nil];
}
- (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
[super touchesEnded:touches withEvent:event];
[self.onPointerUp callWithArgument:nil];
}
- (PLYAnimationHandle *)addKeyframeAnimation:(PLYKeyframeAnimation *)animation
forKeyPath:(NSString *)keyPath {
NSString *key = [NSUUID UUID].UUIDString;
CAAnimation *keyframes = [animation CAKeyframeAnimationWithKeyPath:keyPath];
PLYAnimationHandle *handle = [[PLYAnimationHandle alloc] initWithLayer:self.layer key:key];
keyframes.delegate = [[PLYAnimationDelegate alloc] initWithHandle:handle];
[self.layer addAnimation:keyframes forKey:key];
return handle;
}
@end