Merge branch 'refs/heads/master' into slevenbits
No files matched your search
@@ -1,8 +1,6 @@
|
||||
language: node_js
|
||||
node_js:
|
||||
- 0.8
|
||||
before_install:
|
||||
- jdk_switcher use openjdk6
|
||||
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
|
||||
@@ -717,50 +717,40 @@ var bottomHeight = 71;
|
||||
|
||||
+ (id)themeAttributes
|
||||
{
|
||||
return [CPDictionary dictionaryWithObjects:[CGSizeMake(400.0, 110.0), CGInsetMake(15, 15, 15, 50), 6, 10,
|
||||
CPJustifiedTextAlignment, [CPColor blackColor], [CPFont boldSystemFontOfSize:13.0], [CPNull null], CGSizeMakeZero(),
|
||||
CPJustifiedTextAlignment, [CPColor blackColor], [CPFont systemFontOfSize:12.0], [CPNull null], CGSizeMakeZero(),
|
||||
CGPointMake(15, 12),
|
||||
[CPNull null],
|
||||
[CPNull null],
|
||||
[CPNull null],
|
||||
[CPNull null],
|
||||
[CPNull null],
|
||||
[CPNull null],
|
||||
0.0,
|
||||
0.0,
|
||||
3.0,
|
||||
[CPColor blackColor],
|
||||
[CPFont systemFontOfSize:12.0],
|
||||
[CPNull null],
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
]
|
||||
forKeys:[@"size", @"content-inset", @"informative-offset", @"button-offset",
|
||||
@"message-text-alignment", @"message-text-color", @"message-text-font", @"message-text-shadow-color", @"message-text-shadow-offset",
|
||||
@"informative-text-alignment", @"informative-text-color", @"informative-text-font", @"informative-text-shadow-color", @"informative-text-shadow-offset",
|
||||
@"image-offset",
|
||||
@"information-image",
|
||||
@"warning-image",
|
||||
@"error-image",
|
||||
@"help-image",
|
||||
@"help-image-left-offset",
|
||||
@"help-image-pressed",
|
||||
@"suppression-button-y-offset",
|
||||
@"suppression-button-x-offset",
|
||||
@"default-elements-margin",
|
||||
@"suppression-button-text-color",
|
||||
@"suppression-button-text-font",
|
||||
@"suppression-button-text-shadow-color",
|
||||
@"suppression-button-text-shadow-offset",
|
||||
@"modal-window-button-margin-y",
|
||||
@"modal-window-button-margin-x",
|
||||
@"standard-window-button-margin-y",
|
||||
@"standard-window-button-margin-x"
|
||||
]];
|
||||
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"
|
||||
];
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -617,6 +617,14 @@ CPRunContinuesResponse = -1002;
|
||||
[[theWindow platformWindow] _propagateCurrentDOMEvent:willPropagate];
|
||||
#endif
|
||||
|
||||
if ([anEvent type] == CPMouseMoved)
|
||||
{
|
||||
if (theWindow !== _lastMouseMoveWindow)
|
||||
[_lastMouseMoveWindow _mouseExitedResizeRect];
|
||||
|
||||
_lastMouseMoveWindow = theWindow;
|
||||
}
|
||||
|
||||
if (_eventListeners.length)
|
||||
{
|
||||
var listener = _eventListeners[_eventListeners.length - 1];
|
||||
@@ -637,14 +645,6 @@ CPRunContinuesResponse = -1002;
|
||||
return;
|
||||
}
|
||||
|
||||
if ([anEvent type] == CPMouseMoved)
|
||||
{
|
||||
if (theWindow !== _lastMouseMoveWindow)
|
||||
[_lastMouseMoveWindow _mouseExitedResizeRect];
|
||||
|
||||
_lastMouseMoveWindow = theWindow;
|
||||
}
|
||||
|
||||
if (theWindow)
|
||||
[theWindow sendEvent:anEvent];
|
||||
}
|
||||
|
||||
@@ -897,7 +897,9 @@
|
||||
if (![self canAdd])
|
||||
return;
|
||||
|
||||
[self insert:sender];
|
||||
var newObject = [self automaticallyPreparesContent] ? [self newObject] : [self _defaultNewObject];
|
||||
|
||||
[self addObject:newObject];
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -909,9 +911,14 @@
|
||||
if (![self canInsert])
|
||||
return;
|
||||
|
||||
var newObject = [self automaticallyPreparesContent] ? [self newObject] : [self _defaultNewObject];
|
||||
var newObject = [self automaticallyPreparesContent] ? [self newObject] : [self _defaultNewObject],
|
||||
lastSelectedIndex = [_selectionIndexes lastIndex];
|
||||
|
||||
if (lastSelectedIndex)
|
||||
[self insertObject:newObject atArrangedObjectIndex:lastSelectedIndex];
|
||||
else
|
||||
[self addObject:newObject];
|
||||
|
||||
[self addObject:newObject];
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -1073,12 +1080,12 @@
|
||||
|
||||
@implementation CPArrayController (CPBinder)
|
||||
|
||||
+ (Class)_binderClassForBinding:(CPString)theBinding
|
||||
+ (Class)_binderClassForBinding:(CPString)aBinding
|
||||
{
|
||||
if (theBinding == @"contentArray")
|
||||
if (aBinding == @"contentArray")
|
||||
return [_CPArrayControllerContentBinder class];
|
||||
|
||||
return [super _binderClassForBinding:theBinding];
|
||||
return [super _binderClassForBinding:aBinding];
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -1114,6 +1121,7 @@
|
||||
}
|
||||
|
||||
var isPlaceholder = CPIsControllerMarker(newValue);
|
||||
|
||||
if (isPlaceholder)
|
||||
{
|
||||
if (newValue === CPNotApplicableMarker && [options objectForKey:CPRaisesForNotApplicableKeysBindingOption])
|
||||
|
||||
@@ -61,11 +61,11 @@ var DefaultLineWidth = 1.0;
|
||||
/*!
|
||||
Create a new CPBezierPath object initialized with an oval path drawn within a rectangular path.
|
||||
*/
|
||||
+ (CPBezierPath)bezierPathWithOvalInRect:(CGRect)rect
|
||||
+ (CPBezierPath)bezierPathWithOvalInRect:(CGRect)aRect
|
||||
{
|
||||
var path = [self bezierPath];
|
||||
|
||||
[path appendBezierPathWithOvalInRect:rect];
|
||||
[path appendBezierPathWithOvalInRect:aRect];
|
||||
|
||||
return path;
|
||||
}
|
||||
@@ -73,11 +73,20 @@ var DefaultLineWidth = 1.0;
|
||||
/*!
|
||||
Create a new CPBezierPath object initialized with a rectangular path.
|
||||
*/
|
||||
+ (CPBezierPath)bezierPathWithRect:(CGRect)rect
|
||||
+ (CPBezierPath)bezierPathWithRect:(CGRect)aRect
|
||||
{
|
||||
var path = [self bezierPath];
|
||||
|
||||
[path appendBezierPathWithRect:rect];
|
||||
[path appendBezierPathWithRect:aRect];
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
+ (CPBezierPath)bezierPathWithRoundedRect:(CGRect)aRect xRadius:(float)xRadius yRadius:(float)yRadius
|
||||
{
|
||||
var path = [self bezierPath];
|
||||
|
||||
[path appendBezierPathWithRoundedRect:aRect xRadius:xRadius yRadius:yRadius];
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
@@ -63,19 +63,12 @@ CPBelowBottom = 6;
|
||||
CPTextField _titleView;
|
||||
}
|
||||
|
||||
+ (id)boxEnclosingView:(CPView)aView
|
||||
+ (Class)_binderClassForBinding:(CPString)aBinding
|
||||
{
|
||||
var box = [[self alloc] initWithFrame:CGRectMakeZero()],
|
||||
enclosingView = [aView superview];
|
||||
if ([aBinding hasPrefix:CPDisplayPatternTitleBinding])
|
||||
return [CPTitleWithPatternBinding class];
|
||||
|
||||
[box setAutoresizingMask:[aView autoresizingMask]];
|
||||
[box setFrameFromContentFrame:[aView frame]];
|
||||
|
||||
[enclosingView replaceSubview:aView with:box];
|
||||
|
||||
[box setContentView:aView];
|
||||
|
||||
return box;
|
||||
return [super _binderClassForBinding:aBinding];
|
||||
}
|
||||
|
||||
+ (CPString)defaultThemeClass
|
||||
@@ -96,6 +89,21 @@ CPBelowBottom = 6;
|
||||
@"content-margin"]];
|
||||
}
|
||||
|
||||
+ (id)boxEnclosingView:(CPView)aView
|
||||
{
|
||||
var box = [[self alloc] initWithFrame:CGRectMakeZero()],
|
||||
enclosingView = [aView superview];
|
||||
|
||||
[box setAutoresizingMask:[aView autoresizingMask]];
|
||||
[box setFrameFromContentFrame:[aView frame]];
|
||||
|
||||
[enclosingView replaceSubview:aView with:box];
|
||||
|
||||
[box setContentView:aView];
|
||||
|
||||
return box;
|
||||
}
|
||||
|
||||
- (id)initWithFrame:(CGRect)frameRect
|
||||
{
|
||||
self = [super initWithFrame:frameRect];
|
||||
@@ -411,6 +419,14 @@ CPBelowBottom = 6;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)setValue:(id)aValue forKey:(CPString)aKey
|
||||
{
|
||||
if (aKey === CPDisplayPatternTitleBinding)
|
||||
[self setTitle:aValue || @""];
|
||||
else
|
||||
[super setValue:aValue forKey:aKey];
|
||||
}
|
||||
|
||||
- (void)drawRect:(CGRect)rect
|
||||
{
|
||||
var bounds = CGRectMakeCopy([self bounds]);
|
||||
@@ -421,9 +437,9 @@ CPBelowBottom = 6;
|
||||
// NSBox does not include a horizontal flag for the separator type. We have to determine
|
||||
// the type of separator to draw by the width and height of the frame.
|
||||
if (CGRectGetWidth(bounds) === 5.0)
|
||||
return [self _drawVerticalSeperatorInRect:bounds];
|
||||
return [self _drawVerticalSeparatorInRect:bounds];
|
||||
else if (CGRectGetHeight(bounds) === 5.0)
|
||||
return [self _drawHorizontalSeperatorInRect:bounds];
|
||||
return [self _drawHorizontalSeparatorInRect:bounds];
|
||||
|
||||
break;
|
||||
}
|
||||
@@ -462,7 +478,7 @@ CPBelowBottom = 6;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)_drawHorizontalSeperatorInRect:(CGRect)aRect
|
||||
- (void)_drawHorizontalSeparatorInRect:(CGRect)aRect
|
||||
{
|
||||
var context = [[CPGraphicsContext currentContext] graphicsPort];
|
||||
|
||||
@@ -474,7 +490,7 @@ CPBelowBottom = 6;
|
||||
CGContextStrokePath(context);
|
||||
}
|
||||
|
||||
- (void)_drawVerticalSeperatorInRect:(CGRect)aRect
|
||||
- (void)_drawVerticalSeparatorInRect:(CGRect)aRect
|
||||
{
|
||||
var context = [[CPGraphicsContext currentContext] graphicsPort];
|
||||
|
||||
@@ -534,9 +550,9 @@ CPBelowBottom = 6;
|
||||
borderWidth = [self borderWidth],
|
||||
shadowOffset = [self valueForThemeAttribute:@"inner-shadow-offset"],
|
||||
shadowSize = [self valueForThemeAttribute:@"inner-shadow-size"],
|
||||
shadowColor = [self valueForThemeAttribute:@"inner-shadow-color"];
|
||||
shadowColor = [self valueForThemeAttribute:@"inner-shadow-color"],
|
||||
baseRect = aRect;
|
||||
|
||||
var baseRect = aRect;
|
||||
aRect = CGRectInset(aRect, borderWidth / 2.0, borderWidth / 2.0);
|
||||
|
||||
CGContextSaveGState(context);
|
||||
|
||||
@@ -426,11 +426,26 @@
|
||||
|
||||
- (void)keyDown:(CPEvent)anEvent
|
||||
{
|
||||
var column = [self selectedColumn];
|
||||
if (column === -1)
|
||||
var key = [anEvent charactersIgnoringModifiers],
|
||||
column = [self selectedColumn];
|
||||
|
||||
if (column === CPNotFound)
|
||||
return;
|
||||
|
||||
[_tableViews[column] keyDown:anEvent];
|
||||
if (key === CPLeftArrowFunctionKey || key === CPRightArrowFunctionKey)
|
||||
{
|
||||
if (key === CPLeftArrowFunctionKey)
|
||||
{
|
||||
var previousColumn = column - 1,
|
||||
selectedRow = [self selectedRowInColumn:previousColumn];
|
||||
|
||||
[self selectRow:selectedRow inColumn:previousColumn];
|
||||
}
|
||||
else
|
||||
[self selectRow:0 inColumn:column + 1];
|
||||
}
|
||||
else
|
||||
[_tableViews[column] keyDown:anEvent];
|
||||
}
|
||||
|
||||
// SIZING
|
||||
@@ -829,30 +844,6 @@
|
||||
[super dragViewForRowsWithIndexes:dragRows tableColumns:theTableColumns event:dragEvent offset:dragViewOffset];
|
||||
}
|
||||
|
||||
- (void)moveUp:(id)sender
|
||||
{
|
||||
[super moveUp:sender];
|
||||
[_browser selectRow:[self selectedRow] inColumn:[_browser selectedColumn]];
|
||||
}
|
||||
|
||||
- (void)moveDown:(id)sender
|
||||
{
|
||||
[super moveDown:sender];
|
||||
[_browser selectRow:[self selectedRow] inColumn:[_browser selectedColumn]];
|
||||
}
|
||||
|
||||
- (void)moveLeft:(id)sender
|
||||
{
|
||||
var previousColumn = [_browser selectedColumn] - 1,
|
||||
selectedRow = [_browser selectedRowInColumn:previousColumn];
|
||||
|
||||
[_browser selectRow:selectedRow inColumn:previousColumn];
|
||||
}
|
||||
|
||||
- (void)moveRight:(id)sender
|
||||
{
|
||||
[_browser selectRow:0 inColumn:[_browser selectedColumn] + 1];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@@ -60,11 +60,11 @@ CPMomentaryPushInButton = 7;
|
||||
CPMomentaryPushButton = 0;
|
||||
CPMomentaryLight = 7;
|
||||
|
||||
CPNoButtonMask = 0;
|
||||
CPContentsButtonMask = 1;
|
||||
CPPushInButtonMask = 2;
|
||||
CPGrayButtonMask = 4;
|
||||
CPBackgroundButtonMask = 8;
|
||||
CPNoButtonMask = 0;
|
||||
CPContentsButtonMask = 1;
|
||||
CPPushInButtonMask = 2;
|
||||
CPGrayButtonMask = 4;
|
||||
CPBackgroundButtonMask = 8;
|
||||
|
||||
CPNoCellMask = CPNoButtonMask;
|
||||
CPContentsCellMask = CPContentsButtonMask;
|
||||
@@ -72,16 +72,18 @@ CPPushInCellMask = CPPushInButtonMask;
|
||||
CPChangeGrayCellMask = CPGrayButtonMask;
|
||||
CPChangeBackgroundCellMask = CPBackgroundButtonMask;
|
||||
|
||||
CPButtonStateMixed = CPThemeState("mixed");
|
||||
CPButtonStateBezelStyleRounded = CPThemeState("rounded");
|
||||
CPButtonStateMixed = CPThemeState("mixed");
|
||||
CPButtonStateBezelStyleRounded = CPThemeState("rounded");
|
||||
|
||||
// add all future correspondance between bezel styles and theme state here.
|
||||
var CPButtonBezelStyleStateMap = [CPDictionary dictionaryWithObjects:[CPButtonStateBezelStyleRounded, nil]
|
||||
forKeys:[CPRoundedBezelStyle, CPRoundRectBezelStyle]];
|
||||
|
||||
var CPButtonBezelStyleStateMap = [CPDictionary dictionaryWithObjectsAndKeys:
|
||||
CPButtonStateBezelStyleRounded, CPRoundedBezelStyle,
|
||||
[CPNull null], CPRoundRectBezelStyle];
|
||||
|
||||
/// @cond IGNORE
|
||||
CPButtonDefaultHeight = 25.0;
|
||||
CPButtonImageOffset = 3.0;
|
||||
/// @endcond
|
||||
|
||||
/*!
|
||||
@ingroup appkit
|
||||
@@ -117,6 +119,14 @@ CPButtonImageOffset = 3.0;
|
||||
BOOL _isTracking;
|
||||
}
|
||||
|
||||
+ (Class)_binderClassForBinding:(CPString)aBinding
|
||||
{
|
||||
if (aBinding === CPTargetBinding || [aBinding hasPrefix:CPArgumentBinding])
|
||||
return [CPArgumentTargetBinding class];
|
||||
|
||||
return [super _binderClassForBinding:aBinding];
|
||||
}
|
||||
|
||||
+ (id)buttonWithTitle:(CPString)aTitle
|
||||
{
|
||||
return [self buttonWithTitle:aTitle theme:[CPTheme defaultTheme]];
|
||||
@@ -991,6 +1001,3 @@ var CPButtonImageKey = @"CPButtonImageKey",
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
//@import "CPCheckBox.j"
|
||||
//@import "CPRadio.j"
|
||||
@@ -44,12 +44,12 @@ CPCheckBoxImageOffset = 4.0;
|
||||
return @"check-box";
|
||||
}
|
||||
|
||||
+ (Class)_binderClassForBinding:(CPString)theBinding
|
||||
+ (Class)_binderClassForBinding:(CPString)aBinding
|
||||
{
|
||||
if (theBinding === CPValueBinding)
|
||||
if (aBinding === CPValueBinding)
|
||||
return [_CPCheckBoxValueBinder class];
|
||||
|
||||
return [super _binderClassForBinding:theBinding];
|
||||
return [super _binderClassForBinding:aBinding];
|
||||
}
|
||||
|
||||
- (id)initWithFrame:(CGRect)aFrame
|
||||
|
||||
@@ -20,6 +20,9 @@
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#import "../Foundation/CPRange.h"
|
||||
#import "../Foundation/Ref.h"
|
||||
|
||||
@import <Foundation/CPArray.j>
|
||||
@import <Foundation/CPData.j>
|
||||
@import <Foundation/CPIndexSet.j>
|
||||
@@ -28,6 +31,7 @@
|
||||
|
||||
@import "CPCollectionViewItem.j"
|
||||
@import "CPCompatibility.j"
|
||||
@import "CPDragServer_Constants.j"
|
||||
@import "CPPasteboard.j"
|
||||
@import "CPView.j"
|
||||
|
||||
@@ -67,6 +71,8 @@
|
||||
@return an array of drag types (CPString)
|
||||
*/
|
||||
|
||||
var HORIZONTAL_MARGIN = 2;
|
||||
|
||||
@implementation CPCollectionView : CPView
|
||||
{
|
||||
CPArray _content;
|
||||
@@ -103,6 +109,17 @@
|
||||
id _delegate;
|
||||
|
||||
CPEvent _mouseDownEvent;
|
||||
|
||||
BOOL _needsMinMaxItemSizeUpdate;
|
||||
CGSize _storedFrameSize;
|
||||
|
||||
BOOL _uniformSubviewsResizing @accessors(property=uniformSubviewsResizing);
|
||||
BOOL _lockResizing;
|
||||
|
||||
CPInteger _currentDropIndex;
|
||||
CPDragOperation _currentDragOperation;
|
||||
|
||||
_CPCollectionViewDropIndicator _dropView;
|
||||
}
|
||||
|
||||
- (id)initWithFrame:(CGRect)aFrame
|
||||
@@ -111,28 +128,52 @@
|
||||
|
||||
if (self)
|
||||
{
|
||||
_items = [];
|
||||
_content = [];
|
||||
_maxNumberOfRows = 0;
|
||||
_maxNumberOfColumns = 0;
|
||||
|
||||
_cachedItems = [];
|
||||
|
||||
_itemSize = CGSizeMakeZero();
|
||||
_minItemSize = CGSizeMakeZero();
|
||||
_maxItemSize = CGSizeMakeZero();
|
||||
_minItemSize = _CGSizeMakeZero();
|
||||
_maxItemSize = _CGSizeMakeZero();
|
||||
|
||||
[self setBackgroundColors:nil];
|
||||
|
||||
_verticalMargin = 5.0;
|
||||
_tileWidth = -1.0;
|
||||
|
||||
_selectionIndexes = [CPIndexSet indexSet];
|
||||
_allowsEmptySelection = YES;
|
||||
_isSelectable = YES;
|
||||
_allowsEmptySelection = YES;
|
||||
|
||||
[self _init];
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)_init
|
||||
{
|
||||
_content = [];
|
||||
|
||||
_items = [];
|
||||
_cachedItems = [];
|
||||
|
||||
_numberOfColumns = CPNotFound;
|
||||
_numberOfRows = CPNotFound;
|
||||
|
||||
_itemSize = _CGSizeMakeZero();
|
||||
|
||||
_selectionIndexes = [CPIndexSet indexSet];
|
||||
|
||||
_storedFrameSize = _CGSizeMakeZero();
|
||||
|
||||
_needsMinMaxItemSizeUpdate = YES;
|
||||
_uniformSubviewsResizing = NO;
|
||||
_lockResizing = NO;
|
||||
|
||||
_currentDropIndex = -1;
|
||||
_currentDragOperation = CPDragOperationNone;
|
||||
_dropView = nil;
|
||||
|
||||
[self setAutoresizesSubviews:NO];
|
||||
[self setAutoresizingMask:0];
|
||||
}
|
||||
|
||||
/*!
|
||||
Sets the item prototype to \c anItem
|
||||
|
||||
@@ -187,7 +228,7 @@
|
||||
_itemForDragging = nil;
|
||||
_itemPrototype = anItem;
|
||||
|
||||
[self reloadContent];
|
||||
[self _reloadContentCachingRemovedItems:NO];
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -210,13 +251,7 @@
|
||||
item = _cachedItems.pop();
|
||||
|
||||
else
|
||||
{
|
||||
if (!_itemData)
|
||||
if (_itemPrototype)
|
||||
_itemData = [CPKeyedArchiver archivedDataWithRootObject:_itemPrototype];
|
||||
|
||||
item = [CPKeyedUnarchiver unarchiveObjectWithData:_itemData];
|
||||
}
|
||||
item = [_itemPrototype copy];
|
||||
|
||||
[item setRepresentedObject:anObject];
|
||||
[[item view] setFrameSize:_itemSize];
|
||||
@@ -382,8 +417,13 @@
|
||||
return [_selectionIndexes copy];
|
||||
}
|
||||
|
||||
/* @ignore */
|
||||
- (void)reloadContent
|
||||
{
|
||||
[self _reloadContentCachingRemovedItems:YES];
|
||||
}
|
||||
|
||||
/* @ignore */
|
||||
- (void)_reloadContentCachingRemovedItems:(BOOL)shouldCache
|
||||
{
|
||||
// Remove current views
|
||||
var count = _items.length;
|
||||
@@ -393,7 +433,8 @@
|
||||
[[_items[count] view] removeFromSuperview];
|
||||
[_items[count] setSelected:NO];
|
||||
|
||||
_cachedItems.push(_items[count]);
|
||||
if (shouldCache)
|
||||
_cachedItems.push(_items[count]);
|
||||
}
|
||||
|
||||
_items = [];
|
||||
@@ -417,91 +458,163 @@
|
||||
while ((index = [_selectionIndexes indexGreaterThanIndex:index]) != CPNotFound && index < count)
|
||||
[_items[index] setSelected:YES];
|
||||
|
||||
[self tile];
|
||||
[self tileIfNeeded:NO];
|
||||
}
|
||||
|
||||
/* @ignore */
|
||||
- (void)tile
|
||||
- (void)resizeSubviewsWithOldSize:(CPSize)oldBoundsSize
|
||||
{
|
||||
var width = CGRectGetWidth([self bounds]);
|
||||
// Desactivate subviews autoresizing
|
||||
}
|
||||
|
||||
if (width == _tileWidth)
|
||||
- (void)resizeWithOldSuperviewSize:(CPSize)oldBoundsSize
|
||||
{
|
||||
if (_lockResizing)
|
||||
return;
|
||||
|
||||
// We try to fit as many views per row as possible. Any remaining space is then
|
||||
// either proportioned out to the views (if their minSize != maxSize) or used as
|
||||
// margin
|
||||
var itemSize = CGSizeMakeCopy(_minItemSize);
|
||||
_lockResizing = YES;
|
||||
|
||||
_numberOfColumns = MAX(1.0, FLOOR(width / itemSize.width));
|
||||
[self tile];
|
||||
|
||||
if (_maxNumberOfColumns > 0)
|
||||
_numberOfColumns = MIN(_maxNumberOfColumns, _numberOfColumns);
|
||||
|
||||
var remaining = width - _numberOfColumns * itemSize.width,
|
||||
itemsNeedSizeUpdate = NO;
|
||||
|
||||
if (remaining > 0 && itemSize.width < _maxItemSize.width)
|
||||
itemSize.width = MIN(_maxItemSize.width, itemSize.width + FLOOR(remaining / _numberOfColumns));
|
||||
|
||||
// When we ONE column and a non-integral width, the FLOORing above can cause the item width to be smaller than the total width.
|
||||
if (_maxNumberOfColumns == 1 && itemSize.width < _maxItemSize.width && itemSize.width < width)
|
||||
itemSize.width = MIN(_maxItemSize.width, width);
|
||||
|
||||
if (!CGSizeEqualToSize(_itemSize, itemSize))
|
||||
{
|
||||
_itemSize = itemSize;
|
||||
itemsNeedSizeUpdate = YES;
|
||||
}
|
||||
|
||||
var index = 0,
|
||||
count = _items.length;
|
||||
|
||||
if (_maxNumberOfColumns > 0 && _maxNumberOfRows > 0)
|
||||
count = MIN(count, _maxNumberOfColumns * _maxNumberOfRows);
|
||||
|
||||
_numberOfRows = CEIL(count / _numberOfColumns);
|
||||
|
||||
_horizontalMargin = FLOOR((width - _numberOfColumns * itemSize.width) / (_numberOfColumns + 1));
|
||||
|
||||
var x = _horizontalMargin,
|
||||
y = -itemSize.height;
|
||||
|
||||
for (; index < count; ++index)
|
||||
{
|
||||
if (index % _numberOfColumns == 0)
|
||||
{
|
||||
x = _horizontalMargin;
|
||||
y += _verticalMargin + itemSize.height;
|
||||
}
|
||||
|
||||
var view = [_items[index] view];
|
||||
|
||||
[view setFrameOrigin:CGPointMake(x, y)];
|
||||
|
||||
if (itemsNeedSizeUpdate)
|
||||
[view setFrameSize:_itemSize];
|
||||
|
||||
x += itemSize.width + _horizontalMargin;
|
||||
}
|
||||
|
||||
var superview = [self superview],
|
||||
proposedHeight = y + itemSize.height + _verticalMargin;
|
||||
|
||||
if ([superview isKindOfClass:[CPClipView class]])
|
||||
{
|
||||
var superviewSize = [superview bounds].size;
|
||||
proposedHeight = MAX(superviewSize.height, proposedHeight);
|
||||
}
|
||||
|
||||
_tileWidth = width;
|
||||
[self setFrameSize:CGSizeMake(width, proposedHeight)];
|
||||
_tileWidth = -1.0;
|
||||
_lockResizing = NO;
|
||||
}
|
||||
|
||||
- (void)resizeSubviewsWithOldSize:(CGSize)aSize
|
||||
- (void)tile
|
||||
{
|
||||
[self tile];
|
||||
[self tileIfNeeded:!_uniformSubviewsResizing];
|
||||
}
|
||||
|
||||
- (void)tileIfNeeded:(BOOL)lazyFlag
|
||||
{
|
||||
var frameSize = [[self superview] frameSize],
|
||||
count = _items.length,
|
||||
oldNumberOfColumns = _numberOfColumns,
|
||||
oldNumberOfRows = _numberOfRows,
|
||||
oldItemSize = _itemSize,
|
||||
storedFrameSize = _storedFrameSize;
|
||||
|
||||
// No need to tile if we are not yet placed in the view hierarchy.
|
||||
if (!frameSize)
|
||||
return;
|
||||
|
||||
[self _updateMinMaxItemSizeIfNeeded];
|
||||
|
||||
[self _computeGridWithSize:frameSize count:AT_REF(count)];
|
||||
|
||||
//CPLog.debug("frameSize="+CPStringFromSize(frameSize) + "itemSize="+CPStringFromSize(itemSize) + " ncols=" + colsRowsCount[0] +" nrows="+ colsRowsCount[1]+" displayCount="+ colsRowsCount[2]);
|
||||
|
||||
[self setFrameSize:_storedFrameSize];
|
||||
|
||||
//CPLog.debug("OLD " + oldNumberOfColumns + " NEW " + _numberOfColumns);
|
||||
if (!lazyFlag ||
|
||||
_numberOfColumns !== oldNumberOfColumns ||
|
||||
_numberOfRows !== oldNumberOfRows ||
|
||||
!_CGSizeEqualToSize(_itemSize, oldItemSize))
|
||||
|
||||
[self displayItems:_items frameSize:_storedFrameSize itemSize:_itemSize columns:_numberOfColumns rows:_numberOfRows count:count];
|
||||
}
|
||||
|
||||
- (void)_computeGridWithSize:(CGSize)aSuperviewSize count:(Function)countRef
|
||||
{
|
||||
var width = aSuperviewSize.width,
|
||||
height = aSuperviewSize.height,
|
||||
itemSize = _CGSizeMakeCopy(_minItemSize),
|
||||
maxItemSizeWidth = _maxItemSize.width,
|
||||
maxItemSizeHeight = _maxItemSize.height,
|
||||
itemsCount = [_items count],
|
||||
numberOfRows,
|
||||
numberOfColumns;
|
||||
|
||||
numberOfColumns = FLOOR(width / itemSize.width);
|
||||
|
||||
if (maxItemSizeWidth == 0)
|
||||
numberOfColumns = MIN(numberOfColumns, _maxNumberOfColumns);
|
||||
|
||||
if (_maxNumberOfColumns > 0)
|
||||
numberOfColumns = MIN(MIN(_maxNumberOfColumns, itemsCount), numberOfColumns);
|
||||
|
||||
numberOfColumns = MAX(1.0, numberOfColumns);
|
||||
|
||||
itemSize.width = FLOOR(width / numberOfColumns);
|
||||
|
||||
if (maxItemSizeWidth > 0)
|
||||
{
|
||||
itemSize.width = MIN(maxItemSizeWidth, itemSize.width);
|
||||
|
||||
if (numberOfColumns == 1)
|
||||
itemSize.width = MIN(maxItemSizeWidth, width);
|
||||
}
|
||||
|
||||
numberOfRows = MAX(1.0 , MIN(CEIL(itemsCount / numberOfColumns), _maxNumberOfRows));
|
||||
|
||||
height = MAX(height, numberOfRows * (_minItemSize.height + _verticalMargin));
|
||||
|
||||
var itemSizeHeight = FLOOR(height / numberOfRows);
|
||||
|
||||
if (maxItemSizeHeight > 0)
|
||||
itemSizeHeight = MIN(itemSizeHeight, maxItemSizeHeight);
|
||||
|
||||
_itemSize = _CGSizeMake(MAX(_minItemSize.width, itemSize.width), MAX(_minItemSize.height, itemSizeHeight));
|
||||
_storedFrameSize = _CGSizeMake(MAX(width, _minItemSize.width), height);
|
||||
_numberOfColumns = numberOfColumns;
|
||||
_numberOfRows = numberOfRows;
|
||||
countRef(MIN(itemsCount, numberOfColumns * numberOfRows));
|
||||
}
|
||||
|
||||
- (void)displayItems:(CPArray)displayItems frameSize:(CGSize)aFrameSize itemSize:(CGSize)anItemSize columns:(CPInteger)numberOfColumns rows:(CPInteger)numberOfRows count:(CPInteger)displayCount
|
||||
{
|
||||
// CPLog.debug("DISPLAY ITEMS " + numberOfColumns + " " + numberOfRows);
|
||||
|
||||
_horizontalMargin = _uniformSubviewsResizing ? FLOOR((aFrameSize.width - numberOfColumns * anItemSize.width) / (numberOfColumns + 1)) : HORIZONTAL_MARGIN;
|
||||
|
||||
var x = _horizontalMargin,
|
||||
y = -anItemSize.height;
|
||||
|
||||
[displayItems enumerateObjectsUsingBlock:function(item, idx, stop)
|
||||
{
|
||||
var view = [item view];
|
||||
|
||||
if (idx >= displayCount)
|
||||
{
|
||||
[view setFrameOrigin:_CGPointMake(-anItemSize.width, -anItemSize.height)];
|
||||
return;
|
||||
}
|
||||
|
||||
if (idx % numberOfColumns == 0)
|
||||
{
|
||||
x = _horizontalMargin;
|
||||
y += _verticalMargin + anItemSize.height;
|
||||
}
|
||||
|
||||
[view setFrameOrigin:_CGPointMake(x, y)];
|
||||
[view setFrameSize:anItemSize];
|
||||
|
||||
x += anItemSize.width + _horizontalMargin;
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)_updateMinMaxItemSizeIfNeeded
|
||||
{
|
||||
if (!_needsMinMaxItemSizeUpdate)
|
||||
return;
|
||||
|
||||
var prototypeView;
|
||||
|
||||
if (_itemPrototype && (prototypeView = [_itemPrototype view]))
|
||||
{
|
||||
if (_minItemSize.width == 0)
|
||||
_minItemSize.width = [prototypeView frameSize].width;
|
||||
|
||||
if (_minItemSize.height == 0)
|
||||
_minItemSize.height = [prototypeView frameSize].height;
|
||||
|
||||
if (_maxItemSize.height == 0 && !([prototypeView autoresizingMask] & CPViewHeightSizable))
|
||||
_maxItemSize.height = [prototypeView frameSize].height;
|
||||
|
||||
if (_maxItemSize.width == 0 && !([prototypeView autoresizingMask] & CPViewWidthSizable))
|
||||
_maxItemSize.width = [prototypeView frameSize].width;
|
||||
|
||||
_needsMinMaxItemSizeUpdate = NO;
|
||||
}
|
||||
}
|
||||
|
||||
// Laying Out the Collection View
|
||||
@@ -574,10 +687,14 @@
|
||||
{
|
||||
if (aSize === nil || aSize === undefined)
|
||||
[CPException raise:CPInvalidArgumentException reason:"Invalid value provided for minimum size"];
|
||||
if (CGSizeEqualToSize(_minItemSize, aSize))
|
||||
|
||||
if (_CGSizeEqualToSize(_minItemSize, aSize))
|
||||
return;
|
||||
|
||||
_minItemSize = CGSizeMakeCopy(aSize);
|
||||
_minItemSize = _CGSizeMakeCopy(aSize);
|
||||
|
||||
if (_CGSizeEqualToSize(_minItemSize, _CGSizeMakeZero()))
|
||||
_needsMinMaxItemSizeUpdate = YES;
|
||||
|
||||
[self tile];
|
||||
}
|
||||
@@ -596,10 +713,13 @@
|
||||
*/
|
||||
- (void)setMaxItemSize:(CGSize)aSize
|
||||
{
|
||||
if (CGSizeEqualToSize(_maxItemSize, aSize))
|
||||
if (_CGSizeEqualToSize(_maxItemSize, aSize))
|
||||
return;
|
||||
|
||||
_maxItemSize = CGSizeMakeCopy(aSize);
|
||||
_maxItemSize = _CGSizeMakeCopy(aSize);
|
||||
|
||||
// if (_maxItemSize.width == 0 || _maxItemSize.height == 0)
|
||||
// _needsMinMaxItemSizeUpdate = YES;
|
||||
|
||||
[self tile];
|
||||
}
|
||||
@@ -620,7 +740,7 @@
|
||||
_backgroundColors = backgroundColors;
|
||||
|
||||
if (!_backgroundColors)
|
||||
_backgroundColors = [CPColor whiteColor];
|
||||
_backgroundColors = [[CPColor whiteColor]];
|
||||
|
||||
if ([_backgroundColors count] === 1)
|
||||
[self setBackgroundColor:_backgroundColors[0]];
|
||||
@@ -668,9 +788,9 @@
|
||||
newSelectedRange = nil;
|
||||
|
||||
if (index < firstSelectedIndex)
|
||||
newSelectedRange = CPMakeRange(index, (firstSelectedIndex - index) + 1);
|
||||
newSelectedRange = _CPMakeRange(index, (firstSelectedIndex - index) + 1);
|
||||
else
|
||||
newSelectedRange = CPMakeRange(firstSelectedIndex, (index - firstSelectedIndex) + 1);
|
||||
newSelectedRange = _CPMakeRange(firstSelectedIndex, (index - firstSelectedIndex) + 1);
|
||||
|
||||
indexes = [[self selectionIndexes] copy];
|
||||
[indexes addIndexesInRange:newSelectedRange];
|
||||
@@ -692,65 +812,6 @@
|
||||
[self setSelectionIndexes:[CPIndexSet indexSet]];
|
||||
}
|
||||
|
||||
- (void)mouseDragged:(CPEvent)anEvent
|
||||
{
|
||||
// Don't crash if we never registered the intial click.
|
||||
if (!_mouseDownEvent)
|
||||
return;
|
||||
|
||||
var locationInWindow = [anEvent locationInWindow],
|
||||
mouseDownLocationInWindow = [_mouseDownEvent locationInWindow];
|
||||
|
||||
// FIXME: This is because Safari's drag hysteresis is 3px x 3px
|
||||
if ((ABS(locationInWindow.x - mouseDownLocationInWindow.x) < 3) &&
|
||||
(ABS(locationInWindow.y - mouseDownLocationInWindow.y) < 3))
|
||||
return;
|
||||
|
||||
if (![_delegate respondsToSelector:@selector(collectionView:dragTypesForItemsAtIndexes:)])
|
||||
return;
|
||||
|
||||
// If we don't have any selected items, we've clicked away, and thus the drag is meaningless.
|
||||
if (![_selectionIndexes count])
|
||||
return;
|
||||
|
||||
if ([_delegate respondsToSelector:@selector(collectionView:canDragItemsAtIndexes:withEvent:)] &&
|
||||
![_delegate collectionView:self canDragItemsAtIndexes:_selectionIndexes withEvent:_mouseDownEvent])
|
||||
return;
|
||||
|
||||
// Set up the pasteboard
|
||||
var dragTypes = [_delegate collectionView:self dragTypesForItemsAtIndexes:_selectionIndexes];
|
||||
|
||||
[[CPPasteboard pasteboardWithName:CPDragPboard] declareTypes:dragTypes owner:self];
|
||||
|
||||
if (!_itemForDragging)
|
||||
_itemForDragging = [self newItemForRepresentedObject:_content[[_selectionIndexes firstIndex]]];
|
||||
else
|
||||
[_itemForDragging setRepresentedObject:_content[[_selectionIndexes firstIndex]]];
|
||||
|
||||
var view = [_itemForDragging view];
|
||||
|
||||
[view setFrameSize:_itemSize];
|
||||
[view setAlphaValue:0.7];
|
||||
|
||||
[self dragView:view
|
||||
at:[[_items[[_selectionIndexes firstIndex]] view] frame].origin
|
||||
offset:CGSizeMakeZero()
|
||||
event:_mouseDownEvent
|
||||
pasteboard:nil
|
||||
source:self
|
||||
slideBack:YES];
|
||||
}
|
||||
|
||||
/*!
|
||||
Places the selected items on the specified pasteboard. The items are requested from the collection's delegate.
|
||||
@param aPasteboard the pasteboard to put the items on
|
||||
@param aType the format the pasteboard data
|
||||
*/
|
||||
- (void)pasteboard:(CPPasteboard)aPasteboard provideDataForType:(CPString)aType
|
||||
{
|
||||
[aPasteboard setData:[_delegate collectionView:self dataForItemsAtIndexes:_selectionIndexes forType:aType] forType:aType];
|
||||
}
|
||||
|
||||
// Cappuccino Additions
|
||||
|
||||
/*!
|
||||
@@ -768,6 +829,13 @@
|
||||
[self tile];
|
||||
}
|
||||
|
||||
- (void)setUniformSubviewsResizing:(float)flag
|
||||
{
|
||||
_uniformSubviewsResizing = flag;
|
||||
[self tileIfNeeded:NO];
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
Gets the collection view's current vertical spacing between elements.
|
||||
*/
|
||||
@@ -810,10 +878,17 @@
|
||||
|
||||
- (int)_indexAtPoint:(CGPoint)thePoint
|
||||
{
|
||||
var row = FLOOR(thePoint.y / (_itemSize.height + _verticalMargin)),
|
||||
column = FLOOR(thePoint.x / (_itemSize.width + _horizontalMargin));
|
||||
var column = FLOOR(thePoint.x / (_itemSize.width + _horizontalMargin));
|
||||
|
||||
return row * _numberOfColumns + column;
|
||||
if (column < _numberOfColumns)
|
||||
{
|
||||
var row = FLOOR(thePoint.y / (_itemSize.height + _verticalMargin));
|
||||
|
||||
if (row < _numberOfRows)
|
||||
return (row * _numberOfColumns + column);
|
||||
}
|
||||
|
||||
return CPNotFound;
|
||||
}
|
||||
|
||||
- (CPCollectionViewItem)itemAtIndex:(unsigned)anIndex
|
||||
@@ -844,6 +919,293 @@
|
||||
|
||||
@end
|
||||
|
||||
@implementation CPCollectionView (DragAndDrop)
|
||||
/*
|
||||
TODO: dropOperation is not supported yet. The visible drop operation is like CPCollectionViewDropBefore.
|
||||
*/
|
||||
|
||||
/*!
|
||||
Places the selected items on the specified pasteboard. The items are requested from the collection's delegate.
|
||||
@param aPasteboard the pasteboard to put the items on
|
||||
@param aType the format the pasteboard data
|
||||
*/
|
||||
- (void)pasteboard:(CPPasteboard)aPasteboard provideDataForType:(CPString)aType
|
||||
{
|
||||
[aPasteboard setData:[_delegate collectionView:self dataForItemsAtIndexes:_selectionIndexes forType:aType] forType:aType];
|
||||
}
|
||||
|
||||
- (void)_createDropIndicatorIfNeeded
|
||||
{
|
||||
// Create and position the drop indicator view.
|
||||
|
||||
if (!_dropView)
|
||||
_dropView = [[_CPCollectionViewDropIndicator alloc] initWithFrame:_CGRectMake(-8, -8, 0, 0)];
|
||||
|
||||
[_dropView setFrameSize:_CGSizeMake(10, _itemSize.height + _verticalMargin)];
|
||||
[self addSubview:_dropView];
|
||||
}
|
||||
|
||||
- (void)mouseDragged:(CPEvent)anEvent
|
||||
{
|
||||
// Don't crash if we never registered the intial click.
|
||||
if (!_mouseDownEvent)
|
||||
return;
|
||||
|
||||
[self _createDropIndicatorIfNeeded];
|
||||
|
||||
var locationInWindow = [anEvent locationInWindow],
|
||||
mouseDownLocationInWindow = [_mouseDownEvent locationInWindow];
|
||||
|
||||
// FIXME: This is because Safari's drag hysteresis is 3px x 3px
|
||||
if ((ABS(locationInWindow.x - mouseDownLocationInWindow.x) < 3) &&
|
||||
(ABS(locationInWindow.y - mouseDownLocationInWindow.y) < 3))
|
||||
return;
|
||||
|
||||
if (![_delegate respondsToSelector:@selector(collectionView:dragTypesForItemsAtIndexes:)])
|
||||
return;
|
||||
|
||||
// If we don't have any selected items, we've clicked away, and thus the drag is meaningless.
|
||||
if (![_selectionIndexes count])
|
||||
return;
|
||||
|
||||
if ([_delegate respondsToSelector:@selector(collectionView:canDragItemsAtIndexes:withEvent:)] &&
|
||||
![_delegate collectionView:self canDragItemsAtIndexes:_selectionIndexes withEvent:_mouseDownEvent])
|
||||
return;
|
||||
|
||||
// Set up the pasteboard
|
||||
var dragTypes = [_delegate collectionView:self dragTypesForItemsAtIndexes:_selectionIndexes];
|
||||
|
||||
[[CPPasteboard pasteboardWithName:CPDragPboard] declareTypes:dragTypes owner:self];
|
||||
|
||||
var dragImageOffset = _CGSizeMakeZero(),
|
||||
view = [self _draggingViewForItemsAtIndexes:_selectionIndexes withEvent:_mouseDownEvent offset:dragImageOffset];
|
||||
|
||||
[view setFrameSize:_itemSize];
|
||||
[view setAlphaValue:0.7];
|
||||
|
||||
var dragLocation = [self convertPoint:locationInWindow fromView:nil],
|
||||
dragPoint = _CGPointMake(dragLocation.x - _itemSize.width / 2 , dragLocation.y - _itemSize.height / 2);
|
||||
|
||||
[self dragView:view
|
||||
at:dragPoint
|
||||
offset:dragImageOffset
|
||||
event:_mouseDownEvent
|
||||
pasteboard:nil
|
||||
source:self
|
||||
slideBack:YES];
|
||||
}
|
||||
|
||||
- (CPView)_draggingViewForItemsAtIndexes:(CPIndexSet)indexes withEvent:(CPEvent)anEvent offset:(CGPoint)offset
|
||||
{
|
||||
if ([_delegate respondsToSelector:@selector(collectionView:draggingViewForItemsAtIndexes:withEvent:offset:)])
|
||||
return [_delegate collectionView:self draggingViewForItemsAtIndexes:indexes withEvent:anEvent offset:offset];
|
||||
|
||||
return [self draggingViewForItemsAtIndexes:indexes withEvent:anEvent offset:offset];
|
||||
}
|
||||
|
||||
- (CPView)draggingViewForItemsAtIndexes:(CPIndexSet)indexes withEvent:(CPEvent)event offset:(CGPoint)dragImageOffset
|
||||
{
|
||||
var idx = _content[[indexes firstIndex]];
|
||||
|
||||
if (!_itemForDragging)
|
||||
_itemForDragging = [self newItemForRepresentedObject:idx];
|
||||
else
|
||||
[_itemForDragging setRepresentedObject:idx];
|
||||
|
||||
return [_itemForDragging view];
|
||||
}
|
||||
|
||||
- (BOOL)_canDragItemsAtIndexes:(CPIndexSet)indexes withEvent:(CPEvent)anEvent
|
||||
{
|
||||
if ([self respondsToSelector:@selector(collectionView:canDragItemsAtIndexes:withEvent:)])
|
||||
return [_delegate collectionView:self canDragItemsAtIndexes:indexes withEvent:anEvent];
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (CPDragOperation)draggingEntered:(id)draggingInfo
|
||||
{
|
||||
var dropIndex = -1,
|
||||
dropIndexRef = AT_REF(dropIndex),
|
||||
dragOp = [self _validateDragWithInfo:draggingInfo dropIndex:dropIndexRef dropOperation:1];
|
||||
|
||||
dropIndex = dropIndexRef();
|
||||
|
||||
[self _createDropIndicatorIfNeeded];
|
||||
|
||||
[self _updateDragAndDropStateWithDraggingInfo:draggingInfo newDragOperation:dragOp newDropIndex:dropIndex newDropOperation:1];
|
||||
|
||||
return _currentDragOperation;
|
||||
}
|
||||
|
||||
- (CPDragOperation)draggingUpdated:(id)draggingInfo
|
||||
{
|
||||
if (![self _dropIndexDidChange:draggingInfo])
|
||||
return _currentDragOperation;
|
||||
|
||||
var dropIndex,
|
||||
dropIndexRef = AT_REF(dropIndex);
|
||||
|
||||
var dragOperation = [self _validateDragWithInfo:draggingInfo dropIndex:dropIndexRef dropOperation:1];
|
||||
|
||||
dropIndex = dropIndexRef();
|
||||
|
||||
[self _updateDragAndDropStateWithDraggingInfo:draggingInfo newDragOperation:dragOperation newDropIndex:dropIndex newDropOperation:1];
|
||||
|
||||
return dragOperation;
|
||||
}
|
||||
|
||||
- (CPDragOperation)_validateDragWithInfo:(id)draggingInfo dropIndex:(Function)dropIndexRef dropOperation:(int)dropOperation
|
||||
{
|
||||
var result = CPDragOperationMove,
|
||||
dropIndex = [self _dropIndexForDraggingInfo:draggingInfo proposedDropOperation:dropOperation];
|
||||
|
||||
if ([_delegate respondsToSelector:@selector(collectionView:validateDrop:proposedIndex:dropOperation:)])
|
||||
{
|
||||
var dropIndexRef2 = AT_REF(dropIndex);
|
||||
|
||||
result = [_delegate collectionView:self validateDrop:draggingInfo proposedIndex:dropIndexRef2 dropOperation:dropOperation];
|
||||
|
||||
if (result !== CPDragOperationNone)
|
||||
{
|
||||
dropIndex = dropIndexRef2();
|
||||
}
|
||||
}
|
||||
|
||||
dropIndexRef(dropIndex);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
- (void)draggingExited:(id)draggingInfo
|
||||
{
|
||||
[self _updateDragAndDropStateWithDraggingInfo:draggingInfo newDragOperation:0 newDropIndex:-1 newDropOperation:1];
|
||||
}
|
||||
|
||||
- (void)draggingEnded:(id)draggingInfo
|
||||
{
|
||||
[self _updateDragAndDropStateWithDraggingInfo:draggingInfo newDragOperation:0 newDropIndex:-1 newDropOperation:1];
|
||||
}
|
||||
|
||||
/*
|
||||
Not supported. Use -collectionView:dataForItemsAtIndexes:fortype:
|
||||
- (BOOL)_writeItemsAtIndexes:(CPIndexSet)indexes toPasteboard:(CPPasteboard)pboard
|
||||
{
|
||||
if ([self respondsToSelector:@selector(collectionView:writeItemsAtIndexes:toPasteboard:)])
|
||||
return [_delegate collectionView:self writeItemsAtIndexes:indexes toPasteboard:pboard];
|
||||
|
||||
return NO;
|
||||
}
|
||||
*/
|
||||
|
||||
- (BOOL)performDragOperation:(id)draggingInfo
|
||||
{
|
||||
var result = NO;
|
||||
|
||||
if (_currentDragOperation && _currentDropIndex !== -1)
|
||||
result = [_delegate collectionView:self acceptDrop:draggingInfo index:_currentDropIndex dropOperation:1];
|
||||
|
||||
[self draggingEnded:draggingInfo]; // Is this correct ?
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
- (void)_updateDragAndDropStateWithDraggingInfo:(id)draggingInfo newDragOperation:(CPDragOperation)dragOperation newDropIndex:(CPInteger)dropIndex newDropOperation:(CPInteger)dropOperation
|
||||
{
|
||||
_currentDropIndex = dropIndex;
|
||||
_currentDragOperation = dragOperation;
|
||||
|
||||
var frameOrigin,
|
||||
dropviewFrameWidth = _CGRectGetWidth([_dropView frame]);
|
||||
|
||||
if (_currentDropIndex == -1 || _currentDragOperation == CPDragOperationNone)
|
||||
frameOrigin = _CGPointMake(-dropviewFrameWidth, 0);
|
||||
else if (_currentDropIndex == 0)
|
||||
frameOrigin = _CGPointMake(0, 0);
|
||||
else
|
||||
{
|
||||
var offset;
|
||||
|
||||
if ((_currentDropIndex % _numberOfColumns) !== 0 || _currentDropIndex == [_items count])
|
||||
{
|
||||
dropIndex = _currentDropIndex - 1;
|
||||
offset = (_horizontalMargin - dropviewFrameWidth) / 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
offset = - _itemSize.width - dropviewFrameWidth - (_horizontalMargin - dropviewFrameWidth) / 2;
|
||||
}
|
||||
|
||||
var rect = [self frameForItemAtIndex:dropIndex];
|
||||
|
||||
frameOrigin = _CGPointMake(_CGRectGetMaxX(rect) + offset, rect.origin.y - _verticalMargin);
|
||||
}
|
||||
|
||||
[_dropView setFrameOrigin:frameOrigin];
|
||||
}
|
||||
|
||||
- (BOOL)_dropIndexDidChange:(id)draggingInfo
|
||||
{
|
||||
var dropIndex = [self _dropIndexForDraggingInfo:draggingInfo proposedDropOperation:1];
|
||||
|
||||
if (dropIndex == CPNotFound)
|
||||
dropIndex = [[self content] count];
|
||||
|
||||
return (_currentDropIndex !== dropIndex)
|
||||
}
|
||||
|
||||
- (CPInteger)_dropIndexForDraggingInfo:(id)draggingInfo proposedDropOperation:(int)dropOperation
|
||||
{
|
||||
var location = [self convertPoint:[draggingInfo draggingLocation] fromView:nil],
|
||||
locationX = location.x + _itemSize.width / 2;
|
||||
|
||||
var column = MIN(FLOOR(locationX / (_itemSize.width + _horizontalMargin)), _numberOfColumns),
|
||||
row = FLOOR(location.y / (_itemSize.height + _verticalMargin));
|
||||
|
||||
if (row >= _numberOfRows - 1)
|
||||
{
|
||||
if (row >= _numberOfRows)
|
||||
{
|
||||
row = _numberOfRows - 1;
|
||||
column = _numberOfColumns;
|
||||
}
|
||||
|
||||
return MIN((row * _numberOfColumns + column), [_items count]);
|
||||
}
|
||||
|
||||
return (row * _numberOfColumns + column);
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation _CPCollectionViewDropIndicator : CPView
|
||||
{
|
||||
}
|
||||
|
||||
- (void)drawRect:(CGRect)aRect
|
||||
{
|
||||
var context = [[CPGraphicsContext currentContext] graphicsPort],
|
||||
width = _CGRectGetWidth(aRect),
|
||||
circleRect = _CGRectMake(1, 1, width - 2, width - 2);
|
||||
|
||||
CGContextSetStrokeColor(context, [CPColor colorWithHexString:@"4886ca"]);
|
||||
CGContextSetFillColor(context, [CPColor whiteColor]);
|
||||
CGContextSetLineWidth(context, 3);
|
||||
|
||||
//draw white under the circle thing
|
||||
CGContextFillRect(context, circleRect);
|
||||
//draw the circle thing
|
||||
CGContextStrokeEllipseInRect(context, circleRect);
|
||||
//then draw the line
|
||||
CGContextBeginPath(context);
|
||||
CGContextMoveToPoint(context, FLOOR(width / 2), _CGRectGetMinY(aRect) + width);
|
||||
CGContextAddLineToPoint(context, FLOOR(width / 2), _CGRectGetHeight(aRect));
|
||||
CGContextClosePath(context);
|
||||
CGContextStrokePath(context);
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation CPCollectionView (KeyboardInteraction)
|
||||
|
||||
- (void)_modifySelectionWithNewIndex:(int)anIndex direction:(int)aDirection expand:(BOOL)shouldExpand
|
||||
@@ -858,9 +1220,9 @@
|
||||
|
||||
// if the direction is backward (-1) check with the bottom anchor
|
||||
if (aDirection === -1)
|
||||
[indexes addIndexesInRange:CPMakeRange(anIndex, bottomAnchor - anIndex + 1)];
|
||||
[indexes addIndexesInRange:_CPMakeRange(anIndex, bottomAnchor - anIndex + 1)];
|
||||
else
|
||||
[indexes addIndexesInRange:CPMakeRange(topAnchor, anIndex - topAnchor + 1)];
|
||||
[indexes addIndexesInRange:_CPMakeRange(topAnchor, anIndex - topAnchor + 1)];
|
||||
}
|
||||
else
|
||||
indexes = [CPIndexSet indexSetWithIndex:anIndex];
|
||||
@@ -873,7 +1235,7 @@
|
||||
{
|
||||
var frame = [self frameForItemsAtIndexes:[self selectionIndexes]];
|
||||
|
||||
if (!CGRectIsNull(frame))
|
||||
if (!_CGRectIsNull(frame))
|
||||
[self scrollRectToVisible:frame];
|
||||
}
|
||||
|
||||
@@ -953,6 +1315,11 @@
|
||||
[self interpretKeyEvents:[anEvent]];
|
||||
}
|
||||
|
||||
- (void)setAutoresizingMask:(int)aMask
|
||||
{
|
||||
[super setAutoresizingMask:0];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation CPCollectionView (Deprecated)
|
||||
@@ -987,35 +1354,12 @@ var CPCollectionViewMinItemSizeKey = @"CPCollectionViewMinItemSizeK
|
||||
|
||||
@implementation CPCollectionView (CPCoding)
|
||||
|
||||
- (void)awakeFromCib
|
||||
{
|
||||
[super awakeFromCib];
|
||||
|
||||
var prototypeView = [_itemPrototype view];
|
||||
if (prototypeView && (CGSizeEqualToSize(_minItemSize, CGSizeMakeZero()) || CGSizeEqualToSize(_maxItemSize, CGSizeMakeZero())))
|
||||
{
|
||||
var item = _itemPrototype;
|
||||
|
||||
if (CGSizeEqualToSize(_minItemSize, CGSizeMakeZero()))
|
||||
_minItemSize = [prototypeView frameSize];
|
||||
else if (CGSizeEqualToSize(_maxItemSize, CGSizeMakeZero()))
|
||||
_maxItemSize = [prototypeView frameSize];
|
||||
}
|
||||
}
|
||||
|
||||
- (id)initWithCoder:(CPCoder)aCoder
|
||||
{
|
||||
self = [super initWithCoder:aCoder];
|
||||
|
||||
if (self)
|
||||
{
|
||||
_items = [];
|
||||
_content = [];
|
||||
|
||||
_cachedItems = [];
|
||||
|
||||
_itemSize = CGSizeMakeZero();
|
||||
|
||||
_minItemSize = [aCoder decodeSizeForKey:CPCollectionViewMinItemSizeKey];
|
||||
_maxItemSize = [aCoder decodeSizeForKey:CPCollectionViewMaxItemSizeKey];
|
||||
|
||||
@@ -1029,11 +1373,7 @@ var CPCollectionViewMinItemSizeKey = @"CPCollectionViewMinItemSizeK
|
||||
|
||||
[self setBackgroundColors:[aCoder decodeObjectForKey:CPCollectionViewBackgroundColorsKey]];
|
||||
|
||||
_tileWidth = -1.0;
|
||||
|
||||
_selectionIndexes = [CPIndexSet indexSet];
|
||||
|
||||
_allowsEmptySelection = YES;
|
||||
[self _init];
|
||||
}
|
||||
|
||||
return self;
|
||||
@@ -1043,10 +1383,10 @@ var CPCollectionViewMinItemSizeKey = @"CPCollectionViewMinItemSizeK
|
||||
{
|
||||
[super encodeWithCoder:aCoder];
|
||||
|
||||
if (!CGSizeEqualToSize(_minItemSize, CGSizeMakeZero()))
|
||||
if (!_CGSizeEqualToSize(_minItemSize, _CGSizeMakeZero()))
|
||||
[aCoder encodeSize:_minItemSize forKey:CPCollectionViewMinItemSizeKey];
|
||||
|
||||
if (!CGSizeEqualToSize(_maxItemSize, CGSizeMakeZero()))
|
||||
if (!_CGSizeEqualToSize(_maxItemSize, _CGSizeMakeZero()))
|
||||
[aCoder encodeSize:_maxItemSize forKey:CPCollectionViewMaxItemSizeKey];
|
||||
|
||||
[aCoder encodeInt:_maxNumberOfRows forKey:CPCollectionViewMaxNumberOfRowsKey];
|
||||
|
||||
@@ -22,13 +22,38 @@
|
||||
|
||||
@import "CPViewController.j"
|
||||
|
||||
|
||||
/*!
|
||||
Represents an object inside a CPCollectionView.
|
||||
*/
|
||||
@implementation CPCollectionViewItem : CPViewController
|
||||
{
|
||||
BOOL _isSelected;
|
||||
CPData _cachedArchive;
|
||||
}
|
||||
|
||||
- (id)copy
|
||||
{
|
||||
var cibName = [self cibName],
|
||||
copy;
|
||||
|
||||
if (cibName)
|
||||
{
|
||||
copy = [[[self class] alloc] initWithCibName:cibName bundle:[self cibBundle]];
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!_cachedArchive)
|
||||
_cachedArchive = [CPKeyedArchiver archivedDataWithRootObject:self];
|
||||
|
||||
copy = [CPKeyedUnarchiver unarchiveObjectWithData:_cachedArchive];
|
||||
|
||||
// copy connections
|
||||
}
|
||||
|
||||
[copy setRepresentedObject:[self representedObject]];
|
||||
[copy setSelected:_isSelected];
|
||||
|
||||
return copy;
|
||||
}
|
||||
|
||||
// Setting the Represented Object
|
||||
|
||||
@@ -1302,7 +1302,7 @@ var cloneObject = function(object)
|
||||
if (object.hasOwnProperty(key))
|
||||
if (object[key].constructor === Array)
|
||||
clone[key] = object[key].slice(0);
|
||||
else if (typeof(object) === "object")
|
||||
else if (typeof(object[key]) === "object")
|
||||
clone[key] = cloneObject(object[key]);
|
||||
else
|
||||
clone[key] = object[key];
|
||||
|
||||
@@ -45,12 +45,12 @@ var _CPColorWellDidBecomeExclusiveNotification = @"_CPColorWellDidBecomeExclusiv
|
||||
CPColor _color;
|
||||
}
|
||||
|
||||
+ (Class)_binderClassForBinding:(CPString)theBinding
|
||||
+ (Class)_binderClassForBinding:(CPString)aBinding
|
||||
{
|
||||
if (theBinding == CPValueBinding)
|
||||
if (aBinding == CPValueBinding)
|
||||
return [CPColorWellValueBinder class];
|
||||
|
||||
return [super _binderClassForBinding:theBinding];
|
||||
return [super _binderClassForBinding:aBinding];
|
||||
}
|
||||
|
||||
+ (CPString)defaultThemeClass
|
||||
@@ -315,7 +315,7 @@ var _CPColorWellDidBecomeExclusiveNotification = @"_CPColorWellDidBecomeExclusiv
|
||||
|
||||
- (void)_updatePlaceholdersWithOptions:(CPDictionary)options
|
||||
{
|
||||
var placeholderColor = [CPColor blueColor];
|
||||
var placeholderColor = [CPColor blackColor];
|
||||
|
||||
[self _setPlaceholder:placeholderColor forMarker:CPMultipleValuesMarker isDefault:YES];
|
||||
[self _setPlaceholder:placeholderColor forMarker:CPNoSelectionMarker isDefault:YES];
|
||||
@@ -323,30 +323,19 @@ var _CPColorWellDidBecomeExclusiveNotification = @"_CPColorWellDidBecomeExclusiv
|
||||
[self _setPlaceholder:placeholderColor forMarker:CPNullMarker isDefault:YES];
|
||||
}
|
||||
|
||||
- (void)setValueFor:(CPString)theBinding
|
||||
- (id)valueForBinding:(CPString)aBinding
|
||||
{
|
||||
var destination = [_info objectForKey:CPObservedObjectKey],
|
||||
keyPath = [_info objectForKey:CPObservedKeyPathKey],
|
||||
options = [_info objectForKey:CPOptionsKey],
|
||||
newValue = [destination valueForKeyPath:keyPath],
|
||||
isPlaceholder = CPIsControllerMarker(newValue);
|
||||
return [_source color];
|
||||
}
|
||||
|
||||
if (isPlaceholder)
|
||||
{
|
||||
if (newValue === CPNotApplicableMarker && [options objectForKey:CPRaisesForNotApplicableKeysBindingOption])
|
||||
{
|
||||
[CPException raise:CPGenericException
|
||||
reason:@"can't transform non applicable key on: " + _source + " value: " + newValue];
|
||||
}
|
||||
- (void)setValue:(id)aValue forBinding:(CPString)theBinding
|
||||
{
|
||||
[_source setColor:aValue];
|
||||
}
|
||||
|
||||
newValue = [self _placeholderForMarker:newValue];
|
||||
}
|
||||
else
|
||||
{
|
||||
newValue = [self transformValue:newValue withOptions:options];
|
||||
}
|
||||
|
||||
[_source setColor:newValue];
|
||||
- (void)setPlaceholderValue:(id)aValue withMarker:(CPString)aMarker forBinding:(CPString)aBinding
|
||||
{
|
||||
[_source setColor:aValue];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -63,12 +63,12 @@ var CPComboBoxTextSubview = @"text",
|
||||
return [CPDictionary dictionaryWithObjectsAndKeys:_CGSizeMake(21.0, 29.0), @"popup-button-size", _CGInsetMake(3.0, 3.0, 3.0, 3.0), @"border-inset"];
|
||||
}
|
||||
|
||||
+ (Class)_binderClassForBinding:(CPString)theBinding
|
||||
+ (Class)_binderClassForBinding:(CPString)aBinding
|
||||
{
|
||||
if (theBinding === CPContentBinding || theBinding === CPContentValuesBinding)
|
||||
if (aBinding === CPContentBinding || aBinding === CPContentValuesBinding)
|
||||
return [_CPComboBoxContentBinder class];
|
||||
|
||||
return [super _binderClassForBinding:theBinding];
|
||||
return [super _binderClassForBinding:aBinding];
|
||||
}
|
||||
|
||||
- (id)initWithFrame:(CGRect)aFrame
|
||||
@@ -1111,7 +1111,7 @@ var CPComboBoxCompletionTest = function(object, index, context)
|
||||
*/
|
||||
@implementation _CPComboBoxContentBinder : CPBinder
|
||||
|
||||
- (void)setValueFor:(CPString)theBinding
|
||||
- (void)setValueFor:(CPString)aBinding
|
||||
{
|
||||
var destination = [_info objectForKey:CPObservedObjectKey],
|
||||
keyPath = [_info objectForKey:CPObservedKeyPathKey],
|
||||
@@ -1153,13 +1153,15 @@ var CPComboBoxCompletionTest = function(object, index, context)
|
||||
else
|
||||
newValue = [self transformValue:newValue withOptions:options];
|
||||
|
||||
switch (theBinding)
|
||||
switch (aBinding)
|
||||
{
|
||||
case CPContentBinding: [_source setContent:newValue];
|
||||
break;
|
||||
case CPContentBinding:
|
||||
[_source setContent:newValue];
|
||||
break;
|
||||
|
||||
case CPContentValuesBinding: [_source setContentValues:newValue];
|
||||
break;
|
||||
case CPContentValuesBinding:
|
||||
[_source setContentValues:newValue];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -38,58 +38,58 @@ CPWindowsOperatingSystem = 1;
|
||||
CPOtherOperatingSystem = 2;
|
||||
|
||||
// Features
|
||||
CPCSSRGBAFeature = 1 << 5;
|
||||
CPCSSRGBAFeature = 5;
|
||||
|
||||
CPHTMLCanvasFeature = 1 << 6;
|
||||
CPHTMLContentEditableFeature = 1 << 7;
|
||||
CPHTMLDragAndDropFeature = 1 << 8;
|
||||
CPHTMLCanvasFeature = 6;
|
||||
CPHTMLContentEditableFeature = 7;
|
||||
CPHTMLDragAndDropFeature = 8;
|
||||
|
||||
CPJavaScriptInnerTextFeature = 1 << 9;
|
||||
CPJavaScriptTextContentFeature = 1 << 10;
|
||||
CPJavaScriptClipboardEventsFeature = 1 << 11;
|
||||
CPJavaScriptClipboardAccessFeature = 1 << 12;
|
||||
CPJavaScriptCanvasDrawFeature = 1 << 13;
|
||||
CPJavaScriptCanvasTransformFeature = 1 << 14;
|
||||
CPJavaScriptInnerTextFeature = 9;
|
||||
CPJavaScriptTextContentFeature = 10;
|
||||
CPJavaScriptClipboardEventsFeature = 11;
|
||||
CPJavaScriptClipboardAccessFeature = 12;
|
||||
CPJavaScriptCanvasDrawFeature = 13;
|
||||
CPJavaScriptCanvasTransformFeature = 14;
|
||||
|
||||
CPVMLFeature = 1 << 15;
|
||||
CPVMLFeature = 15;
|
||||
|
||||
CPJavaScriptRemedialKeySupport = 1 << 16;
|
||||
CPJavaScriptShadowFeature = 1 << 20;
|
||||
CPJavaScriptRemedialKeySupport = 16;
|
||||
CPJavaScriptShadowFeature = 20;
|
||||
|
||||
CPJavaScriptNegativeMouseWheelValues = 1 << 22;
|
||||
CPJavaScriptMouseWheelValues_8_15 = 1 << 23;
|
||||
CPJavaScriptNegativeMouseWheelValues = 22;
|
||||
CPJavaScriptMouseWheelValues_8_15 = 23;
|
||||
|
||||
CPOpacityRequiresFilterFeature = 1 << 24;
|
||||
CPOpacityRequiresFilterFeature = 24;
|
||||
|
||||
//Internet explorer does not allow dynamically changing the type of an input element
|
||||
CPInputTypeCanBeChangedFeature = 1 << 25;
|
||||
CPHTML5DragAndDropSourceYOffBy1 = 1 << 26;
|
||||
// Internet explorer does not allow dynamically changing the type of an input element
|
||||
CPInputTypeCanBeChangedFeature = 25;
|
||||
CPHTML5DragAndDropSourceYOffBy1 = 26;
|
||||
|
||||
CPSOPDisabledFromFileURLs = 1 << 27;
|
||||
CPSOPDisabledFromFileURLs = 27;
|
||||
|
||||
// element.style.font can be set for an element not in the DOM.
|
||||
CPInputSetFontOutsideOfDOM = 1 << 28;
|
||||
CPInputSetFontOutsideOfDOM = 28;
|
||||
|
||||
// Input elements have 1 px of extra padding on the left regardless of padding setting.
|
||||
CPInput1PxLeftPadding = 1 << 29;
|
||||
CPInputOnInputEventFeature = 1 << 30;
|
||||
CPInput1PxLeftPadding = 29;
|
||||
CPInputOnInputEventFeature = 30;
|
||||
|
||||
// When an absolutely positioned div (CPView) with an absolutely positioned canvas in it (CPView with drawRect:) moves things on top of the canvas
|
||||
// (subviews) don't redraw correctly. E.g. if you have a bunch of text fields in a CPBox in a sheet which animates in, some of the text fields might
|
||||
// not be visible because the CPBox has a canvas at the bottom and the box moved form offscreen to onscreen.
|
||||
// This bug is probably very related: https://bugs.webkit.org/show_bug.cgi?id=67203
|
||||
CPFileAPIFeature = 31;
|
||||
|
||||
/*
|
||||
When an absolutely positioned div (CPView) with an absolutely positioned canvas in it (CPView with drawRect:) moves things on top of the canvas (subviews) don't redraw correctly. E.g. if you have a bunch of text fields in a CPBox in a sheet which animates in, some of the text fields might not be visible because the CPBox has a canvas at the bottom and the box moved form offscreen to onscreen. This bug is probably very related: https://bugs.webkit.org/show_bug.cgi?id=67203
|
||||
*/
|
||||
CPCanvasParentDrawErrorsOnMovementBug = 1 << 0;
|
||||
|
||||
var USER_AGENT = "",
|
||||
PLATFORM_ENGINE = CPUnknownBrowserEngine,
|
||||
PLATFORM_FEATURES = 0,
|
||||
PLATFORM_FEATURES = [],
|
||||
PLATFORM_BUGS = 0,
|
||||
PLATFORM_STYLE_JS_PROPERTIES = {};
|
||||
|
||||
// default these features to true
|
||||
|
||||
PLATFORM_FEATURES |= CPInputTypeCanBeChangedFeature;
|
||||
PLATFORM_FEATURES |= CPInputSetFontOutsideOfDOM;
|
||||
PLATFORM_FEATURES[CPInputTypeCanBeChangedFeature] = YES;
|
||||
PLATFORM_FEATURES[CPInputSetFontOutsideOfDOM] = YES;
|
||||
|
||||
if (typeof window !== "undefined" && typeof window.navigator !== "undefined")
|
||||
USER_AGENT = window.navigator.userAgent;
|
||||
@@ -99,7 +99,7 @@ if (typeof window !== "undefined" && window.opera)
|
||||
{
|
||||
PLATFORM_ENGINE = CPOperaBrowserEngine;
|
||||
|
||||
PLATFORM_FEATURES |= CPJavaScriptCanvasDrawFeature;
|
||||
PLATFORM_FEATURES[CPJavaScriptCanvasDrawFeature] = YES;
|
||||
}
|
||||
|
||||
// Internet Explorer
|
||||
@@ -108,16 +108,16 @@ else if (typeof window !== "undefined" && window.attachEvent) // Must follow Ope
|
||||
PLATFORM_ENGINE = CPInternetExplorerBrowserEngine;
|
||||
|
||||
// Features we can only be sure of with IE (no known independent tests)
|
||||
PLATFORM_FEATURES |= CPVMLFeature;
|
||||
PLATFORM_FEATURES |= CPJavaScriptRemedialKeySupport;
|
||||
PLATFORM_FEATURES |= CPJavaScriptShadowFeature;
|
||||
PLATFORM_FEATURES[CPVMLFeature] = YES;
|
||||
PLATFORM_FEATURES[CPJavaScriptRemedialKeySupport] = YES;
|
||||
PLATFORM_FEATURES[CPJavaScriptShadowFeature] = YES;
|
||||
|
||||
PLATFORM_FEATURES |= CPOpacityRequiresFilterFeature;
|
||||
PLATFORM_FEATURES[CPOpacityRequiresFilterFeature] = YES;
|
||||
|
||||
PLATFORM_FEATURES &= ~CPInputTypeCanBeChangedFeature;
|
||||
PLATFORM_FEATURES[CPInputTypeCanBeChangedFeature] = NO;
|
||||
|
||||
// Tested in Internet Explore 8 and 9.
|
||||
PLATFORM_FEATURES &= ~CPInputSetFontOutsideOfDOM;
|
||||
PLATFORM_FEATURES[CPInputSetFontOutsideOfDOM] = NO;
|
||||
}
|
||||
|
||||
// WebKit
|
||||
@@ -126,15 +126,15 @@ else if (USER_AGENT.indexOf("AppleWebKit/") != -1)
|
||||
PLATFORM_ENGINE = CPWebKitBrowserEngine;
|
||||
|
||||
// Features we can only be sure of with WebKit (no known independent tests)
|
||||
PLATFORM_FEATURES |= CPCSSRGBAFeature;
|
||||
PLATFORM_FEATURES |= CPHTMLContentEditableFeature;
|
||||
PLATFORM_FEATURES[CPCSSRGBAFeature] = YES;
|
||||
PLATFORM_FEATURES[CPHTMLContentEditableFeature] = YES;
|
||||
|
||||
if (USER_AGENT.indexOf("Chrome") === -1)
|
||||
PLATFORM_FEATURES |= CPHTMLDragAndDropFeature;
|
||||
PLATFORM_FEATURES[CPHTMLDragAndDropFeature] = YES;
|
||||
|
||||
PLATFORM_FEATURES |= CPJavaScriptClipboardEventsFeature;
|
||||
PLATFORM_FEATURES |= CPJavaScriptClipboardAccessFeature;
|
||||
PLATFORM_FEATURES |= CPJavaScriptShadowFeature;
|
||||
PLATFORM_FEATURES[CPJavaScriptClipboardEventsFeature] = YES;
|
||||
PLATFORM_FEATURES[CPJavaScriptClipboardAccessFeature] = YES;
|
||||
PLATFORM_FEATURES[CPJavaScriptShadowFeature] = YES;
|
||||
|
||||
var versionStart = USER_AGENT.indexOf("AppleWebKit/") + "AppleWebKit/".length,
|
||||
versionEnd = USER_AGENT.indexOf(" ", versionStart),
|
||||
@@ -144,22 +144,22 @@ else if (USER_AGENT.indexOf("AppleWebKit/") != -1)
|
||||
minorVersion = parseInt(versionString.substr(versionDivision + 1));
|
||||
|
||||
if ((USER_AGENT.indexOf("Safari") !== CPNotFound && (majorVersion > 525 || (majorVersion === 525 && minorVersion > 14))) || USER_AGENT.indexOf("Chrome") !== CPNotFound)
|
||||
PLATFORM_FEATURES |= CPJavaScriptRemedialKeySupport;
|
||||
PLATFORM_FEATURES[CPJavaScriptRemedialKeySupport] = YES;
|
||||
|
||||
// FIXME this is a terrible hack to get around this bug:
|
||||
// https://bugs.webkit.org/show_bug.cgi?id=21548
|
||||
if (![CPPlatform isBrowser])
|
||||
PLATFORM_FEATURES |= CPJavaScriptRemedialKeySupport;
|
||||
PLATFORM_FEATURES[CPJavaScriptRemedialKeySupport] = YES;
|
||||
|
||||
if (majorVersion < 532 || (majorVersion === 532 && minorVersion < 6))
|
||||
PLATFORM_FEATURES |= CPHTML5DragAndDropSourceYOffBy1;
|
||||
PLATFORM_FEATURES[CPHTML5DragAndDropSourceYOffBy1] = YES;
|
||||
|
||||
// This is supposedly fixed in webkit r123603. Seems to work in Chrome 21 but not Safari 6.0.
|
||||
if (majorVersion < 537)
|
||||
PLATFORM_FEATURES |= CPInput1PxLeftPadding;
|
||||
PLATFORM_FEATURES[CPInput1PxLeftPadding] = YES;
|
||||
|
||||
if (USER_AGENT.indexOf("Chrome") === CPNotFound)
|
||||
PLATFORM_FEATURES |= CPSOPDisabledFromFileURLs;
|
||||
PLATFORM_FEATURES[CPSOPDisabledFromFileURLs] = YES;
|
||||
|
||||
// Assume this bug was introduced around Safari 5.1/Chrome 16. This could probably be tighter.
|
||||
if (majorVersion > 533)
|
||||
@@ -177,59 +177,74 @@ else if (USER_AGENT.indexOf("Gecko") !== -1) // Must follow KHTML check.
|
||||
{
|
||||
PLATFORM_ENGINE = CPGeckoBrowserEngine;
|
||||
|
||||
PLATFORM_FEATURES |= CPJavaScriptCanvasDrawFeature;
|
||||
PLATFORM_FEATURES[CPJavaScriptCanvasDrawFeature] = YES;
|
||||
|
||||
var index = USER_AGENT.indexOf("Firefox"),
|
||||
version = (index === -1) ? 2.0 : parseFloat(USER_AGENT.substring(index + "Firefox".length + 1));
|
||||
|
||||
if (version >= 3.0)
|
||||
PLATFORM_FEATURES |= CPCSSRGBAFeature;
|
||||
PLATFORM_FEATURES[CPCSSRGBAFeature] = YES;
|
||||
|
||||
if (version < 3.0)
|
||||
PLATFORM_FEATURES |= CPJavaScriptMouseWheelValues_8_15;
|
||||
PLATFORM_FEATURES[CPJavaScriptMouseWheelValues_8_15] = YES;
|
||||
|
||||
// Some day this might be fixed and should be version prefixed. No known fixed version yet.
|
||||
PLATFORM_FEATURES |= CPInput1PxLeftPadding;
|
||||
PLATFORM_FEATURES[CPInput1PxLeftPadding] = YES;
|
||||
}
|
||||
|
||||
// Feature Specific Checks
|
||||
// Feature-specific checks
|
||||
if (typeof document != "undefined")
|
||||
{
|
||||
var canvasElement = document.createElement("canvas");
|
||||
// Detect Canvas Support
|
||||
|
||||
// Detect canvas support
|
||||
if (canvasElement && canvasElement.getContext)
|
||||
{
|
||||
PLATFORM_FEATURES |= CPHTMLCanvasFeature;
|
||||
PLATFORM_FEATURES[CPHTMLCanvasFeature] = YES;
|
||||
|
||||
// Detect Canvas setTransform/transform support
|
||||
// Any browser that supports canvas supports CSS opacity
|
||||
PLATFORM_FEATURES[CPOpacityRequiresFilterFeature] = NO;
|
||||
|
||||
// Detect canvas setTransform/transform support
|
||||
var context = document.createElement("canvas").getContext("2d");
|
||||
|
||||
if (context && context.setTransform && context.transform)
|
||||
PLATFORM_FEATURES |= CPJavaScriptCanvasTransformFeature;
|
||||
PLATFORM_FEATURES[CPJavaScriptCanvasTransformFeature] = YES;
|
||||
}
|
||||
|
||||
var DOMElement = document.createElement("div");
|
||||
|
||||
// Detect whether we have innerText or textContent (or neither)
|
||||
if (DOMElement.innerText != undefined)
|
||||
PLATFORM_FEATURES |= CPJavaScriptInnerTextFeature;
|
||||
PLATFORM_FEATURES[CPJavaScriptInnerTextFeature] = YES;
|
||||
else if (DOMElement.textContent != undefined)
|
||||
PLATFORM_FEATURES |= CPJavaScriptTextContentFeature;
|
||||
PLATFORM_FEATURES[CPJavaScriptTextContentFeature] = YES;
|
||||
|
||||
var DOMInputElement = document.createElement("input");
|
||||
|
||||
if ("oninput" in DOMInputElement)
|
||||
PLATFORM_FEATURES |= CPInputOnInputEventFeature;
|
||||
PLATFORM_FEATURES[CPInputOnInputEventFeature] = YES;
|
||||
else if (typeof DOMInputElement.setAttribute === "function")
|
||||
{
|
||||
DOMInputElement.setAttribute("oninput", "return;");
|
||||
|
||||
if (typeof DOMInputElement.oninput === "function")
|
||||
PLATFORM_FEATURES |= CPInputOnInputEventFeature;
|
||||
PLATFORM_FEATURES[CPInputOnInputEventFeature] = YES;
|
||||
}
|
||||
|
||||
// Detect FileAPI support
|
||||
if (typeof DOMInputElement.setAttribute === "function")
|
||||
{
|
||||
DOMInputElement.setAttribute("type", "file");
|
||||
PLATFORM_FEATURES[CPFileAPIFeature] = !!DOMInputElement["files"];
|
||||
}
|
||||
else
|
||||
PLATFORM_FEATURES[CPFileAPIFeature] = NO;
|
||||
}
|
||||
|
||||
function CPFeatureIsCompatible(aFeature)
|
||||
{
|
||||
return PLATFORM_FEATURES & aFeature;
|
||||
return !!PLATFORM_FEATURES[aFeature];
|
||||
}
|
||||
|
||||
function CPPlatformHasBug(aBug)
|
||||
|
||||
@@ -152,12 +152,14 @@ var CPControlBlackColor = [CPColor blackColor];
|
||||
[self exposeBinding:@"enabled"];
|
||||
}
|
||||
|
||||
+ (Class)_binderClassForBinding:(CPString)theBinding
|
||||
+ (Class)_binderClassForBinding:(CPString)aBinding
|
||||
{
|
||||
if (theBinding === CPValueBinding)
|
||||
if (aBinding === CPValueBinding)
|
||||
return [_CPValueBinder class];
|
||||
else if ([aBinding hasPrefix:CPEnabledBinding])
|
||||
return [CPMultipleValueAndBinding class];
|
||||
|
||||
return [super _binderClassForBinding:theBinding];
|
||||
return [super _binderClassForBinding:aBinding];
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -239,6 +241,9 @@ var CPControlBlackColor = [CPColor blackColor];
|
||||
{
|
||||
[self _reverseSetBinding];
|
||||
|
||||
var binding = [CPBinder getBinding:CPTargetBinding forObject:self];
|
||||
[binding invokeAction];
|
||||
|
||||
return [CPApp sendAction:anAction to:anObject from:self];
|
||||
}
|
||||
|
||||
|
||||
@@ -162,8 +162,10 @@ var currentCursor = nil,
|
||||
|
||||
if (doesHaveImage)
|
||||
{
|
||||
var themeResourcePath = [[[CPApp themeBlend] bundle] resourcePath];
|
||||
cssString = [CPString stringWithFormat:@"url(%@cursors/%@.cur), %@", themeResourcePath, cursorName, aString];
|
||||
var themeResourcePath = [[[CPApp themeBlend] bundle] resourcePath],
|
||||
extension = CPBrowserIsEngine(CPInternetExplorerBrowserEngine) ? @"cur" : @"png";
|
||||
|
||||
cssString = [CPString stringWithFormat:@"url(%@cursors/%@.%@), %@", themeResourcePath, cursorName, extension, aString];
|
||||
}
|
||||
|
||||
else
|
||||
|
||||
@@ -89,7 +89,7 @@ CPGradientDrawsAfterEndingLocation = kCGGradientDrawsAfterEndLocation;
|
||||
CGContextClipToRect(ctx, rect);
|
||||
CGContextAddRect(ctx, rect);
|
||||
|
||||
[self _drawAtAngle:angle];
|
||||
[self _drawInRect:rect atAngle:angle];
|
||||
|
||||
CGContextRestoreGState(ctx);
|
||||
}
|
||||
|
||||
@@ -48,8 +48,8 @@ var imagesForNames = { },
|
||||
AppKitImageForNames = { },
|
||||
ImageDescriptionFormat = "%s {\n filename: \"%s\",\n size: { width:%f, height:%f }\n}";
|
||||
|
||||
AppKitImageForNames[CPImageNameColorPanel] = CGSizeMake(26.0, 29.0);
|
||||
AppKitImageForNames[CPImageNameColorPanelHighlighted] = CGSizeMake(26.0, 29.0);
|
||||
AppKitImageForNames[CPImageNameColorPanel] = _CGSizeMake(26.0, 29.0);
|
||||
AppKitImageForNames[CPImageNameColorPanelHighlighted] = _CGSizeMake(26.0, 29.0);
|
||||
|
||||
/*!
|
||||
Returns a resource image with a relative path and size
|
||||
@@ -72,7 +72,7 @@ function CPImageInBundle()
|
||||
if (typeof(arguments[1]) === "number")
|
||||
{
|
||||
if (arguments[1] !== nil && arguments[1] === undefined)
|
||||
size = CGSizeMake(arguments[1], arguments[2]);
|
||||
size = _CGSizeMake(arguments[1], arguments[2]);
|
||||
|
||||
bundle = arguments[3];
|
||||
}
|
||||
@@ -131,7 +131,7 @@ function CPAppKitImage(aFilename, aSize)
|
||||
|
||||
- (id)init
|
||||
{
|
||||
return [self initByReferencingFile:@"" size:CGSizeMake(-1, -1)];
|
||||
return [self initByReferencingFile:@"" size:_CGSizeMake(-1, -1)];
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -148,7 +148,7 @@ function CPAppKitImage(aFilename, aSize)
|
||||
|
||||
if (self)
|
||||
{
|
||||
_size = CGSizeCreateCopy(aSize);
|
||||
_size = _CGSizeMakeCopy(aSize);
|
||||
_filename = aFilename;
|
||||
_loadStatus = CPImageLoadStatusInitialized;
|
||||
}
|
||||
@@ -180,7 +180,7 @@ function CPAppKitImage(aFilename, aSize)
|
||||
*/
|
||||
- (id)initWithContentsOfFile:(CPString)aFilename
|
||||
{
|
||||
self = [self initByReferencingFile:aFilename size:CGSizeMake(-1, -1)];
|
||||
self = [self initByReferencingFile:aFilename size:_CGSizeMake(-1, -1)];
|
||||
|
||||
if (self)
|
||||
[self load];
|
||||
@@ -247,7 +247,7 @@ function CPAppKitImage(aFilename, aSize)
|
||||
*/
|
||||
- (void)setSize:(CGSize)aSize
|
||||
{
|
||||
_size = CGSizeMakeCopy(aSize);
|
||||
_size = _CGSizeMakeCopy(aSize);
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -433,7 +433,7 @@ function CPAppKitImage(aFilename, aSize)
|
||||
|
||||
// FIXME: IE is wrong on image sizes????
|
||||
if (!_size || (_size.width == -1 && _size.height == -1))
|
||||
_size = CGSizeMake(_image.width, _image.height);
|
||||
_size = _CGSizeMake(_image.width, _image.height);
|
||||
|
||||
[[CPNotificationCenter defaultCenter]
|
||||
postNotificationName:CPImageDidLoadNotification
|
||||
|
||||
@@ -70,12 +70,14 @@ var CPImageViewEmptyPlaceholderImage = nil;
|
||||
CPImageViewEmptyPlaceholderImage = [[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"empty.png"]];
|
||||
}
|
||||
|
||||
+ (Class)_binderClassForBinding:(CPString)theBinding
|
||||
+ (Class)_binderClassForBinding:(CPString)aBinding
|
||||
{
|
||||
if (theBinding === CPValueBinding || theBinding === CPValueURLBinding || theBinding === CPValuePathBinding || theBinding === CPDataBinding)
|
||||
if (aBinding === CPValueBinding || aBinding === CPValueURLBinding || aBinding === CPValuePathBinding || aBinding === CPDataBinding)
|
||||
return [CPImageViewValueBinder class];
|
||||
else if ([aBinding hasPrefix:CPEditableBinding])
|
||||
return [CPMultipleValueAndBinding class];
|
||||
|
||||
return [super _binderClassForBinding:theBinding];
|
||||
return [super _binderClassForBinding:aBinding];
|
||||
}
|
||||
|
||||
- (id)initWithFrame:(CGRect)aFrame
|
||||
|
||||
@@ -26,9 +26,11 @@
|
||||
@import <Foundation/CPObject.j>
|
||||
@import <Foundation/CPArray.j>
|
||||
@import <Foundation/CPDictionary.j>
|
||||
@import <Foundation/CPInvocation.j>
|
||||
@import <Foundation/CPValueTransformer.j>
|
||||
@import <Foundation/CPKeyValueObserving.j>
|
||||
|
||||
@class CPButton
|
||||
|
||||
var exposedBindingsMap = [CPDictionary new],
|
||||
bindingsMap = [CPDictionary new];
|
||||
@@ -39,7 +41,7 @@ var CPBindingOperationAnd = 0,
|
||||
@implementation CPBinder : CPObject
|
||||
{
|
||||
CPDictionary _info;
|
||||
id _source;
|
||||
id _source @accessors(getter=source);
|
||||
|
||||
JSObject _suppressedNotifications;
|
||||
JSObject _placeholderForMarker;
|
||||
@@ -95,9 +97,9 @@ var CPBindingOperationAnd = 0,
|
||||
if (!theBinding)
|
||||
return;
|
||||
|
||||
var infoDictionary = theBinding._info,
|
||||
observedObject = [infoDictionary objectForKey:CPObservedObjectKey],
|
||||
keyPath = [infoDictionary objectForKey:CPObservedKeyPathKey];
|
||||
var info = theBinding._info,
|
||||
observedObject = [info objectForKey:CPObservedObjectKey],
|
||||
keyPath = [info objectForKey:CPObservedKeyPathKey];
|
||||
|
||||
[observedObject removeObserver:theBinding forKeyPath:keyPath];
|
||||
[bindings removeObjectForKey:aBinding];
|
||||
@@ -106,6 +108,7 @@ var CPBindingOperationAnd = 0,
|
||||
+ (void)unbindAllForObject:(id)anObject
|
||||
{
|
||||
var bindings = [bindingsMap objectForKey:[anObject UID]];
|
||||
|
||||
if (!bindings)
|
||||
return;
|
||||
|
||||
@@ -120,12 +123,14 @@ var CPBindingOperationAnd = 0,
|
||||
|
||||
- (id)initWithBinding:(CPString)aBinding name:(CPString)aName to:(id)aDestination keyPath:(CPString)aKeyPath options:(CPDictionary)options from:(id)aSource
|
||||
{
|
||||
self = [super init];
|
||||
// We use [self init] here because subclasses override init. We can't override this method
|
||||
// because their initialization has to occur before this method in this class is executed.
|
||||
self = [self init];
|
||||
|
||||
if (self)
|
||||
{
|
||||
_source = aSource;
|
||||
_info = [CPDictionary dictionaryWithObjects:[aDestination, aKeyPath] forKeys:[CPObservedObjectKey, CPObservedKeyPathKey]];
|
||||
_info = [CPDictionary dictionaryWithObjects:[aDestination, aKeyPath] forKeys:[CPObservedObjectKey, CPObservedKeyPathKey]];
|
||||
_suppressedNotifications = {};
|
||||
_placeholderForMarker = {};
|
||||
|
||||
@@ -137,6 +142,7 @@ var CPBindingOperationAnd = 0,
|
||||
[aDestination addObserver:self forKeyPath:aKeyPath options:CPKeyValueObservingOptionNew context:aBinding];
|
||||
|
||||
var bindings = [bindingsMap objectForKey:[_source UID]];
|
||||
|
||||
if (!bindings)
|
||||
{
|
||||
bindings = [CPDictionary new];
|
||||
@@ -150,21 +156,25 @@ var CPBindingOperationAnd = 0,
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)raiseIfNotApplicable:(id)aValue forKeyPath:(CPString)keyPath options:(CPDictionary)options
|
||||
{
|
||||
if (aValue === CPNotApplicableMarker && [options objectForKey:CPRaisesForNotApplicableKeysBindingOption])
|
||||
{
|
||||
[CPException raise:CPGenericException
|
||||
reason:@"Cannot transform non-applicable key on: " + _source + " key path: " + keyPath + " value: " + aValue];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)setValueFor:(CPString)theBinding
|
||||
{
|
||||
var destination = [_info objectForKey:CPObservedObjectKey],
|
||||
keyPath = [_info objectForKey:CPObservedKeyPathKey],
|
||||
options = [_info objectForKey:CPOptionsKey],
|
||||
newValue = [destination valueForKeyPath:keyPath],
|
||||
isPlaceholder = CPIsControllerMarker(newValue);
|
||||
newValue = [destination valueForKeyPath:keyPath];
|
||||
|
||||
if (isPlaceholder)
|
||||
if (CPIsControllerMarker(newValue))
|
||||
{
|
||||
if (newValue === CPNotApplicableMarker && [options objectForKey:CPRaisesForNotApplicableKeysBindingOption])
|
||||
{
|
||||
[CPException raise:CPGenericException
|
||||
reason:@"Cannot transform non-applicable key on: " + _source + " key path: " + keyPath + " value: " + newValue];
|
||||
}
|
||||
[self raiseIfNotApplicable:newValue forKeyPath:keyPath options:options];
|
||||
|
||||
var value = [self _placeholderForMarker:newValue];
|
||||
[self setPlaceholderValue:value withMarker:newValue forBinding:theBinding];
|
||||
@@ -211,6 +221,7 @@ var CPBindingOperationAnd = 0,
|
||||
return;
|
||||
|
||||
var objectSuppressions = _suppressedNotifications[[anObject UID]];
|
||||
|
||||
if (objectSuppressions && objectSuppressions[aKeyPath])
|
||||
return;
|
||||
|
||||
@@ -229,6 +240,7 @@ var CPBindingOperationAnd = 0,
|
||||
if (!valueTransformer)
|
||||
{
|
||||
var valueTransformerClass = CPClassFromString(valueTransformerName);
|
||||
|
||||
if (valueTransformerClass)
|
||||
{
|
||||
valueTransformer = [[valueTransformerClass alloc] init];
|
||||
@@ -286,6 +298,7 @@ var CPBindingOperationAnd = 0,
|
||||
|
||||
var uid = [anObject UID],
|
||||
objectSuppressions = _suppressedNotifications[uid];
|
||||
|
||||
if (!objectSuppressions)
|
||||
_suppressedNotifications[uid] = objectSuppressions = {};
|
||||
|
||||
@@ -302,6 +315,7 @@ var CPBindingOperationAnd = 0,
|
||||
|
||||
var uid = [anObject UID],
|
||||
objectSuppressions = _suppressedNotifications[uid];
|
||||
|
||||
if (!objectSuppressions)
|
||||
return;
|
||||
|
||||
@@ -318,6 +332,7 @@ var CPBindingOperationAnd = 0,
|
||||
optionName = CPBinderPlaceholderOptions[count],
|
||||
isExplicit = [options containsKey:optionName],
|
||||
placeholder = isExplicit ? [options objectForKey:optionName] : nil;
|
||||
|
||||
[self _setPlaceholder:placeholder forMarker:marker isDefault:!isExplicit];
|
||||
}
|
||||
}
|
||||
@@ -330,8 +345,10 @@ var CPBindingOperationAnd = 0,
|
||||
- (void)_placeholderForMarker:aMarker
|
||||
{
|
||||
var placeholder = _placeholderForMarker[aMarker];
|
||||
|
||||
if (placeholder)
|
||||
return placeholder['value'];
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
@@ -358,7 +375,7 @@ var CPBindingOperationAnd = 0,
|
||||
[CPBinder exposeBinding:aBinding forClass:[self class]];
|
||||
}
|
||||
|
||||
+ (Class)_binderClassForBinding:(CPString)theBinding
|
||||
+ (Class)_binderClassForBinding:(CPString)aBinding
|
||||
{
|
||||
return [CPBinder class];
|
||||
}
|
||||
@@ -411,7 +428,7 @@ var CPBindingOperationAnd = 0,
|
||||
[binderClass unbind:aBinding forObject:self];
|
||||
}
|
||||
|
||||
- (id)_replacementKeyPathForBinding:(CPString)binding
|
||||
- (CPString)_replacementKeyPathForBinding:(CPString)binding
|
||||
{
|
||||
return binding;
|
||||
}
|
||||
@@ -420,13 +437,13 @@ var CPBindingOperationAnd = 0,
|
||||
|
||||
/*!
|
||||
@ignore
|
||||
Provides stub implementations that simply call super for the "objectValue" binding
|
||||
This class should not be necessary but assures backwards compliance with our old way of doing bindings
|
||||
Every class with a value binding should implement a subclass to handle it's specific value binding logic
|
||||
Provides stub implementations that simply calls super for the "objectValue" binding.
|
||||
This class should not be necessary but assures backwards compliance with our old way of doing bindings.
|
||||
|
||||
IMPORTANT!
|
||||
Every class with a value binding should implement a subclass to handle its specific value binding logic.
|
||||
*/
|
||||
@implementation _CPValueBinder : CPBinder
|
||||
{
|
||||
}
|
||||
|
||||
- (void)setValueFor:(CPString)theBinding
|
||||
{
|
||||
@@ -440,8 +457,9 @@ var CPBindingOperationAnd = 0,
|
||||
|
||||
@end
|
||||
|
||||
@implementation _CPKeyValueOrBinding : CPBinder
|
||||
@implementation _CPMultipleValueBooleanBinding : CPBinder
|
||||
{
|
||||
CPBindingOperationKind _operation;
|
||||
}
|
||||
|
||||
- (void)setValueFor:(CPString)aBinding
|
||||
@@ -451,7 +469,14 @@ var CPBindingOperationAnd = 0,
|
||||
if (!bindings)
|
||||
return;
|
||||
|
||||
[_source setValue:resolveMultipleValues(aBinding, bindings, CPBindingOperationOr) forKey:aBinding];
|
||||
var baseBinding = aBinding.replace(/\d$/, "");
|
||||
|
||||
[_source setValue:[self resolveMultipleValuesForBinding:baseBinding bindings:bindings booleanOperation:_operation] forKey:baseBinding];
|
||||
}
|
||||
|
||||
- (void)reverseSetValueFor:(CPString)theBinding
|
||||
{
|
||||
// read-only
|
||||
}
|
||||
|
||||
- (void)observeValueForKeyPath:(CPString)aKeyPath ofObject:(id)anObject change:(CPDictionary)changes context:(id)context
|
||||
@@ -459,61 +484,146 @@ var CPBindingOperationAnd = 0,
|
||||
[self setValueFor:context];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation _CPKeyValueAndBinding : CPBinder
|
||||
- (BOOL)resolveMultipleValuesForBinding:(CPString)aBinding bindings:(CPDictionary)bindings booleanOperation:(CPBindingOperationKind)operation
|
||||
{
|
||||
}
|
||||
|
||||
- (void)setValueFor:(CPString)aBinding
|
||||
{
|
||||
var bindings = [bindingsMap objectForKey:[_source UID]];
|
||||
|
||||
if (!bindings)
|
||||
return;
|
||||
|
||||
[_source setValue:resolveMultipleValues(aBinding, bindings, CPBindingOperationAnd) forKey:aBinding];
|
||||
}
|
||||
|
||||
- (void)observeValueForKeyPath:(CPString)aKeyPath ofObject:(id)anObejct change:(CPDictionary)changes context:(id)context
|
||||
{
|
||||
[self setValueFor:context];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
var resolveMultipleValues = function(/*CPString*/key, /*CPDictionary*/bindings, /*GSBindingOperationKind*/operation)
|
||||
{
|
||||
var bindingName = key,
|
||||
var bindingName = aBinding,
|
||||
theBinding,
|
||||
count = 1;
|
||||
count = 2;
|
||||
|
||||
while (theBinding = [bindings objectForKey:bindingName])
|
||||
{
|
||||
var infoDictionary = theBinding._info,
|
||||
object = [infoDictionary objectForKey:CPObservedObjectKey],
|
||||
keyPath = [infoDictionary objectForKey:CPObservedKeyPathKey],
|
||||
options = [infoDictionary objectForKey:CPOptionsKey];
|
||||
var info = theBinding._info,
|
||||
object = [info objectForKey:CPObservedObjectKey],
|
||||
keyPath = [info objectForKey:CPObservedKeyPathKey],
|
||||
options = [info objectForKey:CPOptionsKey],
|
||||
value = [object valueForKeyPath:keyPath];
|
||||
|
||||
var value = [theBinding transformValue:[object valueForKeyPath:keyPath] withOptions:options];
|
||||
if (CPIsControllerMarker(value))
|
||||
{
|
||||
[self raiseIfNotApplicable:value forKeyPath:keyPath options:options];
|
||||
value = [theBinding _placeholderForMarker:value];
|
||||
}
|
||||
else
|
||||
value = [theBinding transformValue:value withOptions:options];
|
||||
|
||||
if (value == operation)
|
||||
return operation;
|
||||
if (operation === CPBindingOperationOr)
|
||||
{
|
||||
// Any true condition means true for OR
|
||||
if (value)
|
||||
return YES;
|
||||
}
|
||||
|
||||
bindingName = [CPString stringWithFormat:@"%@%i", key, ++count];
|
||||
// Any false condition means false for AND
|
||||
else if (!value)
|
||||
return NO;
|
||||
|
||||
bindingName = aBinding + (count++);
|
||||
}
|
||||
|
||||
return !operation;
|
||||
};
|
||||
// If we get here, all OR conditions were false or all AND conditions were true
|
||||
return operation === CPBindingOperationOr ? NO : YES;
|
||||
}
|
||||
|
||||
var invokeAction = function(/*CPString*/targetKey, /*CPString*/argumentKey, /*CPDictionary*/bindings)
|
||||
@end
|
||||
|
||||
@implementation CPMultipleValueAndBinding : _CPMultipleValueBooleanBinding
|
||||
|
||||
- (id)init
|
||||
{
|
||||
var theBinding = [bindings objectForKey:targetKey],
|
||||
infoDictionary = theBinding._info,
|
||||
if (self = [super init])
|
||||
_operation = CPBindingOperationAnd;
|
||||
|
||||
object = [infoDictionary objectForKey:CPObservedObjectKey],
|
||||
keyPath = [infoDictionary objectForKey:CPObservedKeyPathKey],
|
||||
options = [infoDictionary objectForKey:CPOptionsKey],
|
||||
return self;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation CPMultipleValueOrBinding : _CPMultipleValueBooleanBinding
|
||||
|
||||
- (id)init
|
||||
{
|
||||
if (self = [super init])
|
||||
_operation = CPBindingOperationOr;
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation _CPMultipleValueArgumentBinding : CPBinder
|
||||
{
|
||||
CPString _argumentBinding;
|
||||
CPString _targetBinding;
|
||||
}
|
||||
|
||||
- (void)setValueFor:(CPString)theBinding
|
||||
{
|
||||
// Called when the binding is first created
|
||||
[self checkForNullBinding:theBinding initializing:YES];
|
||||
}
|
||||
|
||||
- (void)reverseSetValueFor:(CPString)theBinding
|
||||
{
|
||||
// no-op
|
||||
}
|
||||
|
||||
- (void)observeValueForKeyPath:(CPString)aKeyPath ofObject:(id)anObject change:(CPDictionary)changes context:(id)context
|
||||
{
|
||||
// context is the binding name
|
||||
[self checkForNullBinding:context initializing:NO];
|
||||
}
|
||||
|
||||
/*!
|
||||
@ignore
|
||||
|
||||
When the value of a multiple-value argument binding changes,
|
||||
if the binding is marked not to allow null arguments, we have to check
|
||||
if the binding's value is nil and disable the button if it is.
|
||||
Otherwise the button is enabled.
|
||||
*/
|
||||
- (void)checkForNullBinding:(CPString)theBinding initializing:(BOOL)isInitializing
|
||||
{
|
||||
// Only done for buttons
|
||||
if (![_source isKindOfClass:CPButton])
|
||||
return;
|
||||
|
||||
// We start with the button enabled for the first argument during init,
|
||||
// and subsequent checks can disable it.
|
||||
if (isInitializing && theBinding === CPArgumentBinding)
|
||||
[_source setEnabled:YES];
|
||||
|
||||
var bindings = [bindingsMap valueForKey:[_source UID]],
|
||||
binding = [bindings objectForKey:theBinding],
|
||||
info = binding._info,
|
||||
options = [info objectForKey:CPOptionsKey];
|
||||
|
||||
if (![options valueForKey:CPAllowsNullArgumentBindingOption])
|
||||
{
|
||||
var object = [info objectForKey:CPObservedObjectKey],
|
||||
keyPath = [info objectForKey:CPObservedKeyPathKey],
|
||||
value = [object valueForKeyPath:keyPath];
|
||||
|
||||
if (value === nil || value === undefined)
|
||||
{
|
||||
[_source setEnabled:NO];
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// If a binding value changed and did not fail the null test, enable the button
|
||||
if (!isInitializing)
|
||||
[_source setEnabled:YES];
|
||||
}
|
||||
|
||||
- (void)invokeAction
|
||||
{
|
||||
var bindings = [bindingsMap valueForKey:[_source UID]],
|
||||
theBinding = [bindings objectForKey:CPTargetBinding],
|
||||
|
||||
info = theBinding._info,
|
||||
object = [info objectForKey:CPObservedObjectKey],
|
||||
keyPath = [info objectForKey:CPObservedKeyPathKey],
|
||||
options = [info objectForKey:CPOptionsKey],
|
||||
|
||||
target = [object valueForKeyPath:keyPath],
|
||||
selector = [options objectForKey:CPSelectorNameBindingOption];
|
||||
@@ -521,27 +631,174 @@ var invokeAction = function(/*CPString*/targetKey, /*CPString*/argumentKey, /*CP
|
||||
if (!target || !selector)
|
||||
return;
|
||||
|
||||
var invocation = [CPInvocation invocationWithMethodSignature:[target methodSignatureForSelector:selector]];
|
||||
[invocation setSelector:selector];
|
||||
|
||||
var bindingName = argumentKey,
|
||||
var invocation = [CPInvocation invocationWithMethodSignature:[target methodSignatureForSelector:selector]],
|
||||
bindingName = CPArgumentBinding,
|
||||
count = 1;
|
||||
|
||||
while (theBinding = [bindings objectForKey:bindingName])
|
||||
{
|
||||
infoDictionary = theBinding._info;
|
||||
info = theBinding._info;
|
||||
object = [info objectForKey:CPObservedObjectKey];
|
||||
keyPath = [info objectForKey:CPObservedKeyPathKey];
|
||||
|
||||
keyPath = [infoDictionary objectForKey:CPObserverKeyPathKey];
|
||||
object = [[infoDictionary objectForKey:CPObservedObjectKey] valueForKeyPath:keyPath];
|
||||
[invocation setArgument:[object valueForKeyPath:keyPath] atIndex:++count];
|
||||
|
||||
if (object)
|
||||
[invocation setArgument:object atIndex:++count];
|
||||
|
||||
bindingName = [CPString stringWithFormat:@"%@%i", argumentKey, count];
|
||||
bindingName = CPArgumentBinding + count;
|
||||
}
|
||||
|
||||
[invocation invoke];
|
||||
};
|
||||
[invocation setSelector:selector];
|
||||
[invocation invokeWithTarget:target];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation CPArgumentTargetBinding : _CPMultipleValueArgumentBinding
|
||||
|
||||
- (id)init
|
||||
{
|
||||
if (self = [super init])
|
||||
{
|
||||
_argumentBinding = CPArgumentBinding;
|
||||
_targetBinding = CPTargetBinding;
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation CPDoubleClickArgumentTargetBinding : _CPMultipleValueArgumentBinding
|
||||
|
||||
- (id)init
|
||||
{
|
||||
if (self = [super init])
|
||||
{
|
||||
_argumentBinding = CPArgumentBinding;
|
||||
_targetBinding = CPTargetBinding;
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
/*!
|
||||
Abstract superclass for CPValueWithPatternBinding and CPTitleWithPatternBinding.
|
||||
*/
|
||||
@implementation _CPPatternBinding : CPBinder
|
||||
{
|
||||
CPString _bindingKey;
|
||||
CPString _patternPlaceholder;
|
||||
}
|
||||
|
||||
- (void)setValueFor:(CPString)aBinding
|
||||
{
|
||||
var bindings = [bindingsMap valueForKey:[_source UID]];
|
||||
|
||||
if (!bindings)
|
||||
return;
|
||||
|
||||
// Strip off any trailing number from the binding name
|
||||
var baseBinding = aBinding.replace(/\d$/, ""),
|
||||
result = [self resolveMultipleValuesForBindings:bindings];
|
||||
|
||||
if (result.isPlaceholder)
|
||||
[self setPlaceholderValue:result.value withMarker:result.marker forBinding:baseBinding];
|
||||
else
|
||||
[self setValue:result.value forBinding:baseBinding];
|
||||
}
|
||||
|
||||
- (void)reverseSetValueFor:(CPString)theBinding
|
||||
{
|
||||
// read-only
|
||||
}
|
||||
|
||||
- (void)observeValueForKeyPath:(CPString)aKeyPath ofObject:(id)anObject change:(CPDictionary)changes context:(id)context
|
||||
{
|
||||
[self setValueFor:context];
|
||||
}
|
||||
|
||||
- (JSObject)resolveMultipleValuesForBindings:(CPDictionary)bindings
|
||||
{
|
||||
var theBinding,
|
||||
result = { value:@"", isPlaceholder:NO, marker:nil };
|
||||
|
||||
for (var count = 1; theBinding = [bindings objectForKey:_bindingKey + count]; ++count)
|
||||
{
|
||||
var info = theBinding._info,
|
||||
object = [info objectForKey:CPObservedObjectKey],
|
||||
keyPath = [info objectForKey:CPObservedKeyPathKey],
|
||||
options = [info objectForKey:CPOptionsKey],
|
||||
value = [object valueForKeyPath:keyPath];
|
||||
|
||||
if (count === 1)
|
||||
result.value = [options objectForKey:CPDisplayPatternBindingOption];
|
||||
|
||||
if (CPIsControllerMarker(value))
|
||||
{
|
||||
[self raiseIfNotApplicable:value forKeyPath:keyPath options:options];
|
||||
|
||||
result.isPlaceholder = YES;
|
||||
result.marker = value;
|
||||
|
||||
value = [theBinding _placeholderForMarker:value];
|
||||
}
|
||||
else
|
||||
value = [theBinding transformValue:value withOptions:options];
|
||||
|
||||
if (value === nil || value === undefined)
|
||||
value = @"";
|
||||
|
||||
result.value = result.value.replace("%{" + _patternPlaceholder + count + "}@", [value description]);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
/*!
|
||||
Users of this class must override setValue:forKey: and if the
|
||||
key is CPDisplayPatternValueBinding, set the appropriate value
|
||||
for the control class. For example, CPTextField uses setObjectValue.
|
||||
*/
|
||||
@implementation CPValueWithPatternBinding : _CPPatternBinding
|
||||
|
||||
- (id)init
|
||||
{
|
||||
if (self = [super init])
|
||||
{
|
||||
_bindingKey = CPDisplayPatternValueBinding;
|
||||
_patternPlaceholder = @"value";
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
/*!
|
||||
Users of this class must override setValue:forKey: and if the
|
||||
key is CPDisplayPatternTitleBinding, set the appropriate value
|
||||
for the control class. For example, CPBox uses setTitle.
|
||||
*/
|
||||
@implementation CPTitleWithPatternBinding : _CPPatternBinding
|
||||
|
||||
- (id)init
|
||||
{
|
||||
if (self = [super init])
|
||||
{
|
||||
_bindingKey = CPDisplayPatternTitleBinding;
|
||||
_patternPlaceholder = @"title";
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
// Keys in options dictionary
|
||||
|
||||
@@ -558,11 +815,16 @@ CPNullMarker = @"CPNullMarker";
|
||||
|
||||
// Binding name constants
|
||||
CPAlignmentBinding = @"alignment";
|
||||
CPArgumentBinding = @"argument";
|
||||
CPContentArrayBinding = @"contentArray";
|
||||
CPContentBinding = @"content";
|
||||
CPContentObjectBinding = @"contentObject";
|
||||
CPContentObjectsBinding = @"contentObjects";
|
||||
CPContentValuesBinding = @"contentValues";
|
||||
CPDisplayPatternTitleBinding = @"displayPatternTitle";
|
||||
CPDisplayPatternValueBinding = @"displayPatternValue";
|
||||
CPDoubleClickArgumentBinding = @"doubleClickArgument";
|
||||
CPDoubleClickTargetBinding = @"doubleClickTarget";
|
||||
CPEditableBinding = @"editable";
|
||||
CPEnabledBinding = @"enabled";
|
||||
CPFontBinding = @"font";
|
||||
@@ -581,6 +843,7 @@ CPSelectedTagBinding = @"selectedTag";
|
||||
CPSelectedValueBinding = @"selectedValue";
|
||||
CPSelectedValuesBinding = @"selectedValues";
|
||||
CPSelectionIndexesBinding = @"selectionIndexes";
|
||||
CPTargetBinding = @"target";
|
||||
CPTextColorBinding = @"textColor";
|
||||
CPTitleBinding = @"title";
|
||||
CPToolTipBinding = @"toolTip";
|
||||
@@ -589,7 +852,7 @@ CPValueURLBinding = @"valueURL";
|
||||
CPValuePathBinding = @"valuePath";
|
||||
CPDataBinding = @"data";
|
||||
|
||||
//Binding options constants
|
||||
// Binding options constants
|
||||
CPAllowsEditingMultipleValuesSelectionBindingOption = @"CPAllowsEditingMultipleValuesSelection";
|
||||
CPAllowsNullArgumentBindingOption = @"CPAllowsNullArgument";
|
||||
CPConditionallySetsEditableBindingOption = @"CPConditionallySetsEditable";
|
||||
|
||||
@@ -72,8 +72,6 @@ CPRatingLevelIndicatorStyle = 3;
|
||||
1.0, @"spacing"];
|
||||
}
|
||||
|
||||
|
||||
|
||||
- (id)initWithFrame:(CGRect)aFrame
|
||||
{
|
||||
self = [super initWithFrame:aFrame];
|
||||
@@ -84,17 +82,11 @@ CPRatingLevelIndicatorStyle = 3;
|
||||
_maxValue = 2;
|
||||
_warningValue = 2;
|
||||
_criticalValue = 2;
|
||||
|
||||
[self _init];
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)_init
|
||||
{
|
||||
}
|
||||
|
||||
- (void)layoutSubviews
|
||||
{
|
||||
var bezelView = [self layoutEphemeralSubviewNamed:"bezel"
|
||||
@@ -348,8 +340,6 @@ var CPLevelIndicatorStyleKey = "CPLevelIndicatorStyleKey",
|
||||
|
||||
_isEditable = [aCoder decodeBoolForKey:CPLevelIndicatorIsEditableKey];
|
||||
|
||||
[self _init];
|
||||
|
||||
[self setNeedsLayout];
|
||||
[self setNeedsDisplay:YES];
|
||||
}
|
||||
|
||||
@@ -359,7 +359,12 @@ var _CPMenuBarVisible = NO,
|
||||
*/
|
||||
- (void)itemChanged:(CPMenuItem)aMenuItem
|
||||
{
|
||||
if ([aMenuItem menu] !== self)
|
||||
/*
|
||||
During cib unarchiving, menu items will have a reference to their menu,
|
||||
but of course the items are still being unarchived and the menu's _items
|
||||
have not yet been instantiated. In that case we will not do anything here.
|
||||
*/
|
||||
if ([aMenuItem menu] !== self || !_items)
|
||||
return;
|
||||
|
||||
[aMenuItem setValue:[aMenuItem valueForKey:@"changeCount"] + 1 forKey:@"changeCount"];
|
||||
|
||||
@@ -701,6 +701,8 @@ var STICKY_TIME_INTERVAL = 0.4,
|
||||
if ([item isSeparatorItem] || [item isHidden] || ![item isEnabled])
|
||||
[self moveDown:menu];
|
||||
}
|
||||
else if (menu == [CPApp mainMenu])
|
||||
[menu _highlightItemAtIndex:0];
|
||||
}
|
||||
|
||||
- (void)moveUp:(CPMenu)menu
|
||||
@@ -709,10 +711,12 @@ var STICKY_TIME_INTERVAL = 0.4,
|
||||
|
||||
if (index < 0)
|
||||
{
|
||||
if (index != CPNotFound)
|
||||
if (index != CPNotFound || menu == [CPApp mainMenu])
|
||||
[menu _highlightItemAtIndex:[menu numberOfItems] - 1];
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
[menu _highlightItemAtIndex:index];
|
||||
|
||||
var item = [menu highlightedItem];
|
||||
|
||||
@@ -105,6 +105,14 @@ var CPMenuItemStringRepresentationDictionary = [CPDictionary dictionaryWithObjec
|
||||
_CPMenuItemView _menuItemView;
|
||||
}
|
||||
|
||||
+ (Class)_binderClassForBinding:(CPString)aBinding
|
||||
{
|
||||
if ([aBinding hasPrefix:CPEnabledBinding])
|
||||
return [CPMultipleValueAndBinding class];
|
||||
|
||||
return [super _binderClassForBinding:aBinding];
|
||||
}
|
||||
|
||||
- (id)init
|
||||
{
|
||||
return [self initWithTitle:@"" action:nil keyEquivalent:nil];
|
||||
|
||||
@@ -37,7 +37,6 @@
|
||||
BOOL _isDirty;
|
||||
|
||||
_CPImageAndTextView _imageAndTextView;
|
||||
CPView _submenuIndicatorView;
|
||||
}
|
||||
|
||||
+ (CPString)defaultThemeClass
|
||||
@@ -47,9 +46,8 @@
|
||||
|
||||
+ (id)themeAttributes
|
||||
{
|
||||
return [CPDictionary dictionaryWithObjects:[[CPNull null], [CPNull null], [CPNull null], 8.0, 3.0, 4.0]
|
||||
forKeys:[ @"submenu-indicator-color",
|
||||
@"menu-item-selection-color",
|
||||
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",
|
||||
@@ -76,12 +74,6 @@
|
||||
|
||||
[self addSubview:_imageAndTextView];
|
||||
|
||||
_submenuIndicatorView = [[_CPMenuItemMenuBarSubmenuIndicatorView alloc] initWithFrame:CGRectMake(0.0, 0.0, 9.0, 6.0)];
|
||||
|
||||
[_submenuIndicatorView setAutoresizingMask:CPViewMinYMargin | CPViewMaxYMargin];
|
||||
|
||||
[self addSubview:_submenuIndicatorView];
|
||||
|
||||
[self setAutoresizingMask:CPViewWidthSizable | CPViewHeightSizable];
|
||||
}
|
||||
|
||||
@@ -99,7 +91,7 @@
|
||||
- (CPColor)textShadowColor
|
||||
{
|
||||
if (![_menuItem isEnabled])
|
||||
return [CPColor colorWithWhite:0.8 alpha:0.8];
|
||||
return [CPColor clearColor];
|
||||
|
||||
return _textShadowColor || [CPColor colorWithWhite:1.0 alpha:0.8];
|
||||
}
|
||||
@@ -122,37 +114,11 @@
|
||||
|
||||
imageAndTextViewFrame.origin.x = x;
|
||||
x += CGRectGetWidth(imageAndTextViewFrame);
|
||||
height = MAX(height, CGRectGetHeight(imageAndTextViewFrame));
|
||||
|
||||
var hasSubmenuIndicator = [_menuItem hasSubmenu] && [_menuItem action];
|
||||
|
||||
if (hasSubmenuIndicator)
|
||||
{
|
||||
[_submenuIndicatorView setHidden:NO];
|
||||
[_submenuIndicatorView setColor:[self textColor]];
|
||||
[_submenuIndicatorView setShadowColor:[self textShadowColor]];
|
||||
|
||||
var submenuViewFrame = [_submenuIndicatorView frame];
|
||||
|
||||
submenuViewFrame.origin.x = x + [self valueForThemeAttribute:@"submenu-indicator-margin"];
|
||||
|
||||
x = CGRectGetMaxX(submenuViewFrame);
|
||||
height = MAX(height, CGRectGetHeight(submenuViewFrame));
|
||||
}
|
||||
else
|
||||
[_submenuIndicatorView setHidden:YES];
|
||||
|
||||
height += 2.0 * [self valueForThemeAttribute:@"vertical-margin"];
|
||||
height = MAX(height, CGRectGetHeight(imageAndTextViewFrame)) + 2.0 * [self valueForThemeAttribute:@"vertical-margin"];
|
||||
|
||||
imageAndTextViewFrame.origin.y = FLOOR((height - CGRectGetHeight(imageAndTextViewFrame)) / 2.0);
|
||||
[_imageAndTextView setFrame:imageAndTextViewFrame];
|
||||
|
||||
if (hasSubmenuIndicator)
|
||||
{
|
||||
submenuViewFrame.origin.y = FLOOR((height - CGRectGetHeight(submenuViewFrame)) / 2.0) + 1.0;
|
||||
[_submenuIndicatorView setFrame:submenuViewFrame];
|
||||
}
|
||||
|
||||
[self setAutoresizesSubviews:NO];
|
||||
[self setFrameSize:CGSizeMake(x + [self valueForThemeAttribute:@"horizontal-margin"], height)];
|
||||
[self setAutoresizesSubviews:YES];
|
||||
@@ -172,9 +138,6 @@
|
||||
[_imageAndTextView setImage:[_menuItem alternateImage] || [_menuItem image]];
|
||||
[_imageAndTextView setTextColor:[CPColor whiteColor]];
|
||||
[_imageAndTextView setTextShadowColor:[self valueForThemeAttribute:@"menu-item-text-shadow-color"]];
|
||||
|
||||
[_submenuIndicatorView setColor:[CPColor whiteColor]];
|
||||
[_submenuIndicatorView setShadowColor:[CPColor colorWithWhite:0.1 alpha:0.7]];
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -183,60 +146,7 @@
|
||||
[_imageAndTextView setImage:[_menuItem image]];
|
||||
[_imageAndTextView setTextColor:[self textColor]];
|
||||
[_imageAndTextView setTextShadowColor:[self textShadowColor]];
|
||||
|
||||
[_submenuIndicatorView setColor:[self textColor]];
|
||||
[_submenuIndicatorView setShadowColor:[self textShadowColor]];
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation _CPMenuItemMenuBarSubmenuIndicatorView : CPView
|
||||
{
|
||||
CPColor _color;
|
||||
CPColor _shadowColor;
|
||||
}
|
||||
|
||||
- (void)setColor:(CPColor)aColor
|
||||
{
|
||||
if (_color === aColor)
|
||||
return;
|
||||
|
||||
_color = aColor;
|
||||
|
||||
[self setNeedsDisplay:YES];
|
||||
}
|
||||
|
||||
- (void)setShadowColor:(CPColor)aColor
|
||||
{
|
||||
if (_shadowColor === aColor)
|
||||
return;
|
||||
|
||||
_shadowColor = aColor;
|
||||
|
||||
[self setNeedsDisplay:YES];
|
||||
}
|
||||
|
||||
- (void)drawRect:(CGRect)aRect
|
||||
{
|
||||
var context = [[CPGraphicsContext currentContext] graphicsPort],
|
||||
bounds = [self bounds];
|
||||
|
||||
bounds.size.height -= 1.0;
|
||||
bounds.size.width -= 2.0;
|
||||
bounds.origin.x += 1.0;
|
||||
|
||||
CGContextBeginPath(context);
|
||||
|
||||
CGContextMoveToPoint(context, CGRectGetMinX(bounds), CGRectGetMinY(bounds));
|
||||
CGContextAddLineToPoint(context, CGRectGetMaxX(bounds), CGRectGetMinY(bounds));
|
||||
CGContextAddLineToPoint(context, CGRectGetMidX(bounds), CGRectGetMaxY(bounds));
|
||||
|
||||
CGContextClosePath(context);
|
||||
|
||||
CGContextSetShadowWithColor(context, CGSizeMake(0.0, 1.0), 1.1, _shadowColor || [CPColor whiteColor]);
|
||||
CGContextSetFillColor(context, _color || [CPColor blackColor]);
|
||||
CGContextFillPath(context);
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -22,6 +22,7 @@
|
||||
|
||||
@import <Foundation/CPDictionary.j>
|
||||
@import <Foundation/CPCountedSet.j>
|
||||
@import <Foundation/_CPCollectionKVCOperators.j>
|
||||
|
||||
@import "CPController.j"
|
||||
@import "CPKeyValueBinding.j"
|
||||
@@ -517,8 +518,12 @@ var CPObjectControllerContentKey = @"CPObjectControllerCo
|
||||
|
||||
- (void)addObserver:(id)anObserver forKeyPath:(CPString)aKeyPath options:(CPKeyValueObservingOptions)options context:(id)context
|
||||
{
|
||||
if (aKeyPath.indexOf("@") === 0)
|
||||
if (aKeyPath.charAt(0) === "@")
|
||||
{
|
||||
// Simple collection operators are scalar and can't be proxied
|
||||
if ([_CPCollectionKVCOperator isSimpleCollectionOperator:aKeyPath])
|
||||
return;
|
||||
|
||||
var proxy = [[_CPObservationProxy alloc] initWithKeyPath:aKeyPath observer:anObserver object:self];
|
||||
|
||||
proxy._options = options;
|
||||
@@ -541,8 +546,12 @@ var CPObjectControllerContentKey = @"CPObjectControllerCo
|
||||
|
||||
- (void)removeObserver:(id)anObserver forKeyPath:(CPString)aKeyPath
|
||||
{
|
||||
if (aKeyPath.indexOf("@") === 0)
|
||||
if (aKeyPath.charAt(0) === "@")
|
||||
{
|
||||
// Simple collection operators are scalar and can't be proxied
|
||||
if ([_CPCollectionKVCOperator isSimpleCollectionOperator:aKeyPath])
|
||||
return;
|
||||
|
||||
var proxy = [[_CPObservationProxy alloc] initWithKeyPath:aKeyPath observer:anObserver object:self],
|
||||
index = [_observationProxies indexOfObject:proxy];
|
||||
|
||||
@@ -567,7 +576,7 @@ var CPObjectControllerContentKey = @"CPObjectControllerCo
|
||||
{
|
||||
var proxy = [_observationProxies objectAtIndex:i],
|
||||
keyPath = [proxy keyPath],
|
||||
operator = keyPath.indexOf(".") === 0;
|
||||
operator = keyPath.charAt(0) === ".";
|
||||
|
||||
if (operator)
|
||||
[self willChangeValueForKey:keyPath];
|
||||
@@ -589,7 +598,7 @@ var CPObjectControllerContentKey = @"CPObjectControllerCo
|
||||
{
|
||||
var proxy = [_observationProxies objectAtIndex:i],
|
||||
keyPath = [proxy keyPath],
|
||||
operator = keyPath.indexOf(".") === 0;
|
||||
operator = keyPath.charAt(0) === ".";
|
||||
|
||||
if (operator)
|
||||
[self willChangeValueForKey:keyPath];
|
||||
@@ -626,7 +635,7 @@ var CPObjectControllerContentKey = @"CPObjectControllerCo
|
||||
{
|
||||
var proxy = [_observationProxies objectAtIndex:i],
|
||||
keyPath = [proxy keyPath],
|
||||
operator = keyPath.indexOf(".") === 0;
|
||||
operator = keyPath.charAt(0) === ".";
|
||||
|
||||
if (operator)
|
||||
[self willChangeValueForKey:keyPath];
|
||||
@@ -700,12 +709,18 @@ var CPObjectControllerContentKey = @"CPObjectControllerCo
|
||||
|
||||
- (id)valueForKeyPath:(CPString)theKeyPath
|
||||
{
|
||||
var values = [[_controller selectedObjects] valueForKeyPath:theKeyPath],
|
||||
value = [self _controllerMarkerForValues:values];
|
||||
var values = [[_controller selectedObjects] valueForKeyPath:theKeyPath];
|
||||
|
||||
[_cachedValues setObject:value forKey:theKeyPath];
|
||||
// Simple collection operators like @count return a scalar value, not an array or set
|
||||
if ([values isKindOfClass:CPArray] || [values isKindOfClass:CPSet])
|
||||
{
|
||||
var value = [self _controllerMarkerForValues:values];
|
||||
[_cachedValues setObject:value forKey:theKeyPath];
|
||||
|
||||
return value;
|
||||
return value;
|
||||
}
|
||||
else
|
||||
return values;
|
||||
}
|
||||
|
||||
- (id)valueForKey:(CPString)theKeyPath
|
||||
|
||||
@@ -679,7 +679,7 @@ CPPopUpButtonStatePullsDown = CPThemeState("pulls-down");
|
||||
if ([self pullsDown])
|
||||
{
|
||||
var positionedItem = nil,
|
||||
location = CGPointMake(0.0, CGRectGetMaxY(bounds));
|
||||
location = CGPointMake(0.0, CGRectGetMaxY(bounds) - 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -30,19 +30,19 @@
|
||||
@global
|
||||
@group CPProgressIndicatorStyle
|
||||
*/
|
||||
CPProgressIndicatorBarStyle = 0;
|
||||
CPProgressIndicatorBarStyle = 0;
|
||||
/*
|
||||
@global
|
||||
@group CPProgressIndicatorStyle
|
||||
*/
|
||||
CPProgressIndicatorSpinningStyle = 1;
|
||||
CPProgressIndicatorSpinningStyle = 1;
|
||||
/*
|
||||
@global
|
||||
@group CPProgressIndicatorStyle
|
||||
*/
|
||||
CPProgressIndicatorHUDBarStyle = 2;
|
||||
CPProgressIndicatorHUDBarStyle = 2;
|
||||
|
||||
var CPProgressIndicatorSpinningStyleColors = nil;
|
||||
var CPProgressIndicatorSpinningStyleColors = [];
|
||||
|
||||
/*!
|
||||
@ingroup appkit
|
||||
@@ -61,7 +61,7 @@ var CPProgressIndicatorSpinningStyleColors = nil;
|
||||
|
||||
CPControlSize _controlSize;
|
||||
|
||||
BOOL _isIndeterminate;
|
||||
BOOL _indeterminate;
|
||||
CPProgressIndicatorStyle _style;
|
||||
|
||||
BOOL _isAnimating;
|
||||
@@ -77,8 +77,22 @@ var CPProgressIndicatorSpinningStyleColors = nil;
|
||||
|
||||
+ (CPDictionary)themeAttributes
|
||||
{
|
||||
return [CPDictionary dictionaryWithObjects:[[CPNull null], [CPNull null], 25, [CPNull null], [CPNull null], [CPNull null], [CPNull null]]
|
||||
forKeys:[@"indeterminate-bar-color", @"bar-color", @"default-height", @"bezel-color", @"spinning-mini-gif", @"spinning-small-gif", @"spinning-regular-gif"]];
|
||||
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"];
|
||||
}
|
||||
|
||||
+ (Class)_binderClassForBinding:(CPString)aBinding
|
||||
{
|
||||
if (aBinding === CPValueBinding || aBinding === @"isIndeterminate")
|
||||
return [_CPProgressIndicatorBinder class];
|
||||
|
||||
return [super _binderClassForBinding:aBinding];
|
||||
}
|
||||
|
||||
- (id)initWithFrame:(CGRect)aFrame
|
||||
@@ -259,12 +273,12 @@ var CPProgressIndicatorSpinningStyleColors = nil;
|
||||
Specifies whether this progress indicator should be indeterminate or display progress based on it's max and min.
|
||||
@param isDeterminate \c YES makes the indicator indeterminate
|
||||
*/
|
||||
- (void)setIndeterminate:(BOOL)isIndeterminate
|
||||
- (void)setIndeterminate:(BOOL)indeterminate
|
||||
{
|
||||
if (_isIndeterminate == isIndeterminate)
|
||||
if (_indeterminate == indeterminate)
|
||||
return;
|
||||
|
||||
_isIndeterminate = isIndeterminate;
|
||||
_indeterminate = indeterminate;
|
||||
|
||||
[self updateBackgroundColor];
|
||||
}
|
||||
@@ -274,7 +288,7 @@ var CPProgressIndicatorSpinningStyleColors = nil;
|
||||
*/
|
||||
- (BOOL)isIndeterminate
|
||||
{
|
||||
return _isIndeterminate;
|
||||
return _indeterminate;
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -369,7 +383,7 @@ var CPProgressIndicatorSpinningStyleColors = nil;
|
||||
if (barWidth > 0.0 && barWidth < 4.0)
|
||||
barWidth = 4.0;
|
||||
|
||||
if (_isIndeterminate)
|
||||
if (_indeterminate)
|
||||
barWidth = width;
|
||||
|
||||
return _CGRectMake(0, 0, barWidth, [self valueForThemeAttribute:@"default-height"]);
|
||||
@@ -381,17 +395,18 @@ var CPProgressIndicatorSpinningStyleColors = nil;
|
||||
/* @ignore */
|
||||
- (void)updateBackgroundColor
|
||||
{
|
||||
if ([CPProgressIndicatorSpinningStyleColors count] === 0)
|
||||
{
|
||||
CPProgressIndicatorSpinningStyleColors[CPMiniControlSize] = [self valueForThemeAttribute:@"spinning-mini-gif"];
|
||||
CPProgressIndicatorSpinningStyleColors[CPSmallControlSize] = [self valueForThemeAttribute:@"spinning-small-gif"];
|
||||
CPProgressIndicatorSpinningStyleColors[CPRegularControlSize] = [self valueForThemeAttribute:@"spinning-regular-gif"];
|
||||
}
|
||||
|
||||
[self setNeedsLayout];
|
||||
}
|
||||
|
||||
- (void)layoutSubviews
|
||||
{
|
||||
CPProgressIndicatorSpinningStyleColors = [];
|
||||
|
||||
CPProgressIndicatorSpinningStyleColors[CPMiniControlSize] = [self valueForThemeAttribute:@"spinning-mini-gif"];
|
||||
CPProgressIndicatorSpinningStyleColors[CPSmallControlSize] = [self valueForThemeAttribute:@"spinning-small-gif"];
|
||||
CPProgressIndicatorSpinningStyleColors[CPRegularControlSize] = [self valueForThemeAttribute:@"spinning-regular-gif"];
|
||||
|
||||
if (YES)//_isBezeled)
|
||||
{
|
||||
if (_style == CPProgressIndicatorSpinningStyle)
|
||||
@@ -411,11 +426,10 @@ var CPProgressIndicatorSpinningStyleColors = nil;
|
||||
positioned:CPWindowBelow
|
||||
relativeToEphemeralSubviewNamed:nil];
|
||||
|
||||
if (_isIndeterminate)
|
||||
if (_indeterminate)
|
||||
[barView setBackgroundColor:[self currentValueForThemeAttribute:@"indeterminate-bar-color"]];
|
||||
else
|
||||
[barView setBackgroundColor:[self currentValueForThemeAttribute:@"bar-color"]];
|
||||
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -435,7 +449,7 @@ var CPProgressIndicatorSpinningStyleColors = nil;
|
||||
_maxValue = [aCoder decodeObjectForKey:@"_maxValue"];
|
||||
_doubleValue = [aCoder decodeObjectForKey:@"_doubleValue"];
|
||||
_controlSize = [aCoder decodeObjectForKey:@"_controlSize"];
|
||||
_isIndeterminate = [aCoder decodeObjectForKey:@"_isIndeterminate"];
|
||||
_indeterminate = [aCoder decodeObjectForKey:@"_indeterminate"];
|
||||
_style = [aCoder decodeIntForKey:@"_style"];
|
||||
_isAnimating = [aCoder decodeObjectForKey:@"_isAnimating"];
|
||||
_isDisplayedWhenStoppedSet = [aCoder decodeObjectForKey:@"_isDisplayedWhenStoppedSet"];
|
||||
@@ -449,8 +463,8 @@ var CPProgressIndicatorSpinningStyleColors = nil;
|
||||
|
||||
- (void)encodeWithCoder:(CPCoder)aCoder
|
||||
{
|
||||
// Don't encode the background colour. It can be recreated based on the flags and if encoded causes hardcoded
|
||||
// image paths in the cib while just wasting space.
|
||||
// Don't encode the background colour. It can be recreated based on the flags
|
||||
// and if encoded causes hardcoded image paths in the cib while just wasting space.
|
||||
var backgroundColor = [self backgroundColor];
|
||||
[self setBackgroundColor:nil];
|
||||
[super encodeWithCoder:aCoder];
|
||||
@@ -460,7 +474,7 @@ var CPProgressIndicatorSpinningStyleColors = nil;
|
||||
[aCoder encodeObject:_maxValue forKey:@"_maxValue"];
|
||||
[aCoder encodeObject:_doubleValue forKey:@"_doubleValue"];
|
||||
[aCoder encodeObject:_controlSize forKey:@"_controlSize"];
|
||||
[aCoder encodeObject:_isIndeterminate forKey:@"_isIndeterminate"];
|
||||
[aCoder encodeObject:_indeterminate forKey:@"_indeterminate"];
|
||||
[aCoder encodeInt:_style forKey:@"_style"];
|
||||
[aCoder encodeObject:_isAnimating forKey:@"_isAnimating"];
|
||||
[aCoder encodeObject:_isDisplayedWhenStoppedSet forKey:@"_isDisplayedWhenStoppedSet"];
|
||||
@@ -468,3 +482,52 @@ var CPProgressIndicatorSpinningStyleColors = nil;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@implementation _CPProgressIndicatorBinder : CPBinder
|
||||
|
||||
- (void)_updatePlaceholdersWithOptions:(CPDictionary)options forBinding:(CPString)aBinding
|
||||
{
|
||||
var value = aBinding === CPValueBinding ? 0.0 : YES;
|
||||
|
||||
[self _setPlaceholder:value forMarker:CPMultipleValuesMarker isDefault:YES];
|
||||
[self _setPlaceholder:value forMarker:CPNoSelectionMarker isDefault:YES];
|
||||
[self _setPlaceholder:value forMarker:CPNotApplicableMarker isDefault:YES];
|
||||
[self _setPlaceholder:value forMarker:CPNullMarker isDefault:YES];
|
||||
}
|
||||
|
||||
- (id)valueForBinding:(CPString)aBinding
|
||||
{
|
||||
if (aBinding === CPValueBinding)
|
||||
return [_source doubleValue];
|
||||
else if (aBinding === @"isIndeterminate")
|
||||
[_source isIndeterminate];
|
||||
else
|
||||
return [super valueForBinding:aBinding];
|
||||
}
|
||||
|
||||
- (BOOL)_setValue:(id)aValue forBinding:(CPString)aBinding
|
||||
{
|
||||
if (aBinding === CPValueBinding)
|
||||
[_source setDoubleValue:aValue];
|
||||
else if (aBinding === @"isIndeterminate")
|
||||
[_source setIndeterminate:aValue];
|
||||
else
|
||||
return NO;
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (void)setValue:(id)aValue forBinding:(CPString)aBinding
|
||||
{
|
||||
if (![self _setValue:aValue forBinding:aBinding])
|
||||
[super setValue:aValue forBinding:aBinding];
|
||||
}
|
||||
|
||||
- (void)setPlaceholderValue:(id)aValue withMarker:(CPString)aMarker forBinding:(CPString)aBinding
|
||||
{
|
||||
if (![self _setValue:aValue forBinding:aBinding])
|
||||
[super setPlaceholderValue:aValue withMarker:aMarker forBinding:aBinding];
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -82,15 +82,15 @@
|
||||
}
|
||||
|
||||
/*! @cond */
|
||||
+ (Class)_binderClassForBinding:(CPString)theBinding
|
||||
+ (Class)_binderClassForBinding:(CPString)aBinding
|
||||
{
|
||||
if (theBinding == CPValueBinding)
|
||||
if (aBinding == CPValueBinding)
|
||||
return [CPPredicateEditorValueBinder class];
|
||||
|
||||
return [super _binderClassForBinding:theBinding];
|
||||
return [super _binderClassForBinding:aBinding];
|
||||
}
|
||||
|
||||
- (id)_replacementKeyPathForBinding:(CPString)aBinding
|
||||
- (CPString)_replacementKeyPathForBinding:(CPString)aBinding
|
||||
{
|
||||
if (aBinding == CPValueBinding)
|
||||
return @"predicate";
|
||||
|
||||
@@ -57,6 +57,8 @@ var PARTS_ARRANGEMENT = [CPScrollerKnobSlot, CPScrollerDecrementLine, CPScroll
|
||||
NAMES_FOR_PARTS = {},
|
||||
PARTS_FOR_NAMES = {};
|
||||
|
||||
var _CACHED_THEME_SCROLLER = nil; // This is used by the class methods to pull the theme attributes.
|
||||
|
||||
NAMES_FOR_PARTS[CPScrollerDecrementLine] = @"decrement-line";
|
||||
NAMES_FOR_PARTS[CPScrollerIncrementLine] = @"increment-line";
|
||||
NAMES_FOR_PARTS[CPScrollerKnobSlot] = @"knob-slot";
|
||||
@@ -133,11 +135,13 @@ CPThemeStateScrollerKnobDark = CPThemeState("scroller-knob-dark");
|
||||
*/
|
||||
+ (float)scrollerWidthInStyle:(int)aStyle
|
||||
{
|
||||
var scroller = [[self alloc] init];
|
||||
if (!_CACHED_THEME_SCROLLER)
|
||||
_CACHED_THEME_SCROLLER = [[self alloc] init];
|
||||
|
||||
if (aStyle == CPScrollerStyleLegacy)
|
||||
return [scroller valueForThemeAttribute:@"scroller-width" inState:CPThemeStateScrollViewLegacy];
|
||||
return [scroller currentValueForThemeAttribute:@"scroller-width"];
|
||||
return [_CACHED_THEME_SCROLLER valueForThemeAttribute:@"scroller-width" inState:CPThemeStateScrollViewLegacy];
|
||||
|
||||
return [_CACHED_THEME_SCROLLER currentValueForThemeAttribute:@"scroller-width"];
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -145,7 +149,10 @@ CPThemeStateScrollerKnobDark = CPThemeState("scroller-knob-dark");
|
||||
*/
|
||||
+ (float)scrollerOverlay
|
||||
{
|
||||
return [[[self alloc] init] currentValueForThemeAttribute:@"track-border-overlay"];
|
||||
if (!_CACHED_THEME_SCROLLER)
|
||||
_CACHED_THEME_SCROLLER = [[self alloc] init];
|
||||
|
||||
return [_CACHED_THEME_SCROLLER currentValueForThemeAttribute:@"track-border-overlay"];
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -175,14 +182,17 @@ CPThemeStateScrollerKnobDark = CPThemeState("scroller-knob-dark");
|
||||
_allowFadingOut = YES;
|
||||
_isMouseOver = NO;
|
||||
_style = CPScrollerStyleOverlay;
|
||||
var paramAnimFadeOut = [CPDictionary dictionaryWithObjects:[self, CPViewAnimationFadeOutEffect]
|
||||
forKeys:[CPViewAnimationTargetKey, CPViewAnimationEffectKey]];
|
||||
var paramAnimFadeOut = [CPDictionary dictionaryWithObjects:[self, CPViewAnimationFadeOutEffect]
|
||||
forKeys:[CPViewAnimationTargetKey, CPViewAnimationEffectKey]];
|
||||
|
||||
_animationScroller = [[CPViewAnimation alloc] initWithDuration:0.2 animationCurve:CPAnimationEaseInOut];
|
||||
[_animationScroller setViewAnimations:[paramAnimFadeOut]];
|
||||
[_animationScroller setDelegate:self];
|
||||
[self setAlphaValue:0.0];
|
||||
[self _calculateIsVertical];
|
||||
|
||||
// We have to choose an orientation. If for some bizarre reason width === height,
|
||||
// punt and choose vertical.
|
||||
[self _setIsVertical:_CGRectGetHeight(aFrame) >= _CGRectGetWidth(aFrame)];
|
||||
}
|
||||
|
||||
return self;
|
||||
@@ -639,13 +649,13 @@ CPThemeStateScrollerKnobDark = CPThemeState("scroller-knob-dark");
|
||||
|
||||
if ([anEvent modifierFlags] & CPAlternateKeyMask)
|
||||
{
|
||||
if (_trackingPart == CPScrollerDecrementLine)
|
||||
if (_trackingPart === CPScrollerDecrementLine)
|
||||
_hitPart = CPScrollerDecrementPage;
|
||||
|
||||
else if (_trackingPart == CPScrollerIncrementLine)
|
||||
else if (_trackingPart === CPScrollerIncrementLine)
|
||||
_hitPart = CPScrollerIncrementPage;
|
||||
|
||||
else if (_trackingPart == CPScrollerDecrementPage || _trackingPart == CPScrollerIncrementPage)
|
||||
else if (_trackingPart === CPScrollerDecrementPage || _trackingPart === CPScrollerIncrementPage)
|
||||
{
|
||||
var knobRect = [self rectForPart:CPScrollerKnob],
|
||||
knobWidth = ![self isVertical] ? _CGRectGetWidth(knobRect) : _CGRectGetHeight(knobRect),
|
||||
@@ -673,11 +683,11 @@ CPThemeStateScrollerKnobDark = CPThemeState("scroller-knob-dark");
|
||||
{
|
||||
_trackingStartPoint = [self convertPoint:[anEvent locationInWindow] fromView:nil];
|
||||
|
||||
if (_trackingPart == CPScrollerDecrementPage || _trackingPart == CPScrollerIncrementPage)
|
||||
if (_trackingPart === CPScrollerDecrementPage || _trackingPart === CPScrollerIncrementPage)
|
||||
{
|
||||
var hitPart = [self testPart:[anEvent locationInWindow]];
|
||||
|
||||
if (hitPart == CPScrollerDecrementPage || hitPart == CPScrollerIncrementPage)
|
||||
if (hitPart === CPScrollerDecrementPage || hitPart === CPScrollerIncrementPage)
|
||||
{
|
||||
_trackingPart = hitPart;
|
||||
_hitPart = hitPart;
|
||||
@@ -693,18 +703,13 @@ CPThemeStateScrollerKnobDark = CPThemeState("scroller-knob-dark");
|
||||
|
||||
}
|
||||
|
||||
- (void)_calculateIsVertical
|
||||
- (void)_setIsVertical:(BOOL)isVertical
|
||||
{
|
||||
// Recalculate isVertical.
|
||||
var bounds = [self bounds],
|
||||
width = _CGRectGetWidth(bounds),
|
||||
height = _CGRectGetHeight(bounds);
|
||||
_isVertical = isVertical;
|
||||
|
||||
_isVertical = width < height ? 1 : (width > height ? 0 : -1);
|
||||
|
||||
if (_isVertical === 1)
|
||||
if (_isVertical)
|
||||
[self setThemeState:CPThemeStateVertical];
|
||||
else if (_isVertical === 0)
|
||||
else
|
||||
[self unsetThemeState:CPThemeStateVertical];
|
||||
}
|
||||
|
||||
@@ -739,12 +744,14 @@ CPThemeStateScrollerKnobDark = CPThemeState("scroller-knob-dark");
|
||||
|
||||
switch (_hitPart)
|
||||
{
|
||||
case CPScrollerKnob: return [self trackKnob:anEvent];
|
||||
case CPScrollerKnob:
|
||||
return [self trackKnob:anEvent];
|
||||
|
||||
case CPScrollerDecrementLine:
|
||||
case CPScrollerIncrementLine:
|
||||
case CPScrollerDecrementPage:
|
||||
case CPScrollerIncrementPage: return [self trackScrollButtons:anEvent];
|
||||
case CPScrollerIncrementPage:
|
||||
return [self trackScrollButtons:anEvent];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -792,9 +799,10 @@ CPThemeStateScrollerKnobDark = CPThemeState("scroller-knob-dark");
|
||||
|
||||
@end
|
||||
|
||||
var CPScrollerControlSizeKey = @"CPScrollerControlSize",
|
||||
var CPScrollerControlSizeKey = @"CPScrollerControlSize",
|
||||
CPScrollerIsVerticalKey = @"CPScrollerIsVerticalKey",
|
||||
CPScrollerKnobProportionKey = @"CPScrollerKnobProportion",
|
||||
CPScrollerStyleKey = @"CPScrollerStyleKey";
|
||||
CPScrollerStyleKey = @"CPScrollerStyleKey";
|
||||
|
||||
@implementation CPScroller (CPCoding)
|
||||
|
||||
@@ -803,7 +811,6 @@ var CPScrollerControlSizeKey = @"CPScrollerControlSize",
|
||||
if (self = [super initWithCoder:aCoder])
|
||||
{
|
||||
_controlSize = CPRegularControlSize;
|
||||
|
||||
if ([aCoder containsValueForKey:CPScrollerControlSizeKey])
|
||||
_controlSize = [aCoder decodeIntForKey:CPScrollerControlSizeKey];
|
||||
|
||||
@@ -827,9 +834,9 @@ var CPScrollerControlSizeKey = @"CPScrollerControlSize",
|
||||
[_animationScroller setDelegate:self];
|
||||
[self setAlphaValue:0.0];
|
||||
|
||||
[self _calculateIsVertical];
|
||||
|
||||
[self setStyle:[aCoder decodeIntForKey:CPScrollerStyleKey]];
|
||||
|
||||
[self _setIsVertical:[aCoder decodeBoolForKey:CPScrollerIsVerticalKey]];
|
||||
}
|
||||
|
||||
return self;
|
||||
@@ -840,6 +847,7 @@ var CPScrollerControlSizeKey = @"CPScrollerControlSize",
|
||||
[super encodeWithCoder:aCoder];
|
||||
|
||||
[aCoder encodeInt:_controlSize forKey:CPScrollerControlSizeKey];
|
||||
[aCoder encodeInt:_isVertical forKey:CPScrollerIsVerticalKey];
|
||||
[aCoder encodeFloat:_knobProportion forKey:CPScrollerKnobProportionKey];
|
||||
[aCoder encodeInt:_style forKey:CPScrollerStyleKey];
|
||||
}
|
||||
|
||||
@@ -80,15 +80,15 @@
|
||||
return [CPStepper stepperWithInitialValue:0.0 minValue:0.0 maxValue:59.0];
|
||||
}
|
||||
|
||||
+ (Class)_binderClassForBinding:(CPString)theBinding
|
||||
+ (Class)_binderClassForBinding:(CPString)aBinding
|
||||
{
|
||||
if (theBinding == CPValueBinding || theBinding == CPMinValueBinding || theBinding == CPMaxValueBinding)
|
||||
if (aBinding == CPValueBinding || aBinding == CPMinValueBinding || aBinding == CPMaxValueBinding)
|
||||
return [_CPStepperValueBinder class];
|
||||
|
||||
return [super _binderClassForBinding:theBinding];
|
||||
return [super _binderClassForBinding:aBinding];
|
||||
}
|
||||
|
||||
- (id)_replacementKeyPathForBinding:(CPString)aBinding
|
||||
- (CPString)_replacementKeyPathForBinding:(CPString)aBinding
|
||||
{
|
||||
if (aBinding == CPValueBinding)
|
||||
return @"doubleValue";
|
||||
|
||||
@@ -980,9 +980,16 @@ NOT YET IMPLEMENTED
|
||||
if (_draggedColumn === aColumn)
|
||||
return;
|
||||
|
||||
var previouslyDraggedColumn = _draggedColumn;
|
||||
_draggedColumn = aColumn;
|
||||
|
||||
[self reloadDataForRowIndexes:_exposedRows columnIndexes:[CPIndexSet indexSetWithIndex:[_tableColumns indexOfObject:aColumn]]];
|
||||
// if a column is currently being dragged, update that column (removing data views)
|
||||
if (aColumn)
|
||||
[self reloadDataForRowIndexes:_exposedRows columnIndexes:[CPIndexSet indexSetWithIndex:[_tableColumns indexOfObject:aColumn]]];
|
||||
|
||||
// when the column is dropped, we should also update it.
|
||||
if (previouslyDraggedColumn)
|
||||
[self reloadDataForRowIndexes:_exposedRows columnIndexes:[CPIndexSet indexSetWithIndex:[_tableColumns indexOfObject:previouslyDraggedColumn]]];
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -129,6 +129,18 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
|
||||
CPControlSize _controlSize;
|
||||
}
|
||||
|
||||
+ (Class)_binderClassForBinding:(CPString)aBinding
|
||||
{
|
||||
if (aBinding === CPValueBinding)
|
||||
return [_CPTextFieldValueBinder class];
|
||||
else if ([aBinding hasPrefix:CPDisplayPatternValueBinding])
|
||||
return [_CPTextFieldPatternValueBinder class];
|
||||
else if ([aBinding hasPrefix:CPEditableBinding])
|
||||
return [CPMultipleValueAndBinding class];
|
||||
|
||||
return [super _binderClassForBinding:aBinding];
|
||||
}
|
||||
|
||||
+ (CPTextField)textFieldWithStringValue:(CPString)aStringValue placeholder:(CPString)aPlaceholder width:(float)aWidth
|
||||
{
|
||||
return [self textFieldWithStringValue:aStringValue placeholder:aPlaceholder width:aWidth theme:[CPTheme defaultTheme]];
|
||||
@@ -192,14 +204,6 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
|
||||
return "textfield";
|
||||
}
|
||||
|
||||
+ (Class)_binderClassForBinding:(CPString)theBinding
|
||||
{
|
||||
if (theBinding === CPValueBinding)
|
||||
return [_CPTextFieldValueBinder class];
|
||||
|
||||
return [super _binderClassForBinding:theBinding];
|
||||
}
|
||||
|
||||
+ (id)themeAttributes
|
||||
{
|
||||
return [CPDictionary dictionaryWithObjects:[_CGInsetMakeZero(), _CGInsetMake(1.0, 0.0, 0.0, 0.0), [CPNull null]]
|
||||
@@ -612,8 +616,6 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
|
||||
if (!CPFeatureIsCompatible(CPInputSetFontOutsideOfDOM))
|
||||
element.style.font = [font cssString];
|
||||
|
||||
[[[self window] platformWindow] _propagateCurrentDOMEvent:YES];
|
||||
|
||||
CPTextFieldInputIsActive = YES;
|
||||
|
||||
if (document.attachEvent)
|
||||
@@ -1628,18 +1630,6 @@ var CPTextFieldIsEditableKey = "CPTextFieldIsEditableKey",
|
||||
@end
|
||||
|
||||
@implementation _CPTextFieldValueBinder : CPBinder
|
||||
{
|
||||
}
|
||||
|
||||
- (void)_updatePlaceholdersWithOptions:(CPDictionary)options
|
||||
{
|
||||
[super _updatePlaceholdersWithOptions:options];
|
||||
|
||||
[self _setPlaceholder:@"Multiple Values" forMarker:CPMultipleValuesMarker isDefault:YES];
|
||||
[self _setPlaceholder:@"No Selection" forMarker:CPNoSelectionMarker isDefault:YES];
|
||||
[self _setPlaceholder:@"Not Applicable" forMarker:CPNotApplicableMarker isDefault:YES];
|
||||
[self _setPlaceholder:@"" forMarker:CPNullMarker isDefault:YES];
|
||||
}
|
||||
|
||||
- (void)setPlaceholderValue:(id)aValue withMarker:(CPString)aMarker forBinding:(CPString)aBinding
|
||||
{
|
||||
@@ -1654,3 +1644,17 @@ var CPTextFieldIsEditableKey = "CPTextFieldIsEditableKey",
|
||||
|
||||
@end
|
||||
|
||||
@implementation _CPTextFieldPatternValueBinder : CPValueWithPatternBinding
|
||||
|
||||
- (void)setPlaceholderValue:(id)aValue withMarker:(CPString)aMarker forBinding:(CPString)aBinding
|
||||
{
|
||||
[_source setPlaceholderString:aValue];
|
||||
[_source setObjectValue:nil];
|
||||
}
|
||||
|
||||
- (void)setValue:(id)aValue forBinding:(CPString)aBinding
|
||||
{
|
||||
[_source setObjectValue:aValue];
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -659,7 +659,7 @@ CPTokenFieldDeleteButtonType = 1;
|
||||
return CPTextFieldBlurFunction(
|
||||
anEvent,
|
||||
CPTokenFieldInputOwner,
|
||||
[CPTokenFieldInputOwner._tokenScrollView documentView]._DOMElement,
|
||||
CPTokenFieldInputOwner ? [CPTokenFieldInputOwner._tokenScrollView documentView]._DOMElement : nil,
|
||||
CPTokenFieldDOMInputElement,
|
||||
CPTokenFieldInputResigning,
|
||||
AT_REF(CPTokenFieldInputDidBlur));
|
||||
|
||||
@@ -227,6 +227,14 @@ var CPViewFlags = { },
|
||||
CachedNotificationCenter = [CPNotificationCenter defaultCenter];
|
||||
}
|
||||
|
||||
+ (Class)_binderClassForBinding:(CPString)aBinding
|
||||
{
|
||||
if ([aBinding hasPrefix:CPHiddenBinding])
|
||||
return [CPMultipleValueOrBinding class];
|
||||
|
||||
return [super _binderClassForBinding:aBinding];
|
||||
}
|
||||
|
||||
- (void)_setupViewFlags
|
||||
{
|
||||
var theClass = [self class],
|
||||
@@ -1573,6 +1581,7 @@ var CPViewFlags = { },
|
||||
- (void)rightMouseDown:(CPEvent)anEvent
|
||||
{
|
||||
var menu = [self menuForEvent:anEvent];
|
||||
|
||||
if (menu)
|
||||
[CPMenu popUpContextMenu:menu withEvent:anEvent forView:self];
|
||||
else if ([[self nextResponder] isKindOfClass:CPView])
|
||||
@@ -2323,13 +2332,11 @@ setBoundsOrigin:
|
||||
*/
|
||||
- (BOOL)scrollRectToVisible:(CGRect)aRect
|
||||
{
|
||||
var visibleRect = [self visibleRect];
|
||||
|
||||
// Make sure we have a rect that exists.
|
||||
aRect = CGRectIntersection(aRect, _bounds);
|
||||
|
||||
// If aRect is empty or is already visible then no scrolling required.
|
||||
if (_CGRectIsEmpty(aRect) || CGRectContainsRect(visibleRect, aRect))
|
||||
// If aRect is empty no scrolling required.
|
||||
if (_CGRectIsEmpty(aRect))
|
||||
return NO;
|
||||
|
||||
var enclosingClipView = [self _enclosingClipView];
|
||||
@@ -2338,20 +2345,34 @@ setBoundsOrigin:
|
||||
if (!enclosingClipView)
|
||||
return NO;
|
||||
|
||||
var scrollPoint = _CGPointMakeCopy(visibleRect.origin);
|
||||
var documentView = [enclosingClipView documentView];
|
||||
|
||||
// If the clip view doesn't have a document view, then there isn't much we can do.
|
||||
if (!documentView)
|
||||
return NO;
|
||||
|
||||
// Get the document view visible rect and convert aRect to the document view's coordinate system
|
||||
var documentViewVisibleRect = [documentView visibleRect],
|
||||
rectInDocumentView = [self convertRect:aRect toView:documentView];
|
||||
|
||||
// If already visible then no scrolling required.
|
||||
if (CGRectContainsRect(documentViewVisibleRect, rectInDocumentView))
|
||||
return NO;
|
||||
|
||||
var scrollPoint = _CGPointMakeCopy(documentViewVisibleRect.origin);
|
||||
|
||||
// One of the following has to be true since our current visible rect didn't contain aRect.
|
||||
if (_CGRectGetMinX(aRect) <= _CGRectGetMinX(visibleRect))
|
||||
scrollPoint.x = _CGRectGetMinX(aRect);
|
||||
else if (_CGRectGetMaxX(aRect) > _CGRectGetMaxX(visibleRect))
|
||||
scrollPoint.x += _CGRectGetMaxX(aRect) - _CGRectGetMaxX(visibleRect);
|
||||
if (_CGRectGetMinX(rectInDocumentView) < _CGRectGetMinX(documentViewVisibleRect))
|
||||
scrollPoint.x = _CGRectGetMinX(rectInDocumentView);
|
||||
else if (_CGRectGetMaxX(rectInDocumentView) > _CGRectGetMaxX(documentViewVisibleRect))
|
||||
scrollPoint.x += _CGRectGetMaxX(rectInDocumentView) - _CGRectGetMaxX(documentViewVisibleRect);
|
||||
|
||||
if (_CGRectGetMinY(aRect) <= _CGRectGetMinY(visibleRect))
|
||||
scrollPoint.y = CGRectGetMinY(aRect);
|
||||
else if (_CGRectGetMaxY(aRect) > _CGRectGetMaxY(visibleRect))
|
||||
scrollPoint.y += _CGRectGetMaxY(aRect) - _CGRectGetMaxY(visibleRect);
|
||||
if (_CGRectGetMinY(rectInDocumentView) < _CGRectGetMinY(documentViewVisibleRect))
|
||||
scrollPoint.y = _CGRectGetMinY(rectInDocumentView);
|
||||
else if (_CGRectGetMaxY(rectInDocumentView) > _CGRectGetMaxY(documentViewVisibleRect))
|
||||
scrollPoint.y += _CGRectGetMaxY(rectInDocumentView) - _CGRectGetMaxY(documentViewVisibleRect);
|
||||
|
||||
[enclosingClipView scrollToPoint:CGPointMake(scrollPoint.x, scrollPoint.y)];
|
||||
[enclosingClipView scrollToPoint:scrollPoint];
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
@@ -241,8 +241,7 @@ CPWebViewAppKitScrollMaxPollCount = 3;
|
||||
if (_effectiveScrollMode !== CPWebViewScrollAppKit)
|
||||
return;
|
||||
|
||||
var win = null;
|
||||
try { win = [self DOMWindow]; } catch (e) {}
|
||||
var win = [self DOMWindow];
|
||||
|
||||
if (win && win.addEventListener)
|
||||
{
|
||||
@@ -258,6 +257,7 @@ CPWebViewAppKitScrollMaxPollCount = 3;
|
||||
};
|
||||
|
||||
win.addEventListener("DOMMouseScroll", scrollEventHandler, false);
|
||||
win.addEventListener("wheel", scrollEventHandler, false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -277,8 +277,7 @@ CPWebViewAppKitScrollMaxPollCount = 3;
|
||||
[_frameView setFrameSize:CGSizeMake(CGRectGetMaxX(visibleRect), CGRectGetMaxY(visibleRect))];
|
||||
|
||||
// try to get the document size so we can correctly set the frame
|
||||
var win = null;
|
||||
try { win = [self DOMWindow]; } catch (e) {}
|
||||
var win = [self DOMWindow];
|
||||
|
||||
if (win && win.document && win.document.body)
|
||||
{
|
||||
@@ -579,6 +578,7 @@ CPWebViewAppKitScrollMaxPollCount = 3;
|
||||
{
|
||||
if (_mainFrameURL)
|
||||
[_backwardStack addObject:_mainFrameURL];
|
||||
|
||||
_mainFrameURL = URLString;
|
||||
[_forwardStack removeAllObjects];
|
||||
|
||||
@@ -596,6 +596,7 @@ CPWebViewAppKitScrollMaxPollCount = 3;
|
||||
{
|
||||
if (_mainFrameURL)
|
||||
[_forwardStack addObject:_mainFrameURL];
|
||||
|
||||
_mainFrameURL = [_backwardStack lastObject];
|
||||
[_backwardStack removeLastObject];
|
||||
|
||||
@@ -603,6 +604,7 @@ CPWebViewAppKitScrollMaxPollCount = 3;
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
return NO;
|
||||
}
|
||||
|
||||
@@ -617,6 +619,7 @@ CPWebViewAppKitScrollMaxPollCount = 3;
|
||||
{
|
||||
if (_mainFrameURL)
|
||||
[_backwardStack addObject:_mainFrameURL];
|
||||
|
||||
_mainFrameURL = [_forwardStack lastObject];
|
||||
[_forwardStack removeLastObject];
|
||||
|
||||
@@ -624,6 +627,7 @@ CPWebViewAppKitScrollMaxPollCount = 3;
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
return NO;
|
||||
}
|
||||
|
||||
@@ -671,7 +675,14 @@ CPWebViewAppKitScrollMaxPollCount = 3;
|
||||
*/
|
||||
- (DOMWindow)DOMWindow
|
||||
{
|
||||
return (_iframe.contentDocument && _iframe.contentDocument.defaultView) || _iframe.contentWindow;
|
||||
try
|
||||
{
|
||||
return (_iframe.contentDocument && _iframe.contentDocument.defaultView) || _iframe.contentWindow;
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
return nil;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -682,6 +693,7 @@ CPWebViewAppKitScrollMaxPollCount = 3;
|
||||
- (CPWebScriptObject)windowScriptObject
|
||||
{
|
||||
var win = [self DOMWindow];
|
||||
|
||||
if (!_wso || win != [_wso window])
|
||||
{
|
||||
if (win)
|
||||
@@ -689,6 +701,7 @@ CPWebViewAppKitScrollMaxPollCount = 3;
|
||||
else
|
||||
_wso = nil;
|
||||
}
|
||||
|
||||
return _wso;
|
||||
}
|
||||
|
||||
@@ -726,6 +739,7 @@ CPWebViewAppKitScrollMaxPollCount = 3;
|
||||
- (DOMCSSStyleDeclaration)computedStyleForElement:(DOMElement)element pseudoElement:(CPString)pseudoElement
|
||||
{
|
||||
var win = [[self windowScriptObject] window];
|
||||
|
||||
if (win)
|
||||
{
|
||||
// FIXME: IE version?
|
||||
@@ -758,6 +772,7 @@ CPWebViewAppKitScrollMaxPollCount = 3;
|
||||
{
|
||||
if (drawsBackground == _drawsBackground)
|
||||
return;
|
||||
|
||||
_drawsBackground = drawsBackground;
|
||||
|
||||
[self _applyBackgroundColor];
|
||||
@@ -863,38 +878,47 @@ CPWebViewAppKitScrollMaxPollCount = 3;
|
||||
{
|
||||
return _downloadDelegate;
|
||||
}
|
||||
|
||||
- (void)setDownloadDelegate:(id)anObject
|
||||
{
|
||||
_downloadDelegate = anObject;
|
||||
}
|
||||
|
||||
- (id)frameLoadDelegate
|
||||
{
|
||||
return _frameLoadDelegate;
|
||||
}
|
||||
|
||||
- (void)setFrameLoadDelegate:(id)anObject
|
||||
{
|
||||
_frameLoadDelegate = anObject;
|
||||
}
|
||||
|
||||
- (id)policyDelegate
|
||||
{
|
||||
return _policyDelegate;
|
||||
}
|
||||
|
||||
- (void)setPolicyDelegate:(id)anObject
|
||||
{
|
||||
_policyDelegate = anObject;
|
||||
}
|
||||
|
||||
- (id)resourceLoadDelegate
|
||||
{
|
||||
return _resourceLoadDelegate;
|
||||
}
|
||||
|
||||
- (void)setResourceLoadDelegate:(id)anObject
|
||||
{
|
||||
_resourceLoadDelegate = anObject;
|
||||
}
|
||||
|
||||
- (id)UIDelegate
|
||||
{
|
||||
return _UIDelegate;
|
||||
}
|
||||
|
||||
- (void)setUIDelegate:(id)anObject
|
||||
{
|
||||
_UIDelegate = anObject;
|
||||
@@ -921,6 +945,7 @@ CPWebViewAppKitScrollMaxPollCount = 3;
|
||||
{
|
||||
_window = aWindow;
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
@@ -935,9 +960,12 @@ CPWebViewAppKitScrollMaxPollCount = 3;
|
||||
// Would using "with" be better here?
|
||||
if (typeof _window[methodName] == "function")
|
||||
{
|
||||
try {
|
||||
try
|
||||
{
|
||||
return _window[methodName].apply(args);
|
||||
} catch (e) {
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
@@ -951,11 +979,15 @@ CPWebViewAppKitScrollMaxPollCount = 3;
|
||||
*/
|
||||
- (id)evaluateWebScript:(CPString)script
|
||||
{
|
||||
try {
|
||||
try
|
||||
{
|
||||
return _window.eval(script);
|
||||
} catch (e) {
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
// FIX ME: if we fail inside here, shouldn't we return an exception?
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
@@ -1030,6 +1062,7 @@ CPWebViewAppKitScrollMaxPollCount = 3;
|
||||
- (BOOL)_passesSameOriginPolicy
|
||||
{
|
||||
var documentURL = [CPURL URLWithString:window.location.href];
|
||||
|
||||
if ([documentURL isFileURL] && CPFeatureIsCompatible(CPSOPDisabledFromFileURLs))
|
||||
return YES;
|
||||
|
||||
|
||||
@@ -93,9 +93,9 @@ var CPWindowActionMessageKeys = [
|
||||
Sent from the notification center when the window has been resized.
|
||||
@param notification contains information about the resize event
|
||||
|
||||
@delegate -(CPUndoManager)windowWillReturnUndoManager:(CPWindow)window;
|
||||
@delegate -(CPUndoManager)windowWillReturnUndoManager:(CPWindow)aWindow;
|
||||
Called to obtain the undo manager for a window
|
||||
@param window the window for which to return the undo manager
|
||||
@param aWindow the window for which to return the undo manager
|
||||
@return the window's undo manager
|
||||
|
||||
@delegate -(void)windowDidBecomeMain:(CPNotification)notification;
|
||||
@@ -113,9 +113,9 @@ var CPWindowActionMessageKeys = [
|
||||
resigned key window status.
|
||||
@param notification contains information about the event
|
||||
|
||||
@delegate -(BOOL)windowShouldClose:(id)window;
|
||||
@delegate -(BOOL)windowShouldClose:(id)aWindow;
|
||||
Called when the user tries to close the window.
|
||||
@param window the window to close
|
||||
@param aWindow the window to close
|
||||
@return \c YES allows the window to close. \c NO
|
||||
vetoes the close operation and leaves the window open.
|
||||
|
||||
@@ -216,6 +216,14 @@ var CPWindowActionMessageKeys = [
|
||||
_CPWindowFrameAnimation _frameAnimation;
|
||||
}
|
||||
|
||||
+ (Class)_binderClassForBinding:(CPString)aBinding
|
||||
{
|
||||
if ([aBinding hasPrefix:CPDisplayPatternTitleBinding])
|
||||
return [CPTitleWithPatternBinding class];
|
||||
|
||||
return [super _binderClassForBinding:aBinding];
|
||||
}
|
||||
|
||||
- (id)init
|
||||
{
|
||||
return [self initWithContentRect:_CGRectMakeZero() styleMask:CPTitledWindowMask];
|
||||
@@ -1471,7 +1479,7 @@ CPTexturedBackgroundWindowMask
|
||||
- (void)setRepresentedFilename:(CPString)aFilePath
|
||||
{
|
||||
// FIXME: urls vs filepaths and all.
|
||||
[self setRepresentedURL:aFilePath];
|
||||
[self setRepresentedURL:[CPURL URLWithString:aFilePath]];
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -1479,7 +1487,7 @@ CPTexturedBackgroundWindowMask
|
||||
*/
|
||||
- (CPString)representedFilename
|
||||
{
|
||||
return _representedURL;
|
||||
return [_representedURL absoluteString];
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -3109,6 +3117,14 @@ CPTexturedBackgroundWindowMask
|
||||
[self disableKeyEquivalentForDefaultButton];
|
||||
}
|
||||
|
||||
- (void)setValue:(id)aValue forKey:(CPString)aKey
|
||||
{
|
||||
if (aKey === CPDisplayPatternTitleBinding)
|
||||
[self setTitle:aValue || @""];
|
||||
else
|
||||
[super setValue:aValue forKey:aKey];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
var keyViewComparator = function(lhs, rhs, context)
|
||||
|
||||
@@ -339,6 +339,7 @@
|
||||
|
||||
[_minimizeButton setImage:[self valueForThemeAttribute:@"minimize-image-button"]];
|
||||
[_minimizeButton setAlternateImage:[self valueForThemeAttribute:@"minimize-image-highlighted-button"]];
|
||||
[_dividerView setBackgroundColor:[self valueForThemeAttribute:@"divider-color"]];
|
||||
[_bodyView setBackgroundColor:[self valueForThemeAttribute:@"body-color"]];
|
||||
|
||||
[_headView setNeedsLayout];
|
||||
|
||||
@@ -85,4 +85,5 @@ var _CPCibConnectorSourceKey = @"_CPCibConnectorSourceKey",
|
||||
@end
|
||||
|
||||
// For backwards compatibility.
|
||||
@implementation _CPCibConnector : CPCibConnector { } @end
|
||||
@implementation _CPCibConnector : CPCibConnector
|
||||
@end
|
||||
@@ -260,31 +260,9 @@ var _CPCibObjectDataNamesKeysKey = @"_CPCibObjectDataNamesKeysKey
|
||||
{
|
||||
_replacementObjects[[_fileOwner UID]] = anOwner;
|
||||
|
||||
var index = 0,
|
||||
count = _connections.length,
|
||||
runtimeAttributeConnectors = [],
|
||||
connection = nil;
|
||||
|
||||
for (; index < count; ++index)
|
||||
for (var i = 0, count = _connections.length; i < count; ++i)
|
||||
{
|
||||
connection = _connections[index];
|
||||
|
||||
if ([connection isKindOfClass:CPCibRuntimeAttributesConnector])
|
||||
// Defer runtime attribute connections until after all other connections are made
|
||||
runtimeAttributeConnectors.push(connection);
|
||||
else
|
||||
{
|
||||
[connection replaceObjects:_replacementObjects];
|
||||
[connection establishConnection];
|
||||
}
|
||||
}
|
||||
|
||||
count = runtimeAttributeConnectors.length;
|
||||
|
||||
for (index = 0; index < count; ++index)
|
||||
{
|
||||
connection = runtimeAttributeConnectors[index];
|
||||
|
||||
var connection = _connections[i];
|
||||
[connection replaceObjects:_replacementObjects];
|
||||
[connection establishConnection];
|
||||
}
|
||||
|
||||
@@ -24,10 +24,10 @@
|
||||
@import <Foundation/CPObjJRuntime.j>
|
||||
|
||||
@import "CGGeometry.j"
|
||||
@import "CPToolbar.j"
|
||||
@import "CPView.j"
|
||||
@import "CPWindow_Constants.j"
|
||||
|
||||
@class CPToolbar
|
||||
@import "_CPToolTip.j"
|
||||
|
||||
|
||||
@implementation _CPCibWindowTemplate : CPObject
|
||||
|
||||
@@ -136,13 +136,26 @@ function CGColorSpaceCreateWithName(aName)
|
||||
|
||||
switch (aName)
|
||||
{
|
||||
case kCGColorSpaceGenericGray: return _CGNamedColorSpaces[aName] = _CGColorSpaceCreateWithModel(kCGColorSpaceModelMonochrome, 1, NULL);
|
||||
case kCGColorSpaceGenericRGB: return _CGNamedColorSpaces[aName] = _CGColorSpaceCreateWithModel(kCGColorSpaceModelRGB, 3, NULL);
|
||||
case kCGColorSpaceGenericCMYK: return _CGNamedColorSpaces[aName] = _CGColorSpaceCreateWithModel(kCGColorSpaceModelCMYK, 4, NULL);
|
||||
case kCGColorSpaceGenericRGBLinear: return _CGNamedColorSpaces[aName] = _CGColorSpaceCreateWithModel(kCGColorSpaceModelRGB, 3, NULL);
|
||||
case kCGColorSpaceGenericRGBHDR: return _CGNamedColorSpaces[aName] = _CGColorSpaceCreateWithModel(kCGColorSpaceModelRGB, 3, NULL);
|
||||
case kCGColorSpaceAdobeRGB1998: return _CGNamedColorSpaces[aName] = _CGColorSpaceCreateWithModel(kCGColorSpaceModelRGB, 3, NULL);
|
||||
case kCGColorSpaceSRGB: return _CGNamedColorSpaces[aName] = _CGColorSpaceCreateWithModel(kCGColorSpaceModelRGB, 3, NULL);
|
||||
case kCGColorSpaceGenericGray:
|
||||
return _CGNamedColorSpaces[aName] = _CGColorSpaceCreateWithModel(kCGColorSpaceModelMonochrome, 1, NULL);
|
||||
|
||||
case kCGColorSpaceGenericRGB:
|
||||
return _CGNamedColorSpaces[aName] = _CGColorSpaceCreateWithModel(kCGColorSpaceModelRGB, 3, NULL);
|
||||
|
||||
case kCGColorSpaceGenericCMYK:
|
||||
return _CGNamedColorSpaces[aName] = _CGColorSpaceCreateWithModel(kCGColorSpaceModelCMYK, 4, NULL);
|
||||
|
||||
case kCGColorSpaceGenericRGBLinear:
|
||||
return _CGNamedColorSpaces[aName] = _CGColorSpaceCreateWithModel(kCGColorSpaceModelRGB, 3, NULL);
|
||||
|
||||
case kCGColorSpaceGenericRGBHDR:
|
||||
return _CGNamedColorSpaces[aName] = _CGColorSpaceCreateWithModel(kCGColorSpaceModelRGB, 3, NULL);
|
||||
|
||||
case kCGColorSpaceAdobeRGB1998:
|
||||
return _CGNamedColorSpaces[aName] = _CGColorSpaceCreateWithModel(kCGColorSpaceModelRGB, 3, NULL);
|
||||
|
||||
case kCGColorSpaceSRGB:
|
||||
return _CGNamedColorSpaces[aName] = _CGColorSpaceCreateWithModel(kCGColorSpaceModelRGB, 3, NULL);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
@@ -228,13 +241,15 @@ function CGColorSpaceStandardizeComponents(aColorSpace, components)
|
||||
case kCGColorSpaceModelMonochrome:
|
||||
case kCGColorSpaceModelRGB:
|
||||
case kCGColorSpaceModelCMYK:
|
||||
case kCGColorSpaceModelDeviceN: while (count--)
|
||||
STANDARDIZE(components, count, 0, 1, 255);
|
||||
break;
|
||||
case kCGColorSpaceModelDeviceN:
|
||||
while (count--)
|
||||
STANDARDIZE(components, count, 0, 1, 255);
|
||||
break;
|
||||
|
||||
// We don't currently support these color spaces.
|
||||
case kCGColorSpaceModelIndexed:
|
||||
case kCGColorSpaceModelLab:
|
||||
case kCGColorSpaceModelPattern: break;
|
||||
case kCGColorSpaceModelPattern:
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -270,9 +270,12 @@ var PrimaryPlatformWindow = NULL;
|
||||
_title = aTitle;
|
||||
|
||||
#if PLATFORM(DOM)
|
||||
if (_DOMWindow && _DOMWindow.document
|
||||
&& (aWindow === [CPApp mainWindow] || [aWindow platformWindow] !== [CPPlatformWindow primaryPlatformWindow]))
|
||||
if (_DOMWindow &&
|
||||
_DOMWindow.document &&
|
||||
([aWindow isFullPlatformWindow]))
|
||||
{
|
||||
_DOMWindow.document.title = _title;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -133,15 +133,12 @@
|
||||
// List of all open native windows
|
||||
var PlatformWindows = [CPSet set];
|
||||
|
||||
// Define up here so compressor knows about em.
|
||||
// Define up here so compressor knows about them.
|
||||
var CPDOMEventGetClickCount,
|
||||
CPDOMEventStop,
|
||||
StopDOMEventPropagation,
|
||||
StopContextMenuDOMEventPropagation;
|
||||
|
||||
//right now we hard code q, w, r and t as keys to propogate
|
||||
//these aren't normal keycodes, they are with modifier key codes
|
||||
//might be mac only, we should investigate futher later.
|
||||
var KeyCodesToPrevent = {},
|
||||
CharacterKeysToPrevent = {},
|
||||
KeyCodesToAllow = {},
|
||||
@@ -438,6 +435,7 @@ var resizeTimer = nil;
|
||||
theDocument.addEventListener("touchcancel", touchEventCallback, NO);
|
||||
|
||||
_DOMWindow.addEventListener("DOMMouseScroll", scrollEventCallback, NO);
|
||||
_DOMWindow.addEventListener("wheel", scrollEventCallback, NO);
|
||||
_DOMWindow.addEventListener("mousewheel", scrollEventCallback, NO);
|
||||
|
||||
_DOMWindow.addEventListener("resize", resizeEventCallback, NO);
|
||||
@@ -468,6 +466,7 @@ var resizeTimer = nil;
|
||||
|
||||
//FIXME: does firefox really need a different value?
|
||||
_DOMWindow.removeEventListener("DOMMouseScroll", scrollEventCallback, NO);
|
||||
_DOMWindow.removeEventListener("wheel", scrollEventCallback, NO);
|
||||
_DOMWindow.removeEventListener("mousewheel", scrollEventCallback, NO);
|
||||
|
||||
//_DOMWindow.removeEventListener("beforeunload", this, NO);
|
||||
@@ -554,7 +553,7 @@ var resizeTimer = nil;
|
||||
[PlatformWindows addObject:self];
|
||||
|
||||
// FIXME: cpSetFrame?
|
||||
_DOMWindow.document.write("<!DOCTYPE html><html lang='en'><head></head><body style='background-color:transparent;'></body></html>");
|
||||
_DOMWindow.document.write('<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"></head><body style="background-color:transparent;"></body></html>');
|
||||
_DOMWindow.document.close();
|
||||
|
||||
if (self != [CPPlatformWindow primaryPlatformWindow])
|
||||
@@ -898,6 +897,7 @@ var resizeTimer = nil;
|
||||
timestamp = [CPEvent currentTimestamp], // fake event, might as well use current timestamp
|
||||
windowNumber = [[CPApp keyWindow] windowNumber],
|
||||
modifierFlags = CPPlatformActionKeyMask,
|
||||
location = _lastMouseEventLocation || _CGPointMakeZero(),
|
||||
event = [CPEvent keyEventWithType:CPKeyDown location:location modifierFlags:modifierFlags
|
||||
timestamp:timestamp windowNumber:windowNumber context:nil
|
||||
characters:characters charactersIgnoringModifiers:characters isARepeat:NO keyCode:keyCode];
|
||||
@@ -999,6 +999,7 @@ var resizeTimer = nil;
|
||||
aDOMEvent = window.event;
|
||||
|
||||
var location = nil;
|
||||
|
||||
if (CPFeatureIsCompatible(CPJavaScriptMouseWheelValues_8_15))
|
||||
{
|
||||
var x = aDOMEvent._offsetX || 0.0,
|
||||
@@ -1059,7 +1060,7 @@ var resizeTimer = nil;
|
||||
{
|
||||
// Find the scroll delta
|
||||
var deltaX = _DOMScrollingElement.scrollLeft - 150,
|
||||
deltaY = _DOMScrollingElement.scrollTop - 150;
|
||||
deltaY = (_DOMScrollingElement.scrollTop - 150) || (aDOMEvent.deltaY===undefined?0: aDOMEvent.deltaY);
|
||||
|
||||
// If we scroll super with momentum,
|
||||
// there are so many events going off that
|
||||
@@ -1263,6 +1264,7 @@ var resizeTimer = nil;
|
||||
[_CPToolTip invalidateCurrentToolTipIfNeeded];
|
||||
|
||||
var button = aDOMEvent.button;
|
||||
|
||||
_mouseDownIsRightClick = button == 2 || (CPBrowserIsOperatingSystem(CPMacOperatingSystem) && button == 0 && modifierFlags & CPControlKeyMask);
|
||||
|
||||
if (sourceElement.tagName === "INPUT" && sourceElement != _DOMFocusElement)
|
||||
@@ -1649,7 +1651,7 @@ var resizeTimer = nil;
|
||||
+ (void)preventCharacterKeysFromPropagating:(CPArray)characters
|
||||
{
|
||||
for (var i = characters.length; i > 0; i--)
|
||||
CharacterKeysToPrevent[""+characters[i-1].toLowerCase()] = YES;
|
||||
CharacterKeysToPrevent["" + characters[i - 1].toLowerCase()] = YES;
|
||||
}
|
||||
|
||||
/*!
|
||||
|
||||
|
After Width: | Height: | Size: 203 B |
|
After Width: | Height: | Size: 509 B |
|
After Width: | Height: | Size: 1.9 KiB |
|
After Width: | Height: | Size: 2.4 KiB |
|
After Width: | Height: | Size: 698 B |
|
After Width: | Height: | Size: 234 B |
|
After Width: | Height: | Size: 993 B |
|
After Width: | Height: | Size: 993 B |
|
After Width: | Height: | Size: 993 B |
@@ -2440,6 +2440,14 @@ var themedButtonValues = nil,
|
||||
[@"window-standard-bottom-right.png", 2.0, 2.0]
|
||||
]),
|
||||
|
||||
dividerColor = PatternColor(
|
||||
"window-standard-divider{position}.png",
|
||||
{
|
||||
width: 1.0,
|
||||
height: 1.0,
|
||||
orientation: PatternIsHorizontal
|
||||
}),
|
||||
|
||||
closeButtonImage = PatternImage(@"window-standard-close-button.png", 16, 16),
|
||||
closeButtonImageHighlighted = PatternImage(@"window-standard-button-highlighted.png",16, 16),
|
||||
unsavedButtonImage = PatternImage(@"window-standard-button-unsaved.png",16, 16),
|
||||
@@ -2467,7 +2475,7 @@ var themedButtonValues = nil,
|
||||
[@"title-vertical-alignment", CPCenterVerticalTextAlignment],
|
||||
[@"title-bar-height", 31],
|
||||
|
||||
[@"divider-color", [CPColor colorWithHexString:@"979797"]],
|
||||
[@"divider-color", dividerColor],
|
||||
[@"body-color", bezelColor],
|
||||
[@"title-bar-height", 31],
|
||||
|
||||
@@ -2580,10 +2588,9 @@ var themedButtonValues = nil,
|
||||
|
||||
themeValues =
|
||||
[
|
||||
[@"submenu-indicator-color", [CPColor grayColor]],
|
||||
[@"menu-item-selection-color", [CPColor colorWithHexString:@"5C85D8"]],
|
||||
[@"menu-item-text-shadow-color", [CPColor colorWithCalibratedRed:26.0 / 255.0 green: 73.0 / 255.0 blue:109.0 / 255.0 alpha:1.0]],
|
||||
[@"horizontal-margin", 8.0],
|
||||
[@"horizontal-margin", 12.0],
|
||||
[@"submenu-indicator-margin", 3.0],
|
||||
[@"vertical-margin", 4.0]
|
||||
];
|
||||
|
||||
|
After Width: | Height: | Size: 203 B |
|
After Width: | Height: | Size: 509 B |
|
After Width: | Height: | Size: 1.9 KiB |
|
After Width: | Height: | Size: 2.4 KiB |
|
After Width: | Height: | Size: 698 B |
|
After Width: | Height: | Size: 234 B |
|
Before Width: | Height: | Size: 98 B After Width: | Height: | Size: 1021 B |
|
Before Width: | Height: | Size: 113 B After Width: | Height: | Size: 1.0 KiB |
|
Before Width: | Height: | Size: 120 B After Width: | Height: | Size: 1.0 KiB |
|
Before Width: | Height: | Size: 87 B After Width: | Height: | Size: 1016 B |
|
Before Width: | Height: | Size: 84 B After Width: | Height: | Size: 1013 B |
|
Before Width: | Height: | Size: 84 B After Width: | Height: | Size: 1013 B |
|
Before Width: | Height: | Size: 562 B After Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 128 B After Width: | Height: | Size: 1.0 KiB |
|
Before Width: | Height: | Size: 142 B After Width: | Height: | Size: 1.0 KiB |
|
After Width: | Height: | Size: 87 B |
|
After Width: | Height: | Size: 87 B |
|
After Width: | Height: | Size: 156 B |
|
After Width: | Height: | Size: 400 B |
|
After Width: | Height: | Size: 157 B |
|
After Width: | Height: | Size: 545 B |
|
After Width: | Height: | Size: 992 B |
|
After Width: | Height: | Size: 993 B |
|
After Width: | Height: | Size: 993 B |
@@ -269,7 +269,7 @@ var themedButtonValues = nil,
|
||||
{
|
||||
var button = [[CPPopUpButton alloc] initWithFrame:CGRectMake(0.0, 0.0, 100.0, 25.0) pullsDown:YES],
|
||||
color = PatternColor(
|
||||
"popup-bezel{state}{position}.png",
|
||||
"pulldown-bezel{state}{position}.png",
|
||||
{
|
||||
states: ["", "disabled"],
|
||||
width: 3.0,
|
||||
@@ -1550,14 +1550,14 @@ var themedButtonValues = nil,
|
||||
|
||||
+ (CPProgressIndicator)themedBarProgressIndicator
|
||||
{
|
||||
var progressBar = [[CPProgressIndicator alloc] initWithFrame:CGRectMake(0,0,75,25)];
|
||||
var progressBar = [[CPProgressIndicator alloc] initWithFrame:CGRectMake(0, 0, 75, 20)];
|
||||
[progressBar setDoubleValue:30];
|
||||
|
||||
var bezelColor = PatternColor(
|
||||
"progress-indicator-bezel-border{position}.png",
|
||||
{
|
||||
width: 1.0,
|
||||
height: 25.0,
|
||||
height: 20.0,
|
||||
orientation: PatternIsHorizontal
|
||||
}),
|
||||
|
||||
@@ -1565,14 +1565,15 @@ var themedButtonValues = nil,
|
||||
"progress-indicator-bar{position}.png",
|
||||
{
|
||||
width: 1.0,
|
||||
height: 25.0,
|
||||
height: 20.0,
|
||||
orientation: PatternIsHorizontal
|
||||
});
|
||||
|
||||
themedProgressIndicator =
|
||||
[
|
||||
[@"bezel-color", bezelColor],
|
||||
[@"bar-color", barColor]
|
||||
[@"bar-color", barColor],
|
||||
[@"default-height", 20]
|
||||
];
|
||||
|
||||
[self registerThemeValues:themedProgressIndicator forView:progressBar];
|
||||
@@ -1582,7 +1583,7 @@ var themedButtonValues = nil,
|
||||
|
||||
+ (CPProgressIndicator)themedIndeterminateBarProgressIndicator
|
||||
{
|
||||
var progressBar = [[CPProgressIndicator alloc] initWithFrame:CGRectMake(0,0,75,25)];
|
||||
var progressBar = [[CPProgressIndicator alloc] initWithFrame:CGRectMake(0, 0, 75, 20)];
|
||||
|
||||
[progressBar setIndeterminate:YES];
|
||||
|
||||
@@ -1590,7 +1591,7 @@ var themedButtonValues = nil,
|
||||
"progress-indicator-bezel-border{position}.png",
|
||||
{
|
||||
width: 1.0,
|
||||
height: 25.0,
|
||||
height: 20.0,
|
||||
orientation: PatternIsHorizontal
|
||||
}),
|
||||
|
||||
@@ -1598,7 +1599,7 @@ var themedButtonValues = nil,
|
||||
"progress-indicator-indeterminate-bar{position}.png",
|
||||
{
|
||||
width: 1.0,
|
||||
height: 25.0,
|
||||
height: 20.0,
|
||||
centerWidth: 20.0,
|
||||
orientation: PatternIsHorizontal
|
||||
});
|
||||
@@ -1606,7 +1607,8 @@ var themedButtonValues = nil,
|
||||
themedIndeterminateProgressIndicator =
|
||||
[
|
||||
[@"bezel-color", bezelColor],
|
||||
[@"indeterminate-bar-color", barColor]
|
||||
[@"indeterminate-bar-color", barColor],
|
||||
[@"default-height", 20]
|
||||
];
|
||||
|
||||
[self registerThemeValues:themedIndeterminateProgressIndicator forView:progressBar];
|
||||
@@ -1616,7 +1618,7 @@ var themedButtonValues = nil,
|
||||
|
||||
+ (CPProgressIndicator)themedSpinningProgressIndicator
|
||||
{
|
||||
var progressBar = [[CPProgressIndicator alloc] initWithFrame:CGRectMake(0,0,64,64)];
|
||||
var progressBar = [[CPProgressIndicator alloc] initWithFrame:CGRectMake(0, 0, 64, 64)];
|
||||
[progressBar setStyle:CPProgressIndicatorSpinningStyle];
|
||||
|
||||
var spinningMini = PatternColor(@"progress-indicator-spinning-style-mini.gif", 16.0, 16.0),
|
||||
@@ -1637,7 +1639,7 @@ var themedButtonValues = nil,
|
||||
|
||||
+ (CPBox)themedBox
|
||||
{
|
||||
var box = [[CPBox alloc] initWithFrame:CGRectMake(0,0,100,100)],
|
||||
var box = [[CPBox alloc] initWithFrame:CGRectMake(0, 0, 100, 100)],
|
||||
|
||||
themeValues =
|
||||
[
|
||||
@@ -1658,7 +1660,7 @@ var themedButtonValues = nil,
|
||||
|
||||
+ (CPLevelIndicator)themedLevelIndicator
|
||||
{
|
||||
var levelIndicator = [[CPLevelIndicator alloc] initWithFrame:CGRectMake(0,0,100,100)],
|
||||
var levelIndicator = [[CPLevelIndicator alloc] initWithFrame:CGRectMake(0, 0, 100, 100)],
|
||||
|
||||
bezelColor = PatternColor(
|
||||
"level-indicator-bezel{position}.png",
|
||||
@@ -1873,6 +1875,14 @@ var themedButtonValues = nil,
|
||||
bottomHeight:5.0
|
||||
}),
|
||||
|
||||
dividerColor = PatternColor(
|
||||
"window-standard-divider{position}.png",
|
||||
{
|
||||
width: 1.0,
|
||||
height: 1.0,
|
||||
orientation: PatternIsHorizontal
|
||||
}),
|
||||
|
||||
closeButtonImage = PatternImage(@"window-standard-close-button.png", 16, 16),
|
||||
closeButtonImageInactive = PatternImage(@"window-standard-close-button-inactive.png", 16, 16),
|
||||
closeButtonImageHighlighted = PatternImage(@"window-standard-button-highlighted.png", 16, 16),
|
||||
@@ -1905,7 +1915,7 @@ var themedButtonValues = nil,
|
||||
[@"title-vertical-alignment", CPCenterVerticalTextAlignment],
|
||||
[@"title-bar-height", 31],
|
||||
|
||||
[@"divider-color", [CPColor colorWithHexString:@"858585"]],
|
||||
[@"divider-color", dividerColor],
|
||||
[@"body-color", bezelColor],
|
||||
[@"title-bar-height", 31],
|
||||
|
||||
@@ -2018,10 +2028,9 @@ var themedButtonValues = nil,
|
||||
|
||||
themeValues =
|
||||
[
|
||||
[@"submenu-indicator-color", [CPColor grayColor]],
|
||||
[@"menu-item-selection-color", [CPColor colorWithHexString:@"5C85D8"]],
|
||||
[@"menu-item-text-shadow-color", [CPColor colorWithCalibratedRed:26.0 / 255.0 green: 73.0 / 255.0 blue:109.0 / 255.0 alpha:1.0]],
|
||||
[@"horizontal-margin", 8.0],
|
||||
[@"horizontal-margin", 12.0],
|
||||
[@"submenu-indicator-margin", 3.0],
|
||||
[@"vertical-margin", 4.0]
|
||||
];
|
||||
|
||||
@@ -205,7 +205,7 @@ var _CPAutocompleteMenuMaximumHeight = 307;
|
||||
[self setIndexOfSelectedItem:indexOfSelectedItem];
|
||||
|
||||
[textField setThemeState:CPThemeStateAutocompleting];
|
||||
[_menuWindow orderFront:self];
|
||||
[[textField window] addChildWindow:_menuWindow ordered:CPWindowAbove];
|
||||
|
||||
[self layoutSubviews];
|
||||
}
|
||||
|
||||
@@ -461,6 +461,13 @@ var _CPPopoverWindow_shouldClose_ = 1 << 0,
|
||||
{
|
||||
#if PLATFORM(DOM)
|
||||
_DOMElement.removeEventListener(CPBrowserStyleProperty('transitionend'), transitionCompleteFunction, YES);
|
||||
|
||||
// Make sure to clear these properties when the animation is done. Without this,
|
||||
// the window becomes blurry in Chrome, presumably because the browser composits
|
||||
// a layer with a transform differently even when it's an identity transform.
|
||||
[self setCSS3Property:@"Transform" value:nil];
|
||||
[self setCSS3Property:@"TransformOrigin" value:nil];
|
||||
[self setCSS3Property:@"Transition" value:nil];
|
||||
#endif
|
||||
if (_implementedDelegateMethods & _CPPopoverWindow_didShow_)
|
||||
[_delegate popoverWindowDidShow:self];
|
||||
|
||||
@@ -431,7 +431,7 @@
|
||||
|
||||
- (id)valueForKey:(CPString)aKey
|
||||
{
|
||||
if (aKey.indexOf("@") === 0)
|
||||
if (aKey.charAt(0) === "@")
|
||||
{
|
||||
if (aKey.indexOf(".") !== -1)
|
||||
[CPException raise:CPInvalidArgumentException reason:"called valueForKey: on an array with a complex key (" + aKey + "). use valueForKeyPath:"];
|
||||
@@ -528,7 +528,7 @@
|
||||
Raises an exception.
|
||||
|
||||
CPArray objects are not observable, so this method raises an exception when invoked on an CPArray object.
|
||||
Instead of observing a array, observe the ordered to-many relationship for which the array is the collection of related objects.
|
||||
Instead of observing an array, observe the ordered to-many relationship for which the array is the collection of related objects.
|
||||
*/
|
||||
- (void)addObserver:(id)anObserver forKeyPath:(CPString)aKeyPath options:(CPKeyValueObservingOptions)anOptions context:(id)aContext
|
||||
{
|
||||
@@ -539,7 +539,7 @@
|
||||
Raises an exception.
|
||||
|
||||
CPArray objects are not observable, so this method raises an exception when invoked on an CPArray object.
|
||||
Instead of observing a array, observe the ordered to-many relationship for which the array is the collection of related objects.
|
||||
Instead of observing an array, observe the ordered to-many relationship for which the array is the collection of related objects.
|
||||
*/
|
||||
- (void)removeObserver:(id)anObserver forKeyPath:(CPString)aKeyPath
|
||||
{
|
||||
|
||||
@@ -0,0 +1,353 @@
|
||||
/*
|
||||
* CPByteCountFormatter.j
|
||||
* Foundation
|
||||
*
|
||||
* Created by Aparajita Fishman.
|
||||
* Copyright 2013, Cappuccino Foundation.
|
||||
*
|
||||
* 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 "CPNumberFormatter.j"
|
||||
@import "CPString.j"
|
||||
|
||||
|
||||
// Allowed units
|
||||
CPByteCountFormatterUseDefault = 0;
|
||||
CPByteCountFormatterUseBytes = 1 << 0;
|
||||
CPByteCountFormatterUseKB = 1 << 1;
|
||||
CPByteCountFormatterUseMB = 1 << 2;
|
||||
CPByteCountFormatterUseGB = 1 << 3;
|
||||
CPByteCountFormatterUseTB = 1 << 4;
|
||||
CPByteCountFormatterUsePB = 1 << 5;
|
||||
CPByteCountFormatterUseAll = 0xFFFF;
|
||||
|
||||
// Note: The Cocoa documentation says File is binary, but in practice it's decimal
|
||||
CPByteCountFormatterCountStyleFile = 0;
|
||||
CPByteCountFormatterCountStyleMemory = 1;
|
||||
CPByteCountFormatterCountStyleDecimal = 2;
|
||||
CPByteCountFormatterCountStyleBinary = 3;
|
||||
|
||||
var CPByteCountFormatterUnits = [ @"bytes", @"KB", @"MB", @"GB", @"TB", @"PB" ];
|
||||
|
||||
|
||||
/*!
|
||||
@ingroup foundation
|
||||
@class CPByteCountFormatter
|
||||
|
||||
A complete implementation of NSByteCountFormatter. See
|
||||
https://developer.apple.com/library/mac/#documentation/Foundation/Reference/NSByteCountFormatter_Class/Reference/Reference.html
|
||||
*/
|
||||
@implementation CPByteCountFormatter : CPFormatter
|
||||
{
|
||||
int _countStyle;
|
||||
BOOL _allowsNonnumericFormatting;
|
||||
BOOL _includesActualByteCount;
|
||||
BOOL _includesCount;
|
||||
BOOL _includesUnit;
|
||||
BOOL _adaptive;
|
||||
BOOL _zeroPadsFractionDigits;
|
||||
int _allowedUnits;
|
||||
CPNumberFormatter _numberFormatter;
|
||||
}
|
||||
|
||||
- (id)init
|
||||
{
|
||||
if (self = [super init])
|
||||
{
|
||||
_adaptive = YES;
|
||||
_allowedUnits = CPByteCountFormatterUseDefault;
|
||||
_allowsNonnumericFormatting = YES;
|
||||
_countStyle = CPByteCountFormatterCountStyleFile;
|
||||
_includesActualByteCount = NO;
|
||||
_includesCount = YES;
|
||||
_includesUnit = YES;
|
||||
_zeroPadsFractionDigits = NO;
|
||||
_numberFormatter = [CPNumberFormatter new];
|
||||
[_numberFormatter setNumberStyle:CPNumberFormatterDecimalStyle];
|
||||
[_numberFormatter setMinimumFractionDigits:0];
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
/*! @name Creating Strings from Byte Count */
|
||||
|
||||
+ (CPString)stringFromByteCount:(int)byteCount countStyle:(int)countStyle
|
||||
{
|
||||
var formatter = [CPByteCountFormatter new];
|
||||
|
||||
[formatter setCountStyle:countStyle];
|
||||
|
||||
return [formatter stringFromByteCount:byteCount];
|
||||
}
|
||||
|
||||
- (CPString)stringFromByteCount:(int)byteCount
|
||||
{
|
||||
var divisor,
|
||||
exponent = 0,
|
||||
unitIndex = ((_allowedUnits === 0) || (_allowedUnits & CPByteCountFormatterUseBytes)) ? 0 : -1,
|
||||
bytes = byteCount,
|
||||
unitBytes = bytes,
|
||||
unitCount = [CPByteCountFormatterUnits count];
|
||||
|
||||
if (_countStyle === CPByteCountFormatterCountStyleFile ||
|
||||
_countStyle === CPByteCountFormatterCountStyleDecimal)
|
||||
divisor = 1000;
|
||||
else
|
||||
divisor = 1024;
|
||||
|
||||
while ((bytes >= divisor) && (exponent < unitCount))
|
||||
{
|
||||
bytes /= divisor;
|
||||
++exponent;
|
||||
|
||||
// If there is a valid unit for this exponent,
|
||||
// update the unit we will use and the byte count for that unit
|
||||
if (_allowedUnits === 0 || (_allowedUnits & (1 << exponent)))
|
||||
{
|
||||
unitIndex = exponent;
|
||||
unitBytes = bytes;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
If no allowed unit was found before bytes < divisor,
|
||||
keep dividing until we find an allowed unit. We can skip
|
||||
bytes, if that is allowed unit, unitIndex will be >= 0.
|
||||
*/
|
||||
if (unitIndex === -1)
|
||||
for (var i = 1; i < unitCount; ++i)
|
||||
{
|
||||
unitBytes /= divisor;
|
||||
|
||||
if ((_allowedUnits === 0) || (_allowedUnits & (1 << i)))
|
||||
{
|
||||
unitIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
var minDigits = 0,
|
||||
maxDigits = CPDecimalNoScale;
|
||||
|
||||
// Fractional units get as many digits as they need
|
||||
if (unitBytes >= 1.0)
|
||||
{
|
||||
if (_adaptive)
|
||||
{
|
||||
// 0 fraction digits for bytes and K, 1 fraction digit for MB, 2 digits for GB and above
|
||||
var digits;
|
||||
|
||||
if (exponent <= 1)
|
||||
digits = 0;
|
||||
else if (exponent == 2)
|
||||
digits = 1;
|
||||
else
|
||||
digits = 2;
|
||||
|
||||
maxDigits = digits;
|
||||
|
||||
if (_zeroPadsFractionDigits)
|
||||
minDigits = digits;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_zeroPadsFractionDigits)
|
||||
minDigits = 2;
|
||||
|
||||
if (bytes >= 1)
|
||||
maxDigits = 2;
|
||||
}
|
||||
}
|
||||
|
||||
[_numberFormatter setMinimumFractionDigits:minDigits];
|
||||
[_numberFormatter setMaximumFractionDigits:maxDigits];
|
||||
|
||||
var parts = [];
|
||||
|
||||
if (_includesCount)
|
||||
{
|
||||
if (_allowsNonnumericFormatting && bytes === 0)
|
||||
[parts addObject:@"Zero"];
|
||||
else
|
||||
[parts addObject:[_numberFormatter stringFromNumber:unitBytes]];
|
||||
}
|
||||
|
||||
if (_includesUnit)
|
||||
[parts addObject:CPByteCountFormatterUnits[unitIndex]];
|
||||
|
||||
if ((unitIndex > 0) && _includesCount && _includesUnit && _includesActualByteCount)
|
||||
{
|
||||
[_numberFormatter setMaximumFractionDigits:0];
|
||||
[parts addObject:[CPString stringWithFormat:@"(%s bytes)", [_numberFormatter stringFromNumber:byteCount]]];
|
||||
}
|
||||
|
||||
var result = [parts componentsJoinedByString:@" "];
|
||||
|
||||
if (byteCount === 1)
|
||||
return [result stringByReplacingOccurrencesOfString:@"bytes" withString:@"byte"];
|
||||
else
|
||||
return result;
|
||||
}
|
||||
|
||||
/*!
|
||||
Cocoa returns nil if anObject is not a number.
|
||||
*/
|
||||
- (CPString)stringForObjectValue:(id)anObject
|
||||
{
|
||||
if ([anObject isKindOfClass:CPNumber])
|
||||
return [self stringFromByteCount:anObject];
|
||||
else
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (BOOL)getObjectValue:(id)anObject forString:(CPString)aString errorDescription:(CPString)anError
|
||||
{
|
||||
// Not implemented
|
||||
return NO;
|
||||
}
|
||||
|
||||
/*! @name Setting Formatting Styles */
|
||||
|
||||
- (int)countStyle
|
||||
{
|
||||
return _countStyle;
|
||||
}
|
||||
|
||||
- (void)setCountStyle:(int)style
|
||||
{
|
||||
_countStyle = style;
|
||||
}
|
||||
|
||||
- (BOOL)allowsNonnumericFormatting
|
||||
{
|
||||
return _allowsNonnumericFormatting;
|
||||
}
|
||||
|
||||
- (void)setAllowsNonnumericFormatting:(BOOL)shouldAllowNonnumericFormatting
|
||||
{
|
||||
_allowsNonnumericFormatting = shouldAllowNonnumericFormatting;
|
||||
}
|
||||
|
||||
- (BOOL)includesActualByteCount
|
||||
{
|
||||
return _includesActualByteCount;
|
||||
}
|
||||
|
||||
- (void)setIncludesActualByteCount:(BOOL)shouldIncludeActualByteCount
|
||||
{
|
||||
_includesActualByteCount = shouldIncludeActualByteCount;
|
||||
}
|
||||
|
||||
- (BOOL)isAdaptive
|
||||
{
|
||||
return _adaptive;
|
||||
}
|
||||
|
||||
- (void)setAdaptive:(BOOL)shouldBeAdaptive
|
||||
{
|
||||
_adaptive = shouldBeAdaptive;
|
||||
}
|
||||
|
||||
- (int)allowedUnits
|
||||
{
|
||||
return _allowedUnits;
|
||||
}
|
||||
|
||||
- (void)setAllowedUnits:(int)allowed
|
||||
{
|
||||
// Note: CPByteCountFormatterUseDefault is equivalent to UseAll
|
||||
_allowedUnits = allowed;
|
||||
}
|
||||
|
||||
- (BOOL)includesCount
|
||||
{
|
||||
return _includesCount;
|
||||
}
|
||||
|
||||
- (void)setIncludesCount:(BOOL)shouldIncludeCount
|
||||
{
|
||||
_includesCount = shouldIncludeCount;
|
||||
}
|
||||
|
||||
- (BOOL)includesUnit
|
||||
{
|
||||
return _includesUnit;
|
||||
}
|
||||
|
||||
- (void)setIncludesUnit:(BOOL)shouldIncludeUnit
|
||||
{
|
||||
_includesUnit = shouldIncludeUnit;
|
||||
}
|
||||
|
||||
- (BOOL)zeroPadsFractionDigits
|
||||
{
|
||||
return _zeroPadsFractionDigits;
|
||||
}
|
||||
|
||||
- (void)setZeroPadsFractionDigits:(BOOL)shouldZeroPad
|
||||
{
|
||||
_zeroPadsFractionDigits = shouldZeroPad;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
var CPByteCountFormatterCountStyleKey = @"CPByteCountFormatterCountStyleKey",
|
||||
CPByteCountFormatterAllowsNonnumericFormattingKey = @"CPByteCountFormatterAllowsNonnumericFormattingKey",
|
||||
CPByteCountFormatterIncludesActualByteCountKey = @"CPByteCountFormatterIncludesActualByteCountKey",
|
||||
CPByteCountFormatterIncludesCountKey = @"CPByteCountFormatterIncludesCountKey",
|
||||
CPByteCountFormatterIncludesUnitKey = @"CPByteCountFormatterIncludesUnitKey",
|
||||
CPByteCountFormatterAdaptiveKey = @"CPByteCountFormatterAdaptiveKey",
|
||||
CPByteCountFormatterZeroPadsFractionDigitsKey = @"CPByteCountFormatterZeroPadsFractionDigitsKey",
|
||||
CPByteCountFormatterAllowedUnitsKey = @"CPByteCountFormatterAllowedUnitsKey";
|
||||
|
||||
@implementation CPByteCountFormatter (CPCoding)
|
||||
|
||||
- (id)initWithCoder:(CPCoder)aCoder
|
||||
{
|
||||
self = [super initWithCoder:aCoder];
|
||||
|
||||
if (self)
|
||||
{
|
||||
_countStyle = [aCoder decodeIntForKey:CPByteCountFormatterCountStyleKey];
|
||||
_allowsNonnumericFormatting = [aCoder decodeBoolForKey:CPByteCountFormatterAllowsNonnumericFormattingKey];
|
||||
_includesActualByteCount = [aCoder decodeBoolForKey:CPByteCountFormatterIncludesActualByteCountKey];
|
||||
_includesCount = [aCoder decodeBoolForKey:CPByteCountFormatterIncludesCountKey];
|
||||
_includesUnit = [aCoder decodeBoolForKey:CPByteCountFormatterIncludesUnitKey];
|
||||
_adaptive = [aCoder decodeBoolForKey:CPByteCountFormatterAdaptiveKey];
|
||||
_zeroPadsFractionDigits = [aCoder decodeBoolForKey:CPByteCountFormatterZeroPadsFractionDigitsKey];
|
||||
_allowedUnits = [aCoder decodeIntForKey:CPByteCountFormatterAllowedUnitsKey];
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)encodeWithCoder:(CPCoder)aCoder
|
||||
{
|
||||
[super encodeWithCoder:aCoder];
|
||||
|
||||
[aCoder encodeInt:_countStyle forKey:CPByteCountFormatterCountStyleKey];
|
||||
[aCoder encodeBool:_allowsNonnumericFormatting forKey:CPByteCountFormatterAllowsNonnumericFormattingKey];
|
||||
[aCoder encodeBool:_includesActualByteCount forKey:CPByteCountFormatterIncludesActualByteCountKey];
|
||||
[aCoder encodeBool:_includesCount forKey:CPByteCountFormatterIncludesCountKey];
|
||||
[aCoder encodeBool:_includesUnit forKey:CPByteCountFormatterIncludesUnitKey];
|
||||
[aCoder encodeBool:_adaptive forKey:CPByteCountFormatterAdaptiveKey];
|
||||
[aCoder encodeBool:_zeroPadsFractionDigits forKey:CPByteCountFormatterZeroPadsFractionDigitsKey];
|
||||
[aCoder encodeInt:_allowedUnits forKey:CPByteCountFormatterAllowedUnitsKey];
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -65,6 +65,7 @@ CPDateFormatterFullStyle = 4;
|
||||
case CPDateFormatterShortStyle:
|
||||
var format = "d/m/Y";
|
||||
return aDate.dateFormat(format);
|
||||
|
||||
default:
|
||||
return [aDate description];
|
||||
}
|
||||
@@ -74,11 +75,13 @@ CPDateFormatterFullStyle = 4;
|
||||
{
|
||||
if (!aString)
|
||||
return nil;
|
||||
|
||||
switch (_dateStyle)
|
||||
{
|
||||
case CPDateFormatterShortStyle:
|
||||
var format = "d/m/Y";
|
||||
return Date.parseDate(aString, format);
|
||||
|
||||
default:
|
||||
return Date.parseDate(aString);
|
||||
}
|
||||
|
||||
@@ -117,6 +117,7 @@ function CPDecimalMakeWithString(string, locale)
|
||||
// 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+))?$/);
|
||||
|
||||
if (!matches)
|
||||
return CPDecimalMakeNaN();
|
||||
|
||||
@@ -127,10 +128,12 @@ function CPDecimalMakeWithString(string, locale)
|
||||
exp = matches[5];
|
||||
|
||||
var isNegative = NO;
|
||||
|
||||
if (ds && ds === "-")
|
||||
isNegative = YES;
|
||||
|
||||
var exponent = 0;
|
||||
|
||||
if (exp)
|
||||
exponent = parseInt(exp) * ((es && es === "-")?-1:1);
|
||||
|
||||
@@ -138,6 +141,7 @@ function CPDecimalMakeWithString(string, locale)
|
||||
exponent -= decpart.length;
|
||||
|
||||
var inputlength = (intpart?intpart.length:0) + (decpart?decpart.length:0);
|
||||
|
||||
if (inputlength > CPDecimalMaxDigits)
|
||||
{
|
||||
// input is too long, increase exponent and truncate
|
||||
@@ -154,17 +158,21 @@ function CPDecimalMakeWithString(string, locale)
|
||||
// Representation internally starts at most significant digit
|
||||
var m = [],
|
||||
i = 0;
|
||||
|
||||
for (; i < (intpart?intpart.length:0); i++)
|
||||
{
|
||||
if (i >= CPDecimalMaxDigits)
|
||||
break; // truncate
|
||||
Array.prototype.push.call(m, parseInt(intpart.charAt(i)));
|
||||
}
|
||||
|
||||
var j = 0;
|
||||
|
||||
for (; j < (decpart?decpart.length:0); j++)
|
||||
{
|
||||
if ((i + j) >= CPDecimalMaxDigits)
|
||||
break; // truncate
|
||||
|
||||
Array.prototype.push.call(m, parseInt(decpart.charAt(j)));
|
||||
}
|
||||
|
||||
@@ -199,7 +207,7 @@ function CPDecimalMakeWithParts(mantissa, exponent)
|
||||
return CPDecimalMakeNaN();
|
||||
|
||||
// remaining digits are disposed of via truncation
|
||||
while ((mantissa > 0) && (m.length < CPDecimalMaxDigits)) // count selector here could be optimised away
|
||||
while ((mantissa > 0) && (m.length < CPDecimalMaxDigits))
|
||||
{
|
||||
Array.prototype.unshift.call(m, parseInt(mantissa % 10));
|
||||
mantissa = FLOOR(mantissa / 10);
|
||||
@@ -294,6 +302,7 @@ function CPDecimalIsZero(dcm)
|
||||
function CPDecimalIsOne(dcm)
|
||||
{
|
||||
CPDecimalCompact(dcm);
|
||||
|
||||
// exponent doesn't matter as long as mantissa = 0
|
||||
if (!dcm._isNaN)
|
||||
{
|
||||
@@ -304,7 +313,7 @@ function CPDecimalIsOne(dcm)
|
||||
}
|
||||
|
||||
//private method to copy attribute values
|
||||
function _CPDecimalSet(t,s)
|
||||
function _CPDecimalSet(t, s)
|
||||
{
|
||||
// should all be [x copy] ?
|
||||
t._exponent = s._exponent;
|
||||
@@ -386,16 +395,19 @@ function CPDecimalCompare(leftOperand, rightOperand)
|
||||
s1 = leftOperand._exponent + leftOperand._mantissa.length,
|
||||
s2 = rightOperand._exponent + rightOperand._mantissa.length;
|
||||
|
||||
if (leftIsZero || s1 < s2)
|
||||
if (leftIsZero && rightIsZero)
|
||||
return CPOrderedSame;
|
||||
|
||||
if (leftIsZero || (s1 < s2 && !rightIsZero))
|
||||
{
|
||||
if (rightOperand._isNegative)
|
||||
return CPOrderedDescending;
|
||||
else
|
||||
return CPOrderedAscending;
|
||||
}
|
||||
if (rightIsZero || s1 > s2)
|
||||
if (rightIsZero || (s1 > s2 && !leftIsZero))
|
||||
{
|
||||
if (rightOperand._isNegative)
|
||||
if (leftOperand._isNegative)
|
||||
return CPOrderedAscending;
|
||||
else
|
||||
return CPOrderedDescending;
|
||||
@@ -525,20 +537,22 @@ function CPDecimalAdd(result, leftOperand, rightOperand, roundingMode, longMode)
|
||||
result._isNaN = YES;
|
||||
return CPCalculationNoError;
|
||||
}
|
||||
|
||||
// check for zero
|
||||
if (CPDecimalIsZero(leftOperand))
|
||||
{
|
||||
_CPDecimalSet(result, rightOperand);
|
||||
return CPCalculationNoError;
|
||||
}
|
||||
|
||||
if (CPDecimalIsZero(rightOperand))
|
||||
{
|
||||
_CPDecimalSet(result, leftOperand);
|
||||
return CPCalculationNoError;
|
||||
}
|
||||
|
||||
var n1 = CPDecimalCopy(leftOperand),
|
||||
n2 = CPDecimalCopy(rightOperand);
|
||||
var n1 = CPDecimalCopy(leftOperand),
|
||||
n2 = CPDecimalCopy(rightOperand);
|
||||
|
||||
// For different signs use subtraction
|
||||
if (leftOperand._isNegative != rightOperand._isNegative)
|
||||
@@ -561,6 +575,7 @@ function CPDecimalAdd(result, leftOperand, rightOperand, roundingMode, longMode)
|
||||
var comp = 0,
|
||||
ll = n1._mantissa.length,
|
||||
lr = n2._mantissa.length;
|
||||
|
||||
if (ll == lr)
|
||||
comp = CPOrderedSame;
|
||||
else if (ll > lr)
|
||||
@@ -573,6 +588,7 @@ function CPDecimalAdd(result, leftOperand, rightOperand, roundingMode, longMode)
|
||||
{
|
||||
n1._isNegative = NO;
|
||||
n2._isNegative = NO;
|
||||
|
||||
// SimpleCompare does not look at sign
|
||||
if (comp == CPOrderedDescending)
|
||||
{
|
||||
@@ -582,7 +598,9 @@ function CPDecimalAdd(result, leftOperand, rightOperand, roundingMode, longMode)
|
||||
{
|
||||
adderror = _SimpleAdd(result, n2, n1, roundingMode, longMode);
|
||||
}
|
||||
|
||||
result._isNegative = YES;
|
||||
|
||||
// swap sign over over/underflow exception
|
||||
if (CPCalculationUnderflow == adderror)
|
||||
adderror = CPCalculationOverflow;
|
||||
@@ -624,6 +642,7 @@ function _SimpleSubtract(result, leftOperand, rightOperand, roundingMode)
|
||||
for (; i >= 0; i--)
|
||||
{
|
||||
var d = result._mantissa[i + j] - rightOperand._mantissa[i] - borrow;
|
||||
|
||||
if (d < 0)
|
||||
{
|
||||
d = d + 10;
|
||||
@@ -680,15 +699,16 @@ function CPDecimalSubtract(result, leftOperand, rightOperand, roundingMode)
|
||||
result._isNegative = !result._isNegative;
|
||||
return CPCalculationNoError;
|
||||
}
|
||||
|
||||
if (CPDecimalIsZero(rightOperand))
|
||||
{
|
||||
_CPDecimalSet(result, leftOperand);
|
||||
return CPCalculationNoError;
|
||||
}
|
||||
|
||||
var n1 = CPDecimalCopy(leftOperand),
|
||||
n2 = CPDecimalCopy(rightOperand),
|
||||
error1 = CPCalculationNoError;
|
||||
var n1 = CPDecimalCopy(leftOperand),
|
||||
n2 = CPDecimalCopy(rightOperand),
|
||||
error1 = CPCalculationNoError;
|
||||
|
||||
// For different signs use addition
|
||||
if (leftOperand._isNegative != rightOperand._isNegative)
|
||||
@@ -698,10 +718,12 @@ function CPDecimalSubtract(result, leftOperand, rightOperand, roundingMode)
|
||||
n1._isNegative = NO;
|
||||
error1 = CPDecimalAdd(result, n1, rightOperand, roundingMode);
|
||||
result._isNegative = YES;
|
||||
|
||||
if (error1 == CPCalculationUnderflow)
|
||||
error1 = CPCalculationOverflow;
|
||||
else if (error1 == CPCalculationOverflow) // gnustep has bug here
|
||||
error1 = CPCalculationUnderflow;
|
||||
|
||||
return error1;
|
||||
}
|
||||
else
|
||||
@@ -725,6 +747,7 @@ function CPDecimalSubtract(result, leftOperand, rightOperand, roundingMode)
|
||||
{
|
||||
n1._isNegative = NO;
|
||||
n2._isNegative = NO;
|
||||
|
||||
if (comp == CPOrderedAscending)
|
||||
{
|
||||
error1 = _SimpleSubtract(result, n1, n2, roundingMode);
|
||||
@@ -777,6 +800,7 @@ function _SimpleDivide(result, leftOperand, rightOperand, roundingMode)
|
||||
{
|
||||
if (stopk == k)
|
||||
break;
|
||||
|
||||
if (n1._exponent)
|
||||
{
|
||||
// Put back zeros removed by compacting
|
||||
@@ -795,6 +819,7 @@ function _SimpleDivide(result, leftOperand, rightOperand, roundingMode)
|
||||
Array.prototype.push.call(n1._mantissa, (leftOperand._mantissa[used]));
|
||||
n1._isCompact = NO;
|
||||
}
|
||||
|
||||
used++;
|
||||
}
|
||||
else
|
||||
@@ -805,6 +830,7 @@ function _SimpleDivide(result, leftOperand, rightOperand, roundingMode)
|
||||
k = stopk;
|
||||
break;
|
||||
}
|
||||
|
||||
// Borrow one digit
|
||||
Array.prototype.push.call(n1._mantissa, 0);
|
||||
result._exponent--;
|
||||
@@ -839,6 +865,7 @@ function _SimpleDivide(result, leftOperand, rightOperand, roundingMode)
|
||||
}
|
||||
|
||||
error1 = CPDecimalSubtract(n1, n1, rightOperand, roundingMode);
|
||||
|
||||
if (error1 != CPCalculationNoError)
|
||||
error = error1;
|
||||
|
||||
@@ -875,6 +902,7 @@ function CPDecimalDivide(result, leftOperand, rightOperand, roundingMode)
|
||||
result._isNaN = YES;
|
||||
return CPCalculationDivideByZero;
|
||||
}
|
||||
|
||||
if (CPDecimalIsZero(leftOperand))
|
||||
{
|
||||
_CPDecimalSetZero(result);
|
||||
@@ -914,6 +942,7 @@ function CPDecimalDivide(result, leftOperand, rightOperand, roundingMode)
|
||||
return error;
|
||||
}
|
||||
}
|
||||
|
||||
result._exponent += exp;
|
||||
result._isNegative = neg;
|
||||
return error;
|
||||
@@ -930,8 +959,7 @@ function _SimpleMultiply(result, leftOperand, rightOperand, roundingMode, powerM
|
||||
_CPDecimalSetZero(result);
|
||||
|
||||
// Do every digit of the second number
|
||||
var i = 0;
|
||||
for (; i < rightOperand._mantissa.length; i++)
|
||||
for (var i = 0; i < rightOperand._mantissa.length; i++)
|
||||
{
|
||||
_CPDecimalSetZero(n);
|
||||
|
||||
@@ -942,10 +970,10 @@ function _SimpleMultiply(result, leftOperand, rightOperand, roundingMode, powerM
|
||||
if (d == 0)
|
||||
continue;
|
||||
|
||||
var j = 0;
|
||||
for (j = leftOperand._mantissa.length - 1; j >= 0; j--)
|
||||
for (var j = leftOperand._mantissa.length - 1; j >= 0; j--)
|
||||
{
|
||||
e = leftOperand._mantissa[j] * d + carry;
|
||||
|
||||
if (e >= 10)
|
||||
{
|
||||
carry = FLOOR(e / 10);
|
||||
@@ -957,6 +985,7 @@ function _SimpleMultiply(result, leftOperand, rightOperand, roundingMode, powerM
|
||||
// This is one off to allow final carry
|
||||
n._mantissa[j + 1] = e;
|
||||
}
|
||||
|
||||
n._mantissa[0] = carry;
|
||||
|
||||
CPDecimalCompact(n);
|
||||
@@ -973,17 +1002,20 @@ function _SimpleMultiply(result, leftOperand, rightOperand, roundingMode, powerM
|
||||
result._isNaN = YES;
|
||||
return CPCalculationOverflow;
|
||||
}
|
||||
|
||||
result._exponent += exp;
|
||||
|
||||
// perform round to CPDecimalMaxDigits
|
||||
if (result._mantissa.length > CPDecimalMaxDigits && !powerMode)
|
||||
{
|
||||
result._isCompact = NO;
|
||||
|
||||
var scale = CPDecimalMaxDigits - (result._mantissa.length + result._exponent);
|
||||
CPDecimalRound(result, result, scale, roundingMode); // calls compact
|
||||
|
||||
error = CPCalculationLossOfPrecision;
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
@@ -1020,6 +1052,7 @@ function CPDecimalMultiply(result, leftOperand, rightOperand, roundingMode, powe
|
||||
if (exp > CPDecimalMaxExponent)
|
||||
{
|
||||
result._isNaN = YES;
|
||||
|
||||
if (neg)
|
||||
return CPCalculationUnderflow;
|
||||
else
|
||||
@@ -1038,6 +1071,7 @@ function CPDecimalMultiply(result, leftOperand, rightOperand, roundingMode, powe
|
||||
var comp = 0,
|
||||
ll = n1._mantissa.length,
|
||||
lr = n2._mantissa.length;
|
||||
|
||||
if (ll == lr)
|
||||
comp = CPOrderedSame;
|
||||
else if (ll > lr)
|
||||
@@ -1045,7 +1079,6 @@ function CPDecimalMultiply(result, leftOperand, rightOperand, roundingMode, powe
|
||||
else
|
||||
comp = CPOrderedAscending;
|
||||
|
||||
|
||||
if (comp == CPOrderedDescending)
|
||||
{
|
||||
error = _SimpleMultiply(result, n1, n2, roundingMode, powerMode);
|
||||
@@ -1060,6 +1093,7 @@ function CPDecimalMultiply(result, leftOperand, rightOperand, roundingMode, powe
|
||||
if (result._exponent + exp > CPDecimalMaxExponent)
|
||||
{
|
||||
result._isNaN = YES;
|
||||
|
||||
if (neg)
|
||||
return CPCalculationUnderflow;
|
||||
else
|
||||
@@ -1096,17 +1130,21 @@ function CPDecimalMultiply(result, leftOperand, rightOperand, roundingMode, powe
|
||||
function CPDecimalMultiplyByPowerOf10(result, dcm, power, roundingMode)
|
||||
{
|
||||
_CPDecimalSet(result, dcm);
|
||||
|
||||
var p = result._exponent + power;
|
||||
|
||||
if (p > CPDecimalMaxExponent)
|
||||
{
|
||||
result._isNaN = YES;
|
||||
return CPCalculationOverflow;
|
||||
}
|
||||
|
||||
if (p < CPDecimalMinExponent)
|
||||
{
|
||||
result._isNaN = YES;
|
||||
return CPCalculationUnderflow;
|
||||
}
|
||||
|
||||
result._exponent += power;
|
||||
return CPCalculationNoError;
|
||||
}
|
||||
@@ -1131,6 +1169,7 @@ function CPDecimalPower(result, dcm, power, roundingMode)
|
||||
_CPDecimalSetOne(result);
|
||||
|
||||
var e = power;
|
||||
|
||||
while (e)
|
||||
{
|
||||
if (e & 1)
|
||||
@@ -1174,7 +1213,7 @@ function CPDecimalPower(result, dcm, power, roundingMode)
|
||||
*/
|
||||
function CPDecimalNormalize(dcm1, dcm2, roundingMode, longMode)
|
||||
{
|
||||
var factor = (longMode)?2:1;
|
||||
var factor = (longMode) ? 2 : 1;
|
||||
|
||||
if (dcm1._isNaN || dcm2._isNaN)
|
||||
return CPCalculationNoError; // FIXME: correct behavior?
|
||||
@@ -1182,6 +1221,7 @@ function CPDecimalNormalize(dcm1, dcm2, roundingMode, longMode)
|
||||
// ensure compact
|
||||
if (!dcm1._isCompact)
|
||||
CPDecimalCompact(dcm1);
|
||||
|
||||
if (!dcm2._isCompact)
|
||||
CPDecimalCompact(dcm2);
|
||||
|
||||
@@ -1197,6 +1237,7 @@ function CPDecimalNormalize(dcm1, dcm2, roundingMode, longMode)
|
||||
l = 0;
|
||||
|
||||
var e = 0;
|
||||
|
||||
if (e2 > e1 && e1 >= 0 && e2 >= 0)
|
||||
e = e2 - e1;
|
||||
else if (e2 > e1 && e1 < 0 && e2 >= 0)
|
||||
@@ -1222,6 +1263,7 @@ function CPDecimalNormalize(dcm1, dcm2, roundingMode, longMode)
|
||||
else
|
||||
Array.prototype.push.call(dcm1._mantissa, 0);
|
||||
}
|
||||
|
||||
if (e2 > e1)
|
||||
{
|
||||
dcm2._exponent -= l;
|
||||
@@ -1276,6 +1318,7 @@ function CPDecimalNormalize(dcm1, dcm2, roundingMode, longMode)
|
||||
dcm2._isCompact = NO;
|
||||
}
|
||||
}
|
||||
|
||||
return CPCalculationLossOfPrecision;
|
||||
}
|
||||
|
||||
@@ -1294,8 +1337,10 @@ function CPDecimalNormalize(dcm1, dcm2, roundingMode, longMode)
|
||||
@param roundingMode the rounding mode for the operation
|
||||
@return a CPCalculationError status value.
|
||||
*/
|
||||
function CPDecimalRound(result, dcm, scale ,roundingMode)
|
||||
function CPDecimalRound(result, dcm, scale, roundingMode)
|
||||
{
|
||||
_CPDecimalSet(result, dcm);
|
||||
|
||||
if (dcm._isNaN)
|
||||
return;
|
||||
|
||||
@@ -1308,18 +1353,19 @@ function CPDecimalRound(result, dcm, scale ,roundingMode)
|
||||
if (scale == CPDecimalNoScale)
|
||||
return;
|
||||
|
||||
_CPDecimalSet(result,dcm);
|
||||
|
||||
var mc = result._mantissa.length,
|
||||
l = mc + scale + result._exponent;
|
||||
|
||||
if (mc <= l)
|
||||
return;
|
||||
|
||||
else if (l <= 0)
|
||||
{
|
||||
_CPDecimalSetZero(result);
|
||||
return;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
var c = 0,
|
||||
n = 0,
|
||||
up = 0;
|
||||
@@ -1329,39 +1375,46 @@ function CPDecimalRound(result, dcm, scale ,roundingMode)
|
||||
|
||||
switch (roundingMode)
|
||||
{
|
||||
case CPRoundDown:
|
||||
up = result._isNegative;
|
||||
break;
|
||||
case CPRoundUp:
|
||||
up = !result._isNegative;
|
||||
break;
|
||||
case CPRoundPlain:
|
||||
n = result._mantissa[l];
|
||||
up = (n >= 5);
|
||||
break;
|
||||
case _CPRoundHalfDown:
|
||||
n = result._mantissa[l];
|
||||
up = (n > 5);
|
||||
break;
|
||||
case CPRoundBankers:
|
||||
n = result._mantissa[l];
|
||||
if (n > 5)
|
||||
up = YES;
|
||||
else if (n < 5)
|
||||
up = NO;
|
||||
else
|
||||
{
|
||||
if (l == 0)
|
||||
c = 0;
|
||||
case CPRoundDown:
|
||||
up = result._isNegative;
|
||||
break;
|
||||
|
||||
case CPRoundUp:
|
||||
up = !result._isNegative;
|
||||
break;
|
||||
|
||||
case CPRoundPlain:
|
||||
n = result._mantissa[l];
|
||||
up = (n >= 5);
|
||||
break;
|
||||
|
||||
case _CPRoundHalfDown:
|
||||
n = result._mantissa[l];
|
||||
up = (n > 5);
|
||||
break;
|
||||
|
||||
case CPRoundBankers:
|
||||
n = result._mantissa[l];
|
||||
|
||||
if (n > 5)
|
||||
up = YES;
|
||||
else if (n < 5)
|
||||
up = NO;
|
||||
else
|
||||
c = result._mantissa[l - 1];
|
||||
up = ((c % 2) != 0);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
up = NO;
|
||||
break;
|
||||
{
|
||||
if (l == 0)
|
||||
c = 0;
|
||||
else
|
||||
c = result._mantissa[l - 1];
|
||||
up = ((c % 2) != 0);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
up = NO;
|
||||
break;
|
||||
}
|
||||
|
||||
// cut mantissa
|
||||
result._mantissa = Array.prototype.slice.call(result._mantissa, 0, l);
|
||||
|
||||
@@ -1374,13 +1427,16 @@ function CPDecimalRound(result, dcm, scale ,roundingMode)
|
||||
result._mantissa[i]++;
|
||||
break;
|
||||
}
|
||||
|
||||
result._mantissa[i] = 0;
|
||||
}
|
||||
|
||||
// Final overflow?
|
||||
if (i == -1)
|
||||
{
|
||||
// As all digits are zeros, just change the first
|
||||
result._mantissa[0] = 1;
|
||||
|
||||
if (result._exponent >= CPDecimalMaxExponent)
|
||||
{
|
||||
// Overflow in rounding.
|
||||
@@ -1414,17 +1470,18 @@ function CPDecimalCompact(dcm)
|
||||
_CPDecimalSetZero(dcm);
|
||||
return;
|
||||
}
|
||||
|
||||
// leading zeros, when exponent is zero these mean we need to move our decimal point to compact
|
||||
// if exp is zero does it make sense to have them? don't think so so delete them
|
||||
while (dcm._mantissa[0] === 0)
|
||||
{
|
||||
Array.prototype.shift.call(dcm._mantissa);
|
||||
}
|
||||
|
||||
// trailing zeros, strip them
|
||||
while (dcm._mantissa[dcm._mantissa.length - 1] === 0)
|
||||
{
|
||||
Array.prototype.pop.call(dcm._mantissa);
|
||||
dcm._exponent++;
|
||||
|
||||
if (dcm._exponent + 1 > CPDecimalMaxExponent)
|
||||
{
|
||||
// TODO: test case for this
|
||||
@@ -1478,6 +1535,7 @@ function CPDecimalString(dcm, locale)
|
||||
{
|
||||
string += dcm._mantissa[i];
|
||||
}
|
||||
|
||||
if (l < k)
|
||||
{
|
||||
string += ".";
|
||||
@@ -1486,6 +1544,7 @@ function CPDecimalString(dcm, locale)
|
||||
string += dcm._mantissa[i];
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < dcm._exponent; i++)
|
||||
{
|
||||
string += "0";
|
||||
|
||||
@@ -123,6 +123,7 @@ var CPDefaultDcmHandler = nil;
|
||||
{
|
||||
if (!CPDefaultDcmHandler)
|
||||
CPDefaultDcmHandler = [[CPDecimalNumberHandler alloc] init];
|
||||
|
||||
return CPDefaultDcmHandler;
|
||||
}
|
||||
|
||||
@@ -172,26 +173,37 @@ var CPDefaultDcmHandler = nil;
|
||||
{
|
||||
switch (error)
|
||||
{
|
||||
case CPCalculationNoError: break;
|
||||
case CPCalculationOverflow: if (_raiseOnOverflow)
|
||||
[CPException raise:CPDecimalNumberOverflowException reason:("A CPDecimalNumber overflow has occurred. (Left operand= '" + [leftOperand descriptionWithLocale:nil] + "' Right operand= '" + [rightOperand descriptionWithLocale:nil] + "' Selector= '" + operation + "')") ];
|
||||
else
|
||||
return [CPDecimalNumber notANumber];
|
||||
break;
|
||||
case CPCalculationUnderflow: if (_raiseOnUnderflow)
|
||||
[CPException raise:CPDecimalNumberUnderflowException reason:("A CPDecimalNumber underflow has occurred. (Left operand= '" + [leftOperand descriptionWithLocale:nil] + "' Right operand= '" + [rightOperand descriptionWithLocale:nil] + "' Selector= '" + operation + "')") ];
|
||||
else
|
||||
return [CPDecimalNumber notANumber];
|
||||
break;
|
||||
case CPCalculationLossOfPrecision: if (_raiseOnExactness)
|
||||
[CPException raise:CPDecimalNumberExactnessException reason:("A CPDecimalNumber has been rounded off during a calculation. (Left operand= '" + [leftOperand descriptionWithLocale:nil] + "' Right operand= '" + [rightOperand descriptionWithLocale:nil] + "' Selector= '" + operation + "')") ];
|
||||
break;
|
||||
case CPCalculationDivideByZero: if (_raiseOnDivideByZero)
|
||||
[CPException raise:CPDecimalNumberDivideByZeroException reason:("A CPDecimalNumber divide by zero has occurred. (Left operand= '" + [leftOperand descriptionWithLocale:nil] + "' Right operand= '" + [rightOperand descriptionWithLocale:nil] + "' Selector= '" + operation + "')") ];
|
||||
else
|
||||
return [CPDecimalNumber notANumber]; // Div by zero returns NaN
|
||||
break;
|
||||
default: [CPException raise:CPInvalidArgumentException reason:("An unknown CPDecimalNumber error has occurred. (Left operand= '" + [leftOperand descriptionWithLocale:nil] + "' Right operand= '" + [rightOperand descriptionWithLocale:nil] + "' Selector= '" + operation + "')") ];
|
||||
case CPCalculationNoError:
|
||||
break;
|
||||
|
||||
case CPCalculationOverflow:
|
||||
if (_raiseOnOverflow)
|
||||
[CPException raise:CPDecimalNumberOverflowException reason:("A CPDecimalNumber overflow has occurred. (Left operand= '" + [leftOperand descriptionWithLocale:nil] + "' Right operand= '" + [rightOperand descriptionWithLocale:nil] + "' Selector= '" + operation + "')") ];
|
||||
else
|
||||
return [CPDecimalNumber notANumber];
|
||||
break;
|
||||
|
||||
case CPCalculationUnderflow:
|
||||
if (_raiseOnUnderflow)
|
||||
[CPException raise:CPDecimalNumberUnderflowException reason:("A CPDecimalNumber underflow has occurred. (Left operand= '" + [leftOperand descriptionWithLocale:nil] + "' Right operand= '" + [rightOperand descriptionWithLocale:nil] + "' Selector= '" + operation + "')") ];
|
||||
else
|
||||
return [CPDecimalNumber notANumber];
|
||||
break;
|
||||
|
||||
case CPCalculationLossOfPrecision:
|
||||
if (_raiseOnExactness)
|
||||
[CPException raise:CPDecimalNumberExactnessException reason:("A CPDecimalNumber has been rounded off during a calculation. (Left operand= '" + [leftOperand descriptionWithLocale:nil] + "' Right operand= '" + [rightOperand descriptionWithLocale:nil] + "' Selector= '" + operation + "')") ];
|
||||
break;
|
||||
|
||||
case CPCalculationDivideByZero:
|
||||
if (_raiseOnDivideByZero)
|
||||
[CPException raise:CPDecimalNumberDivideByZeroException reason:("A CPDecimalNumber divide by zero has occurred. (Left operand= '" + [leftOperand descriptionWithLocale:nil] + "' Right operand= '" + [rightOperand descriptionWithLocale:nil] + "' Selector= '" + operation + "')") ];
|
||||
else
|
||||
return [CPDecimalNumber notANumber]; // Div by zero returns NaN
|
||||
break;
|
||||
|
||||
default:
|
||||
[CPException raise:CPInvalidArgumentException reason:("An unknown CPDecimalNumber error has occurred. (Left operand= '" + [leftOperand descriptionWithLocale:nil] + "' Right operand= '" + [rightOperand descriptionWithLocale:nil] + "' Selector= '" + operation + "')")];
|
||||
}
|
||||
|
||||
return nil;
|
||||
@@ -537,6 +549,7 @@ var CPDecimalNumberHandlerRoundingModeKey = @"CPDecimalNumberHandlerRoundi
|
||||
if (res != nil)
|
||||
return res;
|
||||
}
|
||||
|
||||
return [CPDecimalNumber decimalNumberWithDecimal:result];
|
||||
}
|
||||
|
||||
@@ -570,9 +583,11 @@ var CPDecimalNumberHandlerRoundingModeKey = @"CPDecimalNumberHandlerRoundi
|
||||
if (error > CPCalculationNoError)
|
||||
{
|
||||
var res = [behavior exceptionDuringOperation:_cmd error:error leftOperand:self rightOperand:decimalNumber];
|
||||
|
||||
if (res != nil)
|
||||
return res;
|
||||
}
|
||||
|
||||
return [CPDecimalNumber decimalNumberWithDecimal:result];
|
||||
}
|
||||
|
||||
@@ -609,6 +624,7 @@ var CPDecimalNumberHandlerRoundingModeKey = @"CPDecimalNumberHandlerRoundi
|
||||
if (res != nil)
|
||||
return res;
|
||||
}
|
||||
|
||||
return [CPDecimalNumber decimalNumberWithDecimal:result];
|
||||
}
|
||||
|
||||
@@ -642,9 +658,11 @@ var CPDecimalNumberHandlerRoundingModeKey = @"CPDecimalNumberHandlerRoundi
|
||||
if (error > CPCalculationNoError)
|
||||
{
|
||||
var res = [behavior exceptionDuringOperation:_cmd error:error leftOperand:self rightOperand:decimalNumber];
|
||||
|
||||
if (res != nil)
|
||||
return res;
|
||||
}
|
||||
|
||||
return [CPDecimalNumber decimalNumberWithDecimal:result];
|
||||
}
|
||||
|
||||
@@ -678,9 +696,11 @@ var CPDecimalNumberHandlerRoundingModeKey = @"CPDecimalNumberHandlerRoundi
|
||||
if (error > CPCalculationNoError)
|
||||
{
|
||||
var res = [behavior exceptionDuringOperation:_cmd error:error leftOperand:self rightOperand:[CPDecimalNumber decimalNumberWithString:power.toString()]];
|
||||
|
||||
if (res != nil)
|
||||
return res;
|
||||
}
|
||||
|
||||
return [CPDecimalNumber decimalNumberWithDecimal:result];
|
||||
}
|
||||
|
||||
@@ -717,9 +737,11 @@ var CPDecimalNumberHandlerRoundingModeKey = @"CPDecimalNumberHandlerRoundi
|
||||
if (error > CPCalculationNoError)
|
||||
{
|
||||
var res = [behavior exceptionDuringOperation:_cmd error:error leftOperand:self rightOperand:[CPDecimalNumber decimalNumberWithString:power.toString()]];
|
||||
|
||||
if (res != nil)
|
||||
return res;
|
||||
}
|
||||
|
||||
return [CPDecimalNumber decimalNumberWithDecimal:result];
|
||||
}
|
||||
|
||||
@@ -751,6 +773,7 @@ var CPDecimalNumberHandlerRoundingModeKey = @"CPDecimalNumberHandlerRoundi
|
||||
// aNumber type is checked to convert if appropriate
|
||||
if (![aNumber isKindOfClass:[CPDecimalNumber class]])
|
||||
aNumber = [CPDecimalNumber decimalNumberWithString:aNumber.toString()];
|
||||
|
||||
return CPDecimalCompare([self decimalValue], [aNumber decimalValue]);
|
||||
}
|
||||
|
||||
|
||||
@@ -300,7 +300,7 @@
|
||||
var value = arguments[index];
|
||||
|
||||
if (value === nil)
|
||||
break;
|
||||
continue;
|
||||
|
||||
[self setObject:value forKey:arguments[index + 1]];
|
||||
}
|
||||
|
||||
@@ -33,8 +33,8 @@ CPUndefinedKeyException = @"CPUndefinedKeyException";
|
||||
CPTargetObjectUserInfoKey = @"CPTargetObjectUserInfoKey";
|
||||
CPUnknownUserInfoKey = @"CPUnknownUserInfoKey";
|
||||
|
||||
var CPObjectAccessorsForClassKey = @"$CPObjectAccessorsForClassKey",
|
||||
CPObjectModifiersForClassKey = @"$CPObjectModifiersForClassKey";
|
||||
var CPObjectAccessorsForClassKey = @"$CPObjectAccessorsForClassKey",
|
||||
CPObjectModifiersForClassKey = @"$CPObjectModifiersForClassKey";
|
||||
|
||||
@implementation CPObject (CPKeyValueCoding)
|
||||
|
||||
@@ -107,13 +107,20 @@ var CPObjectAccessorsForClassKey = @"$CPObjectAccessorsForClassKey",
|
||||
|
||||
switch (accessor[0])
|
||||
{
|
||||
case 0: return objj_msgSend(self, accessor[1]);
|
||||
// FIXME: We shouldn't be creating a new one every time.
|
||||
case 1: return [[_CPKeyValueCodingArray alloc] initWithTarget:self key:aKey];
|
||||
// FIXME: We shouldn't be creating a new one every time.
|
||||
case 2: return [[_CPKeyValueCodingSet alloc] initWithTarget:self key:aKey];
|
||||
case 3: if ([theClass accessInstanceVariablesDirectly])
|
||||
return self[accessor[1]];
|
||||
case 0:
|
||||
return objj_msgSend(self, accessor[1]);
|
||||
|
||||
case 1:
|
||||
// FIXME: We shouldn't be creating a new one every time.
|
||||
return [[_CPKeyValueCodingArray alloc] initWithTarget:self key:aKey];
|
||||
|
||||
case 2:
|
||||
// FIXME: We shouldn't be creating a new one every time.
|
||||
return [[_CPKeyValueCodingSet alloc] initWithTarget:self key:aKey];
|
||||
|
||||
case 3:
|
||||
if ([theClass accessInstanceVariablesDirectly])
|
||||
return self[accessor[1]];
|
||||
}
|
||||
|
||||
return [self valueForUndefinedKey:aKey];
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* CPKeyValueCoding.j
|
||||
* CPKeyValueObserving.j
|
||||
* Foundation
|
||||
*
|
||||
* Created by Ross Boucher.
|
||||
@@ -788,7 +788,11 @@ var kvoNewAndOld = CPKeyValueObservingOptionNew | CPKeyValueObservingOpti
|
||||
|
||||
if (aPath.indexOf('.') != CPNotFound)
|
||||
{
|
||||
var forwarder = [observers objectForKey:[anObserver UID]].forwarder;
|
||||
// During cib instantiation, it is possible for the forwarder to not yet be available,
|
||||
// so we have to check for nil.
|
||||
var observer = [observers objectForKey:[anObserver UID]],
|
||||
forwarder = observer ? observer.forwarder : nil;
|
||||
|
||||
[forwarder finalize];
|
||||
}
|
||||
|
||||
|
||||
@@ -26,9 +26,6 @@
|
||||
@import "CPFormatter.j"
|
||||
@import "CPDecimalNumber.j"
|
||||
|
||||
#define UPDATE_NUMBER_HANDLER_IF_NECESSARY() if (!_numberHandler) \
|
||||
_numberHandler = [CPDecimalNumberHandler decimalNumberHandlerWithRoundingMode:_roundingMode scale:_maximumFractionDigits raiseOnExactness:NO raiseOnOverflow:NO raiseOnUnderflow:NO raiseOnDivideByZero:YES];
|
||||
#define SET_NEEDS_NUMBER_HANDLER_UPDATE() _numberHandler = nil;
|
||||
|
||||
CPNumberFormatterNoStyle = 0;
|
||||
CPNumberFormatterDecimalStyle = 1;
|
||||
@@ -47,6 +44,9 @@ CPNumberFormatterRoundHalfUp = CPRoundPlain;
|
||||
|
||||
var NumberRegex = new RegExp('(-)?(\\d*)(\\.(\\d*))?');
|
||||
|
||||
#define SET_NEEDS_NUMBER_HANDLER_UPDATE() _numberHandler = nil
|
||||
|
||||
|
||||
/*!
|
||||
@ingroup foundation
|
||||
@class CPNumberFormatter
|
||||
@@ -105,7 +105,7 @@ var NumberRegex = new RegExp('(-)?(\\d*)(\\.(\\d*))?');
|
||||
case CPNumberFormatterCurrencyStyle:
|
||||
case CPNumberFormatterDecimalStyle:
|
||||
case CPNumberFormatterPercentStyle:
|
||||
UPDATE_NUMBER_HANDLER_IF_NECESSARY();
|
||||
[self _updateNumberHandlerIfNecessary];
|
||||
|
||||
dcmn = [dcmn decimalNumberByRoundingAccordingToBehavior:_numberHandler];
|
||||
|
||||
@@ -133,6 +133,7 @@ var NumberRegex = new RegExp('(-)?(\\d*)(\\.(\\d*))?');
|
||||
}
|
||||
|
||||
var string = preFraction;
|
||||
|
||||
if (fraction)
|
||||
string += "." + fraction;
|
||||
|
||||
@@ -151,6 +152,7 @@ var NumberRegex = new RegExp('(-)?(\\d*)(\\.(\\d*))?');
|
||||
string = negativePrefix + string;
|
||||
|
||||
return string;
|
||||
|
||||
default:
|
||||
return [number description];
|
||||
}
|
||||
@@ -197,6 +199,7 @@ var NumberRegex = new RegExp('(-)?(\\d*)(\\.(\\d*))?');
|
||||
_maximumFractionDigits = 3;
|
||||
SET_NEEDS_NUMBER_HANDLER_UPDATE();
|
||||
break;
|
||||
|
||||
case CPNumberFormatterCurrencyStyle:
|
||||
_minimumFractionDigits = 2;
|
||||
_maximumFractionDigits = 2;
|
||||
@@ -223,9 +226,17 @@ var NumberRegex = new RegExp('(-)?(\\d*)(\\.(\\d*))?');
|
||||
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];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
var CPNumberFormatterStyleKey = "CPNumberFormatterStyleKey",
|
||||
var CPNumberFormatterStyleKey = @"CPNumberFormatterStyleKey",
|
||||
CPNumberFormatterMinimumFractionDigitsKey = @"CPNumberFormatterMinimumFractionDigitsKey",
|
||||
CPNumberFormatterMaximumFractionDigitsKey = @"CPNumberFormatterMaximumFractionDigitsKey",
|
||||
CPNumberFormatterRoundingModeKey = @"CPNumberFormatterRoundingModeKey",
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
@import "_CGGeometry.j"
|
||||
@import "CPArray.j"
|
||||
@import "CPBundle.j"
|
||||
@import "CPByteCountFormatter.j"
|
||||
@import "CPCharacterSet.j"
|
||||
@import "CPCoder.j"
|
||||
@import "CPComparisonPredicate.j"
|
||||
|
||||
@@ -22,8 +22,16 @@
|
||||
|
||||
@import "CPObject.j"
|
||||
|
||||
var _CPCollectionKVCOperatorSimpleRE = /^@(avg|count|m(ax|in)|sum)(\.|$)/;
|
||||
|
||||
|
||||
@implementation _CPCollectionKVCOperator : CPObject
|
||||
|
||||
+ (BOOL)isSimpleCollectionOperator:(CPString)operator
|
||||
{
|
||||
return _CPCollectionKVCOperatorSimpleRE.test(operator);
|
||||
}
|
||||
|
||||
+ (id)performOperation:(CPString)operator withCollection:(id)aCollection propertyPath:(CPString)propertyPath
|
||||
{
|
||||
var selector = CPSelectorFromString(operator + @"ForCollection:propertyPath:");
|
||||
|
||||
@@ -111,7 +111,7 @@ function environmentFlags()
|
||||
|
||||
var SHRINKSAFE = require("minify/shrinksafe");
|
||||
function compressor(code) {
|
||||
return SHRINKSAFE.compress(code, { charset : "UTF-16", useServer : true });
|
||||
return SHRINKSAFE.compress(code, { charset : "UTF-8", useServer : true });
|
||||
}
|
||||
|
||||
function gcc(inputFilePath, outputFilePath, flags, compress)
|
||||
|
||||
@@ -184,7 +184,46 @@
|
||||
[self assert:[CPNumber numberWithInt:2] equals:[_arrayController arrangedObjects][1]];
|
||||
}
|
||||
|
||||
- (void)testAdd
|
||||
{
|
||||
_contentArray = [];
|
||||
_arrayController = [[CPArrayController alloc] initWithContent:_contentArray];
|
||||
[self _testAdd];
|
||||
}
|
||||
|
||||
- (void)_testAdd
|
||||
{
|
||||
[_arrayController setObjectClass:[Employee class]];
|
||||
[self assert:[[_arrayController contentArray] count] equals:0];
|
||||
[_arrayController add:nil];
|
||||
[self assert:[[_arrayController contentArray] count] equals:1];
|
||||
[self assert:[[_arrayController arrangedObjects][0] class] equals:[Employee class]];
|
||||
|
||||
// switch it up so that we can tell where this one is.
|
||||
[_arrayController setObjectClass:[Department class]];
|
||||
[_arrayController add:nil];
|
||||
[self assert:[[[_arrayController arrangedObjects] lastObject] class] equals:[Department class]];
|
||||
}
|
||||
|
||||
- (void)testInsert
|
||||
{
|
||||
_contentArray = [];
|
||||
_arrayController = [[CPArrayController alloc] initWithContent:_contentArray];
|
||||
[self _testInsert];
|
||||
}
|
||||
|
||||
- (void)_testInsert
|
||||
{
|
||||
[_arrayController setObjectClass:[Employee class]];
|
||||
[_arrayController add:nil];
|
||||
[_arrayController add:nil];
|
||||
[_arrayController add:nil];
|
||||
|
||||
[_arrayController setObjectClass:[Department class]];
|
||||
[_arrayController setSelectionIndex:1];
|
||||
[_arrayController insert:nil];
|
||||
[self assert:[[[_arrayController arrangedObjects] objectAtIndex:1] class] equals:[Department class]];
|
||||
}
|
||||
|
||||
- (void)_initTestRemoveObjects_SimpleArray
|
||||
{
|
||||
|
||||
@@ -237,7 +237,7 @@
|
||||
|
||||
[arrayController setSelectionIndex:0];
|
||||
|
||||
var options = [CPDictionary dictionaryWithJSObject:{CPMultipleValuesPlaceholderBindingOption:@"Multiple Values"}];
|
||||
var options = [CPDictionary dictionaryWithObject:@"Multiple Values" forKey:CPMultipleValuesPlaceholderBindingOption];
|
||||
[textField bind:@"value" toObject:arrayController withKeyPath:@"selection.cheese" options:options];
|
||||
|
||||
[self assert:@"yellow" equals:[textField stringValue] message:@"text field string value should be 'yellow'"];
|
||||
|
||||
@@ -214,5 +214,53 @@
|
||||
[self assert:replacementDocumentView equals:[scrollView documentView] message:@"documentView was not replaced properly"];
|
||||
}
|
||||
|
||||
- (void)testScrollRectToVisible
|
||||
{
|
||||
var scrollView = [[CPScrollView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)],
|
||||
documentView = [[CPView alloc] initWithFrame:CGRectMake(0, 0, 1000, 1000)],
|
||||
textField1 = [CPTextField textFieldWithStringValue:@"Martin" placeholder:@"" width:10],
|
||||
textField2 = [CPTextField textFieldWithStringValue:@"Malte" placeholder:@"" width:10],
|
||||
textField1Size = CGSizeMakeCopy([textField1 bounds].size),
|
||||
textField2Size = CGSizeMakeCopy([textField2 bounds].size);
|
||||
|
||||
[scrollView setDocumentView:documentView];
|
||||
|
||||
[textField1 setFrameOrigin:CGPointMake(0, 0)];
|
||||
[textField2 setFrameOrigin:CGPointMake(500, 500)];
|
||||
|
||||
[documentView addSubview:textField1];
|
||||
[documentView addSubview:textField2];
|
||||
|
||||
var visibleRect = [documentView visibleRect],
|
||||
originalVisibleSize = CGSizeMakeCopy(visibleRect.size);
|
||||
|
||||
// Make sure we are at the top left corner
|
||||
[self assertPoint:CGPointMake(0, 0) equals:visibleRect.origin message:@"VisibleRect origin not at top left corner"];
|
||||
|
||||
// Make the second text field visible
|
||||
[textField2 scrollRectToVisible:[textField2 bounds]];
|
||||
|
||||
var visibleRectOriginShouldBeAt = CGPointMake(500 - originalVisibleSize.width + textField2Size.width, 500 -originalVisibleSize.height + textField2Size.height);
|
||||
|
||||
visibleRect = [documentView visibleRect];
|
||||
|
||||
// We should now have the text field in the lower right corner
|
||||
[self assertPoint:visibleRectOriginShouldBeAt equals:visibleRect.origin message:@"Second text field not at lower right corner in visible rect"];
|
||||
|
||||
// Make the first text field visible again
|
||||
[textField1 scrollRectToVisible:[textField2 bounds]];
|
||||
|
||||
visibleRect = [documentView visibleRect];
|
||||
|
||||
// We should now be back at top left corner
|
||||
[self assertPoint:CGPointMake(0, 0) equals:visibleRect.origin message:@"VisibleRect origin not at top left corner again"];
|
||||
}
|
||||
|
||||
- (void)assertPoint:(CGPoint)expected equals:(CGPoint)actual message:(CPString)message
|
||||
{
|
||||
[self assert:expected.x equals:actual.x message:@"X: " + message];
|
||||
[self assert:expected.y equals:actual.y message:@"Y: " + message];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
|
||||
@import <AppKit/CPWindow.j>
|
||||
@import <AppKit/_CPBorderlessWindowView.j>
|
||||
@import <Foundation/CPURL.j>
|
||||
|
||||
[CPApplication sharedApplication];
|
||||
|
||||
@@ -109,4 +110,22 @@
|
||||
message:@"nextTextField should be the previous valid key view of contentView"];
|
||||
}
|
||||
|
||||
- (void)testRepresentedFilename
|
||||
{
|
||||
/*
|
||||
representedURL and representedFilename
|
||||
are drawn from the _representedURL variable.
|
||||
*/
|
||||
var aURL = @"http://www.cappuccino-project.org";
|
||||
|
||||
[[self window] setRepresentedURL:[CPURL URLWithString:aURL]];
|
||||
[self assertTrue:[[[self window] representedURL] class] === [CPURL class]];
|
||||
/*
|
||||
Test for Issue 1633
|
||||
Make sure that changing it via setRepresentedFilename doesn't change the type
|
||||
*/
|
||||
[[self window] setRepresentedFilename:aURL];
|
||||
[self assertTrue:[[[self window] representedURL] class] === [CPURL class]];
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -1 +1 @@
|
||||
280NPLIST;1.0;D;K;4;$topD;K;18;CPCibObjectDataKeyD;K;6;CP$UIDd;1;2E;E;K;8;$objectsA;S;5;$nullD;K;10;$classnameS;16;_CPCibObjectDataK;8;$classesA;S;16;_CPCibObjectDataS;8;CPObjectE;E;D;K;6;$classD;K;6;CP$UIDd;1;1E;K;28;_CPCibObjectDataNamesKeysKeyD;K;6;CP$UIDd;1;0E;K;30;_CPCibObjectDataNamesValuesKeyD;K;6;CP$UIDd;1;0E;K;30;_CPCibObjectDataClassesKeysKeyD;K;6;CP$UIDd;1;0E;K;32;_CPCibObjectDataClassesValuesKeyD;K;6;CP$UIDd;1;0E;K;30;_CPCibObjectDataConnectionsKeyD;K;6;CP$UIDd;1;4E;K;28;_CPCibObjectDataFrameworkKeyD;K;6;CP$UIDd;1;0E;K;26;_CPCibObjectDataNextOidKeyD;K;6;CP$UIDd;1;5E;K;30;_CPCibObjectDataObjectsKeysKeyD;K;6;CP$UIDd;1;6E;K;32;_CPCibObjectDataObjectsValuesKeyD;K;6;CP$UIDd;1;7E;K;26;_CPCibObjectDataOidKeysKeyD;K;6;CP$UIDd;1;8E;K;28;_CPCibObjectDataOidValuesKeyD;K;6;CP$UIDd;1;9E;K;28;_CPCibObjectDataFileOwnerKeyD;K;6;CP$UIDd;2;11E;K;33;_CPCibObjectDataVisibleWindowsKeyD;K;6;CP$UIDd;2;13E;E;D;K;10;$classnameS;7;CPArrayK;8;$classesA;S;7;CPArrayS;8;CPObjectE;E;D;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;2;15E;D;K;6;CP$UIDd;2;16E;D;K;6;CP$UIDd;2;17E;D;K;6;CP$UIDd;2;18E;D;K;6;CP$UIDd;2;19E;D;K;6;CP$UIDd;2;20E;D;K;6;CP$UIDd;2;22E;D;K;6;CP$UIDd;2;24E;D;K;6;CP$UIDd;2;25E;D;K;6;CP$UIDd;2;26E;E;E;D;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;E;E;D;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;2;27E;D;K;6;CP$UIDd;2;29E;D;K;6;CP$UIDd;2;31E;D;K;6;CP$UIDd;2;33E;D;K;6;CP$UIDd;1;0E;D;K;6;CP$UIDd;2;35E;D;K;6;CP$UIDd;1;0E;D;K;6;CP$UIDd;2;37E;D;K;6;CP$UIDd;1;0E;D;K;6;CP$UIDd;2;38E;D;K;6;CP$UIDd;1;0E;D;K;6;CP$UIDd;2;40E;E;E;D;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;2;11E;D;K;6;CP$UIDd;2;11E;D;K;6;CP$UIDd;2;29E;D;K;6;CP$UIDd;2;31E;D;K;6;CP$UIDd;2;33E;D;K;6;CP$UIDd;2;31E;D;K;6;CP$UIDd;2;35E;D;K;6;CP$UIDd;2;31E;D;K;6;CP$UIDd;2;37E;D;K;6;CP$UIDd;2;31E;D;K;6;CP$UIDd;2;38E;D;K;6;CP$UIDd;2;11E;E;E;D;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;E;E;D;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;E;E;D;K;10;$classnameS;18;_CPCibCustomObjectK;8;$classesA;S;18;_CPCibCustomObjectS;8;CPObjectE;E;D;K;6;$classD;K;6;CP$UIDd;2;10E;K;27;_CPCibCustomObjectClassNameD;K;6;CP$UIDd;2;41E;E;D;K;10;$classnameS;5;CPSetK;8;$classesA;S;5;CPSetS;8;CPObjectE;E;D;K;6;$classD;K;6;CP$UIDd;2;12E;K;15;CPSetObjectsKeyD;K;6;CP$UIDd;2;42E;E;D;K;10;$classnameS;20;CPCibOutletConnectorK;8;$classesA;S;20;CPCibOutletConnectorS;14;CPCibConnectorS;8;CPObjectE;E;D;K;6;$classD;K;6;CP$UIDd;2;14E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;2;11E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;2;35E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;2;43E;E;D;K;6;$classD;K;6;CP$UIDd;2;14E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;2;11E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;2;40E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;2;44E;E;D;K;6;$classD;K;6;CP$UIDd;2;14E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;2;11E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;2;33E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;2;45E;E;D;K;6;$classD;K;6;CP$UIDd;2;14E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;2;11E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;2;37E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;2;46E;E;D;K;6;$classD;K;6;CP$UIDd;2;14E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;2;11E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;2;29E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;2;47E;E;D;K;6;$classD;K;6;CP$UIDd;2;14E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;2;29E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;2;11E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;2;48E;E;D;K;10;$classnameS;21;CPCibControlConnectorK;8;$classesA;S;21;CPCibControlConnectorS;14;CPCibConnectorS;8;CPObjectE;E;D;K;6;$classD;K;6;CP$UIDd;2;21E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;2;35E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;2;11E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;2;49E;E;D;K;10;$classnameS;21;CPCibBindingConnectorK;8;$classesA;S;21;CPCibBindingConnectorS;14;CPCibConnectorS;8;CPObjectE;E;D;K;6;$classD;K;6;CP$UIDd;2;23E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;2;37E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;2;40E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;2;50E;K;31;CPCibBindingConnectorBindingKeyD;K;6;CP$UIDd;2;51E;K;31;CPCibBindingConnectorKeyPathKeyD;K;6;CP$UIDd;2;52E;K;31;CPCibBindingConnectorOptionsKeyD;K;6;CP$UIDd;2;54E;E;D;K;6;$classD;K;6;CP$UIDd;2;23E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;2;33E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;2;40E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;2;50E;K;31;CPCibBindingConnectorBindingKeyD;K;6;CP$UIDd;2;51E;K;31;CPCibBindingConnectorKeyPathKeyD;K;6;CP$UIDd;2;52E;K;31;CPCibBindingConnectorOptionsKeyD;K;6;CP$UIDd;2;55E;E;D;K;6;$classD;K;6;CP$UIDd;2;23E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;2;40E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;2;11E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;2;56E;K;31;CPCibBindingConnectorBindingKeyD;K;6;CP$UIDd;2;57E;K;31;CPCibBindingConnectorKeyPathKeyD;K;6;CP$UIDd;2;58E;K;31;CPCibBindingConnectorOptionsKeyD;K;6;CP$UIDd;2;59E;E;D;K;6;$cLine truncated
|
||||
280NPLIST;1.0;D;K;4;$topD;K;18;CPCibObjectDataKeyD;K;6;CP$UIDd;1;2E;E;K;8;$objectsA;S;5;$nullD;K;10;$classnameS;16;_CPCibObjectDataK;8;$classesA;S;16;_CPCibObjectDataS;8;CPObjectE;E;D;K;6;$classD;K;6;CP$UIDd;1;1E;K;28;_CPCibObjectDataNamesKeysKeyD;K;6;CP$UIDd;1;0E;K;30;_CPCibObjectDataNamesValuesKeyD;K;6;CP$UIDd;1;0E;K;30;_CPCibObjectDataClassesKeysKeyD;K;6;CP$UIDd;1;0E;K;32;_CPCibObjectDataClassesValuesKeyD;K;6;CP$UIDd;1;0E;K;30;_CPCibObjectDataConnectionsKeyD;K;6;CP$UIDd;1;4E;K;28;_CPCibObjectDataFrameworkKeyD;K;6;CP$UIDd;1;0E;K;26;_CPCibObjectDataNextOidKeyD;K;6;CP$UIDd;1;5E;K;30;_CPCibObjectDataObjectsKeysKeyD;K;6;CP$UIDd;1;6E;K;32;_CPCibObjectDataObjectsValuesKeyD;K;6;CP$UIDd;1;7E;K;26;_CPCibObjectDataOidKeysKeyD;K;6;CP$UIDd;1;8E;K;28;_CPCibObjectDataOidValuesKeyD;K;6;CP$UIDd;1;9E;K;28;_CPCibObjectDataFileOwnerKeyD;K;6;CP$UIDd;2;11E;K;33;_CPCibObjectDataVisibleWindowsKeyD;K;6;CP$UIDd;2;13E;E;D;K;10;$classnameS;7;CPArrayK;8;$classesA;S;7;CPArrayS;8;CPObjectE;E;D;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;2;15E;D;K;6;CP$UIDd;2;16E;D;K;6;CP$UIDd;2;17E;D;K;6;CP$UIDd;2;18E;D;K;6;CP$UIDd;2;19E;D;K;6;CP$UIDd;2;20E;D;K;6;CP$UIDd;2;22E;D;K;6;CP$UIDd;2;24E;D;K;6;CP$UIDd;2;25E;D;K;6;CP$UIDd;2;26E;E;E;D;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;E;E;D;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;2;27E;D;K;6;CP$UIDd;2;29E;D;K;6;CP$UIDd;2;31E;D;K;6;CP$UIDd;2;33E;D;K;6;CP$UIDd;1;0E;D;K;6;CP$UIDd;2;35E;D;K;6;CP$UIDd;1;0E;D;K;6;CP$UIDd;2;37E;D;K;6;CP$UIDd;1;0E;D;K;6;CP$UIDd;2;38E;D;K;6;CP$UIDd;1;0E;D;K;6;CP$UIDd;2;40E;E;E;D;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;2;11E;D;K;6;CP$UIDd;2;11E;D;K;6;CP$UIDd;2;29E;D;K;6;CP$UIDd;2;31E;D;K;6;CP$UIDd;2;33E;D;K;6;CP$UIDd;2;31E;D;K;6;CP$UIDd;2;35E;D;K;6;CP$UIDd;2;31E;D;K;6;CP$UIDd;2;37E;D;K;6;CP$UIDd;2;31E;D;K;6;CP$UIDd;2;38E;D;K;6;CP$UIDd;2;11E;E;E;D;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;E;E;D;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;E;E;D;K;10;$classnameS;18;_CPCibCustomObjectK;8;$classesA;S;18;_CPCibCustomObjectS;8;CPObjectE;E;D;K;6;$classD;K;6;CP$UIDd;2;10E;K;27;_CPCibCustomObjectClassNameD;K;6;CP$UIDd;2;41E;E;D;K;10;$classnameS;5;CPSetK;8;$classesA;S;5;CPSetS;8;CPObjectE;E;D;K;6;$classD;K;6;CP$UIDd;2;12E;K;15;CPSetObjectsKeyD;K;6;CP$UIDd;2;42E;E;D;K;10;$classnameS;20;CPCibOutletConnectorK;8;$classesA;S;20;CPCibOutletConnectorS;14;CPCibConnectorS;8;CPObjectE;E;D;K;6;$classD;K;6;CP$UIDd;2;14E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;2;11E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;2;35E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;2;43E;E;D;K;6;$classD;K;6;CP$UIDd;2;14E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;2;11E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;2;40E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;2;44E;E;D;K;6;$classD;K;6;CP$UIDd;2;14E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;2;11E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;2;33E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;2;45E;E;D;K;6;$classD;K;6;CP$UIDd;2;14E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;2;11E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;2;37E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;2;46E;E;D;K;6;$classD;K;6;CP$UIDd;2;14E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;2;11E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;2;29E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;2;47E;E;D;K;6;$classD;K;6;CP$UIDd;2;14E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;2;29E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;2;11E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;2;48E;E;D;K;10;$classnameS;21;CPCibControlConnectorK;8;$classesA;S;21;CPCibControlConnectorS;14;CPCibConnectorS;8;CPObjectE;E;D;K;6;$classD;K;6;CP$UIDd;2;21E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;2;35E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;2;11E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;2;49E;E;D;K;10;$classnameS;21;CPCibBindingConnectorK;8;$classesA;S;21;CPCibBindingConnectorS;14;CPCibConnectorS;8;CPObjectE;E;D;K;6;$classD;K;6;CP$UIDd;2;23E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;2;37E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;2;40E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;2;50E;K;31;CPCibBindingConnectorBindingKeyD;K;6;CP$UIDd;2;51E;K;31;CPCibBindingConnectorKeyPathKeyD;K;6;CP$UIDd;2;52E;K;31;CPCibBindingConnectorOptionsKeyD;K;6;CP$UIDd;2;54E;E;D;K;6;$classD;K;6;CP$UIDd;2;23E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;2;33E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;2;40E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;2;50E;K;31;CPCibBindingConnectorBindingKeyD;K;6;CP$UIDd;2;51E;K;31;CPCibBindingConnectorKeyPathKeyD;K;6;CP$UIDd;2;52E;K;31;CPCibBindingConnectorOptionsKeyD;K;6;CP$UIDd;2;55E;E;D;K;6;$classD;K;6;CP$UIDd;2;23E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;2;40E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;2;11E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;2;56E;K;31;CPCibBindingConnectorBindingKeyD;K;6;CP$UIDd;2;57E;K;31;CPCibBindingConnectorKeyPathKeyD;K;6;CP$UIDd;2;58E;K;31;CPCibBindingConnectorOptionsKeyD;K;6;CP$UIDd;2;59E;E;D;K;6;$cLine truncated
|
||||