aboutsummaryrefslogtreecommitdiff
path: root/AppKit/GTMNSBezierPath+RoundRect.m
diff options
context:
space:
mode:
authorGravatar gtm.daemon <gtm.daemon@7dc7ac4e-7543-0410-b95c-c1676fc8e2a3>2009-03-16 14:30:25 +0000
committerGravatar gtm.daemon <gtm.daemon@7dc7ac4e-7543-0410-b95c-c1676fc8e2a3>2009-03-16 14:30:25 +0000
commit1c1c70beb8fcba6bbcb3f6ca58215e646dca7888 (patch)
treee1c780c73efa2e6b439adb039da774d4730eb91b /AppKit/GTMNSBezierPath+RoundRect.m
parentf14883b92b7df63f9b7c368d138a551c75c8c977 (diff)
[Author: avi]
Add ability to create rounded rects with different radii for different corners. R=dmaclach
Diffstat (limited to 'AppKit/GTMNSBezierPath+RoundRect.m')
-rw-r--r--AppKit/GTMNSBezierPath+RoundRect.m85
1 files changed, 59 insertions, 26 deletions
diff --git a/AppKit/GTMNSBezierPath+RoundRect.m b/AppKit/GTMNSBezierPath+RoundRect.m
index d4e5050..806bd94 100644
--- a/AppKit/GTMNSBezierPath+RoundRect.m
+++ b/AppKit/GTMNSBezierPath+RoundRect.m
@@ -31,36 +31,69 @@
return bezier;
}
++ (NSBezierPath *)gtm_bezierPathWithRoundRect:(NSRect)rect
+ topLeftCornerRadius:(CGFloat)radiusTL
+ topRightCornerRadius:(CGFloat)radiusTR
+ bottomLeftCornerRadius:(CGFloat)radiusBL
+ bottomRightCornerRadius:(CGFloat)radiusBR {
+ NSBezierPath *bezier = [NSBezierPath bezierPath];
+ [bezier gtm_appendBezierPathWithRoundRect:rect
+ topLeftCornerRadius:radiusTL
+ topRightCornerRadius:radiusTR
+ bottomLeftCornerRadius:radiusBL
+ bottomRightCornerRadius:radiusBR];
+ return bezier;
+}
- (void)gtm_appendBezierPathWithRoundRect:(NSRect)rect
cornerRadius:(CGFloat)radius {
+ if (radius > 0.0) {
+ // Clamp radius to be no larger than half the rect's width or height.
+ radius = MIN(radius, 0.5 * MIN(rect.size.width, rect.size.height));
+
+ [self gtm_appendBezierPathWithRoundRect:rect
+ topLeftCornerRadius:radius
+ topRightCornerRadius:radius
+ bottomLeftCornerRadius:radius
+ bottomRightCornerRadius:radius];
+ } else {
+ // When radius <= 0.0, use plain rectangle.
+ [self appendBezierPathWithRect:rect];
+ }
+}
+
+- (void)gtm_appendBezierPathWithRoundRect:(NSRect)rect
+ topLeftCornerRadius:(CGFloat)radiusTL
+ topRightCornerRadius:(CGFloat)radiusTR
+ bottomLeftCornerRadius:(CGFloat)radiusBL
+ bottomRightCornerRadius:(CGFloat)radiusBR {
+ // Clamp radii to be at least zero. I'd like to clamp both TL+TR and BL+BR to
+ // be less than the width and TL+BL and TR+BR to be less than the height, but
+ // what to do if they're not? Do we scale them both evenly?
+ radiusTL = MAX(0, radiusTL);
+ radiusTR = MAX(0, radiusTR);
+ radiusBL = MAX(0, radiusBL);
+ radiusBR = MAX(0, radiusBR);
+
if (!NSIsEmptyRect(rect)) {
- if (radius > 0.0) {
- // Clamp radius to be no larger than half the rect's width or height.
- radius = MIN(radius, 0.5 * MIN(rect.size.width, rect.size.height));
-
- NSPoint topLeft = NSMakePoint(NSMinX(rect), NSMaxY(rect));
- NSPoint topRight = NSMakePoint(NSMaxX(rect), NSMaxY(rect));
- NSPoint bottomRight = NSMakePoint(NSMaxX(rect), NSMinY(rect));
-
- [self moveToPoint:NSMakePoint(NSMidX(rect), NSMaxY(rect))];
- [self appendBezierPathWithArcFromPoint:topLeft
- toPoint:rect.origin
- radius:radius];
- [self appendBezierPathWithArcFromPoint:rect.origin
- toPoint:bottomRight
- radius:radius];
- [self appendBezierPathWithArcFromPoint:bottomRight
- toPoint:topRight
- radius:radius];
- [self appendBezierPathWithArcFromPoint:topRight
- toPoint:topLeft
- radius:radius];
- [self closePath];
- } else {
- // When radius <= 0.0, use plain rectangle.
- [self appendBezierPathWithRect:rect];
- }
+ NSPoint topLeft = NSMakePoint(NSMinX(rect), NSMaxY(rect));
+ NSPoint topRight = NSMakePoint(NSMaxX(rect), NSMaxY(rect));
+ NSPoint bottomRight = NSMakePoint(NSMaxX(rect), NSMinY(rect));
+
+ [self moveToPoint:NSMakePoint(NSMidX(rect), NSMaxY(rect))];
+ [self appendBezierPathWithArcFromPoint:topLeft
+ toPoint:rect.origin
+ radius:radiusTL];
+ [self appendBezierPathWithArcFromPoint:rect.origin
+ toPoint:bottomRight
+ radius:radiusBL];
+ [self appendBezierPathWithArcFromPoint:bottomRight
+ toPoint:topRight
+ radius:radiusBR];
+ [self appendBezierPathWithArcFromPoint:topRight
+ toPoint:topLeft
+ radius:radiusTR];
+ [self closePath];
}
}