From 699503042f36ac993a4cebc48635ce5d246d376c Mon Sep 17 00:00:00 2001 From: Martin Carlberg Date: Tue, 5 Apr 2016 23:22:29 +0200 Subject: [PATCH] Fixed: First item is always selected if selected binding value is set before content binding value. Test case is provided. --- AppKit/CPPopUpButton.j | 26 +++++++++++++++++++++++--- Tests/AppKit/CPPopUpButtonTest.j | 30 ++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+), 3 deletions(-) diff --git a/AppKit/CPPopUpButton.j b/AppKit/CPPopUpButton.j index 6eecf9420..12f7b8638 100644 --- a/AppKit/CPPopUpButton.j +++ b/AppKit/CPPopUpButton.j @@ -847,7 +847,17 @@ CPPopUpButtonStatePullsDown = CPThemeState("pulls-down"); { var count = [aValue count], options = [_info objectForKey:CPOptionsKey], - offset = [self _getInsertNullOffset]; + offset = [self _getInsertNullOffset], + selectedBindingInfo = [_source infoForBinding:CPSelectedObjectBinding], + selectedObject = nil; + + if (selectedBindingInfo) + { + var destination = [selectedBindingInfo objectForKey:CPObservedObjectKey], + keyPath = [selectedBindingInfo objectForKey:CPObservedKeyPathKey]; + + selectedObject = [destination valueForKeyPath:keyPath]; + } if (count + offset != [_source numberOfItems]) { @@ -858,9 +868,19 @@ CPPopUpButtonStatePullsDown = CPThemeState("pulls-down"); for (var i = 0; i < count; i++) { - var item = [[CPMenuItem alloc] initWithTitle:@"" action:NULL keyEquivalent:nil]; - [self _setValue:[aValue objectAtIndex:i] forItem:item withOptions:options]; + var item = [[CPMenuItem alloc] initWithTitle:@"" action:NULL keyEquivalent:nil], + itemValue = [aValue objectAtIndex:i]; + + [self _setValue:itemValue forItem:item withOptions:options]; [_source addItem:item]; + + // Select this item if it is the one selected by the selected object binding + // This is needed if the selected object binding is set before the items + // from the content binding + if (itemValue === selectedObject) + { + [_source setSelectedIndex:[_source numberOfItems] - 1]; + } } } else diff --git a/Tests/AppKit/CPPopUpButtonTest.j b/Tests/AppKit/CPPopUpButtonTest.j index a66ec0088..d18db9bb2 100644 --- a/Tests/AppKit/CPPopUpButtonTest.j +++ b/Tests/AppKit/CPPopUpButtonTest.j @@ -324,6 +324,36 @@ [self assert:2 equals:[[self button] indexOfSelectedItem]]; } +- (void)testSimpleObjectBindingArrayControllerWithLateContent +{ + var arrayController = [[CPArrayController alloc] init], + objectController = [[CPObjectController alloc] init], + testObject = [CPMutableDictionary dictionary], + martin = [CPDictionary dictionaryWithJSObject:{@"name": @"Martin"}], + malte = [CPDictionary dictionaryWithJSObject:{@"name": @"Malte"}], + johan = [CPDictionary dictionaryWithJSObject:{@"name": @"Johan"}], + menuObjects = [martin, malte, johan]; + + [testObject setObject:@"I'm a testObject" forKey:@"Who am I"]; + [objectController setContent:testObject]; + + [button bind:CPContentBinding toObject:arrayController withKeyPath:@"arrangedObjects" options:nil]; + [button bind:CPContentValuesBinding toObject:arrayController withKeyPath:@"arrangedObjects.name" options:nil]; + [button bind:CPSelectedObjectBinding toObject:objectController withKeyPath:@"selection.xxx" options:nil]; + + [testObject setObject:martin forKey:@"xxx"]; + [arrayController setContent:menuObjects]; + [self assert:0 equals:[[self button] indexOfSelectedItem]]; + [arrayController setContent:nil]; + [testObject setObject:malte forKey:@"xxx"]; + [arrayController setContent:menuObjects]; + [self assert:1 equals:[[self button] indexOfSelectedItem]]; + [arrayController setContent:nil]; + [testObject setObject:johan forKey:@"xxx"]; + [arrayController setContent:menuObjects]; + [self assert:2 equals:[[self button] indexOfSelectedItem]]; +} + - (void)testObjectBindingNullPlaceholderOption { var arrayController = [[CPArrayController alloc] init],