/
Checkbox.m
132 lines (111 loc) · 4.52 KB
/
Checkbox.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
#import "Checkbox.h"
static void
addRoundedRect(CGContextRef ctx, CGRect rect, float cornerRadius) {
float x_left = rect.origin.x;
float x_left_center = x_left + cornerRadius;
float x_right_center = x_left + rect.size.width - cornerRadius;
float x_right = x_left + rect.size.width;
float y_top = rect.origin.y;
float y_top_center = y_top + cornerRadius;
float y_bottom_center = y_top + rect.size.height - cornerRadius;
float y_bottom = y_top + rect.size.height;
/* Begin path */
CGContextBeginPath(ctx);
CGContextMoveToPoint(ctx, x_left, y_top_center);
/* First corner */
CGContextAddArcToPoint(ctx, x_left, y_top, x_left_center, y_top, cornerRadius);
/* Second corner */
CGContextAddArcToPoint(ctx, x_right, y_top, x_right, y_top_center, cornerRadius);
/* Third corner */
CGContextAddArcToPoint(ctx, x_right, y_bottom, x_right_center, y_bottom, cornerRadius);
/* Fourth corner */
CGContextAddArcToPoint(ctx, x_left, y_bottom, x_left, y_bottom_center, cornerRadius);
/* Done */
CGContextClosePath(ctx);
}
@implementation CheckboxDrawing
@synthesize selected;
- (void)setSelected:(BOOL)flag {
selected = flag;
[self setNeedsDisplay];
if (flag) {
CABasicAnimation *scale = [CABasicAnimation animationWithKeyPath:@"transform"];
scale.fromValue = [NSValue valueWithCATransform3D:CATransform3DMakeScale(2, 2, 1)];
scale.toValue = [NSValue valueWithCATransform3D:CATransform3DIdentity];
scale.duration = 0.27;
scale.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];
[self addAnimation:scale forKey:@"selected"];
}
}
- (void)drawInContext:(CGContextRef)context {
CGGradientRef myGradient;
CGColorSpaceRef myColorspace;
size_t num_locations = 2;
CGFloat locations[2] = { 0.0, 1.0 };
CGFloat components[8] = { 0.89, 0.89, 0.89, 1.0, // Start color
0.83, 0.83, 0.83, 1.0 }; // End color
myColorspace = CGColorSpaceCreateDeviceRGB();
myGradient = CGGradientCreateWithColorComponents(myColorspace, components,
locations, num_locations);
CGPoint myStartPoint, myEndPoint;
myStartPoint.x = 0.0;
myStartPoint.y = 0.0;
myEndPoint.x = 0.0;
myEndPoint.y = self.bounds.size.height;
addRoundedRect(context, CGRectInset(self.bounds, 2, 2), 3);
CGContextClip(context);
CGContextDrawLinearGradient(context, myGradient, myStartPoint, myEndPoint, 0);
//CGContextSetRGBStrokeColor(context, 0.53, 0.53, 0.53, 1);
CGContextSetRGBStrokeColor(context, 0.25, 0.25, 0.25, 1);
//// Draw border
CGContextSetLineWidth(context, 1.5);
addRoundedRect(context, CGRectInset(self.bounds, 2, 2), 3);
CGContextStrokePath(context);
if (selected) {
// Clear border where the checkmark crosses it
CGContextSaveGState(context);
CGContextSetBlendMode(context, kCGBlendModeClear);
CGContextMoveToPoint( context, 16, 2);
CGContextAddLineToPoint(context, 20, 1);
CGContextAddLineToPoint(context, 20, 4);
CGContextAddLineToPoint(context, 17, 7);
CGContextAddLineToPoint(context, 16, 2);
CGContextFillPath(context);
// Draw checkmark
CGContextRestoreGState(context);
CGContextSetRGBFillColor(context, 0.25, 0.25, 0.25, 1);
CGContextSetLineWidth(context, 1);
CGContextMoveToPoint( context, 7, 8); // top of left part
CGContextAddLineToPoint(context, 10, 11); // top of middle part
CGContextAddLineToPoint(context, 19, 1); // top of right part
CGContextAddLineToPoint(context, 20, 2); // bottom of right part
//CGContextAddArcToPoint(context, 16, 6, 10.5, 16, 2); // arc from mid right part to bottom of middle part?
//CGContextAddArcToPoint(context, 10.5, 10, 10.5, 16, 2); // arc from mid right part to bottom of middle part?
CGContextAddLineToPoint(context, 16, 6); // steeper path from mid right part to bottom of middle part
CGContextAddLineToPoint(context, 10.5, 16); // bottom of middle part
CGContextAddLineToPoint(context, 5.5, 9.5); // bottom of left part
CGContextAddLineToPoint(context, 7, 8); // close path
CGContextFillPath(context);
}
}
@end
@implementation Checkbox
- (id)initWithFrame:(CGRect)frame {
if (self = [super initWithFrame:frame]) {
CALayer *layer = self.layer;
drawing = [CheckboxDrawing new];
drawing.frame = CGRectMake(0, 0, 21, 21);
[layer addSublayer:drawing];
self.selected = NO;
}
return self;
}
- (void)setSelected:(BOOL)flag {
[super setSelected:flag];
drawing.selected = flag;
}
- (void)dealloc {
[drawing release];
[super dealloc];
}
@end