From 50a52ae5299f8f69f524b48cb313acb9547ccb7f Mon Sep 17 00:00:00 2001 From: Josh Vera Date: Fri, 4 Apr 2014 14:52:23 -0400 Subject: [PATCH 01/22] Separate arrow coordinate calculations from CGPath stuff --- Rebel/RBLPopover.m | 54 +++++++++++++++++++++++++++++----------------- 1 file changed, 34 insertions(+), 20 deletions(-) diff --git a/Rebel/RBLPopover.m b/Rebel/RBLPopover.m index bf4575b..ed0f29d 100644 --- a/Rebel/RBLPopover.m +++ b/Rebel/RBLPopover.m @@ -538,34 +538,48 @@ static CGFloat const RBLPopoverBackgroundViewArrowWidth = 35.0; CGMutablePathRef path = CGPathCreateMutable(); CGPathMoveToPoint(path, NULL, minX, floor(minY + RBLPopoverBackgroundViewBorderRadius)); - if (arrowEdge == CGRectMinXEdge) { - CGPathAddLineToPoint(path, NULL, minX, minArrowY); - CGPathAddLineToPoint(path, NULL, floor(minX - self.arrowSize.height), midOriginY); - CGPathAddLineToPoint(path, NULL, minX, maxArrowY); - } + CGPathAddArc(path, NULL, floor(minX + RBLPopoverBackgroundViewBorderRadius), floor(minY + contentRect.size.height - RBLPopoverBackgroundViewBorderRadius), RBLPopoverBackgroundViewBorderRadius, M_PI, M_PI / 2, 1); - if (arrowEdge == CGRectMaxYEdge) { - CGPathAddLineToPoint(path, NULL, minArrowX, maxY); - CGPathAddLineToPoint(path, NULL, midOriginX, floor(maxY + self.arrowSize.height)); - CGPathAddLineToPoint(path, NULL, maxArrowX, maxY); - } + CGPathAddArc(path, NULL, floor(minX + contentRect.size.width - RBLPopoverBackgroundViewBorderRadius), floor(minY + contentRect.size.height - RBLPopoverBackgroundViewBorderRadius), RBLPopoverBackgroundViewBorderRadius, M_PI / 2, 0.0, 1); - if (arrowEdge == CGRectMaxXEdge) { - CGPathAddLineToPoint(path, NULL, maxX, maxArrowY); - CGPathAddLineToPoint(path, NULL, floor(maxX + self.arrowSize.height), midOriginY); - CGPathAddLineToPoint(path, NULL, maxX, minArrowY); - } + CGPathAddArc(path, NULL, floor(contentRect.origin.x + contentRect.size.width - RBLPopoverBackgroundViewBorderRadius), floor(minY + RBLPopoverBackgroundViewBorderRadius), RBLPopoverBackgroundViewBorderRadius, 0.0, -M_PI / 2, 1); - if (arrowEdge == CGRectMinYEdge) { - CGPathAddLineToPoint(path, NULL, maxArrowX, minY); - CGPathAddLineToPoint(path, NULL, midOriginX, floor(minY - self.arrowSize.height)); - CGPathAddLineToPoint(path, NULL, minArrowX, minY); - } CGPathAddArc(path, NULL, floor(minX + RBLPopoverBackgroundViewBorderRadius), floor(minY + RBLPopoverBackgroundViewBorderRadius), RBLPopoverBackgroundViewBorderRadius, -M_PI / 2, M_PI, 1); + + CGFloat x1, x2, x3, y1, y2, y3; + switch (arrowEdge) { + case CGRectMinXEdge: + x1 = minX, y1 = minArrowY; + x2 = floor(minX - self.arrowSize.height), y2 = midOriginY; + x3 = minX, y3 = maxArrowY; + break; + case CGRectMaxYEdge: + x1 = minArrowX, y1 = maxY; + x2 = midOriginX, y2 = floor(maxY + self.arrowSize.height); + x3 = maxArrowX, y3 = maxY; + break; + case CGRectMaxXEdge: + x1 = maxX, y1 = maxArrowY; + x2 = floor(maxX + self.arrowSize.height), y2 = midOriginY; + x3 = maxX, y3 = minArrowY; + break; + case CGRectMinYEdge: + x1 = maxArrowX, y1 = minY; + x2 = midOriginX, y2 = floor(minY - self.arrowSize.height); + x3 = minArrowX, y3 = minY; + break; + default: + break; + } + + CGPathMoveToPoint(path, NULL, x1, y1); + CGPathAddLineToPoint(path, NULL, x1, y1); + CGPathAddLineToPoint(path, NULL, x2, y2); + CGPathAddLineToPoint(path, NULL, x3, y3); return path; } From 905a29e635f527829d7f4c513a0831a0d4c68649 Mon Sep 17 00:00:00 2001 From: Josh Vera Date: Fri, 4 Apr 2014 17:09:08 -0400 Subject: [PATCH 02/22] Remove arrow shrinking --- Rebel/RBLPopover.m | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/Rebel/RBLPopover.m b/Rebel/RBLPopover.m index ed0f29d..fe41443 100644 --- a/Rebel/RBLPopover.m +++ b/Rebel/RBLPopover.m @@ -508,30 +508,26 @@ static CGFloat const RBLPopoverBackgroundViewArrowWidth = 35.0; maxArrowX = floor(midOriginX + (self.arrowSize.width / 2.0)); CGFloat maxPossible = (NSMaxX(contentRect) - RBLPopoverBackgroundViewBorderRadius); if (maxArrowX > maxPossible) { - CGFloat delta = maxArrowX - maxPossible; maxArrowX = maxPossible; - minArrowX = maxArrowX - (self.arrowSize.width - delta); + minArrowX = maxArrowX - self.arrowSize.width; } else { minArrowX = floor(midOriginX - (self.arrowSize.width / 2.0)); if (minArrowX < RBLPopoverBackgroundViewBorderRadius) { - CGFloat delta = RBLPopoverBackgroundViewBorderRadius - minArrowX; minArrowX = RBLPopoverBackgroundViewBorderRadius; - maxArrowX = minArrowX + (self.arrowSize.width - (delta * 2)); + maxArrowX = minArrowX + self.arrowSize.width; } } } else { minArrowY = floor(midOriginY - (self.arrowSize.width / 2.0)); if (minArrowY < RBLPopoverBackgroundViewBorderRadius) { - CGFloat delta = RBLPopoverBackgroundViewBorderRadius - minArrowY; minArrowY = RBLPopoverBackgroundViewBorderRadius; - maxArrowY = minArrowY + (self.arrowSize.width - (delta * 2)); + maxArrowY = minArrowY + self.arrowSize.width; } else { maxArrowY = floor(midOriginY + (self.arrowSize.width / 2.0)); CGFloat maxPossible = (NSMaxY(contentRect) - RBLPopoverBackgroundViewBorderRadius); if (maxArrowY > maxPossible) { - CGFloat delta = maxArrowY - maxPossible; maxArrowY = maxPossible; - minArrowY = maxArrowY - (self.arrowSize.width - delta); + minArrowY = maxArrowY - self.arrowSize.width; } } } From 17f846484d8ae685f3f31df7d973d8162833d796 Mon Sep 17 00:00:00 2001 From: Josh Vera Date: Fri, 4 Apr 2014 17:12:13 -0400 Subject: [PATCH 03/22] Change demo to show popover relative to button bounds --- Demos/RBLPopoverDemo/RBLPopoverDemo/RPDAppDelegate.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Demos/RBLPopoverDemo/RBLPopoverDemo/RPDAppDelegate.m b/Demos/RBLPopoverDemo/RBLPopoverDemo/RPDAppDelegate.m index 320cc05..5e4926f 100644 --- a/Demos/RBLPopoverDemo/RBLPopoverDemo/RPDAppDelegate.m +++ b/Demos/RBLPopoverDemo/RBLPopoverDemo/RPDAppDelegate.m @@ -70,7 +70,7 @@ } else { NSView *button = sender; self.RBLPopover.behavior = self.behavior; - [self.RBLPopover showRelativeToRect:CGRectZero ofView:button preferredEdge:(CGRectEdge)self.preferredEdge]; + [self.RBLPopover showRelativeToRect:button.bounds ofView:button preferredEdge:(CGRectEdge)self.preferredEdge]; } } From c6ba9866e143748739c64cdcf54902bc3bd215fe Mon Sep 17 00:00:00 2001 From: Josh Vera Date: Fri, 4 Apr 2014 17:13:07 -0400 Subject: [PATCH 04/22] Add popover anchor point and didOffsetFrame properties to RBLBackgroundView --- Rebel/RBLPopover.m | 41 ++++++++++++++++++++++++++++++++--------- 1 file changed, 32 insertions(+), 9 deletions(-) diff --git a/Rebel/RBLPopover.m b/Rebel/RBLPopover.m index fe41443..2eaa596 100644 --- a/Rebel/RBLPopover.m +++ b/Rebel/RBLPopover.m @@ -64,6 +64,10 @@ static CGFloat RBLRectsGetMedianY(CGRect r1, CGRect r2) { @property (nonatomic, assign, readwrite) NSRect popoverOrigin; +@property (nonatomic, assign, readwrite) NSPoint popoverAnchorPoint; + +@property (nonatomic, assign, readwrite) BOOL didOffsetFrame; + - (CGRectEdge)rbl_arrowEdgeForPopoverEdge:(CGRectEdge)popoverEdge; @end @@ -144,7 +148,8 @@ static CGFloat RBLRectsGetMedianY(CGRect r1, CGRect r2) { if (self == nil) return nil; - _anchorPoint = CGPointMake(0.5, 0.5); + + self.anchorPoint = CGPointMake(0.5, 0.5); _contentViewController = viewController; _backgroundView = backgroundView; _behavior = RBLPopoverBehaviorApplicationDefined; @@ -177,7 +182,8 @@ static CGFloat RBLRectsGetMedianY(CGRect r1, CGRect r2) { CGRect screenRect = [positioningView.window convertRectToScreen:windowRelativeRect]; self.backgroundView.popoverOrigin = screenRect; - + self.backgroundView.popoverAnchorPoint = self.anchorPoint; + self.originalViewSize = self.contentViewController.view.frame.size; CGSize contentViewSize = (CGSizeEqualToSize(self.contentSize, CGSizeZero) ? self.contentViewController.view.frame.size : self.contentSize); @@ -270,6 +276,7 @@ static CGFloat RBLRectsGetMedianY(CGRect r1, CGRect r2) { while (!checkPopoverSizeForScreenWithPopoverEdge(popoverEdge)) { if (attemptCount >= 4) { popoverEdge = preferredEdge; + self.backgroundView.didOffsetFrame = YES; return fitRectToScreen(popoverRectForEdge(popoverEdge)); break; } @@ -277,15 +284,21 @@ static CGFloat RBLRectsGetMedianY(CGRect r1, CGRect r2) { popoverEdge = nextEdgeForEdge(popoverEdge); attemptCount ++; } - + + self.backgroundView.didOffsetFrame = NO; return popoverRectForEdge(popoverEdge); }; CGRect popoverScreenRect = popoverRect(); + if (self.shown) { if (self.backgroundView.popoverEdge == popoverEdge) { + CGSize size = [self.backgroundView sizeForBackgroundViewWithContentSize:contentViewSize popoverEdge:popoverEdge]; + self.backgroundView.frame = (NSRect){ .size = size }; + self.backgroundView.popoverEdge = popoverEdge; [self.popoverWindow setFrame:popoverScreenRect display:YES]; + return; } @@ -489,10 +502,14 @@ static CGFloat const RBLPopoverBackgroundViewArrowWidth = 35.0; CGFloat minY = NSMinY(contentRect); CGFloat maxY = NSMaxY(contentRect); - CGRect windowRect = [self.window convertRectFromScreen:self.popoverOrigin]; - CGRect originRect = [self convertRect:windowRect fromView:nil]; - CGFloat midOriginY = floor(RBLRectsGetMedianY(originRect, contentRect)); - CGFloat midOriginX = floor(RBLRectsGetMedianX(originRect, contentRect)); + CGFloat midOriginY = floor(NSMaxY(contentRect) * self.popoverAnchorPoint.y); + CGFloat midOriginX = floor(NSMaxX(contentRect) * self.popoverAnchorPoint.x); + if (self.didOffsetFrame) { + CGRect windowRect = [self.window convertRectFromScreen:self.popoverOrigin]; + CGRect originRect = [self convertRect:windowRect fromView:nil]; + midOriginX = floor(RBLRectsGetMedianX(originRect, contentRect)); + midOriginY = floor(RBLRectsGetMedianY(originRect, contentRect)); + } CGFloat maxArrowX = 0.0; CGFloat minArrowX = 0.0; @@ -555,7 +572,7 @@ static CGFloat const RBLPopoverBackgroundViewArrowWidth = 35.0; break; case CGRectMaxYEdge: x1 = minArrowX, y1 = maxY; - x2 = midOriginX, y2 = floor(maxY + self.arrowSize.height); + x2 = floor((minArrowX + maxArrowX) / 2), y2 = floor(maxY + self.arrowSize.height); x3 = maxArrowX, y3 = maxY; break; case CGRectMaxXEdge: @@ -565,7 +582,7 @@ static CGFloat const RBLPopoverBackgroundViewArrowWidth = 35.0; break; case CGRectMinYEdge: x1 = maxArrowX, y1 = minY; - x2 = midOriginX, y2 = floor(minY - self.arrowSize.height); + x2 = floor((minArrowX + maxArrowX) / 2), y2 = floor(minY - self.arrowSize.height); x3 = minArrowX, y3 = minY; break; default: @@ -617,6 +634,12 @@ static CGFloat const RBLPopoverBackgroundViewArrowWidth = 35.0; [self rbl_updateClippingView]; } +- (void)setPopoverAnchorPoint:(NSPoint)popoverAnchorPoint { + if (NSEqualPoints(popoverAnchorPoint, self.popoverAnchorPoint)) return; + _popoverAnchorPoint = popoverAnchorPoint; + [self rbl_updateClippingView]; +} + - (void)drawRect:(NSRect)rect { [super drawRect:rect]; [self.fillColor set]; From d5cbe5b1b240a6aa733bfc9b0d19ce58204d909c Mon Sep 17 00:00:00 2001 From: Josh Vera Date: Fri, 4 Apr 2014 17:55:53 -0400 Subject: [PATCH 05/22] Flip the edge if the proposed rect for the preferred edge is offscreen --- Rebel/RBLPopover.m | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Rebel/RBLPopover.m b/Rebel/RBLPopover.m index 2eaa596..043e830 100644 --- a/Rebel/RBLPopover.m +++ b/Rebel/RBLPopover.m @@ -276,6 +276,13 @@ static CGFloat RBLRectsGetMedianY(CGRect r1, CGRect r2) { while (!checkPopoverSizeForScreenWithPopoverEdge(popoverEdge)) { if (attemptCount >= 4) { popoverEdge = preferredEdge; + CGRect proposedRect = popoverRectForEdge(popoverEdge); + BOOL medianYOffscreen = (preferredEdge == CGRectMinYEdge || preferredEdge == CGRectMaxYEdge) && NSMinY(proposedRect) < 0; + BOOL medianXOffscreen = (preferredEdge == CGRectMinXEdge || preferredEdge == CGRectMaxXEdge) && NSMinX(proposedRect) < 0; + if (medianYOffscreen || medianXOffscreen) { + popoverEdge = nextEdgeForEdge(popoverEdge); + } + self.backgroundView.didOffsetFrame = YES; return fitRectToScreen(popoverRectForEdge(popoverEdge)); break; From 8846e4463e3d02172dc191b5215690f0c21dbee9 Mon Sep 17 00:00:00 2001 From: Josh Vera Date: Sun, 6 Apr 2014 14:48:09 -0400 Subject: [PATCH 06/22] Just set ivar --- Rebel/RBLPopover.m | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Rebel/RBLPopover.m b/Rebel/RBLPopover.m index 8469ff2..daa9ec1 100644 --- a/Rebel/RBLPopover.m +++ b/Rebel/RBLPopover.m @@ -152,8 +152,7 @@ static CGFloat RBLRectsGetMedianY(CGRect r1, CGRect r2) { if (self == nil) return nil; - - self.anchorPoint = CGPointMake(0.5, 0.5); + _anchorPoint = CGPointMake(0.5, 0.5); _contentViewController = viewController; _backgroundView = backgroundView; _behavior = RBLPopoverBehaviorApplicationDefined; From 26ec75b2178471468f604647542a036fc97bb8c8 Mon Sep 17 00:00:00 2001 From: Josh Vera Date: Sun, 6 Apr 2014 14:50:34 -0400 Subject: [PATCH 07/22] style --- Rebel/RBLPopover.m | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/Rebel/RBLPopover.m b/Rebel/RBLPopover.m index daa9ec1..d7a6c9b 100644 --- a/Rebel/RBLPopover.m +++ b/Rebel/RBLPopover.m @@ -512,13 +512,15 @@ static CGFloat const RBLPopoverBackgroundViewArrowWidth = 35.0; CGFloat minY = NSMinY(contentRect); CGFloat maxY = NSMaxY(contentRect); - CGFloat midOriginY = floor(NSMaxY(contentRect) * self.popoverAnchorPoint.y); - CGFloat midOriginX = floor(NSMaxX(contentRect) * self.popoverAnchorPoint.x); + CGFloat midOriginX, midOriginY; if (self.didOffsetFrame) { CGRect windowRect = [self.window convertRectFromScreen:self.popoverOrigin]; CGRect originRect = [self convertRect:windowRect fromView:nil]; midOriginX = floor(RBLRectsGetMedianX(originRect, contentRect)); midOriginY = floor(RBLRectsGetMedianY(originRect, contentRect)); + } else { + midOriginY = floor(NSMaxY(contentRect) * self.popoverAnchorPoint.y); + midOriginX = floor(NSMaxX(contentRect) * self.popoverAnchorPoint.x); } CGFloat maxArrowX = 0.0; @@ -561,13 +563,10 @@ static CGFloat const RBLPopoverBackgroundViewArrowWidth = 35.0; CGMutablePathRef path = CGPathCreateMutable(); CGPathMoveToPoint(path, NULL, minX, floor(minY + RBLPopoverBackgroundViewBorderRadius)); - CGPathAddArc(path, NULL, floor(minX + RBLPopoverBackgroundViewBorderRadius), floor(minY + contentRect.size.height - RBLPopoverBackgroundViewBorderRadius), RBLPopoverBackgroundViewBorderRadius, M_PI, M_PI / 2, 1); - CGPathAddArc(path, NULL, floor(minX + contentRect.size.width - RBLPopoverBackgroundViewBorderRadius), floor(minY + contentRect.size.height - RBLPopoverBackgroundViewBorderRadius), RBLPopoverBackgroundViewBorderRadius, M_PI / 2, 0.0, 1); - CGPathAddArc(path, NULL, floor(contentRect.origin.x + contentRect.size.width - RBLPopoverBackgroundViewBorderRadius), floor(minY + RBLPopoverBackgroundViewBorderRadius), RBLPopoverBackgroundViewBorderRadius, 0.0, -M_PI / 2, 1); From 7c73e6399ebf180f623e887e89e0854bc16e70e3 Mon Sep 17 00:00:00 2001 From: Josh Vera Date: Sun, 6 Apr 2014 14:51:27 -0400 Subject: [PATCH 08/22] Replace M_PI / 2 with M_PI_2 --- Rebel/RBLPopover.m | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Rebel/RBLPopover.m b/Rebel/RBLPopover.m index d7a6c9b..e125e67 100644 --- a/Rebel/RBLPopover.m +++ b/Rebel/RBLPopover.m @@ -564,13 +564,13 @@ static CGFloat const RBLPopoverBackgroundViewArrowWidth = 35.0; CGMutablePathRef path = CGPathCreateMutable(); CGPathMoveToPoint(path, NULL, minX, floor(minY + RBLPopoverBackgroundViewBorderRadius)); - CGPathAddArc(path, NULL, floor(minX + RBLPopoverBackgroundViewBorderRadius), floor(minY + contentRect.size.height - RBLPopoverBackgroundViewBorderRadius), RBLPopoverBackgroundViewBorderRadius, M_PI, M_PI / 2, 1); + CGPathAddArc(path, NULL, floor(minX + RBLPopoverBackgroundViewBorderRadius), floor(minY + contentRect.size.height - RBLPopoverBackgroundViewBorderRadius), RBLPopoverBackgroundViewBorderRadius, M_PI, M_PI_2, 1); - CGPathAddArc(path, NULL, floor(minX + contentRect.size.width - RBLPopoverBackgroundViewBorderRadius), floor(minY + contentRect.size.height - RBLPopoverBackgroundViewBorderRadius), RBLPopoverBackgroundViewBorderRadius, M_PI / 2, 0.0, 1); + CGPathAddArc(path, NULL, floor(minX + contentRect.size.width - RBLPopoverBackgroundViewBorderRadius), floor(minY + contentRect.size.height - RBLPopoverBackgroundViewBorderRadius), RBLPopoverBackgroundViewBorderRadius, M_PI_2, 0.0, 1); - CGPathAddArc(path, NULL, floor(contentRect.origin.x + contentRect.size.width - RBLPopoverBackgroundViewBorderRadius), floor(minY + RBLPopoverBackgroundViewBorderRadius), RBLPopoverBackgroundViewBorderRadius, 0.0, -M_PI / 2, 1); + CGPathAddArc(path, NULL, floor(contentRect.origin.x + contentRect.size.width - RBLPopoverBackgroundViewBorderRadius), floor(minY + RBLPopoverBackgroundViewBorderRadius), RBLPopoverBackgroundViewBorderRadius, 0.0, -M_PI_2, 1); - CGPathAddArc(path, NULL, floor(minX + RBLPopoverBackgroundViewBorderRadius), floor(minY + RBLPopoverBackgroundViewBorderRadius), RBLPopoverBackgroundViewBorderRadius, -M_PI / 2, M_PI, 1); + CGPathAddArc(path, NULL, floor(minX + RBLPopoverBackgroundViewBorderRadius), floor(minY + RBLPopoverBackgroundViewBorderRadius), RBLPopoverBackgroundViewBorderRadius, -M_PI_2, M_PI, 1); CGFloat x1, x2, x3, y1, y2, y3; switch (arrowEdge) { From 92b4ad2dbbb5bf8e99eaff36a7326b37ef569b56 Mon Sep 17 00:00:00 2001 From: Josh Vera Date: Sun, 6 Apr 2014 14:53:09 -0400 Subject: [PATCH 09/22] Replace NSMax uses with maxX, maxY --- Rebel/RBLPopover.m | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Rebel/RBLPopover.m b/Rebel/RBLPopover.m index e125e67..9c14b14 100644 --- a/Rebel/RBLPopover.m +++ b/Rebel/RBLPopover.m @@ -519,8 +519,8 @@ static CGFloat const RBLPopoverBackgroundViewArrowWidth = 35.0; midOriginX = floor(RBLRectsGetMedianX(originRect, contentRect)); midOriginY = floor(RBLRectsGetMedianY(originRect, contentRect)); } else { - midOriginY = floor(NSMaxY(contentRect) * self.popoverAnchorPoint.y); - midOriginX = floor(NSMaxX(contentRect) * self.popoverAnchorPoint.x); + midOriginX = floor(maxX * self.popoverAnchorPoint.x); + midOriginY = floor(maxY * self.popoverAnchorPoint.y); } CGFloat maxArrowX = 0.0; From 3f6009766a1ec2a56038835f6ac5b1a7ac35fd02 Mon Sep 17 00:00:00 2001 From: Josh Vera Date: Sun, 6 Apr 2014 15:24:18 -0400 Subject: [PATCH 10/22] Clean up popover path calculations --- Rebel/RBLPopover.m | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/Rebel/RBLPopover.m b/Rebel/RBLPopover.m index 9c14b14..65d618f 100644 --- a/Rebel/RBLPopover.m +++ b/Rebel/RBLPopover.m @@ -560,17 +560,24 @@ static CGFloat const RBLPopoverBackgroundViewArrowWidth = 35.0; } } } + + CGFloat minMidpointX = floor(minX + RBLPopoverBackgroundViewBorderRadius); + CGFloat maxMidpointX = floor(maxX - RBLPopoverBackgroundViewBorderRadius); + CGFloat minMidpointY = floor(minY + RBLPopoverBackgroundViewBorderRadius); + CGFloat maxMidpointY = floor(maxY - RBLPopoverBackgroundViewBorderRadius); CGMutablePathRef path = CGPathCreateMutable(); - CGPathMoveToPoint(path, NULL, minX, floor(minY + RBLPopoverBackgroundViewBorderRadius)); + CGPathMoveToPoint(path, NULL, minX, minMidpointY); + + CGFloat radius = RBLPopoverBackgroundViewBorderRadius; - CGPathAddArc(path, NULL, floor(minX + RBLPopoverBackgroundViewBorderRadius), floor(minY + contentRect.size.height - RBLPopoverBackgroundViewBorderRadius), RBLPopoverBackgroundViewBorderRadius, M_PI, M_PI_2, 1); + CGPathAddArc(path, NULL, minMidpointX, maxMidpointY, radius, M_PI, M_PI_2, true); - CGPathAddArc(path, NULL, floor(minX + contentRect.size.width - RBLPopoverBackgroundViewBorderRadius), floor(minY + contentRect.size.height - RBLPopoverBackgroundViewBorderRadius), RBLPopoverBackgroundViewBorderRadius, M_PI_2, 0.0, 1); + CGPathAddArc(path, NULL, maxMidpointX, maxMidpointY, radius, M_PI_2, 0, true); - CGPathAddArc(path, NULL, floor(contentRect.origin.x + contentRect.size.width - RBLPopoverBackgroundViewBorderRadius), floor(minY + RBLPopoverBackgroundViewBorderRadius), RBLPopoverBackgroundViewBorderRadius, 0.0, -M_PI_2, 1); + CGPathAddArc(path, NULL, maxMidpointX, minMidpointY, radius, 0, -M_PI_2, true); - CGPathAddArc(path, NULL, floor(minX + RBLPopoverBackgroundViewBorderRadius), floor(minY + RBLPopoverBackgroundViewBorderRadius), RBLPopoverBackgroundViewBorderRadius, -M_PI_2, M_PI, 1); + CGPathAddArc(path, NULL, minMidpointX, minMidpointY, radius, -M_PI_2, M_PI, true); CGFloat x1, x2, x3, y1, y2, y3; switch (arrowEdge) { From f28d565ca3aa59c85a7fd2bd4692a4fc85e4a32b Mon Sep 17 00:00:00 2001 From: Josh Vera Date: Sun, 6 Apr 2014 20:33:05 -0400 Subject: [PATCH 11/22] Use next edge if screen rect doesn't contain the preferred edge --- Rebel/RBLPopover.m | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/Rebel/RBLPopover.m b/Rebel/RBLPopover.m index 65d618f..c024f34 100644 --- a/Rebel/RBLPopover.m +++ b/Rebel/RBLPopover.m @@ -274,23 +274,30 @@ static CGFloat RBLRectsGetMedianY(CGRect r1, CGRect r2) { return proposedRect; }; - + + BOOL (^screenRectContainsRectEdge)(CGRectEdge) = ^ BOOL (CGRectEdge edge) { + CGRect proposedRect = popoverRectForEdge(edge); + + BOOL minYInBounds = (edge == CGRectMinYEdge && NSMinY(proposedRect) >= NSMinY(screenRect)); + BOOL maxYInBounds = (popoverEdge == CGRectMaxYEdge && NSMaxY(proposedRect) <= NSMaxY(screenRect)); + BOOL minXInBounds = (popoverEdge == CGRectMinXEdge && NSMinX(proposedRect) >= NSMinX(screenRect)); + BOOL maxXInBounds = (popoverEdge == CGRectMaxXEdge && NSMaxX(proposedRect) <= NSMaxX(screenRect)); + + return minYInBounds && maxYInBounds && minXInBounds && maxXInBounds; + }; + NSUInteger attemptCount = 0; while (!checkPopoverSizeForScreenWithPopoverEdge(popoverEdge)) { if (attemptCount >= 4) { - popoverEdge = preferredEdge; - CGRect proposedRect = popoverRectForEdge(popoverEdge); - BOOL medianYOffscreen = (preferredEdge == CGRectMinYEdge || preferredEdge == CGRectMaxYEdge) && NSMinY(proposedRect) < 0; - BOOL medianXOffscreen = (preferredEdge == CGRectMinXEdge || preferredEdge == CGRectMaxXEdge) && NSMinX(proposedRect) < 0; - if (medianYOffscreen || medianXOffscreen) { - popoverEdge = nextEdgeForEdge(popoverEdge); + if (!screenRectContainsRectEdge(preferredEdge)) { + popoverEdge = nextEdgeForEdge(preferredEdge); } self.backgroundView.didOffsetFrame = YES; return fitRectToScreen(popoverRectForEdge(popoverEdge)); break; } - + popoverEdge = nextEdgeForEdge(popoverEdge); attemptCount ++; } From 1fbeeafc1951b845fb934117c82df3a3a1258bd1 Mon Sep 17 00:00:00 2001 From: Josh Vera Date: Sun, 6 Apr 2014 20:33:15 -0400 Subject: [PATCH 12/22] Dont use midOriginY --- Rebel/RBLPopover.m | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Rebel/RBLPopover.m b/Rebel/RBLPopover.m index c024f34..694f03e 100644 --- a/Rebel/RBLPopover.m +++ b/Rebel/RBLPopover.m @@ -307,7 +307,6 @@ static CGFloat RBLRectsGetMedianY(CGRect r1, CGRect r2) { }; CGRect popoverScreenRect = popoverRect(); - if (self.shown) { if (self.backgroundView.popoverEdge == popoverEdge) { @@ -590,7 +589,7 @@ static CGFloat const RBLPopoverBackgroundViewArrowWidth = 35.0; switch (arrowEdge) { case CGRectMinXEdge: x1 = minX, y1 = minArrowY; - x2 = floor(minX - self.arrowSize.height), y2 = midOriginY; + x2 = floor(minX - self.arrowSize.height), y2 = floor((minArrowY + maxArrowY) / 2); x3 = minX, y3 = maxArrowY; break; case CGRectMaxYEdge: @@ -600,7 +599,7 @@ static CGFloat const RBLPopoverBackgroundViewArrowWidth = 35.0; break; case CGRectMaxXEdge: x1 = maxX, y1 = maxArrowY; - x2 = floor(maxX + self.arrowSize.height), y2 = midOriginY; + x2 = floor(maxX + self.arrowSize.height), y2 = floor((minArrowY + maxArrowY) / 2); x3 = maxX, y3 = minArrowY; break; case CGRectMinYEdge: From 7a7b98e371aaaf6ceaf5f729af171095347c8efc Mon Sep 17 00:00:00 2001 From: Josh Vera Date: Mon, 7 Apr 2014 15:16:39 -0400 Subject: [PATCH 13/22] Calculate based on window visible frame --- Rebel/RBLPopover.m | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/Rebel/RBLPopover.m b/Rebel/RBLPopover.m index 694f03e..e48d908 100644 --- a/Rebel/RBLPopover.m +++ b/Rebel/RBLPopover.m @@ -277,13 +277,14 @@ static CGFloat RBLRectsGetMedianY(CGRect r1, CGRect r2) { BOOL (^screenRectContainsRectEdge)(CGRectEdge) = ^ BOOL (CGRectEdge edge) { CGRect proposedRect = popoverRectForEdge(edge); + NSRect screenRect = positioningView.window.screen.visibleFrame; BOOL minYInBounds = (edge == CGRectMinYEdge && NSMinY(proposedRect) >= NSMinY(screenRect)); - BOOL maxYInBounds = (popoverEdge == CGRectMaxYEdge && NSMaxY(proposedRect) <= NSMaxY(screenRect)); - BOOL minXInBounds = (popoverEdge == CGRectMinXEdge && NSMinX(proposedRect) >= NSMinX(screenRect)); - BOOL maxXInBounds = (popoverEdge == CGRectMaxXEdge && NSMaxX(proposedRect) <= NSMaxX(screenRect)); + BOOL maxYInBounds = (edge == CGRectMaxYEdge && NSMaxY(proposedRect) <= NSMaxY(screenRect)); + BOOL minXInBounds = (edge == CGRectMinXEdge && NSMinX(proposedRect) >= NSMinX(screenRect)); + BOOL maxXInBounds = (edge == CGRectMaxXEdge && NSMaxX(proposedRect) <= NSMaxX(screenRect)); - return minYInBounds && maxYInBounds && minXInBounds && maxXInBounds; + return minYInBounds || maxYInBounds || minXInBounds || maxXInBounds; }; NSUInteger attemptCount = 0; From 4366d3e1e37642c108386f45c88483af8b155f69 Mon Sep 17 00:00:00 2001 From: Josh Vera Date: Mon, 7 Apr 2014 15:16:53 -0400 Subject: [PATCH 14/22] Dont forget to set else case --- Rebel/RBLPopover.m | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Rebel/RBLPopover.m b/Rebel/RBLPopover.m index e48d908..96c6c39 100644 --- a/Rebel/RBLPopover.m +++ b/Rebel/RBLPopover.m @@ -290,9 +290,7 @@ static CGFloat RBLRectsGetMedianY(CGRect r1, CGRect r2) { NSUInteger attemptCount = 0; while (!checkPopoverSizeForScreenWithPopoverEdge(popoverEdge)) { if (attemptCount >= 4) { - if (!screenRectContainsRectEdge(preferredEdge)) { - popoverEdge = nextEdgeForEdge(preferredEdge); - } + popoverEdge = (screenRectContainsRectEdge(preferredEdge) ? preferredEdge : nextEdgeForEdge(preferredEdge)); self.backgroundView.didOffsetFrame = YES; return fitRectToScreen(popoverRectForEdge(popoverEdge)); From 4a2b2441e70fffbcfbe718239a92c45f9fe62e31 Mon Sep 17 00:00:00 2001 From: Josh Vera Date: Mon, 7 Apr 2014 23:46:37 -0400 Subject: [PATCH 15/22] Position positioningRect using -alignmentRectForFrame: --- Rebel/RBLPopover.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Rebel/RBLPopover.m b/Rebel/RBLPopover.m index 96c6c39..823dcbf 100644 --- a/Rebel/RBLPopover.m +++ b/Rebel/RBLPopover.m @@ -181,7 +181,7 @@ static CGFloat RBLRectsGetMedianY(CGRect r1, CGRect r2) { positioningRect = [positioningView bounds]; } - NSRect windowRelativeRect = [positioningView convertRect:positioningRect toView:nil]; + NSRect windowRelativeRect = [positioningView convertRect:[positioningView alignmentRectForFrame:positioningRect] toView:nil]; CGRect screenRect = [positioningView.window convertRectToScreen:windowRelativeRect]; self.backgroundView.popoverOrigin = screenRect; From 5a4c6d139b18f75e6cea44f40c91008322d74d4d Mon Sep 17 00:00:00 2001 From: Josh Vera Date: Mon, 7 Apr 2014 23:47:02 -0400 Subject: [PATCH 16/22] Go back to using the median x and y to calculate mid origin x and y --- Rebel/RBLPopover.m | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/Rebel/RBLPopover.m b/Rebel/RBLPopover.m index 823dcbf..f07a2fd 100644 --- a/Rebel/RBLPopover.m +++ b/Rebel/RBLPopover.m @@ -517,17 +517,11 @@ static CGFloat const RBLPopoverBackgroundViewArrowWidth = 35.0; CGFloat minY = NSMinY(contentRect); CGFloat maxY = NSMaxY(contentRect); - CGFloat midOriginX, midOriginY; - if (self.didOffsetFrame) { - CGRect windowRect = [self.window convertRectFromScreen:self.popoverOrigin]; - CGRect originRect = [self convertRect:windowRect fromView:nil]; - midOriginX = floor(RBLRectsGetMedianX(originRect, contentRect)); - midOriginY = floor(RBLRectsGetMedianY(originRect, contentRect)); - } else { - midOriginX = floor(maxX * self.popoverAnchorPoint.x); - midOriginY = floor(maxY * self.popoverAnchorPoint.y); - } - + CGRect windowRect = [self.window convertRectFromScreen:self.popoverOrigin]; + CGRect originRect = [self convertRect:windowRect fromView:nil]; + CGFloat midOriginX = floor(RBLRectsGetMedianX(originRect, contentRect)); + CGFloat midOriginY = floor(RBLRectsGetMedianY(originRect, contentRect)); + CGFloat maxArrowX = 0.0; CGFloat minArrowX = 0.0; CGFloat minArrowY = 0.0; From 4d96766f707b6538d4d18eaf5a693e209dc5a001 Mon Sep 17 00:00:00 2001 From: Josh Vera Date: Mon, 7 Apr 2014 23:47:52 -0400 Subject: [PATCH 17/22] Remove -didOffsetFrame --- Rebel/RBLPopover.m | 4 ---- 1 file changed, 4 deletions(-) diff --git a/Rebel/RBLPopover.m b/Rebel/RBLPopover.m index f07a2fd..6ad26ee 100644 --- a/Rebel/RBLPopover.m +++ b/Rebel/RBLPopover.m @@ -66,8 +66,6 @@ static CGFloat RBLRectsGetMedianY(CGRect r1, CGRect r2) { @property (nonatomic, assign, readwrite) NSPoint popoverAnchorPoint; -@property (nonatomic, assign, readwrite) BOOL didOffsetFrame; - - (CGRectEdge)rbl_arrowEdgeForPopoverEdge:(CGRectEdge)popoverEdge; @end @@ -292,7 +290,6 @@ static CGFloat RBLRectsGetMedianY(CGRect r1, CGRect r2) { if (attemptCount >= 4) { popoverEdge = (screenRectContainsRectEdge(preferredEdge) ? preferredEdge : nextEdgeForEdge(preferredEdge)); - self.backgroundView.didOffsetFrame = YES; return fitRectToScreen(popoverRectForEdge(popoverEdge)); break; } @@ -301,7 +298,6 @@ static CGFloat RBLRectsGetMedianY(CGRect r1, CGRect r2) { attemptCount ++; } - self.backgroundView.didOffsetFrame = NO; return popoverRectForEdge(popoverEdge); }; From 06aba4e0465aa7210e22179c2f1bc7b27f652ad0 Mon Sep 17 00:00:00 2001 From: Josh Vera Date: Mon, 7 Apr 2014 23:49:50 -0400 Subject: [PATCH 18/22] Remove -popoverAnchorPoint --- Rebel/RBLPopover.m | 9 --------- 1 file changed, 9 deletions(-) diff --git a/Rebel/RBLPopover.m b/Rebel/RBLPopover.m index 6ad26ee..dd3d033 100644 --- a/Rebel/RBLPopover.m +++ b/Rebel/RBLPopover.m @@ -64,8 +64,6 @@ static CGFloat RBLRectsGetMedianY(CGRect r1, CGRect r2) { @property (nonatomic, assign, readwrite) NSRect popoverOrigin; -@property (nonatomic, assign, readwrite) NSPoint popoverAnchorPoint; - - (CGRectEdge)rbl_arrowEdgeForPopoverEdge:(CGRectEdge)popoverEdge; @end @@ -183,7 +181,6 @@ static CGFloat RBLRectsGetMedianY(CGRect r1, CGRect r2) { CGRect screenRect = [positioningView.window convertRectToScreen:windowRelativeRect]; self.backgroundView.popoverOrigin = screenRect; - self.backgroundView.popoverAnchorPoint = self.anchorPoint; self.originalViewSize = self.contentViewController.view.frame.size; CGSize contentViewSize = (CGSizeEqualToSize(self.contentSize, CGSizeZero) ? self.contentViewController.view.frame.size : self.contentSize); @@ -645,12 +642,6 @@ static CGFloat const RBLPopoverBackgroundViewArrowWidth = 35.0; [self rbl_updateClippingView]; } -- (void)setPopoverAnchorPoint:(NSPoint)popoverAnchorPoint { - if (NSEqualPoints(popoverAnchorPoint, self.popoverAnchorPoint)) return; - _popoverAnchorPoint = popoverAnchorPoint; - [self rbl_updateClippingView]; -} - - (void)drawRect:(NSRect)rect { [super drawRect:rect]; [self.fillColor set]; From 725f53d7c4cf6b1dc7aaa03b70a7e74b985c23da Mon Sep 17 00:00:00 2001 From: Josh Vera Date: Tue, 8 Apr 2014 10:50:04 -0400 Subject: [PATCH 19/22] No need to set the popoverEdge again --- Rebel/RBLPopover.m | 1 - 1 file changed, 1 deletion(-) diff --git a/Rebel/RBLPopover.m b/Rebel/RBLPopover.m index dd3d033..bbf69b6 100644 --- a/Rebel/RBLPopover.m +++ b/Rebel/RBLPopover.m @@ -304,7 +304,6 @@ static CGFloat RBLRectsGetMedianY(CGRect r1, CGRect r2) { if (self.backgroundView.popoverEdge == popoverEdge) { CGSize size = [self.backgroundView sizeForBackgroundViewWithContentSize:contentViewSize popoverEdge:popoverEdge]; self.backgroundView.frame = (NSRect){ .size = size }; - self.backgroundView.popoverEdge = popoverEdge; [self.popoverWindow setFrame:popoverScreenRect display:YES]; return; From deb6fcc3821a379d3a9ff99c88ec430d097bf972 Mon Sep 17 00:00:00 2001 From: Josh Vera Date: Tue, 8 Apr 2014 11:16:18 -0400 Subject: [PATCH 20/22] Clean up arrow variables --- Rebel/RBLPopover.m | 46 +++++++++++++++++++++++----------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/Rebel/RBLPopover.m b/Rebel/RBLPopover.m index bbf69b6..1a8837d 100644 --- a/Rebel/RBLPopover.m +++ b/Rebel/RBLPopover.m @@ -556,51 +556,51 @@ static CGFloat const RBLPopoverBackgroundViewArrowWidth = 35.0; CGFloat maxMidpointX = floor(maxX - RBLPopoverBackgroundViewBorderRadius); CGFloat minMidpointY = floor(minY + RBLPopoverBackgroundViewBorderRadius); CGFloat maxMidpointY = floor(maxY - RBLPopoverBackgroundViewBorderRadius); - + CGMutablePathRef path = CGPathCreateMutable(); CGPathMoveToPoint(path, NULL, minX, minMidpointY); CGFloat radius = RBLPopoverBackgroundViewBorderRadius; - + CGPathAddArc(path, NULL, minMidpointX, maxMidpointY, radius, M_PI, M_PI_2, true); - + CGPathAddArc(path, NULL, maxMidpointX, maxMidpointY, radius, M_PI_2, 0, true); - + CGPathAddArc(path, NULL, maxMidpointX, minMidpointY, radius, 0, -M_PI_2, true); - + CGPathAddArc(path, NULL, minMidpointX, minMidpointY, radius, -M_PI_2, M_PI, true); - CGFloat x1, x2, x3, y1, y2, y3; + CGPoint minBasePoint, tipPoint, maxBasePoint; switch (arrowEdge) { case CGRectMinXEdge: - x1 = minX, y1 = minArrowY; - x2 = floor(minX - self.arrowSize.height), y2 = floor((minArrowY + maxArrowY) / 2); - x3 = minX, y3 = maxArrowY; + minBasePoint = CGPointMake(minX, minArrowY); + tipPoint = CGPointMake(floor(minX - self.arrowSize.height), floor((minArrowY + maxArrowY) / 2)); + maxBasePoint = CGPointMake(minX, maxArrowY); break; case CGRectMaxYEdge: - x1 = minArrowX, y1 = maxY; - x2 = floor((minArrowX + maxArrowX) / 2), y2 = floor(maxY + self.arrowSize.height); - x3 = maxArrowX, y3 = maxY; + minBasePoint = CGPointMake(minArrowX, maxY); + tipPoint = CGPointMake(floor((minArrowX + maxArrowX) / 2), floor(maxY + self.arrowSize.height)); + maxBasePoint = CGPointMake(maxArrowX, maxY); break; case CGRectMaxXEdge: - x1 = maxX, y1 = maxArrowY; - x2 = floor(maxX + self.arrowSize.height), y2 = floor((minArrowY + maxArrowY) / 2); - x3 = maxX, y3 = minArrowY; + minBasePoint = CGPointMake(maxX, minArrowY); + tipPoint = CGPointMake(floor(maxX + self.arrowSize.height), floor((minArrowY + maxArrowY) / 2)); + maxBasePoint = CGPointMake(maxX, maxArrowY); break; case CGRectMinYEdge: - x1 = maxArrowX, y1 = minY; - x2 = floor((minArrowX + maxArrowX) / 2), y2 = floor(minY - self.arrowSize.height); - x3 = minArrowX, y3 = minY; + minBasePoint = CGPointMake(minArrowX, minY); + tipPoint = CGPointMake(floor((minArrowX + maxArrowX) / 2), floor(minY - self.arrowSize.height)); + maxBasePoint = CGPointMake(maxArrowX, minY); break; default: break; } - CGPathMoveToPoint(path, NULL, x1, y1); - CGPathAddLineToPoint(path, NULL, x1, y1); - CGPathAddLineToPoint(path, NULL, x2, y2); - CGPathAddLineToPoint(path, NULL, x3, y3); - + CGPathMoveToPoint(path, NULL, minBasePoint.x, minBasePoint.y); + CGPathAddLineToPoint(path, NULL, minBasePoint.x, minBasePoint.y); + CGPathAddLineToPoint(path, NULL, tipPoint.x, tipPoint.y); + CGPathAddLineToPoint(path, NULL, maxBasePoint.x, maxBasePoint.y); + return path; } From 1bdf1501fc3378a47859ba49792b42c86810964b Mon Sep 17 00:00:00 2001 From: Josh Vera Date: Tue, 8 Apr 2014 11:16:41 -0400 Subject: [PATCH 21/22] No need to draw beginning point --- Rebel/RBLPopover.m | 1 - 1 file changed, 1 deletion(-) diff --git a/Rebel/RBLPopover.m b/Rebel/RBLPopover.m index 1a8837d..d9111d1 100644 --- a/Rebel/RBLPopover.m +++ b/Rebel/RBLPopover.m @@ -597,7 +597,6 @@ static CGFloat const RBLPopoverBackgroundViewArrowWidth = 35.0; } CGPathMoveToPoint(path, NULL, minBasePoint.x, minBasePoint.y); - CGPathAddLineToPoint(path, NULL, minBasePoint.x, minBasePoint.y); CGPathAddLineToPoint(path, NULL, tipPoint.x, tipPoint.y); CGPathAddLineToPoint(path, NULL, maxBasePoint.x, maxBasePoint.y); From b44ae6a0a2d494e53609a076abf051f83845bae0 Mon Sep 17 00:00:00 2001 From: Josh Vera Date: Tue, 8 Apr 2014 13:09:47 -0400 Subject: [PATCH 22/22] s/Midpoint/Centerpoint --- Rebel/RBLPopover.m | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/Rebel/RBLPopover.m b/Rebel/RBLPopover.m index d9111d1..8a99a5d 100644 --- a/Rebel/RBLPopover.m +++ b/Rebel/RBLPopover.m @@ -552,23 +552,24 @@ static CGFloat const RBLPopoverBackgroundViewArrowWidth = 35.0; } } - CGFloat minMidpointX = floor(minX + RBLPopoverBackgroundViewBorderRadius); - CGFloat maxMidpointX = floor(maxX - RBLPopoverBackgroundViewBorderRadius); - CGFloat minMidpointY = floor(minY + RBLPopoverBackgroundViewBorderRadius); - CGFloat maxMidpointY = floor(maxY - RBLPopoverBackgroundViewBorderRadius); + // These represent the centerpoints of the popover's corner arcs. + CGFloat minCenterpointX = floor(minX + RBLPopoverBackgroundViewBorderRadius); + CGFloat maxCenterpointX = floor(maxX - RBLPopoverBackgroundViewBorderRadius); + CGFloat minCenterpointY = floor(minY + RBLPopoverBackgroundViewBorderRadius); + CGFloat maxCenterpointY = floor(maxY - RBLPopoverBackgroundViewBorderRadius); CGMutablePathRef path = CGPathCreateMutable(); - CGPathMoveToPoint(path, NULL, minX, minMidpointY); + CGPathMoveToPoint(path, NULL, minX, minCenterpointY); CGFloat radius = RBLPopoverBackgroundViewBorderRadius; - CGPathAddArc(path, NULL, minMidpointX, maxMidpointY, radius, M_PI, M_PI_2, true); + CGPathAddArc(path, NULL, minCenterpointX, maxCenterpointY, radius, M_PI, M_PI_2, true); - CGPathAddArc(path, NULL, maxMidpointX, maxMidpointY, radius, M_PI_2, 0, true); + CGPathAddArc(path, NULL, maxCenterpointX, maxCenterpointY, radius, M_PI_2, 0, true); - CGPathAddArc(path, NULL, maxMidpointX, minMidpointY, radius, 0, -M_PI_2, true); + CGPathAddArc(path, NULL, maxCenterpointX, minCenterpointY, radius, 0, -M_PI_2, true); - CGPathAddArc(path, NULL, minMidpointX, minMidpointY, radius, -M_PI_2, M_PI, true); + CGPathAddArc(path, NULL, minCenterpointX, minCenterpointY, radius, -M_PI_2, M_PI, true); CGPoint minBasePoint, tipPoint, maxBasePoint; switch (arrowEdge) {