17 |
17 |
18 |
18 |
19 - (id)initWithFrame:(CGRect)frame |
19 - (id)initWithFrame:(CGRect)frame |
20 { |
20 { |
21 if ((self = [super initWithFrame:frame])) { |
21 if ((self = [super initWithFrame:frame])) { |
22 self.contentMode = UIViewContentModeRedraw; |
22 self.contentMode = UIViewContentModeRedraw; |
23 self.userInteractionEnabled = NO; |
23 self.userInteractionEnabled = NO; |
24 self.opaque = NO; |
24 self.opaque = NO; |
25 self.backgroundColor = [UIColor clearColor]; |
25 self.backgroundColor = [UIColor clearColor]; |
26 cornerRadius = 0.0; // actual value is set by the splitViewController. |
26 cornerRadius = 0.0; // actual value is set by the splitViewController. |
27 cornersPosition = MGCornersPositionLeadingVertical; |
27 cornersPosition = MGCornersPositionLeadingVertical; |
28 } |
28 } |
29 |
29 |
30 return self; |
30 return self; |
31 } |
31 } |
32 |
32 |
33 |
33 |
34 - (void)dealloc |
34 - (void)dealloc |
35 { |
35 { |
36 self.cornerBackgroundColor = nil; |
36 self.cornerBackgroundColor = nil; |
37 |
37 |
38 [super dealloc]; |
38 [super dealloc]; |
39 } |
39 } |
40 |
40 |
41 |
41 |
42 #pragma mark - |
42 #pragma mark - |
|
43 #pragma mark Geometry helpers |
|
44 |
|
45 |
|
46 static double deg2Rad(double degrees) |
|
47 { |
|
48 // Converts degrees to radians. |
|
49 return degrees * (M_PI / 180.0); |
|
50 } |
|
51 |
|
52 |
|
53 #pragma mark - |
43 #pragma mark Drawing |
54 #pragma mark Drawing |
44 |
55 |
45 |
56 |
46 - (void)drawRect:(CGRect)rect |
57 - (void)drawRect:(CGRect)rect |
47 { |
58 { |
48 // Draw two appropriate corners, with cornerBackgroundColor behind them. |
59 // Draw two appropriate corners, with cornerBackgroundColor behind them. |
49 if (cornerRadius > 0) { |
60 if (cornerRadius > 0) { |
50 if (NO) { // just for debugging. |
61 |
51 [[UIColor redColor] set]; |
62 float maxX = CGRectGetMaxX(self.bounds); |
52 UIRectFill(self.bounds); |
63 float maxY = CGRectGetMaxY(self.bounds); |
53 } |
64 UIBezierPath *path = [UIBezierPath bezierPath]; |
54 |
65 CGPoint pt = CGPointZero; |
55 float maxX = CGRectGetMaxX(self.bounds); |
66 switch (cornersPosition) { |
56 float maxY = CGRectGetMaxY(self.bounds); |
67 case MGCornersPositionLeadingVertical: // top of screen for a left/right split |
57 UIBezierPath *path = [UIBezierPath bezierPath]; |
68 [path moveToPoint:pt]; |
58 CGPoint pt = CGPointZero; |
69 pt.y += cornerRadius; |
59 switch (cornersPosition) { |
70 [path appendPath:[UIBezierPath bezierPathWithArcCenter:pt radius:cornerRadius startAngle:(float)deg2Rad(90) endAngle:0 clockwise:YES]]; |
60 case MGCornersPositionLeadingVertical: // top of screen for a left/right split |
71 pt.x += cornerRadius; |
61 [path moveToPoint:pt]; |
72 pt.y -= cornerRadius; |
62 pt.y += cornerRadius; |
73 [path addLineToPoint:pt]; |
63 [path appendPath:[UIBezierPath bezierPathWithArcCenter:pt radius:cornerRadius startAngle:degreesToRadians(90) endAngle:0 clockwise:YES]]; |
74 [path addLineToPoint:CGPointZero]; |
64 pt.x += cornerRadius; |
75 [path closePath]; |
65 pt.y -= cornerRadius; |
76 |
66 [path addLineToPoint:pt]; |
77 pt.x = maxX - cornerRadius; |
67 [path addLineToPoint:CGPointZero]; |
78 pt.y = 0; |
68 [path closePath]; |
79 [path moveToPoint:pt]; |
69 |
80 pt.y = maxY; |
70 pt.x = maxX - cornerRadius; |
81 [path addLineToPoint:pt]; |
71 pt.y = 0; |
82 pt.x += cornerRadius; |
72 [path moveToPoint:pt]; |
83 [path appendPath:[UIBezierPath bezierPathWithArcCenter:pt radius:cornerRadius startAngle:(float)deg2Rad(180) endAngle:(float)deg2Rad(90) clockwise:YES]]; |
73 pt.y = maxY; |
84 pt.y -= cornerRadius; |
74 [path addLineToPoint:pt]; |
85 [path addLineToPoint:pt]; |
75 pt.x += cornerRadius; |
86 pt.x -= cornerRadius; |
76 [path appendPath:[UIBezierPath bezierPathWithArcCenter:pt radius:cornerRadius startAngle:degreesToRadians(180) endAngle:degreesToRadians(90) clockwise:YES]]; |
87 [path addLineToPoint:pt]; |
77 pt.y -= cornerRadius; |
88 [path closePath]; |
78 [path addLineToPoint:pt]; |
89 |
79 pt.x -= cornerRadius; |
90 break; |
80 [path addLineToPoint:pt]; |
91 |
81 [path closePath]; |
92 case MGCornersPositionTrailingVertical: // bottom of screen for a left/right split |
82 |
93 pt.y = maxY; |
83 break; |
94 [path moveToPoint:pt]; |
84 |
95 pt.y -= cornerRadius; |
85 case MGCornersPositionTrailingVertical: // bottom of screen for a left/right split |
96 [path appendPath:[UIBezierPath bezierPathWithArcCenter:pt radius:cornerRadius startAngle:(float)deg2Rad(270) endAngle:(float)deg2Rad(360) clockwise:NO]]; |
86 pt.y = maxY; |
97 pt.x += cornerRadius; |
87 [path moveToPoint:pt]; |
98 pt.y += cornerRadius; |
88 pt.y -= cornerRadius; |
99 [path addLineToPoint:pt]; |
89 [path appendPath:[UIBezierPath bezierPathWithArcCenter:pt radius:cornerRadius startAngle:degreesToRadians(270) endAngle:degreesToRadians(360) clockwise:NO]]; |
100 pt.x -= cornerRadius; |
90 pt.x += cornerRadius; |
101 [path addLineToPoint:pt]; |
91 pt.y += cornerRadius; |
102 [path closePath]; |
92 [path addLineToPoint:pt]; |
103 |
93 pt.x -= cornerRadius; |
104 pt.x = maxX - cornerRadius; |
94 [path addLineToPoint:pt]; |
105 pt.y = maxY; |
95 [path closePath]; |
106 [path moveToPoint:pt]; |
96 |
107 pt.y -= cornerRadius; |
97 pt.x = maxX - cornerRadius; |
108 [path addLineToPoint:pt]; |
98 pt.y = maxY; |
109 pt.x += cornerRadius; |
99 [path moveToPoint:pt]; |
110 [path appendPath:[UIBezierPath bezierPathWithArcCenter:pt radius:cornerRadius startAngle:(float)deg2Rad(180) endAngle:(float)deg2Rad(270) clockwise:NO]]; |
100 pt.y -= cornerRadius; |
111 pt.y += cornerRadius; |
101 [path addLineToPoint:pt]; |
112 [path addLineToPoint:pt]; |
102 pt.x += cornerRadius; |
113 pt.x -= cornerRadius; |
103 [path appendPath:[UIBezierPath bezierPathWithArcCenter:pt radius:cornerRadius startAngle:degreesToRadians(180) endAngle:degreesToRadians(270) clockwise:NO]]; |
114 [path addLineToPoint:pt]; |
104 pt.y += cornerRadius; |
115 [path closePath]; |
105 [path addLineToPoint:pt]; |
116 |
106 pt.x -= cornerRadius; |
117 break; |
107 [path addLineToPoint:pt]; |
118 |
108 [path closePath]; |
119 case MGCornersPositionLeadingHorizontal: // left of screen for a top/bottom split |
109 |
120 pt.x = 0; |
110 break; |
121 pt.y = cornerRadius; |
111 |
122 [path moveToPoint:pt]; |
112 case MGCornersPositionLeadingHorizontal: // left of screen for a top/bottom split |
123 pt.y -= cornerRadius; |
113 pt.x = 0; |
124 [path addLineToPoint:pt]; |
114 pt.y = cornerRadius; |
125 pt.x += cornerRadius; |
115 [path moveToPoint:pt]; |
126 [path appendPath:[UIBezierPath bezierPathWithArcCenter:pt radius:cornerRadius startAngle:(float)deg2Rad(180) endAngle:(float)deg2Rad(270) clockwise:NO]]; |
116 pt.y -= cornerRadius; |
127 pt.y += cornerRadius; |
117 [path addLineToPoint:pt]; |
128 [path addLineToPoint:pt]; |
118 pt.x += cornerRadius; |
129 pt.x -= cornerRadius; |
119 [path appendPath:[UIBezierPath bezierPathWithArcCenter:pt radius:cornerRadius startAngle:degreesToRadians(180) endAngle:degreesToRadians(270) clockwise:NO]]; |
130 [path addLineToPoint:pt]; |
120 pt.y += cornerRadius; |
131 [path closePath]; |
121 [path addLineToPoint:pt]; |
132 |
122 pt.x -= cornerRadius; |
133 pt.x = 0; |
123 [path addLineToPoint:pt]; |
134 pt.y = maxY - cornerRadius; |
124 [path closePath]; |
135 [path moveToPoint:pt]; |
125 |
136 pt.y = maxY; |
126 pt.x = 0; |
137 [path addLineToPoint:pt]; |
127 pt.y = maxY - cornerRadius; |
138 pt.x += cornerRadius; |
128 [path moveToPoint:pt]; |
139 [path appendPath:[UIBezierPath bezierPathWithArcCenter:pt radius:cornerRadius startAngle:(float)deg2Rad(180) endAngle:(float)deg2Rad(90) clockwise:YES]]; |
129 pt.y = maxY; |
140 pt.y -= cornerRadius; |
130 [path addLineToPoint:pt]; |
141 [path addLineToPoint:pt]; |
131 pt.x += cornerRadius; |
142 pt.x -= cornerRadius; |
132 [path appendPath:[UIBezierPath bezierPathWithArcCenter:pt radius:cornerRadius startAngle:degreesToRadians(180) endAngle:degreesToRadians(90) clockwise:YES]]; |
143 [path addLineToPoint:pt]; |
133 pt.y -= cornerRadius; |
144 [path closePath]; |
134 [path addLineToPoint:pt]; |
145 |
135 pt.x -= cornerRadius; |
146 break; |
136 [path addLineToPoint:pt]; |
147 |
137 [path closePath]; |
148 case MGCornersPositionTrailingHorizontal: // right of screen for a top/bottom split |
138 |
149 pt.y = cornerRadius; |
139 break; |
150 [path moveToPoint:pt]; |
140 |
151 pt.y -= cornerRadius; |
141 case MGCornersPositionTrailingHorizontal: // right of screen for a top/bottom split |
152 [path appendPath:[UIBezierPath bezierPathWithArcCenter:pt radius:cornerRadius startAngle:(float)deg2Rad(270) endAngle:(float)deg2Rad(360) clockwise:NO]]; |
142 pt.y = cornerRadius; |
153 pt.x += cornerRadius; |
143 [path moveToPoint:pt]; |
154 pt.y += cornerRadius; |
144 pt.y -= cornerRadius; |
155 [path addLineToPoint:pt]; |
145 [path appendPath:[UIBezierPath bezierPathWithArcCenter:pt radius:cornerRadius startAngle:degreesToRadians(270) endAngle:degreesToRadians(360) clockwise:NO]]; |
156 pt.x -= cornerRadius; |
146 pt.x += cornerRadius; |
157 [path addLineToPoint:pt]; |
147 pt.y += cornerRadius; |
158 [path closePath]; |
148 [path addLineToPoint:pt]; |
159 |
149 pt.x -= cornerRadius; |
160 pt.y = maxY - cornerRadius; |
150 [path addLineToPoint:pt]; |
161 [path moveToPoint:pt]; |
151 [path closePath]; |
162 pt.y += cornerRadius; |
152 |
163 [path appendPath:[UIBezierPath bezierPathWithArcCenter:pt radius:cornerRadius startAngle:(float)deg2Rad(90) endAngle:0 clockwise:YES]]; |
153 pt.y = maxY - cornerRadius; |
164 pt.x += cornerRadius; |
154 [path moveToPoint:pt]; |
165 pt.y -= cornerRadius; |
155 pt.y += cornerRadius; |
166 [path addLineToPoint:pt]; |
156 [path appendPath:[UIBezierPath bezierPathWithArcCenter:pt radius:cornerRadius startAngle:degreesToRadians(90) endAngle:0 clockwise:YES]]; |
167 pt.x -= cornerRadius; |
157 pt.x += cornerRadius; |
168 [path addLineToPoint:pt]; |
158 pt.y -= cornerRadius; |
169 [path closePath]; |
159 [path addLineToPoint:pt]; |
170 |
160 pt.x -= cornerRadius; |
171 break; |
161 [path addLineToPoint:pt]; |
172 |
162 [path closePath]; |
173 default: |
163 |
174 break; |
164 break; |
175 } |
165 |
176 |
166 default: |
177 [self.cornerBackgroundColor set]; |
167 break; |
178 [path fill]; |
168 } |
179 } |
169 |
|
170 [self.cornerBackgroundColor set]; |
|
171 [path fill]; |
|
172 } |
|
173 } |
180 } |
174 |
181 |
175 |
182 |
176 #pragma mark - |
183 #pragma mark - |
177 #pragma mark Accessors and properties |
184 #pragma mark Accessors and properties |
178 |
185 |
179 |
186 |
180 - (void)setCornerRadius:(float)newRadius |
187 - (void)setCornerRadius:(float)newRadius |
181 { |
188 { |
182 if (newRadius != cornerRadius) { |
189 if (newRadius != cornerRadius) { |
183 cornerRadius = newRadius; |
190 cornerRadius = newRadius; |
184 [self setNeedsDisplay]; |
191 [self setNeedsDisplay]; |
185 } |
192 } |
186 } |
193 } |
187 |
194 |
188 |
195 |
189 - (void)setSplitViewController:(MGSplitViewController *)theController |
196 - (void)setSplitViewController:(MGSplitViewController *)theController |
190 { |
197 { |
191 if (theController != splitViewController) { |
198 if (theController != splitViewController) { |
192 splitViewController = theController; |
199 splitViewController = theController; |
193 [self setNeedsDisplay]; |
200 [self setNeedsDisplay]; |
194 } |
201 } |
195 } |
202 } |
196 |
203 |
197 |
204 |
198 - (void)setCornersPosition:(MGCornersPosition)posn |
205 - (void)setCornersPosition:(MGCornersPosition)posn |
199 { |
206 { |
200 if (cornersPosition != posn) { |
207 if (cornersPosition != posn) { |
201 cornersPosition = posn; |
208 cornersPosition = posn; |
202 [self setNeedsDisplay]; |
209 [self setNeedsDisplay]; |
203 } |
210 } |
204 } |
211 } |
205 |
212 |
206 |
213 |
207 - (void)setCornerBackgroundColor:(UIColor *)color |
214 - (void)setCornerBackgroundColor:(UIColor *)color |
208 { |
215 { |
209 if (color != cornerBackgroundColor) { |
216 if (color != cornerBackgroundColor) { |
210 [cornerBackgroundColor release]; |
217 cornerBackgroundColor = color; |
211 cornerBackgroundColor = [color retain]; |
218 [self setNeedsDisplay]; |
212 [self setNeedsDisplay]; |
219 } |
213 } |
|
214 } |
220 } |
215 |
221 |
216 |
222 |
217 @synthesize cornerRadius; |
223 @synthesize cornerRadius; |
218 @synthesize splitViewController; |
224 @synthesize splitViewController; |