mirror of
https://github.com/cappuccino/cappuccino.git
synced 2026-10-29 11:28:49 +00:00
Merge branch 'master' into Localization
This commit is contained in:
commit
bb9408b5d0
326 files changed
+13070
-10224
No files matched your search
+3
-1
@@ -26,6 +26,7 @@
|
||||
@import "CPAccordionView.j"
|
||||
@import "CPAlert.j"
|
||||
@import "CPAnimation.j"
|
||||
@import "CPAppearance.j"
|
||||
@import "CPApplication.j"
|
||||
@import "CPArrayController.j"
|
||||
@import "CPBezierPath.j"
|
||||
@@ -106,7 +107,8 @@
|
||||
@import "CPView.j"
|
||||
@import "CPViewAnimation.j"
|
||||
@import "CPViewController.j"
|
||||
@import "CPVisualEffectView.j"
|
||||
@import "CPWebView.j"
|
||||
@import "CPWindow.j"
|
||||
@import "CPWindowController.j"
|
||||
@import "CPWorkspace.j"
|
||||
@import "CPWorkspace.j"
|
||||
@@ -0,0 +1,162 @@
|
||||
/*
|
||||
* CPAppearance.j
|
||||
* AppKit
|
||||
*
|
||||
* Created by Antoine Mercadal.
|
||||
* 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>
|
||||
@import "CPTheme.j"
|
||||
|
||||
CPAppearanceNameAqua = @"CPAppearanceNameAqua";
|
||||
CPAppearanceNameLightContent = @"CPAppearanceNameLightContent";
|
||||
CPAppearanceNameVibrantDark = @"CPAppearanceNameVibrantDark";
|
||||
CPAppearanceNameVibrantLight = @"CPAppearanceNameVibrantLight";
|
||||
|
||||
var _CPAppearanceCurrent = nil,
|
||||
_CPAppearancesRegistry = @{};
|
||||
|
||||
|
||||
@protocol CPAppearanceCustomization <CPObject>
|
||||
|
||||
@required
|
||||
- (CPAppearance)appearance;
|
||||
- (void)setAppearance:(CPAppearance)appearance;
|
||||
- (CPAppearance)effectiveAppearance;
|
||||
- (void)setEffectiveAppearance:(CPAppearance)appearance;
|
||||
|
||||
@end
|
||||
|
||||
CPThemeStateAppearanceAqua = CPThemeState("appearance-aqua");
|
||||
CPThemeStateAppearanceLightContent = CPThemeState("appearance-light-content");
|
||||
CPThemeStateAppearanceVibrantLight = CPThemeState("appearance-vibrant-light");
|
||||
CPThemeStateAppearanceVibrantDark = CPThemeState("appearance-vibrant-dark");
|
||||
|
||||
|
||||
/*!
|
||||
@ingroup appkit
|
||||
|
||||
A CPAppareance represents the appearance of an to a subset of UI elements.
|
||||
This is a very lightweight implementation of the NSAppearance system, but
|
||||
We are using it for compliance, and especially for the CPVisualEffectView
|
||||
*/
|
||||
@implementation CPAppearance : CPObject
|
||||
{
|
||||
BOOL _allowsVibrancy @accessors(property=allowsVibrancy);
|
||||
|
||||
CPString _name;
|
||||
}
|
||||
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark Class Methods
|
||||
|
||||
/*! Returns the current default CPAppearance
|
||||
*/
|
||||
+ (CPAppearance)currentAppearance
|
||||
{
|
||||
if (!_CPAppearanceCurrent)
|
||||
_CPAppearanceCurrent = [CPAppearance appearanceNamed:CPAppearanceNameAqua];
|
||||
|
||||
return _CPAppearanceCurrent;
|
||||
}
|
||||
|
||||
/*! Sets the current default CPAppearance
|
||||
@param appearance the new current appearance
|
||||
*/
|
||||
+ (void)setCurrentAppearance:(CPAppearance)anAppearance
|
||||
{
|
||||
_CPAppearanceCurrent = anAppearance;
|
||||
}
|
||||
|
||||
/*! Returns the CPAppearance object with the given name
|
||||
@param name the name of the appearance
|
||||
*/
|
||||
+ (CPAppearance)appearanceNamed:(CPString)aName
|
||||
{
|
||||
if (![_CPAppearancesRegistry containsKey:aName])
|
||||
{
|
||||
[_CPAppearancesRegistry setObject:[[CPAppearance alloc] initWithAppearanceNamed:aName bundle:nil]
|
||||
forKey:aName];
|
||||
}
|
||||
|
||||
return [_CPAppearancesRegistry objectForKey:aName];
|
||||
}
|
||||
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark Initialization
|
||||
|
||||
/*! Creates a CPAppearance object initialized to the specified appearance file in the specified bundle
|
||||
This method does actually nothing special. It just creates a default appearance object
|
||||
*/
|
||||
- (id)initWithAppearanceNamed:(CPString)aName bundle:(CPBundle)bundle
|
||||
{
|
||||
if (self = [super init])
|
||||
{
|
||||
_name = aName;
|
||||
_allowsVibrancy = YES;
|
||||
|
||||
if ([_CPAppearancesRegistry containsKey:aName])
|
||||
[CPException raise:CPInternalInconsistencyException reason:"Appearance with name '" + aName + "' is already declared."];
|
||||
|
||||
[_CPAppearancesRegistry setObject:self forKey:aName];
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark Implementation
|
||||
|
||||
- (BOOL)isEqual:(id)anObject
|
||||
{
|
||||
if (![anObject isKindOfClass:CPAppearance])
|
||||
return NO;
|
||||
|
||||
return self._name == anObject._name;
|
||||
}
|
||||
|
||||
- (CPString)description
|
||||
{
|
||||
return @"<CPAppearance @" + [self UID] + @" name: " + _name + ">";
|
||||
}
|
||||
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark CPCoding
|
||||
|
||||
- (id)initWithCoder:(CPCoder)aCoder
|
||||
{
|
||||
if (self = [super init])
|
||||
{
|
||||
_name = [aCoder decodeObjectForKey:@"_name"];
|
||||
_allowsVibrancy = [aCoder decodeBoolForKey:@"_allowsVibrancy"];
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)encodeWithCoder:(CPCoder)aCoder
|
||||
{
|
||||
[aCoder encodeObject:_name forKey:@"_name"];
|
||||
[aCoder encodeBool:_allowsVibrancy forKey:@"_allowsVibrancy"];
|
||||
}
|
||||
|
||||
@end
|
||||
+32
-6
@@ -47,6 +47,8 @@ var CPMainCibFile = @"CPMainCibFile",
|
||||
@protocol CPApplicationDelegate <CPObject>
|
||||
|
||||
@optional
|
||||
- (CPApplicationTerminateReply)applicationShouldTerminate:(CPApplication)sender;
|
||||
- (CPString)applicationShouldTerminateMessage:(CPApplication)sender;
|
||||
- (void)applicationDidBecomeActive:(CPNotification)aNotification;
|
||||
- (void)applicationDidChangeScreenParameters:(CPNotification)aNotification;
|
||||
- (void)applicationDidFinishLaunching:(CPNotification)aNotification;
|
||||
@@ -58,6 +60,9 @@ var CPMainCibFile = @"CPMainCibFile",
|
||||
|
||||
@end
|
||||
|
||||
var CPApplicationDelegate_applicationShouldTerminate_ = 1 << 0,
|
||||
CPApplicationDelegate_applicationShouldTerminateMessage_ = 1 << 1;
|
||||
|
||||
/*!
|
||||
@ingroup appkit
|
||||
@class CPApplication
|
||||
@@ -103,6 +108,8 @@ var CPMainCibFile = @"CPMainCibFile",
|
||||
|
||||
//
|
||||
id <CPApplicationDelegate> _delegate;
|
||||
CPInteger _implementedDelegateMethods;
|
||||
|
||||
BOOL _finishedLaunching;
|
||||
BOOL _isActive;
|
||||
|
||||
@@ -165,6 +172,8 @@ var CPMainCibFile = @"CPMainCibFile",
|
||||
if (_delegate == aDelegate)
|
||||
return;
|
||||
|
||||
_implementedDelegateMethods = 0;
|
||||
|
||||
var defaultCenter = [CPNotificationCenter defaultCenter],
|
||||
delegateNotifications =
|
||||
[
|
||||
@@ -205,6 +214,12 @@ var CPMainCibFile = @"CPMainCibFile",
|
||||
if ([_delegate respondsToSelector:selector])
|
||||
[defaultCenter addObserver:_delegate selector:selector name:notificationName object:self];
|
||||
}
|
||||
|
||||
if ([_delegate respondsToSelector:@selector(applicationShouldTerminate:)])
|
||||
_implementedDelegateMethods |= CPApplicationDelegate_applicationShouldTerminate_
|
||||
|
||||
if ([_delegate respondsToSelector:@selector(applicationShouldTerminateMessage:)])
|
||||
_implementedDelegateMethods |= CPApplicationDelegate_applicationShouldTerminateMessage_
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -426,12 +441,7 @@ var CPMainCibFile = @"CPMainCibFile",
|
||||
{
|
||||
// callback method for terminate:
|
||||
if (didCloseAll)
|
||||
{
|
||||
if ([_delegate respondsToSelector:@selector(applicationShouldTerminate:)])
|
||||
[self replyToApplicationShouldTerminate:[_delegate applicationShouldTerminate:self]];
|
||||
else
|
||||
[self replyToApplicationShouldTerminate:YES];
|
||||
}
|
||||
[self replyToApplicationShouldTerminate:[self _sendDelegateApplicationShouldTerminate]];
|
||||
}
|
||||
|
||||
- (void)replyToApplicationShouldTerminate:(BOOL)terminate
|
||||
@@ -1210,6 +1220,22 @@ var CPMainCibFile = @"CPMainCibFile",
|
||||
userInfo:nil];
|
||||
}
|
||||
|
||||
- (BOOL)_sendDelegateApplicationShouldTerminate
|
||||
{
|
||||
if (!(_implementedDelegateMethods & CPApplicationDelegate_applicationShouldTerminate_))
|
||||
return YES;
|
||||
|
||||
return [_delegate applicationShouldTerminate:self];
|
||||
}
|
||||
|
||||
- (CPString)_sendDelegateApplicationShouldTerminateMessage
|
||||
{
|
||||
if (!(_implementedDelegateMethods & CPApplicationDelegate_applicationShouldTerminateMessage_))
|
||||
return @"You have attempted to leave this page. Are you sure you want to exit this page?";
|
||||
|
||||
return [_delegate applicationShouldTerminateMessage:self];
|
||||
}
|
||||
|
||||
- (void)_didResignActive
|
||||
{
|
||||
if (self._activeMenu)
|
||||
|
||||
@@ -31,6 +31,7 @@ CPApplicationWillResignActiveNotification = @"CPApplicationWillResignA
|
||||
CPApplicationDidResignActiveNotification = @"CPApplicationDidResignActiveNotification";
|
||||
CPApplicationDidChangeScreenParametersNotification = @"CPApplicationDidChangeScreenParametersNotification";
|
||||
|
||||
@typedef CPApplicationTerminateReply
|
||||
CPTerminateNow = YES;
|
||||
CPTerminateCancel = NO;
|
||||
CPTerminateLater = -1; // not currently supported
|
||||
|
||||
+2
-2
@@ -665,10 +665,10 @@ CPButtonImageOffset = 3.0;
|
||||
*/
|
||||
- (void)sizeToFit
|
||||
{
|
||||
[self setFrameSize:[self _minimumFrameSize]];
|
||||
|
||||
[self layoutSubviews];
|
||||
|
||||
[self setFrameSize:[self _minimumFrameSize]];
|
||||
|
||||
if ([self ephemeralSubviewNamed:@"content-view"])
|
||||
[self layoutSubviews];
|
||||
}
|
||||
|
||||
@@ -112,6 +112,8 @@
|
||||
|
||||
- (void)awakeFromCib
|
||||
{
|
||||
[super awakeFromCib];
|
||||
|
||||
var view = [self superview],
|
||||
subview = self;
|
||||
|
||||
|
||||
+1
-1
@@ -195,7 +195,7 @@
|
||||
|
||||
- (CGRect)documentVisibleRect
|
||||
{
|
||||
return [self convertRect:[self bounds] fromView:_documentView];
|
||||
return [_documentView visibleRect];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -60,6 +60,8 @@ var CPCollectionViewDelegate_collectionView_acceptDrop_index_dropOperation_
|
||||
|
||||
@end
|
||||
|
||||
var HORIZONTAL_MARGIN = 2;
|
||||
|
||||
/*!
|
||||
@ingroup appkit
|
||||
@class CPCollectionView
|
||||
@@ -88,9 +90,6 @@ var CPCollectionViewDelegate_collectionView_acceptDrop_index_dropOperation_
|
||||
@param indices the indices to obtain drag types
|
||||
@return an array of drag types (CPString)
|
||||
*/
|
||||
|
||||
var HORIZONTAL_MARGIN = 2;
|
||||
|
||||
@implementation CPCollectionView : CPView
|
||||
{
|
||||
CPArray _content;
|
||||
|
||||
+1
-1
@@ -74,7 +74,7 @@ var CPComboBoxTextSubview = @"text",
|
||||
BOOL _usesDataSource;
|
||||
CGSize _intercellSpacing;
|
||||
CPArray _items;
|
||||
id<CPComboBoxDataSource> _dataSource;
|
||||
id <CPComboBoxDataSource> _dataSource;
|
||||
CPInteger _implementedDelegateComboBoxMethods;
|
||||
CPString _selectedStringValue;
|
||||
float _itemHeight;
|
||||
|
||||
+52
-8
@@ -42,13 +42,6 @@
|
||||
|
||||
@end
|
||||
|
||||
@typedef CPTextAlignment
|
||||
CPLeftTextAlignment = 0;
|
||||
CPRightTextAlignment = 1;
|
||||
CPCenterTextAlignment = 2;
|
||||
CPJustifiedTextAlignment = 3;
|
||||
CPNaturalTextAlignment = 4;
|
||||
|
||||
@typedef CPControlSize
|
||||
CPRegularControlSize = 0;
|
||||
CPSmallControlSize = 1;
|
||||
@@ -126,6 +119,8 @@ var CPControlBlackColor = [CPColor blackColor];
|
||||
CGPoint _previousTrackingLocation;
|
||||
|
||||
CPControlSize _controlSize;
|
||||
|
||||
CPWritingDirection _baseWritingDirection @accessors(property=baseWritingDirection);
|
||||
}
|
||||
|
||||
+ (CPDictionary)themeAttributes
|
||||
@@ -240,7 +235,7 @@ var CPControlBlackColor = [CPColor blackColor];
|
||||
*/
|
||||
- (ThemeState)_controlSizeThemeState
|
||||
{
|
||||
switch(_controlSize)
|
||||
switch (_controlSize)
|
||||
{
|
||||
case CPSmallControlSize:
|
||||
return CPThemeStateControlSizeSmall;
|
||||
@@ -1016,6 +1011,49 @@ var CPControlBlackColor = [CPColor blackColor];
|
||||
return [self hasThemeState:CPThemeStateHighlighted];
|
||||
}
|
||||
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark Base writing direction
|
||||
|
||||
/*!
|
||||
Sets the initial writing direction of the receiver
|
||||
@param writingDirection - It could be CPWritingDirectionNatural, CPWritingDirectionLeftToRight, CPWritingDirectionRightToLeft
|
||||
*/
|
||||
- (void)setBaseWritingDirection:(CPWritingDirection)writingDirection
|
||||
{
|
||||
if (writingDirection == _baseWritingDirection)
|
||||
return;
|
||||
|
||||
[self willChangeValueForKey:@"baseWritingDirection"];
|
||||
_baseWritingDirection = writingDirection;
|
||||
[self didChangeValueForKey:@"baseWritingDirection"];
|
||||
|
||||
#if PLATFORM(DOM)
|
||||
|
||||
var style;
|
||||
|
||||
switch (_baseWritingDirection)
|
||||
{
|
||||
case CPWritingDirectionNatural:
|
||||
style = "initial";
|
||||
break;
|
||||
|
||||
case CPWritingDirectionLeftToRight:
|
||||
style = "ltr";
|
||||
break;
|
||||
|
||||
case CPWritingDirectionRightToLeft:
|
||||
style = "rtl";
|
||||
break;
|
||||
|
||||
default:
|
||||
style = "initial";
|
||||
}
|
||||
|
||||
_DOMElement.style.direction = style;
|
||||
#endif
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
var CPControlActionKey = @"CPControlActionKey",
|
||||
@@ -1027,6 +1065,7 @@ var CPControlActionKey = @"CPControlActionKey",
|
||||
CPControlSendsActionOnEndEditingKey = @"CPControlSendsActionOnEndEditingKey",
|
||||
CPControlTargetKey = @"CPControlTargetKey",
|
||||
CPControlValueKey = @"CPControlValueKey",
|
||||
CPControlBaseWrittingDirectionKey = @"CPControlBaseWrittingDirectionKey";
|
||||
|
||||
__Deprecated__CPImageViewImageKey = @"CPImageViewImageKey";
|
||||
|
||||
@@ -1055,6 +1094,8 @@ var CPControlActionKey = @"CPControlActionKey",
|
||||
[self setFormatter:[aCoder decodeObjectForKey:CPControlFormatterKey]];
|
||||
|
||||
[self setControlSize:[aCoder decodeIntForKey:CPControlControlSizeKey]];
|
||||
|
||||
[self setBaseWritingDirection:[aCoder decodeIntForKey:CPControlBaseWrittingDirectionKey]];
|
||||
}
|
||||
|
||||
return self;
|
||||
@@ -1089,6 +1130,9 @@ var CPControlActionKey = @"CPControlActionKey",
|
||||
[aCoder encodeObject:_formatter forKey:CPControlFormatterKey];
|
||||
|
||||
[aCoder encodeInt:_controlSize forKey:CPControlControlSizeKey];
|
||||
|
||||
[aCoder encodeInt:_baseWritingDirection forKey:CPControlBaseWrittingDirectionKey];
|
||||
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -630,14 +630,6 @@ CPEraDatePickerElementFlag = 0x0100;
|
||||
return [[_locale objectForKey:CPLocaleCountryCode] isEqualToString:@"US"];
|
||||
}
|
||||
|
||||
/*! Check if we are in the english format or not. Depending on the locale
|
||||
*/
|
||||
- (BOOL)_isEnglishFormat
|
||||
{
|
||||
return [[_locale objectForKey:CPLocaleLanguageCode] isEqualToString:@"en"];
|
||||
}
|
||||
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark Key event
|
||||
|
||||
|
||||
@@ -139,7 +139,7 @@ var RADIANS = Math.PI / 180;
|
||||
[_minuteHandLayer setImage:[_datePicker currentValueForThemeAttribute:@"minute-hand-image"]];
|
||||
[_secondHandLayer setImage:[_datePicker currentValueForThemeAttribute:@"second-hand-image"]];
|
||||
|
||||
if ([_datePicker _isEnglishFormat])
|
||||
if ([_datePicker _isAmericanFormat])
|
||||
{
|
||||
if (dateValue.getHours() > 11)
|
||||
[_PMAMTextField setStringValue:@"PM"]
|
||||
|
||||
@@ -198,7 +198,6 @@ var CPZeroKeyCode = 48,
|
||||
else
|
||||
[self _selectTextField:_firstTextField];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*! Select a textField
|
||||
@@ -277,74 +276,99 @@ var CPZeroKeyCode = 48,
|
||||
}
|
||||
}
|
||||
|
||||
/*! performKeyEquivalent event
|
||||
Used for moving in the textField
|
||||
/*!
|
||||
PerformKeyEquivalent event
|
||||
We need to override that to handle the tab key
|
||||
*/
|
||||
- (BOOL)performKeyEquivalent:(CPEvent)anEvent
|
||||
{
|
||||
if (![self isEnabled] || !_currentTextField || [[self window] firstResponder] != _datePicker)
|
||||
return NO;
|
||||
|
||||
var key = [anEvent charactersIgnoringModifiers];
|
||||
|
||||
if (key == CPUpArrowFunctionKey)
|
||||
if ([anEvent charactersIgnoringModifiers] === CPTabCharacter)
|
||||
{
|
||||
[_currentTextField _invalidTimer];
|
||||
[_stepper setDoubleValue:[_currentTextField intValue]];
|
||||
[_stepper performClickUp:self];
|
||||
if ([anEvent modifierFlags] & CPShiftKeyMask)
|
||||
[self insertBacktab:self];
|
||||
else
|
||||
[self insertTab:self];
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
if (key == CPDownArrowFunctionKey)
|
||||
else if ([anEvent charactersIgnoringModifiers] === CPBackTabCharacter)
|
||||
{
|
||||
[_currentTextField _invalidTimer];
|
||||
[_stepper setDoubleValue:[_currentTextField intValue]];
|
||||
[_stepper performClickDown:self];
|
||||
[self insertBacktab:self];
|
||||
return YES;
|
||||
}
|
||||
|
||||
if (key == CPLeftArrowFunctionKey || [anEvent keyCode] == CPTabKeyCode && [anEvent modifierFlags] & CPShiftKeyMask)
|
||||
{
|
||||
if (_currentTextField == _firstTextField && [anEvent keyCode] == CPTabKeyCode)
|
||||
{
|
||||
var previousValidKeyView = [_datePicker previousValidKeyView];
|
||||
|
||||
if (previousValidKeyView)
|
||||
[[self window] makeFirstResponder:previousValidKeyView];
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
[self _selectTextField:[_currentTextField previousTextField]];
|
||||
return YES;
|
||||
}
|
||||
|
||||
if (key == CPRightArrowFunctionKey || [anEvent keyCode] == CPTabKeyCode)
|
||||
{
|
||||
if (_currentTextField == _lastTextField && [anEvent keyCode] == CPTabKeyCode)
|
||||
{
|
||||
var nextValidKeyView = [_datePicker nextValidKeyView];
|
||||
|
||||
if (nextValidKeyView)
|
||||
[[self window] makeFirstResponder:nextValidKeyView];
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
[self _selectTextField:[_currentTextField nextTextField]];
|
||||
return YES;
|
||||
}
|
||||
|
||||
if ([anEvent keyCode] == CPReturnKeyCode)
|
||||
{
|
||||
[_currentTextField _endEditing];
|
||||
|
||||
return [super performKeyEquivalent:anEvent];
|
||||
}
|
||||
|
||||
return [super performKeyEquivalent:anEvent];
|
||||
}
|
||||
|
||||
- (void)insertTab:(id)sender
|
||||
{
|
||||
if (!_currentTextField)
|
||||
return;
|
||||
|
||||
if (_currentTextField == _lastTextField)
|
||||
[[self window] selectNextKeyView:self];
|
||||
else
|
||||
[self moveRight:sender];
|
||||
}
|
||||
|
||||
- (void)moveRight:(id)sender
|
||||
{
|
||||
if (!_currentTextField)
|
||||
return;
|
||||
|
||||
[self _selectTextField:[_currentTextField nextTextField]];
|
||||
}
|
||||
|
||||
- (void)insertBacktab:(id)sender
|
||||
{
|
||||
if (!_currentTextField)
|
||||
return;
|
||||
|
||||
if (_currentTextField == _firstTextField)
|
||||
[[self window] selectPreviousKeyView:self];
|
||||
else
|
||||
[self moveLeft:sender];
|
||||
}
|
||||
|
||||
- (void)moveLeft:(id)sender
|
||||
{
|
||||
if (!_currentTextField)
|
||||
return;
|
||||
|
||||
[self _selectTextField:[_currentTextField previousTextField]];
|
||||
}
|
||||
|
||||
- (void)moveDown:(id)sender
|
||||
{
|
||||
if (!_currentTextField)
|
||||
return;
|
||||
|
||||
[_currentTextField _invalidTimer];
|
||||
[_stepper setDoubleValue:[_currentTextField intValue]];
|
||||
[_stepper performClickDown:self];
|
||||
}
|
||||
|
||||
- (void)moveUp:(id)sender
|
||||
{
|
||||
if (!_currentTextField)
|
||||
return;
|
||||
|
||||
[_currentTextField _invalidTimer];
|
||||
[_stepper setDoubleValue:[_currentTextField intValue]];
|
||||
[_stepper performClickUp:self];
|
||||
}
|
||||
|
||||
- (void)insertNewline:(id)sender
|
||||
{
|
||||
if (!_currentTextField)
|
||||
return;
|
||||
|
||||
[_currentTextField _endEditing];
|
||||
}
|
||||
|
||||
/*! KeyDown event
|
||||
We just care care about the event A/P and every numbers
|
||||
*/
|
||||
@@ -353,7 +377,9 @@ var CPZeroKeyCode = 48,
|
||||
if (![self isEnabled])
|
||||
return;
|
||||
|
||||
if ([_datePicker _isEnglishFormat] && [_currentTextField dateType] == CPAMPMDateType && ([anEvent keyCode] == CPAKeyCode || [anEvent keyCode] == CPPKeyCode || [anEvent keyCode] == CPMajAKeyCode || [anEvent keyCode] == CPMajPKeyCode))
|
||||
[self interpretKeyEvents:[anEvent]];
|
||||
|
||||
if ([_datePicker _isAmericanFormat] && [_currentTextField dateType] == CPAMPMDateType && ([anEvent keyCode] == CPAKeyCode || [anEvent keyCode] == CPPKeyCode || [anEvent keyCode] == CPMajAKeyCode || [anEvent keyCode] == CPMajPKeyCode))
|
||||
{
|
||||
if ([anEvent keyCode] == CPAKeyCode || [anEvent keyCode] == CPMajAKeyCode)
|
||||
[_currentTextField setStringValue:@"AM"];
|
||||
@@ -368,6 +394,7 @@ var CPZeroKeyCode = 48,
|
||||
[_currentTextField setValueForKeyEvent:anEvent];
|
||||
}
|
||||
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark Layout methods
|
||||
|
||||
@@ -725,7 +752,7 @@ var CPZeroKeyCode = 48,
|
||||
|
||||
if (hour != currentHour)
|
||||
{
|
||||
if (([_datePicker _isEnglishFormat] || [_datePicker _isAmericanFormat]))
|
||||
if ([_datePicker _isAmericanFormat])
|
||||
{
|
||||
if (![self _isAMHour])
|
||||
{
|
||||
@@ -1050,7 +1077,7 @@ var CPZeroKeyCode = 48,
|
||||
- (void)_updateHiddenTextFields
|
||||
{
|
||||
var datePickerElements = [_datePicker datePickerElements],
|
||||
isEnglishFormat = [_datePicker _isEnglishFormat];
|
||||
isAmericanFormat = [_datePicker _isAmericanFormat];
|
||||
|
||||
if (datePickerElements & CPYearMonthDatePickerElementFlag)
|
||||
{
|
||||
@@ -1083,7 +1110,7 @@ var CPZeroKeyCode = 48,
|
||||
[_textFieldSeparatorThree setHidden:NO];
|
||||
[_textFieldSeparatorFour setHidden:YES];
|
||||
|
||||
if (isEnglishFormat)
|
||||
if (isAmericanFormat)
|
||||
[_textFieldPMAM setHidden:NO];
|
||||
else
|
||||
[_textFieldPMAM setHidden:YES];
|
||||
@@ -1115,9 +1142,9 @@ var CPZeroKeyCode = 48,
|
||||
verticalInset = contentInset.top - contentInset.bottom,
|
||||
firstTexField = _textFieldMonth,
|
||||
secondTextField = _textFieldDay,
|
||||
isEnglishFormat = [_datePicker _isEnglishFormat];
|
||||
isAmericanFormat = [_datePicker _isAmericanFormat];
|
||||
|
||||
if (!isEnglishFormat)
|
||||
if (!isAmericanFormat)
|
||||
{
|
||||
firstTexField = _textFieldDay;
|
||||
secondTextField = _textFieldMonth;
|
||||
@@ -1131,7 +1158,7 @@ var CPZeroKeyCode = 48,
|
||||
else
|
||||
[secondTextField setFrameOrigin:CGPointMake(CGRectGetMaxX([_textFieldSeparatorOne frame]) + separatorContentInset.right, verticalInset)];
|
||||
|
||||
if (isEnglishFormat && [secondTextField isHidden])
|
||||
if (isAmericanFormat && [secondTextField isHidden])
|
||||
[_textFieldSeparatorTwo setFrameOrigin:CGPointMake(CGRectGetMaxX([firstTexField frame]) + separatorContentInset.left, verticalInset)];
|
||||
else
|
||||
[_textFieldSeparatorTwo setFrameOrigin:CGPointMake(CGRectGetMaxX([secondTextField frame]) + separatorContentInset.left, verticalInset)];
|
||||
@@ -1206,7 +1233,7 @@ var CPZeroKeyCode = 48,
|
||||
{
|
||||
var datePickerElements = [_datePicker datePickerElements];
|
||||
|
||||
if ([_datePicker _isEnglishFormat])
|
||||
if ([_datePicker _isAmericanFormat])
|
||||
{
|
||||
if (datePickerElements & CPYearMonthDayDatePickerElementFlag || datePickerElements & CPYearMonthDatePickerElementFlag)
|
||||
[[self superview] setFirstTextField:_textFieldMonth];
|
||||
@@ -1249,9 +1276,9 @@ var CPZeroKeyCode = 48,
|
||||
var datePickerElements = [_datePicker datePickerElements],
|
||||
firstTexField = _textFieldMonth,
|
||||
secondTextField = _textFieldDay,
|
||||
isEnglishFormat = [_datePicker _isEnglishFormat];
|
||||
isAmericanFormat = [_datePicker _isAmericanFormat];
|
||||
|
||||
if (!isEnglishFormat)
|
||||
if (!isAmericanFormat)
|
||||
{
|
||||
firstTexField = _textFieldDay;
|
||||
secondTextField = _textFieldMonth;
|
||||
@@ -1266,7 +1293,7 @@ var CPZeroKeyCode = 48,
|
||||
|
||||
if (datePickerElements & CPHourMinuteSecondDatePickerElementFlag || datePickerElements & CPHourMinuteDatePickerElementFlag)
|
||||
[_textFieldYear setNextTextField:_textFieldHour];
|
||||
else if (isEnglishFormat || (datePickerElements & CPYearMonthDayDatePickerElementFlag) == CPYearMonthDayDatePickerElementFlag)
|
||||
else if (isAmericanFormat || (datePickerElements & CPYearMonthDayDatePickerElementFlag) == CPYearMonthDayDatePickerElementFlag)
|
||||
[_textFieldYear setNextTextField:firstTexField];
|
||||
else
|
||||
[_textFieldYear setNextTextField:secondTextField];
|
||||
@@ -1275,7 +1302,7 @@ var CPZeroKeyCode = 48,
|
||||
|
||||
if ((datePickerElements & CPHourMinuteSecondDatePickerElementFlag) == CPHourMinuteSecondDatePickerElementFlag)
|
||||
[_textFieldMinute setNextTextField:_textFieldSecond];
|
||||
else if (isEnglishFormat)
|
||||
else if (isAmericanFormat)
|
||||
[_textFieldMinute setNextTextField:_textFieldPMAM];
|
||||
else if ((datePickerElements & CPYearMonthDayDatePickerElementFlag) == CPYearMonthDayDatePickerElementFlag)
|
||||
[_textFieldMinute setNextTextField:firstTexField];
|
||||
@@ -1284,7 +1311,7 @@ var CPZeroKeyCode = 48,
|
||||
else
|
||||
[_textFieldMinute setNextTextField:_textFieldHour];
|
||||
|
||||
if (isEnglishFormat)
|
||||
if (isAmericanFormat)
|
||||
[_textFieldSecond setNextTextField:_textFieldPMAM];
|
||||
else if ((datePickerElements & CPYearMonthDayDatePickerElementFlag) == CPYearMonthDayDatePickerElementFlag)
|
||||
[_textFieldSecond setNextTextField:firstTexField];
|
||||
@@ -1304,9 +1331,9 @@ var CPZeroKeyCode = 48,
|
||||
var datePickerElements = [_datePicker datePickerElements],
|
||||
firstTexField = _textFieldMonth,
|
||||
secondTextField = _textFieldDay,
|
||||
isEnglishFormat = [_datePicker _isEnglishFormat];
|
||||
isAmericanFormat = [_datePicker _isAmericanFormat];
|
||||
|
||||
if (!isEnglishFormat)
|
||||
if (!isAmericanFormat)
|
||||
{
|
||||
firstTexField = _textFieldDay;
|
||||
secondTextField = _textFieldMonth;
|
||||
@@ -1322,14 +1349,14 @@ var CPZeroKeyCode = 48,
|
||||
|
||||
if (datePickerElements & CPYearMonthDatePickerElementFlag)
|
||||
[_textFieldHour setPreviousTextField:_textFieldYear];
|
||||
else if (isEnglishFormat)
|
||||
else if (isAmericanFormat)
|
||||
[_textFieldHour setPreviousTextField:_textFieldPMAM];
|
||||
else if ((datePickerElements & CPHourMinuteSecondDatePickerElementFlag) == CPHourMinuteSecondDatePickerElementFlag)
|
||||
[_textFieldHour setPreviousTextField:_textFieldSecond];
|
||||
else
|
||||
[_textFieldHour setPreviousTextField:_textFieldMinute];
|
||||
|
||||
if (!isEnglishFormat)
|
||||
if (!isAmericanFormat)
|
||||
[_textFieldYear setPreviousTextField:_textFieldMonth];
|
||||
else if ((datePickerElements & CPYearMonthDayDatePickerElementFlag) == CPYearMonthDayDatePickerElementFlag)
|
||||
[_textFieldYear setPreviousTextField:_textFieldDay];
|
||||
@@ -1338,7 +1365,7 @@ var CPZeroKeyCode = 48,
|
||||
|
||||
[secondTextField setPreviousTextField:firstTexField];
|
||||
|
||||
if (isEnglishFormat && datePickerElements & CPHourMinuteDatePickerElementFlag)
|
||||
if (isAmericanFormat && datePickerElements & CPHourMinuteDatePickerElementFlag)
|
||||
[firstTexField setPreviousTextField:_textFieldPMAM];
|
||||
else if ((datePickerElements & CPHourMinuteSecondDatePickerElementFlag) == CPHourMinuteSecondDatePickerElementFlag)
|
||||
[firstTexField setPreviousTextField:_textFieldSecond];
|
||||
@@ -1530,7 +1557,7 @@ var CPMonthDateType = 0,
|
||||
}
|
||||
}
|
||||
|
||||
if (parseInt(newValue) > [self _maxNumberWithMaxDate] || ([_datePicker _isEnglishFormat] && _dateType == CPHourDateType && parseInt(newValue) > 12))
|
||||
if (parseInt(newValue) > [self _maxNumberWithMaxDate] || ([_datePicker _isAmericanFormat] && _dateType == CPHourDateType && parseInt(newValue) > 12))
|
||||
return;
|
||||
|
||||
_firstEvent = NO;
|
||||
@@ -1549,7 +1576,7 @@ var CPMonthDateType = 0,
|
||||
|
||||
if ([stringValue length])
|
||||
{
|
||||
if ([_datePicker _isEnglishFormat] && [self dateType] == CPHourDateType)
|
||||
if ([_datePicker _isAmericanFormat] && [self dateType] == CPHourDateType)
|
||||
{
|
||||
var isAMHour = [[self superview] _isAMHour];
|
||||
|
||||
@@ -1593,7 +1620,7 @@ var CPMonthDateType = 0,
|
||||
if (![objectValue length])
|
||||
objectValue = [self objectValue];
|
||||
|
||||
if ([_datePicker _isEnglishFormat] && [self dateType] == CPHourDateType)
|
||||
if ([_datePicker _isAmericanFormat] && [self dateType] == CPHourDateType)
|
||||
{
|
||||
var isAMHour = [[self superview] _isAMHour];
|
||||
|
||||
@@ -1621,7 +1648,7 @@ var CPMonthDateType = 0,
|
||||
}
|
||||
else if (_dateType != CPAMPMDateType)
|
||||
{
|
||||
if (_dateType == CPHourDateType && [_datePicker _isEnglishFormat])
|
||||
if (_dateType == CPHourDateType && [_datePicker _isAmericanFormat])
|
||||
{
|
||||
var value = parseInt(aStringValue);
|
||||
|
||||
|
||||
@@ -182,7 +182,7 @@ var CPBindingOperationAnd = 0,
|
||||
allBindings = [bindingsForObject allKeys],
|
||||
count = [allBindings count];
|
||||
|
||||
while(count--)
|
||||
while (count--)
|
||||
{
|
||||
if ([[anObject class] isBindingExclusive:allBindings[count]])
|
||||
return NO;
|
||||
|
||||
+2
-2
@@ -26,6 +26,8 @@
|
||||
CPOKButton = 1;
|
||||
CPCancelButton = 0;
|
||||
|
||||
CPDocModalWindowMask = 1 << 6;
|
||||
|
||||
/*!
|
||||
@ingroup appkit
|
||||
@class CPPanel
|
||||
@@ -51,8 +53,6 @@ CPCancelButton = 0;
|
||||
@global
|
||||
@class CPWindow
|
||||
*/
|
||||
CPDocModalWindowMask = 1 << 6;
|
||||
|
||||
@implementation CPPanel : CPWindow
|
||||
{
|
||||
BOOL _becomesKeyOnlyIfNeeded;
|
||||
|
||||
@@ -86,6 +86,9 @@ var CPProgressIndicatorSpinningStyleColors = [];
|
||||
@"spinning-mini-gif": [CPNull null],
|
||||
@"spinning-small-gif": [CPNull null],
|
||||
@"spinning-regular-gif": [CPNull null],
|
||||
@"circular-border-color": [CPNull null],
|
||||
@"circular-border-size": 1,
|
||||
@"circular-color": [CPNull null]
|
||||
};
|
||||
}
|
||||
|
||||
@@ -368,6 +371,7 @@ var CPProgressIndicatorSpinningStyleColors = [];
|
||||
- (void)drawBar
|
||||
{
|
||||
[self setNeedsLayout];
|
||||
[self setNeedsDisplay:YES];
|
||||
}
|
||||
|
||||
- (CPView)createEphemeralSubviewNamed:(CPString)aName
|
||||
@@ -413,6 +417,9 @@ var CPProgressIndicatorSpinningStyleColors = [];
|
||||
{
|
||||
if (_style == CPProgressIndicatorSpinningStyle)
|
||||
{
|
||||
if (!_indeterminate)
|
||||
return;
|
||||
|
||||
// This will cause the bar view to go away due to having a nil rect when _style == CPProgressIndicatorSpinningStyle.
|
||||
[self layoutEphemeralSubviewNamed:"bar-view"
|
||||
positioned:CPWindowBelow
|
||||
@@ -438,6 +445,54 @@ var CPProgressIndicatorSpinningStyleColors = [];
|
||||
[self setBackgroundColor:nil];
|
||||
}
|
||||
|
||||
- (void)drawRect:(CGRect)aRect
|
||||
{
|
||||
if (_style == CPProgressIndicatorSpinningStyle && !_indeterminate)
|
||||
{
|
||||
var context = [[CPGraphicsContext currentContext] graphicsPort],
|
||||
rect = CGRectMakeCopy(aRect),
|
||||
borderSize = [self currentValueForThemeAttribute:@"circular-border-size"];
|
||||
|
||||
rect.origin.x += borderSize;
|
||||
rect.origin.y += borderSize;
|
||||
rect.size.width = rect.size.width - borderSize * 2;
|
||||
rect.size.height = rect.size.height - borderSize * 2;
|
||||
|
||||
if ([self doubleValue] > [self minValue] && [self doubleValue] < [self maxValue])
|
||||
{
|
||||
var midX = CGRectGetMidX(rect),
|
||||
midY = CGRectGetMidY(rect),
|
||||
endAngle = Math.PI * 2 * (([self doubleValue] - [self minValue]) / ([self maxValue] - [self minValue])) - Math.PI / 2,
|
||||
radius = MIN(rect.size.width / 2, rect.size.height / 2)
|
||||
|
||||
CGContextBeginPath(context);
|
||||
CGContextSetLineWidth(context, borderSize);
|
||||
CGContextSetFillColor(context, [self currentValueForThemeAttribute:@"circular-color"])
|
||||
CGContextMoveToPoint(context, midX, midY);
|
||||
CGContextAddArc(context, midX, midY, radius, 3 * Math.PI / 2, endAngle, YES)
|
||||
CGContextAddLineToPoint(context, midX, midY);
|
||||
CGContextClosePath(context);
|
||||
CGContextFillPath(context);
|
||||
CGContextStrokePath(context);
|
||||
}
|
||||
else if ([self doubleValue] == [self maxValue])
|
||||
{
|
||||
CGContextBeginPath(context);
|
||||
CGContextSetFillColor(context, [self currentValueForThemeAttribute:@"circular-color"])
|
||||
CGContextAddEllipseInRect(context, rect);
|
||||
CGContextClosePath(context);
|
||||
CGContextFillPath(context);
|
||||
}
|
||||
|
||||
CGContextBeginPath(context);
|
||||
CGContextSetStrokeColor(context , [self currentValueForThemeAttribute:@"circular-border-color"]);
|
||||
CGContextSetLineWidth(context, borderSize);
|
||||
CGContextAddEllipseInRect(context, rect);
|
||||
CGContextClosePath(context);
|
||||
CGContextStrokePath(context);
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
|
||||
+4
-6
@@ -29,6 +29,7 @@
|
||||
|
||||
@global CPApp
|
||||
|
||||
CPRadioImageOffset = 4.0;
|
||||
|
||||
/*!
|
||||
@ingroup appkit
|
||||
@@ -67,9 +68,6 @@
|
||||
option.
|
||||
|
||||
*/
|
||||
|
||||
CPRadioImageOffset = 4.0;
|
||||
|
||||
@implementation CPRadio : CPButton
|
||||
{
|
||||
CPRadioGroup _radioGroup;
|
||||
@@ -269,9 +267,9 @@ var CPRadioRadioGroupKey = @"CPRadioRadioGroupKey";
|
||||
- (BOOL)selectRadioWithTag:(int)tag
|
||||
{
|
||||
var index = [_radios indexOfObjectPassingTest:function(radio)
|
||||
{
|
||||
return [radio tag] === tag;
|
||||
}];
|
||||
{
|
||||
return [radio tag] === tag;
|
||||
}];
|
||||
|
||||
if (index !== CPNotFound)
|
||||
{
|
||||
|
||||
@@ -487,9 +487,9 @@ CPTransformableAttributeType = 1800;
|
||||
|
||||
- (id)copy
|
||||
{
|
||||
var views = [CPArray array];
|
||||
var views = [CPArray array],
|
||||
copy = [[[self class] alloc] init];
|
||||
|
||||
var copy = [[[self class] alloc] init];
|
||||
[copy _setTemplateType:_templateType];
|
||||
[copy _setOptions:_predicateOptions];
|
||||
[copy _setModifier:_predicateModifier];
|
||||
|
||||
@@ -86,15 +86,6 @@ var _isBrowserUsingOverlayScrollers = function()
|
||||
#endif
|
||||
};
|
||||
|
||||
/*!
|
||||
@ingroup appkit
|
||||
@class CPScrollView
|
||||
|
||||
Used to display views that are too large for the viewing area. the CPScrollView
|
||||
places scroll bars on the side of the view to allow the user to scroll and see the entire
|
||||
contents of the view.
|
||||
*/
|
||||
|
||||
var TIMER_INTERVAL = 0.2,
|
||||
CPScrollViewDelegate_scrollViewWillScroll_ = 1 << 0,
|
||||
CPScrollViewDelegate_scrollViewDidScroll_ = 1 << 1,
|
||||
@@ -104,7 +95,14 @@ var TIMER_INTERVAL = 0.2,
|
||||
var CPScrollerStyleGlobal = CPScrollerStyleOverlay,
|
||||
CPScrollerStyleGlobalChangeNotification = @"CPScrollerStyleGlobalChangeNotification";
|
||||
|
||||
/*!
|
||||
@ingroup appkit
|
||||
@class CPScrollView
|
||||
|
||||
Used to display views that are too large for the viewing area. the CPScrollView
|
||||
places scroll bars on the side of the view to allow the user to scroll and see the entire
|
||||
contents of the view.
|
||||
*/
|
||||
@implementation CPScrollView : CPView
|
||||
{
|
||||
CPClipView _contentView;
|
||||
@@ -1584,6 +1582,8 @@ var CPScrollViewContentViewKey = @"CPScrollViewContentView",
|
||||
*/
|
||||
- (void)awakeFromCib
|
||||
{
|
||||
[super awakeFromCib];
|
||||
|
||||
[self _updateScrollerStyle];
|
||||
[self _updateCornerAndHeaderView];
|
||||
}
|
||||
|
||||
+5
-5
@@ -50,11 +50,6 @@ CPNoScrollerParts = 0;
|
||||
CPOnlyScrollerArrows = 1;
|
||||
CPAllScrollerParts = 2;
|
||||
|
||||
/*!
|
||||
@ingroup appkit
|
||||
@class CPScroller
|
||||
*/
|
||||
|
||||
var PARTS_ARRANGEMENT = [CPScrollerKnobSlot, CPScrollerDecrementLine, CPScrollerIncrementLine, CPScrollerKnob],
|
||||
NAMES_FOR_PARTS = {},
|
||||
PARTS_FOR_NAMES = {};
|
||||
@@ -78,6 +73,11 @@ CPThemeStateScrollViewLegacy = CPThemeState("scroller-style-legacy");
|
||||
CPThemeStateScrollerKnobLight = CPThemeState("scroller-knob-light");
|
||||
CPThemeStateScrollerKnobDark = CPThemeState("scroller-knob-dark");
|
||||
|
||||
/*!
|
||||
@ingroup appkit
|
||||
@class CPScroller
|
||||
*/
|
||||
|
||||
@implementation CPScroller : CPControl
|
||||
{
|
||||
CPUsableScrollerParts _usableParts;
|
||||
|
||||
@@ -34,9 +34,8 @@ CPSearchFieldRecentsMenuItemTag = 1001;
|
||||
CPSearchFieldClearRecentsMenuItemTag = 1002;
|
||||
CPSearchFieldNoRecentsMenuItemTag = 1003;
|
||||
|
||||
var CPAutosavedRecentsChangedNotification = @"CPAutosavedRecentsChangedNotification";
|
||||
|
||||
var RECENT_SEARCH_PREFIX = @" ";
|
||||
var CPAutosavedRecentsChangedNotification = @"CPAutosavedRecentsChangedNotification",
|
||||
RECENT_SEARCH_PREFIX = @" ";
|
||||
|
||||
/*!
|
||||
@ingroup appkit
|
||||
|
||||
@@ -504,7 +504,7 @@ CPSegmentSwitchTrackingMomentary = 2;
|
||||
*/
|
||||
- (void)drawSegmentBezel:(int)aSegment highlight:(BOOL)shouldHighlight
|
||||
{
|
||||
if(aSegment < _themeStates.length)
|
||||
if (aSegment < _themeStates.length)
|
||||
{
|
||||
if (shouldHighlight)
|
||||
_themeStates[aSegment] = _themeStates[aSegment].and(CPThemeStateHighlighted);
|
||||
|
||||
+44
-35
@@ -55,7 +55,9 @@ var CPSplitViewDelegate_splitView_canCollapseSubview_
|
||||
CPSplitViewDelegate_splitView_constrainMaxCoordinate_ofSubviewAt_ = 1 << 5,
|
||||
CPSplitViewDelegate_splitView_constrainMinCoordinate_ofSubviewAt_ = 1 << 6,
|
||||
CPSplitViewDelegate_splitView_constrainSplitPosition_ofSubviewAt_ = 1 << 7,
|
||||
CPSplitViewDelegate_splitView_resizeSubviewsWithOldSize_ = 1 << 8;
|
||||
CPSplitViewDelegate_splitView_resizeSubviewsWithOldSize_ = 1 << 8,
|
||||
CPSplitViewDelegate_splitViewDidResizeSubviews_ = 1 << 9,
|
||||
CPSplitViewDelegate_splitViewWillResizeSubviews_ = 1 << 10;
|
||||
|
||||
#define SPLIT_VIEW_MAYBE_POST_WILL_RESIZE() \
|
||||
if ((_suppressResizeNotificationsMask & DidPostWillResizeNotification) === 0) \
|
||||
@@ -967,26 +969,14 @@ The sum of the views and the sum of the dividers should be equal to the size of
|
||||
if (_delegate === aDelegate)
|
||||
return;
|
||||
|
||||
if ([_delegate respondsToSelector:@selector(splitViewDidResizeSubviews:)])
|
||||
[[CPNotificationCenter defaultCenter] removeObserver:_delegate name:CPSplitViewDidResizeSubviewsNotification object:self];
|
||||
_delegate = aDelegate;
|
||||
_implementedDelegateMethods = 0;
|
||||
|
||||
if ([_delegate respondsToSelector:@selector(splitViewWillResizeSubviews:)])
|
||||
[[CPNotificationCenter defaultCenter] removeObserver:_delegate name:CPSplitViewWillResizeSubviewsNotification object:self];
|
||||
_implementedDelegateMethods |= CPSplitViewDelegate_splitViewWillResizeSubviews_;
|
||||
|
||||
_delegate = aDelegate;
|
||||
_implementedDelegateMethods = 0;
|
||||
|
||||
if ([_delegate respondsToSelector:@selector(splitViewDidResizeSubviews:)])
|
||||
[[CPNotificationCenter defaultCenter] addObserver:_delegate
|
||||
selector:@selector(splitViewDidResizeSubviews:)
|
||||
name:CPSplitViewDidResizeSubviewsNotification
|
||||
object:self];
|
||||
|
||||
if ([_delegate respondsToSelector:@selector(splitViewWillResizeSubviews:)])
|
||||
[[CPNotificationCenter defaultCenter] addObserver:_delegate
|
||||
selector:@selector(splitViewWillResizeSubviews:)
|
||||
name:CPSplitViewWillResizeSubviewsNotification
|
||||
object:self];
|
||||
if ([_delegate respondsToSelector:@selector(splitViewDidResizeSubviews:)])
|
||||
_implementedDelegateMethods |= CPSplitViewDelegate_splitViewDidResizeSubviews_;
|
||||
|
||||
if ([_delegate respondsToSelector:@selector(splitView:canCollapseSubview:)])
|
||||
_implementedDelegateMethods |= CPSplitViewDelegate_splitView_canCollapseSubview_;
|
||||
@@ -1064,27 +1054,12 @@ The sum of the views and the sum of the dividers should be equal to the size of
|
||||
|
||||
- (void)_postNotificationWillResize
|
||||
{
|
||||
var userInfo = nil;
|
||||
|
||||
if (_currentDivider !== CPNotFound)
|
||||
userInfo = @{ @"CPSplitViewDividerIndex": _currentDivider };
|
||||
|
||||
[[CPNotificationCenter defaultCenter] postNotificationName:CPSplitViewWillResizeSubviewsNotification
|
||||
object:self
|
||||
userInfo:userInfo];
|
||||
[self _sendDelegateSplitViewWillResizeSubviews];
|
||||
}
|
||||
|
||||
- (void)_postNotificationDidResize
|
||||
{
|
||||
var userInfo = nil;
|
||||
|
||||
if (_currentDivider !== CPNotFound)
|
||||
userInfo = @{ @"CPSplitViewDividerIndex": _currentDivider };
|
||||
|
||||
[[CPNotificationCenter defaultCenter] postNotificationName:CPSplitViewDidResizeSubviewsNotification
|
||||
object:self
|
||||
userInfo:userInfo];
|
||||
|
||||
[self _sendDelegateSplitViewDidResizeSubviews];
|
||||
|
||||
// TODO Cocoa always autosaves on "viewDidEndLiveResize". If Cappuccino adds support for this we
|
||||
// should do the same.
|
||||
@@ -1369,6 +1344,40 @@ The sum of the views and the sum of the dividers should be equal to the size of
|
||||
[_delegate splitView:self resizeSubviewsWithOldSize:oldSize];
|
||||
}
|
||||
|
||||
/*!
|
||||
@ignore
|
||||
Call the delegate splitViewWillResizeSubviews:
|
||||
*/
|
||||
- (void)_sendDelegateSplitViewWillResizeSubviews
|
||||
{
|
||||
var userInfo = nil;
|
||||
|
||||
if (_currentDivider !== CPNotFound)
|
||||
userInfo = @{ @"CPSplitViewDividerIndex": _currentDivider };
|
||||
|
||||
if (_implementedDelegateMethods & CPSplitViewDelegate_splitViewWillResizeSubviews_)
|
||||
[_delegate splitViewWillResizeSubviews:[[CPNotification alloc] initWithName:CPSplitViewWillResizeSubviewsNotification object:self userInfo:userInfo]];
|
||||
|
||||
[[CPNotificationCenter defaultCenter] postNotificationName:CPSplitViewWillResizeSubviewsNotification object:self userInfo:userInfo];
|
||||
}
|
||||
|
||||
/*!
|
||||
@ignore
|
||||
Call the delegate splitViewDidResizeSubviews:
|
||||
*/
|
||||
- (void)_sendDelegateSplitViewDidResizeSubviews
|
||||
{
|
||||
var userInfo = nil;
|
||||
|
||||
if (_currentDivider !== CPNotFound)
|
||||
userInfo = @{ @"CPSplitViewDividerIndex": _currentDivider };
|
||||
|
||||
if (_implementedDelegateMethods & CPSplitViewDelegate_splitViewDidResizeSubviews_)
|
||||
[_delegate splitViewDidResizeSubviews:[[CPNotification alloc] initWithName:CPSplitViewDidResizeSubviewsNotification object:self userInfo:userInfo]];
|
||||
|
||||
[[CPNotificationCenter defaultCenter] postNotificationName:CPSplitViewDidResizeSubviewsNotification object:self userInfo:userInfo];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
|
||||
@@ -529,6 +529,8 @@ var CPTabViewItemsKey = "CPTabViewItemsKey",
|
||||
|
||||
- (void)awakeFromCib
|
||||
{
|
||||
[super awakeFromCib];
|
||||
|
||||
// This cannot be run in initWithCoder because it might call selectTabViewItem:, which is
|
||||
// not safe to call before the views of the tab views items are fully decoded.
|
||||
[self _updateItems];
|
||||
|
||||
@@ -68,7 +68,7 @@
|
||||
_textField = [[_CPImageAndTextView alloc] initWithFrame:
|
||||
CGRectMake(5.0, 0.0, CGRectGetWidth([self bounds]) - 10.0, CGRectGetHeight([self bounds]))];
|
||||
|
||||
[_textField setAutoresizingMask:CPViewWidthSizable|CPViewHeightSizable];
|
||||
[_textField setAutoresizingMask:CPViewWidthSizable | CPViewHeightSizable];
|
||||
|
||||
[_textField setLineBreakMode:CPLineBreakByTruncatingTail];
|
||||
[_textField setTextColor:[CPColor colorWithRed:51.0 / 255.0 green:51.0 / 255.0 blue:51.0 / 255.0 alpha:1.0]];
|
||||
@@ -196,7 +196,7 @@
|
||||
maxX = CGRectGetMaxX(bounds) - 0.5;
|
||||
|
||||
CGContextSetLineWidth(context, 1);
|
||||
CGContextSetStrokeColor(context, [CPColor colorWithWhite:192.0/255.0 alpha:1.0]);
|
||||
CGContextSetStrokeColor(context, [CPColor colorWithWhite:192.0 / 255.0 alpha:1.0]);
|
||||
|
||||
CGContextBeginPath(context);
|
||||
|
||||
|
||||
+20
-16
@@ -2100,26 +2100,26 @@ NOT YET IMPLEMENTED
|
||||
found = NO,
|
||||
max_rec = 100;
|
||||
|
||||
while (max_rec--)
|
||||
while (max_rec--)
|
||||
{
|
||||
if (!cellView || cellView === contentView)
|
||||
{
|
||||
if (!cellView || cellView === contentView)
|
||||
found = NO;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
var superview = [cellView superview];
|
||||
|
||||
if ([superview isKindOfClass:[CPTableView class]])
|
||||
{
|
||||
found = NO;
|
||||
found = YES;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
var superview = [cellView superview];
|
||||
|
||||
if ([superview isKindOfClass:[CPTableView class]])
|
||||
{
|
||||
found = YES;
|
||||
break;
|
||||
}
|
||||
|
||||
cellView = superview;
|
||||
}
|
||||
cellView = superview;
|
||||
}
|
||||
}
|
||||
|
||||
if (found)
|
||||
{
|
||||
@@ -3593,6 +3593,9 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
|
||||
[self setNeedsDisplay:YES];
|
||||
}
|
||||
|
||||
if (!_isViewBased)
|
||||
[self _setEditingState:NO forView:dataView];
|
||||
|
||||
[self _sendDelegateWillDisplayView:dataView forTableColumn:tableColumn row:row];
|
||||
|
||||
return dataView;
|
||||
@@ -5091,7 +5094,7 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
|
||||
_editingColumn = column;
|
||||
_editingRow = row;
|
||||
|
||||
[aView addObserver:self forKeyPath:@"objectValue" options:CPKeyValueObservingOptionOld|CPKeyValueObservingOptionNew context:"editing"];
|
||||
[aView addObserver:self forKeyPath:@"objectValue" options:CPKeyValueObservingOptionOld | CPKeyValueObservingOptionNew context:"editing"];
|
||||
}
|
||||
|
||||
return aView;
|
||||
@@ -5196,7 +5199,7 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
|
||||
[self _notifyViewDidBecomeFirstResponder];
|
||||
|
||||
// This is for cell-based tables only. In view-based mode, we do not change the textfield apprearence during an edit.
|
||||
if (!_isViewBased && _editingRow !== CPNotFound && [responder isKindOfClass:[CPTextField class]] && [responder isEditable])
|
||||
if (!_isViewBased && _editingRow !== CPNotFound && [responder isKindOfClass:[CPTextField class]] && [responder isEditable] && [responder superview] == self)
|
||||
{
|
||||
[responder setBezeled:YES];
|
||||
[self _registerForEndEditingNote:responder];
|
||||
@@ -6391,6 +6394,7 @@ var CPTableViewDataSourceKey = @"CPTableViewDataSourceKey",
|
||||
|
||||
- (void)awakeFromCib
|
||||
{
|
||||
[super awakeFromCib];
|
||||
[self setThemeState:CPThemeStateTableDataView];
|
||||
}
|
||||
|
||||
|
||||
+13
-1
@@ -38,4 +38,16 @@ CPLeftTextMovement = 19;
|
||||
CPRightTextMovement = 20;
|
||||
CPUpTextMovement = 21;
|
||||
CPDownTextMovement = 22;
|
||||
CPCancelTextMovement = 23;
|
||||
CPCancelTextMovement = 23;
|
||||
|
||||
@typedef CPWritingDirection
|
||||
CPWritingDirectionNatural = -1;
|
||||
CPWritingDirectionLeftToRight = 0;
|
||||
CPWritingDirectionRightToLeft = 1;
|
||||
|
||||
@typedef CPTextAlignment
|
||||
CPLeftTextAlignment = 0;
|
||||
CPRightTextAlignment = 1;
|
||||
CPCenterTextAlignment = 2;
|
||||
CPJustifiedTextAlignment = 3;
|
||||
CPNaturalTextAlignment = 4;
|
||||
+34
-5
@@ -34,7 +34,6 @@
|
||||
@global CPStringPboardType
|
||||
@global CPCursor
|
||||
|
||||
|
||||
@protocol CPTextFieldDelegate <CPControlTextEditingDelegate>
|
||||
|
||||
@end
|
||||
@@ -66,7 +65,8 @@ var CPTextFieldDOMCurrentElement = nil,
|
||||
CPTextFieldCachedSelectStartFunction = nil,
|
||||
CPTextFieldCachedDragFunction = nil,
|
||||
CPTextFieldBlurHandler = nil,
|
||||
CPTextFieldInputFunction = nil;
|
||||
CPTextFieldInputFunction = nil,
|
||||
CPTexFieldCurrentCSSSelectableField = nil;
|
||||
|
||||
var CPSecureTextFieldCharacter = "\u2022";
|
||||
|
||||
@@ -376,7 +376,7 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
|
||||
|
||||
_sendActionOn = CPKeyUpMask | CPKeyDownMask;
|
||||
|
||||
[self setValue:CPLeftTextAlignment forThemeAttribute:@"alignment"];
|
||||
[self setValue:CPNaturalTextAlignment forThemeAttribute:@"alignment"];
|
||||
}
|
||||
|
||||
return self;
|
||||
@@ -700,6 +700,21 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
|
||||
return YES;
|
||||
}
|
||||
|
||||
/*!
|
||||
Set the selection css style for the DOM element of the textField
|
||||
@ignore
|
||||
*/
|
||||
- (void)_setEnableCSSSelection:(BOOL)shouldEnable
|
||||
{
|
||||
#if PLATFORM (DOM)
|
||||
if (CPTexFieldCurrentCSSSelectableField)
|
||||
CPTexFieldCurrentCSSSelectableField._DOMElement.style[CPBrowserStyleProperty(@"user-select")] = @"none";
|
||||
|
||||
CPTexFieldCurrentCSSSelectableField = self;
|
||||
_DOMElement.style[CPBrowserStyleProperty(@"user-select")] = shouldEnable ? @"text" : @"none";
|
||||
#endif
|
||||
}
|
||||
|
||||
/*!
|
||||
Set the css style for the input element of the textField
|
||||
@ignore
|
||||
@@ -753,6 +768,10 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
|
||||
element.style.textAlign = "right";
|
||||
break;
|
||||
|
||||
case CPNaturalTextAlignment:
|
||||
element.style.textAlign = "";
|
||||
break;
|
||||
|
||||
default:
|
||||
element.style.textAlign = "left";
|
||||
}
|
||||
@@ -989,6 +1008,7 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
|
||||
}
|
||||
else if ([self isSelectable])
|
||||
{
|
||||
[self _setEnableCSSSelection:YES];
|
||||
if (document.attachEvent)
|
||||
{
|
||||
CPTextFieldCachedSelectStartFunction = [[self window] platformWindow]._DOMBodyElement.onselectstart;
|
||||
@@ -1030,6 +1050,14 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
|
||||
}
|
||||
}
|
||||
|
||||
- (void)rightMouseDown:(CPEvent)anEvent
|
||||
{
|
||||
if ([self menuForEvent:anEvent] || [[self nextResponder] isKindOfClass:CPView])
|
||||
[super rightMouseDown:anEvent];
|
||||
else
|
||||
[[[anEvent window] platformWindow] _propagateContextMenuDOMEvent:YES];
|
||||
}
|
||||
|
||||
- (void)mouseDragged:(CPEvent)anEvent
|
||||
{
|
||||
if (![self isEnabled] || !([self isSelectable] || [self isEditable]))
|
||||
@@ -2002,7 +2030,7 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
|
||||
{
|
||||
previousContentViewBoundsOrigin = CGPointMakeCopy([[scrollView contentView] boundsOrigin]);
|
||||
|
||||
if(![[self superview] scrollRectToVisible:[self frame]])
|
||||
if (![[self superview] scrollRectToVisible:[self frame]])
|
||||
previousContentViewBoundsOrigin = nil;
|
||||
}
|
||||
|
||||
@@ -2139,7 +2167,8 @@ var CPTextFieldIsEditableKey = "CPTextFieldIsEditableKey",
|
||||
newValue = [self valueForBinding:aBinding],
|
||||
value = [destination valueForKeyPath:keyPath];
|
||||
|
||||
if (CPIsControllerMarker(value) && newValue === nil) return;
|
||||
if (CPIsControllerMarker(value) && newValue === nil)
|
||||
return;
|
||||
|
||||
newValue = [self reverseTransformValue:newValue withOptions:options];
|
||||
|
||||
|
||||
+99
-5
@@ -26,6 +26,7 @@
|
||||
|
||||
@import "CGAffineTransform.j"
|
||||
@import "CGGeometry.j"
|
||||
@import "CPAppearance.j"
|
||||
@import "CPColor.j"
|
||||
@import "CPGraphicsContext.j"
|
||||
@import "CPResponder.j"
|
||||
@@ -131,7 +132,6 @@ var CPViewFlags = { },
|
||||
|
||||
var CPViewHighDPIDrawingEnabled = YES;
|
||||
|
||||
|
||||
/*!
|
||||
@ingroup appkit
|
||||
@class CPView
|
||||
@@ -240,6 +240,10 @@ var CPViewHighDPIDrawingEnabled = YES;
|
||||
BOOL _toolTipInstalled;
|
||||
|
||||
BOOL _isObserving;
|
||||
|
||||
BOOL _allowsVibrancy @accessors(property=allowsVibrancy);
|
||||
CPAppearance _appearance @accessors(getter=appearance);
|
||||
CPAppearance _effectiveAppearance;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -327,6 +331,13 @@ var CPViewHighDPIDrawingEnabled = YES;
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (void)awakeFromCib
|
||||
{
|
||||
[super awakeFromCib];
|
||||
|
||||
[self _recomputeAppearance];
|
||||
}
|
||||
|
||||
- (id)init
|
||||
{
|
||||
return [self initWithFrame:CGRectMakeZero()];
|
||||
@@ -839,9 +850,9 @@ var CPViewHighDPIDrawingEnabled = YES;
|
||||
*/
|
||||
- (void)viewDidMoveToSuperview
|
||||
{
|
||||
// if (_graphicsContext)
|
||||
[self setNeedsDisplay:YES];
|
||||
[self _recomputeAppearance];
|
||||
|
||||
[self setNeedsDisplay:YES];
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -1820,7 +1831,7 @@ var CPViewHighDPIDrawingEnabled = YES;
|
||||
else if ([[self nextResponder] isKindOfClass:CPView])
|
||||
[super rightMouseDown:anEvent];
|
||||
else
|
||||
[[[anEvent window] platformWindow] _propagateContextMenuDOMEvent:YES];
|
||||
[[[anEvent window] platformWindow] _propagateContextMenuDOMEvent:NO];
|
||||
}
|
||||
|
||||
- (CPMenu)menuForEvent:(CPEvent)anEvent
|
||||
@@ -3509,6 +3520,85 @@ setBoundsOrigin:
|
||||
return (_ephemeralSubviewsForNames[aViewName] || nil);
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@implementation CPView (Appearance)
|
||||
|
||||
/*! Returns the receiver's appearance if any, or ask the superview and returns it.
|
||||
*/
|
||||
- (CPAppearance)effectiveAppearance
|
||||
{
|
||||
if (_appearance)
|
||||
return _appearance;
|
||||
|
||||
return [_superview effectiveAppearance];
|
||||
}
|
||||
|
||||
- (void)setAppearance:(CPAppearance)anAppearance
|
||||
{
|
||||
if ([_appearance isEqual:anAppearance])
|
||||
return;
|
||||
|
||||
[self willChangeValueForKey:@"appearance"];
|
||||
_appearance = anAppearance;
|
||||
[self didChangeValueForKey:@"appearance"];
|
||||
|
||||
[self _recomputeAppearance];
|
||||
}
|
||||
|
||||
/*! @ignore
|
||||
*/
|
||||
- (void)_recomputeAppearance
|
||||
{
|
||||
// if we don't have a themeState, it means
|
||||
// the view is not decoding from a cib, so we just return.
|
||||
// this method will be called again in awakeFromCib
|
||||
if (!_themeState)
|
||||
return;
|
||||
|
||||
var effectiveAppearance = [self effectiveAppearance];
|
||||
|
||||
if ([effectiveAppearance isEqual:[CPAppearance appearanceNamed:CPAppearanceNameAqua]])
|
||||
{
|
||||
[self setThemeState:CPThemeStateAppearanceAqua];
|
||||
[self unsetThemeState:CPThemeStateAppearanceLightContent];
|
||||
[self unsetThemeState:CPThemeStateAppearanceVibrantLight];
|
||||
[self unsetThemeState:CPThemeStateAppearanceVibrantDark];
|
||||
}
|
||||
else if ([effectiveAppearance isEqual:[CPAppearance appearanceNamed:CPAppearanceNameLightContent]])
|
||||
{
|
||||
[self unsetThemeState:CPThemeStateAppearanceAqua];
|
||||
[self setThemeState:CPThemeStateAppearanceLightContent];
|
||||
[self unsetThemeState:CPThemeStateAppearanceVibrantLight];
|
||||
[self unsetThemeState:CPThemeStateAppearanceVibrantDark];
|
||||
}
|
||||
else if ([effectiveAppearance isEqual:[CPAppearance appearanceNamed:CPAppearanceNameVibrantLight]])
|
||||
{
|
||||
[self unsetThemeState:CPThemeStateAppearanceAqua];
|
||||
[self unsetThemeState:CPThemeStateAppearanceLightContent];
|
||||
[self setThemeState:CPThemeStateAppearanceVibrantLight];
|
||||
[self unsetThemeState:CPThemeStateAppearanceVibrantDark];
|
||||
}
|
||||
else if ([effectiveAppearance isEqual:[CPAppearance appearanceNamed:CPAppearanceNameVibrantDark]])
|
||||
{
|
||||
[self unsetThemeState:CPThemeStateAppearanceAqua];
|
||||
[self unsetThemeState:CPThemeStateAppearanceLightContent];
|
||||
[self unsetThemeState:CPThemeStateAppearanceVibrantLight];
|
||||
[self setThemeState:CPThemeStateAppearanceVibrantDark];
|
||||
}
|
||||
else
|
||||
{
|
||||
[self unsetThemeState:CPThemeStateAppearanceAqua];
|
||||
[self unsetThemeState:CPThemeStateAppearanceLightContent];
|
||||
[self unsetThemeState:CPThemeStateAppearanceVibrantLight];
|
||||
[self unsetThemeState:CPThemeStateAppearanceVibrantDark];
|
||||
}
|
||||
|
||||
[_subviews makeObjectsPerformSelector:@selector(_recomputeAppearance)];
|
||||
}
|
||||
|
||||
|
||||
@end
|
||||
|
||||
var CPViewAutoresizingMaskKey = @"CPViewAutoresizingMask",
|
||||
@@ -3531,7 +3621,8 @@ var CPViewAutoresizingMaskKey = @"CPViewAutoresizingMask",
|
||||
CPReuseIdentifierKey = @"CPReuseIdentifierKey",
|
||||
CPViewScaleKey = @"CPViewScaleKey",
|
||||
CPViewSizeScaleKey = @"CPViewSizeScaleKey",
|
||||
CPViewIsScaledKey = @"CPViewIsScaledKey";
|
||||
CPViewIsScaledKey = @"CPViewIsScaledKey",
|
||||
CPViewAppearanceKey = @"CPViewAppearanceKey";
|
||||
|
||||
@implementation CPView (CPCoding)
|
||||
|
||||
@@ -3646,6 +3737,8 @@ var CPViewAutoresizingMaskKey = @"CPViewAutoresizingMask",
|
||||
_themeAttributes[attributeName] = CPThemeAttributeDecode(aCoder, attributeName, attributes[count], _theme, themeClass);
|
||||
}
|
||||
|
||||
[self setAppearance:[aCoder decodeObjectForKey:CPViewAppearanceKey]];
|
||||
|
||||
[self setNeedsDisplay:YES];
|
||||
[self setNeedsLayout];
|
||||
}
|
||||
@@ -3734,6 +3827,7 @@ var CPViewAutoresizingMaskKey = @"CPViewAutoresizingMask",
|
||||
[aCoder encodeSize:[self scaleSize] forKey:CPViewScaleKey];
|
||||
[aCoder encodeSize:[self _hierarchyScaleSize] forKey:CPViewSizeScaleKey];
|
||||
[aCoder encodeBool:_isScaled forKey:CPViewIsScaledKey];
|
||||
[aCoder encodeObject:_appearance forKey:CPViewAppearanceKey];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -0,0 +1,231 @@
|
||||
/*
|
||||
* CPVisualEffectView.j
|
||||
* AppKit
|
||||
*
|
||||
* Created by Antoine Mercadal.
|
||||
* Copyright 2015, 280 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>
|
||||
@import "CPAppearance.j"
|
||||
@import "CPView.j"
|
||||
|
||||
@typedef CPVisualEffectMaterial
|
||||
CPVisualEffectMaterialAppearanceBased = 0;
|
||||
CPVisualEffectMaterialLight = 1;
|
||||
CPVisualEffectMaterialDark = 2;
|
||||
CPVisualEffectMaterialTitlebar = 3;
|
||||
|
||||
@typedef CPVisualEffectBlendingMode
|
||||
CPVisualEffectBlendingModeBehindWindow = 0;
|
||||
CPVisualEffectBlendingModeWithinWindow = 1;
|
||||
|
||||
@typedef CPVisualEffectState
|
||||
CPVisualEffectStateFollowsWindowActiveState = 0;
|
||||
CPVisualEffectStateActive = 1;
|
||||
CPVisualEffectStateInactive = 2;
|
||||
|
||||
|
||||
/*! @ingroup appkit
|
||||
|
||||
Very naive implementation of CPVisualEffectView. This view allows
|
||||
to use vibrancy effect. This is only working with Safari 9+ and the
|
||||
support in Chrome/ium should come quite soon.
|
||||
Using this class with a browser that doesn't support backdrop-filter
|
||||
While still work, but you will not get the blurry effect.
|
||||
*/
|
||||
@implementation CPVisualEffectView : CPView
|
||||
{
|
||||
CPImage _maskImage @accessors(property=maskImage);
|
||||
CPVisualEffectBlendingMode _blendingMode @accessors(property=blendingMode);
|
||||
CPVisualEffectMaterial _material @accessors(property=material);
|
||||
CPVisualEffectState _state @accessors(property=state);
|
||||
}
|
||||
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark Initialization
|
||||
|
||||
- (id)initWithFrame:(CGRect)aFrame
|
||||
{
|
||||
if (self = [super initWithFrame:aFrame])
|
||||
{
|
||||
_material = CPVisualEffectMaterialAppearanceBased;
|
||||
_blendingMode = CPVisualEffectBlendingModeWithinWindow;
|
||||
_state = CPVisualEffectStateFollowsWindowActiveState;
|
||||
_appearance = [CPAppearance appearanceNamed:CPAppearanceNameVibrantDark];
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark CPVisualEffectView API
|
||||
|
||||
/*! Sets the appearance of the CPVisualEffectView.
|
||||
|
||||
Only CPAppearance named CPAppearanceNameVibrantDark or CPAppearanceNameVibrantLight are valid
|
||||
|
||||
@param anAppearance the CPAppearance.
|
||||
*/
|
||||
- (void)setAppearance:(CPAppearance)anAppearance
|
||||
{
|
||||
if (![self _validAppearance:anAppearance])
|
||||
[CPException raise:CPInvalidArgumentException reason:"Appearance can only be CPAppearanceNameVibrantDark or CPAppearanceNameVibrantLight in CPVisualEffectView, but is " + anAppearance];
|
||||
|
||||
[super setAppearance:anAppearance];
|
||||
[self _applyVibrancyState];
|
||||
}
|
||||
|
||||
/*! Sets the received effect state.
|
||||
Possible values:
|
||||
<pre>
|
||||
CPVisualEffectStateFollowsWindowActiveState (default)
|
||||
CPVisualEffectStateActive
|
||||
CPVisualEffectStateInactive
|
||||
</pre>
|
||||
*/
|
||||
- (void)setState:(CPVisualEffectState)aState
|
||||
{
|
||||
if (_state == aState)
|
||||
return;
|
||||
|
||||
[self willChangeValueForKey:"state"];
|
||||
_state = aState;
|
||||
[self didChangeValueForKey:"state"];
|
||||
|
||||
[self _applyVibrancyState];
|
||||
}
|
||||
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark Utilities
|
||||
|
||||
- (void)_setEffectEnabled:(BOOL)shouldEnable
|
||||
{
|
||||
var dark = [[self appearance] isEqual:[CPAppearance appearanceNamed:CPAppearanceNameVibrantDark]],
|
||||
prop = CPBrowserStyleProperty("backdrop-filter"),
|
||||
color = (dark ? [CPColor colorWithHexString:@"1e1e1e"] : [CPColor whiteColor]),
|
||||
finalColor = shouldEnable ? [color colorWithAlphaComponent:0.6] : color;
|
||||
|
||||
[self setBackgroundColor:finalColor];
|
||||
|
||||
#if PLATFORM(DOM)
|
||||
self._DOMElement.style[prop] = shouldEnable ? "blur(30px)" : nil;
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
- (void)_applyVibrancyState
|
||||
{
|
||||
switch (_state)
|
||||
{
|
||||
case CPVisualEffectStateFollowsWindowActiveState:
|
||||
[self _setEffectEnabled:[self hasThemeState:CPThemeStateKeyWindow]];
|
||||
break;
|
||||
|
||||
case CPVisualEffectStateActive:
|
||||
[self _setEffectEnabled:YES];
|
||||
break;
|
||||
|
||||
case CPVisualEffectStateInactive:
|
||||
[self _setEffectEnabled:NO];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
- (BOOL)_validAppearance:(CPAppearance)anAppearance
|
||||
{
|
||||
return [anAppearance isEqual:[CPAppearance appearanceNamed:CPAppearanceNameVibrantDark]] || [anAppearance isEqual:[CPAppearance appearanceNamed:CPAppearanceNameVibrantLight]];
|
||||
}
|
||||
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark Overrides
|
||||
|
||||
- (BOOL)setThemeState:(ThemeState)aState
|
||||
{
|
||||
if (aState.isa && [aState isKindOfClass:CPArray])
|
||||
aState = CPThemeState.apply(null, aState);
|
||||
|
||||
var r = [super setThemeState:aState];
|
||||
|
||||
if (r)
|
||||
[self _applyVibrancyState];
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
- (BOOL)unsetThemeState:(ThemeState)aState
|
||||
{
|
||||
if (aState.isa && [aState isKindOfClass:CPArray])
|
||||
aState = CPThemeState.apply(null, aState);
|
||||
|
||||
var r = [super unsetThemeState:aState];
|
||||
|
||||
if (r)
|
||||
[self _applyVibrancyState];
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
- (void)viewDidMoveToSuperview
|
||||
{
|
||||
[super viewDidMoveToSuperview];
|
||||
|
||||
if (_superview)
|
||||
[self _applyVibrancyState];
|
||||
}
|
||||
|
||||
- (void)viewDidMoveToWindow
|
||||
{
|
||||
[super viewDidMoveToWindow];
|
||||
|
||||
if (_window)
|
||||
[self _applyVibrancyState];
|
||||
}
|
||||
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark CPCoding
|
||||
|
||||
- (id)initWithCoder:(CPCoder)aCoder
|
||||
{
|
||||
if (self = [super initWithCoder:aCoder])
|
||||
{
|
||||
_blendingMode = [aCoder decodeIntForKey:@"_blendingMode"] || CPVisualEffectBlendingModeWithinWindow;
|
||||
_maskImage = [aCoder decodeObjectForKey:@"_maskImage"];
|
||||
_material = [aCoder decodeIntForKey:@"_material"] || CPVisualEffectMaterialAppearanceBased;
|
||||
_state = [aCoder decodeIntForKey:@"_state"] || CPVisualEffectStateFollowsWindowActiveState;
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)encodeWithCoder:(CPCoder)aCoder
|
||||
{
|
||||
[super encodeWithCoder:aCoder];
|
||||
|
||||
[aCoder encodeObject:_maskImage forKey:@"_maskImage"];
|
||||
[aCoder encodeInt:_blendingMode forKey:@"_blendingMode"];
|
||||
[aCoder encodeInt:_material forKey:@"_material"];
|
||||
[aCoder encodeInt:_state forKey:@"_state"];
|
||||
}
|
||||
|
||||
|
||||
@end
|
||||
@@ -63,7 +63,7 @@
|
||||
|
||||
@optional
|
||||
- (BOOL)windowShouldClose:(CPWindow)aWindow;
|
||||
- (CPSize)windowWillResize:(CPWindow)sender toSize:(CPSize)aSize;
|
||||
- (CGSize)windowWillResize:(CPWindow)sender toSize:(CGSize)aSize;
|
||||
- (CPUndoManager)windowWillReturnUndoManager:(CPWindow)window;
|
||||
- (void)windowDidBecomeKey:(CPNotification)aNotification;
|
||||
- (void)windowDidBecomeMain:(CPNotification)aNotification;
|
||||
@@ -80,7 +80,7 @@
|
||||
|
||||
@end
|
||||
|
||||
var CPWindowDelegate_windowShouldClose_ = 1 << 1
|
||||
var CPWindowDelegate_windowShouldClose_ = 1 << 1,
|
||||
CPWindowDelegate_windowWillReturnUndoManager_ = 1 << 2,
|
||||
CPWindowDelegate_windowWillClose_ = 1 << 3,
|
||||
CPWindowDelegate_windowWillResize_toSize_ = 1 << 4;
|
||||
@@ -2780,7 +2780,7 @@ CPTexturedBackgroundWindowMask
|
||||
[[CPNotificationCenter defaultCenter] removeObserver:self name:CPWindowDidEndSheetNotification object:self];
|
||||
|
||||
var sheet = _sheetContext[@"nextSheet"],
|
||||
modalDelegate =_sheetContext[@"nextModalDelegate"],
|
||||
modalDelegate = _sheetContext[@"nextModalDelegate"],
|
||||
endSelector = _sheetContext[@"nextEndSelector"],
|
||||
contextInfo = _sheetContext[@"nextContextInfo"];
|
||||
|
||||
@@ -3521,7 +3521,7 @@ var keyViewComparator = function(lhs, rhs, context)
|
||||
@ignore
|
||||
Call the delegate windowWillResize:toSize:
|
||||
*/
|
||||
- (CPSize)_sendDelegateWindowWillResizeToSize:(CPSize)aSize
|
||||
- (CGSize)_sendDelegateWindowWillResizeToSize:(CGSize)aSize
|
||||
{
|
||||
if (!(_implementedDelegateMethods & CPWindowDelegate_windowWillResize_toSize_))
|
||||
return aSize;
|
||||
|
||||
@@ -26,7 +26,6 @@
|
||||
@import "CGGradient.j"
|
||||
@import "_CPWindowView.j"
|
||||
|
||||
@global CPPopoverAppearanceMinimal
|
||||
|
||||
var _CPPopoverWindowViewDefaultCursorSize = CGSizeMake(16, 10);
|
||||
|
||||
@@ -39,7 +38,6 @@ var _CPPopoverWindowViewDefaultCursorSize = CGSizeMake(16, 10);
|
||||
{
|
||||
float _arrowOffsetX @accessors(property=arrowOffsetX);
|
||||
float _arrowOffsetY @accessors(property=arrowOffsetY);
|
||||
int _appearance @accessors(property=appearance);
|
||||
unsigned _preferredEdge @accessors(property=preferredEdge);
|
||||
|
||||
CGSize _cursorSize;
|
||||
@@ -123,7 +121,7 @@ var _CPPopoverWindowViewDefaultCursorSize = CGSizeMake(16, 10);
|
||||
{
|
||||
_arrowOffsetX = 0.0;
|
||||
_arrowOffsetY = 0.0;
|
||||
_appearance = CPPopoverAppearanceMinimal;
|
||||
_appearance = [CPAppearance appearanceNamed:CPAppearanceNameVibrantLight];
|
||||
_cursorSize = CGSizeMakeCopy(_CPPopoverWindowViewDefaultCursorSize);
|
||||
}
|
||||
|
||||
@@ -168,7 +166,7 @@ var _CPPopoverWindowViewDefaultCursorSize = CGSizeMake(16, 10);
|
||||
gradient,
|
||||
frame = [self bounds];
|
||||
|
||||
if (_appearance == CPPopoverAppearanceMinimal)
|
||||
if ([_appearance isEqual:[CPAppearance appearanceNamed:CPAppearanceNameVibrantLight]])
|
||||
{
|
||||
gradient = [self valueForThemeAttribute:@"background-gradient"];
|
||||
strokeColor = [self valueForThemeAttribute:@"stroke-color"];
|
||||
|
||||
@@ -27,7 +27,8 @@
|
||||
|
||||
@import "CGContext.j"
|
||||
@import "CGGeometry.j"
|
||||
|
||||
@import "CPColor.j"
|
||||
@import "CPView.j"
|
||||
|
||||
#define DOM(aLayer) aLayer._DOMElement
|
||||
|
||||
@@ -494,11 +495,11 @@ var CALayerRegisteredRunLoopUpdates = nil;
|
||||
*/
|
||||
- (void)display
|
||||
{
|
||||
#if PLATFORM(DOM)
|
||||
if (!_context)
|
||||
{
|
||||
_context = CGBitmapGraphicsContextCreate();
|
||||
|
||||
#if PLATFORM(DOM)
|
||||
_DOMContentsElement = _context.DOMElement;
|
||||
|
||||
_DOMContentsElement.style.zIndex = -100;
|
||||
@@ -516,7 +517,6 @@ var CALayerRegisteredRunLoopUpdates = nil;
|
||||
_DOMContentsElement.style.height = ROUND(CGRectGetHeight(_backingStoreFrame)) + "px";
|
||||
|
||||
_DOMElement.appendChild(_DOMContentsElement);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (USE_BUFFER)
|
||||
@@ -534,6 +534,7 @@ var CALayerRegisteredRunLoopUpdates = nil;
|
||||
|
||||
[self drawInContext:CABackingStoreGetContext(_contents)];
|
||||
}
|
||||
#endif
|
||||
|
||||
[self composite];
|
||||
}
|
||||
@@ -796,7 +797,6 @@ if (_DOMContentsElement && aLayer._zPosition > _DOMContentsElement.style.zIndex)
|
||||
|
||||
if (mask & CALayerDisplayUpdateMask)
|
||||
[layer display];
|
||||
|
||||
else if (mask & CALayerFrameSizeUpdateMask || mask & CALayerCompositeUpdateMask)
|
||||
[layer composite];
|
||||
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
|
||||
require("../common.jake");
|
||||
|
||||
checkUlimit();
|
||||
|
||||
var framework = require("objective-j/jake").framework,
|
||||
BundleTask = require("objective-j/jake").BundleTask;
|
||||
|
||||
|
||||
@@ -48,10 +48,21 @@ var screenNeedsInitialization = NO,
|
||||
document.documentElement.style.overflow = "hidden";
|
||||
|
||||
if ([CPPlatform isBrowser])
|
||||
{
|
||||
// This differ from cocoa, where shouldTerminate is called in the method terminate of CPApp
|
||||
// Cappuccino acts like this because we can not close a window openend by the user with a script (so not possible in terminate), and we can only prevent the action in the method onbeforeunload in js.
|
||||
window.onbeforeunload = function()
|
||||
{
|
||||
if ([CPApp _sendDelegateApplicationShouldTerminate] != CPTerminateNow)
|
||||
return [CPApp _sendDelegateApplicationShouldTerminateMessage];
|
||||
};
|
||||
|
||||
window.onunload = function()
|
||||
{
|
||||
[self closeAllPlatformWindows];
|
||||
[CPApp terminate:nil];
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
+ (BOOL)isBrowser
|
||||
@@ -138,4 +149,18 @@ var screenNeedsInitialization = NO,
|
||||
object:self];
|
||||
}
|
||||
|
||||
+ (void)closeAllPlatformWindows
|
||||
{
|
||||
var platformWindows = [CPPlatformWindow visiblePlatformWindows],
|
||||
primaryPlatformWindow = [CPPlatformWindow primaryPlatformWindow],
|
||||
platformWindowEnumerator = [platformWindows objectEnumerator],
|
||||
platformWindow = nil;
|
||||
|
||||
while ((platformWindow = [platformWindowEnumerator nextObject]) !== nil)
|
||||
{
|
||||
if (platformWindow != primaryPlatformWindow)
|
||||
[platformWindow orderOut:self];
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -365,6 +365,7 @@ _CPPlatformWindowWillCloseNotification = @"_CPPlatformWindowWillCloseNotificatio
|
||||
_DOMBodyElement.style["-khtml-user-select"] = "none";
|
||||
|
||||
_DOMBodyElement.webkitTouchCallout = "none";
|
||||
_DOMBodyElement.style[CPBrowserStyleProperty(@"user-select")] = @"none";
|
||||
|
||||
[self createDOMElements];
|
||||
[self _addLayers];
|
||||
|
||||
@@ -2999,6 +2999,24 @@ var themedButtonValues = nil,
|
||||
return progressBar;
|
||||
}
|
||||
|
||||
+ (CPProgressIndicator)themedCircularProgressIndicator
|
||||
{
|
||||
var progressBar = [[CPProgressIndicator alloc] initWithFrame:CGRectMake(0, 0, 32, 32)];
|
||||
[progressBar setStyle:CPProgressIndicatorSpinningStyle];
|
||||
[progressBar setIndeterminate:NO];
|
||||
|
||||
var themeValues =
|
||||
[
|
||||
[@"circular-border-color", [CPColor colorWithHexString:@"C7C7C7"]],
|
||||
[@"circular-border-size", 1],
|
||||
[@"circular-color", [CPColor colorWithHexString:@"89B5CD"]]
|
||||
];
|
||||
|
||||
[self registerThemeValues:themeValues forView:progressBar];
|
||||
|
||||
return progressBar;
|
||||
}
|
||||
|
||||
+ (CPBox)themedBox
|
||||
{
|
||||
var box = [[CPBox alloc] initWithFrame:CGRectMake(0,0,100,100)],
|
||||
|
||||
@@ -688,7 +688,8 @@ var themedButtonValues = nil,
|
||||
[@"text-color", [CPColor blackColor], [CPThemeStateTableDataView, CPThemeStateSelectedDataView, CPThemeStateEditable, CPThemeStateFirstResponder, CPThemeStateKeyWindow]],
|
||||
[@"content-inset", CGInsetMake(7.0, 7.0, 5.0, 10.0), [CPThemeStateTableDataView, CPThemeStateEditable]],
|
||||
[@"font", [CPFont systemFontOfSize:CPFontCurrentSystemSize], [CPThemeStateTableDataView, CPThemeStateEditing]],
|
||||
[@"bezel-inset", CGInsetMake(-2.0, -2.0, -2.0, -2.0), [CPThemeStateTableDataView, CPThemeStateEditing]],
|
||||
[@"bezel-inset", CGInsetMake(-2.0, -2.0, -2.0, -2.0), [CPThemeStateTableDataView, CPThemeStateEditable, CPThemeStateEditing]],
|
||||
[@"bezel-inset", CGInsetMake(1.0, 1.0, 1.0, 1.0), [CPThemeStateTableDataView, CPThemeStateEditable]],
|
||||
|
||||
[@"text-color", [CPColor colorWithCalibratedWhite:125.0 / 255.0 alpha:1.0], [CPThemeStateTableDataView, CPThemeStateGroupRow]],
|
||||
[@"text-color", [CPColor whiteColor], [CPThemeStateTableDataView, CPThemeStateGroupRow, CPThemeStateSelectedDataView, CPThemeStateFirstResponder, CPThemeStateKeyWindow]],
|
||||
@@ -2499,6 +2500,24 @@ var themedButtonValues = nil,
|
||||
return progressBar;
|
||||
}
|
||||
|
||||
+ (CPProgressIndicator)themedCircularProgressIndicator
|
||||
{
|
||||
var progressBar = [[CPProgressIndicator alloc] initWithFrame:CGRectMake(0, 0, 32, 32)];
|
||||
[progressBar setStyle:CPProgressIndicatorSpinningStyle];
|
||||
[progressBar setIndeterminate:NO];
|
||||
|
||||
var themeValues =
|
||||
[
|
||||
[@"circular-border-color", [CPColor colorWithHexString:@"A0A0A0"]],
|
||||
[@"circular-border-size", 1],
|
||||
[@"circular-color", [CPColor colorWithHexString:@"5982DA"]]
|
||||
];
|
||||
|
||||
[self registerThemeValues:themeValues forView:progressBar];
|
||||
|
||||
return progressBar;
|
||||
}
|
||||
|
||||
+ (CPBox)themedBox
|
||||
{
|
||||
var box = [[CPBox alloc] initWithFrame:CGRectMake(0, 0, 100, 100)],
|
||||
|
||||
+27
-15
@@ -141,7 +141,12 @@ var _CPPopoverWindow_shouldClose_ = 1 << 4,
|
||||
if (_appearance === anAppearance)
|
||||
return;
|
||||
|
||||
[_windowView setAppearance:anAppearance];
|
||||
_appearance = anAppearance;
|
||||
|
||||
var appearanceName = _appearance == CPPopoverAppearanceMinimal ? CPAppearanceNameVibrantLight : CPAppearanceNameVibrantDark,
|
||||
viewAppearance = [CPAppearance appearanceNamed:appearanceName];
|
||||
|
||||
[_windowView setAppearance:viewAppearance];
|
||||
}
|
||||
|
||||
- (void)setStyleMask:(unsigned)aStyleMask
|
||||
@@ -548,29 +553,36 @@ var _CPPopoverWindow_shouldClose_ = 1 << 4,
|
||||
|
||||
// Now set up the pop-in to normal size transition.
|
||||
// Because we are watching the -webkit-transform, it will occur now.
|
||||
[self setCSS3Property:@"Transform" value:@"scale(1)"];
|
||||
[self setCSS3Property:@"Transition" value:CPBrowserCSSProperty('transform') + @" 50ms linear"];
|
||||
|
||||
_transitionCompleteFunction = function()
|
||||
window.setTimeout(function()
|
||||
{
|
||||
[self setCSS3Property:@"Transform" value:@"scale(1)"];
|
||||
[self setCSS3Property:@"Transition" value:CPBrowserCSSProperty('transform') + @" 50ms linear"];
|
||||
|
||||
_transitionCompleteFunction = function()
|
||||
{
|
||||
#if PLATFORM(DOM)
|
||||
_DOMElement.removeEventListener(CPBrowserStyleProperty('transitionend'), _transitionCompleteFunction, YES);
|
||||
_DOMElement.removeEventListener(CPBrowserStyleProperty('transitionend'), _transitionCompleteFunction, YES);
|
||||
|
||||
// Make sure to clear these properties when the animation is done. Without this,
|
||||
// the window becomes blurry in Chrome, presumably because the browser composits
|
||||
// a layer with a transform differently even when it's an identity transform.
|
||||
[self setCSS3Property:@"Transform" value:nil];
|
||||
[self setCSS3Property:@"TransformOrigin" value:nil];
|
||||
[self setCSS3Property:@"Transition" value:nil];
|
||||
// Make sure to clear these properties when the animation is done. Without this,
|
||||
// the window becomes blurry in Chrome, presumably because the browser composits
|
||||
// a layer with a transform differently even when it's an identity transform.
|
||||
[self setCSS3Property:@"Transform" value:nil];
|
||||
[self setCSS3Property:@"TransformOrigin" value:nil];
|
||||
[self setCSS3Property:@"Transition" value:nil];
|
||||
#endif
|
||||
_isOpening = NO;
|
||||
_isOpening = NO;
|
||||
|
||||
[_delegate _popoverWindowDidShow];
|
||||
}
|
||||
[_delegate _popoverWindowDidShow];
|
||||
}
|
||||
|
||||
#if PLATFORM(DOM)
|
||||
_DOMElement.addEventListener(CPBrowserStyleProperty('transitionend'), _transitionCompleteFunction, YES);
|
||||
_DOMElement.addEventListener(CPBrowserStyleProperty('transitionend'), _transitionCompleteFunction, YES);
|
||||
#endif
|
||||
}, 0); // There are some weird random conditions happening in Chrome 44. If we don't put a timeout to 0 for the end of
|
||||
// the transition, the popover is blinking. It happens on Opera as well...
|
||||
// When the condition is met, the popover will lag a bit when opening...nothing crazy ;)
|
||||
// An issue has been opened here : https://code.google.com/p/chromium/issues/detail?id=523044&thanks=523044&ts=1440095724
|
||||
};
|
||||
|
||||
#if PLATFORM(DOM)
|
||||
|
||||
+25
-10
@@ -366,23 +366,38 @@ function pressEnvironment(rootPath, outputFiles, environment, options) {
|
||||
return {executable:includedBytes, data:dataBytes, mhtml:mhtmlBytes};
|
||||
}
|
||||
|
||||
function pngcrushDirectory(directory) {
|
||||
var directoryPath = FILE.path(directory);
|
||||
var pngs = directoryPath.glob("**/*.png");
|
||||
function pngcrushDirectory(directory)
|
||||
{
|
||||
var directoryPath = FILE.path(directory),
|
||||
pngs = directoryPath.glob("**/*.png");
|
||||
|
||||
system.stderr.print("Running pngcrush on " + pngs.length + " pngs:");
|
||||
pngs.forEach(function(dstPath) {
|
||||
pngs.forEach(function(dstPath)
|
||||
{
|
||||
var tmpPath = FILE.path(dstPath+".tmp");
|
||||
|
||||
var p = OS.popen(["pngcrush", "-rem", "alla", "-reduce", /*"-brute",*/ dstPath, tmpPath]);
|
||||
if (p.wait()) {
|
||||
CPLog.warn("pngcrush failed. Ensure it's installed and on your PATH.");
|
||||
try
|
||||
{
|
||||
var p = OS.popen(["pngcrush", "-rem", "alla", "-reduce", /*"-brute",*/ dstPath, tmpPath]);
|
||||
|
||||
if (p.wait())
|
||||
{
|
||||
CPLog.warn("pngcrush failed. Ensure it's installed and on your PATH.");
|
||||
}
|
||||
else
|
||||
{
|
||||
FILE.move(tmpPath, dstPath);
|
||||
system.stderr.write(".").flush();
|
||||
}
|
||||
}
|
||||
else {
|
||||
FILE.move(tmpPath, dstPath);
|
||||
system.stderr.write(".").flush();
|
||||
finally
|
||||
{
|
||||
p.stdin.close();
|
||||
p.stdout.close();
|
||||
p.stderr.close();
|
||||
}
|
||||
});
|
||||
|
||||
system.stderr.print("");
|
||||
}
|
||||
|
||||
|
||||
@@ -3,10 +3,20 @@ var OS = require("os");
|
||||
|
||||
exports.fontinfo = function(name, size)
|
||||
{
|
||||
var p = OS.popen(["fontinfo", "-n", name, size || 12]);
|
||||
var result;
|
||||
|
||||
if (p.wait() === 0)
|
||||
return JSON.parse(p.stdout.read());
|
||||
else
|
||||
return null;
|
||||
try
|
||||
{
|
||||
var p = OS.popen(["fontinfo", "-n", name, size || 12]);
|
||||
if (p.wait() === 0)
|
||||
result = p.stdout.read();
|
||||
}
|
||||
finally
|
||||
{
|
||||
p.stdin.close();
|
||||
p.stdout.close();
|
||||
p.stderr.close();
|
||||
}
|
||||
|
||||
return result ? JSON.parse(result) : null;
|
||||
};
|
||||
@@ -3,10 +3,20 @@ var OS = require("os");
|
||||
|
||||
exports.imagesize = function(path)
|
||||
{
|
||||
var p = OS.popen(["imagesize", "-n", path]);
|
||||
var result;
|
||||
|
||||
if (p.wait() === 0)
|
||||
return JSON.parse(p.stdout.read());
|
||||
else
|
||||
return null;
|
||||
try
|
||||
{
|
||||
var p = OS.popen(["imagesize", "-n", path]);
|
||||
if (p.wait() === 0)
|
||||
result = p.stdout.read();
|
||||
}
|
||||
finally
|
||||
{
|
||||
p.stdin.close();
|
||||
p.stdout.close();
|
||||
p.stderr.close();
|
||||
}
|
||||
|
||||
return result ? JSON.parse(result) : null;
|
||||
};
|
||||
@@ -208,6 +208,14 @@ var concat = Array.prototype.concat,
|
||||
_CPRaiseInvalidAbstractInvocation(self, _cmd);
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns a hash for the object. Unlike Cocoa, the hash value does not take content into account, so two arrays with the same content (\c isEqual: === YES) will not generate the same hash.
|
||||
*/
|
||||
- (unsigned)hash
|
||||
{
|
||||
return [self UID];
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the first object in the array. If the array is empty, returns \c nil
|
||||
*/
|
||||
|
||||
@@ -196,7 +196,8 @@ var concat = Array.prototype.concat,
|
||||
}
|
||||
|
||||
else
|
||||
for (; index < count; ++index) {
|
||||
for (; index < count; ++index)
|
||||
{
|
||||
var receiver = self[index];
|
||||
receiver == nil ? nil : receiver.isa.objj_msgSend0(receiver, aSelector);
|
||||
}
|
||||
|
||||
@@ -26,9 +26,8 @@
|
||||
@import "CPString.j"
|
||||
|
||||
// The default global behavior class, created lazily
|
||||
var CPDefaultDcmHandler = nil;
|
||||
|
||||
var CPDecimalNumberUIDs = new CFMutableDictionary();
|
||||
var CPDefaultDcmHandler = nil,
|
||||
CPDecimalNumberUIDs = new CFMutableDictionary();
|
||||
|
||||
/*!
|
||||
@class CPDecimalNumberHandler
|
||||
|
||||
@@ -605,11 +605,11 @@
|
||||
}
|
||||
if ([self scanPredicateKeyword:@"TRUE"] || [self scanPredicateKeyword:@"YES"])
|
||||
{
|
||||
return [CPExpression expressionForConstantValue:[CPNumber numberWithBool:YES]];
|
||||
return [CPExpression expressionForConstantValue:YES];
|
||||
}
|
||||
if ([self scanPredicateKeyword:@"FALSE"] || [self scanPredicateKeyword:@"NO"])
|
||||
{
|
||||
return [CPExpression expressionForConstantValue:[CPNumber numberWithBool:NO]];
|
||||
return [CPExpression expressionForConstantValue:NO];
|
||||
}
|
||||
if ([self scanPredicateKeyword:@"SELF"])
|
||||
{
|
||||
|
||||
@@ -266,7 +266,7 @@ var abbreviationDictionary,
|
||||
@"MST" : [@"Mountain Standard Time", @"MST", @"Mountain Daylight Time", @"MDT", @"Mountain Time", @"MT"],
|
||||
@"PHT" : [@"Philippine Standard Time", @"GMT+08:00", @"Philippine Summer Time", @"GMT+08:00", @"Philippine Standard Time", @"Philippines Time"],
|
||||
@"WET" : [@"Western European Standard Time", @"GMT", @"Western European Summer Time", @"GMT+01:00", @"Western European Time", @"Portugal Time (Lisbon)"]
|
||||
};
|
||||
};
|
||||
|
||||
var date = [CPDate date],
|
||||
abbreviation = String(String(date).split("(")[1]).split(")")[0];
|
||||
|
||||
@@ -26,6 +26,16 @@
|
||||
@import "CPURLRequest.j"
|
||||
@import "CPURLResponse.j"
|
||||
|
||||
@protocol CPURLConnectionDelegate <CPObject>
|
||||
|
||||
- (void)connection:(CPURLConnection)anURLConnection didFailWithError:(CPException)anError;
|
||||
- (void)connection:(CPURLConnection)anURLConnection didReceiveData:(CPString)aData;
|
||||
- (void)connection:(CPURLConnection)anURLConnection didReceiveResponse:(CPString)aResponse;
|
||||
- (void)connectionDidFinishLoading:(CPURLConnection)anURLConnection;
|
||||
- (void)connectionDidReceiveAuthenticationChallenge:(CPURLConnection)anURLConnection;
|
||||
|
||||
@end
|
||||
|
||||
@typedef HTTPRequest
|
||||
|
||||
var CPURLConnectionDelegate = nil;
|
||||
@@ -76,16 +86,16 @@ var CPURLConnectionDelegate = nil;
|
||||
*/
|
||||
@implementation CPURLConnection : CPObject
|
||||
{
|
||||
CPURLRequest _originalRequest @accessors(readonly, getter=originalRequest);
|
||||
CPURLRequest _request @accessors(readonly, getter=currentRequest);
|
||||
id _delegate;
|
||||
BOOL _isCanceled;
|
||||
BOOL _isLocalFileConnection;
|
||||
CPURLRequest _originalRequest @accessors(readonly, getter=originalRequest);
|
||||
CPURLRequest _request @accessors(readonly, getter=currentRequest);
|
||||
id <CPURLConnectionDelegate> _delegate;
|
||||
BOOL _isCanceled;
|
||||
BOOL _isLocalFileConnection;
|
||||
|
||||
HTTPRequest _HTTPRequest;
|
||||
HTTPRequest _HTTPRequest;
|
||||
}
|
||||
|
||||
+ (void)setClassDelegate:(id)delegate
|
||||
+ (void)setClassDelegate:(id <CPURLConnectionDelegate>)delegate
|
||||
{
|
||||
CPURLConnectionDelegate = delegate;
|
||||
}
|
||||
@@ -145,7 +155,7 @@ var CPURLConnectionDelegate = nil;
|
||||
@param shouldStartImmediately whether the \c -start method should be called from here
|
||||
@return the initialized url connection
|
||||
*/
|
||||
- (id)initWithRequest:(CPURLRequest)aRequest delegate:(id)aDelegate startImmediately:(BOOL)shouldStartImmediately
|
||||
- (id)initWithRequest:(CPURLRequest)aRequest delegate:(id <CPURLConnectionDelegate>)aDelegate startImmediately:(BOOL)shouldStartImmediately
|
||||
{
|
||||
self = [super init];
|
||||
|
||||
@@ -166,6 +176,7 @@ var CPURLConnectionDelegate = nil;
|
||||
(window.location.protocol === "file:" || window.location.protocol === "app:"));
|
||||
|
||||
_HTTPRequest = new CFHTTPRequest();
|
||||
_HTTPRequest.setTimeout([aRequest timeoutInterval] * 1000);
|
||||
_HTTPRequest.setWithCredentials([aRequest withCredentials]);
|
||||
|
||||
if (shouldStartImmediately)
|
||||
@@ -175,7 +186,7 @@ var CPURLConnectionDelegate = nil;
|
||||
return self;
|
||||
}
|
||||
|
||||
- (id)initWithRequest:(CPURLRequest)aRequest delegate:(id)aDelegate
|
||||
- (id)initWithRequest:(CPURLRequest)aRequest delegate:(id <CPURLConnectionDelegate>)aDelegate
|
||||
{
|
||||
return [self initWithRequest:aRequest delegate:aDelegate startImmediately:YES];
|
||||
}
|
||||
@@ -200,6 +211,7 @@ var CPURLConnectionDelegate = nil;
|
||||
_HTTPRequest.open([_request HTTPMethod], [[_request URL] absoluteString], YES);
|
||||
|
||||
_HTTPRequest.onreadystatechange = function() { [self _readyStateDidChange]; };
|
||||
_HTTPRequest.ontimeout = function() { [self _didTimeout]; };
|
||||
|
||||
var fields = [_request allHTTPHeaderFields],
|
||||
key = nil,
|
||||
@@ -212,11 +224,16 @@ var CPURLConnectionDelegate = nil;
|
||||
}
|
||||
catch (anException)
|
||||
{
|
||||
if ([_delegate respondsToSelector:@selector(connection:didFailWithError:)])
|
||||
[_delegate connection:self didFailWithError:anException];
|
||||
[self _sendDelegateDidFailWithError:anException];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)_sendDelegateDidFailWithError:(CPException)anException
|
||||
{
|
||||
if ([_delegate respondsToSelector:@selector(connection:didFailWithError:)])
|
||||
[_delegate connection:self didFailWithError:anException];
|
||||
}
|
||||
|
||||
/*
|
||||
Cancels the current request.
|
||||
*/
|
||||
@@ -239,10 +256,22 @@ var CPURLConnectionDelegate = nil;
|
||||
return _isLocalFileConnection;
|
||||
}
|
||||
|
||||
/*!
|
||||
@ignore
|
||||
*/
|
||||
- (void)_didTimeout
|
||||
{
|
||||
var exception = [CPException exceptionWithName:@"Timeout exception"
|
||||
reason:"The request timed out."
|
||||
userInfo:@{}];
|
||||
|
||||
[self _sendDelegateDidFailWithError:exception];
|
||||
}
|
||||
|
||||
/* @ignore */
|
||||
- (void)_readyStateDidChange
|
||||
{
|
||||
if (_HTTPRequest.readyState() === CFHTTPRequest.CompleteState)
|
||||
if (_HTTPRequest.readyState() === CFHTTPRequest.CompleteState && !_HTTPRequest.isTimeoutRequest())
|
||||
{
|
||||
var statusCode = _HTTPRequest.status(),
|
||||
URL = [_request URL];
|
||||
|
||||
@@ -25,6 +25,12 @@
|
||||
@import "CPString.j"
|
||||
@import "CPURL.j"
|
||||
|
||||
@typedef CPURLRequestCachePolicy
|
||||
CPURLRequestUseProtocolCachePolicy = 0;
|
||||
CPURLRequestReloadIgnoringLocalCacheData = 1;
|
||||
CPURLRequestReturnCacheDataElseLoad = 2;
|
||||
CPURLRequestReturnCacheDataDontLoad = 3;
|
||||
|
||||
/*!
|
||||
@class CPURLRequest
|
||||
@ingroup foundation
|
||||
@@ -35,14 +41,16 @@
|
||||
*/
|
||||
@implementation CPURLRequest : CPObject
|
||||
{
|
||||
CPURL _URL @accessors(property=URL);
|
||||
CPURL _URL @accessors(property=URL);
|
||||
|
||||
// FIXME: this should be CPData
|
||||
CPString _HTTPBody @accessors(property=HTTPBody);
|
||||
CPString _HTTPMethod @accessors(property=HTTPMethod);
|
||||
BOOL _withCredentials @accessors(property=withCredentials);
|
||||
CPString _HTTPBody @accessors(property=HTTPBody);
|
||||
CPString _HTTPMethod @accessors(property=HTTPMethod);
|
||||
BOOL _withCredentials @accessors(property=withCredentials);
|
||||
|
||||
CPDictionary _HTTPHeaderFields @accessors(readonly, getter=allHTTPHeaderFields);
|
||||
CPDictionary _HTTPHeaderFields @accessors(readonly, getter=allHTTPHeaderFields);
|
||||
CPTimeInterval _timeoutInterval @accessors(readonly, getter=timeoutInterval);
|
||||
CPURLRequestCachePolicy _cachePolicy @accessors(readonly, getter=cachePolicy);
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -55,6 +63,18 @@
|
||||
return [[CPURLRequest alloc] initWithURL:aURL];
|
||||
}
|
||||
|
||||
/*!
|
||||
Creates a request with a specified URL, cachePolicy and timeoutInterval
|
||||
@param aURL the URL of the request
|
||||
@param aCachePolicy the cache policy of the request
|
||||
@param aTimeoutInterval the timeoutInterval of the request
|
||||
@return a CPURLRequest
|
||||
*/
|
||||
+ (id)requestWithURL:(CPURL)anURL cachePolicy:(CPURLRequestCachePolicy)aCachePolicy timeoutInterval:(CPTimeInterval)aTimeoutInterval
|
||||
{
|
||||
return [[CPURLRequest alloc] initWithURL:anURL cachePolicy:aCachePolicy timeoutInterval:aTimeoutInterval];
|
||||
}
|
||||
|
||||
/*!
|
||||
Equal to `[receiver initWithURL:nil]`.
|
||||
*/
|
||||
@@ -63,6 +83,25 @@
|
||||
return [self initWithURL:nil];
|
||||
}
|
||||
|
||||
/*!
|
||||
Initializes the request with a URL. This is the designated initializer.
|
||||
|
||||
@param aURL the url to set
|
||||
@param aCachePolicy the cache policy of the request
|
||||
@param aTimeoutInterval the timeoutInterval of the request
|
||||
@return the initialized CPURLRequest
|
||||
*/
|
||||
- (id)initWithURL:(CPURL)anURL cachePolicy:(CPURLRequestCachePolicy)aCachePolicy timeoutInterval:(CPTimeInterval)aTimeoutInterval
|
||||
{
|
||||
if (self = [self initWithURL:anURL])
|
||||
{
|
||||
_cachePolicy = aCachePolicy;
|
||||
_timeoutInterval = aTimeoutInterval;
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
/*!
|
||||
Initializes the request with a URL. This is the designated initializer.
|
||||
|
||||
@@ -71,9 +110,7 @@
|
||||
*/
|
||||
- (id)initWithURL:(CPURL)aURL
|
||||
{
|
||||
self = [super init];
|
||||
|
||||
if (self)
|
||||
if (self = [super init])
|
||||
{
|
||||
[self setURL:aURL];
|
||||
|
||||
@@ -81,9 +118,34 @@
|
||||
_HTTPMethod = @"GET";
|
||||
_HTTPHeaderFields = @{};
|
||||
_withCredentials = NO;
|
||||
_timeoutInterval = 60.0;
|
||||
_cachePolicy = CPURLRequestUseProtocolCachePolicy;
|
||||
|
||||
[self setValue:"Thu, 01 Jan 1970 00:00:00 GMT" forHTTPHeaderField:"If-Modified-Since"];
|
||||
[self setValue:"no-cache" forHTTPHeaderField:"Cache-Control"];
|
||||
|
||||
switch (_cachePolicy)
|
||||
{
|
||||
case CPURLRequestUseProtocolCachePolicy:
|
||||
// TODO: implement everything about cache...
|
||||
[self setValue:"no-cache" forHTTPHeaderField:"Cache-Control"];
|
||||
break;
|
||||
|
||||
case CPURLRequestReturnCacheDataElseLoad:
|
||||
[self setValue:"max-stale=31536000" forHTTPHeaderField:"Cache-Control"];
|
||||
break;
|
||||
|
||||
case CPURLRequestReturnCacheDataDontLoad:
|
||||
[self setValue:"only-if-cached" forHTTPHeaderField:"Cache-Control"];
|
||||
break;
|
||||
|
||||
case CPURLRequestReloadIgnoringLocalCacheData:
|
||||
[self setValue:"no-cache" forHTTPHeaderField:"Cache-Control"];
|
||||
break;
|
||||
|
||||
default:
|
||||
[self setValue:"no-cache" forHTTPHeaderField:"Cache-Control"];
|
||||
}
|
||||
|
||||
[self setValue:"XMLHttpRequest" forHTTPHeaderField:"X-Requested-With"];
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,109 @@
|
||||
/*
|
||||
* CPUserNotification.j
|
||||
* Foundation
|
||||
*
|
||||
* Created by Alexandre Wilhelm.
|
||||
* Copyright 2015, 280 North, Inc.
|
||||
*
|
||||
* 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 "CPAttributedString.j"
|
||||
@import "CPArray.j"
|
||||
@import "CPDate.j"
|
||||
@import "CPDictionary.j"
|
||||
@import "CPObject.j"
|
||||
@import "CPTimeZone.j"
|
||||
|
||||
// We need something from the AppKit in Foundation ???
|
||||
@class CPImage
|
||||
|
||||
@typedef CPUserNotificationAction
|
||||
@typedef CPUserNotificationActivationType
|
||||
|
||||
/*!
|
||||
@global CPUserNotificationActivationType
|
||||
@group CPUserNotificationActivationType
|
||||
The user did not interact with the notification alert.
|
||||
*/
|
||||
CPUserNotificationActivationTypeNone = 0;
|
||||
|
||||
/*!
|
||||
@global CPUserNotificationActivationType
|
||||
@group CPUserNotificationActivationType
|
||||
The user clicked on the contents of the notification alert.
|
||||
*/
|
||||
CPUserNotificationActivationTypeContentsClicked = 1;
|
||||
|
||||
/*!
|
||||
@global CPUserNotificationActivationType
|
||||
@group CPUserNotificationActivationType
|
||||
The user clicked on the action button of the notification alert.
|
||||
*/
|
||||
CPUserNotificationActivationTypeActionButtonClicked = 2;
|
||||
|
||||
/*!
|
||||
@global CPUserNotificationActivationType
|
||||
@group CPUserNotificationActivationType
|
||||
The user replied to the notification.
|
||||
*/
|
||||
CPUserNotificationActivationTypeReplied = 3,
|
||||
|
||||
/*!
|
||||
@global CPUserNotificationActivationType
|
||||
@group CPUserNotificationActivationType
|
||||
The user clicked on the additional action button of the notification alert.
|
||||
*/
|
||||
CPUserNotificationActivationTypeAdditionalActionClicked = 4;
|
||||
|
||||
/*!
|
||||
@class CPUserNotification
|
||||
@ingroup foundation
|
||||
|
||||
@brief The CPUserNotification class is used to configure a notification that is scheduled for display by the UserNotificationCenter class.
|
||||
*/
|
||||
@implementation CPUserNotification : CPObject
|
||||
{
|
||||
BOOL _presented @accessors(getter=isPresented);
|
||||
BOOL _remote @accessors(getter=isRemote);
|
||||
CPDate _actualDeliveryDate @accessors(getter=actualDeliveryDate);
|
||||
CPDate _deliveryDate @accessors(property=deliveryDate);
|
||||
CPDictionary _userInfo @accessors(property=userInfo);
|
||||
CPImage _contentImage @accessors(property=contentImage);
|
||||
CPString _identifier @accessors(property=identifier);
|
||||
CPString _informativeText @accessors(property=informativeText);
|
||||
CPString _title @accessors(property=title);
|
||||
CPTimeInterval _deliveryRepeatInterval @accessors(property=deliveryRepeatInterval);
|
||||
CPTimeZone _deliveryTimeZone @accessors(property=deliveryTimeZone);
|
||||
CPUserNotificationActivationType _activationType @accessors(getter=activationType);
|
||||
}
|
||||
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark Creating an user notification
|
||||
|
||||
- (id)init
|
||||
{
|
||||
self = [super init];
|
||||
|
||||
if (self)
|
||||
{
|
||||
_identifier = [self UID];
|
||||
}
|
||||
|
||||
return self
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,293 @@
|
||||
/*
|
||||
* CPUserNotificationCenter.j
|
||||
* Foundation
|
||||
*
|
||||
* Created by Alexandre Wilhelm.
|
||||
* Copyright 2015, 280 North, Inc.
|
||||
*
|
||||
* 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 "CPArray.j"
|
||||
@import "CPObject.j"
|
||||
@import "CPTimer.j"
|
||||
@import "CPUserNotification.j"
|
||||
|
||||
@protocol CPUserNotificationCenterDelegate <CPObject>
|
||||
|
||||
@optional
|
||||
- (BOOL)userNotificationCenter:(CPUserNotificationCenter)center shouldPresentNotification:(CPUserNotification)notification;
|
||||
- (void)userNotificationCenter:(CPUserNotificationCenter)center didDeliverNotification:(CPUserNotification)notification;
|
||||
- (void)userNotificationCenter:(CPUserNotificationCenter)center didActivateNotification:(CPUserNotification)notification;
|
||||
|
||||
@end
|
||||
|
||||
// Remove compiling warnings
|
||||
@class Notification
|
||||
|
||||
@global CPApp
|
||||
|
||||
var CPUserNotificationCenterDelegate_userNotificationCenter_shouldPresentNotification_ = 1 << 0,
|
||||
CPUserNotificationCenterDelegate_userNotificationCenter_didDeliverNotification_ = 1 << 1,
|
||||
CPUserNotificationCenterDelegate_userNotificationCenter_didActivateNotification_ = 1 << 2;
|
||||
|
||||
var CPUserNotificationDefaultCenter = nil;
|
||||
|
||||
/*!
|
||||
@class CPUserNotificationCenter
|
||||
@ingroup foundation
|
||||
|
||||
@brief The CPUserNotificationCenter class delivers user notifications to the user from applications or helper applications.
|
||||
*/
|
||||
@implementation CPUserNotificationCenter : CPObject
|
||||
{
|
||||
CPArray _deliveredNotifications @accessors(property=deliveredNotifications);
|
||||
CPArray _scheduledNotifications @accessors(property=scheduledNotifications);
|
||||
id <CPUserNotificationCenterDelegate> _delegate;
|
||||
|
||||
CPInteger _implementedDelegateMethods;
|
||||
CPMutableDictionary _timersForUserNotification;
|
||||
}
|
||||
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark Creating Default User Notification Center
|
||||
|
||||
/*!
|
||||
Returns the user's notification center
|
||||
*/
|
||||
+ (CPNotificationCenter)defaultUserNotificationCenter
|
||||
{
|
||||
if (!CPUserNotificationDefaultCenter)
|
||||
CPUserNotificationDefaultCenter = [[CPUserNotificationCenter alloc] init];
|
||||
|
||||
return CPUserNotificationDefaultCenter;
|
||||
}
|
||||
|
||||
- (id)init
|
||||
{
|
||||
self = [super init];
|
||||
|
||||
if (self)
|
||||
{
|
||||
_deliveredNotifications = [];
|
||||
_scheduledNotifications = [];
|
||||
_timersForUserNotification = @{};
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark Getting and Setting the Delegate
|
||||
|
||||
- (void)setDelegate:(id <CPUserNotificationCenterDelegate>)aDelegate
|
||||
{
|
||||
if (_delegate === aDelegate)
|
||||
return;
|
||||
|
||||
_delegate = aDelegate;
|
||||
_implementedDelegateMethods = 0;
|
||||
|
||||
if ([_delegate respondsToSelector:@selector(userNotificationCenter:shouldPresentNotification:)])
|
||||
_implementedDelegateMethods |= CPUserNotificationCenterDelegate_userNotificationCenter_shouldPresentNotification_;
|
||||
|
||||
if ([_delegate respondsToSelector:@selector(userNotificationCenter:didDeliverNotification:)])
|
||||
_implementedDelegateMethods |= CPUserNotificationCenterDelegate_userNotificationCenter_didDeliverNotification_;
|
||||
|
||||
if ([_delegate respondsToSelector:@selector(userNotificationCenter:didActivateNotification:)])
|
||||
_implementedDelegateMethods |= CPUserNotificationCenterDelegate_userNotificationCenter_didActivateNotification_;
|
||||
}
|
||||
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark Managing the Scheduled Notification Queue
|
||||
|
||||
/*!
|
||||
Schedules the given user notification
|
||||
@param anUserNotification the user notification
|
||||
*/
|
||||
- (void)scheduleNotification:(CPUserNotification)anUserNotification
|
||||
{
|
||||
var scheduledDate = [[anUserNotification deliveryDate] copy];
|
||||
[scheduledDate _dateWithTimeZone:[anUserNotification deliveryTimeZone]];
|
||||
|
||||
var timer = [[CPTimer alloc] initWithFireDate:scheduledDate
|
||||
interval:[anUserNotification deliveryRepeatInterval]
|
||||
target:self
|
||||
selector:@selector(_scheduledUserNotificationTimerDidFire:)
|
||||
userInfo:anUserNotification
|
||||
repeats:([anUserNotification deliveryRepeatInterval] ? YES : NO)];
|
||||
|
||||
[_scheduledNotifications addObject:anUserNotification];
|
||||
_timersForUserNotification[[anUserNotification UID]] = timer;
|
||||
|
||||
[[CPRunLoop currentRunLoop] addTimer:timer forMode:CPDefaultRunLoopMode];
|
||||
}
|
||||
|
||||
- (void)_scheduledUserNotificationTimerDidFire:(CPTimer)aTimer
|
||||
{
|
||||
[self deliverNotification:[aTimer userInfo]];
|
||||
}
|
||||
|
||||
/*!
|
||||
Removes the given user notification for the scheduled notifications.
|
||||
@param anUserNotification the user notification
|
||||
*/
|
||||
- (void)removeScheduledNotification:(CPUserNotification)anUserNotification
|
||||
{
|
||||
if ([_scheduledNotifications indexOfObject:anUserNotification] != CPNotFound)
|
||||
{
|
||||
[_scheduledNotifications removeObject:anUserNotification];
|
||||
[_timersForUserNotification[[anUserNotification UID]] invalidate];
|
||||
delete _timersForUserNotification[[anUserNotification UID]];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark Managing the Delivered Notifications
|
||||
|
||||
/*!
|
||||
Deliver the given user notification
|
||||
@param aNotification the user notification
|
||||
*/
|
||||
- (void)deliverNotification:(CPUserNotification)aNotification
|
||||
{
|
||||
[self _launchUserNotification:aNotification];
|
||||
}
|
||||
|
||||
/*!
|
||||
Remove a delivered user notification from the user notification center.
|
||||
@param aNotification the user notification
|
||||
*/
|
||||
- (void)removeDeliveredNotification:(CPUserNotification)aNotification
|
||||
{
|
||||
[_deliveredNotifications removeObject:aNotification];
|
||||
}
|
||||
|
||||
/*!
|
||||
Remove all delivered user notifications from the user notification center.
|
||||
*/
|
||||
- (void)removeAllDeliveredNotifications
|
||||
{
|
||||
[_deliveredNotifications removeAllObjects];
|
||||
}
|
||||
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark Permission Utilities
|
||||
|
||||
- (void)_askPermissionForUserNotification:(CPUserNotification)anUserNotification
|
||||
{
|
||||
Notification.requestPermission(function (permission) {
|
||||
if (permission == "granted")
|
||||
// We need to relaunch the notification if the permission are granted
|
||||
[self _launchUserNotification:anUserNotification];
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark Notification Utilities
|
||||
|
||||
- (void)_launchUserNotification:(CPUserNotification)anUserNotification
|
||||
{
|
||||
// If the browser version is unsupported, remain silent.
|
||||
if (!window || !'Notification' in window)
|
||||
return;
|
||||
|
||||
if (Notification.permission === 'default')
|
||||
[self _askPermissionForUserNotification:anUserNotification];
|
||||
|
||||
if (Notification.permission === 'granted')
|
||||
{
|
||||
if (([self _delegateRespondsToShouldPresentNotification] && [self _sendDelegateShouldPresentNotification:anUserNotification])
|
||||
|| ![CPApp isActive])
|
||||
{
|
||||
var notification = new Notification(
|
||||
[anUserNotification title],
|
||||
{
|
||||
'body': [anUserNotification informativeText],
|
||||
'icon': [[anUserNotification contentImage] filename],
|
||||
// ...prevent duplicate notifications
|
||||
'tag' : [anUserNotification identifier]
|
||||
}
|
||||
);
|
||||
|
||||
anUserNotification._presented = YES;
|
||||
|
||||
notification.onclick = function () {
|
||||
anUserNotification._activationType = CPUserNotificationActivationTypeContentsClicked;
|
||||
[self _sendDelegateDidActivateNotification:anUserNotification];
|
||||
|
||||
// Remove the notification from Notification Center when clicked.
|
||||
this.close();
|
||||
};
|
||||
|
||||
// Callback function when the notification is closed.
|
||||
notification.onclose = function () {
|
||||
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
anUserNotification._presented = NO;
|
||||
}
|
||||
|
||||
anUserNotification._activationType = CPUserNotificationActivationTypeNone;
|
||||
anUserNotification._actualDeliveryDate = [CPDate date];
|
||||
[_deliveredNotifications addObject:anUserNotification];
|
||||
|
||||
if (![anUserNotification deliveryRepeatInterval])
|
||||
[self removeScheduledNotification:anUserNotification];
|
||||
|
||||
[self _sendDelegateDidDeliverNotification:anUserNotification];
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@implementation CPUserNotificationCenter (CPUserNotificationCenterDelegate)
|
||||
|
||||
- (BOOL)_delegateRespondsToShouldPresentNotification
|
||||
{
|
||||
return _implementedDelegateMethods & CPUserNotificationCenterDelegate_userNotificationCenter_shouldPresentNotification_;
|
||||
}
|
||||
|
||||
- (BOOL)_sendDelegateShouldPresentNotification:(CPUserNotification)aNotification
|
||||
{
|
||||
return [_delegate userNotificationCenter:self shouldPresentNotification:aNotification];
|
||||
}
|
||||
|
||||
- (void)_sendDelegateDidActivateNotification:(CPUserNotification)aNotification
|
||||
{
|
||||
if (!(_implementedDelegateMethods & CPUserNotificationCenterDelegate_userNotificationCenter_didActivateNotification_))
|
||||
return;
|
||||
|
||||
[_delegate userNotificationCenter:self didActivateNotification:aNotification];
|
||||
}
|
||||
|
||||
- (void)_sendDelegateDidDeliverNotification:(CPUserNotification)aNotification
|
||||
{
|
||||
if (!(_implementedDelegateMethods & CPUserNotificationCenterDelegate_userNotificationCenter_didDeliverNotification_))
|
||||
return;
|
||||
|
||||
[_delegate userNotificationCenter:self didDeliverNotification:aNotification];
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -78,6 +78,8 @@
|
||||
@import "CPURLRequest.j"
|
||||
@import "CPURLResponse.j"
|
||||
@import "CPUserDefaults.j"
|
||||
@import "CPUserNotification.j"
|
||||
@import "CPUserNotificationCenter.j"
|
||||
@import "CPUserSessionManager.j"
|
||||
@import "CPValue.j"
|
||||
@import "CPValueTransformer.j"
|
||||
|
||||
@@ -128,12 +128,21 @@ function generateDocs(/* boolean */ noFrame)
|
||||
// If the Doxygen application is installed on Mac OS X, use that
|
||||
if (!doxygen && executableExists("mdfind"))
|
||||
{
|
||||
var p = OS.popen(["mdfind", "kMDItemContentType == 'com.apple.application-bundle' && kMDItemCFBundleIdentifier == 'org.doxygen'"]);
|
||||
if (p.wait() === 0)
|
||||
try
|
||||
{
|
||||
var doxygenApps = p.stdout.read().split("\n");
|
||||
if (doxygenApps[0])
|
||||
doxygen = FILE.join(doxygenApps[0], "Contents/Resources/doxygen");
|
||||
var p = OS.popen(["mdfind", "kMDItemContentType == 'com.apple.application-bundle' && kMDItemCFBundleIdentifier == 'org.doxygen'"]);
|
||||
if (p.wait() === 0)
|
||||
{
|
||||
var doxygenApps = p.stdout.read().split("\n");
|
||||
if (doxygenApps[0])
|
||||
doxygen = FILE.join(doxygenApps[0], "Contents/Resources/doxygen");
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
p.stdin.close();
|
||||
p.stdout.close();
|
||||
p.stderr.close();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -112,7 +112,13 @@ GLOBAL(CFHTTPRequest) = function()
|
||||
determineAndDispatchHTTPRequestEvents(self);
|
||||
};
|
||||
|
||||
this._timeoutHandler = function()
|
||||
{
|
||||
dispatchTimeoutHTTPRequestEvents(self);
|
||||
};
|
||||
|
||||
this._nativeRequest.onreadystatechange = this._stateChangeHandler;
|
||||
this._nativeRequest.ontimeout = this._timeoutHandler;
|
||||
|
||||
if (CFHTTPRequest.AuthenticationDelegate !== nil)
|
||||
this._eventDispatcher.addEventListener("HTTP403", function()
|
||||
@@ -209,6 +215,16 @@ CFHTTPRequest.prototype.getResponseHeader = function(/*String*/ aHeader)
|
||||
return this._nativeRequest.getResponseHeader(aHeader);
|
||||
};
|
||||
|
||||
CFHTTPRequest.prototype.setTimeout = function(/*int*/ aTimeout)
|
||||
{
|
||||
this._nativeRequest.timeout = aTimeout;
|
||||
};
|
||||
|
||||
CFHTTPRequest.prototype.getTimeout = function(/*int*/ aTimeout)
|
||||
{
|
||||
return this._nativeRequest.timeout;
|
||||
};
|
||||
|
||||
CFHTTPRequest.prototype.getAllResponseHeaders = function()
|
||||
{
|
||||
return this._nativeRequest.getAllResponseHeaders();
|
||||
@@ -235,7 +251,10 @@ CFHTTPRequest.prototype.send = function(/*Object*/ aBody)
|
||||
if (!this._isOpen)
|
||||
{
|
||||
delete this._nativeRequest.onreadystatechange;
|
||||
delete this._nativeRequest.ontimeout;
|
||||
|
||||
this._nativeRequest.open(this._method, this._URL, this._async, this._user, this._password);
|
||||
this._nativeRequest.ontimeout = this._timeoutHandler;
|
||||
this._nativeRequest.onreadystatechange = this._stateChangeHandler;
|
||||
}
|
||||
|
||||
@@ -277,25 +296,35 @@ CFHTTPRequest.prototype.removeEventListener = function(/*String*/ anEventName, /
|
||||
this._eventDispatcher.removeEventListener(anEventName, anEventListener);
|
||||
};
|
||||
|
||||
CFHTTPRequest.prototype.setWithCredentials = function(/*Boolean*/ willSendWithCredentials)
|
||||
CFHTTPRequest.prototype.setWithCredentials = function(/*Boolean*/ willSendWithCredentials)
|
||||
{
|
||||
this._nativeRequest.withCredentials = willSendWithCredentials;
|
||||
};
|
||||
|
||||
CFHTTPRequest.prototype.withCredentials = function()
|
||||
CFHTTPRequest.prototype.withCredentials = function()
|
||||
{
|
||||
return this._nativeRequest.withCredentials;
|
||||
};
|
||||
|
||||
CFHTTPRequest.prototype.isTimeoutRequest = function()
|
||||
{
|
||||
// Can we consider that as a timeout ?
|
||||
return !this.success() && !this._nativeRequest.response && !this._nativeRequest.responseText && !this._nativeRequest.responseType && !this._nativeRequest.responseURL && !this._nativeRequest.responseXML;
|
||||
};
|
||||
|
||||
function dispatchTimeoutHTTPRequestEvents(/*CFHTTPRequest*/ aRequest)
|
||||
{
|
||||
aRequest._eventDispatcher.dispatchEvent({ type:"timeout", request:aRequest});
|
||||
}
|
||||
|
||||
function determineAndDispatchHTTPRequestEvents(/*CFHTTPRequest*/ aRequest)
|
||||
{
|
||||
var eventDispatcher = aRequest._eventDispatcher;
|
||||
var eventDispatcher = aRequest._eventDispatcher,
|
||||
nativeRequest = aRequest._nativeRequest,
|
||||
readyStates = ["uninitialized", "loading", "loaded", "interactive", "complete"];
|
||||
|
||||
eventDispatcher.dispatchEvent({ type:"readystatechange", request:aRequest});
|
||||
|
||||
var nativeRequest = aRequest._nativeRequest,
|
||||
readyStates = ["uninitialized", "loading", "loaded", "interactive", "complete"];
|
||||
|
||||
if (readyStates[aRequest.readyState()] === "complete")
|
||||
{
|
||||
var status = "HTTP" + aRequest.status();
|
||||
@@ -323,12 +352,21 @@ function FileRequest(/*CFURL*/ aURL, onsuccess, onfailure, onprogress)
|
||||
var aFilePath = aURL.toString().substring(5),
|
||||
OS = require("os"),
|
||||
gccFlags = require("objective-j").currentCompilerFlags(),
|
||||
gcc = OS.popen("gcc -E -x c -P " + (gccFlags ? gccFlags : "") + " " + OS.enquote(aFilePath), { charset:"UTF-8" }),
|
||||
chunk,
|
||||
fileContents = "";
|
||||
|
||||
while (chunk = gcc.stdout.read())
|
||||
fileContents += chunk;
|
||||
try
|
||||
{
|
||||
var gcc = OS.popen("gcc -E -x c -P " + (gccFlags ? gccFlags : "") + " " + OS.enquote(aFilePath), { charset:"UTF-8" });
|
||||
while (chunk = gcc.stdout.read())
|
||||
fileContents += chunk;
|
||||
}
|
||||
finally
|
||||
{
|
||||
gcc.stdin.close();
|
||||
gcc.stdout.close();
|
||||
gcc.stderr.close();
|
||||
}
|
||||
|
||||
if (fileContents.length > 0)
|
||||
{
|
||||
|
||||
@@ -94,6 +94,7 @@ exports.run = function(args)
|
||||
print(" -I, --objj-include-paths include a specific framework paths")
|
||||
print(" -h, --help print this help");
|
||||
print(" -m, --multifiles launch objj on several files")
|
||||
print(" -x, --xml specify the output format in xml.")
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -101,45 +102,57 @@ exports.run = function(args)
|
||||
{
|
||||
switch (argv[0])
|
||||
{
|
||||
case "--objj-include-paths":
|
||||
case "-I":
|
||||
argv.shift();
|
||||
OBJJ_INCLUDE_PATHS.unshift.apply(OBJJ_INCLUDE_PATHS, argv.shift().split(":"));
|
||||
break;
|
||||
|
||||
case "--multifiles":
|
||||
case "-m":
|
||||
argv.shift();
|
||||
multipleFiles = true;
|
||||
break
|
||||
|
||||
case "-x":
|
||||
case "--xml":
|
||||
argv.shift();
|
||||
exports.outputFormatInXML = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (argv && argv.length > 0)
|
||||
{
|
||||
var endCommand = false;
|
||||
var endCommand = false,
|
||||
errors = [];
|
||||
|
||||
while (argv.length > 0)
|
||||
{
|
||||
var arg0 = argv.shift();
|
||||
var mainFilePath = FILE.canonical(arg0);
|
||||
var arg0 = argv.shift(),
|
||||
mainFilePath = FILE.canonical(arg0);
|
||||
|
||||
if (multipleFiles)
|
||||
{
|
||||
// This is needed to process every files passed in args
|
||||
// Otherwise it would stop when an error is raised or we would like to objj the other given files
|
||||
try
|
||||
{
|
||||
exports.make_narwhal_factory(mainFilePath)(require, { }, module, system, print);
|
||||
}
|
||||
catch(e)
|
||||
{
|
||||
print("\n" + e);
|
||||
}
|
||||
}
|
||||
else
|
||||
try
|
||||
{
|
||||
exports.make_narwhal_factory(mainFilePath)(require, { }, module, system, print);
|
||||
}
|
||||
catch(e)
|
||||
{
|
||||
if (exports.outputFormatInXML)
|
||||
{
|
||||
var dict = new CFMutableDictionary();
|
||||
dict.addValueForKey('line', e.line ? e.line : 0);
|
||||
dict.addValueForKey('sourcePath', e.path ? e.path : mainFilePath);
|
||||
dict.addValueForKey('message', e.message);
|
||||
|
||||
errors.push(dict);
|
||||
}
|
||||
else
|
||||
{
|
||||
errors.push("\n" + e);
|
||||
}
|
||||
}
|
||||
|
||||
if (typeof main === "function")
|
||||
{
|
||||
@@ -157,6 +170,14 @@ exports.run = function(args)
|
||||
ObjectiveJ.FileExecutable.resetFileExecutables();
|
||||
objj_resetRegisterClasses();
|
||||
}
|
||||
|
||||
if (errors.length)
|
||||
{
|
||||
if (exports.outputFormatInXML)
|
||||
throw CFPropertyListCreateXMLData(errors, kCFPropertyListXMLFormat_v1_0).rawString();
|
||||
else
|
||||
throw errors;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -229,6 +250,7 @@ function getPackage() {
|
||||
exports.version = function() { return getPackage()["version"]; }
|
||||
exports.revision = function() { return getPackage()["cappuccino-revision"]; }
|
||||
exports.timestamp = function() { return new Date(getPackage()["cappuccino-timestamp"]); }
|
||||
exports.outputFormatInXML = false;
|
||||
|
||||
exports.fullVersionString = function() {
|
||||
return sprintf("objective-j %s (%04d-%02d-%02d %s)",
|
||||
|
||||
@@ -46,18 +46,39 @@ function compileWithResolvedFlags(aFilePath, objjcFlags, gccFlags, asPlainJavasc
|
||||
|
||||
if (!shouldObjjPreprocess)
|
||||
{
|
||||
if (OS.popen("which gcc").stdout.read().length === 0)
|
||||
fileContents = FILE.read(aFilePath, { charset:"UTF-8" });
|
||||
else
|
||||
try
|
||||
{
|
||||
// GCC preprocess the file.
|
||||
var gcc = OS.popen("gcc -E -x c -P " + (gccFlags ? gccFlags.join(" ") : "") + " " + OS.enquote(aFilePath), { charset:"UTF-8" }),
|
||||
chunk = "";
|
||||
var p = OS.popen("which gcc");
|
||||
|
||||
while (chunk = gcc.stdout.read())
|
||||
fileContents += chunk;
|
||||
if (p.stdout.read().length === 0)
|
||||
{
|
||||
fileContents = FILE.read(aFilePath, { charset:"UTF-8" });
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
var gcc = OS.popen("gcc -E -x c -P " + (gccFlags ? gccFlags.join(" ") : "") + " " + OS.enquote(aFilePath), { charset:"UTF-8" }),
|
||||
chunk = "";
|
||||
|
||||
while (chunk = gcc.stdout.read())
|
||||
fileContents += chunk;
|
||||
}
|
||||
finally
|
||||
{
|
||||
gcc.stdin.close();
|
||||
gcc.stdout.close();
|
||||
gcc.stderr.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
p.stdin.close();
|
||||
p.stdout.close();
|
||||
p.stderr.close();
|
||||
}
|
||||
|
||||
return fileContents;
|
||||
}
|
||||
|
||||
|
||||
@@ -22,7 +22,6 @@
|
||||
|
||||
var FILE = require("file");
|
||||
|
||||
|
||||
var BUNDLE_TASK = require("objective-j/jake/bundletask");
|
||||
|
||||
exports.BundleTask = BUNDLE_TASK.BundleTask;
|
||||
|
||||
+15
-6
@@ -40,8 +40,8 @@ $BROWSER_FILES = new FileList($BROWSER_FILE).include($OBJECTIVEJ_FILES);
|
||||
|
||||
filedir($BUILD_BROWSER_FILE, $BROWSER_FILES, function(aTask)
|
||||
{
|
||||
gcc($BROWSER_FILE,
|
||||
$BUILD_BROWSER_FILE,
|
||||
gcc($BROWSER_FILE,
|
||||
$BUILD_BROWSER_FILE,
|
||||
environmentFlags("Browser", "ObjJ").concat($INCLUDE_FLAGS, $DEBUG_FLAGS), $CONFIGURATION !== "Debug");
|
||||
});
|
||||
|
||||
@@ -119,11 +119,20 @@ function gcc(inputFilePath, outputFilePath, flags, compress)
|
||||
stream.print("Building... \0green(" + outputFilePath +"\0)");
|
||||
|
||||
// GCC preprocess the file.
|
||||
var cmd = ["gcc", "-E", "-x", "c", "-P"].concat(flags, inputFilePath).join(" ");
|
||||
var gcc = OS.popen(cmd, { charset:"UTF-8" });
|
||||
var cmd = ["gcc", "-E", "-x", "c", "-P"].concat(flags, inputFilePath).join(" "),
|
||||
contents = FILE.read("header.txt", { charset : "UTF-8" });
|
||||
|
||||
var contents = FILE.read("header.txt", { charset : "UTF-8" });
|
||||
contents += gcc.stdout.read();
|
||||
try
|
||||
{
|
||||
var gcc = OS.popen(cmd, { charset:"UTF-8" });
|
||||
contents += gcc.stdout.read();
|
||||
}
|
||||
finally
|
||||
{
|
||||
gcc.stdin.close();
|
||||
gcc.stdout.close();
|
||||
gcc.stderr.close();
|
||||
}
|
||||
|
||||
if (FILE.extension(inputFilePath) === ".js" && compress)
|
||||
contents = compressor(contents);
|
||||
|
||||
@@ -394,9 +394,22 @@ var ObjJAcornCompiler = function(/*String*/ aString, /*CFURL*/ aURL, /*unsigned*
|
||||
#ifdef BROWSER
|
||||
console.log(message);
|
||||
#else
|
||||
print(message);
|
||||
if (exports.outputFormatInXML)
|
||||
{
|
||||
var dict = new CFMutableDictionary();
|
||||
dict.addValueForKey('line', e.line);
|
||||
dict.addValueForKey('sourcePath', this.URL.path());
|
||||
dict.addValueForKey('message', message);
|
||||
|
||||
print(CFPropertyListCreateXMLData([dict], kCFPropertyListXMLFormat_v1_0).rawString());
|
||||
}
|
||||
else
|
||||
{
|
||||
print(message);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
throw e;
|
||||
}
|
||||
|
||||
@@ -434,6 +447,8 @@ exports.ObjJAcornCompiler.compileFileDependencies = function(/*String*/ aString,
|
||||
|
||||
ObjJAcornCompiler.prototype.compilePass2 = function()
|
||||
{
|
||||
var warnings = [];
|
||||
|
||||
ObjJAcornCompiler.currentCompileFile = this.URL;
|
||||
this.pass = 2;
|
||||
this.jsBuffer = new StringBuffer();
|
||||
@@ -442,14 +457,32 @@ ObjJAcornCompiler.prototype.compilePass2 = function()
|
||||
compile(this.tokens, new Scope(null ,{ compiler: this }), pass2);
|
||||
for (var i = 0; i < this.warnings.length; i++)
|
||||
{
|
||||
var message = this.prettifyMessage(this.warnings[i], "WARNING");
|
||||
var warning = this.warnings[i],
|
||||
type = "WARNING";
|
||||
|
||||
var message = this.prettifyMessage(warning, type);
|
||||
#ifdef BROWSER
|
||||
console.log(message);
|
||||
#else
|
||||
print(message);
|
||||
if (exports.outputFormatInXML)
|
||||
{
|
||||
var dict = new CFMutableDictionary();
|
||||
dict.addValueForKey('line', warning.line)
|
||||
dict.addValueForKey('sourcePath', this.URL.path())
|
||||
dict.addValueForKey('message', message)
|
||||
|
||||
warnings.push(dict);
|
||||
}
|
||||
else
|
||||
{
|
||||
print(message);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (warnings.length && exports.outputFormatInXML)
|
||||
print(CFPropertyListCreateXMLData(warnings, kCFPropertyListXMLFormat_v1_0).rawString());
|
||||
|
||||
//print(this.URL + ": " + this.jsBuffer.toString());
|
||||
return this.jsBuffer.toString();
|
||||
}
|
||||
@@ -660,9 +693,13 @@ ObjJAcornCompiler.prototype.prettifyMessage = function(/* Message */ aMessage, /
|
||||
ObjJAcornCompiler.prototype.error_message = function(errorMessage, node)
|
||||
{
|
||||
var pos = exports.acorn.getLineInfo(this.source, node.start),
|
||||
syntaxError = {message: errorMessage, line: pos.line, column: pos.column, lineStart: pos.lineStart, lineEnd: pos.lineEnd};
|
||||
syntaxErrorData = {message: errorMessage, line: pos.line, column: pos.column, lineStart: pos.lineStart, lineEnd: pos.lineEnd},
|
||||
syntaxError = new SyntaxError(this.prettifyMessage(syntaxErrorData, "ERROR"));
|
||||
|
||||
return new SyntaxError(this.prettifyMessage(syntaxError, "ERROR"));
|
||||
syntaxError.line = pos.line;
|
||||
syntaxError.path = this.URL.path();
|
||||
|
||||
return syntaxError;
|
||||
}
|
||||
|
||||
ObjJAcornCompiler.prototype.pushImport = function(url)
|
||||
|
||||
+3
-1
@@ -1,3 +1,5 @@
|
||||
[](https://travis-ci.org/cappuccino/cappuccino)
|
||||
|
||||
Welcome to Cappuccino!
|
||||
======================
|
||||
|
||||
@@ -71,7 +73,7 @@ If you need help with Cappuccino, you can get help from the following sources:
|
||||
- Mailing Lists:
|
||||
- [Objective-J](http://groups.google.com/group/objectivej)
|
||||
- [Objective-J Developers](http://groups.google.com/group/objectivej-dev)
|
||||
- IRC: irc://irc.freenode.net#cappuccino
|
||||
- [Gitter] (https://gitter.im/cappuccino/cappuccino)
|
||||
|
||||
If you discover any bugs, please file a ticket at:
|
||||
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
@import <AppKit/CPApplication.j>
|
||||
@import <AppKit/CPAnimation.j>
|
||||
|
||||
[CPApplication sharedApplication];
|
||||
|
||||
@implementation CPAnimation (TestMethods)
|
||||
{
|
||||
}
|
||||
@@ -18,11 +16,17 @@
|
||||
{
|
||||
}
|
||||
|
||||
- (void)setUp
|
||||
{
|
||||
// This will init the global var CPApp which are used internally in the AppKit
|
||||
[[CPApplication alloc] init];
|
||||
}
|
||||
|
||||
- (void)testScheduleTimerWithIntervalBasedOnDefaultFrameRate
|
||||
{
|
||||
var animation = [[CPAnimation alloc] initWithDuration:0.1 animationCurve:CPAnimationLinear];
|
||||
[animation startAnimation];
|
||||
|
||||
|
||||
[self assert:1.0/60.0 equals:[[animation timer] timeInterval]];
|
||||
}
|
||||
|
||||
@@ -31,7 +35,7 @@
|
||||
var animation = [[CPAnimation alloc] initWithDuration:0.1 animationCurve:CPAnimationLinear];
|
||||
[animation setFrameRate:30];
|
||||
[animation startAnimation];
|
||||
|
||||
|
||||
[self assert:1.0/30.0 equals:[[animation timer] timeInterval]];
|
||||
}
|
||||
|
||||
@@ -40,7 +44,7 @@
|
||||
var animation = [[CPAnimation alloc] initWithDuration:0.1 animationCurve:CPAnimationLinear];
|
||||
[animation setFrameRate:0];
|
||||
[animation startAnimation];
|
||||
|
||||
|
||||
[self assert:0.0001 equals:[[animation timer] timeInterval]];
|
||||
}
|
||||
|
||||
|
||||
@@ -65,7 +65,7 @@ var globalResults = [];
|
||||
{
|
||||
// This sets up the CPApp convenience variable, the unit tests fails
|
||||
// if this is not done, because the framework internally uses CPApp.
|
||||
app = [CPApplication sharedApplication];
|
||||
app = [[CPApplication alloc] init];
|
||||
|
||||
// fake the window.location.hash
|
||||
window.location = {hash: "#var1=1/var2=2"};
|
||||
|
||||
@@ -6,6 +6,15 @@ var ELEMENTS = 200,
|
||||
REPEATS = 25;
|
||||
|
||||
@implementation CPArrayControllerPerformance : OJTestCase
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
- (void)setUp
|
||||
{
|
||||
// This will init the global var CPApp which are used internally in the AppKit
|
||||
[[CPApplication alloc] init];
|
||||
}
|
||||
|
||||
- (CPArrayController)setupWithElements:(int)aCount
|
||||
{
|
||||
|
||||
@@ -56,6 +56,9 @@
|
||||
|
||||
- (void)setUp
|
||||
{
|
||||
// This will init the global var CPApp which are used internally in the AppKit
|
||||
[[CPApplication alloc] init];
|
||||
|
||||
_contentArray = [self makeTestArray];
|
||||
[self initControllerWithSimpleArray]
|
||||
}
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
@import <Foundation/Foundation.j>
|
||||
@import <AppKit/AppKit.j>
|
||||
|
||||
[CPApplication sharedApplication];
|
||||
|
||||
|
||||
@implementation CPAutosizePerformance : OJTestCase
|
||||
{
|
||||
CPInteger NUMBER_OF_VIEWS;
|
||||
@@ -12,6 +9,9 @@
|
||||
|
||||
- (void)setUp
|
||||
{
|
||||
// This will init the global var CPApp which are used internally in the AppKit
|
||||
[[CPApplication alloc] init];
|
||||
|
||||
NUMBER_OF_VIEWS = 50;
|
||||
RESIZES_COUNT = 250;
|
||||
}
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
@class CPBrowserDelegate
|
||||
|
||||
|
||||
@implementation CPBrowserTest : OJTestCase
|
||||
{
|
||||
CPBrowser browser;
|
||||
@@ -11,6 +10,9 @@
|
||||
|
||||
- (void)setUp
|
||||
{
|
||||
// This will init the global var CPApp which are used internally in the AppKit
|
||||
[[CPApplication alloc] init];
|
||||
|
||||
browser = [[CPBrowser alloc] initWithFrame:CGRectMake(0, 0, 500, 300)];
|
||||
delegate = [CPBrowserDelegate new];
|
||||
[delegate setEntries:[".1", ".1.1", ".1.2", ".1.2.1", ".1.2.2", ".2", ".3", ".3.1"]];
|
||||
|
||||
@@ -1,10 +1,7 @@
|
||||
|
||||
@import <AppKit/CPButton.j>
|
||||
@import <AppKit/CPApplication.j>
|
||||
@import <AppKit/CPText.j>
|
||||
|
||||
[CPApplication sharedApplication];
|
||||
|
||||
@implementation CPButtonTest : OJTestCase
|
||||
{
|
||||
CPButton button;
|
||||
@@ -13,6 +10,9 @@
|
||||
|
||||
- (void)setUp
|
||||
{
|
||||
// This will init the global var CPApp which are used internally in the AppKit
|
||||
[[CPApplication alloc] init];
|
||||
|
||||
button = [CPButton buttonWithTitle:"hello world"];
|
||||
wasClicked = NO;
|
||||
}
|
||||
|
||||
@@ -1,11 +1,15 @@
|
||||
@import <AppKit/CPCheckBox.j>
|
||||
|
||||
[CPApplication sharedApplication]
|
||||
|
||||
@implementation CPCheckBoxTest : OJTestCase
|
||||
{
|
||||
}
|
||||
|
||||
- (void)setUp
|
||||
{
|
||||
// This will init the global var CPApp which are used internally in the AppKit
|
||||
[[CPApplication alloc] init];
|
||||
}
|
||||
|
||||
/*!
|
||||
Verify that CPCheckBox placeholders work, both explicit and default ones.
|
||||
*/
|
||||
|
||||
@@ -9,6 +9,9 @@
|
||||
|
||||
- (void)setUp
|
||||
{
|
||||
// This will init the global var CPApp which are used internally in the AppKit
|
||||
[[CPApplication alloc] init];
|
||||
|
||||
_collectionView = [[CPCollectionView alloc] initWithFrame:CGRectMakeZero()];
|
||||
_globalResults = nil;
|
||||
}
|
||||
|
||||
@@ -4,6 +4,12 @@
|
||||
{
|
||||
}
|
||||
|
||||
- (void)setUp
|
||||
{
|
||||
// This will init the global var CPApp which are used internally in the AppKit
|
||||
[[CPApplication alloc] init];
|
||||
}
|
||||
|
||||
- (void)testHexStringConversion
|
||||
{
|
||||
var colors = ['000000', '0099CC', '7E8EAB', 'FFFFFF'];
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
@import <AppKit/CPColorWell.j>
|
||||
@import <AppKit/CPApplication.j>
|
||||
|
||||
[CPApplication sharedApplication];
|
||||
|
||||
@implementation CPColorWellTest : OJTestCase
|
||||
{
|
||||
CPColorWell colorWell;
|
||||
@@ -10,6 +8,9 @@
|
||||
|
||||
- (void)setUp
|
||||
{
|
||||
// This will init the global var CPApp which are used internally in the AppKit
|
||||
[[CPApplication alloc] init];
|
||||
|
||||
colorWell = [[CPColorWell alloc] initWithFrame:CGRectMakeZero()];
|
||||
}
|
||||
|
||||
|
||||
@@ -4,8 +4,6 @@
|
||||
|
||||
@import "CPNotificationCenterHelper.j"
|
||||
|
||||
[CPApplication sharedApplication];
|
||||
|
||||
@implementation CPComboBoxTest : OJTestCase
|
||||
{
|
||||
CPComboBox comboBox;
|
||||
@@ -14,6 +12,9 @@
|
||||
|
||||
- (void)setUp
|
||||
{
|
||||
// This will init the global var CPApp which are used internally in the AppKit
|
||||
[[CPApplication alloc] init];
|
||||
|
||||
comboBox = [[CPComboBox alloc] initWithFrame:CGRectMake(0, 0, 200, 30)];
|
||||
}
|
||||
|
||||
|
||||
@@ -10,6 +10,9 @@
|
||||
|
||||
- (void)setUp
|
||||
{
|
||||
// This will init the global var CPApp which are used internally in the AppKit
|
||||
[[CPApplication alloc] init];
|
||||
|
||||
// set up a dummy DOM element.
|
||||
DOMElement = {
|
||||
style: {
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
@import <OJUnit/OJTestCase.j>
|
||||
|
||||
@import <AppKit/CPDatePicker.j>
|
||||
@import <AppKit/CPApplication.j>
|
||||
@import <Foundation/Foundation.j>
|
||||
|
||||
|
||||
@implementation CPDatePickerTest : OJTestCase
|
||||
{
|
||||
CPDatePicker datePicker;
|
||||
}
|
||||
|
||||
- (void)setUp
|
||||
{
|
||||
// This will init the global var CPApp which are used internally in the AppKit
|
||||
[[CPApplication alloc] init];
|
||||
|
||||
datePicker = [[CPDatePicker alloc] initWithFrame:CGRectMake(200, 28, 0, 0)];
|
||||
}
|
||||
|
||||
- (void)testCanCreate
|
||||
{
|
||||
[self assertTrue:!!datePicker];
|
||||
}
|
||||
|
||||
- (void)testLayoutSubviews
|
||||
{
|
||||
[[CPRunLoop currentRunLoop] limitDateForMode:CPDefaultRunLoopMode];
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -7,8 +7,8 @@
|
||||
|
||||
- (void)setUp
|
||||
{
|
||||
// CPApplication must be initialised for some event handling to work.
|
||||
[CPApplication sharedApplication];
|
||||
// This will init the global var CPApp which are used internally in the AppKit
|
||||
[[CPApplication alloc] init];
|
||||
}
|
||||
|
||||
/*!
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
@import <AppKit/AppKit.j>
|
||||
|
||||
[CPApplication sharedApplication];
|
||||
|
||||
@implementation CPFontManagerTest : OJTestCase
|
||||
{
|
||||
CPFont fontA;
|
||||
@@ -14,6 +12,9 @@
|
||||
|
||||
- (void)setUp
|
||||
{
|
||||
// This will init the global var CPApp which are used internally in the AppKit
|
||||
[[CPApplication alloc] init];
|
||||
|
||||
fontA = [CPFont systemFontOfSize:8.0];
|
||||
}
|
||||
|
||||
|
||||
@@ -11,6 +11,9 @@
|
||||
|
||||
- (void)setUp
|
||||
{
|
||||
// This will init the global var CPApp which are used internally in the AppKit
|
||||
[[CPApplication alloc] init];
|
||||
|
||||
_systemFont = [CPFont systemFontOfSize:15];
|
||||
_boldSystemFont = [CPFont boldSystemFontOfSize:15];
|
||||
|
||||
|
||||
@@ -4,6 +4,12 @@
|
||||
{
|
||||
}
|
||||
|
||||
- (void)setUp
|
||||
{
|
||||
// This will init the global var CPApp which are used internally in the AppKit
|
||||
[[CPApplication alloc] init];
|
||||
}
|
||||
|
||||
- (void)testInitWithContentsOfFile_nil
|
||||
{
|
||||
var image = [[CPImage alloc] initWithContentsOfFile:nil];
|
||||
|
||||
@@ -3,9 +3,16 @@
|
||||
@import <AppKit/CPEvent.j>
|
||||
@import <AppKit/CPButton.j>
|
||||
|
||||
[CPApplication sharedApplication];
|
||||
|
||||
@implementation CPKeyEquivalentPerformance : OJTestCase
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
- (void)setUp
|
||||
{
|
||||
// This will init the global var CPApp which are used internally in the AppKit
|
||||
[[CPApplication alloc] init];
|
||||
}
|
||||
|
||||
- (void)testKeyEquivalentSpeed
|
||||
{
|
||||
|
||||
@@ -20,8 +20,8 @@
|
||||
|
||||
- (void)setUp
|
||||
{
|
||||
// CPApp must be initialised or action sending will not work.
|
||||
[CPApplication sharedApplication];
|
||||
// This will init the global var CPApp which are used internally in the AppKit
|
||||
[[CPApplication alloc] init];
|
||||
|
||||
track = [Track new];
|
||||
[track setVolume:5.0];
|
||||
|
||||
@@ -21,6 +21,12 @@
|
||||
CPArrayController arrayController @accessors;
|
||||
}
|
||||
|
||||
- (void)setUp
|
||||
{
|
||||
// This will init the global var CPApp which are used internally in the AppKit
|
||||
[[CPApplication alloc] init];
|
||||
}
|
||||
|
||||
- (void)testExposingBindings
|
||||
{
|
||||
[BindingTester exposeBinding:@"foo"];
|
||||
|
||||
@@ -7,6 +7,12 @@
|
||||
{
|
||||
}
|
||||
|
||||
- (void)setUp
|
||||
{
|
||||
// This will init the global var CPApp which are used internally in the AppKit
|
||||
[[CPApplication alloc] init];
|
||||
}
|
||||
|
||||
+ (CPLevelIndicator)indicatorWithLowWarning
|
||||
{
|
||||
var levelIndicator = [[CPLevelIndicator alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];
|
||||
@@ -44,7 +50,7 @@
|
||||
|
||||
[levelIndicator setObjectValue:4];
|
||||
[[CPRunLoop currentRunLoop] limitDateForMode:CPDefaultRunLoopMode];
|
||||
|
||||
|
||||
[self assert:[CPColor yellowColor] equals:[GET_LEVEL_INDICATOR_SEGMENT(levelIndicator, 0) backgroundColor]];
|
||||
}
|
||||
|
||||
@@ -54,7 +60,7 @@
|
||||
|
||||
[levelIndicator setObjectValue:2];
|
||||
[[CPRunLoop currentRunLoop] limitDateForMode:CPDefaultRunLoopMode];
|
||||
|
||||
|
||||
[self assert:[CPColor redColor] equals:[GET_LEVEL_INDICATOR_SEGMENT(levelIndicator, 0) backgroundColor]];
|
||||
}
|
||||
|
||||
@@ -74,7 +80,7 @@
|
||||
|
||||
[levelIndicator setObjectValue:6];
|
||||
[[CPRunLoop currentRunLoop] limitDateForMode:CPDefaultRunLoopMode];
|
||||
|
||||
|
||||
[self assert:[CPColor yellowColor] equals:[GET_LEVEL_INDICATOR_SEGMENT(levelIndicator, 0) backgroundColor]];
|
||||
}
|
||||
|
||||
@@ -84,7 +90,7 @@
|
||||
|
||||
[levelIndicator setObjectValue:8];
|
||||
[[CPRunLoop currentRunLoop] limitDateForMode:CPDefaultRunLoopMode];
|
||||
|
||||
|
||||
[self assert:[CPColor redColor] equals:[GET_LEVEL_INDICATOR_SEGMENT(levelIndicator, 0) backgroundColor]];
|
||||
}
|
||||
@end
|
||||
@@ -1,10 +1,8 @@
|
||||
|
||||
@import <AppKit/CPMenu.j>
|
||||
@import <AppKit/CPMenuItem.j>
|
||||
@import <AppKit/CPApplication.j>
|
||||
@import <AppKit/CPText.j>
|
||||
|
||||
[CPApplication sharedApplication]
|
||||
|
||||
@implementation CPMenuTest : OJTestCase
|
||||
{
|
||||
@@ -21,6 +19,9 @@
|
||||
|
||||
- (void)setUp
|
||||
{
|
||||
// This will init the global var CPApp which are used internally in the AppKit
|
||||
[[CPApplication alloc] init];
|
||||
|
||||
// Set up a fairly complete menu to have something to work with.
|
||||
menu = [[CPMenu alloc] initWithTitle:@"MainMenu"];
|
||||
|
||||
|
||||
@@ -11,6 +11,9 @@ var CPMenuValidatedUserInterfaceItemTestValidatedItems = [];
|
||||
|
||||
- (void)setUp
|
||||
{
|
||||
// This will init the global var CPApp which are used internally in the AppKit
|
||||
[[CPApplication alloc] init];
|
||||
|
||||
_menuTarget = [[MenuTarget alloc] init];
|
||||
[[CPApplication sharedApplication] setDelegate:_menuTarget];
|
||||
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
@class TestOutlineDataSource
|
||||
|
||||
|
||||
@implementation CPOutlineViewTest : OJTestCase
|
||||
{
|
||||
CPOutlineView outlineView;
|
||||
@@ -12,6 +11,9 @@
|
||||
|
||||
- (void)setUp
|
||||
{
|
||||
// This will init the global var CPApp which are used internally in the AppKit
|
||||
[[CPApplication alloc] init];
|
||||
|
||||
outlineView = [[CPOutlineView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];
|
||||
|
||||
tableColumn = [[CPTableColumn alloc] initWithIdentifier:@"Foo"];
|
||||
|
||||
@@ -6,6 +6,12 @@
|
||||
{
|
||||
}
|
||||
|
||||
- (void)setUp
|
||||
{
|
||||
// This will init the global var CPApp which are used internally in the AppKit
|
||||
[[CPApplication alloc] init];
|
||||
}
|
||||
|
||||
- (void)testSetString_forType_
|
||||
{
|
||||
var pboard = [CPPasteboard generalPasteboard];
|
||||
|
||||
@@ -11,6 +11,9 @@
|
||||
|
||||
- (void)setUp
|
||||
{
|
||||
// This will init the global var CPApp which are used internally in the AppKit
|
||||
[[CPApplication alloc] init];
|
||||
|
||||
button = [CPPopUpButton new];
|
||||
}
|
||||
|
||||
|
||||
@@ -8,6 +8,9 @@
|
||||
|
||||
- (void)setUp
|
||||
{
|
||||
// This will init the global var CPApp which are used internally in the AppKit
|
||||
[[CPApplication alloc] init];
|
||||
|
||||
_editor = [[CPPredicateEditor alloc] initWithFrame:CGRectMakeZero()];
|
||||
}
|
||||
|
||||
|
||||
@@ -4,8 +4,6 @@
|
||||
|
||||
@import <AppKit/CPPlatformWindow+DOMKeys.j>
|
||||
|
||||
[CPApplication sharedApplication]
|
||||
|
||||
@implementation CPResponderTest : OJTestCase
|
||||
{
|
||||
CPWindow theWindow;
|
||||
@@ -14,6 +12,9 @@
|
||||
|
||||
- (void)setUp
|
||||
{
|
||||
// This will init the global var CPApp which are used internally in the AppKit
|
||||
[[CPApplication alloc] init];
|
||||
|
||||
responder = [TestResponder new];
|
||||
responder.doCommandCalls = [];
|
||||
}
|
||||
|
||||
@@ -2,12 +2,17 @@
|
||||
|
||||
@import "CPNotificationCenterHelper.j"
|
||||
|
||||
[CPApplication sharedApplication];
|
||||
|
||||
@implementation CPScrollViewTest : OJTestCase
|
||||
{
|
||||
}
|
||||
|
||||
- (void)setUp
|
||||
{
|
||||
// This will init the global var CPApp which are used internally in the AppKit
|
||||
[[CPApplication alloc] init];
|
||||
}
|
||||
|
||||
/*!
|
||||
Test that scroll views don't generate bad layouts when very small.
|
||||
*/
|
||||
@@ -334,11 +339,49 @@
|
||||
[self assert:[CPNotificationCenterHelper registeredNotificationsForObserver:scrollView] equals:[] message:@"Notications registered for the scrollView in the notification center are wrong"];
|
||||
}
|
||||
|
||||
- (void)testDocumentVisibleRect
|
||||
{
|
||||
var theWindow = [[CPWindow alloc] initWithContentRect:CGRectMake(0.0, 0.0, 1024.0, 768.0)
|
||||
styleMask:CPWindowNotSizable],
|
||||
windowView = [theWindow contentView],
|
||||
aScrollView = [[CPScrollView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)],
|
||||
aDocumentView = [[CPView alloc] initWithFrame:CGRectMake(0, 0, 200, 200)];
|
||||
|
||||
[CPScrollView setGlobalScrollerStyle:CPScrollerStyleOverlay];
|
||||
|
||||
[aScrollView setDocumentView:aDocumentView];
|
||||
[windowView addSubview:aScrollView];
|
||||
|
||||
[self assertRect:CGRectMake(0, 0, 100, 100) equals:[aScrollView documentVisibleRect] message:@"documentVisibleRect is wrong in CPScrollView"];
|
||||
|
||||
[aDocumentView setScaleSize:CGSizeMake(0.5, 0.5)];
|
||||
[self assertRect:CGRectMake(0, 0, 200, 200) equals:[aScrollView documentVisibleRect] message:@"documentVisibleRect is wrong in CPScrollView after scaling"];
|
||||
|
||||
[aDocumentView setScaleSize:CGSizeMake(1, 1)];
|
||||
[aDocumentView scrollRectToVisible:CGRectMake(120, 120, 20, 20)];
|
||||
[self assertRect:CGRectMake(40, 40, 100, 100) equals:[aScrollView documentVisibleRect] message:@"documentVisibleRect is wrong in CPScrollView"];
|
||||
|
||||
[aDocumentView setScaleSize:CGSizeMake(0.5, 0.5)];
|
||||
[self assertRect:CGRectMake(80, 80, 200, 200) equals:[aScrollView documentVisibleRect] message:@"documentVisibleRect is wrong in CPScrollView"];
|
||||
}
|
||||
|
||||
- (void)assertPoint:(CGPoint)expected equals:(CGPoint)actual message:(CPString)message
|
||||
{
|
||||
[self assert:expected.x equals:actual.x message:@"X: " + message];
|
||||
[self assert:expected.y equals:actual.y message:@"Y: " + message];
|
||||
}
|
||||
|
||||
- (void)assertSize:(CGSize)expected equals:(CGSize)actual message:(CPString)message
|
||||
{
|
||||
[self assert:expected.width equals:actual.width message:@"Width: " + message];
|
||||
[self assert:expected.height equals:actual.height message:@"Height: " + message];
|
||||
}
|
||||
|
||||
- (void)assertRect:(CGRect)expected equals:(CGRect)actual message:(CPString)message
|
||||
{
|
||||
[self assertPoint:expected.origin equals:actual.origin message:message]
|
||||
[self assertSize:expected.size equals:actual.size message:message]
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -7,6 +7,9 @@
|
||||
|
||||
- (void)setUp
|
||||
{
|
||||
// This will init the global var CPApp which are used internally in the AppKit
|
||||
[[CPApplication alloc] init];
|
||||
|
||||
_searchField = [[CPSearchField alloc] initWithFrame:CGRectMakeZero()];
|
||||
}
|
||||
|
||||
|
||||
@@ -8,6 +8,9 @@
|
||||
|
||||
- (void)setUp
|
||||
{
|
||||
// This will init the global var CPApp which are used internally in the AppKit
|
||||
[[CPApplication alloc] init];
|
||||
|
||||
_segmentedControl = [[CPSegmentedControl alloc] initWithFrame:CGRectMakeZero()];
|
||||
[_segmentedControl setSegmentCount:3];
|
||||
}
|
||||
|
||||
@@ -4,6 +4,12 @@
|
||||
{
|
||||
}
|
||||
|
||||
- (void)setUp
|
||||
{
|
||||
// This will init the global var CPApp which are used internally in the AppKit
|
||||
[[CPApplication alloc] init];
|
||||
}
|
||||
|
||||
- (void)testIsContinuous
|
||||
{
|
||||
// While normally testing simple instance variables is a waste of time,
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
|
||||
@import <AppKit/CPApplication.j>
|
||||
@import <AppKit/CPSplitView.j>
|
||||
|
||||
[CPApplication sharedApplication];
|
||||
|
||||
@implementation CPSplitViewTest : OJTestCase
|
||||
{
|
||||
CPSplitView splitView;
|
||||
@@ -13,6 +10,9 @@
|
||||
|
||||
- (void)setUp
|
||||
{
|
||||
// This will init the global var CPApp which are used internally in the AppKit
|
||||
[[CPApplication alloc] init];
|
||||
|
||||
splitView = [[CPSplitView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];
|
||||
viewA = [[CPView alloc] initWithFrame:CGRectMake(0, 0, 100, 50)];
|
||||
viewB = [[CPView alloc] initWithFrame:CGRectMake(0, 0, 100, 50)];
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
@import <AppKit/CPStepper.j>
|
||||
@import <AppKit/CPApplication.j>
|
||||
|
||||
[CPApplication sharedApplication]
|
||||
|
||||
@implementation CPStepperTest : OJTestCase
|
||||
{
|
||||
CPStepper stepper;
|
||||
@@ -10,6 +8,9 @@
|
||||
|
||||
- (void)setUp
|
||||
{
|
||||
// This will init the global var CPApp which are used internally in the AppKit
|
||||
[[CPApplication alloc] init];
|
||||
|
||||
stepper = [CPStepper stepper];
|
||||
[stepper setValueWraps:NO];
|
||||
}
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
@import <Foundation/Foundation.j>
|
||||
@import <AppKit/AppKit.j>
|
||||
|
||||
|
||||
|
||||
@implementation CPTabView (TEST)
|
||||
|
||||
- (CPSegmentedControl)tabs
|
||||
@@ -27,6 +25,9 @@
|
||||
|
||||
- (void)setUp
|
||||
{
|
||||
// This will init the global var CPApp which are used internally in the AppKit
|
||||
[[CPApplication alloc] init];
|
||||
|
||||
_tabView = [[CPTabView alloc] initWithFrame:CGRectMake(0, 0, 800, 600)];
|
||||
|
||||
_tabItem1 = [[CPTabViewItem alloc] initWithIdentifier:@"id1"];
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
@import <AppKit/AppKit.j>
|
||||
|
||||
[CPApplication sharedApplication];
|
||||
|
||||
@implementation CPTableViewReloadDataTest : OJTestCase
|
||||
{
|
||||
CPWindow theWindow;
|
||||
@@ -11,6 +9,9 @@
|
||||
|
||||
- (void)setUp
|
||||
{
|
||||
// This will init the global var CPApp which are used internally in the AppKit
|
||||
[[CPApplication alloc] init];
|
||||
|
||||
tableContent = [];
|
||||
// setup a reasonable table
|
||||
theWindow = [[CPWindow alloc] initWithContentRect:CGRectMake(0.0, 0.0, 1024.0, 768.0)
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
@import <AppKit/AppKit.j>
|
||||
|
||||
[CPApplication sharedApplication];
|
||||
|
||||
@implementation CPTableViewTableColumnTest : OJTestCase
|
||||
{
|
||||
CPWindow theWindow;
|
||||
@@ -10,6 +8,9 @@
|
||||
|
||||
- (void)setUp
|
||||
{
|
||||
// This will init the global var CPApp which are used internally in the AppKit
|
||||
[[CPApplication alloc] init];
|
||||
|
||||
// setup a reasonable table
|
||||
theWindow = [[CPWindow alloc] initWithContentRect:CGRectMake(0.0, 0.0, 1024.0, 768.0)
|
||||
styleMask:CPWindowNotSizable];
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
|
||||
@import "CPNotificationCenterHelper.j"
|
||||
|
||||
[CPApplication sharedApplication];
|
||||
|
||||
@implementation CPTableViewTest : OJTestCase
|
||||
{
|
||||
CPWindow theWindow;
|
||||
@@ -17,6 +15,9 @@
|
||||
|
||||
- (void)setUp
|
||||
{
|
||||
// This will init the global var CPApp which are used internally in the AppKit
|
||||
[[CPApplication alloc] init];
|
||||
|
||||
// setup a reasonable table
|
||||
theWindow = [[CPWindow alloc] initWithContentRect:CGRectMake(0.0, 0.0, 1024.0, 768.0) styleMask:CPWindowNotSizable];
|
||||
|
||||
|
||||
@@ -1,11 +1,16 @@
|
||||
@import <AppKit/CPTextField.j>
|
||||
|
||||
[CPApplication sharedApplication]
|
||||
|
||||
@implementation CPTextFieldTest : OJTestCase
|
||||
{
|
||||
}
|
||||
|
||||
- (void)setUp
|
||||
{
|
||||
// This will init the global var CPApp which are used internally in the AppKit
|
||||
[[CPApplication alloc] init];
|
||||
}
|
||||
|
||||
/*!
|
||||
Detect regressions with JS object theme attribute encoding in subclasses.
|
||||
|
||||
|
||||
Loaded 100 of 326 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user