Skip to content

Loading…

Fixed scrollRectToVisible in CPView #1678

Merged
merged 1 commit into from

3 participants

@mrcarlberg
Cappuccino member

Earlier it only worked correctly when the receiver was the document view of the clip view.
Added test case.

I have also converted the test case to cocoa

@mrcarlberg mrcarlberg Fixed scrollRectToVisible in CPView:
Earlier it only worked when the receiver was the document view of the clip view.
Added test case.
1d1f2d7
@cappbot

Milestone: Someday. Label: #new. What's next? A reviewer should examine this issue.

@mrcarlberg mrcarlberg added a commit to mrcarlberg/cappuccino that referenced this pull request
@mrcarlberg mrcarlberg Make sure the text field is visible before focus so the browser
will not scroll without the NSScrollView knowing about it
Issue #1675 and maybe a little of issue #1301
This fix will not work without pull
request #1678 - Fixed scrollRectToVisible in CPView
182f4c3
@aljungberg aljungberg added a commit that referenced this pull request
@aljungberg aljungberg Refs #1678. Minor tweak. 2ddb858
@aljungberg aljungberg merged commit 1d1f2d7 into cappuccino:master
@aljungberg
Cappuccino member

Merged. Thanks for taking the time for making a Cocoa unit test too!

+bug
+AppKit
+#fixed
assignee=aljungberg
milestone=0.9.7

@aljungberg aljungberg was assigned
@cappbot

Assignee: aljungberg. Milestone: 0.9.7. Labels: #fixed, AppKit, bug. What's next? This issue is considered successfully resolved.

@mrcarlberg mrcarlberg deleted the mrcarlberg:scroll_rect_to_visible branch
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Sep 28, 2012
  1. @mrcarlberg

    Fixed scrollRectToVisible in CPView:

    mrcarlberg committed
    Earlier it only worked when the receiver was the document view of the clip view.
    Added test case.
Showing with 74 additions and 14 deletions.
  1. +26 −14 AppKit/CPView.j
  2. +48 −0 Tests/AppKit/CPScrollViewTest.j
View
40 AppKit/CPView.j
@@ -2359,13 +2359,11 @@ setBoundsOrigin:
*/
- (BOOL)scrollRectToVisible:(CGRect)aRect
{
- var visibleRect = [self visibleRect];
-
// Make sure we have a rect that exists.
aRect = CGRectIntersection(aRect, _bounds);
- // If aRect is empty or is already visible then no scrolling required.
- if (_CGRectIsEmpty(aRect) || CGRectContainsRect(visibleRect, aRect))
+ // If aRect is empty no scrolling required.
+ if (CGRectIsEmpty(aRect))
return NO;
var enclosingClipView = [self _enclosingClipView];
@@ -2374,20 +2372,34 @@ setBoundsOrigin:
if (!enclosingClipView)
return NO;
- var scrollPoint = _CGPointMakeCopy(visibleRect.origin);
+ var documentView = [enclosingClipView documentView];
+
+ // If the clip view doesn't have a document view, then there isn't much we can do.
+ if (!documentView)
+ return NO;
+
+ // Get the document view visible rect and convert aRect to the document view's coordinate system
+ var documentViewVisibleRect = [documentView visibleRect],
+ rectInDocumentView = [self convertRect:aRect toView:documentView];
+
+ // If already visible then no scrolling required.
+ if (CGRectContainsRect(documentViewVisibleRect, rectInDocumentView))
+ return NO;
+
+ var scrollPoint = CGPointMakeCopy(documentViewVisibleRect.origin);
// One of the following has to be true since our current visible rect didn't contain aRect.
- if (_CGRectGetMinX(aRect) <= _CGRectGetMinX(visibleRect))
- scrollPoint.x = _CGRectGetMinX(aRect);
- else if (_CGRectGetMaxX(aRect) > _CGRectGetMaxX(visibleRect))
- scrollPoint.x += _CGRectGetMaxX(aRect) - _CGRectGetMaxX(visibleRect);
+ if (_CGRectGetMinX(rectInDocumentView) < _CGRectGetMinX(documentViewVisibleRect))
+ scrollPoint.x = _CGRectGetMinX(rectInDocumentView);
+ else if (_CGRectGetMaxX(rectInDocumentView) > _CGRectGetMaxX(documentViewVisibleRect))
+ scrollPoint.x += _CGRectGetMaxX(rectInDocumentView) - _CGRectGetMaxX(documentViewVisibleRect);
- if (_CGRectGetMinY(aRect) <= _CGRectGetMinY(visibleRect))
- scrollPoint.y = CGRectGetMinY(aRect);
- else if (_CGRectGetMaxY(aRect) > _CGRectGetMaxY(visibleRect))
- scrollPoint.y += _CGRectGetMaxY(aRect) - _CGRectGetMaxY(visibleRect);
+ if (_CGRectGetMinY(rectInDocumentView) < _CGRectGetMinY(documentViewVisibleRect))
+ scrollPoint.y = _CGRectGetMinY(rectInDocumentView);
+ else if (_CGRectGetMaxY(rectInDocumentView) > _CGRectGetMaxY(documentViewVisibleRect))
+ scrollPoint.y += _CGRectGetMaxY(rectInDocumentView) - _CGRectGetMaxY(documentViewVisibleRect);
- [enclosingClipView scrollToPoint:CGPointMake(scrollPoint.x, scrollPoint.y)];
+ [enclosingClipView scrollToPoint:scrollPoint];
return YES;
}
View
48 Tests/AppKit/CPScrollViewTest.j
@@ -214,5 +214,53 @@
[self assert:replacementDocumentView equals:[scrollView documentView] message:@"documentView was not replaced properly"];
}
+- (void)testScrollRectToVisible
+{
+ var scrollView = [[CPScrollView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)],
+ documentView = [[CPView alloc] initWithFrame:CGRectMake(0, 0, 1000, 1000)],
+ textField1 = [CPTextField textFieldWithStringValue:@"Martin" placeholder:@"" width:10],
+ textField2 = [CPTextField textFieldWithStringValue:@"Malte" placeholder:@"" width:10],
+ textField1Size = CGSizeMakeCopy([textField1 bounds].size),
+ textField2Size = CGSizeMakeCopy([textField2 bounds].size);
+
+ [scrollView setDocumentView:documentView];
+
+ [textField1 setFrameOrigin:CGPointMake(0, 0)];
+ [textField2 setFrameOrigin:CGPointMake(500, 500)];
+
+ [documentView addSubview:textField1];
+ [documentView addSubview:textField2];
+
+ var visibleRect = [documentView visibleRect],
+ originalVisibleSize = CGSizeMakeCopy(visibleRect.size);
+
+ // Make sure we are at the top left corner
+ [self assertPoint:CGPointMake(0, 0) equals:visibleRect.origin message:@"VisibleRect origin not at top left corner"];
+
+ // Make the second text field visible
+ [textField2 scrollRectToVisible:[textField2 bounds]];
+
+ var visibleRectOriginShouldBeAt = CGPointMake(500 - originalVisibleSize.width + textField2Size.width, 500 -originalVisibleSize.height + textField2Size.height);
+
+ visibleRect = [documentView visibleRect];
+
+ // We should now have the text field in the lower right corner
+ [self assertPoint:visibleRectOriginShouldBeAt equals:visibleRect.origin message:@"Second text field not at lower right corner in visible rect"];
+
+ // Make the first text field visible again
+ [textField1 scrollRectToVisible:[textField2 bounds]];
+
+ visibleRect = [documentView visibleRect];
+
+ // We should now be back at top left corner
+ [self assertPoint:CGPointMake(0, 0) equals:visibleRect.origin message:@"VisibleRect origin not at top left corner again"];
+}
+
+- (void)assertPoint:(CGPoint)expected equals:(CGPoint)actual message:(CPString)message
+{
+ [self assert:expected.x equals:actual.x message:@"X: " + message];
+ [self assert:expected.y equals:actual.y message:@"Y: " + message];
+}
+
@end
Something went wrong with that request. Please try again.