From 73f02cc1bf8f44a4c74fdb91e5acde257417d164 Mon Sep 17 00:00:00 2001 From: Didier Korthoudt Date: Tue, 21 Aug 2018 09:14:21 +0200 Subject: [PATCH] NEW: Add first responder management based on content view to CPScrollView (#2757) --- AppKit/CPScrollView.j | 45 +++++++++++++++++++++++++++++++++ Tests/AppKit/CPScrollViewTest.j | 8 +++--- 2 files changed, 49 insertions(+), 4 deletions(-) diff --git a/AppKit/CPScrollView.j b/AppKit/CPScrollView.j index 39a884307..9f2009a32 100644 --- a/AppKit/CPScrollView.j +++ b/AppKit/CPScrollView.j @@ -1508,6 +1508,51 @@ Notifies the delegate when the scroll view has finished scrolling. @end +#pragma mark - + +@implementation CPScrollView (FirstResponder) + +// Those 4 next methods are needed to (un)set CPThemeStateFirstResponder based on content view + +- (void)viewWillMoveToWindow:(CPWindow)aWindow +{ + [super viewWillMoveToWindow:aWindow]; + + [self _stopObservingFirstResponderForWindow:[self window]]; + + if (aWindow) + [self _startObservingFirstResponderForWindow:aWindow]; +} + +- (void)_startObservingFirstResponderForWindow:(CPWindow)aWindow +{ + [[CPNotificationCenter defaultCenter] addObserver:self selector:@selector(_firstResponderDidChange:) name:_CPWindowDidChangeFirstResponderNotification object:aWindow]; +} + +- (void)_stopObservingFirstResponderForWindow:(CPWindow)aWindow +{ + [[CPNotificationCenter defaultCenter] removeObserver:self name:_CPWindowDidChangeFirstResponderNotification object:aWindow]; +} + +- (void)_firstResponderDidChange:(CPNotification)aNotification +{ + var responder = [[self window] firstResponder], + // FIXME: We add focus ring only on table views right now. When focus ring management will be added, this must be adapted. + shouldAddFocusRing = [responder isKindOfClass:[CPTableView class]], + found; + + while (!(found = (responder === self)) && responder) + responder = [responder superview]; + + if (found && shouldAddFocusRing) + [self setThemeState:CPThemeStateFirstResponder]; + else + [self unsetThemeState:CPThemeStateFirstResponder]; +} + +@end + +#pragma mark - var CPScrollViewContentViewKey = @"CPScrollViewContentView", CPScrollViewHeaderClipViewKey = @"CPScrollViewHeaderClipViewKey", diff --git a/Tests/AppKit/CPScrollViewTest.j b/Tests/AppKit/CPScrollViewTest.j index 5bcaad4b4..81c3c7a91 100644 --- a/Tests/AppKit/CPScrollViewTest.j +++ b/Tests/AppKit/CPScrollViewTest.j @@ -327,16 +327,16 @@ theWindow = [[CPWindow alloc] initWithContentRect:CGRectMake(0.0, 0.0, 1024.0, 768.0) styleMask:CPWindowNotSizable]; - [self assert:[CPNotificationCenterHelper registeredNotificationsForObserver:scrollView] equals:[] message:@"Notications registered for the scrollView in the notification center are wrong"]; + [self assert:[CPNotificationCenterHelper registeredNotificationsForObserver:scrollView] equals:[] message:@"Notications registered for the scrollView in the notification center are wrong -1-"]; [[theWindow contentView] addSubview:scrollView]; - [self assert:[CPNotificationCenterHelper registeredNotificationsForObserver:scrollView] equals:[@"CPScrollerStyleGlobalChangeNotification"] message:@"Notications registered for the scrollView in the notification center are wrong"]; + [self assert:[CPNotificationCenterHelper registeredNotificationsForObserver:scrollView] equals:[@"CPScrollerStyleGlobalChangeNotification", @"_CPWindowDidChangeFirstResponderNotification"] message:@"Notications registered for the scrollView in the notification center are wrong -2-"]; [[theWindow contentView] addSubview:scrollView]; - [self assert:[CPNotificationCenterHelper registeredNotificationsForObserver:scrollView] equals:[@"CPScrollerStyleGlobalChangeNotification"] message:@"Notications registered for the scrollView in the notification center are wrong"]; + [self assert:[CPNotificationCenterHelper registeredNotificationsForObserver:scrollView] equals:[@"CPScrollerStyleGlobalChangeNotification", @"_CPWindowDidChangeFirstResponderNotification"] message:@"Notications registered for the scrollView in the notification center are wrong -3-"]; [scrollView removeFromSuperview]; - [self assert:[CPNotificationCenterHelper registeredNotificationsForObserver:scrollView] equals:[] message:@"Notications registered for the scrollView in the notification center are wrong"]; + [self assert:[CPNotificationCenterHelper registeredNotificationsForObserver:scrollView] equals:[] message:@"Notications registered for the scrollView in the notification center are wrong -4-"]; } - (void)testDocumentVisibleRect