mirror of
https://github.com/cappuccino/cappuccino.git
synced 2026-09-14 22:51:28 +00:00
Merge branch 'master' of https://github.com/cappuccino/cappuccino into preprocess
Conflicts: Objective-J/ObjJAcornCompiler.js Objective-J/acorn.js
This commit is contained in:
@@ -11,3 +11,5 @@ xcuserdata/
|
||||
!*.xcodeproj/project.pbxproj
|
||||
*.xCodeSupport/
|
||||
*.XcodeSupport/
|
||||
*.sublime-project
|
||||
*.sublime-workspace
|
||||
|
||||
+1
-1
@@ -3,4 +3,4 @@ node_js:
|
||||
- 0.8
|
||||
install: ./bootstrap.sh --quiet --noprompt --directory ./narwhal
|
||||
script: jake test
|
||||
env: PATH=$HOME/build/$TRAVIS_REPO_SLUG/narwhal/bin:$PATH CAPP_BUILD=$HOME/build/$TRAVIS_REPO_SLUG/Build NARWHAL_ENGINE=rhino
|
||||
env: PATH="$TRAVIS_BUILD_DIR/narwhal/bin:$PATH" CAPP_BUILD="$TRAVIS_BUILD_DIR/Build" NARWHAL_ENGINE=rhino
|
||||
|
||||
+34
-34
@@ -717,40 +717,40 @@ var bottomHeight = 71;
|
||||
|
||||
+ (id)themeAttributes
|
||||
{
|
||||
return [CPDictionary dictionaryWithObjectsAndKeys:
|
||||
CGSizeMake(400.0, 110.0), @"size",
|
||||
CGInsetMake(15, 15, 15, 50), @"content-inset",
|
||||
6, @"informative-offset",
|
||||
10, @"button-offset",
|
||||
CPJustifiedTextAlignment, @"message-text-alignment",
|
||||
[CPColor blackColor], @"message-text-color",
|
||||
[CPFont boldSystemFontOfSize:13.0], @"message-text-font",
|
||||
[CPNull null], @"message-text-shadow-color",
|
||||
CGSizeMakeZero(), @"message-text-shadow-offset",
|
||||
CPJustifiedTextAlignment, @"informative-text-alignment",
|
||||
[CPColor blackColor], @"informative-text-color",
|
||||
[CPFont systemFontOfSize:12.0], @"informative-text-font",
|
||||
[CPNull null], @"informative-text-shadow-color",
|
||||
CGSizeMakeZero(), @"informative-text-shadow-offset",
|
||||
CGPointMake(15, 12), @"image-offset",
|
||||
[CPNull null], @"information-image",
|
||||
[CPNull null], @"warning-image",
|
||||
[CPNull null], @"error-image",
|
||||
[CPNull null], @"help-image",
|
||||
15, @"help-image-left-offset",
|
||||
[CPNull null], @"help-image-pressed",
|
||||
0.0, @"suppression-button-y-offset",
|
||||
0.0, @"suppression-button-x-offset",
|
||||
3.0, @"default-elements-margin",
|
||||
[CPColor blackColor], @"suppression-button-text-color",
|
||||
[CPFont systemFontOfSize:12.0], @"suppression-button-text-font",
|
||||
[CPNull null], @"suppression-button-text-shadow-color",
|
||||
0.0, @"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"
|
||||
];
|
||||
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
|
||||
|
||||
@@ -1358,7 +1358,7 @@ var _CPAppBootstrapperActions = nil;
|
||||
if (mainCibFile)
|
||||
{
|
||||
[mainBundle loadCibFile:mainCibFile
|
||||
externalNameTable:[CPDictionary dictionaryWithObject:CPApp forKey:CPCibOwner]
|
||||
externalNameTable:@{ CPCibOwner: CPApp }
|
||||
loadDelegate:self];
|
||||
|
||||
return YES;
|
||||
|
||||
+10
-9
@@ -78,15 +78,16 @@ CPBelowBottom = 6;
|
||||
|
||||
+ (id)themeAttributes
|
||||
{
|
||||
return [CPDictionary dictionaryWithObjects:[[CPNull null], [CPNull null], 1.0, 3.0, CGSizeMakeZero(), 6.0, [CPNull null], CGSizeMakeZero()]
|
||||
forKeys:[ @"background-color",
|
||||
@"border-color",
|
||||
@"border-width",
|
||||
@"corner-radius",
|
||||
@"inner-shadow-offset",
|
||||
@"inner-shadow-size",
|
||||
@"inner-shadow-color",
|
||||
@"content-margin"]];
|
||||
return @{
|
||||
@"background-color": [CPNull null],
|
||||
@"border-color": [CPNull null],
|
||||
@"border-width": 1.0,
|
||||
@"corner-radius": 3.0,
|
||||
@"inner-shadow-offset": CGSizeMakeZero(),
|
||||
@"inner-shadow-size": 6.0,
|
||||
@"inner-shadow-color": [CPNull null],
|
||||
@"content-margin": CGSizeMakeZero(),
|
||||
};
|
||||
}
|
||||
|
||||
+ (id)boxEnclosingView:(CPView)aView
|
||||
|
||||
+2
-2
@@ -73,11 +73,11 @@
|
||||
|
||||
+ (id)themeAttributes
|
||||
{
|
||||
return [CPDictionary dictionaryWithJSObject:{
|
||||
return @{
|
||||
@"image-control-resize": [CPNull null],
|
||||
@"image-control-leaf": [CPNull null],
|
||||
@"image-control-leaf-pressed": [CPNull null]
|
||||
}];
|
||||
};
|
||||
}
|
||||
|
||||
- (id)initWithFrame:(CGRect)aFrame
|
||||
|
||||
+11
-5
@@ -76,9 +76,10 @@ CPButtonStateMixed = CPThemeState("mixed");
|
||||
CPButtonStateBezelStyleRounded = CPThemeState("rounded");
|
||||
|
||||
// add all future correspondance between bezel styles and theme state here.
|
||||
var CPButtonBezelStyleStateMap = [CPDictionary dictionaryWithObjectsAndKeys:
|
||||
CPButtonStateBezelStyleRounded, CPRoundedBezelStyle,
|
||||
[CPNull null], CPRoundRectBezelStyle];
|
||||
var CPButtonBezelStyleStateMap = @{
|
||||
CPRoundedBezelStyle: CPButtonStateBezelStyleRounded,
|
||||
CPRoundRectBezelStyle: [CPNull null],
|
||||
};
|
||||
|
||||
/// @cond IGNORE
|
||||
CPButtonDefaultHeight = 25.0;
|
||||
@@ -150,8 +151,13 @@ CPButtonImageOffset = 3.0;
|
||||
|
||||
+ (id)themeAttributes
|
||||
{
|
||||
return [CPDictionary dictionaryWithObjects:[[CPNull null], 0.0, _CGInsetMakeZero(), _CGInsetMakeZero(), [CPNull null]]
|
||||
forKeys:[@"image", @"image-offset", @"bezel-inset", @"content-inset", @"bezel-color"]];
|
||||
return @{
|
||||
@"image": [CPNull null],
|
||||
@"image-offset": 0.0,
|
||||
@"bezel-inset": _CGInsetMakeZero(),
|
||||
@"content-inset": _CGInsetMakeZero(),
|
||||
@"bezel-color": [CPNull null],
|
||||
};
|
||||
}
|
||||
|
||||
/*!
|
||||
|
||||
+11
-18
@@ -81,24 +81,17 @@
|
||||
|
||||
+ (id)themeAttributes
|
||||
{
|
||||
return [CPDictionary dictionaryWithObjects:[ CGInsetMake(0.0, 0.0, 0.0, 0.0),
|
||||
CGSizeMakeZero(),
|
||||
[CPNull null],
|
||||
[CPNull null],
|
||||
[CPNull null],
|
||||
[CPNull null],
|
||||
[CPNull null],
|
||||
[CPNull null],
|
||||
[CPNull null]]
|
||||
forKeys:[ @"resize-control-inset",
|
||||
@"resize-control-size",
|
||||
@"resize-control-color",
|
||||
@"bezel-color",
|
||||
@"button-bezel-color",
|
||||
@"button-text-color",
|
||||
@"button-image-plus",
|
||||
@"button-image-minus",
|
||||
@"button-image-action"]];
|
||||
return @{
|
||||
@"resize-control-inset": CGInsetMake(0.0, 0.0, 0.0, 0.0),
|
||||
@"resize-control-size": CGSizeMakeZero(),
|
||||
@"resize-control-color": [CPNull null],
|
||||
@"bezel-color": [CPNull null],
|
||||
@"button-bezel-color": [CPNull null],
|
||||
@"button-text-color": [CPNull null],
|
||||
@"button-image-plus": [CPNull null],
|
||||
@"button-image-minus": [CPNull null],
|
||||
@"button-image-action": [CPNull null],
|
||||
};
|
||||
}
|
||||
|
||||
- (id)initWithFrame:(CGRect)aFrame
|
||||
|
||||
+29
-18
@@ -45,10 +45,10 @@
|
||||
if (_documentView == aView)
|
||||
return;
|
||||
|
||||
var defaultCenter = [CPNotificationCenter defaultCenter];
|
||||
|
||||
if (_documentView)
|
||||
{
|
||||
var defaultCenter = [CPNotificationCenter defaultCenter];
|
||||
|
||||
[defaultCenter
|
||||
removeObserver:self
|
||||
name:CPViewFrameDidChangeNotification
|
||||
@@ -67,24 +67,30 @@
|
||||
if (_documentView)
|
||||
{
|
||||
[self addSubview:_documentView];
|
||||
|
||||
[_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];
|
||||
[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];
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the document view.
|
||||
*/
|
||||
@@ -234,7 +240,12 @@ var CPClipViewDocumentViewKey = @"CPScrollViewDocumentView";
|
||||
- (id)initWithCoder:(CPCoder)aCoder
|
||||
{
|
||||
if (self = [super initWithCoder:aCoder])
|
||||
[self setDocumentView:[aCoder decodeObjectForKey:CPClipViewDocumentViewKey]];
|
||||
{
|
||||
// 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;
|
||||
}
|
||||
|
||||
+40
-44
@@ -21,7 +21,6 @@
|
||||
*/
|
||||
|
||||
#import "../Foundation/CPRange.h"
|
||||
#import "../Foundation/Ref.h"
|
||||
|
||||
@import <Foundation/CPArray.j>
|
||||
@import <Foundation/CPData.j>
|
||||
@@ -35,9 +34,6 @@
|
||||
@import "CPPasteboard.j"
|
||||
@import "CPView.j"
|
||||
|
||||
@class CPClipView
|
||||
|
||||
|
||||
/*!
|
||||
@ingroup appkit
|
||||
@class CPCollectionView
|
||||
@@ -49,7 +45,7 @@
|
||||
@par Delegate Methods
|
||||
|
||||
@delegate - (void)collectionViewDidChangeSelection:(CPCollectionView)collectionView;
|
||||
Called when the selection in the collection view has changed.
|
||||
DEPRECATED: Please do not use.
|
||||
@param collectionView the collection view who's selection changed
|
||||
|
||||
@delegate - (void)collectionView:(CPCollectionView)collectionView didDoubleClickOnItemAtIndex:(int)index;
|
||||
@@ -176,50 +172,47 @@ var HORIZONTAL_MARGIN = 2;
|
||||
|
||||
/*!
|
||||
Sets the item prototype to \c anItem
|
||||
@param anItem the new item prototype.
|
||||
|
||||
The item prototype should implement the CPCoding protocol
|
||||
because the item is copied by archiving and unarchiving the
|
||||
prototypal view.
|
||||
@note
|
||||
- If anItem is located in an external cib file, representedObject, outlets, and bindings will be automatically restored when an item is created.
|
||||
- If anItem and its view belong to the same cib as the collection view, the item prototype should implement the CPCoding protocol because the item is copied by archiving and unarchiving the prototypal view.
|
||||
@note
|
||||
Bindings won't be restored through archiving, instead you need to subclass the -representedObject: method and update the view there.
|
||||
|
||||
Example:
|
||||
@par Example:
|
||||
|
||||
<pre>
|
||||
@implement MyCustomView : CPCollectionViewItem
|
||||
{
|
||||
CPArray items @accessors;
|
||||
}
|
||||
@code
|
||||
@implementation MyCustomPrototypeItem: CPCollectionViewItem
|
||||
{
|
||||
@outlet CPTextField textField;
|
||||
}
|
||||
|
||||
- (id)initWithFrame:(CGRect)aFrame
|
||||
{
|
||||
self = [super initWithFrame:aFrame];
|
||||
if (self)
|
||||
{
|
||||
items = [];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
- (id)initWithCoder:(CPCoder)aCoder
|
||||
{
|
||||
self = [super initWithCoder:aCoder];
|
||||
|
||||
- (id)initWithCoder:(CPCoder)aCoder
|
||||
{
|
||||
self = [super initWithCoder:aCoder];
|
||||
items = [aCoder decodeObjectForKey:@"KEY"];
|
||||
return self;
|
||||
}
|
||||
textField = [aCoder decodeObjectForKey:@"TextField"];
|
||||
|
||||
- (void)encodeWithCoder:(CPCoder)aCoder
|
||||
{
|
||||
[aCoder encodeObject:items forKey:@"KEY"];
|
||||
[super encodeWithCoder:aCoder];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
@end
|
||||
</pre>
|
||||
- (void)encodeWithCoder:(CPCoder)aCoder
|
||||
{
|
||||
[super encodeWithCoder:aCoder];
|
||||
[aCoder encodeConditionalObject:textField forKey:@"TextField"];
|
||||
}
|
||||
|
||||
This will allow the collection view to create multiple 'clean' copies
|
||||
of the item prototype which will maintain the original values for item
|
||||
and all of the properties archived by the super class.
|
||||
- (void)setRepresentedObject:(id)anObject
|
||||
{
|
||||
[super setRepresentedObject:anObject];
|
||||
[textField setStringValue:[anObject objectForKey:@"value"]];
|
||||
[[self view] setColor:[anObject objectForKey:@"color"]];
|
||||
}
|
||||
|
||||
@end
|
||||
@endcode
|
||||
|
||||
@param anItem the new item prototype
|
||||
*/
|
||||
- (void)setItemPrototype:(CPCollectionViewItem)anItem
|
||||
{
|
||||
@@ -406,7 +399,10 @@ var HORIZONTAL_MARGIN = 2;
|
||||
[[binderClass getBinding:@"selectionIndexes" forObject:self] reverseSetValueFor:@"selectionIndexes"];
|
||||
|
||||
if ([_delegate respondsToSelector:@selector(collectionViewDidChangeSelection:)])
|
||||
{
|
||||
CPLog.warn("The delegate method collectionViewDidChangeSelection: is deprecated and will be removed in a future version, please bind to selectionIndexes instead.");
|
||||
[_delegate collectionViewDidChangeSelection:self];
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -498,7 +494,7 @@ var HORIZONTAL_MARGIN = 2;
|
||||
|
||||
[self _updateMinMaxItemSizeIfNeeded];
|
||||
|
||||
[self _computeGridWithSize:frameSize count:AT_REF(count)];
|
||||
[self _computeGridWithSize:frameSize count:@ref(count)];
|
||||
|
||||
//CPLog.debug("frameSize="+CPStringFromSize(frameSize) + "itemSize="+CPStringFromSize(itemSize) + " ncols=" + colsRowsCount[0] +" nrows="+ colsRowsCount[1]+" displayCount="+ colsRowsCount[2]);
|
||||
|
||||
@@ -1029,7 +1025,7 @@ var HORIZONTAL_MARGIN = 2;
|
||||
- (CPDragOperation)draggingEntered:(id)draggingInfo
|
||||
{
|
||||
var dropIndex = -1,
|
||||
dropIndexRef = AT_REF(dropIndex),
|
||||
dropIndexRef = @ref(dropIndex),
|
||||
dragOp = [self _validateDragWithInfo:draggingInfo dropIndex:dropIndexRef dropOperation:1];
|
||||
|
||||
dropIndex = dropIndexRef();
|
||||
@@ -1047,7 +1043,7 @@ var HORIZONTAL_MARGIN = 2;
|
||||
return _currentDragOperation;
|
||||
|
||||
var dropIndex,
|
||||
dropIndexRef = AT_REF(dropIndex);
|
||||
dropIndexRef = @ref(dropIndex);
|
||||
|
||||
var dragOperation = [self _validateDragWithInfo:draggingInfo dropIndex:dropIndexRef dropOperation:1];
|
||||
|
||||
@@ -1065,7 +1061,7 @@ var HORIZONTAL_MARGIN = 2;
|
||||
|
||||
if ([_delegate respondsToSelector:@selector(collectionView:validateDrop:proposedIndex:dropOperation:)])
|
||||
{
|
||||
var dropIndexRef2 = AT_REF(dropIndex);
|
||||
var dropIndexRef2 = @ref(dropIndex);
|
||||
|
||||
result = [_delegate collectionView:self validateDrop:draggingInfo proposedIndex:dropIndexRef2 dropOperation:dropOperation];
|
||||
|
||||
|
||||
@@ -60,8 +60,13 @@ var _CPColorWellDidBecomeExclusiveNotification = @"_CPColorWellDidBecomeExclusiv
|
||||
|
||||
+ (id)themeAttributes
|
||||
{
|
||||
return [CPDictionary dictionaryWithObjects:[_CGInsetMakeZero(), [CPNull null], _CGInsetMake(3.0, 3.0, 3.0, 3.0), _CGInsetMakeZero(), [CPNull null]]
|
||||
forKeys:[@"bezel-inset", @"bezel-color", @"content-inset", @"content-border-inset", @"content-border-color"]];
|
||||
return @{
|
||||
@"bezel-inset": _CGInsetMakeZero(),
|
||||
@"bezel-color": [CPNull null],
|
||||
@"content-inset": _CGInsetMake(3.0, 3.0, 3.0, 3.0),
|
||||
@"content-border-inset": _CGInsetMakeZero(),
|
||||
@"content-border-color": [CPNull null],
|
||||
};
|
||||
}
|
||||
|
||||
- (void)_reverseSetBinding
|
||||
|
||||
+4
-1
@@ -60,7 +60,10 @@ var CPComboBoxTextSubview = @"text",
|
||||
|
||||
+ (id)themeAttributes
|
||||
{
|
||||
return [CPDictionary dictionaryWithObjectsAndKeys:_CGSizeMake(21.0, 29.0), @"popup-button-size", _CGInsetMake(3.0, 3.0, 3.0, 3.0), @"border-inset"];
|
||||
return @{
|
||||
@"popup-button-size": _CGSizeMake(21.0, 29.0),
|
||||
@"border-inset": _CGInsetMake(3.0, 3.0, 3.0, 3.0),
|
||||
};
|
||||
}
|
||||
|
||||
+ (Class)_binderClassForBinding:(CPString)aBinding
|
||||
|
||||
+18
-29
@@ -20,8 +20,6 @@
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#import "../Foundation/Ref.h"
|
||||
|
||||
@import <Foundation/CPFormatter.j>
|
||||
@import <Foundation/CPTimer.j>
|
||||
|
||||
@@ -112,28 +110,19 @@ var CPControlBlackColor = [CPColor blackColor];
|
||||
|
||||
+ (CPDictionary)themeAttributes
|
||||
{
|
||||
return [CPDictionary dictionaryWithObjects:[CPLeftTextAlignment,
|
||||
CPTopVerticalTextAlignment,
|
||||
CPLineBreakByClipping,
|
||||
[CPColor blackColor],
|
||||
[CPFont systemFontOfSize:CPFontCurrentSystemSize],
|
||||
[CPNull null],
|
||||
_CGSizeMakeZero(),
|
||||
CPImageLeft,
|
||||
CPScaleToFit,
|
||||
_CGSizeMakeZero(),
|
||||
_CGSizeMake(-1.0, -1.0)]
|
||||
forKeys:[@"alignment",
|
||||
@"vertical-alignment",
|
||||
@"line-break-mode",
|
||||
@"text-color",
|
||||
@"font",
|
||||
@"text-shadow-color",
|
||||
@"text-shadow-offset",
|
||||
@"image-position",
|
||||
@"image-scaling",
|
||||
@"min-size",
|
||||
@"max-size"]];
|
||||
return @{
|
||||
@"alignment": CPLeftTextAlignment,
|
||||
@"vertical-alignment": CPTopVerticalTextAlignment,
|
||||
@"line-break-mode": CPLineBreakByClipping,
|
||||
@"text-color": [CPColor blackColor],
|
||||
@"font": [CPFont systemFontOfSize:CPFontCurrentSystemSize],
|
||||
@"text-shadow-color": [CPNull null],
|
||||
@"text-shadow-offset": _CGSizeMakeZero(),
|
||||
@"image-position": CPImageLeft,
|
||||
@"image-scaling": CPScaleToFit,
|
||||
@"min-size": _CGSizeMakeZero(),
|
||||
@"max-size": _CGSizeMake(-1.0, -1.0),
|
||||
};
|
||||
}
|
||||
|
||||
+ (void)initialize
|
||||
@@ -562,10 +551,10 @@ var CPControlBlackColor = [CPColor blackColor];
|
||||
{
|
||||
value = nil;
|
||||
|
||||
if ([_formatter getObjectValue:AT_REF(value) forString:aString errorDescription:nil] === NO)
|
||||
if ([_formatter getObjectValue:@ref(value) forString:aString errorDescription:nil] === NO)
|
||||
{
|
||||
// If the given string is non-empty and doesn't work, Cocoa tries an empty string.
|
||||
if (!aString || [_formatter getObjectValue:AT_REF(value) forString:@"" errorDescription:nil] === NO)
|
||||
if (!aString || [_formatter getObjectValue:@ref(value) forString:@"" errorDescription:nil] === NO)
|
||||
value = undefined; // Means the value is invalid
|
||||
}
|
||||
}
|
||||
@@ -618,7 +607,7 @@ var CPControlBlackColor = [CPColor blackColor];
|
||||
if ([note object] != self)
|
||||
return;
|
||||
|
||||
[[CPNotificationCenter defaultCenter] postNotificationName:CPControlTextDidBeginEditingNotification object:self userInfo:[CPDictionary dictionaryWithObject:[note object] forKey:"CPFieldEditor"]];
|
||||
[[CPNotificationCenter defaultCenter] postNotificationName:CPControlTextDidBeginEditingNotification object:self userInfo:@{ "CPFieldEditor": [note object] }];
|
||||
}
|
||||
|
||||
- (void)textDidChange:(CPNotification)note
|
||||
@@ -627,7 +616,7 @@ var CPControlBlackColor = [CPColor blackColor];
|
||||
if ([note object] != self)
|
||||
return;
|
||||
|
||||
[[CPNotificationCenter defaultCenter] postNotificationName:CPControlTextDidChangeNotification object:self userInfo:[CPDictionary dictionaryWithObject:[note object] forKey:"CPFieldEditor"]];
|
||||
[[CPNotificationCenter defaultCenter] postNotificationName:CPControlTextDidChangeNotification object:self userInfo:@{ "CPFieldEditor": [note object] }];
|
||||
}
|
||||
|
||||
- (void)textDidEndEditing:(CPNotification)note
|
||||
@@ -638,7 +627,7 @@ var CPControlBlackColor = [CPColor blackColor];
|
||||
|
||||
[self _reverseSetBinding];
|
||||
|
||||
[[CPNotificationCenter defaultCenter] postNotificationName:CPControlTextDidEndEditingNotification object:self userInfo:[CPDictionary dictionaryWithObject:[note object] forKey:"CPFieldEditor"]];
|
||||
[[CPNotificationCenter defaultCenter] postNotificationName:CPControlTextDidEndEditingNotification object:self userInfo:@{ "CPFieldEditor": [note object] }];
|
||||
}
|
||||
|
||||
/*!
|
||||
|
||||
+1
-1
@@ -129,7 +129,7 @@ var CPDocumentUntitledCount = 0;
|
||||
if (self)
|
||||
{
|
||||
_windowControllers = [];
|
||||
_viewControllersForWindowControllers = [CPDictionary dictionary];
|
||||
_viewControllersForWindowControllers = @{};
|
||||
|
||||
_hasUndoManager = YES;
|
||||
_changeCount = 0;
|
||||
|
||||
@@ -148,7 +148,7 @@ var CPSharedDocumentController = nil;
|
||||
{
|
||||
var type = [self typeForContentsOfURL:anAbsoluteURL error:anError];
|
||||
|
||||
result = [self makeDocumentWithContentsOfURL:anAbsoluteURL ofType:type delegate:self didReadSelector:@selector(document:didRead:contextInfo:) contextInfo:[CPDictionary dictionaryWithObject:shouldDisplay forKey:@"shouldDisplay"]];
|
||||
result = [self makeDocumentWithContentsOfURL:anAbsoluteURL ofType:type delegate:self didReadSelector:@selector(document:didRead:contextInfo:) contextInfo:@{ @"shouldDisplay": shouldDisplay }];
|
||||
|
||||
[self addDocument:result];
|
||||
|
||||
|
||||
@@ -248,7 +248,7 @@ var CPDraggingSource_draggedImage_movedTo_ = 1 << 0,
|
||||
_draggingUpdateTimer = [CPTimer scheduledTimerWithTimeInterval:CPDragServerPeriodicUpdateInterval
|
||||
target:self
|
||||
selector:@selector(_sendPeriodicDraggingUpdate:)
|
||||
userInfo:[CPDictionary dictionaryWithJSObject:{platformWindow:aPlatformWindow, location:aLocation}]
|
||||
userInfo:@{ "platformWindow":aPlatformWindow, "location":aLocation }
|
||||
repeats:NO];
|
||||
|
||||
var scrollView = [_draggingDestination isKindOfClass:[CPView class]] ? [_draggingDestination enclosingScrollView] : nil;
|
||||
|
||||
@@ -107,7 +107,7 @@ var IEFlashCLSID = "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000";
|
||||
varString = [varString stringByAppendingFormat:@"&%@=%@", key, [aDictionary objectForKey:key]];
|
||||
|
||||
if (!_params)
|
||||
_params = [CPDictionary dictionary];
|
||||
_params = @{};
|
||||
|
||||
[_params setObject:varString forKey:@"flashvars"];
|
||||
[self setParameters:_params];
|
||||
@@ -137,7 +137,7 @@ var IEFlashCLSID = "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000";
|
||||
#if PLATFORM(DOM)
|
||||
if (!CPBrowserIsEngine(CPInternetExplorerBrowserEngine))
|
||||
{
|
||||
_paramElements = [CPDictionary dictionary];
|
||||
_paramElements = @{};
|
||||
|
||||
var enumerator = [_params keyEnumerator],
|
||||
key;
|
||||
|
||||
@@ -208,7 +208,8 @@ var CPSharedFontManager = nil,
|
||||
|
||||
- (@action)addFontTrait:(id)sender
|
||||
{
|
||||
_activeChange = [CPDictionary dictionaryWithObject:[sender tag] forKey:@"addTraits"];
|
||||
var tag = [sender tag];
|
||||
_activeChange = tag === nil ? @{} : @{ @"addTraits": tag };
|
||||
|
||||
[self sendAction];
|
||||
}
|
||||
|
||||
+37
-14
@@ -32,8 +32,8 @@
|
||||
|
||||
@class CPButton
|
||||
|
||||
var exposedBindingsMap = [CPDictionary new],
|
||||
bindingsMap = [CPDictionary new];
|
||||
var exposedBindingsMap = @{},
|
||||
bindingsMap = @{};
|
||||
|
||||
var CPBindingOperationAnd = 0,
|
||||
CPBindingOperationOr = 1;
|
||||
@@ -130,7 +130,10 @@ var CPBindingOperationAnd = 0,
|
||||
if (self)
|
||||
{
|
||||
_source = aSource;
|
||||
_info = [CPDictionary dictionaryWithObjects:[aDestination, aKeyPath] forKeys:[CPObservedObjectKey, CPObservedKeyPathKey]];
|
||||
_info = @{
|
||||
CPObservedObjectKey: aDestination,
|
||||
CPObservedKeyPathKey: aKeyPath,
|
||||
};
|
||||
_suppressedNotifications = {};
|
||||
_placeholderForMarker = {};
|
||||
|
||||
@@ -145,7 +148,7 @@ var CPBindingOperationAnd = 0,
|
||||
|
||||
if (!bindings)
|
||||
{
|
||||
bindings = [CPDictionary new];
|
||||
bindings = @{};
|
||||
[bindingsMap setObject:bindings forKey:[_source UID]];
|
||||
}
|
||||
|
||||
@@ -342,12 +345,12 @@ var CPBindingOperationAnd = 0,
|
||||
[self _updatePlaceholdersWithOptions:options];
|
||||
}
|
||||
|
||||
- (void)_placeholderForMarker:aMarker
|
||||
- (JSObject)_placeholderForMarker:(id)aMarker
|
||||
{
|
||||
var placeholder = _placeholderForMarker[aMarker];
|
||||
var placeholder = _placeholderForMarker[[aMarker UID]];
|
||||
|
||||
if (placeholder)
|
||||
return placeholder['value'];
|
||||
return placeholder.value;
|
||||
|
||||
return nil;
|
||||
}
|
||||
@@ -356,14 +359,14 @@ var CPBindingOperationAnd = 0,
|
||||
{
|
||||
if (isDefault)
|
||||
{
|
||||
var existingPlaceholder = _placeholderForMarker[aMarker];
|
||||
var existingPlaceholder = _placeholderForMarker[[aMarker UID]];
|
||||
|
||||
// Don't overwrite an explicitly set placeholder with a default.
|
||||
if (existingPlaceholder && !existingPlaceholder['isDefault'])
|
||||
if (existingPlaceholder && !existingPlaceholder.isDefault)
|
||||
return;
|
||||
}
|
||||
|
||||
_placeholderForMarker[aMarker] = { 'isDefault': isDefault, 'value': aPlaceholder };
|
||||
_placeholderForMarker[[aMarker UID]] = { 'isDefault': isDefault, 'value': aPlaceholder };
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -799,6 +802,26 @@ var CPBindingOperationAnd = 0,
|
||||
|
||||
@end
|
||||
|
||||
@implementation _CPStateMarker : CPObject
|
||||
{
|
||||
CPString _name;
|
||||
}
|
||||
|
||||
- (id)initWithName:(CPString)aName
|
||||
{
|
||||
if (self = [super init])
|
||||
_name = aName
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (CPString)description
|
||||
{
|
||||
return "<" + _name + ">";
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
// Keys in options dictionary
|
||||
|
||||
@@ -808,10 +831,10 @@ CPObservedKeyPathKey = @"CPObservedKeyPathKey";
|
||||
CPOptionsKey = @"CPOptionsKey";
|
||||
|
||||
// special markers
|
||||
CPMultipleValuesMarker = @"CPMultipleValuesMarker";
|
||||
CPNoSelectionMarker = @"CPNoSelectionMarker";
|
||||
CPNotApplicableMarker = @"CPNotApplicableMarker";
|
||||
CPNullMarker = @"CPNullMarker";
|
||||
CPNoSelectionMarker = [[_CPStateMarker alloc] initWithName:@"NO SELECTION MARKER"];
|
||||
CPMultipleValuesMarker = [[_CPStateMarker alloc] initWithName:@"MULTIPLE VALUES MARKER"];
|
||||
CPNotApplicableMarker = [[_CPStateMarker alloc] initWithName:@"NOT APPLICABLE MARKER"];
|
||||
CPNullMarker = [[_CPStateMarker alloc] initWithName:@"NULL MARKER"];
|
||||
|
||||
// Binding name constants
|
||||
CPAlignmentBinding = @"alignment";
|
||||
|
||||
@@ -64,12 +64,14 @@ CPRatingLevelIndicatorStyle = 3;
|
||||
|
||||
+ (id)themeAttributes
|
||||
{
|
||||
return [CPDictionary dictionaryWithObjectsAndKeys:[CPNull null], @"bezel-color",
|
||||
[CPNull null], @"color-empty",
|
||||
[CPNull null], @"color-normal",
|
||||
[CPNull null], @"color-warning",
|
||||
[CPNull null], @"color-critical",
|
||||
1.0, @"spacing"];
|
||||
return @{
|
||||
@"bezel-color": [CPNull null],
|
||||
@"color-empty": [CPNull null],
|
||||
@"color-normal": [CPNull null],
|
||||
@"color-warning": [CPNull null],
|
||||
@"color-critical": [CPNull null],
|
||||
@"spacing": 1.0,
|
||||
};
|
||||
}
|
||||
|
||||
- (id)initWithFrame:(CGRect)aFrame
|
||||
|
||||
+36
-24
@@ -77,7 +77,7 @@ var _CPMenuBarVisible = NO,
|
||||
if (self !== [CPMenu class])
|
||||
return;
|
||||
|
||||
[[self class] setMenuBarAttributes:[CPDictionary dictionary]];
|
||||
[[self class] setMenuBarAttributes:@{}];
|
||||
}
|
||||
|
||||
+ (BOOL)menuBarVisible
|
||||
@@ -148,6 +148,13 @@ var _CPMenuBarVisible = NO,
|
||||
return _CPMenuBarImage;
|
||||
}
|
||||
|
||||
+ (void)_setOrRemoveMenuBarAttribute:(id)aValue forKey:(id)aKey
|
||||
{
|
||||
if (aValue === nil)
|
||||
[_CPMenuBarAttributes removeObjectForKey:aKey];
|
||||
else
|
||||
[_CPMenuBarAttributes setObject:aValue forKey:aKey];
|
||||
}
|
||||
|
||||
+ (void)setMenuBarAttributes:(CPDictionary)attributes
|
||||
{
|
||||
@@ -172,8 +179,8 @@ var _CPMenuBarVisible = NO,
|
||||
|
||||
else if (!textColor && !titleColor)
|
||||
{
|
||||
[_CPMenuBarAttributes setObject:[[CPTheme defaultTheme] valueForAttributeWithName:@"menu-bar-text-color" forClass:_CPMenuView] forKey:@"CPMenuBarTextColor"];
|
||||
[_CPMenuBarAttributes setObject:[[CPTheme defaultTheme] valueForAttributeWithName:@"menu-bar-title-color" forClass:_CPMenuView] forKey:@"CPMenuBarTitleColor"];
|
||||
[self _setOrRemoveMenuBarAttribute:[[CPTheme defaultTheme] valueForAttributeWithName:@"menu-bar-text-color" forClass:_CPMenuView] forKey:@"CPMenuBarTextColor"];
|
||||
[self _setOrRemoveMenuBarAttribute:[[CPTheme defaultTheme] valueForAttributeWithName:@"menu-bar-title-color" forClass:_CPMenuView] forKey:@"CPMenuBarTitleColor"];
|
||||
}
|
||||
|
||||
if (!textShadowColor && titleShadowColor)
|
||||
@@ -184,18 +191,18 @@ var _CPMenuBarVisible = NO,
|
||||
|
||||
else if (!textShadowColor && !titleShadowColor)
|
||||
{
|
||||
[_CPMenuBarAttributes setObject:[[CPTheme defaultTheme] valueForAttributeWithName:@"menu-bar-text-shadow-color" forClass:_CPMenuView] forKey:@"CPMenuBarTextShadowColor"];
|
||||
[_CPMenuBarAttributes setObject:[[CPTheme defaultTheme] valueForAttributeWithName:@"menu-bar-title-shadow-color" forClass:_CPMenuView] forKey:@"CPMenuBarTitleShadowColor"];
|
||||
[self _setOrRemoveMenuBarAttribute:[[CPTheme defaultTheme] valueForAttributeWithName:@"menu-bar-text-shadow-color" forClass:_CPMenuView] forKey:@"CPMenuBarTextShadowColor"];
|
||||
[self _setOrRemoveMenuBarAttribute:[[CPTheme defaultTheme] valueForAttributeWithName:@"menu-bar-title-shadow-color" forClass:_CPMenuView] forKey:@"CPMenuBarTitleShadowColor"];
|
||||
}
|
||||
|
||||
if (!highlightColor)
|
||||
[_CPMenuBarAttributes setObject:[[CPTheme defaultTheme] valueForAttributeWithName:@"menu-bar-highlight-color" forClass:_CPMenuView] forKey:@"CPMenuBarHighlightColor"];
|
||||
[self _setOrRemoveMenuBarAttribute:[[CPTheme defaultTheme] valueForAttributeWithName:@"menu-bar-highlight-color" forClass:_CPMenuView] forKey:@"CPMenuBarHighlightColor"];
|
||||
|
||||
if (!highlightTextColor)
|
||||
[_CPMenuBarAttributes setObject:[[CPTheme defaultTheme] valueForAttributeWithName:@"menu-bar-highlight-text-color" forClass:_CPMenuView] forKey:@"CPMenuBarHighlightTextColor"];
|
||||
[self _setOrRemoveMenuBarAttribute:[[CPTheme defaultTheme] valueForAttributeWithName:@"menu-bar-highlight-text-color" forClass:_CPMenuView] forKey:@"CPMenuBarHighlightTextColor"];
|
||||
|
||||
if (!highlightTextShadowColor)
|
||||
[_CPMenuBarAttributes setObject:[[CPTheme defaultTheme] valueForAttributeWithName:@"menu-bar-highlight-text-shadow-color" forClass:_CPMenuView] forKey:@"CPMenuBarHighlightTextShadowColor"];
|
||||
[self _setOrRemoveMenuBarAttribute:[[CPTheme defaultTheme] valueForAttributeWithName:@"menu-bar-highlight-text-shadow-color" forClass:_CPMenuView] forKey:@"CPMenuBarHighlightTextShadowColor"];
|
||||
|
||||
if (_CPMenuBarSharedWindow)
|
||||
{
|
||||
@@ -373,7 +380,7 @@ var _CPMenuBarVisible = NO,
|
||||
[[CPNotificationCenter defaultCenter]
|
||||
postNotificationName:CPMenuDidChangeItemNotification
|
||||
object:self
|
||||
userInfo:[CPDictionary dictionaryWithObject:[_items indexOfObjectIdenticalTo:aMenuItem] forKey:@"CPMenuItemIndex"]];
|
||||
userInfo:@{ @"CPMenuItemIndex": [_items indexOfObjectIdenticalTo:aMenuItem] }];
|
||||
}
|
||||
|
||||
// Finding Menu Items
|
||||
@@ -628,22 +635,27 @@ var _CPMenuBarVisible = NO,
|
||||
|
||||
if (!validator)
|
||||
{
|
||||
// Check to see if there is a target binding with a valid selector
|
||||
var info = [CPBinder infoForBinding:CPTargetBinding forObject:item],
|
||||
valid = NO;
|
||||
|
||||
if (info)
|
||||
// If targetForAction: returns nil, it could be that there is no action.
|
||||
// If there is an action and nil is returned, no valid target could be found.
|
||||
if ([item action] || [item target])
|
||||
[item setEnabled:NO];
|
||||
else
|
||||
{
|
||||
var object = [info objectForKey:CPObservedObjectKey],
|
||||
keyPath = [info objectForKey:CPObservedKeyPathKey],
|
||||
options = [info objectForKey:CPOptionsKey],
|
||||
target = [object valueForKeyPath:keyPath],
|
||||
selector = [options valueForKey:CPSelectorNameBindingOption];
|
||||
// Check to see if there is a target binding with an invalid selector
|
||||
var info = [CPBinder infoForBinding:CPTargetBinding forObject:item];
|
||||
|
||||
valid = target && selector && [target respondsToSelector:CPSelectorFromString(selector)];
|
||||
if (info)
|
||||
{
|
||||
var object = [info objectForKey:CPObservedObjectKey],
|
||||
keyPath = [info objectForKey:CPObservedKeyPathKey],
|
||||
options = [info objectForKey:CPOptionsKey],
|
||||
target = [object valueForKeyPath:keyPath],
|
||||
selector = [options valueForKey:CPSelectorNameBindingOption];
|
||||
|
||||
if (target && selector && ![target respondsToSelector:CPSelectorFromString(selector)])
|
||||
[item setEnabled:NO];
|
||||
}
|
||||
}
|
||||
|
||||
[item setEnabled:valid];
|
||||
}
|
||||
else if (![validator respondsToSelector:[item action]])
|
||||
[item setEnabled:NO];
|
||||
@@ -1136,7 +1148,7 @@ var _CPMenuBarVisible = NO,
|
||||
[[CPNotificationCenter defaultCenter]
|
||||
postNotificationName:CPMenuDidAddItemNotification
|
||||
object:self
|
||||
userInfo:[CPDictionary dictionaryWithObject:anIndex forKey:@"CPMenuItemIndex"]];
|
||||
userInfo:@{ @"CPMenuItemIndex": anIndex }];
|
||||
}
|
||||
|
||||
- (void)removeObjectFromItemsAtIndex:(CPUInteger)anIndex
|
||||
@@ -1150,7 +1162,7 @@ var _CPMenuBarVisible = NO,
|
||||
[[CPNotificationCenter defaultCenter]
|
||||
postNotificationName:CPMenuDidRemoveItemNotification
|
||||
object:self
|
||||
userInfo:[CPDictionary dictionaryWithObject:anIndex forKey:@"CPMenuItemIndex"]];
|
||||
userInfo:@{ @"CPMenuItemIndex": anIndex }];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -434,39 +434,34 @@ _CPMenuWindowAttachedMenuBackgroundStyle = 2;
|
||||
|
||||
+ (id)themeAttributes
|
||||
{
|
||||
return [CPDictionary dictionaryWithObjects:[ [CPNull null], [CPNull null], [CPNull null], [CPNull null], CGInsetMake(5.0, 1.0, 1.0, 5.0), 16.0,
|
||||
[CPNull null], [CPNull null], [CPNull null], 30.0, 10.0, 10.0, 10.0,
|
||||
[CPNull null], [CPNull null], [CPNull null], [CPNull null], [CPNull null], [CPNull null], [CPNull null], 28.0, [CPNull null], 1.0,
|
||||
[CPNull null], [CPNull null], [CPNull null]]
|
||||
forKeys:[ @"menu-window-more-above-image",
|
||||
@"menu-window-more-below-image",
|
||||
@"menu-window-pop-up-background-style-color",
|
||||
@"menu-window-menu-bar-background-style-color",
|
||||
@"menu-window-margin-inset",
|
||||
@"menu-window-scroll-indicator-height",
|
||||
|
||||
@"menu-bar-window-background-color",
|
||||
@"menu-bar-window-background-selected-color",
|
||||
@"menu-bar-window-font",
|
||||
@"menu-bar-window-height",
|
||||
@"menu-bar-window-margin",
|
||||
@"menu-bar-window-left-margin",
|
||||
@"menu-bar-window-right-margin",
|
||||
|
||||
@"menu-bar-text-color",
|
||||
@"menu-bar-title-color",
|
||||
@"menu-bar-text-shadow-color",
|
||||
@"menu-bar-title-shadow-color",
|
||||
@"menu-bar-highlight-color",
|
||||
@"menu-bar-highlight-text-color",
|
||||
@"menu-bar-highlight-text-shadow-color",
|
||||
@"menu-bar-height",
|
||||
@"menu-bar-icon-image",
|
||||
@"menu-bar-icon-image-alpha-value",
|
||||
|
||||
@"menu-general-icon-new",
|
||||
@"menu-general-icon-save",
|
||||
@"menu-general-icon-open"]];
|
||||
return @{
|
||||
@"menu-window-more-above-image": [CPNull null],
|
||||
@"menu-window-more-below-image": [CPNull null],
|
||||
@"menu-window-pop-up-background-style-color": [CPNull null],
|
||||
@"menu-window-menu-bar-background-style-color": [CPNull null],
|
||||
@"menu-window-margin-inset": CGInsetMake(5.0, 1.0, 1.0, 5.0),
|
||||
@"menu-window-scroll-indicator-height": 16.0,
|
||||
@"menu-bar-window-background-color": [CPNull null],
|
||||
@"menu-bar-window-background-selected-color": [CPNull null],
|
||||
@"menu-bar-window-font": [CPNull null],
|
||||
@"menu-bar-window-height": 30.0,
|
||||
@"menu-bar-window-margin": 10.0,
|
||||
@"menu-bar-window-left-margin": 10.0,
|
||||
@"menu-bar-window-right-margin": 10.0,
|
||||
@"menu-bar-text-color": [CPNull null],
|
||||
@"menu-bar-title-color": [CPNull null],
|
||||
@"menu-bar-text-shadow-color": [CPNull null],
|
||||
@"menu-bar-title-shadow-color": [CPNull null],
|
||||
@"menu-bar-highlight-color": [CPNull null],
|
||||
@"menu-bar-highlight-text-color": [CPNull null],
|
||||
@"menu-bar-highlight-text-shadow-color": [CPNull null],
|
||||
@"menu-bar-height": 28.0,
|
||||
@"menu-bar-icon-image": [CPNull null],
|
||||
@"menu-bar-icon-image-alpha-value": 1.0,
|
||||
@"menu-general-icon-new": [CPNull null],
|
||||
@"menu-general-icon-save": [CPNull null],
|
||||
@"menu-general-icon-open": [CPNull null],
|
||||
};
|
||||
}
|
||||
|
||||
- (unsigned)numberOfUnhiddenItems
|
||||
|
||||
@@ -33,25 +33,25 @@
|
||||
|
||||
@global CPApp
|
||||
|
||||
var CPMenuItemStringRepresentationDictionary = [CPDictionary dictionaryWithObjectsAndKeys:
|
||||
"\u238B", CPEscapeFunctionKey,
|
||||
"\u21E5", CPTabCharacter,
|
||||
"\u21E4", CPBackTabCharacter,
|
||||
"\u2423", CPSpaceFunctionKey,
|
||||
"\u23CE", CPCarriageReturnCharacter,
|
||||
"\u232B", CPBackspaceCharacter,
|
||||
"\u232B", CPDeleteFunctionKey,
|
||||
"\u2326", CPDeleteCharacter,
|
||||
"\u21F1", CPHomeFunctionKey,
|
||||
"\u21F2", CPEndFunctionKey,
|
||||
"\u21DE", CPPageUpFunctionKey,
|
||||
"\u21DF", CPPageDownFunctionKey,
|
||||
"\u2191", CPUpArrowFunctionKey,
|
||||
"\u2193", CPDownArrowFunctionKey,
|
||||
"\u2190", CPLeftArrowFunctionKey,
|
||||
"\u2192", CPRightArrowFunctionKey,
|
||||
"\u2327", CPClearDisplayFunctionKey
|
||||
];
|
||||
var CPMenuItemStringRepresentationDictionary = @{
|
||||
CPEscapeFunctionKey: "\u238B",
|
||||
CPTabCharacter: "\u21E5",
|
||||
CPBackTabCharacter: "\u21E4",
|
||||
CPSpaceFunctionKey: "\u2423",
|
||||
CPCarriageReturnCharacter: "\u23CE",
|
||||
CPBackspaceCharacter: "\u232B",
|
||||
CPDeleteFunctionKey: "\u232B",
|
||||
CPDeleteCharacter: "\u2326",
|
||||
CPHomeFunctionKey: "\u21F1",
|
||||
CPEndFunctionKey: "\u21F2",
|
||||
CPPageUpFunctionKey: "\u21DE",
|
||||
CPPageDownFunctionKey: "\u21DF",
|
||||
CPUpArrowFunctionKey: "\u2191",
|
||||
CPDownArrowFunctionKey: "\u2193",
|
||||
CPLeftArrowFunctionKey: "\u2190",
|
||||
CPRightArrowFunctionKey: "\u2192",
|
||||
CPClearDisplayFunctionKey: "\u2327",
|
||||
};
|
||||
|
||||
/*!
|
||||
@ingroup appkit
|
||||
|
||||
@@ -46,12 +46,13 @@
|
||||
|
||||
+ (id)themeAttributes
|
||||
{
|
||||
return [CPDictionary dictionaryWithObjects:[[CPNull null], [CPNull null], 12.0, 3.0, 4.0]
|
||||
forKeys:[ @"menu-item-selection-color",
|
||||
@"menu-item-text-shadow-color",
|
||||
@"horizontal-margin",
|
||||
@"submenu-indicator-margin",
|
||||
@"vertical-margin"]];
|
||||
return @{
|
||||
@"menu-item-selection-color": [CPNull null],
|
||||
@"menu-item-text-shadow-color": [CPNull null],
|
||||
@"horizontal-margin": 12.0,
|
||||
@"submenu-indicator-margin": 3.0,
|
||||
@"vertical-margin": 4.0,
|
||||
};
|
||||
}
|
||||
|
||||
+ (id)view
|
||||
|
||||
@@ -47,24 +47,25 @@
|
||||
|
||||
+ (id)themeAttributes
|
||||
{
|
||||
return [CPDictionary dictionaryWithObjects:[[CPNull null], [CPNull null], [CPNull null], [CPNull null], [CPNull null], [CPNull null], [CPNull null], [CPNull null], [CPNull null], [CPNull null], [CPNull null], 3.0, 17.0, 14.0, 17.0, 4.0, 30.0]
|
||||
forKeys:[ @"submenu-indicator-color",
|
||||
@"menu-item-selection-color",
|
||||
@"menu-item-text-shadow-color",
|
||||
@"menu-item-text-color",
|
||||
@"menu-item-default-off-state-image",
|
||||
@"menu-item-default-off-state-highlighted-image",
|
||||
@"menu-item-default-on-state-image",
|
||||
@"menu-item-default-on-state-highlighted-image",
|
||||
@"menu-item-default-mixed-state-image",
|
||||
@"menu-item-default-mixed-state-highlighted-image",
|
||||
@"menu-item-separator-color",
|
||||
@"left-margin",
|
||||
@"right-margin",
|
||||
@"state-column-width",
|
||||
@"indentation-width",
|
||||
@"vertical-margin",
|
||||
@"right-columns-margin"]];
|
||||
return @{
|
||||
@"submenu-indicator-color": [CPNull null],
|
||||
@"menu-item-selection-color": [CPNull null],
|
||||
@"menu-item-text-shadow-color": [CPNull null],
|
||||
@"menu-item-text-color": [CPNull null],
|
||||
@"menu-item-default-off-state-image": [CPNull null],
|
||||
@"menu-item-default-off-state-highlighted-image": [CPNull null],
|
||||
@"menu-item-default-on-state-image": [CPNull null],
|
||||
@"menu-item-default-on-state-highlighted-image": [CPNull null],
|
||||
@"menu-item-default-mixed-state-image": [CPNull null],
|
||||
@"menu-item-default-mixed-state-highlighted-image": [CPNull null],
|
||||
@"menu-item-separator-color": [CPNull null],
|
||||
@"left-margin": 3.0,
|
||||
@"right-margin": 17.0,
|
||||
@"state-column-width": 14.0,
|
||||
@"indentation-width": 17.0,
|
||||
@"vertical-margin": 4.0,
|
||||
@"right-columns-margin": 30.0,
|
||||
};
|
||||
}
|
||||
|
||||
+ (id)view
|
||||
|
||||
@@ -55,8 +55,7 @@
|
||||
|
||||
+ (id)themeAttributes
|
||||
{
|
||||
return [CPDictionary dictionaryWithObjects:[]
|
||||
forKeys:[]];
|
||||
return @{};
|
||||
}
|
||||
|
||||
// Not used in the Appkit
|
||||
|
||||
@@ -106,11 +106,13 @@
|
||||
{
|
||||
if (self = [super init])
|
||||
{
|
||||
[self setContent:aContent];
|
||||
[self setEditable:YES];
|
||||
[self setObjectClass:[CPMutableDictionary class]];
|
||||
|
||||
_observedKeys = [[CPCountedSet alloc] init];
|
||||
_selection = [[CPControllerSelectionProxy alloc] initWithController:self];
|
||||
|
||||
[self setContent:aContent];
|
||||
}
|
||||
|
||||
return self;
|
||||
@@ -667,7 +669,7 @@ var CPObjectControllerContentKey = @"CPObjectControllerCo
|
||||
{
|
||||
if (self = [super init])
|
||||
{
|
||||
_cachedValues = [CPDictionary dictionary];
|
||||
_cachedValues = @{};
|
||||
_observationProxies = [CPArray array];
|
||||
_controller = aController;
|
||||
_observedObjectsByKeyPath = {};
|
||||
|
||||
+39
-32
@@ -35,20 +35,21 @@ CPOutlineViewItemWillExpandNotification = @"CPOutlineViewItemWillExpandN
|
||||
CPOutlineViewSelectionDidChangeNotification = @"CPOutlineViewSelectionDidChangeNotification";
|
||||
CPOutlineViewSelectionIsChangingNotification = @"CPOutlineViewSelectionIsChangingNotification";
|
||||
|
||||
var CPOutlineViewDataSource_outlineView_setObjectValue_forTableColumn_byItem_ = 1 << 1,
|
||||
CPOutlineViewDataSource_outlineView_shouldDeferDisplayingChildrenOfItem_ = 1 << 2,
|
||||
var CPOutlineViewDataSource_outlineView_objectValue_forTableColumn_byItem_ = 1 << 1,
|
||||
CPOutlineViewDataSource_outlineView_setObjectValue_forTableColumn_byItem_ = 1 << 2,
|
||||
CPOutlineViewDataSource_outlineView_shouldDeferDisplayingChildrenOfItem_ = 1 << 3,
|
||||
|
||||
CPOutlineViewDataSource_outlineView_acceptDrop_item_childIndex_ = 1 << 3,
|
||||
CPOutlineViewDataSource_outlineView_validateDrop_proposedItem_proposedChildIndex_ = 1 << 4,
|
||||
CPOutlineViewDataSource_outlineView_validateDrop_proposedRow_proposedDropOperation_ = 1 << 5,
|
||||
CPOutlineViewDataSource_outlineView_namesOfPromisedFilesDroppedAtDestination_forDraggedItems_ = 1 << 6,
|
||||
CPOutlineViewDataSource_outlineView_acceptDrop_item_childIndex_ = 1 << 4,
|
||||
CPOutlineViewDataSource_outlineView_validateDrop_proposedItem_proposedChildIndex_ = 1 << 5,
|
||||
CPOutlineViewDataSource_outlineView_validateDrop_proposedRow_proposedDropOperation_ = 1 << 6,
|
||||
CPOutlineViewDataSource_outlineView_namesOfPromisedFilesDroppedAtDestination_forDraggedItems_ = 1 << 7,
|
||||
|
||||
CPOutlineViewDataSource_outlineView_itemForPersistentObject_ = 1 << 7,
|
||||
CPOutlineViewDataSource_outlineView_persistentObjectForItem_ = 1 << 8,
|
||||
CPOutlineViewDataSource_outlineView_itemForPersistentObject_ = 1 << 8,
|
||||
CPOutlineViewDataSource_outlineView_persistentObjectForItem_ = 1 << 9,
|
||||
|
||||
CPOutlineViewDataSource_outlineView_writeItems_toPasteboard_ = 1 << 9,
|
||||
CPOutlineViewDataSource_outlineView_writeItems_toPasteboard_ = 1 << 10,
|
||||
|
||||
CPOutlineViewDataSource_outlineView_sortDescriptorsDidChange_ = 1 << 10;
|
||||
CPOutlineViewDataSource_outlineView_sortDescriptorsDidChange_ = 1 << 11;
|
||||
|
||||
var CPOutlineViewDelegate_outlineView_dataViewForTableColumn_item_ = 1 << 1,
|
||||
CPOutlineViewDelegate_outlineView_didClickTableColumn_ = 1 << 2,
|
||||
@@ -230,12 +231,12 @@ var CPOutlineViewCoalesceSelectionNotificationStateOff = 0,
|
||||
if (![aDataSource respondsToSelector:@selector(outlineView:numberOfChildrenOfItem:)])
|
||||
[CPException raise:CPInternalInconsistencyException reason:"Data source must implement 'outlineView:numberOfChildrenOfItem:'"];
|
||||
|
||||
if (![aDataSource respondsToSelector:@selector(outlineView:objectValueForTableColumn:byItem:)])
|
||||
[CPException raise:CPInternalInconsistencyException reason:"Data source must implement 'outlineView:objectValueForTableColumn:byItem:'"];
|
||||
|
||||
_outlineViewDataSource = aDataSource;
|
||||
_implementedOutlineViewDataSourceMethods = 0;
|
||||
|
||||
if ([_outlineViewDataSource respondsToSelector:@selector(outlineView:objectValueForTableColumn:byItem:)])
|
||||
_implementedOutlineViewDataSourceMethods |= CPOutlineViewDataSource_outlineView_objectValue_forTableColumn_byItem_;
|
||||
|
||||
if ([_outlineViewDataSource respondsToSelector:@selector(outlineView:setObjectValue:forTableColumn:byItem:)])
|
||||
_implementedOutlineViewDataSourceMethods |= CPOutlineViewDataSource_outlineView_setObjectValue_forTableColumn_byItem_;
|
||||
|
||||
@@ -1441,7 +1442,7 @@ var CPOutlineViewCoalesceSelectionNotificationStateOff = 0,
|
||||
[[CPNotificationCenter defaultCenter]
|
||||
postNotificationName:CPOutlineViewItemWillExpandNotification
|
||||
object:self
|
||||
userInfo:[CPDictionary dictionaryWithObject:item forKey:"CPObject"]];
|
||||
userInfo:@{ "CPObject": item }];
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -1452,7 +1453,7 @@ var CPOutlineViewCoalesceSelectionNotificationStateOff = 0,
|
||||
[[CPNotificationCenter defaultCenter]
|
||||
postNotificationName:CPOutlineViewItemDidExpandNotification
|
||||
object:self
|
||||
userInfo:[CPDictionary dictionaryWithObject:item forKey:"CPObject"]];
|
||||
userInfo:@{ "CPObject": item }];
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -1463,7 +1464,7 @@ var CPOutlineViewCoalesceSelectionNotificationStateOff = 0,
|
||||
[[CPNotificationCenter defaultCenter]
|
||||
postNotificationName:CPOutlineViewItemWillCollapseNotification
|
||||
object:self
|
||||
userInfo:[CPDictionary dictionaryWithObject:item forKey:"CPObject"]];
|
||||
userInfo:@{ "CPObject": item }];
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -1474,7 +1475,7 @@ var CPOutlineViewCoalesceSelectionNotificationStateOff = 0,
|
||||
[[CPNotificationCenter defaultCenter]
|
||||
postNotificationName:CPOutlineViewItemDidCollapseNotification
|
||||
object:self
|
||||
userInfo:[CPDictionary dictionaryWithObject:item forKey:"CPObject"]];
|
||||
userInfo:@{ "CPObject": item }];
|
||||
}
|
||||
|
||||
- (void)keyDown:(CPEvent)anEvent
|
||||
@@ -1533,6 +1534,16 @@ var CPOutlineViewCoalesceSelectionNotificationStateOff = 0,
|
||||
[super keyDown:anEvent];
|
||||
}
|
||||
|
||||
- (BOOL)_dataSourceRespondsToObjectValueForTableColumn
|
||||
{
|
||||
return _implementedOutlineViewDataSourceMethods & CPOutlineViewDataSource_outlineView_objectValue_forTableColumn_byItem_;
|
||||
}
|
||||
|
||||
- (BOOL)_delegateRespondsToDataViewForTableColumn
|
||||
{
|
||||
return _implementedOutlineViewDelegateMethods & CPOutlineViewDelegate_outlineView_dataViewForTableColumn_item_;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
// FIX ME: We're using with() here because Safari fails if we use anOutlineView._itemInfosForItems or whatever...
|
||||
@@ -1826,21 +1837,6 @@ var _loadItemInfoForItem = function(/*CPOutlineView*/ anOutlineView, /*id*/ anIt
|
||||
return self;
|
||||
}
|
||||
|
||||
- (CPView)tableView:(CPTableView)theTableView dataViewForTableColumn:(CPTableColumn)theTableColumn row:(int)theRow
|
||||
{
|
||||
var dataView = nil;
|
||||
|
||||
if ((_outlineView._implementedOutlineViewDelegateMethods & CPOutlineViewDelegate_outlineView_dataViewForTableColumn_item_))
|
||||
dataView = [_outlineView._outlineViewDelegate outlineView:_outlineView
|
||||
dataViewForTableColumn:theTableColumn
|
||||
item:[_outlineView itemAtRow:theRow]];
|
||||
|
||||
if (!dataView)
|
||||
dataView = [theTableColumn dataViewForRow:theRow];
|
||||
|
||||
return dataView;
|
||||
}
|
||||
|
||||
- (BOOL)tableView:(CPTableView)theTableView shouldSelectRow:(int)theRow
|
||||
{
|
||||
return SHOULD_SELECT_ITEM(_outlineView, [_outlineView itemAtRow:theRow]);
|
||||
@@ -1897,6 +1893,17 @@ var _loadItemInfoForItem = function(/*CPOutlineView*/ anOutlineView, /*id*/ anIt
|
||||
return [_outlineView menu] || [[_outlineView class] defaultMenu];
|
||||
}
|
||||
|
||||
- (CPView)tableView:(CPTableView)aTableView dataViewForTableColumn:(CPTableColumn)aTableColumn row:(int)aRow
|
||||
{
|
||||
if ((_outlineView._implementedOutlineViewDelegateMethods & CPOutlineViewDelegate_outlineView_dataViewForTableColumn_item_))
|
||||
{
|
||||
var item = [_outlineView itemAtRow:aRow];
|
||||
return [_outlineView._outlineViewDelegate outlineView:_outlineView dataViewForTableColumn:aTableColumn item:item]
|
||||
}
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation CPDisclosureButton : CPButton
|
||||
|
||||
+1
-1
@@ -116,7 +116,7 @@ CPDocModalWindowMask = 1 << 6;
|
||||
|
||||
- (BOOL)canBecomeKeyWindow
|
||||
{
|
||||
return YES;
|
||||
return YES;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -79,7 +79,7 @@ var CPPasteboards = nil,
|
||||
|
||||
[self setVersion:1.0];
|
||||
|
||||
CPPasteboards = [CPDictionary dictionary];
|
||||
CPPasteboards = @{};
|
||||
|
||||
if (typeof window.cpPasteboardWithName !== "undefined")
|
||||
supportsNativePasteboard = YES;
|
||||
@@ -121,8 +121,8 @@ var CPPasteboards = nil,
|
||||
// _name = aName;
|
||||
_types = [];
|
||||
|
||||
_owners = [CPDictionary dictionary];
|
||||
_provided = [CPDictionary dictionary];
|
||||
_owners = @{};
|
||||
_provided = @{};
|
||||
|
||||
_changeCount = 0;
|
||||
|
||||
@@ -188,8 +188,8 @@ var CPPasteboards = nil,
|
||||
{
|
||||
[_types setArray:types];
|
||||
|
||||
_owners = [CPDictionary dictionary];
|
||||
_provided = [CPDictionary dictionary];
|
||||
_owners = @{};
|
||||
_provided = @{};
|
||||
|
||||
var count = _types.length;
|
||||
|
||||
|
||||
@@ -77,14 +77,15 @@ var CPProgressIndicatorSpinningStyleColors = [];
|
||||
|
||||
+ (CPDictionary)themeAttributes
|
||||
{
|
||||
return [CPDictionary dictionaryWithObjectsAndKeys:
|
||||
[CPNull null], @"indeterminate-bar-color",
|
||||
[CPNull null], @"bar-color",
|
||||
20, @"default-height",
|
||||
[CPNull null], @"bezel-color",
|
||||
[CPNull null], @"spinning-mini-gif",
|
||||
[CPNull null], @"spinning-small-gif",
|
||||
[CPNull null], @"spinning-regular-gif"];
|
||||
return @{
|
||||
@"indeterminate-bar-color": [CPNull null],
|
||||
@"bar-color": [CPNull null],
|
||||
@"default-height": 20,
|
||||
@"bezel-color": [CPNull null],
|
||||
@"spinning-mini-gif": [CPNull null],
|
||||
@"spinning-small-gif": [CPNull null],
|
||||
@"spinning-regular-gif": [CPNull null],
|
||||
};
|
||||
}
|
||||
|
||||
+ (Class)_binderClassForBinding:(CPString)aBinding
|
||||
|
||||
@@ -360,7 +360,11 @@
|
||||
rootItems = [treeChild children];
|
||||
}
|
||||
|
||||
var row = [CPDictionary dictionaryWithObjectsAndKeys:criteria, @"criteria", values, @"displayValues", rowType, @"rowType"];
|
||||
var row = @{
|
||||
@"criteria": criteria,
|
||||
@"displayValues": values,
|
||||
@"rowType": rowType,
|
||||
};
|
||||
|
||||
return row;
|
||||
}
|
||||
|
||||
@@ -124,8 +124,16 @@ var CPRuleEditorItemPBoardType = @"CPRuleEditorItemPBoardType",
|
||||
|
||||
+ (id)themeAttributes
|
||||
{
|
||||
return [CPDictionary dictionaryWithObjects:[[CPNull null], [CPNull null], [CPNull null], [CPNull null], [CPNull null], [CPNull null], [CPNull null], [CPNull null]]
|
||||
forKeys:[@"alternating-row-colors", @"selected-color", @"slice-top-border-color", @"slice-bottom-border-color", @"slice-last-bottom-border-color", @"font", @"add-image", @"remove-image"]];
|
||||
return @{
|
||||
@"alternating-row-colors": [CPNull null],
|
||||
@"selected-color": [CPNull null],
|
||||
@"slice-top-border-color": [CPNull null],
|
||||
@"slice-bottom-border-color": [CPNull null],
|
||||
@"slice-last-bottom-border-color": [CPNull null],
|
||||
@"font": [CPNull null],
|
||||
@"add-image": [CPNull null],
|
||||
@"remove-image": [CPNull null],
|
||||
};
|
||||
}
|
||||
|
||||
- (id)initWithFrame:(CGRect)frame
|
||||
@@ -791,7 +799,7 @@ TODO: implement
|
||||
*/
|
||||
- (CPPredicate)predicateForRow:(CPInteger)aRow
|
||||
{
|
||||
var predicateParts = [CPDictionary dictionary],
|
||||
var predicateParts = @{},
|
||||
items = [self criteriaForRow:aRow],
|
||||
count = [items count],
|
||||
predicate,
|
||||
@@ -1387,7 +1395,10 @@ TODO: implement
|
||||
{
|
||||
var item = [items objectAtIndex:i],
|
||||
value = [values objectAtIndex:i],
|
||||
itemAndValue = [CPDictionary dictionaryWithObjects:[item, value] forKeys:["item", "value"]];
|
||||
itemAndValue = @{
|
||||
"item": item,
|
||||
"value": value,
|
||||
};
|
||||
|
||||
[itemsAndValues addObject:itemAndValue];
|
||||
}
|
||||
@@ -1771,7 +1782,7 @@ TODO: implement
|
||||
|
||||
if (animate)
|
||||
{
|
||||
var animation = [CPDictionary dictionary];
|
||||
var animation = @{};
|
||||
[animation setObject:aslice forKey:CPViewAnimationTargetKey];
|
||||
[animation setObject:startRect forKey:CPViewAnimationStartFrameKey];
|
||||
[animation setObject:targetRect forKey:CPViewAnimationEndFrameKey];
|
||||
@@ -1866,17 +1877,17 @@ TODO: implement
|
||||
|
||||
- (CPString)_toolTipForAddCompoundRowButton
|
||||
{
|
||||
return @"Add Compound row";
|
||||
return [_standardLocalizer localizedStringForString:@"Add compound row"];
|
||||
}
|
||||
|
||||
- (CPString)_toolTipForAddSimpleRowButton
|
||||
{
|
||||
return @"Add row";
|
||||
return [_standardLocalizer localizedStringForString:@"Add row"];
|
||||
}
|
||||
|
||||
- (CPString)_toolTipForDeleteRowButton
|
||||
{
|
||||
return @"Delete row";
|
||||
return [_standardLocalizer localizedStringForString:@"Delete row"];
|
||||
}
|
||||
|
||||
- (void)_updateSliceIndentations
|
||||
@@ -2268,7 +2279,7 @@ TODO: implement
|
||||
|
||||
- (void)_postRowCountChangedNotificationOfType:(CPString)notificationName indexes:indexes
|
||||
{
|
||||
var userInfo = [CPDictionary dictionaryWithObject:indexes forKey:"indexes"];
|
||||
var userInfo = @{ "indexes": indexes };
|
||||
[[CPNotificationCenter defaultCenter] postNotificationName:notificationName object:self userInfo:userInfo];
|
||||
}
|
||||
|
||||
|
||||
@@ -59,7 +59,7 @@ var LocalizerStringsRegex = new RegExp("\"(.+)\"\\s*=\\s*\"(.+)\"\\s*;\\s*(//.+)
|
||||
|
||||
- (void)loadContent:(CPString)aContent
|
||||
{
|
||||
var dict = [CPDictionary dictionary],
|
||||
var dict = @{},
|
||||
lines = [aContent componentsSeparatedByString:"\n"],
|
||||
count = [lines count];
|
||||
|
||||
|
||||
@@ -271,7 +271,11 @@ var CONTROL_HEIGHT = 16.,
|
||||
}
|
||||
}
|
||||
|
||||
repObject = [CPDictionary dictionaryWithObjectsAndKeys:childItem, @"item", childValue, @"value", i, @"indexInCriteria"];
|
||||
repObject = @{
|
||||
@"item": childItem,
|
||||
@"value": childValue,
|
||||
@"indexInCriteria": i
|
||||
};
|
||||
[menuItem setRepresentedObject:repObject];
|
||||
[menuItems addObject:menuItem];
|
||||
}
|
||||
|
||||
@@ -143,10 +143,10 @@ var CPScrollerStyleGlobal = CPScrollerStyleOverlay,
|
||||
|
||||
+ (CPDictionary)themeAttributes
|
||||
{
|
||||
return [CPDictionary dictionaryWithJSObject:{
|
||||
@"bottom-corner-color": [CPColor whiteColor],
|
||||
@"border-color": [CPColor blackColor]
|
||||
}];
|
||||
return @{
|
||||
@"bottom-corner-color": [CPColor whiteColor],
|
||||
@"border-color": [CPColor blackColor]
|
||||
};
|
||||
}
|
||||
|
||||
+ (CGSize)contentSizeForFrameSize:(CGSize)frameSize hasHorizontalScroller:(BOOL)hFlag hasVerticalScroller:(BOOL)vFlag borderType:(CPBorderType)borderType
|
||||
|
||||
+21
-17
@@ -110,19 +110,19 @@ CPThemeStateScrollerKnobDark = CPThemeState("scroller-knob-dark");
|
||||
|
||||
+ (id)themeAttributes
|
||||
{
|
||||
return [CPDictionary dictionaryWithJSObject:{
|
||||
@"scroller-width": 7.0,
|
||||
@"knob-slot-color": [CPNull null],
|
||||
@"decrement-line-color": [CPNull null],
|
||||
@"increment-line-color": [CPNull null],
|
||||
@"knob-color": [CPNull null],
|
||||
@"decrement-line-size":_CGSizeMakeZero(),
|
||||
@"increment-line-size":_CGSizeMakeZero(),
|
||||
@"track-inset":_CGInsetMakeZero(),
|
||||
@"knob-inset": _CGInsetMakeZero(),
|
||||
@"minimum-knob-length":21.0,
|
||||
@"track-border-overlay": 9.0
|
||||
}];
|
||||
return @{
|
||||
@"scroller-width": 7.0,
|
||||
@"knob-slot-color": [CPNull null],
|
||||
@"decrement-line-color": [CPNull null],
|
||||
@"increment-line-color": [CPNull null],
|
||||
@"knob-color": [CPNull null],
|
||||
@"decrement-line-size":_CGSizeMakeZero(),
|
||||
@"increment-line-size":_CGSizeMakeZero(),
|
||||
@"track-inset":_CGInsetMakeZero(),
|
||||
@"knob-inset": _CGInsetMakeZero(),
|
||||
@"minimum-knob-length":21.0,
|
||||
@"track-border-overlay": 9.0
|
||||
};
|
||||
}
|
||||
|
||||
+ (float)scrollerWidth
|
||||
@@ -182,8 +182,10 @@ CPThemeStateScrollerKnobDark = CPThemeState("scroller-knob-dark");
|
||||
_allowFadingOut = YES;
|
||||
_isMouseOver = NO;
|
||||
_style = CPScrollerStyleOverlay;
|
||||
var paramAnimFadeOut = [CPDictionary dictionaryWithObjects:[self, CPViewAnimationFadeOutEffect]
|
||||
forKeys:[CPViewAnimationTargetKey, CPViewAnimationEffectKey]];
|
||||
var paramAnimFadeOut = @{
|
||||
CPViewAnimationTargetKey: self,
|
||||
CPViewAnimationEffectKey: CPViewAnimationFadeOutEffect,
|
||||
};
|
||||
|
||||
_animationScroller = [[CPViewAnimation alloc] initWithDuration:0.2 animationCurve:CPAnimationEaseInOut];
|
||||
[_animationScroller setViewAnimations:[paramAnimFadeOut]];
|
||||
@@ -826,8 +828,10 @@ var CPScrollerControlSizeKey = @"CPScrollerControlSize",
|
||||
_allowFadingOut = YES;
|
||||
_isMouseOver = NO;
|
||||
|
||||
var paramAnimFadeOut = [CPDictionary dictionaryWithObjects:[self, CPViewAnimationFadeOutEffect]
|
||||
forKeys:[CPViewAnimationTargetKey, CPViewAnimationEffectKey]];
|
||||
var paramAnimFadeOut = @{
|
||||
CPViewAnimationTargetKey: self,
|
||||
CPViewAnimationEffectKey: CPViewAnimationFadeOutEffect,
|
||||
};
|
||||
|
||||
_animationScroller = [[CPViewAnimation alloc] initWithDuration:0.2 animationCurve:CPAnimationEaseInOut];
|
||||
[_animationScroller setViewAnimations:[paramAnimFadeOut]];
|
||||
|
||||
@@ -69,13 +69,12 @@ var RECENT_SEARCH_PREFIX = @" ";
|
||||
|
||||
+ (CPDictionary)themeAttributes
|
||||
{
|
||||
return [CPDictionary dictionaryWithJSObject:
|
||||
{
|
||||
return @{
|
||||
@"image-search": [CPNull null],
|
||||
@"image-find": [CPNull null],
|
||||
@"image-cancel": [CPNull null],
|
||||
@"image-cancel-pressed": [CPNull null]
|
||||
}];
|
||||
};
|
||||
}
|
||||
|
||||
- (id)initWithFrame:(CGRect)frame
|
||||
|
||||
+123
-2
@@ -58,8 +58,33 @@ CPSegmentSwitchTrackingMomentary = 2;
|
||||
|
||||
+ (id)themeAttributes
|
||||
{
|
||||
return [CPDictionary dictionaryWithObjects:[CPCenterTextAlignment, CPCenterVerticalTextAlignment, CPImageLeft, CPImageScaleNone, _CGInsetMakeZero(), _CGInsetMakeZero(), [CPNull null], [CPNull null], [CPNull null], [CPNull null], 1.0, 24.0]
|
||||
forKeys:[@"alignment", @"vertical-alignment", @"image-position", @"image-scaling", @"bezel-inset", @"content-inset", @"left-segment-bezel-color", @"right-segment-bezel-color", @"center-segment-bezel-color", @"divider-bezel-color", @"divider-thickness", @"default-height"]];
|
||||
return @{
|
||||
@"alignment": CPCenterTextAlignment,
|
||||
@"vertical-alignment": CPCenterVerticalTextAlignment,
|
||||
@"image-position": CPImageLeft,
|
||||
@"image-scaling": CPImageScaleNone,
|
||||
@"bezel-inset": _CGInsetMakeZero(),
|
||||
@"content-inset": _CGInsetMakeZero(),
|
||||
@"left-segment-bezel-color": [CPNull null],
|
||||
@"right-segment-bezel-color": [CPNull null],
|
||||
@"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
|
||||
@@ -79,6 +104,19 @@ CPSegmentSwitchTrackingMomentary = 2;
|
||||
return self;
|
||||
}
|
||||
|
||||
- (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");
|
||||
else
|
||||
[super bind:aBinding toObject:anObject withKeyPath:aKeyPath options:options];
|
||||
}
|
||||
|
||||
- (void)_reverseSetBinding
|
||||
{
|
||||
[_CPSegmentedControlBinder reverseSetValueForObject:self];
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the tag of the selected segment.
|
||||
*/
|
||||
@@ -177,6 +215,21 @@ CPSegmentSwitchTrackingMomentary = 2;
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (BOOL)_selectSegmentWithLabel:(CPString)aLabel
|
||||
{
|
||||
var index = 0;
|
||||
|
||||
for (; index < _segments.length; ++index)
|
||||
if (_segments[index].label == aLabel)
|
||||
{
|
||||
[self setSelectedSegment:index];
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
return NO;
|
||||
}
|
||||
|
||||
// Specifying Tracking Mode
|
||||
|
||||
- (BOOL)isTracking
|
||||
@@ -891,6 +944,74 @@ var CPSegmentedControlSegmentsKey = "CPSegmentedControlSegmentsKey",
|
||||
|
||||
@end
|
||||
|
||||
var CPSegmentedControlBindersMap = {},
|
||||
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
|
||||
{
|
||||
[super _updatePlaceholdersWithOptions:options];
|
||||
|
||||
[self _setPlaceholder:CPSegmentedControlNoSelectionPlaceholder forMarker:CPMultipleValuesMarker isDefault:YES];
|
||||
[self _setPlaceholder:CPSegmentedControlNoSelectionPlaceholder forMarker:CPNoSelectionMarker isDefault:YES];
|
||||
[self _setPlaceholder:CPSegmentedControlNoSelectionPlaceholder forMarker:CPNotApplicableMarker isDefault:YES];
|
||||
[self _setPlaceholder:CPSegmentedControlNoSelectionPlaceholder forMarker:CPNullMarker isDefault:YES];
|
||||
}
|
||||
|
||||
- (void)setPlaceholderValue:(id)aValue withMarker:(CPString)aMarker forBinding:(CPString)aBinding
|
||||
{
|
||||
if (aValue == CPSegmentedControlNoSelectionPlaceholder)
|
||||
[_source setSelected:NO forSegment:[_source selectedSegment]];
|
||||
else
|
||||
[self setValue:aValue forBinding:aBinding];
|
||||
}
|
||||
|
||||
- (void)setValue:(id)aValue forBinding:(CPString)aBinding
|
||||
{
|
||||
if (aBinding == CPSelectedIndexBinding)
|
||||
[_source setSelectedSegment:aValue];
|
||||
else if (aBinding == CPSelectedTagBinding)
|
||||
[_source selectSegmentWithTag:aValue];
|
||||
else if (aBinding == CPSelectedLabelBinding)
|
||||
[_source _selectSegmentWithLabel:aValue];
|
||||
}
|
||||
|
||||
- (id)valueForBinding:(CPString)aBinding
|
||||
{
|
||||
var selectedIndex = [_source selectedSegment];
|
||||
|
||||
if (aBinding == CPSelectedIndexBinding)
|
||||
return selectedIndex;
|
||||
else if (aBinding == CPSelectedTagBinding)
|
||||
return [_source tagForSegment:selectedIndex];
|
||||
else if (aBinding == CPSelectedLabelBinding)
|
||||
return [_source labelForSegment:selectedIndex];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation _CPSegmentItem : CPObject
|
||||
{
|
||||
|
||||
@@ -49,11 +49,10 @@ CPThemeStateShadowViewHeavy = CPThemeState("shadowview-style-heavy");
|
||||
|
||||
+ (id)themeAttributes
|
||||
{
|
||||
return [CPDictionary dictionaryWithJSObject:
|
||||
{
|
||||
return @{
|
||||
@"bezel-color": [CPNull null],
|
||||
@"content-inset": CGInsetMakeZero()
|
||||
}];
|
||||
};
|
||||
}
|
||||
|
||||
+ (CGRect)frameForContentFrame:(CGRect)aFrame withWeight:(CPShadowWeight)aWeight
|
||||
|
||||
+6
-2
@@ -51,8 +51,12 @@ CPCircularSlider = 1;
|
||||
|
||||
+ (id)themeAttributes
|
||||
{
|
||||
return [CPDictionary dictionaryWithObjects:[[CPNull null], _CGSizeMakeZero(), 0.0, [CPNull null]]
|
||||
forKeys:[@"knob-color", @"knob-size", @"track-width", @"track-color"]];
|
||||
return @{
|
||||
@"knob-color": [CPNull null],
|
||||
@"knob-size": _CGSizeMakeZero(),
|
||||
@"track-width": 0.0,
|
||||
@"track-color": [CPNull null],
|
||||
};
|
||||
}
|
||||
|
||||
- (id)initWithFrame:(CGRect)aFrame
|
||||
|
||||
+17
-13
@@ -105,16 +105,13 @@ var ShouldSuppressResizeNotifications = 1,
|
||||
|
||||
+ (id)themeAttributes
|
||||
{
|
||||
return [CPDictionary dictionaryWithObjects:[1.0,
|
||||
10.0,
|
||||
[CPColor grayColor],
|
||||
[CPNull null],
|
||||
[CPNull null]]
|
||||
forKeys:[@"divider-thickness",
|
||||
@"pane-divider-thickness",
|
||||
@"pane-divider-color",
|
||||
@"horizontal-divider-color",
|
||||
@"vertical-divider-color"]];
|
||||
return @{
|
||||
@"divider-thickness": 1.0,
|
||||
@"pane-divider-thickness": 10.0,
|
||||
@"pane-divider-color": [CPColor grayColor],
|
||||
@"horizontal-divider-color": [CPNull null],
|
||||
@"vertical-divider-color": [CPNull null],
|
||||
};
|
||||
}
|
||||
|
||||
- (id)initWithFrame:(CGRect)aFrame
|
||||
@@ -1032,7 +1029,7 @@ The sum of the views and the sum of the dividers should be equal to the size of
|
||||
var userInfo = nil;
|
||||
|
||||
if (_currentDivider !== CPNotFound)
|
||||
userInfo = [CPDictionary dictionaryWithObject:_currentDivider forKey:@"CPSplitViewDividerIndex"];
|
||||
userInfo = @{ @"CPSplitViewDividerIndex": _currentDivider };
|
||||
|
||||
[[CPNotificationCenter defaultCenter] postNotificationName:CPSplitViewWillResizeSubviewsNotification
|
||||
object:self
|
||||
@@ -1044,7 +1041,7 @@ The sum of the views and the sum of the dividers should be equal to the size of
|
||||
var userInfo = nil;
|
||||
|
||||
if (_currentDivider !== CPNotFound)
|
||||
userInfo = [CPDictionary dictionaryWithObject:_currentDivider forKey:@"CPSplitViewDividerIndex"];
|
||||
userInfo = @{ @"CPSplitViewDividerIndex": _currentDivider };
|
||||
|
||||
[[CPNotificationCenter defaultCenter] postNotificationName:CPSplitViewDidResizeSubviewsNotification
|
||||
object:self
|
||||
@@ -1160,7 +1157,14 @@ The sum of the views and the sum of the dividers should be equal to the size of
|
||||
_preCollapsePositions = [CPMutableDictionary new];
|
||||
|
||||
for (var i = 0, count = [preCollapseArray count]; i < count; i++)
|
||||
[_preCollapsePositions setObject:preCollapseArray[i] forKey:i + ""];
|
||||
{
|
||||
var item = preCollapseArray[i];
|
||||
|
||||
if (item === nil)
|
||||
[_preCollapsePositions removeObjectForKey:String(i)];
|
||||
else
|
||||
[_preCollapsePositions setObject:item forKey:String(i)];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+6
-2
@@ -269,8 +269,12 @@
|
||||
|
||||
+ (id)themeAttributes
|
||||
{
|
||||
return [CPDictionary dictionaryWithObjects:[[CPNull null], [CPNull null], _CGSizeMakeZero(), _CGSizeMakeZero()]
|
||||
forKeys:[@"bezel-color-up-button", @"bezel-color-down-button", @"up-button-size", @"down-button-size"]];
|
||||
return @{
|
||||
@"bezel-color-up-button": [CPNull null],
|
||||
@"bezel-color-down-button": [CPNull null],
|
||||
@"up-button-size": _CGSizeMakeZero(),
|
||||
@"down-button-size": _CGSizeMakeZero(),
|
||||
};
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
+13
-14
@@ -508,13 +508,8 @@ var CPTabViewItemsKey = "CPTabViewItemsKey",
|
||||
|
||||
[self setDelegate:[aCoder decodeObjectForKey:CPTabViewDelegateKey]];
|
||||
|
||||
var selected = [aCoder decodeObjectForKey:CPTabViewSelectedItemKey];
|
||||
if (selected)
|
||||
[self selectTabViewItem:selected];
|
||||
|
||||
[self setTabViewType:[aCoder decodeIntForKey:CPTabViewTypeKey]];
|
||||
|
||||
[self setNeedsLayout];
|
||||
self.selectOnAwake = [aCoder decodeObjectForKey:CPTabViewSelectedItemKey];
|
||||
_type = [aCoder decodeIntForKey:CPTabViewTypeKey];
|
||||
}
|
||||
|
||||
return self;
|
||||
@@ -522,13 +517,17 @@ var CPTabViewItemsKey = "CPTabViewItemsKey",
|
||||
|
||||
- (void)awakeFromCib
|
||||
{
|
||||
// This is a quick and dirty fix of the tab view item we decode and install in _box
|
||||
// having a different _superview decoded later in the decoding process - e.g. the
|
||||
// CPTabView itself as is the case when we're coming from an xib. This solution could
|
||||
// probably be improved by fixing this in nib2cib instead, but the _box doesn't yet
|
||||
// exist then so it's not totally clear what to change the superview to at that stage.
|
||||
if ([_box contentView])
|
||||
_box._contentView._superview = _box;
|
||||
if (self.selectOnAwake)
|
||||
{
|
||||
[self selectTabViewItem:self.selectOnAwake];
|
||||
delete self.selectOnAwake;
|
||||
}
|
||||
|
||||
var type = _type;
|
||||
_type = nil;
|
||||
[self setTabViewType:type];
|
||||
|
||||
[self setNeedsLayout];
|
||||
}
|
||||
|
||||
- (void)encodeWithCoder:(CPCoder)aCoder
|
||||
|
||||
+10
-22
@@ -52,7 +52,7 @@ CPTableColumnUserResizingMask = 1 << 1;
|
||||
CPTableView _tableView;
|
||||
CPView _headerView;
|
||||
CPView _dataView;
|
||||
Object _dataViewData;
|
||||
CPData _dataViewData;
|
||||
|
||||
float _width;
|
||||
float _minWidth;
|
||||
@@ -86,7 +86,7 @@ CPTableColumnUserResizingMask = 1 << 1;
|
||||
|
||||
if (self)
|
||||
{
|
||||
_dataViewData = { };
|
||||
_dataViewData = nil;
|
||||
|
||||
_width = 100.0;
|
||||
_minWidth = 10.0;
|
||||
@@ -395,12 +395,12 @@ CPTableColumnUserResizingMask = 1 << 1;
|
||||
- (void)setDataView:(CPView)aView
|
||||
{
|
||||
if (_dataView)
|
||||
_dataViewData[[_dataView UID]] = nil;
|
||||
_dataViewData = nil;
|
||||
|
||||
[aView setThemeState:CPThemeStateTableDataView];
|
||||
|
||||
_dataView = aView;
|
||||
_dataViewData[[aView UID]] = [CPKeyedArchiver archivedDataWithRootObject:aView];
|
||||
_dataViewData = [CPKeyedArchiver archivedDataWithRootObject:aView];
|
||||
}
|
||||
|
||||
- (CPView)dataView
|
||||
@@ -424,24 +424,12 @@ CPTableColumnUserResizingMask = 1 << 1;
|
||||
/*!
|
||||
@ignore
|
||||
*/
|
||||
- (id)_newDataViewForRow:(int)aRowIndex
|
||||
- (id)_newDataView
|
||||
{
|
||||
var dataView = [self dataViewForRow:aRowIndex],
|
||||
dataViewUID = [dataView UID];
|
||||
if (!_dataViewData)
|
||||
return nil;
|
||||
|
||||
var x = [self tableView]._cachedDataViews[dataViewUID];
|
||||
if (x && x.length)
|
||||
return x.pop();
|
||||
|
||||
// if we haven't cached an archive of the data view, do it now
|
||||
if (!_dataViewData[dataViewUID])
|
||||
_dataViewData[dataViewUID] = [CPKeyedArchiver archivedDataWithRootObject:dataView];
|
||||
|
||||
// unarchive the data view cache
|
||||
var newDataView = [CPKeyedUnarchiver unarchiveObjectWithData:_dataViewData[dataViewUID]];
|
||||
newDataView.identifier = dataViewUID;
|
||||
|
||||
// make sure only we have control over the size and placement
|
||||
var newDataView = [CPKeyedUnarchiver unarchiveObjectWithData:_dataViewData];
|
||||
[newDataView setAutoresizingMask:CPViewNotSizable];
|
||||
|
||||
return newDataView;
|
||||
@@ -560,7 +548,7 @@ CPTableColumnUserResizingMask = 1 << 1;
|
||||
[[CPNotificationCenter defaultCenter]
|
||||
postNotificationName:CPTableViewColumnDidResizeNotification
|
||||
object:[self tableView]
|
||||
userInfo:[CPDictionary dictionaryWithObjects:[self, oldWidth] forKeys:[@"CPTableColumn", "CPOldWidth"]]];
|
||||
userInfo:@{ @"CPTableColumn": self, @"CPOldWidth": oldWidth }];
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -757,7 +745,7 @@ var CPTableColumnIdentifierKey = @"CPTableColumnIdentifierKey",
|
||||
|
||||
if (self)
|
||||
{
|
||||
_dataViewData = { };
|
||||
_dataViewData = nil;
|
||||
|
||||
_width = [aCoder decodeFloatForKey:CPTableColumnWidthKey];
|
||||
_minWidth = [aCoder decodeFloatForKey:CPTableColumnMinWidthKey];
|
||||
|
||||
@@ -45,8 +45,16 @@
|
||||
|
||||
+ (id)themeAttributes
|
||||
{
|
||||
return [CPDictionary dictionaryWithObjects:[[CPNull null], CPLeftTextAlignment, CPLineBreakByTruncatingTail, CGInsetMakeZero(), [CPNull null], [CPNull null], [CPNull null], CGSizeMakeZero()]
|
||||
forKeys:[@"background-color", @"text-alignment", @"line-break-mode", @"text-inset", @"text-color", @"font", @"text-shadow-color", @"text-shadow-offset"]];
|
||||
return @{
|
||||
@"background-color": [CPNull null],
|
||||
@"text-alignment": CPLeftTextAlignment,
|
||||
@"line-break-mode": CPLineBreakByTruncatingTail,
|
||||
@"text-inset": CGInsetMakeZero(),
|
||||
@"text-color": [CPNull null],
|
||||
@"font": [CPNull null],
|
||||
@"text-shadow-color": [CPNull null],
|
||||
@"text-shadow-offset": CGSizeMakeZero(),
|
||||
};
|
||||
}
|
||||
|
||||
- (void)initWithFrame:(CGRect)frame
|
||||
@@ -239,8 +247,10 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal
|
||||
|
||||
+ (id)themeAttributes
|
||||
{
|
||||
return [CPDictionary dictionaryWithObjects:[[CPNull null], [CPColor grayColor]]
|
||||
forKeys:[@"background-color", @"divider-color"]];
|
||||
return @{
|
||||
@"background-color": [CPNull null],
|
||||
@"divider-color": [CPColor grayColor],
|
||||
};
|
||||
}
|
||||
|
||||
- (void)_init
|
||||
@@ -321,6 +331,9 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal
|
||||
{
|
||||
var headerView = [_tableView._tableColumns[column] headerView];
|
||||
[headerView setThemeState:CPThemeStateHighlighted];
|
||||
|
||||
if (_tableView._editingColumn == column)
|
||||
[[self window] makeFirstResponder:_tableView];
|
||||
}
|
||||
|
||||
_pressedColumn = column;
|
||||
|
||||
+433
-83
@@ -25,6 +25,7 @@
|
||||
|
||||
@import "CPDragServer_Constants.j"
|
||||
@import "CGGradient.j"
|
||||
@import "CPCib.j"
|
||||
@import "CPCompatibility.j"
|
||||
@import "CPControl.j"
|
||||
@import "CPImageView.j"
|
||||
@@ -188,6 +189,8 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
|
||||
|
||||
Object _dataViewsForTableColumns;
|
||||
Object _cachedDataViews;
|
||||
CPDictionary _archivedDataViews;
|
||||
Object _unavailable_custom_cibs;
|
||||
|
||||
//Configuring Behavior
|
||||
BOOL _allowsColumnReordering;
|
||||
@@ -230,6 +233,8 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
|
||||
CPDate _startTrackingTimestamp;
|
||||
BOOL _trackingPointMovedOutOfClickSlop;
|
||||
CGPoint _editingCellIndex;
|
||||
CPInteger _editingRow;
|
||||
CPInteger _editingColumn;
|
||||
|
||||
_CPTableDrawView _tableDrawView;
|
||||
|
||||
@@ -255,6 +260,7 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
|
||||
BOOL _disableAutomaticResizing @accessors(property=disableAutomaticResizing);
|
||||
BOOL _lastColumnShouldSnap;
|
||||
BOOL _implementsCustomDrawRow;
|
||||
BOOL _isViewBased;
|
||||
BOOL _contentBindingExpicitelySet;
|
||||
|
||||
CPTableColumn _draggedColumn;
|
||||
@@ -274,26 +280,18 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
|
||||
*/
|
||||
+ (id)themeAttributes
|
||||
{
|
||||
return [CPDictionary dictionaryWithObjects:[[CPNull null],
|
||||
[CPNull null],
|
||||
[CPNull null],
|
||||
[CPNull null],
|
||||
[CPNull null],
|
||||
[CPNull null],
|
||||
[CPNull null],
|
||||
[CPNull null],
|
||||
[CPNull null],
|
||||
25.0]
|
||||
forKeys:[@"alternating-row-colors",
|
||||
@"grid-color",
|
||||
@"highlighted-grid-color",
|
||||
@"selection-color",
|
||||
@"sourcelist-selection-color",
|
||||
@"sort-image",
|
||||
@"sort-image-reversed",
|
||||
@"selection-radius",
|
||||
@"image-generic-file",
|
||||
@"default-row-height"]];
|
||||
return @{
|
||||
@"alternating-row-colors": [CPNull null],
|
||||
@"grid-color": [CPNull null],
|
||||
@"highlighted-grid-color": [CPNull null],
|
||||
@"selection-color": [CPNull null],
|
||||
@"sourcelist-selection-color": [CPNull null],
|
||||
@"sort-image": [CPNull null],
|
||||
@"sort-image-reversed": [CPNull null],
|
||||
@"selection-radius": [CPNull null],
|
||||
@"image-generic-file": [CPNull null],
|
||||
@"default-row-height": 25.0,
|
||||
};
|
||||
}
|
||||
|
||||
- (id)initWithFrame:(CGRect)aFrame
|
||||
@@ -380,7 +378,8 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
|
||||
_exposedRows = [CPIndexSet indexSet];
|
||||
_exposedColumns = [CPIndexSet indexSet];
|
||||
_cachedDataViews = { };
|
||||
|
||||
_archivedDataViews = nil;
|
||||
_unavailable_custom_cibs = { };
|
||||
_cachedRowHeights = [];
|
||||
|
||||
_groupRows = [CPIndexSet indexSet];
|
||||
@@ -392,6 +391,9 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
|
||||
_draggedColumn = nil;
|
||||
_draggingViews = [CPArray array];
|
||||
|
||||
_editingRow = CPNotFound;
|
||||
_editingColumn = CPNotFound;
|
||||
|
||||
/* //gradients for the source list when CPTableView is NOT first responder or the window is NOT key
|
||||
// FIX ME: we need to actually implement this.
|
||||
_sourceListInactiveGradient = CGGradientCreateWithColorComponents(CGColorSpaceCreateDeviceRGB(), [168.0/255.0,183.0/255.0,205.0/255.0,1.0,157.0/255.0,174.0/255.0,199.0/255.0,1.0], [0,1], 2);
|
||||
@@ -402,6 +404,8 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
|
||||
|
||||
if (!_sortDescriptors)
|
||||
_sortDescriptors = [];
|
||||
|
||||
[self _startObservingFirstResponder];
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -1029,8 +1033,7 @@ NOT YET IMPLEMENTED
|
||||
// TODO Only notify when a column drag operation ends, not each time a column reaches a new slot?
|
||||
[[CPNotificationCenter defaultCenter] postNotificationName:CPTableViewColumnDidMoveNotification
|
||||
object:self
|
||||
userInfo:[CPDictionary dictionaryWithObjects:[fromIndex, toIndex]
|
||||
forKeys:[@"CPOldColumn", @"CPNewColumn"]]];
|
||||
userInfo:@{ @"CPOldColumn": fromIndex, @"CPNewColumn": toIndex }];
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -1492,20 +1495,29 @@ NOT YET IMPLEMENTED
|
||||
{
|
||||
// FIX ME: Cocoa documentation says all this should be called in THIS method:
|
||||
// sets up the field editor, and sends selectWithFrame:inView:editor:delegate:start:length: and editWithFrame:inView:editor:delegate:event: to the field editor's NSCell object with the NSTableView as the text delegate.
|
||||
if (_isViewBased)
|
||||
{
|
||||
var identifier = [_tableColumns[columnIndex] UID],
|
||||
view = _dataViewsForTableColumns[identifier][rowIndex];
|
||||
|
||||
if (![self isRowSelected:rowIndex])
|
||||
[[CPException exceptionWithName:@"Error" reason:@"Attempt to edit row="+rowIndex+" when not selected." userInfo:nil] raise];
|
||||
[[self window] makeFirstResponder:view];
|
||||
}
|
||||
else
|
||||
{
|
||||
if (![self isRowSelected:rowIndex])
|
||||
[[CPException exceptionWithName:@"Error" reason:@"Attempt to edit row="+rowIndex+" when not selected." userInfo:nil] raise];
|
||||
|
||||
[self scrollRowToVisible:rowIndex];
|
||||
[self scrollColumnToVisible:columnIndex];
|
||||
[self scrollRowToVisible:rowIndex];
|
||||
[self scrollColumnToVisible:columnIndex];
|
||||
|
||||
// TODO Do something with flag.
|
||||
// TODO Do something with flag.
|
||||
|
||||
_editingCellIndex = CGPointMake(columnIndex, rowIndex);
|
||||
_editingCellIndex._shouldSelect = flag;
|
||||
_editingCellIndex = CGPointMake(columnIndex, rowIndex);
|
||||
_editingCellIndex._shouldSelect = flag;
|
||||
|
||||
[self reloadDataForRowIndexes:[CPIndexSet indexSetWithIndex:rowIndex]
|
||||
columnIndexes:[CPIndexSet indexSetWithIndex:columnIndex]];
|
||||
[self reloadDataForRowIndexes:[CPIndexSet indexSetWithIndex:rowIndex]
|
||||
columnIndexes:[CPIndexSet indexSetWithIndex:columnIndex]];
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -1902,6 +1914,90 @@ NOT YET IMPLEMENTED
|
||||
return row;
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the index of the row for the specified view.
|
||||
|
||||
@param view The view.
|
||||
@return The index of the row corresponding to the view. Returns -1 if the view is not a dataView, or a subview of a dataView.
|
||||
@discussion This is typically needed in the action method for a CPButton (or CPControl) to find out what row (and column) the action should be performed on.
|
||||
The implementation is O(rxc) where r is the number of visible rows, and c is the number of visible columns, so this method should generally not be called within a loop.
|
||||
*/
|
||||
- (CPInteger)rowForView:(CPView)aView
|
||||
{
|
||||
return [self rowNotColumn:YES forView:aView];
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the index of the column for the specified view.
|
||||
|
||||
@param view The view.
|
||||
@return The index of the column corresponding to the view. Returns -1 if the view is not a dataView, or a subview of a dataView.
|
||||
@discussion This is typically needed in the action method for a CPButton (or CPControl) to find out what row (and column) the action should be performed on.
|
||||
The implementation is O(rxc) where r is the number of visible rows, and c is the number of visible columns, so this method should generally not be called within a loop.
|
||||
*/
|
||||
- (CPInteger)columnForView:(CPView)aView
|
||||
{
|
||||
return [self rowNotColumn:NO forView:aView];
|
||||
}
|
||||
|
||||
/*!
|
||||
@ignore
|
||||
*/
|
||||
- (CPInteger)rowNotColumn:(BOOL)isRow forView:(CPView)aView
|
||||
{
|
||||
if (![aView isKindOfClass:[CPView class]])
|
||||
return -1;
|
||||
|
||||
var cellView = aView,
|
||||
contentView = [[self window] contentView];
|
||||
|
||||
while (1)
|
||||
{
|
||||
if (cellView == contentView)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
var superview = [cellView superview];
|
||||
|
||||
if ([superview isKindOfClass:[CPTableView class]])
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
cellView = superview;
|
||||
}
|
||||
}
|
||||
|
||||
var exposedRows = [],
|
||||
exposedColumns = [];
|
||||
|
||||
[_exposedRows getIndexes:exposedRows maxCount:-1 inIndexRange:nil];
|
||||
[_exposedColumns getIndexes:exposedColumns maxCount:-1 inIndexRange:nil];
|
||||
|
||||
var colcount = exposedColumns.length,
|
||||
countOfRows = exposedRows.length;
|
||||
|
||||
while (colcount--)
|
||||
{
|
||||
var column = exposedColumns[colcount],
|
||||
tableColumnUID = [_tableColumns[column] UID],
|
||||
dataViewsInTableColumn = _dataViewsForTableColumns[tableColumnUID],
|
||||
rowcount = countOfRows;
|
||||
|
||||
while (rowcount--)
|
||||
{
|
||||
var row = exposedRows[rowcount];
|
||||
|
||||
if (cellView == dataViewsInTableColumn[row])
|
||||
return isRow ? row : column;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns a rect for the dataview / cell at the column and row given.
|
||||
If the column or row index is greater than the number of columns or rows a CGZeroRect is returned
|
||||
@@ -2223,10 +2319,8 @@ NOT YET IMPLEMENTED
|
||||
|
||||
var heightObject = _cachedRowHeights[_cachedRowHeights.length - 1],
|
||||
height = heightObject.heightAboveRow + heightObject.height + _intercellSpacing.height;
|
||||
|
||||
}
|
||||
|
||||
|
||||
if ([superview isKindOfClass:[CPClipView class]])
|
||||
{
|
||||
var superviewSize = [superview bounds].size;
|
||||
@@ -2355,10 +2449,10 @@ NOT YET IMPLEMENTED
|
||||
for (var i = 0; i < [columns count]; i++)
|
||||
{
|
||||
var column = [columns objectAtIndex:i],
|
||||
metaData = [CPDictionary dictionaryWithJSObject:{
|
||||
@"identifier": [column identifier],
|
||||
@"width": [column width]
|
||||
}];
|
||||
metaData = @{
|
||||
@"identifier": [column identifier],
|
||||
@"width": [column width]
|
||||
};
|
||||
|
||||
[columnsSetup addObject:metaData];
|
||||
}
|
||||
@@ -2401,9 +2495,29 @@ NOT YET IMPLEMENTED
|
||||
Sets the delegate of the receiver.
|
||||
@param aDelegate the delegate object for the tableview.
|
||||
|
||||
The delegate can provide easy notification for user interaction, display behaviour, contextual menus, and more.
|
||||
The delegate can provide notification for user interaction, display behaviour, contextual menus, and more.
|
||||
|
||||
|
||||
@section Providing Views for Rows and Columns:
|
||||
|
||||
Returns the view used to display the specified row and column.
|
||||
@code
|
||||
- (CPView)tableView:(CPTableView)tableView viewForTableColumn:(CPTableColumn)tableColumn row:(CPInteger)row
|
||||
@endcode
|
||||
|
||||
@param
|
||||
The view to display the specified column and row. Returning nil is acceptable, and a view will not be shown at that location.
|
||||
|
||||
@discussion
|
||||
This method is required if you wish to use a view-based table view in Interface builder or cell-based table views without using CPTableColumn's setDataView: method.
|
||||
|
||||
It is recommended that the implementation of this method first call the CPTableView method makeViewWithIdentifier:owner: passing, respectively, the tableColumn parameter’s identifier and self as the owner to attempt to reuse a view that is no longer visible. The frame of the view returned by this method is not important, and it will be automatically set by the table.
|
||||
|
||||
The view's properties should be properly set up before returning the result. The delegate do not need to implement tableview:objectValueforTableColumn:row:.
|
||||
|
||||
When using bindings, this method is optional if at least one identifier has been associated with the table view at design time. If this method is not implemented, the table will automatically call the CPTableView method makeViewWithIdentifier:owner: with the tableColumn parameter’s identifier and the table view’s delegate respectively as parameters, to attempt to reuse a previous view, or automatically unarchive a prototype associated with the table view.
|
||||
|
||||
The autoresizingMask of the returned view will automatically be set to CPViewNotSizable if the data view was created in Interface builder in a table column. Otherwise, for example if the view is created manually in code, this method expects the data view to have a CPViewNotSizable mask.
|
||||
|
||||
|
||||
@section displayingcells Displaying Cells:
|
||||
@@ -2419,8 +2533,6 @@ Group rows are a way to separate a groups of data in a tableview. Return YES if
|
||||
@endcode
|
||||
|
||||
|
||||
|
||||
|
||||
@section editingcells Editing Cells:
|
||||
|
||||
Return YES if the dataview at a given index and column should be edited, otherwise NO.
|
||||
@@ -2429,9 +2541,6 @@ Return YES if the dataview at a given index and column should be edited, otherwi
|
||||
@endcode
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@section sizes Setting Row and Column Size:
|
||||
|
||||
Return the height of the row at a given index. Only implement this if you want variable row heights. Otherwise use setRowHeight: on the tableview.
|
||||
@@ -2440,8 +2549,6 @@ Return the height of the row at a given index. Only implement this if you want v
|
||||
@endcode
|
||||
|
||||
|
||||
|
||||
|
||||
@section selection Selecting in the TableView:
|
||||
@note These methods are only called when the user does something.@endnote
|
||||
|
||||
@@ -2460,7 +2567,7 @@ Return YES if the table column given should be selected, otherwise NO to deny th
|
||||
- (BOOL)tableView:(CPTableView)aTableView shouldSelectTableColumn:(CPTableColumn)aTableColumn;
|
||||
@endcode
|
||||
|
||||
Inform the delegate that the tableview is in the process of chaining the selection.
|
||||
Informs the delegate that the tableview is in the process of chaining the selection.
|
||||
This usually happens when the user is dragging their mouse across rows.
|
||||
@code
|
||||
- (void)tableViewSelectionIsChanging:(CPNotification)aNotification
|
||||
@@ -2472,10 +2579,7 @@ Informs the delegate that the tableview selection has changed.
|
||||
@endcode
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@section movingandresizingcolumsn Moving and Resizing Columns:
|
||||
@section movingandresizingcolumns Moving and Resizing Columns:
|
||||
|
||||
Return YES if the column at a given index should move to a new column index, otherwise NO.
|
||||
@code
|
||||
@@ -2483,13 +2587,13 @@ Return YES if the column at a given index should move to a new column index, oth
|
||||
@endcode
|
||||
|
||||
|
||||
Notifies the delegate that the tableview drag occurred. This is send on mouse up.
|
||||
Notifies the delegate that the tableview drag occurred. This is sent on mouse up.
|
||||
@code
|
||||
- (void)tableView:(CPTableView)tableView didDragTableColumn:(CPTableColumn)tableColumn;
|
||||
@endcode
|
||||
|
||||
|
||||
Notifies the delegate that a tablecolumn was moved by the user.
|
||||
Notifies the delegate that a table column was moved by the user.
|
||||
@code
|
||||
- (void)tableViewColumnDidMove:(CPNotification)aNotification;
|
||||
@endcode
|
||||
@@ -2500,8 +2604,6 @@ Notifies the delegate that the user resized the table column
|
||||
@endcode
|
||||
|
||||
|
||||
|
||||
|
||||
@section mousevents Responding to Mouse Events:
|
||||
|
||||
Sent when the user clicks a table column but doesn't drag.
|
||||
@@ -2510,7 +2612,7 @@ Sent when the user clicks a table column but doesn't drag.
|
||||
@endcode
|
||||
|
||||
|
||||
Notify the delegate that the user click the table header of a column.
|
||||
Notify the delegate that the user has clicked the table header of a column.
|
||||
@code
|
||||
- (void)tableView:(CPTableView)tableView mouseDownInHeaderOfTableColumn:(CPTableColumn)tableColumn;
|
||||
@endcode
|
||||
@@ -2518,15 +2620,15 @@ Notify the delegate that the user click the table header of a column.
|
||||
|
||||
@section contextualmenus Contextual Menus:
|
||||
|
||||
Called when the user right clicks on the tableview. -1 is passed for the row or column if the user doesn't right click on a real row or column
|
||||
Return a CPMenu that should be displayed if the user right clicks. If you do not implement this the tableview will just call super on menuForEvent
|
||||
Called when the user right-clicks on the tableview. -1 is passed for the row or column if the user doesn't right click on a real row or column
|
||||
Return a CPMenu that should be displayed if the user right-clicks. If you do not implement this the tableview will call super on menuForEvent
|
||||
@code
|
||||
- (CPMenu)tableView:(CPTableView)aTableView menuForTableColumn:(CPTableColumn)aColumn row:(int)aRow;
|
||||
@endcode
|
||||
|
||||
|
||||
@section deletekey Delete Key
|
||||
Called when the user presses the delete key. Many times you will want to delete data (or prompt for deletion) when the user hids the delete key.
|
||||
Called when the user presses the delete key. Many times you will want to delete data (or prompt for deletion) when the user presses the delete key.
|
||||
Your delegate can implement this method to avoid subclassing the tableview to add this behaviour.
|
||||
|
||||
@code
|
||||
@@ -2576,6 +2678,8 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
|
||||
if ([_delegate respondsToSelector:@selector(tableView:dataViewForTableColumn:row:)])
|
||||
_implementedDelegateMethods |= CPTableViewDelegate_tableView_dataViewForTableColumn_row_;
|
||||
|
||||
[self _updateIsViewBased];
|
||||
|
||||
if ([_delegate respondsToSelector:@selector(tableView:didClickTableColumn:)])
|
||||
_implementedDelegateMethods |= CPTableViewDelegate_tableView_didClickTableColumn_;
|
||||
|
||||
@@ -2944,6 +3048,8 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
|
||||
headerView = [tableColumn headerView],
|
||||
row = [_exposedRows firstIndex];
|
||||
|
||||
[dragView setFrame:bounds];
|
||||
|
||||
while (row !== CPNotFound)
|
||||
{
|
||||
var dataView = [self _newDataViewForRow:row tableColumn:tableColumn],
|
||||
@@ -2969,7 +3075,6 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
|
||||
|
||||
[dragView setBackgroundColor:[CPColor whiteColor]];
|
||||
[dragView setAlphaValue:0.7];
|
||||
[dragView setFrame:bounds];
|
||||
|
||||
return dragView;
|
||||
}
|
||||
@@ -3000,7 +3105,6 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
|
||||
[[CPException exceptionWithName:@"Error" reason:reason userInfo:nil] raise];
|
||||
}
|
||||
|
||||
|
||||
_retargetedDropRow = row;
|
||||
_retargetedDropOperation = operation;
|
||||
}
|
||||
@@ -3130,6 +3234,16 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
|
||||
return _sortDescriptors;
|
||||
}
|
||||
|
||||
- (BOOL)_dataSourceRespondsToObjectValueForTableColumn
|
||||
{
|
||||
return _implementedDataSourceMethods & CPTableViewDataSource_tableView_objectValueForTableColumn_row_;
|
||||
}
|
||||
|
||||
- (BOOL)_delegateRespondsToDataViewForTableColumn
|
||||
{
|
||||
return _implementedDelegateMethods & CPTableViewDelegate_tableView_dataViewForTableColumn_row_;
|
||||
}
|
||||
|
||||
/*!
|
||||
@ignore
|
||||
*/
|
||||
@@ -3149,12 +3263,12 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
|
||||
// tableView:objectValueForTableColumn:row: is optional if content bindings are in place.
|
||||
if (objectValue === undefined)
|
||||
{
|
||||
if (_implementedDataSourceMethods & CPTableViewDataSource_tableView_objectValueForTableColumn_row_)
|
||||
if ([self _dataSourceRespondsToObjectValueForTableColumn])
|
||||
{
|
||||
objectValue = [_dataSource tableView:self objectValueForTableColumn:aTableColumn row:aRowIndex];
|
||||
tableColumnObjectValues[aRowIndex] = objectValue;
|
||||
}
|
||||
else if (![self infoForBinding:@"content"])
|
||||
else if (![self _delegateRespondsToDataViewForTableColumn] && ![self infoForBinding:@"content"])
|
||||
{
|
||||
CPLog.warn(@"no content binding established and data source " + [_dataSource description] + " does not implement tableView:objectValueForTableColumn:row:");
|
||||
}
|
||||
@@ -3177,7 +3291,6 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
|
||||
// there are multiple views in the clip view?
|
||||
if ([superview isKindOfClass:[CPClipView class]])
|
||||
_exposedRect = [superview bounds];
|
||||
|
||||
else
|
||||
_exposedRect = [self bounds];
|
||||
}
|
||||
@@ -3301,7 +3414,8 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
|
||||
|
||||
[dataViews replaceObjectAtIndex:row withObject:nil];
|
||||
|
||||
[self _enqueueReusableDataView:dataView];
|
||||
if (row !== _editingRow || column !== _editingColumn)
|
||||
[self _enqueueReusableDataView:dataView];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3373,7 +3487,7 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
|
||||
[dataView unsetThemeState:CPThemeStateGroupRow];
|
||||
}
|
||||
|
||||
[self setNeedsDisplay:YES]
|
||||
[self setNeedsDisplay:YES];
|
||||
}
|
||||
|
||||
if (_implementedDelegateMethods & CPTableViewDelegate_tableView_willDisplayView_forTableColumn_row_)
|
||||
@@ -3384,6 +3498,9 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
|
||||
|
||||
_dataViewsForTableColumns[tableColumnUID][row] = dataView;
|
||||
|
||||
if (_isViewBased)
|
||||
continue;
|
||||
|
||||
if (isButton || (_editingCellIndex && _editingCellIndex.x === column && _editingCellIndex.y === row))
|
||||
{
|
||||
if (isTextField)
|
||||
@@ -3421,7 +3538,7 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
|
||||
if (_contentBindingExpicitelySet)
|
||||
[self _prepareContentBindedDataView:aDataView forRow:aRow];
|
||||
else
|
||||
// For both cell-based and view-based
|
||||
// For both cell-based and view-based
|
||||
[aTableColumn _prepareDataView:aDataView forRow:aRow];
|
||||
}
|
||||
|
||||
@@ -3534,17 +3651,124 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
|
||||
/*!
|
||||
@ignore
|
||||
*/
|
||||
- (CPView)_newDataViewForRow:(CPInteger)aRow tableColumn:(CPTableColumn)aTableColumn
|
||||
- (CPView)_dataViewForTableColumn:(CPTableColumn)aTableColumn row:(CPInteger)aRow
|
||||
{
|
||||
if ((_implementedDelegateMethods & CPTableViewDelegate_tableView_dataViewForTableColumn_row_))
|
||||
var view = nil;
|
||||
|
||||
if ([self _delegateRespondsToDataViewForTableColumn])
|
||||
{
|
||||
var dataView = [_delegate tableView:self dataViewForTableColumn:aTableColumn row:aRow];
|
||||
[aTableColumn setDataView:dataView];
|
||||
view = [_delegate tableView:self dataViewForTableColumn:aTableColumn row:aRow];
|
||||
|
||||
if (!view)
|
||||
[CPException raise:CPInternalInconsistencyException reason:"The view returned by -tableView:dataViewForTableColumn:row: should not be nil"];
|
||||
}
|
||||
|
||||
return [aTableColumn _newDataViewForRow:aRow];
|
||||
return view;
|
||||
}
|
||||
|
||||
/*!
|
||||
@ignore
|
||||
*/
|
||||
- (CPView)_newDataViewForRow:(CPInteger)aRow tableColumn:(CPTableColumn)aTableColumn
|
||||
{
|
||||
var view = [self _dataViewForTableColumn:aTableColumn row:aRow];
|
||||
|
||||
if (!view)
|
||||
{
|
||||
var columnIdentifier = [aTableColumn identifier];
|
||||
|
||||
// For Pre-Lion nibs, there is no automatic identifier for table column; use UID as identifier.
|
||||
if (!columnIdentifier)
|
||||
columnIdentifier = [aTableColumn UID];
|
||||
|
||||
view = [self makeViewWithIdentifier:columnIdentifier owner:_delegate];
|
||||
|
||||
if (!view)
|
||||
view = [aTableColumn _newDataView];
|
||||
|
||||
[view setIdentifier:columnIdentifier];
|
||||
}
|
||||
|
||||
return view;
|
||||
}
|
||||
|
||||
/*
|
||||
Returns a view with the specified identifier.
|
||||
|
||||
@param identifier The view identifier. Must not be nil.
|
||||
@param owner The owner of the CIB that may be loaded and instituted to create a new view with the particular identifier.
|
||||
@return A view for the row.
|
||||
|
||||
@discussion
|
||||
Typically identifier is associated with an external CIB and the table view will automatically instantiate the CIB with the provided owner. The owner of the CIB that may be loaded and instantiated to create a new view with the particular identifier is typically the table view’s delegate. The owner is useful in setting up outlets and target and actions from the view.
|
||||
|
||||
This method will typically be called by the delegate in tableView:dataViewForTableColumn:row:, but it can also be overridden to provide custom views for the identifier. This method may also return a reused view with the same identifier that was no longer available on screen.
|
||||
*/
|
||||
- (id)makeViewWithIdentifier:(CPString)anIdentifier owner:(id)anOwner
|
||||
{
|
||||
if (!anIdentifier)
|
||||
return nil;
|
||||
|
||||
var view,
|
||||
// See if we have some reusable view available
|
||||
reusableViews = _cachedDataViews[anIdentifier];
|
||||
|
||||
if (reusableViews && reusableViews.length)
|
||||
view = reusableViews.pop();
|
||||
// Otherwise see if we have a view in the cib with this identifier
|
||||
else if (_isViewBased)
|
||||
view = [self _unarchiveViewWithIdentifier:anIdentifier owner:anOwner];
|
||||
|
||||
return view;
|
||||
}
|
||||
|
||||
/*!
|
||||
@ignore
|
||||
*/
|
||||
- (CPView)_unarchiveViewWithIdentifier:(CPString)anIdentifier owner:(id)anOwner
|
||||
{
|
||||
var cib = [_archivedDataViews objectForKey:anIdentifier];
|
||||
|
||||
if (!cib && !_unavailable_custom_cibs[anIdentifier])
|
||||
{
|
||||
var bundle = anOwner ? [CPBundle bundleForClass:[anOwner class]] : [CPBundle mainBundle];
|
||||
cib = [[CPCib alloc] initWithCibNamed:anIdentifier bundle:bundle];
|
||||
}
|
||||
|
||||
if (!cib)
|
||||
{
|
||||
_unavailable_custom_cibs[anIdentifier] = YES;
|
||||
return nil;
|
||||
}
|
||||
|
||||
var objects = [],
|
||||
load = [cib instantiateCibWithOwner:anOwner topLevelObjects:objects];
|
||||
|
||||
if (!load)
|
||||
return nil;
|
||||
|
||||
var count = objects.length;
|
||||
|
||||
while (count--)
|
||||
{
|
||||
var obj = objects[count];
|
||||
|
||||
if ([obj isKindOfClass:[CPView class]])
|
||||
{
|
||||
[obj setIdentifier:anIdentifier];
|
||||
[obj setAutoresizingMask:CPViewNotSizable];
|
||||
|
||||
return obj;
|
||||
}
|
||||
}
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (void)_updateIsViewBased
|
||||
{
|
||||
_isViewBased = (_implementedDelegateMethods & CPTableViewDelegate_tableView_dataViewForTableColumn_row_ || _archivedDataViews != nil);
|
||||
}
|
||||
/*!
|
||||
@ignore
|
||||
*/
|
||||
@@ -3554,7 +3778,7 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
|
||||
return;
|
||||
|
||||
// FIXME: yuck!
|
||||
var identifier = aDataView.identifier;
|
||||
var identifier = [aDataView identifier];
|
||||
|
||||
if (!_cachedDataViews[identifier])
|
||||
_cachedDataViews[identifier] = [aDataView];
|
||||
@@ -4133,7 +4357,6 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
|
||||
else
|
||||
_selectionAnchorRow = row;
|
||||
|
||||
|
||||
//set ivars for startTrackingPoint and time...
|
||||
_startTrackingPoint = aPoint;
|
||||
_startTrackingTimestamp = new Date();
|
||||
@@ -4199,7 +4422,6 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
|
||||
else
|
||||
_draggedRowIndexes = [CPIndexSet indexSetWithIndex:row];
|
||||
|
||||
|
||||
//ask the datasource for the data
|
||||
var pboard = [CPPasteboard pasteboardWithName:CPDragPboard];
|
||||
|
||||
@@ -4294,7 +4516,7 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
|
||||
}
|
||||
|
||||
// Accept either tableView:setObjectValue:forTableColumn:row: delegate method, or a binding.
|
||||
if (mouseIsUp
|
||||
if (!_isViewBased && mouseIsUp
|
||||
&& !_trackingPointMovedOutOfClickSlop
|
||||
&& ([[CPApp currentEvent] clickCount] > 1)
|
||||
&& ((_implementedDataSourceMethods & CPTableViewDataSource_tableView_setObjectValue_forTableColumn_row_)
|
||||
@@ -4406,7 +4628,7 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
|
||||
var row = [self _proposedRowAtPoint:theDragPoint],
|
||||
rowRect = [self rectOfRow:row];
|
||||
|
||||
// If there is no (the default) or to little inter cell spacing we create some room for the CPTableViewDropAbove indicator
|
||||
// If there is no (the default) or too little inter-cell spacing we create some room for the CPTableViewDropAbove indicator
|
||||
// This probably doesn't work if the row height is smaller than or around 5.0
|
||||
if ([self intercellSpacing].height < 5.0)
|
||||
rowRect = CGRectInset(rowRect, 0.0, 5.0 - [self intercellSpacing].height);
|
||||
@@ -4426,7 +4648,7 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
|
||||
- (CPInteger)_proposedRowAtPoint:(CGPoint)dragPoint
|
||||
{
|
||||
var row = [self rowAtPoint:dragPoint],
|
||||
// Determine if the mouse is currently closer to this row or the row below it
|
||||
// Determine if the mouse is currently closer to this row or the row below it
|
||||
lowerRow = row + 1,
|
||||
rect = [self rectOfRow:row],
|
||||
bottomPoint = _CGRectGetMaxY(rect),
|
||||
@@ -4525,7 +4747,7 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
|
||||
- (BOOL)prepareForDragOperation:(id)sender
|
||||
{
|
||||
// FIX ME: is there anything else that needs to happen here?
|
||||
// actual validation is called in dragginUpdated:
|
||||
// actual validation is called in draggingUpdated:
|
||||
[_dropOperationFeedbackView removeFromSuperview];
|
||||
|
||||
return (_implementedDataSourceMethods & CPTableViewDataSource_tableView_validateDrop_proposedRow_proposedDropOperation_);
|
||||
@@ -4705,7 +4927,6 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
/*!
|
||||
@ignore
|
||||
*/
|
||||
@@ -4714,6 +4935,78 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
|
||||
return YES;
|
||||
}
|
||||
|
||||
/*!
|
||||
@ignore
|
||||
*/
|
||||
- (id)hitTest:(CGPoint)aPoint
|
||||
{
|
||||
var hit = [super hitTest:aPoint];
|
||||
|
||||
if ([[CPApp currentEvent] type] == CPLeftMouseDown && [hit acceptsFirstResponder] && ![self isRowSelected:[self rowForView:hit]])
|
||||
return self;
|
||||
|
||||
return hit;
|
||||
}
|
||||
|
||||
- (void)_startObservingFirstResponder
|
||||
{
|
||||
[[CPNotificationCenter defaultCenter] addObserver:self selector:@selector(_firstResponderDidChange:) name:_CPWindowDidChangeFirstResponderNotification object:[self window]];
|
||||
}
|
||||
|
||||
- (void)_stopObservingFirstResponder
|
||||
{
|
||||
[[CPNotificationCenter defaultCenter] removeObserver:self name:_CPWindowDidChangeFirstResponderNotification object:[self window]];
|
||||
}
|
||||
|
||||
- (void)_firstResponderDidChange:(CPNotification)aNotification
|
||||
{
|
||||
var responder = [[self window] firstResponder];
|
||||
|
||||
_editingRow = [self rowForView:responder];
|
||||
_editingColumn = [self columnForView:responder];
|
||||
|
||||
if (_editingRow !== CPNotFound && [responder isKindOfClass:[CPTextField class]] && ![responder isBezeled])
|
||||
{
|
||||
[responder setBezeled:YES];
|
||||
[self _registerForEndEditingNote:responder];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)_registerForEndEditingNote:(CPView)aTextField
|
||||
{
|
||||
[[CPNotificationCenter defaultCenter] addObserver:self selector:@selector(_textFieldEditingDidEnd:) name:CPControlTextDidEndEditingNotification object:aTextField];
|
||||
}
|
||||
|
||||
- (void)_unregisterForEndEditingNote:(CPView)aTextField
|
||||
{
|
||||
[[CPNotificationCenter defaultCenter] removeObserver:self name:CPControlTextDidEndEditingNotification object:aTextField];
|
||||
}
|
||||
|
||||
- (void)_textFieldEditingDidEnd:(CPNotification)aNote
|
||||
{
|
||||
// FIXME: When you edit a text field and hit enter without any text modification, the CPControlTextDidEndEditingNotification
|
||||
// is NOT sent. This is a bug in CPTextField or CPControl according to cocoa.
|
||||
var textField = [aNote object];
|
||||
|
||||
[self _unregisterForEndEditingNote:textField];
|
||||
[textField setBezeled:NO];
|
||||
|
||||
var action = [self _disableActionIfExists:textField];
|
||||
[textField resignFirstResponder];
|
||||
[textField setAction:action];
|
||||
}
|
||||
|
||||
- (SEL)_disableActionIfExists:(CPView)aView
|
||||
{
|
||||
// TODO: We disable action to prevent it from beeing sent twice when we resign the FR inside a textEndEditing notification.
|
||||
// Check if this is due to a bug in CPTextField.
|
||||
var action = nil;
|
||||
if ([aView respondsToSelector:@selector(action)] && (action = [aView action]))
|
||||
[aView setAction:nil];
|
||||
|
||||
return action;
|
||||
}
|
||||
|
||||
/*!
|
||||
@ignore
|
||||
*/
|
||||
@@ -4801,11 +5094,10 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
|
||||
if (i >= [self numberOfRows] || i < 0)
|
||||
return;
|
||||
|
||||
|
||||
if (_implementedDelegateMethods & CPTableViewDelegate_tableView_shouldSelectRow_)
|
||||
{
|
||||
|
||||
while (![_delegate tableView:self shouldSelectRow:i] && (i < [self numberOfRows] || i > 0))
|
||||
while (![_delegate tableView:self shouldSelectRow:i] && (i < [self numberOfRows] && i > 0))
|
||||
shouldGoUpward ? i-- : i++; //check to see if the row can be selected if it can't be then see if the next row can be selected
|
||||
|
||||
// If the index still can be selected after the loop then just return.
|
||||
@@ -4855,6 +5147,7 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@implementation CPTableView (Bindings)
|
||||
|
||||
+ (id)_binderClassForBinding:(CPString)aBinding
|
||||
@@ -4908,6 +5201,7 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@implementation CPTableContentBinder : CPBinder
|
||||
{
|
||||
id _content @accessors(property=content);
|
||||
@@ -4925,6 +5219,7 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
|
||||
|
||||
@end
|
||||
|
||||
|
||||
var CPTableViewDataSourceKey = @"CPTableViewDataSourceKey",
|
||||
CPTableViewDelegateKey = @"CPTableViewDelegateKey",
|
||||
CPTableViewHeaderViewKey = @"CPTableViewHeaderViewKey",
|
||||
@@ -4944,7 +5239,8 @@ var CPTableViewDataSourceKey = @"CPTableViewDataSourceKey",
|
||||
CPTableViewAlternatingRowColorsKey = @"CPTableViewAlternatingRowColorsKey",
|
||||
CPTableViewHeaderViewKey = @"CPTableViewHeaderViewKey",
|
||||
CPTableViewCornerViewKey = @"CPTableViewCornerViewKey",
|
||||
CPTableViewAutosaveNameKey = @"CPTableViewAutosaveNameKey";
|
||||
CPTableViewAutosaveNameKey = @"CPTableViewAutosaveNameKey",
|
||||
CPTableViewArchivedReusableViewsKey = @"CPTableViewArchivedReusableViewsKey";
|
||||
|
||||
@implementation CPTableView (CPCoding)
|
||||
|
||||
@@ -4988,6 +5284,11 @@ var CPTableViewDataSourceKey = @"CPTableViewDataSourceKey",
|
||||
|
||||
[self _init];
|
||||
|
||||
if ([aCoder containsValueForKey:CPTableViewArchivedReusableViewsKey])
|
||||
_archivedDataViews = [aCoder decodeObjectForKey:CPTableViewArchivedReusableViewsKey];
|
||||
|
||||
[self _updateIsViewBased];
|
||||
|
||||
[self viewWillMoveToSuperview:[self superview]];
|
||||
|
||||
// Do this as late as possible to make sure the tableview is fully configured
|
||||
@@ -5028,10 +5329,14 @@ var CPTableViewDataSourceKey = @"CPTableViewDataSourceKey",
|
||||
[aCoder encodeObject:_headerView forKey:CPTableViewHeaderViewKey];
|
||||
|
||||
[aCoder encodeObject:_autosaveName forKey:CPTableViewAutosaveNameKey];
|
||||
|
||||
if (_archivedDataViews)
|
||||
[aCoder encodeObject:_archivedDataViews forKey:CPTableViewArchivedReusableViewsKey];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@implementation CPIndexSet (tableview)
|
||||
|
||||
- (void)removeMatches:(CPIndexSet)otherSet
|
||||
@@ -5162,6 +5467,7 @@ var CPTableViewDataSourceKey = @"CPTableViewDataSourceKey",
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@implementation _CPColumnDragView : CPView
|
||||
{
|
||||
CPColor _lineColor;
|
||||
@@ -5199,3 +5505,47 @@ var CPTableViewDataSourceKey = @"CPTableViewDataSourceKey",
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@implementation CPTableCellView : CPView
|
||||
{
|
||||
id _objectValue @accessors(property=objectValue);
|
||||
|
||||
CPTextField _textField @accessors(property=textField);
|
||||
CPImageView _imageView @accessors(property=imageView);
|
||||
}
|
||||
|
||||
- (void)awakeFromCib
|
||||
{
|
||||
[self setThemeState:CPThemeStateTableDataView];
|
||||
}
|
||||
|
||||
- (void)setThemeState:(CPThemeState)aState
|
||||
{
|
||||
[super setThemeState:aState];
|
||||
[self recursivelyPerformSelector:@selector(setThemeState:) withObject:aState startingFrom:self];
|
||||
}
|
||||
|
||||
- (void)unsetThemeState:(CPThemeState)aState
|
||||
{
|
||||
[super unsetThemeState:aState];
|
||||
[self recursivelyPerformSelector:@selector(unsetThemeState:) withObject:aState startingFrom:self];
|
||||
}
|
||||
|
||||
- (void)recursivelyPerformSelector:(SEL)selector withObject:(id)anObject startingFrom:(id)aView
|
||||
{
|
||||
[[aView subviews] enumerateObjectsUsingBlock:function(view, idx)
|
||||
{
|
||||
[view performSelector:selector withObject:anObject];
|
||||
|
||||
if (![view isKindOfClass:[self class]]) // Avoid infinite loop if a subview is a CPTableCellView.
|
||||
[self recursivelyPerformSelector:selector withObject:anObject startingFrom:view];
|
||||
}];
|
||||
}
|
||||
|
||||
- (CPString)description
|
||||
{
|
||||
return "<" + [self className] + " 0x" + [CPString stringWithHash:[self UID]] + " identifier=" + [self identifier] + ">";
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
+23
-11
@@ -20,8 +20,6 @@
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#import "../Foundation/Ref.h"
|
||||
|
||||
@import "CPControl.j"
|
||||
@import "CPStringDrawing.j"
|
||||
@import "CPCompatibility.j"
|
||||
@@ -72,15 +70,15 @@ function CPTextFieldBlurFunction(anEvent, owner, domElement, inputElement, resig
|
||||
}, 0.0);
|
||||
}
|
||||
|
||||
CPTextFieldHandleBlur(anEvent, AT_REF(owner));
|
||||
AT_DEREF(didBlurRef, YES);
|
||||
CPTextFieldHandleBlur(anEvent, @ref(owner));
|
||||
@deref(didBlurRef) = YES;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function CPTextFieldHandleBlur(anEvent, ownerRef)
|
||||
{
|
||||
AT_DEREF(ownerRef, nil);
|
||||
@deref(ownerRef) = nil;
|
||||
|
||||
[[CPRunLoop currentRunLoop] limitDateForMode:CPDefaultRunLoopMode];
|
||||
}
|
||||
@@ -206,8 +204,11 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
|
||||
|
||||
+ (id)themeAttributes
|
||||
{
|
||||
return [CPDictionary dictionaryWithObjects:[_CGInsetMakeZero(), _CGInsetMake(1.0, 0.0, 0.0, 0.0), [CPNull null]]
|
||||
forKeys:[@"bezel-inset", @"content-inset", @"bezel-color"]];
|
||||
return @{
|
||||
@"bezel-inset": _CGInsetMakeZero(),
|
||||
@"content-inset": _CGInsetMake(1.0, 0.0, 0.0, 0.0),
|
||||
@"bezel-color": [CPNull null],
|
||||
};
|
||||
}
|
||||
|
||||
/* @ignore */
|
||||
@@ -233,7 +234,7 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
|
||||
CPTextFieldInputOwner._DOMElement,
|
||||
CPTextFieldDOMInputElement,
|
||||
CPTextFieldInputResigning,
|
||||
AT_REF(CPTextFieldInputDidBlur));
|
||||
@ref(CPTextFieldInputDidBlur));
|
||||
};
|
||||
|
||||
if (CPFeatureIsCompatible(CPInputOnInputEventFeature))
|
||||
@@ -347,6 +348,11 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
|
||||
// We only allow first responder status if the field is editable and enabled.
|
||||
if (!shouldBeEditable && [[self window] firstResponder] === self)
|
||||
[[self window] makeFirstResponder:nil];
|
||||
|
||||
if (shouldBeEditable)
|
||||
[self setThemeState:CPThemeStateEditable];
|
||||
else
|
||||
[self unsetThemeState:CPThemeStateEditable];
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -770,7 +776,7 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
|
||||
|
||||
var error = @"";
|
||||
|
||||
if ([self _setStringValue:aValue isNewValue:NO errorDescription:AT_REF(error)] === NO)
|
||||
if ([self _setStringValue:aValue isNewValue:NO errorDescription:@ref(error)] === NO)
|
||||
{
|
||||
var acceptInvalidValue = NO;
|
||||
|
||||
@@ -1037,7 +1043,7 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
|
||||
{
|
||||
var object = nil;
|
||||
|
||||
if ([formatter getObjectValue:AT_REF(object) forString:aValue errorDescription:anError])
|
||||
if ([formatter getObjectValue:@ref(object) forString:aValue errorDescription:anError])
|
||||
objectValue = object;
|
||||
else
|
||||
{
|
||||
@@ -1076,7 +1082,7 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
|
||||
|
||||
// Formatting failed, get an "empty" object by formatting an empty string.
|
||||
// If that fails, the value is undefined.
|
||||
if ([formatter getObjectValue:AT_REF(value) forString:@"" errorDescription:nil] === NO)
|
||||
if ([formatter getObjectValue:@ref(value) forString:@"" errorDescription:nil] === NO)
|
||||
value = undefined;
|
||||
|
||||
[super setObjectValue:value];
|
||||
@@ -1652,6 +1658,9 @@ var CPTextFieldIsEditableKey = "CPTextFieldIsEditableKey",
|
||||
|
||||
- (void)setValue:(id)aValue forBinding:(CPString)aBinding
|
||||
{
|
||||
if (!aValue || (aValue.isa && [aValue isMemberOfClass:CPNull]))
|
||||
[_source setPlaceholderString:[self _placeholderForMarker:CPNullMarker]];
|
||||
|
||||
[_source setObjectValue:aValue];
|
||||
}
|
||||
|
||||
@@ -1667,6 +1676,9 @@ var CPTextFieldIsEditableKey = "CPTextFieldIsEditableKey",
|
||||
|
||||
- (void)setValue:(id)aValue forBinding:(CPString)aBinding
|
||||
{
|
||||
if (!aValue || (aValue.isa && [aValue isMemberOfClass:CPNull]))
|
||||
[_source setPlaceholderString:[self _placeholderForMarker:CPNullMarker]];
|
||||
|
||||
[_source setObjectValue:aValue];
|
||||
}
|
||||
|
||||
|
||||
+7
-7
@@ -85,7 +85,7 @@ var CPThemesByName = { },
|
||||
if (self)
|
||||
{
|
||||
_name = aName;
|
||||
_attributes = [CPDictionary dictionary];
|
||||
_attributes = @{};
|
||||
|
||||
CPThemesByName[_name] = self;
|
||||
}
|
||||
@@ -270,7 +270,7 @@ var CPThemesByName = { },
|
||||
|
||||
if (!attributes)
|
||||
{
|
||||
attributes = [CPDictionary dictionary];
|
||||
attributes = @{};
|
||||
|
||||
[_attributes setObject:attributes forKey:aClass];
|
||||
}
|
||||
@@ -443,7 +443,7 @@ CPThemeStateKeyWindow = CPThemeState("keyWindow");
|
||||
_cache = { };
|
||||
_name = aName;
|
||||
_defaultValue = aDefaultValue;
|
||||
_values = [CPDictionary dictionary];
|
||||
_values = @{};
|
||||
}
|
||||
|
||||
return self;
|
||||
@@ -474,9 +474,9 @@ CPThemeStateKeyWindow = CPThemeState("keyWindow");
|
||||
_cache = {};
|
||||
|
||||
if (aValue === undefined || aValue === nil)
|
||||
_values = [CPDictionary dictionary];
|
||||
_values = @{};
|
||||
else
|
||||
_values = [CPDictionary dictionaryWithObject:aValue forKey:String(CPThemeStateNormal)];
|
||||
_values = @{ String(CPThemeStateNormal): aValue };
|
||||
}
|
||||
|
||||
- (void)setValue:(id)aValue forState:(CPThemeState)aState
|
||||
@@ -585,7 +585,7 @@ CPThemeStateKeyWindow = CPThemeState("keyWindow");
|
||||
|
||||
_name = [aCoder decodeObjectForKey:@"name"];
|
||||
_defaultValue = [aCoder decodeObjectForKey:@"defaultValue"];
|
||||
_values = [CPDictionary dictionary];
|
||||
_values = @{};
|
||||
|
||||
if ([aCoder containsValueForKey:@"value"])
|
||||
{
|
||||
@@ -633,7 +633,7 @@ CPThemeStateKeyWindow = CPThemeState("keyWindow");
|
||||
}
|
||||
else
|
||||
{
|
||||
var encodedValues = [CPDictionary dictionary];
|
||||
var encodedValues = @{};
|
||||
|
||||
while (count--)
|
||||
{
|
||||
|
||||
@@ -21,7 +21,6 @@
|
||||
*/
|
||||
|
||||
#import "../Foundation/CPRange.h"
|
||||
#import "../Foundation/Ref.h"
|
||||
|
||||
@import <Foundation/CPCharacterSet.j>
|
||||
@import <Foundation/CPIndexSet.j>
|
||||
@@ -101,7 +100,7 @@ CPTokenFieldDeleteButtonType = 1;
|
||||
|
||||
+ (id)themeAttributes
|
||||
{
|
||||
return [CPDictionary dictionaryWithObject:_CGInsetMakeZero() forKey:@"editor-inset"];
|
||||
return @{ @"editor-inset": _CGInsetMakeZero() };
|
||||
}
|
||||
|
||||
- (id)initWithFrame:(CGRect)frame
|
||||
@@ -667,7 +666,7 @@ CPTokenFieldDeleteButtonType = 1;
|
||||
CPTokenFieldInputOwner ? [CPTokenFieldInputOwner._tokenScrollView documentView]._DOMElement : nil,
|
||||
CPTokenFieldDOMInputElement,
|
||||
CPTokenFieldInputResigning,
|
||||
AT_REF(CPTokenFieldInputDidBlur));
|
||||
@ref(CPTokenFieldInputDidBlur));
|
||||
};
|
||||
|
||||
// FIXME make this not onblur
|
||||
|
||||
+14
-22
@@ -118,8 +118,8 @@ var CPToolbarsByIdentifier = nil,
|
||||
if (self !== [CPToolbar class])
|
||||
return;
|
||||
|
||||
CPToolbarsByIdentifier = [CPDictionary dictionary];
|
||||
CPToolbarConfigurationsByIdentifier = [CPDictionary dictionary];
|
||||
CPToolbarsByIdentifier = @{};
|
||||
CPToolbarConfigurationsByIdentifier = @{};
|
||||
}
|
||||
|
||||
/* @ignore */
|
||||
@@ -230,7 +230,7 @@ var CPToolbarsByIdentifier = nil,
|
||||
- (void)_setWindow:(CPWindow)aWindow
|
||||
{
|
||||
if (_window)
|
||||
[[CPNotificationCenter defaultCenter] removeObserver:self object:_window];
|
||||
[[CPNotificationCenter defaultCenter] removeObserver:self name:_CPWindowDidChangeFirstResponderNotification object:_window];
|
||||
|
||||
_window = aWindow;
|
||||
|
||||
@@ -605,25 +605,17 @@ var _CPToolbarItemInfoMake = function(anIndex, aView, aLabel, aMinWidth)
|
||||
|
||||
+ (id)themeAttributes
|
||||
{
|
||||
return [CPDictionary dictionaryWithObjects:[10.0,
|
||||
20.0,
|
||||
[CPNull null],
|
||||
[CPNull null],
|
||||
_CGInsetMake(4.0, 4.0, 4.0, 10),
|
||||
59.0,
|
||||
46.0,
|
||||
[CPNull null],
|
||||
CGRectMake(0.0, 0.0, 2.0, 32.0)]
|
||||
forKeys:[
|
||||
@"item-margin",
|
||||
@"extra-item-width",
|
||||
@"extra-item-extra-image",
|
||||
@"extra-item-extra-alternate-image",
|
||||
@"content-inset",
|
||||
@"regular-size-height",
|
||||
@"small-size-height",
|
||||
@"image-item-separator-color",
|
||||
@"image-item-separator-size"]];
|
||||
return @{
|
||||
@"item-margin": 10.0,
|
||||
@"extra-item-width": 20.0,
|
||||
@"extra-item-extra-image": [CPNull null],
|
||||
@"extra-item-extra-alternate-image": [CPNull null],
|
||||
@"content-inset": _CGInsetMake(4.0, 4.0, 4.0, 10),
|
||||
@"regular-size-height": 59.0,
|
||||
@"small-size-height": 46.0,
|
||||
@"image-item-separator-color": [CPNull null],
|
||||
@"image-item-separator-size": CGRectMake(0.0, 0.0, 2.0, 32.0),
|
||||
};
|
||||
}
|
||||
|
||||
- (id)initWithFrame:(CGRect)aFrame
|
||||
|
||||
+29
-6
@@ -134,6 +134,7 @@ var CPViewFlags = { },
|
||||
CPGraphicsContext _graphicsContext;
|
||||
|
||||
int _tag;
|
||||
CPString _identifier @accessors(property=identifier);
|
||||
|
||||
CGRect _frame;
|
||||
CGRect _bounds;
|
||||
@@ -475,6 +476,10 @@ var CPViewFlags = { },
|
||||
{
|
||||
if (aSubview === self)
|
||||
[CPException raise:CPInvalidArgumentException reason:"can't add a view as a subview of itself"];
|
||||
#if DEBUG
|
||||
if (!aSubview._superview && _subviews.indexOf(aSubview) !== CPNotFound)
|
||||
[CPException raise:CPInvalidArgumentException reason:"can't insert a subview in duplicate (probably partially decoded)"];
|
||||
#endif
|
||||
|
||||
// We will have to adjust the z-index of all views starting at this index.
|
||||
var count = _subviews.length;
|
||||
@@ -565,10 +570,10 @@ var CPViewFlags = { },
|
||||
|
||||
[_superview willRemoveSubview:self];
|
||||
|
||||
[_superview._subviews removeObject:self];
|
||||
[_superview._subviews removeObjectIdenticalTo:self];
|
||||
|
||||
#if PLATFORM(DOM)
|
||||
CPDOMDisplayServerRemoveChild(_superview._DOMElement, _DOMElement);
|
||||
CPDOMDisplayServerRemoveChild(_superview._DOMElement, _DOMElement);
|
||||
#endif
|
||||
_superview = nil;
|
||||
|
||||
@@ -1365,6 +1370,7 @@ var CPViewFlags = { },
|
||||
}
|
||||
else
|
||||
{
|
||||
[self setNeedsDisplay:YES];
|
||||
[self _notifyViewDidUnhide];
|
||||
}
|
||||
}
|
||||
@@ -1500,7 +1506,7 @@ var CPViewFlags = { },
|
||||
|
||||
/*!
|
||||
Returns whether the receiver should be sent a \c -mouseDown: message for \c anEvent.<br/>
|
||||
Returns \c YES by default.
|
||||
Returns \c NO by default.
|
||||
@return \c YES, if the view object accepts first mouse-down event. \c NO, otherwise.
|
||||
*/
|
||||
- (BOOL)acceptsFirstMouse:(CPEvent)anEvent
|
||||
@@ -2816,7 +2822,7 @@ setBoundsOrigin:
|
||||
|
||||
- (CPDictionary)_themeAttributeDictionary
|
||||
{
|
||||
var dictionary = [CPDictionary dictionary];
|
||||
var dictionary = @{};
|
||||
|
||||
if (_themeAttributes)
|
||||
{
|
||||
@@ -3009,7 +3015,8 @@ var CPViewAutoresizingMaskKey = @"CPViewAutoresizingMask",
|
||||
CPViewThemeStateKey = @"CPViewThemeStateKey",
|
||||
CPViewWindowKey = @"CPViewWindowKey",
|
||||
CPViewNextKeyViewKey = @"CPViewNextKeyViewKey",
|
||||
CPViewPreviousKeyViewKey = @"CPViewPreviousKeyViewKey";
|
||||
CPViewPreviousKeyViewKey = @"CPViewPreviousKeyViewKey",
|
||||
CPReuseIdentifierKey = @"CPReuseIdentifierKey";
|
||||
|
||||
@implementation CPView (CPCoding)
|
||||
|
||||
@@ -3038,11 +3045,24 @@ var CPViewAutoresizingMaskKey = @"CPViewAutoresizingMask",
|
||||
{
|
||||
// We have to manually check because it may be 0, so we can't use ||
|
||||
_tag = [aCoder containsValueForKey:CPViewTagKey] ? [aCoder decodeIntForKey:CPViewTagKey] : -1;
|
||||
_identifier = [aCoder decodeObjectForKey:CPReuseIdentifierKey];
|
||||
|
||||
_window = [aCoder decodeObjectForKey:CPViewWindowKey];
|
||||
_subviews = [aCoder decodeObjectForKey:CPViewSubviewsKey] || [];
|
||||
_superview = [aCoder decodeObjectForKey:CPViewSuperviewKey];
|
||||
|
||||
// We have to manually add the subviews so that they will receive
|
||||
// viewWillMoveToSuperview: and viewDidMoveToSuperview:
|
||||
_subviews = [];
|
||||
|
||||
var subviews = [aCoder decodeObjectForKey:CPViewSubviewsKey] || [];
|
||||
|
||||
for (var i = 0, count = [subviews count]; i < count; ++i)
|
||||
{
|
||||
// addSubview won't do anything if the superview is already self, so clear it
|
||||
subviews[i]._superview = nil;
|
||||
[self addSubview:subviews[i]];
|
||||
}
|
||||
|
||||
// FIXME: Should we encode/decode this?
|
||||
_registeredDraggedTypes = [CPSet set];
|
||||
_registeredDraggedTypesArray = [];
|
||||
@@ -3188,6 +3208,9 @@ var CPViewAutoresizingMaskKey = @"CPViewAutoresizingMask",
|
||||
for (var attributeName in _themeAttributes)
|
||||
if (_themeAttributes.hasOwnProperty(attributeName))
|
||||
CPThemeAttributeEncode(aCoder, _themeAttributes[attributeName]);
|
||||
|
||||
if (_identifier)
|
||||
[aCoder encodeObject:_identifier forKey:CPReuseIdentifierKey];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -59,8 +59,12 @@ CPViewAnimationFadeOutEffect = @"CPViewAnimationFadeOutEffect";
|
||||
|
||||
For example:
|
||||
<pre>
|
||||
var animation = [CPDictionary dictionaryWithObjects:[myViewToAnimate, aStartFrame, anEndFrame, CPViewAnimationFadeInEffect]
|
||||
forKeys:[CPViewAnimationTargetKey, CPViewAnimationStartFrameKey, CPViewAnimationEndFrameKey, CPViewAnimationEffectKey]];
|
||||
var animation = @{
|
||||
CPViewAnimationTargetKey: myViewToAnimate,
|
||||
CPViewAnimationStartFrameKey: aStartFrame,
|
||||
CPViewAnimationEndFrameKey: anEndFrame,
|
||||
CPViewAnimationEffectKey: CPViewAnimationFadeInEffect,
|
||||
};
|
||||
</pre>
|
||||
|
||||
If you pass nil instead of an array of dictionaries you should later call setViewAnimations:.
|
||||
|
||||
@@ -85,7 +85,7 @@ var CPViewControllerCachedCibs;
|
||||
if (self !== [CPViewController class])
|
||||
return;
|
||||
|
||||
CPViewControllerCachedCibs = [CPDictionary dictionary];
|
||||
CPViewControllerCachedCibs = @{};
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -103,7 +103,7 @@ var CPViewControllerCachedCibs;
|
||||
|
||||
- (id)initWithCibName:(CPString)aCibNameOrNil bundle:(CPBundle)aCibBundleOrNil owner:(id)anOwner
|
||||
{
|
||||
return [self initWithCibName:aCibNameOrNil bundle:aCibBundleOrNil externalNameTable:[CPDictionary dictionaryWithObject:anOwner forKey:CPCibOwner]];
|
||||
return [self initWithCibName:aCibNameOrNil bundle:aCibBundleOrNil externalNameTable:@{ CPCibOwner: anOwner }];
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -128,7 +128,7 @@ var CPViewControllerCachedCibs;
|
||||
// Don't load the cib until someone actually requests the view. The user may just be intending to use setView:.
|
||||
_cibName = aCibNameOrNil;
|
||||
_cibBundle = aCibBundleOrNil || [CPBundle mainBundle];
|
||||
_cibExternalNameTable = anExternalNameTable || [CPDictionary dictionaryWithObject:self forKey:CPCibOwner];
|
||||
_cibExternalNameTable = anExternalNameTable || @{ CPCibOwner: self };
|
||||
|
||||
_isLoading = NO;
|
||||
_isLazy = NO;
|
||||
@@ -298,7 +298,7 @@ var CPViewControllerViewKey = @"CPViewControllerViewKey",
|
||||
var bundlePath = [aCoder decodeObjectForKey:CPViewControllerBundleKey];
|
||||
_cibBundle = bundlePath ? [CPBundle bundleWithPath:bundlePath] : [CPBundle mainBundle];
|
||||
|
||||
_cibExternalNameTable = [CPDictionary dictionaryWithObject:self forKey:CPCibOwner];
|
||||
_cibExternalNameTable = @{ CPCibOwner: self };
|
||||
_isLazy = YES;
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -962,7 +962,7 @@ CPWebViewAppKitScrollMaxPollCount = 3;
|
||||
{
|
||||
try
|
||||
{
|
||||
return _window[methodName].apply(args);
|
||||
return _window[methodName].apply(_window, args);
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
|
||||
+21
-23
@@ -297,15 +297,16 @@ CPTexturedBackgroundWindowMask
|
||||
|
||||
[self setLevel:CPNormalWindowLevel];
|
||||
|
||||
_minSize = _CGSizeMake(0.0, 0.0);
|
||||
_maxSize = _CGSizeMake(1000000.0, 1000000.0);
|
||||
|
||||
// Create our border view which is the actual root of our view hierarchy.
|
||||
_windowView = [[windowViewClass alloc] initWithFrame:_CGRectMake(0.0, 0.0, _CGRectGetWidth(_frame), _CGRectGetHeight(_frame)) styleMask:aStyleMask];
|
||||
|
||||
[_windowView _setWindow:self];
|
||||
[_windowView setNextResponder:self];
|
||||
|
||||
// Size calculation needs _windowView
|
||||
_minSize = [self _calculateMinSizeForProposedSize:_CGSizeMake(0.0, 0.0)];
|
||||
_maxSize = _CGSizeMake(1000000.0, 1000000.0);
|
||||
|
||||
[self setMovableByWindowBackground:aStyleMask & CPHUDBackgroundWindowMask];
|
||||
|
||||
// Create a generic content view.
|
||||
@@ -393,7 +394,7 @@ CPTexturedBackgroundWindowMask
|
||||
return _CPDocModalWindowView;
|
||||
|
||||
else if (aStyleMask & _CPModalWindowMask)
|
||||
return _CPModalWindowView
|
||||
return _CPModalWindowView;
|
||||
|
||||
return _CPStandardWindowView;
|
||||
}
|
||||
@@ -630,20 +631,6 @@ CPTexturedBackgroundWindowMask
|
||||
return _CGRectMakeCopy(_frame);
|
||||
}
|
||||
|
||||
/*!
|
||||
Sets the window's frame rectangle. Also tells the window whether it should animate
|
||||
the resize operation, and redraw itself if necessary.
|
||||
@param aFrame the new size and location for the window
|
||||
@param shouldDisplay whether the window should redraw its views
|
||||
@param shouldAnimate whether the window resize should be animated.
|
||||
*/
|
||||
- (void)_setClippedFrame:(CGRect)aFrame display:(BOOL)shouldDisplay animate:(BOOL)shouldAnimate
|
||||
{
|
||||
aFrame.size.width = MIN(MAX(aFrame.size.width, _minSize.width), _maxSize.width)
|
||||
aFrame.size.height = MIN(MAX(aFrame.size.height, _minSize.height), _maxSize.height);
|
||||
[self setFrame:aFrame display:shouldDisplay animate:shouldAnimate];
|
||||
}
|
||||
|
||||
/*!
|
||||
Sets the frame of the window.
|
||||
|
||||
@@ -751,7 +738,7 @@ CPTexturedBackgroundWindowMask
|
||||
*/
|
||||
- (void)setFrame:(CGRect)aFrame display:(BOOL)shouldDisplay
|
||||
{
|
||||
[self _setClippedFrame:aFrame display:shouldDisplay animate:NO];
|
||||
[self setFrame:aFrame display:shouldDisplay animate:NO];
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -760,7 +747,7 @@ CPTexturedBackgroundWindowMask
|
||||
*/
|
||||
- (void)setFrame:(CGRect)aFrame
|
||||
{
|
||||
[self _setClippedFrame:aFrame display:YES animate:NO];
|
||||
[self setFrame:aFrame display:YES animate:NO];
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -769,7 +756,7 @@ CPTexturedBackgroundWindowMask
|
||||
*/
|
||||
- (void)setFrameOrigin:(CGPoint)anOrigin
|
||||
{
|
||||
[self _setClippedFrame:_CGRectMake(anOrigin.x, anOrigin.y, _CGRectGetWidth(_frame), _CGRectGetHeight(_frame)) display:YES animate:NO];
|
||||
[self setFrame:_CGRectMake(anOrigin.x, anOrigin.y, _CGRectGetWidth(_frame), _CGRectGetHeight(_frame)) display:YES animate:NO];
|
||||
|
||||
// reposition sheet
|
||||
if ([self attachedSheet])
|
||||
@@ -782,7 +769,7 @@ CPTexturedBackgroundWindowMask
|
||||
*/
|
||||
- (void)setFrameSize:(CGSize)aSize
|
||||
{
|
||||
[self _setClippedFrame:_CGRectMake(_CGRectGetMinX(_frame), _CGRectGetMinY(_frame), aSize.width, aSize.height) display:YES animate:NO];
|
||||
[self setFrame:_CGRectMake(_CGRectGetMinX(_frame), _CGRectGetMinY(_frame), aSize.width, aSize.height) display:YES animate:NO];
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -1068,6 +1055,8 @@ CPTexturedBackgroundWindowMask
|
||||
/*!
|
||||
Sets the window's minimum size. If the provided
|
||||
size is the same as the current minimum size, the method simply returns.
|
||||
The height is pinned to the difference in height between the frame rect
|
||||
and content rect, to account for a title bar + toolbar.
|
||||
@param aSize the new minimum size for the window
|
||||
*/
|
||||
- (void)setMinSize:(CGSize)aSize
|
||||
@@ -1075,7 +1064,7 @@ CPTexturedBackgroundWindowMask
|
||||
if (_CGSizeEqualToSize(_minSize, aSize))
|
||||
return;
|
||||
|
||||
_minSize = _CGSizeMakeCopy(aSize);
|
||||
_minSize = [self _calculateMinSizeForProposedSize:aSize];
|
||||
|
||||
var size = _CGSizeMakeCopy([self frame].size),
|
||||
needsFrameChange = NO;
|
||||
@@ -1104,6 +1093,15 @@ CPTexturedBackgroundWindowMask
|
||||
return _minSize;
|
||||
}
|
||||
|
||||
/*! @ignore */
|
||||
- (CGSize)_calculateMinSizeForProposedSize:(CGSize)proposedSize
|
||||
{
|
||||
var contentFrame = [self contentRectForFrameRect:_frame],
|
||||
minHeight = _CGRectGetHeight(_frame) - _CGRectGetHeight(contentFrame);
|
||||
|
||||
return _CGSizeMake(MAX(proposedSize.width, 0), MAX(proposedSize.height, minHeight));
|
||||
}
|
||||
|
||||
/*!
|
||||
Sets the window's maximum size. If the provided
|
||||
size is the same as the current maximum size,
|
||||
|
||||
@@ -34,8 +34,9 @@
|
||||
|
||||
+ (id)themeAttributes
|
||||
{
|
||||
return [CPDictionary dictionaryWithObjects:[[CPColor grayColor]]
|
||||
forKeys:[@"toolbar-background-color"]];
|
||||
return @{
|
||||
@"toolbar-background-color": [CPColor grayColor],
|
||||
};
|
||||
}
|
||||
|
||||
- (void)setShowsResizeIndicator:(BOOL)shouldShowResizeIndicator
|
||||
|
||||
@@ -36,8 +36,21 @@
|
||||
|
||||
+ (id)themeAttributes
|
||||
{
|
||||
return [CPDictionary dictionaryWithObjects:[[CPColor whiteColor], 8]
|
||||
forKeys:[ @"body-color", @"height-shadow"]];
|
||||
return @{
|
||||
@"body-color": [CPColor whiteColor],
|
||||
@"height-shadow": 8,
|
||||
};
|
||||
}
|
||||
|
||||
+ (CGRect)contentRectForFrameRect:(CGRect)aFrameRect
|
||||
{
|
||||
/*
|
||||
This window view class draws a frame.
|
||||
So we have to inset the content rect to be inside the frame.
|
||||
*/
|
||||
var contentRect = [super contentRectForFrameRect:aFrameRect];
|
||||
|
||||
return _CGRectInset(contentRect, 1.0, 1.0);
|
||||
}
|
||||
|
||||
- (id)initWithFrame:(CGRect)aFrame styleMask:(unsigned)aStyleMask
|
||||
@@ -65,12 +78,12 @@
|
||||
|
||||
- (CGRect)contentRectForFrameRect:(CGRect)aFrameRect
|
||||
{
|
||||
return aFrameRect;
|
||||
return [[self class] contentRectForFrameRect:aFrameRect];
|
||||
}
|
||||
|
||||
- (CGRect)frameRectForContentRect:(CGRect)aContentRect
|
||||
{
|
||||
return aContentRect;
|
||||
return [[self class] frameRectForContentRect:aContentRect];
|
||||
}
|
||||
|
||||
- (void)_enableSheet:(BOOL)enable
|
||||
|
||||
@@ -36,6 +36,22 @@
|
||||
return @"hud-window-view";
|
||||
}
|
||||
|
||||
+ (CGRect)contentRectForFrameRect:(CGRect)aFrameRect
|
||||
{
|
||||
/*
|
||||
This window view class draws a frame.
|
||||
So we have to inset the content rect to be inside the frame.
|
||||
The top coordinate has already been adjusted by _CPTitleableWindowView.
|
||||
*/
|
||||
var contentRect = [super contentRectForFrameRect:aFrameRect];
|
||||
|
||||
contentRect.origin.x += 1;
|
||||
contentRect.size.width -= 2;
|
||||
contentRect.size.height -= 1;
|
||||
|
||||
return contentRect;
|
||||
}
|
||||
|
||||
- (CGRect)contentRectForFrameRect:(CGRect)aFrameRect
|
||||
{
|
||||
var contentRect = [[self class] contentRectForFrameRect:aFrameRect];
|
||||
|
||||
@@ -56,14 +56,12 @@ var _CPPopoverWindowViewDefaultCursorSize = _CGSizeMake(16, 10),
|
||||
|
||||
+ (id)themeAttributes
|
||||
{
|
||||
return [CPDictionary dictionaryWithObjects:[[CPNull null],
|
||||
[CPNull null],
|
||||
[CPNull null],
|
||||
[CPNull null]]
|
||||
forKeys:[@"background-gradient",
|
||||
@"background-gradient-hud",
|
||||
@"stroke-color",
|
||||
@"stroke-color-hud"]];
|
||||
return @{
|
||||
@"background-gradient": [CPNull null],
|
||||
@"background-gradient-hud": [CPNull null],
|
||||
@"stroke-color": [CPNull null],
|
||||
@"stroke-color-hud": [CPNull null],
|
||||
};
|
||||
}
|
||||
|
||||
/*!
|
||||
|
||||
@@ -43,8 +43,7 @@
|
||||
|
||||
+ (id)themeAttributes
|
||||
{
|
||||
return [CPDictionary dictionaryWithObjects:[]
|
||||
forKeys:[]];
|
||||
return @{};
|
||||
}
|
||||
|
||||
- (void)layoutSubviews
|
||||
|
||||
@@ -25,12 +25,13 @@
|
||||
|
||||
@class _CPDocModalWindowView
|
||||
|
||||
var _CPStandardWindowViewDividerViewHeight = 1.0;
|
||||
|
||||
@implementation _CPTexturedWindowHeadView : CPView
|
||||
{
|
||||
_CPWindowView _parentView;
|
||||
CPView _gradientView;
|
||||
CPView _solidView;
|
||||
CPView _dividerView;
|
||||
}
|
||||
|
||||
+ (CPString)defaultThemeClass
|
||||
@@ -40,8 +41,7 @@
|
||||
|
||||
+ (id)themeAttributes
|
||||
{
|
||||
return [CPDictionary dictionaryWithObjects:[]
|
||||
forKeys:[]];
|
||||
return @{};
|
||||
}
|
||||
|
||||
- (id)initWithFrame:(CGRect)aFrame windowView:(_CPWindowView)parentView
|
||||
@@ -51,10 +51,10 @@
|
||||
if (self)
|
||||
{
|
||||
_parentView = parentView;
|
||||
_gradientView = [[CPView alloc] initWithFrame:CGRectMakeZero()];
|
||||
_gradientView = [[CPView alloc] initWithFrame:_CGRectMakeZero()];
|
||||
[self addSubview:_gradientView];
|
||||
|
||||
_solidView = [[CPView alloc] initWithFrame:CGRectMakeZero()];
|
||||
_solidView = [[CPView alloc] initWithFrame:_CGRectMakeZero()];
|
||||
[self addSubview:_solidView];
|
||||
}
|
||||
|
||||
@@ -68,10 +68,10 @@
|
||||
var gradientHeight = [[CPTheme defaultTheme] valueForAttributeWithName:@"gradient-height" forClass:_CPStandardWindowView],
|
||||
bounds = [self bounds];
|
||||
|
||||
[_gradientView setFrame:CGRectMake(0.0, 0.0, CGRectGetWidth(bounds), gradientHeight)];
|
||||
[_gradientView setFrame:_CGRectMake(0.0, 0.0, _CGRectGetWidth(bounds), gradientHeight)];
|
||||
[_gradientView setBackgroundColor:[[CPTheme defaultTheme] valueForAttributeWithName:@"bezel-head-color" inState:[_parentView themeState] forClass:_CPStandardWindowView]];
|
||||
|
||||
[_solidView setFrame:CGRectMake(0.0, gradientHeight, CGRectGetWidth(bounds), CGRectGetHeight(bounds) - gradientHeight)];
|
||||
[_solidView setFrame:_CGRectMake(0.0, gradientHeight, _CGRectGetWidth(bounds), _CGRectGetHeight(bounds) - gradientHeight)];
|
||||
[_solidView setBackgroundColor:[[CPTheme defaultTheme] valueForAttributeWithName:@"solid-color" forClass:_CPStandardWindowView]];
|
||||
}
|
||||
|
||||
@@ -79,8 +79,8 @@
|
||||
{
|
||||
var bounds = [self bounds];
|
||||
|
||||
[_gradientView setFrameSize:CGSizeMake(CGRectGetWidth(bounds), [[CPTheme defaultTheme] valueForAttributeWithName:@"gradient-height" forClass:_CPStandardWindowView])];
|
||||
[_solidView setFrameSize:CGSizeMake(CGRectGetWidth(bounds), CGRectGetHeight(bounds) - [[CPTheme defaultTheme] valueForAttributeWithName:@"gradient-height" forClass:_CPStandardWindowView])];
|
||||
[_gradientView setFrameSize:_CGSizeMake(_CGRectGetWidth(bounds), [[CPTheme defaultTheme] valueForAttributeWithName:@"gradient-height" forClass:_CPStandardWindowView])];
|
||||
[_solidView setFrameSize:_CGSizeMake(_CGRectGetWidth(bounds), _CGRectGetHeight(bounds) - [[CPTheme defaultTheme] valueForAttributeWithName:@"gradient-height" forClass:_CPStandardWindowView])];
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -106,19 +106,40 @@
|
||||
|
||||
+ (id)themeAttributes
|
||||
{
|
||||
return [CPDictionary dictionaryWithObjects:[[CPNull null], [CPNull null], [CPNull null], [CPColor blackColor], [CPColor whiteColor], 32, [CPNull null], [CPNull null],[CPNull null], [CPNull null], [CPNull null], [CPNull null]]
|
||||
forKeys:[ @"gradient-height",
|
||||
@"solid-color",
|
||||
@"bezel-head-color",
|
||||
@"divider-color",
|
||||
@"body-color",
|
||||
@"title-bar-height",
|
||||
@"minimize-image-highlighted-button",
|
||||
@"minimize-image-button",
|
||||
@"close-image-button",
|
||||
@"close-image-highlighted-button",
|
||||
@"unsaved-image-button",
|
||||
@"unsaved-image-highlighted-button"]];
|
||||
return @{
|
||||
@"gradient-height": [CPNull null],
|
||||
@"solid-color": [CPNull null],
|
||||
@"bezel-head-color": [CPNull null],
|
||||
@"divider-color": [CPColor blackColor],
|
||||
@"body-color": [CPColor whiteColor],
|
||||
@"title-bar-height": 32,
|
||||
@"minimize-image-highlighted-button": [CPNull null],
|
||||
@"minimize-image-button": [CPNull null],
|
||||
@"close-image-button": [CPNull null],
|
||||
@"close-image-highlighted-button": [CPNull null],
|
||||
@"unsaved-image-button": [CPNull null],
|
||||
@"unsaved-image-highlighted-button": [CPNull null],
|
||||
};
|
||||
}
|
||||
|
||||
+ (CGRect)contentRectForFrameRect:(CGRect)aFrameRect
|
||||
{
|
||||
/*
|
||||
This window view class draws a frame.
|
||||
So we have to inset the content rect to be inside the frame.
|
||||
The top coordinate has already been adjusted by _CPTitleableWindowView.
|
||||
*/
|
||||
var contentRect = [super contentRectForFrameRect:aFrameRect];
|
||||
|
||||
contentRect.origin.x += 1;
|
||||
contentRect.size.width -= 2;
|
||||
contentRect.size.height -= 1;
|
||||
|
||||
// Adjust for the divider
|
||||
contentRect.origin.y += _CPStandardWindowViewDividerViewHeight;
|
||||
contentRect.size.height -= _CPStandardWindowViewDividerViewHeight;
|
||||
|
||||
return contentRect;
|
||||
}
|
||||
|
||||
- (id)initWithFrame:(CGRect)aFrame styleMask:(unsigned)aStyleMask
|
||||
@@ -130,34 +151,34 @@
|
||||
var theClass = [self class],
|
||||
bounds = [self bounds];
|
||||
|
||||
_headView = [[_CPTexturedWindowHeadView alloc] initWithFrame:CGRectMake(0.0, 0.0, CGRectGetWidth(bounds), [self valueForThemeAttribute:@"title-bar-height"]) windowView:self];
|
||||
_headView = [[_CPTexturedWindowHeadView alloc] initWithFrame:_CGRectMake(0.0, 0.0, _CGRectGetWidth(bounds), [self valueForThemeAttribute:@"title-bar-height"]) windowView:self];
|
||||
|
||||
[_headView setAutoresizingMask:CPViewWidthSizable];;
|
||||
[_headView setHitTests:NO];
|
||||
|
||||
[self addSubview:_headView positioned:CPWindowBelow relativeTo:_titleField];
|
||||
|
||||
_dividerView = [[CPView alloc] initWithFrame:CGRectMake(0.0, CGRectGetMaxY([_headView frame]), CGRectGetWidth(bounds), 1.0)];
|
||||
_dividerView = [[CPView alloc] initWithFrame:_CGRectMake(0.0, _CGRectGetMaxY([_headView frame]), _CGRectGetWidth(bounds), _CPStandardWindowViewDividerViewHeight)];
|
||||
|
||||
[_dividerView setAutoresizingMask:CPViewWidthSizable];
|
||||
[_dividerView setHitTests:NO];
|
||||
|
||||
[self addSubview:_dividerView];
|
||||
|
||||
var y = CGRectGetMaxY([_dividerView frame]);
|
||||
var y = _CGRectGetMaxY([_dividerView frame]);
|
||||
|
||||
_bodyView = [[CPView alloc] initWithFrame:CGRectMake(0.0, y, CGRectGetWidth(bounds), CGRectGetHeight(bounds) - y)];
|
||||
_bodyView = [[CPView alloc] initWithFrame:_CGRectMake(0.0, y, _CGRectGetWidth(bounds), _CGRectGetHeight(bounds) - y)];
|
||||
|
||||
[_bodyView setAutoresizingMask:CPViewWidthSizable | CPViewHeightSizable];
|
||||
[_bodyView setHitTests:NO];
|
||||
|
||||
[self addSubview:_bodyView];
|
||||
|
||||
[self setResizeIndicatorOffset:CGSizeMake(2.0, 2.0)];
|
||||
[self setResizeIndicatorOffset:_CGSizeMake(2.0, 2.0)];
|
||||
|
||||
if (_styleMask & CPClosableWindowMask)
|
||||
{
|
||||
_closeButton = [[CPButton alloc] initWithFrame:CGRectMake(8.0, 8.0, 16.0, 16.0)];
|
||||
_closeButton = [[CPButton alloc] initWithFrame:_CGRectMake(8.0, 8.0, 16.0, 16.0)];
|
||||
|
||||
[_closeButton setButtonType:CPMomentaryChangeButton];
|
||||
[_closeButton setBordered:NO];
|
||||
@@ -168,7 +189,7 @@
|
||||
|
||||
if (_styleMask & CPMiniaturizableWindowMask && ![CPPlatform isBrowser])
|
||||
{
|
||||
_minimizeButton = [[CPButton alloc] initWithFrame:CGRectMake(27.0, 7.0, 16.0, 16.0)];
|
||||
_minimizeButton = [[CPButton alloc] initWithFrame:_CGRectMake(27.0, 7.0, 16.0, 16.0)];
|
||||
[_minimizeButton setButtonType:CPMomentaryChangeButton];
|
||||
[_minimizeButton setBordered:NO];
|
||||
|
||||
@@ -192,7 +213,7 @@
|
||||
|
||||
- (CGSize)toolbarOffset
|
||||
{
|
||||
return CGSizeMake(0.0, [self valueForThemeAttribute:@"title-bar-height"]);
|
||||
return _CGSizeMake(0.0, [self valueForThemeAttribute:@"title-bar-height"]);
|
||||
}
|
||||
|
||||
- (void)tile
|
||||
@@ -286,7 +307,7 @@
|
||||
- (BOOL)couldBeMoveEvent:(CPEvent)anEvent
|
||||
{
|
||||
if (![_headView isHidden])
|
||||
if (CGRectContainsPoint([_headView frame], [self convertPoint:[anEvent locationInWindow] fromView:nil]))
|
||||
if (_CGRectContainsPoint([_headView frame], [self convertPoint:[anEvent locationInWindow] fromView:nil]))
|
||||
return YES;
|
||||
|
||||
return [super couldBeMoveEvent:anEvent];
|
||||
@@ -345,4 +366,18 @@
|
||||
[_headView setNeedsLayout];
|
||||
}
|
||||
|
||||
- (CGSize)_minimumResizeSize
|
||||
{
|
||||
// The minimum width is such that the close button would always be visible.
|
||||
// We give the same margin to the right of the button as there is to the left.
|
||||
var size = [super _minimumResizeSize],
|
||||
closeSize = [self valueForThemeAttribute:@"close-image-size"],
|
||||
closeOrigin = [self valueForThemeAttribute:@"close-image-origin"];
|
||||
|
||||
size.width = closeSize.width + (closeOrigin.x * 2);
|
||||
size.height += _CPStandardWindowViewDividerViewHeight;
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -36,8 +36,8 @@
|
||||
|
||||
+ (CGRect)contentRectForFrameRect:(CGRect)aFrameRect
|
||||
{
|
||||
var contentRect = CGRectMakeCopy(aFrameRect),
|
||||
titleBarHeight = [[self class] titleBarHeight];
|
||||
var contentRect = [super contentRectForFrameRect:aFrameRect],
|
||||
titleBarHeight = [self titleBarHeight];
|
||||
|
||||
contentRect.origin.y += titleBarHeight;
|
||||
contentRect.size.height -= titleBarHeight;
|
||||
@@ -48,7 +48,7 @@
|
||||
+ (CGRect)frameRectForContentRect:(CGRect)aContentRect
|
||||
{
|
||||
var frameRect = CGRectMakeCopy(aContentRect),
|
||||
titleBarHeight = [[self class] titleBarHeight];
|
||||
titleBarHeight = [self titleBarHeight];
|
||||
|
||||
frameRect.origin.y -= titleBarHeight;
|
||||
frameRect.size.height += titleBarHeight;
|
||||
@@ -113,4 +113,12 @@
|
||||
[_titleField setTextShadowOffset:[self currentValueForThemeAttribute:@"title-text-shadow-offset"]];
|
||||
}
|
||||
|
||||
- (CGSize)_minimumResizeSize
|
||||
{
|
||||
var size = [super _minimumResizeSize];
|
||||
|
||||
size.height += [[self class] titleBarHeight];
|
||||
return size;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -40,16 +40,13 @@
|
||||
|
||||
+ (id)themeAttributes
|
||||
{
|
||||
return [CPDictionary dictionaryWithObjects:[[CPColor colorWithHexString:@"E3E3E3"],
|
||||
[CPColor colorWithHexString:@"FFFFCA"],
|
||||
2.0,
|
||||
1.0,
|
||||
[CPColor blackColor]]
|
||||
forKeys:[@"stroke-color",
|
||||
@"background-color",
|
||||
@"border-radius",
|
||||
@"stroke-width",
|
||||
@"color"]];
|
||||
return @{
|
||||
@"stroke-color": [CPColor colorWithHexString:@"E3E3E3"],
|
||||
@"background-color": [CPColor colorWithHexString:@"FFFFCA"],
|
||||
@"border-radius": 2.0,
|
||||
@"stroke-width": 1.0,
|
||||
@"color": [CPColor blackColor],
|
||||
};
|
||||
}
|
||||
|
||||
/*! compute the contentView frame from a given window frame
|
||||
@@ -57,7 +54,7 @@
|
||||
*/
|
||||
+ (CGRect)contentRectForFrameRect:(CGRect)aFrameRect
|
||||
{
|
||||
var contentRect = CGRectMakeCopy(aFrameRect);
|
||||
var contentRect = [super contentRectForFrameRect:aFrameRect];
|
||||
|
||||
contentRect.origin.x += 3;
|
||||
contentRect.origin.y += 3;
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
@global CPApp
|
||||
|
||||
var _CPWindowViewCornerResizeRectWidth = 10,
|
||||
_CPWindowViewMinContentHeight = 2,
|
||||
|
||||
_CPWindowViewResizeRegionNone = -1,
|
||||
_CPWindowViewResizeRegionTopLeft = 0,
|
||||
@@ -82,26 +83,27 @@ _CPWindowViewResizeSlop = 3;
|
||||
|
||||
+ (id)themeAttributes
|
||||
{
|
||||
return [CPDictionary dictionaryWithObjects:[25, CGInsetMakeZero(), 5, [CPColor clearColor], CGSizeMakeZero(), [CPNull null], [CPColor blackColor], [CPNull null],[CPNull null], [CPNull null], [CPNull null], [CPNull null] , [CPColor blackColor], [CPFont systemFontOfSize:CPFontCurrentSystemSize], [CPNull null], _CGSizeMakeZero(), CPCenterTextAlignment, CPLineBreakByTruncatingTail, CPTopVerticalTextAlignment]
|
||||
forKeys:[ @"title-bar-height",
|
||||
@"shadow-inset",
|
||||
@"shadow-distance",
|
||||
@"window-shadow-color",
|
||||
@"size-indicator",
|
||||
@"resize-indicator",
|
||||
@"attached-sheet-shadow-color",
|
||||
@"close-image-origin",
|
||||
@"close-image-size",
|
||||
@"close-image",
|
||||
@"close-active-image",
|
||||
@"bezel-color",
|
||||
@"title-text-color",
|
||||
@"title-font",
|
||||
@"title-text-shadow-color",
|
||||
@"title-text-shadow-offset",
|
||||
@"title-alignment",
|
||||
@"title-line-break-mode",
|
||||
@"title-vertical-alignment"]];
|
||||
return @{
|
||||
@"title-bar-height": 25,
|
||||
@"shadow-inset": CGInsetMakeZero(),
|
||||
@"shadow-distance": 5,
|
||||
@"window-shadow-color": [CPColor clearColor],
|
||||
@"size-indicator": CGSizeMakeZero(),
|
||||
@"resize-indicator": [CPNull null],
|
||||
@"attached-sheet-shadow-color": [CPColor blackColor],
|
||||
@"close-image-origin": [CPNull null],
|
||||
@"close-image-size": [CPNull null],
|
||||
@"close-image": [CPNull null],
|
||||
@"close-active-image": [CPNull null],
|
||||
@"bezel-color": [CPNull null],
|
||||
@"title-text-color": [CPColor blackColor],
|
||||
@"title-font": [CPFont systemFontOfSize:CPFontCurrentSystemSize],
|
||||
@"title-text-shadow-color": [CPNull null],
|
||||
@"title-text-shadow-offset": _CGSizeMakeZero(),
|
||||
@"title-alignment": CPCenterTextAlignment,
|
||||
@"title-line-break-mode": CPLineBreakByTruncatingTail,
|
||||
@"title-vertical-alignment": CPTopVerticalTextAlignment,
|
||||
};
|
||||
}
|
||||
|
||||
- (CGRect)contentRectForFrameRect:(CGRect)aFrameRect
|
||||
@@ -465,34 +467,63 @@ _CPWindowViewResizeSlop = 3;
|
||||
{
|
||||
var deltaX = globalLocation.x - _mouseDraggedPoint.x,
|
||||
deltaY = globalLocation.y - _mouseDraggedPoint.y,
|
||||
newX = _CGRectGetMinX(_resizeFrame),
|
||||
newY = _CGRectGetMinY(_resizeFrame),
|
||||
newWidth = _CGRectGetWidth(_resizeFrame),
|
||||
newHeight = _CGRectGetHeight(_resizeFrame),
|
||||
startX = _CGRectGetMinX(_resizeFrame),
|
||||
startY = _CGRectGetMinY(_resizeFrame),
|
||||
startWidth = _CGRectGetWidth(_resizeFrame),
|
||||
startHeight = _CGRectGetHeight(_resizeFrame),
|
||||
newX,
|
||||
newY,
|
||||
newWidth,
|
||||
newHeight,
|
||||
platformFrame = [[theWindow platformWindow] usableContentFrame],
|
||||
resizeMinSize = [self _minimumResizeSize],
|
||||
minSize = [theWindow minSize],
|
||||
maxSize = [theWindow maxSize];
|
||||
|
||||
minSize = _CGSizeMake(MAX(minSize.width, resizeMinSize.width), MAX(minSize.height, resizeMinSize.height));
|
||||
|
||||
// Calculate x and width first
|
||||
switch (_resizeRegion)
|
||||
{
|
||||
case _CPWindowViewResizeRegionTopLeft:
|
||||
case _CPWindowViewResizeRegionLeft:
|
||||
case _CPWindowViewResizeRegionBottomLeft:
|
||||
if (minSize && deltaX > 0)
|
||||
deltaX = MIN(newWidth - minSize.width, deltaX);
|
||||
else if (maxSize && deltaX < 0)
|
||||
deltaX = MAX(newWidth - maxSize.width, deltaX);
|
||||
// If it is shrinking from the left edge, the maximum distance it can move
|
||||
// is the distance between the original width and the min width.
|
||||
if (deltaX > 0)
|
||||
deltaX = MIN(startWidth - minSize.width, deltaX);
|
||||
|
||||
newX += deltaX,
|
||||
newWidth -= deltaX;
|
||||
// If it is growing from the left edge, the maximum distance it can move
|
||||
// is the distance between the original width and the max width.
|
||||
else if (deltaX < 0)
|
||||
deltaX = -MIN(maxSize.width - startWidth, ABS(deltaX));
|
||||
|
||||
// When resizing from the left, we change the origin and the width
|
||||
newX = startX + deltaX;
|
||||
newWidth = startWidth - deltaX;
|
||||
break;
|
||||
|
||||
case _CPWindowViewResizeRegionTopRight:
|
||||
case _CPWindowViewResizeRegionRight:
|
||||
case _CPWindowViewResizeRegionBottomRight:
|
||||
newWidth += deltaX;
|
||||
// If it is growing from the right edge, the maximum distance it can move
|
||||
// is the distance between the original width and the max width.
|
||||
if (deltaX > 0)
|
||||
deltaX = MIN(maxSize.width - startWidth, deltaX);
|
||||
|
||||
// If it is shrinking from the right edge, the maximum distance it can move
|
||||
// is the distance between the original width and the min width.
|
||||
else if (deltaX < 0)
|
||||
deltaX = -MIN(startWidth - minSize.width, ABS(deltaX));
|
||||
|
||||
// When resizing from the right, change only the width
|
||||
newX = startX;
|
||||
newWidth = startWidth + deltaX;
|
||||
break;
|
||||
|
||||
default:
|
||||
newX = startX;
|
||||
newWidth = startWidth;
|
||||
}
|
||||
|
||||
// Now calculate y and height
|
||||
@@ -501,20 +532,42 @@ _CPWindowViewResizeSlop = 3;
|
||||
case _CPWindowViewResizeRegionTopLeft:
|
||||
case _CPWindowViewResizeRegionTop:
|
||||
case _CPWindowViewResizeRegionTopRight:
|
||||
if (minSize && deltaY > 0)
|
||||
deltaY = MIN(newHeight - minSize.height, deltaY);
|
||||
else if (maxSize && deltaY < 0)
|
||||
deltaY = MAX(newHeight - maxSize.height, deltaY);
|
||||
// If it is shrinking from the top edge, the maximum distance it can move
|
||||
// is the distance between the original height and the min height.
|
||||
if (deltaY > 0)
|
||||
deltaY = MIN(startHeight - minSize.height, deltaY);
|
||||
|
||||
newY += deltaY,
|
||||
newHeight -= deltaY;
|
||||
// If it is growing from the top edge, the maximum distance it can move
|
||||
// is the distance between the original height and the max height.
|
||||
else if (deltaY < 0)
|
||||
deltaY = -MIN(maxSize.height - startHeight, ABS(deltaY));
|
||||
|
||||
// When resizing from the top, change the origin and the height
|
||||
newY = startY + deltaY;
|
||||
newHeight = startHeight - deltaY;
|
||||
break;
|
||||
|
||||
case _CPWindowViewResizeRegionBottomLeft:
|
||||
case _CPWindowViewResizeRegionBottom:
|
||||
case _CPWindowViewResizeRegionBottomRight:
|
||||
newHeight += deltaY;
|
||||
// If it is growing from the bottom edge, the maximum distance it can move
|
||||
// is the distance between the original height and the max height.
|
||||
if (deltaY > 0)
|
||||
deltaY = MIN(maxSize.height - startHeight, deltaY);
|
||||
|
||||
// If it is shrinking from the bottom edge, the maximum distance it can move
|
||||
// is the distance between the original height and the min height.
|
||||
else if (deltaY < 0)
|
||||
deltaY = -MIN(startHeight - minSize.height, ABS(deltaY));
|
||||
|
||||
// When resizing from the bottom, change only the height
|
||||
newY = startY;
|
||||
newHeight = startHeight + deltaY;
|
||||
break;
|
||||
|
||||
default:
|
||||
newY = startY;
|
||||
newHeight = startHeight;
|
||||
}
|
||||
|
||||
if (theWindow._isSheet && theWindow._parentView && (frame.size.width !== newWidth))
|
||||
@@ -808,4 +861,9 @@ _CPWindowViewResizeSlop = 3;
|
||||
}
|
||||
}
|
||||
|
||||
- (CGSize)_minimumResizeSize
|
||||
{
|
||||
return _CGSizeMake(0, _CPWindowViewMinContentHeight);
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
|
||||
An instance of a CPWindowController manages a CPWindow. Windows are typically loaded via a cib,
|
||||
but they can also manage windows created in code. A CPWindowController can manage a window by
|
||||
itself or work with AppKits's document-based architecture.
|
||||
itself or work with AppKit's document-based architecture.
|
||||
|
||||
In a Document based app, a CPWindowController instance is created and managed by a CPDocument subclass.
|
||||
|
||||
@@ -144,7 +144,7 @@
|
||||
if (_window)
|
||||
return;
|
||||
|
||||
[[CPBundle mainBundle] loadCibFile:[self windowCibPath] externalNameTable:[CPDictionary dictionaryWithObject:_cibOwner forKey:CPCibOwner]];
|
||||
[[CPBundle mainBundle] loadCibFile:[self windowCibPath] externalNameTable:@{ CPCibOwner: _cibOwner }];
|
||||
}
|
||||
|
||||
/*!
|
||||
|
||||
+23
-1
@@ -165,7 +165,7 @@ var CPCibObjectDataKey = @"CPCibObjectDataKey";
|
||||
|
||||
- (BOOL)instantiateCibWithOwner:(id)anOwner topLevelObjects:(CPArray)topLevelObjects
|
||||
{
|
||||
return [self instantiateCibWithExternalNameTable:[CPDictionary dictionaryWithObjects:[anOwner, topLevelObjects] forKeys:[CPCibOwner, CPCibTopLevelObjects]]];
|
||||
return [self instantiateCibWithExternalNameTable:@{ CPCibOwner: anOwner, CPCibTopLevelObjects: topLevelObjects }];
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -198,3 +198,25 @@ var CPCibObjectDataKey = @"CPCibObjectDataKey";
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
var CPCibDataFileKey = @"CPCibDataFileKey",
|
||||
CPCibBundleIdentifierKey = @"CPCibBundleIdentifierKey";
|
||||
|
||||
@implementation CPCib (CPCoding)
|
||||
|
||||
- (id)initWithCoder:(CPCoder)aCoder
|
||||
{
|
||||
self = [super init];
|
||||
|
||||
var base64 = [aCoder decodeObjectForKey:CPCibDataFileKey];
|
||||
_data = [CPData dataWithBase64:base64];
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)encodeWithCoder:(CPCoder)aCoder
|
||||
{
|
||||
[aCoder encodeObject:[_data base64] forKey:CPCibDataFileKey];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -52,7 +52,7 @@ var CPCibOwner = @"CPCibOwner";
|
||||
var bundle = anOwner ? [CPBundle bundleForClass:[anOwner class]] : [CPBundle mainBundle],
|
||||
path = [bundle pathForResource:aName];
|
||||
|
||||
return [self loadCibFile:path externalNameTable:[CPDictionary dictionaryWithObject:anOwner forKey:CPCibOwner]];
|
||||
return [self loadCibFile:path externalNameTable:@{ CPCibOwner: anOwner }];
|
||||
}
|
||||
|
||||
- (CPCib)loadCibFile:(CPString)aFileName externalNameTable:(CPDictionary)aNameTable
|
||||
@@ -78,7 +78,7 @@ var CPCibOwner = @"CPCibOwner";
|
||||
var bundle = anOwner ? [CPBundle bundleForClass:[anOwner class]] : [CPBundle mainBundle],
|
||||
path = [bundle pathForResource:aName];
|
||||
|
||||
return [self loadCibFile:path externalNameTable:[CPDictionary dictionaryWithObject:anOwner forKey:CPCibOwner] loadDelegate:aDelegate];
|
||||
return [self loadCibFile:path externalNameTable:@{ CPCibOwner: anOwner } loadDelegate:aDelegate];
|
||||
}
|
||||
|
||||
- (CPCib)loadCibFile:(CPString)aFileName externalNameTable:(CPDictionary)aNameTable loadDelegate:(id)aDelegate
|
||||
|
||||
@@ -46,12 +46,12 @@ var _CPCibCustomResourceClassNameKey = @"_CPCibCustomResourceClassNameKey",
|
||||
|
||||
+ (id)imageResourceWithName:(CPString)aResourceName size:(CGSize)aSize
|
||||
{
|
||||
return [[self alloc] initWithClassName:@"CPImage" resourceName:aResourceName properties:[CPDictionary dictionaryWithObject:aSize forKey:@"size"]];
|
||||
return [[self alloc] initWithClassName:@"CPImage" resourceName:aResourceName properties:@{ @"size": aSize }];
|
||||
}
|
||||
|
||||
+ (id)imageResourceWithName:(CPString)aResourceName size:(CGSize)aSize bundleClass:(CPString)aBundleClass
|
||||
{
|
||||
return [[self alloc] initWithClassName:@"CPImage" resourceName:aResourceName properties:[CPDictionary dictionaryWithObjects:[aSize, aBundleClass] forKeys:[@"size", @"bundleClass"]]];
|
||||
return [[self alloc] initWithClassName:@"CPImage" resourceName:aResourceName properties:@{ @"size": aSize, @"bundleClass": aBundleClass }];
|
||||
}
|
||||
|
||||
- (id)initWithClassName:(CPString)aClassName resourceName:(CPString)aResourceName properties:(CPDictionary)properties
|
||||
|
||||
@@ -116,6 +116,7 @@ var _CPCibCustomViewClassNameKey = @"_CPCibCustomViewClassNameKey";
|
||||
[view setHitTests:[self hitTests]];
|
||||
[view setHidden:[self isHidden]];
|
||||
[view setAlphaValue:[self alphaValue]];
|
||||
[view setIdentifier:[self identifier]];
|
||||
|
||||
[_superview replaceSubview:self with:view];
|
||||
|
||||
|
||||
@@ -44,7 +44,7 @@ var CAMediaNamedTimingFunctions = nil;
|
||||
{
|
||||
if (!CAMediaNamedTimingFunctions)
|
||||
{
|
||||
CAMediaNamedTimingFunctions = [CPDictionary dictionary];
|
||||
CAMediaNamedTimingFunctions = @{};
|
||||
|
||||
[CAMediaNamedTimingFunctions setObject:[CAMediaTimingFunction functionWithControlPoints:0.0 :0.0 :1.0 :1.0] forKey:kCAMediaTimingFunctionLinear];
|
||||
[CAMediaNamedTimingFunctions setObject:[CAMediaTimingFunction functionWithControlPoints:0.42 :0.0 :1.0 :1.0] forKey:kCAMediaTimingFunctionEaseIn];
|
||||
|
||||
@@ -101,7 +101,7 @@ function CGPathAddArc(aPath, aTransform, x, y, aRadius, aStartAngle, anEndAngle,
|
||||
// Angles that equal "modulo" 2 pi return as equal after transforming them,
|
||||
// so we have to make sure to make them different again if they were different
|
||||
// to start out with. It's the difference between no circle and a full circle.
|
||||
if (anEndAngle === aStartAngle && oldEndAngle != oldStartAngle)
|
||||
if (anEndAngle === aStartAngle && oldEndAngle !== oldStartAngle)
|
||||
if (oldStartAngle > oldEndAngle)
|
||||
anEndAngle = anEndAngle - PI2;
|
||||
else
|
||||
@@ -204,7 +204,7 @@ function CGPathAddLineToPoint(aPath, aTransform, x, y)
|
||||
{
|
||||
var point = _CGPointMake(x, y);
|
||||
|
||||
if (aTransform != NULL)
|
||||
if (aTransform !== NULL)
|
||||
point = _CGPointApplyAffineTransform(point, aTransform);
|
||||
|
||||
aPath.elements[aPath.count++] = { type: kCGPathElementAddLineToPoint, x:point.x, y:point.y };
|
||||
@@ -304,7 +304,7 @@ function CGPathMoveToPoint(aPath, aTransform, x, y)
|
||||
{
|
||||
var point = _CGPointMake(x, y);
|
||||
|
||||
if (aTransform != NULL)
|
||||
if (aTransform !== NULL)
|
||||
point = _CGPointApplyAffineTransform(point, aTransform);
|
||||
|
||||
aPath.start = aPath.current = point;
|
||||
@@ -312,16 +312,17 @@ function CGPathMoveToPoint(aPath, aTransform, x, y)
|
||||
// If the previous op was a move, just update that point
|
||||
if (aPath.count)
|
||||
{
|
||||
var previous = aPath.elements[count - 1];
|
||||
var previous = aPath.elements[aPath.count - 1];
|
||||
|
||||
if (previous.type === kCGPathElementMoveToPoint)
|
||||
{
|
||||
previous.x = point.x;
|
||||
previous.y = point.y;
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
aPath.elements[aPath.count++] = { type:kCGPathElementMoveToPoint, x:point.x, y:point.y };
|
||||
|
||||
aPath.elements[aPath.count++] = { type:kCGPathElementMoveToPoint, x:point.x, y:point.y };
|
||||
}
|
||||
|
||||
var KAPPA = 4.0 * ((SQRT2 - 1.0) / 3.0);
|
||||
@@ -407,7 +408,7 @@ function CGPathCloseSubpath(aPath)
|
||||
|
||||
// After closing, the current point is the previous path's starting point
|
||||
aPath.current = _CGPointCreateCopy(aPath.start);
|
||||
aPath.elements[aPath.count++] = { type:kCGPathElementCloseSubpath, points:[aPath.start] };
|
||||
aPath.elements[aPath.count++] = { type:kCGPathElementCloseSubpath, start:aPath.start };
|
||||
}
|
||||
|
||||
function CGPathEqualToPath(aPath, anotherPath)
|
||||
@@ -415,7 +416,7 @@ function CGPathEqualToPath(aPath, anotherPath)
|
||||
if (aPath === anotherPath)
|
||||
return YES;
|
||||
|
||||
if (aPath.count != anotherPath.count || !_CGPointEqualToPoint(aPath.start, anotherPath.start) || !_CGPointEqualToPoint(aPath.current, anotherPath.current))
|
||||
if (aPath.count !== anotherPath.count || !_CGPointEqualToPoint(aPath.start, anotherPath.start) || !_CGPointEqualToPoint(aPath.current, anotherPath.current))
|
||||
return NO;
|
||||
|
||||
var i = 0,
|
||||
@@ -426,18 +427,70 @@ function CGPathEqualToPath(aPath, anotherPath)
|
||||
var element = aPath[i],
|
||||
anotherElement = anotherPath[i];
|
||||
|
||||
if (element.type != anotherElement.type)
|
||||
if (element.type !== anotherElement.type)
|
||||
return NO;
|
||||
|
||||
if ((element.type === kCGPathElementAddArc || element.type === kCGPathElementAddArcToPoint) &&
|
||||
element.radius != anotherElement.radius)
|
||||
return NO;
|
||||
switch (element.type)
|
||||
{
|
||||
case kCGPathElementAddArc:
|
||||
if (element.x !== anotherElement.x ||
|
||||
element.y !== anotherElement.y ||
|
||||
element.radius !== anotherElement.radius ||
|
||||
element.startAngle !== anotherElement.startAngle ||
|
||||
element.endAngle !== anotherElement.endAngle ||
|
||||
element.clockwise !== anotherElement.clockwise)
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
break;
|
||||
|
||||
var j = element.points.length;
|
||||
case kCGPathElementAddArcToPoint:
|
||||
if (element.p1x !== anotherElement.p1x ||
|
||||
element.p1y !== anotherElement.p1y ||
|
||||
element.p2x !== anotherElement.p2x ||
|
||||
element.p2y !== anotherElement.p2y ||
|
||||
element.radius !== anotherElement.radius)
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
break;
|
||||
|
||||
while (j--)
|
||||
if (!_CGPointEqualToPoint(element.points[j], anotherElement.points[j]))
|
||||
return NO;
|
||||
case kCGPathElementAddCurveToPoint:
|
||||
if (element.cp1x !== anotherElement.cp1x ||
|
||||
element.cp1y !== anotherElement.cp1y ||
|
||||
element.cp2x !== anotherElement.cp2x ||
|
||||
element.cp2y !== anotherElement.cp2y ||
|
||||
element.x !== anotherElement.x ||
|
||||
element.y !== anotherElement.y)
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
break;
|
||||
|
||||
case kCGPathElementAddLineToPoint:
|
||||
case kCGPathElementMoveToPoint:
|
||||
if (element.x !== anotherElement.x ||
|
||||
element.y !== anotherElement.y)
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
break;
|
||||
|
||||
case kCGPathElementAddQuadCurveToPoint:
|
||||
if (element.cpx !== anotherElement.cpx ||
|
||||
element.cpy !== anotherElement.cpy ||
|
||||
element.x !== anotherElement.x ||
|
||||
element.y !== anotherElement.y)
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
break;
|
||||
|
||||
case kCGPathElementCloseSubpath:
|
||||
if (!_CGPointEqualToPoint(element.start, anotherElement.start))
|
||||
return NO;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return YES;
|
||||
|
||||
@@ -50,7 +50,11 @@
|
||||
|
||||
+ (CPDictionary)metricsOfFont:(CPFont)aFont
|
||||
{
|
||||
return [CPDictionary dictionaryWithObjectsAndKeys:0, @"ascender", 0, @"descender", 0, @"lineHeight"];
|
||||
return @{
|
||||
@"ascender": 0,
|
||||
@"descender": 0,
|
||||
@"lineHeight": 0,
|
||||
};
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -110,7 +110,7 @@ var PrimaryPlatformWindow = NULL;
|
||||
|
||||
#if PLATFORM(DOM)
|
||||
_windowLevels = [];
|
||||
_windowLayers = [CPDictionary dictionary];
|
||||
_windowLayers = @{};
|
||||
|
||||
_charCodes = {};
|
||||
#endif
|
||||
|
||||
@@ -165,7 +165,11 @@ var DOMFixedWidthSpanElement = nil,
|
||||
baseline = DOMMetricsImgElement.offsetTop + DOMMetricsImgElement.offsetHeight,
|
||||
descender = baseline - lineHeight;
|
||||
|
||||
return [CPDictionary dictionaryWithObjectsAndKeys:baseline, @"ascender", descender, @"descender", lineHeight, @"lineHeight"];
|
||||
return @{
|
||||
@"ascender": baseline,
|
||||
@"descender": descender,
|
||||
@"lineHeight": lineHeight,
|
||||
};
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -213,7 +213,7 @@ var resizeTimer = nil;
|
||||
_contentRect = _CGRectMakeZero();
|
||||
|
||||
_windowLevels = [];
|
||||
_windowLayers = [CPDictionary dictionary];
|
||||
_windowLayers = @{};
|
||||
|
||||
[self registerDOMWindow];
|
||||
[self updateFromNativeContentRect];
|
||||
|
||||
@@ -988,7 +988,9 @@ var themedButtonValues = nil,
|
||||
[@"text-color", [CPColor colorWithCalibratedWhite:51.0 / 255.0 alpha:1.0], CPThemeStateTableDataView],
|
||||
[@"text-color", [CPColor whiteColor], CPThemeStateTableDataView | CPThemeStateSelectedTableDataView],
|
||||
[@"font", [CPFont boldSystemFontOfSize:CPFontCurrentSystemSize], CPThemeStateTableDataView | CPThemeStateSelectedTableDataView],
|
||||
[@"text-color", [CPColor blackColor], CPThemeStateTableDataView | CPThemeStateEditing],
|
||||
[@"text-color", [CPColor blackColor], CPThemeStateTableDataView | CPThemeStateEditable],
|
||||
[@"text-color", [CPColor blackColor], CPThemeStateTableDataView | CPThemeStateSelectedTableDataView | CPThemeStateEditing],
|
||||
[@"text-color", [CPColor blackColor], CPThemeStateTableDataView | CPThemeStateBezeled],
|
||||
[@"content-inset", CGInsetMake(8.0, 8.0, 7.0, 5.0), CPThemeStateTableDataView | CPThemeStateEditing],
|
||||
[@"font", [CPFont systemFontOfSize:CPFontCurrentSystemSize], CPThemeStateTableDataView | CPThemeStateEditing],
|
||||
[@"bezel-inset", CGInsetMake(-1.0, -1.0, -1.0, -1.0), CPThemeStateTableDataView | CPThemeStateEditing],
|
||||
@@ -1838,11 +1840,11 @@ var themedButtonValues = nil,
|
||||
alternatingRowColors = [[CPColor whiteColor], [CPColor colorWithRed:245.0 / 255.0 green:249.0 / 255.0 blue:252.0 / 255.0 alpha:1.0]],
|
||||
gridColor = [CPColor colorWithHexString:@"cccccc"],
|
||||
selectionColor = [CPColor colorWithHexString:@"5f83b9"],
|
||||
sourceListSelectionColor = [CPDictionary dictionaryWithObjects: [CGGradientCreateWithColorComponents(CGColorSpaceCreateDeviceRGB(), [98.0 / 255.0, 143.0 / 210.0, 209.0 / 255.0, 1.0, 46.0 / 255.0, 88.0 / 176.0, 208.0 / 255.0,1.0], [0,1], 2),
|
||||
[CPColor colorWithCalibratedRed:81.0 / 255.0 green:127.0 / 255.0 blue:200.0 / 255.0 alpha:1.0],
|
||||
[CPColor colorWithCalibratedRed:34.0 / 255.0 green:63.0 / 255.0 blue:123.0 / 255.0 alpha:1.0]
|
||||
]
|
||||
forKeys: [CPSourceListGradient, CPSourceListTopLineColor, CPSourceListBottomLineColor]],
|
||||
sourceListSelectionColor = @{
|
||||
CPSourceListGradient: CGGradientCreateWithColorComponents(CGColorSpaceCreateDeviceRGB(), [98.0 / 255.0, 143.0 / 210.0, 209.0 / 255.0, 1.0, 46.0 / 255.0, 88.0 / 176.0, 208.0 / 255.0,1.0], [0,1], 2),
|
||||
CPSourceListTopLineColor: [CPColor colorWithCalibratedRed:81.0 / 255.0 green:127.0 / 255.0 blue:200.0 / 255.0 alpha:1.0],
|
||||
CPSourceListBottomLineColor: [CPColor colorWithCalibratedRed:34.0 / 255.0 green:63.0 / 255.0 blue:123.0 / 255.0 alpha:1.0],
|
||||
},
|
||||
|
||||
themedTableViewValues =
|
||||
[
|
||||
|
||||
@@ -549,7 +549,8 @@ var themedButtonValues = nil,
|
||||
[@"text-color", [CPColor whiteColor], CPThemeStateTableDataView | CPThemeStateSelectedTableDataView],
|
||||
[@"font", [CPFont boldSystemFontOfSize:12.0], CPThemeStateTableDataView | CPThemeStateSelectedTableDataView],
|
||||
[@"text-color", [CPColor blackColor], CPThemeStateTableDataView | CPThemeStateEditing],
|
||||
[@"content-inset", CGInsetMake(7.0, 7.0, 5.0, 10.0), CPThemeStateTableDataView | CPThemeStateEditing],
|
||||
[@"text-color", [CPColor blackColor], CPThemeStateTableDataView | CPThemeStateSelectedTableDataView | CPThemeStateEditable],
|
||||
[@"content-inset", CGInsetMake(7.0, 7.0, 5.0, 10.0), CPThemeStateTableDataView | CPThemeStateEditable],
|
||||
[@"font", [CPFont systemFontOfSize:12.0], CPThemeStateTableDataView | CPThemeStateEditing],
|
||||
[@"bezel-inset", CGInsetMake(-2.0, -2.0, -2.0, -2.0), CPThemeStateTableDataView | CPThemeStateEditing],
|
||||
|
||||
@@ -1295,19 +1296,16 @@ var themedButtonValues = nil,
|
||||
alternatingRowColors = [[CPColor whiteColor], [CPColor colorWithRed:245.0 / 255.0 green:249.0 / 255.0 blue:252.0 / 255.0 alpha:1.0]],
|
||||
gridColor = [CPColor colorWithHexString:@"dce0e2"],
|
||||
selectionColor = [CPColor colorWithHexString:@"5780d8"],
|
||||
sourceListSelectionColor = [CPDictionary dictionaryWithObjectsAndKeys:
|
||||
CGGradientCreateWithColorComponents(
|
||||
sourceListSelectionColor = @{
|
||||
CPSourceListGradient: CGGradientCreateWithColorComponents(
|
||||
CGColorSpaceCreateDeviceRGB(),
|
||||
[109.0 / 255.0, 150.0 / 255.0, 238.0 / 255.0, 1.0, 72.0 / 255.0, 113.0 / 255.0, 201.0 / 255.0, 1.0],
|
||||
[0, 1],
|
||||
2
|
||||
),
|
||||
CPSourceListGradient,
|
||||
[CPColor colorWithCalibratedRed:73.0 / 255.0 green:109.0 / 255.0 blue:187.0 / 255.0 alpha:1.0],
|
||||
CPSourceListTopLineColor,
|
||||
[CPColor colorWithCalibratedRed:44.0 / 255.0 green:79.0 / 255.0 blue:155.0 / 255.0 alpha:1.0],
|
||||
CPSourceListBottomLineColor
|
||||
],
|
||||
CPSourceListTopLineColor: [CPColor colorWithCalibratedRed:73.0 / 255.0 green:109.0 / 255.0 blue:187.0 / 255.0 alpha:1.0],
|
||||
CPSourceListBottomLineColor: [CPColor colorWithCalibratedRed:44.0 / 255.0 green:79.0 / 255.0 blue:155.0 / 255.0 alpha:1.0],
|
||||
},
|
||||
|
||||
themedTableViewValues =
|
||||
[
|
||||
|
||||
@@ -162,7 +162,7 @@ function themeFromCibData(data)
|
||||
topLevelObjects = [];
|
||||
|
||||
[cib _setAwakenCustomResources:NO];
|
||||
[cib instantiateCibWithExternalNameTable:[CPDictionary dictionaryWithObject:topLevelObjects forKey:CPCibTopLevelObjects]];
|
||||
[cib instantiateCibWithExternalNameTable:@{ CPCibTopLevelObjects: topLevelObjects }];
|
||||
|
||||
var count = topLevelObjects.length,
|
||||
theme = nil,
|
||||
|
||||
@@ -54,7 +54,7 @@ var _CPAutocompleteMenuMaximumHeight = 307;
|
||||
{
|
||||
textField = aTextField;
|
||||
|
||||
_menuWindow = [[CPWindow alloc] initWithContentRect:CGRectMake(0, 0, 100, 100) styleMask:CPBorderlessWindowMask];
|
||||
_menuWindow = [[_CPAutocompleteWindow alloc] initWithContentRect:CGRectMake(0, 0, 100, 100) styleMask:CPBorderlessWindowMask];
|
||||
|
||||
[_menuWindow setLevel:CPPopUpMenuWindowLevel];
|
||||
[_menuWindow setHasShadow:YES];
|
||||
@@ -83,9 +83,8 @@ var _CPAutocompleteMenuMaximumHeight = 307;
|
||||
[tableView setHeaderView:nil];
|
||||
[tableView setCornerView:nil];
|
||||
[tableView setRowHeight:24.0];
|
||||
[tableView setGridStyleMask:CPTableViewSolidHorizontalGridLineMask];
|
||||
[tableView setGridStyleMask:CPTableViewGridNone];
|
||||
[tableView setBackgroundColor:[CPColor clearColor]];
|
||||
[tableView setGridColor:[CPColor colorWithRed:242.0 / 255.0 green:243.0 / 255.0 blue:245.0 / 255.0 alpha:1.0]];
|
||||
|
||||
[scrollView setDocumentView:tableView];
|
||||
}
|
||||
@@ -269,9 +268,22 @@ var _CPAutocompleteMenuMaximumHeight = 307;
|
||||
|
||||
@end
|
||||
|
||||
@implementation _CPAutocompleteWindow : CPPanel
|
||||
|
||||
- (BOOL)becomesKeyOnlyIfNeeded
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation _CPNonFirstResponderTableView : CPTableView
|
||||
|
||||
- (BOOL)needsPanelToBecomeKey
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (BOOL)acceptsFirstResponder
|
||||
{
|
||||
return NO;
|
||||
|
||||
@@ -33,8 +33,10 @@
|
||||
|
||||
+ (id)themeAttributes
|
||||
{
|
||||
return [CPDictionary dictionaryWithObjects:[[CPNull null], [CPNull null]]
|
||||
forKeys:[@"background-color", @"divider-color"]];
|
||||
return @{
|
||||
@"background-color": [CPNull null],
|
||||
@"divider-color": [CPNull null],
|
||||
};
|
||||
}
|
||||
|
||||
- (void)drawRect:(CGRect)aRect
|
||||
|
||||
@@ -218,7 +218,7 @@
|
||||
*/
|
||||
- (void)removeObject:(id)anObject
|
||||
{
|
||||
[self removeObject:anObject inRange:CPMakeRange(0, self.length)];
|
||||
[self removeObject:anObject inRange:CPMakeRange(0, [self count])];
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -233,7 +233,7 @@
|
||||
while ((index = [self indexOfObject:anObject inRange:aRange]) != CPNotFound)
|
||||
{
|
||||
[self removeObjectAtIndex:index];
|
||||
aRange = CPIntersectionRange(CPMakeRange(index, self.length - index), aRange);
|
||||
aRange = CPIntersectionRange(CPMakeRange(index, [self count] - index), aRange);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -262,7 +262,7 @@
|
||||
}
|
||||
|
||||
/*!
|
||||
Remove the first instance of \c anObject from the array.
|
||||
Remove all instances of \c anObject from the array.
|
||||
The search for the object is done using \c ==.
|
||||
@param anObject the object to remove
|
||||
*/
|
||||
|
||||
@@ -618,11 +618,12 @@ var concat = Array.prototype.concat,
|
||||
var index = 0,
|
||||
count = [self count],
|
||||
shouldStop = NO,
|
||||
shouldStopRef = AT_REF(shouldStop);
|
||||
shouldStopRef = @ref(shouldStop);
|
||||
|
||||
for (; index < count; ++index)
|
||||
{
|
||||
aFunction([self objectAtIndex:index], index, shouldStopRef);
|
||||
|
||||
if (shouldStop)
|
||||
return;
|
||||
}
|
||||
@@ -630,8 +631,6 @@ var concat = Array.prototype.concat,
|
||||
|
||||
- (void)enumerateObjectsWithOptions:(CPEnumerationOptions)options usingBlock:(Function /*(id anObject, int idx, @ref BOOL stop)*/)aFunction
|
||||
{
|
||||
var shouldStop = NO;
|
||||
|
||||
if (options & CPEnumerationReverse)
|
||||
{
|
||||
var index = [self count] - 1,
|
||||
@@ -645,9 +644,13 @@ var concat = Array.prototype.concat,
|
||||
increment = 1;
|
||||
}
|
||||
|
||||
var shouldStop = NO,
|
||||
shouldStopRef = @ref(shouldStop);
|
||||
|
||||
for (; index !== stop; index += increment)
|
||||
{
|
||||
aFunction([self objectAtIndex:index], index, AT_REF(shouldStop));
|
||||
aFunction([self objectAtIndex:index], index, shouldStopRef);
|
||||
|
||||
if (shouldStop)
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -246,6 +246,26 @@ var concat = Array.prototype.concat,
|
||||
splice.call(self, anIndex, 1);
|
||||
}
|
||||
|
||||
- (void)removeObjectIdenticalTo:(id)anObject
|
||||
{
|
||||
if (indexOf)
|
||||
{
|
||||
var anIndex;
|
||||
while ((anIndex = indexOf.call(self, anObject)) !== -1)
|
||||
splice.call(self, anIndex, 1);
|
||||
}
|
||||
else
|
||||
[super removeObjectIdenticalTo:anObject inRange:CPMakeRange(0, self.length)];
|
||||
}
|
||||
|
||||
- (void)removeObjectIdenticalTo:(id)anObject inRange:(CPRange)aRange
|
||||
{
|
||||
if (indexOf && !aRange)
|
||||
[self removeObjectIdenticalTo:anObject];
|
||||
|
||||
[super removeObjectIdenticalTo:anObject inRange:aRange];
|
||||
}
|
||||
|
||||
- (void)addObject:(id)anObject
|
||||
{
|
||||
push.call(self, anObject);
|
||||
|
||||
@@ -50,6 +50,15 @@
|
||||
}
|
||||
|
||||
// Creating a CPAttributedString Object
|
||||
/*!
|
||||
Creates an empty attributed string.
|
||||
@return a new empty CPAttributedString.
|
||||
*/
|
||||
- (id)init
|
||||
{
|
||||
return [self initWithString:@"" attributes:nil];
|
||||
}
|
||||
|
||||
/*!
|
||||
Creates a new attributed string from a character string.
|
||||
@param aString is the string to initialise from.
|
||||
@@ -67,7 +76,7 @@
|
||||
*/
|
||||
- (id)initWithAttributedString:(CPAttributedString)aString
|
||||
{
|
||||
var string = [self initWithString:"" attributes:nil];
|
||||
var string = [self initWithString:@"" attributes:nil];
|
||||
|
||||
[string setAttributedString:aString];
|
||||
|
||||
@@ -89,9 +98,9 @@
|
||||
if (self)
|
||||
{
|
||||
if (!attributes)
|
||||
attributes = [CPDictionary dictionary];
|
||||
attributes = @{};
|
||||
|
||||
_string = ""+aString;
|
||||
_string = "" + aString;
|
||||
_rangeEntries = [makeRangeEntry(CPMakeRange(0, _string.length), attributes)];
|
||||
}
|
||||
|
||||
@@ -135,10 +144,11 @@
|
||||
if (anIndex < 0 || anIndex > _string.length || anIndex === undefined)
|
||||
return CPNotFound;
|
||||
|
||||
//find the range entry that contains anIndex.
|
||||
// find the range entry that contains anIndex.
|
||||
var sortFunction = function(index, entry)
|
||||
{
|
||||
//index is the character index we're searching for, while range is the actual range entry we're comparing against
|
||||
// index is the character index we're searching for,
|
||||
// while range is the actual range entry we're comparing against
|
||||
if (CPLocationInRange(index, entry.range))
|
||||
return CPOrderedSame;
|
||||
else if (CPMaxRange(entry.range) <= index)
|
||||
@@ -166,18 +176,19 @@
|
||||
same as those at index, \c anIndex. If not required pass
|
||||
\c nil.
|
||||
@return a CPDictionary containing the attributes associated with the
|
||||
character at index \c anIndex. Returns \c nil if index
|
||||
character at index \c anIndex. Returns an empty dictionary if index
|
||||
is out of bounds.
|
||||
*/
|
||||
- (CPDictionary)attributesAtIndex:(unsigned)anIndex effectiveRange:(CPRangePointer)aRange
|
||||
{
|
||||
//find the range entry that contains anIndex.
|
||||
// find the range entry that contains anIndex.
|
||||
var entryIndex = [self _indexOfEntryWithIndex:anIndex];
|
||||
|
||||
if (entryIndex == CPNotFound)
|
||||
return nil;
|
||||
if (entryIndex === CPNotFound)
|
||||
return @{};
|
||||
|
||||
var matchingRange = _rangeEntries[entryIndex];
|
||||
|
||||
if (aRange)
|
||||
{
|
||||
aRange.location = matchingRange.range.location;
|
||||
@@ -205,15 +216,15 @@
|
||||
@param rangeLimit a range limiting the search for the attributes' applicable
|
||||
range.
|
||||
@return a CPDictionary containing the attributes associated with the
|
||||
character at index \c anIndex. Returns \c nil if index
|
||||
character at index \c anIndex. Returns an empty dictionary if index
|
||||
is out of bounds.
|
||||
*/
|
||||
- (CPDictionary)attributesAtIndex:(unsigned)anIndex longestEffectiveRange:(CPRangePointer)aRange inRange:(CPRange)rangeLimit
|
||||
{
|
||||
var startingEntryIndex = [self _indexOfEntryWithIndex:anIndex];
|
||||
|
||||
if (startingEntryIndex == CPNotFound)
|
||||
return nil;
|
||||
if (startingEntryIndex === CPNotFound)
|
||||
return @{};
|
||||
|
||||
if (!aRange)
|
||||
return _rangeEntries[startingEntryIndex].attributes;
|
||||
@@ -226,7 +237,7 @@
|
||||
return _rangeEntries[startingEntryIndex].attributes;
|
||||
}
|
||||
|
||||
//scan backwards
|
||||
// scan backwards
|
||||
var nextRangeIndex = startingEntryIndex - 1,
|
||||
currentEntry = _rangeEntries[startingEntryIndex],
|
||||
comparisonDict = currentEntry.attributes;
|
||||
@@ -246,7 +257,7 @@
|
||||
|
||||
aRange.location = MAX(currentEntry.range.location, rangeLimit.location);
|
||||
|
||||
//scan forwards
|
||||
// scan forwards
|
||||
currentEntry = _rangeEntries[startingEntryIndex];
|
||||
nextRangeIndex = startingEntryIndex + 1;
|
||||
|
||||
@@ -323,10 +334,9 @@
|
||||
*/
|
||||
- (id)attribute:(CPString)attribute atIndex:(unsigned)anIndex longestEffectiveRange:(CPRangePointer)aRange inRange:(CPRange)rangeLimit
|
||||
{
|
||||
//find the range entry that contains anIndex.
|
||||
var startingEntryIndex = [self _indexOfEntryWithIndex:anIndex];
|
||||
|
||||
if (startingEntryIndex == CPNotFound || !attribute)
|
||||
if (startingEntryIndex === CPNotFound || !attribute)
|
||||
return nil;
|
||||
|
||||
if (!aRange)
|
||||
@@ -340,7 +350,7 @@
|
||||
return [_rangeEntries[startingEntryIndex].attributes objectForKey:attribute];
|
||||
}
|
||||
|
||||
//scan backwards
|
||||
// scan backwards
|
||||
var nextRangeIndex = startingEntryIndex - 1,
|
||||
currentEntry = _rangeEntries[startingEntryIndex],
|
||||
comparisonAttribute = [currentEntry.attributes objectForKey:attribute];
|
||||
@@ -360,7 +370,7 @@
|
||||
|
||||
aRange.location = MAX(currentEntry.range.location, rangeLimit.location);
|
||||
|
||||
//scan forwards
|
||||
// scan forwards
|
||||
currentEntry = _rangeEntries[startingEntryIndex];
|
||||
nextRangeIndex = startingEntryIndex + 1;
|
||||
|
||||
@@ -394,7 +404,7 @@
|
||||
if (!aString)
|
||||
return NO;
|
||||
|
||||
if (_string != [aString string])
|
||||
if (_string !== [aString string])
|
||||
return NO;
|
||||
|
||||
var myRange = CPMakeRange(),
|
||||
@@ -405,9 +415,12 @@
|
||||
|
||||
while (CPMaxRange(CPUnionRange(myRange, comparisonRange)) < length)
|
||||
{
|
||||
if (CPIntersectionRange(myRange, comparisonRange).length > 0 && ![myAttributes isEqualToDictionary:comparisonAttributes])
|
||||
if (CPIntersectionRange(myRange, comparisonRange).length > 0 &&
|
||||
![myAttributes isEqualToDictionary:comparisonAttributes])
|
||||
{
|
||||
return NO;
|
||||
if (CPMaxRange(myRange) < CPMaxRange(comparisonRange))
|
||||
}
|
||||
else if (CPMaxRange(myRange) < CPMaxRange(comparisonRange))
|
||||
myAttributes = [self attributesAtIndex:CPMaxRange(myRange) effectiveRange:myRange];
|
||||
else
|
||||
comparisonAttributes = [aString attributesAtIndex:CPMaxRange(comparisonRange) effectiveRange:comparisonRange];
|
||||
@@ -425,7 +438,7 @@
|
||||
*/
|
||||
- (BOOL)isEqual:(id)anObject
|
||||
{
|
||||
if (anObject == self)
|
||||
if (anObject === self)
|
||||
return YES;
|
||||
|
||||
if ([anObject isKindOfClass:[self class]])
|
||||
@@ -449,8 +462,12 @@
|
||||
reason:"tried to get attributedSubstring for an invalid range: "+(aRange?CPStringFromRange(aRange):"nil")];
|
||||
|
||||
var newString = [[CPAttributedString alloc] initWithString:_string.substring(aRange.location, CPMaxRange(aRange))],
|
||||
entryIndex = [self _indexOfEntryWithIndex:aRange.location],
|
||||
currentRangeEntry = _rangeEntries[entryIndex],
|
||||
entryIndex = [self _indexOfEntryWithIndex:aRange.location];
|
||||
|
||||
if (entryIndex === CPNotFound)
|
||||
_CPRaiseRangeException(self, _cmd, aRange.location, _string.length);
|
||||
|
||||
var currentRangeEntry = _rangeEntries[entryIndex],
|
||||
lastIndex = CPMaxRange(aRange);
|
||||
|
||||
newString._rangeEntries = [];
|
||||
@@ -507,17 +524,25 @@
|
||||
- (void)replaceCharactersInRange:(CPRange)aRange withString:(CPString)aString
|
||||
{
|
||||
if (!aString)
|
||||
aString = "";
|
||||
aString = @"";
|
||||
|
||||
var startingIndex = [self _indexOfEntryWithIndex:aRange.location],
|
||||
startingRangeEntry = _rangeEntries[startingIndex],
|
||||
endingIndex = [self _indexOfEntryWithIndex:MAX(CPMaxRange(aRange) - 1, 0)],
|
||||
endingRangeEntry = _rangeEntries[endingIndex],
|
||||
var startingIndex = [self _indexOfEntryWithIndex:aRange.location];
|
||||
|
||||
if (startingIndex === CPNotFound)
|
||||
_CPRaiseRangeException(self, _cmd, aRange.location, _string.length);
|
||||
|
||||
var startingRangeEntry = _rangeEntries[startingIndex],
|
||||
endingIndex = [self _indexOfEntryWithIndex:MAX(CPMaxRange(aRange) - 1, 0)];
|
||||
|
||||
if (endingIndex === CPNotFound)
|
||||
_CPRaiseRangeException(self, _cmd, MAX(CPMaxRange(aRange) - 1, 0), _string.length);
|
||||
|
||||
var endingRangeEntry = _rangeEntries[endingIndex],
|
||||
additionalLength = aString.length - aRange.length;
|
||||
|
||||
_string = _string.substring(0, aRange.location) + aString + _string.substring(CPMaxRange(aRange));
|
||||
|
||||
if (startingIndex == endingIndex)
|
||||
if (startingIndex === endingIndex)
|
||||
startingRangeEntry.range.length += additionalLength;
|
||||
else
|
||||
{
|
||||
@@ -562,7 +587,7 @@
|
||||
endingEntryIndex = [self _indexOfRangeEntryForIndex:CPMaxRange(aRange) splitOnMaxIndex:YES],
|
||||
current = startingEntryIndex;
|
||||
|
||||
if (endingEntryIndex == CPNotFound)
|
||||
if (endingEntryIndex === CPNotFound)
|
||||
endingEntryIndex = _rangeEntries.length;
|
||||
|
||||
while (current < endingEntryIndex)
|
||||
@@ -588,7 +613,7 @@
|
||||
endingEntryIndex = [self _indexOfRangeEntryForIndex:CPMaxRange(aRange) splitOnMaxIndex:YES],
|
||||
current = startingEntryIndex;
|
||||
|
||||
if (endingEntryIndex == CPNotFound)
|
||||
if (endingEntryIndex === CPNotFound)
|
||||
endingEntryIndex = _rangeEntries.length;
|
||||
|
||||
while (current < endingEntryIndex)
|
||||
@@ -620,7 +645,7 @@
|
||||
*/
|
||||
- (void)addAttribute:(CPString)anAttribute value:(id)aValue range:(CPRange)aRange
|
||||
{
|
||||
[self addAttributes:[CPDictionary dictionaryWithObject:aValue forKey:anAttribute] range:aRange];
|
||||
[self addAttributes:@{ anAttribute: aValue } range:aRange];
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -635,7 +660,7 @@
|
||||
endingEntryIndex = [self _indexOfRangeEntryForIndex:CPMaxRange(aRange) splitOnMaxIndex:YES],
|
||||
current = startingEntryIndex;
|
||||
|
||||
if (endingEntryIndex == CPNotFound)
|
||||
if (endingEntryIndex === CPNotFound)
|
||||
endingEntryIndex = _rangeEntries.length;
|
||||
|
||||
while (current < endingEntryIndex)
|
||||
@@ -674,7 +699,7 @@
|
||||
otherRangeEntries = aString._rangeEntries,
|
||||
length = [aString length];
|
||||
|
||||
if (entryIndexOfNextEntry == CPNotFound)
|
||||
if (entryIndexOfNextEntry === CPNotFound)
|
||||
entryIndexOfNextEntry = _rangeEntries.length;
|
||||
|
||||
_string = _string.substring(0, anIndex) + aString._string + _string.substring(anIndex);
|
||||
@@ -734,12 +759,12 @@
|
||||
{
|
||||
var index = [self _indexOfEntryWithIndex:characterIndex];
|
||||
|
||||
if (index < 0)
|
||||
if (index === CPNotFound)
|
||||
return index;
|
||||
|
||||
var rangeEntry = _rangeEntries[index];
|
||||
|
||||
if (rangeEntry.range.location == characterIndex || (CPMaxRange(rangeEntry.range) - 1 == characterIndex && !split))
|
||||
if (rangeEntry.range.location === characterIndex || (CPMaxRange(rangeEntry.range) - 1 === characterIndex && !split))
|
||||
return index;
|
||||
|
||||
var newEntries = splitRangeEntryAtIndex(rangeEntry, characterIndex);
|
||||
@@ -805,9 +830,9 @@
|
||||
|
||||
@end
|
||||
|
||||
var isEqual = function isEqual(a, b)
|
||||
var isEqual = function(a, b)
|
||||
{
|
||||
if (a == b)
|
||||
if (a === b)
|
||||
return YES;
|
||||
|
||||
if ([a respondsToSelector:@selector(isEqual:)] && [a isEqual:b])
|
||||
@@ -816,17 +841,17 @@ var isEqual = function isEqual(a, b)
|
||||
return NO;
|
||||
};
|
||||
|
||||
var makeRangeEntry = function makeRangeEntry(/*CPRange*/aRange, /*CPDictionary*/attributes)
|
||||
var makeRangeEntry = function(/*CPRange*/aRange, /*CPDictionary*/attributes)
|
||||
{
|
||||
return {range:aRange, attributes:[attributes copy]};
|
||||
};
|
||||
|
||||
var copyRangeEntry = function copyRangeEntry(/*RangeEntry*/aRangeEntry)
|
||||
var copyRangeEntry = function(/*RangeEntry*/aRangeEntry)
|
||||
{
|
||||
return makeRangeEntry(CPMakeRangeCopy(aRangeEntry.range), [aRangeEntry.attributes copy]);
|
||||
};
|
||||
|
||||
var splitRangeEntryAtIndex = function splitRangeEntryAtIndex(/*RangeEntry*/aRangeEntry, /*unsigned*/anIndex)
|
||||
var splitRangeEntryAtIndex = function(/*RangeEntry*/aRangeEntry, /*unsigned*/anIndex)
|
||||
{
|
||||
var newRangeEntry = copyRangeEntry(aRangeEntry),
|
||||
cachedIndex = CPMaxRange(aRangeEntry.range);
|
||||
|
||||
@@ -20,8 +20,6 @@
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#import "Ref.h"
|
||||
|
||||
@import "CPDate.j"
|
||||
@import "CPString.j"
|
||||
@import "CPFormatter.j"
|
||||
@@ -104,7 +102,7 @@ CPDateFormatterFullStyle = 4;
|
||||
{
|
||||
// TODO Error handling.
|
||||
var value = [self dateFromString:aString];
|
||||
AT_DEREF(anObject, value);
|
||||
@deref(anObject) = value;
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
@@ -108,7 +108,7 @@ function CPDecimalMakeWithString(string, locale)
|
||||
// Regexp solution as found in JSON spec, with working regexp (I added groupings)
|
||||
// Test here: http://www.regexplanet.com/simple/index.html
|
||||
// Info from: http://stackoverflow.com/questions/638565/parsing-scientific-notation-sensibly
|
||||
// ([+\-]?)((?:0|[1-9]\d*)) - integer part, cant have leading zeros
|
||||
// ([+\-]?)((?:0|[0-9]\d*)) - integer part, can have leading zeros (follows Cocoa behaviour)
|
||||
// (?:\.(\d*))? - optional decimal part plus number in group
|
||||
// (?:[eE]([+\-]?)(\d+))? - optional exponent part plus number in group
|
||||
// group 0: string, 1: sign, 2: integer, 3: decimal, 4: exponent sign, 5: exponent
|
||||
@@ -116,7 +116,7 @@ function CPDecimalMakeWithString(string, locale)
|
||||
// Note: this doesn't accept .01 for example, should it?
|
||||
// If yes simply add '?' after integer part group, i.e. ([+\-]?)((?:0|[1-9]\d*)?)
|
||||
// Note: now it accept .01 style.
|
||||
var matches = string.match(/^([+\-]?)((?:0|[1-9]\d*)?)(?:\.(\d*))?(?:[eE]([+\-]?)(\d+))?$/);
|
||||
var matches = string.match(/^([+\-]?)((?:0|[0-9]\d*)?)(?:\.(\d*))?(?:[eE]([+\-]?)(\d+))?$/);
|
||||
|
||||
if (!matches)
|
||||
return CPDecimalMakeNaN();
|
||||
|
||||
@@ -0,0 +1,153 @@
|
||||
/*
|
||||
* CPDelayedPerform.j
|
||||
* Foundation
|
||||
*
|
||||
* Portions based on NSDelayedPerform.m (2013-03-03) in Cocotron (http://www.cocotron.org/)
|
||||
* Copyright (c) 2006-2007 Christopher J. W. Lloyd
|
||||
*
|
||||
* Created by Alexander Ljungberg.
|
||||
* Copyright 2013, SlevenBits Ltd.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
@import "CPObject.j"
|
||||
@import "CPRunLoop.j"
|
||||
@import "CPString.j"
|
||||
|
||||
@implementation CPDelayedPerform : CPObject
|
||||
{
|
||||
id _object;
|
||||
SEL _selector;
|
||||
id _argument;
|
||||
}
|
||||
|
||||
+ (CPDelayedPerform)delayedPerformWithObject:anObject selector:(SEL)aSelector argument:anArgument
|
||||
{
|
||||
return [[self alloc] initWithObject:anObject selector:aSelector argument:anArgument];
|
||||
}
|
||||
|
||||
- (id)initWithObject:(id)anObject selector:(SEL)aSelector argument:(id)anArgument
|
||||
{
|
||||
if (self = [super init])
|
||||
{
|
||||
_object = anObject;
|
||||
_selector = aSelector;
|
||||
_argument = anArgument;
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (BOOL)isEqualToPerform:(CPDelayedPerform)anOther
|
||||
{
|
||||
if (!anOther || !anOther.isa)
|
||||
return NO;
|
||||
|
||||
if (_object !== anOther._object)
|
||||
return NO;
|
||||
|
||||
if (!_selector || !anOther._selector)
|
||||
return YES;
|
||||
|
||||
if (_selector !== anOther._selector)
|
||||
return NO;
|
||||
|
||||
if (_argument !== anOther._argument)
|
||||
return NO;
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (void)perform
|
||||
{
|
||||
try
|
||||
{
|
||||
[_object performSelector:_selector withObject:_argument];
|
||||
}
|
||||
catch(ex)
|
||||
{
|
||||
CPLog(@"exception %@ raised during delayed perform", ex);
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation CPRunLoop(CPDelayedPerform)
|
||||
|
||||
- (void)invalidateTimerWithDelayedPerform:(CPDelayedPerform)aDelayedPerform
|
||||
{
|
||||
for (var aKey in _timersForModes)
|
||||
{
|
||||
if (!_timersForModes.hasOwnProperty(aKey))
|
||||
continue;
|
||||
|
||||
var timersForMode = _timersForModes[aKey];
|
||||
for (var i = 0, count = [timersForMode count]; i < count; i++)
|
||||
{
|
||||
var aTimer = [timersForMode objectAtIndex:i],
|
||||
userInfo = [aTimer userInfo];
|
||||
|
||||
if ([userInfo isKindOfClass:CPDelayedPerform] && [userInfo isEqualToPerform:aDelayedPerform])
|
||||
[aTimer invalidate];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation CPObject(CPDelayedPerform)
|
||||
|
||||
+ (void)cancelPreviousPerformRequestsWithTarget:target selector:(SEL)selector object:argument
|
||||
{
|
||||
var aDelayedPerform = [CPDelayedPerform delayedPerformWithObject:target selector:selector argument:argument];
|
||||
|
||||
[[CPRunLoop currentRunLoop] invalidateTimerWithDelayedPerform:aDelayedPerform];
|
||||
}
|
||||
|
||||
+ (void)cancelPreviousPerformRequestsWithTarget:target
|
||||
{
|
||||
var aDelayedPerform = [CPDelayedPerform delayedPerformWithObject:target selector:NULL argument:nil];
|
||||
|
||||
[[CPRunLoop currentRunLoop] invalidateTimerWithDelayedPerform:aDelayedPerform];
|
||||
}
|
||||
|
||||
+ (void)_delayedPerform:(CPTimer)aTimer
|
||||
{
|
||||
var aDelayedPerform = [aTimer userInfo];
|
||||
|
||||
[aDelayedPerform perform];
|
||||
}
|
||||
|
||||
+ (void)object:object performSelector:(SEL)selector withObject:argument afterDelay:(CPTimeInterval)delay inModes:(CPArray)modes
|
||||
{
|
||||
var aDelayedPerform = [CPDelayedPerform delayedPerformWithObject:object selector:selector argument:argument],
|
||||
aTimer = [CPTimer timerWithTimeInterval:delay target:[CPObject class] selector:@selector(_delayedPerform:) userInfo:aDelayedPerform repeats:NO];
|
||||
|
||||
for (var i = 0, count = [modes count]; i < count; i++)
|
||||
[[CPRunLoop currentRunLoop] addTimer:aTimer forMode:[modes objectAtIndex:i]];
|
||||
}
|
||||
|
||||
- (void)performSelector:(SEL)selector withObject:object afterDelay:(CPTimeInterval)delay
|
||||
{
|
||||
[[self class] object:self performSelector:selector withObject:object afterDelay:delay inModes:[CPArray arrayWithObject:CPDefaultRunLoopMode]];
|
||||
}
|
||||
|
||||
- (void)performSelector:(SEL)selector withObject:object afterDelay:(CPTimeInterval)delay inModes:(CPArray)modes
|
||||
{
|
||||
[[self class] object:self performSelector:selector withObject:object afterDelay:delay inModes:modes];
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -25,7 +25,9 @@
|
||||
@import "CPException.j"
|
||||
@import "CPNull.j"
|
||||
@import "CPObject.j"
|
||||
#import "Ref.h"
|
||||
|
||||
//FIXME: After release of 0.9.7 remove below variable
|
||||
var CPDictionaryShowNilDeprecationMessage = YES;
|
||||
|
||||
/* @ignore */
|
||||
@implementation _CPDictionaryValueEnumerator : CPEnumerator
|
||||
@@ -254,14 +256,43 @@
|
||||
self = [super init];
|
||||
|
||||
if ([objects count] != [keyArray count])
|
||||
[CPException raise:CPInvalidArgumentException reason:"Counts are different.(" + [objects count] + "!=" + [keyArray count] + ")"];
|
||||
[CPException raise:CPInvalidArgumentException reason:[CPString stringWithFormat:@"Counts are different.(%d != %d)", [objects count], [keyArray count]]];
|
||||
|
||||
if (self)
|
||||
{
|
||||
var i = [keyArray count];
|
||||
|
||||
while (i--)
|
||||
[self setObject:objects[i] forKey:keyArray[i]];
|
||||
{
|
||||
var value = objects[i],
|
||||
key = keyArray[i];
|
||||
|
||||
if (value === nil)
|
||||
{
|
||||
CPDictionaryShowNilDeprecationMessage = NO;
|
||||
CPLog.warn([CPString stringWithFormat:@"[%s %s] DEPRECATED: Attempt to insert nil object from objects[%d]", [self className], _cmd, i]);
|
||||
|
||||
if (typeof(objj_backtrace_print) === "function")
|
||||
objj_backtrace_print(CPLog.warn);
|
||||
|
||||
// FIXME: After release of 0.9.7 change this block to:
|
||||
// [CPException raise:CPInvalidArgumentException reason:@"Attempt to insert nil object from objects[" + i + @"]"];
|
||||
}
|
||||
|
||||
if (key === nil)
|
||||
{
|
||||
CPDictionaryShowNilDeprecationMessage = NO;
|
||||
CPLog.warn([CPString stringWithFormat:@"[%s %s] DEPRECATED: Attempt to insert nil key from keys[%d]", [self className], _cmd, i]);
|
||||
|
||||
if (typeof(objj_backtrace_print) === "function")
|
||||
objj_backtrace_print(CPLog.warn);
|
||||
|
||||
// FIXME: After release of 0.9.7 change this block to:
|
||||
// [CPException raise:CPInvalidArgumentException reason:@"Attempt to insert nil key from keys[" + i + @"]"];
|
||||
}
|
||||
|
||||
[self setObject:value forKey:key];
|
||||
}
|
||||
}
|
||||
|
||||
return self;
|
||||
@@ -297,12 +328,34 @@
|
||||
|
||||
for (; index < argCount; index += 2)
|
||||
{
|
||||
var value = arguments[index];
|
||||
var value = arguments[index],
|
||||
key = arguments[index + 1];
|
||||
|
||||
if (value === nil)
|
||||
continue;
|
||||
{
|
||||
CPDictionaryShowNilDeprecationMessage = NO;
|
||||
CPLog.warn([CPString stringWithFormat:@"[%s %s] DEPRECATED: Attempt to insert nil object from objects[%d]", [self className], _cmd, (index / 2) - 1]);
|
||||
|
||||
[self setObject:value forKey:arguments[index + 1]];
|
||||
if (typeof(objj_backtrace_print) === "function")
|
||||
objj_backtrace_print(CPLog.warn);
|
||||
|
||||
// FIXME: After release of 0.9.7 change 3 lines above to this:
|
||||
// [CPException raise:CPInvalidArgumentException reason:@"Attempt to insert nil object from objects[" + ((index / 2) - 1) + @"]"];
|
||||
}
|
||||
|
||||
if (key === nil)
|
||||
{
|
||||
CPDictionaryShowNilDeprecationMessage = NO;
|
||||
CPLog.warn([CPString stringWithFormat:@"[%s %s] DEPRECATED: Attempt to insert nil key from keys[%d]", [self className], _cmd, (index / 2) - 1]);
|
||||
|
||||
if (typeof(objj_backtrace_print) === "function")
|
||||
objj_backtrace_print(CPLog.warn);
|
||||
|
||||
// FIXME: After release of 0.9.7 change 3 lines above to this:
|
||||
// [CPException raise:CPInvalidArgumentException reason:@"Attempt to insert nil key from keys[" + ((index / 2) - 1) + @"]"];
|
||||
}
|
||||
|
||||
[self setObject:value forKey:key];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -405,7 +458,7 @@
|
||||
key = nil,
|
||||
value = nil,
|
||||
shouldStop = NO,
|
||||
stopRef = AT_REF(shouldStop);
|
||||
stopRef = @ref(shouldStop);
|
||||
|
||||
for (; index !== stop; index += increment)
|
||||
{
|
||||
@@ -611,6 +664,35 @@
|
||||
*/
|
||||
- (void)setObject:(id)anObject forKey:(id)aKey
|
||||
{
|
||||
// FIXME: After release of 0.9.7, remove this test and leave the contents of its block
|
||||
if (CPDictionaryShowNilDeprecationMessage)
|
||||
{
|
||||
if (aKey === nil)
|
||||
{
|
||||
CPLog.warn([CPString stringWithFormat:@"[%s %s] DEPRECATED: key cannot be nil", [self className], _cmd]);
|
||||
|
||||
if (typeof(objj_backtrace_print) === "function")
|
||||
objj_backtrace_print(CPLog.warn);
|
||||
|
||||
// FIXME: After release of 0.9.7 change this block to:
|
||||
// [CPException raise:CPInvalidArgumentException reason:@"key cannot be nil"];
|
||||
}
|
||||
|
||||
if (anObject === nil)
|
||||
{
|
||||
CPLog.warn([CPString stringWithFormat:@"[%s %s] DEPRECATED: object cannot be nil (key: %s)", [self className], _cmd, aKey]);
|
||||
|
||||
if (typeof(objj_backtrace_print) === "function")
|
||||
objj_backtrace_print(CPLog.warn);
|
||||
|
||||
// FIXME: After release of 0.9.7 change this block to:
|
||||
// [CPException raise:CPInvalidArgumentException reason:@"object cannot be nil (key: " + aKey + @")"];
|
||||
}
|
||||
}
|
||||
// FIXME: After release of 0.9.7 remove 2 lines below.
|
||||
else
|
||||
CPDictionaryShowNilDeprecationMessage = YES;
|
||||
|
||||
self.setValueForKey(aKey, anObject);
|
||||
}
|
||||
|
||||
@@ -666,7 +748,7 @@
|
||||
- (void)enumerateKeysAndObjectsUsingBlock:(Function /*(id aKey, id anObject, @ref BOOL stop)*/)aFunction
|
||||
{
|
||||
var shouldStop = NO,
|
||||
shouldStopRef = AT_REF(shouldStop),
|
||||
shouldStopRef = @ref(shouldStop),
|
||||
keys = self._keys,
|
||||
count = self._count;
|
||||
|
||||
|
||||
+11
-13
@@ -33,8 +33,6 @@
|
||||
make sure that you cannot configure the public subclasses CPDateFormatter and CPNumberFormatter to satisfy your requirements.
|
||||
*/
|
||||
|
||||
#import "Ref.h"
|
||||
|
||||
@import "CPException.j"
|
||||
@import "CPObject.j"
|
||||
|
||||
@@ -124,10 +122,10 @@
|
||||
*/
|
||||
- (BOOL)isPartialStringValid:(CPString)aPartialString newEditingString:(CPStringRef)aNewString errorDescription:(CPStringRef)anError
|
||||
{
|
||||
AT_DEREF(aPartialString, nil);
|
||||
@deref(aPartialString) = nil;
|
||||
|
||||
if (anError)
|
||||
AT_DEREF(anError, nil);
|
||||
@deref(anError) = nil;
|
||||
|
||||
return YES;
|
||||
}
|
||||
@@ -137,32 +135,32 @@
|
||||
not necessarily at the end of the string, and preserve the selection (or set a different one, such as selecting the erroneous part of
|
||||
the string the user has typed).
|
||||
|
||||
In a subclass implementation, evaluate aPartialString according to the context. Return \c YES if aPartialString is acceptable and \c NO if aPartialString
|
||||
is unacceptable. Assign a new string by reference to aPartialString and a new range by reference to aProposedSelectedRange and return \c NO if you want to replace the string and
|
||||
In a subclass implementation, evaluate aPartialStringRef according to the context. Return \c YES if aPartialStringRef is acceptable and \c NO if aPartialStringRef
|
||||
is unacceptable. Assign a new string by reference to aPartialStringRef and a new range by reference to aProposedSelectedRangeRef and return \c NO if you want to replace the string and
|
||||
change the selection range. If you return \c NO, you can also return by reference a CPString object (in anError) that explains the reason why the
|
||||
validation failed; the delegate (if any) of the CPControl can then respond to the failure in
|
||||
control:didFailToValidatePartialString:errorDescription:.
|
||||
|
||||
@param aPartialString The new string to validate.
|
||||
@param aProposedSelectedRange The selection range that will be used if the string is accepted or replaced.
|
||||
@param aPartialStringRef The new string to validate.
|
||||
@param aProposedSelectedRangeRef The selection range that will be used if the string is accepted or replaced.
|
||||
@param originalString The original string, before the proposed change.
|
||||
@param originalSelectedRange The selection range over which the change is to take place.
|
||||
@param anError If non-nil, if validation fails contains an CPString object that describes the problem.
|
||||
@return \c YES if aPartialString is acceptable, otherwise \c NO.
|
||||
@return \c YES if aPartialStringRef is acceptable, otherwise \c NO.
|
||||
|
||||
*/
|
||||
- (BOOL)isPartialStringValid:(CPStringRef)aPartialString proposedSelectedRange:(CPRangeRef)aProposedSelectedRange originalString:(CPString)originalString originalSelectedRange:(CPRange)originalSelectedRange errorDescription:(CPStringRef)anError
|
||||
- (BOOL)isPartialStringValid:(CPStringRef)aPartialStringRef proposedSelectedRange:(CPRangeRef)aProposedSelectedRangeRef originalString:(CPString)originalString originalSelectedRange:(CPRange)originalSelectedRange errorDescription:(CPStringRef)anError
|
||||
{
|
||||
var newString = nil,
|
||||
valid = [self isPartialStringValid:aPartialString newEditingString:AT_REF(newString) errorDescription:anError];
|
||||
valid = [self isPartialStringValid:aPartialStringRef newEditingString:@ref(newString) errorDescription:anError];
|
||||
|
||||
if (!valid)
|
||||
{
|
||||
AT_DEREF(aPartialString, newString);
|
||||
@deref(aPartialStringRef) = newString;
|
||||
|
||||
// If a new string is passed back, the selection is always put at the end
|
||||
if (newString !== nil)
|
||||
AT_DEREF(aProposedSelectedRange, CPMakeRange(newString.length, 0));
|
||||
@deref(aProposedSelectedRangeRef) = CPMakeRange(newString.length, 0);
|
||||
}
|
||||
|
||||
return valid;
|
||||
|
||||
@@ -548,7 +548,7 @@
|
||||
{
|
||||
if (_CPLocationInRange(rangeIndex, enumerationRange))
|
||||
{
|
||||
aFunction(rangeIndex, AT_REF(shouldStop));
|
||||
aFunction(rangeIndex, @ref(shouldStop));
|
||||
if (shouldStop)
|
||||
return;
|
||||
}
|
||||
@@ -629,7 +629,7 @@
|
||||
{
|
||||
if (_CPLocationInRange(rangeIndex, aRange))
|
||||
{
|
||||
if (aPredicate(rangeIndex, AT_REF(shouldStop)))
|
||||
if (aPredicate(rangeIndex, @ref(shouldStop)))
|
||||
return rangeIndex;
|
||||
|
||||
if (shouldStop)
|
||||
@@ -690,7 +690,7 @@
|
||||
{
|
||||
if (_CPLocationInRange(rangeIndex, aRange))
|
||||
{
|
||||
if (aPredicate(rangeIndex, AT_REF(shouldStop)))
|
||||
if (aPredicate(rangeIndex, @ref(shouldStop)))
|
||||
[indexesPassingTest addIndex:rangeIndex];
|
||||
|
||||
if (shouldStop)
|
||||
|
||||
@@ -144,7 +144,7 @@ var CPObjectAccessorsForClassKey = @"$CPObjectAccessorsForClassKey",
|
||||
{
|
||||
var index = 0,
|
||||
count = keys.length,
|
||||
dictionary = [CPDictionary dictionary];
|
||||
dictionary = @{};
|
||||
|
||||
for (; index < count; ++index)
|
||||
{
|
||||
@@ -165,7 +165,7 @@ var CPObjectAccessorsForClassKey = @"$CPObjectAccessorsForClassKey",
|
||||
{
|
||||
[[CPException exceptionWithName:CPUndefinedKeyException
|
||||
reason:[self _objectDescription] + " is not key value coding-compliant for the key " + aKey
|
||||
userInfo:[CPDictionary dictionaryWithObjects:[self, aKey] forKeys:[CPTargetObjectUserInfoKey, CPUnknownUserInfoKey]]] raise];
|
||||
userInfo:@{ CPTargetObjectUserInfoKey: self, CPUnknownUserInfoKey: aKey }] raise];
|
||||
}
|
||||
|
||||
- (void)setValue:(id)aValue forKeyPath:(CPString)aKeyPath
|
||||
@@ -258,7 +258,7 @@ var CPObjectAccessorsForClassKey = @"$CPObjectAccessorsForClassKey",
|
||||
{
|
||||
[[CPException exceptionWithName:CPUndefinedKeyException
|
||||
reason:[self _objectDescription] + " is not key value coding-compliant for the key " + aKey
|
||||
userInfo:[CPDictionary dictionaryWithObjects:[self, aKey] forKeys:[CPTargetObjectUserInfoKey, CPUnknownUserInfoKey]]] raise];
|
||||
userInfo:@{ CPTargetObjectUserInfoKey: self, CPUnknownUserInfoKey: aKey }] raise];
|
||||
}
|
||||
|
||||
- (CPString)_objectDescription
|
||||
|
||||
@@ -755,7 +755,7 @@ var kvoNewAndOld = CPKeyValueObservingOptionNew | CPKeyValueObservingOpti
|
||||
|
||||
if (!observers)
|
||||
{
|
||||
observers = [CPDictionary dictionary];
|
||||
observers = @{};
|
||||
_observersForKey[aPath] = observers;
|
||||
_observersForKeyLength++;
|
||||
}
|
||||
@@ -769,7 +769,7 @@ var kvoNewAndOld = CPKeyValueObservingOptionNew | CPKeyValueObservingOpti
|
||||
if (newValue === nil || newValue === undefined)
|
||||
newValue = [CPNull null];
|
||||
|
||||
var changes = [CPDictionary dictionaryWithObject:newValue forKey:CPKeyValueChangeNewKey];
|
||||
var changes = @{ CPKeyValueChangeNewKey: newValue };
|
||||
[anObserver observeValueForKeyPath:aPath ofObject:_targetObject change:changes context:aContext];
|
||||
}
|
||||
}
|
||||
@@ -1006,7 +1006,7 @@ var kvoNewAndOld = CPKeyValueObservingOptionNew | CPKeyValueObservingOpti
|
||||
if (!aKey)
|
||||
return;
|
||||
|
||||
var changeOptions = [CPDictionary dictionaryWithObject:CPKeyValueChangeSetting forKey:CPKeyValueChangeKindKey];
|
||||
var changeOptions = @{ CPKeyValueChangeKindKey: CPKeyValueChangeSetting };
|
||||
|
||||
[[_CPKVOProxy proxyForObject:self] _sendNotificationsForKey:aKey changeOptions:changeOptions isBefore:YES];
|
||||
}
|
||||
@@ -1036,7 +1036,7 @@ var kvoNewAndOld = CPKeyValueObservingOptionNew | CPKeyValueObservingOpti
|
||||
if (!aKey)
|
||||
return;
|
||||
|
||||
var changeOptions = [CPDictionary dictionaryWithObjects:[change, indexes] forKeys:[CPKeyValueChangeKindKey, CPKeyValueChangeIndexesKey]];
|
||||
var changeOptions = @{ CPKeyValueChangeKindKey: change, CPKeyValueChangeIndexesKey: indexes };
|
||||
|
||||
[[_CPKVOProxy proxyForObject:self] _sendNotificationsForKey:aKey changeOptions:changeOptions isBefore:YES];
|
||||
}
|
||||
@@ -1067,7 +1067,7 @@ var kvoNewAndOld = CPKeyValueObservingOptionNew | CPKeyValueObservingOpti
|
||||
return;
|
||||
|
||||
var changeKind = _changeKindForSetMutationKind(mutationKind),
|
||||
changeOptions = [CPDictionary dictionaryWithObject:changeKind forKey:CPKeyValueChangeKindKey];
|
||||
changeOptions = @{ CPKeyValueChangeKindKey: changeKind };
|
||||
//set hidden change-dict ivars to support unordered to-many relationships
|
||||
changeOptions[_CPKeyValueChangeSetMutationObjectsKey] = objects;
|
||||
changeOptions[_CPKeyValueChangeSetMutationKindKey] = mutationKind;
|
||||
@@ -1215,10 +1215,11 @@ var kvoNewAndOld = CPKeyValueObservingOptionNew | CPKeyValueObservingOpti
|
||||
{
|
||||
var oldValue = [_value valueForKeyPath:_secondPart],
|
||||
newValue = [_object valueForKeyPath:_firstPart + "." + _secondPart],
|
||||
pathChanges = [CPDictionary dictionaryWithObjectsAndKeys:
|
||||
newValue ? newValue : [CPNull null], CPKeyValueChangeNewKey,
|
||||
oldValue ? oldValue : [CPNull null], CPKeyValueChangeOldKey,
|
||||
CPKeyValueChangeSetting, CPKeyValueChangeKindKey];
|
||||
pathChanges = @{
|
||||
CPKeyValueChangeNewKey: newValue ? newValue : [CPNull null],
|
||||
CPKeyValueChangeOldKey: oldValue ? oldValue : [CPNull null],
|
||||
CPKeyValueChangeKindKey: CPKeyValueChangeSetting,
|
||||
};
|
||||
|
||||
[_observer observeValueForKeyPath:_firstPart + "." + _secondPart ofObject:_object change:pathChanges context:_context];
|
||||
|
||||
|
||||
@@ -132,7 +132,7 @@ var _CPKeyedArchiverStringClass = Nil,
|
||||
_CPKeyedArchiverStringClass = [CPString class];
|
||||
_CPKeyedArchiverNumberClass = [CPNumber class];
|
||||
|
||||
_CPKeyedArchiverNullReference = [CPDictionary dictionaryWithObject:0 forKey:_CPKeyedArchiverUIDKey];
|
||||
_CPKeyedArchiverNullReference = @{ _CPKeyedArchiverUIDKey: 0 };
|
||||
}
|
||||
|
||||
+ (BOOL)allowsKeyedCoding
|
||||
@@ -172,12 +172,12 @@ var _CPKeyedArchiverStringClass = Nil,
|
||||
|
||||
_objects = [];
|
||||
|
||||
_UIDs = [CPDictionary dictionary];
|
||||
_conditionalUIDs = [CPDictionary dictionary];
|
||||
_UIDs = @{};
|
||||
_conditionalUIDs = @{};
|
||||
|
||||
_replacementObjects = [CPDictionary dictionary];
|
||||
_replacementObjects = @{};
|
||||
|
||||
_plistObject = [CPDictionary dictionary];
|
||||
_plistObject = @{};
|
||||
_plistObjects = [CPArray arrayWithObject:_CPKeyedArchiverNullString];
|
||||
}
|
||||
|
||||
@@ -212,7 +212,7 @@ var _CPKeyedArchiverStringClass = Nil,
|
||||
[_delegate archiver:self didEncodeObject:object];
|
||||
}
|
||||
|
||||
_plistObject = [CPDictionary dictionary];
|
||||
_plistObject = @{};
|
||||
|
||||
[_plistObject setObject:topObject forKey:_CPKeyedArchiverTopKey];
|
||||
[_plistObject setObject:_plistObjects forKey:_CPKeyedArchiverObjectsKey];
|
||||
@@ -395,7 +395,7 @@ var _CPKeyedArchiverStringClass = Nil,
|
||||
{
|
||||
var key,
|
||||
keys = [aDictionary keyEnumerator],
|
||||
references = [CPDictionary dictionary];
|
||||
references = @{};
|
||||
|
||||
while ((key = [keys nextObject]) !== nil)
|
||||
[references setObject:_CPKeyedArchiverEncodeObject(self, [aDictionary objectForKey:key], NO) forKey:key];
|
||||
@@ -414,7 +414,7 @@ var _CPKeyedArchiverStringClass = Nil,
|
||||
+ (void)setClassName:(CPString)aClassName forClass:(Class)aClass
|
||||
{
|
||||
if (!CPArchiverReplacementClassNames)
|
||||
CPArchiverReplacementClassNames = [CPDictionary dictionary];
|
||||
CPArchiverReplacementClassNames = @{};
|
||||
|
||||
[CPArchiverReplacementClassNames setObject:aClassName forKey:CPStringFromClass(aClass)];
|
||||
}
|
||||
@@ -446,7 +446,7 @@ var _CPKeyedArchiverStringClass = Nil,
|
||||
- (void)setClassName:(CPString)aClassName forClass:(Class)aClass
|
||||
{
|
||||
if (!_replacementClassNames)
|
||||
_replacementClassNames = [CPDictionary dictionary];
|
||||
_replacementClassNames = @{};
|
||||
|
||||
[_replacementClassNames setObject:aClassName forKey:CPStringFromClass(aClass)];
|
||||
}
|
||||
@@ -503,7 +503,8 @@ var _CPKeyedArchiverEncodeObject = function(self, anObject, isConditional)
|
||||
}
|
||||
}
|
||||
|
||||
[self._replacementObjects setObject:object forKey:GUID];
|
||||
if (object != nil && GUID != nil)
|
||||
[self._replacementObjects setObject:object forKey:GUID];
|
||||
}
|
||||
|
||||
// If we still don't have an object by this point, then return a
|
||||
@@ -541,7 +542,7 @@ var _CPKeyedArchiverEncodeObject = function(self, anObject, isConditional)
|
||||
else
|
||||
{
|
||||
// Only actually encode the object and create a plist representation if it is not a simple type.
|
||||
plistObject = [CPDictionary dictionary];
|
||||
plistObject = @{};
|
||||
|
||||
[self._objects addObject:object];
|
||||
|
||||
@@ -559,7 +560,7 @@ var _CPKeyedArchiverEncodeObject = function(self, anObject, isConditional)
|
||||
|
||||
if (!classUID)
|
||||
{
|
||||
var plistClass = [CPDictionary dictionary],
|
||||
var plistClass = @{},
|
||||
hierarchy = [];
|
||||
|
||||
[plistClass setObject:className forKey:_CPKeyedArchiverClassNameKey];
|
||||
@@ -576,7 +577,7 @@ var _CPKeyedArchiverEncodeObject = function(self, anObject, isConditional)
|
||||
[self._UIDs setObject:classUID forKey:className];
|
||||
}
|
||||
|
||||
[plistObject setObject:[CPDictionary dictionaryWithObject:classUID forKey:_CPKeyedArchiverUIDKey] forKey:_CPKeyedArchiverClassKey];
|
||||
[plistObject setObject:@{ _CPKeyedArchiverUIDKey: classUID } forKey:_CPKeyedArchiverClassKey];
|
||||
}
|
||||
|
||||
UID = [self._conditionalUIDs objectForKey:GUID];
|
||||
@@ -595,5 +596,5 @@ var _CPKeyedArchiverEncodeObject = function(self, anObject, isConditional)
|
||||
}
|
||||
}
|
||||
|
||||
return [CPDictionary dictionaryWithObject:UID forKey:_CPKeyedArchiverUIDKey];
|
||||
return @{ _CPKeyedArchiverUIDKey: UID };
|
||||
};
|
||||
|
||||
@@ -65,7 +65,7 @@ var CPNotificationDefaultCenter = nil;
|
||||
|
||||
if (self)
|
||||
{
|
||||
_namedRegistries = [CPDictionary dictionary];
|
||||
_namedRegistries = @{};
|
||||
_unnamedRegistry = [[_CPNotificationRegistry alloc] init];
|
||||
}
|
||||
return self;
|
||||
@@ -189,7 +189,7 @@ var _CPNotificationCenterPostNotification = function(/* CPNotificationCenter */
|
||||
|
||||
if (self)
|
||||
{
|
||||
_objectObservers = [CPDictionary dictionary];
|
||||
_objectObservers = @{};
|
||||
}
|
||||
|
||||
return self;
|
||||
|
||||
@@ -20,8 +20,6 @@
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#import "Ref.h"
|
||||
|
||||
@import "CPString.j"
|
||||
@import "CPFormatter.j"
|
||||
@import "CPDecimalNumber.j"
|
||||
@@ -63,6 +61,8 @@ var NumberRegex = new RegExp('(-)?(\\d*)(\\.(\\d*))?');
|
||||
CPNumberFormatterRoundingMode _roundingMode @accessors(property=roundingMode);
|
||||
CPUInteger _minimumFractionDigits @accessors(property=minimumFractionDigits);
|
||||
CPUInteger _maximumFractionDigits @accessors(property=maximumFractionDigits);
|
||||
CPUInteger _minimum @accessors(property=minimum);
|
||||
CPUInteger _maximum @accessors(property=maximum);
|
||||
CPString _currencyCode @accessors(property=currencyCode);
|
||||
CPString _currencySymbol @accessors(property=currencySymbol);
|
||||
BOOL _generatesDecimalNumbers @accessors(property=generatesDecimalNumbers);
|
||||
@@ -81,6 +81,8 @@ var NumberRegex = new RegExp('(-)?(\\d*)(\\.(\\d*))?');
|
||||
_maximumFractionDigits = 0;
|
||||
_groupingSeparator = @",";
|
||||
_generatesDecimalNumbers = YES;
|
||||
_minimum = nil;
|
||||
_maximum = nil;
|
||||
|
||||
// FIXME Add locale support.
|
||||
_currencyCode = @"USD";
|
||||
@@ -179,11 +181,35 @@ var NumberRegex = new RegExp('(-)?(\\d*)(\\.(\\d*))?');
|
||||
return [self stringForObjectValue:anObject];
|
||||
}
|
||||
|
||||
- (BOOL)getObjectValue:(id)anObject forString:(CPString)aString errorDescription:(CPString)anError
|
||||
- (BOOL)getObjectValue:(id)anObjectRef forString:(CPString)aString errorDescription:(CPString)anErrorRef
|
||||
{
|
||||
// TODO Error handling.
|
||||
var value = [self numberFromString:aString];
|
||||
AT_DEREF(anObject, value);
|
||||
// Interpret an empty string as nil, like in Cocoa.
|
||||
if (aString === @"")
|
||||
{
|
||||
@deref(anObjectRef) = nil;
|
||||
return YES;
|
||||
}
|
||||
|
||||
var value = [self numberFromString:aString],
|
||||
error = @"";
|
||||
|
||||
// this will return false if we've received anything but a number, most likely NaN
|
||||
if (!isFinite(value))
|
||||
error = @"Value is not a number";
|
||||
else if (_minimum !== nil && value < _minimum)
|
||||
error = @"Value is less than the minimum allowed value";
|
||||
else if (_maximum !== nil && value > _maximum)
|
||||
error = @"Value is greater than the maximum allowed value";
|
||||
|
||||
if (error)
|
||||
{
|
||||
if (anErrorRef)
|
||||
@deref(anErrorRef) = error;
|
||||
|
||||
return NO;
|
||||
}
|
||||
|
||||
@deref(anObjectRef) = value;
|
||||
|
||||
return YES;
|
||||
}
|
||||
@@ -226,12 +252,29 @@ var NumberRegex = new RegExp('(-)?(\\d*)(\\.(\\d*))?');
|
||||
SET_NEEDS_NUMBER_HANDLER_UPDATE();
|
||||
}
|
||||
|
||||
- (void)setMinimum:(CPUInteger)aNumber
|
||||
{
|
||||
_minimum = aNumber;
|
||||
SET_NEEDS_NUMBER_HANDLER_UPDATE();
|
||||
}
|
||||
|
||||
- (void)setMaximum:(CPUInteger)aNumber
|
||||
{
|
||||
_maximum = aNumber;
|
||||
SET_NEEDS_NUMBER_HANDLER_UPDATE();
|
||||
}
|
||||
|
||||
#pragma mark Private
|
||||
|
||||
- (void)_updateNumberHandlerIfNecessary
|
||||
{
|
||||
if (!_numberHandler)
|
||||
_numberHandler = [CPDecimalNumberHandler decimalNumberHandlerWithRoundingMode:_roundingMode scale:_maximumFractionDigits raiseOnExactness:NO raiseOnOverflow:NO raiseOnUnderflow:NO raiseOnDivideByZero:YES];
|
||||
_numberHandler = [CPDecimalNumberHandler decimalNumberHandlerWithRoundingMode:_roundingMode
|
||||
scale:_maximumFractionDigits
|
||||
raiseOnExactness:NO
|
||||
raiseOnOverflow:NO
|
||||
raiseOnUnderflow:NO
|
||||
raiseOnDivideByZero:YES];
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -239,6 +282,8 @@ var NumberRegex = new RegExp('(-)?(\\d*)(\\.(\\d*))?');
|
||||
var CPNumberFormatterStyleKey = @"CPNumberFormatterStyleKey",
|
||||
CPNumberFormatterMinimumFractionDigitsKey = @"CPNumberFormatterMinimumFractionDigitsKey",
|
||||
CPNumberFormatterMaximumFractionDigitsKey = @"CPNumberFormatterMaximumFractionDigitsKey",
|
||||
CPNumberFormatterMinimumKey = @"CPNumberFormatterMinimumKey",
|
||||
CPNumberFormatterMaximumKey = @"CPNumberFormatterMaximumKey",
|
||||
CPNumberFormatterRoundingModeKey = @"CPNumberFormatterRoundingModeKey",
|
||||
CPNumberFormatterGroupingSeparatorKey = @"CPNumberFormatterGroupingSeparatorKey",
|
||||
CPNumberFormatterCurrencyCodeKey = @"CPNumberFormatterCurrencyCodeKey",
|
||||
@@ -256,6 +301,8 @@ var CPNumberFormatterStyleKey = @"CPNumberFormatterStyleKey",
|
||||
_numberStyle = [aCoder decodeIntForKey:CPNumberFormatterStyleKey];
|
||||
_minimumFractionDigits = [aCoder decodeIntForKey:CPNumberFormatterMinimumFractionDigitsKey];
|
||||
_maximumFractionDigits = [aCoder decodeIntForKey:CPNumberFormatterMaximumFractionDigitsKey];
|
||||
_minimum = [aCoder decodeIntForKey:CPNumberFormatterMinimumKey];
|
||||
_maximum = [aCoder decodeIntForKey:CPNumberFormatterMaximumKey];
|
||||
_roundingMode = [aCoder decodeIntForKey:CPNumberFormatterRoundingModeKey];
|
||||
_groupingSeparator = [aCoder decodeObjectForKey:CPNumberFormatterGroupingSeparatorKey];
|
||||
_currencyCode = [aCoder decodeObjectForKey:CPNumberFormatterCurrencyCodeKey];
|
||||
@@ -273,6 +320,8 @@ var CPNumberFormatterStyleKey = @"CPNumberFormatterStyleKey",
|
||||
[aCoder encodeInt:_numberStyle forKey:CPNumberFormatterStyleKey];
|
||||
[aCoder encodeInt:_minimumFractionDigits forKey:CPNumberFormatterMinimumFractionDigitsKey];
|
||||
[aCoder encodeInt:_maximumFractionDigits forKey:CPNumberFormatterMaximumFractionDigitsKey];
|
||||
[aCoder encodeInt:_minimum forKey:CPNumberFormatterMinimumKey];
|
||||
[aCoder encodeInt:_maximum forKey:CPNumberFormatterMaximumKey];
|
||||
[aCoder encodeInt:_roundingMode forKey:CPNumberFormatterRoundingModeKey];
|
||||
[aCoder encodeObject:_groupingSeparator forKey:CPNumberFormatterGroupingSeparatorKey];
|
||||
[aCoder encodeObject:_currencyCode forKey:CPNumberFormatterCurrencyCodeKey];
|
||||
|
||||
@@ -279,15 +279,6 @@
|
||||
|
||||
@end
|
||||
|
||||
#define REFERENCE(variable) \
|
||||
function(newValue)\
|
||||
{\
|
||||
var oldValue = variable;\
|
||||
if (typeof newValue != 'undefined')\
|
||||
variable = newValue;\
|
||||
return oldValue;\
|
||||
}
|
||||
|
||||
@implementation CPPredicateScanner : CPScanner
|
||||
{
|
||||
CPEnumerator _args;
|
||||
@@ -573,7 +564,7 @@ function(newValue)\
|
||||
ident,
|
||||
dbl;
|
||||
|
||||
if ([self scanDouble:REFERENCE(dbl)])
|
||||
if ([self scanDouble:@ref(dbl)])
|
||||
return [CPExpression expressionForConstantValue:dbl];
|
||||
|
||||
// FIXME: handle integer, hex constants, 0x 0o 0b
|
||||
@@ -706,7 +697,7 @@ function(newValue)\
|
||||
str = @"";
|
||||
|
||||
[self setCharactersToBeSkipped:nil];
|
||||
[self scanUpToString:@"\"" intoString:REFERENCE(str)];
|
||||
[self scanUpToString:@"\"" intoString:@ref(str)];
|
||||
|
||||
if ([self scanString:@"\"" intoString:NULL] == NO)
|
||||
CPRaiseParseError(self, @"expression");
|
||||
@@ -722,7 +713,7 @@ function(newValue)\
|
||||
str = @"";
|
||||
|
||||
[self setCharactersToBeSkipped:nil];
|
||||
[self scanUpToString:@"'" intoString:REFERENCE(str)];
|
||||
[self scanUpToString:@"'" intoString:@ref(str)];
|
||||
|
||||
if ([self scanString:@"'" intoString:NULL] == NO)
|
||||
CPRaiseParseError(self, @"expression");
|
||||
@@ -784,7 +775,7 @@ function(newValue)\
|
||||
if (!identifier)
|
||||
identifier = [CPCharacterSet characterSetWithCharactersInString:@"_$abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"];
|
||||
|
||||
if (![self scanCharactersFromSet:identifier intoString:REFERENCE(ident)])
|
||||
if (![self scanCharactersFromSet:identifier intoString:@ref(ident)])
|
||||
CPRaiseParseError(self, @"expression");
|
||||
|
||||
return [CPExpression expressionForKeyPath:ident];
|
||||
@@ -846,7 +837,7 @@ function(newValue)\
|
||||
if (![self scanString:@"(" intoString:NULL])
|
||||
{
|
||||
var str;
|
||||
[self scanCharactersFromSet:[CPCharacterSet lowercaseLetterCharacterSet] intoString:REFERENCE(str)];
|
||||
[self scanCharactersFromSet:[CPCharacterSet lowercaseLetterCharacterSet] intoString:@ref(str)];
|
||||
|
||||
if (![self scanString:@":(" intoString:NULL])
|
||||
CPRaiseParseError(self, @"expression");
|
||||
|
||||
@@ -55,7 +55,7 @@
|
||||
var collection = [_collection expressionValueWithObject:object context:context],
|
||||
count = [collection count],
|
||||
result = [CPArray array],
|
||||
bindings = [CPDictionary dictionaryWithObject:[CPExpression expressionForEvaluatedObject] forKey:[self variable]],
|
||||
bindings = @{ [self variable]: [CPExpression expressionForEvaluatedObject] },
|
||||
i = 0;
|
||||
|
||||
for (; i < count; i++)
|
||||
|
||||
@@ -270,7 +270,6 @@ var CPRunLoopLastNativeRunLoop = 0;
|
||||
|
||||
aTimer._lastNativeRunLoopsForModes[aMode] = CPRunLoopLastNativeRunLoop;
|
||||
|
||||
|
||||
// FIXME: Hack for not doing this in CommonJS
|
||||
if ([CFBundle.environments() indexOfObject:("Browser")] !== CPNotFound)
|
||||
{
|
||||
@@ -308,6 +307,7 @@ var CPRunLoopLastNativeRunLoop = 0;
|
||||
nextTimerFireDate = _nextTimerFireDatesForModes[aMode];
|
||||
|
||||
// Perform Timers if necessary
|
||||
|
||||
if (_didAddTimer || nextTimerFireDate && nextTimerFireDate <= now)
|
||||
{
|
||||
_didAddTimer = NO;
|
||||
@@ -326,12 +326,16 @@ var CPRunLoopLastNativeRunLoop = 0;
|
||||
|
||||
_timersForModes[aMode] = nil;
|
||||
|
||||
// Loop through timers looking for ones that had fired
|
||||
// If we're running in CommonJS (unit tests) we shouldn't wait for at least 1 native run loop
|
||||
// since those will never happen.
|
||||
var hasNativeTimers = [CFBundle.environments() indexOfObject:("Browser")] !== CPNotFound;
|
||||
|
||||
// Loop through timers looking for ones that had fired
|
||||
while (index--)
|
||||
{
|
||||
var timer = timers[index];
|
||||
|
||||
if (timer._lastNativeRunLoopsForModes[aMode] < CPRunLoopLastNativeRunLoop && timer._isValid && timer._fireDate <= now)
|
||||
if ((!hasNativeTimers || timer._lastNativeRunLoopsForModes[aMode] < CPRunLoopLastNativeRunLoop) && timer._isValid && timer._fireDate <= now)
|
||||
[timer fire];
|
||||
|
||||
// Timer may or may not still be valid
|
||||
|
||||
@@ -77,7 +77,7 @@
|
||||
|
||||
_HTTPBody = @"";
|
||||
_HTTPMethod = @"GET";
|
||||
_HTTPHeaderFields = [CPDictionary dictionary];
|
||||
_HTTPHeaderFields = @{};
|
||||
|
||||
[self setValue:"Thu, 01 Jan 1970 00:00:00 GMT" forHTTPHeaderField:"If-Modified-Since"];
|
||||
[self setValue:"no-cache" forHTTPHeaderField:"Cache-Control"];
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user