diff --git a/AppKit/AppKit.j b/AppKit/AppKit.j index f9b0e4d72..84fc150c9 100644 --- a/AppKit/AppKit.j +++ b/AppKit/AppKit.j @@ -103,6 +103,7 @@ @import "CPTokenField.j" @import "CPToolbar.j" @import "CPToolbarItem.j" +@import "CPTrackingArea.j" @import "CPTreeNode.j" @import "CPUserDefaultsController.j" @import "CPView.j" diff --git a/AppKit/CPControl.j b/AppKit/CPControl.j index 8c7ea8958..26aaca67d 100644 --- a/AppKit/CPControl.j +++ b/AppKit/CPControl.j @@ -27,6 +27,7 @@ @import "CPShadow.j" @import "CPView.j" @import "CPKeyValueBinding.j" +@import "CPTrackingArea.j" @global CPApp @@ -200,7 +201,6 @@ var CPControlBlackColor = [CPColor blackColor]; return self; } - #pragma mark - #pragma mark Control Size @@ -1056,6 +1056,19 @@ var CPControlBlackColor = [CPColor blackColor]; @end +@implementation CPControl (CPTrackingArea) + +- (void)updateTrackingAreas +{ + [self removeAllTrackingAreas]; + [self addTrackingArea:[[CPTrackingArea alloc] initWithRect:CGRectMakeZero() + options:CPTrackingMouseEnteredAndExited | CPTrackingActiveInKeyWindow | CPTrackingInVisibleRect + owner:self + userInfo:nil]]; +} + +@end + var CPControlActionKey = @"CPControlActionKey", CPControlControlSizeKey = @"CPControlControlSizeKey", CPControlControlStateKey = @"CPControlControlStateKey", diff --git a/AppKit/CPCursor.j b/AppKit/CPCursor.j index 6e0b36cff..57f3039c6 100755 --- a/AppKit/CPCursor.j +++ b/AppKit/CPCursor.j @@ -123,6 +123,9 @@ var currentCursor = nil, - (void)set { + if (currentCursor === self) + return; + currentCursor = self; #if PLATFORM(DOM) diff --git a/AppKit/CPEvent.j b/AppKit/CPEvent.j index 1189ad962..66837649d 100644 --- a/AppKit/CPEvent.j +++ b/AppKit/CPEvent.j @@ -29,6 +29,7 @@ @import "CPCompatibility.j" @import "CGGeometry.j" @import "CPText.j" +@import "CPTrackingArea.j" @class CPTextField @class CPWindow @@ -82,6 +83,8 @@ var _CPEventPeriodicEventPeriod = 0, BOOL _suppressCappuccinoCut; BOOL _suppressCappuccinoPaste; #endif + + CPTrackingArea _trackingArea; } /*! @@ -141,6 +144,27 @@ var _CPEventPeriodicEventPeriod = 0, timestamp:aTimestamp windowNumber:aWindowNumber context:aGraphicsContext eventNumber:anEventNumber clickCount:aClickCount pressure:aPressure]; } +/*! + Creates a new mouse tracking event. + + @param anEventType the event type + @param aPoint the location of the cursor in the window specified by \c aWindowNumber + @param modifierFlags a bitwise combination of the modifiers specified in the CPEvent globals + @param aTimestamp the time the event occurred + @param aWindowNumber the number of the CPWindow where the event occurred + @param aGraphicsContext the graphics context where the event occurred + @param anEventNumber a number for this event + @param aTrackingArea the tracking area that triggered the event + @throws CPInternalInconsistencyException if an invalid event type is provided + @return the new mouse event + */ ++ (id)enterExitEventWithType:(CPEventType)anEventType location:(CGPoint)aPoint modifierFlags:(unsigned)modifierFlags + timestamp:(CPTimeInterval)aTimestamp windowNumber:(int)aWindowNumber context:(CPGraphicsContext)aGraphicsContext + eventNumber:(int)anEventNumber trackingArea:(CPTrackingArea)aTrackingArea +{ + return [[self alloc] _initEnterExitEventWithType:anEventType location:aPoint modifierFlags:modifierFlags timestamp:aTimestamp windowNumber:aWindowNumber context:aGraphicsContext eventNumber:anEventNumber trackingArea:aTrackingArea]; +} + /*! Creates a new custom event. @@ -201,6 +225,28 @@ var _CPEventPeriodicEventPeriod = 0, return self; } +/* @ignore */ +- (id)_initEnterExitEventWithType:(CPEventType)anEventType location:(CGPoint)aPoint modifierFlags:(unsigned)modifierFlags + timestamp:(CPTimeInterval)aTimestamp windowNumber:(int)aWindowNumber context:(CPGraphicsContext)aGraphicsContext + eventNumber:(int)anEventNumber trackingArea:(CPTrackingArea)aTrackingArea +{ + if ((anEventType != CPMouseEntered) && (anEventType != CPMouseExited) && (anEventType != CPCursorUpdate)) + [CPException raise:CPInternalInconsistencyException reason:"Invalid event type"]; + + if (self = [self _initWithType:anEventType]) + { + _location = CGPointCreateCopy(aPoint); + _modifierFlags = modifierFlags; + _timestamp = aTimestamp; + _context = aGraphicsContext; + _eventNumber = anEventNumber; + _trackingArea = aTrackingArea; + _window = [CPApp windowWithWindowNumber:aWindowNumber]; + } + + return self; +} + /* @ignore */ - (id)_initKeyEventWithType:(CPEventType)anEventType location:(CGPoint)aPoint modifierFlags:(unsigned int)modifierFlags timestamp:(CPTimeInterval)aTimestamp windowNumber:(int)aWindowNumber context:(CPGraphicsContext)aGraphicsContext @@ -583,6 +629,14 @@ var _CPEventPeriodicEventPeriod = 0, } } +- (CPTrackingArea)trackingArea +{ + if ((_type !== CPMouseEntered) && (_type !== CPMouseExited) && (_type !== CPCursorUpdate)) + [CPException raise:CPInternalInconsistencyException format:@"You can't call trackingArea for events of type %#x", _type] + + return _trackingArea; +} + @end function _CPEventFirePeriodEvent() diff --git a/AppKit/CPResponder.j b/AppKit/CPResponder.j index eddf8b628..eb1bc841c 100644 --- a/AppKit/CPResponder.j +++ b/AppKit/CPResponder.j @@ -24,6 +24,7 @@ @import @import "CPEvent.j" +@import "CPCursor.j" @class CPKeyBinding @class CPMenu @@ -200,6 +201,18 @@ CPDeleteForwardKeyCode = 46; [_nextResponder performSelector:_cmd withObject:anEvent]; } +/*! + Notifies the receiver that the mouse entered the receiver's area and that it can adapt the cursor. + @param anEvent contains information about the exit + */ +- (void)cursorUpdate:(CPEvent)anEvent +{ + if (_nextResponder) + [_nextResponder performSelector:_cmd withObject:anEvent]; + else + [[CPCursor arrowCursor] set]; +} + /*! Notifies the receiver that the mouse scroll wheel has moved. @param anEvent information about the scroll diff --git a/AppKit/CPSplitView.j b/AppKit/CPSplitView.j index e10c67e8d..0bd1043ed 100644 --- a/AppKit/CPSplitView.j +++ b/AppKit/CPSplitView.j @@ -26,6 +26,7 @@ @import "CPImage.j" @import "CPView.j" @import "CPCursor.j" +@import "CPTrackingArea.j" @class CPUserDefaults @global CPApp @@ -562,26 +563,6 @@ var ShouldSuppressResizeNotifications = 1, //[[self window] setAcceptsMouseMovedEvents:YES]; } -- (void)mouseEntered:(CPEvent)anEvent -{ - // Tracking code handles cursor by itself. - if (_currentDivider == CPNotFound) - [self _updateResizeCursor:anEvent]; -} - -- (void)mouseMoved:(CPEvent)anEvent -{ - if (_currentDivider == CPNotFound) - [self _updateResizeCursor:anEvent]; -} - -- (void)mouseExited:(CPEvent)anEvent -{ - if (_currentDivider == CPNotFound) - // FIXME: we should use CPCursor push/pop (if previous currentCursor != arrow). - [[CPCursor arrowCursor] set]; -} - - (void)_updateResizeCursor:(CPEvent)anEvent { var point = [self convertPoint:[anEvent locationInWindow] fromView:nil]; @@ -1205,6 +1186,29 @@ The sum of the views and the sum of the dividers should be equal to the size of @end +@implementation CPSplitView (CPTrackingArea) + +- (void)updateTrackingAreas +{ + [self removeAllTrackingAreas]; + + var options = CPTrackingCursorUpdate | CPTrackingActiveInKeyWindow; + + for (var i = 0; i < _subviews.length - 1; i++) + [self addTrackingArea:[[CPTrackingArea alloc] initWithRect:[self effectiveRectOfDividerAtIndex:i] + options:options + owner:self + userInfo:nil]]; +} + +- (void)cursorUpdate:(CPEvent)anEvent +{ + if (_currentDivider === CPNotFound) + [self _updateResizeCursor:anEvent]; +} + +@end + @implementation CPSplitView (CPSplitViewDelegate) @@ -1376,6 +1380,8 @@ The sum of the views and the sum of the dividers should be equal to the size of [_delegate splitViewDidResizeSubviews:[[CPNotification alloc] initWithName:CPSplitViewDidResizeSubviewsNotification object:self userInfo:userInfo]]; [[CPNotificationCenter defaultCenter] postNotificationName:CPSplitViewDidResizeSubviewsNotification object:self userInfo:userInfo]; + + [self updateTrackingAreas]; } @end diff --git a/AppKit/CPTableHeaderView.j b/AppKit/CPTableHeaderView.j index 3c4532d2c..58f5cb152 100644 --- a/AppKit/CPTableHeaderView.j +++ b/AppKit/CPTableHeaderView.j @@ -24,6 +24,7 @@ @import "CPView.j" @import "CPCursor.j" @import "_CPImageAndTextView.j" +@import "CPTrackingArea.j" @class CPTableView @@ -305,7 +306,9 @@ var CPTableHeaderViewResizeZone = 3.0, self = [super initWithFrame:aFrame]; if (self) + { [self _init]; + } return self; } @@ -456,34 +459,26 @@ var CPTableHeaderViewResizeZone = 3.0, _activeColumn = -1; } -- (void)mouseEntered:(CPEvent)theEvent +@end + +@implementation CPTableHeaderView (CPTrackingArea) + +- (void)updateTrackingAreas { - var location = [theEvent globalLocation]; - - if (CGPointEqualToPoint(location, _mouseEnterExitLocation)) - return; - - _mouseEnterExitLocation = location; - - [self _updateResizeCursor:theEvent]; + [self removeAllTrackingAreas]; + + var options = CPTrackingCursorUpdate | CPTrackingActiveInKeyWindow; + + for (var i = 0; i < _tableView._tableColumns.length; i++) + [self addTrackingArea:[[CPTrackingArea alloc] initWithRect:[self _cursorRectForColumn:i] + options:options + owner:self + userInfo:nil]]; } -- (void)mouseMoved:(CPEvent)theEvent +- (void)cursorUpdate:(CPEvent)anEvent { - [self _updateResizeCursor:theEvent]; -} - -- (void)mouseExited:(CPEvent)theEvent -{ - var location = [theEvent globalLocation]; - - if (CGPointEqualToPoint(location, _mouseEnterExitLocation)) - return; - - _mouseEnterExitLocation = location; - - // FIXME: we should use CPCursor push/pop (if previous currentCursor != arrow). - [[CPCursor arrowCursor] set]; + [self _updateResizeCursor:anEvent]; } @end @@ -697,6 +692,7 @@ var CPTableHeaderViewResizeZone = 3.0, [[_tableView headerView] setNeedsLayout]; [[CPCursor arrowCursor] set]; + [self updateTrackingAreas]; } - (BOOL)_shouldResizeTableColumn:(CPInteger)aColumnIndex at:(CGPoint)aPoint @@ -762,7 +758,10 @@ var CPTableHeaderViewResizeZone = 3.0, var tableColumn = [[_tableView tableColumns] objectAtIndex:aColumnIndex]; if ([tableColumn width] != _columnOldWidth) + { [_tableView _didResizeTableColumn:tableColumn oldWidth:_columnOldWidth]; + [self updateTrackingAreas]; + } [tableColumn setDisableResizingPosting:NO]; [_tableView setDisableAutomaticResizing:NO]; @@ -772,13 +771,6 @@ var CPTableHeaderViewResizeZone = 3.0, - (void)_updateResizeCursor:(CPEvent)theEvent { - // never get stuck in resize cursor mode (FIXME take out when we turn on tracking rects) - if (![_tableView allowsColumnResizing] || ([theEvent type] === CPLeftMouseUp && ![[self window] acceptsMouseMovedEvents])) - { - [[CPCursor arrowCursor] set]; - return; - } - var mouseLocation = [self convertPoint:[theEvent locationInWindow] fromView:nil], mouseOverLocation = CGPointMake(MAX(mouseLocation.x - CPTableHeaderViewResizeZone, 0.0), mouseLocation.y), overColumn = [self columnAtPoint:mouseOverLocation]; diff --git a/AppKit/CPTrackingArea.j b/AppKit/CPTrackingArea.j new file mode 100644 index 000000000..9e41afef4 --- /dev/null +++ b/AppKit/CPTrackingArea.j @@ -0,0 +1,164 @@ +/* + * CPTrackingArea.j + * AppKit + * + * Created by Didier Korthoudt. + * Copyright 2015, Cappuccino Project. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +@import + +@class CPView + +/* @group CPTrackingAreaOptions */ +@typedef CPTrackingAreaOptions +CPTrackingMouseEnteredAndExited = 1 << 1; +CPTrackingMouseMoved = 1 << 2; +CPTrackingCursorUpdate = 1 << 3; +CPTrackingActiveWhenFirstResponder = 1 << 4; +CPTrackingActiveInKeyWindow = 1 << 5; +CPTrackingActiveInActiveApp = 1 << 6; +CPTrackingActiveAlways = 1 << 7; +CPTrackingAssumeInside = 1 << 8; +CPTrackingInVisibleRect = 1 << 9; +CPTrackingEnabledDuringMouseDrag = 1 << 10; + +var CPTrackingAreaViewRectKey = @"CPTrackinkAreaViewRectKey", + CPTrackingAreaOptionsKey = @"CPTrackingAreaOptionsKey", + CPTrackingAreaOwnerKey = @"CPTrackingAreaOwnerKey", + CPTrackingAreaUserInfoKey = @"CPTrackingAreaUserInfoKey", + CPTrackingAreaReferencingViewKey = @"CPTrackingAreaReferencingViewKey", + CPTrackingAreaWindowRect = @"CPTrackingAreaWindowRect"; + +CPTrackingOwnerImplementsMouseEntered = 1 << 1; +CPTrackingOwnerImplementsMouseExited = 1 << 2; +CPTrackingOwnerImplementsMouseMoved = 1 << 3; +CPTrackingOwnerImplementsCursorUpdate = 1 << 4; + +/*! + @ingroup appkit + + A CPTrackingArea defines a region of view that generates mouse-tracking and + cursor-update events when the mouse is over that region. + */ +@implementation CPTrackingArea : CPObject +{ + CGRect _viewRect @accessors(getter=rect); + CPTrackingAreaOptions _options @accessors(getter=options); + id _owner @accessors(getter=owner); + CPDictionary _userInfo @accessors(getter=userInfo); + + CPView _referencingView @accessors(property=view); + CGRect _windowRect @accessors(getter=windowRect); + + unsigned _implementedOwnerMethods @accessors(getter=implementedOwnerMethods); +} + + +#pragma mark - +#pragma mark Initialization + +/*! + Initializes and returns an object defining a region of a view to receive mouse-tracking events, mouse-moved events, cursor-update events, or possibly + all these events. + */ +- (CPTrackingArea)initWithRect:(CGRect)aRect options:(CPTrackingAreaOptions)options owner:(id)owner userInfo:(CPDictionary)userInfo +{ + if (owner === nil) + [CPException raise:CPInternalInconsistencyException reason:"No owner specified"]; + + if (options === 0) + [CPException raise:CPInternalInconsistencyException reason:"Invalid CPTrackingArea options"]; + + // Check options: + // - at least one of CPTrackingMouseEnteredAndExited, CPTrackingMouseMoved, CPTrackingCursorUpdate + // - exactly one of CPTrackingActiveWhenFirstResponder, CPTrackingActiveInKeyWindow, CPTrackingActiveInActiveApp, CPTrackingActiveAlways + // - no check on CPTrackingAssumeInside, CPTrackingInVisibleRect, CPTrackingEnableDuringMouseDrag + + if (!((options & CPTrackingMouseEnteredAndExited) || (options & CPTrackingMouseMoved) || (options & CPTrackingCursorUpdate))) + [CPException raise:CPInternalInconsistencyException reason:"Invalid CPTrackingAreaOptions: must use at least one of [CPTrackingMouseEnteredAndExited | CPTrackingMouseMoved | CPTrackingCursorUpdate]"]; + + if ((((options & CPTrackingActiveWhenFirstResponder) > 0) + ((options & CPTrackingActiveInKeyWindow) > 0) + ((options & CPTrackingActiveInActiveApp) > 0) + ((options & CPTrackingActiveAlways) > 0)) !== 1) + [CPException raise:CPInternalInconsistencyException reason:"Tracking area options may only specify one of [CPTrackingActiveWhenFirstResponder | CPTrackingActiveInKeyWindow | CPTrackingActiveInActiveApp | CPTrackingActiveAlways]."]; + + if (self = [super init]) + { + _viewRect = aRect; + _options = options; + _owner = owner; + _userInfo = userInfo; + + // Cache owner implemented methods + + if ([_owner respondsToSelector:@selector(mouseEntered:)]) + _implementedOwnerMethods |= CPTrackingOwnerImplementsMouseEntered; + + if ([_owner respondsToSelector:@selector(mouseExited:)]) + _implementedOwnerMethods |= CPTrackingOwnerImplementsMouseExited; + + if ([_owner respondsToSelector:@selector(mouseMoved:)]) + _implementedOwnerMethods |= CPTrackingOwnerImplementsMouseMoved; + + if ([_owner respondsToSelector:@selector(cursorUpdate:)]) + _implementedOwnerMethods |= CPTrackingOwnerImplementsCursorUpdate; + } + + return self; +} + + +#pragma mark - +#pragma mark Implementation + +- (void)_updateWindowRect +{ + _windowRect = [_referencingView convertRect:((_options & CPTrackingInVisibleRect) ? [_referencingView visibleRect] : _viewRect) toView:[[_referencingView window] _windowView]]; +} + +@end + +#pragma mark - +#pragma mark CPCoding + +@implementation CPTrackingArea (CPCoding) + +- (id)initWithCoder:(CPCoder)aCoder +{ + if (self = [super init]) + { + _viewRect = [aCoder decodeObjectForKey:CPTrackingAreaViewRectKey]; + _options = [aCoder decodeObjectForKey:CPTrackingAreaOptionsKey]; + _owner = [aCoder decodeObjectForKey:CPTrackingAreaOwnerKey]; + _userInfo = [aCoder decodeObjectForKey:CPTrackingAreaUserInfoKey]; + _referencingView = [aCoder decodeObjectForKey:CPTrackingAreaReferencingViewKey]; + _windowRect = [aCoder decodeObjectForKey:CPTrackingAreaWindowRect]; + } + + return self; +} + +- (void)encodeWithCoder:(CPCoder)aCoder +{ + [aCoder encodeObject:_viewRect forKey:CPTrackingAreaViewRectKey]; + [aCoder encodeObject:_options forKey:CPTrackingAreaOptionsKey]; + [aCoder encodeObject:_owner forKey:CPTrackingAreaOwnerKey]; + [aCoder encodeObject:_userInfo forKey:CPTrackingAreaUserInfoKey]; + [aCoder encodeObject:_referencingView forKey:CPTrackingAreaReferencingViewKey]; + [aCoder encodeObject:_windowRect forKey:CPTrackingAreaWindowRect]; +} + +@end diff --git a/AppKit/CPView.j b/AppKit/CPView.j index 3041765a7..5b8d66007 100644 --- a/AppKit/CPView.j +++ b/AppKit/CPView.j @@ -32,6 +32,7 @@ @import "CPGraphicsContext.j" @import "CPResponder.j" @import "CPTheme.j" +@import "CPTrackingArea.j" @import "CPWindow_Constants.j" @import "_CPDisplayServer.j" @@ -239,6 +240,9 @@ var CPViewHighDPIDrawingEnabled = YES; BOOL _allowsVibrancy @accessors(property=allowsVibrancy); CPAppearance _appearance @accessors(getter=appearance); CPAppearance _effectiveAppearance; + + CPMutableArray _trackingAreas @accessors(getter=trackingAreas, copy); + BOOL _inhibitUpdateTrackingAreas; } /* @@ -352,6 +356,8 @@ var CPViewHighDPIDrawingEnabled = YES; _registeredDraggedTypes = [CPSet set]; _registeredDraggedTypesArray = []; + _trackingAreas = []; + _tag = -1; _frame = CGRectMakeCopy(aFrame); @@ -799,8 +805,30 @@ var CPViewHighDPIDrawingEnabled = YES; [_window _noteUnregisteredDraggedTypes:_registeredDraggedTypes]; [aWindow _noteRegisteredDraggedTypes:_registeredDraggedTypes]; } + + // View must be removed from the current window viewsWithTrackingAreas + if (_window && (_trackingAreas.length > 0)) + [_window _removeTrackingAreaView:self]; _window = aWindow; + + if (_window) + { + var owners; + + if (_trackingAreas.length > 0) + { + // View must be added to the new window viewsWithTrackingAreas + [_window _addTrackingAreaView:self]; + owners = [self _calcTrackingAreaOwners]; + } + else + owners = [self]; + + // Notify that view tracking areas should be updated + // Cocoa doesn't notify on leaving a window + [self _updateTrackingAreasForOwners:owners]; + } var count = [_subviews count]; @@ -994,6 +1022,9 @@ var CPViewHighDPIDrawingEnabled = YES; if (_isSuperviewAClipView) [[self superview] viewFrameChanged:[[CPNotification alloc] initWithName:CPViewFrameDidChangeNotification object:self userInfo:nil]]; + + if (!_inhibitUpdateTrackingAreas) + [self _updateTrackingAreas]; } /*! @@ -1064,6 +1095,9 @@ var CPViewHighDPIDrawingEnabled = YES; CPDOMDisplayServerSetStyleLeftTop(_DOMElement, transform, origin.x, origin.y); #endif + + if (!_inhibitUpdateTrackingAreas && !_inhibitFrameAndBoundsChangedNotifications) + [self _updateTrackingAreas]; } /*! @@ -1215,6 +1249,9 @@ var CPViewHighDPIDrawingEnabled = YES; if (_isSuperviewAClipView && !_inhibitFrameAndBoundsChangedNotifications) [[self superview] viewFrameChanged:[[CPNotification alloc] initWithName:CPViewFrameDidChangeNotification object:self userInfo:nil]]; + + if (!_inhibitUpdateTrackingAreas && !_inhibitFrameAndBoundsChangedNotifications) + [self _updateTrackingAreas]; } /*! @@ -1261,6 +1298,9 @@ var CPViewHighDPIDrawingEnabled = YES; if (_isSuperviewAClipView) [[self superview] viewBoundsChanged:[[CPNotification alloc] initWithName:CPViewBoundsDidChangeNotification object:self userInfo:nil]]; + + if (!_inhibitUpdateTrackingAreas) + [self _updateTrackingAreas]; } /*! @@ -1326,6 +1366,9 @@ var CPViewHighDPIDrawingEnabled = YES; if (_isSuperviewAClipView && !_inhibitFrameAndBoundsChangedNotifications) [[self superview] viewBoundsChanged:[[CPNotification alloc] initWithName:CPViewBoundsDidChangeNotification object:self userInfo:nil]]; + + if (!_inhibitUpdateTrackingAreas && !_inhibitFrameAndBoundsChangedNotifications) + [self _updateTrackingAreas]; } /*! @@ -1367,6 +1410,9 @@ var CPViewHighDPIDrawingEnabled = YES; if (_isSuperviewAClipView && !_inhibitFrameAndBoundsChangedNotifications) [[self superview] viewBoundsChanged:[[CPNotification alloc] initWithName:CPViewBoundsDidChangeNotification object:self userInfo:nil]]; + + if (!_inhibitUpdateTrackingAreas && !_inhibitFrameAndBoundsChangedNotifications) + [self _updateTrackingAreas]; } @@ -3401,6 +3447,141 @@ setBoundsOrigin: */} +@end + +@implementation CPView (TrackingAreaAdditions) + +- (void)addTrackingArea:(CPTrackingArea)trackingArea +{ + // Consistency check + if (!trackingArea || [_trackingAreas containsObjectIdenticalTo:trackingArea]) + return; + + if ([trackingArea view]) + [CPException raise:CPInternalInconsistencyException reason:"Tracking area has already been added to another view."]; + + [_trackingAreas addObject:trackingArea]; + [trackingArea setView:self]; + + if (_window) + [_window _addTrackingArea:trackingArea]; + + [trackingArea _updateWindowRect]; +} + +- (void)removeTrackingArea:(CPTrackingArea)trackingArea +{ + // Consistency check + if (!trackingArea) + return; + + if (![_trackingAreas containsObjectIdenticalTo:trackingArea]) + [CPException raise:CPInternalInconsistencyException reason:"Trying to remove unreferenced trackingArea"]; + + [self _removeTrackingArea:trackingArea]; +} + +/*! + Invoked automatically when the view’s geometry changes such that its tracking areas need to be recalculated. + + You should override this method to remove out of date tracking areas and add recomputed tracking areas; + + Cocoa calls this on every view, whereas they have tracking area(s) or not. + Cappuccino behaves differently : + - updateTrackingAreas is called when placing a view in the view hierarchy (that is in a window) + - if you have only CPTrackingInVisibleRect tracking areas attached to a view, it will not be called again (until you move the view in the hierarchy) + - if you have at least one non-CPTrackingInVisibleRect tracking area attached, it will be called every time the view geometry could be modified + You don't have to touch to CPTrackingInVisibleRect tracking areas, they will be automatically updated + + Please note that it is the owner of a tracking area who is called for updateTrackingAreas. + But, if a view without any tracking area is inserted in the view hierarchy (that is, in a window), the view is called for updateTrackingAreas. + This enables you to use updateTrackingArea to initially attach your tracking areas to the view. +*/ +- (void)updateTrackingAreas +{ + +} + +/*! + This utility method is intended for CPView subclasses overriding updateTrackingAreas + + Typical use would be : + + - (void)updateTrackingAreas + { + [self removeAllTrackingAreas]; + + ... add your specific updated tracking areas ... + } + +*/ +- (void)removeAllTrackingAreas +{ + while (_trackingAreas.length > 0) + [self _removeTrackingArea:_trackingAreas[0]]; +} + +// Internal methods + +- (void)_removeTrackingArea:(CPTrackingArea)trackingArea +{ + if (_window) + [_window _removeTrackingArea:trackingArea]; + + [trackingArea setView:nil]; + [_trackingAreas removeObjectIdenticalTo:trackingArea]; +} + +- (void)_updateTrackingAreas +{ + _inhibitUpdateTrackingAreas = YES; + + [self _recursivelyUpdateTrackingAreas]; + + _inhibitUpdateTrackingAreas = NO; +} + +- (void)_recursivelyUpdateTrackingAreas +{ + [self _updateTrackingAreasForOwners:[self _calcTrackingAreaOwners]]; + + for (var i = 0; i < _subviews.length; i++) + [_subviews[i] _recursivelyUpdateTrackingAreas]; +} + +- (CPArray)_calcTrackingAreaOwners +{ + // First search all owners that must be notified + // Remark: 99.99% of time, the only owner will be the view itself + // In the same time, update the rects of InVisibleRect tracking areas + + var owners = []; + + for (var i = 0; i < _trackingAreas.length; i++) + { + var trackingArea = _trackingAreas[i]; + + if ([trackingArea options] & CPTrackingInVisibleRect) + [trackingArea _updateWindowRect]; + + else + { + var owner = [trackingArea owner]; + + if (![owners containsObjectIdenticalTo:owner]) + [owners addObject:owner]; + } + } + + return owners; +} + +- (void)_updateTrackingAreasForOwners:(CPArray)owners +{ + for (var i = 0; i < owners.length; i++) + [owners[i] updateTrackingAreas]; +} + @end var CPViewAutoresizingMaskKey = @"CPViewAutoresizingMask", @@ -3423,6 +3604,7 @@ var CPViewAutoresizingMaskKey = @"CPViewAutoresizingMask", CPViewSizeScaleKey = @"CPViewSizeScaleKey", CPViewIsScaledKey = @"CPViewIsScaledKey", CPViewAppearanceKey = @"CPViewAppearanceKey"; + CPViewTrackingAreasKey = @"CPViewTrackingAreasKey"; @implementation CPView (CPCoding) @@ -3450,6 +3632,11 @@ var CPViewAutoresizingMaskKey = @"CPViewAutoresizingMask", if (self) { + _trackingAreas = [aCoder decodeObjectForKey:CPViewTrackingAreasKey]; + + if (!_trackingAreas) + _trackingAreas = []; + // We have to manually check because it may be 0, so we can't use || _tag = [aCoder containsValueForKey:CPViewTagKey] ? [aCoder decodeIntForKey:CPViewTagKey] : -1; _identifier = [aCoder decodeObjectForKey:CPReuseIdentifierKey]; @@ -3607,6 +3794,7 @@ var CPViewAutoresizingMaskKey = @"CPViewAutoresizingMask", [aCoder encodeSize:[self _hierarchyScaleSize] forKey:CPViewSizeScaleKey]; [aCoder encodeBool:_isScaled forKey:CPViewIsScaledKey]; [aCoder encodeObject:_appearance forKey:CPViewAppearanceKey]; + [aCoder encodeObject:_trackingAreas forKey:CPViewTrackingAreasKey]; } @end diff --git a/AppKit/CPWindow/CPWindow.j b/AppKit/CPWindow/CPWindow.j index 5606fcac4..79b4b7324 100644 --- a/AppKit/CPWindow/CPWindow.j +++ b/AppKit/CPWindow/CPWindow.j @@ -36,6 +36,7 @@ @import "CPResponder.j" @import "CPScreen.j" @import "CPText.j" +@import "CPTrackingArea.j" @import "CPView.j" @import "CPWindow_Constants.j" @import "_CPBorderlessBridgeWindowView.j" @@ -198,6 +199,10 @@ var CPWindowActionMessageKeys = [ CPView _toolbarView; CPArray _mouseEnteredStack; + CPArray _cursorUpdateStack; + CPArray _trackingAreaViews; + id _activeCursorTrackingArea; + CPArray _queuedTrackingEvents; CPView _leftMouseDownView; CPView _rightMouseDownView; @@ -335,6 +340,12 @@ CPTexturedBackgroundWindowMask [self setLevel:CPNormalWindowLevel]; + _trackingAreaViews = []; + _mouseEnteredStack = []; + _cursorUpdateStack = []; + _queuedTrackingEvents = []; + _activeCursorTrackingArea = nil; + // Create our border view which is the actual root of our view hierarchy. _windowView = [[windowViewClass alloc] initWithFrame:CGRectMake(0.0, 0.0, CGRectGetWidth(_frame), CGRectGetHeight(_frame)) styleMask:aStyleMask]; @@ -557,6 +568,11 @@ CPTexturedBackgroundWindowMask } } +- (CPView)_windowView +{ + return _windowView; +} + /*! Sets the receiver as a full platform window. If you pass YES the CPWindow instance will fill the entire browser content area, otherwise the CPWindow will be a window inside of your browser window which the user can drag around, and resize (if you allow). @@ -1923,6 +1939,9 @@ CPTexturedBackgroundWindowMask _leftMouseDownView = nil; + // If mouseUp ends a drag operation, send delayed events for tracking views under the mouse, then flush delayed events + [self _flushTrackingEventQueueForMouseAt:point]; + return; case CPLeftMouseDown: @@ -1958,6 +1977,11 @@ CPTexturedBackgroundWindowMask case CPLeftMouseDragged: case CPRightMouseDragged: + // First, we search for any tracking area requesting CPTrackingEnabledDuringMouseDrag. + // At the same time, we update the entered stack. + [self _handleTrackingAreaEvent:anEvent]; + + // Normal mouseDragged workflow if (!_leftMouseDownView) return [[_windowView hitTest:point] mouseDragged:anEvent]; @@ -1976,61 +2000,12 @@ CPTexturedBackgroundWindowMask return [_leftMouseDownView performSelector:selector withObject:anEvent]; case CPMouseMoved: - [_windowView setCursorForLocation:point resizing:NO]; // Ignore mouse moves for parents of sheets if (!_acceptsMouseMovedEvents || sheet) return; - - if (!_mouseEnteredStack) - _mouseEnteredStack = []; - - var hitTestView = [_windowView hitTest:point]; - - if ([_mouseEnteredStack count] && [_mouseEnteredStack lastObject] === hitTestView) - return [hitTestView mouseMoved:anEvent]; - - var view = hitTestView, - mouseEnteredStack = []; - - while (view) - { - mouseEnteredStack.unshift(view); - - view = [view superview]; - } - - var deviation = MIN(_mouseEnteredStack.length, mouseEnteredStack.length); - - while (deviation--) - if (_mouseEnteredStack[deviation] === mouseEnteredStack[deviation]) - break; - - var index = deviation + 1, - count = _mouseEnteredStack.length; - - if (index < count) - { - var event = [CPEvent mouseEventWithType:CPMouseExited location:point modifierFlags:[anEvent modifierFlags] timestamp:[anEvent timestamp] windowNumber:_windowNumber context:nil eventNumber:-1 clickCount:1 pressure:0]; - - for (; index < count; ++index) - [_mouseEnteredStack[index] mouseExited:event]; - } - - index = deviation + 1; - count = mouseEnteredStack.length; - - if (index < count) - { - var event = [CPEvent mouseEventWithType:CPMouseEntered location:point modifierFlags:[anEvent modifierFlags] timestamp:[anEvent timestamp] windowNumber:_windowNumber context:nil eventNumber:-1 clickCount:1 pressure:0]; - - for (; index < count; ++index) - [mouseEnteredStack[index] mouseEntered:event]; - } - - _mouseEnteredStack = mouseEnteredStack; - - [hitTestView mouseMoved:anEvent]; + + [self _handleTrackingAreaEvent:anEvent]; } } @@ -3844,6 +3819,384 @@ var interpolate = function(fromValue, toValue, progress) @end +@implementation CPWindow (TrackingAreaAdditions) + +- (void)_addTrackingAreaView:(CPView)aView +{ + var trackingAreas = [aView trackingAreas]; + + for (var i = 0; i < trackingAreas.length; i++) + [self _addTrackingArea:trackingAreas[i]]; +} + +- (void)_removeTrackingAreaView:(CPView)aView +{ + var trackingAreas = [aView trackingAreas]; + + for (var i = 0; i < trackingAreas.length; i++) + [self _removeTrackingArea:trackingAreas[i]]; +} + +- (void)_addTrackingArea:(CPTrackingArea)trackingArea +{ + var trackingAreaView = [trackingArea view]; + + if (![_trackingAreaViews containsObjectIdenticalTo:trackingAreaView]) + [_trackingAreaViews addObject:trackingAreaView]; + + // If CPTrackingAssumeInside option is set, put the tracking area in the _mouseEnteredStack + + if ([trackingArea options] & CPTrackingAssumeInside) + [_mouseEnteredStack addObject:trackingArea]; +} + +- (void)_removeTrackingArea:(CPTrackingArea)trackingArea +{ + // If mouse is in the tracking area, we remove it from the stack to avoid to fire a future mouseExited event + + [_mouseEnteredStack removeObjectIdenticalTo:trackingArea]; + + var trackingAreaView = [trackingArea view]; + + [_trackingAreaViews removeObjectIdenticalTo:trackingAreaView]; +} + +- (void)_handleTrackingAreaEvent:(CPEvent)anEvent +{ + var mouseEnteredStack = [], + cursorUpdateStack = [], + point = [anEvent locationInWindow], + dragging = ([anEvent type] !== CPMouseMoved); + + // Handle mouse entering tracking areas (and calc mouseEnteredStack and cursorUpdateStack) + + [self _handleMouseMovedAndEnteredEventsForEvent:anEvent atPoint:point dragging:dragging mouseEnteredStack:mouseEnteredStack cursorUpdateStack:cursorUpdateStack]; + + // Handle mouse exiting tracking areas + + [self _handleMouseExitedEventsForEvent:anEvent atPoint:point dragging:dragging mouseEnteredStack:mouseEnteredStack]; + + // Cursor update + + if (cursorUpdateStack.length > 0) + { + [self _handleCursorUpdateEventsForEvent:anEvent atPoint:point dragging:dragging cursorUpdateStack:cursorUpdateStack]; + } + else if (!dragging) + { + // Here, we are outsite the window content view tracking area, so let _windowView set the cursor (resize cursor, ...) + + [_windowView setCursorForLocation:point resizing:NO]; + _activeCursorTrackingArea = nil; + } + + // Prepare for next call + + _mouseEnteredStack = mouseEnteredStack; + _cursorUpdateStack = cursorUpdateStack; +} + +- (void)_handleMouseMovedAndEnteredEventsForEvent:(CPEvent)anEvent atPoint:(CGPoint)point dragging:(BOOL)dragging mouseEnteredStack:(CPArray)mouseEnteredStack cursorUpdateStack:(CPArray)cursorUpdateStack +{ + var isKeyWindow = [self isKeyWindow]; + + for (var i = 0; i < _trackingAreaViews.length; i++) + { + var aView = _trackingAreaViews[i], + trackingAreas = [aView trackingAreas]; + + if ([aView isHidden]) + continue; + + for (var j = 0; j < trackingAreas.length; j++) + { + var aTrackingArea = trackingAreas[j], + trackingOptions = [aTrackingArea options], + trackingImplementedMethods = [aTrackingArea implementedOwnerMethods]; + + if (!(((trackingOptions & CPTrackingActiveAlways) || + (trackingOptions & CPTrackingActiveInActiveApp) || + ((trackingOptions & CPTrackingActiveInKeyWindow) && isKeyWindow) || + ((trackingOptions & CPTrackingActiveWhenFirstResponder) && isKeyWindow && (_firstResponder === aView))) && + (CGRectContainsPoint([aTrackingArea windowRect], point)))) + { + continue; + } + + [mouseEnteredStack addObject:aTrackingArea]; + + if ([_mouseEnteredStack containsObjectIdenticalTo:aTrackingArea]) + { + // Mouse was already in this rect so it's a mouseMoved + + if (!dragging && (trackingOptions & CPTrackingMouseMoved) && (trackingImplementedMethods & CPTrackingOwnerImplementsMouseMoved)) + [[aTrackingArea owner] mouseMoved:anEvent]; + } + else if ((trackingOptions & CPTrackingMouseEnteredAndExited) && (trackingImplementedMethods & CPTrackingOwnerImplementsMouseEntered)) + { + var mouseEnteredEvent = [CPEvent enterExitEventWithType:CPMouseEntered + location:point + modifierFlags:[anEvent modifierFlags] + timestamp:[anEvent timestamp] + windowNumber:_windowNumber + context:nil + eventNumber:-1 + trackingArea:aTrackingArea]; + + if (dragging && !(trackingOptions & CPTrackingEnabledDuringMouseDrag)) + [self _queueTrackingEvent:mouseEnteredEvent]; + else + [[aTrackingArea owner] mouseEntered:mouseEnteredEvent]; + } + + if ((trackingOptions & CPTrackingCursorUpdate) && (trackingImplementedMethods & CPTrackingOwnerImplementsCursorUpdate)) + [cursorUpdateStack addObject:aTrackingArea]; + } + } +} + +- (void)_handleMouseExitedEventsForEvent:(CPEvent)anEvent atPoint:(CGPoint)point dragging:(BOOL)dragging mouseEnteredStack:(CPArray)mouseEnteredStack +{ + // Search for exited views (were in _mouseEnteredStack but no more in mouseEnteredStack) + + for (var i = 0; i < _mouseEnteredStack.length; i++) + { + var aTrackingArea = _mouseEnteredStack[i], + trackingOptions = [aTrackingArea options]; + + if ([mouseEnteredStack containsObjectIdenticalTo:aTrackingArea]) + continue; + + // Mouse is no more in this area so it's a mouseExited + + if ((trackingOptions & CPTrackingMouseEnteredAndExited) && ([aTrackingArea implementedOwnerMethods] & CPTrackingOwnerImplementsMouseExited)) + { + var mouseExitedEvent = [CPEvent enterExitEventWithType:CPMouseExited + location:point + modifierFlags:[anEvent modifierFlags] + timestamp:[anEvent timestamp] + windowNumber:_windowNumber + context:nil + eventNumber:-1 + trackingArea:aTrackingArea]; + + if (dragging && !(trackingOptions & CPTrackingEnabledDuringMouseDrag)) + [self _queueTrackingEvent:mouseExitedEvent]; + else + [[aTrackingArea owner] mouseExited:mouseExitedEvent]; + } + + // If this is the active cursor area, we reset _cursorUpdateStack so a new active area will be computed + + if (aTrackingArea === _activeCursorTrackingArea) + { + _cursorUpdateStack = []; + _activeCursorTrackingArea = nil; + } + } +} + +- (void)_handleCursorUpdateEventsForEvent:(CPEvent)anEvent atPoint:(CGPoint)point dragging:(BOOL)dragging cursorUpdateStack:(CPArray)cursorUpdateStack +{ + var overlappingTrackingAreas = []; + + for (var i = 0; i < cursorUpdateStack.length; i++) + { + var aTrackingArea = cursorUpdateStack[i]; + + if ((![_cursorUpdateStack containsObjectIdenticalTo:aTrackingArea]) || (aTrackingArea === _activeCursorTrackingArea)) + [overlappingTrackingAreas addObject:aTrackingArea]; + } + + var nbOverlappingTrackingAreas = overlappingTrackingAreas.length; + + if (nbOverlappingTrackingAreas > 0) + { + var frontmostTrackingArea = overlappingTrackingAreas[0], + frontmostView = [frontmostTrackingArea view]; + + for (var i = 1; i < nbOverlappingTrackingAreas; i++) + { + var aTrackingArea = overlappingTrackingAreas[i], + aView = [aTrackingArea view]; + + // First, if aView is _windowView, skip to next overlapping tracking area + // as _windowView can't be the frontmost view if there's multiple overlapping tracking areas. + + if (aView === _windowView) + continue; + + // Then, if frontmostView is _windowView, aView must become frontmostView + + if (frontmostView === _windowView) + { + frontmostTrackingArea = aTrackingArea; + frontmostView = aView; + + continue; + } + + // Next verify if aView is a subview of frontmostView + // If so, it's our new frontmost view + + var searchingView = aView; + + while ((searchingView !== _contentView) && ([searchingView superview] !== frontmostView)) + searchingView = [searchingView superview]; + + if (searchingView !== _contentView) + { + frontmostTrackingArea = aTrackingArea; + frontmostView = aView; + + continue; + } + + // aView is not a subview of frontmostView + // Search in view hierarchy which one will be over the other + // (this is done by comparing their draw order) + + var firstView = frontmostView, + firstSuperview = [firstView superview]; + + while (firstView !== _contentView) + { + var secondView = aView, + secondSuperview = [secondView superview]; + + while ((secondSuperview !== _contentView) && (firstSuperview !== secondSuperview)) + { + secondView = secondSuperview; + secondSuperview = [secondView superview]; + } + + if (firstSuperview === secondSuperview) + break; + + firstView = firstSuperview; + firstSuperview = [firstView superview]; + } + + if (firstSuperview !== secondSuperview) + [CPException raise:CPInternalInconsistencyException reason:"Problem with view hierarchy"]; + + var firstSuperviewSubviews = [firstSuperview subviews], + firstViewIndex = [firstSuperviewSubviews indexOfObject:firstView], + secondViewIndex = [firstSuperviewSubviews indexOfObject:secondView]; + + if (secondViewIndex > firstViewIndex) + { + frontmostTrackingArea = aTrackingArea; + frontmostView = aView; + } + } + + if (frontmostTrackingArea !== _activeCursorTrackingArea) + { + var cursorUpdateEvent = [CPEvent enterExitEventWithType:CPCursorUpdate + location:point + modifierFlags:[anEvent modifierFlags] + timestamp:[anEvent timestamp] + windowNumber:_windowNumber + context:nil + eventNumber:-1 + trackingArea:frontmostTrackingArea]; + + if (dragging) + [self _queueTrackingEvent:cursorUpdateEvent]; + else + [[frontmostTrackingArea owner] cursorUpdate:cursorUpdateEvent]; + + _activeCursorTrackingArea = frontmostTrackingArea; + } + } +} + +- (void)_queueTrackingEvent:(CPEvent)anEvent +{ + // This will put a tracking event in the _queuedTrackingEvents queue. + // + // We optimize this queue with this policy : + // - if mouseEntered, search if queue contains a previous mouseExited for the same tracking area. If so, discard both. + // - if mouseExited, search if queue contains a previous mouseEntered for the same tracking area. If so, discard both. + // + // This is not Cocoa way of doing as it would send every event. + // But final result should be the same. + + var eventType = [anEvent type], + trackingArea = [anEvent trackingArea]; + + switch ([anEvent type]) + { + case CPMouseEntered: + for (var i = 0; i < _queuedTrackingEvents.length; i++) + { + var queuedEvent = _queuedTrackingEvents[i]; + + if (([queuedEvent trackingArea] === trackingArea) && ([queuedEvent type] === CPMouseExited)) + { + [_queuedTrackingEvents removeObjectAtIndex:i]; + return; + } + } + + [_queuedTrackingEvents addObject:anEvent]; + break; + + case CPMouseExited: + for (var i = 0; i < _queuedTrackingEvents.length; i++) + { + var queuedEvent = _queuedTrackingEvents[i]; + + if (([queuedEvent trackingArea] === trackingArea) && ([queuedEvent type] === CPMouseEntered)) + { + [_queuedTrackingEvents removeObjectAtIndex:i]; + return; + } + } + + [_queuedTrackingEvents addObject:anEvent]; + break; + + case CPCursorUpdate: + [_queuedTrackingEvents addObject:anEvent]; + break; + } +} + +- (void)_flushTrackingEventQueueForMouseAt:(CGPoint)point +{ + for (var i = 0; i < _queuedTrackingEvents.length; i++) + { + var queuedEvent = _queuedTrackingEvents[i], + trackingArea = [queuedEvent trackingArea], + trackingOwner = [trackingArea owner]; + + switch ([queuedEvent type]) + { + case CPMouseEntered: + [trackingOwner mouseEntered:queuedEvent]; + break; + + case CPMouseExited: + [trackingOwner mouseExited:queuedEvent]; + break; + + case CPCursorUpdate: + [trackingOwner updateTrackingAreas]; + + if (CGRectContainsPoint([trackingArea windowRect], point)) + [trackingOwner cursorUpdate:queuedEvent]; + + break; + } + } + + _queuedTrackingEvents = []; +} + +@end + function _CPWindowFullPlatformWindowSessionMake(aWindowView, aContentRect, hasShadow, aLevel) { return { windowView:aWindowView, contentRect:aContentRect, hasShadow:hasShadow, level:aLevel }; diff --git a/AppKit/CPWindow/_CPWindowView.j b/AppKit/CPWindow/_CPWindowView.j index 0ffd01121..6e4127928 100644 --- a/AppKit/CPWindow/_CPWindowView.j +++ b/AppKit/CPWindow/_CPWindowView.j @@ -353,7 +353,9 @@ _CPWindowViewResizeSlop = 3; if ([theWindow isFullPlatformWindow] || !(_styleMask & CPResizableWindowMask) || (CPWindowResizeStyle !== CPWindowResizeStyleModern)) + { return; + } var globalPoint = [theWindow convertBaseToGlobal:aPoint], resizeRegion = isResizing ? _resizeRegion : [self resizeRegionForPoint:globalPoint], @@ -969,3 +971,18 @@ _CPWindowViewResizeSlop = 3; } @end + +@implementation _CPWindowView (TrackingAreaAdditions) + +- (void)updateTrackingAreas +{ + [self removeAllTrackingAreas]; + + [self addTrackingArea:[[CPTrackingArea alloc] initWithRect:[self contentRectForFrameRect:[self frame]] + options:CPTrackingCursorUpdate | CPTrackingActiveInActiveApp + owner:self + userInfo:nil]]; +} + +@end + diff --git a/Tests/AppKit/CPViewTest.j b/Tests/AppKit/CPViewTest.j index 5131a2fc3..426a6c086 100644 --- a/Tests/AppKit/CPViewTest.j +++ b/Tests/AppKit/CPViewTest.j @@ -2,6 +2,14 @@ @import var methodCalled; +var updateTrackingAreasCalls, + mouseEnteredCalls, + mouseExitedCalls, + mouseMovedCalls, + cursorUpdateCalls, + involvedViewForMouseEntered, + involvedViewForMouseExited, + involvedViewForCursorUpdate; @implementation CPViewTest : OJTestCase { @@ -30,6 +38,7 @@ var methodCalled; [view3 setIdentifier:@"view3"]; methodCalled = []; + updateTrackingAreasCalls = 0; [super setUp]; } @@ -886,6 +895,581 @@ var methodCalled; [self assert:nil equals:[view effectiveAppearance]]; } +// TrackingAreaAdditions + +- (void)testTrackingAreas +{ + var trackingArea = [[CPTrackingArea alloc] initWithRect:CGRectMakeZero() options:CPTrackingMouseEnteredAndExited | CPTrackingActiveInKeyWindow | CPTrackingInVisibleRect owner:self userInfo:nil]; + + [self assert:0 equals:[[view trackingAreas] count] message:@"Initially, a view has no tracking area"]; + + // + + [view addTrackingArea:trackingArea]; + [self assert:1 equals:[[view trackingAreas] count] message:@"After adding a tracking area"]; + [self assert:view equals:[trackingArea view] message:@"Tracking area should be linked to view"]; + + // + + [view removeTrackingArea:trackingArea]; + [self assert:0 equals:[[view trackingAreas] count] message:@"After removing the only tracking area"]; + [self assert:nil equals:[trackingArea view] message:@"Tracking area should be unlinked"]; + + // + + [view addTrackingArea:trackingArea]; + [view addTrackingArea:trackingArea]; + [view addTrackingArea:trackingArea]; + [self assert:1 equals:[[view trackingAreas] count] message:@"Adding the same tracking area multiple times should add it once"]; + [self assert:view equals:[trackingArea view] message:@"Tracking area should be linked to view"]; + + var trackingArea2 = [[CPTrackingArea alloc] initWithRect:CGRectMakeZero() options:CPTrackingMouseEnteredAndExited | CPTrackingActiveInKeyWindow owner:self userInfo:nil]; + + // + + [view addTrackingArea:trackingArea2]; + [self assert:2 equals:[[view trackingAreas] count] message:@"After adding a second tracking area"]; + [self assert:view equals:[trackingArea2 view] message:@"Tracking area should be linked to view"]; + + // + + [view removeAllTrackingAreas]; + [self assert:0 equals:[[view trackingAreas] count] message:@"After removing all tracking areas"]; + [self assert:nil equals:[trackingArea view] message:@"Tracking area should be unlinked"]; + [self assert:nil equals:[trackingArea2 view] message:@"Tracking area should be unlinked"]; + + // + + [view addTrackingArea:trackingArea]; + + var contentView = [window contentView]; + + [contentView addSubview:view]; + [self assert:0 equals:updateTrackingAreasCalls message:@"Putting a view with a CPTrackingAreaInVisibleRect in a window should not call updateTrackingAreas"]; + + [view removeFromSuperview]; + + // + + [view addTrackingArea:trackingArea2]; + [contentView addSubview:view]; + [self assert:1 equals:updateTrackingAreasCalls message:@"Putting a view with a non CPTrackingAreaInVisibleRect in a window should call updateTrackingAreas"]; + + [view removeAllTrackingAreas]; + + // + + var viewTA = [[CPTrackingAreaView alloc] initWithFrame:CGRectMakeZero()]; + updateTrackingAreasCalls = 0; + + [contentView addSubview:viewTA]; + [self assert:1 equals:updateTrackingAreasCalls message:@"Putting a view with no tracking areas in a window should call updateTrackingAreas"]; + + // + + updateTrackingAreasCalls = 0; + + [viewTA addTrackingArea:trackingArea]; + [viewTA setFrame:CGRectMake(10, 10, 10, 10)]; + [self assert:0 equals:updateTrackingAreasCalls message:@"Changing geometry of a view with a CPTrackingAreaInVisibleRect should not call updateTrackingAreas"]; + + // + + updateTrackingAreasCalls = 0; + + [viewTA addTrackingArea:trackingArea2]; + [viewTA setFrame:CGRectMake(20, 20, 20, 20)]; + [self assert:1 equals:updateTrackingAreasCalls message:@"Changing geometry of a view with a non CPTrackingAreaInVisibleRect should call updateTrackingAreas"]; + + // + + var trackingAreaAll = [[CPTrackingArea alloc] initWithRect:CGRectMakeZero() options:CPTrackingMouseEnteredAndExited | CPTrackingMouseMoved | CPTrackingCursorUpdate | CPTrackingActiveInActiveApp | CPTrackingInVisibleRect owner:viewTA userInfo:nil]; + + [viewTA removeAllTrackingAreas]; + [viewTA addTrackingArea:trackingAreaAll]; + + // Mouse enters the tracking area + + [self moveMouseAtPoint:CGPointMake(21, 21) dragging:NO]; + + [self assert:1 equals:mouseEnteredCalls message:@"Mouse entering a tracking area should call mouseEntered"]; + [self assert:0 equals:mouseExitedCalls message:@"Mouse entering a tracking area should not call mouseExited"]; + [self assert:0 equals:mouseMovedCalls message:@"Mouse entering a tracking area should not call mouseMoved"]; + [self assert:1 equals:cursorUpdateCalls message:@"Mouse entering a tracking area should call cursorUpdate"]; + + // Mouse moves in the tracking area + + [self moveMouseAtPoint:CGPointMake(22, 22) dragging:NO]; + + [self assert:0 equals:mouseEnteredCalls message:@"Mouse moving in a tracking area should not call mouseEntered"]; + [self assert:0 equals:mouseExitedCalls message:@"Mouse moving in a tracking area should not call mouseExited"]; + [self assert:1 equals:mouseMovedCalls message:@"Mouse moving in a tracking area should call mouseMoved"]; + [self assert:0 equals:cursorUpdateCalls message:@"Mouse moving in a tracking area should not call cursorUpdate"]; + + // Mouse exits from the tracking area + + [self moveMouseAtPoint:CGPointMake(0, 0) dragging:NO]; + + [self assert:0 equals:mouseEnteredCalls message:@"Mouse exiting from a tracking area should not call mouseEntered"]; + [self assert:1 equals:mouseExitedCalls message:@"Mouse exiting from a tracking area should call mouseExited"]; + [self assert:0 equals:mouseMovedCalls message:@"Mouse exiting from a tracking area should not call mouseMoved"]; + [self assert:0 equals:cursorUpdateCalls message:@"Mouse exiting from a tracking area should not call cursorUpdate"]; + + // Mouse enters the tracking area while dragging + + [self moveMouseAtPoint:CGPointMake(21, 21) dragging:YES]; + + [self assert:0 equals:mouseEnteredCalls message:@"While dragging, mouse entering a tracking area without CPTrackingEnabledDuringMouseDrag should not call mouseEntered"]; + [self assert:0 equals:mouseExitedCalls message:@"While dragging, mouse entering a tracking area without CPTrackingEnabledDuringMouseDrag should not call mouseExited"]; + [self assert:0 equals:mouseMovedCalls message:@"While dragging, mouse entering a tracking area without CPTrackingEnabledDuringMouseDrag should not call mouseMoved"]; + [self assert:0 equals:cursorUpdateCalls message:@"While dragging, mouse entering a tracking area without CPTrackingEnabledDuringMouseDrag should not call cursorUpdate"]; + + // Mouse moves in the tracking area while dragging + + [self moveMouseAtPoint:CGPointMake(22, 22) dragging:YES]; + + [self assert:0 equals:mouseEnteredCalls message:@"While dragging, mouse moving in a tracking area without CPTrackingEnabledDuringMouseDrag should not call mouseEntered"]; + [self assert:0 equals:mouseExitedCalls message:@"While dragging, mouse moving in a tracking area without CPTrackingEnabledDuringMouseDrag should not call mouseExited"]; + [self assert:0 equals:mouseMovedCalls message:@"While dragging, mouse moving in a tracking area without CPTrackingEnabledDuringMouseDrag should not call mouseMoved"]; + [self assert:0 equals:cursorUpdateCalls message:@"While dragging, mouse moving in a tracking area without CPTrackingEnabledDuringMouseDrag should not call cursorUpdate"]; + + // Mouse exits from the tracking area while dragging + + [self moveMouseAtPoint:CGPointMake(0, 0) dragging:YES]; + + [self assert:0 equals:mouseEnteredCalls message:@"While dragging, mouse exiting from a tracking area without CPTrackingEnabledDuringMouseDrag should not call mouseEntered"]; + [self assert:0 equals:mouseExitedCalls message:@"While dragging, mouse exiting from a tracking area without CPTrackingEnabledDuringMouseDrag should not call mouseExited"]; + [self assert:0 equals:mouseMovedCalls message:@"While dragging, mouse exiting from a tracking area without CPTrackingEnabledDuringMouseDrag should not call mouseMoved"]; + [self assert:0 equals:cursorUpdateCalls message:@"While dragging, mouse exiting from a tracking area without CPTrackingEnabledDuringMouseDrag should not call cursorUpdate"]; + + // + + var trackingAreaAllWithDrag = [[CPTrackingArea alloc] initWithRect:CGRectMakeZero() options:CPTrackingMouseEnteredAndExited | CPTrackingMouseMoved | CPTrackingCursorUpdate | CPTrackingActiveInActiveApp | CPTrackingInVisibleRect | CPTrackingEnabledDuringMouseDrag owner:viewTA userInfo:nil]; + + [viewTA removeAllTrackingAreas]; + [viewTA addTrackingArea:trackingAreaAllWithDrag]; + + // Mouse enters the tracking area while dragging (option set) + + [self moveMouseAtPoint:CGPointMake(21, 21) dragging:YES]; + + [self assert:1 equals:mouseEnteredCalls message:@"While dragging, mouse entering a tracking area with CPTrackingEnabledDuringMouseDrag should call mouseEntered"]; + [self assert:0 equals:mouseExitedCalls message:@"While dragging, mouse entering a tracking area with CPTrackingEnabledDuringMouseDrag should not call mouseExited"]; + [self assert:0 equals:mouseMovedCalls message:@"While dragging, mouse entering a tracking area with CPTrackingEnabledDuringMouseDrag should not call mouseMoved"]; + [self assert:0 equals:cursorUpdateCalls message:@"While dragging, mouse entering a tracking area with CPTrackingEnabledDuringMouseDrag should not call cursorUpdate"]; + + // Mouse moves in the tracking area while dragging (option set) + + [self moveMouseAtPoint:CGPointMake(22, 22) dragging:YES]; + + [self assert:0 equals:mouseEnteredCalls message:@"While dragging, mouse moving in a tracking area with CPTrackingEnabledDuringMouseDrag should not call mouseEntered"]; + [self assert:0 equals:mouseExitedCalls message:@"While dragging, mouse moving in a tracking area with CPTrackingEnabledDuringMouseDrag should not call mouseExited"]; + [self assert:0 equals:mouseMovedCalls message:@"While dragging, mouse moving in a tracking area with CPTrackingEnabledDuringMouseDrag should not call mouseMoved"]; + [self assert:0 equals:cursorUpdateCalls message:@"While dragging, mouse moving in a tracking area with CPTrackingEnabledDuringMouseDrag should not call cursorUpdate"]; + + // Mouse exits from the tracking area while dragging (option set) + + [self moveMouseAtPoint:CGPointMake(0, 0) dragging:YES]; + + [self assert:0 equals:mouseEnteredCalls message:@"While dragging, mouse exiting from a tracking area with CPTrackingEnabledDuringMouseDrag should not call mouseEntered"]; + [self assert:1 equals:mouseExitedCalls message:@"While dragging, mouse exiting from a tracking area with CPTrackingEnabledDuringMouseDrag should call mouseExited"]; + [self assert:0 equals:mouseMovedCalls message:@"While dragging, mouse exiting from a tracking area with CPTrackingEnabledDuringMouseDrag should not call mouseMoved"]; + [self assert:0 equals:cursorUpdateCalls message:@"While dragging, mouse exiting from a tracking area with CPTrackingEnabledDuringMouseDrag should not call cursorUpdate"]; + + // Nested views + + var innerViewTA = [[CPTrackingAreaView alloc] initWithFrame:CGRectMake(5, 5, 10, 10)]; + + [viewTA addSubview:innerViewTA]; + + var innerTrackingArea = [[CPTrackingArea alloc] initWithRect:CGRectMakeZero() options:CPTrackingMouseEnteredAndExited | CPTrackingMouseMoved | CPTrackingCursorUpdate | CPTrackingActiveInActiveApp | CPTrackingInVisibleRect owner:innerViewTA userInfo:nil]; + + [innerViewTA addTrackingArea:innerTrackingArea]; + + // Mouse enters outer view + + [self moveMouseAtPoint:CGPointMake(21, 21) dragging:NO]; + + [self assert:1 equals:mouseEnteredCalls message:@"Mouse entering outer tracking area should call mouseEntered"]; + [self assert:0 equals:mouseExitedCalls message:@"Mouse entering outer tracking area should not call mouseExited"]; + [self assert:0 equals:mouseMovedCalls message:@"Mouse entering outer tracking area should not call mouseMoved"]; + [self assert:1 equals:cursorUpdateCalls message:@"Mouse entering outer tracking area should call cursorUpdate"]; + + // Mouse enters inner view + + [self moveMouseAtPoint:CGPointMake(26, 26) dragging:NO]; + + [self assert:1 equals:mouseEnteredCalls message:@"Mouse entering inner tracking area should call mouseEntered"]; + [self assert:0 equals:mouseExitedCalls message:@"Mouse entering inner tracking area should not call mouseExited"]; + [self assert:1 equals:mouseMovedCalls message:@"Mouse entering inner tracking area should call mouseMoved"]; + [self assert:1 equals:cursorUpdateCalls message:@"Mouse entering inner tracking area should call cursorUpdate"]; + + // Mouse moves in inner view + + [self moveMouseAtPoint:CGPointMake(27, 27) dragging:NO]; + + [self assert:0 equals:mouseEnteredCalls message:@"Mouse moving in inner tracking area should not call mouseEntered"]; + [self assert:0 equals:mouseExitedCalls message:@"Mouse moving in inner tracking area should not call mouseExited"]; + [self assert:2 equals:mouseMovedCalls message:@"Mouse moving in inner tracking area should call mouseMoved for both views"]; + [self assert:0 equals:cursorUpdateCalls message:@"Mouse moving in inner tracking area should not call cursorUpdate"]; + + // Mouse leaves inner view but remains in outer view + + [self moveMouseAtPoint:CGPointMake(36, 36) dragging:NO]; + + [self assert:0 equals:mouseEnteredCalls message:@"Mouse moving from inner to outer tracking area should not call mouseEntered"]; + [self assert:1 equals:mouseExitedCalls message:@"Mouse moving from inner to outer tracking area should call mouseExited (for inner)"]; + [self assert:1 equals:mouseMovedCalls message:@"Mouse moving from inner to outer tracking area should call mouseMoved (for outer)"]; + [self assert:1 equals:cursorUpdateCalls message:@"Mouse moving from inner to outer tracking area should call cursorUpdate (for outer)"]; + + [self assert:innerViewTA equals:involvedViewForMouseExited message:@"Inner view should receive mouseExited"]; + [self assert:viewTA equals:involvedViewForCursorUpdate message:@"Outer view should receive cursorUpdate"]; + + // Complex test for cursor update frontmost tracking area detection + + var viewA = [[CPTrackingAreaView alloc] initWithFrame:CGRectMake(0, 30, 40, 40)]; + var viewB = [[CPTrackingAreaView alloc] initWithFrame:CGRectMake(30, 20, 40, 40)]; + var viewC = [[CPTrackingAreaView alloc] initWithFrame:CGRectMake(10, 0, 40, 40)]; + + [contentView setSubviews:[CPArray array]]; + [contentView addSubview:viewA]; + [contentView addSubview:viewB]; + [contentView addSubview:viewC]; + + var subviewA = [[CPTrackingAreaView alloc] initWithFrame:CGRectMake(20, 0, 20, 20)]; + var subviewB = [[CPTrackingAreaView alloc] initWithFrame:CGRectMake(0, 0, 20, 20)]; + var subviewC = [[CPTrackingAreaView alloc] initWithFrame:CGRectMake(0, 20, 40, 20)]; + + [viewA addSubview:subviewA]; + [viewB addSubview:subviewB]; + [viewC addSubview:subviewC]; + + var options = CPTrackingCursorUpdate | CPTrackingActiveInActiveApp | CPTrackingInVisibleRect; + var options2 = CPTrackingMouseEnteredAndExited | CPTrackingActiveInActiveApp | CPTrackingInVisibleRect; + var options3 = CPTrackingCursorUpdate | CPTrackingActiveInActiveApp; + + var viewATrackingArea = [[CPTrackingArea alloc] initWithRect:CGRectMakeZero() options:options owner:viewA userInfo:nil]; + var viewBTrackingArea = [[CPTrackingArea alloc] initWithRect:CGRectMakeZero() options:options owner:viewB userInfo:nil]; + var viewCTrackingArea = [[CPTrackingArea alloc] initWithRect:CGRectMakeZero() options:options2 owner:viewC userInfo:nil]; + + var subviewATrackingArea = [[CPTrackingArea alloc] initWithRect:CGRectMakeZero() options:options owner:subviewA userInfo:nil]; + var subviewBTrackingArea = [[CPTrackingArea alloc] initWithRect:CGRectMakeZero() options:options owner:subviewB userInfo:nil]; + var subviewCtrackingArea = [[CPTrackingArea alloc] initWithRect:CGRectMake(20, 0, 20, 20) options:options3 owner:subviewC userInfo:nil]; + + [viewA addTrackingArea:viewATrackingArea]; + [viewB addTrackingArea:viewBTrackingArea]; + [viewC addTrackingArea:viewCTrackingArea]; + + [subviewA addTrackingArea:subviewATrackingArea]; + [subviewB addTrackingArea:subviewBTrackingArea]; + [subviewC addTrackingArea:subviewCtrackingArea]; + + // Step 1 + + [self moveMouseAtPoint:CGPointMake(5, 25) dragging:NO]; + + [self assert:0 equals:cursorUpdateCalls message:@"Step 1 : no cursorUpdate should be called"]; + [self assert:nil equals:involvedViewForCursorUpdate message:@"Step 1 : no view should be called for cursorUpdate"]; + + // Step 2 + + [self moveMouseAtPoint:CGPointMake(5, 35) dragging:NO]; + + [self assert:1 equals:cursorUpdateCalls message:@"Step 2 : 1 cursorUpdate should be called"]; + [self assert:viewA equals:involvedViewForCursorUpdate message:@"Step 2 : viewA should be called for cursorUpdate"]; + + // Step 3 + + [self moveMouseAtPoint:CGPointMake(15, 35) dragging:NO]; + + [self assert:0 equals:cursorUpdateCalls message:@"Step 3 : no cursorUpdate should be called"]; + [self assert:nil equals:involvedViewForCursorUpdate message:@"Step 3 : no view should be called for cursorUpdate"]; + + // Step 4 + + [self moveMouseAtPoint:CGPointMake(25, 35) dragging:NO]; + + [self assert:1 equals:cursorUpdateCalls message:@"Step 4 : 1 cursorUpdate should be called"]; + [self assert:subviewA equals:involvedViewForCursorUpdate message:@"Step 4 : subviewA should be called for cursorUpdate"]; + + // Step 5 + + [self moveMouseAtPoint:CGPointMake(35, 35) dragging:NO]; + + [self assert:1 equals:cursorUpdateCalls message:@"Step 5 : 1 cursorUpdate should be called"]; + [self assert:subviewC equals:involvedViewForCursorUpdate message:@"Step 5 : subviewC should be called for cursorUpdate"]; + + // Step 6 + + [self moveMouseAtPoint:CGPointMake(45, 35) dragging:NO]; + + [self assert:0 equals:cursorUpdateCalls message:@"Step 6 : no cursorUpdate should be called"]; + [self assert:nil equals:involvedViewForCursorUpdate message:@"Step 6 : no view should be called for cursorUpdate"]; + + // Step 7 + + [self moveMouseAtPoint:CGPointMake(55, 35) dragging:NO]; + + [self assert:1 equals:cursorUpdateCalls message:@"Step 7 : 1 cursorUpdate should be called"]; + [self assert:viewB equals:involvedViewForCursorUpdate message:@"Step 7 : viewB should be called for cursorUpdate"]; + + // Step 8 + + [self moveMouseAtPoint:CGPointMake(75, 35) dragging:NO]; + + [self assert:0 equals:cursorUpdateCalls message:@"Step 8 : no cursorUpdate should be called"]; + [self assert:nil equals:involvedViewForCursorUpdate message:@"Step 8 : no view should be called for cursorUpdate"]; + + // Cursor tests + + var viewA = [[CPTrackingAreaViewWithCursorUpdate alloc] initWithFrame:CGRectMake(20, 20, 40, 40)]; + var viewB = [[CPTrackingAreaView alloc] initWithFrame:CGRectMake(10, 10, 80, 80)]; + var viewC = [[CPTrackingAreaViewWithoutCursorUpdate alloc] initWithFrame:CGRectMake(10, 10, 80, 80)]; + + [contentView setSubviews:[CPArray array]]; + [contentView addSubview:viewA]; + + var options = CPTrackingCursorUpdate | CPTrackingActiveInActiveApp | CPTrackingInVisibleRect; + + var viewATrackingArea = [[CPTrackingArea alloc] initWithRect:CGRectMakeZero() options:options owner:viewA userInfo:nil]; + var viewBTrackingArea = [[CPTrackingArea alloc] initWithRect:CGRectMakeZero() options:options owner:viewB userInfo:nil]; + var viewCTrackingArea = [[CPTrackingArea alloc] initWithRect:CGRectMakeZero() options:options owner:viewC userInfo:nil]; + + [viewA addTrackingArea:viewATrackingArea]; + [viewB addTrackingArea:viewBTrackingArea]; + [viewC addTrackingArea:viewCTrackingArea]; + + // Step 1.1 : outside the view + + [self moveMouseAtPoint:CGPointMake(10, 10) dragging:NO]; + + [self assert:[CPCursor arrowCursor] equals:[CPCursor currentCursor] message:@"Step 1.1 : cursor should be an arrow"]; + + // Step 1.2 : inside the view + + [self moveMouseAtPoint:CGPointMake(30, 30) dragging:NO]; + + [self assert:[CPCursor crosshairCursor] equals:[CPCursor currentCursor] message:@"Step 1.2 : cursor should be a crosshair"]; + + // Step 1.3 : outside the view + + [self moveMouseAtPoint:CGPointMake(70, 70) dragging:NO]; + + [self assert:[CPCursor arrowCursor] equals:[CPCursor currentCursor] message:@"Step 1.3 : cursor should be an arrow"]; + + // Step 1.4 : inside the view with dragging + + [self moveMouseAtPoint:CGPointMake(30, 30) dragging:YES]; + + [self assert:[CPCursor arrowCursor] equals:[CPCursor currentCursor] message:@"Step 1.4 : cursor should be an arrow"]; + + // Step 1.5 : mouse up (ends dragging) + + [self mouseUpAtPoint:CGPointMake(30, 30)]; + + [self assert:[CPCursor crosshairCursor] equals:[CPCursor currentCursor] message:@"Step 1.5 : cursor should be a crosshair"]; + + // Step 1.6 : outside the view with dragging + + [self moveMouseAtPoint:CGPointMake(10, 10) dragging:YES]; + + [self assert:[CPCursor crosshairCursor] equals:[CPCursor currentCursor] message:@"Step 1.6 : cursor should be a crosshair"]; + + // Step 1.7 : mouse up (ends dragging) + + [self mouseUpAtPoint:CGPointMake(10, 10)]; + + [self assert:[CPCursor arrowCursor] equals:[CPCursor currentCursor] message:@"Step 1.7 : cursor should be an arrow"]; + + // + + [self moveMouseAtPoint:CGPointMake(1, 1) dragging:NO]; + + [viewA removeFromSuperview]; + [contentView addSubview:viewB]; + [viewB addSubview:viewA]; + + // Step 2.1 : outside the superview + + [self moveMouseAtPoint:CGPointMake(5, 5) dragging:NO]; + + [self assert:[CPCursor arrowCursor] equals:[CPCursor currentCursor] message:@"Step 2.1 : cursor should be an arrow"]; + + // Step 2.2 : inside the superview / outside the subview + + [self moveMouseAtPoint:CGPointMake(15, 15) dragging:NO]; + + [self assert:[CPCursor arrowCursor] equals:[CPCursor currentCursor] message:@"Step 2.2 : cursor should be an arrow"]; + + // Step 2.3 : inside the subview + + [self moveMouseAtPoint:CGPointMake(35, 35) dragging:NO]; + + [self assert:[CPCursor crosshairCursor] equals:[CPCursor currentCursor] message:@"Step 2.3 : cursor should be a crosshair"]; + + // Step 2.4 : outside the subview / inside the superview + + [self moveMouseAtPoint:CGPointMake(15, 15) dragging:NO]; + + [self assert:[CPCursor crosshairCursor] equals:[CPCursor currentCursor] message:@"Step 2.4 : cursor should be a crosshair"]; + + // Step 2.5 : outside the superview + + [self moveMouseAtPoint:CGPointMake(5, 5) dragging:NO]; + + [self assert:[CPCursor arrowCursor] equals:[CPCursor currentCursor] message:@"Step 2.5 : cursor should be an arrow"]; + + // + + [self moveMouseAtPoint:CGPointMake(1, 1) dragging:NO]; + + [viewA removeFromSuperview]; + [viewB removeFromSuperview]; + [contentView addSubview:viewC]; + [viewC addSubview:viewA]; + + // Step 3.1 : outside the superview + + [self moveMouseAtPoint:CGPointMake(5, 5) dragging:NO]; + + [self assert:[CPCursor arrowCursor] equals:[CPCursor currentCursor] message:@"Step 3.1 : cursor should be an arrow"]; + + // Step 3.2 : inside the superview / outside the subview + + [self moveMouseAtPoint:CGPointMake(15, 15) dragging:NO]; + + [self assert:[CPCursor arrowCursor] equals:[CPCursor currentCursor] message:@"Step 3.2 : cursor should be an arrow"]; + + // Step 3.3 : inside the subview + + [self moveMouseAtPoint:CGPointMake(35, 35) dragging:NO]; + + [self assert:[CPCursor crosshairCursor] equals:[CPCursor currentCursor] message:@"Step 3.3 : cursor should be a crosshair"]; + + // Step 3.4 : outside the subview / inside the superview + + [self moveMouseAtPoint:CGPointMake(15, 15) dragging:NO]; + + [self assert:[CPCursor arrowCursor] equals:[CPCursor currentCursor] message:@"Step 3.4 : cursor should be an arrow"]; + + // Step 3.5 : outside the superview + + [self moveMouseAtPoint:CGPointMake(5, 5) dragging:NO]; + + [self assert:[CPCursor arrowCursor] equals:[CPCursor currentCursor] message:@"Step 3.5 : cursor should be an arrow"]; + +} + +- (void)updateTrackingAreas +{ + updateTrackingAreasCalls++; +} + +- (void)resetCounters +{ + mouseEnteredCalls = 0; + mouseExitedCalls = 0; + mouseMovedCalls = 0; + cursorUpdateCalls = 0; + + involvedViewForMouseEntered = nil; + involvedViewForMouseExited = nil; + involvedViewForCursorUpdate = nil; +} + +- (void)moveMouseAtPoint:(CGPoint)aPoint dragging:(BOOL)dragging +{ + var anEvent = [CPEvent mouseEventWithType:(dragging ? CPLeftMouseDragged : CPMouseMoved) + location:aPoint + modifierFlags:0 + timestamp:0 + windowNumber:[window windowNumber] + context:nil + eventNumber:-1 + clickCount:0 + pressure:0]; + + [self resetCounters]; + + [[CPApplication sharedApplication] sendEvent:anEvent]; +} + +- (void)mouseUpAtPoint:(CGPoint)aPoint +{ + var anEvent = [CPEvent mouseEventWithType:CPLeftMouseUp + location:aPoint + modifierFlags:0 + timestamp:0 + windowNumber:[window windowNumber] + context:nil + eventNumber:-1 + clickCount:0 + pressure:0]; + + [self resetCounters]; + + [[CPApplication sharedApplication] sendEvent:anEvent]; +} + +@end + +@implementation CPTrackingAreaView : CPView +{ + +} + +- (void)mouseEntered:(CPEvent)anEvent +{ + mouseEnteredCalls++; + + involvedViewForMouseEntered = [[anEvent trackingArea] view]; +} + +- (void)mouseExited:(CPEvent)anEvent +{ + mouseExitedCalls++; + + involvedViewForMouseExited = [[anEvent trackingArea] view]; +} + +- (void)mouseMoved:(CPEvent)anEvent +{ + mouseMovedCalls++; +} + +- (void)cursorUpdate:(CPEvent)anEvent +{ + cursorUpdateCalls++; + + involvedViewForCursorUpdate = [[anEvent trackingArea] view]; +} + +- (void)updateTrackingAreas +{ + updateTrackingAreasCalls++; +} + +@end + +@implementation CPTrackingAreaViewWithCursorUpdate : CPTrackingAreaView +{ + +} + +- (void)cursorUpdate:(CPEvent)anEvent +{ + [[CPCursor crosshairCursor] set]; + + [super cursorUpdate:anEvent]; +} + +@end + +@implementation CPTrackingAreaViewWithoutCursorUpdate : CPView +{ + +} + @end @implementation CPLayoutView : CPView diff --git a/Tests/Manual/TrackingArea/AppController.j b/Tests/Manual/TrackingArea/AppController.j new file mode 100644 index 000000000..5c9f6f729 --- /dev/null +++ b/Tests/Manual/TrackingArea/AppController.j @@ -0,0 +1,699 @@ +/* + * AppController.j + * TrackingArea + * + * Created by Didier Korthoudt on November 2, 2015. + * Copyright 2015, Your Company All rights reserved. + */ + +@import +@import +@import + +@class SensibleView; +@class SensibleViewTA; +@class SensibleViewAutoTA; +@class SensibleViewWithoutCursorUpdate; + +@implementation AppController : CPObject +{ + @outlet CPWindow theWindow; + + SensibleView v1; + SensibleView v2; + SensibleView v3; + SensibleView v4; + SensibleView v5; + SensibleView v6; + SensibleView v7; + SensibleView v8; + SensibleView v9; + SensibleView v10; + SensibleViewWithoutCursorUpdate v11; + SensibleView v12; + + SensibleViewTA w2; + SensibleView w3; + SensibleViewAutoTA w4; + SensibleView w5; + SensibleView w6; + SensibleView w7; + + @outlet SensibleView s1; + + SensibleView cursorCapturingView; +} + +- (void)applicationDidFinishLaunching:(CPNotification)aNotification +{ + // This is called when the application is done loading. + + var message = [[CPAlert alloc] init]; + + [message setMessageText:@"CPTrackingArea test application"]; + [message setInformativeText:@"Play with various cases, try to drag mouse, observe events in the console, ..."]; + [message setDelegate:self]; + [message setAlertStyle:CPInformationalAlertStyle]; + + [message addButtonWithTitle:@"OK"]; + + [message beginSheetModalForWindow:theWindow modalDelegate:nil didEndSelector:nil contextInfo:nil]; +} + +- (void)awakeFromCib +{ + // This is called when the cib is done loading. + // You can implement this method on any object instantiated from a Cib. + // It's a useful hook for setting up current UI values, and other things. + + // In this case, we want the window from Cib to become our full browser window + [theWindow setFullPlatformWindow:YES]; + + var p = [theWindow contentView]; + + // No tracking area + + v1 = [[SensibleView alloc] initWithFrame:CGRectMake(30, 10, 50, 50)]; + + [v1 setViewName:@"no_tracking_area"]; + [v1 setViewColor:[CPColor greenColor]]; + [v1 setViewCursor:[CPCursor crosshairCursor]]; + + [p addSubview:v1]; + + [self addLabel:@"No tracking area" forView:v1]; + + // CPTrackingMouseEnteredAndExited + + v2 = [[SensibleView alloc] initWithFrame:CGRectMake(160, 10, 50, 50)]; + + [v2 setViewName:@"CPTrackingMouseEnteredAndExited"]; + [v2 setViewColor:[CPColor greenColor]]; + [v2 setViewCursor:[CPCursor crosshairCursor]]; + + var t = [[CPTrackingArea alloc] initWithRect:CGRectMakeZero() + options:CPTrackingMouseEnteredAndExited | CPTrackingActiveInKeyWindow | CPTrackingInVisibleRect + owner:v2 + userInfo:nil]; + + [v2 addTrackingArea:t]; + + [p addSubview:v2]; + + [self addLabel:@"MouseEnteredAndExited\nInVisibleRect" forView:v2]; + + // CPTrackingCursorUpdate + + v3 = [[SensibleView alloc] initWithFrame:CGRectMake(290, 10, 50, 50)]; + + [v3 setViewName:@"CPTrackingCursorUpdate"]; + [v3 setViewColor:[CPColor greenColor]]; + [v3 setViewCursor:[CPCursor crosshairCursor]]; + + var t = [[CPTrackingArea alloc] initWithRect:CGRectMakeZero() + options:CPTrackingCursorUpdate | CPTrackingActiveInKeyWindow | CPTrackingInVisibleRect + owner:v3 + userInfo:nil]; + + [v3 addTrackingArea:t]; + + [p addSubview:v3]; + + [self addLabel:@"CursorUpdate\nInVisibleRect" forView:v3]; + + // CPTrackingMouseMoved + + v4 = [[SensibleView alloc] initWithFrame:CGRectMake(420, 10, 50, 50)]; + + [v4 setViewName:@"CPTrackingMouseMoved"]; + [v4 setViewColor:[CPColor greenColor]]; + [v4 setViewCursor:[CPCursor crosshairCursor]]; + + var t = [[CPTrackingArea alloc] initWithRect:CGRectMakeZero() + options:CPTrackingMouseMoved | CPTrackingActiveInKeyWindow | CPTrackingInVisibleRect + owner:v4 + userInfo:nil]; + + [v4 addTrackingArea:t]; + + [p addSubview:v4]; + + [self addLabel:@"MouseMoved\nInVisibleRect" forView:v4]; + + // CPTrackingMouseEnteredAndExited & CPTrackingCursorUpdate + + v5 = [[SensibleView alloc] initWithFrame:CGRectMake(550, 10, 50, 50)]; + + [v5 setViewName:@"CPTrackingMouseEnteredAndExited+CPTrackingCursorUpdate"]; + [v5 setViewColor:[CPColor greenColor]]; + [v5 setViewCursor:[CPCursor crosshairCursor]]; + + var t = [[CPTrackingArea alloc] initWithRect:CGRectMakeZero() + options:CPTrackingMouseEnteredAndExited | CPTrackingCursorUpdate | CPTrackingActiveInKeyWindow | CPTrackingInVisibleRect + owner:v5 + userInfo:nil]; + + [v5 addTrackingArea:t]; + + [p addSubview:v5]; + + [self addLabel:@"MouseEnteredAndExited\nCursorUpdate\nInVisibleRect" forView:v5]; + + // CPTrackingMouseMoved & CPTrackingCursorUpdate + + v6 = [[SensibleView alloc] initWithFrame:CGRectMake(680, 10, 50, 50)]; + + [v6 setViewName:@"CPTrackingMouseMoved+CPTrackingCursorUpdate"]; + [v6 setViewColor:[CPColor greenColor]]; + [v6 setViewCursor:[CPCursor crosshairCursor]]; + + var t = [[CPTrackingArea alloc] initWithRect:CGRectMakeZero() + options:CPTrackingMouseMoved | CPTrackingCursorUpdate | CPTrackingActiveInKeyWindow | CPTrackingInVisibleRect + owner:v6 + userInfo:nil]; + + [v6 addTrackingArea:t]; + + [p addSubview:v6]; + + [self addLabel:@"MouseMoved\nCursorUpdate\nInVisibleRect" forView:v6]; + + // CPTrackingMouseEnteredAndExited & CPTrackingMouseMoved + + v7 = [[SensibleView alloc] initWithFrame:CGRectMake(810, 10, 50, 50)]; + + [v7 setViewName:@"CPTrackingMouseEnteredAndExited+CPTrackingMouseMoved"]; + [v7 setViewColor:[CPColor greenColor]]; + [v7 setViewCursor:[CPCursor crosshairCursor]]; + + var t = [[CPTrackingArea alloc] initWithRect:CGRectMakeZero() + options:CPTrackingMouseEnteredAndExited | CPTrackingMouseMoved | CPTrackingActiveInKeyWindow | CPTrackingInVisibleRect + owner:v7 + userInfo:nil]; + + [v7 addTrackingArea:t]; + + [p addSubview:v7]; + + [self addLabel:@"MouseEnteredAndExited\nMouseMoved\nInVisibleRect" forView:v7]; + + // CPTrackingMouseEnteredAndExited & CPTrackingMouseMoved & CPTrackingCursorUpdate + + v8 = [[SensibleView alloc] initWithFrame:CGRectMake(940, 10, 50, 50)]; + + [v8 setViewName:@"CPTrackingMouseEnteredAndExited+CPTrackingMouseMoved+CPTrackingCursorUpdate"]; + [v8 setViewColor:[CPColor greenColor]]; + [v8 setViewCursor:[CPCursor crosshairCursor]]; + + var t = [[CPTrackingArea alloc] initWithRect:CGRectMakeZero() + options:CPTrackingMouseEnteredAndExited | CPTrackingMouseMoved | CPTrackingCursorUpdate | CPTrackingActiveInKeyWindow | CPTrackingInVisibleRect + owner:v8 + userInfo:nil]; + + [v8 addTrackingArea:t]; + + [p addSubview:v8]; + + [self addLabel:@"MouseEnteredAndExited\nMouseMoved\nCursorUpdate\nInVisibleRect" forView:v8]; + + // nested views, superview implements cursorUpdate but does nothing + + v9 = [[SensibleView alloc] initWithFrame:CGRectMake(1070, 10, 50, 50)]; + + [v9 setViewName:@"Superview with cursorUpdate but doing nothing"]; + [v9 setViewColor:[CPColor greenColor]]; + [v9 setViewCursor:nil]; + + var t = [[CPTrackingArea alloc] initWithRect:CGRectMakeZero() + options:CPTrackingMouseEnteredAndExited | CPTrackingCursorUpdate | CPTrackingActiveInKeyWindow | CPTrackingInVisibleRect + owner:v9 + userInfo:nil]; + + [v9 addTrackingArea:t]; + + [p addSubview:v9]; + + [self addLabel:@"Outer view implements\ncursorUpdate but does nothing.\nInner view implements\ncursorUpdate" forView:v9]; + + v10 = [[SensibleView alloc] initWithFrame:CGRectMake(10, 10, 30, 30)]; + + [v10 setViewName:@"Subview with cursorUpdate"]; + [v10 setViewColor:[CPColor blueColor]]; + [v10 setViewCursor:[CPCursor crosshairCursor]]; + + var t = [[CPTrackingArea alloc] initWithRect:CGRectMakeZero() + options:CPTrackingMouseEnteredAndExited | CPTrackingCursorUpdate | CPTrackingActiveInKeyWindow | CPTrackingInVisibleRect + owner:v10 + userInfo:nil]; + + [v10 addTrackingArea:t]; + + [v9 addSubview:v10]; + + // nested views, superview doesn't implement cursorUpdate but requests it + + v11 = [[SensibleViewWithoutCursorUpdate alloc] initWithFrame:CGRectMake(1200, 10, 50, 50)]; + + [v11 setViewName:@"Superview without cursorUpdate"]; + [v11 setViewColor:[CPColor greenColor]]; + [v11 setViewCursor:[CPCursor pointingHandCursor]]; + + var t = [[CPTrackingArea alloc] initWithRect:CGRectMakeZero() + options:CPTrackingMouseEnteredAndExited | CPTrackingCursorUpdate | CPTrackingActiveInKeyWindow | CPTrackingInVisibleRect + owner:v11 + userInfo:nil]; + + [v11 addTrackingArea:t]; + + [p addSubview:v11]; + + [self addLabel:@"Outer view doesn't implement\ncursorUpdate but requests it.\nInner view implements\ncursorUpdate" forView:v11]; + + v12 = [[SensibleView alloc] initWithFrame:CGRectMake(10, 10, 30, 30)]; + + [v12 setViewName:@"Subview with cursorUpdate"]; + [v12 setViewColor:[CPColor blueColor]]; + [v12 setViewCursor:[CPCursor crosshairCursor]]; + + var t = [[CPTrackingArea alloc] initWithRect:CGRectMakeZero() + options:CPTrackingMouseEnteredAndExited | CPTrackingCursorUpdate | CPTrackingActiveInKeyWindow | CPTrackingInVisibleRect + owner:v12 + userInfo:nil]; + + [v12 addTrackingArea:t]; + + [v11 addSubview:v12]; + + // Not CPTrackingInVisibleRect + + w2 = [[SensibleViewTA alloc] initWithFrame:CGRectMake(160, 110, 50, 50)]; + + [w2 setViewName:@"Not CPTrackingInVisibleRect"]; + [w2 setViewColor:[CPColor greenColor]]; + [w2 setViewCursor:[CPCursor crosshairCursor]]; + + var t = [[CPTrackingArea alloc] initWithRect:CGRectMake(0, 0, 25, 25) + options:CPTrackingMouseEnteredAndExited | CPTrackingActiveInKeyWindow + owner:w2 + userInfo:nil]; + + [w2 addTrackingArea:t]; + + [p addSubview:w2]; + + [self addLabel:@"MouseEnteredAndExited\n(top-left quarter is the active area)" forView:w2]; + + // CPTrackingEnabledDuringMouseDrag + + w3 = [[SensibleView alloc] initWithFrame:CGRectMake(290, 110, 50, 50)]; + + [w3 setViewName:@"CPTrackingEnabledDuringMouseDrag"]; + [w3 setViewColor:[CPColor greenColor]]; + [w3 setViewCursor:[CPCursor crosshairCursor]]; + + var t = [[CPTrackingArea alloc] initWithRect:CGRectMakeZero() + options:CPTrackingMouseEnteredAndExited | CPTrackingActiveInKeyWindow | CPTrackingInVisibleRect | CPTrackingEnabledDuringMouseDrag + owner:w3 + userInfo:nil]; + + [w3 addTrackingArea:t]; + + [p addSubview:w3]; + + [self addLabel:@"MouseEnteredAndExited\nInVisibleRect\nEnabledDuringMouseDrag" forView:w3]; + + // View in CPScrollView + + [s1 setViewName:@"View in CPScrollView"]; + [s1 setViewColor:[CPColor greenColor]]; + [s1 setViewCursor:[CPCursor crosshairCursor]]; + + var t = [[CPTrackingArea alloc] initWithRect:CGRectMakeZero() + options:CPTrackingMouseEnteredAndExited | CPTrackingActiveInKeyWindow | CPTrackingInVisibleRect + owner:s1 + userInfo:nil]; + + [s1 addTrackingArea:t]; + + // No itinial TA + + w4 = [[SensibleViewAutoTA alloc] initWithFrame:CGRectMake(420, 110, 50, 50)]; + + [w4 setViewName:@"No itinial TA"]; + [w4 setViewColor:[CPColor greenColor]]; + [w4 setViewCursor:[CPCursor crosshairCursor]]; + + [p addSubview:w4]; + + [self addLabel:@"This one has no initial\ntracking area but\nuses updateTrackingAreas to\nattach one" forView:w4]; + + // Two views with tracking areas where the owner is not the view itself + + w5 = [[SensibleView alloc] initWithFrame:CGRectMake(550, 110, 50, 50)]; + + [w5 setViewName:@"firstView"]; + [w5 setViewColor:[CPColor greenColor]]; + [w5 setViewCursor:[CPCursor crosshairCursor]]; + + [p addSubview:w5]; + + [self addLabel:@"(firstView)\nThis view has a tracking area\nowned by the blue view" forView:w5]; + + w6 = [[SensibleView alloc] initWithFrame:CGRectMake(680, 110, 50, 50)]; + + [w6 setViewName:@"secondView"]; + [w6 setViewColor:[CPColor greenColor]]; + [w6 setViewCursor:[CPCursor crosshairCursor]]; + + [p addSubview:w6]; + + [self addLabel:@"(secondView)\nThis view has a tracking area\nowned by the blue view" forView:w6]; + + w7 = [[SensibleView alloc] initWithFrame:CGRectMake(810, 110, 50, 50)]; + + [w7 setViewName:@"masterView"]; + [w7 setViewColor:[CPColor blueColor]]; + [w7 setViewCursor:[CPCursor crosshairCursor]]; + + [p addSubview:w7]; + + [self addLabel:@"I'm the owner of the\ntracking areas of\nthe 2 views on my left" forView:w7]; + + var t = [[CPTrackingArea alloc] initWithRect:CGRectMakeZero() + options:CPTrackingMouseEnteredAndExited | CPTrackingActiveInKeyWindow | CPTrackingInVisibleRect + owner:w7 + userInfo:@{ @"trigger": @"View 1" } ]; + + [w5 addTrackingArea:t]; + + var t = [[CPTrackingArea alloc] initWithRect:CGRectMakeZero() + options:CPTrackingMouseEnteredAndExited | CPTrackingActiveInKeyWindow | CPTrackingInVisibleRect + owner:w7 + userInfo:@{ @"trigger": @"View 2" } ]; + + [w6 addTrackingArea:t]; + + + // Cursor update complex test + + for (var i = 0; i < 10; i++) + { + var v = [[SensibleView alloc] initWithFrame:CGRectMake((i == 0 ? 50 : 20), (i == 0 ? 240 : 20), 400-(i*40), 400-(i*40))]; + + [p addSubview:v]; + p = v; + + [v setViewName:[CPString stringWithFormat:@"v%d",i]]; + + var c = [CPColor colorWithHexString:[CPString stringWithFormat:@"%d%d%d%d%d%d",i,i,i,i,i,i]]; + + [v setViewColor:c]; + + switch (i) + { + case 0: [v setViewCursor:[CPCursor crosshairCursor]]; break; + case 1: [v setViewCursor:[CPCursor pointingHandCursor]]; break; + case 2: [v setViewCursor:[CPCursor resizeNorthwestCursor]]; break; + case 3: [v setViewCursor:[CPCursor IBeamCursor]]; break; + case 4: [v setViewCursor:[CPCursor dragCopyCursor]]; break; + case 5: [v setViewCursor:[CPCursor dragLinkCursor]]; break; + case 6: [v setViewCursor:[CPCursor contextualMenuCursor]]; break; + case 7: [v setViewCursor:[CPCursor openHandCursor]]; break; + case 8: [v setViewCursor:[CPCursor closedHandCursor]]; break; + case 9: [v setViewCursor:[CPCursor resizeNorthSouthCursor]]; break; + } + + var t = [[CPTrackingArea alloc] initWithRect:CGRectMakeZero() + options:CPTrackingMouseEnteredAndExited | CPTrackingCursorUpdate | CPTrackingActiveInKeyWindow | CPTrackingInVisibleRect | CPTrackingEnabledDuringMouseDrag + owner:v + userInfo:nil]; + [v addTrackingArea:t]; + } + + + var p = [theWindow contentView]; + + for (var i = 0; i < 10; i++) + { + var v = [[SensibleView alloc] initWithFrame:CGRectMake((i == 0 ? 460 : 0), (i == 0 ? 240 : 0), 400-(i*40), 400-(i*40))]; + + [p addSubview:v]; + p = v; + + [v setViewName:[CPString stringWithFormat:@"v%d",i]]; + + var c = [CPColor colorWithHexString:[CPString stringWithFormat:@"%d%d%d%d%d%d",i,i,i,i,i,i]]; + + [v setViewColor:c]; + + switch (i) + { + case 0: [v setViewCursor:[CPCursor crosshairCursor]]; break; + case 1: [v setViewCursor:[CPCursor pointingHandCursor]]; break; + case 2: [v setViewCursor:[CPCursor resizeNorthwestCursor]]; break; + case 3: [v setViewCursor:[CPCursor IBeamCursor]]; break; + case 4: [v setViewCursor:[CPCursor dragCopyCursor]]; break; + case 5: [v setViewCursor:[CPCursor dragLinkCursor]]; break; + case 6: [v setViewCursor:[CPCursor contextualMenuCursor]]; break; + case 7: [v setViewCursor:[CPCursor openHandCursor]]; break; + case 8: [v setViewCursor:[CPCursor closedHandCursor]]; break; + case 9: [v setViewCursor:[CPCursor resizeNorthSouthCursor]]; break; + } + + var t = [[CPTrackingArea alloc] initWithRect:CGRectMakeZero() + options:CPTrackingMouseEnteredAndExited | CPTrackingCursorUpdate | CPTrackingActiveInKeyWindow | CPTrackingInVisibleRect + owner:v + userInfo:nil]; + [v addTrackingArea:t]; + } + + var item = [CPButton buttonWithTitle:@"Add a view that catches cursor updates but not mouse entered/exited events"]; + + [item setTarget:self]; + [item setAction:@selector(showHideView:)]; + [item setCenter:CGPointMake(455, 660)]; + + [[theWindow contentView] addSubview:item]; +} + +- (void)showHideView:(id)aSender +{ + if (!cursorCapturingView) + { + cursorCapturingView = [[SensibleView alloc] initWithFrame:CGRectMake(250, 440, 410, 200)]; + + [cursorCapturingView setViewColor:[CPColor colorWithHexString:@"c8d3b2"]]; + [cursorCapturingView setViewName:@"cursorCapturingView"]; + [cursorCapturingView setViewCursor:[CPCursor disappearingItemCursor]]; + + [cursorCapturingView setAlphaValue:0.7]; + + var t = [[CPTrackingArea alloc] initWithRect:CGRectMakeZero() + options:CPTrackingCursorUpdate | CPTrackingActiveInKeyWindow | CPTrackingInVisibleRect + owner:cursorCapturingView + userInfo:nil]; + [cursorCapturingView addTrackingArea:t]; + + + [[theWindow contentView] addSubview:cursorCapturingView]; + + [aSender setTitle:@"Hide the view catching cursor updates but not mouse entered/exited events"]; + } + else if ([cursorCapturingView isHidden]) + { + [cursorCapturingView setHidden:NO]; + + [aSender setTitle:@"Hide the view catching cursor updates but not mouse entered/exited events"]; + } + else + { + [cursorCapturingView setHidden:YES]; + + [aSender setTitle:@"Add a view that catches cursor updates but not mouse entered/exited events"]; + } +} + +- (void)addLabel:(CPString)title forView:(CPView)view +{ + var label = [CPTextField labelWithTitle:title], + labelSize = [label frameSize], + viewFrame = [view frame]; + + [label setFrameOrigin:CGPointMake(viewFrame.origin.x + viewFrame.size.width / 2 - labelSize.width / 2, viewFrame.origin.y + viewFrame.size.height + 4)]; + [label setFont:[CPFont systemFontOfSize:9]]; + [label setAlignment:CPCenterTextAlignment]; + [label setVerticalAlignment:CPTopVerticalTextAlignment]; + + [[view superview] addSubview:label]; +} + +@end + +@implementation SensibleView : CPView +{ + CPString viewName @accessors; + CPCursor viewCursor @accessors; + CPColor viewColor; + CPTextField coords; +} + +- (id)initWithFrame:(CGRect)aFrame +{ + self = [super initWithFrame:aFrame]; + + if (self) + { + coords = [CPTextField labelWithTitle:@"WWWW,WWWW"]; + [coords setFont:[CPFont systemFontOfSize:9]]; + [coords setAlignment:CPCenterTextAlignment]; + [coords setCenter:CGPointMake(25,25)]; + [coords setStringValue:@""]; + + [self addSubview:coords]; + } + + return self; +} + +- (void)mouseEntered:(CPEvent)anEvent +{ + CPLog.trace("mouseEntered @"+viewName); + + [self setBackgroundColor:[CPColor redColor]]; + + var trigger = [[[anEvent trackingArea] userInfo] valueForKey:@"trigger"]; + + if (trigger) + [coords setStringValue:trigger]; +} + +- (void)mouseExited:(CPEvent)anEvent +{ + CPLog.trace("mouseExited @"+viewName); + + [self setBackgroundColor:viewColor]; + + [coords setStringValue:@""]; +} + +- (void)mouseMoved:(CPEvent)anEvent +{ + var l = [anEvent locationInWindow]; + + [coords setStringValue:[CPString stringWithFormat:@"%d,%d",l.x,l.y]]; +} + +- (void)cursorUpdate:(CPEvent)anEvent +{ + CPLog.trace("cursorUpdate @"+viewName); + + if (viewCursor) + [viewCursor set]; +} + +- (void)setViewColor:(CPColor)aColor +{ + viewColor = aColor; + [self setBackgroundColor:aColor]; +} + +@end + +@implementation SensibleViewWithoutCursorUpdate : CPView +{ + CPString viewName @accessors; + CPCursor viewCursor @accessors; + CPColor viewColor; + CPTextField coords; +} + +- (id)initWithFrame:(CGRect)aFrame +{ + self = [super initWithFrame:aFrame]; + + if (self) + { + coords = [CPTextField labelWithTitle:@"WWWW,WWWW"]; + [coords setFont:[CPFont systemFontOfSize:9]]; + [coords setAlignment:CPCenterTextAlignment]; + [coords setCenter:CGPointMake(25,25)]; + [coords setStringValue:@""]; + + [self addSubview:coords]; + } + + return self; +} + +- (void)mouseEntered:(CPEvent)anEvent +{ + CPLog.trace("mouseEntered @"+viewName); + + [self setBackgroundColor:[CPColor redColor]]; + + var trigger = [[[anEvent trackingArea] userInfo] valueForKey:@"trigger"]; + + if (trigger) + [coords setStringValue:trigger]; +} + +- (void)mouseExited:(CPEvent)anEvent +{ + CPLog.trace("mouseExited @"+viewName); + + [self setBackgroundColor:viewColor]; + + [coords setStringValue:@""]; +} + +- (void)mouseMoved:(CPEvent)anEvent +{ + var l = [anEvent locationInWindow]; + + [coords setStringValue:[CPString stringWithFormat:@"%d,%d",l.x,l.y]]; +} + +- (void)setViewColor:(CPColor)aColor +{ + viewColor = aColor; + [self setBackgroundColor:aColor]; +} + +@end + +@implementation SensibleViewTA : SensibleView + +- (void)updateTrackingAreas +{ + CPLog.trace("updateTrackingAreas @"+viewName); + + [self removeAllTrackingAreas]; + + var t = [[CPTrackingArea alloc] initWithRect:CGRectMake(0, 0, 25, 25) + options:CPTrackingMouseEnteredAndExited | CPTrackingActiveInKeyWindow + owner:self + userInfo:nil]; + + [self addTrackingArea:t]; +} + +@end + +@implementation SensibleViewAutoTA : SensibleView + +- (void)updateTrackingAreas +{ + CPLog.trace("updateTrackingAreas @"+viewName); + + [self removeAllTrackingAreas]; + + var t = [[CPTrackingArea alloc] initWithRect:CGRectMakeZero() + options:CPTrackingMouseEnteredAndExited | CPTrackingActiveInKeyWindow | CPTrackingInVisibleRect + owner:self + userInfo:nil]; + + [self addTrackingArea:t]; +} + +@end + diff --git a/Tests/Manual/TrackingArea/Info.plist b/Tests/Manual/TrackingArea/Info.plist new file mode 100644 index 000000000..91b1e76fa --- /dev/null +++ b/Tests/Manual/TrackingArea/Info.plist @@ -0,0 +1,14 @@ + + + + + Main cib file base name + MainMenu.cib + CPBundleName + TrackingArea + CPBundleVersion + 1.0 + CPHumanReadableCopyright + Copyright © 2015, Your Company All rights reserved. + + diff --git a/Tests/Manual/TrackingArea/Jakefile b/Tests/Manual/TrackingArea/Jakefile new file mode 100644 index 000000000..51bb86ba2 --- /dev/null +++ b/Tests/Manual/TrackingArea/Jakefile @@ -0,0 +1,184 @@ +/* + * Jakefile + * TrackingArea + * + * Created by You on November 2, 2015. + * Copyright 2015, Your Company All rights reserved. + */ + +var ENV = require("system").env, + FILE = require("file"), + JAKE = require("jake"), + task = JAKE.task, + FileList = JAKE.FileList, + app = require("cappuccino/jake").app, + configuration = ENV["CONFIG"] || ENV["CONFIGURATION"] || ENV["c"] || "Debug", + OS = require("os"), + projectName = "TrackingArea"; + +app (projectName, function(task) +{ + ENV["OBJJ_INCLUDE_PATHS"] = "Frameworks"; + + if (configuration === "Debug") + ENV["OBJJ_INCLUDE_PATHS"] = FILE.join(ENV["OBJJ_INCLUDE_PATHS"], configuration); + + task.setBuildIntermediatesPath(FILE.join("Build", "TrackingArea.build", configuration)); + task.setBuildPath(FILE.join("Build", configuration)); + + task.setProductName("TrackingArea"); + task.setIdentifier("com.yourcompany.TrackingArea"); + task.setVersion("1.0"); + task.setAuthor("Your Company"); + task.setEmail("feedback @nospam@ yourcompany.com"); + task.setSummary("TrackingArea"); + task.setSources(new FileList("**/*.j").exclude(FILE.join("Build", "**")).exclude(FILE.join("Frameworks", "Source", "**"))); + task.setResources(new FileList("Resources/**")); + task.setIndexFilePath("index.html"); + task.setInfoPlistPath("Info.plist"); + + if (configuration === "Debug") + task.setCompilerFlags("-DDEBUG -g"); + else + task.setCompilerFlags("-O2"); +}); + +task ("default", [projectName], function() +{ + printResults(configuration); +}); + +task ("build", ["default"], function() +{ + updateApplicationSize(); +}); + +task ("debug", function() +{ + configuration = ENV["CONFIGURATION"] = "Debug"; + JAKE.subjake(["."], "build", ENV); +}); + +task ("release", function() +{ + configuration = ENV["CONFIGURATION"] = "Release"; + JAKE.subjake(["."], "build", ENV); +}); + +task ("run", ["debug"], function() +{ + OS.system(["open", FILE.join("Build", "Debug", projectName, "index.html")]); +}); + +task ("run-release", ["release"], function() +{ + OS.system(["open", FILE.join("Build", "Release", projectName, "index.html")]); +}); + +task ("deploy", ["release"], function() +{ + FILE.mkdirs(FILE.join("Build", "Deployment", projectName)); + OS.system(["press", "-f", FILE.join("Build", "Release", projectName), FILE.join("Build", "Deployment", projectName)]); + printResults("Deployment") +}); + +task ("desktop", ["release"], function() +{ + FILE.mkdirs(FILE.join("Build", "Desktop", projectName)); + require("cappuccino/nativehost").buildNativeHost(FILE.join("Build", "Release", projectName), FILE.join("Build", "Desktop", projectName, "TrackingArea.app")); + printResults("Desktop") +}); + +task ("run-desktop", ["desktop"], function() +{ + OS.system([FILE.join("Build", "Desktop", projectName, "TrackingArea.app", "Contents", "MacOS", "NativeHost"), "-i"]); +}); + +function printResults(configuration) +{ + print("----------------------------"); + print(configuration+" app built at path: "+FILE.join("Build", configuration, projectName)); + print("----------------------------"); +} + +function updateApplicationSize() +{ + print("Calculating application file sizes..."); + + var contents = FILE.read(FILE.join("Build", configuration, projectName, "Info.plist"), { charset:"UTF-8" }), + format = CFPropertyList.sniffedFormatOfString(contents), + plist = CFPropertyList.propertyListFromString(contents), + totalBytes = {executable:0, data:0, mhtml:0}; + + // Get the size of all framework executables and sprite data + var frameworksDir = "Frameworks"; + + if (configuration === "Debug") + frameworksDir = FILE.join(frameworksDir, "Debug"); + + var frameworks = FILE.list(frameworksDir); + + frameworks.forEach(function(framework) + { + if (framework !== "Source") + addBundleFileSizes(FILE.join(frameworksDir, framework), totalBytes); + }); + + // Read in the default theme name, and attempt to get its size + var themeName = plist.valueForKey("CPDefaultTheme") || "Aristo2", + themePath = nil; + + if (themeName === "Aristo" || themeName === "Aristo2") + themePath = FILE.join(frameworksDir, "AppKit", "Resources", themeName + ".blend"); + else + themePath = FILE.join("Frameworks", "Resources", themeName + ".blend"); + + if (FILE.isDirectory(themePath)) + addBundleFileSizes(themePath, totalBytes); + + // Add sizes for the app + addBundleFileSizes(FILE.join("Build", configuration, projectName), totalBytes); + + print("Executables: " + totalBytes.executable + ", sprite data: " + totalBytes.data + ", total: " + (totalBytes.executable + totalBytes.data)); + + var dict = new CFMutableDictionary(); + + dict.setValueForKey("executable", totalBytes.executable); + dict.setValueForKey("data", totalBytes.data); + dict.setValueForKey("mhtml", totalBytes.mhtml); + + plist.setValueForKey("CPApplicationSize", dict); + + FILE.write(FILE.join("Build", configuration, projectName, "Info.plist"), CFPropertyList.stringFromPropertyList(plist, format), { charset:"UTF-8" }); +} + +function addBundleFileSizes(bundlePath, totalBytes) +{ + var bundleName = FILE.basename(bundlePath), + environment = bundleName === "Foundation" ? "Objj" : "Browser", + bundlePath = FILE.join(bundlePath, environment + ".environment"); + + if (FILE.isDirectory(bundlePath)) + { + var filename = bundleName + ".sj", + filePath = new FILE.Path(FILE.join(bundlePath, filename)); + + if (filePath.exists()) + totalBytes.executable += filePath.size(); + + filePath = new FILE.Path(FILE.join(bundlePath, "dataURLs.txt")); + + if (filePath.exists()) + totalBytes.data += filePath.size(); + + filePath = new FILE.Path(FILE.join(bundlePath, "MHTMLData.txt")); + + if (filePath.exists()) + totalBytes.mhtml += filePath.size(); + + filePath = new FILE.Path(FILE.join(bundlePath, "MHTMLPaths.txt")); + + if (filePath.exists()) + totalBytes.mhtml += filePath.size(); + } +} diff --git a/Tests/Manual/TrackingArea/Resources/MainMenu.cib b/Tests/Manual/TrackingArea/Resources/MainMenu.cib new file mode 100644 index 000000000..c9ecff6f4 --- /dev/null +++ b/Tests/Manual/TrackingArea/Resources/MainMenu.cib @@ -0,0 +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;21E;D;K;6;CP$UIDd;2;22E;D;K;6;CP$UIDd;2;23E;D;K;6;CP$UIDd;2;25E;D;K;6;CP$UIDd;2;26E;D;K;6;CP$UIDd;2;27E;D;K;6;CP$UIDd;2;28E;D;K;6;CP$UIDd;2;29E;D;K;6;CP$UIDd;2;30E;D;K;6;CP$UIDd;2;31E;D;K;6;CP$UIDd;2;32E;D;K;6;CP$UIDd;2;33E;D;K;6;CP$UIDd;2;34E;D;K;6;CP$UIDd;2;35E;D;K;6;CP$UIDd;2;36E;D;K;6;CP$UIDd;2;37E;D;K;6;CP$UIDd;2;38E;D;K;6;CP$UIDd;2;39E;D;K;6;CP$UIDd;2;40E;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;44E;D;K;6;CP$UIDd;2;45E;D;K;6;CP$UIDd;2;46E;D;K;6;CP$UIDd;2;47E;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;51E;D;K;6;CP$UIDd;2;52E;D;K;6;CP$UIDd;2;53E;D;K;6;CP$UIDd;2;54E;D;K;6;CP$UIDd;2;55E;D;K;6;CP$UIDd;2;56E;D;K;6;CP$UIDd;2;57E;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;58E;D;K;6;CP$UIDd;2;60E;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;65E;D;K;6;CP$UIDd;2;66E;D;K;6;CP$UIDd;2;67E;D;K;6;CP$UIDd;2;68E;D;K;6;CP$UIDd;2;69E;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;73E;D;K;6;CP$UIDd;2;74E;D;K;6;CP$UIDd;2;75E;D;K;6;CP$UIDd;2;76E;D;K;6;CP$UIDd;2;77E;D;K;6;CP$UIDd;2;78E;D;K;6;CP$UIDd;2;79E;D;K;6;CP$UIDd;2;80E;D;K;6;CP$UIDd;2;81E;D;K;6;CP$UIDd;2;82E;D;K;6;CP$UIDd;2;83E;D;K;6;CP$UIDd;2;84E;D;K;6;CP$UIDd;2;85E;D;K;6;CP$UIDd;2;86E;D;K;6;CP$UIDd;2;87E;D;K;6;CP$UIDd;2;88E;D;K;6;CP$UIDd;2;89E;D;K;6;CP$UIDd;2;90E;D;K;6;CP$UIDd;2;91E;D;K;6;CP$UIDd;2;92E;D;K;6;CP$UIDd;2;93E;D;K;6;CP$UIDd;2;94E;D;K;6;CP$UIDd;2;95E;D;K;6;CP$UIDd;2;96E;D;K;6;CP$UIDd;2;97E;D;K;6;CP$UIDd;2;98E;D;K;6;CP$UIDd;2;99E;D;K;6;CP$UIDd;3;100E;D;K;6;CP$UIDd;3;101E;D;K;6;CP$UIDd;3;102E;D;K;6;CP$UIDd;3;103E;D;K;6;CP$UIDd;3;104E;D;K;6;CP$UIDd;3;105E;D;K;6;CP$UIDd;3;106E;D;K;6;CP$UIDd;3;107E;D;K;6;CP$UIDd;3;108E;D;K;6;CP$UIDd;3;109E;D;K;6;CP$UIDd;3;110E;D;K;6;CP$UIDd;3;111E;D;K;6;CP$UIDd;3;112E;D;K;6;CP$UIDd;3;113E;D;K;6;CP$UIDd;3;114E;D;K;6;CP$UIDd;3;115E;D;K;6;CP$UIDd;3;116E;D;K;6;CP$UIDd;3;117E;D;K;6;CP$UIDd;3;118E;D;K;6;CP$UIDd;3;119E;D;K;6;CP$UIDd;3;120E;D;K;6;CP$UIDd;3;121E;D;K;6;CP$UIDd;3;122E;D;K;6;CP$UIDd;3;123E;D;K;6;CP$UIDd;3;124E;D;K;6;CP$UIDd;3;125E;D;K;6;CP$UIDd;3;126E;D;K;6;CP$UIDd;3;128E;D;K;6;CP$UIDd;3;130E;D;K;6;CP$UIDd;3;132E;D;K;6;CP$UIDd;3;134E;D;K;6;CP$UIDd;3;135E;D;K;6;CP$UIDd;3;136E;D;K;6;CP$UIDd;3;137E;D;K;6;CP$UIDd;3;138E;D;K;6;CP$UIDd;3;139E;D;K;6;CP$UIDd;3;141E;D;K;6;CP$UIDd;3;143E;D;K;6;CP$UIDd;3;144E;D;K;6;CP$UIDd;3;145E;D;K;6;CP$UIDd;3;147E;D;K;6;CP$UIDd;3;148E;D;K;6;CP$UIDd;3;149E;D;K;6;CP$UIDd;3;150E;D;K;6;CP$UIDd;3;152E;D;K;6;CP$UIDd;3;154E;D;K;6;CP$UIDd;1;0E;D;K;6;CP$UIDd;3;155E;D;K;6;CP$UIDd;1;0E;D;K;6;CP$UIDd;3;156E;D;K;6;CP$UIDd;1;0E;D;K;6;CP$UIDd;3;157E;D;K;6;CP$UIDd;3;158E;D;K;6;CP$UIDd;3;160E;D;K;6;CP$UIDd;3;162E;D;K;6;CP$UIDd;1;0E;D;K;6;CP$UIDd;3;163E;D;K;6;CP$UIDd;1;0E;D;K;6;CP$UIDd;3;164E;D;K;6;CP$UIDd;1;0E;D;K;6;CP$UIDd;3;165E;D;K;6;CP$UIDd;1;0E;D;K;6;CP$UIDd;3;166E;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;60E;D;K;6;CP$UIDd;2;62E;D;K;6;CP$UIDd;2;63E;D;K;6;CP$UIDd;2;63E;D;K;6;CP$UIDd;2;63E;D;K;6;CP$UIDd;2;63E;D;K;6;CP$UIDd;2;63E;D;K;6;CP$UIDd;2;60E;D;K;6;CP$UIDd;2;69E;D;K;6;CP$UIDd;2;70E;D;K;6;CP$UIDd;2;70E;D;K;6;CP$UIDd;2;70E;D;K;6;CP$UIDd;2;73E;D;K;6;CP$UIDd;2;74E;D;K;6;CP$UIDd;2;70E;D;K;6;CP$UIDd;2;70E;D;K;6;CP$UIDd;2;70E;D;K;6;CP$UIDd;2;70E;D;K;6;CP$UIDd;2;70E;D;K;6;CP$UIDd;2;60E;D;K;6;CP$UIDd;2;81E;D;K;6;CP$UIDd;2;82E;D;K;6;CP$UIDd;2;82E;D;K;6;CP$UIDd;2;82E;D;K;6;CP$UIDd;2;82E;D;K;6;CP$UIDd;2;82E;D;K;6;CP$UIDd;2;82E;D;K;6;CP$UIDd;2;82E;D;K;6;CP$UIDd;2;82E;D;K;6;CP$UIDd;2;82E;D;K;6;CP$UIDd;2;82E;D;K;6;CP$UIDd;2;92E;D;K;6;CP$UIDd;2;93E;D;K;6;CP$UIDd;2;93E;D;K;6;CP$UIDd;2;93E;D;K;6;CP$UIDd;2;93E;D;K;6;CP$UIDd;2;93E;D;K;6;CP$UIDd;2;82E;D;K;6;CP$UIDd;2;99E;D;K;6;CP$UIDd;3;100E;D;K;6;CP$UIDd;3;100E;D;K;6;CP$UIDd;3;100E;D;K;6;CP$UIDd;3;100E;D;K;6;CP$UIDd;2;82E;D;K;6;CP$UIDd;3;105E;D;K;6;CP$UIDd;3;106E;D;K;6;CP$UIDd;3;106E;D;K;6;CP$UIDd;3;106E;D;K;6;CP$UIDd;2;82E;D;K;6;CP$UIDd;3;110E;D;K;6;CP$UIDd;3;111E;D;K;6;CP$UIDd;3;111E;D;K;6;CP$UIDd;2;60E;D;K;6;CP$UIDd;3;114E;D;K;6;CP$UIDd;3;115E;D;K;6;CP$UIDd;3;115E;D;K;6;CP$UIDd;2;60E;D;K;6;CP$UIDd;3;118E;D;K;6;CP$UIDd;3;119E;D;K;6;CP$UIDd;3;119E;D;K;6;CP$UIDd;3;119E;D;K;6;CP$UIDd;3;119E;D;K;6;CP$UIDd;2;60E;D;K;6;CP$UIDd;3;124E;D;K;6;CP$UIDd;3;125E;D;K;6;CP$UIDd;2;11E;D;K;6;CP$UIDd;3;128E;D;K;6;CP$UIDd;3;130E;D;K;6;CP$UIDd;3;132E;D;K;6;CP$UIDd;3;132E;D;K;6;CP$UIDd;3;132E;D;K;6;CP$UIDd;3;130E;D;K;6;CP$UIDd;3;137E;D;K;6;CP$UIDd;3;137E;D;K;6;CP$UIDd;3;130E;D;K;6;CP$UIDd;3;141E;D;K;6;CP$UIDd;3;143E;D;K;6;CP$UIDd;3;144E;D;K;6;CP$UIDd;3;141E;D;K;6;CP$UIDd;3;141E;D;K;6;CP$UIDd;3;130E;D;K;6;CP$UIDd;3;149E;D;K;6;CP$UIDd;3;150E;D;K;6;CP$UIDd;3;152E;D;K;6;CP$UIDd;3;154E;D;K;6;CP$UIDd;3;152E;D;K;6;CP$UIDd;3;155E;D;K;6;CP$UIDd;3;152E;D;K;6;CP$UIDd;3;156E;D;K;6;CP$UIDd;3;149E;D;K;6;CP$UIDd;3;149E;D;K;6;CP$UIDd;3;149E;D;K;6;CP$UIDd;3;130E;D;K;6;CP$UIDd;3;162E;D;K;6;CP$UIDd;3;130E;D;K;6;CP$UIDd;3;163E;D;K;6;CP$UIDd;3;130E;D;K;6;CP$UIDd;3;164E;D;K;6;CP$UIDd;3;130E;D;K;6;CP$UIDd;3;165E;D;K;6;CP$UIDd;2;11E;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;3;167E;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;3;168E;E;D;K;10;$classnameS;31;CPCibRuntimeAttributesConnectorK;8;$classesA;S;31;CPCibRuntimeAttributesConnectorS;14;CPCibConnectorS;8;CPObjectE;E;D;K;6;$classD;K;6;CP$UIDd;2;14E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;3;135E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;1;0E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;1;0E;K;40;CPCibRuntimeAttributesConnectorObjectKeyD;K;6;CP$UIDd;3;135E;K;42;CPCibRuntimeAttributesConnectorKeyPathsKeyD;K;6;CP$UIDd;3;169E;K;40;CPCibRuntimeAttributesConnectorValuesKeyD;K;6;CP$UIDd;3;170E;E;D;K;6;$classD;K;6;CP$UIDd;2;14E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;3;138E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;1;0E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;1;0E;K;40;CPCibRuntimeAttributesConnectorObjectKeyD;K;6;CP$UIDd;3;138E;K;42;CPCibRuntimeAttributesConnectorKeyPathsKeyD;K;6;CP$UIDd;3;171E;K;40;CPCibRuntimeAttributesConnectorValuesKeyD;K;6;CP$UIDd;3;172E;E;D;K;6;$classD;K;6;CP$UIDd;2;14E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;3;134E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;1;0E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;1;0E;K;40;CPCibRuntimeAttributesConnectorObjectKeyD;K;6;CP$UIDd;3;134E;K;42;CPCibRuntimeAttributesConnectorKeyPathsKeyD;K;6;CP$UIDd;3;173E;K;40;CPCibRuntimeAttributesConnectorValuesKeyD;K;6;CP$UIDd;3;174E;E;D;K;6;$classD;K;6;CP$UIDd;2;14E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;3;136E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;1;0E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;1;0E;K;40;CPCibRuntimeAttributesConnectorObjectKeyD;K;6;CP$UIDd;3;136E;K;42;CPCibRuntimeAttributesConnectorKeyPathsKeyD;K;6;CP$UIDd;3;175E;K;40;CPCibRuntimeAttributesConnectorValuesKeyD;K;6;CP$UIDd;3;176E;E;D;K;6;$classD;K;6;CP$UIDd;2;14E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;3;139E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;1;0E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;1;0E;K;40;CPCibRuntimeAttributesConnectorObjectKeyD;K;6;CP$UIDd;3;139E;K;42;CPCibRuntimeAttributesConnectorKeyPathsKeyD;K;6;CP$UIDd;3;177E;K;40;CPCibRuntimeAttributesConnectorValuesKeyD;K;6;CP$UIDd;3;178E;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;20E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;2;11E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;3;166E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;179E;E;D;K;6;$classD;K;6;CP$UIDd;2;20E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;3;166E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;3;145E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;180E;E;D;K;6;$classD;K;6;CP$UIDd;2;20E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;3;166E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;3;128E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;181E;E;D;K;10;$classnameS;21;CPCibControlConnectorK;8;$classesA;S;21;CPCibControlConnectorS;14;CPCibConnectorS;8;CPObjectE;E;D;K;6;$classD;K;6;CP$UIDd;2;24E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;3;123E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;1;0E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;182E;E;D;K;6;$classD;K;6;CP$UIDd;2;24E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;3;120E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;1;0E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;183E;E;D;K;6;$classD;K;6;CP$UIDd;2;24E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;2;64E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;2;11E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;184E;E;D;K;6;$classD;K;6;CP$UIDd;2;24E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;2;72E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;1;0E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;185E;E;D;K;6;$classD;K;6;CP$UIDd;2;24E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;2;77E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;1;0E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;186E;E;D;K;6;$classD;K;6;CP$UIDd;2;24E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;2;78E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;1;0E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;187E;E;D;K;6;$classD;K;6;CP$UIDd;2;24E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;2;79E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;1;0E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;188E;E;D;K;6;$classD;K;6;CP$UIDd;2;24E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;2;71E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;1;0E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;189E;E;D;K;6;$classD;K;6;CP$UIDd;2;24E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;3;126E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;1;0E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;190E;E;D;K;6;$classD;K;6;CP$UIDd;2;24E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;2;80E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;1;0E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;191E;E;D;K;6;$classD;K;6;CP$UIDd;2;24E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;2;75E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;1;0E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;192E;E;D;K;6;$classD;K;6;CP$UIDd;2;24E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;2;68E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;2;58E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;193E;E;D;K;6;$classD;K;6;CP$UIDd;2;24E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;3;113E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;1;0E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;194E;E;D;K;6;$classD;K;6;CP$UIDd;2;24E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;3;112E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;1;0E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;195E;E;D;K;6;$classD;K;6;CP$UIDd;2;24E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;2;87E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;1;0E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;196E;E;D;K;6;$classD;K;6;CP$UIDd;2;24E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;2;90E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;1;0E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;197E;E;D;K;6;$classD;K;6;CP$UIDd;2;24E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;2;86E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;1;0E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;198E;E;D;K;6;$classD;K;6;CP$UIDd;2;24E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;3;102E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;1;0E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;199E;E;D;K;6;$classD;K;6;CP$UIDd;2;24E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;2;89E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;1;0E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;200E;E;D;K;6;$classD;K;6;CP$UIDd;2;24E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;2;88E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;1;0E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;201E;E;D;K;6;$classD;K;6;CP$UIDd;2;24E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;3;101E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;1;0E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;202E;E;D;K;6;$classD;K;6;CP$UIDd;2;24E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;2;83E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;1;0E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;203E;E;D;K;6;$classD;K;6;CP$UIDd;2;24E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;2;94E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;1;0E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;204E;E;D;K;6;$classD;K;6;CP$UIDd;2;24E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;2;98E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;1;0E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;205E;E;D;K;6;$classD;K;6;CP$UIDd;2;24E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;2;84E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;1;0E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;206E;E;D;K;6;$classD;K;6;CP$UIDd;2;24E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;3;103E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;1;0E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;207E;E;D;K;6;$classD;K;6;CP$UIDd;2;24E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;3;121E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;1;0E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;208E;E;D;K;6;$classD;K;6;CP$UIDd;2;24E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;3;116E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;1;0E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;209E;E;D;K;6;$classD;K;6;CP$UIDd;2;24E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;3;117E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;1;0E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;210E;E;D;K;6;$classD;K;6;CP$UIDd;2;24E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;3;104E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;1;0E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;211E;E;D;K;6;$classD;K;6;CP$UIDd;2;24E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;3;107E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;1;0E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;212E;E;D;K;6;$classD;K;6;CP$UIDd;2;24E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;3;108E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;1;0E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;213E;E;D;K;6;$classD;K;6;CP$UIDd;2;24E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;3;109E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;1;0E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;214E;E;D;K;6;$classD;K;6;CP$UIDd;2;10E;K;27;_CPCibCustomObjectClassNameD;K;6;CP$UIDd;3;167E;E;D;K;10;$classnameS;6;CPMenuK;8;$classesA;S;6;CPMenuS;8;CPObjectE;E;D;K;6;$classD;K;6;CP$UIDd;2;59E;K;14;CPMenuTitleKeyD;K;6;CP$UIDd;3;215E;K;13;CPMenuNameKeyD;K;6;CP$UIDd;3;216E;K;14;CPMenuItemsKeyD;K;6;CP$UIDd;3;217E;E;D;K;10;$classnameS;10;CPMenuItemK;8;$classesA;S;10;CPMenuItemS;8;CPObjectE;E;D;K;6;$classD;K;6;CP$UIDd;2;61E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;218E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;2;63E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;3;219E;K;20;CPMenuItemSubmenuKeyD;K;6;CP$UIDd;2;63E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;2;60E;K;38;CPMenuItemKeyEquivalentModifierMaskKeyD;K;6;CP$UIDd;3;220E;E;D;K;6;$classD;K;6;CP$UIDd;2;59E;K;14;CPMenuTitleKeyD;K;6;CP$UIDd;3;218E;K;13;CPMenuNameKeyD;K;6;CP$UIDd;3;221E;K;14;CPMenuItemsKeyD;K;6;CP$UIDd;3;222E;E;D;K;6;$classD;K;6;CP$UIDd;2;61E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;223E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;2;63E;E;D;K;6;$classD;K;6;CP$UIDd;2;61E;K;24;CPMenuItemIsSeparatorKeyD;K;6;CP$UIDd;3;224E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;225E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;22;CPMenuItemIsEnabledKeyD;K;6;CP$UIDd;3;226E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;2;63E;K;38;CPMenuItemKeyEquivalentModifierMaskKeyD;K;6;CP$UIDd;3;220E;E;D;K;6;$classD;K;6;CP$UIDd;2;61E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;227E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;2;63E;K;26;CPMenuItemKeyEquivalentKeyD;K;6;CP$UIDd;3;228E;K;38;CPMenuItemKeyEquivalentModifierMaskKeyD;K;6;CP$UIDd;3;220E;E;D;K;6;$classD;K;6;CP$UIDd;2;61E;K;24;CPMenuItemIsSeparatorKeyD;K;6;CP$UIDd;3;224E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;225E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;22;CPMenuItemIsEnabledKeyD;K;6;CP$UIDd;3;226E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;2;63E;K;38;CPMenuItemKeyEquivalentModifierMaskKeyD;K;6;CP$UIDd;3;220E;E;D;K;6;$classD;K;6;CP$UIDd;2;61E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;229E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;2;63E;K;26;CPMenuItemKeyEquivalentKeyD;K;6;CP$UIDd;3;230E;K;38;CPMenuItemKeyEquivalentModifierMaskKeyD;K;6;CP$UIDd;3;220E;E;D;K;6;$classD;K;6;CP$UIDd;2;61E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;231E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;2;70E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;3;219E;K;20;CPMenuItemSubmenuKeyD;K;6;CP$UIDd;2;70E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;2;60E;K;38;CPMenuItemKeyEquivalentModifierMaskKeyD;K;6;CP$UIDd;3;220E;E;D;K;6;$classD;K;6;CP$UIDd;2;59E;K;14;CPMenuTitleKeyD;K;6;CP$UIDd;3;231E;K;14;CPMenuItemsKeyD;K;6;CP$UIDd;3;232E;E;D;K;6;$classD;K;6;CP$UIDd;2;61E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;233E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;2;70E;K;26;CPMenuItemKeyEquivalentKeyD;K;6;CP$UIDd;3;234E;K;38;CPMenuItemKeyEquivalentModifierMaskKeyD;K;6;CP$UIDd;3;220E;E;D;K;6;$classD;K;6;CP$UIDd;2;61E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;235E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;2;70E;K;26;CPMenuItemKeyEquivalentKeyD;K;6;CP$UIDd;3;236E;K;38;CPMenuItemKeyEquivalentModifierMaskKeyD;K;6;CP$UIDd;3;220E;E;D;K;6;$classD;K;6;CP$UIDd;2;61E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;237E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;2;74E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;3;219E;K;20;CPMenuItemSubmenuKeyD;K;6;CP$UIDd;2;74E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;2;70E;K;38;CPMenuItemKeyEquivalentModifierMaskKeyD;K;6;CP$UIDd;3;220E;E;D;K;6;$classD;K;6;CP$UIDd;2;59E;K;14;CPMenuTitleKeyD;K;6;CP$UIDd;3;237E;K;13;CPMenuNameKeyD;K;6;CP$UIDd;3;238E;K;14;CPMenuItemsKeyD;K;6;CP$UIDd;3;239E;E;D;K;6;$classD;K;6;CP$UIDd;2;61E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;240E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;2;74E;K;38;CPMenuItemKeyEquivalentModifierMaskKeyD;K;6;CP$UIDd;3;220E;E;D;K;6;$classD;K;6;CP$UIDd;2;61E;K;24;CPMenuItemIsSeparatorKeyD;K;6;CP$UIDd;3;224E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;225E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;22;CPMenuItemIsEnabledKeyD;K;6;CP$UIDd;3;226E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;2;70E;K;38;CPMenuItemKeyEquivalentModifierMaskKeyD;K;6;CP$UIDd;3;220E;E;D;K;6;$classD;K;6;CP$UIDd;2;61E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;241E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;2;70E;K;26;CPMenuItemKeyEquivalentKeyD;K;6;CP$UIDd;3;242E;K;38;CPMenuItemKeyEquivalentModifierMaskKeyD;K;6;CP$UIDd;3;220E;E;D;K;6;$classD;K;6;CP$UIDd;2;61E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;243E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;2;70E;K;26;CPMenuItemKeyEquivalentKeyD;K;6;CP$UIDd;3;244E;K;38;CPMenuItemKeyEquivalentModifierMaskKeyD;K;6;CP$UIDd;3;220E;E;D;K;6;$classD;K;6;CP$UIDd;2;61E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;245E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;2;70E;K;26;CPMenuItemKeyEquivalentKeyD;K;6;CP$UIDd;3;246E;K;38;CPMenuItemKeyEquivalentModifierMaskKeyD;K;6;CP$UIDd;3;247E;E;D;K;6;$classD;K;6;CP$UIDd;2;61E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;248E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;2;70E;E;D;K;6;$classD;K;6;CP$UIDd;2;61E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;249E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;2;82E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;3;219E;K;20;CPMenuItemSubmenuKeyD;K;6;CP$UIDd;2;82E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;2;60E;K;38;CPMenuItemKeyEquivalentModifierMaskKeyD;K;6;CP$UIDd;3;220E;E;D;K;6;$classD;K;6;CP$UIDd;2;59E;K;14;CPMenuTitleKeyD;K;6;CP$UIDd;3;249E;K;14;CPMenuItemsKeyD;K;6;CP$UIDd;3;250E;E;D;K;6;$classD;K;6;CP$UIDd;2;61E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;251E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;2;82E;K;26;CPMenuItemKeyEquivalentKeyD;K;6;CP$UIDd;3;252E;K;38;CPMenuItemKeyEquivalentModifierMaskKeyD;K;6;CP$UIDd;3;220E;E;D;K;6;$classD;K;6;CP$UIDd;2;61E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;253E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;2;82E;K;26;CPMenuItemKeyEquivalentKeyD;K;6;CP$UIDd;3;254E;K;38;CPMenuItemKeyEquivalentModifierMaskKeyD;K;6;CP$UIDd;3;247E;E;D;K;6;$classD;K;6;CP$UIDd;2;61E;K;24;CPMenuItemIsSeparatorKeyD;K;6;CP$UIDd;3;224E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;225E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;22;CPMenuItemIsEnabledKeyD;K;6;CP$UIDd;3;226E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;2;82E;K;38;CPMenuItemKeyEquivalentModifierMaskKeyD;K;6;CP$UIDd;3;220E;E;D;K;6;$classD;K;6;CP$UIDd;2;61E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;255E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;2;82E;K;26;CPMenuItemKeyEquivalentKeyD;K;6;CP$UIDd;3;256E;K;38;CPMenuItemKeyEquivalentModifierMaskKeyD;K;6;CP$UIDd;3;220E;E;D;K;6;$classD;K;6;CP$UIDd;2;61E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;257E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;2;82E;K;26;CPMenuItemKeyEquivalentKeyD;K;6;CP$UIDd;3;258E;K;38;CPMenuItemKeyEquivalentModifierMaskKeyD;K;6;CP$UIDd;3;220E;E;D;K;6;$classD;K;6;CP$UIDd;2;61E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;259E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;2;82E;K;26;CPMenuItemKeyEquivalentKeyD;K;6;CP$UIDd;3;260E;K;38;CPMenuItemKeyEquivalentModifierMaskKeyD;K;6;CP$UIDd;3;220E;E;D;K;6;$classD;K;6;CP$UIDd;2;61E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;261E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;2;82E;K;38;CPMenuItemKeyEquivalentModifierMaskKeyD;K;6;CP$UIDd;3;220E;E;D;K;6;$classD;K;6;CP$UIDd;2;61E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;262E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;2;82E;K;26;CPMenuItemKeyEquivalentKeyD;K;6;CP$UIDd;3;263E;K;38;CPMenuItemKeyEquivalentModifierMaskKeyD;K;6;CP$UIDd;3;220E;E;D;K;6;$classD;K;6;CP$UIDd;2;61E;K;24;CPMenuItemIsSeparatorKeyD;K;6;CP$UIDd;3;224E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;225E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;22;CPMenuItemIsEnabledKeyD;K;6;CP$UIDd;3;226E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;2;82E;K;38;CPMenuItemKeyEquivalentModifierMaskKeyD;K;6;CP$UIDd;3;220E;E;D;K;6;$classD;K;6;CP$UIDd;2;61E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;264E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;2;93E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;3;219E;K;20;CPMenuItemSubmenuKeyD;K;6;CP$UIDd;2;93E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;2;82E;K;38;CPMenuItemKeyEquivalentModifierMaskKeyD;K;6;CP$UIDd;3;220E;E;D;K;6;$classD;K;6;CP$UIDd;2;59E;K;14;CPMenuTitleKeyD;K;6;CP$UIDd;3;264E;K;14;CPMenuItemsKeyD;K;6;CP$UIDd;3;265E;E;D;K;6;$classD;K;6;CP$UIDd;2;61E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;266E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;16;CPMenuItemTagKeyD;K;6;CP$UIDd;3;267E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;2;93E;K;26;CPMenuItemKeyEquivalentKeyD;K;6;CP$UIDd;3;268E;K;38;CPMenuItemKeyEquivalentModifierMaskKeyD;K;6;CP$UIDd;3;220E;E;D;K;6;$classD;K;6;CP$UIDd;2;61E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;269E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;16;CPMenuItemTagKeyD;K;6;CP$UIDd;3;270E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;2;93E;K;26;CPMenuItemKeyEquivalentKeyD;K;6;CP$UIDd;3;271E;K;38;CPMenuItemKeyEquivalentModifierMaskKeyD;K;6;CP$UIDd;3;220E;E;D;K;6;$classD;K;6;CP$UIDd;2;61E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;272E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;16;CPMenuItemTagKeyD;K;6;CP$UIDd;3;273E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;2;93E;K;26;CPMenuItemKeyEquivalentKeyD;K;6;CP$UIDd;3;274E;K;38;CPMenuItemKeyEquivalentModifierMaskKeyD;K;6;CP$UIDd;3;247E;E;D;K;6;$classD;K;6;CP$UIDd;2;61E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;275E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;16;CPMenuItemTagKeyD;K;6;CP$UIDd;3;276E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;2;93E;K;26;CPMenuItemKeyEquivalentKeyD;K;6;CP$UIDd;3;277E;K;38;CPMenuItemKeyEquivalentModifierMaskKeyD;K;6;CP$UIDd;3;220E;E;D;K;6;$classD;K;6;CP$UIDd;2;61E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;278E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;2;93E;K;26;CPMenuItemKeyEquivalentKeyD;K;6;CP$UIDd;3;279E;K;38;CPMenuItemKeyEquivalentModifierMaskKeyD;K;6;CP$UIDd;3;220E;E;D;K;6;$classD;K;6;CP$UIDd;2;61E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;280E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;3;100E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;3;219E;K;20;CPMenuItemSubmenuKeyD;K;6;CP$UIDd;3;100E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;2;82E;K;38;CPMenuItemKeyEquivalentModifierMaskKeyD;K;6;CP$UIDd;3;220E;E;D;K;6;$classD;K;6;CP$UIDd;2;59E;K;14;CPMenuTitleKeyD;K;6;CP$UIDd;3;280E;K;14;CPMenuItemsKeyD;K;6;CP$UIDd;3;281E;E;D;K;6;$classD;K;6;CP$UIDd;2;61E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;282E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;3;100E;K;26;CPMenuItemKeyEquivalentKeyD;K;6;CP$UIDd;3;283E;K;38;CPMenuItemKeyEquivalentModifierMaskKeyD;K;6;CP$UIDd;3;220E;E;D;K;6;$classD;K;6;CP$UIDd;2;61E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;284E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;3;100E;K;26;CPMenuItemKeyEquivalentKeyD;K;6;CP$UIDd;3;285E;K;38;CPMenuItemKeyEquivalentModifierMaskKeyD;K;6;CP$UIDd;3;220E;E;D;K;6;$classD;K;6;CP$UIDd;2;61E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;286E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;3;100E;K;38;CPMenuItemKeyEquivalentModifierMaskKeyD;K;6;CP$UIDd;3;220E;E;D;K;6;$classD;K;6;CP$UIDd;2;61E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;287E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;3;100E;K;38;CPMenuItemKeyEquivalentModifierMaskKeyD;K;6;CP$UIDd;3;220E;E;D;K;6;$classD;K;6;CP$UIDd;2;61E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;288E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;3;106E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;3;219E;K;20;CPMenuItemSubmenuKeyD;K;6;CP$UIDd;3;106E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;2;82E;K;38;CPMenuItemKeyEquivalentModifierMaskKeyD;K;6;CP$UIDd;3;220E;E;D;K;6;$classD;K;6;CP$UIDd;2;59E;K;14;CPMenuTitleKeyD;K;6;CP$UIDd;3;288E;K;14;CPMenuItemsKeyD;K;6;CP$UIDd;3;289E;E;D;K;6;$classD;K;6;CP$UIDd;2;61E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;290E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;16;CPMenuItemTagKeyD;K;6;CP$UIDd;3;267E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;3;106E;K;26;CPMenuItemKeyEquivalentKeyD;K;6;CP$UIDd;3;268E;K;38;CPMenuItemKeyEquivalentModifierMaskKeyD;K;6;CP$UIDd;3;220E;E;D;K;6;$classD;K;6;CP$UIDd;2;61E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;291E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;16;CPMenuItemTagKeyD;K;6;CP$UIDd;3;270E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;3;106E;K;26;CPMenuItemKeyEquivalentKeyD;K;6;CP$UIDd;3;271E;K;38;CPMenuItemKeyEquivalentModifierMaskKeyD;K;6;CP$UIDd;3;220E;E;D;K;6;$classD;K;6;CP$UIDd;2;61E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;292E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;16;CPMenuItemTagKeyD;K;6;CP$UIDd;3;273E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;3;106E;K;26;CPMenuItemKeyEquivalentKeyD;K;6;CP$UIDd;3;274E;K;38;CPMenuItemKeyEquivalentModifierMaskKeyD;K;6;CP$UIDd;3;247E;E;D;K;6;$classD;K;6;CP$UIDd;2;61E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;293E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;3;111E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;3;219E;K;20;CPMenuItemSubmenuKeyD;K;6;CP$UIDd;3;111E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;2;82E;K;38;CPMenuItemKeyEquivalentModifierMaskKeyD;K;6;CP$UIDd;3;220E;E;D;K;6;$classD;K;6;CP$UIDd;2;59E;K;14;CPMenuTitleKeyD;K;6;CP$UIDd;3;293E;K;14;CPMenuItemsKeyD;K;6;CP$UIDd;3;294E;E;D;K;6;$classD;K;6;CP$UIDd;2;61E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;295E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;3;111E;K;38;CPMenuItemKeyEquivalentModifierMaskKeyD;K;6;CP$UIDd;3;220E;E;D;K;6;$classD;K;6;CP$UIDd;2;61E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;296E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;3;111E;K;38;CPMenuItemKeyEquivalentModifierMaskKeyD;K;6;CP$UIDd;3;220E;E;D;K;6;$classD;K;6;CP$UIDd;2;61E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;297E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;3;115E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;3;219E;K;20;CPMenuItemSubmenuKeyD;K;6;CP$UIDd;3;115E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;2;60E;K;38;CPMenuItemKeyEquivalentModifierMaskKeyD;K;6;CP$UIDd;3;220E;E;D;K;6;$classD;K;6;CP$UIDd;2;59E;K;14;CPMenuTitleKeyD;K;6;CP$UIDd;3;297E;K;14;CPMenuItemsKeyD;K;6;CP$UIDd;3;298E;E;D;K;6;$classD;K;6;CP$UIDd;2;61E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;299E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;3;115E;K;26;CPMenuItemKeyEquivalentKeyD;K;6;CP$UIDd;3;300E;K;38;CPMenuItemKeyEquivalentModifierMaskKeyD;K;6;CP$UIDd;3;301E;E;D;K;6;$classD;K;6;CP$UIDd;2;61E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;302E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;3;115E;K;38;CPMenuItemKeyEquivalentModifierMaskKeyD;K;6;CP$UIDd;3;220E;E;D;K;6;$classD;K;6;CP$UIDd;2;61E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;303E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;3;119E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;3;219E;K;20;CPMenuItemSubmenuKeyD;K;6;CP$UIDd;3;119E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;2;60E;K;38;CPMenuItemKeyEquivalentModifierMaskKeyD;K;6;CP$UIDd;3;220E;E;D;K;6;$classD;K;6;CP$UIDd;2;59E;K;14;CPMenuTitleKeyD;K;6;CP$UIDd;3;303E;K;13;CPMenuNameKeyD;K;6;CP$UIDd;3;304E;K;14;CPMenuItemsKeyD;K;6;CP$UIDd;3;305E;E;D;K;6;$classD;K;6;CP$UIDd;2;61E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;306E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;3;119E;K;26;CPMenuItemKeyEquivalentKeyD;K;6;CP$UIDd;3;307E;K;38;CPMenuItemKeyEquivalentModifierMaskKeyD;K;6;CP$UIDd;3;220E;E;D;K;6;$classD;K;6;CP$UIDd;2;61E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;308E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;3;119E;K;38;CPMenuItemKeyEquivalentModifierMaskKeyD;K;6;CP$UIDd;3;220E;E;D;K;6;$classD;K;6;CP$UIDd;2;61E;K;24;CPMenuItemIsSeparatorKeyD;K;6;CP$UIDd;3;224E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;225E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;22;CPMenuItemIsEnabledKeyD;K;6;CP$UIDd;3;226E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;3;119E;K;38;CPMenuItemKeyEquivalentModifierMaskKeyD;K;6;CP$UIDd;3;220E;E;D;K;6;$classD;K;6;CP$UIDd;2;61E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;309E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;3;119E;K;38;CPMenuItemKeyEquivalentModifierMaskKeyD;K;6;CP$UIDd;3;220E;E;D;K;6;$classD;K;6;CP$UIDd;2;61E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;310E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;3;125E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;3;219E;K;20;CPMenuItemSubmenuKeyD;K;6;CP$UIDd;3;125E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;2;60E;K;38;CPMenuItemKeyEquivalentModifierMaskKeyD;K;6;CP$UIDd;3;220E;E;D;K;6;$classD;K;6;CP$UIDd;2;59E;K;14;CPMenuTitleKeyD;K;6;CP$UIDd;3;310E;K;14;CPMenuItemsKeyD;K;6;CP$UIDd;3;311E;E;D;K;6;$classD;K;6;CP$UIDd;2;61E;K;18;CPMenuItemTitleKeyD;K;6;CP$UIDd;3;312E;K;19;CPMenuItemTargetKeyD;K;6;CP$UIDd;1;0E;K;19;CPMenuItemActionKeyD;K;6;CP$UIDd;1;0E;K;17;CPMenuItemMenuKeyD;K;6;CP$UIDd;3;125E;K;26;CPMenuItemKeyEquivalentKeyD;K;6;CP$UIDd;3;313E;K;38;CPMenuItemKeyEquivalentModifierMaskKeyD;K;6;CP$UIDd;3;220E;E;D;K;10;$classnameS;20;_CPCibWindowTemplateK;8;$classesA;S;20;_CPCibWindowTemplateS;8;CPObjectE;E;D;K;6;$classD;K;6;CP$UIDd;3;127E;K;30;_CPCibWindowTemplateMaxSizeKeyD;K;6;CP$UIDd;3;314E;K;32;_CPCibWindowTemplateViewClassKeyD;K;6;CP$UIDd;1;0E;K;34;_CPCibWindowTemplateWindowClassKeyD;K;6;CP$UIDd;3;315E;K;30;_CPCibWindowTemplateWTFlagsKeyD;K;6;CP$UIDd;3;316E;K;33;_CPCibWindowTemplateWindowRectKeyD;K;6;CP$UIDd;3;317E;K;33;_CPCibWindowTemplateScreenRectKeyD;K;6;CP$UIDd;3;318E;K;30;_CPCibWindowTempatStyleMaskKeyD;K;6;CP$UIDd;3;319E;K;34;_CPCibWindowTemplateWindowTitleKeyD;K;6;CP$UIDd;3;303E;K;33;_CPCibWindowTemplateWindowViewKeyD;K;6;CP$UIDd;3;130E;E;D;K;10;$classnameS;6;CPViewK;8;$classesA;S;6;CPViewS;11;CPResponderS;8;CPObjectE;E;D;K;6;$classD;K;6;CP$UIDd;3;129E;K;18;CPResponderMenuKeyD;K;6;CP$UIDd;1;0E;K;12;CPViewTagKeyD;K;6;CP$UIDd;3;320E;K;14;CPViewFrameKeyD;K;6;CP$UIDd;3;321E;K;15;CPViewBoundsKeyD;K;6;CP$UIDd;3;321E;K;17;CPViewSubviewsKeyD;K;6;CP$UIDd;3;322E;K;19;CPViewThemeClassKeyD;K;6;CP$UIDd;1;0E;K;19;CPViewThemeStateKeyD;K;6;CP$UIDd;3;323E;K;14;CPViewScaleKeyD;K;6;CP$UIDd;3;324E;K;18;CPViewSizeScaleKeyD;K;6;CP$UIDd;3;324E;K;17;CPViewIsScaledKeyD;K;6;CP$UIDd;3;226E;K;19;CPViewAppearanceKeyD;K;6;CP$UIDd;1;0E;E;D;K;10;$classnameS;11;CPSplitViewK;8;$classesA;S;11;CPSplitViewS;6;CPViewS;11;CPResponderS;8;CPObjectE;E;D;K;6;$classD;K;6;CP$UIDd;3;131E;K;27;CPResponderNextResponderKeyD;K;6;CP$UIDd;3;130E;K;18;CPResponderMenuKeyD;K;6;CP$UIDd;1;0E;K;12;CPViewTagKeyD;K;6;CP$UIDd;3;320E;K;14;CPViewFrameKeyD;K;6;CP$UIDd;3;325E;K;15;CPViewBoundsKeyD;K;6;CP$UIDd;3;326E;K;17;CPViewSubviewsKeyD;K;6;CP$UIDd;3;327E;K;18;CPViewSuperviewKeyD;K;6;CP$UIDd;3;130E;K;22;CPViewAutoresizingMaskD;K;6;CP$UIDd;3;328E;K;19;CPViewThemeClassKeyD;K;6;CP$UIDd;3;329E;K;19;CPViewThemeStateKeyD;K;6;CP$UIDd;3;323E;K;14;CPViewScaleKeyD;K;6;CP$UIDd;3;324E;K;18;CPViewSizeScaleKeyD;K;6;CP$UIDd;3;324E;K;17;CPViewIsScaledKeyD;K;6;CP$UIDd;3;226E;K;19;CPViewAppearanceKeyD;K;6;CP$UIDd;1;0E;K;22;CPSplitViewDelegateKeyD;K;6;CP$UIDd;1;0E;K;24;CPSplitViewIsVerticalKeyD;K;6;CP$UIDd;3;224E;K;28;CPSplitViewIsPaneSplitterKeyD;K;6;CP$UIDd;3;226E;K;26;CPSplitViewAutosaveNameKeyD;K;6;CP$UIDd;1;0E;E;D;K;10;$classnameS;16;_CPCibCustomViewK;8;$classesA;S;16;_CPCibCustomViewS;6;CPViewS;11;CPResponderS;8;CPObjectE;E;D;K;6;$classD;K;6;CP$UIDd;3;133E;K;27;CPResponderNextResponderKeyD;K;6;CP$UIDd;3;132E;K;18;CPResponderMenuKeyD;K;6;CP$UIDd;1;0E;K;12;CPViewTagKeyD;K;6;CP$UIDd;3;320E;K;14;CPViewFrameKeyD;K;6;CP$UIDd;3;330E;K;15;CPViewBoundsKeyD;K;6;CP$UIDd;3;330E;K;18;CPViewSuperviewKeyD;K;6;CP$UIDd;3;132E;K;22;CPViewAutoresizingMaskD;K;6;CP$UIDd;3;331E;K;19;CPViewThemeClassKeyD;K;6;CP$UIDd;1;0E;K;19;CPViewThemeStateKeyD;K;6;CP$UIDd;3;323E;K;14;CPViewScaleKeyD;K;6;CP$UIDd;3;324E;K;18;CPViewSizeScaleKeyD;K;6;CP$UIDd;3;324E;K;17;CPViewIsScaledKeyD;K;6;CP$UIDd;3;226E;K;19;CPViewAppearanceKeyD;K;6;CP$UIDd;1;0E;K;28;_CPCibCustomViewClassNameKeyD;K;6;CP$UIDd;3;332E;E;D;K;6;$classD;K;6;CP$UIDd;3;133E;K;27;CPResponderNextResponderKeyD;K;6;CP$UIDd;3;132E;K;18;CPResponderMenuKeyD;K;6;CP$UIDd;1;0E;K;12;CPViewTagKeyD;K;6;CP$UIDd;3;320E;K;14;CPViewFrameKeyD;K;6;CP$UIDd;3;333E;K;15;CPViewBoundsKeyD;K;6;CP$UIDd;3;330E;K;18;CPViewSuperviewKeyD;K;6;CP$UIDd;3;132E;K;22;CPViewAutoresizingMaskD;K;6;CP$UIDd;3;331E;K;19;CPViewThemeClassKeyD;K;6;CP$UIDd;1;0E;K;19;CPViewThemeStateKeyD;K;6;CP$UIDd;3;323E;K;14;CPViewScaleKeyD;K;6;CP$UIDd;3;324E;K;18;CPViewSizeScaleKeyD;K;6;CP$UIDd;3;324E;K;17;CPViewIsScaledKeyD;K;6;CP$UIDd;3;226E;K;19;CPViewAppearanceKeyD;K;6;CP$UIDd;1;0E;K;28;_CPCibCustomViewClassNameKeyD;K;6;CP$UIDd;3;332E;E;D;K;6;$classD;K;6;CP$UIDd;3;133E;K;27;CPResponderNextResponderKeyD;K;6;CP$UIDd;3;132E;K;18;CPResponderMenuKeyD;K;6;CP$UIDd;1;0E;K;12;CPViewTagKeyD;K;6;CP$UIDd;3;320E;K;14;CPViewFrameKeyD;K;6;CP$UIDd;3;334E;K;15;CPViewBoundsKeyD;K;6;CP$UIDd;3;335E;K;18;CPViewSuperviewKeyD;K;6;CP$UIDd;3;132E;K;22;CPViewAutoresizingMaskD;K;6;CP$UIDd;3;328E;K;19;CPViewThemeClassKeyD;K;6;CP$UIDd;1;0E;K;19;CPViewThemeStateKeyD;K;6;CP$UIDd;3;323E;K;14;CPViewScaleKeyD;K;6;CP$UIDd;3;324E;K;18;CPViewSizeScaleKeyD;K;6;CP$UIDd;3;324E;K;17;CPViewIsScaledKeyD;K;6;CP$UIDd;3;226E;K;19;CPViewAppearanceKeyD;K;6;CP$UIDd;1;0E;K;28;_CPCibCustomViewClassNameKeyD;K;6;CP$UIDd;3;332E;E;D;K;6;$classD;K;6;CP$UIDd;3;131E;K;27;CPResponderNextResponderKeyD;K;6;CP$UIDd;3;130E;K;18;CPResponderMenuKeyD;K;6;CP$UIDd;1;0E;K;12;CPViewTagKeyD;K;6;CP$UIDd;3;320E;K;14;CPViewFrameKeyD;K;6;CP$UIDd;3;336E;K;15;CPViewBoundsKeyD;K;6;CP$UIDd;3;337E;K;17;CPViewSubviewsKeyD;K;6;CP$UIDd;3;338E;K;18;CPViewSuperviewKeyD;K;6;CP$UIDd;3;130E;K;22;CPViewAutoresizingMaskD;K;6;CP$UIDd;3;328E;K;19;CPViewThemeClassKeyD;K;6;CP$UIDd;3;329E;K;19;CPViewThemeStateKeyD;K;6;CP$UIDd;3;323E;K;14;CPViewScaleKeyD;K;6;CP$UIDd;3;324E;K;18;CPViewSizeScaleKeyD;K;6;CP$UIDd;3;324E;K;17;CPViewIsScaledKeyD;K;6;CP$UIDd;3;226E;K;19;CPViewAppearanceKeyD;K;6;CP$UIDd;1;0E;K;22;CPSplitViewDelegateKeyD;K;6;CP$UIDd;1;0E;K;24;CPSplitViewIsVerticalKeyD;K;6;CP$UIDd;3;226E;K;28;CPSplitViewIsPaneSplitterKeyD;K;6;CP$UIDd;3;224E;K;26;CPSplitViewAutosaveNameKeyD;K;6;CP$UIDd;1;0E;E;D;K;6;$classD;K;6;CP$UIDd;3;133E;K;27;CPResponderNextResponderKeyD;K;6;CP$UIDd;3;137E;K;18;CPResponderMenuKeyD;K;6;CP$UIDd;1;0E;K;12;CPViewTagKeyD;K;6;CP$UIDd;3;320E;K;14;CPViewFrameKeyD;K;6;CP$UIDd;3;339E;K;15;CPViewBoundsKeyD;K;6;CP$UIDd;3;340E;K;18;CPViewSuperviewKeyD;K;6;CP$UIDd;3;137E;K;22;CPViewAutoresizingMaskD;K;6;CP$UIDd;3;331E;K;19;CPViewThemeClassKeyD;K;6;CP$UIDd;1;0E;K;19;CPViewThemeStateKeyD;K;6;CP$UIDd;3;323E;K;14;CPViewScaleKeyD;K;6;CP$UIDd;3;324E;K;18;CPViewSizeScaleKeyD;K;6;CP$UIDd;3;324E;K;17;CPViewIsScaledKeyD;K;6;CP$UIDd;3;226E;K;19;CPViewAppearanceKeyD;K;6;CP$UIDd;1;0E;K;28;_CPCibCustomViewClassNameKeyD;K;6;CP$UIDd;3;332E;E;D;K;6;$classD;K;6;CP$UIDd;3;133E;K;27;CPResponderNextResponderKeyD;K;6;CP$UIDd;3;137E;K;18;CPResponderMenuKeyD;K;6;CP$UIDd;1;0E;K;12;CPViewTagKeyD;K;6;CP$UIDd;3;320E;K;14;CPViewFrameKeyD;K;6;CP$UIDd;3;341E;K;15;CPViewBoundsKeyD;K;6;CP$UIDd;3;341E;K;18;CPViewSuperviewKeyD;K;6;CP$UIDd;3;137E;K;22;CPViewAutoresizingMaskD;K;6;CP$UIDd;3;331E;K;19;CPViewThemeClassKeyD;K;6;CP$UIDd;1;0E;K;19;CPViewThemeStateKeyD;K;6;CP$UIDd;3;323E;K;14;CPViewScaleKeyD;K;6;CP$UIDd;3;324E;K;18;CPViewSizeScaleKeyD;K;6;CP$UIDd;3;324E;K;17;CPViewIsScaledKeyD;K;6;CP$UIDd;3;226E;K;19;CPViewAppearanceKeyD;K;6;CP$UIDd;1;0E;K;28;_CPCibCustomViewClassNameKeyD;K;6;CP$UIDd;3;332E;E;D;K;10;$classnameS;12;CPScrollViewK;8;$classesA;S;12;CPScrollViewS;6;CPViewS;11;CPResponderS;8;CPObjectE;E;D;K;6;$classD;K;6;CP$UIDd;3;140E;K;27;CPResponderNextResponderKeyD;K;6;CP$UIDd;3;130E;K;18;CPResponderMenuKeyD;K;6;CP$UIDd;1;0E;K;12;CPViewTagKeyD;K;6;CP$UIDd;3;320E;K;14;CPViewFrameKeyD;K;6;CP$UIDd;3;342E;K;15;CPViewBoundsKeyD;K;6;CP$UIDd;3;343E;K;17;CPViewSubviewsKeyD;K;6;CP$UIDd;3;344E;K;18;CPViewSuperviewKeyD;K;6;CP$UIDd;3;130E;K;22;CPViewAutoresizingMaskD;K;6;CP$UIDd;3;328E;K;19;CPViewThemeClassKeyD;K;6;CP$UIDd;3;345E;K;19;CPViewThemeStateKeyD;K;6;CP$UIDd;3;323E;K;14;CPViewScaleKeyD;K;6;CP$UIDd;3;324E;K;18;CPViewSizeScaleKeyD;K;6;CP$UIDd;3;324E;K;17;CPViewIsScaledKeyD;K;6;CP$UIDd;3;226E;K;19;CPViewAppearanceKeyD;K;6;CP$UIDd;1;0E;K;23;CPScrollViewContentViewD;K;6;CP$UIDd;3;143E;K;29;CPScrollViewHeaderClipViewKeyD;K;6;CP$UIDd;1;0E;K;21;CPScrollViewVScrollerD;K;6;CP$UIDd;3;148E;K;21;CPScrollViewHScrollerD;K;6;CP$UIDd;3;147E;K;23;CPScrollViewVLineScrollD;K;6;CP$UIDd;3;346E;K;23;CPScrollViewVPageScrollD;K;6;CP$UIDd;3;346E;K;23;CPScrollViewHLineScrollD;K;6;CP$UIDd;3;346E;K;23;CPScrollViewHPageScrollD;K;6;CP$UIDd;3;346E;K;24;CPScrollViewHasVScrollerD;K;6;CP$UIDd;3;224E;K;24;CPScrollViewHasHScrollerD;K;6;CP$UIDd;3;224E;K;29;CPScrollViewAutohidesScrollerD;K;6;CP$UIDd;3;226E;K;25;CPScrollViewCornerViewKeyD;K;6;CP$UIDd;1;0E;K;31;CPScrollViewBottomCornerViewKeyD;K;6;CP$UIDd;3;347E;K;25;CPScrollViewBorderTypeKeyD;K;6;CP$UIDd;3;270E;K;28;CPScrollViewScrollerStyleKeyD;K;6;CP$UIDd;1;0E;K;32;CPScrollViewScrollerKnobStyleKeyD;K;6;CP$UIDd;3;320E;E;D;K;10;$classnameS;10;CPClipViewK;8;$classesA;S;10;CPClipViewS;6;CPViewS;11;CPResponderS;8;CPObjectE;E;D;K;6;$classD;K;6;CP$UIDd;3;142E;K;27;CPResponderNextResponderKeyD;K;6;CP$UIDd;3;141E;K;18;CPResponderMenuKeyD;K;6;CP$UIDd;1;0E;K;12;CPViewTagKeyD;K;6;CP$UIDd;3;320E;K;14;CPViewFrameKeyD;K;6;CP$UIDd;3;348E;K;15;CPViewBoundsKeyD;K;6;CP$UIDd;3;349E;K;17;CPViewSubviewsKeyD;K;6;CP$UIDd;3;350E;K;18;CPViewSuperviewKeyD;K;6;CP$UIDd;3;141E;K;22;CPViewAutoresizingMaskD;K;6;CP$UIDd;3;351E;K;21;CPViewBackgroundColorD;K;6;CP$UIDd;3;353E;K;19;CPViewThemeClassKeyD;K;6;CP$UIDd;1;0E;K;19;CPViewThemeStateKeyD;K;6;CP$UIDd;3;323E;K;14;CPViewScaleKeyD;K;6;CP$UIDd;3;324E;K;18;CPViewSizeScaleKeyD;K;6;CP$UIDd;3;324E;K;17;CPViewIsScaledKeyD;K;6;CP$UIDd;3;226E;K;19;CPViewAppearanceKeyD;K;6;CP$UIDd;1;0E;K;24;CPScrollViewDocumentViewD;K;6;CP$UIDd;3;144E;E;D;K;6;$classD;K;6;CP$UIDd;3;129E;K;27;CPResponderNextResponderKeyD;K;6;CP$UIDd;3;143E;K;18;CPResponderMenuKeyD;K;6;CP$UIDd;1;0E;K;12;CPViewTagKeyD;K;6;CP$UIDd;3;320E;K;14;CPViewFrameKeyD;K;6;CP$UIDd;3;354E;K;15;CPViewBoundsKeyD;K;6;CP$UIDd;3;354E;K;17;CPViewSubviewsKeyD;K;6;CP$UIDd;3;355E;K;18;CPViewSuperviewKeyD;K;6;CP$UIDd;3;143E;K;22;CPViewAutoresizingMaskD;K;6;CP$UIDd;3;351E;K;19;CPViewThemeClassKeyD;K;6;CP$UIDd;1;0E;K;19;CPViewThemeStateKeyD;K;6;CP$UIDd;3;323E;K;14;CPViewScaleKeyD;K;6;CP$UIDd;3;324E;K;18;CPViewSizeScaleKeyD;K;6;CP$UIDd;3;324E;K;17;CPViewIsScaledKeyD;K;6;CP$UIDd;3;226E;K;19;CPViewAppearanceKeyD;K;6;CP$UIDd;1;0E;E;D;K;6;$classD;K;6;CP$UIDd;3;133E;K;27;CPResponderNextResponderKeyD;K;6;CP$UIDd;3;144E;K;18;CPResponderMenuKeyD;K;6;CP$UIDd;1;0E;K;12;CPViewTagKeyD;K;6;CP$UIDd;3;320E;K;14;CPViewFrameKeyD;K;6;CP$UIDd;3;356E;K;15;CPViewBoundsKeyD;K;6;CP$UIDd;3;357E;K;18;CPViewSuperviewKeyD;K;6;CP$UIDd;3;144E;K;22;CPViewAutoresizingMaskD;K;6;CP$UIDd;3;328E;K;19;CPViewThemeClassKeyD;K;6;CP$UIDd;1;0E;K;19;CPViewThemeStateKeyD;K;6;CP$UIDd;3;323E;K;14;CPViewScaleKeyD;K;6;CP$UIDd;3;324E;K;18;CPViewSizeScaleKeyD;K;6;CP$UIDd;3;324E;K;17;CPViewIsScaledKeyD;K;6;CP$UIDd;3;226E;K;19;CPViewAppearanceKeyD;K;6;CP$UIDd;1;0E;K;28;_CPCibCustomViewClassNameKeyD;K;6;CP$UIDd;3;358E;E;D;K;10;$classnameS;10;CPScrollerK;8;$classesA;S;10;CPScrollerS;9;CPControlS;6;CPViewS;11;CPResponderS;8;CPObjectE;E;D;K;6;$classD;K;6;CP$UIDd;3;146E;K;27;CPResponderNextResponderKeyD;K;6;CP$UIDd;3;141E;K;18;CPResponderMenuKeyD;K;6;CP$UIDd;1;0E;K;12;CPViewTagKeyD;K;6;CP$UIDd;3;320E;K;14;CPViewFrameKeyD;K;6;CP$UIDd;3;359E;K;15;CPViewBoundsKeyD;K;6;CP$UIDd;3;360E;K;18;CPViewSuperviewKeyD;K;6;CP$UIDd;3;141E;K;22;CPViewAutoresizingMaskD;K;6;CP$UIDd;3;331E;K;19;CPViewThemeClassKeyD;K;6;CP$UIDd;3;361E;K;19;CPViewThemeStateKeyD;K;6;CP$UIDd;3;362E;K;14;CPViewScaleKeyD;K;6;CP$UIDd;3;324E;K;18;CPViewSizeScaleKeyD;K;6;CP$UIDd;3;324E;K;17;CPViewIsScaledKeyD;K;6;CP$UIDd;3;226E;K;19;CPViewAppearanceKeyD;K;6;CP$UIDd;1;0E;K;17;CPControlValueKeyD;K;6;CP$UIDd;3;320E;K;18;CPControlTargetKeyD;K;6;CP$UIDd;3;141E;K;18;CPControlActionKeyD;K;6;CP$UIDd;3;363E;K;24;CPControlSendActionOnKeyD;K;6;CP$UIDd;3;364E;K;23;CPControlControlSizeKeyD;K;6;CP$UIDd;1;0E;K;33;CPControlBaseWrittingDirectionKeyD;K;6;CP$UIDd;1;0E;K;23;CPScrollerIsVerticalKeyD;K;6;CP$UIDd;3;226E;K;24;CPScrollerKnobProportionD;K;6;CP$UIDd;3;267E;K;18;CPScrollerStyleKeyD;K;6;CP$UIDd;1;0E;E;D;K;6;$classD;K;6;CP$UIDd;3;146E;K;27;CPResponderNextResponderKeyD;K;6;CP$UIDd;3;141E;K;18;CPResponderMenuKeyD;K;6;CP$UIDd;1;0E;K;12;CPViewTagKeyD;K;6;CP$UIDd;3;320E;K;14;CPViewFrameKeyD;K;6;CP$UIDd;3;365E;K;15;CPViewBoundsKeyD;K;6;CP$UIDd;3;366E;K;18;CPViewSuperviewKeyD;K;6;CP$UIDd;3;141E;K;22;CPViewAutoresizingMaskD;K;6;CP$UIDd;3;331E;K;19;CPViewThemeClassKeyD;K;6;CP$UIDd;3;361E;K;19;CPViewThemeStateKeyD;K;6;CP$UIDd;3;362E;K;14;CPViewScaleKeyD;K;6;CP$UIDd;3;324E;K;18;CPViewSizeScaleKeyD;K;6;CP$UIDd;3;324E;K;17;CPViewIsScaledKeyD;K;6;CP$UIDd;3;226E;K;19;CPViewAppearanceKeyD;K;6;CP$UIDd;1;0E;K;17;CPControlValueKeyD;K;6;CP$UIDd;3;320E;K;18;CPControlTargetKeyD;K;6;CP$UIDd;3;141E;K;18;CPControlActionKeyD;K;6;CP$UIDd;3;367E;K;24;CPControlSendActionOnKeyD;K;6;CP$UIDd;3;364E;K;23;CPControlControlSizeKeyD;K;6;CP$UIDd;1;0E;K;33;CPControlBaseWrittingDirectionKeyD;K;6;CP$UIDd;1;0E;K;23;CPScrollerIsVerticalKeyD;K;6;CP$UIDd;3;224E;K;24;CPScrollerKnobProportionD;K;6;CP$UIDd;3;267E;K;18;CPScrollerStyleKeyD;K;6;CP$UIDd;1;0E;E;D;K;6;$classD;K;6;CP$UIDd;3;140E;K;27;CPResponderNextResponderKeyD;K;6;CP$UIDd;3;130E;K;18;CPResponderMenuKeyD;K;6;CP$UIDd;1;0E;K;12;CPViewTagKeyD;K;6;CP$UIDd;3;320E;K;14;CPViewFrameKeyD;K;6;CP$UIDd;3;368E;K;15;CPViewBoundsKeyD;K;6;CP$UIDd;3;369E;K;17;CPViewSubviewsKeyD;K;6;CP$UIDd;3;370E;K;18;CPViewSuperviewKeyD;K;6;CP$UIDd;3;130E;K;22;CPViewAutoresizingMaskD;K;6;CP$UIDd;3;328E;K;19;CPViewThemeClassKeyD;K;6;CP$UIDd;3;345E;K;19;CPViewThemeStateKeyD;K;6;CP$UIDd;3;323E;K;14;CPViewScaleKeyD;K;6;CP$UIDd;3;324E;K;18;CPViewSizeScaleKeyD;K;6;CP$UIDd;3;324E;K;17;CPViewIsScaledKeyD;K;6;CP$UIDd;3;226E;K;19;CPViewAppearanceKeyD;K;6;CP$UIDd;1;0E;K;23;CPScrollViewContentViewD;K;6;CP$UIDd;3;150E;K;29;CPScrollViewHeaderClipViewKeyD;K;6;CP$UIDd;3;371E;K;21;CPScrollViewVScrollerD;K;6;CP$UIDd;3;158E;K;21;CPScrollViewHScrollerD;K;6;CP$UIDd;3;157E;K;23;CPScrollViewVLineScrollD;K;6;CP$UIDd;3;346E;K;23;CPScrollViewVPageScrollD;K;6;CP$UIDd;3;346E;K;23;CPScrollViewHLineScrollD;K;6;CP$UIDd;3;346E;K;23;CPScrollViewHPageScrollD;K;6;CP$UIDd;3;346E;K;24;CPScrollViewHasVScrollerD;K;6;CP$UIDd;3;224E;K;24;CPScrollViewHasHScrollerD;K;6;CP$UIDd;3;224E;K;29;CPScrollViewAutohidesScrollerD;K;6;CP$UIDd;3;224E;K;25;CPScrollViewCornerViewKeyD;K;6;CP$UIDd;1;0E;K;31;CPScrollViewBottomCornerViewKeyD;K;6;CP$UIDd;3;372E;K;25;CPScrollViewBorderTypeKeyD;K;6;CP$UIDd;3;270E;K;28;CPScrollViewScrollerStyleKeyD;K;6;CP$UIDd;1;0E;K;32;CPScrollViewScrollerKnobStyleKeyD;K;6;CP$UIDd;3;320E;E;D;K;6;$classD;K;6;CP$UIDd;3;142E;K;27;CPResponderNextResponderKeyD;K;6;CP$UIDd;3;149E;K;18;CPResponderMenuKeyD;K;6;CP$UIDd;1;0E;K;12;CPViewTagKeyD;K;6;CP$UIDd;3;320E;K;14;CPViewFrameKeyD;K;6;CP$UIDd;3;373E;K;15;CPViewBoundsKeyD;K;6;CP$UIDd;3;374E;K;17;CPViewSubviewsKeyD;K;6;CP$UIDd;3;375E;K;18;CPViewSuperviewKeyD;K;6;CP$UIDd;3;149E;K;22;CPViewAutoresizingMaskD;K;6;CP$UIDd;3;351E;K;21;CPViewBackgroundColorD;K;6;CP$UIDd;3;376E;K;19;CPViewThemeClassKeyD;K;6;CP$UIDd;1;0E;K;19;CPViewThemeStateKeyD;K;6;CP$UIDd;3;323E;K;14;CPViewScaleKeyD;K;6;CP$UIDd;3;324E;K;18;CPViewSizeScaleKeyD;K;6;CP$UIDd;3;324E;K;17;CPViewIsScaledKeyD;K;6;CP$UIDd;3;226E;K;19;CPViewAppearanceKeyD;K;6;CP$UIDd;1;0E;K;24;CPScrollViewDocumentViewD;K;6;CP$UIDd;3;152E;E;D;K;10;$classnameS;11;CPTableViewK;8;$classesA;S;11;CPTableViewS;9;CPControlS;6;CPViewS;11;CPResponderS;8;CPObjectE;E;D;K;6;$classD;K;6;CP$UIDd;3;151E;K;27;CPResponderNextResponderKeyD;K;6;CP$UIDd;3;150E;K;18;CPResponderMenuKeyD;K;6;CP$UIDd;1;0E;K;12;CPViewTagKeyD;K;6;CP$UIDd;3;320E;K;14;CPViewFrameKeyD;K;6;CP$UIDd;3;377E;K;15;CPViewBoundsKeyD;K;6;CP$UIDd;3;377E;K;18;CPViewSuperviewKeyD;K;6;CP$UIDd;3;150E;K;21;CPViewBackgroundColorD;K;6;CP$UIDd;3;376E;K;19;CPViewThemeClassKeyD;K;6;CP$UIDd;3;378E;K;19;CPViewThemeStateKeyD;K;6;CP$UIDd;3;323E;K;12;$agrid-colorD;K;6;CP$UIDd;3;379E;K;14;CPViewScaleKeyD;K;6;CP$UIDd;3;324E;K;18;CPViewSizeScaleKeyD;K;6;CP$UIDd;3;324E;K;17;CPViewIsScaledKeyD;K;6;CP$UIDd;3;226E;K;19;CPViewAppearanceKeyD;K;6;CP$UIDd;1;0E;K;24;CPControlSendActionOnKeyD;K;6;CP$UIDd;3;364E;K;23;CPControlControlSizeKeyD;K;6;CP$UIDd;1;0E;K;33;CPControlBaseWrittingDirectionKeyD;K;6;CP$UIDd;1;0E;K;24;CPTableViewDataSourceKeyD;K;6;CP$UIDd;1;0E;K;22;CPTableViewDelegateKeyD;K;6;CP$UIDd;1;0E;K;23;CPTableViewRowHeightKeyD;K;6;CP$UIDd;3;380E;K;30;CPTableViewIntercellSpacingKeyD;K;6;CP$UIDd;3;381E;K;37;CPTableViewSelectionHighlightStyleKeyD;K;6;CP$UIDd;3;320E;K;37;CPTableViewColumnAutoresizingStyleKeyD;K;6;CP$UIDd;3;364E;K;31;CPTableViewMultipleSelectionKeyD;K;6;CP$UIDd;3;226E;K;28;CPTableViewEmptySelectionKeyD;K;6;CP$UIDd;3;224E;K;30;CPTableViewColumnReorderingKeyD;K;6;CP$UIDd;3;224E;K;28;CPTableViewColumnResizingKeyD;K;6;CP$UIDd;3;224E;K;29;CPTableViewColumnSelectionKeyD;K;6;CP$UIDd;3;224E;K;26;CPTableViewTableColumnsKeyD;K;6;CP$UIDd;3;382E;K;23;CPTableViewGridColorKeyD;K;6;CP$UIDd;3;379E;K;27;CPTableViewGridStyleMaskKeyD;K;6;CP$UIDd;3;320E;K;39;CPTableViewUsesAlternatingBackgroundKeyD;K;6;CP$UIDd;3;226E;K;34;CPTableViewAlternatingRowColorsKeyD;K;6;CP$UIDd;1;0E;K;24;CPTableViewCornerViewKeyD;K;6;CP$UIDd;3;384E;K;24;CPTableViewHeaderViewKeyD;K;6;CP$UIDd;3;160E;K;26;CPTableViewAutosaveNameKeyD;K;6;CP$UIDd;1;0E;E;D;K;10;$classnameS;13;CPTableColumnK;8;$classesA;S;13;CPTableColumnS;8;CPObjectE;E;D;K;6;$classD;K;6;CP$UIDd;3;153E;K;26;CPTableColumnIdentifierKeyD;K;6;CP$UIDd;1;0E;K;21;CPTableColumnWidthKeyD;K;6;CP$UIDd;3;385E;K;24;CPTableColumnMinWidthKeyD;K;6;CP$UIDd;3;386E;K;24;CPTableColumnMaxWidthKeyD;K;6;CP$UIDd;3;387E;K;26;CPTableColumnHeaderViewKeyD;K;6;CP$UIDd;3;389E;K;24;CPTableColumnDataViewKeyD;K;6;CP$UIDd;3;390E;K;28;CPTableColumnResizingMaskKeyD;K;6;CP$UIDd;3;273E;K;24;CPTableColumnIsHiddenKeyD;K;6;CP$UIDd;3;226E;K;26;CPTableColumnIsEditableKeyD;K;6;CP$UIDd;3;224E;K;28;CPSortDescriptorPrototypeKeyD;K;6;CP$UIDd;1;0E;E;D;K;6;$classD;K;6;CP$UIDd;3;153E;K;26;CPTableColumnIdentifierKeyD;K;6;CP$UIDd;1;0E;K;21;CPTableColumnWidthKeyD;K;6;CP$UIDd;3;391E;K;24;CPTableColumnMinWidthKeyD;K;6;CP$UIDd;3;386E;K;24;CPTableColumnMaxWidthKeyD;K;6;CP$UIDd;3;387E;K;26;CPTableColumnHeaderViewKeyD;K;6;CP$UIDd;3;392E;K;24;CPTableColumnDataViewKeyD;K;6;CP$UIDd;3;393E;K;28;CPTableColumnResizingMaskKeyD;K;6;CP$UIDd;3;273E;K;24;CPTableColumnIsHiddenKeyD;K;6;CP$UIDd;3;226E;K;26;CPTableColumnIsEditableKeyD;K;6;CP$UIDd;3;224E;K;28;CPSortDescriptorPrototypeKeyD;K;6;CP$UIDd;1;0E;E;D;K;6;$classD;K;6;CP$UIDd;3;153E;K;26;CPTableColumnIdentifierKeyD;K;6;CP$UIDd;1;0E;K;21;CPTableColumnWidthKeyD;K;6;CP$UIDd;3;394E;K;24;CPTableColumnMinWidthKeyD;K;6;CP$UIDd;3;346E;K;24;CPTableColumnMaxWidthKeyD;K;6;CP$UIDd;3;395E;K;26;CPTableColumnHeaderViewKeyD;K;6;CP$UIDd;3;396E;K;24;CPTableColumnDataViewKeyD;K;6;CP$UIDd;3;397E;K;28;CPTableColumnResizingMaskKeyD;K;6;CP$UIDd;3;273E;K;24;CPTableColumnIsHiddenKeyD;K;6;CP$UIDd;3;226E;K;26;CPTableColumnIsEditableKeyD;K;6;CP$UIDd;3;224E;K;28;CPSortDescriptorPrototypeKeyD;K;6;CP$UIDd;1;0E;E;D;K;6;$classD;K;6;CP$UIDd;3;146E;K;27;CPResponderNextResponderKeyD;K;6;CP$UIDd;3;149E;K;18;CPResponderMenuKeyD;K;6;CP$UIDd;1;0E;K;12;CPViewTagKeyD;K;6;CP$UIDd;3;320E;K;14;CPViewFrameKeyD;K;6;CP$UIDd;3;398E;K;15;CPViewBoundsKeyD;K;6;CP$UIDd;3;399E;K;18;CPViewSuperviewKeyD;K;6;CP$UIDd;3;149E;K;22;CPViewAutoresizingMaskD;K;6;CP$UIDd;3;331E;K;17;CPViewIsHiddenKeyD;K;6;CP$UIDd;3;400E;K;19;CPViewThemeClassKeyD;K;6;CP$UIDd;3;361E;K;19;CPViewThemeStateKeyD;K;6;CP$UIDd;3;362E;K;14;CPViewScaleKeyD;K;6;CP$UIDd;3;324E;K;18;CPViewSizeScaleKeyD;K;6;CP$UIDd;3;324E;K;17;CPViewIsScaledKeyD;K;6;CP$UIDd;3;226E;K;19;CPViewAppearanceKeyD;K;6;CP$UIDd;1;0E;K;17;CPControlValueKeyD;K;6;CP$UIDd;3;320E;K;18;CPControlTargetKeyD;K;6;CP$UIDd;3;149E;K;18;CPControlActionKeyD;K;6;CP$UIDd;3;363E;K;24;CPControlSendActionOnKeyD;K;6;CP$UIDd;3;364E;K;23;CPControlControlSizeKeyD;K;6;CP$UIDd;1;0E;K;33;CPControlBaseWrittingDirectionKeyD;K;6;CP$UIDd;1;0E;K;23;CPScrollerIsVerticalKeyD;K;6;CP$UIDd;3;226E;K;24;CPScrollerKnobProportionD;K;6;CP$UIDd;3;267E;K;18;CPScrollerStyleKeyD;K;6;CP$UIDd;1;0E;E;D;K;6;$classD;K;6;CP$UIDd;3;146E;K;27;CPResponderNextResponderKeyD;K;6;CP$UIDd;3;149E;K;18;CPResponderMenuKeyD;K;6;CP$UIDd;1;0E;K;12;CPViewTagKeyD;K;6;CP$UIDd;3;320E;K;14;CPViewFrameKeyD;K;6;CP$UIDd;3;401E;K;15;CPViewBoundsKeyD;K;6;CP$UIDd;3;402E;K;18;CPViewSuperviewKeyD;K;6;CP$UIDd;3;149E;K;22;CPViewAutoresizingMaskD;K;6;CP$UIDd;3;331E;K;17;CPViewIsHiddenKeyD;K;6;CP$UIDd;3;400E;K;19;CPViewThemeClassKeyD;K;6;CP$UIDd;3;361E;K;19;CPViewThemeStateKeyD;K;6;CP$UIDd;3;362E;K;14;CPViewScaleKeyD;K;6;CP$UIDd;3;324E;K;18;CPViewSizeScaleKeyD;K;6;CP$UIDd;3;324E;K;17;CPViewIsScaledKeyD;K;6;CP$UIDd;3;226E;K;19;CPViewAppearanceKeyD;K;6;CP$UIDd;1;0E;K;17;CPControlValueKeyD;K;6;CP$UIDd;3;320E;K;18;CPControlTargetKeyD;K;6;CP$UIDd;3;149E;K;18;CPControlActionKeyD;K;6;CP$UIDd;3;367E;K;24;CPControlSendActionOnKeyD;K;6;CP$UIDd;3;364E;K;23;CPControlControlSizeKeyD;K;6;CP$UIDd;1;0E;K;33;CPControlBaseWrittingDirectionKeyD;K;6;CP$UIDd;1;0E;K;23;CPScrollerIsVerticalKeyD;K;6;CP$UIDd;3;224E;K;24;CPScrollerKnobProportionD;K;6;CP$UIDd;3;403E;K;18;CPScrollerStyleKeyD;K;6;CP$UIDd;1;0E;E;D;K;10;$classnameS;17;CPTableHeaderViewK;8;$classesA;S;17;CPTableHeaderViewS;6;CPViewS;11;CPResponderS;8;CPObjectE;E;D;K;6;$classD;K;6;CP$UIDd;3;159E;K;27;CPResponderNextResponderKeyD;K;6;CP$UIDd;3;371E;K;18;CPResponderMenuKeyD;K;6;CP$UIDd;1;0E;K;12;CPViewTagKeyD;K;6;CP$UIDd;3;320E;K;14;CPViewFrameKeyD;K;6;CP$UIDd;3;404E;K;15;CPViewBoundsKeyD;K;6;CP$UIDd;3;404E;K;18;CPViewSuperviewKeyD;K;6;CP$UIDd;3;371E;K;19;CPViewThemeClassKeyD;K;6;CP$UIDd;3;405E;K;19;CPViewThemeStateKeyD;K;6;CP$UIDd;3;323E;K;14;CPViewScaleKeyD;K;6;CP$UIDd;3;324E;K;18;CPViewSizeScaleKeyD;K;6;CP$UIDd;3;324E;K;17;CPViewIsScaledKeyD;K;6;CP$UIDd;3;226E;K;19;CPViewAppearanceKeyD;K;6;CP$UIDd;1;0E;K;29;CPTableHeaderViewTableViewKeyD;K;6;CP$UIDd;3;152E;E;D;K;10;$classnameS;11;CPTextFieldK;8;$classesA;S;11;CPTextFieldS;9;CPControlS;6;CPViewS;11;CPResponderS;8;CPObjectE;E;D;K;6;$classD;K;6;CP$UIDd;3;161E;K;27;CPResponderNextResponderKeyD;K;6;CP$UIDd;3;130E;K;18;CPResponderMenuKeyD;K;6;CP$UIDd;1;0E;K;12;CPViewTagKeyD;K;6;CP$UIDd;3;320E;K;14;CPViewFrameKeyD;K;6;CP$UIDd;3;406E;K;15;CPViewBoundsKeyD;K;6;CP$UIDd;3;407E;K;18;CPViewSuperviewKeyD;K;6;CP$UIDd;3;130E;K;22;CPViewAutoresizingMaskD;K;6;CP$UIDd;3;328E;K;19;CPViewThemeClassKeyD;K;6;CP$UIDd;3;408E;K;19;CPViewThemeStateKeyD;K;6;CP$UIDd;3;409E;K;11;$aalignmentD;K;6;CP$UIDd;3;364E;K;17;$aline-break-modeD;K;6;CP$UIDd;3;320E;K;6;$afontD;K;6;CP$UIDd;3;411E;K;14;CPViewScaleKeyD;K;6;CP$UIDd;3;324E;K;18;CPViewSizeScaleKeyD;K;6;CP$UIDd;3;324E;K;17;CPViewIsScaledKeyD;K;6;CP$UIDd;3;226E;K;19;CPViewAppearanceKeyD;K;6;CP$UIDd;1;0E;K;35;CPControlSendsActionOnEndEditingKeyD;K;6;CP$UIDd;3;224E;K;17;CPControlValueKeyD;K;6;CP$UIDd;3;412E;K;24;CPControlSendActionOnKeyD;K;6;CP$UIDd;3;364E;K;23;CPControlControlSizeKeyD;K;6;CP$UIDd;3;270E;K;33;CPControlBaseWrittingDirectionKeyD;K;6;CP$UIDd;3;413E;K;24;CPTextFieldIsEditableKeyD;K;6;CP$UIDd;3;226E;K;26;CPTextFieldIsSelectableKeyD;K;6;CP$UIDd;3;226E;K;29;CPTextFieldDrawsBackgroundKeyD;K;6;CP$UIDd;3;226E;K;29;CPTextFieldBackgroundColorKeyD;K;6;CP$UIDd;3;353E;K;27;CPTextFieldLineBreakModeKeyD;K;6;CP$UIDd;3;320E;K;23;CPTextFieldAlignmentKeyD;K;6;CP$UIDd;3;364E;K;31;CPTextFieldPlaceholderStringKeyD;K;6;CP$UIDd;1;0E;K;29;CPTextFieldUsesSingleLineModeD;K;6;CP$UIDd;3;224E;K;16;CPTextFieldWrapsD;K;6;CP$UIDd;3;224E;K;18;CPTextFieldScrollsD;K;6;CP$UIDd;3;226E;E;D;K;6;$classD;K;6;CP$UIDd;3;161E;K;27;CPResponderNextResponderKeyD;K;6;CP$UIDd;3;130E;K;18;CPResponderMenuKeyD;K;6;CP$UIDd;1;0E;K;12;CPViewTagKeyD;K;6;CP$UIDd;3;320E;K;14;CPViewFrameKeyD;K;6;CP$UIDd;3;414E;K;15;CPViewBoundsKeyD;K;6;CP$UIDd;3;415E;K;18;CPViewSuperviewKeyD;K;6;CP$UIDd;3;130E;K;22;CPViewAutoresizingMaskD;K;6;CP$UIDd;3;328E;K;19;CPViewThemeClassKeyD;K;6;CP$UIDd;3;408E;K;19;CPViewThemeStateKeyD;K;6;CP$UIDd;3;409E;K;11;$aalignmentD;K;6;CP$UIDd;3;364E;K;17;$aline-break-modeD;K;6;CP$UIDd;3;320E;K;6;$afontD;K;6;CP$UIDd;3;416E;K;14;CPViewScaleKeyD;K;6;CP$UIDd;3;324E;K;18;CPViewSizeScaleKeyD;K;6;CP$UIDd;3;324E;K;17;CPViewIsScaledKeyD;K;6;CP$UIDd;3;226E;K;19;CPViewAppearanceKeyD;K;6;CP$UIDd;1;0E;K;35;CPControlSendsActionOnEndEditingKeyD;K;6;CP$UIDd;3;224E;K;17;CPControlValueKeyD;K;6;CP$UIDd;3;417E;K;24;CPControlSendActionOnKeyD;K;6;CP$UIDd;3;364E;K;23;CPControlControlSizeKeyD;K;6;CP$UIDd;3;270E;K;33;CPControlBaseWrittingDirectionKeyD;K;6;CP$UIDd;3;413E;K;24;CPTextFieldIsEditableKeyD;K;6;CP$UIDd;3;226E;K;26;CPTextFieldIsSelectableKeyD;K;6;CP$UIDd;3;226E;K;29;CPTextFieldDrawsBackgroundKeyD;K;6;CP$UIDd;3;226E;K;29;CPTextFieldBackgroundColorKeyD;K;6;CP$UIDd;3;353E;K;27;CPTextFieldLineBreakModeKeyD;K;6;CP$UIDd;3;320E;K;23;CPTextFieldAlignmentKeyD;K;6;CP$UIDd;3;364E;K;31;CPTextFieldPlaceholderStringKeyD;K;6;CP$UIDd;1;0E;K;29;CPTextFieldUsesSingleLineModeD;K;6;CP$UIDd;3;224E;K;16;CPTextFieldWrapsD;K;6;CP$UIDd;3;224E;K;18;CPTextFieldScrollsD;K;6;CP$UIDd;3;226E;E;D;K;6;$classD;K;6;CP$UIDd;3;161E;K;27;CPResponderNextResponderKeyD;K;6;CP$UIDd;3;130E;K;18;CPResponderMenuKeyD;K;6;CP$UIDd;1;0E;K;12;CPViewTagKeyD;K;6;CP$UIDd;3;320E;K;14;CPViewFrameKeyD;K;6;CP$UIDd;3;418E;K;15;CPViewBoundsKeyD;K;6;CP$UIDd;3;415E;K;18;CPViewSuperviewKeyD;K;6;CP$UIDd;3;130E;K;22;CPViewAutoresizingMaskD;K;6;CP$UIDd;3;328E;K;19;CPViewThemeClassKeyD;K;6;CP$UIDd;3;408E;K;19;CPViewThemeStateKeyD;K;6;CP$UIDd;3;409E;K;11;$aalignmentD;K;6;CP$UIDd;3;364E;K;17;$aline-break-modeD;K;6;CP$UIDd;3;320E;K;6;$afontD;K;6;CP$UIDd;3;419E;K;14;CPViewScaleKeyD;K;6;CP$UIDd;3;324E;K;18;CPViewSizeScaleKeyD;K;6;CP$UIDd;3;324E;K;17;CPViewIsScaledKeyD;K;6;CP$UIDd;3;226E;K;19;CPViewAppearanceKeyD;K;6;CP$UIDd;1;0E;K;35;CPControlSendsActionOnEndEditingKeyD;K;6;CP$UIDd;3;224E;K;17;CPControlValueKeyD;K;6;CP$UIDd;3;420E;K;24;CPControlSendActionOnKeyD;K;6;CP$UIDd;3;364E;K;23;CPControlControlSizeKeyD;K;6;CP$UIDd;3;270E;K;33;CPControlBaseWrittingDirectionKeyD;K;6;CP$UIDd;3;413E;K;24;CPTextFieldIsEditableKeyD;K;6;CP$UIDd;3;226E;K;26;CPTextFieldIsSelectableKeyD;K;6;CP$UIDd;3;226E;K;29;CPTextFieldDrawsBackgroundKeyD;K;6;CP$UIDd;3;226E;K;29;CPTextFieldBackgroundColorKeyD;K;6;CP$UIDd;3;353E;K;27;CPTextFieldLineBreakModeKeyD;K;6;CP$UIDd;3;320E;K;23;CPTextFieldAlignmentKeyD;K;6;CP$UIDd;3;364E;K;31;CPTextFieldPlaceholderStringKeyD;K;6;CP$UIDd;1;0E;K;29;CPTextFieldUsesSingleLineModeD;K;6;CP$UIDd;3;224E;K;16;CPTextFieldWrapsD;K;6;CP$UIDd;3;224E;K;18;CPTextFieldScrollsD;K;6;CP$UIDd;3;226E;E;D;K;6;$classD;K;6;CP$UIDd;3;161E;K;27;CPResponderNextResponderKeyD;K;6;CP$UIDd;3;130E;K;18;CPResponderMenuKeyD;K;6;CP$UIDd;1;0E;K;12;CPViewTagKeyD;K;6;CP$UIDd;3;320E;K;14;CPViewFrameKeyD;K;6;CP$UIDd;3;421E;K;15;CPViewBoundsKeyD;K;6;CP$UIDd;3;422E;K;18;CPViewSuperviewKeyD;K;6;CP$UIDd;3;130E;K;22;CPViewAutoresizingMaskD;K;6;CP$UIDd;3;328E;K;19;CPViewThemeClassKeyD;K;6;CP$UIDd;3;408E;K;19;CPViewThemeStateKeyD;K;6;CP$UIDd;3;409E;K;11;$aalignmentD;K;6;CP$UIDd;3;364E;K;17;$aline-break-modeD;K;6;CP$UIDd;3;320E;K;6;$afontD;K;6;CP$UIDd;3;423E;K;14;CPViewScaleKeyD;K;6;CP$UIDd;3;324E;K;18;CPViewSizeScaleKeyD;K;6;CP$UIDd;3;324E;K;17;CPViewIsScaledKeyD;K;6;CP$UIDd;3;226E;K;19;CPViewAppearanceKeyD;K;6;CP$UIDd;1;0E;K;35;CPControlSendsActionOnEndEditingKeyD;K;6;CP$UIDd;3;224E;K;17;CPControlValueKeyD;K;6;CP$UIDd;3;424E;K;24;CPControlSendActionOnKeyD;K;6;CP$UIDd;3;364E;K;23;CPControlControlSizeKeyD;K;6;CP$UIDd;3;270E;K;33;CPControlBaseWrittingDirectionKeyD;K;6;CP$UIDd;3;413E;K;24;CPTextFieldIsEditableKeyD;K;6;CP$UIDd;3;226E;K;26;CPTextFieldIsSelectableKeyD;K;6;CP$UIDd;3;226E;K;29;CPTextFieldDrawsBackgroundKeyD;K;6;CP$UIDd;3;226E;K;29;CPTextFieldBackgroundColorKeyD;K;6;CP$UIDd;3;353E;K;27;CPTextFieldLineBreakModeKeyD;K;6;CP$UIDd;3;320E;K;23;CPTextFieldAlignmentKeyD;K;6;CP$UIDd;3;364E;K;31;CPTextFieldPlaceholderStringKeyD;K;6;CP$UIDd;1;0E;K;29;CPTextFieldUsesSingleLineModeD;K;6;CP$UIDd;3;224E;K;16;CPTextFieldWrapsD;K;6;CP$UIDd;3;224E;K;18;CPTextFieldScrollsD;K;6;CP$UIDd;3;226E;E;D;K;6;$classD;K;6;CP$UIDd;2;10E;K;27;_CPCibCustomObjectClassNameD;K;6;CP$UIDd;3;425E;E;S;13;CPApplicationD;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;3;128E;E;E;D;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;3;426E;E;E;D;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;3;427E;E;E;D;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;3;426E;E;E;D;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;3;428E;E;E;D;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;3;426E;E;E;D;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;3;429E;E;E;D;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;3;426E;E;E;D;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;3;430E;E;E;D;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;3;426E;E;E;D;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;3;431E;E;E;S;8;delegateS;2;s1S;9;theWindowS;15;arrangeInFront:S;19;performMiniaturize:S;29;orderFrontStandardAboutPanel:S;13;openDocument:S;13;performClose:S;13;saveDocument:S;15;saveDocumentAs:S;12;newDocument:S;9;showHelp:S;22;revertDocumentToSaved:S;21;clearRecentDocuments:S;10;terminate:S;13;stopSpeaking:S;14;startSpeaking:S;5;copy:S;10;selectAll:S;4;cut:S;14;checkSpelling:S;7;delete:S;6;paste:S;15;showGuessPanel:S;5;undo:S;23;performFindPanelAction:S;29;centerSelectionInVisibleArea:S;5;redo:S;30;toggleContinuousSpellChecking:S;12;performZoom:S;19;toggleToolbarShown:S;31;runToolbarCustomizationPalette:S;22;toggleGrammarChecking:S;24;toggleSmartInsertDelete:S;33;toggleAutomaticQuoteSubstitution:S;29;toggleAutomaticLinkDetection:S;9;AMainMenuS;11;_CPMainMenuD;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;2;62E;D;K;6;CP$UIDd;2;69E;D;K;6;CP$UIDd;2;81E;D;K;6;CP$UIDd;3;114E;D;K;6;CP$UIDd;3;118E;D;K;6;CP$UIDd;3;124E;E;E;S;14;NewApplicationS;14;submenuAction:d;7;1048576S;18;_CPApplicationMenuD;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;2;64E;D;K;6;CP$UIDd;2;65E;D;K;6;CP$UIDd;2;66E;D;K;6;CP$UIDd;2;67E;D;K;6;CP$UIDd;2;68E;E;E;S;20;About NewApplicationT;S;0;F;S;12;Preferences…S;1;,S;19;Quit NewApplicationS;1;qS;4;FileD;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;2;71E;D;K;6;CP$UIDd;2;72E;D;K;6;CP$UIDd;2;73E;D;K;6;CP$UIDd;2;76E;D;K;6;CP$UIDd;2;77E;D;K;6;CP$UIDd;2;78E;D;K;6;CP$UIDd;2;79E;D;K;6;CP$UIDd;2;80E;E;E;S;3;NewS;1;nS;5;Open…S;1;oS;11;Open RecentS;22;_CPRecentDocumentsMenuD;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;2;75E;E;E;S;10;Clear MenuS;5;CloseS;1;wS;4;SaveS;1;sS;8;Save As…S;1;Sd;7;1179648S;15;Revert to SavedS;4;EditD;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;2;83E;D;K;6;CP$UIDd;2;84E;D;K;6;CP$UIDd;2;85E;D;K;6;CP$UIDd;2;86E;D;K;6;CP$UIDd;2;87E;D;K;6;CP$UIDd;2;88E;D;K;6;CP$UIDd;2;89E;D;K;6;CP$UIDd;2;90E;D;K;6;CP$UIDd;2;91E;D;K;6;CP$UIDd;2;92E;D;K;6;CP$UIDd;2;99E;D;K;6;CP$UIDd;3;105E;D;K;6;CP$UIDd;3;110E;E;E;S;4;UndoS;1;zS;4;RedoS;1;ZS;3;CutS;1;xS;4;CopyS;1;cS;5;PasteS;1;vS;6;DeleteS;10;Select AllS;1;aS;4;FindD;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;2;94E;D;K;6;CP$UIDd;2;95E;D;K;6;CP$UIDd;2;96E;D;K;6;CP$UIDd;2;97E;D;K;6;CP$UIDd;2;98E;E;E;S;5;Find…d;1;1S;1;fS;9;Find Nextd;1;2S;1;gS;13;Find Previousd;1;3S;1;GS;22;Use Selection for Findd;1;7S;1;eS;17;Jump to SelectionS;1;jS;20;Spelling and GrammarD;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;3;101E;D;K;6;CP$UIDd;3;102E;D;K;6;CP$UIDd;3;103E;D;K;6;CP$UIDd;3;104E;E;E;S;14;Show Spelling…S;1;:S;14;Check SpellingS;1;;S;27;Check Spelling While TypingS;27;Check Grammar With SpellingS;13;SubstitutionsD;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;3;107E;D;K;6;CP$UIDd;3;108E;D;K;6;CP$UIDd;3;109E;E;E;S;16;Smart Copy/PasteS;12;Smart QuotesS;11;Smart LinksS;6;SpeechD;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;3;112E;D;K;6;CP$UIDd;3;113E;E;E;S;14;Start SpeakingS;13;Stop SpeakingS;4;ViewD;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;3;116E;D;K;6;CP$UIDd;3;117E;E;E;S;12;Show ToolbarS;1;td;7;1572864S;18;Customize Toolbar…S;6;WindowS;14;_CPWindowsMenuD;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;3;120E;D;K;6;CP$UIDd;3;121E;D;K;6;CP$UIDd;3;122E;D;K;6;CP$UIDd;3;123E;E;E;S;8;MinimizeS;1;mS;4;ZoomS;18;Bring All to FrontS;4;HelpD;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;3;126E;E;E;S;19;NewApplication HelpS;1;?S;32;{10000000000000, 10000000000000}S;8;CPWindowd;10;1881669632S;27;{{119, -560}, {1374, 1031}}S;22;{{0, 0}, {2560, 1417}}d;2;15d;1;0S;22;{{0, 0}, {1374, 1031}}D;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;3;132E;D;K;6;CP$UIDd;3;137E;D;K;6;CP$UIDd;3;141E;D;K;6;CP$UIDd;3;149E;D;K;6;CP$UIDd;3;162E;D;K;6;CP$UIDd;3;163E;D;K;6;CP$UIDd;3;164E;D;K;6;CP$UIDd;3;165E;E;E;S;6;normalS;6;{1, 1}S;23;{{940, 147}, {214, 73}}S;19;{{0, 0}, {214, 73}}D;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;3;134E;D;K;6;CP$UIDd;3;135E;D;K;6;CP$UIDd;3;136E;E;E;d;2;36S;9;splitviewS;18;{{0, 0}, {59, 73}}d;1;8S;6;CPViewS;19;{{60, 0}, {59, 73}}S;20;{{120, 0}, {94, 73}}S;18;{{0, 0}, {94, 73}}S;24;{{940, 231}, {214, 102}}S;20;{{0, 0}, {214, 102}}D;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;3;138E;D;K;6;CP$UIDd;3;139E;E;E;S;20;{{0, 57}, {214, 45}}S;19;{{0, 0}, {214, 45}}S;19;{{0, 0}, {214, 48}}S;24;{{940, 355}, {277, 163}}S;20;{{0, 0}, {277, 163}}D;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;3;143E;D;K;6;CP$UIDd;3;147E;D;K;6;CP$UIDd;3;148E;D;K;6;CP$UIDd;3;347E;E;E;S;10;scrollviewd;2;10D;K;6;$classD;K;6;CP$UIDd;3;129E;K;27;CPResponderNextResponderKeyD;K;6;CP$UIDd;3;141E;K;18;CPResponderMenuKeyD;K;6;CP$UIDd;1;0E;K;14;CPViewFrameKeyD;K;6;CP$UIDd;3;432E;K;15;CPViewBoundsKeyD;K;6;CP$UIDd;3;432E;K;18;CPViewSuperviewKeyD;K;6;CP$UIDd;3;141E;K;19;CPViewThemeClassKeyD;K;6;CP$UIDd;1;0E;K;19;CPViewThemeStateKeyD;K;6;CP$UIDd;3;323E;K;14;CPViewScaleKeyD;K;6;CP$UIDd;3;324E;K;18;CPViewSizeScaleKeyD;K;6;CP$UIDd;3;324E;K;17;CPViewIsScaledKeyD;K;6;CP$UIDd;3;226E;K;19;CPViewAppearanceKeyD;K;6;CP$UIDd;1;0E;E;S;20;{{1, 1}, {275, 161}}S;20;{{0, 0}, {275, 161}}D;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;3;144E;E;E;d;2;18D;K;10;$classnameS;7;CPColorK;8;$classesA;S;7;CPColorS;8;CPObjectE;E;D;K;6;$classD;K;6;CP$UIDd;3;352E;K;20;CPColorComponentsKeyD;K;6;CP$UIDd;3;433E;E;S;20;{{0, 0}, {290, 346}}D;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;3;145E;E;E;S;22;{{56, 204}, {163, 96}}S;19;{{0, 0}, {163, 96}}S;12;SensibleViewS;19;{{1, 2}, {275, 15}}S;19;{{0, 0}, {275, 15}}S;8;scrollerS;27;controlSizeRegular+disabledS;29;_horizontalScrollerDidScroll:d;1;4S;21;{{261, 1}, {15, 161}}S;19;{{0, 0}, {15, 161}}S;27;_verticalScrollerDidScroll:S;24;{{940, 535}, {277, 119}}S;20;{{0, 0}, {277, 119}}D;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;3;150E;D;K;6;CP$UIDd;3;371E;D;K;6;CP$UIDd;3;157E;D;K;6;CP$UIDd;3;158E;D;K;6;CP$UIDd;3;372E;E;E;D;K;6;$classD;K;6;CP$UIDd;3;142E;K;27;CPResponderNextResponderKeyD;K;6;CP$UIDd;3;149E;K;18;CPResponderMenuKeyD;K;6;CP$UIDd;1;0E;K;12;CPViewTagKeyD;K;6;CP$UIDd;3;320E;K;14;CPViewFrameKeyD;K;6;CP$UIDd;3;434E;K;15;CPViewBoundsKeyD;K;6;CP$UIDd;3;404E;K;17;CPViewSubviewsKeyD;K;6;CP$UIDd;3;435E;K;18;CPViewSuperviewKeyD;K;6;CP$UIDd;3;149E;K;22;CPViewAutoresizingMaskD;K;6;CP$UIDd;3;331E;K;19;CPViewThemeClassKeyD;K;6;CP$UIDd;1;0E;K;19;CPViewThemeStateKeyD;K;6;CP$UIDd;3;323E;K;14;CPViewScaleKeyD;K;6;CP$UIDd;3;324E;K;18;CPViewSizeScaleKeyD;K;6;CP$UIDd;3;324E;K;17;CPViewIsScaledKeyD;K;6;CP$UIDd;3;226E;K;19;CPViewAppearanceKeyD;K;6;CP$UIDd;1;0E;K;24;CPScrollViewDocumentViewD;K;6;CP$UIDd;3;160E;E;D;K;6;$classD;K;6;CP$UIDd;3;129E;K;27;CPResponderNextResponderKeyD;K;6;CP$UIDd;3;149E;K;18;CPResponderMenuKeyD;K;6;CP$UIDd;1;0E;K;14;CPViewFrameKeyD;K;6;CP$UIDd;3;432E;K;15;CPViewBoundsKeyD;K;6;CP$UIDd;3;432E;K;18;CPViewSuperviewKeyD;K;6;CP$UIDd;3;149E;K;19;CPViewThemeClassKeyD;K;6;CP$UIDd;1;0E;K;19;CPViewThemeStateKeyD;K;6;CP$UIDd;3;323E;K;14;CPViewScaleKeyD;K;6;CP$UIDd;3;324E;K;18;CPViewSizeScaleKeyD;K;6;CP$UIDd;3;324E;K;17;CPViewIsScaledKeyD;K;6;CP$UIDd;3;226E;K;19;CPViewAppearanceKeyD;K;6;CP$UIDd;1;0E;E;S;20;{{1, 1}, {275, 118}}S;20;{{0, 0}, {275, 118}}D;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;3;152E;E;E;D;K;6;$classD;K;6;CP$UIDd;3;352E;K;20;CPColorComponentsKeyD;K;6;CP$UIDd;3;436E;E;S;19;{{0, 0}, {275, 95}}S;9;tableviewD;K;6;$classD;K;6;CP$UIDd;3;352E;K;20;CPColorComponentsKeyD;K;6;CP$UIDd;3;437E;E;d;2;25S;6;{3, 2}D;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;3;154E;D;K;6;CP$UIDd;3;155E;D;K;6;CP$UIDd;3;156E;E;E;D;K;10;$classnameS;13;_CPCornerViewK;8;$classesA;S;13;_CPCornerViewS;6;CPViewS;11;CPResponderS;8;CPObjectE;E;D;K;6;$classD;K;6;CP$UIDd;3;383E;K;18;CPResponderMenuKeyD;K;6;CP$UIDd;1;0E;K;12;CPViewTagKeyD;K;6;CP$UIDd;3;320E;K;14;CPViewFrameKeyD;K;6;CP$UIDd;3;438E;K;15;CPViewBoundsKeyD;K;6;CP$UIDd;3;438E;K;19;CPViewThemeClassKeyD;K;6;CP$UIDd;3;439E;K;19;CPViewThemeStateKeyD;K;6;CP$UIDd;3;323E;K;14;CPViewScaleKeyD;K;6;CP$UIDd;3;324E;K;18;CPViewSizeScaleKeyD;K;6;CP$UIDd;3;324E;K;17;CPViewIsScaledKeyD;K;6;CP$UIDd;3;226E;K;19;CPViewAppearanceKeyD;K;6;CP$UIDd;1;0E;E;f;11;78.77734375d;2;40d;4;1000D;K;10;$classnameS;24;_CPTableColumnHeaderViewK;8;$classesA;S;24;_CPTableColumnHeaderViewS;6;CPViewS;11;CPResponderS;8;CPObjectE;E;D;K;6;$classD;K;6;CP$UIDd;3;388E;K;18;CPResponderMenuKeyD;K;6;CP$UIDd;1;0E;K;14;CPViewFrameKeyD;K;6;CP$UIDd;3;432E;K;15;CPViewBoundsKeyD;K;6;CP$UIDd;3;432E;K;17;CPViewSubviewsKeyD;K;6;CP$UIDd;3;440E;K;19;CPViewThemeClassKeyD;K;6;CP$UIDd;3;441E;K;19;CPViewThemeStateKeyD;K;6;CP$UIDd;3;323E;K;16;$atext-alignmentD;K;6;CP$UIDd;3;364E;K;12;$atext-colorD;K;6;CP$UIDd;3;442E;K;6;$afontD;K;6;CP$UIDd;3;443E;K;14;CPViewScaleKeyD;K;6;CP$UIDd;3;324E;K;18;CPViewSizeScaleKeyD;K;6;CP$UIDd;3;324E;K;17;CPViewIsScaledKeyD;K;6;CP$UIDd;3;226E;K;19;CPViewAppearanceKeyD;K;6;CP$UIDd;1;0E;K;38;_CPTableColumnHeaderViewStringValueKeyD;K;6;CP$UIDd;3;444E;K;32;_CPTableColumnHeaderViewImageKeyD;K;6;CP$UIDd;1;0E;K;31;_CPTableColumnHeaderViewFontKeyD;K;6;CP$UIDd;3;443E;E;D;K;6;$classD;K;6;CP$UIDd;3;161E;K;18;CPResponderMenuKeyD;K;6;CP$UIDd;1;0E;K;14;CPViewFrameKeyD;K;6;CP$UIDd;3;432E;K;15;CPViewBoundsKeyD;K;6;CP$UIDd;3;432E;K;19;CPViewThemeClassKeyD;K;6;CP$UIDd;3;408E;K;19;CPViewThemeStateKeyD;K;6;CP$UIDd;3;445E;K;11;$aalignmentD;K;6;CP$UIDd;3;364E;K;17;$aline-break-modeD;K;6;CP$UIDd;3;364E;K;6;$afontD;K;6;CP$UIDd;3;446E;K;14;CPViewScaleKeyD;K;6;CP$UIDd;3;324E;K;18;CPViewSizeScaleKeyD;K;6;CP$UIDd;3;324E;K;17;CPViewIsScaledKeyD;K;6;CP$UIDd;3;226E;K;19;CPViewAppearanceKeyD;K;6;CP$UIDd;1;0E;K;17;CPControlValueKeyD;K;6;CP$UIDd;3;447E;K;24;CPControlSendActionOnKeyD;K;6;CP$UIDd;3;448E;K;23;CPControlControlSizeKeyD;K;6;CP$UIDd;3;320E;K;33;CPControlBaseWrittingDirectionKeyD;K;6;CP$UIDd;3;413E;K;24;CPTextFieldIsEditableKeyD;K;6;CP$UIDd;3;224E;K;26;CPTextFieldIsSelectableKeyD;K;6;CP$UIDd;3;224E;K;29;CPTextFieldDrawsBackgroundKeyD;K;6;CP$UIDd;3;226E;K;29;CPTextFieldBackgroundColorKeyD;K;6;CP$UIDd;3;376E;K;27;CPTextFieldLineBreakModeKeyD;K;6;CP$UIDd;3;364E;K;23;CPTextFieldAlignmentKeyD;K;6;CP$UIDd;3;364E;K;31;CPTextFieldPlaceholderStringKeyD;K;6;CP$UIDd;1;0E;K;29;CPTextFieldUsesSingleLineModeD;K;6;CP$UIDd;3;226E;K;16;CPTextFieldWrapsD;K;6;CP$UIDd;3;226E;K;18;CPTextFieldScrollsD;K;6;CP$UIDd;3;226E;E;f;10;106.203125D;K;6;$classD;K;6;CP$UIDd;3;388E;K;18;CPResponderMenuKeyD;K;6;CP$UIDd;1;0E;K;14;CPViewFrameKeyD;K;6;CP$UIDd;3;432E;K;15;CPViewBoundsKeyD;K;6;CP$UIDd;3;432E;K;17;CPViewSubviewsKeyD;K;6;CP$UIDd;3;449E;K;19;CPViewThemeClassKeyD;K;6;CP$UIDd;3;441E;K;19;CPViewThemeStateKeyD;K;6;CP$UIDd;3;323E;K;16;$atext-alignmentD;K;6;CP$UIDd;3;364E;K;12;$atext-colorD;K;6;CP$UIDd;3;442E;K;6;$afontD;K;6;CP$UIDd;3;443E;K;14;CPViewScaleKeyD;K;6;CP$UIDd;3;324E;K;18;CPViewSizeScaleKeyD;K;6;CP$UIDd;3;324E;K;17;CPViewIsScaledKeyD;K;6;CP$UIDd;3;226E;K;19;CPViewAppearanceKeyD;K;6;CP$UIDd;1;0E;K;38;_CPTableColumnHeaderViewStringValueKeyD;K;6;CP$UIDd;3;450E;K;32;_CPTableColumnHeaderViewImageKeyD;K;6;CP$UIDd;1;0E;K;31;_CPTableColumnHeaderViewFontKeyD;K;6;CP$UIDd;3;443E;E;D;K;6;$classD;K;6;CP$UIDd;3;161E;K;18;CPResponderMenuKeyD;K;6;CP$UIDd;1;0E;K;14;CPViewFrameKeyD;K;6;CP$UIDd;3;432E;K;15;CPViewBoundsKeyD;K;6;CP$UIDd;3;432E;K;19;CPViewThemeClassKeyD;K;6;CP$UIDd;3;408E;K;19;CPViewThemeStateKeyD;K;6;CP$UIDd;3;445E;K;11;$aalignmentD;K;6;CP$UIDd;3;364E;K;17;$aline-break-modeD;K;6;CP$UIDd;3;364E;K;6;$afontD;K;6;CP$UIDd;3;446E;K;14;CPViewScaleKeyD;K;6;CP$UIDd;3;324E;K;18;CPViewSizeScaleKeyD;K;6;CP$UIDd;3;324E;K;17;CPViewIsScaledKeyD;K;6;CP$UIDd;3;226E;K;19;CPViewAppearanceKeyD;K;6;CP$UIDd;1;0E;K;17;CPControlValueKeyD;K;6;CP$UIDd;3;447E;K;24;CPControlSendActionOnKeyD;K;6;CP$UIDd;3;448E;K;23;CPControlControlSizeKeyD;K;6;CP$UIDd;3;320E;K;33;CPControlBaseWrittingDirectionKeyD;K;6;CP$UIDd;3;413E;K;24;CPTextFieldIsEditableKeyD;K;6;CP$UIDd;3;224E;K;26;CPTextFieldIsSelectableKeyD;K;6;CP$UIDd;3;224E;K;29;CPTextFieldDrawsBackgroundKeyD;K;6;CP$UIDd;3;226E;K;29;CPTextFieldBackgroundColorKeyD;K;6;CP$UIDd;3;376E;K;27;CPTextFieldLineBreakModeKeyD;K;6;CP$UIDd;3;364E;K;23;CPTextFieldAlignmentKeyD;K;6;CP$UIDd;3;364E;K;31;CPTextFieldPlaceholderStringKeyD;K;6;CP$UIDd;1;0E;K;29;CPTextFieldUsesSingleLineModeD;K;6;CP$UIDd;3;226E;K;16;CPTextFieldWrapsD;K;6;CP$UIDd;3;226E;K;18;CPTextFieldScrollsD;K;6;CP$UIDd;3;226E;E;d;2;81f;22;3.4028234663852886e+38D;K;6;$classD;K;6;CP$UIDd;3;388E;K;18;CPResponderMenuKeyD;K;6;CP$UIDd;1;0E;K;14;CPViewFrameKeyD;K;6;CP$UIDd;3;432E;K;15;CPViewBoundsKeyD;K;6;CP$UIDd;3;432E;K;17;CPViewSubviewsKeyD;K;6;CP$UIDd;3;451E;K;19;CPViewThemeClassKeyD;K;6;CP$UIDd;3;441E;K;19;CPViewThemeStateKeyD;K;6;CP$UIDd;3;323E;K;16;$atext-alignmentD;K;6;CP$UIDd;3;320E;K;12;$atext-colorD;K;6;CP$UIDd;3;442E;K;6;$afontD;K;6;CP$UIDd;3;443E;K;14;CPViewScaleKeyD;K;6;CP$UIDd;3;324E;K;18;CPViewSizeScaleKeyD;K;6;CP$UIDd;3;324E;K;17;CPViewIsScaledKeyD;K;6;CP$UIDd;3;226E;K;19;CPViewAppearanceKeyD;K;6;CP$UIDd;1;0E;K;38;_CPTableColumnHeaderViewStringValueKeyD;K;6;CP$UIDd;3;452E;K;32;_CPTableColumnHeaderViewImageKeyD;K;6;CP$UIDd;1;0E;K;31;_CPTableColumnHeaderViewFontKeyD;K;6;CP$UIDd;3;443E;E;D;K;6;$classD;K;6;CP$UIDd;3;161E;K;18;CPResponderMenuKeyD;K;6;CP$UIDd;1;0E;K;14;CPViewFrameKeyD;K;6;CP$UIDd;3;432E;K;15;CPViewBoundsKeyD;K;6;CP$UIDd;3;432E;K;19;CPViewThemeClassKeyD;K;6;CP$UIDd;3;408E;K;19;CPViewThemeStateKeyD;K;6;CP$UIDd;3;445E;K;11;$aalignmentD;K;6;CP$UIDd;3;320E;K;17;$aline-break-modeD;K;6;CP$UIDd;3;364E;K;6;$afontD;K;6;CP$UIDd;3;446E;K;14;CPViewScaleKeyD;K;6;CP$UIDd;3;324E;K;18;CPViewSizeScaleKeyD;K;6;CP$UIDd;3;324E;K;17;CPViewIsScaledKeyD;K;6;CP$UIDd;3;226E;K;19;CPViewAppearanceKeyD;K;6;CP$UIDd;1;0E;K;17;CPControlValueKeyD;K;6;CP$UIDd;3;447E;K;24;CPControlSendActionOnKeyD;K;6;CP$UIDd;3;448E;K;23;CPControlControlSizeKeyD;K;6;CP$UIDd;3;320E;K;33;CPControlBaseWrittingDirectionKeyD;K;6;CP$UIDd;3;413E;K;24;CPTextFieldIsEditableKeyD;K;6;CP$UIDd;3;224E;K;26;CPTextFieldIsSelectableKeyD;K;6;CP$UIDd;3;224E;K;29;CPTextFieldDrawsBackgroundKeyD;K;6;CP$UIDd;3;226E;K;29;CPTextFieldBackgroundColorKeyD;K;6;CP$UIDd;3;376E;K;27;CPTextFieldLineBreakModeKeyD;K;6;CP$UIDd;3;364E;K;23;CPTextFieldAlignmentKeyD;K;6;CP$UIDd;3;320E;K;31;CPTextFieldPlaceholderStringKeyD;K;6;CP$UIDd;1;0E;K;29;CPTextFieldUsesSingleLineModeD;K;6;CP$UIDd;3;226E;K;16;CPTextFieldWrapsD;K;6;CP$UIDd;3;226E;K;18;CPTextFieldScrollsD;K;6;CP$UIDd;3;226E;E;S;22;{{1, -127}, {307, 15}}S;19;{{0, 0}, {307, 15}}d;11;-2147483648S;21;{{224, 0}, {15, 102}}S;19;{{0, 0}, {15, 102}}f;18;0.8368794326241135S;19;{{0, 0}, {275, 23}}S;14;tableHeaderRowS;23;{{1225, 535}, {84, 44}}S;18;{{0, 0}, {84, 44}}S;9;textfieldS;15;controlSizeMiniD;K;10;$classnameS;6;CPFontK;8;$classesA;S;6;CPFontS;8;CPObjectE;E;D;K;6;$classD;K;6;CP$UIDd;3;410E;K;13;CPFontNameKeyD;K;6;CP$UIDd;3;453E;K;13;CPFontSizeKeyD;K;6;CP$UIDd;3;454E;K;15;CPFontIsBoldKeyD;K;6;CP$UIDd;3;226E;K;17;CPFontIsItalicKeyD;K;6;CP$UIDd;3;226E;K;17;CPFontIsSystemKeyD;K;6;CP$UIDd;3;224E;E;S;61;CPTableHeaderView now using tracking areas for cursor updatesd;2;-1S;23;{{1225, 355}, {74, 55}}S;18;{{0, 0}, {74, 55}}D;K;6;$classD;K;6;CP$UIDd;3;410E;K;13;CPFontNameKeyD;K;6;CP$UIDd;3;453E;K;13;CPFontSizeKeyD;K;6;CP$UIDd;3;454E;K;15;CPFontIsBoldKeyD;K;6;CP$UIDd;3;226E;K;17;CPFontIsItalicKeyD;K;6;CP$UIDd;3;226E;K;17;CPFontIsSystemKeyD;K;6;CP$UIDd;3;224E;E;S;69;CPScrollView (scroll down to view and test a view with tracking area)S;23;{{1162, 156}, {74, 55}}D;K;6;$classD;K;6;CP$UIDd;3;410E;K;13;CPFontNameKeyD;K;6;CP$UIDd;3;453E;K;13;CPFontSizeKeyD;K;6;CP$UIDd;3;454E;K;15;CPFontIsBoldKeyD;K;6;CP$UIDd;3;226E;K;17;CPFontIsItalicKeyD;K;6;CP$UIDd;3;226E;K;17;CPFontIsSystemKeyD;K;6;CP$UIDd;3;224E;E;S;79;CPSplitView with thin vertical dividers, using tracking area for cursor updatesS;23;{{1162, 262}, {74, 39}}S;18;{{0, 0}, {74, 39}}D;K;6;$classD;K;6;CP$UIDd;3;410E;K;13;CPFontNameKeyD;K;6;CP$UIDd;3;453E;K;13;CPFontSizeKeyD;K;6;CP$UIDd;3;454E;K;15;CPFontIsBoldKeyD;K;6;CP$UIDd;3;226E;K;17;CPFontIsItalicKeyD;K;6;CP$UIDd;3;226E;K;17;CPFontIsSystemKeyD;K;6;CP$UIDd;3;224E;E;S;42;CPSplitView with thick horizontal dividersS;13;AppControllerS;15;backgroundColorD;K;6;$classD;K;6;CP$UIDd;3;352E;K;20;CPColorComponentsKeyD;K;6;CP$UIDd;3;455E;E;D;K;6;$classD;K;6;CP$UIDd;3;352E;K;20;CPColorComponentsKeyD;K;6;CP$UIDd;3;456E;E;D;K;6;$classD;K;6;CP$UIDd;3;352E;K;20;CPColorComponentsKeyD;K;6;CP$UIDd;3;457E;E;D;K;6;$classD;K;6;CP$UIDd;3;352E;K;20;CPColorComponentsKeyD;K;6;CP$UIDd;3;458E;E;D;K;6;$classD;K;6;CP$UIDd;3;352E;K;20;CPColorComponentsKeyD;K;6;CP$UIDd;3;459E;E;S;16;{{0, 0}, {0, 0}}D;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;3;460E;D;K;6;CP$UIDd;3;460E;D;K;6;CP$UIDd;3;460E;D;K;6;CP$UIDd;3;267E;E;E;S;20;{{1, 96}, {275, 23}}D;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;3;160E;E;E;D;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;3;267E;D;K;6;CP$UIDd;3;267E;D;K;6;CP$UIDd;3;267E;D;K;6;CP$UIDd;3;267E;E;E;D;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;3;461E;D;K;6;CP$UIDd;3;461E;D;K;6;CP$UIDd;3;461E;D;K;6;CP$UIDd;3;267E;E;E;S;18;{{0, 0}, {14, 25}}S;10;cornerviewD;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;3;463E;E;E;S;12;columnHeaderD;K;6;$classD;K;6;CP$UIDd;3;352E;K;20;CPColorComponentsKeyD;K;6;CP$UIDd;3;464E;E;D;K;6;$classD;K;6;CP$UIDd;3;410E;K;13;CPFontNameKeyD;K;6;CP$UIDd;3;453E;K;13;CPFontSizeKeyD;K;6;CP$UIDd;3;465E;K;15;CPFontIsBoldKeyD;K;6;CP$UIDd;3;224E;K;17;CPFontIsItalicKeyD;K;6;CP$UIDd;3;226E;K;17;CPFontIsSystemKeyD;K;6;CP$UIDd;3;224E;E;S;5;FirstS;41;controlSizeRegular+editable+tableDataViewD;K;6;$classD;K;6;CP$UIDd;3;410E;K;13;CPFontNameKeyD;K;6;CP$UIDd;3;453E;K;13;CPFontSizeKeyD;K;6;CP$UIDd;3;413E;K;15;CPFontIsBoldKeyD;K;6;CP$UIDd;3;226E;K;17;CPFontIsItalicKeyD;K;6;CP$UIDd;3;226E;K;17;CPFontIsSystemKeyD;K;6;CP$UIDd;3;224E;E;S;9;Text Celld;4;3072D;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;3;466E;E;E;S;6;SecondD;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;3;467E;E;E;S;5;ThirdS;28;_CPFontSystemFacePlaceholderd;1;9D;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;3;468E;D;K;6;CP$UIDd;3;320E;D;K;6;CP$UIDd;3;320E;D;K;6;CP$UIDd;3;267E;E;E;D;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;3;320E;D;K;6;CP$UIDd;3;469E;D;K;6;CP$UIDd;3;470E;D;K;6;CP$UIDd;3;267E;E;E;D;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;3;320E;D;K;6;CP$UIDd;3;471E;D;K;6;CP$UIDd;3;320E;D;K;6;CP$UIDd;3;267E;E;E;D;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;3;472E;D;K;6;CP$UIDd;3;473E;D;K;6;CP$UIDd;3;474E;D;K;6;CP$UIDd;3;267E;E;E;D;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;3;475E;D;K;6;CP$UIDd;3;476E;D;K;6;CP$UIDd;3;477E;D;K;6;CP$UIDd;3;267E;E;E;f;18;0.6862745098039216f;3;0.8D;K;10;$classnameS;19;_CPImageAndTextViewK;8;$classesA;S;19;_CPImageAndTextViewS;6;CPViewS;11;CPResponderS;8;CPObjectE;E;D;K;6;$classD;K;6;CP$UIDd;3;462E;K;27;CPResponderNextResponderKeyD;K;6;CP$UIDd;3;389E;K;18;CPResponderMenuKeyD;K;6;CP$UIDd;1;0E;K;14;CPViewFrameKeyD;K;6;CP$UIDd;3;478E;K;15;CPViewBoundsKeyD;K;6;CP$UIDd;3;479E;K;18;CPViewSuperviewKeyD;K;6;CP$UIDd;3;389E;K;22;CPViewAutoresizingMaskD;K;6;CP$UIDd;3;351E;K;17;CPViewHitTestsKeyD;K;6;CP$UIDd;3;226E;K;19;CPViewThemeClassKeyD;K;6;CP$UIDd;1;0E;K;19;CPViewThemeStateKeyD;K;6;CP$UIDd;3;323E;K;14;CPViewScaleKeyD;K;6;CP$UIDd;3;324E;K;18;CPViewSizeScaleKeyD;K;6;CP$UIDd;3;324E;K;17;CPViewIsScaledKeyD;K;6;CP$UIDd;3;226E;K;19;CPViewAppearanceKeyD;K;6;CP$UIDd;1;0E;E;D;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;3;480E;D;K;6;CP$UIDd;3;480E;D;K;6;CP$UIDd;3;480E;D;K;6;CP$UIDd;3;267E;E;E;d;2;12D;K;6;$classD;K;6;CP$UIDd;3;462E;K;27;CPResponderNextResponderKeyD;K;6;CP$UIDd;3;392E;K;18;CPResponderMenuKeyD;K;6;CP$UIDd;1;0E;K;14;CPViewFrameKeyD;K;6;CP$UIDd;3;478E;K;15;CPViewBoundsKeyD;K;6;CP$UIDd;3;479E;K;18;CPViewSuperviewKeyD;K;6;CP$UIDd;3;392E;K;22;CPViewAutoresizingMaskD;K;6;CP$UIDd;3;351E;K;17;CPViewHitTestsKeyD;K;6;CP$UIDd;3;226E;K;19;CPViewThemeClassKeyD;K;6;CP$UIDd;1;0E;K;19;CPViewThemeStateKeyD;K;6;CP$UIDd;3;323E;K;14;CPViewScaleKeyD;K;6;CP$UIDd;3;324E;K;18;CPViewSizeScaleKeyD;K;6;CP$UIDd;3;324E;K;17;CPViewIsScaledKeyD;K;6;CP$UIDd;3;226E;K;19;CPViewAppearanceKeyD;K;6;CP$UIDd;1;0E;E;D;K;6;$classD;K;6;CP$UIDd;3;462E;K;27;CPResponderNextResponderKeyD;K;6;CP$UIDd;3;396E;K;18;CPResponderMenuKeyD;K;6;CP$UIDd;1;0E;K;14;CPViewFrameKeyD;K;6;CP$UIDd;3;478E;K;15;CPViewBoundsKeyD;K;6;CP$UIDd;3;479E;K;18;CPViewSuperviewKeyD;K;6;CP$UIDd;3;396E;K;22;CPViewAutoresizingMaskD;K;6;CP$UIDd;3;351E;K;17;CPViewHitTestsKeyD;K;6;CP$UIDd;3;226E;K;19;CPViewThemeClassKeyD;K;6;CP$UIDd;1;0E;K;19;CPViewThemeStateKeyD;K;6;CP$UIDd;3;323E;K;14;CPViewScaleKeyD;K;6;CP$UIDd;3;324E;K;18;CPViewSizeScaleKeyD;K;6;CP$UIDd;3;324E;K;17;CPViewIsScaledKeyD;K;6;CP$UIDd;3;226E;K;19;CPViewAppearanceKeyD;K;6;CP$UIDd;1;0E;E;f;12;0.5669043624f;12;0.2389628775f;11;0.647965604f;12;0.5314072987f;12;0.5763914944f;12;0.5976963141f;12;0.5329355132f;12;0.4716600252f;12;0.3736891779f;12;0.1722158138S;18;{{5, 0}, {-10, 0}}S;18;{{0, 0}, {-10, 0}}f;18;0.5019607843137255E;K;9;$archiverS;15;CPKeyedArchiverK;8;$versionS;6;100000E; \ No newline at end of file diff --git a/Tests/Manual/TrackingArea/Resources/MainMenu.xib b/Tests/Manual/TrackingArea/Resources/MainMenu.xib new file mode 100644 index 000000000..5377684fc --- /dev/null +++ b/Tests/Manual/TrackingArea/Resources/MainMenu.xib @@ -0,0 +1,525 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Tests/Manual/TrackingArea/index-debug.html b/Tests/Manual/TrackingArea/index-debug.html new file mode 100644 index 000000000..ea5f6f364 --- /dev/null +++ b/Tests/Manual/TrackingArea/index-debug.html @@ -0,0 +1,193 @@ + + + + + + + + + + + + + + + + + + TrackingArea + + + + + + + + + + + + + + +
+
+
+ +
+
+ +
+ + diff --git a/Tests/Manual/TrackingArea/index.html b/Tests/Manual/TrackingArea/index.html new file mode 100644 index 000000000..cc1a78e03 --- /dev/null +++ b/Tests/Manual/TrackingArea/index.html @@ -0,0 +1,161 @@ + + + + + + + + + + + + + + + + + + TrackingArea + + + + + + + + + + + + +
+
+
+ +
+
+ +
+ + diff --git a/Tests/Manual/TrackingArea/main.j b/Tests/Manual/TrackingArea/main.j new file mode 100644 index 000000000..4cbeeb386 --- /dev/null +++ b/Tests/Manual/TrackingArea/main.j @@ -0,0 +1,18 @@ +/* + * AppController.j + * TrackingArea + * + * Created by You on November 2, 2015. + * Copyright 2015, Your Company All rights reserved. + */ + +@import +@import + +@import "AppController.j" + + +function main(args, namedArgs) +{ + CPApplicationMain(args, namedArgs); +}