Merge remote-tracking branch 'cappuccino/master'

This commit is contained in:
Didier Korthoudt committed 2015-12-22 18:07:02 +01:00
commit b32499f6ec
20 files changed
+3286 -103

No files matched your search

+1
View File
@@ -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"
+14 -1
View File
@@ -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",
+3
View File
@@ -123,6 +123,9 @@ var currentCursor = nil,
- (void)set
{
if (currentCursor === self)
return;
currentCursor = self;
#if PLATFORM(DOM)
+54
View File
@@ -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()
+13
View File
@@ -24,6 +24,7 @@
@import <Foundation/CPObjJRuntime.j>
@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
+26 -20
View File
@@ -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
+23 -31
View File
@@ -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];
+164
View File
@@ -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 <Foundation/Foundation.j>
@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
+188
View File
@@ -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
+404 -51
View File
@@ -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 };
+17
View File
@@ -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
+584
View File
@@ -2,6 +2,14 @@
@import <AppKit/CPApplication.j>
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
+699
View File
@@ -0,0 +1,699 @@
/*
* AppController.j
* TrackingArea
*
* Created by Didier Korthoudt on November 2, 2015.
* Copyright 2015, Your Company All rights reserved.
*/
@import <Foundation/Foundation.j>
@import <AppKit/AppKit.j>
@import <AppKit/CPTrackingArea.j>
@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
+14
View File
@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Main cib file base name</key>
<string>MainMenu.cib</string>
<key>CPBundleName</key>
<string>TrackingArea</string>
<key>CPBundleVersion</key>
<string>1.0</string>
<key>CPHumanReadableCopyright</key>
<string>Copyright © 2015, Your Company All rights reserved.</string>
</dict>
</plist>
+184
View File
@@ -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();
}
}
@@ -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;Line truncated
@@ -0,0 +1,525 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="9060" systemVersion="15C50" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none">
<dependencies>
<deployment version="1050" identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="9060"/>
</dependencies>
<objects>
<customObject id="-2" userLabel="File's Owner" customClass="NSApplication">
<connections>
<outlet property="delegate" destination="450" id="451"/>
</connections>
</customObject>
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
<menu title="AMainMenu" systemMenu="main" id="29" userLabel="MainMenu">
<items>
<menuItem title="NewApplication" id="56">
<menu key="submenu" title="NewApplication" systemMenu="apple" id="57">
<items>
<menuItem title="About NewApplication" id="58">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="orderFrontStandardAboutPanel:" target="-2" id="142"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="236">
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
</menuItem>
<menuItem title="Preferences…" keyEquivalent="," id="129"/>
<menuItem isSeparatorItem="YES" id="143">
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
</menuItem>
<menuItem title="Quit NewApplication" keyEquivalent="q" id="136">
<connections>
<action selector="terminate:" target="-3" id="449"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="File" id="83">
<menu key="submenu" title="File" id="81">
<items>
<menuItem title="New" keyEquivalent="n" id="82">
<connections>
<action selector="newDocument:" target="-1" id="373"/>
</connections>
</menuItem>
<menuItem title="Open…" keyEquivalent="o" id="72">
<connections>
<action selector="openDocument:" target="-1" id="374"/>
</connections>
</menuItem>
<menuItem title="Open Recent" id="124">
<menu key="submenu" title="Open Recent" systemMenu="recentDocuments" id="125">
<items>
<menuItem title="Clear Menu" id="126">
<connections>
<action selector="clearRecentDocuments:" target="-1" id="127"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem isSeparatorItem="YES" id="79">
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
</menuItem>
<menuItem title="Close" keyEquivalent="w" id="73">
<connections>
<action selector="performClose:" target="-1" id="193"/>
</connections>
</menuItem>
<menuItem title="Save" keyEquivalent="s" id="75">
<connections>
<action selector="saveDocument:" target="-1" id="362"/>
</connections>
</menuItem>
<menuItem title="Save As…" keyEquivalent="S" id="80">
<modifierMask key="keyEquivalentModifierMask" shift="YES" command="YES"/>
<connections>
<action selector="saveDocumentAs:" target="-1" id="363"/>
</connections>
</menuItem>
<menuItem title="Revert to Saved" id="112">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="revertDocumentToSaved:" target="-1" id="364"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="Edit" id="217">
<menu key="submenu" title="Edit" id="205">
<items>
<menuItem title="Undo" keyEquivalent="z" id="207">
<connections>
<action selector="undo:" target="-1" id="223"/>
</connections>
</menuItem>
<menuItem title="Redo" keyEquivalent="Z" id="215">
<modifierMask key="keyEquivalentModifierMask" shift="YES" command="YES"/>
<connections>
<action selector="redo:" target="-1" id="231"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="206">
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
</menuItem>
<menuItem title="Cut" keyEquivalent="x" id="199">
<connections>
<action selector="cut:" target="-1" id="228"/>
</connections>
</menuItem>
<menuItem title="Copy" keyEquivalent="c" id="197">
<connections>
<action selector="copy:" target="-1" id="224"/>
</connections>
</menuItem>
<menuItem title="Paste" keyEquivalent="v" id="203">
<connections>
<action selector="paste:" target="-1" id="226"/>
</connections>
</menuItem>
<menuItem title="Delete" id="202">
<connections>
<action selector="delete:" target="-1" id="235"/>
</connections>
</menuItem>
<menuItem title="Select All" keyEquivalent="a" id="198">
<connections>
<action selector="selectAll:" target="-1" id="232"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="214">
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
</menuItem>
<menuItem title="Find" id="218">
<menu key="submenu" title="Find" id="220">
<items>
<menuItem title="Find…" tag="1" keyEquivalent="f" id="209">
<connections>
<action selector="performFindPanelAction:" target="-1" id="241"/>
</connections>
</menuItem>
<menuItem title="Find Next" tag="2" keyEquivalent="g" id="208"/>
<menuItem title="Find Previous" tag="3" keyEquivalent="G" id="213">
<modifierMask key="keyEquivalentModifierMask" shift="YES" command="YES"/>
</menuItem>
<menuItem title="Use Selection for Find" tag="7" keyEquivalent="e" id="221"/>
<menuItem title="Jump to Selection" keyEquivalent="j" id="210">
<connections>
<action selector="centerSelectionInVisibleArea:" target="-1" id="245"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="Spelling and Grammar" id="216">
<menu key="submenu" title="Spelling and Grammar" id="200">
<items>
<menuItem title="Show Spelling…" keyEquivalent=":" id="204">
<connections>
<action selector="showGuessPanel:" target="-1" id="230"/>
</connections>
</menuItem>
<menuItem title="Check Spelling" keyEquivalent=";" id="201">
<connections>
<action selector="checkSpelling:" target="-1" id="225"/>
</connections>
</menuItem>
<menuItem title="Check Spelling While Typing" id="219">
<connections>
<action selector="toggleContinuousSpellChecking:" target="-1" id="222"/>
</connections>
</menuItem>
<menuItem title="Check Grammar With Spelling" id="346">
<connections>
<action selector="toggleGrammarChecking:" target="-1" id="347"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="Substitutions" id="348">
<menu key="submenu" title="Substitutions" id="349">
<items>
<menuItem title="Smart Copy/Paste" tag="1" keyEquivalent="f" id="350">
<connections>
<action selector="toggleSmartInsertDelete:" target="-1" id="355"/>
</connections>
</menuItem>
<menuItem title="Smart Quotes" tag="2" keyEquivalent="g" id="351">
<connections>
<action selector="toggleAutomaticQuoteSubstitution:" target="-1" id="356"/>
</connections>
</menuItem>
<menuItem title="Smart Links" tag="3" keyEquivalent="G" id="354">
<modifierMask key="keyEquivalentModifierMask" shift="YES" command="YES"/>
<connections>
<action selector="toggleAutomaticLinkDetection:" target="-1" id="357"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="Speech" id="211">
<menu key="submenu" title="Speech" id="212">
<items>
<menuItem title="Start Speaking" id="196">
<connections>
<action selector="startSpeaking:" target="-1" id="233"/>
</connections>
</menuItem>
<menuItem title="Stop Speaking" id="195">
<connections>
<action selector="stopSpeaking:" target="-1" id="227"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="View" id="295">
<menu key="submenu" title="View" id="296">
<items>
<menuItem title="Show Toolbar" keyEquivalent="t" id="297">
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
<connections>
<action selector="toggleToolbarShown:" target="-1" id="366"/>
</connections>
</menuItem>
<menuItem title="Customize Toolbar…" id="298">
<connections>
<action selector="runToolbarCustomizationPalette:" target="-1" id="365"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="Window" id="19">
<menu key="submenu" title="Window" systemMenu="window" id="24">
<items>
<menuItem title="Minimize" keyEquivalent="m" id="23">
<connections>
<action selector="performMiniaturize:" target="-1" id="37"/>
</connections>
</menuItem>
<menuItem title="Zoom" id="239">
<connections>
<action selector="performZoom:" target="-1" id="240"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="92">
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
</menuItem>
<menuItem title="Bring All to Front" id="5">
<connections>
<action selector="arrangeInFront:" target="-1" id="39"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="Help" id="103">
<menu key="submenu" title="Help" id="106">
<items>
<menuItem title="NewApplication Help" keyEquivalent="?" id="111">
<connections>
<action selector="showHelp:" target="-1" id="360"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
</items>
</menu>
<window title="Window" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" animationBehavior="default" id="371">
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES"/>
<windowPositionMask key="initialPositionMask" leftStrut="YES" topStrut="YES"/>
<rect key="contentRect" x="119" y="946" width="1374" height="1031"/>
<rect key="screenRect" x="0.0" y="0.0" width="2560" height="1417"/>
<view key="contentView" id="372">
<rect key="frame" x="0.0" y="0.0" width="1374" height="1031"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<splitView arrangesAllSubviews="NO" dividerStyle="thin" vertical="YES" id="Gf7-bI-H4t">
<rect key="frame" x="940" y="811" width="214" height="73"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<subviews>
<customView id="Sze-Eb-8Fx">
<rect key="frame" x="0.0" y="0.0" width="59" height="73"/>
<autoresizingMask key="autoresizingMask"/>
<animations/>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="color" keyPath="backgroundColor">
<color key="value" red="0.0" green="0.53140729870000003" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
</userDefinedRuntimeAttribute>
</userDefinedRuntimeAttributes>
</customView>
<customView id="59Y-bY-6NO">
<rect key="frame" x="60" y="0.0" width="59" height="73"/>
<autoresizingMask key="autoresizingMask"/>
<animations/>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="color" keyPath="backgroundColor">
<color key="value" red="0.56690436239999997" green="0.0" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
</userDefinedRuntimeAttribute>
</userDefinedRuntimeAttributes>
</customView>
<customView id="e86-da-1nH">
<rect key="frame" x="120" y="0.0" width="94" height="73"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<animations/>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="color" keyPath="backgroundColor">
<color key="value" red="0.57639149440000004" green="0.59769631410000001" blue="0.53293551319999999" alpha="1" colorSpace="calibratedRGB"/>
</userDefinedRuntimeAttribute>
</userDefinedRuntimeAttributes>
</customView>
</subviews>
<animations/>
<holdingPriorities>
<real value="250"/>
<real value="250"/>
<real value="250"/>
</holdingPriorities>
</splitView>
<splitView arrangesAllSubviews="NO" id="9ty-Ct-bpx">
<rect key="frame" x="940" y="698" width="214" height="102"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<subviews>
<customView id="Eb6-2a-ijs">
<rect key="frame" x="0.0" y="0.0" width="214" height="45"/>
<autoresizingMask key="autoresizingMask"/>
<animations/>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="color" keyPath="backgroundColor">
<color key="value" red="0.0" green="0.2389628775" blue="0.64796560400000003" alpha="1" colorSpace="calibratedRGB"/>
</userDefinedRuntimeAttribute>
</userDefinedRuntimeAttributes>
</customView>
<customView id="sJR-ny-vXH">
<rect key="frame" x="0.0" y="54" width="214" height="48"/>
<autoresizingMask key="autoresizingMask"/>
<animations/>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="color" keyPath="backgroundColor">
<color key="value" red="0.4716600252" green="0.3736891779" blue="0.17221581380000001" alpha="1" colorSpace="calibratedRGB"/>
</userDefinedRuntimeAttribute>
</userDefinedRuntimeAttributes>
</customView>
</subviews>
<animations/>
<holdingPriorities>
<real value="250"/>
<real value="250"/>
</holdingPriorities>
</splitView>
<scrollView horizontalLineScroll="10" horizontalPageScroll="10" verticalLineScroll="10" verticalPageScroll="10" usesPredominantAxisScrolling="NO" id="pZB-1q-EQ1">
<rect key="frame" x="940" y="513" width="277" height="163"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<clipView key="contentView" id="Tsy-28-w1p">
<rect key="frame" x="1" y="1" width="275" height="161"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<view id="35c-jE-A9i">
<rect key="frame" x="0.0" y="0.0" width="290" height="346"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<customView id="qhh-BF-uJV" customClass="SensibleView">
<rect key="frame" x="56" y="46" width="163" height="96"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<animations/>
</customView>
</subviews>
<animations/>
</view>
</subviews>
<animations/>
</clipView>
<animations/>
<scroller key="horizontalScroller" verticalHuggingPriority="750" horizontal="YES" id="haI-QJ-idG">
<rect key="frame" x="1" y="146" width="275" height="16"/>
<autoresizingMask key="autoresizingMask"/>
<animations/>
</scroller>
<scroller key="verticalScroller" verticalHuggingPriority="750" doubleValue="1" horizontal="NO" id="en7-ag-3l6">
<rect key="frame" x="261" y="1" width="15" height="161"/>
<autoresizingMask key="autoresizingMask"/>
<animations/>
</scroller>
</scrollView>
<scrollView autohidesScrollers="YES" horizontalLineScroll="19" horizontalPageScroll="10" verticalLineScroll="19" verticalPageScroll="10" usesPredominantAxisScrolling="NO" id="F6I-OP-yvg">
<rect key="frame" x="940" y="377" width="277" height="119"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<clipView key="contentView" id="mCM-Xi-afN">
<rect key="frame" x="1" y="23" width="275" height="95"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<tableView verticalHuggingPriority="750" allowsExpansionToolTips="YES" columnAutoresizingStyle="lastColumnOnly" columnSelection="YES" multipleSelection="NO" autosaveColumns="NO" headerView="ZTR-Tg-hlW" id="soC-Ts-qCo">
<rect key="frame" x="0.0" y="0.0" width="275" height="95"/>
<autoresizingMask key="autoresizingMask"/>
<animations/>
<size key="intercellSpacing" width="3" height="2"/>
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
<color key="gridColor" name="gridColor" catalog="System" colorSpace="catalog"/>
<tableColumns>
<tableColumn width="78.77734375" minWidth="40" maxWidth="1000" id="ce2-Dt-Q9a">
<tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" title="First">
<font key="font" metaFont="smallSystem"/>
<color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="headerColor" catalog="System" colorSpace="catalog"/>
</tableHeaderCell>
<textFieldCell key="dataCell" lineBreakMode="truncatingTail" selectable="YES" editable="YES" title="Text Cell" id="Mhu-mt-2hd">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
<tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
</tableColumn>
<tableColumn width="106.203125" minWidth="40" maxWidth="1000" id="oyN-zb-Aen">
<tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" title="Second">
<font key="font" metaFont="smallSystem"/>
<color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="headerColor" catalog="System" colorSpace="catalog"/>
</tableHeaderCell>
<textFieldCell key="dataCell" lineBreakMode="truncatingTail" selectable="YES" editable="YES" title="Text Cell" id="POl-Ii-IlH">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
<tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
</tableColumn>
<tableColumn width="81" minWidth="10" maxWidth="3.4028234663852886e+38" id="4WF-b2-Qjp">
<tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" alignment="left" title="Third">
<font key="font" metaFont="smallSystem"/>
<color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
</tableHeaderCell>
<textFieldCell key="dataCell" lineBreakMode="truncatingTail" selectable="YES" editable="YES" alignment="left" title="Text Cell" id="6Vv-pe-Az4">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
<tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
</tableColumn>
</tableColumns>
</tableView>
</subviews>
<animations/>
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
</clipView>
<animations/>
<scroller key="horizontalScroller" hidden="YES" verticalHuggingPriority="750" horizontal="YES" id="vti-fg-vzI">
<rect key="frame" x="1" y="231" width="307" height="15"/>
<autoresizingMask key="autoresizingMask"/>
<animations/>
</scroller>
<scroller key="verticalScroller" hidden="YES" verticalHuggingPriority="750" horizontal="NO" id="EWM-fi-aQY">
<rect key="frame" x="224" y="17" width="15" height="102"/>
<autoresizingMask key="autoresizingMask"/>
<animations/>
</scroller>
<tableHeaderView key="headerView" id="ZTR-Tg-hlW">
<rect key="frame" x="0.0" y="0.0" width="275" height="23"/>
<autoresizingMask key="autoresizingMask"/>
<animations/>
</tableHeaderView>
</scrollView>
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" id="USC-6c-rhh">
<rect key="frame" x="1223" y="452" width="88" height="44"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<animations/>
<textFieldCell key="cell" controlSize="mini" sendsActionOnEndEditing="YES" title="CPTableHeaderView now using tracking areas for cursor updates" id="yKB-Vw-OTW">
<font key="font" metaFont="system" size="9"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" id="tjU-JO-PMX">
<rect key="frame" x="1223" y="621" width="78" height="55"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<animations/>
<textFieldCell key="cell" controlSize="mini" sendsActionOnEndEditing="YES" title="CPScrollView (scroll down to view and test a view with tracking area)" id="t8v-6H-YXg">
<font key="font" metaFont="system" size="9"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" id="5Zj-ir-6wr">
<rect key="frame" x="1160" y="820" width="78" height="55"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<animations/>
<textFieldCell key="cell" controlSize="mini" sendsActionOnEndEditing="YES" title="CPSplitView with thin vertical dividers, using tracking area for cursor updates" id="sLE-AN-vtO">
<font key="font" metaFont="system" size="9"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" id="NBW-q0-pOz">
<rect key="frame" x="1160" y="730" width="78" height="39"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<animations/>
<textFieldCell key="cell" controlSize="mini" sendsActionOnEndEditing="YES" title="CPSplitView with thick horizontal dividers" id="LoF-bh-fEg">
<font key="font" metaFont="system" size="9"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
</subviews>
<animations/>
</view>
<point key="canvasLocation" x="625" y="736.5"/>
</window>
<customObject id="450" customClass="AppController">
<connections>
<outlet property="s1" destination="qhh-BF-uJV" id="L8n-I6-kzA"/>
<outlet property="theWindow" destination="371" id="459"/>
</connections>
</customObject>
</objects>
</document>
+193
View File
@@ -0,0 +1,193 @@
<!DOCTYPE html>
<html lang="en">
<!--
index-debug.html
TrackingArea
Created by You on November 2, 2015.
Copyright 2015, Your Company All rights reserved.
-->
<head>
<meta charset="utf-8">
<!--[if lte IE 8]>
<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7, chrome=1">
<![endif]-->
<!--[if gte IE 9]>
<meta http-equiv="X-UA-Compatible" content="IE=edge, chrome=1">
<![endif]-->
<meta name="viewport" content="initial-scale=1.0, user-scalable=no">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<link rel="apple-touch-icon" href="Resources/icon.png">
<link rel="apple-touch-startup-image" href="Resources/default.png">
<title>TrackingArea</title>
<!-- Custom javascript goes here -->
<!-- End custom javascript -->
<script type="text/javascript">
OBJJ_MAIN_FILE = "main.j";
OBJJ_INCLUDE_PATHS = ["Frameworks/Debug", "Frameworks"];
// Uncomment below to generate debug symbols, type signatures and inline objj_msgSend functions
// OBJJ_COMPILER_FLAGS = ["IncludeDebugSymbols", "IncludeTypeSignatures", "InlineMsgSend"];
var progressBar = null;
OBJJ_PROGRESS_CALLBACK = function(percent, appSize, path)
{
percent = percent * 100;
if (!progressBar)
progressBar = document.getElementById("progress-bar");
if (progressBar)
progressBar.style.width = Math.min(percent, 100) + "%";
}
var loadingHTML =
'<div id="loading">' +
' <div id="loading-text">Loading...</div>' +
' <div id="progress-indicator">' +
' <span id="progress-bar" style="width:0%"></span>' +
' </div>' +
'</div>';
</script>
<script type="text/javascript" src="Frameworks/Debug/Objective-J/Objective-J.js" charset="UTF-8"></script>
<script type="text/javascript">
objj_msgSend_reset();
// DEBUG OPTIONS:
// Uncomment to enable printing of backtraces on exceptions:
//objj_msgSend_decorate(objj_backtrace_decorator);
// Uncomment to supress exceptions that take place inside a message
//objj_msgSend_decorate(objj_supress_exceptions_decorator)
// Uncomment to enable runtime type checking:
//objj_msgSend_decorate(objj_typecheck_decorator);
// Uncomment (along with both above) to print backtraces on type check errors:
//objj_typecheck_prints_backtrace = true;
// Uncomment to disable the default logger (CPLogConsole if window.console exists, CPLogPopup otherwise):
//CPLogUnregister(CPLogDefault);
// Uncomment to enable a specific logger:
//CPLogRegister(CPLogConsole);
//CPLogRegister(CPLogPopup);
// Tag view DOM elements with a "data-cappuccino-view" attribute that contains
// the class name of the view that created them. Comment this or set to false to disable.
appkit_tag_dom_elements = true;
</script>
<style type="text/css">
html, body, h1, p {
margin: 0;
padding: 0;
}
/* We need a body wrapper because Cappuccino is unhappy if we change the body element */
#cappuccino-body {
/* Position it absolutely so it will fill the height without content */
position: absolute;
top: 0;
bottom: 0;
width: 100%;
/* Put it at the bottom of the stack so it doesn't interfere with UI */
z-index: 0;
}
#cappuccino-body .container {
display: table;
margin: 0 auto;
height: 100%;
}
#cappuccino-body .content {
display: table-cell;
height: 100%;
vertical-align: top;
}
#loading {
position: relative;
top: 35%;
}
#loading-text {
height: 1.5em;
color: #555;
font: normal bold 36px/36px Arial, sans-serif;
}
#progress-indicator {
padding: 0px;
height: 16px;
border: 5px solid #555;
border-radius: 18px;
background-color: white;
}
#progress-bar {
position: relative;
top: -1px;
left: -1px;
display: block;
height: 18px;
/* Compensate for moving the bar left 1px to overlap the indicator border */
border-right: 1px solid #555;
background-color: #555;
}
#noscript {
position: relative;
top: 35%;
padding: 1em 1.5em;
border: 5px solid #555;
border-radius: 16px;
background-color: white;
color: #555;
text-align: center;
font: bold 24px Arial, sans-serif;
}
#noscript a {
color: #98c0ff;
text-decoration: none;
}
</style>
</head>
<body>
<div id="cappuccino-body">
<div class="container">
<div class="content">
<script type="text/javascript">
document.write(loadingHTML);
</script>
</div>
</div>
<noscript style="position:absolute; top:0; left:0; width:100%; height:100%">
<div class="container">
<div class="content">
<div id="noscript">
<p style="font-size:120%; margin-bottom:.75em">JavaScript is required for this site.</p>
<p><a href="http://www.enable-javascript.com" target="_blank">Enable JavaScript</a></p>
</div>
</div>
</div>
</noscript>
</div>
</body>
</html>
+161
View File
@@ -0,0 +1,161 @@
<!DOCTYPE html>
<html lang="en">
<!--
index.html
TrackingArea
Created by You on November 2, 2015.
Copyright 2015, Your Company All rights reserved.
-->
<head>
<meta charset="utf-8">
<!--[if lte IE 8]>
<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7, chrome=1">
<![endif]-->
<!--[if gte IE 9]>
<meta http-equiv="X-UA-Compatible" content="IE=edge, chrome=1">
<![endif]-->
<meta name="viewport" content="initial-scale=1.0, user-scalable=no">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<link rel="apple-touch-icon" href="Resources/icon.png">
<link rel="apple-touch-startup-image" href="Resources/default.png">
<title>TrackingArea</title>
<!-- Custom javascript goes here -->
<!-- End custom javascript -->
<script type="text/javascript">
OBJJ_MAIN_FILE = "main.j";
var progressBar = null;
OBJJ_PROGRESS_CALLBACK = function(percent, appSize, path)
{
percent = percent * 100;
if (!progressBar)
progressBar = document.getElementById("progress-bar");
if (progressBar)
progressBar.style.width = Math.min(percent, 100) + "%";
}
var loadingHTML =
'<div id="loading">' +
' <div id="loading-text">Loading...</div>' +
' <div id="progress-indicator">' +
' <span id="progress-bar" style="width:0%"></span>' +
' </div>' +
'</div>';
</script>
<script type="text/javascript" src="Frameworks/Objective-J/Objective-J.js" charset="UTF-8"></script>
<style type="text/css">
html, body, h1, p {
margin: 0;
padding: 0;
}
/* We need a body wrapper because Cappuccino is unhappy if we change the body element */
#cappuccino-body {
/* Position it absolutely so it will fill the height without content */
position: absolute;
top: 0;
bottom: 0;
width: 100%;
/* Put it at the bottom of the stack so it doesn't interfere with UI */
z-index: 0;
}
#cappuccino-body .container {
display: table;
margin: 0 auto;
height: 100%;
}
#cappuccino-body .content {
display: table-cell;
height: 100%;
vertical-align: top;
}
#loading {
position: relative;
top: 35%;
}
#loading-text {
height: 1.5em;
color: #555;
font: normal bold 36px/36px Arial, sans-serif;
}
#progress-indicator {
padding: 0px;
height: 16px;
border: 5px solid #555;
border-radius: 18px;
background-color: white;
}
#progress-bar {
position: relative;
top: -1px;
left: -1px;
display: block;
height: 18px;
/* Compensate for moving the bar left 1px to overlap the indicator border */
border-right: 1px solid #555;
background-color: #555;
}
#noscript {
position: relative;
top: 35%;
padding: 1em 1.5em;
border: 5px solid #555;
border-radius: 16px;
background-color: white;
color: #555;
text-align: center;
font: bold 24px Arial, sans-serif;
}
#noscript a {
color: #98c0ff;
text-decoration: none;
}
</style>
</head>
<body>
<div id="cappuccino-body">
<div class="container">
<div class="content">
<script type="text/javascript">
document.write(loadingHTML);
</script>
</div>
</div>
<noscript style="position:absolute; top:0; left:0; width:100%; height:100%">
<div class="container">
<div class="content">
<div id="noscript">
<p style="font-size:120%; margin-bottom:.75em">JavaScript is required for this site.</p>
<p><a href="http://www.enable-javascript.com" target="_blank">Enable JavaScript</a></p>
</div>
</div>
</div>
</noscript>
</div>
</body>
</html>
+18
View File
@@ -0,0 +1,18 @@
/*
* AppController.j
* TrackingArea
*
* Created by You on November 2, 2015.
* Copyright 2015, Your Company All rights reserved.
*/
@import <Foundation/Foundation.j>
@import <AppKit/AppKit.j>
@import "AppController.j"
function main(args, namedArgs)
{
CPApplicationMain(args, namedArgs);
}