diff --git a/AppKit/CPTableView.j b/AppKit/CPTableView.j index db922aa75..a450ccb08 100644 --- a/AppKit/CPTableView.j +++ b/AppKit/CPTableView.j @@ -3665,8 +3665,8 @@ Your delegate can implement this method to avoid subclassing the tableview to ad identifier = [[aTableColumn dataView] UID]; view = [self makeViewWithIdentifier:identifier owner:_delegate]; - if (!view) - view = [aTableColumn _newDataView]; + if (!view) + view = [aTableColumn _newDataView]; } [view setIdentifier:identifier]; @@ -5106,15 +5106,16 @@ Your delegate can implement this method to avoid subclassing the tableview to ad [self getColumn:@ref(column) row:@ref(row) forView:responder]; - if (row == CPNotFound && column == CPNotFound) - [self _notifyViewDidResignFirstResponder]; - _editingRow = row; _editingColumn = column; // We want to keep the 'First Responder' theme state for the table view as a whole, even when a subview is being edited. // This makes sure the theming effects of a focused table remain in effect even as cells are being edited in it. - [self _notifyViewDidBecomeFirstResponder]; + // Check if the firstResponder is outside the tableview: + if (responder !== self && _editingRow == CPNotFound && _editingColumn == CPNotFound) + [self _notifyViewDidResignFirstResponder]; + else + [self _notifyViewDidBecomeFirstResponder]; // This is for cell-based tables only. In view-based mode, we do not change the textfield apprearence during an edit. if (!_isViewBased && _editingRow !== CPNotFound && [responder isKindOfClass:[CPTextField class]] && [responder isEditable]) diff --git a/Tests/AppKit/CPTableViewTest.j b/Tests/AppKit/CPTableViewTest.j index 880dbcd99..4138caae7 100644 --- a/Tests/AppKit/CPTableViewTest.j +++ b/Tests/AppKit/CPTableViewTest.j @@ -18,8 +18,7 @@ - (void)setUp { // setup a reasonable table - theWindow = [[CPWindow alloc] initWithContentRect:CGRectMake(0.0, 0.0, 1024.0, 768.0) - styleMask:CPWindowNotSizable]; + theWindow = [[CPWindow alloc] initWithContentRect:CGRectMake(0.0, 0.0, 1024.0, 768.0) styleMask:CPWindowNotSizable]; tableView = [[FirstResponderConfigurableTableView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)]; tableColumn = [[CPTableColumn alloc] initWithIdentifier:@"Foo"]; @@ -435,7 +434,70 @@ [scrollView removeFromSuperview]; [self assert:[CPNotificationCenterHelper registeredNotificationsForObserver:tableView] equals:[] message:@"Notications registered for the tableView in the notification center are wrong"]; +} +- (void)testTableDataViewState +{ + var textField = [[CPTextField alloc] initWithFrame:CGRectMake(110, 0, 100, 32)]; + [textField setEditable:YES]; + [[theWindow contentView] addSubview:textField]; + + var dataSource = [TestDataSource new]; + + [dataSource setTableEntries:["A", "B", "C"]]; + [tableView setDataSource:dataSource]; + [tableView setDelegate:[EditableTableDelegate new]]; + + [theWindow makeFirstResponder:tableView]; + [tableView selectRowIndexes:[CPIndexSet indexSetWithIndex:0] byExtendingSelection:NO]; + + [tableView enumerateAvailableViewsUsingBlock:function(dataView, row, column, stop) + { + if (row == 0) + { + [self assertTrue:[dataView hasThemeState:CPThemeStateTableDataView] message:"CPThemeStateTableDataView should be enabled"]; + [self assertTrue:[dataView hasThemeState:CPThemeStateSelectedDataView] message:"CPThemeStateSelectedDataView should be enabled"]; + [self assertTrue:[dataView hasThemeState:CPThemeStateFirstResponder] message:"CPThemeStateFirstResponder should be enabled"]; + } + + if (row == 1) + { + [self assertTrue:[dataView hasThemeState:CPThemeStateTableDataView] message:"CPThemeStateTableDataView should be enabled"]; + [self assertFalse:[dataView hasThemeState:CPThemeStateSelectedDataView] message:"CPThemeStateSelectedDataView should be disabled"]; + [self assertTrue:[dataView hasThemeState:CPThemeStateFirstResponder] message:"CPThemeStateFirstResponder should be enabled"]; + } + }]; + + [tableView selectRowIndexes:[CPIndexSet indexSetWithIndex:1] byExtendingSelection:NO]; + + [tableView enumerateAvailableViewsUsingBlock:function(dataView, row, column, stop) + { + if (row == 0) + { + [self assertTrue:[dataView hasThemeState:CPThemeStateTableDataView] message:"CPThemeStateTableDataView should be enabled"]; + [self assertFalse:[dataView hasThemeState:CPThemeStateSelectedDataView] message:"CPThemeStateSelectedDataView should be disabled"]; + [self assertTrue:[dataView hasThemeState:CPThemeStateFirstResponder] message:"CPThemeStateFirstResponder should be enabled"]; + } + }]; + + [theWindow makeFirstResponder:textField]; + + [tableView enumerateAvailableViewsUsingBlock:function(dataView, row, column, stop) + { + if (row == 0) + { + [self assertTrue:[dataView hasThemeState:CPThemeStateTableDataView] message:"CPThemeStateTableDataView should be enabled"]; + [self assertFalse:[dataView hasThemeState:CPThemeStateSelectedDataView] message:"CPThemeStateSelectedDataView should be disabled"]; + [self assertFalse:[dataView hasThemeState:CPThemeStateFirstResponder] message:"CPThemeStateFirstResponder should be disabled"]; + } + + if (row == 1) + { + [self assertTrue:[dataView hasThemeState:CPThemeStateTableDataView] message:"CPThemeStateTableDataView should be enabled"]; + [self assertTrue:[dataView hasThemeState:CPThemeStateSelectedDataView] message:"CPThemeStateSelectedDataView should be enabled"]; + [self assertFalse:[dataView hasThemeState:CPThemeStateFirstResponder] message:"CPThemeStateFirstResponder should be disabled"]; + } + }]; } @end