mirror of
https://github.com/cappuccino/cappuccino.git
synced 2026-08-25 04:57:03 +00:00
Merge remote-tracking branch 'origin' into RetinaDisplayed
This commit is contained in:
@@ -16,3 +16,4 @@ xcuserdata/
|
||||
Tests/Manual/**/*.xcodeproj
|
||||
*.sublime-project
|
||||
*.sublime-workspace
|
||||
*.tm_properties
|
||||
|
||||
+49
-48
@@ -44,6 +44,7 @@
|
||||
var CPAlertDelegate_alertShowHelp_ = 1 << 0,
|
||||
CPAlertDelegate_alertDidEnd_returnCode_ = 1 << 1;
|
||||
|
||||
@typedef CPAlertStyle
|
||||
/*
|
||||
@global
|
||||
@group CPAlertStyle
|
||||
@@ -70,6 +71,54 @@ var bottomHeight = 71;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@implementation _CPAlertThemeView : CPView
|
||||
|
||||
+ (CPString)defaultThemeClass
|
||||
{
|
||||
return @"alert";
|
||||
}
|
||||
|
||||
+ (CPDictionary)themeAttributes
|
||||
{
|
||||
return @{
|
||||
@"size": CGSizeMake(400.0, 110.0),
|
||||
@"content-inset": CGInsetMake(15, 15, 15, 50),
|
||||
@"informative-offset": 6,
|
||||
@"button-offset": 10,
|
||||
@"message-text-alignment": CPJustifiedTextAlignment,
|
||||
@"message-text-color": [CPColor blackColor],
|
||||
@"message-text-font": [CPFont boldSystemFontOfSize:13.0],
|
||||
@"message-text-shadow-color": [CPNull null],
|
||||
@"message-text-shadow-offset": CGSizeMakeZero(),
|
||||
@"informative-text-alignment": CPJustifiedTextAlignment,
|
||||
@"informative-text-color": [CPColor blackColor],
|
||||
@"informative-text-font": [CPFont systemFontOfSize:12.0],
|
||||
@"informative-text-shadow-color": [CPNull null],
|
||||
@"informative-text-shadow-offset": CGSizeMakeZero(),
|
||||
@"image-offset": CGPointMake(15, 12),
|
||||
@"information-image": [CPNull null],
|
||||
@"warning-image": [CPNull null],
|
||||
@"error-image": [CPNull null],
|
||||
@"help-image": [CPNull null],
|
||||
@"help-image-left-offset": 15,
|
||||
@"help-image-pressed": [CPNull null],
|
||||
@"suppression-button-y-offset": 0.0,
|
||||
@"suppression-button-x-offset": 0.0,
|
||||
@"default-elements-margin": 3.0,
|
||||
@"suppression-button-text-color": [CPColor blackColor],
|
||||
@"suppression-button-text-font": [CPFont systemFontOfSize:12.0],
|
||||
@"suppression-button-text-shadow-color": [CPNull null],
|
||||
@"suppression-button-text-shadow-offset": 0.0,
|
||||
@"modal-window-button-margin-y": 0.0,
|
||||
@"modal-window-button-margin-x": 0.0,
|
||||
@"standard-window-button-margin-y": 0.0,
|
||||
@"standard-window-button-margin-x": 0.0,
|
||||
};
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
/*!
|
||||
@ingroup appkit
|
||||
|
||||
@@ -813,51 +862,3 @@ var bottomHeight = 71;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@implementation _CPAlertThemeView : CPView
|
||||
|
||||
+ (CPString)defaultThemeClass
|
||||
{
|
||||
return @"alert";
|
||||
}
|
||||
|
||||
+ (CPDictionary)themeAttributes
|
||||
{
|
||||
return @{
|
||||
@"size": CGSizeMake(400.0, 110.0),
|
||||
@"content-inset": CGInsetMake(15, 15, 15, 50),
|
||||
@"informative-offset": 6,
|
||||
@"button-offset": 10,
|
||||
@"message-text-alignment": CPJustifiedTextAlignment,
|
||||
@"message-text-color": [CPColor blackColor],
|
||||
@"message-text-font": [CPFont boldSystemFontOfSize:13.0],
|
||||
@"message-text-shadow-color": [CPNull null],
|
||||
@"message-text-shadow-offset": CGSizeMakeZero(),
|
||||
@"informative-text-alignment": CPJustifiedTextAlignment,
|
||||
@"informative-text-color": [CPColor blackColor],
|
||||
@"informative-text-font": [CPFont systemFontOfSize:12.0],
|
||||
@"informative-text-shadow-color": [CPNull null],
|
||||
@"informative-text-shadow-offset": CGSizeMakeZero(),
|
||||
@"image-offset": CGPointMake(15, 12),
|
||||
@"information-image": [CPNull null],
|
||||
@"warning-image": [CPNull null],
|
||||
@"error-image": [CPNull null],
|
||||
@"help-image": [CPNull null],
|
||||
@"help-image-left-offset": 15,
|
||||
@"help-image-pressed": [CPNull null],
|
||||
@"suppression-button-y-offset": 0.0,
|
||||
@"suppression-button-x-offset": 0.0,
|
||||
@"default-elements-margin": 3.0,
|
||||
@"suppression-button-text-color": [CPColor blackColor],
|
||||
@"suppression-button-text-font": [CPFont systemFontOfSize:12.0],
|
||||
@"suppression-button-text-shadow-color": [CPNull null],
|
||||
@"suppression-button-text-shadow-offset": 0.0,
|
||||
@"modal-window-button-margin-y": 0.0,
|
||||
@"modal-window-button-margin-x": 0.0,
|
||||
@"standard-window-button-margin-y": 0.0,
|
||||
@"standard-window-button-margin-x": 0.0,
|
||||
};
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
+1
-16
@@ -42,25 +42,10 @@ var CPAnimationDelegate_animationShouldStart_ = 1 << 1,
|
||||
CPAnimationDelegate_animationDidEnd_ = 1 << 3,
|
||||
CPAnimationDelegate_animationDidStop_ = 1 << 4;
|
||||
|
||||
/*
|
||||
@global
|
||||
@group CPAnimationCurve
|
||||
*/
|
||||
@typedef CPAnimationCurve
|
||||
CPAnimationEaseInOut = 0;
|
||||
/*
|
||||
@global
|
||||
@group CPAnimationCurve
|
||||
*/
|
||||
CPAnimationEaseIn = 1;
|
||||
/*
|
||||
@global
|
||||
@group CPAnimationCurve
|
||||
*/
|
||||
CPAnimationEaseOut = 2;
|
||||
/*
|
||||
@global
|
||||
@group CPAnimationCurve
|
||||
*/
|
||||
CPAnimationLinear = 3;
|
||||
|
||||
ACTUAL_FRAME_RATE = 0;
|
||||
|
||||
@@ -37,6 +37,8 @@
|
||||
@import "CPWindowController.j"
|
||||
@import "_CPPopoverWindow.j"
|
||||
|
||||
@typedef CPModalSession
|
||||
|
||||
var CPMainCibFile = @"CPMainCibFile",
|
||||
CPMainCibFileHumanFriendly = @"Main cib file base name",
|
||||
CPEventModifierFlags = 0;
|
||||
@@ -448,7 +450,7 @@ var CPMainCibFile = @"CPMainCibFile",
|
||||
[CPPlatform activateIgnoringOtherApps:shouldIgnoreOtherApps];
|
||||
_isActive = YES;
|
||||
|
||||
[self _willResignActive];
|
||||
[self _didBecomeActive];
|
||||
}
|
||||
|
||||
- (void)deactivate
|
||||
@@ -986,7 +988,9 @@ var CPMainCibFile = @"CPMainCibFile",
|
||||
return;
|
||||
}
|
||||
|
||||
[aSheet._windowView _enableSheet:YES inWindow:aWindow];
|
||||
if (![aWindow attachedSheet])
|
||||
[aSheet._windowView _enableSheet:YES inWindow:aWindow];
|
||||
|
||||
[aWindow _attachSheet:aSheet modalDelegate:aModalDelegate didEndSelector:didEndSelector contextInfo:contextInfo];
|
||||
}
|
||||
|
||||
@@ -1173,7 +1177,7 @@ var CPMainCibFile = @"CPMainCibFile",
|
||||
[[self keyWindow] orderFront:self];
|
||||
else if ([self mainWindow])
|
||||
[[self mainWindow] makeKeyAndOrderFront:self];
|
||||
else
|
||||
else if ([self mainMenu])
|
||||
[[self mainMenu]._menuWindow makeKeyWindow]; //FIXME this may not actually work
|
||||
|
||||
_previousKeyWindow = nil;
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
*/
|
||||
|
||||
@import <Foundation/CPIndexSet.j>
|
||||
|
||||
@import <Foundation/CPPredicate.j>
|
||||
@import "CPObjectController.j"
|
||||
@import "CPKeyValueBinding.j"
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
@import "CPView.j"
|
||||
|
||||
// CPBoxType
|
||||
@typedef CPBoxType
|
||||
CPBoxPrimary = 0;
|
||||
CPBoxSecondary = 1;
|
||||
CPBoxSeparator = 2;
|
||||
@@ -31,12 +32,14 @@ CPBoxOldStyle = 3;
|
||||
CPBoxCustom = 4;
|
||||
|
||||
// CPBorderType
|
||||
@typedef CPBorderType
|
||||
CPNoBorder = 0;
|
||||
CPLineBorder = 1;
|
||||
CPBezelBorder = 2;
|
||||
CPGrooveBorder = 3;
|
||||
|
||||
// CPTitlePosition
|
||||
@typedef CPTitlePosition
|
||||
CPNoTitle = 0;
|
||||
CPAboveTop = 1;
|
||||
CPAtTop = 2;
|
||||
|
||||
+2
-2
@@ -29,8 +29,7 @@
|
||||
@import "CPWindow_Constants.j"
|
||||
|
||||
/* @group CPBezelStyle */
|
||||
|
||||
// IB style
|
||||
@typedef CPBezelStyle
|
||||
CPRoundedBezelStyle = 1; // Push
|
||||
CPRegularSquareBezelStyle = 2; // Bevel
|
||||
CPThickSquareBezelStyle = 3;
|
||||
@@ -49,6 +48,7 @@ CPHUDBezelStyle = -1;
|
||||
|
||||
|
||||
/* @group CPButtonType */
|
||||
@typedef CPButtonType
|
||||
CPMomentaryLightButton = 0;
|
||||
CPPushOnPushOffButton = 1;
|
||||
CPToggleButton = 2;
|
||||
|
||||
+10
-3
@@ -28,6 +28,8 @@
|
||||
@global CPPopUpButtonStatePullsDown
|
||||
@global CPKeyValueChangeOldKey
|
||||
@global CPKeyValueChangeNewKey
|
||||
@global CPKeyValueObservingOptionNew
|
||||
@global CPKeyValueObservingOptionOld
|
||||
|
||||
@implementation CPButtonBar : CPView
|
||||
{
|
||||
@@ -131,13 +133,17 @@
|
||||
- (void)setButtons:(CPArray)buttons
|
||||
{
|
||||
for (var i = [_buttons count] - 1; i >= 0; i--)
|
||||
{
|
||||
[_buttons[i] removeFromSuperview];
|
||||
[_buttons[i] removeObserver:self forKeyPath:@"hidden"];
|
||||
}
|
||||
|
||||
|
||||
_buttons = [CPArray arrayWithArray:buttons];
|
||||
|
||||
for (var i = [_buttons count] - 1; i >= 0; i--)
|
||||
{
|
||||
[_buttons[i] addObserver:self forKeyPath:@"hidden" options:nil context:nil];
|
||||
[_buttons[i] addObserver:self forKeyPath:@"hidden" options:CPKeyValueObservingOptionNew | CPKeyValueObservingOptionOld context:nil];
|
||||
[_buttons[i] setBordered:YES];
|
||||
}
|
||||
|
||||
@@ -228,10 +234,11 @@
|
||||
{
|
||||
var button = buttonsNotHidden[count];
|
||||
|
||||
[button removeFromSuperview];
|
||||
|
||||
if ([button isHidden])
|
||||
{
|
||||
[button removeFromSuperview];
|
||||
[buttonsNotHidden removeObject:button];
|
||||
}
|
||||
}
|
||||
|
||||
var currentButtonOffset = _resizeControlIsLeftAligned ? CGRectGetMaxX([self bounds]) + 1 : -1,
|
||||
|
||||
@@ -111,6 +111,30 @@ CPCheckBoxImageOffset = 4.0;
|
||||
return startedTracking;
|
||||
}
|
||||
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark Override methods from CPButton
|
||||
|
||||
- (CGSize)_minimumFrameSize
|
||||
{
|
||||
var size = [super _minimumFrameSize],
|
||||
contentView = [self ephemeralSubviewNamed:@"content-view"];
|
||||
|
||||
if (!contentView && [[self title] length])
|
||||
{
|
||||
var minSize = [self currentValueForThemeAttribute:@"min-size"],
|
||||
maxSize = [self currentValueForThemeAttribute:@"max-size"];
|
||||
|
||||
// Here we always add the min size to the control which is the size of the view of the checkBox
|
||||
size.width += minSize.width + CPCheckBoxImageOffset;
|
||||
|
||||
if (maxSize.width >= 0.0)
|
||||
size.width = MIN(size.width, maxSize.width);
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation _CPCheckBoxValueBinder : CPBinder
|
||||
|
||||
@@ -46,49 +46,12 @@
|
||||
return;
|
||||
|
||||
if (_documentView)
|
||||
{
|
||||
var defaultCenter = [CPNotificationCenter defaultCenter];
|
||||
|
||||
[defaultCenter
|
||||
removeObserver:self
|
||||
name:CPViewFrameDidChangeNotification
|
||||
object:_documentView];
|
||||
|
||||
[defaultCenter
|
||||
removeObserver:self
|
||||
name:CPViewBoundsDidChangeNotification
|
||||
object:_documentView];
|
||||
|
||||
[_documentView removeFromSuperview];
|
||||
}
|
||||
|
||||
_documentView = aView;
|
||||
|
||||
if (_documentView)
|
||||
{
|
||||
[self addSubview:_documentView];
|
||||
[self _observeDocumentView];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)_observeDocumentView
|
||||
{
|
||||
var defaultCenter = [CPNotificationCenter defaultCenter];
|
||||
|
||||
[_documentView setPostsFrameChangedNotifications:YES];
|
||||
[_documentView setPostsBoundsChangedNotifications:YES];
|
||||
|
||||
[defaultCenter
|
||||
addObserver:self
|
||||
selector:@selector(viewFrameChanged:)
|
||||
name:CPViewFrameDidChangeNotification
|
||||
object:_documentView];
|
||||
|
||||
[defaultCenter
|
||||
addObserver:self
|
||||
selector:@selector(viewBoundsChanged:)
|
||||
name:CPViewBoundsDidChangeNotification
|
||||
object:_documentView];
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -249,7 +212,6 @@ var CPClipViewDocumentViewKey = @"CPScrollViewDocumentView";
|
||||
// Don't call setDocumentView: here. It calls addSubview:, but it's A) not necessary since the
|
||||
// view hierarchy is fully encoded and B) dangerous if the subview is not fully decoded.
|
||||
_documentView = [aCoder decodeObjectForKey:CPClipViewDocumentViewKey];
|
||||
[self _observeDocumentView];
|
||||
}
|
||||
|
||||
return self;
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
@import "CPPasteboard.j"
|
||||
@import "CPView.j"
|
||||
|
||||
@class _CPCollectionViewDropIndicator
|
||||
|
||||
var CPCollectionViewDelegate_collectionView_acceptDrop_index_dropOperation_ = 1 << 0,
|
||||
CPCollectionViewDelegate_collectionView_canDragItemsAtIndexes_withEvent_ = 1 << 1,
|
||||
@@ -608,7 +609,7 @@ var HORIZONTAL_MARGIN = 2;
|
||||
|
||||
height = MAX(height, numberOfRows * (_minItemSize.height + _verticalMargin));
|
||||
|
||||
var itemSizeHeight = FLOOR(height / numberOfRows);
|
||||
var itemSizeHeight = FLOOR(height / numberOfRows) - _verticalMargin;
|
||||
|
||||
if (maxItemSizeHeight > 0)
|
||||
itemSizeHeight = MIN(itemSizeHeight, maxItemSizeHeight);
|
||||
|
||||
@@ -27,6 +27,9 @@
|
||||
@import "CPView.j"
|
||||
|
||||
@class CPSlider
|
||||
@class _CPColorPanelToolbar
|
||||
@class _CPColorPanelSwatches
|
||||
@class _CPColorPanelPreview
|
||||
|
||||
@global CPApp
|
||||
|
||||
|
||||
@@ -25,6 +25,8 @@
|
||||
@import "CPView.j"
|
||||
|
||||
@class CPSlider
|
||||
@class CPColorPanel
|
||||
@class __CPColorWheel
|
||||
|
||||
@global CPColorPickerViewWidth
|
||||
@global CPColorPickerViewHeight
|
||||
|
||||
+39
-5
@@ -86,14 +86,12 @@ var _CPColorWellDidBecomeExclusiveNotification = @"_CPColorWellDidBecomeExclusiv
|
||||
_active = NO;
|
||||
_color = [CPColor whiteColor];
|
||||
[self setBordered:YES];
|
||||
|
||||
[self _registerForNotifications];
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)_registerForNotifications
|
||||
- (void)_registerNotifications
|
||||
{
|
||||
var defaultCenter = [CPNotificationCenter defaultCenter];
|
||||
|
||||
@@ -110,6 +108,22 @@ var _CPColorWellDidBecomeExclusiveNotification = @"_CPColorWellDidBecomeExclusiv
|
||||
object:[CPColorPanel sharedColorPanel]];
|
||||
}
|
||||
|
||||
- (void)_removeNotifications
|
||||
{
|
||||
var defaultCenter = [CPNotificationCenter defaultCenter];
|
||||
|
||||
[defaultCenter
|
||||
removeObserver:self
|
||||
name:_CPColorWellDidBecomeExclusiveNotification
|
||||
object:nil];
|
||||
|
||||
[defaultCenter
|
||||
removeObserver:self
|
||||
name:CPWindowWillCloseNotification
|
||||
object:[CPColorPanel sharedColorPanel]];
|
||||
|
||||
}
|
||||
|
||||
/*!
|
||||
Sets whether the color well is bordered.
|
||||
*/
|
||||
@@ -312,6 +326,28 @@ var _CPColorWellDidBecomeExclusiveNotification = @"_CPColorWellDidBecomeExclusiv
|
||||
[contentBorderView setBackgroundColor:[self currentValueForThemeAttribute:@"content-border-color"]];
|
||||
}
|
||||
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark Observers method
|
||||
|
||||
- (void)_addObservers
|
||||
{
|
||||
if (_isObserving)
|
||||
return;
|
||||
|
||||
[super _addObservers];
|
||||
[self _registerNotifications];
|
||||
}
|
||||
|
||||
- (void)_removeObservers
|
||||
{
|
||||
if (!_isObserving)
|
||||
return;
|
||||
|
||||
[super _removeObservers];
|
||||
[self _removeNotifications];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation CPColorWellValueBinder : CPBinder
|
||||
@@ -363,8 +399,6 @@ var CPColorWellColorKey = "CPColorWellColorKey",
|
||||
_active = NO;
|
||||
_color = [aCoder decodeObjectForKey:CPColorWellColorKey];
|
||||
[self setBordered:[aCoder decodeBoolForKey:CPColorWellBorderedKey]];
|
||||
|
||||
[self _registerForNotifications];
|
||||
}
|
||||
|
||||
return self;
|
||||
|
||||
+137
-71
@@ -53,6 +53,11 @@ CPComboBoxWillPopUpNotification = @"CPComboBoxWillPopUpNotification";
|
||||
|
||||
CPComboBoxStateButtonBordered = CPThemeState("button-bordered");
|
||||
|
||||
var CPComboBoxDelegate_comboBoxSelectionIsChanging_ = 1 << 0,
|
||||
CPComboBoxDelegate_comboBoxSelectionDidChange_ = 1 << 1,
|
||||
CPComboBoxDelegate_comboBoxWillPopUp_ = 1 << 2,
|
||||
CPComboBoxDelegate_comboBoxWillDismiss_ = 1 << 3;
|
||||
|
||||
var CPComboBoxTextSubview = @"text",
|
||||
CPComboBoxButtonSubview = @"button",
|
||||
CPComboBoxDefaultNumberOfVisibleItems = 5,
|
||||
@@ -61,17 +66,20 @@ var CPComboBoxTextSubview = @"text",
|
||||
|
||||
@implementation CPComboBox : CPTextField
|
||||
{
|
||||
CPArray _items;
|
||||
_CPPopUpList _listDelegate;
|
||||
CPComboBoxDataSource _dataSource;
|
||||
BOOL _usesDataSource;
|
||||
BOOL _completes;
|
||||
BOOL _canComplete;
|
||||
int _numberOfVisibleItems;
|
||||
BOOL _forceSelection;
|
||||
BOOL _hasVerticalScroller;
|
||||
CPString _selectedStringValue;
|
||||
BOOL _popUpButtonCausedResign;
|
||||
BOOL _canComplete;
|
||||
BOOL _completes;
|
||||
BOOL _forceSelection;
|
||||
BOOL _hasVerticalScroller;
|
||||
BOOL _popUpButtonCausedResign;
|
||||
BOOL _usesDataSource;
|
||||
CGSize _intercellSpacing;
|
||||
CPArray _items;
|
||||
id<CPComboBoxDataSource> _dataSource;
|
||||
CPInteger _implementedDelegateComboBoxMethods;
|
||||
CPString _selectedStringValue;
|
||||
float _itemHeight;
|
||||
int _numberOfVisibleItems;
|
||||
_CPPopUpList _listDelegate;
|
||||
}
|
||||
|
||||
+ (CPString)defaultThemeClass
|
||||
@@ -140,7 +148,9 @@ var CPComboBoxTextSubview = @"text",
|
||||
return;
|
||||
|
||||
_hasVerticalScroller = flag;
|
||||
[[_listDelegate scrollView] setHasVerticalScroller:flag];
|
||||
|
||||
if (_listDelegate)
|
||||
[[_listDelegate scrollView] setHasVerticalScroller:_hasVerticalScroller];
|
||||
}
|
||||
|
||||
- (CGSize)intercellSpacing
|
||||
@@ -150,7 +160,13 @@ var CPComboBoxTextSubview = @"text",
|
||||
|
||||
- (void)setIntercellSpacing:(CGSize)aSize
|
||||
{
|
||||
[[_listDelegate tableView] setIntercellSpacing:aSize];
|
||||
if (_intercellSpacing && CGSizeEqualToSize(aSize, _intercellSpacing))
|
||||
return;
|
||||
|
||||
_intercellSpacing = aSize;
|
||||
|
||||
if (_listDelegate)
|
||||
[[_listDelegate tableView] setIntercellSpacing:_intercellSpacing];
|
||||
}
|
||||
|
||||
- (BOOL)isButtonBordered
|
||||
@@ -173,10 +189,18 @@ var CPComboBoxTextSubview = @"text",
|
||||
|
||||
- (void)setItemHeight:(float)itemHeight
|
||||
{
|
||||
[[_listDelegate tableView] setRowHeight:itemHeight];
|
||||
if (itemHeight === _itemHeight)
|
||||
return;
|
||||
|
||||
// FIXME: This shouldn't be necessary, but CPTableView does not tile after setRowHeight
|
||||
[[_listDelegate tableView] reloadData];
|
||||
_itemHeight = itemHeight;
|
||||
|
||||
if (_listDelegate)
|
||||
{
|
||||
[[_listDelegate tableView] setRowHeight:_itemHeight];
|
||||
|
||||
// FIXME: This shouldn't be necessary, but CPTableView does not tile after setRowHeight
|
||||
[[_listDelegate tableView] reloadData];
|
||||
}
|
||||
}
|
||||
|
||||
- (int)numberOfVisibleItems
|
||||
@@ -210,41 +234,21 @@ var CPComboBoxTextSubview = @"text",
|
||||
if (aDelegate === delegate)
|
||||
return;
|
||||
|
||||
var defaultCenter = [CPNotificationCenter defaultCenter];
|
||||
|
||||
if (delegate)
|
||||
{
|
||||
[defaultCenter removeObserver:delegate name:CPComboBoxSelectionIsChangingNotification object:self];
|
||||
[defaultCenter removeObserver:delegate name:CPComboBoxSelectionDidChangeNotification object:self];
|
||||
[defaultCenter removeObserver:delegate name:CPComboBoxWillDismissNotification object:self];
|
||||
[defaultCenter removeObserver:delegate name:CPComboBoxWillPopUpNotification object:self];
|
||||
}
|
||||
_implementedDelegateComboBoxMethods = 0;
|
||||
|
||||
if (aDelegate)
|
||||
{
|
||||
if ([aDelegate respondsToSelector:@selector(comboBoxSelectionIsChanging:)])
|
||||
[defaultCenter addObserver:delegate
|
||||
selector:@selector(comboBoxSelectionIsChanging:)
|
||||
name:CPComboBoxSelectionIsChangingNotification
|
||||
object:self];
|
||||
_implementedDelegateComboBoxMethods |= CPComboBoxDelegate_comboBoxSelectionIsChanging_;
|
||||
|
||||
if ([aDelegate respondsToSelector:@selector(comboBoxSelectionDidChange:)])
|
||||
[defaultCenter addObserver:delegate
|
||||
selector:@selector(comboBoxSelectionDidChange:)
|
||||
name:CPComboBoxSelectionDidChangeNotification
|
||||
object:self];
|
||||
_implementedDelegateComboBoxMethods |= CPComboBoxDelegate_comboBoxSelectionDidChange_;
|
||||
|
||||
if ([aDelegate respondsToSelector:@selector(comboBoxWillPopUp:)])
|
||||
[defaultCenter addObserver:delegate
|
||||
selector:@selector(comboBoxWillPopUp:)
|
||||
name:CPComboBoxWillPopUpNotification
|
||||
object:self];
|
||||
_implementedDelegateComboBoxMethods |= CPComboBoxDelegate_comboBoxWillPopUp_;
|
||||
|
||||
if ([aDelegate respondsToSelector:@selector(comboBoxWillDismiss:)])
|
||||
[defaultCenter addObserver:delegate
|
||||
selector:@selector(comboBoxWillDissmis:)
|
||||
name:CPComboBoxWillDismissNotification
|
||||
object:self];
|
||||
_implementedDelegateComboBoxMethods |= CPComboBoxDelegate_comboBoxWillDismiss_;
|
||||
}
|
||||
|
||||
[super setDelegate:aDelegate];
|
||||
@@ -394,49 +398,57 @@ var CPComboBoxTextSubview = @"text",
|
||||
if (_listDelegate === aDelegate)
|
||||
return;
|
||||
|
||||
var defaultCenter = [CPNotificationCenter defaultCenter];
|
||||
|
||||
if (_listDelegate)
|
||||
{
|
||||
[defaultCenter removeObserver:self name:_CPPopUpListWillPopUpNotification object:_listDelegate];
|
||||
[defaultCenter removeObserver:self name:_CPPopUpListWillDismissNotification object:_listDelegate];
|
||||
[defaultCenter removeObserver:self name:_CPPopUpListDidDismissNotification object:_listDelegate];
|
||||
[defaultCenter removeObserver:self name:_CPPopUpListItemWasClickedNotification object:_listDelegate];
|
||||
|
||||
var oldTableView = [_listDelegate tableView];
|
||||
|
||||
if (oldTableView)
|
||||
{
|
||||
[defaultCenter removeObserver:self name:CPTableViewSelectionIsChangingNotification object:oldTableView];
|
||||
[defaultCenter removeObserver:self name:CPTableViewSelectionDidChangeNotification object:oldTableView];
|
||||
}
|
||||
}
|
||||
[self _removeObserversForListDelegate:_listDelegate];
|
||||
|
||||
_listDelegate = aDelegate;
|
||||
|
||||
// We only add the observers if the CPComboBox is displayed
|
||||
if ([self window])
|
||||
[self _addObserversForListDelegate:_listDelegate]
|
||||
|
||||
// Apply our text style to the list
|
||||
[_listDelegate setFont:[self font]];
|
||||
[_listDelegate setAlignment:[self alignment]];
|
||||
|
||||
[[_listDelegate scrollView] setHasVerticalScroller:_hasVerticalScroller];
|
||||
|
||||
if (_intercellSpacing)
|
||||
[[_listDelegate tableView] setIntercellSpacing:_intercellSpacing];
|
||||
|
||||
if (_itemHeight)
|
||||
[[_listDelegate tableView] setRowHeight:_itemHeight];
|
||||
}
|
||||
|
||||
- (void)_addObserversForListDelegate:(_CPPopUpList)aDelegate
|
||||
{
|
||||
if (!aDelegate)
|
||||
return;
|
||||
|
||||
var defaultCenter = [CPNotificationCenter defaultCenter];
|
||||
|
||||
[defaultCenter addObserver:self
|
||||
selector:@selector(comboBoxWillPopUp:)
|
||||
name:_CPPopUpListWillPopUpNotification
|
||||
object:_listDelegate];
|
||||
object:aDelegate];
|
||||
|
||||
[defaultCenter addObserver:self
|
||||
selector:@selector(comboBoxWillDismiss:)
|
||||
name:_CPPopUpListWillDismissNotification
|
||||
object:_listDelegate];
|
||||
object:aDelegate];
|
||||
|
||||
[defaultCenter addObserver:self
|
||||
selector:@selector(listDidDismiss:)
|
||||
name:_CPPopUpListDidDismissNotification
|
||||
object:_listDelegate];
|
||||
object:aDelegate];
|
||||
|
||||
[defaultCenter addObserver:self
|
||||
selector:@selector(itemWasClicked:)
|
||||
name:_CPPopUpListItemWasClickedNotification
|
||||
object:_listDelegate];
|
||||
object:aDelegate];
|
||||
|
||||
[[_listDelegate scrollView] setHasVerticalScroller:_hasVerticalScroller];
|
||||
[[aDelegate scrollView] setHasVerticalScroller:_hasVerticalScroller];
|
||||
|
||||
var tableView = [_listDelegate tableView];
|
||||
var tableView = [aDelegate tableView];
|
||||
|
||||
[defaultCenter addObserver:self
|
||||
selector:@selector(comboBoxSelectionIsChanging:)
|
||||
@@ -447,10 +459,27 @@ var CPComboBoxTextSubview = @"text",
|
||||
selector:@selector(comboBoxSelectionDidChange:)
|
||||
name:CPTableViewSelectionDidChangeNotification
|
||||
object:tableView];
|
||||
}
|
||||
|
||||
// Apply our text style to the list
|
||||
[_listDelegate setFont:[self font]];
|
||||
[_listDelegate setAlignment:[self alignment]];
|
||||
- (void)_removeObserversForListDelegate:(_CPPopUpList)aDelegate
|
||||
{
|
||||
if (!aDelegate)
|
||||
return;
|
||||
|
||||
var defaultCenter = [CPNotificationCenter defaultCenter];
|
||||
|
||||
[defaultCenter removeObserver:self name:_CPPopUpListWillPopUpNotification object:aDelegate];
|
||||
[defaultCenter removeObserver:self name:_CPPopUpListWillDismissNotification object:aDelegate];
|
||||
[defaultCenter removeObserver:self name:_CPPopUpListDidDismissNotification object:aDelegate];
|
||||
[defaultCenter removeObserver:self name:_CPPopUpListItemWasClickedNotification object:aDelegate];
|
||||
|
||||
var oldTableView = [aDelegate tableView];
|
||||
|
||||
if (oldTableView)
|
||||
{
|
||||
[defaultCenter removeObserver:self name:CPTableViewSelectionIsChangingNotification object:oldTableView];
|
||||
[defaultCenter removeObserver:self name:CPTableViewSelectionDidChangeNotification object:oldTableView];
|
||||
}
|
||||
}
|
||||
|
||||
- (int)indexOfItemWithObjectValue:(id)anObject
|
||||
@@ -495,8 +524,6 @@ var CPComboBoxTextSubview = @"text",
|
||||
if (!_listDelegate)
|
||||
[self setListDelegate:[[_CPPopUpList alloc] initWithDataSource:self]];
|
||||
|
||||
[self _selectMatchingItem];
|
||||
|
||||
// Note the offset here is 1 less than the focus ring width because the outer edge
|
||||
// of the focus ring is very transparent and it looks better if the list is closer.
|
||||
if (CPComboBoxFocusRingWidth < 0)
|
||||
@@ -507,6 +534,7 @@ var CPComboBoxTextSubview = @"text",
|
||||
}
|
||||
|
||||
[_listDelegate popUpRelativeToRect:[self _borderFrame] view:self offset:CPComboBoxFocusRingWidth - 1];
|
||||
[self _selectMatchingItem];
|
||||
}
|
||||
|
||||
/*! @ignore */
|
||||
@@ -842,13 +870,17 @@ var CPComboBoxTextSubview = @"text",
|
||||
- (void)setFont:(CPFont)aFont
|
||||
{
|
||||
[super setFont:aFont];
|
||||
[_listDelegate setFont:aFont];
|
||||
|
||||
if (_listDelegate)
|
||||
[_listDelegate setFont:aFont];
|
||||
}
|
||||
|
||||
- (void)setAlignment:(CPTextAlignment)alignment
|
||||
{
|
||||
[super setAlignment:alignment];
|
||||
[_listDelegate setAlignment:alignment];
|
||||
|
||||
if (_listDelegate)
|
||||
[_listDelegate setAlignment:alignment];
|
||||
}
|
||||
|
||||
#pragma mark Pop Up Button Layout
|
||||
@@ -973,6 +1005,28 @@ var CPComboBoxTextSubview = @"text",
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark Observers method
|
||||
|
||||
- (void)_addObservers
|
||||
{
|
||||
if (_isObserving)
|
||||
return;
|
||||
|
||||
[super _addObservers];
|
||||
[self _addObserversForListDelegate:_listDelegate];
|
||||
}
|
||||
|
||||
- (void)_removeObservers
|
||||
{
|
||||
if (!_isObserving)
|
||||
return;
|
||||
|
||||
[super _removeObservers];
|
||||
[self _removeObserversForListDelegate:_listDelegate];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation CPComboBox (CPComboBoxDelegate)
|
||||
@@ -980,24 +1034,36 @@ var CPComboBoxTextSubview = @"text",
|
||||
/*! @ignore */
|
||||
- (void)comboBoxSelectionIsChanging:(CPNotification)aNotification
|
||||
{
|
||||
if (_implementedDelegateComboBoxMethods & CPComboBoxDelegate_comboBoxSelectionIsChanging_)
|
||||
[_delegate comboBoxSelectionIsChanging:[[CPNotification alloc] initWithName:CPComboBoxSelectionIsChangingNotification object:self userInfo:nil]];
|
||||
|
||||
[[CPNotificationCenter defaultCenter] postNotificationName:CPComboBoxSelectionIsChangingNotification object:self];
|
||||
}
|
||||
|
||||
/*! @ignore */
|
||||
- (void)comboBoxSelectionDidChange:(CPNotification)aNotification
|
||||
{
|
||||
if (_implementedDelegateComboBoxMethods & CPComboBoxDelegate_comboBoxSelectionDidChange_)
|
||||
[_delegate comboBoxSelectionDidChange:[[CPNotification alloc] initWithName:CPComboBoxSelectionDidChangeNotification object:self userInfo:nil]];
|
||||
|
||||
[[CPNotificationCenter defaultCenter] postNotificationName:CPComboBoxSelectionDidChangeNotification object:self];
|
||||
}
|
||||
|
||||
/*! @ignore */
|
||||
- (void)comboBoxWillPopUp:(CPNotification)aNotification
|
||||
{
|
||||
if (_implementedDelegateComboBoxMethods & CPComboBoxDelegate_comboBoxWillPopUp_)
|
||||
[_delegate comboBoxWillPopUp:[[CPNotification alloc] initWithName:CPComboBoxWillPopUpNotification object:self userInfo:nil]];
|
||||
|
||||
[[CPNotificationCenter defaultCenter] postNotificationName:CPComboBoxWillPopUpNotification object:self];
|
||||
}
|
||||
|
||||
/*! @ignore */
|
||||
- (void)comboBoxWillDismiss:(CPNotification)aNotification
|
||||
{
|
||||
if (_implementedDelegateComboBoxMethods & CPComboBoxDelegate_comboBoxWillDismiss_)
|
||||
[_delegate comboBoxWillDismiss:[[CPNotification alloc] initWithName:CPComboBoxWillDismissNotification object:self userInfo:nil]];
|
||||
|
||||
[[CPNotificationCenter defaultCenter] postNotificationName:CPComboBoxWillDismissNotification object:self];
|
||||
}
|
||||
|
||||
|
||||
@@ -78,6 +78,8 @@ CPInputOnInputEventFeature = 30;
|
||||
|
||||
CPFileAPIFeature = 31;
|
||||
|
||||
CPAltEnterTextAreaFeature = 32;
|
||||
|
||||
|
||||
|
||||
/*
|
||||
@@ -100,6 +102,7 @@ var USER_AGENT = "",
|
||||
// default these features to true
|
||||
PLATFORM_FEATURES[CPInputTypeCanBeChangedFeature] = YES;
|
||||
PLATFORM_FEATURES[CPInputSetFontOutsideOfDOM] = YES;
|
||||
PLATFORM_FEATURES[CPAltEnterTextAreaFeature] = YES;
|
||||
|
||||
if (typeof window !== "undefined" && typeof window.navigator !== "undefined")
|
||||
USER_AGENT = window.navigator.userAgent;
|
||||
@@ -208,6 +211,7 @@ else if (USER_AGENT.indexOf("Gecko") !== -1) // Must follow KHTML check.
|
||||
// Some day this might be fixed and should be version prefixed. No known fixed version yet.
|
||||
PLATFORM_FEATURES[CPInput1PxLeftPadding] = YES;
|
||||
|
||||
PLATFORM_FEATURES[CPAltEnterTextAreaFeature] = NO;
|
||||
// This was supposed to be added in Firefox 22, but when testing with the latest beta as of 2013-06-14
|
||||
// it does not seem to work. It seems to exhibit the CPJavaScriptPasteRequiresEditableTarget problem,
|
||||
// and in addition doesn't seem to work with our native copy code either.
|
||||
|
||||
+17
-1
@@ -42,16 +42,19 @@
|
||||
|
||||
@end
|
||||
|
||||
@typedef CPTextAlignment
|
||||
CPLeftTextAlignment = 0;
|
||||
CPRightTextAlignment = 1;
|
||||
CPCenterTextAlignment = 2;
|
||||
CPJustifiedTextAlignment = 3;
|
||||
CPNaturalTextAlignment = 4;
|
||||
|
||||
@typedef CPControlSize
|
||||
CPRegularControlSize = 0;
|
||||
CPSmallControlSize = 1;
|
||||
CPMiniControlSize = 2;
|
||||
|
||||
@typedef CPLineBreakMode
|
||||
CPLineBreakByWordWrapping = 0;
|
||||
CPLineBreakByCharWrapping = 1;
|
||||
CPLineBreakByClipping = 2;
|
||||
@@ -59,11 +62,13 @@ CPLineBreakByTruncatingHead = 3;
|
||||
CPLineBreakByTruncatingTail = 4;
|
||||
CPLineBreakByTruncatingMiddle = 5;
|
||||
|
||||
@typedef CPVerticalTextAlignment
|
||||
CPTopVerticalTextAlignment = 1;
|
||||
CPCenterVerticalTextAlignment = 2;
|
||||
CPBottomVerticalTextAlignment = 3;
|
||||
|
||||
// Deprecated for use with images, use the CPImageScale constants
|
||||
@typedef CPImageScaling
|
||||
CPScaleProportionally = 0;
|
||||
CPScaleToFit = 1;
|
||||
CPScaleNone = 2;
|
||||
@@ -73,6 +78,7 @@ CPImageScaleAxesIndependently = 1;
|
||||
CPImageScaleNone = 2;
|
||||
CPImageScaleProportionallyUpOrDown = 3;
|
||||
|
||||
@typedef CPCellImagePosition
|
||||
CPNoImage = 0;
|
||||
CPImageOnly = 1;
|
||||
CPImageLeft = 2;
|
||||
@@ -260,10 +266,20 @@ var CPControlBlackColor = [CPColor blackColor];
|
||||
maxSize = [self currentValueForThemeAttribute:@"max-size"];
|
||||
|
||||
if (minSize.width > 0)
|
||||
{
|
||||
frameSize.width = MAX(minSize.width, frameSize.width);
|
||||
|
||||
if (maxSize.width > 0)
|
||||
frameSize.width = MIN(maxSize.width, frameSize.width);
|
||||
}
|
||||
|
||||
if (minSize.height > 0)
|
||||
frameSize.height = minSize.height;
|
||||
{
|
||||
frameSize.height = MAX(minSize.height, frameSize.height);
|
||||
|
||||
if (maxSize.height > 0)
|
||||
frameSize.height = MIN(maxSize.height, frameSize.height);
|
||||
}
|
||||
|
||||
[self setFrameSize:frameSize];
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@ Cursor support by browser:
|
||||
*/
|
||||
|
||||
@import <Foundation/CPObject.j>
|
||||
@import "CPImage.j"
|
||||
|
||||
@global CPApp
|
||||
|
||||
|
||||
@@ -75,6 +75,7 @@ CPEraDatePickerElementFlag = 0x0100;
|
||||
CPInteger _datePickerStyle @accessors(property=datePickerStyle);
|
||||
CPInteger _timeInterval @accessors(property=timeInterval);
|
||||
|
||||
BOOL _invokedByUserEvent;
|
||||
_CPDatePickerTextField _datePickerTextfield;
|
||||
_CPDatePickerCalendar _datePickerCalendar;
|
||||
unsigned _implementedCDatePickerDelegateMethods;
|
||||
@@ -312,6 +313,7 @@ CPEraDatePickerElementFlag = 0x0100;
|
||||
if (aDateValue == nil)
|
||||
return;
|
||||
|
||||
_invokedByUserEvent = NO;
|
||||
[self _setDateValue:aDateValue timeInterval:_timeInterval];
|
||||
}
|
||||
|
||||
@@ -359,7 +361,8 @@ CPEraDatePickerElementFlag = 0x0100;
|
||||
_timeInterval = (_datePickerMode == CPSingleDateMode)? 0 : aTimeInterval;
|
||||
[self didChangeValueForKey:@"timeInterval"];
|
||||
|
||||
[self sendAction:[self action] to:[self target]];
|
||||
if (_invokedByUserEvent)
|
||||
[self sendAction:[self action] to:[self target]];
|
||||
|
||||
if (_datePickerStyle == CPTextFieldAndStepperDatePickerStyle || _datePickerStyle == CPTextFieldDatePickerStyle)
|
||||
[_datePickerTextfield setDateValue:_dateValue];
|
||||
|
||||
@@ -29,6 +29,9 @@
|
||||
@import <Foundation/Foundation.j>
|
||||
|
||||
@class CPDatePicker
|
||||
@class _CPDatePickerMonthView
|
||||
@class _CPDatePickerHeaderView
|
||||
@class _CPDatePickerBox
|
||||
|
||||
@global CPApp
|
||||
@global CPSingleDateMode
|
||||
@@ -63,7 +66,7 @@ var CPShortWeekDayNameArrayEn = [@"Mo", @"Tu", @"We", @"Th", @"Fr", @"Sa", @"Su"
|
||||
_CPDatePickerMonthView _monthView;
|
||||
_CPDatePickerHeaderView _headerView;
|
||||
_CPDatePickerClock _datePickerClock;
|
||||
CPBox _box;
|
||||
_CPDatePickerBox _box;
|
||||
CPDatePicker _datePicker;
|
||||
CPInteger _startSelectionIndex;
|
||||
CPInteger _currentSelectionIndex;
|
||||
@@ -97,7 +100,7 @@ var CPShortWeekDayNameArrayEn = [@"Mo", @"Tu", @"We", @"Th", @"Fr", @"Sa", @"Su"
|
||||
sizeCalendar = [_datePicker valueForThemeAttribute:@"size-calendar"],
|
||||
sizeClock = [_datePicker valueForThemeAttribute:@"size-clock"];
|
||||
|
||||
_box = [[_DatePickerBox alloc] initWithFrame:CGRectMake(0, 0, sizeCalendar.width, sizeHeader.height + sizeCalendar.height)];
|
||||
_box = [[_CPDatePickerBox alloc] initWithFrame:CGRectMake(0, 0, sizeCalendar.width, sizeHeader.height + sizeCalendar.height)];
|
||||
[_box setDatePicker:_datePicker];
|
||||
|
||||
_headerView = [[_CPDatePickerHeaderView alloc] initWithFrame:CGRectMake(0, 0, sizeHeader.width, sizeHeader.height) datePicker:_datePicker delegate:self];
|
||||
@@ -734,7 +737,7 @@ var CPShortWeekDayNameArrayEn = [@"Mo", @"Tu", @"We", @"Th", @"Fr", @"Sa", @"Su"
|
||||
|
||||
[dayTile setDate:[currentDate copy]];
|
||||
[dayTile setStringValue:currentDate.getDate()];
|
||||
[dayTile setDisabled:![self isEnabled] || currentDate.getMonth() !== currentMonth.getMonth()];
|
||||
[dayTile setDisabled:![self isEnabled] || currentDate.getMonth() !== currentMonth.getMonth() || currentDate < [_datePicker minDate] || currentDate > [_datePicker maxDate]];
|
||||
[dayTile setHighlighted:isPresentMonth && currentDate.getDate() == now.getDate()];
|
||||
}
|
||||
|
||||
@@ -896,6 +899,8 @@ var CPShortWeekDayNameArrayEn = [@"Mo", @"Tu", @"We", @"Th", @"Fr", @"Sa", @"Su"
|
||||
_indexDayTile = -1;
|
||||
_eventDragged = nil
|
||||
|
||||
_datePicker._invokedByUserEvent = YES;
|
||||
|
||||
// Check if we have to change or not the month of the component
|
||||
if ([dayTile date].getMonth() == _date.getMonth())
|
||||
{
|
||||
@@ -948,6 +953,8 @@ var CPShortWeekDayNameArrayEn = [@"Mo", @"Tu", @"We", @"Th", @"Fr", @"Sa", @"Su"
|
||||
else
|
||||
[_delegate _displayNextMonth];
|
||||
}
|
||||
|
||||
_datePicker._invokedByUserEvent = NO;
|
||||
}
|
||||
|
||||
/*! Mouse dragged event
|
||||
@@ -965,6 +972,8 @@ var CPShortWeekDayNameArrayEn = [@"Mo", @"Tu", @"We", @"Th", @"Fr", @"Sa", @"Su"
|
||||
_indexDayTile = [self indexOfTileForEvent:anEvent];
|
||||
_eventDragged = anEvent;
|
||||
|
||||
_datePicker._invokedByUserEvent = YES;
|
||||
|
||||
if ([_datePicker datePickerMode] == CPSingleDateMode)
|
||||
{
|
||||
// Check if we have to change or not the month of the component
|
||||
@@ -1006,6 +1015,8 @@ var CPShortWeekDayNameArrayEn = [@"Mo", @"Tu", @"We", @"Th", @"Fr", @"Sa", @"Su"
|
||||
[_datePicker _setDateValue:[self _hoursMinutesSecondsFromDatePickerForDate:_clickDate] timeInterval:[dateTile timeIntervalSinceDate:dateValueAtMidnight]];
|
||||
}
|
||||
}
|
||||
|
||||
_datePicker._invokedByUserEvent = NO;
|
||||
}
|
||||
|
||||
- (void)mouseUp:(CPEvent)anEvent
|
||||
@@ -1258,7 +1269,7 @@ var CPShortWeekDayNameArrayEn = [@"Mo", @"Tu", @"We", @"Th", @"Fr", @"Sa", @"Su"
|
||||
@end
|
||||
|
||||
|
||||
@implementation _DatePickerBox : CPView
|
||||
@implementation _CPDatePickerBox : CPView
|
||||
{
|
||||
CPDatePicker _datePicker @accessors(property=datePicker);
|
||||
}
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
@import "CPImageView.j"
|
||||
@import "CALayer.j"
|
||||
|
||||
|
||||
@class _CPCibCustomResource
|
||||
@class CPDatePicker
|
||||
|
||||
|
||||
@@ -31,6 +31,10 @@
|
||||
@import <Foundation/CPLocale.j>
|
||||
|
||||
@class CPDatePicker
|
||||
@class _CPDatePickerElementTextField
|
||||
@class _CPDatePickerElementView
|
||||
@class _CPDatePickerMonthView
|
||||
@class _CPDatePickerHeaderView
|
||||
|
||||
@global CPSingleDateMode
|
||||
@global CPRangeDateMode
|
||||
@@ -92,8 +96,6 @@ var CPZeroKeyCode = 48,
|
||||
[_stepper setAction:@selector(_clickStepper:)];
|
||||
[self addSubview:_stepper];
|
||||
|
||||
[[CPNotificationCenter defaultCenter] addObserver:self selector:@selector(_datePickerElementTextFieldBecomeFirstResponder:) name:CPDatePickerElementTextFieldBecomeFirstResponder object:self];
|
||||
|
||||
[self setNeedsLayout];
|
||||
[self setNeedsDisplay:YES];
|
||||
}
|
||||
@@ -336,10 +338,11 @@ var CPZeroKeyCode = 48,
|
||||
if ([anEvent keyCode] == CPReturnKeyCode)
|
||||
{
|
||||
[_currentTextField _endEditing];
|
||||
return YES;
|
||||
|
||||
return [super performKeyEquivalent:anEvent];
|
||||
}
|
||||
|
||||
return NO;
|
||||
return [super performKeyEquivalent:anEvent];
|
||||
}
|
||||
|
||||
/*! KeyDown event
|
||||
@@ -365,7 +368,6 @@ var CPZeroKeyCode = 48,
|
||||
[_currentTextField setValueForKeyEvent:anEvent];
|
||||
}
|
||||
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark Layout methods
|
||||
|
||||
@@ -414,6 +416,30 @@ var CPZeroKeyCode = 48,
|
||||
[_datePickerElementView setNeedsLayout];
|
||||
}
|
||||
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark Override observers
|
||||
|
||||
- (void)_removeObservers
|
||||
{
|
||||
if (!_isObserving)
|
||||
return;
|
||||
|
||||
[super _removeObservers];
|
||||
|
||||
[[CPNotificationCenter defaultCenter] removeObserver:self name:CPDatePickerElementTextFieldBecomeFirstResponder object:self];
|
||||
}
|
||||
|
||||
- (void)_addObservers
|
||||
{
|
||||
if (_isObserving)
|
||||
return;
|
||||
|
||||
[super _addObservers];
|
||||
|
||||
[[CPNotificationCenter defaultCenter] addObserver:self selector:@selector(_datePickerElementTextFieldBecomeFirstResponder:) name:CPDatePickerElementTextFieldBecomeFirstResponder object:self];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@@ -524,8 +550,6 @@ var CPZeroKeyCode = 48,
|
||||
[self addSubview: _textFieldSeparatorThree];
|
||||
[self addSubview: _textFieldSeparatorFour];
|
||||
|
||||
[[CPNotificationCenter defaultCenter] addObserver:self selector:@selector(_datePickerElementTextFieldAMPMChangedNotification:) name:CPDatePickerElementTextFieldAMPMChangedNotification object:_textFieldPMAM];
|
||||
|
||||
[self setNeedsLayout];
|
||||
}
|
||||
|
||||
@@ -533,12 +557,91 @@ var CPZeroKeyCode = 48,
|
||||
#pragma mark -
|
||||
#pragma mark Responder methods
|
||||
|
||||
/*! @ignore */
|
||||
- (BOOL)acceptsFirstResponder
|
||||
{
|
||||
return NO;
|
||||
// This is needed to accept to be firstResponder when nothing is selected.
|
||||
// This element needs to be first responder when the CPDatePicker is in the CPTableView
|
||||
// When clicking on a row of a CPTableView where there isn't a date element, the CPTableView will ask this element to know if it can becomes or not a firstResponder.
|
||||
return [_datePicker isEnabled] && ![self superview]._currentTextField;
|
||||
}
|
||||
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark Override observers
|
||||
|
||||
- (void)_removeObservers
|
||||
{
|
||||
if (!_isObserving)
|
||||
return;
|
||||
|
||||
[super _removeObservers];
|
||||
|
||||
[[CPNotificationCenter defaultCenter] removeObserver:self name:CPDatePickerElementTextFieldAMPMChangedNotification object:_textFieldPMAM];
|
||||
}
|
||||
|
||||
- (void)_addObservers
|
||||
{
|
||||
if (_isObserving)
|
||||
return;
|
||||
|
||||
[super _addObservers];
|
||||
|
||||
[[CPNotificationCenter defaultCenter] addObserver:self selector:@selector(_datePickerElementTextFieldAMPMChangedNotification:) name:CPDatePickerElementTextFieldAMPMChangedNotification object:_textFieldPMAM];
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark Mouse event
|
||||
|
||||
- (BOOL)continueTracking:(CGPoint)lastPoint at:(CGPoint)aPoint
|
||||
{
|
||||
[self _selectTextFieldForPoint:aPoint];
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (BOOL)startTrackingAt:(CGPoint)aPoint
|
||||
{
|
||||
[self _selectTextFieldForPoint:aPoint];
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (void)_selectTextFieldForPoint:(CGPoint)aPoint
|
||||
{
|
||||
var textField = [self _textFieldForPoint:aPoint],
|
||||
superview = [self superview];
|
||||
|
||||
if (!textField || [superview._currentTextField] == textField)
|
||||
return;
|
||||
|
||||
[[CPNotificationCenter defaultCenter] postNotificationName:CPDatePickerElementTextFieldBecomeFirstResponder object:superview userInfo:[CPDictionary dictionaryWithObject:textField forKey:@"textField"]];
|
||||
}
|
||||
|
||||
- (_CPDatePickerElementTextField)_textFieldForPoint:(CGPoint)aPoint
|
||||
{
|
||||
if (![_textFieldDay isHidden] && CGRectContainsPoint([_textFieldDay frame], aPoint))
|
||||
return _textFieldDay;
|
||||
|
||||
if (![_textFieldMonth isHidden] && CGRectContainsPoint([_textFieldMonth frame], aPoint))
|
||||
return _textFieldMonth;
|
||||
|
||||
if (![_textFieldYear isHidden] && CGRectContainsPoint([_textFieldYear frame], aPoint))
|
||||
return _textFieldYear;
|
||||
|
||||
if (![_textFieldHour isHidden] && CGRectContainsPoint([_textFieldHour frame], aPoint))
|
||||
return _textFieldHour;
|
||||
|
||||
if (![_textFieldMinute isHidden] && CGRectContainsPoint([_textFieldMinute frame], aPoint))
|
||||
return _textFieldMinute;
|
||||
|
||||
if (![_textFieldSecond isHidden] && CGRectContainsPoint([_textFieldSecond frame], aPoint))
|
||||
return _textFieldSecond;
|
||||
|
||||
if (![_textFieldPMAM isHidden] && CGRectContainsPoint([_textFieldPMAM frame], aPoint))
|
||||
return _textFieldPMAM;
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark Setter Getter methods
|
||||
|
||||
@@ -679,7 +782,9 @@ var CPZeroKeyCode = 48,
|
||||
dateValue.setHours(dateValue.getHours() - 12);
|
||||
}
|
||||
|
||||
[_datePicker setDateValue:dateValue];
|
||||
_datePicker._invokedByUserEvent = YES;
|
||||
[_datePicker _setDateValue:dateValue timeInterval:[_datePicker timeInterval]];
|
||||
_datePicker._invokedByUserEvent = NO;
|
||||
}
|
||||
|
||||
|
||||
@@ -1282,6 +1387,12 @@ var CPMonthDateType = 0,
|
||||
return self;
|
||||
}
|
||||
|
||||
/*! @ignore */
|
||||
- (BOOL)acceptsFirstResponder
|
||||
{
|
||||
return [_datePicker isEnabled];
|
||||
}
|
||||
|
||||
/*! Set the dateType of the textField
|
||||
*/
|
||||
- (void)setDateType:(int)aDateType
|
||||
@@ -1636,7 +1747,9 @@ var CPMonthDateType = 0,
|
||||
newDateValue.setSeconds(newDateValue.getSeconds() + secondsFromGMT - secondsFromGMTTimeZone);
|
||||
}
|
||||
|
||||
[_datePicker setDateValue:newDateValue];
|
||||
_datePicker._invokedByUserEvent = YES;
|
||||
[_datePicker _setDateValue:newDateValue timeInterval:[_datePicker timeInterval]];
|
||||
_datePicker._invokedByUserEvent = NO;
|
||||
}
|
||||
|
||||
|
||||
@@ -1663,6 +1776,7 @@ var CPMonthDateType = 0,
|
||||
- (void)makeSelectable
|
||||
{
|
||||
[self setThemeState:CPThemeStateSelected];
|
||||
[_datePicker setThemeState:CPThemeStateEditing];
|
||||
}
|
||||
|
||||
/*! Unsert the theme CPThemeStateSelected
|
||||
@@ -1671,6 +1785,7 @@ var CPMonthDateType = 0,
|
||||
{
|
||||
_firstEvent = YES;
|
||||
[self unsetThemeState:CPThemeStateSelected];
|
||||
[_datePicker unsetThemeState:CPThemeStateEditing];
|
||||
}
|
||||
|
||||
|
||||
@@ -1734,4 +1849,9 @@ var CPMonthDateType = 0,
|
||||
return frameSize;
|
||||
}
|
||||
|
||||
- (CGRect)bezelRectForBounds:(CGRect)bounds
|
||||
{
|
||||
return CGRectMakeCopy(bounds);
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
@typedef CPDragOperation
|
||||
CPDragOperationNone = 0;
|
||||
CPDragOperationCopy = 1 << 1;
|
||||
CPDragOperationLink = 1 << 1;
|
||||
|
||||
@@ -31,9 +31,15 @@
|
||||
@import "CPText.j"
|
||||
|
||||
@class CPTextField
|
||||
@class CPWindow
|
||||
@class CPGraphicsContext
|
||||
|
||||
@global CPApp
|
||||
|
||||
@typedef DOMEvent
|
||||
@typedef CPEventType
|
||||
|
||||
|
||||
var _CPEventPeriodicEventPeriod = 0,
|
||||
_CPEventPeriodicEventTimer = nil,
|
||||
_CPEventUpperCaseRegex = new RegExp("[A-Z]"),
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
@global CPImagesPboardType
|
||||
@global appkit_tag_dom_elements
|
||||
|
||||
@typedef CPImageAlignment
|
||||
CPImageAlignCenter = 0;
|
||||
CPImageAlignTop = 1;
|
||||
CPImageAlignTopLeft = 2;
|
||||
@@ -178,6 +179,7 @@ var CPImageViewEmptyPlaceholderImage = nil;
|
||||
|
||||
- (void)imageDidLoad:(CPNotification)aNotification
|
||||
{
|
||||
[[CPNotificationCenter defaultCenter] removeObserver:self name:CPImageDidLoadNotification object:[self objectValue]];
|
||||
[self hideOrDisplayContents];
|
||||
|
||||
[self setNeedsLayout];
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
var exposedBindingsMap = @{},
|
||||
bindingsMap = @{};
|
||||
|
||||
@typedef CPBindingOperationKind
|
||||
var CPBindingOperationAnd = 0,
|
||||
CPBindingOperationOr = 1;
|
||||
|
||||
@@ -70,6 +71,20 @@ var CPBindingOperationAnd = 0,
|
||||
return [[bindingsMap objectForKey:[anObject UID]] objectForKey:aBinding];
|
||||
}
|
||||
|
||||
+ (void)_reverseSetValueFromExclusiveBinderForObject:(id)anObject
|
||||
{
|
||||
var bindersByBindingName = [bindingsMap objectForKey:[anObject UID]];
|
||||
|
||||
[bindersByBindingName enumerateKeysAndObjectsUsingBlock:function(binding, binder, stop)
|
||||
{
|
||||
if ([binder isKindOfClass:[self class]])
|
||||
{
|
||||
[binder reverseSetValueFor:binding];
|
||||
stop(YES);
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
||||
+ (CPDictionary)infoForBinding:(CPString)aBinding forObject:(id)anObject
|
||||
{
|
||||
var theBinding = [self getBinding:aBinding forObject:anObject];
|
||||
@@ -116,7 +131,7 @@ var CPBindingOperationAnd = 0,
|
||||
count = allKeys.length;
|
||||
|
||||
while (count--)
|
||||
[anObject unbind:[bindings objectForKey:allKeys[count]]];
|
||||
[anObject unbind:allKeys[count]];
|
||||
|
||||
[bindingsMap removeObjectForKey:[anObject UID]];
|
||||
}
|
||||
@@ -142,7 +157,7 @@ var CPBindingOperationAnd = 0,
|
||||
|
||||
[self _updatePlaceholdersWithOptions:options forBinding:aName];
|
||||
|
||||
[aDestination addObserver:self forKeyPath:aKeyPath options:CPKeyValueObservingOptionNew context:aBinding];
|
||||
[aDestination addObserver:self forKeyPath:aKeyPath options:0 context:aBinding];
|
||||
|
||||
var bindings = [bindingsMap objectForKey:[_source UID]];
|
||||
|
||||
@@ -159,6 +174,24 @@ var CPBindingOperationAnd = 0,
|
||||
return self;
|
||||
}
|
||||
|
||||
+ (BOOL)isBindingAllowed:(CPString)aBinding forObject:(id)anObject
|
||||
{
|
||||
if ([[anObject class] isBindingExclusive:aBinding])
|
||||
{
|
||||
var bindingsForObject = [bindingsMap objectForKey:[anObject UID]],
|
||||
allBindings = [bindingsForObject allKeys],
|
||||
count = [allBindings count];
|
||||
|
||||
while(count--)
|
||||
{
|
||||
if ([[anObject class] isBindingExclusive:allBindings[count]])
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (void)raiseIfNotApplicable:(id)aValue forKeyPath:(CPString)keyPath options:(CPDictionary)options
|
||||
{
|
||||
if (aValue === CPNotApplicableMarker && [options objectForKey:CPRaisesForNotApplicableKeysBindingOption])
|
||||
@@ -387,6 +420,11 @@ var CPBindingOperationAnd = 0,
|
||||
return [CPBinder class];
|
||||
}
|
||||
|
||||
+ (BOOL)isBindingExclusive:(CPString)aBinding
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (CPArray)exposedBindings
|
||||
{
|
||||
var exposedBindings = [],
|
||||
@@ -415,6 +453,11 @@ var CPBindingOperationAnd = 0,
|
||||
if (!anObject || !aKeyPath)
|
||||
return CPLog.error("Invalid object or path on " + self + " for " + aBinding);
|
||||
|
||||
if (![CPBinder isBindingAllowed:aBinding forObject:self])
|
||||
{
|
||||
CPLog.warn([self description] + " : cannot bind " + aBinding + " because another binding with the same functionality is already in use.");
|
||||
return;
|
||||
}
|
||||
//if (![[self exposedBindings] containsObject:aBinding])
|
||||
// CPLog.warn("No binding exposed on " + self + " for " + aBinding);
|
||||
|
||||
|
||||
@@ -25,11 +25,13 @@
|
||||
|
||||
@global CPApp
|
||||
|
||||
@typedef CPTickMarkPosition
|
||||
CPTickMarkBelow = 0;
|
||||
CPTickMarkAbove = 1;
|
||||
CPTickMarkLeft = CPTickMarkAbove;
|
||||
CPTickMarkRight = CPTickMarkBelow;
|
||||
|
||||
@typedef CPLevelIndicatorStyle
|
||||
CPRelevancyLevelIndicatorStyle = 0;
|
||||
CPContinuousCapacityLevelIndicatorStyle = 1;
|
||||
CPDiscreteCapacityLevelIndicatorStyle = 2;
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
@import "_CPMenuManager.j"
|
||||
|
||||
@class _CPMenuView
|
||||
@class CPMenu
|
||||
|
||||
@global CPMenuDidAddItemNotification
|
||||
@global CPMenuDidChangeItemNotification
|
||||
|
||||
@@ -25,6 +25,8 @@
|
||||
@import "CPWindow.j"
|
||||
@import "_CPMenuManager.j"
|
||||
|
||||
@class _CPMenuView
|
||||
|
||||
var _CPMenuWindowPool = [],
|
||||
_CPMenuWindowPoolCapacity = 5,
|
||||
|
||||
@@ -410,7 +412,7 @@ _CPMenuWindowAttachedMenuBackgroundStyle = 2;
|
||||
{
|
||||
// Don't return indexes of items that aren't visible.
|
||||
if (!CGRectContainsPoint([_menuClipView bounds], [_menuClipView convertPoint:aPoint fromView:nil]))
|
||||
return NO;
|
||||
return CPNotFound;
|
||||
|
||||
return [_menuView itemIndexAtPoint:[_menuView convertPoint:aPoint fromView:nil]];
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
|
||||
@class _CPMenuBarWindow
|
||||
@class _CPMenuView
|
||||
@class CPMenuItem
|
||||
|
||||
@implementation _CPMenuItemMenuBarView : CPView
|
||||
{
|
||||
|
||||
@@ -24,6 +24,9 @@
|
||||
@import "CPImageView.j"
|
||||
@import "_CPImageAndTextView.j"
|
||||
|
||||
@class CPMenuItem
|
||||
|
||||
|
||||
@implementation _CPMenuItemStandardView : CPView
|
||||
{
|
||||
CPMenuItem _menuItem @accessors(property=menuItem);
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
@import "_CPMenuItemStandardView.j"
|
||||
@import "_CPMenuItemMenuBarView.j"
|
||||
|
||||
@class CPMenuItem
|
||||
@global CPApp
|
||||
|
||||
/*
|
||||
|
||||
@@ -749,7 +749,7 @@ var CPObjectControllerContentKey = @"CPObjectControllerCo
|
||||
|
||||
- (void)setValue:(id)theValue forKey:(CPString)theKeyPath
|
||||
{
|
||||
[self setValue:theKeyPath forKeyPath:theKeyPath];
|
||||
[self setValue:theValue forKeyPath:theKeyPath];
|
||||
}
|
||||
|
||||
- (unsigned)count
|
||||
|
||||
+57
-96
@@ -223,6 +223,22 @@ var CPOutlineViewCoalesceSelectionNotificationStateOff = 0,
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)_initSubclass
|
||||
{
|
||||
_BlockDeselectView = function(view, row, column)
|
||||
{
|
||||
[view unsetThemeState:CPThemeStateSelectedDataView];
|
||||
[_disclosureControlsForRows[row] unsetThemeState:CPThemeStateSelected];
|
||||
};
|
||||
|
||||
_BlockSelectView = function(view, row, column)
|
||||
{
|
||||
[view setThemeState:CPThemeStateSelectedDataView];
|
||||
[_disclosureControlsForRows[row] setThemeState:CPThemeStateSelected];
|
||||
};
|
||||
}
|
||||
|
||||
/*!
|
||||
In addition to standard delegation, the outline view also supports data
|
||||
source delegation. This method sets the data source object. Just like the
|
||||
@@ -679,7 +695,7 @@ var CPOutlineViewCoalesceSelectionNotificationStateOff = 0,
|
||||
|
||||
[self _cleanPendingItem];
|
||||
|
||||
[super reloadData];
|
||||
[super _reloadDataViews];
|
||||
}
|
||||
|
||||
- (void)_reloadItem:(id)anItem
|
||||
@@ -1308,7 +1324,7 @@ var CPOutlineViewCoalesceSelectionNotificationStateOff = 0,
|
||||
/*!
|
||||
Reloads all the data of the outlineview.
|
||||
*/
|
||||
- (void)reloadData
|
||||
- (void)_reloadDataViews
|
||||
{
|
||||
[self reloadItem:nil reloadChildren:YES];
|
||||
}
|
||||
@@ -1340,6 +1356,25 @@ var CPOutlineViewCoalesceSelectionNotificationStateOff = 0,
|
||||
else
|
||||
[super removeTableColumn:aTableColumn];
|
||||
}
|
||||
|
||||
- (void)_addDraggedDataView:(CPView)aDataView toView:(CPView)aSuperview forColumn:(CPInteger)column row:(CPInteger)row offset:(CGPoint)offset
|
||||
{
|
||||
var control;
|
||||
|
||||
[super _addDraggedDataView:aDataView toView:aSuperview forColumn:column row:row offset:offset];
|
||||
|
||||
if (_tableColumns[column] === _outlineTableColumn && (control = _disclosureControlsForRows[row]))
|
||||
{
|
||||
var controlFrame = [self frameOfOutlineDisclosureControlAtRow:row];
|
||||
|
||||
controlFrame.origin.x -= offset.x;
|
||||
controlFrame.origin.y -= offset.y;
|
||||
|
||||
[control setFrame:controlFrame];
|
||||
[aSuperview addSubview:control];
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
@ignore
|
||||
We override this because we need a special behavior for the outline
|
||||
@@ -1355,67 +1390,6 @@ var CPOutlineViewCoalesceSelectionNotificationStateOff = 0,
|
||||
return [super frameOfDataViewAtColumn:aColumn row:aRow];
|
||||
}
|
||||
|
||||
/*!
|
||||
@ignore
|
||||
We need to offset the dataview and add the disclosure triangle.
|
||||
*/
|
||||
- (CPView)_dragViewForColumn:(CPInteger)theColumnIndex event:(CPEvent)theDragEvent offset:(CGPoint)theDragViewOffset
|
||||
{
|
||||
var dragView = [[_CPColumnDragView alloc] initWithLineColor:[self gridColor]],
|
||||
tableColumn = [[self tableColumns] objectAtIndex:theColumnIndex],
|
||||
defaultRowHeight = [self valueForThemeAttribute:@"default-row-height"],
|
||||
bounds = CGRectMake(0.0, 0.0, [tableColumn width], CGRectGetHeight([self exposedRect]) + defaultRowHeight),
|
||||
columnRect = [self rectOfColumn:theColumnIndex],
|
||||
headerView = [tableColumn headerView],
|
||||
row = [_exposedRows firstIndex];
|
||||
|
||||
while (row !== CPNotFound)
|
||||
{
|
||||
var dataView = [self _newDataViewForRow:row tableColumn:tableColumn],
|
||||
dataViewFrame = [self frameOfDataViewAtColumn:theColumnIndex row:row];
|
||||
|
||||
// Only one column is ever dragged so we just place the view at
|
||||
dataViewFrame.origin.x = 0.0;
|
||||
|
||||
// Offset by table header height - scroll position
|
||||
dataViewFrame.origin.y = (CGRectGetMinY(dataViewFrame) - CGRectGetMinY([self exposedRect])) + defaultRowHeight;
|
||||
[dataView setFrame:dataViewFrame];
|
||||
|
||||
[dataView setObjectValue:[self _objectValueForTableColumn:tableColumn row:row]];
|
||||
|
||||
|
||||
if (tableColumn === _outlineTableColumn)
|
||||
{
|
||||
// first inset the dragview
|
||||
var indentationWidth = ([self levelForRow:row] + 1) * [self indentationPerLevel];
|
||||
|
||||
dataViewFrame.origin.x += indentationWidth;
|
||||
dataViewFrame.size.width -= indentationWidth;
|
||||
|
||||
[dataView setFrame:dataViewFrame];
|
||||
}
|
||||
|
||||
[dragView addSubview:dataView];
|
||||
|
||||
row = [_exposedRows indexGreaterThanIndex:row];
|
||||
}
|
||||
|
||||
// Add the column header view
|
||||
var headerFrame = [headerView frame];
|
||||
headerFrame.origin = CGPointMakeZero();
|
||||
|
||||
var columnHeaderView = [[_CPTableColumnHeaderView alloc] initWithFrame:headerFrame];
|
||||
[columnHeaderView setStringValue:[headerView stringValue]];
|
||||
[columnHeaderView setThemeState:[headerView themeState]];
|
||||
[dragView addSubview:columnHeaderView];
|
||||
|
||||
[dragView setBackgroundColor:[CPColor whiteColor]];
|
||||
[dragView setAlphaValue:0.7];
|
||||
[dragView setFrame:bounds];
|
||||
|
||||
return dragView;
|
||||
}
|
||||
|
||||
/*!
|
||||
Retargets the drop item for the outlineview.
|
||||
|
||||
@@ -1539,43 +1513,22 @@ var CPOutlineViewCoalesceSelectionNotificationStateOff = 0,
|
||||
@ignore
|
||||
We need to move the disclosure control too.
|
||||
*/
|
||||
- (void)_layoutDataViewsInRows:(CPIndexSet)rows columns:(CPIndexSet)columns
|
||||
- (void)_layoutViewsForRowIndexes:(CPIndexSet)rowIndexes columnIndexes:(CPIndexSet)columnIndexes
|
||||
{
|
||||
var rowArray = [],
|
||||
columnArray = [];
|
||||
|
||||
[rows getIndexes:rowArray maxCount:-1 inIndexRange:nil];
|
||||
[columns getIndexes:columnArray maxCount:-1 inIndexRange:nil];
|
||||
|
||||
var columnIndex = 0,
|
||||
columnsCount = columnArray.length;
|
||||
|
||||
for (; columnIndex < columnsCount; ++columnIndex)
|
||||
[self _enumerateViewsInRows:rowIndexes columns:columnIndexes usingBlock:function(view, row, column, stop)
|
||||
{
|
||||
var column = columnArray[columnIndex],
|
||||
tableColumn = _tableColumns[column],
|
||||
tableColumnUID = [tableColumn UID],
|
||||
dataViewsForTableColumn = _dataViewsForTableColumns[tableColumnUID],
|
||||
rowIndex = 0,
|
||||
rowsCount = rowArray.length;
|
||||
var control;
|
||||
|
||||
for (; rowIndex < rowsCount; ++rowIndex)
|
||||
[view setFrame:[self frameOfDataViewAtColumn:column row:row]];
|
||||
|
||||
if (_tableColumns[column] === _outlineTableColumn && (control = _disclosureControlsForRows[row]))
|
||||
{
|
||||
var row = rowArray[rowIndex],
|
||||
dataView = dataViewsForTableColumn[row],
|
||||
dataViewFrame = [self frameOfDataViewAtColumn:column row:row];
|
||||
|
||||
[dataView setFrame:dataViewFrame];
|
||||
|
||||
if (tableColumn === _outlineTableColumn)
|
||||
{
|
||||
var control = _disclosureControlsForRows[row],
|
||||
frame = [self frameOfOutlineDisclosureControlAtRow:row];
|
||||
|
||||
[control setFrame:frame];
|
||||
}
|
||||
var frame = [self frameOfOutlineDisclosureControlAtRow:row];
|
||||
[control setFrame:frame];
|
||||
}
|
||||
}
|
||||
}];
|
||||
|
||||
[self setNeedsDisplay:YES];
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -1587,7 +1540,7 @@ var CPOutlineViewCoalesceSelectionNotificationStateOff = 0,
|
||||
|
||||
var outlineColumn = [[self tableColumns] indexOfObjectIdenticalTo:[self outlineTableColumn]];
|
||||
|
||||
if (![columns containsIndex:outlineColumn] || [self outlineTableColumn] === _draggedColumn)
|
||||
if (![columns containsIndex:outlineColumn] || outlineColumn === _draggedColumnIndex)
|
||||
return;
|
||||
|
||||
var rowArray = [];
|
||||
@@ -1890,6 +1843,14 @@ var CPOutlineViewCoalesceSelectionNotificationStateOff = 0,
|
||||
return _implementedOutlineViewDelegateMethods & CPOutlineViewDelegate_outlineView_dataViewForTableColumn_item_;
|
||||
}
|
||||
|
||||
- (id)_hitTest:(CPView)aView
|
||||
{
|
||||
if ([aView isKindOfClass:[CPDisclosureButton class]])
|
||||
return aView;
|
||||
|
||||
return [super _hitTest:aView];
|
||||
}
|
||||
|
||||
- (BOOL)_delegateRespondsToShouldExpandItem
|
||||
{
|
||||
return _implementedOutlineViewDelegateMethods & CPOutlineViewDelegate_outlineView_shouldExpandItem_;
|
||||
|
||||
@@ -26,6 +26,9 @@
|
||||
@import <Foundation/CPDictionary.j>
|
||||
@import <Foundation/CPPropertyListSerialization.j>
|
||||
|
||||
@class CPWebScriptObject
|
||||
|
||||
@typedef DataTransfer
|
||||
|
||||
CPGeneralPboard = @"CPGeneralPboard";
|
||||
CPFontPboard = @"CPFontPboard";
|
||||
@@ -66,7 +69,7 @@ var CPPasteboards = nil,
|
||||
unsigned _changeCount;
|
||||
CPString _stateUID;
|
||||
|
||||
WebScriptObject _nativePasteboard;
|
||||
CPWebScriptObject _nativePasteboard;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
+14
-29
@@ -771,13 +771,6 @@ CPPopUpButtonStatePullsDown = CPThemeState("pulls-down");
|
||||
[[self selectedItem] setState:CPOffState];
|
||||
}
|
||||
|
||||
- (void)_reverseSetBinding
|
||||
{
|
||||
[_CPPopUpButtonSelectionBinder reverseSetValueForObject:self];
|
||||
|
||||
[super _reverseSetBinding];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation CPPopUpButton (BindingSupport)
|
||||
@@ -800,6 +793,20 @@ CPPopUpButtonStatePullsDown = CPThemeState("pulls-down");
|
||||
return [super _binderClassForBinding:aBinding];
|
||||
}
|
||||
|
||||
+ (BOOL)isBindingExclusive:(CPString)aBinding
|
||||
{
|
||||
return (aBinding == CPSelectedIndexBinding ||
|
||||
aBinding == CPSelectedTagBinding ||
|
||||
aBinding == CPSelectedValueBinding);
|
||||
}
|
||||
|
||||
- (void)_reverseSetBinding
|
||||
{
|
||||
[_CPPopUpButtonSelectionBinder _reverseSetValueFromExclusiveBinderForObject:self];
|
||||
|
||||
[super _reverseSetBinding];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation _CPPopUpButtonContentBinder : CPBinder
|
||||
@@ -929,30 +936,8 @@ CPPopUpButtonStatePullsDown = CPThemeState("pulls-down");
|
||||
|
||||
@end
|
||||
|
||||
var binderForObject = {};
|
||||
|
||||
@implementation _CPPopUpButtonSelectionBinder : CPBinder
|
||||
{
|
||||
CPString _selectionBinding @accessors;
|
||||
}
|
||||
|
||||
- (id)initWithBinding:(CPString)aBinding name:(CPString)aName to:(id)aDestination keyPath:(CPString)aKeyPath options:(CPDictionary)options from:(id)aSource
|
||||
{
|
||||
self = [super initWithBinding:aBinding name:aName to:aDestination keyPath:aKeyPath options:options from:aSource];
|
||||
|
||||
if (self)
|
||||
{
|
||||
binderForObject[[aSource UID]] = self;
|
||||
_selectionBinding = aName;
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
+ (void)reverseSetValueForObject:(id)aSource
|
||||
{
|
||||
var binder = binderForObject[[aSource UID]];
|
||||
[binder reverseSetValueFor:[binder _selectionBinding]];
|
||||
}
|
||||
|
||||
- (void)setPlaceholderValue:(id)aValue withMarker:(CPString)aMarker forBinding:(CPString)aBinding
|
||||
|
||||
+12
-3
@@ -28,6 +28,7 @@
|
||||
@import "CPImageView.j"
|
||||
@import "CPResponder.j"
|
||||
@import "CPView.j"
|
||||
@import "CPViewController.j"
|
||||
@import "_CPPopoverWindow.j"
|
||||
|
||||
@protocol CPPopoverDelegate <CPObject>
|
||||
@@ -310,9 +311,8 @@ Set the behavior of the CPPopover. It can be:
|
||||
if ([_popoverWindow isClosing])
|
||||
return;
|
||||
|
||||
if (_implementedDelegateMethods & CPPopoverDelegate_popover_shouldClose_)
|
||||
if (![_delegate popoverShouldClose:self])
|
||||
return;
|
||||
if (![self _popoverShouldClose])
|
||||
return;
|
||||
|
||||
[self _close];
|
||||
}
|
||||
@@ -346,6 +346,15 @@ Set the behavior of the CPPopover. It can be:
|
||||
[_delegate popoverDidShow:self];
|
||||
}
|
||||
|
||||
/*! @ignore */
|
||||
- (BOOL)_popoverShouldClose
|
||||
{
|
||||
if (_implementedDelegateMethods & CPPopoverDelegate_popover_shouldClose_)
|
||||
return [_delegate popoverShouldClose:self];
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
/*! @ignore */
|
||||
- (void)_popoverWillClose
|
||||
{
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
@import "CPWindow_Constants.j"
|
||||
|
||||
|
||||
@typedef CPProgressIndicatorStyle
|
||||
/*
|
||||
@global
|
||||
@group CPProgressIndicatorStyle
|
||||
|
||||
+10
-23
@@ -25,6 +25,8 @@
|
||||
|
||||
@import "CPButton.j"
|
||||
|
||||
@class CPRadioGroup
|
||||
|
||||
@global CPApp
|
||||
|
||||
|
||||
@@ -356,7 +358,7 @@ var CPRadioRadioGroupKey = @"CPRadioRadioGroupKey";
|
||||
[_selectedRadio setState:CPOffState];
|
||||
|
||||
_selectedRadio = aRadio;
|
||||
[_CPRadioGroupSelectionBinder reverseSetValueForObject:self];
|
||||
[_CPRadioGroupSelectionBinder _reverseSetValueFromExclusiveBinderForObject:self];
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -407,32 +409,17 @@ var CPRadioGroupRadiosKey = @"CPRadioGroupRadiosKey",
|
||||
return [super _binderClassForBinding:aBinding];
|
||||
}
|
||||
|
||||
@end
|
||||
+ (BOOL)isBindingExclusive:(CPString)aBinding
|
||||
{
|
||||
return (aBinding == CPSelectedIndexBinding ||
|
||||
aBinding == CPSelectedTagBinding ||
|
||||
aBinding == CPSelectedValueBinding);
|
||||
}
|
||||
|
||||
var binderForObject = {};
|
||||
@end
|
||||
|
||||
@implementation _CPRadioGroupSelectionBinder : CPBinder
|
||||
{
|
||||
CPString _selectionBinding @accessors;
|
||||
}
|
||||
|
||||
- (id)initWithBinding:(CPString)aBinding name:(CPString)aName to:(id)aDestination keyPath:(CPString)aKeyPath options:(CPDictionary)options from:(id)aSource
|
||||
{
|
||||
self = [super initWithBinding:aBinding name:aName to:aDestination keyPath:aKeyPath options:options from:aSource];
|
||||
|
||||
if (self)
|
||||
{
|
||||
binderForObject[[aSource UID]] = self;
|
||||
_selectionBinding = aName;
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
+ (void)reverseSetValueForObject:(id)aSource
|
||||
{
|
||||
var binder = binderForObject[[aSource UID]];
|
||||
[binder reverseSetValueFor:[binder _selectionBinding]];
|
||||
}
|
||||
|
||||
- (void)setPlaceholderValue:(id)aValue withMarker:(CPString)aMarker forBinding:(CPString)aBinding
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
@import "CPEvent.j"
|
||||
|
||||
@class CPKeyBinding
|
||||
@class CPMenu
|
||||
|
||||
CPDeleteKeyCode = 8;
|
||||
CPTabKeyCode = 9;
|
||||
|
||||
@@ -2207,7 +2207,7 @@ TODO: implement
|
||||
indexOfDropLine = FLOOR(y / _sliceHeight),
|
||||
numberOfRows = [self numberOfRows];
|
||||
|
||||
if (indexOfDropLine < 0 || indexOfDropLine > numberOfRows || (indexOfDropLine >= [_draggingRows firstIndex] && indexOfDropLine <= [_draggingRows lastIndex] + 1))
|
||||
if (indexOfDropLine <= 0 || indexOfDropLine > numberOfRows || (indexOfDropLine >= [_draggingRows firstIndex] && indexOfDropLine <= [_draggingRows lastIndex] + 1))
|
||||
{
|
||||
if (_subviewIndexOfDropLine !== CPNotFound && indexOfDropLine !== _subviewIndexOfDropLine)
|
||||
[self _clearDropLine];
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
|
||||
CPRuleEditorPredicateLeftExpression = "CPRuleEditorPredicateLeftExpression";
|
||||
CPRuleEditorPredicateRightExpression = "CPRuleEditorPredicateRightExpression";
|
||||
CPRuleEditorPredicateComparisonModifier = "CPRuleEditorPredicateComparisonModifier";
|
||||
@@ -36,5 +37,6 @@ CPRuleEditorNestingModeList = 1; // Allows a single list, with no nes
|
||||
CPRuleEditorNestingModeCompound = 2; // Unlimited nesting and compound rows; this is the default
|
||||
CPRuleEditorNestingModeSimple = 3; // One compound row at the top with subrows beneath it, and no further nesting allowed
|
||||
|
||||
@typedef CPRuleEditorRowType
|
||||
CPRuleEditorRowTypeSimple = 0;
|
||||
CPRuleEditorRowTypeCompound = 1;
|
||||
|
||||
@@ -20,6 +20,8 @@
|
||||
@import <Foundation/CPObject.j>
|
||||
@import <Foundation/CPString.j>
|
||||
|
||||
@class CPPredicateEditorRowTemplate
|
||||
|
||||
@implementation _CPPredicateEditorTree : CPObject
|
||||
{
|
||||
CPPredicateEditorRowTemplate template @accessors;
|
||||
|
||||
@@ -19,6 +19,8 @@
|
||||
|
||||
@import "CPView.j"
|
||||
|
||||
@class CPRuleEditor
|
||||
|
||||
@implementation _CPRuleEditorViewSlice : CPView
|
||||
{
|
||||
CPRuleEditor _ruleEditor;
|
||||
|
||||
@@ -65,8 +65,6 @@
|
||||
[self addSubview:_subtractButton];
|
||||
|
||||
[self setAutoresizingMask:CPViewWidthSizable];
|
||||
|
||||
[[CPNotificationCenter defaultCenter] addObserver:self selector:@selector(_textDidChange:) name:CPControlTextDidChangeNotification object:nil];
|
||||
}
|
||||
|
||||
- (CPButton)_createRowButton
|
||||
@@ -124,8 +122,8 @@
|
||||
{
|
||||
var title = [[itemsArray objectAtIndex:index] title],
|
||||
font = [_ruleEditor font],
|
||||
width = [title sizeWithFont:font].width + 20,
|
||||
rect = CGRectMake(0, 0, (width - width % 40) + 80, [_ruleEditor rowHeight]),
|
||||
width = [title sizeWithFont:font].width + 35, // 35 for right arrows + margins
|
||||
rect = CGRectMake(0, 0, width, [_ruleEditor rowHeight]),
|
||||
popup = [[CPPopUpButton alloc] initWithFrame:rect];
|
||||
|
||||
[popup setValue:font forThemeAttribute:@"font"];
|
||||
@@ -317,8 +315,14 @@
|
||||
{
|
||||
[ruleView setControlSize:CPSmallControlSize];
|
||||
|
||||
var minSize = [ruleView currentValueForThemeAttribute:@"min-size"],
|
||||
frame = [ruleView frame];
|
||||
|
||||
// Force controls to their minimum size
|
||||
frame.size.height = minSize.height;
|
||||
[ruleView setFrame:frame];
|
||||
|
||||
[_ruleOptionViews addObject:ruleView];
|
||||
var frame = [ruleView frame];
|
||||
[_ruleOptionInitialViewFrames addObject:frame];
|
||||
[_ruleOptionFrames addObject:frame];
|
||||
|
||||
@@ -491,6 +495,26 @@
|
||||
[self layoutSubviews];
|
||||
}
|
||||
|
||||
- (void)_addObservers
|
||||
{
|
||||
if (_isObserving)
|
||||
return;
|
||||
|
||||
[super _addObservers];
|
||||
|
||||
[[CPNotificationCenter defaultCenter] addObserver:self selector:@selector(_textDidChange:) name:CPControlTextDidChangeNotification object:nil];
|
||||
}
|
||||
|
||||
- (void)_removeObservers
|
||||
{
|
||||
if (!_isObserving)
|
||||
return;
|
||||
|
||||
[super _removeObservers];
|
||||
|
||||
[[CPNotificationCenter defaultCenter] removeObserver:self name:CPControlTextDidChangeNotification object:nil];
|
||||
}
|
||||
|
||||
- (void)drawRect:(CGRect)rect
|
||||
{
|
||||
[super drawRect:rect];
|
||||
@@ -516,4 +540,4 @@
|
||||
[self _sendRuleAction:nil];
|
||||
}
|
||||
|
||||
@end
|
||||
@end
|
||||
|
||||
+31
-5
@@ -264,11 +264,6 @@ var CPScrollerStyleGlobal = CPScrollerStyleOverlay,
|
||||
_delegate = nil;
|
||||
_scrollTimer = nil;
|
||||
_implementedDelegateMethods = 0;
|
||||
|
||||
[[CPNotificationCenter defaultCenter] addObserver:self
|
||||
selector:@selector(_didReceiveDefaultStyleChange:)
|
||||
name:CPScrollerStyleGlobalChangeNotification
|
||||
object:nil];
|
||||
}
|
||||
|
||||
return self;
|
||||
@@ -1270,6 +1265,37 @@ Notifies the delegate when the scroll view has finished scrolling.
|
||||
#pragma mark -
|
||||
#pragma mark Overrides
|
||||
|
||||
|
||||
- (void)_removeObservers
|
||||
{
|
||||
if (!_isObserving)
|
||||
return;
|
||||
|
||||
[[CPNotificationCenter defaultCenter] removeObserver:self
|
||||
name:CPScrollerStyleGlobalChangeNotification
|
||||
object:nil];
|
||||
|
||||
[super _removeObservers];
|
||||
}
|
||||
|
||||
- (void)_addObservers
|
||||
{
|
||||
if (_isObserving)
|
||||
return;
|
||||
|
||||
//Make sure to have the last global style for the scroller
|
||||
[self _didReceiveDefaultStyleChange:nil];
|
||||
|
||||
[[CPNotificationCenter defaultCenter] addObserver:self
|
||||
selector:@selector(_didReceiveDefaultStyleChange:)
|
||||
name:CPScrollerStyleGlobalChangeNotification
|
||||
object:nil];
|
||||
|
||||
[super _addObservers];
|
||||
}
|
||||
|
||||
|
||||
|
||||
- (void)drawRect:(CGRect)aRect
|
||||
{
|
||||
[super drawRect:aRect];
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
@global CPApp
|
||||
|
||||
// CPScroller Constants
|
||||
@typedef CPScrollerPart
|
||||
CPScrollerNoPart = 0;
|
||||
CPScrollerDecrementPage = 1;
|
||||
CPScrollerKnob = 2;
|
||||
@@ -44,6 +45,7 @@ CPScrollerKnobSlot = 6;
|
||||
CPScrollerIncrementArrow = 0;
|
||||
CPScrollerDecrementArrow = 1;
|
||||
|
||||
@typedef CPUsableScrollerParts
|
||||
CPNoScrollerParts = 0;
|
||||
CPOnlyScrollerArrows = 1;
|
||||
CPAllScrollerParts = 2;
|
||||
|
||||
+18
-6
@@ -119,16 +119,28 @@ var RECENT_SEARCH_PREFIX = @" ";
|
||||
_canResignFirstResponder = YES;
|
||||
}
|
||||
|
||||
- (void)viewWillMoveToSuperview:(CPView)aView
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark Override observers
|
||||
|
||||
- (void)_removeObservers
|
||||
{
|
||||
[super viewWillMoveToSuperview:aView];
|
||||
if (!_isObserving)
|
||||
return;
|
||||
|
||||
[super _removeObservers];
|
||||
|
||||
// First we remove any observer that may have been in place to avoid memory leakage.
|
||||
[[CPNotificationCenter defaultCenter] removeObserver:self name:CPControlTextDidChangeNotification object:self];
|
||||
}
|
||||
|
||||
// Register the observe here if we need to.
|
||||
if (aView)
|
||||
[[CPNotificationCenter defaultCenter] addObserver:self selector:@selector(_searchFieldTextDidChange:) name:CPControlTextDidChangeNotification object:self];
|
||||
- (void)_addObservers
|
||||
{
|
||||
if (_isObserving)
|
||||
return;
|
||||
|
||||
[super _addObservers];
|
||||
|
||||
[[CPNotificationCenter defaultCenter] addObserver:self selector:@selector(_searchFieldTextDidChange:) name:CPControlTextDidChangeNotification object:self];
|
||||
}
|
||||
|
||||
// Managing Buttons
|
||||
|
||||
+97
-56
@@ -25,9 +25,11 @@
|
||||
@import "CPControl.j"
|
||||
@import "CPWindow_Constants.j"
|
||||
@import "_CPImageAndTextView.j"
|
||||
@import "CPMenu.j"
|
||||
|
||||
@global CPApp
|
||||
|
||||
@typedef CPSegmentSwitchTracking
|
||||
CPSegmentSwitchTrackingSelectOne = 0;
|
||||
CPSegmentSwitchTrackingSelectAny = 1;
|
||||
CPSegmentSwitchTrackingMomentary = 2;
|
||||
@@ -70,23 +72,9 @@ CPSegmentSwitchTrackingMomentary = 2;
|
||||
@"center-segment-bezel-color": [CPNull null],
|
||||
@"divider-bezel-color": [CPNull null],
|
||||
@"divider-thickness": 1.0,
|
||||
@"default-height": 24.0,
|
||||
};
|
||||
}
|
||||
|
||||
+ (Class)_binderClassForBinding:(CPString)aBinding
|
||||
{
|
||||
if ([self _isSelectionBinding:aBinding])
|
||||
return [_CPSegmentedControlBinder class];
|
||||
|
||||
return [super _binderClassForBinding:aBinding];
|
||||
}
|
||||
|
||||
+ (BOOL)_isSelectionBinding:(CPString)aBinding
|
||||
{
|
||||
return (aBinding === CPSelectedIndexBinding || aBinding === CPSelectedLabelBinding || aBinding === CPSelectedTagBinding);
|
||||
}
|
||||
|
||||
- (id)initWithFrame:(CGRect)aRect
|
||||
{
|
||||
_segments = [];
|
||||
@@ -104,17 +92,14 @@ CPSegmentSwitchTrackingMomentary = 2;
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)bind:(CPString)aBinding toObject:(id)anObject withKeyPath:(CPString)aKeyPath options:(CPDictionary)options
|
||||
/*!
|
||||
Sets the control's size.
|
||||
@param aControlSize the control's size
|
||||
*/
|
||||
- (void)setControlSize:(CPControlSize)aControlSize
|
||||
{
|
||||
if ([[self class] _isSelectionBinding:aBinding] && _trackingMode !== CPSegmentSwitchTrackingSelectOne)
|
||||
CPLog.warn("Binding " + aBinding + " needs CPSegmentSwitchTrackingSelectOne tracking mode");
|
||||
else
|
||||
[super bind:aBinding toObject:anObject withKeyPath:aKeyPath options:options];
|
||||
}
|
||||
|
||||
- (void)_reverseSetBinding
|
||||
{
|
||||
[_CPSegmentedControlBinder reverseSetValueForObject:self];
|
||||
[super setControlSize:aControlSize];
|
||||
[self _sizeToControlSize];
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -512,7 +497,7 @@ CPSegmentSwitchTrackingMomentary = 2;
|
||||
|
||||
- (CGRect)rectForEphemeralSubviewNamed:(CPString)aName
|
||||
{
|
||||
var height = [self currentValueForThemeAttribute:@"default-height"],
|
||||
var height = [self currentValueForThemeAttribute:@"min-size"].height,
|
||||
contentInset = [self currentValueForThemeAttribute:@"content-inset"],
|
||||
bezelInset = [self currentValueForThemeAttribute:@"bezel-inset"],
|
||||
bounds = [self bounds];
|
||||
@@ -577,10 +562,17 @@ CPSegmentSwitchTrackingMomentary = 2;
|
||||
return;
|
||||
|
||||
var themeState = _themeStates[0],
|
||||
isDisabled = [self hasThemeState:CPThemeStateDisabled];
|
||||
isDisabled = [self hasThemeState:CPThemeStateDisabled],
|
||||
isControlSizeSmall = [self hasThemeState:CPThemeStateControlSizeSmall],
|
||||
isControlSizeMini = [self hasThemeState:CPThemeStateControlSizeMini];
|
||||
|
||||
themeState = isDisabled ? themeState.and(CPThemeStateDisabled) : themeState;
|
||||
|
||||
if (isControlSizeSmall)
|
||||
themeState = themeState.and(CPThemeStateControlSizeSmall);
|
||||
else if (isControlSizeMini)
|
||||
themeState = themeState.and(CPThemeStateControlSizeMini);
|
||||
|
||||
var leftCapColor = [self valueForThemeAttribute:@"left-segment-bezel-color"
|
||||
inState:themeState],
|
||||
|
||||
@@ -594,6 +586,11 @@ CPSegmentSwitchTrackingMomentary = 2;
|
||||
|
||||
themeState = isDisabled ? themeState.and(CPThemeStateDisabled) : themeState;
|
||||
|
||||
if (isControlSizeSmall)
|
||||
themeState = themeState.and(CPThemeStateControlSizeSmall);
|
||||
else if (isControlSizeMini)
|
||||
themeState = themeState.and(CPThemeStateControlSizeMini);
|
||||
|
||||
var rightCapColor = [self valueForThemeAttribute:@"right-segment-bezel-color"
|
||||
inState:themeState],
|
||||
|
||||
@@ -609,6 +606,11 @@ CPSegmentSwitchTrackingMomentary = 2;
|
||||
|
||||
themeState = isDisabled ? themeState.and(CPThemeStateDisabled) : themeState;
|
||||
|
||||
if (isControlSizeSmall)
|
||||
themeState = themeState.and(CPThemeStateControlSizeSmall);
|
||||
else if (isControlSizeMini)
|
||||
themeState = themeState.and(CPThemeStateControlSizeMini);
|
||||
|
||||
var bezelColor = [self valueForThemeAttribute:@"center-segment-bezel-color"
|
||||
inState:themeState],
|
||||
|
||||
@@ -618,7 +620,6 @@ CPSegmentSwitchTrackingMomentary = 2;
|
||||
|
||||
[bezelView setBackgroundColor:bezelColor];
|
||||
|
||||
|
||||
// layout image/title views
|
||||
var segment = _segments[i],
|
||||
contentView = [self layoutEphemeralSubviewNamed:@"segment-content-" + i
|
||||
@@ -651,6 +652,11 @@ CPSegmentSwitchTrackingMomentary = 2;
|
||||
|
||||
borderState = isDisabled ? borderState.and(CPThemeStateDisabled) : borderState;
|
||||
|
||||
if (isControlSizeSmall)
|
||||
borderState = borderState.and(CPThemeStateControlSizeSmall);
|
||||
else if (isControlSizeMini)
|
||||
borderState = borderState.and(CPThemeStateControlSizeMini);
|
||||
|
||||
var borderColor = [self valueForThemeAttribute:@"divider-bezel-color"
|
||||
inState:borderState],
|
||||
|
||||
@@ -707,7 +713,6 @@ CPSegmentSwitchTrackingMomentary = 2;
|
||||
|
||||
// Update control size
|
||||
var frame = [self frame];
|
||||
|
||||
[self setFrameSize:CGSizeMake(CGRectGetWidth(frame) + delta, CGRectGetHeight(frame))];
|
||||
|
||||
// Update segment width
|
||||
@@ -743,7 +748,7 @@ CPSegmentSwitchTrackingMomentary = 2;
|
||||
|
||||
- (CGRect)bezelFrameForSegment:(unsigned)aSegment
|
||||
{
|
||||
var height = [self currentValueForThemeAttribute:@"default-height"],
|
||||
var height = [self currentValueForThemeAttribute:@"min-size"].height,
|
||||
bezelInset = [self currentValueForThemeAttribute:@"bezel-inset"],
|
||||
width = [self widthForSegment:aSegment],
|
||||
left = [self _leftOffsetForSegment:aSegment];
|
||||
@@ -753,7 +758,7 @@ CPSegmentSwitchTrackingMomentary = 2;
|
||||
|
||||
- (CGRect)contentFrameForSegment:(unsigned)aSegment
|
||||
{
|
||||
var height = [self currentValueForThemeAttribute:@"default-height"],
|
||||
var height = [self currentValueForThemeAttribute:@"min-size"].height,
|
||||
contentInset = [self currentValueForThemeAttribute:@"content-inset"],
|
||||
width = [self widthForSegment:aSegment],
|
||||
left = [self _leftOffsetForSegment:aSegment];
|
||||
@@ -915,8 +920,7 @@ var CPSegmentedControlSegmentsKey = "CPSegmentedControlSegmentsKey",
|
||||
else
|
||||
_trackingMode = CPSegmentSwitchTrackingSelectOne;
|
||||
|
||||
// HACK
|
||||
|
||||
// Here we update the themeStates array for each segments to know if there are selected or not
|
||||
for (var i = 0; i < _segments.length; i++)
|
||||
_themeStates[i] = [_segments[i] selected] ? CPThemeStateSelected : CPThemeStateNormal;
|
||||
|
||||
@@ -924,12 +928,32 @@ var CPSegmentedControlSegmentsKey = "CPSegmentedControlSegmentsKey",
|
||||
for (var i = 0; i < _segments.length; i++)
|
||||
[self tileWithChangedSegment:i];
|
||||
|
||||
var difference = MAX(originalWidth - [self frame].size.width, 0.0),
|
||||
remainingWidth = FLOOR(difference / _segments.length);
|
||||
var thickness = [self currentValueForThemeAttribute:@"divider-thickness"],
|
||||
dividerExtraSpace = ([_segments count] - 1) * thickness,
|
||||
difference = MAX(originalWidth - [self frame].size.width - dividerExtraSpace, 0.0),
|
||||
remainingWidth = FLOOR(difference / _segments.length),
|
||||
widthOfAllSegments = 0;
|
||||
|
||||
for (var i = 0; i < _segments.length; i++)
|
||||
{
|
||||
[self setWidth:[_segments[i] width] + remainingWidth forSegment:i];
|
||||
widthOfAllSegments += [_segments[i] width];
|
||||
}
|
||||
|
||||
// Here we handle the leftovers pixel, and we will add one pixel to each segment cell till we have the same size as the originalSize.
|
||||
// This is needed to have a perfect/same alignment between our application and xCode.
|
||||
var leftOversPixel = originalWidth - (widthOfAllSegments + dividerExtraSpace);
|
||||
|
||||
// Make sure we don't make an out of range
|
||||
if (leftOversPixel < _segments.length - 1)
|
||||
{
|
||||
for (var i = 0; i < leftOversPixel; i++)
|
||||
{
|
||||
[self setWidth:[_segments[i] width] + 1 forSegment:i];
|
||||
}
|
||||
}
|
||||
|
||||
[self setFrameSize:CGSizeMake(originalWidth, [self frame].size.height)];
|
||||
[self tileWithChangedSegment:0];
|
||||
}
|
||||
|
||||
@@ -948,31 +972,48 @@ var CPSegmentedControlSegmentsKey = "CPSegmentedControlSegmentsKey",
|
||||
|
||||
@end
|
||||
|
||||
var CPSegmentedControlBindersMap = {},
|
||||
CPSegmentedControlNoSelectionPlaceholder = "CPSegmentedControlNoSelectionPlaceholder";
|
||||
@implementation CPSegmentedControl (BindingSupport)
|
||||
|
||||
+ (Class)_binderClassForBinding:(CPString)aBinding
|
||||
{
|
||||
if ([self _isSelectionBinding:aBinding])
|
||||
return [_CPSegmentedControlBinder class];
|
||||
|
||||
return [super _binderClassForBinding:aBinding];
|
||||
}
|
||||
|
||||
+ (BOOL)_isSelectionBinding:(CPString)aBinding
|
||||
{
|
||||
return (aBinding === CPSelectedIndexBinding || aBinding === CPSelectedLabelBinding || aBinding === CPSelectedTagBinding);
|
||||
}
|
||||
|
||||
+ (BOOL)isBindingExclusive:(CPString)aBinding
|
||||
{
|
||||
return [self _isSelectionBinding:aBinding];
|
||||
}
|
||||
|
||||
- (void)bind:(CPString)aBinding toObject:(id)anObject withKeyPath:(CPString)aKeyPath options:(CPDictionary)options
|
||||
{
|
||||
if ([[self class] _isSelectionBinding:aBinding] && _trackingMode !== CPSegmentSwitchTrackingSelectOne)
|
||||
{
|
||||
CPLog.warn("Binding " + aBinding + " needs CPSegmentSwitchTrackingSelectOne tracking mode");
|
||||
return;
|
||||
}
|
||||
|
||||
[super bind:aBinding toObject:anObject withKeyPath:aKeyPath options:options];
|
||||
}
|
||||
|
||||
- (void)_reverseSetBinding
|
||||
{
|
||||
[_CPSegmentedControlBinder _reverseSetValueFromExclusiveBinderForObject:self];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
var CPSegmentedControlNoSelectionPlaceholder = "CPSegmentedControlNoSelectionPlaceholder";
|
||||
|
||||
@implementation _CPSegmentedControlBinder : CPBinder
|
||||
{
|
||||
CPString _selectionBinding @accessors(readonly, getter=selectionBinding);
|
||||
}
|
||||
|
||||
+ (void)reverseSetValueForObject:(id)aSource
|
||||
{
|
||||
var binder = CPSegmentedControlBindersMap[[aSource UID]];
|
||||
[binder reverseSetValueFor:[binder selectionBinding]];
|
||||
}
|
||||
|
||||
- (id)initWithBinding:(CPString)aBinding name:(CPString)aName to:(id)aDestination keyPath:(CPString)aKeyPath options:(CPDictionary)options from:(id)aSource
|
||||
{
|
||||
self = [super initWithBinding:aBinding name:aName to:aDestination keyPath:aKeyPath options:options from:aSource];
|
||||
|
||||
if (self)
|
||||
{
|
||||
CPSegmentedControlBindersMap[[aSource UID]] = self;
|
||||
_selectionBinding = aName;
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)_updatePlaceholdersWithOptions:(CPDictionary)options
|
||||
|
||||
+5
-2
@@ -22,6 +22,9 @@
|
||||
|
||||
@import <Foundation/CPObject.j>
|
||||
|
||||
@import "CGGeometry.j"
|
||||
@import "CPColor.j"
|
||||
@import "CPGraphicsContext.j"
|
||||
|
||||
/*!
|
||||
@deprecated
|
||||
@@ -31,9 +34,9 @@
|
||||
*/
|
||||
@implementation CPShadow : CPObject
|
||||
{
|
||||
CGSize _offset @accessors(property=shadowOffset);
|
||||
CGSize _offset @accessors(property=shadowOffset);
|
||||
float _blurRadius @accessors(property=shadowBlurRadius);
|
||||
CPColor _color @accessors(property=shadowColor);
|
||||
CPColor _color @accessors(property=shadowColor);
|
||||
}
|
||||
|
||||
/*!
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
@import "CPImage.j"
|
||||
@import "CPView.j"
|
||||
|
||||
|
||||
@typedef CPShadowWeight
|
||||
CPLightShadow = 0;
|
||||
CPHeavyShadow = 1;
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
@import <Foundation/CPObject.j>
|
||||
@import <Foundation/CPRunLoop.j>
|
||||
|
||||
@typedef HTMLAudioElement
|
||||
|
||||
@protocol CPSoundDelegate <CPObject>
|
||||
|
||||
|
||||
+7
-8
@@ -25,7 +25,6 @@
|
||||
@import "CPTextField.j"
|
||||
|
||||
|
||||
|
||||
/*!
|
||||
CPStepper is an implementation of Cocoa NSStepper.
|
||||
|
||||
@@ -53,9 +52,9 @@
|
||||
@param maxValue the maximal acceptable value of the stepper
|
||||
@return Initialized CPStepper
|
||||
*/
|
||||
+ (CPStepper)stepperWithInitialValue:(float)aValue minValue:(float)aMinValue maxValue:(float)aMaxValue
|
||||
+ (id)stepperWithInitialValue:(float)aValue minValue:(float)aMinValue maxValue:(float)aMaxValue
|
||||
{
|
||||
var stepper = [[CPStepper alloc] initWithFrame:CGRectMakeZero()];
|
||||
var stepper = [[self alloc] initWithFrame:CGRectMakeZero()];
|
||||
|
||||
[stepper setDoubleValue:aValue];
|
||||
[stepper setMinValue:aMinValue];
|
||||
@@ -75,14 +74,14 @@
|
||||
|
||||
@return Initialized CPStepper
|
||||
*/
|
||||
+ (CPStepper)stepper
|
||||
+ (id)stepper
|
||||
{
|
||||
return [CPStepper stepperWithInitialValue:0.0 minValue:0.0 maxValue:59.0];
|
||||
}
|
||||
|
||||
+ (Class)_binderClassForBinding:(CPString)aBinding
|
||||
{
|
||||
if (aBinding == CPValueBinding || aBinding == CPMinValueBinding || aBinding == CPMaxValueBinding)
|
||||
if (aBinding === CPValueBinding || aBinding === CPMinValueBinding || aBinding === CPMaxValueBinding)
|
||||
return [_CPStepperValueBinder class];
|
||||
|
||||
return [super _binderClassForBinding:aBinding];
|
||||
@@ -90,7 +89,7 @@
|
||||
|
||||
- (CPString)_replacementKeyPathForBinding:(CPString)aBinding
|
||||
{
|
||||
if (aBinding == CPValueBinding)
|
||||
if (aBinding === CPValueBinding)
|
||||
return @"doubleValue";
|
||||
|
||||
return [super _replacementKeyPathForBinding:aBinding];
|
||||
@@ -240,7 +239,7 @@
|
||||
if (![self isEnabled])
|
||||
return;
|
||||
|
||||
if (aSender == _buttonUp)
|
||||
if (aSender === _buttonUp)
|
||||
[self setDoubleValue:([self doubleValue] + _increment)];
|
||||
else
|
||||
[self setDoubleValue:([self doubleValue] - _increment)];
|
||||
@@ -293,7 +292,7 @@
|
||||
|
||||
- (void)_updatePlaceholdersWithOptions:(CPDictionary)options forBinding:(CPString)aBinding
|
||||
{
|
||||
var placeholder = (aBinding == CPMaxValueBinding) ? [_source maxValue] : [_source minValue];
|
||||
var placeholder = (aBinding === CPMaxValueBinding) ? [_source maxValue] : [_source minValue];
|
||||
|
||||
[super _updatePlaceholdersWithOptions:options];
|
||||
|
||||
|
||||
+2
-1
@@ -25,6 +25,7 @@
|
||||
@import "CPTabViewItem.j"
|
||||
@import "CPView.j"
|
||||
|
||||
@typedef CPTabViewType
|
||||
CPTopTabsBezelBorder = 0;
|
||||
//CPLeftTabsBezelBorder = 1;
|
||||
CPBottomTabsBezelBorder = 2;
|
||||
@@ -94,7 +95,7 @@ var CPTabViewDidSelectTabViewItemSelector = 1 << 1,
|
||||
_tabs = [[CPSegmentedControl alloc] initWithFrame:CGRectMake(0, 0, 0, 0)];
|
||||
[_tabs setHitTests:NO];
|
||||
|
||||
var height = [_tabs valueForThemeAttribute:@"default-height"];
|
||||
var height = [_tabs valueForThemeAttribute:@"min-size"].height;
|
||||
[_tabs setFrameSize:CGSizeMake(0, height)];
|
||||
|
||||
_box = [[CPBox alloc] initWithFrame:[self bounds]];
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
@import <Foundation/CPObject.j>
|
||||
|
||||
@import "CPView.j"
|
||||
|
||||
@class CPTabView
|
||||
|
||||
/*
|
||||
The tab is currently selected.
|
||||
|
||||
+8
-20
@@ -28,9 +28,8 @@
|
||||
|
||||
@import "CPTextField.j"
|
||||
|
||||
@global CPTableViewColumnDidResizeNotification
|
||||
|
||||
@class _CPTableColumnHeaderView
|
||||
@class CPTableView
|
||||
|
||||
CPTableColumnNoResizing = 0;
|
||||
CPTableColumnAutoresizingMask = 1 << 0;
|
||||
@@ -181,11 +180,11 @@ CPTableColumnUserResizingMask = 1 << 1;
|
||||
columns = [CPIndexSet indexSetWithIndexesInRange:CPMakeRange(index, [tableView._exposedColumns lastIndex] - index + 1)];
|
||||
|
||||
// FIXME: Would be faster with some sort of -setNeedsDisplayInColumns: that updates a dirtyTableColumnForDisplay cache; then marked columns would relayout their data views at display time.
|
||||
[tableView _layoutDataViewsInRows:rows columns:columns];
|
||||
[tableView _layoutViewsForRowIndexes:rows columnIndexes:columns];
|
||||
[tableView tile];
|
||||
|
||||
if (!_disableResizingPosting)
|
||||
[self _postDidResizeNotificationWithOldWidth:oldWidth];
|
||||
[[self tableView] _didResizeTableColumn:self oldWidth:oldWidth];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -394,8 +393,8 @@ CPTableColumnUserResizingMask = 1 << 1;
|
||||
*/
|
||||
- (void)setDataView:(CPView)aView
|
||||
{
|
||||
if (_dataView)
|
||||
_dataViewData = nil;
|
||||
if (_dataView === aView)
|
||||
return;
|
||||
|
||||
[aView setThemeState:CPThemeStateTableDataView];
|
||||
|
||||
@@ -538,19 +537,6 @@ CPTableColumnUserResizingMask = 1 << 1;
|
||||
return _headerToolTip;
|
||||
}
|
||||
|
||||
/*!
|
||||
@ignore
|
||||
*/
|
||||
- (void)_postDidResizeNotificationWithOldWidth:(float)oldWidth
|
||||
{
|
||||
[[self tableView] _didResizeTableColumn:self];
|
||||
|
||||
[[CPNotificationCenter defaultCenter]
|
||||
postNotificationName:CPTableViewColumnDidResizeNotification
|
||||
object:[self tableView]
|
||||
userInfo:@{ @"CPTableColumn": self, @"CPOldWidth": oldWidth }];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation CPTableColumnValueBinder : CPBinder
|
||||
@@ -564,7 +550,9 @@ CPTableColumnUserResizingMask = 1 << 1;
|
||||
rowIndexes = [CPIndexSet indexSetWithIndexesInRange:CPMakeRange(0, [tableView numberOfRows])],
|
||||
columnIndexes = [CPIndexSet indexSetWithIndex:column];
|
||||
|
||||
[tableView reloadDataForRowIndexes:rowIndexes columnIndexes:columnIndexes];
|
||||
// Reloads objectValues only, not the views.
|
||||
// FIXME: reload data for all rows or just exposed rows ?
|
||||
[tableView _reloadDataForRowIndexes:rowIndexes columnIndexes:columnIndexes];
|
||||
}
|
||||
|
||||
- (CPSortDescriptor)_defaultSortDescriptorPrototype
|
||||
|
||||
+399
-362
@@ -20,19 +20,14 @@
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
@import <Foundation/CPIndexSet.j>
|
||||
|
||||
@import "CPCursor.j"
|
||||
@import "CPPasteboard.j"
|
||||
@import "CPTableColumn.j"
|
||||
@import "CPTableView.j"
|
||||
@import "CPView.j"
|
||||
@import "CPCursor.j"
|
||||
@import "_CPImageAndTextView.j"
|
||||
|
||||
@class CPTableView
|
||||
|
||||
@global CPApp
|
||||
|
||||
|
||||
@implementation _CPTableColumnHeaderView : CPView
|
||||
{
|
||||
_CPImageAndTextView _textField;
|
||||
@@ -69,13 +64,18 @@
|
||||
|
||||
- (void)_init
|
||||
{
|
||||
_textField = [[_CPImageAndTextView alloc] initWithFrame:CGRectMakeZero()];
|
||||
_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]];
|
||||
[_textField setFont:[CPFont boldSystemFontOfSize:12.0]];
|
||||
[_textField setAlignment:CPLeftTextAlignment];
|
||||
[_textField setVerticalAlignment:CPCenterVerticalTextAlignment];
|
||||
[_textField setTextShadowColor:[CPColor whiteColor]];
|
||||
[_textField setTextShadowOffset:CGSizeMake(0,1)];
|
||||
|
||||
[self addSubview:_textField];
|
||||
}
|
||||
@@ -168,26 +168,49 @@
|
||||
|
||||
- (void)_setIndicatorImage:(CPImage)anImage
|
||||
{
|
||||
if (anImage)
|
||||
{
|
||||
[_textField setImage:anImage];
|
||||
[_textField setImagePosition:CPImageRight];
|
||||
}
|
||||
else
|
||||
{
|
||||
[_textField setImagePosition:CPNoImage];
|
||||
}
|
||||
if (anImage)
|
||||
{
|
||||
[_textField setImage:anImage];
|
||||
[_textField setImagePosition:CPImageRight];
|
||||
}
|
||||
else
|
||||
{
|
||||
[_textField setImagePosition:CPNoImage];
|
||||
}
|
||||
}
|
||||
|
||||
- (CPImage)_indicatorImage
|
||||
{
|
||||
return [_textField imagePosition] === CPNoImage ? nil : [_textField image];
|
||||
}
|
||||
|
||||
- (void)drawRect:(CGRect)aRect
|
||||
{
|
||||
var bounds = [self bounds];
|
||||
|
||||
if (!CGRectIntersectsRect(aRect, bounds))
|
||||
return;
|
||||
|
||||
var context = [[CPGraphicsContext currentContext] graphicsPort],
|
||||
maxX = CGRectGetMaxX(bounds) - 0.5;
|
||||
|
||||
CGContextSetLineWidth(context, 1);
|
||||
CGContextSetStrokeColor(context, [CPColor colorWithWhite:192.0/255.0 alpha:1.0]);
|
||||
|
||||
CGContextBeginPath(context);
|
||||
|
||||
CGContextMoveToPoint(context, maxX, CGRectGetMinY(bounds));
|
||||
CGContextAddLineToPoint(context, maxX, CGRectGetMaxY(bounds));
|
||||
|
||||
CGContextStrokePath(context);
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringValueKey",
|
||||
_CPTableColumnHeaderViewFontKey = @"_CPTableColumnHeaderViewFontKey",
|
||||
_CPTableColumnHeaderViewTextColorKey = @"_CPTableColumnHeaderViewTextColorKey",
|
||||
_CPTableColumnHeaderViewTextShadowColorKey = @"_CPTableColumnHeaderViewTextShadowColorKey",
|
||||
_CPTableColumnHeaderViewAlignmentKey = @"_CPTableColumnHeaderViewAlignmentKey",
|
||||
_CPTableColumnHeaderViewLineBreakModeKey = @"_CPTableColumnHeaderViewLineBreakModeKey",
|
||||
_CPTableColumnHeaderViewImageKey = @"_CPTableColumnHeaderViewImageKey";
|
||||
_CPTableColumnHeaderViewIsDraggingKey = @"_CPTableColumnHeaderViewIsDraggingKey";
|
||||
|
||||
@implementation _CPTableColumnHeaderView (CPCoding)
|
||||
|
||||
@@ -199,10 +222,7 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal
|
||||
[self _setIndicatorImage:[aCoder decodeObjectForKey:_CPTableColumnHeaderViewImageKey]];
|
||||
[self setStringValue:[aCoder decodeObjectForKey:_CPTableColumnHeaderViewStringValueKey]];
|
||||
[self setFont:[aCoder decodeObjectForKey:_CPTableColumnHeaderViewFontKey]];
|
||||
[self setTextColor:[aCoder decodeObjectForKey:_CPTableColumnHeaderViewTextColorKey]];
|
||||
[self setTextShadowColor:[aCoder decodeObjectForKey:_CPTableColumnHeaderViewTextShadowColorKey]];
|
||||
[self setAlignment:[aCoder decodeIntForKey:_CPTableColumnHeaderViewAlignmentKey]];
|
||||
[self setLineBreakMode:[aCoder decodeIntForKey:_CPTableColumnHeaderViewLineBreakModeKey]];
|
||||
[self setFont:[aCoder decodeObjectForKey:_CPTableColumnHeaderViewFontKey]];
|
||||
}
|
||||
|
||||
return self;
|
||||
@@ -214,31 +234,37 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal
|
||||
|
||||
[aCoder encodeObject:[_textField text] forKey:_CPTableColumnHeaderViewStringValueKey];
|
||||
[aCoder encodeObject:[_textField image] forKey:_CPTableColumnHeaderViewImageKey];
|
||||
[aCoder encodeObject:[self font] forKey:_CPTableColumnHeaderViewFontKey];
|
||||
[aCoder encodeObject:[self textColor] forKey:_CPTableColumnHeaderViewTextColorKey];
|
||||
[aCoder encodeObject:[self textShadowColor] forKey:_CPTableColumnHeaderViewTextShadowColorKey];
|
||||
[aCoder encodeInt:[self alignment] forKey:_CPTableColumnHeaderViewAlignmentKey];
|
||||
[aCoder encodeInt:[self lineBreakMode] forKey:_CPTableColumnHeaderViewLineBreakModeKey];
|
||||
[aCoder encodeObject:[_textField font] forKey:_CPTableColumnHeaderViewFontKey];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
CPTableHeaderViewDragColumnHeaderTag = 1;
|
||||
|
||||
var CPTableHeaderViewResizeZone = 3.0,
|
||||
CPTableHeaderViewDragTolerance = 10.0;
|
||||
|
||||
@implementation CPTableHeaderView : CPView
|
||||
{
|
||||
CGPoint _mouseDownLocation;
|
||||
CGPoint _previousTrackingLocation;
|
||||
int _activeColumn;
|
||||
int _pressedColumn;
|
||||
int _lastDragDestinationColumnIndex;
|
||||
CGPoint _mouseDownLocation;
|
||||
CGPoint _columnMouseDownLocation;
|
||||
CGPoint _mouseEnterExitLocation;
|
||||
CGPoint _previousTrackingLocation;
|
||||
|
||||
BOOL _isResizing;
|
||||
BOOL _isDragging;
|
||||
BOOL _isTrackingColumn;
|
||||
BOOL _drawsColumnLines;
|
||||
int _activeColumn;
|
||||
int _pressedColumn;
|
||||
|
||||
float _columnOldWidth;
|
||||
BOOL _isResizing;
|
||||
BOOL _isDragging;
|
||||
BOOL _canDragColumn;
|
||||
|
||||
CPTableView _tableView @accessors(property=tableView);
|
||||
CPView _columnDragView;
|
||||
CPView _columnDragHeaderView;
|
||||
CPView _columnDragClipView;
|
||||
|
||||
float _columnOldWidth;
|
||||
|
||||
CPTableView _tableView @accessors(property=tableView);
|
||||
}
|
||||
|
||||
+ (CPString)defaultThemeClass
|
||||
@@ -258,14 +284,16 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal
|
||||
- (void)_init
|
||||
{
|
||||
_mouseDownLocation = CGPointMakeZero();
|
||||
_columnMouseDownLocation = CGPointMakeZero();
|
||||
_mouseEnterExitLocation = CGPointMakeZero();
|
||||
_previousTrackingLocation = CGPointMakeZero();
|
||||
|
||||
_activeColumn = -1;
|
||||
_pressedColumn = -1;
|
||||
|
||||
_isResizing = NO;
|
||||
_isDragging = NO;
|
||||
_isTrackingColumn = NO;
|
||||
_drawsColumnLines = YES;
|
||||
_canDragColumn = NO;
|
||||
|
||||
_columnOldWidth = 0.0;
|
||||
|
||||
@@ -282,14 +310,39 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal
|
||||
return self;
|
||||
}
|
||||
|
||||
- (int)columnAtPoint:(CGPoint)aPoint
|
||||
// Checking Altered Columns
|
||||
|
||||
- (CPInteger)draggedColumn
|
||||
{
|
||||
return [_tableView columnAtPoint:CGPointMake(aPoint.x, aPoint.y)];
|
||||
return _isDragging ? _activeColumn : -1;
|
||||
}
|
||||
|
||||
- (float)draggedDistance
|
||||
{
|
||||
if (_isDragging)
|
||||
return (CGRectGetMinX(_columnDragClipView) - _columnMouseDownLocation.x);
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
- (CPInteger)resizedColumn
|
||||
{
|
||||
if (_isResizing)
|
||||
return _activeColumn;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Utility Methods
|
||||
|
||||
- (CPInteger)columnAtPoint:(CGPoint)aPoint
|
||||
{
|
||||
return [_tableView columnAtPoint:aPoint];
|
||||
}
|
||||
|
||||
- (CGRect)headerRectOfColumn:(CPInteger)aColumnIndex
|
||||
{
|
||||
var headerRect = CGRectMakeCopy([self bounds]),
|
||||
var headerRect = [self bounds],
|
||||
columnRect = [_tableView rectOfColumn:aColumnIndex];
|
||||
|
||||
headerRect.origin.x = CGRectGetMinX(columnRect);
|
||||
@@ -298,16 +351,145 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal
|
||||
return headerRect;
|
||||
}
|
||||
|
||||
- (void)setDrawsColumnLines:(BOOL)aFlag
|
||||
// CPView Overrides
|
||||
|
||||
- (void)viewDidMoveToWindow
|
||||
{
|
||||
_drawsColumnLines = aFlag;
|
||||
[super viewDidMoveToWindow];
|
||||
|
||||
[[self window] setAcceptsMouseMovedEvents:YES];
|
||||
}
|
||||
|
||||
- (BOOL)drawsColumnLines
|
||||
- (void)layoutSubviews
|
||||
{
|
||||
return _drawsColumnLines;
|
||||
var tableColumns = [_tableView tableColumns],
|
||||
count = [tableColumns count];
|
||||
|
||||
for (var i = 0; i < count; i++)
|
||||
{
|
||||
var column = [tableColumns objectAtIndex:i],
|
||||
headerView = [column headerView],
|
||||
frame = [self headerRectOfColumn:i];
|
||||
|
||||
[headerView setFrame:frame];
|
||||
|
||||
if ([headerView superview] != self)
|
||||
[self addSubview:headerView];
|
||||
}
|
||||
}
|
||||
|
||||
// CPResponder Overrides
|
||||
|
||||
- (void)mouseDown:(CPEvent)theEvent
|
||||
{
|
||||
var currentLocation = [self convertPoint:[theEvent locationInWindow] fromView:nil],
|
||||
adjustedLocation = CGPointMake(MAX(currentLocation.x - CPTableHeaderViewResizeZone, 0.0), currentLocation.y),
|
||||
columnIndex = [self columnAtPoint:adjustedLocation];
|
||||
|
||||
if (columnIndex === -1)
|
||||
return;
|
||||
|
||||
_mouseDownLocation = currentLocation;
|
||||
_activeColumn = columnIndex;
|
||||
_canDragColumn = YES;
|
||||
|
||||
[_tableView _sendDelegateMouseDownInHeaderOfTableColumn:columnIndex];
|
||||
|
||||
if ([self _shouldResizeTableColumn:columnIndex at:currentLocation])
|
||||
[self _startResizingTableColumn:columnIndex at:currentLocation];
|
||||
else
|
||||
[self _setPressedColumn:columnIndex];
|
||||
}
|
||||
|
||||
- (void)mouseDragged:(CPEvent)theEvent
|
||||
{
|
||||
var currentLocation = [self convertPoint:[theEvent locationInWindow] fromView:nil],
|
||||
adjustedLocation = CGPointMake(MAX(currentLocation.x - CPTableHeaderViewResizeZone, 0.0), currentLocation.y),
|
||||
columnIndex = [self columnAtPoint:adjustedLocation];
|
||||
|
||||
if (_isResizing)
|
||||
{
|
||||
[self _autoscroll:theEvent localLocation:currentLocation];
|
||||
[self _continueResizingTableColumn:_activeColumn at:currentLocation];
|
||||
}
|
||||
else if (_isDragging)
|
||||
{
|
||||
// Disable autoscrolling until it behaves correctly.
|
||||
//[self _autoscroll:theEvent localLocation:currentLocation];
|
||||
[self _dragTableColumn:_activeColumn to:currentLocation];
|
||||
}
|
||||
else // tracking a press, could become a drag
|
||||
{
|
||||
if (CGRectContainsPoint([self headerRectOfColumn:_activeColumn], currentLocation))
|
||||
{
|
||||
if ([self _shouldDragTableColumn:columnIndex at:currentLocation])
|
||||
[self _startDraggingTableColumn:columnIndex at:currentLocation];
|
||||
else
|
||||
[self _setPressedColumn:_activeColumn];
|
||||
}
|
||||
else
|
||||
[self _setPressedColumn:-1];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)mouseUp:(CPEvent)theEvent
|
||||
{
|
||||
if (_isResizing)
|
||||
{
|
||||
[self _stopResizingTableColumn:_activeColumn];
|
||||
}
|
||||
else if (_isDragging)
|
||||
{
|
||||
[self _stopDraggingTableColumn:_activeColumn];
|
||||
}
|
||||
else if (_activeColumn != -1)
|
||||
{
|
||||
var currentLocation = [self convertPoint:[theEvent locationInWindow] fromView:nil];
|
||||
|
||||
if (CGRectContainsPoint([self headerRectOfColumn:_activeColumn], currentLocation))
|
||||
[_tableView _didClickTableColumn:_activeColumn modifierFlags:[theEvent modifierFlags]];
|
||||
}
|
||||
|
||||
[self _setPressedColumn:-1];
|
||||
[self _updateResizeCursor:[CPApp currentEvent]];
|
||||
|
||||
_activeColumn = -1;
|
||||
}
|
||||
|
||||
- (void)mouseEntered:(CPEvent)theEvent
|
||||
{
|
||||
var location = [theEvent globalLocation];
|
||||
|
||||
if (CGPointEqualToPoint(location, _mouseEnterExitLocation))
|
||||
return;
|
||||
|
||||
_mouseEnterExitLocation = location;
|
||||
|
||||
[self _updateResizeCursor:theEvent];
|
||||
}
|
||||
|
||||
- (void)mouseMoved:(CPEvent)theEvent
|
||||
{
|
||||
[self _updateResizeCursor:theEvent];
|
||||
}
|
||||
|
||||
- (void)mouseExited:(CPEvent)theEvent
|
||||
{
|
||||
var location = [theEvent globalLocation];
|
||||
|
||||
if (CGPointEqualToPoint(location, _mouseEnterExitLocation))
|
||||
return;
|
||||
|
||||
_mouseEnterExitLocation = location;
|
||||
|
||||
// FIXME: we should use CPCursor push/pop (if previous currentCursor != arrow).
|
||||
[[CPCursor arrowCursor] set];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation CPTableHeaderView (CPTableHeaderViewPrivate)
|
||||
|
||||
- (CGRect)_cursorRectForColumn:(CPInteger)column
|
||||
{
|
||||
if (column == -1 || !([_tableView._tableColumns[column] resizingMask] & CPTableColumnUserResizingMask))
|
||||
@@ -315,14 +497,17 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal
|
||||
|
||||
var rect = [self headerRectOfColumn:column];
|
||||
|
||||
rect.origin.x = CGRectGetMaxX(rect) - 5;
|
||||
rect.size.width = 20;
|
||||
rect.origin.x = (CGRectGetMaxX(rect) - CPTableHeaderViewResizeZone) - 1.0;
|
||||
rect.size.width = (CPTableHeaderViewResizeZone * 2.0) + 1.0; // + 1 for resize line
|
||||
|
||||
return rect;
|
||||
}
|
||||
|
||||
- (void)_setPressedColumn:(CPInteger)column
|
||||
{
|
||||
if (_pressedColumn === column)
|
||||
return;
|
||||
|
||||
if (_pressedColumn != -1)
|
||||
{
|
||||
var headerView = [_tableView._tableColumns[_pressedColumn] headerView];
|
||||
@@ -333,132 +518,37 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal
|
||||
{
|
||||
var headerView = [_tableView._tableColumns[column] headerView];
|
||||
[headerView setThemeState:CPThemeStateHighlighted];
|
||||
|
||||
if (_tableView._editingCellIndex || _tableView._editingColumn == column)
|
||||
[[self window] makeFirstResponder:_tableView];
|
||||
}
|
||||
else
|
||||
{
|
||||
// Once the mouse leaves the pressed column, it can no longer drag
|
||||
_canDragColumn = NO;
|
||||
}
|
||||
|
||||
_pressedColumn = column;
|
||||
}
|
||||
|
||||
- (void)mouseDown:(CPEvent)theEvent
|
||||
{
|
||||
[self trackMouse:theEvent];
|
||||
}
|
||||
|
||||
- (void)trackMouse:(CPEvent)theEvent
|
||||
{
|
||||
var type = [theEvent type],
|
||||
currentLocation = [self convertPoint:[theEvent locationInWindow] fromView:nil];
|
||||
|
||||
// Take the right columns resize tracking area into account
|
||||
currentLocation.x -= 5.0;
|
||||
|
||||
var columnIndex = [self columnAtPoint:currentLocation],
|
||||
shouldResize = [self shouldResizeTableColumn:columnIndex at:CGPointMake(currentLocation.x + 5.0, currentLocation.y)];
|
||||
|
||||
if (type === CPLeftMouseUp)
|
||||
{
|
||||
if (shouldResize)
|
||||
[self stopResizingTableColumn:_activeColumn at:currentLocation];
|
||||
else if ([self _shouldStopTrackingTableColumn:columnIndex at:currentLocation])
|
||||
{
|
||||
[_tableView _didClickTableColumn:columnIndex modifierFlags:[theEvent modifierFlags]];
|
||||
[self stopTrackingTableColumn:columnIndex at:currentLocation];
|
||||
|
||||
_isTrackingColumn = NO;
|
||||
}
|
||||
|
||||
[self _updateResizeCursor:[CPApp currentEvent]];
|
||||
|
||||
_activeColumn = CPNotFound;
|
||||
return;
|
||||
}
|
||||
|
||||
if (type === CPLeftMouseDown)
|
||||
{
|
||||
if (columnIndex === -1)
|
||||
return;
|
||||
|
||||
_mouseDownLocation = currentLocation;
|
||||
_activeColumn = columnIndex;
|
||||
|
||||
[_tableView _sendDelegateMouseDownInHeaderOfTableColumn:columnIndex];
|
||||
|
||||
if (shouldResize)
|
||||
[self startResizingTableColumn:columnIndex at:currentLocation];
|
||||
else
|
||||
{
|
||||
[self startTrackingTableColumn:columnIndex at:currentLocation];
|
||||
_isTrackingColumn = YES;
|
||||
}
|
||||
}
|
||||
else if (type === CPLeftMouseDragged)
|
||||
{
|
||||
if (shouldResize)
|
||||
[self continueResizingTableColumn:_activeColumn at:currentLocation];
|
||||
else
|
||||
{
|
||||
if (_activeColumn === columnIndex && CGRectContainsPoint([self headerRectOfColumn:columnIndex], currentLocation))
|
||||
{
|
||||
if (_isTrackingColumn && _pressedColumn !== -1)
|
||||
{
|
||||
if (![self continueTrackingTableColumn:columnIndex at:currentLocation])
|
||||
return; // Stop tracking the column, because it's being dragged
|
||||
} else
|
||||
[self startTrackingTableColumn:columnIndex at:currentLocation];
|
||||
|
||||
} else if (_isTrackingColumn && _pressedColumn !== -1)
|
||||
[self stopTrackingTableColumn:_activeColumn at:currentLocation];
|
||||
}
|
||||
}
|
||||
|
||||
_previousTrackingLocation = currentLocation;
|
||||
[CPApp setTarget:self selector:@selector(trackMouse:) forNextEventMatchingMask:CPLeftMouseDraggedMask | CPLeftMouseUpMask untilDate:nil inMode:nil dequeue:YES];
|
||||
}
|
||||
|
||||
- (void)startTrackingTableColumn:(CPInteger)aColumnIndex at:(CGPoint)aPoint
|
||||
{
|
||||
_lastDragDestinationColumnIndex = -1;
|
||||
[self _setPressedColumn:aColumnIndex];
|
||||
}
|
||||
|
||||
- (BOOL)continueTrackingTableColumn:(CPInteger)aColumnIndex at:(CGPoint)aPoint
|
||||
{
|
||||
if ([self _shouldDragTableColumn:aColumnIndex at:aPoint])
|
||||
{
|
||||
var columnRect = [self headerRectOfColumn:aColumnIndex],
|
||||
offset = CGPointMakeZero(),
|
||||
view = [_tableView _dragViewForColumn:aColumnIndex event:[CPApp currentEvent] offset:offset],
|
||||
viewLocation = CGPointMakeZero();
|
||||
|
||||
viewLocation.x = ( CGRectGetMinX(columnRect) + offset.x ) + ( aPoint.x - _mouseDownLocation.x );
|
||||
viewLocation.y = CGRectGetMinY(columnRect) + offset.y;
|
||||
|
||||
[self dragView:view at:viewLocation offset:CGSizeMakeZero() event:[CPApp currentEvent]
|
||||
pasteboard:[CPPasteboard pasteboardWithName:CPDragPboard] source:self slideBack:YES];
|
||||
|
||||
return NO;
|
||||
}
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (BOOL)_shouldStopTrackingTableColumn:(CPInteger)aColumnIndex at:(CGPoint)aPoint
|
||||
{
|
||||
return _isTrackingColumn && _activeColumn === aColumnIndex &&
|
||||
CGRectContainsPoint([self headerRectOfColumn:aColumnIndex], aPoint);
|
||||
}
|
||||
|
||||
- (void)stopTrackingTableColumn:(CPInteger)aColumnIndex at:(CGPoint)aPoint
|
||||
{
|
||||
[self _setPressedColumn:CPNotFound];
|
||||
[self _updateResizeCursor:[CPApp currentEvent]];
|
||||
}
|
||||
|
||||
- (BOOL)_shouldDragTableColumn:(CPInteger)aColumnIndex at:(CGPoint)aPoint
|
||||
{
|
||||
return ABS(aPoint.x - _mouseDownLocation.x) >= 10.0 && [_tableView _sendDelegateShouldReorderColumn:aColumnIndex toColumn:-1];
|
||||
return _canDragColumn && [_tableView allowsColumnReordering] && ABS(aPoint.x - _mouseDownLocation.x) >= CPTableHeaderViewDragTolerance;
|
||||
}
|
||||
|
||||
- (void)_autoscroll:(CPEvent)theEvent localLocation:(CGPoint)theLocation
|
||||
{
|
||||
// Constrain the y coordinate so we don't autoscroll vertically
|
||||
var constrainedLocation = CGPointMake(theLocation.x, CGRectGetMinY([_tableView visibleRect])),
|
||||
constrainedEvent = [CPEvent mouseEventWithType:CPLeftMouseDragged
|
||||
location:[self convertPoint:constrainedLocation toView:nil]
|
||||
modifierFlags:[theEvent modifierFlags]
|
||||
timestamp:[theEvent timestamp]
|
||||
windowNumber:[theEvent windowNumber]
|
||||
context:nil
|
||||
eventNumber:0
|
||||
clickCount:[theEvent clickCount]
|
||||
pressure:[theEvent pressure]];
|
||||
|
||||
[self autoscroll:constrainedEvent];
|
||||
[_tableView autoscroll:constrainedEvent];
|
||||
}
|
||||
|
||||
- (CGRect)_headerRectOfLastVisibleColumn
|
||||
@@ -477,155 +567,203 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (void)_constrainDragView:(CPView)theDragView at:(CGPoint)aPoint
|
||||
- (CGPoint)_constrainDragPoint:(CGPoint)aPoint
|
||||
{
|
||||
var tableColumns = [_tableView tableColumns],
|
||||
// This effectively clamps the value between the minimum and maximum
|
||||
var visibleRect = [_tableView visibleRect],
|
||||
lastColumnRect = [self _headerRectOfLastVisibleColumn],
|
||||
activeColumnRect = [self headerRectOfColumn:_activeColumn],
|
||||
dragWindow = [theDragView window],
|
||||
frame = [dragWindow frame];
|
||||
maxX = CGRectGetMaxX(lastColumnRect) - CGRectGetWidth(activeColumnRect) - CGRectGetMinX(visibleRect),
|
||||
point = CGPointMake(MAX(MIN(aPoint.x, maxX), -CGRectGetMinX(visibleRect)), aPoint.y);
|
||||
|
||||
// Convert the frame origin from the global coordinate system to the windows' coordinate system
|
||||
frame.origin = [[self window] convertGlobalToBase:frame.origin];
|
||||
// the from the window to the view
|
||||
frame.origin = [self convertPoint:frame.origin fromView:nil];
|
||||
|
||||
// This effectively clamps the value between the minimum and maximum
|
||||
frame.origin.x = MAX(0.0, MIN(CGRectGetMinX(frame), CGRectGetMaxX(lastColumnRect) - CGRectGetWidth(activeColumnRect)));
|
||||
|
||||
// Make sure the column cannot move vertically
|
||||
frame.origin.y = CGRectGetMinY(lastColumnRect);
|
||||
|
||||
// Convert the calculated origin back to the window coordinate system
|
||||
frame.origin = [self convertPoint:frame.origin toView:nil];
|
||||
// Then back to the global coordinate system
|
||||
frame.origin = [[self window] convertBaseToGlobal:frame.origin];
|
||||
|
||||
[dragWindow setFrame:frame];
|
||||
return point;
|
||||
}
|
||||
|
||||
- (void)_moveColumn:(CPInteger)aFromIndex toColumn:(CPInteger)aToIndex
|
||||
{
|
||||
if ([_tableView _sendDelegateShouldReorderColumn:aFromIndex toColumn:aToIndex])
|
||||
{
|
||||
[_tableView moveColumn:aFromIndex toColumn:aToIndex];
|
||||
_activeColumn = aToIndex;
|
||||
_pressedColumn = _activeColumn;
|
||||
}
|
||||
}
|
||||
[_tableView moveColumn:aFromIndex toColumn:aToIndex];
|
||||
_activeColumn = aToIndex;
|
||||
_pressedColumn = _activeColumn;
|
||||
|
||||
- (void)draggedView:(CPView)aView beganAt:(CGPoint)aPoint
|
||||
{
|
||||
_isDragging = YES;
|
||||
|
||||
var column = [[_tableView tableColumns] objectAtIndex:_activeColumn];
|
||||
|
||||
[[column headerView] setHidden:YES];
|
||||
[_tableView _setDraggedColumn:column];
|
||||
[_tableView _setDraggedColumn:_activeColumn];
|
||||
|
||||
[self setNeedsDisplay:YES];
|
||||
}
|
||||
|
||||
- (void)draggedView:(CPView)aView movedTo:(CGPoint)aPoint
|
||||
- (BOOL)isDragging
|
||||
{
|
||||
[self _constrainDragView:aView at:aPoint];
|
||||
return _isDragging;
|
||||
}
|
||||
|
||||
var dragWindow = [aView window],
|
||||
dragWindowFrame = [dragWindow frame];
|
||||
- (void)_startDraggingTableColumn:(CPInteger)aColumnIndex at:(CGPoint)aPoint
|
||||
{
|
||||
_isDragging = YES;
|
||||
_columnDragView = [_tableView _dragViewForColumn:aColumnIndex];
|
||||
_previousTrackingLocation = aPoint;
|
||||
|
||||
var hoverPoint = CGPointCreateCopy(aPoint);
|
||||
// Create a new clip view for the drag view that clips to the header + visible content
|
||||
var headerHeight = CGRectGetHeight([self frame]),
|
||||
scrollView = [self enclosingScrollView],
|
||||
contentFrame = [[scrollView contentView] frame];
|
||||
|
||||
if (aPoint.x < _previousTrackingLocation.x)
|
||||
hoverPoint = CGPointMake(CGRectGetMinX(dragWindowFrame), CGRectGetMinY(dragWindowFrame));
|
||||
else if (aPoint.x > _previousTrackingLocation.x)
|
||||
hoverPoint = CGPointMake(CGRectGetMaxX(dragWindowFrame), CGRectGetMinY(dragWindowFrame));
|
||||
contentFrame.origin.y -= headerHeight;
|
||||
contentFrame.size.height += headerHeight;
|
||||
|
||||
// Convert the hover point from the global coordinate system to windows' coordinate system
|
||||
hoverPoint = [[self window] convertGlobalToBase:hoverPoint];
|
||||
// then to the view
|
||||
hoverPoint = [self convertPoint:hoverPoint fromView:nil];
|
||||
_columnDragClipView = [[CPView alloc] initWithFrame:contentFrame];
|
||||
|
||||
var hoveredColumn = [self columnAtPoint:hoverPoint];
|
||||
[_columnDragClipView addSubview:_columnDragView];
|
||||
|
||||
if (hoveredColumn !== _lastDragDestinationColumnIndex && hoveredColumn !== -1)
|
||||
// Insert the clip view above the table header (and content)
|
||||
[scrollView addSubview:_columnDragClipView positioned:CPWindowAbove relativeTo:self];
|
||||
|
||||
// Hide the underlying column header subviews, we just want to draw the chrome
|
||||
var headerView = [[[_tableView tableColumns] objectAtIndex:aColumnIndex] headerView];
|
||||
|
||||
[[headerView subviews] makeObjectsPerformSelector:@selector(setHidden:) withObject:YES];
|
||||
|
||||
// The underlying column header shows normal state
|
||||
[headerView unsetThemeState:CPThemeStateHighlighted | CPThemeStateSelected];
|
||||
|
||||
// Keep track of the location within the column header where the original mousedown occurred
|
||||
_columnDragHeaderView = [_columnDragView viewWithTag:CPTableHeaderViewDragColumnHeaderTag];
|
||||
|
||||
_columnMouseDownLocation = [self convertPoint:_mouseDownLocation toView:_columnDragHeaderView];
|
||||
|
||||
[_tableView _setDraggedColumn:aColumnIndex];
|
||||
|
||||
[[CPCursor closedHandCursor] set];
|
||||
|
||||
[self setNeedsDisplay:YES];
|
||||
}
|
||||
|
||||
- (void)_dragTableColumn:(CPInteger)aColumnIndex to:(CGPoint)aPoint
|
||||
{
|
||||
var delta = aPoint.x - _previousTrackingLocation.x,
|
||||
columnPoint = [_columnDragHeaderView convertPoint:aPoint fromView:self];
|
||||
|
||||
// Only move if the mouse is past the original click point in the direction of movement
|
||||
if ((delta > 0 && columnPoint.x > _columnMouseDownLocation.x) || (delta < 0 && columnPoint.x < _columnMouseDownLocation.x))
|
||||
{
|
||||
var columnRect = [self headerRectOfColumn:hoveredColumn],
|
||||
columnCenterPoint = [self convertPoint:CGPointMake(CGRectGetMidX(columnRect), CGRectGetMidY(columnRect)) fromView:self];
|
||||
var dragFrame = [_columnDragView frame],
|
||||
newOrigin = [self _constrainDragPoint:CGPointMake(CGRectGetMinX(dragFrame) + delta, CGRectGetMinY(dragFrame))];
|
||||
|
||||
if (hoveredColumn < _activeColumn && hoverPoint.x < columnCenterPoint.x)
|
||||
[_columnDragView setFrameOrigin:newOrigin];
|
||||
|
||||
// When the edge of the dragged column passes the midpoint of an adjacent column, they swap
|
||||
var hoverPoint = CGPointMakeCopy(aPoint);
|
||||
|
||||
// The drag frame is in content view coordinates, we need it to be in our coordinates
|
||||
dragFrame = [self convertRect:dragFrame fromView:[_columnDragView superview]];
|
||||
|
||||
if (delta > 0)
|
||||
hoverPoint.x = CGRectGetMaxX(dragFrame);
|
||||
else
|
||||
hoverPoint.x = CGRectGetMinX(dragFrame);
|
||||
|
||||
var hoveredColumn = [self columnAtPoint:hoverPoint];
|
||||
|
||||
if (hoveredColumn !== -1)
|
||||
{
|
||||
[self _moveColumn:_activeColumn toColumn:hoveredColumn];
|
||||
_lastDragDestinationColumnIndex = hoveredColumn;
|
||||
}
|
||||
else if (hoveredColumn > _activeColumn && hoverPoint.x > columnCenterPoint.x)
|
||||
{
|
||||
[self _moveColumn:_activeColumn toColumn:hoveredColumn];
|
||||
_lastDragDestinationColumnIndex = hoveredColumn;
|
||||
var columnRect = [self headerRectOfColumn:hoveredColumn],
|
||||
columnCenterPoint = CGPointMake(CGRectGetMidX(columnRect), CGRectGetMidY(columnRect));
|
||||
|
||||
if (hoveredColumn < _activeColumn && hoverPoint.x < columnCenterPoint.x)
|
||||
[self _moveColumn:_activeColumn toColumn:hoveredColumn];
|
||||
else if (hoveredColumn > _activeColumn && hoverPoint.x > columnCenterPoint.x)
|
||||
[self _moveColumn:_activeColumn toColumn:hoveredColumn];
|
||||
}
|
||||
}
|
||||
|
||||
_previousTrackingLocation = aPoint;
|
||||
}
|
||||
|
||||
- (void)draggedView:(CPImage)aView endedAt:(CGPoint)aLocation operation:(CPDragOperation)anOperation
|
||||
- (void)_stopDraggingTableColumn:(CPInteger)aColumnIndex
|
||||
{
|
||||
_isDragging = NO;
|
||||
_isTrackingColumn = NO; // We need to do this explicitly because the mouse up section of trackMouse is never reached
|
||||
|
||||
[_tableView _setDraggedColumn:nil];
|
||||
[[[[_tableView tableColumns] objectAtIndex:_activeColumn] headerView] setHidden:NO];
|
||||
[self stopTrackingTableColumn:_activeColumn at:aLocation];
|
||||
[_columnDragClipView removeFromSuperview];
|
||||
[_tableView _setDraggedColumn:-1];
|
||||
|
||||
[self setNeedsDisplay:YES];
|
||||
var headerView = [[[_tableView tableColumns] objectAtIndex:aColumnIndex] headerView];
|
||||
|
||||
[_tableView _enqueueDraggingViews];
|
||||
[[headerView subviews] makeObjectsPerformSelector:@selector(setHidden:) withObject:NO];
|
||||
|
||||
if (_tableView._draggedColumnIsSelected)
|
||||
[headerView setThemeState:CPThemeStateSelected];
|
||||
|
||||
var columnRect = [_tableView rectOfColumn:aColumnIndex];
|
||||
|
||||
[_tableView _reloadDataViews];
|
||||
[[_tableView headerView] setNeedsLayout];
|
||||
|
||||
[[CPCursor arrowCursor] set];
|
||||
}
|
||||
|
||||
- (BOOL)shouldResizeTableColumn:(CPInteger)aColumnIndex at:(CGPoint)aPoint
|
||||
- (BOOL)_shouldResizeTableColumn:(CPInteger)aColumnIndex at:(CGPoint)aPoint
|
||||
{
|
||||
if (_isResizing)
|
||||
return YES;
|
||||
|
||||
if (_isTrackingColumn)
|
||||
return NO;
|
||||
|
||||
return [_tableView allowsColumnResizing] && CGRectContainsPoint([self _cursorRectForColumn:aColumnIndex], aPoint);
|
||||
}
|
||||
|
||||
- (void)startResizingTableColumn:(CPInteger)aColumnIndex at:(CGPoint)aPoint
|
||||
- (void)_startResizingTableColumn:(CPInteger)aColumnIndex at:(CGPoint)aPoint
|
||||
{
|
||||
_isResizing = YES;
|
||||
_previousTrackingLocation = aPoint;
|
||||
_activeColumn = aColumnIndex;
|
||||
|
||||
var tableColumn = [[_tableView tableColumns] objectAtIndex:aColumnIndex];
|
||||
|
||||
_columnOldWidth = [tableColumn width];
|
||||
|
||||
[tableColumn setDisableResizingPosting:YES];
|
||||
[_tableView setDisableAutomaticResizing:YES];
|
||||
}
|
||||
|
||||
- (void)continueResizingTableColumn:(CPInteger)aColumnIndex at:(CGPoint)aPoint
|
||||
- (void)_continueResizingTableColumn:(CPInteger)aColumnIndex at:(CGPoint)aPoint
|
||||
{
|
||||
var tableColumn = [[_tableView tableColumns] objectAtIndex:aColumnIndex],
|
||||
newWidth = [tableColumn width] + aPoint.x - _previousTrackingLocation.x;
|
||||
delta = aPoint.x - _previousTrackingLocation.x,
|
||||
spacing = [_tableView intercellSpacing].width,
|
||||
newWidth = [tableColumn width] + spacing + delta,
|
||||
minWidth = [tableColumn minWidth] + spacing,
|
||||
maxWidth = [tableColumn maxWidth] + spacing;
|
||||
|
||||
if (newWidth < [tableColumn minWidth])
|
||||
if (newWidth <= minWidth)
|
||||
[[CPCursor resizeRightCursor] set];
|
||||
else if (newWidth > [tableColumn maxWidth])
|
||||
else if (newWidth >= maxWidth)
|
||||
[[CPCursor resizeLeftCursor] set];
|
||||
else
|
||||
{
|
||||
_tableView._lastColumnShouldSnap = NO;
|
||||
[tableColumn setWidth:newWidth];
|
||||
|
||||
[[CPCursor resizeLeftRightCursor] set];
|
||||
|
||||
var columnRect = [_tableView rectOfColumn:aColumnIndex],
|
||||
columnWidth = CGRectGetWidth(columnRect);
|
||||
|
||||
if ((delta > 0 && columnWidth == maxWidth) || (delta < 0 && columnWidth == minWidth))
|
||||
return;
|
||||
|
||||
var columnMinX = CGRectGetMinX(columnRect),
|
||||
columnMaxX = CGRectGetMaxX(columnRect);
|
||||
|
||||
if ((delta > 0 && aPoint.x > columnMaxX) || (delta < 0 && aPoint.x < columnMaxX))
|
||||
{
|
||||
[tableColumn setWidth:newWidth - spacing];
|
||||
|
||||
[self setNeedsLayout];
|
||||
[self setNeedsDisplay:YES];
|
||||
}
|
||||
|
||||
_previousTrackingLocation = aPoint;
|
||||
}
|
||||
|
||||
- (void)stopResizingTableColumn:(CPInteger)aColumnIndex at:(CGPoint)aPoint
|
||||
- (void)_stopResizingTableColumn:(CPInteger)aColumnIndex
|
||||
{
|
||||
var tableColumn = [[_tableView tableColumns] objectAtIndex:aColumnIndex];
|
||||
[tableColumn _postDidResizeNotificationWithOldWidth:_columnOldWidth];
|
||||
|
||||
if ([tableColumn width] != _columnOldWidth)
|
||||
[_tableView _didResizeTableColumn:tableColumn oldWidth:_columnOldWidth];
|
||||
|
||||
[tableColumn setDisableResizingPosting:NO];
|
||||
[_tableView setDisableAutomaticResizing:NO];
|
||||
|
||||
@@ -642,17 +780,18 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal
|
||||
}
|
||||
|
||||
var mouseLocation = [self convertPoint:[theEvent locationInWindow] fromView:nil],
|
||||
mouseOverLocation = CGPointMake(mouseLocation.x - 5, mouseLocation.y),
|
||||
mouseOverLocation = CGPointMake(MAX(mouseLocation.x - CPTableHeaderViewResizeZone, 0.0), mouseLocation.y),
|
||||
overColumn = [self columnAtPoint:mouseOverLocation];
|
||||
|
||||
if (overColumn >= 0 && CGRectContainsPoint([self _cursorRectForColumn:overColumn], mouseLocation))
|
||||
{
|
||||
var tableColumn = [[_tableView tableColumns] objectAtIndex:overColumn],
|
||||
spacing = [_tableView intercellSpacing].width,
|
||||
width = [tableColumn width];
|
||||
|
||||
if (width == [tableColumn minWidth])
|
||||
if (width <= [tableColumn minWidth])
|
||||
[[CPCursor resizeRightCursor] set];
|
||||
else if (width == [tableColumn maxWidth])
|
||||
else if (width >= [tableColumn maxWidth])
|
||||
[[CPCursor resizeLeftCursor] set];
|
||||
else
|
||||
[[CPCursor resizeLeftRightCursor] set];
|
||||
@@ -661,101 +800,9 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal
|
||||
[[CPCursor arrowCursor] set];
|
||||
}
|
||||
|
||||
- (void)mouseEntered:(CPEvent)theEvent
|
||||
{
|
||||
[self _updateResizeCursor:theEvent];
|
||||
}
|
||||
@end // CPTableView (CPTableViewPrivate)
|
||||
|
||||
- (void)mouseMoved:(CPEvent)theEvent
|
||||
{
|
||||
[self _updateResizeCursor:theEvent];
|
||||
}
|
||||
|
||||
- (void)mouseExited:(CPEvent)theEvent
|
||||
{
|
||||
// FIXME: we should use CPCursor push/pop (if previous currentCursor != arrow).
|
||||
[[CPCursor arrowCursor] set];
|
||||
}
|
||||
|
||||
- (void)layoutSubviews
|
||||
{
|
||||
var tableColumns = [_tableView tableColumns],
|
||||
count = [tableColumns count],
|
||||
lineThickness = [self currentValueForThemeAttribute:@"divider-thickness"];
|
||||
|
||||
for (var i = 0; i < count; i++)
|
||||
{
|
||||
var column = [tableColumns objectAtIndex:i],
|
||||
headerView = [column headerView],
|
||||
frame = [self headerRectOfColumn:i];
|
||||
|
||||
// Make space for the gridline on the right.
|
||||
frame.origin.x -= 0.5;
|
||||
frame.size.width -= lineThickness;
|
||||
frame.size.height -= 0.5;
|
||||
// Note: we're not adding in intercell spacing here. This setting only affects the regular
|
||||
// table cell data views, not the header. Verified in Cocoa on March 29th, 2011.
|
||||
|
||||
[headerView setFrame:frame];
|
||||
|
||||
if ([headerView superview] != self)
|
||||
[self addSubview:headerView];
|
||||
}
|
||||
|
||||
[self setBackgroundColor:[self currentValueForThemeAttribute:@"background-color"]];
|
||||
}
|
||||
|
||||
- (void)drawRect:(CGRect)aRect
|
||||
{
|
||||
if (!_tableView || ![self drawsColumnLines])
|
||||
return;
|
||||
|
||||
var context = [[CPGraphicsContext currentContext] graphicsPort],
|
||||
exposedColumnIndexes = [_tableView columnIndexesInRect:aRect],
|
||||
columnsArray = [],
|
||||
tableColumns = [_tableView tableColumns],
|
||||
exposedTableColumns = _tableView._exposedColumns,
|
||||
firstIndex = [exposedTableColumns firstIndex],
|
||||
exposedRange = CPMakeRange(firstIndex, [exposedTableColumns lastIndex] - firstIndex + 1),
|
||||
lineThickness = [self currentValueForThemeAttribute:@"divider-thickness"];
|
||||
|
||||
CGContextSetLineWidth(context, lineThickness);
|
||||
CGContextSetStrokeColor(context, [self currentValueForThemeAttribute:@"divider-color"]);
|
||||
|
||||
[exposedColumnIndexes getIndexes:columnsArray maxCount:-1 inIndexRange:exposedRange];
|
||||
|
||||
var columnArrayIndex = 0,
|
||||
columnArrayCount = columnsArray.length,
|
||||
columnMaxX;
|
||||
|
||||
CGContextBeginPath(context);
|
||||
|
||||
for (; columnArrayIndex < columnArrayCount; columnArrayIndex++)
|
||||
{
|
||||
// grab each column rect and add vertical lines
|
||||
var columnIndex = columnsArray[columnArrayIndex],
|
||||
columnToStroke = [self headerRectOfColumn:columnIndex];
|
||||
|
||||
columnMaxX = CGRectGetMaxX(columnToStroke);
|
||||
|
||||
CGContextMoveToPoint(context, FLOOR(columnMaxX) - 0.5 * lineThickness, ROUND(CGRectGetMinY(columnToStroke)));
|
||||
CGContextAddLineToPoint(context, FLOOR(columnMaxX) - 0.5 * lineThickness, ROUND(CGRectGetMaxY(columnToStroke)) - 1.0);
|
||||
}
|
||||
|
||||
CGContextClosePath(context);
|
||||
CGContextStrokePath(context);
|
||||
|
||||
/*if (_isDragging)
|
||||
{
|
||||
CGContextSetFillColor(context, [CPColor grayColor]);
|
||||
CGContextFillRect(context, [self headerRectOfColumn:_activeColumn])
|
||||
}*/
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
var CPTableHeaderViewTableViewKey = @"CPTableHeaderViewTableViewKey",
|
||||
CPTableHeaderViewDrawsColumnLines = @"CPTableHeaderViewDrawsColumnLines";
|
||||
var CPTableHeaderViewTableViewKey = @"CPTableHeaderViewTableViewKey";
|
||||
|
||||
@implementation CPTableHeaderView (CPCoding)
|
||||
|
||||
@@ -765,15 +812,6 @@ var CPTableHeaderViewTableViewKey = @"CPTableHeaderViewTableViewKey",
|
||||
{
|
||||
[self _init];
|
||||
_tableView = [aCoder decodeObjectForKey:CPTableHeaderViewTableViewKey];
|
||||
|
||||
// FIX ME: Take this out before 1.0
|
||||
if ([aCoder containsValueForKey:CPTableHeaderViewDrawsColumnLines])
|
||||
_drawsColumnLines = [aCoder decodeBoolForKey:CPTableHeaderViewDrawsColumnLines];
|
||||
else
|
||||
{
|
||||
_drawsColumnLines = YES;
|
||||
CPLog.warn("The tableview header being decoded is using an old cib. Please run Nib2Cib.");
|
||||
}
|
||||
}
|
||||
|
||||
return self;
|
||||
@@ -783,7 +821,6 @@ var CPTableHeaderViewTableViewKey = @"CPTableHeaderViewTableViewKey",
|
||||
{
|
||||
[super encodeWithCoder:aCoder];
|
||||
[aCoder encodeObject:_tableView forKey:CPTableHeaderViewTableViewKey];
|
||||
[aCoder encodeBool:_drawsColumnLines forKey:CPTableHeaderViewDrawsColumnLines];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
+756
-673
File diff suppressed because it is too large
Load Diff
+273
-158
@@ -31,24 +31,32 @@
|
||||
|
||||
@global CPApp
|
||||
@global CPStringPboardType
|
||||
@global CPCursor
|
||||
|
||||
|
||||
@protocol CPTextFieldDelegate <CPControlTextEditingDelegate>
|
||||
|
||||
@end
|
||||
|
||||
var CPTextFieldDelegate_control_didFailToFormatString_errorDescription_ = 1 << 1,
|
||||
CPTextFieldDelegate_controlTextDidBeginEditing_ = 1 << 2,
|
||||
CPTextFieldDelegate_controlTextDidChange_ = 1 << 3,
|
||||
CPTextFieldDelegate_controlTextDidEndEditing_ = 1 << 4,
|
||||
CPTextFieldDelegate_controlTextDidFocus_ = 1 << 5,
|
||||
CPTextFieldDelegate_controlTextDidBlur_ = 1 << 6;
|
||||
|
||||
var CPTextFieldDelegate_control_didFailToFormatString_errorDescription_ = 1 << 1;
|
||||
|
||||
@typedef CPTextFieldBezelStyle
|
||||
CPTextFieldSquareBezel = 0; /*! A textfield bezel with squared corners. */
|
||||
CPTextFieldRoundedBezel = 1; /*! A textfield bezel with rounded corners. */
|
||||
|
||||
CPTextFieldDidFocusNotification = @"CPTextFieldDidFocusNotification";
|
||||
CPTextFieldDidBlurNotification = @"CPTextFieldDidBlurNotification";
|
||||
|
||||
var CPTextFieldDOMInputElement = nil,
|
||||
CPTextFieldDOMPasswordInputElement = nil,
|
||||
var CPTextFieldDOMCurrentElement = nil,
|
||||
CPTextFieldDOMTextAreaElement = nil,
|
||||
CPTextFieldDOMStandardInputElement = nil,
|
||||
CPTextFieldDOMPasswordInputElement = nil,
|
||||
CPTextFieldInputOwner = nil,
|
||||
CPTextFieldTextDidChangeValue = nil,
|
||||
CPTextFieldInputResigning = NO,
|
||||
@@ -141,6 +149,9 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
|
||||
// NS-style Display Properties
|
||||
CPTextFieldBezelStyle _bezelStyle;
|
||||
BOOL _isBordered;
|
||||
BOOL _usesSingleLineMode;
|
||||
BOOL _wraps;
|
||||
BOOL _scrolls;
|
||||
}
|
||||
|
||||
+ (Class)_binderClassForBinding:(CPString)aBinding
|
||||
@@ -239,101 +250,112 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
|
||||
[self _sizeToControlSize];
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
|
||||
#pragma mark -
|
||||
|
||||
#if PLATFORM(DOM)
|
||||
- (DOMElement)_inputElement
|
||||
{
|
||||
if (!CPTextFieldDOMInputElement)
|
||||
if (!CPTextFieldDOMTextAreaElement)
|
||||
{
|
||||
CPTextFieldDOMInputElement = document.createElement("input");
|
||||
CPTextFieldDOMInputElement.style.position = "absolute";
|
||||
CPTextFieldDOMInputElement.style.border = "0px";
|
||||
CPTextFieldDOMInputElement.style.padding = "0px";
|
||||
CPTextFieldDOMInputElement.style.margin = "0px";
|
||||
CPTextFieldDOMInputElement.style.whiteSpace = "pre";
|
||||
CPTextFieldDOMInputElement.style.background = "transparent";
|
||||
CPTextFieldDOMInputElement.style.outline = "none";
|
||||
CPTextFieldDOMTextAreaElement = document.createElement("textarea");
|
||||
CPTextFieldDOMTextAreaElement.style.position = "absolute";
|
||||
CPTextFieldDOMTextAreaElement.style.border = "0px";
|
||||
CPTextFieldDOMTextAreaElement.style.padding = "0px";
|
||||
CPTextFieldDOMTextAreaElement.style.margin = "0px";
|
||||
CPTextFieldDOMTextAreaElement.style.background = "transparent";
|
||||
CPTextFieldDOMTextAreaElement.style.outline = "none";
|
||||
CPTextFieldDOMTextAreaElement.style.resize = "none";
|
||||
CPTextFieldDOMTextAreaElement.style.overflow = "hidden";
|
||||
CPTextFieldDOMTextAreaElement.spellcheck = NO;
|
||||
}
|
||||
|
||||
if (!CPTextFieldDOMStandardInputElement)
|
||||
{
|
||||
CPTextFieldDOMStandardInputElement = document.createElement("input");
|
||||
CPTextFieldDOMStandardInputElement.style.position = "absolute";
|
||||
CPTextFieldDOMStandardInputElement.style.border = "0px";
|
||||
CPTextFieldDOMStandardInputElement.style.padding = "0px";
|
||||
CPTextFieldDOMStandardInputElement.style.margin = "0px";
|
||||
CPTextFieldDOMStandardInputElement.style.whiteSpace = "pre";
|
||||
CPTextFieldDOMStandardInputElement.style.background = "transparent";
|
||||
CPTextFieldDOMStandardInputElement.style.outline = "none";
|
||||
CPTextFieldDOMStandardInputElement.spellcheck = NO;
|
||||
}
|
||||
|
||||
if (!CPTextFieldDOMPasswordInputElement)
|
||||
{
|
||||
CPTextFieldDOMPasswordInputElement = document.createElement("input");
|
||||
CPTextFieldDOMPasswordInputElement.style.position = "absolute";
|
||||
CPTextFieldDOMPasswordInputElement.style.border = "0px";
|
||||
CPTextFieldDOMPasswordInputElement.style.padding = "0px";
|
||||
CPTextFieldDOMPasswordInputElement.style.margin = "0px";
|
||||
CPTextFieldDOMPasswordInputElement.style.whiteSpace = "pre";
|
||||
CPTextFieldDOMPasswordInputElement.style.background = "transparent";
|
||||
CPTextFieldDOMPasswordInputElement.style.outline = "none";
|
||||
CPTextFieldDOMPasswordInputElement.type = "password";
|
||||
CPTextFieldDOMPasswordInputElement.spellcheck = NO;
|
||||
}
|
||||
|
||||
if (!CPTextFieldBlurHandler)
|
||||
{
|
||||
CPTextFieldBlurHandler = function(anEvent)
|
||||
{
|
||||
return CPTextFieldBlurFunction(
|
||||
anEvent,
|
||||
CPTextFieldInputOwner,
|
||||
CPTextFieldInputOwner ? CPTextFieldInputOwner._DOMElement : nil,
|
||||
CPTextFieldDOMInputElement,
|
||||
CPTextFieldDOMCurrentElement,
|
||||
CPTextFieldInputResigning,
|
||||
@ref(CPTextFieldInputDidBlur));
|
||||
};
|
||||
}
|
||||
|
||||
if (CPFeatureIsCompatible(CPInputOnInputEventFeature))
|
||||
if (!CPTextFieldInputFunction)
|
||||
{
|
||||
if (!CPFeatureIsCompatible(CPInputOnInputEventFeature))
|
||||
return;
|
||||
|
||||
CPTextFieldInputFunction = function(anEvent)
|
||||
{
|
||||
CPTextFieldInputFunction = function(anEvent)
|
||||
{
|
||||
if (!CPTextFieldInputOwner)
|
||||
return;
|
||||
if (!CPTextFieldInputOwner)
|
||||
return;
|
||||
|
||||
var cappEvent = [CPEvent keyEventWithType:CPKeyUp
|
||||
location:CGPointMakeZero()
|
||||
modifierFlags:0
|
||||
timestamp:[CPEvent currentTimestamp]
|
||||
windowNumber:[[CPApp keyWindow] windowNumber]
|
||||
context:nil
|
||||
characters:nil
|
||||
charactersIgnoringModifiers:nil
|
||||
isARepeat:NO
|
||||
keyCode:nil];
|
||||
var cappEvent = [CPEvent keyEventWithType:CPKeyUp
|
||||
location:CGPointMakeZero()
|
||||
modifierFlags:0
|
||||
timestamp:[CPEvent currentTimestamp]
|
||||
windowNumber:[[CPApp keyWindow] windowNumber]
|
||||
context:nil
|
||||
characters:nil
|
||||
charactersIgnoringModifiers:nil
|
||||
isARepeat:NO
|
||||
keyCode:nil];
|
||||
|
||||
[CPTextFieldInputOwner keyUp:cappEvent];
|
||||
[CPTextFieldInputOwner keyUp:cappEvent];
|
||||
|
||||
[[CPRunLoop currentRunLoop] limitDateForMode:CPDefaultRunLoopMode];
|
||||
}
|
||||
|
||||
CPTextFieldDOMInputElement.oninput = CPTextFieldInputFunction;
|
||||
[[CPRunLoop currentRunLoop] limitDateForMode:CPDefaultRunLoopMode];
|
||||
}
|
||||
|
||||
// FIXME make this not onblur
|
||||
CPTextFieldDOMInputElement.onblur = CPTextFieldBlurHandler;
|
||||
CPTextFieldDOMPasswordInputElement.oninput = CPTextFieldInputFunction;
|
||||
CPTextFieldDOMPasswordInputElement.onblur = CPTextFieldBlurHandler;
|
||||
|
||||
CPTextFieldDOMStandardInputElement = CPTextFieldDOMInputElement;
|
||||
CPTextFieldDOMStandardInputElement.oninput = CPTextFieldInputFunction;
|
||||
CPTextFieldDOMPasswordInputElement.onblur = CPTextFieldBlurHandler;
|
||||
|
||||
CPTextFieldDOMTextAreaElement.oninput = CPTextFieldInputFunction;
|
||||
CPTextFieldDOMTextAreaElement.onblur = CPTextFieldBlurHandler;
|
||||
}
|
||||
|
||||
if (CPFeatureIsCompatible(CPInputTypeCanBeChangedFeature))
|
||||
{
|
||||
if ([self isSecure])
|
||||
CPTextFieldDOMInputElement.type = "password";
|
||||
else
|
||||
CPTextFieldDOMInputElement.type = "text";
|
||||
|
||||
return CPTextFieldDOMInputElement;
|
||||
}
|
||||
|
||||
if ([self isSecure])
|
||||
{
|
||||
if (!CPTextFieldDOMPasswordInputElement)
|
||||
{
|
||||
CPTextFieldDOMPasswordInputElement = document.createElement("input");
|
||||
CPTextFieldDOMPasswordInputElement.style.position = "absolute";
|
||||
CPTextFieldDOMPasswordInputElement.style.border = "0px";
|
||||
CPTextFieldDOMPasswordInputElement.style.padding = "0px";
|
||||
CPTextFieldDOMPasswordInputElement.style.margin = "0px";
|
||||
CPTextFieldDOMPasswordInputElement.style.whiteSpace = "pre";
|
||||
CPTextFieldDOMPasswordInputElement.style.background = "transparent";
|
||||
CPTextFieldDOMPasswordInputElement.style.outline = "none";
|
||||
CPTextFieldDOMPasswordInputElement.type = "password";
|
||||
|
||||
CPTextFieldDOMPasswordInputElement.onblur = CPTextFieldBlurHandler;
|
||||
}
|
||||
|
||||
CPTextFieldDOMInputElement = CPTextFieldDOMPasswordInputElement;
|
||||
}
|
||||
CPTextFieldDOMCurrentElement = CPTextFieldDOMPasswordInputElement;
|
||||
else if (_usesSingleLineMode)
|
||||
CPTextFieldDOMCurrentElement = CPTextFieldDOMStandardInputElement;
|
||||
else
|
||||
{
|
||||
CPTextFieldDOMInputElement = CPTextFieldDOMStandardInputElement;
|
||||
}
|
||||
CPTextFieldDOMCurrentElement = CPTextFieldDOMTextAreaElement;
|
||||
|
||||
return CPTextFieldDOMInputElement;
|
||||
return CPTextFieldDOMCurrentElement;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -552,6 +574,24 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
|
||||
return _textFieldBackgroundColor;
|
||||
}
|
||||
|
||||
/*! @ignore */
|
||||
- (void)_setUsesSingleLineMode:(BOOL)aFlag
|
||||
{
|
||||
_usesSingleLineMode = aFlag;
|
||||
}
|
||||
|
||||
/*! @ignore */
|
||||
- (void)_setWraps:(BOOL)aFlag
|
||||
{
|
||||
_wraps = aFlag;
|
||||
}
|
||||
|
||||
/*! @ignore */
|
||||
- (void)_setScrolls:(BOOL)aFlag
|
||||
{
|
||||
_scrolls = aFlag;
|
||||
}
|
||||
|
||||
/*! @ignore */
|
||||
- (BOOL)acceptsFirstResponder
|
||||
{
|
||||
@@ -607,28 +647,10 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
|
||||
|
||||
[self _setCSSStyleForInputElement];
|
||||
|
||||
var element = [self _inputElement],
|
||||
font = [self currentValueForThemeAttribute:@"font"],
|
||||
contentRect = [self contentRectForBounds:[self bounds]],
|
||||
left = CGRectGetMinX(contentRect);
|
||||
|
||||
var element = [self _inputElement];
|
||||
element.value = _stringValue;
|
||||
|
||||
// If the browser has a built in left padding, compensate for it. We need the input text to be exactly on top of the original text.
|
||||
if (CPFeatureIsCompatible(CPInput1PxLeftPadding))
|
||||
left -= 1;
|
||||
|
||||
element.style.left = left + "px";
|
||||
element.style.width = CGRectGetWidth(contentRect) + "px";
|
||||
element.style.verticalAlign = "top";
|
||||
element.style.cursor = "auto";
|
||||
|
||||
_DOMElement.appendChild(element);
|
||||
|
||||
// The font change above doesn't work for some browsers if the element isn't already appendChild'ed.
|
||||
if (!CPFeatureIsCompatible(CPInputSetFontOutsideOfDOM))
|
||||
element.style.font = [font cssString];
|
||||
|
||||
CPTextFieldInputIsActive = YES;
|
||||
|
||||
if (document.attachEvent)
|
||||
@@ -672,37 +694,18 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
|
||||
*/
|
||||
- (void)_setCSSStyleForInputElement
|
||||
{
|
||||
|
||||
#if PLATFORM(DOM)
|
||||
var element = [self _inputElement],
|
||||
font = [self currentValueForThemeAttribute:@"font"],
|
||||
lineHeight = [font defaultLineHeightForFont],
|
||||
contentRect = [self contentRectForBounds:[self bounds]],
|
||||
verticalAlign = [self currentValueForThemeAttribute:"vertical-alignment"];
|
||||
|
||||
if ([self hasThemeState:CPTextFieldStatePlaceholder])
|
||||
element.style.color = [[self valueForThemeAttribute:@"text-color" inState:CPTextFieldStatePlaceholder] cssString];
|
||||
else
|
||||
element.style.color = [[self valueForThemeAttribute:@"text-color" inState:CPThemeStateEditing] cssString];
|
||||
var element = [self _inputElement],
|
||||
font = [self currentValueForThemeAttribute:@"font"],
|
||||
lineHeight = [font defaultLineHeightForFont],
|
||||
contentRect = [self contentRectForBounds:[self bounds]],
|
||||
verticalAlign = [self currentValueForThemeAttribute:"vertical-alignment"],
|
||||
left = CGRectGetMinX(contentRect);
|
||||
|
||||
if (CPFeatureIsCompatible(CPInputSetFontOutsideOfDOM))
|
||||
element.style.font = [font cssString];
|
||||
|
||||
element.style.zIndex = 1000;
|
||||
|
||||
switch ([self alignment])
|
||||
{
|
||||
case CPCenterTextAlignment:
|
||||
element.style.textAlign = "center";
|
||||
break;
|
||||
|
||||
case CPRightTextAlignment:
|
||||
element.style.textAlign = "right";
|
||||
break;
|
||||
|
||||
default:
|
||||
element.style.textAlign = "left";
|
||||
}
|
||||
// If the browser has a built in left padding, compensate for it. We need the input text to be exactly on top of the original text.
|
||||
if (CPFeatureIsCompatible(CPInput1PxLeftPadding))
|
||||
left -= 1;
|
||||
|
||||
switch (verticalAlign)
|
||||
{
|
||||
@@ -723,12 +726,41 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
|
||||
break;
|
||||
}
|
||||
|
||||
element.style.top = topPoint;
|
||||
element.style.height = ROUND(lineHeight) + "px";
|
||||
element.style.lineHeight = ROUND(lineHeight) + "px";
|
||||
if ([self hasThemeState:CPTextFieldStatePlaceholder])
|
||||
element.style.color = [[self valueForThemeAttribute:@"text-color" inState:CPTextFieldStatePlaceholder] cssString];
|
||||
else
|
||||
element.style.color = [[self valueForThemeAttribute:@"text-color" inState:CPThemeStateEditing] cssString];
|
||||
|
||||
switch ([self alignment])
|
||||
{
|
||||
case CPCenterTextAlignment:
|
||||
element.style.textAlign = "center";
|
||||
break;
|
||||
|
||||
case CPRightTextAlignment:
|
||||
element.style.textAlign = "right";
|
||||
break;
|
||||
|
||||
default:
|
||||
element.style.textAlign = "left";
|
||||
}
|
||||
|
||||
var isTextArea = element.nodeName.toUpperCase() == "TEXTAREA";
|
||||
|
||||
element.style.zIndex = 1000;
|
||||
element.style.top = topPoint;
|
||||
element.style.lineHeight = ROUND(lineHeight) + "px";
|
||||
element.style.height = isTextArea ? CGRectGetHeight(contentRect) + "px" : ROUND(lineHeight) + "px";;
|
||||
element.style.width = CGRectGetWidth(contentRect) + "px";
|
||||
element.style.left = left + "px";
|
||||
element.style.verticalAlign = "top";
|
||||
element.style.cursor = "auto";
|
||||
element.style.font = [font cssString];
|
||||
|
||||
if (isTextArea)
|
||||
element.style.whiteSpace = _wraps ? "pre" : "nowrap";
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
/*! @ignore */
|
||||
@@ -834,6 +866,26 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
|
||||
}
|
||||
}
|
||||
|
||||
- (void)_removeObservers
|
||||
{
|
||||
if (!_isObserving)
|
||||
return;
|
||||
|
||||
[super _removeObservers];
|
||||
[self _setObserveWindowKeyNotifications:NO];
|
||||
}
|
||||
|
||||
- (void)_addObservers
|
||||
{
|
||||
if (_isObserving)
|
||||
return;
|
||||
|
||||
[super _addObservers];
|
||||
|
||||
if ([[self window] firstResponder] === self)
|
||||
[self _setObserveWindowKeyNotifications:YES];
|
||||
}
|
||||
|
||||
- (void)_windowDidResignKey:(CPNotification)aNotification
|
||||
{
|
||||
if (![[self window] isKeyWindow])
|
||||
@@ -902,6 +954,12 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
|
||||
[self textDidChange:[CPNotification notificationWithName:CPControlTextDidChangeNotification object:self userInfo:nil]];
|
||||
}
|
||||
|
||||
- (void)mouseMoved:(CPEvent)anEvent
|
||||
{
|
||||
[super mouseMoved:anEvent];
|
||||
[self _updateCursorForEvent:anEvent];
|
||||
}
|
||||
|
||||
- (void)mouseDown:(CPEvent)anEvent
|
||||
{
|
||||
// Don't track! (ever?)
|
||||
@@ -1072,7 +1130,11 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
|
||||
range = [self selectedRange],
|
||||
element = [self _inputElement];
|
||||
|
||||
element.value = [element.value stringByReplacingCharactersInRange:[self selectedRange] withString:aCharacter];
|
||||
// we don't need to do this in case of textarea
|
||||
// or we will end up with 2 carriage returns
|
||||
if (aCharacter != CPNewlineCharacter || element.nodeName.toUpperCase() != "TEXTAREA" || !CPFeatureIsCompatible(CPAltEnterTextAreaFeature))
|
||||
element.value = [element.value stringByReplacingCharactersInRange:[self selectedRange] withString:aCharacter];
|
||||
|
||||
[self _setStringValue:element.value];
|
||||
|
||||
// NOTE: _stringValue is now the current input element value
|
||||
@@ -1090,6 +1152,9 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
|
||||
if ([note object] != self)
|
||||
return;
|
||||
|
||||
if (_implementedDelegateMethods & CPTextFieldDelegate_controlTextDidBlur_)
|
||||
[_delegate controlTextDidBlur:note];
|
||||
|
||||
[[CPNotificationCenter defaultCenter] postNotification:note];
|
||||
}
|
||||
|
||||
@@ -1099,6 +1164,9 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
|
||||
if ([note object] != self)
|
||||
return;
|
||||
|
||||
if (_implementedDelegateMethods & CPTextFieldDelegate_controlTextDidFocus_)
|
||||
[_delegate controlTextDidFocus:note];
|
||||
|
||||
[[CPNotificationCenter defaultCenter] postNotification:note];
|
||||
}
|
||||
|
||||
@@ -1109,9 +1177,57 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
|
||||
|
||||
[self _continuouslyReverseSetBinding];
|
||||
|
||||
if (_implementedDelegateMethods & CPTextFieldDelegate_controlTextDidChange_)
|
||||
[_delegate controlTextDidChange:note];
|
||||
|
||||
[super textDidChange:note];
|
||||
}
|
||||
|
||||
- (void)textDidBeginEditing:(CPNotification)note
|
||||
{
|
||||
//this looks to prevent false propagation of notifications for other objects
|
||||
if ([note object] != self)
|
||||
return;
|
||||
|
||||
if (_implementedDelegateMethods & CPTextFieldDelegate_controlTextDidBeginEditing_)
|
||||
[_delegate controlTextDidBeginEditing:[[CPNotification alloc] initWithName:CPControlTextDidBeginEditingNotification object:self userInfo:@{"CPFieldEditor": [note object]}]]
|
||||
|
||||
[super textDidBeginEditing:note];
|
||||
}
|
||||
|
||||
- (void)textDidEndEditing:(CPNotification)note
|
||||
{
|
||||
//this looks to prevent false propagation of notifications for other objects
|
||||
if ([note object] != self)
|
||||
return;
|
||||
|
||||
[super textDidEndEditing:note];
|
||||
|
||||
if (_implementedDelegateMethods & CPTextFieldDelegate_controlTextDidEndEditing_)
|
||||
[_delegate controlTextDidEndEditing:note];
|
||||
}
|
||||
|
||||
- (void)_updateCursorForEvent:(CPEvent)anEvent
|
||||
{
|
||||
var frame = CGRectMakeCopy([self frame]),
|
||||
contentInset = [self currentValueForThemeAttribute:@"content-inset"];
|
||||
|
||||
frame = [[self superview] convertRectToBase:CGRectInsetByInset(frame, contentInset)];
|
||||
|
||||
if ([self isEnabled] && ([self isSelectable] || [self isEditable]) && CGRectContainsPoint(frame, [anEvent locationInWindow]))
|
||||
{
|
||||
#if PLATFORM(DOM)
|
||||
self._DOMElement.style.cursor = "text";
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
#if PLATFORM(DOM)
|
||||
self._DOMElement.style.cursor = "default";
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the string in the text field.
|
||||
*/
|
||||
@@ -1635,17 +1751,8 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
|
||||
|
||||
- (void)setDelegate:(id <CPTextFieldDelegate>)aDelegate
|
||||
{
|
||||
var defaultCenter = [CPNotificationCenter defaultCenter];
|
||||
|
||||
//unsubscribe the existing delegate if it exists
|
||||
if (_delegate)
|
||||
{
|
||||
[defaultCenter removeObserver:_delegate name:CPControlTextDidBeginEditingNotification object:self];
|
||||
[defaultCenter removeObserver:_delegate name:CPControlTextDidChangeNotification object:self];
|
||||
[defaultCenter removeObserver:_delegate name:CPControlTextDidEndEditingNotification object:self];
|
||||
[defaultCenter removeObserver:_delegate name:CPTextFieldDidFocusNotification object:self];
|
||||
[defaultCenter removeObserver:_delegate name:CPTextFieldDidBlurNotification object:self];
|
||||
}
|
||||
if (_delegate === aDelegate)
|
||||
return;
|
||||
|
||||
_delegate = aDelegate;
|
||||
_implementedDelegateMethods = 0;
|
||||
@@ -1654,40 +1761,19 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
|
||||
_implementedDelegateMethods |= CPTextFieldDelegate_control_didFailToFormatString_errorDescription_
|
||||
|
||||
if ([_delegate respondsToSelector:@selector(controlTextDidBeginEditing:)])
|
||||
[defaultCenter
|
||||
addObserver:_delegate
|
||||
selector:@selector(controlTextDidBeginEditing:)
|
||||
name:CPControlTextDidBeginEditingNotification
|
||||
object:self];
|
||||
_implementedDelegateMethods |= CPTextFieldDelegate_controlTextDidBeginEditing_;
|
||||
|
||||
if ([_delegate respondsToSelector:@selector(controlTextDidChange:)])
|
||||
[defaultCenter
|
||||
addObserver:_delegate
|
||||
selector:@selector(controlTextDidChange:)
|
||||
name:CPControlTextDidChangeNotification
|
||||
object:self];
|
||||
|
||||
_implementedDelegateMethods |= CPTextFieldDelegate_controlTextDidChange_;
|
||||
|
||||
if ([_delegate respondsToSelector:@selector(controlTextDidEndEditing:)])
|
||||
[defaultCenter
|
||||
addObserver:_delegate
|
||||
selector:@selector(controlTextDidEndEditing:)
|
||||
name:CPControlTextDidEndEditingNotification
|
||||
object:self];
|
||||
_implementedDelegateMethods |= CPTextFieldDelegate_controlTextDidEndEditing_;
|
||||
|
||||
if ([_delegate respondsToSelector:@selector(controlTextDidFocus:)])
|
||||
[defaultCenter
|
||||
addObserver:_delegate
|
||||
selector:@selector(controlTextDidFocus:)
|
||||
name:CPTextFieldDidFocusNotification
|
||||
object:self];
|
||||
_implementedDelegateMethods |= CPTextFieldDelegate_controlTextDidFocus_;
|
||||
|
||||
if ([_delegate respondsToSelector:@selector(controlTextDidBlur:)])
|
||||
[defaultCenter
|
||||
addObserver:_delegate
|
||||
selector:@selector(controlTextDidBlur:)
|
||||
name:CPTextFieldDidBlurNotification
|
||||
object:self];
|
||||
_implementedDelegateMethods |= CPTextFieldDelegate_controlTextDidBlur_;
|
||||
}
|
||||
|
||||
- (id)delegate
|
||||
@@ -1896,7 +1982,11 @@ var CPTextFieldIsEditableKey = "CPTextFieldIsEditableKey",
|
||||
CPTextFieldLineBreakModeKey = "CPTextFieldLineBreakModeKey",
|
||||
CPTextFieldAlignmentKey = "CPTextFieldAlignmentKey",
|
||||
CPTextFieldBackgroundColorKey = "CPTextFieldBackgroundColorKey",
|
||||
CPTextFieldPlaceholderStringKey = "CPTextFieldPlaceholderStringKey";
|
||||
CPTextFieldPlaceholderStringKey = "CPTextFieldPlaceholderStringKey",
|
||||
CPTextFieldUsesSingleLineMode = "CPTextFieldUsesSingleLineMode",
|
||||
CPTextFieldWraps = "CPTextFieldWraps",
|
||||
CPTextFieldScrolls = "CPTextFieldScrolls";
|
||||
|
||||
|
||||
@implementation CPTextField (CPCoding)
|
||||
|
||||
@@ -1922,6 +2012,10 @@ var CPTextFieldIsEditableKey = "CPTextFieldIsEditableKey",
|
||||
[self setAlignment:[aCoder decodeIntForKey:CPTextFieldAlignmentKey]];
|
||||
|
||||
[self setPlaceholderString:[aCoder decodeObjectForKey:CPTextFieldPlaceholderStringKey]];
|
||||
|
||||
[self _setUsesSingleLineMode:[aCoder decodeBoolForKey:CPTextFieldUsesSingleLineMode]];
|
||||
[self _setWraps:[aCoder decodeBoolForKey:CPTextFieldWraps]];
|
||||
[self _setScrolls:[aCoder decodeBoolForKey:CPTextFieldScrolls]];
|
||||
}
|
||||
|
||||
return self;
|
||||
@@ -1946,6 +2040,10 @@ var CPTextFieldIsEditableKey = "CPTextFieldIsEditableKey",
|
||||
[aCoder encodeInt:[self alignment] forKey:CPTextFieldAlignmentKey];
|
||||
|
||||
[aCoder encodeObject:_placeholderString forKey:CPTextFieldPlaceholderStringKey];
|
||||
|
||||
[aCoder encodeBool:_usesSingleLineMode forKey:CPTextFieldUsesSingleLineMode];
|
||||
[aCoder encodeBool:_wraps forKey:CPTextFieldWraps];
|
||||
[aCoder encodeBool:_scrolls forKey:CPTextFieldScrolls];
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -1976,6 +2074,23 @@ var CPTextFieldIsEditableKey = "CPTextFieldIsEditableKey",
|
||||
[_source setObjectValue:aValue];
|
||||
}
|
||||
|
||||
- (void)reverseSetValueFor:(CPString)aBinding
|
||||
{
|
||||
var destination = [_info objectForKey:CPObservedObjectKey],
|
||||
keyPath = [_info objectForKey:CPObservedKeyPathKey],
|
||||
options = [_info objectForKey:CPOptionsKey],
|
||||
newValue = [self valueForBinding:aBinding],
|
||||
value = [destination valueForKeyPath:keyPath];
|
||||
|
||||
if (CPIsControllerMarker(value) && newValue === nil) return;
|
||||
|
||||
newValue = [self reverseTransformValue:newValue withOptions:options];
|
||||
|
||||
[self suppressSpecificNotificationFromObject:destination keyPath:keyPath];
|
||||
[destination setValue:newValue forKeyPath:keyPath];
|
||||
[self unsuppressSpecificNotificationFromObject:destination keyPath:keyPath];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation _CPTextFieldPatternValueBinder : CPValueWithPatternBinding
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
@import <Foundation/CPKeyedUnarchiver.j>
|
||||
|
||||
@class CPView
|
||||
@class _CPThemeAttribute
|
||||
|
||||
var CPThemesByName = { },
|
||||
CPThemeDefaultTheme = nil,
|
||||
|
||||
@@ -33,6 +33,9 @@
|
||||
@import "CPTextField.j"
|
||||
@import "CPWindow_Constants.j"
|
||||
|
||||
@class _CPTokenFieldTokenCloseButton
|
||||
@class _CPTokenFieldTokenDisclosureButton
|
||||
|
||||
@global CPApp
|
||||
@global CPTextFieldDidFocusNotification
|
||||
@global CPTextFieldDidBlurNotification
|
||||
|
||||
+3
-1
@@ -37,6 +37,8 @@ var CPToolbarDelegate_toolbar_itemForItemIdentifier_willBeInsertedIntoToolbar_
|
||||
CPToolbarDelegate_toolbarSelectableItemIdentifiers_ = 1 << 4,
|
||||
CPToolbarDelegate_toolbarWillAddItem_ = 1 << 5;
|
||||
|
||||
|
||||
@typedef CPToolbarDisplayMode
|
||||
/*
|
||||
@global
|
||||
@group CPToolbarDisplayMode
|
||||
@@ -58,7 +60,7 @@ CPToolbarDisplayModeIconOnly = 2;
|
||||
*/
|
||||
CPToolbarDisplayModeLabelOnly = 3;
|
||||
|
||||
|
||||
@typedef CPToolbarSizeMode
|
||||
CPToolbarSizeModeDefault = 0;
|
||||
CPToolbarSizeModeRegular = 1;
|
||||
CPToolbarSizeModeSmall = 2;
|
||||
|
||||
+107
-35
@@ -40,9 +40,12 @@
|
||||
@class CPMenu
|
||||
@class CPClipView
|
||||
@class CPScrollView
|
||||
@class CALayer
|
||||
|
||||
@global appkit_tag_dom_elements
|
||||
|
||||
@typedef _CPViewFullScreenModeState
|
||||
|
||||
#if PLATFORM(DOM)
|
||||
|
||||
if (typeof(appkit_tag_dom_elements) !== "undefined" && appkit_tag_dom_elements)
|
||||
@@ -174,6 +177,7 @@ var CPViewHighDPIDrawingEnabled = YES;
|
||||
BOOL _postsBoundsChangedNotifications;
|
||||
BOOL _inhibitFrameAndBoundsChangedNotifications;
|
||||
BOOL _inLiveResize;
|
||||
BOOL _isSuperviewAClipView;
|
||||
|
||||
#if PLATFORM(DOM)
|
||||
DOMElement _DOMElement;
|
||||
@@ -234,6 +238,8 @@ var CPViewHighDPIDrawingEnabled = YES;
|
||||
Function _toolTipFunctionIn;
|
||||
Function _toolTipFunctionOut;
|
||||
BOOL _toolTipInstalled;
|
||||
|
||||
BOOL _isObserving;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -532,8 +538,12 @@ var CPViewHighDPIDrawingEnabled = YES;
|
||||
[CPException raise:CPInvalidArgumentException reason:"can't insert a subview in duplicate (probably partially decoded)"];
|
||||
#endif
|
||||
|
||||
// Notify the subview that it will be moving.
|
||||
[aSubview viewWillMoveToSuperview:self];
|
||||
|
||||
// We will have to adjust the z-index of all views starting at this index.
|
||||
var count = _subviews.length;
|
||||
var count = _subviews.length,
|
||||
lastWindow;
|
||||
|
||||
// Dirty the key view loop, in case the window wants to auto recalculate it
|
||||
[[self window] _dirtyKeyViewLoop];
|
||||
@@ -561,14 +571,12 @@ var CPViewHighDPIDrawingEnabled = YES;
|
||||
}
|
||||
else
|
||||
{
|
||||
var superview = aSubview._superview;
|
||||
|
||||
lastWindow = [superview window];
|
||||
|
||||
// Remove the view from its previous superview.
|
||||
[aSubview removeFromSuperview];
|
||||
|
||||
// Set the subview's window to our own.
|
||||
[aSubview _setWindow:_window];
|
||||
|
||||
// Notify the subview that it will be moving.
|
||||
[aSubview viewWillMoveToSuperview:self];
|
||||
[aSubview _removeFromSuperview];
|
||||
|
||||
// Set ourselves as the superview.
|
||||
aSubview._superview = self;
|
||||
@@ -601,6 +609,15 @@ var CPViewHighDPIDrawingEnabled = YES;
|
||||
if (![aSubview isHidden] && [self isHiddenOrHasHiddenAncestor])
|
||||
[aSubview _notifyViewDidHide];
|
||||
|
||||
[aSubview viewDidMoveToSuperview];
|
||||
|
||||
// Set the subview's window to our own.
|
||||
if (_window)
|
||||
[aSubview _setWindow:_window];
|
||||
|
||||
if (!_window && lastWindow)
|
||||
[aSubview _setWindow:nil];
|
||||
|
||||
// This method might be called before we are fully unarchived, in which case the theme state isn't set up yet
|
||||
// and none of the below matters anyhow.
|
||||
if (_themeState)
|
||||
@@ -616,8 +633,6 @@ var CPViewHighDPIDrawingEnabled = YES;
|
||||
[aSubview _notifyWindowDidResignKey];
|
||||
}
|
||||
|
||||
[aSubview viewDidMoveToSuperview];
|
||||
|
||||
[self didAddSubview:aSubview];
|
||||
}
|
||||
|
||||
@@ -634,6 +649,18 @@ var CPViewHighDPIDrawingEnabled = YES;
|
||||
Does nothing if there's no container view.
|
||||
*/
|
||||
- (void)removeFromSuperview
|
||||
{
|
||||
var superview = _superview;
|
||||
|
||||
[self viewWillMoveToSuperview:nil];
|
||||
[self _removeFromSuperview];
|
||||
[self viewDidMoveToSuperview];
|
||||
|
||||
if (superview)
|
||||
[self _setWindow:nil];
|
||||
}
|
||||
|
||||
- (void)_removeFromSuperview
|
||||
{
|
||||
if (!_superview)
|
||||
return;
|
||||
@@ -658,8 +685,6 @@ var CPViewHighDPIDrawingEnabled = YES;
|
||||
[self _notifyViewDidResignFirstResponder];
|
||||
|
||||
_superview = nil;
|
||||
|
||||
[self _setWindow:nil];
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -669,14 +694,14 @@ var CPViewHighDPIDrawingEnabled = YES;
|
||||
*/
|
||||
- (void)replaceSubview:(CPView)aSubview with:(CPView)aView
|
||||
{
|
||||
if (aSubview._superview !== self)
|
||||
if (aSubview._superview !== self || aSubview === aView)
|
||||
return;
|
||||
|
||||
var index = [_subviews indexOfObjectIdenticalTo:aSubview];
|
||||
|
||||
[aSubview removeFromSuperview];
|
||||
|
||||
[self _insertSubview:aView atIndex:index];
|
||||
|
||||
[aSubview removeFromSuperview];
|
||||
}
|
||||
|
||||
- (void)setSubviews:(CPArray)newSubviews
|
||||
@@ -751,13 +776,10 @@ var CPViewHighDPIDrawingEnabled = YES;
|
||||
/* @ignore */
|
||||
- (void)_setWindow:(CPWindow)aWindow
|
||||
{
|
||||
if (_window === aWindow)
|
||||
return;
|
||||
|
||||
[[self window] _dirtyKeyViewLoop];
|
||||
|
||||
// Clear out first responder if we're the first responder and leaving.
|
||||
if ([_window firstResponder] === self)
|
||||
if ([_window firstResponder] === self && _window != aWindow)
|
||||
[_window makeFirstResponder:nil];
|
||||
|
||||
// Notify the view and its subviews
|
||||
@@ -827,6 +849,12 @@ var CPViewHighDPIDrawingEnabled = YES;
|
||||
*/
|
||||
- (void)viewWillMoveToSuperview:(CPView)aView
|
||||
{
|
||||
_isSuperviewAClipView = [aView isKindOfClass:[CPClipView class]];
|
||||
|
||||
[self _removeObservers];
|
||||
|
||||
if (aView)
|
||||
[self _addObservers];
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -845,6 +873,32 @@ var CPViewHighDPIDrawingEnabled = YES;
|
||||
{
|
||||
}
|
||||
|
||||
- (void)_removeObservers
|
||||
{
|
||||
if (!_isObserving)
|
||||
return;
|
||||
|
||||
var count = [_subviews count];
|
||||
|
||||
while (count--)
|
||||
[_subviews[count] _removeObservers];
|
||||
|
||||
_isObserving = NO;
|
||||
}
|
||||
|
||||
- (void)_addObservers
|
||||
{
|
||||
if (_isObserving)
|
||||
return;
|
||||
|
||||
var count = [_subviews count];
|
||||
|
||||
while (count--)
|
||||
[_subviews[count] _addObservers];
|
||||
|
||||
_isObserving = YES;
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the menu item containing the receiver or one of its ancestor views.
|
||||
@return a menu item, or \c nil if the view or one of its ancestors wasn't found
|
||||
@@ -928,6 +982,9 @@ var CPViewHighDPIDrawingEnabled = YES;
|
||||
|
||||
if (_postsFrameChangedNotifications)
|
||||
[CachedNotificationCenter postNotificationName:CPViewFrameDidChangeNotification object:self];
|
||||
|
||||
if (_isSuperviewAClipView)
|
||||
[[self superview] viewFrameChanged:[[CPNotification alloc] initWithName:CPViewFrameDidChangeNotification object:self userInfo:nil]];
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -990,6 +1047,9 @@ var CPViewHighDPIDrawingEnabled = YES;
|
||||
if (_postsFrameChangedNotifications && !_inhibitFrameAndBoundsChangedNotifications)
|
||||
[CachedNotificationCenter postNotificationName:CPViewFrameDidChangeNotification object:self];
|
||||
|
||||
if (_isSuperviewAClipView && !_inhibitFrameAndBoundsChangedNotifications)
|
||||
[[self superview] viewFrameChanged:[[CPNotification alloc] initWithName:CPViewFrameDidChangeNotification object:self userInfo:nil]];
|
||||
|
||||
#if PLATFORM(DOM)
|
||||
var transform = _superview ? _superview._boundsTransform : NULL;
|
||||
|
||||
@@ -1061,7 +1121,7 @@ var CPViewHighDPIDrawingEnabled = YES;
|
||||
// Make sure to repeat the top and bottom pieces horizontally if they're not the exact width needed.
|
||||
if (top)
|
||||
{
|
||||
CPDomDisplayServerSetStyleBackgroundSize(_DOMImageParts[partIndex], frameSize.width + "px", top + "px");
|
||||
CPDOMDisplayServerSetStyleBackgroundSize(_DOMImageParts[partIndex], frameSize.width + "px", top + "px");
|
||||
CPDOMDisplayServerSetStyleSize(_DOMImageParts[partIndex], size.width, top);
|
||||
partIndex++;
|
||||
}
|
||||
@@ -1069,13 +1129,13 @@ var CPViewHighDPIDrawingEnabled = YES;
|
||||
{
|
||||
var height = frameSize.height - top - bottom;
|
||||
|
||||
CPDomDisplayServerSetStyleBackgroundSize(_DOMImageParts[partIndex], frameSize.width + "px", height + "px");
|
||||
CPDOMDisplayServerSetStyleBackgroundSize(_DOMImageParts[partIndex], frameSize.width + "px", height + "px");
|
||||
CPDOMDisplayServerSetStyleSize(_DOMImageParts[partIndex], size.width, size.height - top - bottom);
|
||||
partIndex++;
|
||||
}
|
||||
if (bottom)
|
||||
{
|
||||
CPDomDisplayServerSetStyleBackgroundSize(_DOMImageParts[partIndex], frameSize.width + "px", bottom + "px");
|
||||
CPDOMDisplayServerSetStyleBackgroundSize(_DOMImageParts[partIndex], frameSize.width + "px", bottom + "px");
|
||||
CPDOMDisplayServerSetStyleSize(_DOMImageParts[partIndex], size.width, bottom);
|
||||
}
|
||||
}
|
||||
@@ -1087,7 +1147,7 @@ var CPViewHighDPIDrawingEnabled = YES;
|
||||
// Make sure to repeat the left and right pieces vertically if they're not the exact height needed.
|
||||
if (left)
|
||||
{
|
||||
CPDomDisplayServerSetStyleBackgroundSize(_DOMImageParts[partIndex], left + "px", frameSize.height + "px");
|
||||
CPDOMDisplayServerSetStyleBackgroundSize(_DOMImageParts[partIndex], left + "px", frameSize.height + "px");
|
||||
CPDOMDisplayServerSetStyleSize(_DOMImageParts[partIndex], left, size.height);
|
||||
partIndex++;
|
||||
}
|
||||
@@ -1095,13 +1155,13 @@ var CPViewHighDPIDrawingEnabled = YES;
|
||||
{
|
||||
var width = (frameSize.width - left - right);
|
||||
|
||||
CPDomDisplayServerSetStyleBackgroundSize(_DOMImageParts[partIndex], width + "px", frameSize.height + "px");
|
||||
CPDOMDisplayServerSetStyleBackgroundSize(_DOMImageParts[partIndex], width + "px", frameSize.height + "px");
|
||||
CPDOMDisplayServerSetStyleSize(_DOMImageParts[partIndex], size.width - left - right, size.height);
|
||||
partIndex++;
|
||||
}
|
||||
if (right)
|
||||
{
|
||||
CPDomDisplayServerSetStyleBackgroundSize(_DOMImageParts[partIndex], right + "px", frameSize.height + "px");
|
||||
CPDOMDisplayServerSetStyleBackgroundSize(_DOMImageParts[partIndex], right + "px", frameSize.height + "px");
|
||||
CPDOMDisplayServerSetStyleSize(_DOMImageParts[partIndex], right, size.height);
|
||||
}
|
||||
}
|
||||
@@ -1151,6 +1211,9 @@ var CPViewHighDPIDrawingEnabled = YES;
|
||||
|
||||
if (_postsFrameChangedNotifications && !_inhibitFrameAndBoundsChangedNotifications)
|
||||
[CachedNotificationCenter postNotificationName:CPViewFrameDidChangeNotification object:self];
|
||||
|
||||
if (_isSuperviewAClipView && !_inhibitFrameAndBoundsChangedNotifications)
|
||||
[[self superview] viewFrameChanged:[[CPNotification alloc] initWithName:CPViewFrameDidChangeNotification object:self userInfo:nil]];
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -1185,6 +1248,9 @@ var CPViewHighDPIDrawingEnabled = YES;
|
||||
|
||||
if (_postsBoundsChangedNotifications)
|
||||
[CachedNotificationCenter postNotificationName:CPViewBoundsDidChangeNotification object:self];
|
||||
|
||||
if (_isSuperviewAClipView)
|
||||
[[self superview] viewBoundsChanged:[[CPNotification alloc] initWithName:CPViewBoundsDidChangeNotification object:self userInfo:nil]];
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -1247,6 +1313,9 @@ var CPViewHighDPIDrawingEnabled = YES;
|
||||
|
||||
if (_postsBoundsChangedNotifications && !_inhibitFrameAndBoundsChangedNotifications)
|
||||
[CachedNotificationCenter postNotificationName:CPViewBoundsDidChangeNotification object:self];
|
||||
|
||||
if (_isSuperviewAClipView && !_inhibitFrameAndBoundsChangedNotifications)
|
||||
[[self superview] viewBoundsChanged:[[CPNotification alloc] initWithName:CPViewBoundsDidChangeNotification object:self userInfo:nil]];
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -1285,6 +1354,9 @@ var CPViewHighDPIDrawingEnabled = YES;
|
||||
|
||||
if (_postsBoundsChangedNotifications && !_inhibitFrameAndBoundsChangedNotifications)
|
||||
[CachedNotificationCenter postNotificationName:CPViewBoundsDidChangeNotification object:self];
|
||||
|
||||
if (_isSuperviewAClipView && !_inhibitFrameAndBoundsChangedNotifications)
|
||||
[[self superview] viewBoundsChanged:[[CPNotification alloc] initWithName:CPViewBoundsDidChangeNotification object:self userInfo:nil]];
|
||||
}
|
||||
|
||||
|
||||
@@ -1843,7 +1915,7 @@ var CPViewHighDPIDrawingEnabled = YES;
|
||||
_DOMImageParts[0].style.background = [_backgroundColor cssString];
|
||||
|
||||
if (patternImage)
|
||||
CPDomDisplayServerSetStyleBackgroundSize(_DOMImageParts[0], [patternImage size].width + "px", [patternImage size].height + "px");
|
||||
CPDOMDisplayServerSetStyleBackgroundSize(_DOMImageParts[0], [patternImage size].width + "px", [patternImage size].height + "px");
|
||||
|
||||
if (CPFeatureIsCompatible(CPOpacityRequiresFilterFeature))
|
||||
_DOMImageParts[0].style.filter = "alpha(opacity=" + [_backgroundColor alphaComponent] * 100 + ")";
|
||||
@@ -1857,7 +1929,7 @@ var CPViewHighDPIDrawingEnabled = YES;
|
||||
_DOMElement.style.background = colorCSS;
|
||||
|
||||
if (patternImage)
|
||||
CPDomDisplayServerSetStyleBackgroundSize(_DOMElement, [patternImage size].width + "px", [patternImage size].height + "px");
|
||||
CPDOMDisplayServerSetStyleBackgroundSize(_DOMElement, [patternImage size].width + "px", [patternImage size].height + "px");
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1962,7 +2034,7 @@ var CPViewHighDPIDrawingEnabled = YES;
|
||||
// Make sure to repeat the top and bottom pieces horizontally if they're not the exact width needed.
|
||||
if (top)
|
||||
{
|
||||
CPDomDisplayServerSetStyleBackgroundSize(_DOMImageParts[partIndex], frameSize.width + "px", top + "px");
|
||||
CPDOMDisplayServerSetStyleBackgroundSize(_DOMImageParts[partIndex], frameSize.width + "px", top + "px");
|
||||
CPDOMDisplayServerSetStyleLeftTop(_DOMImageParts[partIndex], NULL, 0.0, 0.0);
|
||||
CPDOMDisplayServerSetStyleSize(_DOMImageParts[partIndex], frameSize.width, top);
|
||||
partIndex++;
|
||||
@@ -1972,14 +2044,14 @@ var CPViewHighDPIDrawingEnabled = YES;
|
||||
var height = frameSize.height - top - bottom;
|
||||
|
||||
//_DOMImageParts[partIndex].style.backgroundSize = frameSize.width + "px " + height + "px";
|
||||
CPDomDisplayServerSetStyleBackgroundSize(_DOMImageParts[partIndex], frameSize.width + "px", height + "px");
|
||||
CPDOMDisplayServerSetStyleBackgroundSize(_DOMImageParts[partIndex], frameSize.width + "px", height + "px");
|
||||
CPDOMDisplayServerSetStyleLeftTop(_DOMImageParts[partIndex], NULL, 0.0, top);
|
||||
CPDOMDisplayServerSetStyleSize(_DOMImageParts[partIndex], frameSize.width, height);
|
||||
partIndex++;
|
||||
}
|
||||
if (bottom)
|
||||
{
|
||||
CPDomDisplayServerSetStyleBackgroundSize(_DOMImageParts[partIndex], frameSize.width + "px", bottom + "px");
|
||||
CPDOMDisplayServerSetStyleBackgroundSize(_DOMImageParts[partIndex], frameSize.width + "px", bottom + "px");
|
||||
CPDOMDisplayServerSetStyleLeftBottom(_DOMImageParts[partIndex], NULL, 0.0, 0.0);
|
||||
CPDOMDisplayServerSetStyleSize(_DOMImageParts[partIndex], frameSize.width, bottom);
|
||||
}
|
||||
@@ -1994,7 +2066,7 @@ var CPViewHighDPIDrawingEnabled = YES;
|
||||
// Make sure to repeat the left and right pieces vertically if they're not the exact height needed.
|
||||
if (left)
|
||||
{
|
||||
CPDomDisplayServerSetStyleBackgroundSize(_DOMImageParts[partIndex], left + "px", frameSize.height + "px");
|
||||
CPDOMDisplayServerSetStyleBackgroundSize(_DOMImageParts[partIndex], left + "px", frameSize.height + "px");
|
||||
CPDOMDisplayServerSetStyleLeftTop(_DOMImageParts[partIndex], NULL, 0.0, 0.0);
|
||||
CPDOMDisplayServerSetStyleSize(_DOMImageParts[partIndex], left, frameSize.height);
|
||||
partIndex++;
|
||||
@@ -2003,14 +2075,14 @@ var CPViewHighDPIDrawingEnabled = YES;
|
||||
{
|
||||
var width = (frameSize.width - left - right);
|
||||
|
||||
CPDomDisplayServerSetStyleBackgroundSize(_DOMImageParts[partIndex], width + "px", frameSize.height + "px");
|
||||
CPDOMDisplayServerSetStyleBackgroundSize(_DOMImageParts[partIndex], width + "px", frameSize.height + "px");
|
||||
CPDOMDisplayServerSetStyleLeftTop(_DOMImageParts[partIndex], NULL, left, 0.0);
|
||||
CPDOMDisplayServerSetStyleSize(_DOMImageParts[partIndex], width, frameSize.height);
|
||||
partIndex++;
|
||||
}
|
||||
if (right)
|
||||
{
|
||||
CPDomDisplayServerSetStyleBackgroundSize(_DOMImageParts[partIndex], right + "px", frameSize.height + "px");
|
||||
CPDOMDisplayServerSetStyleBackgroundSize(_DOMImageParts[partIndex], right + "px", frameSize.height + "px");
|
||||
CPDOMDisplayServerSetStyleRightTop(_DOMImageParts[partIndex], NULL, 0.0, 0.0);
|
||||
CPDOMDisplayServerSetStyleSize(_DOMImageParts[partIndex], right, frameSize.height);
|
||||
}
|
||||
@@ -2999,10 +3071,10 @@ setBoundsOrigin:
|
||||
|
||||
- (BOOL)unsetThemeState:(ThemeState)aState
|
||||
{
|
||||
if (aState && aState.isa && [aState isKindOfClass:CPArray])
|
||||
if (aState && aState.isa && [aState isKindOfClass:CPArray])
|
||||
aState = CPThemeState.apply(null, aState);
|
||||
|
||||
var oldThemeState = _themeState
|
||||
var oldThemeState = _themeState;
|
||||
_themeState = _themeState.without(aState);
|
||||
|
||||
if (oldThemeState === _themeState)
|
||||
|
||||
@@ -210,6 +210,7 @@ var CPViewControllerCachedCibs;
|
||||
[cibOwner viewControllerDidLoadCib:self];
|
||||
|
||||
_isLoading = NO;
|
||||
_isLazy = NO;
|
||||
[self _viewDidLoad];
|
||||
}
|
||||
else if (_isLazy)
|
||||
|
||||
+4
-1
@@ -23,6 +23,9 @@
|
||||
@import "CPView.j"
|
||||
@import "CPScrollView.j"
|
||||
|
||||
@class CPWebScriptObject
|
||||
|
||||
@typedef Window
|
||||
|
||||
// FIXME: implement these where possible:
|
||||
/*
|
||||
@@ -93,7 +96,7 @@ CPWebViewAppKitScrollMaxPollCount = 3;
|
||||
CPScrollView _scrollView;
|
||||
CPView _frameView;
|
||||
|
||||
IFrame _iframe;
|
||||
DOMElement _iframe;
|
||||
CPString _mainFrameURL;
|
||||
CPArray _backwardStack;
|
||||
CPArray _forwardStack;
|
||||
|
||||
+78
-12
@@ -50,9 +50,15 @@
|
||||
|
||||
@class CPMenu
|
||||
@class CPProgressIndicator
|
||||
@class CPToolbar
|
||||
@class CPWindowController
|
||||
@class _CPWindowFrameAnimation
|
||||
|
||||
@global CPApp
|
||||
|
||||
@typedef _CPWindowFullPlatformWindowSession
|
||||
|
||||
|
||||
@protocol CPWindowDelegate <CPObject>
|
||||
|
||||
@optional
|
||||
@@ -901,16 +907,21 @@ CPTexturedBackgroundWindowMask
|
||||
|
||||
- (void)_orderFront
|
||||
{
|
||||
|
||||
#if PLATFORM(DOM)
|
||||
// -dw- if a sheet is clicked, the parent window should come up too
|
||||
if (_isSheet)
|
||||
[_parentView orderFront:self];
|
||||
|
||||
if (!_isVisible)
|
||||
[self _setFrame:_frame display:YES animate:NO constrainWidth:YES constrainHeight:YES];
|
||||
// Save the boolean since it will be updated in the method order:window:relativeTo:
|
||||
var wasVisible = _isVisible;
|
||||
|
||||
[_platformWindow orderFront:self];
|
||||
[_platformWindow order:CPWindowAbove window:self relativeTo:nil];
|
||||
|
||||
// setFrame is set after ordering the window as this method can send some notifications
|
||||
if (!wasVisible)
|
||||
[self _setFrame:_frame display:YES animate:NO constrainWidth:YES constrainHeight:YES];
|
||||
#endif
|
||||
|
||||
if (!CPApp._keyWindow)
|
||||
@@ -931,6 +942,23 @@ CPTexturedBackgroundWindowMask
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
Called when the window is displayed in the DOM
|
||||
*/
|
||||
- (void)_windowWillBeAddedToTheDOM
|
||||
{
|
||||
[[self contentView] _addObservers];
|
||||
}
|
||||
|
||||
/*
|
||||
Called when the window is removed in the DOM
|
||||
*/
|
||||
- (void)_windowWillBeRemovedFromTheDOM
|
||||
{
|
||||
[[self contentView] _removeObservers];
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Makes the receiver the last window in the screen ordering.
|
||||
@param aSender the object that requested this
|
||||
@@ -977,6 +1005,7 @@ CPTexturedBackgroundWindowMask
|
||||
[_platformWindow order:CPWindowOut window:self relativeTo:nil];
|
||||
#endif
|
||||
|
||||
[self makeFirstResponder:nil];
|
||||
[self _updateMainAndKeyWindows];
|
||||
}
|
||||
|
||||
@@ -1841,6 +1870,12 @@ CPTexturedBackgroundWindowMask
|
||||
if (_leftMouseDownView !== _firstResponder && [_leftMouseDownView acceptsFirstResponder])
|
||||
[self makeFirstResponder:_leftMouseDownView];
|
||||
|
||||
var keyWindow = [CPApp keyWindow];
|
||||
|
||||
// This is only when we move from a platform to another one
|
||||
if ([keyWindow platformWindow] != [self platformWindow])
|
||||
[self makeKeyAndOrderFront:self];
|
||||
|
||||
[CPApp activateIgnoringOtherApps:YES];
|
||||
|
||||
var theWindow = [anEvent window],
|
||||
@@ -2472,7 +2507,7 @@ CPTexturedBackgroundWindowMask
|
||||
if (currentWindow === self || currentWindow === menuWindow)
|
||||
continue;
|
||||
|
||||
if ([currentWindow isVisible] && [currentWindow canBecomeKeyWindow])
|
||||
if ([currentWindow isVisible] && [currentWindow canBecomeKeyWindow] && [currentWindow platformWindow] == [keyWindow platformWindow])
|
||||
{
|
||||
[currentWindow makeKeyWindow];
|
||||
break;
|
||||
@@ -2674,6 +2709,23 @@ CPTexturedBackgroundWindowMask
|
||||
[attachedSheet setFrame:sheetFrame display:YES animate:NO];
|
||||
}
|
||||
|
||||
- (void)_previousSheetIsClosedNotification:(CPNotification)aNotification
|
||||
{
|
||||
[[CPNotificationCenter defaultCenter] removeObserver:self name:CPWindowDidEndSheetNotification object:self];
|
||||
|
||||
var sheet = _sheetContext[@"nextSheet"],
|
||||
modalDelegate =_sheetContext[@"nextModalDelegate"],
|
||||
endSelector = _sheetContext[@"nextEndSelector"],
|
||||
contextInfo = _sheetContext[@"nextContextInfo"];
|
||||
|
||||
// Needed, because when the notification CPWindowDidEndSheetNotification is sent, the sheetContext is not up to date...
|
||||
setTimeout(function()
|
||||
{
|
||||
[sheet._windowView _enableSheet:YES inWindow:self];
|
||||
[self _attachSheet:sheet modalDelegate:modalDelegate didEndSelector:endSelector contextInfo:contextInfo];
|
||||
}, 0)
|
||||
}
|
||||
|
||||
/*
|
||||
Starting point for sheet session, called from CPApplication beginSheet:
|
||||
*/
|
||||
@@ -2682,9 +2734,24 @@ CPTexturedBackgroundWindowMask
|
||||
{
|
||||
if (_sheetContext)
|
||||
{
|
||||
[CPException raise:CPInternalInconsistencyException
|
||||
reason:@"The target window of beginSheet: already has a sheet, did you forget orderOut: ?"];
|
||||
return;
|
||||
// Here we wait till the current sheet is closed
|
||||
if (_sheetContext[@"isClosing"])
|
||||
{
|
||||
// Here we save the next sheet to open
|
||||
_sheetContext[@"nextSheet"] = aSheet;
|
||||
_sheetContext[@"nextModalDelegate"] = aModalDelegate;
|
||||
_sheetContext[@"nextEndSelector"] = didEndSelector;
|
||||
_sheetContext[@"nextContextInfo"] = contextInfo;
|
||||
|
||||
[[CPNotificationCenter defaultCenter] addObserver:self selector:@selector(_previousSheetIsClosedNotification:) name:CPWindowDidEndSheetNotification object:self];
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
[CPException raise:CPInternalInconsistencyException
|
||||
reason:@"The target window of beginSheet: already has a sheet, did you forget orderOut: ?"];
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
_sheetContext = {
|
||||
@@ -2736,7 +2803,12 @@ CPTexturedBackgroundWindowMask
|
||||
*/
|
||||
- (void)_detachSheetWindow
|
||||
{
|
||||
if (_sheetContext["isClosing"])
|
||||
return;
|
||||
|
||||
_sheetContext["isAttached"] = NO;
|
||||
_sheetContext["isClosing"] = YES;
|
||||
_sheetContext["opened"] = NO;
|
||||
|
||||
// A timer seems to be necessary for the animation to work correctly.
|
||||
// It would be ideal to block here and spin the event loop, until attach is complete.
|
||||
@@ -2869,12 +2941,6 @@ CPTexturedBackgroundWindowMask
|
||||
return;
|
||||
}
|
||||
|
||||
if (_sheetContext["isClosing"])
|
||||
return;
|
||||
|
||||
_sheetContext["opened"] = NO;
|
||||
_sheetContext["isClosing"] = YES;
|
||||
|
||||
// The parent window can be orderedOut to disable the sheet animate out, as in Cocoa
|
||||
if ([self isVisible])
|
||||
{
|
||||
|
||||
@@ -81,6 +81,7 @@ CPWindowMinYMargin = 8;
|
||||
CPWindowHeightSizable = 16;
|
||||
CPWindowMaxYMargin = 32;
|
||||
|
||||
@typedef CPWindowLevel
|
||||
CPBackgroundWindowLevel = -1;
|
||||
/*
|
||||
Default level for windows
|
||||
@@ -143,6 +144,7 @@ CPDraggingWindowLevel = 500;
|
||||
*/
|
||||
CPScreenSaverWindowLevel = 1000;
|
||||
|
||||
@typedef CPWindowOrderingMode
|
||||
/*
|
||||
The receiver is placed directly in front of the window specified.
|
||||
@global
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
|
||||
@import "CPCib.j"
|
||||
@import "CPResponder.j"
|
||||
@import "CPViewController.j"
|
||||
@import "CPWindow.j"
|
||||
|
||||
@class CPDocument
|
||||
|
||||
@@ -22,6 +22,8 @@
|
||||
|
||||
@import "CGGeometry.j"
|
||||
|
||||
@typedef CGAffineTransform
|
||||
|
||||
|
||||
function CGAffineTransformMake(a, b, c, d, tx, ty)
|
||||
{
|
||||
|
||||
@@ -20,6 +20,8 @@
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
@typedef CGColorSpace
|
||||
|
||||
kCGColorSpaceModelUnknown = -1;
|
||||
kCGColorSpaceModelMonochrome = 0;
|
||||
kCGColorSpaceModelRGB = 1;
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
@import "CGGeometry.j"
|
||||
@import "CGPath.j"
|
||||
|
||||
@typedef CGContext
|
||||
|
||||
kCGLineCapButt = 0;
|
||||
kCGLineCapRound = 1;
|
||||
@@ -737,7 +738,7 @@ else if (CPFeatureIsCompatible(CPVMLFeature))
|
||||
else
|
||||
{
|
||||
// I have declared these functions here to make it compile without warnings with the new compiler under rhino.
|
||||
CGContextClearRect = CGContextDrawLinearGradient = CGContextClip = CGContextClipToRect = function() {throw new Error("function is not declared in this environment")}
|
||||
CGContextClearRect = CGContextDrawLinearGradient = CGContextClip = CGContextClipToRect = CGContextDrawImage = function() {throw new Error("function is not declared in this environment")}
|
||||
}
|
||||
/*!
|
||||
@endcond
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
@import "CGColor.j"
|
||||
@import "CGColorSpace.j"
|
||||
|
||||
@typedef CGGradient
|
||||
|
||||
kCGGradientDrawsBeforeStartLocation = 1 << 0;
|
||||
kCGGradientDrawsAfterEndLocation = 1 << 1;
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
@import "CGAffineTransform.j"
|
||||
@import "CGGeometry.j"
|
||||
|
||||
@typedef CGPath
|
||||
|
||||
kCGPathElementMoveToPoint = 0;
|
||||
kCGPathElementAddLineToPoint = 1;
|
||||
@@ -629,4 +630,4 @@ function CGPathContainsPoint(aPath, aTransform, point, eoFill)
|
||||
|
||||
/*!
|
||||
@}
|
||||
*/
|
||||
*/
|
||||
|
||||
@@ -27,9 +27,12 @@
|
||||
|
||||
@class CPMenu
|
||||
@class CPPlatformPasteboard
|
||||
@class CPWindow
|
||||
|
||||
@global CPApp
|
||||
|
||||
@typedef DOMWindow
|
||||
|
||||
var PrimaryPlatformWindow = NULL;
|
||||
|
||||
@implementation CPPlatformWindow : CPObject
|
||||
|
||||
@@ -80,7 +80,7 @@ aDOMElement.style.bottom = ROUND(____p.y) + "px";
|
||||
aDOMElement.width = MAX(0.0, ROUND(aWidth));\
|
||||
aDOMElement.height = MAX(0.0, ROUND(aHeight));
|
||||
|
||||
#define CPDomDisplayServerSetStyleBackgroundSize(aDOMElement, aWidth, aHeight)\
|
||||
#define CPDOMDisplayServerSetStyleBackgroundSize(aDOMElement, aWidth, aHeight)\
|
||||
aDOMElement.style.backgroundSize = aWidth + ' ' + aHeight;
|
||||
|
||||
#define CPDOMDisplayServerAppendChild(aParentElement, aChildElement) aParentElement.appendChild(aChildElement)
|
||||
@@ -129,7 +129,7 @@ aDOMElement.style.bottom = ROUND(____p.y) + "px";
|
||||
CPDOMDisplayServerInstructions[__index + 2] = aWidth;\
|
||||
CPDOMDisplayServerInstructions[__index + 3] = aHeight;
|
||||
|
||||
#define CPDomDisplayServerSetStyleBackgroundSize(aDOMElement, aWidth, aHeight)\
|
||||
#define CPDOMDisplayServerSetStyleBackgroundSize(aDOMElement, aWidth, aHeight)\
|
||||
aDOMElement.style.backgroundSize = aWidth + ' ' + aHeight;
|
||||
|
||||
#define CPDOMDisplayServerAppendChild(aParentElement, aChildElement)\
|
||||
|
||||
@@ -1143,7 +1143,7 @@ var PreventScroll = true;
|
||||
|
||||
_mouseDownIsRightClick = button == 2 || (CPBrowserIsOperatingSystem(CPMacOperatingSystem) && button == 0 && modifierFlags & CPControlKeyMask);
|
||||
|
||||
if (sourceElement.tagName === "INPUT" && sourceElement != _DOMFocusElement)
|
||||
if ((sourceElement.tagName === "INPUT" || sourceElement.tagName === "TEXTAREA") && sourceElement != _DOMFocusElement)
|
||||
{
|
||||
if ([CPPlatform supportsDragAndDrop])
|
||||
{
|
||||
@@ -1280,7 +1280,7 @@ var PreventScroll = true;
|
||||
insertionIndex = _windowLevels[middle] > aLevel ? middle : middle + 1
|
||||
|
||||
[_windowLevels insertObject:aLevel atIndex:insertionIndex];
|
||||
layer._DOMElement.style.zIndex = aLevel;
|
||||
layer._DOMElement.style.zIndex = aLevel + 1; // adding one avoids negative zIndices. These have been causing issues in Chrome
|
||||
|
||||
_DOMBodyElement.appendChild(layer._DOMElement);
|
||||
}
|
||||
@@ -1299,7 +1299,10 @@ var PreventScroll = true;
|
||||
// When ordering out, ignore otherWindow, simply remove aWindow from its level.
|
||||
// If layer is nil, this will be a no-op.
|
||||
if (orderingMode === CPWindowOut)
|
||||
{
|
||||
[aWindow _windowWillBeRemovedFromTheDOM];
|
||||
return [layer removeWindow:aWindow];
|
||||
}
|
||||
|
||||
/*
|
||||
If aWindow is a child of otherWindow and is not yet visible,
|
||||
@@ -1345,6 +1348,8 @@ var PreventScroll = true;
|
||||
if (otherWindow)
|
||||
insertionIndex = orderingMode === CPWindowAbove ? otherWindow._index + 1 : otherWindow._index;
|
||||
|
||||
[aWindow _windowWillBeAddedToTheDOM];
|
||||
|
||||
// Place the window at the appropriate index.
|
||||
[layer insertWindow:aWindow atIndex:insertionIndex];
|
||||
|
||||
@@ -1395,6 +1400,9 @@ var PreventScroll = true;
|
||||
|
||||
var index = ordering === CPWindowAbove ? parent._index + 1 : parent._index;
|
||||
|
||||
if (!childWasVisible)
|
||||
[child _windowWillBeAddedToTheDOM];
|
||||
|
||||
[aLayer insertWindow:child atIndex:index];
|
||||
|
||||
if (!childWasVisible)
|
||||
|
||||
@@ -1258,6 +1258,19 @@ var themedButtonValues = nil,
|
||||
["textfield-bezel-square-disabled-8.png", 6.0, 6.0]
|
||||
]),
|
||||
|
||||
bezelFocusedColor = PatternColor(
|
||||
[
|
||||
["textfield-bezel-square-focused-0.png", 6.0, 6.0],
|
||||
["textfield-bezel-square-focused-1.png", 1.0, 6.0],
|
||||
["textfield-bezel-square-focused-2.png", 6.0, 6.0],
|
||||
["textfield-bezel-square-focused-3.png", 6.0, 1.0],
|
||||
["textfield-bezel-square-focused-4.png", 1.0, 1.0],
|
||||
["textfield-bezel-square-focused-5.png", 6.0, 1.0],
|
||||
["textfield-bezel-square-focused-6.png", 6.0, 6.0],
|
||||
["textfield-bezel-square-focused-7.png", 1.0, 6.0],
|
||||
["textfield-bezel-square-focused-8.png", 6.0, 6.0]
|
||||
]),
|
||||
|
||||
bezelColorDatePickerTextField = PatternColor(
|
||||
[
|
||||
[@"datepicker-date-segment-0.png", 4.0, 18.0],
|
||||
@@ -1268,6 +1281,7 @@ var themedButtonValues = nil,
|
||||
themeValues =
|
||||
[
|
||||
[@"bezel-color", bezelColor, CPThemeStateBezeled],
|
||||
[@"bezel-color", bezelFocusedColor, [CPThemeStateBezeled, CPThemeStateEditing]],
|
||||
[@"bezel-color", bezelDisabledColor, [CPThemeStateBezeled, CPThemeStateDisabled]],
|
||||
|
||||
[@"font", [CPFont boldSystemFontOfSize:13.0]],
|
||||
@@ -1275,8 +1289,10 @@ var themedButtonValues = nil,
|
||||
|
||||
[@"content-inset", CGInsetMake(6.0, 0.0, 0.0, 3.0), CPThemeStateNormal],
|
||||
[@"content-inset", CGInsetMake(6.0, 0.0, 0.0, 5.0), CPThemeStateBezeled],
|
||||
[@"content-inset", CGInsetMake(6.0, 0.0, 0.0, 5.0), [CPThemeStateBezeled, CPThemeStateEditing]],
|
||||
|
||||
[@"bezel-inset", CGInsetMake(0.0, -3.0, 0.0, -3.0), CPThemeStateBezeled],
|
||||
[@"bezel-inset", CGInsetMake(0.0, -3.0, 0.0, -3.0), [CPThemeStateBezeled, CPThemeStateEditing]],
|
||||
|
||||
[@"datepicker-textfield-bezel-color", [CPColor clearColor], CPThemeStateNormal],
|
||||
[@"datepicker-textfield-bezel-color", bezelColorDatePickerTextField, CPThemeStateSelected],
|
||||
@@ -1301,10 +1317,12 @@ var themedButtonValues = nil,
|
||||
// CPThemeStateControlSizeSmall
|
||||
[@"content-inset", CGInsetMake(5.0, 0.0, 0.0, 5.0), [CPThemeStateControlSizeSmall, CPThemeStateNormal]],
|
||||
[@"content-inset", CGInsetMake(5.0, 0.0, 0.0, 5.0), [CPThemeStateControlSizeSmall, CPThemeStateBezeled]],
|
||||
[@"content-inset", CGInsetMake(5.0, 0.0, 0.0, 5.0), [CPThemeStateControlSizeSmall, CPThemeStateEditing, CPThemeStateBezeled]],
|
||||
|
||||
[@"min-size-datepicker-textfield", CGSizeMake(6.0, 16.0), CPThemeStateControlSizeSmall],
|
||||
[@"date-hour-margin", 5.0, CPThemeStateControlSizeSmall],
|
||||
[@"stepper-margin", 3.0, CPThemeStateControlSizeSmall],
|
||||
[@"stepper-margin", 3.0, [CPThemeStateControlSizeSmall, CPThemeStateEditing]],
|
||||
|
||||
[@"min-size", CGSizeMake(0, 26.0), CPThemeStateControlSizeSmall],
|
||||
[@"max-size", CGSizeMake(-1.0, 26.0), CPThemeStateControlSizeSmall],
|
||||
@@ -1313,10 +1331,12 @@ var themedButtonValues = nil,
|
||||
// CPThemeStateControlSizeMini
|
||||
[@"content-inset", CGInsetMake(4.0, 0.0, 0.0, 4.0), [CPThemeStateControlSizeMini, CPThemeStateNormal]],
|
||||
[@"content-inset", CGInsetMake(4.0, 0.0, 0.0, 4.0), [CPThemeStateControlSizeMini, CPThemeStateBezeled]],
|
||||
[@"content-inset", CGInsetMake(4.0, 0.0, 0.0, 4.0), [CPThemeStateControlSizeMini, CPThemeStateEditing, CPThemeStateBezeled]],
|
||||
|
||||
[@"min-size-datepicker-textfield", CGSizeMake(6.0, 12.0), CPThemeStateControlSizeMini],
|
||||
[@"date-hour-margin", 2.0, CPThemeStateControlSizeMini],
|
||||
[@"stepper-margin", 2.0, CPThemeStateControlSizeMini],
|
||||
[@"stepper-margin", 2.0, [CPThemeStateControlSizeMini, CPThemeStateEditing]],
|
||||
|
||||
[@"min-size", CGSizeMake(0, 22.0), CPThemeStateControlSizeMini],
|
||||
[@"max-size", CGSizeMake(-1.0, 22.0), CPThemeStateControlSizeMini],
|
||||
@@ -1820,8 +1840,8 @@ var themedButtonValues = nil,
|
||||
|
||||
// The right border inset has to make room for the focus ring and popup button
|
||||
[@"content-inset", CGInsetMake(8.0, 27.0, 7.0, 8.0), [CPThemeStateBezeled, CPComboBoxStateButtonBordered]],
|
||||
[@"content-inset", CGInsetMake(8.0, 24.0, 7.0, 8.0), CPThemeStateBezeled],
|
||||
[@"content-inset", CGInsetMake(8.0, 24.0, 7.0, 8.0), [CPThemeStateBezeled, CPThemeStateEditing]],
|
||||
[@"content-inset", CGInsetMake(8.0, 27.0, 7.0, 8.0), CPThemeStateBezeled],
|
||||
[@"content-inset", CGInsetMake(8.0, 27.0, 7.0, 8.0), [CPThemeStateBezeled, CPThemeStateEditing]],
|
||||
|
||||
[@"popup-button-size", CGSizeMake(21.0, 23.0), [CPThemeStateBezeled, CPComboBoxStateButtonBordered]],
|
||||
[@"popup-button-size", CGSizeMake(17.0, 23.0), CPThemeStateBezeled],
|
||||
@@ -2089,6 +2109,52 @@ var themedButtonValues = nil,
|
||||
pushedHighlightedLeftBezelColor = PatternColor("segmented-control-bezel-pushed-highlighted-left.png", 4.0, 24.0),
|
||||
pushedHighlightedRightBezelColor = PatternColor("segmented-control-bezel-pushed-highlighted-right.png", 4.0, 24.0);
|
||||
|
||||
var smallCenterBezelColor = PatternColor("segmented-control-bezel-center.png", 1.0, 20.0),
|
||||
smallDividerBezelColor = PatternColor("segmented-control-bezel-divider.png", 1.0, 20.0),
|
||||
smallCenterHighlightedBezelColor = PatternColor("segmented-control-bezel-highlighted-center.png", 1.0, 20.0),
|
||||
smallDividerHighlightedBezelColor = PatternColor("segmented-control-bezel-highlighted-divider.png", 1.0, 20.0),
|
||||
smallLeftHighlightedBezelColor = PatternColor("segmented-control-bezel-highlighted-left.png", 4.0, 20.0),
|
||||
smallRightHighlightedBezelColor = PatternColor("segmented-control-bezel-highlighted-right.png", 4.0, 20.0),
|
||||
smallInactiveCenterBezelColor = PatternColor("segmented-control-bezel-disabled-center.png", 1.0, 20.0),
|
||||
smallInactiveDividerBezelColor = PatternColor("segmented-control-bezel-disabled-divider.png", 1.0, 20.0),
|
||||
smallInactiveLeftBezelColor = PatternColor("segmented-control-bezel-disabled-left.png", 4.0, 20.0),
|
||||
smallInactiveRightBezelColor = PatternColor("segmented-control-bezel-disabled-right.png", 4.0, 20.0),
|
||||
smallInactiveHighlightedCenterBezelColor = PatternColor("segmented-control-bezel-highlighted-disabled-center.png", 1.0, 20.0),
|
||||
smallInactiveHighlightedDividerBezelColor = PatternColor("segmented-control-bezel-highlighted-disabled-divider.png", 1.0, 20.0),
|
||||
smallInactiveHighlightedLeftBezelColor = PatternColor("segmented-control-bezel-highlighted-disabled-left.png", 4.0, 20.0),
|
||||
smallInactiveHighlightedRightBezelColor = PatternColor("segmented-control-bezel-highlighted-disabled-right.png", 4.0, 20.0),
|
||||
smallLeftBezelColor = PatternColor("segmented-control-bezel-left.png", 4.0, 20.0),
|
||||
smallRightBezelColor = PatternColor("segmented-control-bezel-right.png", 4.0, 20.0),
|
||||
smallPushedCenterBezelColor = PatternColor("segmented-control-bezel-pushed-center.png", 1.0, 20.0),
|
||||
smallPushedLeftBezelColor = PatternColor("segmented-control-bezel-pushed-left.png", 4.0, 20.0),
|
||||
smallPushedRightBezelColor = PatternColor("segmented-control-bezel-pushed-right.png", 4.0, 20.0),
|
||||
smallPushedHighlightedCenterBezelColor = PatternColor("segmented-control-bezel-pushed-highlighted-center.png", 1.0, 20.0),
|
||||
smallPushedHighlightedLeftBezelColor = PatternColor("segmented-control-bezel-pushed-highlighted-left.png", 4.0, 20.0),
|
||||
smallPushedHighlightedRightBezelColor = PatternColor("segmented-control-bezel-pushed-highlighted-right.png", 4.0, 20.0);
|
||||
|
||||
var miniCenterBezelColor = PatternColor("segmented-control-bezel-center.png", 1.0, 15.0),
|
||||
miniDividerBezelColor = PatternColor("segmented-control-bezel-divider.png", 1.0, 15.0),
|
||||
miniCenterHighlightedBezelColor = PatternColor("segmented-control-bezel-highlighted-center.png", 1.0, 15.0),
|
||||
miniDividerHighlightedBezelColor = PatternColor("segmented-control-bezel-highlighted-divider.png", 1.0, 15.0),
|
||||
miniLeftHighlightedBezelColor = PatternColor("segmented-control-bezel-highlighted-left.png", 4.0, 15.0),
|
||||
miniRightHighlightedBezelColor = PatternColor("segmented-control-bezel-highlighted-right.png", 4.0, 15.0),
|
||||
miniInactiveCenterBezelColor = PatternColor("segmented-control-bezel-disabled-center.png", 1.0, 15.0),
|
||||
miniInactiveDividerBezelColor = PatternColor("segmented-control-bezel-disabled-divider.png", 1.0, 15.0),
|
||||
miniInactiveLeftBezelColor = PatternColor("segmented-control-bezel-disabled-left.png", 4.0, 15.0),
|
||||
miniInactiveRightBezelColor = PatternColor("segmented-control-bezel-disabled-right.png", 4.0, 15.0),
|
||||
miniInactiveHighlightedCenterBezelColor = PatternColor("segmented-control-bezel-highlighted-disabled-center.png", 1.0, 15.0),
|
||||
miniInactiveHighlightedDividerBezelColor = PatternColor("segmented-control-bezel-highlighted-disabled-divider.png", 1.0, 15.0),
|
||||
miniInactiveHighlightedLeftBezelColor = PatternColor("segmented-control-bezel-highlighted-disabled-left.png", 4.0, 15.0),
|
||||
miniInactiveHighlightedRightBezelColor = PatternColor("segmented-control-bezel-highlighted-disabled-right.png", 4.0, 15.0),
|
||||
miniLeftBezelColor = PatternColor("segmented-control-bezel-left.png", 4.0, 15.0),
|
||||
miniRightBezelColor = PatternColor("segmented-control-bezel-right.png", 4.0, 15.0),
|
||||
miniPushedCenterBezelColor = PatternColor("segmented-control-bezel-pushed-center.png", 1.0, 15.0),
|
||||
miniPushedLeftBezelColor = PatternColor("segmented-control-bezel-pushed-left.png", 4.0, 15.0),
|
||||
miniPushedRightBezelColor = PatternColor("segmented-control-bezel-pushed-right.png", 4.0, 15.0),
|
||||
miniPushedHighlightedCenterBezelColor = PatternColor("segmented-control-bezel-pushed-highlighted-center.png", 1.0, 15.0),
|
||||
miniPushedHighlightedLeftBezelColor = PatternColor("segmented-control-bezel-pushed-highlighted-left.png", 4.0, 15.0),
|
||||
miniPushedHighlightedRightBezelColor = PatternColor("segmented-control-bezel-pushed-highlighted-right.png", 4.0, 15.0);
|
||||
|
||||
themedSegmentedControlValues =
|
||||
[
|
||||
[@"center-segment-bezel-color", centerBezelColor, CPThemeStateNormal],
|
||||
@@ -2117,9 +2183,75 @@ var themedButtonValues = nil,
|
||||
[@"right-segment-bezel-color", pushedRightBezelColor, CPThemeStateHighlighted],
|
||||
[@"right-segment-bezel-color", pushedHighlightedRightBezelColor, [CPThemeStateHighlighted, CPThemeStateSelected]],
|
||||
|
||||
|
||||
[@"center-segment-bezel-color", smallCenterBezelColor, [CPThemeStateControlSizeSmall, CPThemeStateNormal]],
|
||||
[@"center-segment-bezel-color", smallInactiveCenterBezelColor, [CPThemeStateControlSizeSmall, CPThemeStateDisabled]],
|
||||
[@"center-segment-bezel-color", smallInactiveHighlightedCenterBezelColor, [CPThemeStateControlSizeSmall, CPThemeStateSelected, CPThemeStateDisabled]],
|
||||
[@"center-segment-bezel-color", smallCenterHighlightedBezelColor, [CPThemeStateControlSizeSmall, CPThemeStateSelected]],
|
||||
[@"center-segment-bezel-color", smallPushedCenterBezelColor, [CPThemeStateControlSizeSmall, CPThemeStateHighlighted]],
|
||||
[@"center-segment-bezel-color", smallPushedHighlightedCenterBezelColor, [CPThemeStateControlSizeSmall, CPThemeStateHighlighted, CPThemeStateSelected]],
|
||||
|
||||
[@"divider-bezel-color", smallDividerBezelColor, [CPThemeStateControlSizeSmall, CPThemeStateNormal]],
|
||||
[@"divider-bezel-color", smallInactiveDividerBezelColor, [CPThemeStateControlSizeSmall, CPThemeStateDisabled]],
|
||||
[@"divider-bezel-color", smallInactiveHighlightedDividerBezelColor, [CPThemeStateControlSizeSmall, CPThemeStateSelected, CPThemeStateDisabled]],
|
||||
[@"divider-bezel-color", smallDividerHighlightedBezelColor, [CPThemeStateControlSizeSmall, CPThemeStateSelected]],
|
||||
|
||||
[@"left-segment-bezel-color", smallLeftBezelColor, [CPThemeStateControlSizeSmall, CPThemeStateNormal]],
|
||||
[@"left-segment-bezel-color", smallInactiveLeftBezelColor, [CPThemeStateControlSizeSmall, CPThemeStateDisabled]],
|
||||
[@"left-segment-bezel-color", smallInactiveHighlightedLeftBezelColor, [CPThemeStateControlSizeSmall, CPThemeStateSelected, CPThemeStateDisabled]],
|
||||
[@"left-segment-bezel-color", smallLeftHighlightedBezelColor, [CPThemeStateControlSizeSmall, CPThemeStateSelected]],
|
||||
[@"left-segment-bezel-color", smallPushedLeftBezelColor, [CPThemeStateControlSizeSmall, CPThemeStateHighlighted]],
|
||||
[@"left-segment-bezel-color", smallPushedHighlightedLeftBezelColor, [CPThemeStateControlSizeSmall, CPThemeStateHighlighted, CPThemeStateSelected]],
|
||||
|
||||
[@"right-segment-bezel-color", smallRightBezelColor, [CPThemeStateControlSizeSmall, CPThemeStateNormal]],
|
||||
[@"right-segment-bezel-color", smallInactiveRightBezelColor, [CPThemeStateControlSizeSmall, CPThemeStateDisabled]],
|
||||
[@"right-segment-bezel-color", smallInactiveHighlightedRightBezelColor, [CPThemeStateControlSizeSmall, CPThemeStateSelected, CPThemeStateDisabled]],
|
||||
[@"right-segment-bezel-color", smallRightHighlightedBezelColor, [CPThemeStateControlSizeSmall, CPThemeStateSelected]],
|
||||
[@"right-segment-bezel-color", smallPushedRightBezelColor, [CPThemeStateControlSizeSmall, CPThemeStateHighlighted]],
|
||||
[@"right-segment-bezel-color", smallPushedHighlightedRightBezelColor, [CPThemeStateControlSizeSmall, CPThemeStateHighlighted, CPThemeStateSelected]],
|
||||
|
||||
|
||||
[@"center-segment-bezel-color", miniCenterBezelColor, [CPThemeStateControlSizeMini, CPThemeStateNormal]],
|
||||
[@"center-segment-bezel-color", miniInactiveCenterBezelColor, [CPThemeStateControlSizeMini, CPThemeStateDisabled]],
|
||||
[@"center-segment-bezel-color", miniInactiveHighlightedCenterBezelColor, [CPThemeStateControlSizeMini, CPThemeStateSelected, CPThemeStateDisabled]],
|
||||
[@"center-segment-bezel-color", miniCenterHighlightedBezelColor, [CPThemeStateControlSizeMini, CPThemeStateSelected]],
|
||||
[@"center-segment-bezel-color", miniPushedCenterBezelColor, [CPThemeStateControlSizeMini, CPThemeStateHighlighted]],
|
||||
[@"center-segment-bezel-color", miniPushedHighlightedCenterBezelColor, [CPThemeStateControlSizeMini, CPThemeStateHighlighted, CPThemeStateSelected]],
|
||||
|
||||
[@"divider-bezel-color", miniDividerBezelColor, [CPThemeStateControlSizeMini, CPThemeStateNormal]],
|
||||
[@"divider-bezel-color", miniInactiveDividerBezelColor, [CPThemeStateControlSizeMini, CPThemeStateDisabled]],
|
||||
[@"divider-bezel-color", miniInactiveHighlightedDividerBezelColor, [CPThemeStateControlSizeMini, CPThemeStateSelected, CPThemeStateDisabled]],
|
||||
[@"divider-bezel-color", miniDividerHighlightedBezelColor, [CPThemeStateControlSizeMini, CPThemeStateSelected]],
|
||||
|
||||
[@"left-segment-bezel-color", miniLeftBezelColor, [CPThemeStateControlSizeMini, CPThemeStateNormal]],
|
||||
[@"left-segment-bezel-color", miniInactiveLeftBezelColor, [CPThemeStateControlSizeMini, CPThemeStateDisabled]],
|
||||
[@"left-segment-bezel-color", miniInactiveHighlightedLeftBezelColor, [CPThemeStateControlSizeMini, CPThemeStateSelected, CPThemeStateDisabled]],
|
||||
[@"left-segment-bezel-color", miniLeftHighlightedBezelColor, [CPThemeStateControlSizeMini, CPThemeStateSelected]],
|
||||
[@"left-segment-bezel-color", miniPushedLeftBezelColor, [CPThemeStateControlSizeMini, CPThemeStateHighlighted]],
|
||||
[@"left-segment-bezel-color", miniPushedHighlightedLeftBezelColor, [CPThemeStateControlSizeMini, CPThemeStateHighlighted, CPThemeStateSelected]],
|
||||
|
||||
[@"right-segment-bezel-color", miniRightBezelColor, [CPThemeStateControlSizeMini, CPThemeStateNormal]],
|
||||
[@"right-segment-bezel-color", miniInactiveRightBezelColor, [CPThemeStateControlSizeMini, CPThemeStateDisabled]],
|
||||
[@"right-segment-bezel-color", miniInactiveHighlightedRightBezelColor, [CPThemeStateControlSizeMini, CPThemeStateSelected, CPThemeStateDisabled]],
|
||||
[@"right-segment-bezel-color", miniRightHighlightedBezelColor, [CPThemeStateControlSizeMini, CPThemeStateSelected]],
|
||||
[@"right-segment-bezel-color", miniPushedRightBezelColor, [CPThemeStateControlSizeMini, CPThemeStateHighlighted]],
|
||||
[@"right-segment-bezel-color", miniPushedHighlightedRightBezelColor, [CPThemeStateControlSizeMini, CPThemeStateHighlighted, CPThemeStateSelected]],
|
||||
|
||||
[@"content-inset", CGInsetMake(0.0, 4.0, 0.0, 4.0), CPThemeStateNormal],
|
||||
[@"bezel-inset", CGInsetMake(0.0, 0.0, 0.0, 0.0), CPThemeStateNormal],
|
||||
|
||||
[@"min-size", CGSizeMake(-1.0, 24.0)],
|
||||
[@"max-size", CGSizeMake(-1.0, 24.0)],
|
||||
[@"nib2cib-adjustment-frame", CGRectMake(1.0, 1.0, -3.0, 0.0)],
|
||||
|
||||
[@"min-size", CGSizeMake(-1.0, 20.0), CPThemeStateControlSizeSmall],
|
||||
[@"max-size", CGSizeMake(-1.0, 20.0), CPThemeStateControlSizeSmall],
|
||||
[@"nib2cib-adjustment-frame", CGRectMake(2.0, 0.0, -4.0, 0.0), CPThemeStateControlSizeSmall],
|
||||
|
||||
[@"min-size", CGSizeMake(-1.0, 15.0), CPThemeStateControlSizeMini],
|
||||
[@"max-size", CGSizeMake(-1.0, 15.0), CPThemeStateControlSizeMini],
|
||||
[@"nib2cib-adjustment-frame", CGRectMake(1.0, 0.0, -2.0, 0.0), CPThemeStateControlSizeMini],
|
||||
|
||||
[@"font", [CPFont boldSystemFontOfSize:CPFontCurrentSystemSize]],
|
||||
[@"text-color", [CPColor colorWithCalibratedWhite:79.0 / 255.0 alpha:1.0]],
|
||||
[@"text-color", [CPColor colorWithCalibratedWhite:0.6 alpha:1.0], CPThemeStateDisabled],
|
||||
@@ -2128,8 +2260,7 @@ var themedButtonValues = nil,
|
||||
[@"text-shadow-offset", CGSizeMake(0.0, 1.0)],
|
||||
[@"line-break-mode", CPLineBreakByTruncatingTail],
|
||||
|
||||
[@"divider-thickness", 1.0],
|
||||
[@"default-height", 25.0]
|
||||
[@"divider-thickness", 1.0]
|
||||
];
|
||||
|
||||
[self registerThemeValues:themedSegmentedControlValues forView:segmentedControl];
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 3.5 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 3.9 KiB After Width: | Height: | Size: 3.4 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 3.5 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 3.9 KiB After Width: | Height: | Size: 3.4 KiB |
@@ -374,7 +374,7 @@ var themedButtonValues = nil,
|
||||
[@"font", [CPFont boldSystemFontOfSize:11.0]],
|
||||
|
||||
[@"min-size", CGSizeMake(32.0, 20.0), CPThemeStateControlSizeSmall],
|
||||
[@"max-size", CGSizeMake(1.0, 20.0), CPThemeStateControlSizeSmall],
|
||||
[@"max-size", CGSizeMake(-1.0, 20.0), CPThemeStateControlSizeSmall],
|
||||
[@"nib2cib-adjustment-frame", CGRectMake(3.0, 4.0, -6.0, 0.0), CPThemeStateControlSizeSmall],
|
||||
|
||||
// CPThemeStateControlSizeMini
|
||||
@@ -386,7 +386,7 @@ var themedButtonValues = nil,
|
||||
|
||||
[@"min-size", CGSizeMake(32.0, 16.0), CPThemeStateControlSizeMini],
|
||||
[@"max-size", CGSizeMake(-1.0, 16.0), CPThemeStateControlSizeMini],
|
||||
[@"nib2cib-adjustment-frame", CGRectMake(1.0, 10.0, -3.0, 0.0), CPThemeStateControlSizeMini]
|
||||
[@"nib2cib-adjustment-frame", CGRectMake(1.0, 10.0, -3.0, 0.0), CPThemeStateControlSizeMini]
|
||||
];
|
||||
|
||||
[self registerThemeValues:themeValues forView:button];
|
||||
@@ -824,6 +824,14 @@ var themedButtonValues = nil,
|
||||
height: 4.0
|
||||
}),
|
||||
|
||||
bezelFocusedColor = PatternColor(
|
||||
"textfield-bezel-square-focused{position}.png",
|
||||
{
|
||||
positions: "#",
|
||||
width: 9.0,
|
||||
height: 9.0
|
||||
}),
|
||||
|
||||
bezelColorDatePickerTextField = PatternColor(
|
||||
[
|
||||
[@"datepicker-date-segment-0.png", 4.0, 18.0],
|
||||
@@ -835,14 +843,17 @@ var themedButtonValues = nil,
|
||||
[
|
||||
[@"bezel-color", bezelColor["@"], CPThemeStateBezeled],
|
||||
[@"bezel-color", bezelColor["disabled"], [CPThemeStateBezeled, CPThemeStateDisabled]],
|
||||
[@"bezel-color", bezelFocusedColor, [CPThemeStateBezeled, CPThemeStateEditing]],
|
||||
|
||||
[@"font", [CPFont systemFontOfSize:CPFontCurrentSystemSize]],
|
||||
[@"text-color", [CPColor colorWithWhite:0.2 alpha:0.5], CPThemeStateDisabled],
|
||||
|
||||
[@"content-inset", CGInsetMake(6.0, 0.0, 0.0, 3.0), CPThemeStateNormal],
|
||||
[@"content-inset", CGInsetMake(3.0, 0.0, 0.0, 3.0), CPThemeStateBezeled],
|
||||
[@"content-inset", CGInsetMake(6.0, 0.0, 0.0, 6.0), [CPThemeStateNormal, CPThemeStateBezeled, CPThemeStateEditing]],
|
||||
|
||||
[@"bezel-inset", CGInsetMake(3.0, 0.0, 3.0, 0.0), CPThemeStateBezeled],
|
||||
[@"bezel-inset", CGInsetMake(0.0, 0, 0.0, -3.0), [CPThemeStateNormal, CPThemeStateBezeled, CPThemeStateEditing]],
|
||||
|
||||
[@"datepicker-textfield-bezel-color", [CPColor clearColor], CPThemeStateNormal],
|
||||
[@"datepicker-textfield-bezel-color", bezelColorDatePickerTextField, CPThemeStateSelected],
|
||||
@@ -859,6 +870,7 @@ var themedButtonValues = nil,
|
||||
[@"min-size-datepicker-textfield", CGSizeMake(6.0, 18.0)],
|
||||
[@"date-hour-margin", 7.0],
|
||||
[@"stepper-margin", 5.0],
|
||||
[@"stepper-margin", 2.0, CPThemeStateEditing],
|
||||
|
||||
[@"min-size", CGSizeMake(0, 29.0)],
|
||||
[@"max-size", CGSizeMake(-1.0, 29.0)],
|
||||
@@ -867,10 +879,12 @@ var themedButtonValues = nil,
|
||||
// CPThemeStateControlSizeSmall
|
||||
[@"content-inset", CGInsetMake(5.0, 0.0, 0.0, 3.0), [CPThemeStateControlSizeSmall, CPThemeStateNormal]],
|
||||
[@"content-inset", CGInsetMake(2.0, 0.0, 0.0, 3.0), [CPThemeStateControlSizeSmall, CPThemeStateBezeled]],
|
||||
[@"content-inset", CGInsetMake(5.0, 0.0, 0.0, 6.0), [CPThemeStateControlSizeSmall, CPThemeStateBezeled, CPThemeStateEditing]],
|
||||
|
||||
[@"min-size-datepicker-textfield", CGSizeMake(6.0, 16.0), CPThemeStateControlSizeSmall],
|
||||
[@"date-hour-margin", 5.0, CPThemeStateControlSizeSmall],
|
||||
[@"stepper-margin", 3.0, CPThemeStateControlSizeSmall],
|
||||
[@"stepper-margin", 0.0, [CPThemeStateControlSizeSmall, CPThemeStateEditing]],
|
||||
|
||||
[@"min-size", CGSizeMake(0, 26.0), CPThemeStateControlSizeSmall],
|
||||
[@"max-size", CGSizeMake(-1.0, 26.0), CPThemeStateControlSizeSmall],
|
||||
@@ -879,10 +893,12 @@ var themedButtonValues = nil,
|
||||
// CPThemeStateControlSizeMini
|
||||
[@"content-inset", CGInsetMake(3.0, 0.0, 0.0, 3.0), [CPThemeStateControlSizeMini, CPThemeStateNormal]],
|
||||
[@"content-inset", CGInsetMake(1.0, 0.0, 0.0, 3.0), [CPThemeStateControlSizeMini, CPThemeStateBezeled]],
|
||||
[@"content-inset", CGInsetMake(4.0, 0.0, 0.0, 6.0), [CPThemeStateControlSizeMini, CPThemeStateBezeled, CPThemeStateEditing]],
|
||||
|
||||
[@"min-size-datepicker-textfield", CGSizeMake(6.0, 12.0), CPThemeStateControlSizeMini],
|
||||
[@"date-hour-margin", 2.0, CPThemeStateControlSizeMini],
|
||||
[@"stepper-margin", 2.0, CPThemeStateControlSizeMini],
|
||||
[@"stepper-margin", -1.0, [CPThemeStateControlSizeMini, CPThemeStateEditing]],
|
||||
|
||||
[@"min-size", CGSizeMake(0, 22.0), CPThemeStateControlSizeMini],
|
||||
[@"max-size", CGSizeMake(-1.0, 22.0), CPThemeStateControlSizeMini],
|
||||
@@ -1312,9 +1328,9 @@ var themedButtonValues = nil,
|
||||
[@"bezel-inset", CGInsetMake(3.0, 5.0, 3.0, 4.0), [CPThemeStateBezeled, CPThemeStateDisabled]],
|
||||
|
||||
// The right border inset has to make room for the focus ring and popup button
|
||||
[@"content-inset", CGInsetMake(9.0, 26.0, 7.0, 10.0), [CPThemeStateBezeled, CPComboBoxStateButtonBordered]],
|
||||
[@"content-inset", CGInsetMake(9.0, 26.0, 7.0, 10.0), CPThemeStateBezeled],
|
||||
[@"content-inset", CGInsetMake(9.0, 24.0, 7.0, 10.0), [CPThemeStateBezeled, CPThemeStateEditing]],
|
||||
[@"content-inset", CGInsetMake(9.0, 30.0, 7.0, 10.0), [CPThemeStateBezeled, CPComboBoxStateButtonBordered]],
|
||||
[@"content-inset", CGInsetMake(9.0, 30.0, 7.0, 10.0), CPThemeStateBezeled],
|
||||
[@"content-inset", CGInsetMake(9.0, 28.0, 7.0, 10.0), [CPThemeStateBezeled, CPThemeStateEditing]],
|
||||
|
||||
[@"popup-button-size", CGSizeMake(21.0, 23.0), [CPThemeStateBezeled, CPComboBoxStateButtonBordered]],
|
||||
[@"popup-button-size", CGSizeMake(17.0, 23.0), CPThemeStateBezeled],
|
||||
@@ -1466,6 +1482,8 @@ var themedButtonValues = nil,
|
||||
|
||||
[@"font", [CPFont systemFontOfSize:CPFontCurrentSystemSize], CPThemeStateNormal],
|
||||
[@"text-color", regularDisabledTextColor, CPThemeStateDisabled],
|
||||
[@"text-color", [CPColor colorWithCalibratedWhite:51.0 / 255.0 alpha:1.0], CPThemeStateTableDataView],
|
||||
[@"text-color", [CPColor whiteColor], [CPThemeStateTableDataView, CPThemeStateSelectedDataView, CPThemeStateFirstResponder, CPThemeStateKeyWindow]],
|
||||
[@"image-offset", CPCheckBoxImageOffset],
|
||||
|
||||
// CPThemeStateControlSizeRegular
|
||||
@@ -1587,6 +1605,52 @@ var themedButtonValues = nil,
|
||||
pushedHighlightedLeftBezelColor = PatternColor("segmented-control-bezel-pushed-highlighted-left.png", 4.0, 25.0),
|
||||
pushedHighlightedRightBezelColor = PatternColor("segmented-control-bezel-pushed-highlighted-right.png", 4.0, 25.0);
|
||||
|
||||
var smallCenterBezelColor = PatternColor("segmented-control-bezel-center.png", 1.0, 20.0),
|
||||
smallDividerBezelColor = PatternColor("segmented-control-bezel-divider.png", 1.0, 20.0),
|
||||
smallCenterHighlightedBezelColor = PatternColor("segmented-control-bezel-highlighted-center.png", 1.0, 20.0),
|
||||
smallDividerHighlightedBezelColor = PatternColor("segmented-control-bezel-highlighted-divider.png", 1.0, 20.0),
|
||||
smallLeftHighlightedBezelColor = PatternColor("segmented-control-bezel-highlighted-left.png", 4.0, 20.0),
|
||||
smallRightHighlightedBezelColor = PatternColor("segmented-control-bezel-highlighted-right.png", 4.0, 20.0),
|
||||
smallInactiveCenterBezelColor = PatternColor("segmented-control-bezel-disabled-center.png", 1.0, 20.0),
|
||||
smallInactiveDividerBezelColor = PatternColor("segmented-control-bezel-disabled-divider.png", 1.0, 20.0),
|
||||
smallInactiveLeftBezelColor = PatternColor("segmented-control-bezel-disabled-left.png", 4.0, 20.0),
|
||||
smallInactiveRightBezelColor = PatternColor("segmented-control-bezel-disabled-right.png", 4.0, 20.0),
|
||||
smallInactiveHighlightedCenterBezelColor = PatternColor("segmented-control-bezel-highlighted-disabled-center.png", 1.0, 20.0),
|
||||
smallInactiveHighlightedDividerBezelColor = PatternColor("segmented-control-bezel-highlighted-disabled-divider.png", 1.0, 20.0),
|
||||
smallInactiveHighlightedLeftBezelColor = PatternColor("segmented-control-bezel-highlighted-disabled-left.png", 4.0, 20.0),
|
||||
smallInactiveHighlightedRightBezelColor = PatternColor("segmented-control-bezel-highlighted-disabled-right.png", 4.0, 20.0),
|
||||
smallLeftBezelColor = PatternColor("segmented-control-bezel-left.png", 4.0, 20.0),
|
||||
smallRightBezelColor = PatternColor("segmented-control-bezel-right.png", 4.0, 20.0),
|
||||
smallPushedCenterBezelColor = PatternColor("segmented-control-bezel-pushed-center.png", 1.0, 20.0),
|
||||
smallPushedLeftBezelColor = PatternColor("segmented-control-bezel-pushed-left.png", 4.0, 20.0),
|
||||
smallPushedRightBezelColor = PatternColor("segmented-control-bezel-pushed-right.png", 4.0, 20.0),
|
||||
smallPushedHighlightedCenterBezelColor = PatternColor("segmented-control-bezel-pushed-highlighted-center.png", 1.0, 20.0),
|
||||
smallPushedHighlightedLeftBezelColor = PatternColor("segmented-control-bezel-pushed-highlighted-left.png", 4.0, 20.0),
|
||||
smallPushedHighlightedRightBezelColor = PatternColor("segmented-control-bezel-pushed-highlighted-right.png", 4.0, 20.0);
|
||||
|
||||
var miniCenterBezelColor = PatternColor("segmented-control-bezel-center.png", 1.0, 15.0),
|
||||
miniDividerBezelColor = PatternColor("segmented-control-bezel-divider.png", 1.0, 15.0),
|
||||
miniCenterHighlightedBezelColor = PatternColor("segmented-control-bezel-highlighted-center.png", 1.0, 15.0),
|
||||
miniDividerHighlightedBezelColor = PatternColor("segmented-control-bezel-highlighted-divider.png", 1.0, 15.0),
|
||||
miniLeftHighlightedBezelColor = PatternColor("segmented-control-bezel-highlighted-left.png", 4.0, 15.0),
|
||||
miniRightHighlightedBezelColor = PatternColor("segmented-control-bezel-highlighted-right.png", 4.0, 15.0),
|
||||
miniInactiveCenterBezelColor = PatternColor("segmented-control-bezel-disabled-center.png", 1.0, 15.0),
|
||||
miniInactiveDividerBezelColor = PatternColor("segmented-control-bezel-disabled-divider.png", 1.0, 15.0),
|
||||
miniInactiveLeftBezelColor = PatternColor("segmented-control-bezel-disabled-left.png", 4.0, 15.0),
|
||||
miniInactiveRightBezelColor = PatternColor("segmented-control-bezel-disabled-right.png", 4.0, 15.0),
|
||||
miniInactiveHighlightedCenterBezelColor = PatternColor("segmented-control-bezel-highlighted-disabled-center.png", 1.0, 15.0),
|
||||
miniInactiveHighlightedDividerBezelColor = PatternColor("segmented-control-bezel-highlighted-disabled-divider.png", 1.0, 15.0),
|
||||
miniInactiveHighlightedLeftBezelColor = PatternColor("segmented-control-bezel-highlighted-disabled-left.png", 4.0, 15.0),
|
||||
miniInactiveHighlightedRightBezelColor = PatternColor("segmented-control-bezel-highlighted-disabled-right.png", 4.0, 15.0),
|
||||
miniLeftBezelColor = PatternColor("segmented-control-bezel-left.png", 4.0, 15.0),
|
||||
miniRightBezelColor = PatternColor("segmented-control-bezel-right.png", 4.0, 15.0),
|
||||
miniPushedCenterBezelColor = PatternColor("segmented-control-bezel-pushed-center.png", 1.0, 15.0),
|
||||
miniPushedLeftBezelColor = PatternColor("segmented-control-bezel-pushed-left.png", 4.0, 15.0),
|
||||
miniPushedRightBezelColor = PatternColor("segmented-control-bezel-pushed-right.png", 4.0, 15.0),
|
||||
miniPushedHighlightedCenterBezelColor = PatternColor("segmented-control-bezel-pushed-highlighted-center.png", 1.0, 15.0),
|
||||
miniPushedHighlightedLeftBezelColor = PatternColor("segmented-control-bezel-pushed-highlighted-left.png", 4.0, 15.0),
|
||||
miniPushedHighlightedRightBezelColor = PatternColor("segmented-control-bezel-pushed-highlighted-right.png", 4.0, 15.0);
|
||||
|
||||
themedSegmentedControlValues =
|
||||
[
|
||||
[@"center-segment-bezel-color", centerBezelColor, CPThemeStateNormal],
|
||||
@@ -1615,8 +1679,74 @@ var themedButtonValues = nil,
|
||||
[@"right-segment-bezel-color", pushedRightBezelColor, CPThemeStateHighlighted],
|
||||
[@"right-segment-bezel-color", pushedHighlightedRightBezelColor, [CPThemeStateHighlighted, CPThemeStateSelected]],
|
||||
|
||||
[@"content-inset", CGInsetMake(0.0, 4.0, 0.0, 4.0), CPThemeStateNormal],
|
||||
[@"bezel-inset", CGInsetMake(0.0, 0.0, 0.0, 0.0), CPThemeStateNormal],
|
||||
|
||||
[@"center-segment-bezel-color", smallCenterBezelColor, [CPThemeStateControlSizeSmall, CPThemeStateNormal]],
|
||||
[@"center-segment-bezel-color", smallInactiveCenterBezelColor, [CPThemeStateControlSizeSmall, CPThemeStateDisabled]],
|
||||
[@"center-segment-bezel-color", smallInactiveHighlightedCenterBezelColor, [CPThemeStateControlSizeSmall, CPThemeStateSelected, CPThemeStateDisabled]],
|
||||
[@"center-segment-bezel-color", smallCenterHighlightedBezelColor, [CPThemeStateControlSizeSmall, CPThemeStateSelected]],
|
||||
[@"center-segment-bezel-color", smallPushedCenterBezelColor, [CPThemeStateControlSizeSmall, CPThemeStateHighlighted]],
|
||||
[@"center-segment-bezel-color", smallPushedHighlightedCenterBezelColor, [CPThemeStateControlSizeSmall, CPThemeStateHighlighted, CPThemeStateSelected]],
|
||||
|
||||
[@"divider-bezel-color", smallDividerBezelColor, [CPThemeStateControlSizeSmall, CPThemeStateNormal]],
|
||||
[@"divider-bezel-color", smallInactiveDividerBezelColor, [CPThemeStateControlSizeSmall, CPThemeStateDisabled]],
|
||||
[@"divider-bezel-color", smallInactiveHighlightedDividerBezelColor, [CPThemeStateControlSizeSmall, CPThemeStateSelected, CPThemeStateDisabled]],
|
||||
[@"divider-bezel-color", smallDividerHighlightedBezelColor, [CPThemeStateControlSizeSmall, CPThemeStateSelected]],
|
||||
|
||||
[@"left-segment-bezel-color", smallLeftBezelColor, [CPThemeStateControlSizeSmall, CPThemeStateNormal]],
|
||||
[@"left-segment-bezel-color", smallInactiveLeftBezelColor, [CPThemeStateControlSizeSmall, CPThemeStateDisabled]],
|
||||
[@"left-segment-bezel-color", smallInactiveHighlightedLeftBezelColor, [CPThemeStateControlSizeSmall, CPThemeStateSelected, CPThemeStateDisabled]],
|
||||
[@"left-segment-bezel-color", smallLeftHighlightedBezelColor, [CPThemeStateControlSizeSmall, CPThemeStateSelected]],
|
||||
[@"left-segment-bezel-color", smallPushedLeftBezelColor, [CPThemeStateControlSizeSmall, CPThemeStateHighlighted]],
|
||||
[@"left-segment-bezel-color", smallPushedHighlightedLeftBezelColor, [CPThemeStateControlSizeSmall, CPThemeStateHighlighted, CPThemeStateSelected]],
|
||||
|
||||
[@"right-segment-bezel-color", smallRightBezelColor, [CPThemeStateControlSizeSmall, CPThemeStateNormal]],
|
||||
[@"right-segment-bezel-color", smallInactiveRightBezelColor, [CPThemeStateControlSizeSmall, CPThemeStateDisabled]],
|
||||
[@"right-segment-bezel-color", smallInactiveHighlightedRightBezelColor, [CPThemeStateControlSizeSmall, CPThemeStateSelected, CPThemeStateDisabled]],
|
||||
[@"right-segment-bezel-color", smallRightHighlightedBezelColor, [CPThemeStateControlSizeSmall, CPThemeStateSelected]],
|
||||
[@"right-segment-bezel-color", smallPushedRightBezelColor, [CPThemeStateControlSizeSmall, CPThemeStateHighlighted]],
|
||||
[@"right-segment-bezel-color", smallPushedHighlightedRightBezelColor, [CPThemeStateControlSizeSmall, CPThemeStateHighlighted, CPThemeStateSelected]],
|
||||
|
||||
|
||||
[@"center-segment-bezel-color", miniCenterBezelColor, [CPThemeStateControlSizeMini, CPThemeStateNormal]],
|
||||
[@"center-segment-bezel-color", miniInactiveCenterBezelColor, [CPThemeStateControlSizeMini, CPThemeStateDisabled]],
|
||||
[@"center-segment-bezel-color", miniInactiveHighlightedCenterBezelColor, [CPThemeStateControlSizeMini, CPThemeStateSelected, CPThemeStateDisabled]],
|
||||
[@"center-segment-bezel-color", miniCenterHighlightedBezelColor, [CPThemeStateControlSizeMini, CPThemeStateSelected]],
|
||||
[@"center-segment-bezel-color", miniPushedCenterBezelColor, [CPThemeStateControlSizeMini, CPThemeStateHighlighted]],
|
||||
[@"center-segment-bezel-color", miniPushedHighlightedCenterBezelColor, [CPThemeStateControlSizeMini, CPThemeStateHighlighted, CPThemeStateSelected]],
|
||||
|
||||
[@"divider-bezel-color", miniDividerBezelColor, [CPThemeStateControlSizeMini, CPThemeStateNormal]],
|
||||
[@"divider-bezel-color", miniInactiveDividerBezelColor, [CPThemeStateControlSizeMini, CPThemeStateDisabled]],
|
||||
[@"divider-bezel-color", miniInactiveHighlightedDividerBezelColor, [CPThemeStateControlSizeMini, CPThemeStateSelected, CPThemeStateDisabled]],
|
||||
[@"divider-bezel-color", miniDividerHighlightedBezelColor, [CPThemeStateControlSizeMini, CPThemeStateSelected]],
|
||||
|
||||
[@"left-segment-bezel-color", miniLeftBezelColor, [CPThemeStateControlSizeMini, CPThemeStateNormal]],
|
||||
[@"left-segment-bezel-color", miniInactiveLeftBezelColor, [CPThemeStateControlSizeMini, CPThemeStateDisabled]],
|
||||
[@"left-segment-bezel-color", miniInactiveHighlightedLeftBezelColor, [CPThemeStateControlSizeMini, CPThemeStateSelected, CPThemeStateDisabled]],
|
||||
[@"left-segment-bezel-color", miniLeftHighlightedBezelColor, [CPThemeStateControlSizeMini, CPThemeStateSelected]],
|
||||
[@"left-segment-bezel-color", miniPushedLeftBezelColor, [CPThemeStateControlSizeMini, CPThemeStateHighlighted]],
|
||||
[@"left-segment-bezel-color", miniPushedHighlightedLeftBezelColor, [CPThemeStateControlSizeMini, CPThemeStateHighlighted, CPThemeStateSelected]],
|
||||
|
||||
[@"right-segment-bezel-color", miniRightBezelColor, [CPThemeStateControlSizeMini, CPThemeStateNormal]],
|
||||
[@"right-segment-bezel-color", miniInactiveRightBezelColor, [CPThemeStateControlSizeMini, CPThemeStateDisabled]],
|
||||
[@"right-segment-bezel-color", miniInactiveHighlightedRightBezelColor, [CPThemeStateControlSizeMini, CPThemeStateSelected, CPThemeStateDisabled]],
|
||||
[@"right-segment-bezel-color", miniRightHighlightedBezelColor, [CPThemeStateControlSizeMini, CPThemeStateSelected]],
|
||||
[@"right-segment-bezel-color", miniPushedRightBezelColor, [CPThemeStateControlSizeMini, CPThemeStateHighlighted]],
|
||||
[@"right-segment-bezel-color", miniPushedHighlightedRightBezelColor, [CPThemeStateControlSizeMini, CPThemeStateHighlighted, CPThemeStateSelected]],
|
||||
|
||||
[@"content-inset", CGInsetMake(0.0, 4.0, 0.0, 4.0), CPThemeStateNormal],
|
||||
[@"bezel-inset", CGInsetMake(0.0, 0.0, 0.0, 0.0), CPThemeStateNormal],
|
||||
|
||||
[@"min-size", CGSizeMake(-1.0, 25.0)],
|
||||
[@"max-size", CGSizeMake(-1.0, 25.0)],
|
||||
[@"nib2cib-adjustment-frame", CGRectMake(2.0, 2.0, -4.0, 1.0)],
|
||||
|
||||
[@"min-size", CGSizeMake(-1.0, 20.0), CPThemeStateControlSizeSmall],
|
||||
[@"max-size", CGSizeMake(-1.0, 20.0), CPThemeStateControlSizeSmall],
|
||||
[@"nib2cib-adjustment-frame", CGRectMake(2.0, 0.0, -5.0, 0.0), CPThemeStateControlSizeSmall],
|
||||
|
||||
[@"min-size", CGSizeMake(-1.0, 15.0), CPThemeStateControlSizeMini],
|
||||
[@"max-size", CGSizeMake(-1.0, 15.0), CPThemeStateControlSizeMini],
|
||||
[@"nib2cib-adjustment-frame", CGRectMake(1.0, 0.0, -2.0, 0.0), CPThemeStateControlSizeMini],
|
||||
|
||||
[@"font", [CPFont boldSystemFontOfSize:12.0]],
|
||||
[@"text-color", regularTextColor],
|
||||
@@ -1635,8 +1765,7 @@ var themedButtonValues = nil,
|
||||
[@"text-shadow-offset", CGSizeMake(0.0, 0.0), [CPThemeStateSelected, CPThemeStateDisabled]],
|
||||
[@"line-break-mode", CPLineBreakByTruncatingTail],
|
||||
|
||||
[@"divider-thickness", 1.0],
|
||||
[@"default-height", 25.0]
|
||||
[@"divider-thickness", 1.0]
|
||||
];
|
||||
|
||||
[self registerThemeValues:themedSegmentedControlValues forView:segmentedControl];
|
||||
@@ -2152,6 +2281,8 @@ var themedButtonValues = nil,
|
||||
sliceLastBottomBorderColor = [CPColor colorWithWhite:0.6 alpha:1.0],
|
||||
buttonAddImage = PatternImage(@"rule-editor-button-add-image.png", 20.0, 20.0),
|
||||
buttonRemoveImage = PatternImage(@"rule-editor-button-remove-image.png", 20.0, 20.0),
|
||||
buttonAddHighlightedImage = PatternImage(@"rule-editor-button-add-highlighted-image.png", 20.0, 20.0),
|
||||
buttonRemoveHighlightedImage = PatternImage(@"rule-editor-button-remove-highlighted-image.png", 20.0, 20.0),
|
||||
fontColor = [CPColor colorWithWhite:150 / 255 alpha:1],
|
||||
|
||||
ruleEditorThemedValues =
|
||||
@@ -2165,9 +2296,9 @@ var themedButtonValues = nil,
|
||||
[@"font", [CPFont systemFontOfSize:10.0]],
|
||||
[@"font-color", fontColor],
|
||||
[@"add-image", buttonAddImage, CPThemeStateNormal],
|
||||
[@"add-image", buttonAddImage, CPThemeStateHighlighted],
|
||||
[@"add-image", buttonAddHighlightedImage, CPThemeStateHighlighted],
|
||||
[@"remove-image", buttonRemoveImage, CPThemeStateNormal],
|
||||
[@"remove-image", buttonRemoveImage, CPThemeStateHighlighted],
|
||||
[@"remove-image", buttonRemoveHighlightedImage, CPThemeStateHighlighted],
|
||||
[@"vertical-alignment", CPCenterVerticalTextAlignment],
|
||||
];
|
||||
|
||||
|
||||
@@ -137,22 +137,27 @@ var BKLearnMoreToolbarItemIdentifier = @"BKLearnMoreToolbarItemId
|
||||
|
||||
[theWindow setFullPlatformWindow:YES];
|
||||
[theWindow makeKeyAndOrderFront:self];
|
||||
|
||||
[_themesCollectionView addObserver:self forKeyPath:@"selectionIndexes" options:CPKeyValueObservingOptionNew | CPKeyValueObservingOptionInitial context:nil];
|
||||
}
|
||||
|
||||
- (void)collectionViewDidChangeSelection:(CPCollectionView)aCollectionView
|
||||
- (void)observeValueForKeyPath:(CPString)keyPath ofObject:(id)object change:(CPDictionary)change context:(void)context
|
||||
{
|
||||
var themeDescriptorClass = _themeDescriptorClasses[[[aCollectionView selectionIndexes] firstIndex]],
|
||||
itemSize = [themeDescriptorClass itemSize];
|
||||
if (object == _themesCollectionView && keyPath == @"selectionIndexes")
|
||||
{
|
||||
var themeDescriptorClass = _themeDescriptorClasses[[[object selectionIndexes] firstIndex]],
|
||||
itemSize = [themeDescriptorClass itemSize];
|
||||
|
||||
// Make room for label and apply a minimum size.
|
||||
itemSize.width = MAX(100.0, itemSize.width + 20.0);
|
||||
itemSize.height = MAX(100.0, itemSize.height + 30.0);
|
||||
// Make room for label and apply a minimum size.
|
||||
itemSize.width = MAX(100.0, itemSize.width + 20.0);
|
||||
itemSize.height = MAX(100.0, itemSize.height + 30.0);
|
||||
|
||||
[_themedObjectsCollectionView setMinItemSize:itemSize];
|
||||
[_themedObjectsCollectionView setMaxItemSize:itemSize];
|
||||
[_themedObjectsCollectionView setMinItemSize:itemSize];
|
||||
[_themedObjectsCollectionView setMaxItemSize:itemSize];
|
||||
|
||||
[_themedObjectsCollectionView setContent:[themeDescriptorClass themedShowcaseObjectTemplates]];
|
||||
[BKShowcaseCell setBackgroundColor:[themeDescriptorClass showcaseBackgroundColor]];
|
||||
[_themedObjectsCollectionView setContent:[themeDescriptorClass themedShowcaseObjectTemplates]];
|
||||
[BKShowcaseCell setBackgroundColor:[themeDescriptorClass showcaseBackgroundColor]];
|
||||
}
|
||||
}
|
||||
|
||||
- (BOOL)hasLearnMoreURL
|
||||
|
||||
@@ -71,7 +71,7 @@ var _CPimageAndTextViewFrameSizeChangedFlag = 1 << 0,
|
||||
|
||||
#if PLATFORM(DOM)
|
||||
DOMElement _DOMImageElement;
|
||||
DOMELement _DOMTextElement;
|
||||
DOMElement _DOMTextElement;
|
||||
DOMElement _DOMTextShadowElement;
|
||||
#endif
|
||||
}
|
||||
|
||||
+125
-111
@@ -65,6 +65,126 @@ var ListMinimumItems = 3;
|
||||
var ListColumnIdentifier = @"1";
|
||||
|
||||
|
||||
@implementation _CPPopUpPanel : CPPanel
|
||||
|
||||
- (id)initWithContentRect:(CGRect)aContentRect styleMask:(unsigned)aStyleMask
|
||||
{
|
||||
if (self = [super initWithContentRect:aContentRect styleMask:aStyleMask])
|
||||
_constrainsToUsableScreen = NO;
|
||||
|
||||
[self _trapNextMouseDown];
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns \c YES if the receiver is able to receive input events
|
||||
even when a modal session is active.
|
||||
*/
|
||||
- (BOOL)worksWhenModal
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (void)sendEvent:(CPEvent)anEvent
|
||||
{
|
||||
var type = [anEvent type];
|
||||
|
||||
if (type === CPLeftMouseDown || type === CPRightMouseDown)
|
||||
[[self delegate] setListWasClicked:YES];
|
||||
|
||||
return [super sendEvent:anEvent];
|
||||
}
|
||||
|
||||
- (void)_mouseWasClicked:(CPEvent)anEvent
|
||||
{
|
||||
// This is needed, when the user close the list with the key enter
|
||||
if (![self isVisible])
|
||||
{
|
||||
[CPApp sendEvent:anEvent];
|
||||
return;
|
||||
}
|
||||
|
||||
var mouseWindow = [anEvent window],
|
||||
rect = CGRectInsetByInset([[[self delegate] dataSource] bounds], [[[self delegate] dataSource] currentValueForThemeAttribute:@"content-inset"]),
|
||||
point = [[[self delegate] dataSource] convertPoint:[anEvent locationInWindow] fromView:nil];
|
||||
|
||||
// If we click somewhere else than the comboBox or the panel we close the panel
|
||||
if (mouseWindow != self && !CGRectContainsPoint(rect, point))
|
||||
{
|
||||
[[self delegate] close];
|
||||
}
|
||||
else
|
||||
{
|
||||
// If we click on the panel, the app will know what to do
|
||||
if (mouseWindow == self)
|
||||
[CPApp sendEvent:anEvent];
|
||||
|
||||
// If we click on the comboBox field, we will trap the next mouse down
|
||||
if (CGRectContainsPoint(rect, point))
|
||||
[self _trapNextMouseDown];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
- (void)_trapNextMouseDown
|
||||
{
|
||||
// Dequeue the event and mouseWasClicked will do what it needs to do
|
||||
[CPApp setTarget:self selector:@selector(_mouseWasClicked:) forNextEventMatchingMask:CPLeftMouseDownMask untilDate:nil inMode:CPDefaultRunLoopMode dequeue:YES];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation _CPPopUpTableView : CPTableView
|
||||
{
|
||||
BOOL _acceptFirstResponder;
|
||||
}
|
||||
|
||||
- (id)initWithFrame:(CGRect)aFrame
|
||||
{
|
||||
if (self = [super initWithFrame:aFrame])
|
||||
{
|
||||
// We want the autocomplete to remain first responder until we are clicked.
|
||||
_acceptFirstResponder = NO;
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)trackMouse:(CPEvent)anEvent
|
||||
{
|
||||
if (![self isEnabled])
|
||||
return;
|
||||
|
||||
[[self delegate] setItemWasClicked:YES];
|
||||
|
||||
// CPTableView will not track the click if it is not first responder
|
||||
_acceptFirstResponder = YES;
|
||||
[[self window] makeFirstResponder:self];
|
||||
[super trackMouse:anEvent];
|
||||
}
|
||||
|
||||
- (void)stopTracking:(CGPoint)lastPoint at:(CGPoint)aPoint mouseIsUp:(BOOL)mouseIsUp
|
||||
{
|
||||
_acceptFirstResponder = NO;
|
||||
[super stopTracking:lastPoint at:aPoint mouseIsUp:mouseIsUp];
|
||||
}
|
||||
|
||||
- (BOOL)acceptsFirstResponder
|
||||
{
|
||||
return _acceptFirstResponder;
|
||||
}
|
||||
|
||||
/*!
|
||||
Return the column used for the list.
|
||||
*/
|
||||
- (CPTableColumn)listColumn
|
||||
{
|
||||
return _tableColumns[0];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
/*!
|
||||
This class is a controller for a panel that can pop up and display a scrollable list of items in a CPTableView.
|
||||
It is used by CPComboBox to display the list of choices.
|
||||
@@ -216,6 +336,11 @@ var ListColumnIdentifier = @"1";
|
||||
if ([_panel isVisible])
|
||||
return;
|
||||
|
||||
[self listWillPopUp];
|
||||
|
||||
[_panel _trapNextMouseDown];
|
||||
[[aView window] addChildWindow:_panel ordered:CPWindowAbove];
|
||||
|
||||
var rowRect = [_tableView rectOfRow:[self numberOfRowsInTableView:_tableView] - 1],
|
||||
frame = CGRectMake(0, 0, MAX(_listWidth, CGRectGetWidth(aRect)), CGRectGetMaxY(rowRect));
|
||||
|
||||
@@ -226,10 +351,6 @@ var ListColumnIdentifier = @"1";
|
||||
[_scrollView setFrameSize:CGSizeMakeCopy(frame.size)];
|
||||
[_tableView setEnabled:[_dataSource numberOfItemsInList:self] > 0];
|
||||
[self scrollItemAtIndexToTop:[_tableView selectedRow]];
|
||||
|
||||
[self listWillPopUp];
|
||||
|
||||
[_panel orderFront:nil];
|
||||
}
|
||||
|
||||
#pragma mark Setting Display Attributes
|
||||
@@ -800,110 +921,3 @@ var _CPPopUpListDataSourceKey = @"_CPPopUpListDataSourceKey",
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation _CPPopUpTableView : CPTableView
|
||||
{
|
||||
BOOL _acceptFirstResponder;
|
||||
}
|
||||
|
||||
- (id)initWithFrame:(CGRect)aFrame
|
||||
{
|
||||
if (self = [super initWithFrame:aFrame])
|
||||
{
|
||||
// We want the autocomplete to remain first responder until we are clicked.
|
||||
_acceptFirstResponder = NO;
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)trackMouse:(CPEvent)anEvent
|
||||
{
|
||||
if (![self isEnabled])
|
||||
return;
|
||||
|
||||
[[self delegate] setItemWasClicked:YES];
|
||||
|
||||
// CPTableView will not track the click if it is not first responder
|
||||
_acceptFirstResponder = YES;
|
||||
[[self window] makeFirstResponder:self];
|
||||
[super trackMouse:anEvent];
|
||||
}
|
||||
|
||||
- (void)stopTracking:(CGPoint)lastPoint at:(CGPoint)aPoint mouseIsUp:(BOOL)mouseIsUp
|
||||
{
|
||||
_acceptFirstResponder = NO;
|
||||
[super stopTracking:lastPoint at:aPoint mouseIsUp:mouseIsUp];
|
||||
}
|
||||
|
||||
- (BOOL)acceptsFirstResponder
|
||||
{
|
||||
return _acceptFirstResponder;
|
||||
}
|
||||
|
||||
/*!
|
||||
Return the column used for the list.
|
||||
*/
|
||||
- (CPTableColumn)listColumn
|
||||
{
|
||||
return _tableColumns[0];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation _CPPopUpPanel : CPPanel
|
||||
|
||||
- (id)initWithContentRect:(CGRect)aContentRect styleMask:(unsigned)aStyleMask
|
||||
{
|
||||
if (self = [super initWithContentRect:aContentRect styleMask:aStyleMask])
|
||||
_constrainsToUsableScreen = NO;
|
||||
|
||||
[self _trapNextMouseDown];
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns \c YES if the receiver is able to receive input events
|
||||
even when a modal session is active.
|
||||
*/
|
||||
- (BOOL)worksWhenModal
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (void)sendEvent:(CPEvent)anEvent
|
||||
{
|
||||
var type = [anEvent type];
|
||||
|
||||
if (type === CPLeftMouseDown || type === CPRightMouseDown)
|
||||
[[self delegate] setListWasClicked:YES];
|
||||
|
||||
return [super sendEvent:anEvent];
|
||||
}
|
||||
|
||||
- (void)orderFront:(id)sender
|
||||
{
|
||||
[self _trapNextMouseDown];
|
||||
[super orderFront:sender];
|
||||
}
|
||||
|
||||
- (void)_mouseWasClicked:(CPEvent)anEvent
|
||||
{
|
||||
var mouseWindow = [anEvent window],
|
||||
rect = [[[self delegate] dataSource] bounds],
|
||||
point = [[[self delegate] dataSource] convertPoint:[anEvent locationInWindow] fromView:nil];
|
||||
|
||||
if (mouseWindow != self && !CGRectContainsPoint(rect, point))
|
||||
[[self delegate] close];
|
||||
else
|
||||
[self _trapNextMouseDown];
|
||||
}
|
||||
|
||||
- (void)_trapNextMouseDown
|
||||
{
|
||||
// Don't dequeue the event so clicks in controls will work
|
||||
[CPApp setTarget:self selector:@selector(_mouseWasClicked:) forNextEventMatchingMask:CPLeftMouseDownMask untilDate:nil inMode:CPDefaultRunLoopMode dequeue:NO];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
+15
-12
@@ -64,6 +64,7 @@ var _CPPopoverWindow_shouldClose_ = 1 << 4,
|
||||
BOOL _isObservingFrame;
|
||||
BOOL _shouldPerformAnimation;
|
||||
CPInteger _implementedDelegateMethods;
|
||||
CGRect _targetRect;
|
||||
CPWindow _targetWindow;
|
||||
JSObject _orderOutTransitionFunction;
|
||||
JSObject _transitionCompleteFunction;
|
||||
@@ -206,8 +207,7 @@ var _CPPopoverWindow_shouldClose_ = 1 << 4,
|
||||
if (![_targetView window])
|
||||
return;
|
||||
|
||||
var point = [self computeOriginFromRect:[_targetView bounds] ofView:_targetView preferredEdge:[_windowView preferredEdge]];
|
||||
|
||||
var point = [self computeOriginFromRect:_targetRect ofView:_targetView preferredEdge:[_windowView preferredEdge]];
|
||||
[self setFrameOrigin:point];
|
||||
}
|
||||
}
|
||||
@@ -362,7 +362,6 @@ var _CPPopoverWindow_shouldClose_ = 1 << 4,
|
||||
[self setFrameOrigin:point];
|
||||
[_windowView showCursor];
|
||||
[_windowView setNeedsDisplay:YES];
|
||||
[self makeKeyAndOrderFront:nil];
|
||||
|
||||
if (positioningView !== _targetView)
|
||||
{
|
||||
@@ -371,6 +370,9 @@ var _CPPopoverWindow_shouldClose_ = 1 << 4,
|
||||
_targetView = positioningView;
|
||||
}
|
||||
|
||||
_targetRect = aRect;
|
||||
[self makeKeyAndOrderFront:nil];
|
||||
|
||||
/*
|
||||
If _targetView's window is not a full platform window,
|
||||
add us as a child, because when we close we are detached from
|
||||
@@ -417,7 +419,7 @@ var _CPPopoverWindow_shouldClose_ = 1 << 4,
|
||||
|
||||
if ([self isVisible])
|
||||
{
|
||||
var point = [self computeOriginFromRect:[_targetView bounds] ofView:_targetView preferredEdge:[_windowView preferredEdge]];
|
||||
var point = [self computeOriginFromRect:_targetRect ofView:_targetView preferredEdge:[_windowView preferredEdge]];
|
||||
[self setFrameOrigin:point];
|
||||
}
|
||||
}
|
||||
@@ -581,10 +583,12 @@ var _CPPopoverWindow_shouldClose_ = 1 << 4,
|
||||
|
||||
- (void)_orderFront
|
||||
{
|
||||
if (![self isVisible])
|
||||
[self _addFrameObserver];
|
||||
var wasVisible = [self isVisible];
|
||||
|
||||
[super _orderFront];
|
||||
|
||||
if (!wasVisible)
|
||||
[self _addFrameObserver];
|
||||
}
|
||||
|
||||
- (void)_parentDidOrderInChild
|
||||
@@ -720,17 +724,16 @@ var _CPPopoverWindow_shouldClose_ = 1 << 4,
|
||||
break;
|
||||
}
|
||||
|
||||
[_delegate close];
|
||||
[_delegate performClose:self];
|
||||
break;
|
||||
|
||||
case CPPopoverBehaviorTransient:
|
||||
[_delegate close];
|
||||
break;
|
||||
|
||||
case CPPopoverBehaviorApplicationDefined:
|
||||
[self _trapNextMouseDown];
|
||||
[_delegate performClose:self];
|
||||
break;
|
||||
}
|
||||
|
||||
if ([self isVisible])
|
||||
[self _trapNextMouseDown];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
@import "CPImage.j"
|
||||
@import "CPView.j"
|
||||
|
||||
@class CPToolbar
|
||||
@global CPApp
|
||||
|
||||
CPToolbarItemVisibilityPriorityStandard = 0;
|
||||
|
||||
@@ -53,7 +53,7 @@
|
||||
@param aType the structure or object type
|
||||
@param anObject the object to be encoded
|
||||
*/
|
||||
- (void)encodeValueOfObjCType:(CPString)aType at:(id)anObject
|
||||
- (void)encodeValueOfObjJType:(CPString)aType at:(id)anObject
|
||||
{
|
||||
_CPRaiseInvalidAbstractInvocation(self, _cmd);
|
||||
}
|
||||
|
||||
@@ -74,24 +74,36 @@ var CPDateReferenceDate = new Date(Date.UTC(2001, 0, 1, 0, 0, 0, 0));
|
||||
|
||||
- (id)initWithTimeIntervalSinceNow:(CPTimeInterval)seconds
|
||||
{
|
||||
if (!_isNumberType(seconds))
|
||||
CPLog.warn(@"The parameter of the method initWithTimeIntervalSinceNow: should be an integer or a float");
|
||||
|
||||
self = new Date((new Date()).getTime() + seconds * 1000);
|
||||
return self;
|
||||
}
|
||||
|
||||
- (id)initWithTimeIntervalSince1970:(CPTimeInterval)seconds
|
||||
{
|
||||
if (!_isNumberType(seconds))
|
||||
CPLog.warn(@"The parameter of the method initWithTimeIntervalSince1970: should be an integer or a float");
|
||||
|
||||
self = new Date(seconds * 1000);
|
||||
return self;
|
||||
}
|
||||
|
||||
- (id)initWithTimeIntervalSinceReferenceDate:(CPTimeInterval)seconds
|
||||
{
|
||||
if (!_isNumberType(seconds))
|
||||
CPLog.warn(@"The parameter of the method initWithTimeIntervalSinceReferenceDate: should be an integer or a float");
|
||||
|
||||
self = [self initWithTimeInterval:seconds sinceDate:CPDateReferenceDate];
|
||||
return self;
|
||||
}
|
||||
|
||||
- (id)initWithTimeInterval:(CPTimeInterval)seconds sinceDate:(CPDate)refDate
|
||||
{
|
||||
if (!_isNumberType(seconds))
|
||||
CPLog.warn(@"The parameter of the method initWithTimeInterval:sinceDate: should be an integer or a float");
|
||||
|
||||
self = new Date(refDate.getTime() + seconds * 1000);
|
||||
return self;
|
||||
}
|
||||
@@ -275,3 +287,11 @@ Date.parseISO8601 = function (date)
|
||||
};
|
||||
|
||||
Date.prototype.isa = CPDate;
|
||||
|
||||
function _isNumberType(value)
|
||||
{
|
||||
if (typeof value === 'number')
|
||||
return YES;
|
||||
else
|
||||
return NO;
|
||||
}
|
||||
@@ -28,16 +28,19 @@
|
||||
@import "CPLocale.j"
|
||||
|
||||
@class CPNull
|
||||
@class CPDictionary
|
||||
|
||||
@global CPLocaleLanguageCode
|
||||
@global CPLocaleCountryCode
|
||||
|
||||
@typedef CPDateFormatterStyle
|
||||
CPDateFormatterNoStyle = 0;
|
||||
CPDateFormatterShortStyle = 1;
|
||||
CPDateFormatterMediumStyle = 2;
|
||||
CPDateFormatterLongStyle = 3;
|
||||
CPDateFormatterFullStyle = 4;
|
||||
|
||||
@typedef CPDateFormatterBehavior
|
||||
CPDateFormatterBehaviorDefault = 0;
|
||||
CPDateFormatterBehavior10_0 = 1000;
|
||||
CPDateFormatterBehavior10_4 = 1040;
|
||||
|
||||
@@ -52,6 +52,8 @@
|
||||
@import "CPArray.j"
|
||||
@import "CPNumber.j"
|
||||
|
||||
@typedef CPDecimal
|
||||
|
||||
// Decimal size limits
|
||||
CPDecimalMaxDigits = 38;
|
||||
CPDecimalMaxExponent = 127;
|
||||
@@ -68,6 +70,7 @@ CPCalculationUnderflow = 3;
|
||||
CPCalculationDivideByZero = 4;
|
||||
|
||||
//CPRoundingMode Enum
|
||||
@typedef CPRoundingMode
|
||||
CPRoundPlain = 1;
|
||||
CPRoundDown = 2;
|
||||
CPRoundUp = 3;
|
||||
|
||||
+34
-32
@@ -31,38 +31,6 @@ var CPDictionaryShowNilDeprecationMessage = YES,
|
||||
|
||||
CPDictionaryMaxDescriptionRecursion = 10;
|
||||
|
||||
/* @ignore */
|
||||
@implementation _CPDictionaryValueEnumerator : CPEnumerator
|
||||
{
|
||||
CPEnumerator _keyEnumerator;
|
||||
CPDictionary _dictionary;
|
||||
}
|
||||
|
||||
- (id)initWithDictionary:(CPDictionary)aDictionary
|
||||
{
|
||||
self = [super init];
|
||||
|
||||
if (self)
|
||||
{
|
||||
_keyEnumerator = [aDictionary keyEnumerator];
|
||||
_dictionary = aDictionary;
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (id)nextObject
|
||||
{
|
||||
var key = [_keyEnumerator nextObject];
|
||||
|
||||
if (key === nil)
|
||||
return nil;
|
||||
|
||||
return [_dictionary objectForKey:key];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
/*!
|
||||
@class CPDictionary
|
||||
@ingroup foundation
|
||||
@@ -801,6 +769,40 @@ var CPDictionaryShowNilDeprecationMessage = YES,
|
||||
|
||||
@end
|
||||
|
||||
|
||||
/* @ignore */
|
||||
@implementation _CPDictionaryValueEnumerator : CPEnumerator
|
||||
{
|
||||
CPEnumerator _keyEnumerator;
|
||||
CPDictionary _dictionary;
|
||||
}
|
||||
|
||||
- (id)initWithDictionary:(CPDictionary)aDictionary
|
||||
{
|
||||
self = [super init];
|
||||
|
||||
if (self)
|
||||
{
|
||||
_keyEnumerator = [aDictionary keyEnumerator];
|
||||
_dictionary = aDictionary;
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (id)nextObject
|
||||
{
|
||||
var key = [_keyEnumerator nextObject];
|
||||
|
||||
if (key === nil)
|
||||
return nil;
|
||||
|
||||
return [_dictionary objectForKey:key];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
/*!
|
||||
@class CPMutableDictionary
|
||||
@ingroup compatibility
|
||||
|
||||
+97
-26
@@ -24,31 +24,52 @@
|
||||
@import "CPObject.j"
|
||||
@import "CPString.j"
|
||||
|
||||
CPCappuccinoErrorDomain = CPCocoaErrorDomain = @"CPCappuccinoErrorDomain";
|
||||
// CPPOSIXErrorDomain = @"CPPOSIXErrorDomain";
|
||||
// CPOSStatusErrorDomain = @"CPOSStatusErrorDomain";
|
||||
CPCappuccinoErrorDomain = kCFErrorDomainCappuccino;
|
||||
CPCocoaErrorDomain = kCFErrorDomainCappuccino; // compat
|
||||
|
||||
CPUnderlyingErrorKey = @"CPUnderlyingErrorKey";
|
||||
CPUnderlyingErrorKey = kCFErrorUnderlyingErrorKey;
|
||||
|
||||
CPLocalizedDescriptionKey = @"CPLocalizedDescriptionKey";
|
||||
CPLocalizedFailureReasonErrorKey = @"CPLocalizedFailureReasonErrorKey";
|
||||
CPLocalizedRecoverySuggestionErrorKey = @"CPLocalizedRecoverySuggestionErrorKey";
|
||||
CPLocalizedDescriptionKey = kCFErrorLocalizedDescriptionKey;
|
||||
CPLocalizedFailureReasonErrorKey = kCFErrorLocalizedFailureReasonKey;
|
||||
CPLocalizedRecoverySuggestionErrorKey = kCFErrorLocalizedRecoverySuggestionKey;
|
||||
CPLocalizedRecoveryOptionsErrorKey = @"CPLocalizedRecoveryOptionsErrorKey";
|
||||
CPRecoveryAttempterErrorKey = @"CPRecoveryAttempterErrorKey";
|
||||
CPHelpAnchorErrorKey = @"CPHelpAnchorErrorKey";
|
||||
|
||||
CPStringEncodingErrorKey = @"CPStringEncodingErrorKey";
|
||||
CPURLErrorKey = @"CPURLErrorKey";
|
||||
CPFilePathErrorKey = @"CPFilePathErrorKey";
|
||||
CPURLErrorKey = kCFErrorURLKey;
|
||||
CPFilePathErrorKey = kCFErrorFilePathKey;
|
||||
|
||||
/*!
|
||||
@class CPError
|
||||
@ingroup foundation
|
||||
@brief Used for encapsulating, presenting, and recovery from errors.
|
||||
|
||||
CPError is toll-free bridged with CFError() methods.
|
||||
|
||||
An example of initializing a CPError:
|
||||
<pre>
|
||||
|
||||
var userInfo = @{CPLocalizedDescriptionKey: @"A localized error description",
|
||||
CPLocalizedFailureReasonErrorKey: @"A localized failure reason",
|
||||
CPUnderlyingErrorKey: @"An underlying error message"},
|
||||
|
||||
err = [CPError errorWithDomain:CPCappuccinoErrorDomain code:-10 userInfo:userInfo];
|
||||
</pre>
|
||||
*/
|
||||
@implementation CPError : CPObject
|
||||
{
|
||||
CPInteger _code @accessors(property=code, readonly);
|
||||
CPString _domain @accessors(property=domain, readonly);
|
||||
CPDictionary _userInfo @accessors(property=userInfo, readonly);
|
||||
}
|
||||
|
||||
+ (id)alloc
|
||||
{
|
||||
var obj = new CFError();
|
||||
obj.isa = [self class];
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
|
||||
+ (id)errorWithDomain:(CPString)aDomain code:(CPInteger)aCode userInfo:(CPDictionary)aDict
|
||||
{
|
||||
return [[CPError alloc] initWithDomain:aDomain code:aCode userInfo:aDict];
|
||||
@@ -56,44 +77,94 @@ CPFilePathErrorKey = @"CPFilePathErrorKey";
|
||||
|
||||
- (id)initWithDomain:(CPString)aDomain code:(CPInteger)aCode userInfo:(CPDictionary)aDict
|
||||
{
|
||||
if (self = [super init])
|
||||
{
|
||||
_domain = aDomain;
|
||||
_code = aCode;
|
||||
_userInfo = aDict;
|
||||
}
|
||||
|
||||
return self;
|
||||
var result = new CFError(aDomain, aCode, aDict);
|
||||
result.isa = [self class];
|
||||
return result;
|
||||
}
|
||||
|
||||
- (CPInteger)code
|
||||
{
|
||||
return self.code();
|
||||
}
|
||||
|
||||
- (CPString)userInfo
|
||||
{
|
||||
return self.userInfo();
|
||||
}
|
||||
|
||||
- (CPString)domain
|
||||
{
|
||||
return self.domain();
|
||||
}
|
||||
|
||||
/*!
|
||||
By default this method returns the object in the user info dictionary for the key
|
||||
CPLocalizedDescriptionKey. If the user info dictionary doesn’t contain a value for
|
||||
CPLocalizedDescriptionKey, a default string is constructed from the domain and code.
|
||||
*/
|
||||
- (CPString)localizedDescription
|
||||
{
|
||||
return [_userInfo objectForKey:CPLocalizedDescriptionKey];
|
||||
return self.description();
|
||||
}
|
||||
|
||||
- (CPString)localizedFailureReason
|
||||
{
|
||||
return [_userInfo objectForKey:CPLocalizedFailureReasonErrorKey];
|
||||
return self.failureReason();
|
||||
}
|
||||
|
||||
- (CPArray)localizedRecoveryOptions
|
||||
{
|
||||
return [_userInfo objectForKey:CPLocalizedRecoveryOptionsErrorKey];
|
||||
var userInfo = self.userInfo(),
|
||||
recoveryOptions = userInfo.valueForKey(CPLocalizedRecoveryOptionsErrorKey);
|
||||
|
||||
return recoveryOptions;
|
||||
}
|
||||
|
||||
- (CPString)localizedRecoverySuggestion
|
||||
{
|
||||
return [_userInfo objectForKey:CPLocalizedRecoverySuggestionErrorKey];
|
||||
return self.recoverySuggestion();
|
||||
}
|
||||
|
||||
- (id)recoveryAttempter
|
||||
{
|
||||
return [_userInfo objectForKey:CPRecoveryAttempterErrorKey];
|
||||
var userInfo = self.userInfo(),
|
||||
recoveryAttempter = userInfo.valueForKey(CPRecoveryAttempterErrorKey);
|
||||
|
||||
return recoveryAttempter;
|
||||
}
|
||||
|
||||
- (CPString)description
|
||||
{
|
||||
return [CPString stringWithFormat:@"Error Domain=%@ Code=%d UserInfo=%p %@", _domain, _code, _userInfo, [self localizedDescription]];
|
||||
return [CPString stringWithFormat:@"Error Domain=%@ Code=%d \"%@\" UserInfo=%@", self.domain(), self.code(), self.description(), self.userInfo()];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
var CPErrorCodeKey = @"CPErrorCodeKey",
|
||||
CPErrorDomainKey = @"CPErrorDomainKey",
|
||||
CPErrorUserInfoKey = @"CPErrorUserInfoKey";
|
||||
|
||||
@implementation CPError (CPCoding)
|
||||
|
||||
- (id)initWithCoder:(CPCoder)aCoder
|
||||
{
|
||||
var code = [aCoder decodeIntForKey:CPErrorCodeKey],
|
||||
domain = [aCoder decodeObjectForKey:CPErrorDomainKey],
|
||||
userInfo = [aCoder decodeObjectForKey:CPErrorUserInfoKey];
|
||||
|
||||
return [self initWithDomain:domain
|
||||
code:code
|
||||
userInfo:userInfo];
|
||||
}
|
||||
|
||||
- (void)encodeWithCoder:(CPCoder)aCoder
|
||||
{
|
||||
[aCoder encodeObject:self.domain() forKey:CPErrorDomainKey];
|
||||
[aCoder encodeObject:self.code() forKey:CPErrorCodeKey];
|
||||
[aCoder encodeObject:self.userInfo() forKey:CPErrorUserInfoKey];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
CFError.prototype.isa = CPError;
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
|
||||
@import "_CGGeometry.j"
|
||||
|
||||
@typedef CPRectEdge
|
||||
CPMinXEdge = 0;
|
||||
CPMinYEdge = 1;
|
||||
CPMaxXEdge = 2;
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
*/
|
||||
|
||||
@import "CPObject.j"
|
||||
@import "CPArray.j"
|
||||
|
||||
/*!
|
||||
@class CPInvocation
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
@import "CPException.j"
|
||||
@import "CPObject.j"
|
||||
@import "CPRunLoop.j"
|
||||
@import "CPURLRequest.j"
|
||||
|
||||
CPJSONPConnectionCallbacks = {};
|
||||
|
||||
|
||||
@@ -327,6 +327,7 @@ var kvoNewAndOld = CPKeyValueObservingOptionNew | CPKeyValueObservingOpti
|
||||
Class _nativeClass;
|
||||
CPDictionary _changesForKey;
|
||||
CPDictionary _nestingForKey;
|
||||
CPDictionary _minOptionsForKey;
|
||||
Object _observersForKey;
|
||||
int _observersForKeyLength;
|
||||
CPSet _replacedKeys;
|
||||
@@ -354,6 +355,7 @@ var kvoNewAndOld = CPKeyValueObservingOptionNew | CPKeyValueObservingOpti
|
||||
_observersForKey = {};
|
||||
_changesForKey = {};
|
||||
_nestingForKey = {};
|
||||
_minOptionsForKey = {};
|
||||
_observersForKeyLength = 0;
|
||||
|
||||
[self _replaceClass];
|
||||
@@ -767,12 +769,20 @@ var kvoNewAndOld = CPKeyValueObservingOptionNew | CPKeyValueObservingOpti
|
||||
|
||||
if (options & CPKeyValueObservingOptionInitial)
|
||||
{
|
||||
var newValue = [_targetObject valueForKeyPath:aPath];
|
||||
var changes;
|
||||
|
||||
if (newValue === nil || newValue === undefined)
|
||||
newValue = [CPNull null];
|
||||
if (options & CPKeyValueObservingOptionNew)
|
||||
{
|
||||
var newValue = [_targetObject valueForKeyPath:aPath];
|
||||
|
||||
if (newValue == nil)
|
||||
newValue = [CPNull null];
|
||||
|
||||
changes = @{ CPKeyValueChangeKindKey: CPKeyValueChangeSetting, CPKeyValueChangeNewKey: newValue };
|
||||
} else {
|
||||
changes = @{ CPKeyValueChangeKindKey: CPKeyValueChangeSetting };
|
||||
}
|
||||
|
||||
var changes = @{ CPKeyValueChangeNewKey: newValue };
|
||||
[anObserver observeValueForKeyPath:aPath ofObject:_targetObject change:changes context:aContext];
|
||||
}
|
||||
}
|
||||
@@ -819,7 +829,9 @@ var kvoNewAndOld = CPKeyValueObservingOptionNew | CPKeyValueObservingOpti
|
||||
|
||||
- (void)_sendNotificationsForKey:(CPString)aKey changeOptions:(CPDictionary)changeOptions isBefore:(BOOL)isBefore
|
||||
{
|
||||
var changes = _changesForKey[aKey];
|
||||
var changes = _changesForKey[aKey],
|
||||
observers = [_observersForKey[aKey] allValues],
|
||||
observersMinimumOptions = 0;
|
||||
|
||||
if (isBefore)
|
||||
{
|
||||
@@ -838,61 +850,78 @@ var kvoNewAndOld = CPKeyValueObservingOptionNew | CPKeyValueObservingOpti
|
||||
|
||||
_nestingForKey[aKey] = 1;
|
||||
|
||||
// Get the combined minimum of the ...Old and ...New options for all observers
|
||||
var count = observers ? observers.length : 0;
|
||||
|
||||
while (count--)
|
||||
{
|
||||
var observerInfo = observers[count];
|
||||
|
||||
observersMinimumOptions |= observerInfo.options & kvoNewAndOld;
|
||||
}
|
||||
|
||||
_minOptionsForKey[aKey] = observersMinimumOptions;
|
||||
changes = changeOptions;
|
||||
|
||||
var indexes = [changes objectForKey:CPKeyValueChangeIndexesKey],
|
||||
setMutationKind = changes[_CPKeyValueChangeSetMutationKindKey];
|
||||
|
||||
if (setMutationKind)
|
||||
if (observersMinimumOptions & CPKeyValueObservingOptionOld)
|
||||
{
|
||||
var setMutationObjects = [changes[_CPKeyValueChangeSetMutationObjectsKey] copy],
|
||||
setExistingObjects = [[_targetObject valueForKey: aKey] copy];
|
||||
var indexes = [changes objectForKey:CPKeyValueChangeIndexesKey],
|
||||
setMutationKind = changes[_CPKeyValueChangeSetMutationKindKey];
|
||||
|
||||
if (setMutationKind == CPKeyValueMinusSetMutation)
|
||||
if (setMutationKind)
|
||||
{
|
||||
[setExistingObjects intersectSet: setMutationObjects];
|
||||
[changes setValue:setExistingObjects forKey:CPKeyValueChangeOldKey];
|
||||
var setMutationObjects = [changes[_CPKeyValueChangeSetMutationObjectsKey] copy],
|
||||
setExistingObjects = [[_targetObject valueForKey: aKey] copy];
|
||||
|
||||
if (setMutationKind == CPKeyValueMinusSetMutation)
|
||||
{
|
||||
[setExistingObjects intersectSet: setMutationObjects];
|
||||
[changes setValue:setExistingObjects forKey:CPKeyValueChangeOldKey];
|
||||
}
|
||||
else if (setMutationKind === CPKeyValueIntersectSetMutation || setMutationKind === CPKeyValueSetSetMutation)
|
||||
{
|
||||
[setExistingObjects minusSet: setMutationObjects];
|
||||
[changes setValue:setExistingObjects forKey:CPKeyValueChangeOldKey];
|
||||
}
|
||||
|
||||
//for unordered to-many relationships (CPSet) even new values can only be calculated before!!!
|
||||
if (setMutationKind === CPKeyValueUnionSetMutation || setMutationKind === CPKeyValueSetSetMutation)
|
||||
{
|
||||
[setMutationObjects minusSet: setExistingObjects];
|
||||
//hide new value (for CPKeyValueObservingOptionPrior messages)
|
||||
//as long as "didChangeValue..." is not yet called!
|
||||
changes[_CPKeyValueChangeSetMutationNewValueKey] = setMutationObjects;
|
||||
}
|
||||
}
|
||||
else if (setMutationKind === CPKeyValueIntersectSetMutation || setMutationKind === CPKeyValueSetSetMutation)
|
||||
else if (indexes)
|
||||
{
|
||||
[setExistingObjects minusSet: setMutationObjects];
|
||||
[changes setValue:setExistingObjects forKey:CPKeyValueChangeOldKey];
|
||||
var type = [changes objectForKey:CPKeyValueChangeKindKey];
|
||||
|
||||
// for ordered to-many relationships, oldvalue is only sensible for replace and remove
|
||||
if (type === CPKeyValueChangeReplacement || type === CPKeyValueChangeRemoval)
|
||||
{
|
||||
//FIXME: do we need to go through and replace "" with CPNull?
|
||||
var newValues = [[_targetObject mutableArrayValueForKeyPath:aKey] objectsAtIndexes:indexes];
|
||||
[changes setValue:newValues forKey:CPKeyValueChangeOldKey];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var oldValue = [_targetObject valueForKey:aKey];
|
||||
|
||||
if (oldValue === nil || oldValue === undefined)
|
||||
oldValue = [CPNull null];
|
||||
|
||||
[changes setObject:oldValue forKey:CPKeyValueChangeOldKey];
|
||||
}
|
||||
|
||||
//for unordered to-many relationships (CPSet) even new values can only be calculated before!!!
|
||||
if (setMutationKind === CPKeyValueUnionSetMutation || setMutationKind === CPKeyValueSetSetMutation)
|
||||
{
|
||||
[setMutationObjects minusSet: setExistingObjects];
|
||||
//hide new value (for CPKeyValueObservingOptionPrior messages)
|
||||
//as long as "didChangeValue..." is not yet called!
|
||||
changes[_CPKeyValueChangeSetMutationNewValueKey] = setMutationObjects;
|
||||
}
|
||||
}
|
||||
else if (indexes)
|
||||
{
|
||||
var type = [changes objectForKey:CPKeyValueChangeKindKey];
|
||||
|
||||
// for ordered to-many relationships, oldvalue is only sensible for replace and remove
|
||||
if (type === CPKeyValueChangeReplacement || type === CPKeyValueChangeRemoval)
|
||||
{
|
||||
//FIXME: do we need to go through and replace "" with CPNull?
|
||||
var newValues = [[_targetObject mutableArrayValueForKeyPath:aKey] objectsAtIndexes:indexes];
|
||||
[changes setValue:newValues forKey:CPKeyValueChangeOldKey];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var oldValue = [_targetObject valueForKey:aKey];
|
||||
|
||||
if (oldValue === nil || oldValue === undefined)
|
||||
oldValue = [CPNull null];
|
||||
|
||||
[changes setObject:oldValue forKey:CPKeyValueChangeOldKey];
|
||||
}
|
||||
|
||||
[changes setObject:1 forKey:CPKeyValueChangeNotificationIsPriorKey];
|
||||
|
||||
_changesForKey[aKey] = changes;
|
||||
|
||||
// Clear ...New option as it should never be sent for a ...Prior option
|
||||
observersMinimumOptions &= ~CPKeyValueObservingOptionNew;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -927,55 +956,97 @@ var kvoNewAndOld = CPKeyValueObservingOptionNew | CPKeyValueObservingOpti
|
||||
|
||||
[changes removeObjectForKey:CPKeyValueChangeNotificationIsPriorKey];
|
||||
|
||||
var indexes = [changes objectForKey:CPKeyValueChangeIndexesKey],
|
||||
setMutationKind = changes[_CPKeyValueChangeSetMutationKindKey];
|
||||
observersMinimumOptions = _minOptionsForKey[aKey];
|
||||
|
||||
if (setMutationKind)
|
||||
if (observersMinimumOptions & CPKeyValueObservingOptionNew)
|
||||
{
|
||||
//old and new values for unordered to-many relationships can only be calculated before
|
||||
//set recalculated hidden new value as soon as "didChangeValue..." is called!
|
||||
var newValue = changes[_CPKeyValueChangeSetMutationNewValueKey];
|
||||
[changes setValue:newValue forKey:CPKeyValueChangeNewKey];
|
||||
var indexes = [changes objectForKey:CPKeyValueChangeIndexesKey],
|
||||
setMutationKind = changes[_CPKeyValueChangeSetMutationKindKey];
|
||||
|
||||
//delete hidden values
|
||||
delete changes[_CPKeyValueChangeSetMutationNewValueKey];
|
||||
delete changes[_CPKeyValueChangeSetMutationObjectsKey];
|
||||
delete changes[_CPKeyValueChangeSetMutationKindKey];
|
||||
}
|
||||
else if (indexes)
|
||||
{
|
||||
var type = [changes objectForKey:CPKeyValueChangeKindKey];
|
||||
|
||||
// for ordered to-many relationships, newvalue is only sensible for replace and insert
|
||||
if (type == CPKeyValueChangeReplacement || type == CPKeyValueChangeInsertion)
|
||||
if (setMutationKind)
|
||||
{
|
||||
//FIXME: do we need to go through and replace "" with CPNull?
|
||||
var newValues = [[_targetObject mutableArrayValueForKeyPath:aKey] objectsAtIndexes:indexes];
|
||||
[changes setValue:newValues forKey:CPKeyValueChangeNewKey];
|
||||
//old and new values for unordered to-many relationships can only be calculated before
|
||||
//set recalculated hidden new value as soon as "didChangeValue..." is called!
|
||||
var newValue = changes[_CPKeyValueChangeSetMutationNewValueKey];
|
||||
[changes setValue:newValue forKey:CPKeyValueChangeNewKey];
|
||||
|
||||
//delete hidden values
|
||||
delete changes[_CPKeyValueChangeSetMutationNewValueKey];
|
||||
delete changes[_CPKeyValueChangeSetMutationObjectsKey];
|
||||
delete changes[_CPKeyValueChangeSetMutationKindKey];
|
||||
}
|
||||
else if (indexes)
|
||||
{
|
||||
var type = [changes objectForKey:CPKeyValueChangeKindKey];
|
||||
|
||||
// for ordered to-many relationships, newvalue is only sensible for replace and insert
|
||||
if (type == CPKeyValueChangeReplacement || type == CPKeyValueChangeInsertion)
|
||||
{
|
||||
//FIXME: do we need to go through and replace "" with CPNull?
|
||||
var newValues = [[_targetObject mutableArrayValueForKeyPath:aKey] objectsAtIndexes:indexes];
|
||||
[changes setValue:newValues forKey:CPKeyValueChangeNewKey];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var newValue = [_targetObject valueForKey:aKey];
|
||||
|
||||
if (newValue === nil || newValue === undefined)
|
||||
newValue = [CPNull null];
|
||||
|
||||
[changes setObject:newValue forKey:CPKeyValueChangeNewKey];
|
||||
}
|
||||
}
|
||||
|
||||
delete _minOptionsForKey[aKey];
|
||||
delete _changesForKey[aKey];
|
||||
}
|
||||
|
||||
var count = observers ? observers.length : 0,
|
||||
changesCache = {};
|
||||
|
||||
while (count--)
|
||||
{
|
||||
var observerInfo = observers[count],
|
||||
options = observerInfo.options,
|
||||
onlyNewAndOldOptions = options & kvoNewAndOld,
|
||||
observerChanges = nil;
|
||||
|
||||
if (isBefore)
|
||||
{
|
||||
// Only send 'observeValueForKeyPath:' for '...Prior' option when handling 'willChangeValue...'
|
||||
if (options & CPKeyValueObservingOptionPrior)
|
||||
{
|
||||
observerChanges = changes;
|
||||
// The new values are not yet created in the change dictionary so remove ...New option to get a working cache below
|
||||
onlyNewAndOldOptions &= ~CPKeyValueObservingOptionNew;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var newValue = [_targetObject valueForKey:aKey];
|
||||
|
||||
if (newValue === nil || newValue === undefined)
|
||||
newValue = [CPNull null];
|
||||
|
||||
[changes setObject:newValue forKey:CPKeyValueChangeNewKey];
|
||||
observerChanges = changes;
|
||||
}
|
||||
|
||||
delete _changesForKey[aKey];
|
||||
}
|
||||
|
||||
var observers = [_observersForKey[aKey] allValues],
|
||||
count = observers ? observers.length : 0;
|
||||
|
||||
while (count--)
|
||||
{
|
||||
var observerInfo = observers[count];
|
||||
|
||||
if (!isBefore || (observerInfo.options & CPKeyValueObservingOptionPrior))
|
||||
[observerInfo.observer observeValueForKeyPath:aKey ofObject:_targetObject change:changes context:observerInfo.context];
|
||||
if (observerChanges)
|
||||
{
|
||||
// Don't change the 'change' dictionary when the observer wants the minimum options.
|
||||
// The ...New option is remved above for the ...Prior case
|
||||
if (onlyNewAndOldOptions !== observersMinimumOptions)
|
||||
{
|
||||
// Use a subset of the 'change' dictionary. First try to find it in the cache
|
||||
observerChanges = changesCache[onlyNewAndOldOptions];
|
||||
if (!observerChanges)
|
||||
{
|
||||
// Not in the cache. Build a new dictionary and store it in the cache
|
||||
changesCache[onlyNewAndOldOptions] = observerChanges = [changes mutableCopy];
|
||||
if (!(onlyNewAndOldOptions & CPKeyValueObservingOptionOld))
|
||||
[observerChanges removeObjectForKey:CPKeyValueChangeOldKey];
|
||||
if (!(onlyNewAndOldOptions & CPKeyValueObservingOptionNew))
|
||||
[observerChanges removeObjectForKey:CPKeyValueChangeNewKey];
|
||||
}
|
||||
}
|
||||
[observerInfo.observer observeValueForKeyPath:aKey ofObject:_targetObject change:observerChanges context:observerInfo.context];
|
||||
}
|
||||
}
|
||||
|
||||
var dependentKeysMap = _nativeClass[DependentKeysKey];
|
||||
@@ -1226,13 +1297,21 @@ var kvoNewAndOld = CPKeyValueObservingOptionNew | CPKeyValueObservingOpti
|
||||
{
|
||||
if (aKeyPath === _firstPart)
|
||||
{
|
||||
var oldValue = [_value valueForKeyPath:_secondPart],
|
||||
newValue = [_object valueForKeyPath:_firstPart + "." + _secondPart],
|
||||
pathChanges = @{
|
||||
CPKeyValueChangeNewKey: newValue ? newValue : [CPNull null],
|
||||
CPKeyValueChangeOldKey: oldValue ? oldValue : [CPNull null],
|
||||
CPKeyValueChangeKindKey: CPKeyValueChangeSetting,
|
||||
};
|
||||
var pathChanges = [CPMutableDictionary dictionaryWithObject:CPKeyValueChangeSetting forKey:CPKeyValueChangeKindKey];
|
||||
|
||||
if (_options & CPKeyValueObservingOptionOld)
|
||||
{
|
||||
var oldValue = [_value valueForKeyPath:_secondPart];
|
||||
|
||||
[pathChanges setObject:oldValue != null ? oldValue : [CPNull null] forKey:CPKeyValueChangeOldKey];
|
||||
}
|
||||
|
||||
if (_options & CPKeyValueObservingOptionNew)
|
||||
{
|
||||
var newValue = [_object valueForKeyPath:_firstPart + "." + _secondPart];
|
||||
|
||||
[pathChanges setObject:newValue != null ? newValue : [CPNull null] forKey:CPKeyValueChangeNewKey];
|
||||
}
|
||||
|
||||
[_observer observeValueForKeyPath:_firstPart + "." + _secondPart ofObject:_object change:pathChanges context:_context];
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
|
||||
@import "CPException.j"
|
||||
@import "CPObject.j"
|
||||
@import "CPDictionary.j"
|
||||
|
||||
/*!
|
||||
@class CPNotification
|
||||
|
||||
@@ -27,6 +27,8 @@
|
||||
@import "CPNull.j"
|
||||
@import "CPSet.j"
|
||||
|
||||
@class _CPNotificationRegistry
|
||||
|
||||
var CPNotificationDefaultCenter = nil;
|
||||
|
||||
/*!
|
||||
@@ -68,7 +70,8 @@ var CPNotificationDefaultCenter = nil;
|
||||
_namedRegistries = @{};
|
||||
_unnamedRegistry = [[_CPNotificationRegistry alloc] init];
|
||||
}
|
||||
return self;
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -81,9 +84,36 @@ var CPNotificationDefaultCenter = nil;
|
||||
*/
|
||||
- (void)addObserver:(id)anObserver selector:(SEL)aSelector name:(CPString)aNotificationName object:(id)anObject
|
||||
{
|
||||
var registry,
|
||||
var registry = [self _registryForNotificationName:aNotificationName],
|
||||
observer = [[_CPNotificationObserver alloc] initWithObserver:anObserver selector:aSelector];
|
||||
|
||||
[registry addObserver:observer object:anObject];
|
||||
}
|
||||
|
||||
/*!
|
||||
Adds an entry to the receiver’s dispatch table with a block, and optional criteria: notification name and sender.
|
||||
@param aNotificationName the name of the notification the observer wants to watch
|
||||
@param anObject the object in the notification the observer wants to watch
|
||||
@param queue is ignored for the moment
|
||||
@param block the block to be executed when the notification is received.
|
||||
*/
|
||||
- (id <CPObject>)addObserverForName:(CPString)aNotificationName object:(id)anObject queue:(id)queue usingBlock:(Function)block
|
||||
{
|
||||
var registry = [self _registryForNotificationName:aNotificationName],
|
||||
observer = [[_CPNotificationObserver alloc] initWithBlock:block];
|
||||
|
||||
[registry addObserver:observer object:anObject];
|
||||
|
||||
return observer;
|
||||
}
|
||||
|
||||
/*!
|
||||
@ignore
|
||||
*/
|
||||
- (_CPNotificationRegistry)_registryForNotificationName:(CPString)aNotificationName
|
||||
{
|
||||
var registry;
|
||||
|
||||
if (aNotificationName == nil)
|
||||
registry = _unnamedRegistry;
|
||||
else if (!(registry = [_namedRegistries objectForKey:aNotificationName]))
|
||||
@@ -92,7 +122,7 @@ var CPNotificationDefaultCenter = nil;
|
||||
[_namedRegistries setObject:registry forKey:aNotificationName];
|
||||
}
|
||||
|
||||
[registry addObserver:observer object:anObject];
|
||||
return registry;
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -233,7 +263,8 @@ var _CPNotificationCenterPostNotification = function(/* CPNotificationCenter */
|
||||
observersEnumerator = [observers objectEnumerator];
|
||||
|
||||
while ((observer = [observersEnumerator nextObject]) !== nil)
|
||||
if ([observer observer] == anObserver)
|
||||
if ([observer observer] == anObserver ||
|
||||
([observer block] && [anObserver respondsToSelector:@selector(block)] && [observer block] == [anObserver block]))
|
||||
[observers removeObject:observer];
|
||||
|
||||
if (![observers count])
|
||||
@@ -248,7 +279,8 @@ var _CPNotificationCenterPostNotification = function(/* CPNotificationCenter */
|
||||
observersEnumerator = [observers objectEnumerator];
|
||||
|
||||
while ((observer = [observersEnumerator nextObject]) !== nil)
|
||||
if ([observer observer] == anObserver)
|
||||
if ([observer observer] == anObserver ||
|
||||
([observer block] && [anObserver respondsToSelector:@selector(block)] && [observer block] == [anObserver block]))
|
||||
[observers removeObject:observer];
|
||||
|
||||
if (![observers count])
|
||||
@@ -312,8 +344,9 @@ var _CPNotificationCenterPostNotification = function(/* CPNotificationCenter */
|
||||
/* @ignore */
|
||||
@implementation _CPNotificationObserver : CPObject
|
||||
{
|
||||
id _observer;
|
||||
SEL _selector;
|
||||
id _observer;
|
||||
Function _block;
|
||||
SEL _selector;
|
||||
}
|
||||
|
||||
- (id)initWithObserver:(id)anObserver selector:(SEL)aSelector
|
||||
@@ -327,13 +360,34 @@ var _CPNotificationCenterPostNotification = function(/* CPNotificationCenter */
|
||||
return self;
|
||||
}
|
||||
|
||||
- (id)initWithBlock:(Function)aBlock
|
||||
{
|
||||
if (self)
|
||||
{
|
||||
_block = aBlock;
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (id)observer
|
||||
{
|
||||
return _observer;
|
||||
}
|
||||
|
||||
- (id)block
|
||||
{
|
||||
return _block;
|
||||
}
|
||||
|
||||
- (void)postNotification:(CPNotification)aNotification
|
||||
{
|
||||
if (_block)
|
||||
{
|
||||
_block(aNotification);
|
||||
return;
|
||||
}
|
||||
|
||||
[_observer performSelector:_selector withObject:aNotification];
|
||||
}
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
@import "CPFormatter.j"
|
||||
@import "CPDecimalNumber.j"
|
||||
|
||||
|
||||
@typedef CPNumberFormatterStyle
|
||||
CPNumberFormatterNoStyle = 0;
|
||||
CPNumberFormatterDecimalStyle = 1;
|
||||
CPNumberFormatterCurrencyStyle = 2;
|
||||
@@ -32,6 +32,7 @@ CPNumberFormatterPercentStyle = 3;
|
||||
CPNumberFormatterScientificStyle = 4;
|
||||
CPNumberFormatterSpellOutStyle = 5;
|
||||
|
||||
@typedef CPNumberFormatterRoundingMode
|
||||
CPNumberFormatterRoundCeiling = CPRoundUp;
|
||||
CPNumberFormatterRoundFloor = CPRoundDown;
|
||||
CPNumberFormatterRoundDown = CPRoundDown;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user