More key view loop madness

- It turns out Cocoa DOES recalculate the loop when calling recalculateKeyViewLoop. It does not wait until selectNext/PreviousKeyView is called.
- Cocoa calculates the key view loop for nibs that do not have one, but does not call recalculateKeyViewLoop.
- If there is no first responder and no initial first responder when a window first becomes key, use the first valid key view, not the first geometric key view.
- Made allViews function a method, not sure why it was a function.
- Unit tests now pass.
This commit is contained in:
Aparajita Fishman committed 2013-01-10 09:11:58 +07:00
1 parent 782f47a30b
commit af2e0348c1
5 files changed
+66 -52

No files matched your search

+53 -38
View File
@@ -533,7 +533,8 @@ CPTexturedBackgroundWindowMask
- (void)awakeFromCib
{
// At this time we know the final screen (or browser) size and can apply the positioning mask, if any, from the nib.
// At this time we know the final screen (or browser) size
// and can apply the positioning mask, if any, from the nib.
if (_positioningScreenRect)
{
var actualScreenRect = [CPPlatform isBrowser] ? [_platformWindow contentBounds] : [[self screen] visibleFrame],
@@ -575,6 +576,34 @@ CPTexturedBackgroundWindowMask
[self setFrameOrigin:origin];
}
}
/*
Calculate the key view loop if necessary. Note that Cocoa does not call recalculateKeyViewLoop when awaking a nib. If a key view loop was set in the cib, we have to chain it to the content view.
*/
if ([self _hasKeyViewLoop:[_contentView subviews]])
{
var views = [self _viewsSortedByPosition],
count = [views count];
// The first view is the content view.
// Find the first subview that has a next key view.
for (var i = 1; i < count; ++i)
{
var view = views[i];
if ([view nextKeyView])
{
[_contentView setNextKeyView:view];
break;
}
}
}
else
{
// Cooca does NOT call the public method recalculateKeyViewLoop for nibs,
// but it does calculate the loop.
[self _doRecalculateKeyViewLoop];
}
}
- (void)_setWindowView:(CPView)aWindowView
@@ -1415,8 +1444,8 @@ CPTexturedBackgroundWindowMask
[self makeFirstResponder:_initialFirstResponder];
else
{
// Make the first valid key view of the content view the first responder
var view = [self _firstValidKeyView];
// Make the first valid key view the first responder
var view = [_contentView nextValidKeyView];
if (view)
[self makeFirstResponder:view];
@@ -1430,17 +1459,6 @@ CPTexturedBackgroundWindowMask
[self makeFirstResponder:_firstResponder];
}
- (CPView)_firstValidKeyView
{
var views = [self _viewsSortedByPosition];
for (var index = 0, count = [views count]; index < count; ++index)
if ([views[index] canBecomeKeyView])
return views[index];
return nil;
}
/*!
Attempts to make the \c aResponder the first responder. Before trying
to make it the first responder, the receiver will ask the current first responder
@@ -1845,22 +1863,7 @@ CPTexturedBackgroundWindowMask
// The first time a window is loaded, if it does not have a key view loop
// established, calculate it now.
if (![self _hasKeyViewLoop:[_contentView subviews]])
{
// Do this to be compliant with Cocoa docs, it just marks the loop as dirty
[self recalculateKeyViewLoop];
/*
We have to calculate now. Otherwise, the following can happen for a window with autorecalculatesKeyViewLoop == NO:
- Window opens, recalculateKeyViewLoop marks loop dirty.
- Add a new text field, focus the field.
- Tab from the field. Because loop is dirty, it is recalculated,
even though it shouldn't because autorecalculatesKeyViewLoop == NO.
By calculating the loop now, we ensure that the loop stays clean.
*/
[self _doRecalculateKeyViewLoop];
}
}
[self _setupFirstResponder];
@@ -2850,7 +2853,7 @@ CPTexturedBackgroundWindowMask
/*
Recursively traverse an array of views (depth last) until we find one that has a next or previous key view set. Return nil if none can be found.
We don't use allViews here because it is wasteful to enumerate the entire view hierarchy when we will probably find a key view at the top level.
We don't use _allViews here because it is wasteful to enumerate the entire view hierarchy when we will probably find a key view at the top level.
*/
- (BOOL)_hasKeyViewLoop:(CPArray)theViews
{
@@ -2876,14 +2879,21 @@ CPTexturedBackgroundWindowMask
return NO;
}
/*!
Recalculates the key view loop, based on geometric position.
Note that the Cocoa documentation says that this method only marks the loop
as dirty, the recalculation is not done until the next or previous key view
of the window is requested. In reality, Cocoa does recalculate the loop
when this method is called.
*/
- (void)recalculateKeyViewLoop
{
_keyViewLoopIsDirty = YES;
[self _doRecalculateKeyViewLoop];
}
- (CPArray)_viewsSortedByPosition
{
var views = allViews(self);
var views = [self _allViews];
[views sortUsingFunction:keyViewComparator context:nil];
return views;
@@ -3059,17 +3069,22 @@ CPTexturedBackgroundWindowMask
[self disableKeyEquivalentForDefaultButton];
}
@end
var allViews = function(aWindow)
- (CPArray)_allViews
{
var views = [[aWindow contentView] subviews];
var contentView = [self contentView],
views = [CPArray arrayWithObject:contentView];
for (var index = 0; index < views.length; ++index)
[views addObjectsFromArray:[contentView subviews]];
// Start from index 1 because index 0 is the contentView
// and its subviews have already been added
for (var index = 1; index < views.length; ++index)
views = views.concat([views[index] subviews]);
return views;
};
}
@end
var keyViewComparator = function(lhs, rhs, context)
{
+4 -5
View File
@@ -19,12 +19,11 @@
[self assertTrue:!![self window]];
}
- (void)testThatContentViewIsInitialFirstResponder
- (void)testThatNilIsInitialFirstResponder
{
var contentView = [[self window] contentView];
[self assert:contentView
[self assert:nil
equals:[[self window] initialFirstResponder]
message:@"The window's content view must be the initial first responder"];
message:@"The initial first responder must be null"];
}
- (void)testKeyViewLoop
@@ -34,11 +33,11 @@
[textField setFrame:CGRectMake(100.0, 100.0, 100.0, 26.0)];
[contentView addSubview:textField];
[[self window] recalculateKeyViewLoop];
var nextTextField = [CPTextField textFieldWithStringValue:@"" placeholder:@"" width:100];
[nextTextField setFrame:CGRectMake(100.0, 200.0, 100.0, 26.0)];
[contentView addSubview:nextTextField];
[[self window] recalculateKeyViewLoop];
// Test nextKeyView
+2 -2
View File
@@ -11,12 +11,12 @@
@implementation AppController : CPObject
{
@outlet CPWindow customNoInitial;
@outlet CPWindow keyWindow;
}
- (void)applicationDidFinishLaunching:(CPNotification)aNotification
{
[customNoInitial makeKeyAndOrderFront:self];
[keyWindow makeKeyAndOrderFront:self];
}
@end
@@ -1 +1 @@
280NPLIST;1.0;D;K;4;$topD;K;18;CPCibObjectDataKeyD;K;6;CP$UIDd;1;2E;E;K;8;$objectsA;S;5;$nullD;K;10;$classnameS;16;_CPCibObjectDataK;8;$classesA;S;16;_CPCibObjectDataS;8;CPObjectE;E;D;K;6;$classD;K;6;CP$UIDd;1;1E;K;28;_CPCibObjectDataNamesKeysKeyD;K;6;CP$UIDd;1;0E;K;30;_CPCibObjectDataNamesValuesKeyD;K;6;CP$UIDd;1;0E;K;30;_CPCibObjectDataClassesKeysKeyD;K;6;CP$UIDd;1;0E;K;32;_CPCibObjectDataClassesValuesKeyD;K;6;CP$UIDd;1;0E;K;30;_CPCibObjectDataConnectionsKeyD;K;6;CP$UIDd;1;4E;K;28;_CPCibObjectDataFrameworkKeyD;K;6;CP$UIDd;1;0E;K;26;_CPCibObjectDataNextOidKeyD;K;6;CP$UIDd;1;5E;K;30;_CPCibObjectDataObjectsKeysKeyD;K;6;CP$UIDd;1;6E;K;32;_CPCibObjectDataObjectsValuesKeyD;K;6;CP$UIDd;1;7E;K;26;_CPCibObjectDataOidKeysKeyD;K;6;CP$UIDd;1;8E;K;28;_CPCibObjectDataOidValuesKeyD;K;6;CP$UIDd;1;9E;K;28;_CPCibObjectDataFileOwnerKeyD;K;6;CP$UIDd;2;11E;K;33;_CPCibObjectDataVisibleWindowsKeyD;K;6;CP$UIDd;2;13E;E;D;K;10;$classnameS;7;CPArrayK;8;$classesA;S;7;CPArrayS;8;CPObjectE;E;D;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;2;15E;D;K;6;CP$UIDd;2;16E;D;K;6;CP$UIDd;2;17E;D;K;6;CP$UIDd;2;18E;D;K;6;CP$UIDd;2;19E;D;K;6;CP$UIDd;2;20E;D;K;6;CP$UIDd;2;21E;D;K;6;CP$UIDd;2;22E;D;K;6;CP$UIDd;2;23E;D;K;6;CP$UIDd;2;24E;D;K;6;CP$UIDd;2;26E;D;K;6;CP$UIDd;2;27E;D;K;6;CP$UIDd;2;28E;E;E;D;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;E;E;D;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;2;29E;D;K;6;CP$UIDd;2;30E;D;K;6;CP$UIDd;2;32E;D;K;6;CP$UIDd;2;34E;D;K;6;CP$UIDd;2;36E;D;K;6;CP$UIDd;1;0E;D;K;6;CP$UIDd;2;37E;D;K;6;CP$UIDd;1;0E;D;K;6;CP$UIDd;2;38E;D;K;6;CP$UIDd;1;0E;D;K;6;CP$UIDd;2;39E;D;K;6;CP$UIDd;1;0E;D;K;6;CP$UIDd;2;40E;D;K;6;CP$UIDd;1;0E;D;K;6;CP$UIDd;2;41E;D;K;6;CP$UIDd;2;42E;D;K;6;CP$UIDd;2;43E;D;K;6;CP$UIDd;1;0E;D;K;6;CP$UIDd;2;44E;D;K;6;CP$UIDd;1;0E;D;K;6;CP$UIDd;2;45E;D;K;6;CP$UIDd;1;0E;D;K;6;CP$UIDd;2;46E;D;K;6;CP$UIDd;1;0E;D;K;6;CP$UIDd;2;47E;D;K;6;CP$UIDd;1;0E;D;K;6;CP$UIDd;2;48E;D;K;6;CP$UIDd;2;49E;D;K;6;CP$UIDd;2;50E;D;K;6;CP$UIDd;1;0E;D;K;6;CP$UIDd;2;51E;D;K;6;CP$UIDd;1;0E;D;K;6;CP$UIDd;2;52E;D;K;6;CP$UIDd;1;0E;D;K;6;CP$UIDd;2;53E;D;K;6;CP$UIDd;1;0E;D;K;6;CP$UIDd;2;54E;D;K;6;CP$UIDd;1;0E;D;K;6;CP$UIDd;2;55E;D;K;6;CP$UIDd;2;56E;D;K;6;CP$UIDd;2;57E;D;K;6;CP$UIDd;1;0E;D;K;6;CP$UIDd;2;58E;D;K;6;CP$UIDd;1;0E;D;K;6;CP$UIDd;2;59E;D;K;6;CP$UIDd;1;0E;D;K;6;CP$UIDd;2;60E;D;K;6;CP$UIDd;1;0E;D;K;6;CP$UIDd;2;61E;D;K;6;CP$UIDd;1;0E;D;K;6;CP$UIDd;2;62E;D;K;6;CP$UIDd;2;63E;D;K;6;CP$UIDd;2;64E;D;K;6;CP$UIDd;1;0E;D;K;6;CP$UIDd;2;65E;D;K;6;CP$UIDd;1;0E;D;K;6;CP$UIDd;2;66E;D;K;6;CP$UIDd;1;0E;D;K;6;CP$UIDd;2;68E;D;K;6;CP$UIDd;1;0E;D;K;6;CP$UIDd;2;69E;D;K;6;CP$UIDd;1;0E;D;K;6;CP$UIDd;2;70E;D;K;6;CP$UIDd;2;71E;D;K;6;CP$UIDd;2;72E;D;K;6;CP$UIDd;1;0E;D;K;6;CP$UIDd;2;73E;D;K;6;CP$UIDd;1;0E;D;K;6;CP$UIDd;2;74E;D;K;6;CP$UIDd;1;0E;D;K;6;CP$UIDd;2;75E;D;K;6;CP$UIDd;1;0E;E;E;D;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;2;11E;D;K;6;CP$UIDd;2;11E;D;K;6;CP$UIDd;2;11E;D;K;6;CP$UIDd;2;32E;D;K;6;CP$UIDd;2;34E;D;K;6;CP$UIDd;2;36E;D;K;6;CP$UIDd;2;34E;D;K;6;CP$UIDd;2;37E;D;K;6;CP$UIDd;2;34E;D;K;6;CP$UIDd;2;38E;D;K;6;CP$UIDd;2;34E;D;K;6;CP$UIDd;2;39E;D;K;6;CP$UIDd;2;34E;D;K;6;CP$UIDd;2;40E;D;K;6;CP$UIDd;2;11E;D;K;6;CP$UIDd;2;41E;D;K;6;CP$UIDd;2;42E;D;K;6;CP$UIDd;2;43E;D;K;6;CP$UIDd;2;42E;D;K;6;CP$UIDd;2;44E;D;K;6;CP$UIDd;2;42E;D;K;6;CP$UIDd;2;45E;D;K;6;CP$UIDd;2;42E;D;K;6;CP$UIDd;2;46E;D;K;6;CP$UIDd;2;42E;D;K;6;CP$UIDd;2;47E;D;K;6;CP$UIDd;2;11E;D;K;6;CP$UIDd;2;48E;D;K;6;CP$UIDd;2;49E;D;K;6;CP$UIDd;2;50E;D;K;6;CP$UIDd;2;49E;D;K;6;CP$UIDd;2;51E;D;K;6;CP$UIDd;2;49E;D;K;6;CP$UIDd;2;52E;D;K;6;CP$UIDd;2;49E;D;K;6;CP$UIDd;2;53E;D;K;6;CP$UIDd;2;49E;D;K;6;CP$UIDd;2;54E;D;K;6;CP$UIDd;2;11E;D;K;6;CP$UIDd;2;55E;D;K;6;CP$UIDd;2;56E;D;K;6;CP$UIDd;2;57E;D;K;6;CP$UIDd;2;56E;D;K;6;CP$UIDd;2;58E;D;K;6;CP$UIDd;2;56E;D;K;6;CP$UIDd;2;59E;D;K;6;CP$UIDd;2;56E;D;K;6;CP$UIDd;2;60E;D;K;6;CP$UIDd;2;56E;D;K;6;CP$UIDd;2;61E;D;K;6;CP$UIDd;2;11E;D;K;6;CP$UIDd;2;62E;D;K;6;CP$UIDd;2;63E;D;K;6;CP$UIDd;2;64E;D;K;6;CP$UIDd;2;63E;D;K;6;CP$UIDd;2;65E;D;K;6;CP$UIDd;2;63E;D;K;6;CP$UIDd;2;66E;D;K;6;CP$UIDd;2;63E;D;K;6;CP$UIDd;2;68E;D;K;6;CP$UIDd;2;63E;D;K;6;CP$UIDd;2;69E;D;K;6;CP$UIDd;2;11E;D;K;6;CP$UIDd;2;70E;D;K;6;CP$UIDd;2;71E;D;K;6;CP$UIDd;2;72E;D;K;6;CP$UIDd;2;71E;D;K;6;CP$UIDd;2;73E;D;K;6;CP$UIDd;2;71E;D;K;6;CP$UIDd;2;74E;D;K;6;CP$UIDd;2;71E;D;K;6;CP$UIDd;2;75E;E;E;D;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;E;E;D;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;E;E;D;K;10;$classnameS;18;_CPCibCustomObjectK;8;$classesA;S;18;_CPCibCustomObjectS;8;CPObjectE;E;D;K;6;$classD;K;6;CP$UIDd;2;10E;K;27;_CPCibCustomObjectClassNameD;K;6;CP$UIDd;2;76E;E;D;K;10;$classnameS;5;CPSetK;8;$classesA;S;5;CPSetS;8;CPObjectE;E;D;K;6;$classD;K;6;CP$UIDd;2;12E;K;15;CPSetObjectsKeyD;K;6;CP$UIDd;2;77E;E;D;K;10;$classnameS;20;CPCibOutletConnectorK;8;$classesA;S;20;CPCibOutletConnectorS;14;CPCibConnectorS;8;CPObjectE;E;D;K;6;$classD;K;6;CP$UIDd;2;14E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;2;11E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;2;30E;K;23;_CPCibConnectorLabelKeyLine truncated
280NPLIST;1.0;D;K;4;$topD;K;18;CPCibObjectDataKeyD;K;6;CP$UIDd;1;2E;E;K;8;$objectsA;S;5;$nullD;K;10;$classnameS;16;_CPCibObjectDataK;8;$classesA;S;16;_CPCibObjectDataS;8;CPObjectE;E;D;K;6;$classD;K;6;CP$UIDd;1;1E;K;28;_CPCibObjectDataNamesKeysKeyD;K;6;CP$UIDd;1;0E;K;30;_CPCibObjectDataNamesValuesKeyD;K;6;CP$UIDd;1;0E;K;30;_CPCibObjectDataClassesKeysKeyD;K;6;CP$UIDd;1;0E;K;32;_CPCibObjectDataClassesValuesKeyD;K;6;CP$UIDd;1;0E;K;30;_CPCibObjectDataConnectionsKeyD;K;6;CP$UIDd;1;4E;K;28;_CPCibObjectDataFrameworkKeyD;K;6;CP$UIDd;1;0E;K;26;_CPCibObjectDataNextOidKeyD;K;6;CP$UIDd;1;5E;K;30;_CPCibObjectDataObjectsKeysKeyD;K;6;CP$UIDd;1;6E;K;32;_CPCibObjectDataObjectsValuesKeyD;K;6;CP$UIDd;1;7E;K;26;_CPCibObjectDataOidKeysKeyD;K;6;CP$UIDd;1;8E;K;28;_CPCibObjectDataOidValuesKeyD;K;6;CP$UIDd;1;9E;K;28;_CPCibObjectDataFileOwnerKeyD;K;6;CP$UIDd;2;11E;K;33;_CPCibObjectDataVisibleWindowsKeyD;K;6;CP$UIDd;2;13E;E;D;K;10;$classnameS;7;CPArrayK;8;$classesA;S;7;CPArrayS;8;CPObjectE;E;D;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;2;15E;D;K;6;CP$UIDd;2;16E;D;K;6;CP$UIDd;2;17E;D;K;6;CP$UIDd;2;18E;D;K;6;CP$UIDd;2;19E;D;K;6;CP$UIDd;2;20E;D;K;6;CP$UIDd;2;21E;D;K;6;CP$UIDd;2;22E;D;K;6;CP$UIDd;2;23E;D;K;6;CP$UIDd;2;24E;D;K;6;CP$UIDd;2;26E;D;K;6;CP$UIDd;2;27E;D;K;6;CP$UIDd;2;28E;E;E;D;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;E;E;D;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;2;29E;D;K;6;CP$UIDd;2;30E;D;K;6;CP$UIDd;2;32E;D;K;6;CP$UIDd;2;34E;D;K;6;CP$UIDd;2;36E;D;K;6;CP$UIDd;1;0E;D;K;6;CP$UIDd;2;37E;D;K;6;CP$UIDd;1;0E;D;K;6;CP$UIDd;2;38E;D;K;6;CP$UIDd;1;0E;D;K;6;CP$UIDd;2;39E;D;K;6;CP$UIDd;1;0E;D;K;6;CP$UIDd;2;40E;D;K;6;CP$UIDd;1;0E;D;K;6;CP$UIDd;2;41E;D;K;6;CP$UIDd;2;42E;D;K;6;CP$UIDd;2;43E;D;K;6;CP$UIDd;1;0E;D;K;6;CP$UIDd;2;44E;D;K;6;CP$UIDd;1;0E;D;K;6;CP$UIDd;2;45E;D;K;6;CP$UIDd;1;0E;D;K;6;CP$UIDd;2;46E;D;K;6;CP$UIDd;1;0E;D;K;6;CP$UIDd;2;47E;D;K;6;CP$UIDd;1;0E;D;K;6;CP$UIDd;2;48E;D;K;6;CP$UIDd;2;49E;D;K;6;CP$UIDd;2;50E;D;K;6;CP$UIDd;1;0E;D;K;6;CP$UIDd;2;51E;D;K;6;CP$UIDd;1;0E;D;K;6;CP$UIDd;2;52E;D;K;6;CP$UIDd;1;0E;D;K;6;CP$UIDd;2;53E;D;K;6;CP$UIDd;1;0E;D;K;6;CP$UIDd;2;54E;D;K;6;CP$UIDd;1;0E;D;K;6;CP$UIDd;2;55E;D;K;6;CP$UIDd;2;56E;D;K;6;CP$UIDd;2;57E;D;K;6;CP$UIDd;1;0E;D;K;6;CP$UIDd;2;58E;D;K;6;CP$UIDd;1;0E;D;K;6;CP$UIDd;2;59E;D;K;6;CP$UIDd;1;0E;D;K;6;CP$UIDd;2;60E;D;K;6;CP$UIDd;1;0E;D;K;6;CP$UIDd;2;61E;D;K;6;CP$UIDd;1;0E;D;K;6;CP$UIDd;2;62E;D;K;6;CP$UIDd;2;63E;D;K;6;CP$UIDd;2;64E;D;K;6;CP$UIDd;1;0E;D;K;6;CP$UIDd;2;65E;D;K;6;CP$UIDd;1;0E;D;K;6;CP$UIDd;2;66E;D;K;6;CP$UIDd;1;0E;D;K;6;CP$UIDd;2;68E;D;K;6;CP$UIDd;1;0E;D;K;6;CP$UIDd;2;69E;D;K;6;CP$UIDd;1;0E;D;K;6;CP$UIDd;2;70E;D;K;6;CP$UIDd;2;71E;D;K;6;CP$UIDd;2;72E;D;K;6;CP$UIDd;1;0E;D;K;6;CP$UIDd;2;73E;D;K;6;CP$UIDd;1;0E;D;K;6;CP$UIDd;2;74E;D;K;6;CP$UIDd;1;0E;D;K;6;CP$UIDd;2;75E;D;K;6;CP$UIDd;1;0E;E;E;D;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;2;11E;D;K;6;CP$UIDd;2;11E;D;K;6;CP$UIDd;2;11E;D;K;6;CP$UIDd;2;32E;D;K;6;CP$UIDd;2;34E;D;K;6;CP$UIDd;2;36E;D;K;6;CP$UIDd;2;34E;D;K;6;CP$UIDd;2;37E;D;K;6;CP$UIDd;2;34E;D;K;6;CP$UIDd;2;38E;D;K;6;CP$UIDd;2;34E;D;K;6;CP$UIDd;2;39E;D;K;6;CP$UIDd;2;34E;D;K;6;CP$UIDd;2;40E;D;K;6;CP$UIDd;2;11E;D;K;6;CP$UIDd;2;41E;D;K;6;CP$UIDd;2;42E;D;K;6;CP$UIDd;2;43E;D;K;6;CP$UIDd;2;42E;D;K;6;CP$UIDd;2;44E;D;K;6;CP$UIDd;2;42E;D;K;6;CP$UIDd;2;45E;D;K;6;CP$UIDd;2;42E;D;K;6;CP$UIDd;2;46E;D;K;6;CP$UIDd;2;42E;D;K;6;CP$UIDd;2;47E;D;K;6;CP$UIDd;2;11E;D;K;6;CP$UIDd;2;48E;D;K;6;CP$UIDd;2;49E;D;K;6;CP$UIDd;2;50E;D;K;6;CP$UIDd;2;49E;D;K;6;CP$UIDd;2;51E;D;K;6;CP$UIDd;2;49E;D;K;6;CP$UIDd;2;52E;D;K;6;CP$UIDd;2;49E;D;K;6;CP$UIDd;2;53E;D;K;6;CP$UIDd;2;49E;D;K;6;CP$UIDd;2;54E;D;K;6;CP$UIDd;2;11E;D;K;6;CP$UIDd;2;55E;D;K;6;CP$UIDd;2;56E;D;K;6;CP$UIDd;2;57E;D;K;6;CP$UIDd;2;56E;D;K;6;CP$UIDd;2;58E;D;K;6;CP$UIDd;2;56E;D;K;6;CP$UIDd;2;59E;D;K;6;CP$UIDd;2;56E;D;K;6;CP$UIDd;2;60E;D;K;6;CP$UIDd;2;56E;D;K;6;CP$UIDd;2;61E;D;K;6;CP$UIDd;2;11E;D;K;6;CP$UIDd;2;62E;D;K;6;CP$UIDd;2;63E;D;K;6;CP$UIDd;2;64E;D;K;6;CP$UIDd;2;63E;D;K;6;CP$UIDd;2;65E;D;K;6;CP$UIDd;2;63E;D;K;6;CP$UIDd;2;66E;D;K;6;CP$UIDd;2;63E;D;K;6;CP$UIDd;2;68E;D;K;6;CP$UIDd;2;63E;D;K;6;CP$UIDd;2;69E;D;K;6;CP$UIDd;2;11E;D;K;6;CP$UIDd;2;70E;D;K;6;CP$UIDd;2;71E;D;K;6;CP$UIDd;2;72E;D;K;6;CP$UIDd;2;71E;D;K;6;CP$UIDd;2;73E;D;K;6;CP$UIDd;2;71E;D;K;6;CP$UIDd;2;74E;D;K;6;CP$UIDd;2;71E;D;K;6;CP$UIDd;2;75E;E;E;D;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;E;E;D;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;E;E;D;K;10;$classnameS;18;_CPCibCustomObjectK;8;$classesA;S;18;_CPCibCustomObjectS;8;CPObjectE;E;D;K;6;$classD;K;6;CP$UIDd;2;10E;K;27;_CPCibCustomObjectClassNameD;K;6;CP$UIDd;2;76E;E;D;K;10;$classnameS;5;CPSetK;8;$classesA;S;5;CPSetS;8;CPObjectE;E;D;K;6;$classD;K;6;CP$UIDd;2;12E;K;15;CPSetObjectsKeyD;K;6;CP$UIDd;2;77E;E;D;K;10;$classnameS;20;CPCibOutletConnectorK;8;$classesA;S;20;CPCibOutletConnectorS;14;CPCibConnectorS;8;CPObjectE;E;D;K;6;$classD;K;6;CP$UIDd;2;14E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;2;11E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;2;30E;K;23;_CPCibConnectorLabelKeyLine truncated
@@ -878,11 +878,11 @@
</object>
<object class="IBConnectionRecord">
<object class="IBOutletConnection" key="connection">
<string key="label">customNoInitial</string>
<string key="label">keyWindow</string>
<reference key="source" ref="635946545"/>
<reference key="destination" ref="561821772"/>
</object>
<int key="connectionID">736</int>
<int key="connectionID">783</int>
</object>
<object class="IBConnectionRecord">
<object class="IBOutletConnection" key="connection">
@@ -1751,7 +1751,7 @@
<reference key="dict.values" ref="0"/>
</object>
<nil key="sourceID"/>
<int key="maxID">779</int>
<int key="maxID">783</int>
</object>
<object class="IBClassDescriber" key="IBDocument.Classes">
<object class="NSMutableArray" key="referencedPartialClassDescriptions">
@@ -1760,13 +1760,13 @@
<string key="className">AppController</string>
<string key="superclassName">NSObject</string>
<object class="NSMutableDictionary" key="outlets">
<string key="NS.key.0">customNoInitial</string>
<string key="NS.key.0">keyWindow</string>
<string key="NS.object.0">NSWindow</string>
</object>
<object class="NSMutableDictionary" key="toOneOutletInfosByName">
<string key="NS.key.0">customNoInitial</string>
<string key="NS.key.0">keyWindow</string>
<object class="IBToOneOutletInfo" key="NS.object.0">
<string key="name">customNoInitial</string>
<string key="name">keyWindow</string>
<string key="candidateClassName">NSWindow</string>
</object>
</object>