diff --git a/AppKit/CPAccordionView.j b/AppKit/CPAccordionView.j index c9bcf71a7..ec1798a67 100644 --- a/AppKit/CPAccordionView.j +++ b/AppKit/CPAccordionView.j @@ -30,7 +30,12 @@ #import "CoreGraphics/CGGeometry.h" - +/*! + @ingroup appkit + @class CPAccordionViewItem + +
A CPAccordionViewItem represents a single section of a CPAccordionView.
+*/ @implementation CPAccordionViewItem : CPObject { CPString _identifier @accessors(property=identifier); @@ -43,6 +48,10 @@ return [self initWithIdentifier:@""]; } +/*! + Initializes a new CPAccordionViewItem with the specified identifier. This identifier may + then be used in subsequent methods to provide abstract introspection of the CPAccordionView. +*/ - (id)initWithIdentifier:(CPString)anIdentifier { self = [super init]; @@ -55,6 +64,25 @@ @end +/*! + @ingroup appkit + @class CPAccordionView + +CPAccordionView provides a container for CPAccordionViewItem objects and manages layout state + for all sublayout items.
+ + Example+var myAccordionView = [[CPAccordionView alloc] initWithFrame:CGRectMakeZero()]; +var firstItem = [[CPAccordionViewItem alloc] initWithIdentifier:@"firstSection"]]; +[firstItem setView:[[CPView alloc] initWithFrame:CGRectMakeZero()]]; +var secondItem = [[CPAccordionViewItem alloc] initWithIdentifier:@"secondSection"]]; +[secondItem setView:[[CPView alloc] initWithFrame:CGRectMakeZero()]]; +[myAccordionView addItem:firstItem]; +[myAccordionView addItem:secondItem]; +[myAccordionView setAutoresizingMask: CPViewWidthSizable | CPViewHeightSizable]; ++*/ @implementation CPAccordionView : CPView { CPInteger _dirtyItemIndex; @@ -64,7 +92,10 @@ CPMutableArray _itemViews; CPIndexSet _expandedItemIndexes; } - +/*! + Initializes the receiver for usage with the specified bounding rectangle + @return the initialized view +*/ - (id)initWithFrame:(CGRect)aFrame { self = [super initWithFrame:aFrame]; @@ -95,7 +126,11 @@ { return _items; } - +/*! + Append a CPAccordionViewItem to the receiver. Note that the CPAccordionViewItem must contain + a valid CPView derived component or a TypeError will be generated when the contents of the + ViewItem are disclosed. +*/ - (void)addItem:(CPAccordionViewItem)anItem { [self insertItem:anItem atIndex:_items.length]; diff --git a/AppKit/CPApplication.j b/AppKit/CPApplication.j index 56964473d..e23aab878 100644 --- a/AppKit/CPApplication.j +++ b/AppKit/CPApplication.j @@ -54,7 +54,7 @@ CPRunStoppedResponse = -1000; CPRunAbortedResponse = -1001; CPRunContinuesResponse = -1002; -/*! +/*! @ingroup appkit @class CPApplication @@ -62,7 +62,7 @@ CPRunContinuesResponse = -1002; Every GUI application has exactly one instance of CPApplication (or of a custom subclass of CPApplication). Your program's main() function can create that instance by calling the \c CPApplicationMain function. A simple example looks like this: - +
function main(args, namedArgs)
{
@@ -82,25 +82,25 @@ CPRunContinuesResponse = -1002;
@implementation CPApplication : CPResponder
{
CPArray _eventListeners;
-
+
CPEvent _currentEvent;
-
+
CPArray _windows;
CPWindow _keyWindow;
CPWindow _mainWindow;
CPWindow _previousKeyWindow;
CPWindow _previousMainWindow;
-
+
CPMenu _mainMenu;
CPDocumentController _documentController;
-
+
CPModalSession _currentSession;
-
+
//
id _delegate;
BOOL _finishedLaunching;
BOOL _isActive;
-
+
CPDictionary _namedArgs;
CPArray _args;
CPString _fullArgsString;
@@ -119,7 +119,7 @@ CPRunContinuesResponse = -1002;
{
if (!CPApp)
CPApp = [[CPApplication alloc] init];
-
+
return CPApp;
}
@@ -131,73 +131,18 @@ CPRunContinuesResponse = -1002;
- (id)init
{
self = [super init];
-
+
+ CPApp = self;
+
if (self)
{
_eventListeners = [];
-
+
_windows = [];
-
+
[_windows addObject:nil];
-
- // FIXME: This should be read from the cib.
- _mainMenu = [[CPMenu alloc] initWithTitle:@"MainMenu"];
-
- // FIXME: We should implement autoenabling.
- [_mainMenu setAutoenablesItems:NO];
-
- var bundle = [CPBundle bundleForClass:[CPApplication class]],
- newMenuItem = [[CPMenuItem alloc] initWithTitle:@"New" action:@selector(newDocument:) keyEquivalent:@"n"];
-
- [newMenuItem setImage:[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPApplication/New.png"] size:CGSizeMake(16.0, 16.0)]];
- [newMenuItem setAlternateImage:[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPApplication/NewHighlighted.png"] size:CGSizeMake(16.0, 16.0)]];
-
- [_mainMenu addItem:newMenuItem];
-
- var openMenuItem = [[CPMenuItem alloc] initWithTitle:@"Open" action:@selector(openDocument:) keyEquivalent:@"o"];
-
- [openMenuItem setImage:[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPApplication/Open.png"] size:CGSizeMake(16.0, 16.0)]];
- [openMenuItem setAlternateImage:[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPApplication/OpenHighlighted.png"] size:CGSizeMake(16.0, 16.0)]];
-
- [_mainMenu addItem:openMenuItem];
-
- var saveMenu = [[CPMenu alloc] initWithTitle:@"Save"],
- saveMenuItem = [[CPMenuItem alloc] initWithTitle:@"Save" action:@selector(saveDocument:) keyEquivalent:nil];
-
- [saveMenuItem setImage:[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPApplication/Save.png"] size:CGSizeMake(16.0, 16.0)]];
- [saveMenuItem setAlternateImage:[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPApplication/SaveHighlighted.png"] size:CGSizeMake(16.0, 16.0)]];
-
- [saveMenu addItem:[[CPMenuItem alloc] initWithTitle:@"Save" action:@selector(saveDocument:) keyEquivalent:@"s"]];
- [saveMenu addItem:[[CPMenuItem alloc] initWithTitle:@"Save As" action:@selector(saveDocumentAs:) keyEquivalent:nil]];
-
- [saveMenuItem setSubmenu:saveMenu];
-
- [_mainMenu addItem:saveMenuItem];
-
- var editMenuItem = [[CPMenuItem alloc] initWithTitle:@"Edit" action:nil keyEquivalent:nil],
- editMenu = [[CPMenu alloc] initWithTitle:@"Edit"],
-
- undoMenuItem = [[CPMenuItem alloc] initWithTitle:@"Undo" action:@selector(undo:) keyEquivalent:CPUndoKeyEquivalent],
- redoMenuItem = [[CPMenuItem alloc] initWithTitle:@"Redo" action:@selector(redo:) keyEquivalent:CPRedoKeyEquivalent];
-
- [undoMenuItem setKeyEquivalentModifierMask:CPUndoKeyEquivalentModifierMask];
- [redoMenuItem setKeyEquivalentModifierMask:CPRedoKeyEquivalentModifierMask];
-
- [editMenu addItem:undoMenuItem];
- [editMenu addItem:redoMenuItem];
-
- [editMenu addItem:[[CPMenuItem alloc] initWithTitle:@"Cut" action:@selector(cut:) keyEquivalent:@"x"]],
- [editMenu addItem:[[CPMenuItem alloc] initWithTitle:@"Copy" action:@selector(copy:) keyEquivalent:@"c"]],
- [editMenu addItem:[[CPMenuItem alloc] initWithTitle:@"Paste" action:@selector(paste:) keyEquivalent:@"v"]];
-
- [editMenuItem setSubmenu:editMenu];
- [editMenuItem setHidden:YES];
-
- [_mainMenu addItem:editMenuItem];
-
- [_mainMenu addItem:[CPMenuItem separatorItem]];
}
-
+
return self;
}
@@ -278,28 +223,28 @@ CPRunContinuesResponse = -1002;
// We also want to set the default cursor on the body, so that buttons and things don't have an iBeam
[[CPCursor arrowCursor] set];
-
+
var bundle = [CPBundle mainBundle],
types = [bundle objectForInfoDictionaryKey:@"CPBundleDocumentTypes"];
-
+
if ([types count] > 0)
_documentController = [CPDocumentController sharedDocumentController];
-
+
var delegateClassName = [bundle objectForInfoDictionaryKey:@"CPApplicationDelegateClass"];
-
+
if (delegateClassName)
{
var delegateClass = objj_getClass(delegateClassName);
-
+
if (delegateClass)
if ([_documentController class] == delegateClass)
[self setDelegate:_documentController];
else
[self setDelegate:[[delegateClass alloc] init]];
}
-
+
var defaultCenter = [CPNotificationCenter defaultCenter];
-
+
[defaultCenter
postNotificationName:CPApplicationWillFinishLaunchingNotification
object:self];
@@ -388,14 +333,14 @@ CPRunContinuesResponse = -1002;
versionLabel = [contentView viewWithTag:3],
copyrightLabel = [contentView viewWithTag:4],
standardPath = [[CPBundle bundleForClass:[self class]] pathForResource:@"standardApplicationIcon.png"];
-
+
// FIXME move this into the CIB eventually
[applicationLabel setFont:[CPFont boldSystemFontOfSize:14.0]];
[applicationLabel setAlignment:CPCenterTextAlignment];
[versionLabel setAlignment:CPCenterTextAlignment];
[copyrightLabel setAlignment:CPCenterTextAlignment];
- [imageView setImage:applicationIcon || [[CPImage alloc] initWithContentsOfFile:standardPath
+ [imageView setImage:applicationIcon || [[CPImage alloc] initWithContentsOfFile:standardPath
size:CGSizeMake(256, 256)]];
[applicationLabel setStringValue:applicationTitle || ""];
@@ -499,10 +444,10 @@ CPRunContinuesResponse = -1002;
return;
// raise exception;
}
-
+
_currentSession._state = aCode;
_currentSession = _currentSession._previous;
-
+
// if (aCode == CPRunAbortedResponse)
[self _removeRunModalLoop];
}
@@ -511,12 +456,12 @@ CPRunContinuesResponse = -1002;
- (void)_removeRunModalLoop
{
var count = _eventListeners.length;
-
+
while (count--)
if (_eventListeners[count]._callback === _CPRunModalLoop)
{
_eventListeners.splice(count, 1);
-
+
return;
}
}
@@ -554,12 +499,12 @@ CPRunContinuesResponse = -1002;
{
aModalSession._previous = _currentSession;
_currentSession = aModalSession;
-
+
var theWindow = aModalSession._window;
[theWindow center];
[theWindow makeKeyAndOrderFront:self];
-
+
// [theWindow._bridge _obscureWindowsBelowModalWindow];
[CPApp setCallback:_CPRunModalLoop forNextEventMatchingMask:CPAnyEventMask untilDate:nil inMode:0 dequeue:NO];
@@ -573,7 +518,7 @@ CPRunContinuesResponse = -1002;
{
if (!_currentSession)
return nil;
-
+
return _currentSession._window;
}
@@ -618,7 +563,7 @@ CPRunContinuesResponse = -1002;
{
if (_eventListeners[_eventListeners.length - 1]._mask & (1 << [anEvent type]))
_eventListeners.pop()._callback(anEvent);
-
+
return;
}
@@ -729,11 +674,11 @@ CPRunContinuesResponse = -1002;
if ([super tryToPerform:anAction with:anObject])
return YES;
-
+
if([_delegate respondsToSelector:anAction])
{
[_delegate performSelector:anAction withObject:anObject];
-
+
return YES;
}
@@ -753,9 +698,9 @@ CPRunContinuesResponse = -1002;
if (!target)
return NO;
-
+
[target performSelector:anAction withObject:aSender];
-
+
return YES;
}
@@ -774,10 +719,10 @@ CPRunContinuesResponse = -1002;
{
if (!anAction)
return nil;
-
+
if (aTarget)
return aTarget;
-
+
return [self targetForAction:anAction];
}
@@ -802,28 +747,28 @@ CPRunContinuesResponse = -1002;
{
var responder = [aWindow firstResponder],
checkWindow = YES;
-
+
while (responder)
{
if ([responder respondsToSelector:anAction])
return responder;
-
+
if (responder == aWindow)
checkWindow = NO;
-
+
responder = [responder nextResponder];
}
-
+
if (checkWindow && [aWindow respondsToSelector:anAction])
return aWindow;
-
+
var delegate = [aWindow delegate];
-
+
if ([delegate respondsToSelector:anAction])
return delegate;
var windowController = [aWindow windowController];
-
+
if ([windowController respondsToSelector:anAction])
return windowController;
@@ -852,26 +797,26 @@ CPRunContinuesResponse = -1002;
{
if (!anAction)
return nil;
-
+
var target = [self _targetForWindow:[self keyWindow] action:anAction];
-
+
if (target)
return target;
-
+
target = [self _targetForWindow:[self mainWindow] action:anAction];
-
+
if (target)
return target;
-
+
if ([self respondsToSelector:anAction])
return self;
-
+
if ([_delegate respondsToSelector:anAction])
return _delegate;
-
+
if ([_documentController respondsToSelector:anAction])
return _documentController;
-
+
return nil;
}
@@ -901,14 +846,14 @@ CPRunContinuesResponse = -1002;
@param aContextInfo
*/
- (void)beginSheet:(CPWindow)aSheet modalForWindow:(CPWindow)aWindow modalDelegate:(id)aModalDelegate didEndSelector:(SEL)aDidEndSelector contextInfo:(id)aContextInfo
-{
+{
var styleMask = [aSheet styleMask];
if (!(styleMask & CPDocModalWindowMask))
{
[CPException raise:CPInternalInconsistencyException reason:@"Currently only CPDocModalWindowMask style mask is supported for attached sheets"];
return;
}
-
+
[aWindow orderFront:self];
[aWindow _attachSheet:aSheet modalDelegate:aModalDelegate didEndSelector:aDidEndSelector contextInfo:aContextInfo];
}
@@ -916,15 +861,15 @@ CPRunContinuesResponse = -1002;
- (void)endSheet:(CPWindow)sheet returnCode:(int)returnCode
{
var count = [_windows count];
-
+
while (--count >= 0)
{
var aWindow = [_windows objectAtIndex:count];
var context = aWindow._sheetContext;
-
+
if (context != nil && context["sheet"] === sheet)
{
- context["returnCode"] = returnCode;
+ context["returnCode"] = returnCode;
[aWindow _detachSheetWindow];
return;
}
@@ -940,7 +885,7 @@ CPRunContinuesResponse = -1002;
{
if(_fullArgsString !== window.location.hash)
[self _reloadArguments];
-
+
return _args;
}
@@ -950,28 +895,28 @@ CPRunContinuesResponse = -1002;
{
_args = [];
window.location.hash = @"#";
-
+
return;
}
-
+
if([args class] != CPArray)
args = [CPArray arrayWithObject:args];
-
+
_args = args;
-
+
var toEncode = [_args copy];
for(var i=0, count = toEncode.length; i [self lastColumn] +1)
+ return [CPIndexSet indexSet];
+
return [[self tableViewInColumn:column] selectedRowIndexes];
}
@@ -551,8 +598,6 @@
[[self tableViewInColumn:column] selectRowIndexes:indexSet byExtendingSelection:NO];
- [self setNextResponder:[self tableViewInColumn:[self lastColumn]]];
-
[self scrollColumnToVisible:column];
if ([_delegate respondsToSelector:@selector(browserSelectionDidChange:)])
@@ -604,6 +649,8 @@
@end
+var _CPBrowserResizeControlBackgroundImage = nil;
+
@implementation _CPBrowserResizeControl : CPView
{
CGPoint _mouseDownX;
@@ -612,6 +659,26 @@
unsigned _width;
}
++ (CPImage)backgroundImage
+{
+ if (!_CPBrowserResizeControlBackgroundImage)
+ {
+ var path = [[CPBundle bundleForClass:[self class]] pathForResource:"browser-resize-control.png"];
+ _CPBrowserResizeControlBackgroundImage = [[CPImage alloc] initWithContentsOfFile:path
+ size:CGSizeMake(15, 14)];
+ }
+
+ return _CPBrowserResizeControlBackgroundImage;
+}
+
+- (id)initWithFrame:(CGRect)aFrame
+{
+ if (self = [super initWithFrame:aFrame])
+ [self setBackgroundColor:[CPColor colorWithPatternImage:[[self class] backgroundImage]]];
+
+ return self;
+}
+
- (void)mouseDown:(CPEvent)anEvent
{
_mouseDownX = [anEvent locationInWindow].x;
@@ -626,9 +693,11 @@
[_browser setWidth:_width + deltaX ofColumn:_index];
}
-@end
+- (void)mouseUp:(CPEvent)anEvent
+{
+}
-var _CPBrowserResizeControlBackgroundImage = nil;
+@end
@implementation _CPBrowserScrollView : CPScrollView
{
@@ -636,24 +705,11 @@ var _CPBrowserResizeControlBackgroundImage = nil;
CPBrowser _browser @accessors;
}
-+ (CPImage)backgroundImage
-{
- if (!_CPBrowserResizeControlBackgroundImage)
- {
- var path = [[CPBundle bundleForClass:[self class]] pathForResource:"browser-resize-control.png"];
- _CPBrowserResizeControlBackgroundImage = [[CPImage alloc] initWithContentsOfFile:path
- size:CGSizeMake(15, 14)];
- }
-
- return _CPBrowserResizeControlBackgroundImage;
-}
-
- (void)initWithFrame:(CGRect)aFrame
{
if (self = [super initWithFrame:aFrame])
{
_resizeControl = [[_CPBrowserResizeControl alloc] initWithFrame:CGRectMakeZero()];
- [_resizeControl setBackgroundColor:[CPColor colorWithPatternImage:[[self class] backgroundImage]]];
[self addSubview:_resizeControl];
}
diff --git a/AppKit/CPButton.j b/AppKit/CPButton.j
index 8a602a607..57a105bd5 100644
--- a/AppKit/CPButton.j
+++ b/AppKit/CPButton.j
@@ -74,7 +74,7 @@ CPChangeBackgroundCellMask = CPBackgroundButtonMask;
CPButtonStateMixed = CPThemeState("mixed");
-/*!
+/*!
@ingroup appkit
@class CPButton
@@ -85,10 +85,10 @@ CPButtonStateMixed = CPThemeState("mixed");
@implementation CPButton : CPControl
{
BOOL _allowsMixedState;
-
+
CPString _title;
CPString _alternateTitle;
-
+
CPImage _image;
CPImage _alternateImage;
@@ -131,7 +131,7 @@ CPButtonStateMixed = CPThemeState("mixed");
- (id)initWithFrame:(CGRect)aFrame
{
self = [super initWithFrame:aFrame];
-
+
if (self)
{
// Should we instead override the defaults?
@@ -139,13 +139,13 @@ CPButtonStateMixed = CPThemeState("mixed");
[self setValue:CPCenterVerticalTextAlignment forThemeAttribute:@"vertical-alignment"];
[self setValue:CPImageLeft forThemeAttribute:@"image-position"];
[self setValue:CPScaleNone forThemeAttribute:@"image-scaling"];
-
+
_controlSize = CPRegularControlSize;
-
+
// [self setBezelStyle:CPRoundRectBezelStyle];
[self setBordered:YES];
}
-
+
return self;
}
@@ -248,9 +248,9 @@ CPButtonStateMixed = CPThemeState("mixed");
{
if (_title === aTitle)
return;
-
+
_title = aTitle;
-
+
[self setNeedsLayout];
[self setNeedsDisplay:YES];
}
@@ -264,7 +264,7 @@ CPButtonStateMixed = CPThemeState("mixed");
{
if (_alternateTitle === aTitle)
return;
-
+
_alternateTitle = aTitle;
[self setNeedsLayout];
@@ -280,9 +280,9 @@ CPButtonStateMixed = CPThemeState("mixed");
{
if (_image === anImage)
return;
-
+
_image = anImage;
-
+
[self setNeedsLayout];
[self setNeedsDisplay:YES];
}
@@ -300,9 +300,9 @@ CPButtonStateMixed = CPThemeState("mixed");
{
if (_alternateImage === anImage)
return;
-
+
_alternateImage = anImage;
-
+
[self setNeedsLayout];
[self setNeedsDisplay:YES];
}
@@ -373,13 +373,13 @@ CPButtonStateMixed = CPThemeState("mixed");
[self setShowsStateBy:CPContentsCellMask];
break;
- case CPSwitchButton: [CPException raise:CPInvalidArgumentException
+ case CPSwitchButton: [CPException raise:CPInvalidArgumentException
reason:"The CPSwitchButton type is not supported in Cappuccino, use the CPCheckBox class instead."];
- case CPRadioButton: [CPException raise:CPInvalidArgumentException
+ case CPRadioButton: [CPException raise:CPInvalidArgumentException
reason:"The CPRadioButton type is not supported in Cappuccino, use the CPRadio class instead."];
- default: [CPException raise:CPInvalidArgumentException
+ default: [CPException raise:CPInvalidArgumentException
reason:"Unknown button type."];
}
@@ -395,7 +395,7 @@ CPButtonStateMixed = CPThemeState("mixed");
_imageDimsWhenDisabled = imageShouldDimWhenDisabled;
- if (_imageDimsWhenDisabled)
+ if ([self hasThemeState:CPThemeStateDisabled])
{
[self setNeedsDisplay:YES];
[self setNeedsLayout];
@@ -410,7 +410,7 @@ CPButtonStateMixed = CPThemeState("mixed");
- (BOOL)startTrackingAt:(CGPoint)aPoint
{
[self highlight:YES];
-
+
return [super startTrackingAt:aPoint];
}
@@ -435,7 +435,7 @@ CPButtonStateMixed = CPThemeState("mixed");
bounds.origin.y += contentInset.top;
bounds.size.width -= contentInset.left + contentInset.right;
bounds.size.height -= contentInset.top + contentInset.bottom;
-
+
return bounds;
}
@@ -483,10 +483,10 @@ CPButtonStateMixed = CPThemeState("mixed");
{
if (aName === "bezel-view")
return [self bezelRectForBounds:[self bounds]];
-
+
else if (aName === "content-view")
return [self contentRectForBounds:[self bounds]];
-
+
return [super rectForEphemeralSubviewNamed:aName];
}
@@ -497,7 +497,7 @@ CPButtonStateMixed = CPThemeState("mixed");
var view = [[CPView alloc] initWithFrame:_CGRectMakeZero()];
[view setHitTests:NO];
-
+
return view;
}
else
@@ -530,6 +530,7 @@ CPButtonStateMixed = CPThemeState("mixed");
[contentView setTextShadowOffset:[self currentValueForThemeAttribute:@"text-shadow-offset"]];
[contentView setImagePosition:[self currentValueForThemeAttribute:@"image-position"]];
[contentView setImageScaling:[self currentValueForThemeAttribute:@"image-scaling"]];
+ [contentView setDimsImage:[self hasThemeState:CPThemeStateDisabled] && _imageDimsWhenDisabled];
}
}
@@ -569,11 +570,12 @@ CPButtonStateMixed = CPThemeState("mixed");
@end
-var CPButtonImageKey = @"CPButtonImageKey",
- CPButtonAlternateImageKey = @"CPButtonAlternateImageKey",
- CPButtonTitleKey = @"CPButtonTitleKey",
- CPButtonAlternateTitleKey = @"CPButtonAlternateTitleKey",
- CPButtonIsBorderedKey = @"CPButtonIsBorderedKey";
+var CPButtonImageKey = @"CPButtonImageKey",
+ CPButtonAlternateImageKey = @"CPButtonAlternateImageKey",
+ CPButtonTitleKey = @"CPButtonTitleKey",
+ CPButtonAlternateTitleKey = @"CPButtonAlternateTitleKey",
+ CPButtonIsBorderedKey = @"CPButtonIsBorderedKey",
+ CPButtonImageDimsWhenDisabledKey = @"CPButtonImageDimsWhenDisabledKey";
@implementation CPButton (CPCoding)
@@ -584,21 +586,23 @@ var CPButtonImageKey = @"CPButtonImageKey",
- (id)initWithCoder:(CPCoder)aCoder
{
self = [super initWithCoder:aCoder];
-
+
if (self)
{
_controlSize = CPRegularControlSize;
[self setImage:[aCoder decodeObjectForKey:CPButtonImageKey]];
[self setAlternateImage:[aCoder decodeObjectForKey:CPButtonAlternateImageKey]];
-
+
[self setTitle:[aCoder decodeObjectForKey:CPButtonTitleKey]];
[self setAlternateTitle:[aCoder decodeObjectForKey:CPButtonAlternateTitleKey]];
-
+
+ [self setImageDimsWhenDisabled:[aCoder decodeObjectForKey:CPButtonImageDimsWhenDisabledKey]];
+
[self setNeedsLayout];
[self setNeedsDisplay:YES];
}
-
+
return self;
}
@@ -615,6 +619,8 @@ var CPButtonImageKey = @"CPButtonImageKey",
[aCoder encodeObject:_title forKey:CPButtonTitleKey];
[aCoder encodeObject:_alternateTitle forKey:CPButtonAlternateTitleKey];
+
+ [aCoder encodeObject:[self imageDimsWhenDisabled] forKey:CPButtonImageDimsWhenDisabledKey];
}
@end
diff --git a/AppKit/CPButtonBar.j b/AppKit/CPButtonBar.j
index daf2e9518..01aa1d833 100644
--- a/AppKit/CPButtonBar.j
+++ b/AppKit/CPButtonBar.j
@@ -14,8 +14,9 @@
+ (id)plusButton
{
var button = [[CPButton alloc] initWithFrame:CGRectMake(0, 0, 35, 25)],
- image = [[CPImage alloc] initWithContentsOfFile:[[CPBundle bundleForClass:self] pathForResource:@"plus_button.png"] size:CGSizeMake(11, 12)];
+ image = [[CPImage alloc] initWithContentsOfFile:[[CPBundle bundleForClass:[CPButtonBar class]] pathForResource:@"plus_button.png"] size:CGSizeMake(11, 12)];
+ [button setBordered:NO];
[button setImage:image];
[button setImagePosition:CPImageOnly];
@@ -25,14 +26,30 @@
+ (id)minusButton
{
var button = [[CPButton alloc] initWithFrame:CGRectMake(0, 0, 35, 25)],
- image = [[CPImage alloc] initWithContentsOfFile:[[CPBundle bundleForClass:self] pathForResource:@"minus_button.png"] size:CGSizeMake(11, 4)];
+ image = [[CPImage alloc] initWithContentsOfFile:[[CPBundle bundleForClass:[CPButtonBar class]] pathForResource:@"minus_button.png"] size:CGSizeMake(11, 4)];
+ [button setBordered:NO];
[button setImage:image];
[button setImagePosition:CPImageOnly];
return button;
}
++ (id)actionPopupButton
+{
+ var button = [[CPPopUpButton alloc] initWithFrame:CGRectMake(0, 0, 35, 25)],
+ image = [[CPImage alloc] initWithContentsOfFile:[[CPBundle bundleForClass:[CPButtonBar class]] pathForResource:@"action_button.png"] size:CGSizeMake(22, 14)];
+
+ [button addItemWithTitle:nil];
+ [[button lastItem] setImage:image];
+ [button setImagePosition:CPImageOnly];
+ [button setValue:CGInsetMake(0, 0, 0, 0) forThemeAttribute:"content-inset"];
+
+ [button setPullsDown:YES];
+
+ return button;
+}
+
+ (CPString)themeClass
{
return @"button-bar";
@@ -40,8 +57,8 @@
+ (id)themeAttributes
{
- return [CPDictionary dictionaryWithObjects:[CGInsetMake(0.0, 0.0, 0.0, 0.0), CGSizeMakeZero(), [CPNull null], [CPNull null], [CPNull null]]
- forKeys:[@"resize-control-inset", @"resize-control-size", @"resize-control-color", @"bezel-color", @"button-bezel-color"]];
+ return [CPDictionary dictionaryWithObjects:[CGInsetMake(0.0, 0.0, 0.0, 0.0), CGSizeMakeZero(), [CPNull null], [CPNull null], [CPNull null], [CPNull null]]
+ forKeys:[@"resize-control-inset", @"resize-control-size", @"resize-control-color", @"bezel-color", @"button-bezel-color", @"button-text-color"]];
}
- (id)initWithFrame:(CGRect)aFrame
@@ -82,25 +99,8 @@
_buttons = [CPArray arrayWithArray:buttons];
for (var i = 0, count = [_buttons count]; i < count; i++)
- {
- var button = _buttons[i];
+ [_buttons[i] setBordered:YES];
- var normalColor = [self valueForThemeAttribute:@"button-bezel-color" inState:CPThemeStateNormal],
- highlightedColor = [self valueForThemeAttribute:@"button-bezel-color" inState:CPThemeStateHighlighted],
- disabledColor = [self valueForThemeAttribute:@"button-bezel-color" inState:CPThemeStateDisabled];
-
- [button setValue:normalColor forThemeAttribute:@"bezel-color" inState:CPThemeStateNormal|CPThemeStateBordered];
- [button setValue:highlightedColor forThemeAttribute:@"bezel-color" inState:CPThemeStateHighlighted|CPThemeStateBordered];
- [button setValue:disabledColor forThemeAttribute:@"bezel-color" inState:CPThemeStateDisabled|CPThemeStateBordered];
-
- // FIXME shouldn't need this
- [button setValue:normalColor forThemeAttribute:@"bezel-color" inState:CPThemeStateNormal|CPThemeStateBordered|CPPopUpButtonStatePullsDown];
- [button setValue:highlightedColor forThemeAttribute:@"bezel-color" inState:CPThemeStateHighlighted|CPThemeStateBordered|CPPopUpButtonStatePullsDown];
- [button setValue:disabledColor forThemeAttribute:@"bezel-color" inState:CPThemeStateDisabled|CPThemeStateBordered|CPPopUpButtonStatePullsDown];
-
- [button setBordered:YES];
- }
-
[self setNeedsLayout];
}
@@ -176,6 +176,11 @@
{
[self setBackgroundColor:[self currentValueForThemeAttribute:@"bezel-color"]];
+ var normalColor = [self valueForThemeAttribute:@"button-bezel-color" inState:CPThemeStateNormal],
+ highlightedColor = [self valueForThemeAttribute:@"button-bezel-color" inState:CPThemeStateHighlighted],
+ disabledColor = [self valueForThemeAttribute:@"button-bezel-color" inState:CPThemeStateDisabled],
+ textColor = [self valueForThemeAttribute:@"button-text-color" inState:CPThemeStateNormal];
+
var buttonsNotHidden = [CPArray arrayWithArray:_buttons],
count = [buttonsNotHidden count];
@@ -184,13 +189,23 @@
[buttonsNotHidden removeObject:buttonsNotHidden[count]];
var currentButtonOffset = _resizeControlIsLeftAligned ? CGRectGetMaxX([self bounds]) + 1 : -1,
- height = CGRectGetHeight([self bounds]) - 1;
+ bounds = [self bounds],
+ height = CGRectGetHeight(bounds) - 1,
+ frameWidth = CGRectGetWidth(bounds),
+ resizeRect = _hasResizeControl ? [self rectForEphemeralSubviewNamed:"resize-control-view"] : CGRectMakeZero(),
+ resizeWidth = CGRectGetWidth(resizeRect),
+ availableWidth = frameWidth - resizeWidth - 1;
for (var i = 0, count = [buttonsNotHidden count]; i < count; i++)
{
var button = buttonsNotHidden[i],
width = CGRectGetWidth([button frame]);
+ if (availableWidth > width)
+ availableWidth -=width;
+ else
+ break;
+
if (_resizeControlIsLeftAligned)
{
[button setFrame:CGRectMake(currentButtonOffset - width, 1, width, height)];
@@ -202,6 +217,16 @@
currentButtonOffset += width - 1;
}
+ [button setValue:normalColor forThemeAttribute:@"bezel-color" inState:CPThemeStateNormal|CPThemeStateBordered];
+ [button setValue:highlightedColor forThemeAttribute:@"bezel-color" inState:CPThemeStateHighlighted|CPThemeStateBordered];
+ [button setValue:disabledColor forThemeAttribute:@"bezel-color" inState:CPThemeStateDisabled|CPThemeStateBordered];
+ [button setValue:textColor forThemeAttribute:@"text-color" inState:CPThemeStateBordered];
+
+ // FIXME shouldn't need this
+ [button setValue:normalColor forThemeAttribute:@"bezel-color" inState:CPThemeStateNormal|CPThemeStateBordered|CPPopUpButtonStatePullsDown];
+ [button setValue:highlightedColor forThemeAttribute:@"bezel-color" inState:CPThemeStateHighlighted|CPThemeStateBordered|CPPopUpButtonStatePullsDown];
+ [button setValue:disabledColor forThemeAttribute:@"bezel-color" inState:CPThemeStateDisabled|CPThemeStateBordered|CPPopUpButtonStatePullsDown];
+
[self addSubview:button];
}
@@ -216,6 +241,12 @@
}
}
+- (void)setFrameSize:(CGSize)aSize
+{
+ [super setFrameSize:aSize];
+ [self setNeedsLayout];
+}
+
@end
var CPButtonBarHasResizeControlKey = @"CPButtonBarHasResizeControlKey",
@@ -246,4 +277,3 @@ var CPButtonBarHasResizeControlKey = @"CPButtonBarHasResizeControlKey",
}
@end
-
diff --git a/AppKit/CPCheckBox.j b/AppKit/CPCheckBox.j
index 2c2852883..eec4de33b 100644
--- a/AppKit/CPCheckBox.j
+++ b/AppKit/CPCheckBox.j
@@ -61,4 +61,27 @@
return self;
}
+- (void)takeStateFromKeyPath:(CPString)aKeyPath ofObjects:(CPArray)objects
+{
+ var count = objects.length,
+ value = [objects[0] valueForKeyPath:aKeyPath] ? CPOnState : CPOffState;
+
+ [self setAllowsMixedState:NO];
+ [self setState:value];
+
+ while (count-- > 1)
+ {
+ if (value !== ([objects[count] valueForKeyPath:aKeyPath] ? CPOnState : CPOffState))
+ {
+ [self setAllowsMixedState:YES];
+ [self setState:CPMixedState];
+ }
+ }
+}
+
+- (void)takeValueFromKeyPath:(CPString)aKeyPath ofObjects:(CPArray)objects
+{
+ [self takeStateFromKeyPath:aKeyPath ofObjects:objects];
+}
+
@end
diff --git a/AppKit/CPClipView.j b/AppKit/CPClipView.j
index f1dc67e10..16eabd711 100644
--- a/AppKit/CPClipView.j
+++ b/AppKit/CPClipView.j
@@ -190,17 +190,39 @@
- (BOOL)autoscroll:(CPEvent)anEvent
{
var bounds = [self bounds],
- eventLocation = [self convertPoint:[anEvent locationInWindow] fromView:nil];
+ eventLocation = [self convertPoint:[anEvent locationInWindow] fromView:nil],
+ superview = [self superview],
+ deltaX = 0,
+ deltaY = 0;
- if (CPRectContainsPoint(bounds, eventLocation))
+ if (CGRectContainsPoint(bounds, eventLocation))
return NO;
- var newRect = CGRectMakeZero();
+ if (![superview isKindOfClass:[CPScrollView class]] || [superview hasVerticalScroller])
+ {
+ if (eventLocation.y < CGRectGetMinY(bounds))
+ deltaY = CGRectGetMinY(bounds) - eventLocation.y;
+ else if (eventLocation.y > CGRectGetMaxY(bounds))
+ deltaY = CGRectGetMaxY(bounds) - eventLocation.y;
+ if (deltaY < -bounds.size.height)
+ deltaY = -bounds.size.height;
+ if (deltaY > bounds.size.height)
+ deltaY = bounds.size.height;
+ }
- newRect.origin = eventLocation;
- newRect.size = CPSizeMake(10, 10);
+ if (![superview isKindOfClass:[CPScrollView class]] || [superview hasHorizontalScroller])
+ {
+ if (eventLocation.x < CGRectGetMinX(bounds))
+ deltaX = CGRectGetMinX(bounds) - eventLocation.x;
+ else if (eventLocation.x > CGRectGetMaxX(bounds))
+ deltaX = CGRectGetMaxX(bounds) - eventLocation.x;
+ if (deltaX < -bounds.size.width)
+ deltaX = -bounds.size.width;
+ if (deltaX > bounds.size.width)
+ deltaX = bounds.size.width;
+ }
- return [_documentView scrollRectToVisible:newRect];
+ return [self scrollToPoint:CGPointMake(bounds.origin.x - deltaX, bounds.origin.y - deltaY)];
}
@end
diff --git a/AppKit/CPCollectionView.j b/AppKit/CPCollectionView.j
index cf91c32cd..77c4ca4d6 100644
--- a/AppKit/CPCollectionView.j
+++ b/AppKit/CPCollectionView.j
@@ -30,16 +30,16 @@
@import "CPCollectionViewItem.j"
-/*!
+/*!
@ingroup appkit
@class CPCollectionView
- This class displays an array as a grid of objects, where each object is represented by a view.
- The view is controlled by creating a CPCollectionViewItem and specifying its view, then
+ This class displays an array as a grid of objects, where each object is represented by a view.
+ The view is controlled by creating a CPCollectionViewItem and specifying its view, then
setting that item as the collection view prototype.
-
+
@par Delegate Methods
-
+
@delegate -(void)collectionViewDidChangeSelection:(CPCollectionView)collectionView;
Called when the selection in the collection view has changed.
@param collectionView the collection view who's selection changed
@@ -67,35 +67,35 @@
{
CPArray _content;
CPArray _items;
-
+
CPData _itemData;
CPCollectionViewItem _itemPrototype;
CPCollectionViewItem _itemForDragging;
CPMutableArray _cachedItems;
-
+
unsigned _maxNumberOfRows;
unsigned _maxNumberOfColumns;
-
+
CGSize _minItemSize;
CGSize _maxItemSize;
CPArray _backgroundColors;
float _tileWidth;
-
+
BOOL _isSelectable;
BOOL _allowsMultipleSelection;
BOOL _allowsEmptySelection;
CPIndexSet _selectionIndexes;
-
+
CGSize _itemSize;
-
+
float _horizontalMargin;
float _verticalMargin;
-
+
unsigned _numberOfRows;
unsigned _numberOfColumns;
-
+
id _delegate;
CPEvent _mouseDownEvent;
@@ -104,14 +104,14 @@
- (id)initWithFrame:(CGRect)aFrame
{
self = [super initWithFrame:aFrame];
-
+
if (self)
{
_items = [];
_content = [];
-
+
_cachedItems = [];
-
+
_itemSize = CGSizeMakeZero();
_minItemSize = CGSizeMakeZero();
_maxItemSize = CGSizeMakeZero();
@@ -120,12 +120,12 @@
_verticalMargin = 5.0;
_tileWidth = -1.0;
-
+
_selectionIndexes = [CPIndexSet indexSet];
_allowsEmptySelection = YES;
_isSelectable = YES;
}
-
+
return self;
}
@@ -196,8 +196,8 @@
// Setting the Content
/*!
- Sets the content of the collection view to the content in \c anArray.
- This array can be of any type, and each element will be passed to the \c -setRepresentedObject: method.
+ Sets the content of the collection view to the content in \c anArray.
+ This array can be of any type, and each element will be passed to the \c -setRepresentedObject: method.
It's the responsibility of your custom collection view item to interpret the object.
@param anArray the content array
*/
@@ -205,9 +205,9 @@
{
if (_content == anArray)
return;
-
+
_content = anArray;
-
+
[self reloadContent];
}
@@ -236,13 +236,13 @@
{
if (_isSelectable == isSelectable)
return;
-
+
_isSelectable = isSelectable;
-
+
if (!_isSelectable)
{
var index = CPNotFound;
-
+
while ((index = [_selectionIndexes indexGreaterThanIndex:index]) != CPNotFound)
[_items[index] setSelected:NO];
}
@@ -299,19 +299,19 @@
{
if (_selectionIndexes == anIndexSet || !_isSelectable)
return;
-
+
var index = CPNotFound;
-
+
while ((index = [_selectionIndexes indexGreaterThanIndex:index]) != CPNotFound)
[_items[index] setSelected:NO];
-
+
_selectionIndexes = anIndexSet;
-
+
var index = CPNotFound;
-
+
while ((index = [_selectionIndexes indexGreaterThanIndex:index]) != CPNotFound)
[_items[index] setSelected:YES];
-
+
if ([_delegate respondsToSelector:@selector(collectionViewDidChangeSelection:)])
[_delegate collectionViewDidChangeSelection:self]
}
@@ -326,10 +326,10 @@
/* @ignore */
- (void)reloadContent
-{
+{
// Remove current views
var count = _items.length;
-
+
while (count--)
{
[[_items[count] view] removeFromSuperview];
@@ -337,7 +337,7 @@
_cachedItems.push(_items[count]);
}
-
+
_items = [];
if (!_itemPrototype || !_content)
@@ -350,7 +350,7 @@
for (; index < count; ++index)
{
_items.push([self newItemForRepresentedObject:_content[index]]);
-
+
[self addSubview:[_items[index] view]];
}
@@ -365,49 +365,49 @@
- (void)tile
{
var width = CGRectGetWidth([self bounds]);
-
+
if (![_content count] || width == _tileWidth)
return;
-
- // We try to fit as many views per row as possible. Any remaining space is then
+
+ // 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);
-
+
_numberOfColumns = MAX(1.0, FLOOR(width / itemSize.width));
-
+
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)
@@ -415,19 +415,28 @@
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, y + itemSize.height + _verticalMargin)];
+ [self setFrameSize:CGSizeMake(width, proposedHeight)];
_tileWidth = -1.0;
}
@@ -445,9 +454,9 @@
{
if (_maxNumberOfRows == aMaxNumberOfRows)
return;
-
+
_maxNumberOfRows = aMaxNumberOfRows;
-
+
[self tile];
}
@@ -467,9 +476,9 @@
{
if (_maxNumberOfColumns == aMaxNumberOfColumns)
return;
-
+
_maxNumberOfColumns = aMaxNumberOfColumns;
-
+
[self tile];
}
@@ -506,9 +515,9 @@
{
if (CGSizeEqualToSize(_minItemSize, aSize))
return;
-
+
_minItemSize = CGSizeMakeCopy(aSize);
-
+
[self tile];
}
@@ -528,9 +537,9 @@
{
if (CGSizeEqualToSize(_maxItemSize, aSize))
return;
-
+
_maxItemSize = CGSizeMakeCopy(aSize);
-
+
[self tile];
}
@@ -590,6 +599,14 @@
- (void)mouseDragged:(CPEvent)anEvent
{
+ 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;
@@ -648,9 +665,9 @@
{
if (_verticalMargin == aVerticalMargin)
return;
-
+
_verticalMargin = aVerticalMargin;
-
+
[self tile];
}
@@ -701,7 +718,7 @@
count = [indexArray count];
for (; index < count; ++index)
- frame = CGRectUnion(frame, [self rectForItemAtIndex:indexArray[index]]);
+ frame = CGRectUnion(frame, [self frameForItemAtIndex:indexArray[index]]);
return frame;
}
@@ -721,7 +738,7 @@
- (void)moveLeft:(id)sender
{
var index = [[self selectionIndexes] firstIndex];
- if (index === CPNotFound)
+ if (index === CPNotFound)
index = [[self items] count];
index = MAX(index - 1, 0);
@@ -749,7 +766,7 @@
- (void)moveUp:(id)sender
{
var index = [[self selectionIndexes] firstIndex];
- if (index == CPNotFound)
+ if (index == CPNotFound)
index = [[self items] count];
index = MAX(0, index - [self numberOfColumns]);
@@ -821,20 +838,20 @@ var CPCollectionViewMinItemSizeKey = @"CPCollectionViewMinItemSizeKey",
_cachedItems = [];
_itemSize = CGSizeMakeZero();
-
+
_minItemSize = [aCoder decodeSizeForKey:CPCollectionViewMinItemSizeKey] || CGSizeMakeZero();
_maxItemSize = [aCoder decodeSizeForKey:CPCollectionViewMaxItemSizeKey] || CGSizeMakeZero();
-
+
_verticalMargin = [aCoder decodeFloatForKey:CPCollectionViewVerticalMarginKey];
-
+
_isSelectable = [aCoder decodeBoolForKey:CPCollectionViewSelectableKey];
[self setBackgroundColors:[aCoder decodeObjectForKey:CPCollectionViewBackgroundColorsKey]];
-
+
_tileWidth = -1.0;
_selectionIndexes = [CPIndexSet indexSet];
-
+
_allowsEmptySelection = YES;
}
@@ -847,12 +864,12 @@ var CPCollectionViewMinItemSizeKey = @"CPCollectionViewMinItemSizeKey",
if (!CGSizeEqualToSize(_minItemSize, CGSizeMakeZero()))
[aCoder encodeSize:_minItemSize forKey:CPCollectionViewMinItemSizeKey];
-
+
if (!CGSizeEqualToSize(_maxItemSize, CGSizeMakeZero()))
[aCoder encodeSize:_maxItemSize forKey:CPCollectionViewMaxItemSizeKey];
-
+
[aCoder encodeBool:_isSelectable forKey:CPCollectionViewSelectableKey];
-
+
[aCoder encodeFloat:_verticalMargin forKey:CPCollectionViewVerticalMarginKey];
[aCoder encodeObject:_backgroundColors forKey:CPCollectionViewBackgroundColorsKey];
diff --git a/AppKit/CPColorWell.j b/AppKit/CPColorWell.j
index 2c2586821..040e5c548 100644
--- a/AppKit/CPColorWell.j
+++ b/AppKit/CPColorWell.j
@@ -231,11 +231,17 @@ var _CPColorWellDidBecomeExclusiveNotification = @"_CPColorWellDidBecomeExclusiv
- (void)mouseDown:(CPEvent)anEvent
{
+ if (![self isEnabled])
+ return;
+
[self drawBezelWithHighlight:YES];
}
- (void)mouseDragged:(CPEvent)anEvent
{
+ if (![self isEnabled])
+ return;
+
[self drawBezelWithHighlight:CGRectContainsPoint([self bounds], [self convertPoint:[anEvent locationInWindow] fromView:nil])];
}
@@ -243,7 +249,7 @@ var _CPColorWellDidBecomeExclusiveNotification = @"_CPColorWellDidBecomeExclusiv
{
[self drawBezelWithHighlight:NO];
- if (!CGRectContainsPoint([self bounds], [self convertPoint:[anEvent locationInWindow] fromView:nil]))
+ if (!CGRectContainsPoint([self bounds], [self convertPoint:[anEvent locationInWindow] fromView:nil]) || ![self isEnabled])
return;
[self activate:YES];
diff --git a/AppKit/CPCursor.j b/AppKit/CPCursor.j
index 95b1dc79a..45b3f1ab8 100755
--- a/AppKit/CPCursor.j
+++ b/AppKit/CPCursor.j
@@ -167,7 +167,9 @@ var currentCursor = nil,
{
if (CPBrowserIsEngine(CPWebKitBrowserEngine))
return [CPCursor cursorWithCSSString:@"-webkit-grab"];
- else if (CPBrowserIsEngine(CPGeckoBrowserEngine) || CPBrowserIsEngine(CPOperaBrowserEngine))
+ else if (CPBrowserIsEngine(CPGeckoBrowserEngine))
+ return [CPCursor cursorWithCSSString:@"-moz-grab"];
+ else if (CPBrowserIsEngine(CPOperaBrowserEngine))
return [CPCursor cursorWithCSSString:@"move"];
return [CPCursor cursorWithImageNamed:CPStringFromSelector(_cmd)]; // WebKit only. move in FFMac|Opera
@@ -177,8 +179,10 @@ var currentCursor = nil,
{
if (CPBrowserIsEngine(CPWebKitBrowserEngine))
return [CPCursor cursorWithCSSString:@"-webkit-grabbing"];
+ else if (CPBrowserIsEngine(CPGeckoBrowserEngine))
+ return [CPCursor cursorWithCSSString:@"-moz-grabbing"];
- return [CPCursor cursorWithImageNamed:CPStringFromSelector(_cmd)]; // WebKit only
+ return [CPCursor cursorWithImageNamed:CPStringFromSelector(_cmd)]; // WebKit || FF
}
+ (CPCursor)disappearingItemCursor
diff --git a/AppKit/CPDragServer.j b/AppKit/CPDragServer.j
index 06f8d2435..9469f331f 100644
--- a/AppKit/CPDragServer.j
+++ b/AppKit/CPDragServer.j
@@ -40,29 +40,10 @@ CPDragOperationEvery = -1;
#define DRAGGING_WINDOW(anObject) ([anObject isKindOfClass:[CPWindow class]] ? anObject : [anObject window])
-var CPDragServerPreviousEvent = nil,
-CPDragServerAutoscrollInterval = nil;
-/*
-var CPDragServerAutoscroll = function()
-{
- [CPDragServerSource autoscroll:CPDragServerPreviousEvent];
-}
+var CPDragServerPreviousEvent = nil,
+ CPDragServerPeriodicUpdateInterval = 0.05;
- if (CPDragServerAutoscrollInterval === nil)
- {
- if ([CPDragServerSource respondsToSelector:@selector(autoscroll:)])
- CPDragServerAutoscrollInterval = setInterval(CPDragServerAutoscroll, 100);
- }
-
- CPDragServerPreviousEvent = anEvent;
-
- if (CPDragServerAutoscrollInterval !== nil)
- clearInterval(CPDragServerAutoscrollInterval);
-
- CPDragServerAutoscrollInterval = nil;
-*/
-
-var CPSharedDragServer = nil;
+var CPSharedDragServer = nil;
var CPDragServerSource = nil;
var CPDragServerDraggingInfo = nil;
@@ -150,10 +131,13 @@ var CPDraggingSource_draggedImage_movedTo_ = 1 << 0,
CGPoint _draggingLocation;
id _draggingDestination;
+ BOOL _draggingDestinationWantsPeriodicUpdates;
CGPoint _startDragLocation;
BOOL _shouldSlideBack;
unsigned _dragOperation;
+
+ CPTimer _draggingUpdateTimer;
}
/*
@@ -234,6 +218,9 @@ var CPDraggingSource_draggedImage_movedTo_ = 1 << 0,
- (CPDragOperation)draggingUpdatedInPlatformWindow:(CPPlatformWindow)aPlatformWindow location:(CGPoint)aLocation
{
+ [_draggingUpdateTimer invalidate];
+ _draggingUpdateTimer = nil;
+
var dragOperation = CPDragOperationCopy;
// We have to convert base to bridge since the drag event comes from the source window, not the drag window.
var draggingDestination = [aPlatformWindow _dragHitTest:aLocation pasteboard:[CPDragServerDraggingInfo draggingPasteboard]];
@@ -243,25 +230,89 @@ var CPDraggingSource_draggedImage_movedTo_ = 1 << 0,
if(draggingDestination !== _draggingDestination)
{
- if (_draggingDestination && [_draggingDestination respondsToSelector:@selector(draggingExited:)])
+ if ([_draggingDestination respondsToSelector:@selector(draggingExited:)])
[_draggingDestination draggingExited:CPDragServerDraggingInfo];
_draggingDestination = draggingDestination;
- if (_draggingDestination && [_draggingDestination respondsToSelector:@selector(draggingEntered:)])
+ if ([_draggingDestination respondsToSelector:@selector(wantsPeriodicDraggingUpdates)])
+ _draggingDestinationWantsPeriodicUpdates = [_draggingDestination wantsPeriodicDraggingUpdates];
+ else
+ _draggingDestinationWantsPeriodicUpdates = YES;
+
+ if ([_draggingDestination respondsToSelector:@selector(draggingEntered:)])
dragOperation = [_draggingDestination draggingEntered:CPDragServerDraggingInfo];
}
- else if (_draggingDestination && [_draggingDestination respondsToSelector:@selector(draggingUpdated:)])
+ else if ([_draggingDestination respondsToSelector:@selector(draggingUpdated:)])
dragOperation = [_draggingDestination draggingUpdated:CPDragServerDraggingInfo];
if (!_draggingDestination)
dragOperation = CPDragOperationNone;
+ else
+ {
+ if (_draggingDestinationWantsPeriodicUpdates)
+ _draggingUpdateTimer = [CPTimer scheduledTimerWithTimeInterval:CPDragServerPeriodicUpdateInterval
+ target:self
+ selector:@selector(_sendPeriodicDraggingUpdate:)
+ userInfo:[CPDictionary dictionaryWithJSObject:{platformWindow:aPlatformWindow, location:aLocation}]
+ repeats:NO];
+
+ var scrollView = [_draggingDestination isKindOfClass:[CPView class]] ? [_draggingDestination enclosingScrollView] : nil;
+ if (scrollView)
+ {
+ var contentView = [scrollView contentView],
+ bounds = [contentView bounds],
+ insetBounds = CGRectInset(bounds, 10, 10)
+ eventLocation = [contentView convertPoint:_draggingLocation fromView:nil],
+ deltaX = 0,
+ deltaY = 0;
+
+ if (!CGRectContainsPoint(insetBounds, eventLocation))
+ {
+ if ([scrollView hasVerticalScroller])
+ {
+ if (eventLocation.y < CGRectGetMinY(insetBounds))
+ deltaY = CGRectGetMinY(insetBounds) - eventLocation.y;
+ else if (eventLocation.y > CGRectGetMaxY(insetBounds))
+ deltaY = CGRectGetMaxY(insetBounds) - eventLocation.y;
+ if (deltaY < -insetBounds.size.height)
+ deltaY = -insetBounds.size.height;
+ if (deltaY > insetBounds.size.height)
+ deltaY = insetBounds.size.height;
+ }
+
+ if ([scrollView hasHorizontalScroller])
+ {
+ if (eventLocation.x < CGRectGetMinX(insetBounds))
+ deltaX = CGRectGetMinX(insetBounds) - eventLocation.x;
+ else if (eventLocation.x > CGRectGetMaxX(insetBounds))
+ deltaX = CGRectGetMaxX(insetBounds) - eventLocation.x;
+ if (deltaX < -insetBounds.size.width)
+ deltaX = -insetBounds.size.width;
+ if (deltaX > insetBounds.size.width)
+ deltaX = insetBounds.size.width;
+ }
+
+ [contentView scrollToPoint:CGPointMake(bounds.origin.x - deltaX, bounds.origin.y - deltaY)];
+ }
+ }
+ }
return dragOperation;
}
+- (void)_sendPeriodicDraggingUpdate:(CPTimer)aTimer
+{
+ var userInfo = [aTimer userInfo];
+ _dragOperation = [self draggingUpdatedInPlatformWindow:[userInfo objectForKey:@"platformWindow"]
+ location:[userInfo objectForKey:@"location"]];
+}
+
- (void)draggingEndedInPlatformWindow:(CPPlatformWindow)aPlatformWindow globalLocation:(CGPoint)aLocation operation:(CPDragOperation)anOperation
{
+ [_draggingUpdateTimer invalidate];
+ _draggingUpdateTimer = nil;
+
[_draggedView removeFromSuperview];
if (![CPPlatform supportsDragAndDrop])
@@ -404,13 +455,25 @@ var CPDraggingSource_draggedImage_movedTo_ = 1 << 0,
// Stop tracking events.
return;
}
-
- [self draggingSourceUpdatedWithGlobalLocation:platformWindowLocation];
- _dragOperation = [self draggingUpdatedInPlatformWindow:platformWindow location:platformWindowLocation];
+ else if (type === CPKeyDown)
+ {
+ var keyCode = [anEvent keyCode];
+ if (keyCode === CPEscapeKeyCode)
+ {
+ _dragOperation = CPDragOperationNone;
+ [self draggingEndedInPlatformWindow:platformWindow globalLocation:CGPointMakeZero() operation:_dragOperation];
+ return;
+ }
+ }
+ else
+ {
+ [self draggingSourceUpdatedWithGlobalLocation:platformWindowLocation];
+ _dragOperation = [self draggingUpdatedInPlatformWindow:platformWindow location:platformWindowLocation];
+ }
// If we're not a mouse up, then we're going to want to grab the next event.
[CPApp setTarget:self selector:@selector(trackDragging:)
- forNextEventMatchingMask:CPMouseMovedMask | CPLeftMouseDraggedMask | CPLeftMouseUpMask
+ forNextEventMatchingMask:CPMouseMovedMask | CPLeftMouseDraggedMask | CPLeftMouseUpMask | CPKeyDownMask
untilDate:nil inMode:0 dequeue:NO];
}
diff --git a/AppKit/CPImageView.j b/AppKit/CPImageView.j
index 234f74ceb..7d365f71f 100644
--- a/AppKit/CPImageView.j
+++ b/AppKit/CPImageView.j
@@ -365,7 +365,7 @@ var LEFT_SHADOW_INSET = 3.0,
return _isEditable;
}
-- (void)performDragOperation:(CPDraggingInfo)aSender
+- (BOOL)performDragOperation:(CPDraggingInfo)aSender
{
var images = [CPKeyedUnarchiver unarchiveObjectWithData:[[aSender draggingPasteboard] dataForType:CPImagesPboardType]];
@@ -374,6 +374,8 @@ var LEFT_SHADOW_INSET = 3.0,
[self setImage:images[0]];
[self sendAction:[self action] to:[self target]];
}
+
+ return YES;
}
@end
diff --git a/AppKit/CPMenu/CPMenu.j b/AppKit/CPMenu/CPMenu.j
index 1116437b7..687fb7045 100644
--- a/AppKit/CPMenu/CPMenu.j
+++ b/AppKit/CPMenu/CPMenu.j
@@ -747,6 +747,9 @@ var _CPMenuBarVisible = NO,
}
// Show it.
+ if ([CPPlatform isBrowser])
+ [menuWindow setPlatformWindow:[[aView window] platformWindow]];
+
[menuWindow orderFront:self];
// Track it.
@@ -816,6 +819,9 @@ var _CPMenuBarVisible = NO,
[menuWindow setFrameOrigin:CGRectIntersection(unconstrainedFrame, constraintRect).origin];
}
+ if ([CPPlatform isBrowser])
+ [menuWindow setPlatformWindow:[[aView window] platformWindow]];
+
[menuWindow orderFront:self];
[[_CPMenuManager sharedMenuManager]
diff --git a/AppKit/CPOutlineView.j b/AppKit/CPOutlineView.j
index 6711eba89..df90c688d 100644
--- a/AppKit/CPOutlineView.j
+++ b/AppKit/CPOutlineView.j
@@ -85,6 +85,8 @@ CPOutlineViewDropOnItemIndex = -1;
BOOL _shouldRetargetChildIndex;
CPInteger _retargedChildIndex;
+ CPTimer _dragHoverTimer;
+ id _dropItem;
}
- (id)initWithFrame:(CGRect)aFrame
@@ -108,6 +110,7 @@ CPOutlineViewDropOnItemIndex = -1;
_retargedChildIndex = nil;
_shouldRetargetChildIndex = NO;
+ _startHoverTime = nil;
[self setIndentationPerLevel:16.0];
[self setIndentationMarkerFollowsDataView:YES];
@@ -213,7 +216,7 @@ CPOutlineViewDropOnItemIndex = -1;
- (void)expandItem:(id)anItem expandChildren:(BOOL)shouldExpandChildren
{
var itemInfo = null;
-
+
if (!anItem)
itemInfo = _rootItemInfo;
else
@@ -221,10 +224,16 @@ CPOutlineViewDropOnItemIndex = -1;
if (!itemInfo)
return;
-
- itemInfo.isExpanded = YES;
- [self reloadItem:anItem reloadChildren:YES];
-
+
+ // to prevent items which are already expanded from firing notifications
+ if (!itemInfo.isExpanded)
+ {
+ [self _noteItemWillExpand:anItem];
+ itemInfo.isExpanded = YES;
+ [self _noteItemDidExpand:anItem];
+ [self reloadItem:anItem reloadChildren:YES];
+ }
+
if (shouldExpandChildren)
{
var children = itemInfo.children,
@@ -248,7 +257,9 @@ CPOutlineViewDropOnItemIndex = -1;
if (!itemInfo.isExpanded)
return;
+ [self _noteItemWillCollapse:anItem];
itemInfo.isExpanded = NO;
+ [self _noteItemDidCollapse:anItem];
[self reloadItem:anItem reloadChildren:YES];
}
@@ -382,43 +393,14 @@ CPOutlineViewDropOnItemIndex = -1;
return frame;
}
-- (void)selectRowIndexes:(CPIndexSet)rows byExtendingSelection:(BOOL)shouldExtendSelection
+- (void)_performSelection:(BOOL)select forRow:(CPInteger)rowIndex context:(id)context
{
- // First un highlight the old disclosure controls
- var previousSelectedRows = [];
- [[self selectedRowIndexes] getIndexes:previousSelectedRows maxCount:-1 inIndexRange:nil];
+ [super _performSelection:select forRow:rowIndex context:context];
- var index = [previousSelectedRows count];
- while (index--)
- {
- var rowIndex = previousSelectedRows[index],
- item = [self itemAtRow:rowIndex];
+ var control = _disclosureControlsForRows[rowIndex],
+ selector = select ? @"setThemeState:" : @"unsetThemeState:";
- if (![self isExpandable:item])
- continue;
-
- var control = _disclosureControlsForRows[rowIndex];
- [control setHighlighted:NO];
- }
-
- [super selectRowIndexes:rows byExtendingSelection:shouldExtendSelection];
-
- // Now highlight the new disclosure controls
- var selectedRows = [];
- [rows getIndexes:selectedRows maxCount:-1 inIndexRange:nil];
-
- var index = [selectedRows count];
- while (index--)
- {
- var rowIndex = selectedRows[index],
- item = [self itemAtRow:rowIndex];
-
- if (![self isExpandable:item])
- continue;
-
- var control = _disclosureControlsForRows[rowIndex];
- [control setHighlighted:YES];
- }
+ [control performSelector:CPSelectorFromString(selector) withObject:CPThemeStateSelected];
}
- (void)setDelegate:(id)aDelegate
@@ -453,6 +435,35 @@ CPOutlineViewDropOnItemIndex = -1;
removeObserver:_outlineViewDelegate
name:CPOutlineViewSelectionIsChangingNotification
object:self];
+
+
+
+ if ([_outlineViewDelegate respondsToSelector:@selector(outlineViewItemWillExpand:)])
+ [defaultCenter
+ removeObserver:_outlineViewDelegate
+ name:CPOutlineViewItemWillExpandNotification
+ object:self];
+
+
+ if ([_outlineViewDelegate respondsToSelector:@selector(outlineViewItemDidExpand:)])
+ [defaultCenter
+ removeObserver:_outlineViewDelegate
+ name:CPOutlineViewItemDidExpandNotification
+ object:self];
+
+
+ if ([_outlineViewDelegate respondsToSelector:@selector(outlineViewItemWillCollapse:)])
+ [defaultCenter
+ removeObserver:_outlineViewDelegate
+ name:CPOutlineViewItemWillCollapseNotification
+ object:self];
+
+
+ if ([_outlineViewDelegate respondsToSelector:@selector(outlineViewItemDidCollapse:)])
+ [defaultCenter
+ removeObserver:_outlineViewDelegate
+ name:CPOutlineViewItemDidCollapseNotification
+ object:self];
}
_outlineViewDelegate = aDelegate;
@@ -500,6 +511,36 @@ CPOutlineViewDropOnItemIndex = -1;
selector:@selector(outlineViewSelectionIsChanging:)
name:CPOutlineViewSelectionIsChangingNotification
object:self];
+
+
+ if ([_outlineViewDelegate respondsToSelector:@selector(outlineViewItemWillExpand:)])
+ [defaultCenter
+ addObserver:_outlineViewDelegate
+ selector:@selector(outlineViewItemWillExpand:)
+ name:CPOutlineViewItemWillExpandNotification
+ object:self];
+
+ if ([_outlineViewDelegate respondsToSelector:@selector(outlineViewItemDidExpand:)])
+ [defaultCenter
+ addObserver:_outlineViewDelegate
+ selector:@selector(outlineViewItemDidExpand:)
+ name:CPOutlineViewItemDidExpandNotification
+ object:self];
+
+ if ([_outlineViewDelegate respondsToSelector:@selector(outlineViewItemWillCollapse:)])
+ [defaultCenter
+ addObserver:_outlineViewDelegate
+ selector:@selector(outlineViewItemWillCollapse:)
+ name:CPOutlineViewItemWillCollapseNotification
+ object:self];
+
+ if ([_outlineViewDelegate respondsToSelector:@selector(outlineViewItemDidCollapse:)])
+ [defaultCenter
+ addObserver:_outlineViewDelegate
+ selector:@selector(outlineViewItemDidCollapse:)
+ name:CPOutlineViewItemDidCollapseNotification
+ object:self];
+
}
- (id)delegate
@@ -534,11 +575,48 @@ CPOutlineViewDropOnItemIndex = -1;
- (void)setDropItem:(id)theItem dropChildIndex:(int)theIndex
{
+ if (_dropItem !== theItem && theIndex < 0 && [self isExpandable:theItem] && ![self isItemExpanded:theItem])
+ {
+ if (_dragHoverTimer)
+ [_dragHoverTimer invalidate];
+
+ var autoExpandCallBack = function(){
+ if (_dropItem)
+ {
+ [_dropOperationFeedbackView blink];
+ [CPTimer scheduledTimerWithTimeInterval:.3 callback:objj_msgSend(self, "expandItem:", _dropItem) repeats:NO]; //[self expandItem:_dropItem];
+ }
+ }
+
+ _dragHoverTimer = [CPTimer scheduledTimerWithTimeInterval:.8 callback:autoExpandCallBack repeats:NO];
+ }
+
+ if (theIndex >= 0)
+ {
+ [_dragHoverTimer invalidate];
+ _dragHoverTimer = nil;
+ }
+
+ _dropItem = theItem;
_retargetedItem = theItem;
_shouldRetargetItem = YES;
_retargedChildIndex = theIndex;
_shouldRetargetChildIndex = YES;
+
+ // set CPTableView's _retargetedDropRow based on retargetedItem and retargetedChildIndex
+ var retargetedItemInfo = (_retargetedItem !== nil) ? _itemInfosForItems[[_retargetedItem UID]] : _rootItemInfo,
+ retargetedChildItem = (_retargedChildIndex !== CPOutlineViewDropOnItemIndex) ? retargetedItemInfo.children[_retargedChildIndex] : _retargetedItem;
+
+ _retargetedDropRow = [self rowForItem:retargetedChildItem];
+}
+
+- (void)_draggingEnded
+{
+ [super _draggingEnded];
+ _dropItem = nil;
+ [_dragHoverTimer invalidate];
+ _dragHoverTimer = nil;
}
- (id)_parentItemForUpperRow:(int)theUpperRowIndex andLowerRow:(int)theLowerRowIndex atMouseOffset:(CPPoint)theOffset
@@ -619,6 +697,8 @@ CPOutlineViewDropOnItemIndex = -1;
_disclosureControlsForRows[row] = control;
[control setState:[self isItemExpanded:item] ? CPOnState : CPOffState];
+ var selector = [self isRowSelected:row] ? @"setThemeState:" : @"unsetThemeState:";
+ [control performSelector:CPSelectorFromString(selector) withObject:CPThemeStateSelected];
[control setFrame:frame];
[self addSubview:control];
@@ -709,6 +789,38 @@ CPOutlineViewDropOnItemIndex = -1;
userInfo:nil];
}
+- (void)_noteItemWillExpand:(id)item
+{
+ [[CPNotificationCenter defaultCenter]
+ postNotificationName:CPOutlineViewItemWillExpandNotification
+ object:self
+ userInfo:[CPDictionary dictionaryWithObject:item forKey:"CPObject"]];
+}
+
+- (void)_noteItemDidExpand:(id)item
+{
+ [[CPNotificationCenter defaultCenter]
+ postNotificationName:CPOutlineViewItemDidExpandNotification
+ object:self
+ userInfo:[CPDictionary dictionaryWithObject:item forKey:"CPObject"]];
+}
+
+- (void)_noteItemWillCollapse:(id)item
+{
+ [[CPNotificationCenter defaultCenter]
+ postNotificationName:CPOutlineViewItemWillCollapseNotification
+ object:self
+ userInfo:[CPDictionary dictionaryWithObject:item forKey:"CPObject"]];
+}
+
+- (void)_noteItemDidCollapse:(id)item
+{
+ [[CPNotificationCenter defaultCenter]
+ postNotificationName:CPOutlineViewItemDidCollapseNotification
+ object:self
+ userInfo:[CPDictionary dictionaryWithObject:item forKey:"CPObject"]];
+}
+
@end
// FIX ME: We're using with() here because Safari fails if we use anOutlineView._itemInfosForItems or whatever...
@@ -880,6 +992,13 @@ var _loadItemInfoForItem = function(/*CPOutlineView*/ anOutlineView, /*id*/ anIt
return [_outlineView._outlineViewDataSource outlineView:_outlineView objectValueForTableColumn:aTableColumn byItem:_outlineView._itemsForRows[aRow]];
}
+- (void)tableView:(CPTableView)aTableView setObjectValue:(id)aValue forTableColumn:(CPTableColumn)aColumn row:(CPInteger)aRow
+{
+ if (!(_outlineView._implementedOutlineViewDataSourceMethods & CPOutlineViewDataSource_outlineView_setObjectValue_forTableColumn_byItem_))
+ return;
+ [_outlineView._outlineViewDataSource outlineView:_outlineView setObjectValue:aValue forTableColumn:aColumn byItem:_outlineView._itemsForRows[aRow]];
+}
+
- (BOOL)tableView:(CPTableView)aTableColumn writeRowsWithIndexes:(CPIndexSet)theIndexes toPasteboard:(CPPasteboard)thePasteboard
{
if (!(_outlineView._implementedOutlineViewDataSourceMethods & CPOutlineViewDataSource_outlineView_writeItems_toPasteboard_))
@@ -1007,6 +1126,14 @@ var _loadItemInfoForItem = function(/*CPOutlineView*/ anOutlineView, /*id*/ anIt
return YES;
}
+- (BOOL)tableView:(CPTableView)aTableView shouldEditTableColumn:(CPTableColumn)aColumn row:(int)aRow
+{
+ if ((_outlineView._implementedOutlineViewDelegateMethods & CPOutlineViewDelegate_outlineView_shouldEditTableColumn_item_))
+ return [_outlineView._outlineViewDelegate outlineView:_outlineView shouldEditTableColumn:aColumn item:[_outlineView itemAtRow:aRow]];
+
+ return NO;
+}
+
- (float)tableView:(CPTableView)theTableView heightOfRow:(int)theRow
{
if ((_outlineView._implementedOutlineViewDelegateMethods & CPOutlineViewDelegate_outlineView_heightOfRowByItem_))
@@ -1080,8 +1207,10 @@ var _loadItemInfoForItem = function(/*CPOutlineView*/ anOutlineView, /*id*/ anIt
CGContextAddLineToPoint(context, 0.0, 0.0);
CGContextClosePath(context);
-
- CGContextSetFillColor(context, [self isHighlighted] ? [CPColor whiteColor] : [CPColor grayColor]);
+ var isHighlighted = [self hasThemeState:CPThemeStateHighlighted];
+ var color = [self hasThemeState:CPThemeStateSelected] ? (isHighlighted ? [CPColor lightGrayColor] : [CPColor whiteColor]) : (isHighlighted ? [CPColor blackColor] : [CPColor grayColor]);
+
+ CGContextSetFillColor(context, color);
CGContextFillPath(context);
}
diff --git a/AppKit/CPPopUpButton.j b/AppKit/CPPopUpButton.j
index 08a340626..b5ac0e1e1 100644
--- a/AppKit/CPPopUpButton.j
+++ b/AppKit/CPPopUpButton.j
@@ -32,7 +32,7 @@ var VISIBLE_MARGIN = 7.0;
CPPopUpButtonStatePullsDown = CPThemeState("pulls-down");
-/*!
+/*!
@ingroup appkit
@class CPPopUpButton
@@ -42,7 +42,7 @@ CPPopUpButtonStatePullsDown = CPThemeState("pulls-down");
{
int _selectedIndex;
CPRectEdge _preferredEdge;
-
+
CPMenu _menu;
}
@@ -60,21 +60,21 @@ CPPopUpButtonStatePullsDown = CPThemeState("pulls-down");
- (id)initWithFrame:(CGRect)aFrame pullsDown:(BOOL)shouldPullDown
{
self = [super initWithFrame:aFrame];
-
+
if (self)
{
_selectedIndex = CPNotFound;
_preferredEdge = CPMaxYEdge;
-
+
[self setValue:CPImageLeft forThemeAttribute:@"image-position"];
[self setValue:CPLeftTextAlignment forThemeAttribute:@"alignment"];
[self setValue:CPLineBreakByTruncatingTail forThemeAttribute:@"line-break-mode"];
-
+
[self setMenu:[[CPMenu alloc] initWithTitle:@""]];
[self setPullsDown:shouldPullDown];
}
-
+
return self;
}
@@ -145,7 +145,7 @@ CPPopUpButtonStatePullsDown = CPThemeState("pulls-down");
{
var index = 0,
count = [titles count];
-
+
for (; index < count; ++index)
[self addItemWithTitle:titles[index]];
}
@@ -159,11 +159,11 @@ CPPopUpButtonStatePullsDown = CPThemeState("pulls-down");
{
var items = [self itemArray],
count = [items count];
-
+
while (count--)
if ([items[count] title] == aTitle)
[self removeItemAtIndex:count];
-
+
[_menu insertItemWithTitle:aTitle action:NULL keyEquivalent:nil atIndex:anIndex];
}
@@ -173,7 +173,7 @@ CPPopUpButtonStatePullsDown = CPThemeState("pulls-down");
- (void)removeAllItems
{
var count = [_menu numberOfItems];
-
+
while (count--)
[_menu removeItemAtIndex:0];
}
@@ -206,7 +206,7 @@ CPPopUpButtonStatePullsDown = CPThemeState("pulls-down");
{
if (_selectedIndex < 0 || _selectedIndex > [self numberOfItems] - 1)
return nil;
-
+
return [_menu itemAtIndex:_selectedIndex];
}
@@ -253,15 +253,15 @@ CPPopUpButtonStatePullsDown = CPThemeState("pulls-down");
{
if (_selectedIndex == anIndex)
return;
-
+
if (_selectedIndex >= 0 && ![self pullsDown])
[[self selectedItem] setState:CPOffState];
-
+
_selectedIndex = anIndex;
if (_selectedIndex >= 0 && ![self pullsDown])
[[self selectedItem] setState:CPOnState];
-
+
[self synchronizeTitleAndSelectedItem];
}
@@ -310,7 +310,7 @@ CPPopUpButtonStatePullsDown = CPThemeState("pulls-down");
return;
var defaultCenter = [CPNotificationCenter defaultCenter];
-
+
if (_menu)
{
[defaultCenter
@@ -330,7 +330,7 @@ CPPopUpButtonStatePullsDown = CPThemeState("pulls-down");
}
_menu = aMenu;
-
+
if (_menu)
{
[defaultCenter
@@ -338,20 +338,20 @@ CPPopUpButtonStatePullsDown = CPThemeState("pulls-down");
selector:@selector(menuDidAddItem:)
name:CPMenuDidAddItemNotification
object:_menu];
-
+
[defaultCenter
addObserver:self
selector:@selector(menuDidChangeItem:)
name:CPMenuDidChangeItemNotification
object:_menu];
-
+
[defaultCenter
addObserver:self
selector:@selector(menuDidRemoveItem:)
name:CPMenuDidRemoveItemNotification
object:_menu];
}
-
+
[self synchronizeTitleAndSelectedItem];
}
@@ -396,12 +396,13 @@ CPPopUpButtonStatePullsDown = CPThemeState("pulls-down");
{
var titles = [],
items = [self itemArray],
-
index = 0,
count = [items count];
-
+
for (; index < count; ++index)
- items.push([items[index] title]);
+ titles.push([items[index] title]);
+
+ return titles;
}
/*!
@@ -519,14 +520,14 @@ CPPopUpButtonStatePullsDown = CPThemeState("pulls-down");
else
{
var index = [self indexOfItemWithTitle:aTitle];
-
+
if (index < 0)
{
[self addItemWithTitle:aTitle];
-
+
index = [self numberOfItems] - 1;
}
-
+
[self selectItemAtIndex:index];
}
}
@@ -554,7 +555,7 @@ CPPopUpButtonStatePullsDown = CPThemeState("pulls-down");
if ([self pullsDown])
{
var items = [_menu itemArray];
-
+
if ([items count] > 0)
item = items[0];
}
@@ -573,22 +574,22 @@ CPPopUpButtonStatePullsDown = CPThemeState("pulls-down");
- (void)menuDidAddItem:(CPNotification)aNotification
{
var index = [[aNotification userInfo] objectForKey:@"CPMenuItemIndex"];
-
+
if (_selectedIndex < 0)
[self selectItemAtIndex:0];
-
+
else if (index == _selectedIndex)
[self synchronizeTitleAndSelectedItem];
-
+
else if (index < _selectedIndex)
++_selectedIndex;
-
+
if (index == 0 && [self pullsDown])
{
var items = [_menu itemArray];
-
+
[items[0] setHidden:YES];
-
+
if (items.length > 0)
[items[1] setHidden:NO];
}
@@ -613,10 +614,10 @@ CPPopUpButtonStatePullsDown = CPThemeState("pulls-down");
if ([self pullsDown] && index != 0)
return;
-
+
if (![self pullsDown] && index != _selectedIndex)
return;
-
+
[self synchronizeTitleAndSelectedItem];
}
@@ -627,7 +628,7 @@ CPPopUpButtonStatePullsDown = CPThemeState("pulls-down");
- (void)menuDidRemoveItem:(CPNotification)aNotification
{
var numberOfItems = [self numberOfItems];
-
+
if (numberOfItems <= _selectedIndex && numberOfItems > 0)
[self selectItemAtIndex:numberOfItems - 1];
else
@@ -703,6 +704,23 @@ CPPopUpButtonStatePullsDown = CPThemeState("pulls-down");
[self sendAction:[self action] to:[self target]];
}
+- (void)takeValueFromKeyPath:(CPString)aKeyPath ofObjects:(CPArray)objects
+{
+ var count = objects.length,
+ value = [objects[0] valueForKeyPath:aKeyPath];
+
+ [self selectItemWithTag:value];
+ [self setEnabled:YES];
+
+ while (count-- > 1)
+ {
+ if (value !== [objects[count] valueForKeyPath:aKeyPath])
+ {
+ [[self selectedItem] setState:CPOffState];
+ }
+ }
+}
+
@end
var CPPopUpButtonMenuKey = @"CPPopUpButtonMenuKey",
@@ -720,7 +738,7 @@ var CPPopUpButtonMenuKey = @"CPPopUpButtonMenuKey",
- (id)initWithCoder:(CPCoder)aCoder
{
self = [super initWithCoder:aCoder];
-
+
if (self)
{
// Nothing is currently selected
@@ -729,7 +747,7 @@ var CPPopUpButtonMenuKey = @"CPPopUpButtonMenuKey",
[self setMenu:[aCoder decodeObjectForKey:CPPopUpButtonMenuKey]];
[self selectItemAtIndex:[aCoder decodeObjectForKey:CPPopUpButtonSelectedIndexKey]];
}
-
+
return self;
}
@@ -741,7 +759,7 @@ var CPPopUpButtonMenuKey = @"CPPopUpButtonMenuKey",
- (void)encodeWithCoder:(CPCoder)aCoder
{
[super encodeWithCoder:aCoder];
-
+
[aCoder encodeObject:_menu forKey:CPPopUpButtonMenuKey];
[aCoder encodeInt:_selectedIndex forKey:CPPopUpButtonSelectedIndexKey];
}
diff --git a/AppKit/CPScrollView.j b/AppKit/CPScrollView.j
index 82badfea4..051195b66 100644
--- a/AppKit/CPScrollView.j
+++ b/AppKit/CPScrollView.j
@@ -27,7 +27,7 @@
#include "CoreGraphics/CGGeometry.h"
-/*!
+/*!
@ingroup appkit
@class CPScrollView
@@ -44,12 +44,12 @@
BOOL _hasVerticalScroller;
BOOL _hasHorizontalScroller;
BOOL _autohidesScrollers;
-
+
CPScroller _verticalScroller;
CPScroller _horizontalScroller;
-
+
int _recursionCount;
-
+
float _verticalLineScroll;
float _verticalPageScroll;
float _horizontalLineScroll;
@@ -158,11 +158,11 @@
if (_recursionCount > 5)
return;
-
+
++_recursionCount;
var documentView = [self documentView];
-
+
if (!documentView)
{
if (_autohidesScrollers)
@@ -250,7 +250,7 @@
[_verticalScroller setFloatValue:0.0];
[_verticalScroller setKnobProportion:1.0];
}
-
+
if (shouldShowHorizontalScroller)
{
[_horizontalScroller setFloatValue:(difference.width <= 0.0) ? 0.0 : scrollPoint.x / difference.width];
@@ -279,13 +279,13 @@
{
if (_horizontalScroller === aScroller)
return;
-
+
[_horizontalScroller removeFromSuperview];
[_horizontalScroller setTarget:nil];
[_horizontalScroller setAction:nil];
-
+
_horizontalScroller = aScroller;
-
+
[_horizontalScroller setTarget:self];
[_horizontalScroller setAction:@selector(_horizontalScrollerDidScroll:)];
@@ -339,13 +339,13 @@
{
if (_verticalScroller === aScroller)
return;
-
+
[_verticalScroller removeFromSuperview];
[_verticalScroller setTarget:nil];
[_verticalScroller setAction:nil];
-
+
_verticalScroller = aScroller;
-
+
[_verticalScroller setTarget:self];
[_verticalScroller setAction:@selector(_verticalScrollerDidScroll:)];
@@ -403,7 +403,7 @@
return;
_autohidesScrollers = autohidesScrollers;
-
+
[self reflectScrolledClipView:_contentView];
}
@@ -445,9 +445,7 @@
- (CPView)_headerView
{
- var headerClipViewSubviews = [_headerClipView subviews];
-
- return [headerClipViewSubviews count] ? headerClipViewSubviews[0] : nil;
+ return [_headerClipView documentView];
}
- (CGRect)_cornerViewFrame
@@ -482,30 +480,30 @@
/* @ignore */
- (void)_verticalScrollerDidScroll:(CPScroller)aScroller
{
- var value = [aScroller floatValue],
- documentFrame = [[_contentView documentView] frame];
+ var value = [aScroller floatValue],
+ documentFrame = [[_contentView documentView] frame],
contentBounds = [_contentView bounds];
switch ([_verticalScroller hitPart])
{
case CPScrollerDecrementLine: contentBounds.origin.y -= _verticalLineScroll;
break;
-
+
case CPScrollerIncrementLine: contentBounds.origin.y += _verticalLineScroll;
break;
-
+
case CPScrollerDecrementPage: contentBounds.origin.y -= _CGRectGetHeight(contentBounds) - _verticalPageScroll;
break;
-
+
case CPScrollerIncrementPage: contentBounds.origin.y += _CGRectGetHeight(contentBounds) - _verticalPageScroll;
break;
-
+
case CPScrollerKnobSlot:
case CPScrollerKnob:
// We want integral bounds!
default: contentBounds.origin.y = ROUND(value * (_CGRectGetHeight(documentFrame) - _CGRectGetHeight(contentBounds)));
}
-
+
[_contentView scrollToPoint:contentBounds.origin];
}
@@ -515,21 +513,21 @@
var value = [aScroller floatValue],
documentFrame = [[self documentView] frame],
contentBounds = [_contentView bounds];
-
+
switch ([_horizontalScroller hitPart])
{
case CPScrollerDecrementLine: contentBounds.origin.x -= _horizontalLineScroll;
break;
-
+
case CPScrollerIncrementLine: contentBounds.origin.x += _horizontalLineScroll;
break;
-
+
case CPScrollerDecrementPage: contentBounds.origin.x -= _CGRectGetWidth(contentBounds) - _horizontalPageScroll;
break;
-
+
case CPScrollerIncrementPage: contentBounds.origin.x += _CGRectGetWidth(contentBounds) - _horizontalPageScroll;
break;
-
+
case CPScrollerKnobSlot:
case CPScrollerKnob:
// We want integral bounds!
@@ -670,15 +668,32 @@
*/
- (void)scrollWheel:(CPEvent)anEvent
{
- var documentFrame = [[self documentView] frame],
- contentBounds = [_contentView bounds];
+ [self _respondToScrollWheelEventWithDeltaX:[anEvent deltaX] * _horizontalLineScroll
+ deltaY:[anEvent deltaY] * _verticalLineScroll];
+}
+
+- (void)_respondToScrollWheelEventWithDeltaX:(float)deltaX deltaY:(float)deltaY
+{
+ var documentFrame = [[self documentView] frame],
+ contentBounds = [_contentView bounds],
+ contentFrame = [_contentView frame],
+ enclosingScrollView = [self enclosingScrollView],
+ extraX = 0,
+ extraY = 0;
// We want integral bounds!
- contentBounds.origin.x = ROUND(contentBounds.origin.x + [anEvent deltaX] * _horizontalLineScroll);
- contentBounds.origin.y = ROUND(contentBounds.origin.y + [anEvent deltaY] * _verticalLineScroll);
+ contentBounds.origin.x = ROUND(contentBounds.origin.x + deltaX);
+ contentBounds.origin.y = ROUND(contentBounds.origin.y + deltaY);
- [_contentView scrollToPoint:contentBounds.origin];
- [_headerClipView scrollToPoint:CGPointMake(contentBounds.origin.x, 0.0)];
+ var constrainedOrigin = [_contentView constrainScrollPoint:CGPointCreateCopy(contentBounds.origin)];
+ extraX = ((contentBounds.origin.x - constrainedOrigin.x) / _horizontalLineScroll) * [enclosingScrollView horizontalLineScroll];
+ extraY = ((contentBounds.origin.y - constrainedOrigin.y) / _verticalLineScroll) * [enclosingScrollView verticalLineScroll];
+
+ [_contentView scrollToPoint:constrainedOrigin];
+ [_headerClipView scrollToPoint:CGPointMake(constrainedOrigin.x, 0.0)];
+
+ if (extraX || extraY)
+ [enclosingScrollView _respondToScrollWheelEventWithDeltaX:extraX deltaY:extraY];
}
- (void)keyDown:(CPEvent)anEvent
@@ -756,10 +771,16 @@ var CPScrollViewContentViewKey = "CPScrollViewContentView",
_horizontalLineScroll = [aCoder decodeFloatForKey:CPScrollViewHLineScrollKey];
_horizontalPageScroll = [aCoder decodeFloatForKey:CPScrollViewHPageScrollKey];
-
+
_contentView = [aCoder decodeObjectForKey:CPScrollViewContentViewKey];
_headerClipView = [aCoder decodeObjectForKey:CPScrollViewHeaderClipViewKey];
-
+
+ if (!_headerClipView)
+ {
+ _headerClipView = [[CPClipView alloc] init];
+ [self addSubview:_headerClipView];
+ }
+
_verticalScroller = [aCoder decodeObjectForKey:CPScrollViewVScrollerKey];
_horizontalScroller = [aCoder decodeObjectForKey:CPScrollViewHScrollerKey];
@@ -772,25 +793,25 @@ var CPScrollViewContentViewKey = "CPScrollViewContentView",
// Do to the anything goes nature of decoding, our subviews may not exist yet, so layout at the end of the run loop when we're sure everything is in a correct state.
[[CPRunLoop currentRunLoop] performSelector:@selector(reflectScrolledClipView:) target:self argument:_contentView order:0 modes:[CPDefaultRunLoopMode]];
}
-
+
return self;
}
- (void)encodeWithCoder:(CPCoder)aCoder
{
[super encodeWithCoder:aCoder];
-
+
[aCoder encodeObject:_contentView forKey:CPScrollViewContentViewKey];
[aCoder encodeObject:_headerClipView forKey:CPScrollViewHeaderClipViewKey];
[aCoder encodeObject:_verticalScroller forKey:CPScrollViewVScrollerKey];
[aCoder encodeObject:_horizontalScroller forKey:CPScrollViewHScrollerKey];
-
+
[aCoder encodeFloat:_verticalLineScroll forKey:CPScrollViewVLineScrollKey];
[aCoder encodeFloat:_verticalPageScroll forKey:CPScrollViewVPageScrollKey];
[aCoder encodeFloat:_horizontalLineScroll forKey:CPScrollViewHLineScrollKey];
[aCoder encodeFloat:_horizontalPageScroll forKey:CPScrollViewHPageScrollKey];
-
+
[aCoder encodeBool:_hasVerticalScroller forKey:CPScrollViewHasVScrollerKey];
[aCoder encodeBool:_hasHorizontalScroller forKey:CPScrollViewHasHScrollerKey];
[aCoder encodeBool:_autohidesScrollers forKey:CPScrollViewAutohidesScrollerKey];
diff --git a/AppKit/CPSearchField.j b/AppKit/CPSearchField.j
index 50528fb0d..f5fdea74a 100644
--- a/AppKit/CPSearchField.j
+++ b/AppKit/CPSearchField.j
@@ -581,7 +581,7 @@ var CPSearchFieldSearchImage = nil,
- (void)_sendPartialString
{
- [[self target] performSelector:[self action] withObject:self];
+ [self _sendAction:self];
}
- (void)_searchFieldCancel:(id)sender
diff --git a/AppKit/CPSlider.j b/AppKit/CPSlider.j
index 76ea7db96..b448becd0 100644
--- a/AppKit/CPSlider.j
+++ b/AppKit/CPSlider.j
@@ -396,6 +396,18 @@ CPCircularSlider = 1;
_sendActionOn &= ~CPLeftMouseDraggedMask;
}
+- (void)takeValueFromKeyPath:(CPString)aKeyPath ofObjects:(CPArray)objects
+{
+ var count = objects.length,
+ value = [objects[0] valueForKeyPath:aKeyPath];
+
+ [self setObjectValue:value];
+
+ while (count-- > 1)
+ if (value !== ([objects[count] valueForKeyPath:aKeyPath]))
+ return [self setFloatValue:1.0];
+}
+
@end
var CPSliderMinValueKey = "CPSliderMinValueKey",
diff --git a/AppKit/CPSplitView.j b/AppKit/CPSplitView.j
index d7c2bb72e..70f1a9282 100644
--- a/AppKit/CPSplitView.j
+++ b/AppKit/CPSplitView.j
@@ -217,10 +217,9 @@ var CPSplitViewHorizontalImage = nil,
_DOMDividerElements[_drawingDivider].style.backgroundRepeat = "repeat";
CPDOMDisplayServerAppendChild(_DOMElement, _DOMDividerElements[_drawingDivider]);
-
- [self _setupDOMDivider];
}
+ [self _setupDOMDivider];
CPDOMDisplayServerSetStyleLeftTop(_DOMDividerElements[_drawingDivider], NULL, _CGRectGetMinX(aRect), _CGRectGetMinY(aRect));
CPDOMDisplayServerSetStyleSize(_DOMDividerElements[_drawingDivider], _CGRectGetWidth(aRect), _CGRectGetHeight(aRect));
#endif
diff --git a/AppKit/CPTableColumn.j b/AppKit/CPTableColumn.j
index 13a025811..b1720cf56 100644
--- a/AppKit/CPTableColumn.j
+++ b/AppKit/CPTableColumn.j
@@ -79,11 +79,16 @@ CPTableColumnUserResizingMask = 1 << 1;
[self setHeaderView:header];
var textDataView = [CPTextField new];
- [textDataView setLineBreakMode:CPLineBreakByTruncatingTail];
- [textDataView setValue:[CPColor colorWithHexString:@"333333"] forThemeAttribute:@"text-color"];
- [textDataView setValue:[CPColor whiteColor] forThemeAttribute:@"text-color" inState:CPThemeStateSelected];
- [textDataView setValue:[CPFont boldSystemFontOfSize:12] forThemeAttribute:@"font" inState:CPThemeStateSelected];
+
+ [textDataView setValue:[CPColor colorWithRed:51.0 / 255.0 green:51.0 / 255.0 blue:51.0 / 255.0 alpha:1.0]
+ forThemeAttribute:"text-color"];
+
+ [textDataView setValue:[CPColor whiteColor] forThemeAttribute:@"text-color" inState:CPThemeStateSelectedDataView];
+ [textDataView setLineBreakMode:CPLineBreakByTruncatingTail];
+ [textDataView setValue:[CPFont boldSystemFontOfSize:12.0] forThemeAttribute:@"font" inState:CPThemeStateSelectedDataView];
[textDataView setValue:CPCenterVerticalTextAlignment forThemeAttribute:@"vertical-alignment"];
+ [textDataView setValue:CGInsetMake(0.0, 0.0, 0.0, 5.0) forThemeAttribute:@"content-inset"];
+
[self setDataView:textDataView];
}
@@ -348,7 +353,14 @@ CPTableColumnUserResizingMask = 1 << 1;
- (void)setHidden:(BOOL)shouldBeHidden
{
+ shouldBeHidden = !!shouldBeHidden
+ if (_isHidden === shouldBeHidden)
+ return;
+
_isHidden = shouldBeHidden;
+
+ [[self headerView] setHidden:shouldBeHidden];
+ [[self tableView] _tableColumnVisibilityDidChange:self];
}
- (BOOL)isHidden
@@ -427,7 +439,10 @@ var CPTableColumnIdentifierKey = @"CPTableColumnIdentifierKey",
CPTableColumnWidthKey = @"CPTableColumnWidthKey",
CPTableColumnMinWidthKey = @"CPTableColumnMinWidthKey",
CPTableColumnMaxWidthKey = @"CPTableColumnMaxWidthKey",
- CPTableColumnResizingMaskKey = @"CPTableColumnResizingMaskKey";
+ CPTableColumnResizingMaskKey = @"CPTableColumnResizingMaskKey",
+ CPTableColumnIsHiddenkey = @"CPTableColumnIsHiddenKey",
+ CPSortDescriptorPrototypeKey = @"CPSortDescriptorPrototypeKey";
+ CPTableColumnIsHiddenkey = @"CPTableColumnIsHiddenKey";
@implementation CPTableColumn (CPCoding)
@@ -449,6 +464,9 @@ var CPTableColumnIdentifierKey = @"CPTableColumnIdentifierKey",
[self setHeaderView:[aCoder decodeObjectForKey:CPTableColumnHeaderViewKey]];
_resizingMask = [aCoder decodeBoolForKey:CPTableColumnResizingMaskKey];
+ _isHidden = [aCoder decodeBoolForKey:CPTableColumnIsHiddenkey];
+
+ _sortDescriptorPrototype = [aCoder decodeObjectForKey:CPSortDescriptorPrototypeKey];
}
return self;
@@ -466,6 +484,9 @@ var CPTableColumnIdentifierKey = @"CPTableColumnIdentifierKey",
[aCoder encodeObject:_dataView forKey:CPTableColumnDataViewKey];
[aCoder encodeObject:_resizingMask forKey:CPTableColumnResizingMaskKey];
+ [aCoder encodeBool:_isHidden forKey:CPTableColumnIsHiddenkey];
+
+ [aCoder encodeObject:_sortDescriptorPrototype forKey:CPSortDescriptorPrototypeKey];
}
@end
diff --git a/AppKit/CPTableHeaderView.j b/AppKit/CPTableHeaderView.j
index 8d8d3b9ec..76f71f426 100644
--- a/AppKit/CPTableHeaderView.j
+++ b/AppKit/CPTableHeaderView.j
@@ -26,7 +26,7 @@
@implementation _CPTableColumnHeaderView : CPView
{
- _CPImageAndTextView _textField;
+ _CPImageAndTextView _textField;
}
- (void)initWithFrame:(CGRect)frame
@@ -36,17 +36,19 @@
{
[self _init];
}
-
+
return self;
}
- (void)_init
{
- _textField = [[_CPImageAndTextView alloc] initWithFrame:CGRectMake(5, 1, CGRectGetWidth([self bounds]) - 10, CGRectGetHeight([self bounds]) - 1)];
+ _textField = [[_CPImageAndTextView alloc] initWithFrame:
+ CGRectMake(5.0, 0.0, CGRectGetWidth([self bounds]) - 10.0, CGRectGetHeight([self bounds]))];
+
[_textField setAutoresizingMask:CPViewWidthSizable|CPViewHeightSizable];
-
+
[_textField setLineBreakMode:CPLineBreakByTruncatingTail];
- [_textField setTextColor: [CPColor colorWithHexString: @"333333"]];
+ [_textField setTextColor:[CPColor colorWithRed:51.0 / 255.0 green:51.0 / 255.0 blue:51.0 / 255.0 alpha:1.0]];
[_textField setFont:[CPFont boldSystemFontOfSize:12.0]];
[_textField setAlignment:CPLeftTextAlignment];
[_textField setVerticalAlignment:CPCenterVerticalTextAlignment];
@@ -61,13 +63,13 @@
var themeState = [self themeState];
if(themeState & CPThemeStateSelected && themeState & CPThemeStateHighlighted)
- [self setBackgroundColor:[CPColor colorWithPatternImage:CPAppKitImage("tableview-headerview-highlighted-pressed.png", CGSizeMake(1.0, 22.0))]];
+ [self setBackgroundColor:[CPColor colorWithPatternImage:CPAppKitImage("tableview-headerview-highlighted-pressed.png", CGSizeMake(1.0, 23.0))]];
else if (themeState & CPThemeStateSelected)
- [self setBackgroundColor:[CPColor colorWithPatternImage:CPAppKitImage("tableview-headerview-highlighted.png", CGSizeMake(1.0, 22.0))]];
+ [self setBackgroundColor:[CPColor colorWithPatternImage:CPAppKitImage("tableview-headerview-highlighted.png", CGSizeMake(1.0, 23.0))]];
else if (themeState & CPThemeStateHighlighted)
- [self setBackgroundColor:[CPColor colorWithPatternImage:CPAppKitImage("tableview-headerview-pressed.png", CGSizeMake(1.0, 22.0))]];
+ [self setBackgroundColor:[CPColor colorWithPatternImage:CPAppKitImage("tableview-headerview-pressed.png", CGSizeMake(1.0, 23.0))]];
else
- [self setBackgroundColor:[CPColor colorWithPatternImage:CPAppKitImage("tableview-headerview.png", CGSizeMake(1.0, 22.0))]];
+ [self setBackgroundColor:[CPColor colorWithPatternImage:CPAppKitImage("tableview-headerview.png", CGSizeMake(1.0, 23.0))]];
}
- (void)setStringValue:(CPString)string
@@ -137,7 +139,7 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal
- (void)encodeWithCoder:(CPCoder)aCoder
{
[super encodeWithCoder:aCoder];
-
+
[aCoder encodeObject:[_textField text] forKey:_CPTableColumnHeaderViewStringValueKey];
[aCoder encodeObject:[_textField image] forKey:_CPTableColumnHeaderViewImageKey];
[aCoder encodeObject:[_textField font] forKey:_CPTableColumnHeaderViewFontKey];
@@ -147,27 +149,34 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal
@implementation CPTableHeaderView : CPView
{
- int _resizedColumn @accessors(readonly, property=resizedColumn);
- int _draggedColumn @accessors(readonly, property=draggedColumn);
- int _pressedColumn @accessors(readonly, property=pressedColumn);
-
- float _draggedDistance @accessors(readonly, property=draggedDistance);
- float _lastLocation;
- float _columnOldWidth;
-
- CPTableView _tableView @accessors(property=tableView);
+ CPPoint _mouseDownLocation;
+ CPPoint _previousTrackingLocation;
+ int _activeColumn;
+ int _pressedColumn;
+
+ BOOL _isResizing;
+ BOOL _isDragging;
+ BOOL _isTrackingColumn;
+
+ float _columnOldWidth;
+
+ CPTableView _tableView @accessors(property=tableView);
}
- (void)_init
{
- _resizedColumn = -1;
- _draggedColumn = -1;
+ _mouseDownLocation = CPPointMakeZero();
+ _previousTrackingLocation = CPPointMakeZero();
+ _activeColumn = -1;
_pressedColumn = -1;
- _draggedDistance = 0.0;
- _lastLocation = nil;
- _columnOldWidth = nil;
- [self setBackgroundColor:[CPColor colorWithPatternImage:CPAppKitImage("tableview-headerview.png", CGSizeMake(1.0, 22.0))]];
+ _isResizing = NO;
+ _isDragging = NO;
+ _isTrackingColumn = NO;
+
+ _columnOldWidth = 0.0;
+
+ [self setBackgroundColor:[CPColor colorWithPatternImage:CPAppKitImage("tableview-headerview.png", CGSizeMake(1.0, 23.0))]];
}
- (id)initWithFrame:(CGRect)aFrame
@@ -182,26 +191,18 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal
- (int)columnAtPoint:(CGPoint)aPoint
{
- return [_tableView columnAtPoint:CGPointMake(aPoint.x, 0)];
+ return [_tableView columnAtPoint:CGPointMake(aPoint.x, aPoint.y)];
}
- (CGRect)headerRectOfColumn:(int)aColumnIndex
{
- var tableColumns = [_tableView tableColumns];
+ var headerRect = [self bounds],
+ columnRect = [_tableView rectOfColumn:aColumnIndex];
- if (aColumnIndex < 0 || aColumnIndex > [tableColumns count])
- [CPException raise:"invalid" reason:"tried to get headerRectOfColumn: on invalid column"];
+ headerRect.origin.x = CPRectGetMinX(columnRect);
+ headerRect.size.width = CPRectGetWidth(columnRect);
- // UPDATE COLUMN RANGES ?
-
- var tableRange = _tableView._tableColumnRanges[aColumnIndex],
- bounds = [self bounds];
-
- var rMinX = ROUND(tableRange.location);
- bounds.origin.x = rMinX;
- bounds.size.width = FLOOR(tableRange.length + tableRange.location - rMinX);
-
- return bounds;
+ return headerRect;
}
- (CGRect)_cursorRectForColumn:(int)column
@@ -224,116 +225,292 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal
var headerView = [_tableView._tableColumns[_pressedColumn] headerView];
[headerView unsetThemeState:CPThemeStateHighlighted];
}
-
+
if (column != -1)
{
var headerView = [_tableView._tableColumns[column] headerView];
[headerView setThemeState:CPThemeStateHighlighted];
}
-
+
_pressedColumn = column;
}
- (void)mouseDown:(CPEvent)theEvent
{
- var mouseLocation = [self convertPoint:[theEvent locationInWindow] fromView:nil],
- clickedColumn = [self columnAtPoint:mouseLocation];
-
- // should we send column -1 ?
- [_tableView _sendDelegateDidMouseDownInHeader:clickedColumn];
-
- var resizeLocation = CGPointMake(mouseLocation.x - 5, mouseLocation.y),
- resizedColumn = [self columnAtPoint:resizeLocation];
-
- if (resizedColumn == -1)
- return;
-
- // 2 different tracking methods: one for resizing/stop-resizing, another one for selection/reordering
- if ([_tableView allowsColumnResizing]
- && CGRectContainsPoint([self _cursorRectForColumn:resizedColumn], mouseLocation))
- {
- _resizedColumn = resizedColumn;
- [_tableView._tableColumns[_resizedColumn] setDisableResizingPosting:YES];
- [_tableView setDisableAutomaticResizing:YES];
- [self trackResizeWithEvent:theEvent];
- }
- else
- {
- [self _setPressedColumn:clickedColumn];
- [self trackMouseWithEvent:theEvent];
- }
+ [self trackMouse:theEvent];
}
-- (void)trackMouseWithEvent:(CPEvent)theEvent
+- (void)trackMouse:(CPEvent)theEvent
{
- var type = [theEvent type];
-
- if (type == CPLeftMouseUp)
- {
- var location = [self convertPoint:[theEvent locationInWindow] fromView:nil],
- clickedColumn = [self columnAtPoint:location];
+ var type = [theEvent type],
+ currentLocation = [self convertPoint:[theEvent locationInWindow] fromView:nil];
- [self _setPressedColumn:-1];
-
- if (clickedColumn != -1)
- [_tableView _didClickTableColumn:clickedColumn modifierFlags:[theEvent modifierFlags]];
-
- return;
- }
+ // Take the right columns resize tracking area into account
+ currentLocation.x -= 5.0;
- [CPApp setTarget:self selector:@selector(trackMouseWithEvent:) forNextEventMatchingMask:CPLeftMouseDraggedMask | CPLeftMouseUpMask | CPLeftMouseDownMask untilDate:nil inMode:nil dequeue:YES];
-}
-
-- (void)trackResizeWithEvent:(CPEvent)anEvent
-{
- var location = [self convertPoint:[anEvent locationInWindow] fromView:nil],
- tableColumn = [[_tableView tableColumns] objectAtIndex:_resizedColumn],
- type = [anEvent type];
-
- if (_lastLocation == nil)
- _lastLocation = location;
-
- if (_columnOldWidth == nil)
- _columnOldWidth = [tableColumn width];
+ var columnIndex = [self columnAtPoint:currentLocation],
+ shouldResize = [self shouldResizeTableColumn:columnIndex at:CPPointMake(currentLocation.x + 5.0, currentLocation.y)];
if (type === CPLeftMouseUp)
- {
- [self _updateResizeCursor:anEvent];
-
- [tableColumn _postDidResizeNotificationWithOldWidth:_columnOldWidth];
- [tableColumn setDisableResizingPosting:NO];
- [_tableView setDisableAutomaticResizing:NO];
-
- _resizedColumn = -1;
- _lastLocation = nil;
- _columnOldWidth = nil;
-
- return;
- }
- else if (type === CPLeftMouseDragged)
{
- var newWidth = [tableColumn width] + location.x - _lastLocation.x;
-
- if (newWidth < [tableColumn minWidth])
- [[CPCursor resizeRightCursor] set];
- else if (newWidth > [tableColumn maxWidth])
- [[CPCursor resizeLeftCursor] set];
+ if (shouldResize)
+ [self stopResizingTableColumn:_activeColumn at:currentLocation];
+ else if ([self _shouldStopTrackingTableColumn:columnIndex at:currentLocation])
+ {
+ [_tableView _didClickTableColumn:columnIndex modifierFlags:[theEvent modifierFlags]];
+ [self stopTrackingTableColumn:columnIndex at:currentLocation];
+
+ _isTrackingColumn = NO;
+ }
+
+ [self _updateResizeCursor:[CPApp currentEvent]];
+
+ _activeColumn = CPNotFound;
+ return;
+ }
+
+ if (type === CPLeftMouseDown)
+ {
+ if (columnIndex === -1)
+ return;
+
+ _mouseDownLocation = currentLocation;
+ _activeColumn = columnIndex;
+
+ [_tableView _sendDelegateDidMouseDownInHeader:columnIndex];
+
+ if (shouldResize)
+ [self startResizingTableColumn:columnIndex at:currentLocation];
else
{
- _tableView._lastColumnShouldSnap = NO;
- [tableColumn setWidth:newWidth];
- // FIXME: there has to be a better way to do this...
- // We should refactor the auto resizing crap.
- // We need to figure out the exact cocoa behavior here though.
- _lastLocation = location;
+ [self startTrackingTableColumn:columnIndex at:currentLocation];
+ _isTrackingColumn = YES;
+ }
+ }
+ else if (type === CPLeftMouseDragged)
+ {
+ if (shouldResize)
+ [self continueResizingTableColumn:_activeColumn at:currentLocation];
+ else
+ {
+ if (_activeColumn === columnIndex && CPRectContainsPoint([self headerRectOfColumn:columnIndex], currentLocation))
+ {
+ if (_isTrackingColumn && _pressedColumn !== -1)
+ {
+ if (![self continueTrackingTableColumn:columnIndex at:currentLocation])
+ return; // Stop tracking the column, because it's being dragged
+ } else
+ [self startTrackingTableColumn:columnIndex at:currentLocation];
- [[CPCursor resizeLeftRightCursor] set];
- [self setNeedsLayout];
- [self setNeedsDisplay:YES];
+ } else if (_isTrackingColumn && _pressedColumn !== -1)
+ [self stopTrackingTableColumn:_activeColumn at:currentLocation];
}
}
- [CPApp setTarget:self selector:@selector(trackResizeWithEvent:) forNextEventMatchingMask:CPLeftMouseDraggedMask | CPLeftMouseUpMask untilDate:nil inMode:nil dequeue:YES];
+ _previousTrackingLocation = currentLocation;
+ [CPApp setTarget:self selector:@selector(trackMouse:) forNextEventMatchingMask:CPLeftMouseDraggedMask | CPLeftMouseUpMask untilDate:nil inMode:nil dequeue:YES];
+}
+
+- (void)startTrackingTableColumn:(int)aColumnIndex at:(CPPoint)aPoint
+{
+ [self _setPressedColumn:aColumnIndex];
+}
+
+- (BOOL)continueTrackingTableColumn:(int)aColumnIndex at:(CPPoint)aPoint
+{
+ if ([self _shouldDragTableColumn:aColumnIndex at:aPoint])
+ {
+ var columnRect = [self headerRectOfColumn:aColumnIndex],
+ offset = CPPointMakeZero(),
+ view = [_tableView _dragViewForColumn:aColumnIndex event:[CPApp currentEvent] offset:offset],
+ viewLocation = CPPointMakeZero();
+
+ viewLocation.x = ( CPRectGetMinX(columnRect) + offset.x ) + ( aPoint.x - _mouseDownLocation.x );
+ viewLocation.y = CPRectGetMinY(columnRect) + offset.y;
+
+ [self dragView:view at:viewLocation offset:CPSizeMakeZero() event:[CPApp currentEvent]
+ pasteboard:[CPPasteboard pasteboardWithName:CPDragPboard] source:self slideBack:YES];
+
+ return NO;
+ }
+
+ return YES;
+}
+
+- (BOOL)_shouldStopTrackingTableColumn:(int)aColumnIndex at:(CPPoint)aPoint
+{
+ return _isTrackingColumn && _activeColumn === aColumnIndex &&
+ CPRectContainsPoint([self headerRectOfColumn:aColumnIndex], aPoint);
+}
+
+- (void)stopTrackingTableColumn:(int)aColumnIndex at:(CPPoint)aPoint
+{
+ [self _setPressedColumn:CPNotFound];
+ [self _updateResizeCursor:[CPApp currentEvent]];
+}
+
+- (BOOL)_shouldDragTableColumn:(int)aColumnIndex at:(CPPoint)aPoint
+{
+ return [_tableView allowsColumnReordering] && ABS(aPoint.x - _mouseDownLocation.x) >= 10.0;
+}
+
+- (CPRect)_headerRectOfLastVisibleColumn
+{
+ var tableColumns = [_tableView tableColumns],
+ columnIndex = [tableColumns count];
+
+ while (columnIndex--)
+ {
+ var tableColumn = [tableColumns objectAtIndex:columnIndex];
+
+ if (![tableColumn isHidden])
+ return [self headerRectOfColumn:columnIndex];
+ }
+
+ return nil;
+}
+
+- (void)_constrainDragView:(CPView)theDragView at:(CPPoint)aPoint
+{
+ var tableColumns = [_tableView tableColumns],
+ lastColumnRect = [self _headerRectOfLastVisibleColumn];
+ activeColumnRect = [self headerRectOfColumn:_activeColumn];
+ dragWindow = [theDragView window],
+ frame = [dragWindow frame];
+
+ // Convert the frame origin from the global coordinate system to the windows' coordinate system
+ frame.origin = [[self window] convertGlobalToBase:frame.origin];
+ // the from the window to the view
+ frame.origin = [self convertPoint:frame.origin fromView:nil];
+
+ // This effectively clamps the value between the minimum and maximum
+ frame.origin.x = MAX(0.0, MIN(CGRectGetMinX(frame), CGRectGetMaxX(lastColumnRect) - CGRectGetWidth(activeColumnRect)));
+
+ // Make sure the column cannot move vertically
+ frame.origin.y = CPRectGetMinY(lastColumnRect);
+
+ // Convert the calculated origin back to the window coordinate system
+ frame.origin = [self convertPoint:frame.origin toView:nil];
+ // Then back to the global coordinate system
+ frame.origin = [[self window] convertBaseToGlobal:frame.origin];
+
+ [dragWindow setFrame:frame];
+}
+
+- (void)_moveColumn:(int)aFromIndex toColumn:(int)aToIndex
+{
+ [_tableView moveColumn:aFromIndex toColumn:aToIndex];
+ _activeColumn = aToIndex;
+ _pressedColumn = _activeColumn;
+
+ [_tableView _setDraggedColumn:_activeColumn];
+}
+
+- (void)draggedView:(CPView)aView beganAt:(CPPoint)aPoint
+{
+ _isDragging = YES;
+
+ [[[[_tableView tableColumns] objectAtIndex:_activeColumn] headerView] setHidden:YES];
+ [_tableView _setDraggedColumn:_activeColumn];
+
+ [self setNeedsDisplay:YES];
+}
+
+- (void)draggedView:(CPView)aView movedTo:(CPPoint)aPoint
+{
+ [self _constrainDragView:aView at:aPoint];
+
+ var dragWindow = [aView window],
+ dragWindowFrame = [dragWindow frame];
+
+ var hoverPoint = CGPointCreateCopy(aPoint);
+
+ if (aPoint.x < _previousTrackingLocation.x)
+ hoverPoint = CGPointMake(CGRectGetMinX(dragWindowFrame), CGRectGetMinY(dragWindowFrame));
+ else if (aPoint.x > _previousTrackingLocation.x)
+ hoverPoint = CGPointMake(CGRectGetMaxX(dragWindowFrame), CGRectGetMinY(dragWindowFrame));
+
+ // Convert the hover point from the global coordinate system to windows' coordinate system
+ hoverPoint = [[self window] convertGlobalToBase:hoverPoint];
+ // then to the view
+ hoverPoint = [self convertPoint:hoverPoint fromView:nil];
+
+ var hoveredColumn = [self columnAtPoint:hoverPoint];
+
+ if (hoveredColumn !== -1)
+ {
+ var columnRect = [self headerRectOfColumn:hoveredColumn],
+ columnCenterPoint = [self convertPoint:CGPointMake(CGRectGetMidX(columnRect), CGRectGetMidY(columnRect)) fromView:self];
+ if (hoveredColumn < _activeColumn && hoverPoint.x < columnCenterPoint.x)
+ [self _moveColumn:_activeColumn toColumn:hoveredColumn];
+ else if (hoveredColumn > _activeColumn && hoverPoint.x > columnCenterPoint.x)
+ [self _moveColumn:_activeColumn toColumn:hoveredColumn];
+ }
+
+ _previousTrackingLocation = aPoint;
+}
+
+- (void)draggedView:(CPImage)aView endedAt:(CGPoint)aLocation operation:(CPDragOperation)anOperation
+{
+ _isDragging = NO;
+ _isTrackingColumn = NO; // We need to do this explicitly because the mouse up section of trackMouse is never reached
+
+ [_tableView _setDraggedColumn:-1];
+ [[[[_tableView tableColumns] objectAtIndex:_activeColumn] headerView] setHidden:NO];
+ [self stopTrackingTableColumn:_activeColumn at:aLocation];
+
+ [self setNeedsDisplay:YES];
+}
+
+- (BOOL)shouldResizeTableColumn:(int)aColumnIndex at:(CPPoint)aPoint
+{
+ if (_isResizing)
+ return YES;
+
+ if (_isTrackingColumn)
+ return NO;
+
+ return [_tableView allowsColumnResizing] && CPRectContainsPoint([self _cursorRectForColumn:aColumnIndex], aPoint);
+}
+
+- (void)startResizingTableColumn:(int)aColumnIndex at:(CPPoint)aPoint
+{
+ _isResizing = YES;
+
+ var tableColumn = [[_tableView tableColumns] objectAtIndex:aColumnIndex];
+
+ [tableColumn setDisableResizingPosting:YES];
+ [_tableView setDisableAutomaticResizing:YES];
+}
+
+- (void)continueResizingTableColumn:(int)aColumnIndex at:(CPPoint)aPoint
+{
+ var tableColumn = [[_tableView tableColumns] objectAtIndex:aColumnIndex],
+ newWidth = [tableColumn width] + aPoint.x - _previousTrackingLocation.x;
+
+ if (newWidth < [tableColumn minWidth])
+ [[CPCursor resizeRightCursor] set];
+ else if (newWidth > [tableColumn maxWidth])
+ [[CPCursor resizeLeftCursor] set];
+ else
+ {
+ _tableView._lastColumnShouldSnap = NO;
+ [tableColumn setWidth:newWidth];
+
+ [[CPCursor resizeLeftRightCursor] set];
+ [self setNeedsLayout];
+ [self setNeedsDisplay:YES];
+ }
+}
+
+- (void)stopResizingTableColumn:(int)aColumnIndex at:(CPPoint)aPoint
+{
+ var tableColumn = [[_tableView tableColumns] objectAtIndex:aColumnIndex];
+ [tableColumn _postDidResizeNotificationWithOldWidth:_columnOldWidth];
+ [tableColumn setDisableResizingPosting:NO];
+ [_tableView setDisableAutomaticResizing:NO];
+
+ _isResizing = NO;
}
- (void)_updateResizeCursor:(CPEvent)theEvent
@@ -348,12 +525,12 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal
var mouseLocation = [self convertPoint:[theEvent locationInWindow] fromView:nil],
mouseOverLocation = CGPointMake(mouseLocation.x - 5, mouseLocation.y),
overColumn = [self columnAtPoint:mouseOverLocation];
-
+
if (overColumn >= 0 && CGRectContainsPoint([self _cursorRectForColumn:overColumn], mouseLocation))
{
var tableColumn = [[_tableView tableColumns] objectAtIndex:overColumn],
width = [tableColumn width];
-
+
if (width == [tableColumn minWidth])
[[CPCursor resizeRightCursor] set];
else if (width == [tableColumn maxWidth])
@@ -365,12 +542,6 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal
[[CPCursor arrowCursor] set];
}
-- (void)viewDidMoveToWindow
-{
- //if ([_tableView allowsColumnResizing])
- // [[self window] setAcceptsMouseMovedEvents:YES];
-}
-
- (void)mouseEntered:(CPEvent)theEvent
{
[self _updateResizeCursor:theEvent];
@@ -391,12 +562,12 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal
{
var tableColumns = [_tableView tableColumns],
count = [tableColumns count];
-
+
for (var i = 0; i < count; i++)
{
var column = [tableColumns objectAtIndex:i],
headerView = [column headerView];
-
+
var frame = [self headerRectOfColumn:i];
frame.size.height -= 0.5;
if (i > 0)
@@ -404,9 +575,9 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal
frame.origin.x += 0.5;
frame.size.width -= 1;
}
-
+
[headerView setFrame:frame];
-
+
if([headerView superview] != self)
[self addSubview:headerView];
}
@@ -433,43 +604,28 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal
var columnArrayIndex = 0,
columnArrayCount = columnsArray.length,
columnMaxX;
-
+
CGContextBeginPath(context);
for(; columnArrayIndex < columnArrayCount; columnArrayIndex++)
{
// grab each column rect and add vertical lines
var columnIndex = columnsArray[columnArrayIndex],
columnToStroke = [self headerRectOfColumn:columnIndex];
-
+
columnMaxX = CGRectGetMaxX(columnToStroke);
-
+
CGContextMoveToPoint(context, ROUND(columnMaxX) + 0.5, ROUND(CGRectGetMinY(columnToStroke)));
CGContextAddLineToPoint(context, ROUND(columnMaxX) + 0.5, ROUND(CGRectGetMaxY(columnToStroke)));
}
-
+
CGContextClosePath(context);
CGContextStrokePath(context);
-
-/*
- var maxY = CGRectGetMaxY([self bounds]);
- // draw normal gradient for remaining space
- if (supportsCanvasGradient)
+
+ if (_isDragging)
{
- aRect.origin.x = columnMaxX - 0.5;
- aRect.size.width -= columnMaxX;
- CGContextBeginPath(context);
- CGContextAddRect(context, CGRectMake(columnMaxX + 1, 0, CGRectGetMaxX([self bounds]) - columnMaxX, CGRectGetHeight([self bounds])));
- CGContextClosePath(context);
- CGContextDrawLinearGradient(context, [_CPTableColumnHeaderView headerGradient], CGPointMake(0,0), CGPointMake(0, maxY - 1),0);
- }
-
- // Draw bottom line
- CGContextBeginPath(context);
- CGContextMoveToPoint(context, 0, maxY - 0.5);
- CGContextAddLineToPoint(context, CGRectGetMaxX([self bounds]), maxY - 0.5);
- CGContextClosePath(context);
- CGContextStrokePath(context);
-*/
+ CGContextSetFillColor(context, [CPColor grayColor]);
+ CGContextFillRect(context, [self headerRectOfColumn:_activeColumn])
+ }
}
@end
@@ -495,5 +651,4 @@ var CPTableHeaderViewTableViewKey = @"CPTableHeaderViewTableViewKey";
[aCoder encodeObject:_tableView forKey:CPTableHeaderViewTableViewKey];
}
-@end
-
+@end
\ No newline at end of file
diff --git a/AppKit/CPTableView.j b/AppKit/CPTableView.j
index 4e4c536dd..88fe5d5cb 100644
--- a/AppKit/CPTableView.j
+++ b/AppKit/CPTableView.j
@@ -28,7 +28,6 @@
@import "_CPCornerView.j"
@import "CPScroller.j"
-
CPTableViewColumnDidMoveNotification = @"CPTableViewColumnDidMoveNotification";
CPTableViewColumnDidResizeNotification = @"CPTableViewColumnDidResizeNotification";
CPTableViewSelectionDidChangeNotification = @"CPTableViewSelectionDidChangeNotification";
@@ -75,6 +74,10 @@ CPTableViewDraggingDestinationFeedbackStyleSourceList = 1;
CPTableViewDropOn = 0;
CPTableViewDropAbove = 1;
+CPSourceListGradient = "CPSourceListGradient";
+CPSourceListTopLineColor = "CPSourceListTopLineColor";
+CPSourceListBottomLineColor = "CPSourceListBottomLineColor";
+
// TODO: add docs
CPTableViewSelectionHighlightStyleNone = -1;
@@ -86,7 +89,7 @@ CPTableViewSolidVerticalGridLineMask = 1 << 0;
CPTableViewSolidHorizontalGridLineMask = 1 << 1;
CPTableViewNoColumnAutoresizing = 0;
-CPTableViewUniformColumnAutoresizingStyle = 1;
+CPTableViewUniformColumnAutoresizingStyle = 1; // FIX ME: This is FUBAR
CPTableViewSequentialColumnAutoresizingStyle = 2;
CPTableViewReverseSequentialColumnAutoresizingStyle = 3;
CPTableViewLastColumnOnlyAutoresizingStyle = 4;
@@ -123,13 +126,13 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
@end
-/*!
+/*!
@ingroup appkit
@class CPTableView
- CPTableView object displays record-oriented data in a table and
+ CPTableView object displays record-oriented data in a table and
allows the user to edit values and resize and rearrange columns.
- A CPTableView requires you to set a dataSource which implements numberOfRowsInTableView:
+ A CPTableView requires you to set a dataSource which implements numberOfRowsInTableView:
and tableView:objectValueForTableColumn:row:
*/
@implementation CPTableView : CPControl
@@ -159,7 +162,7 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
BOOL _allowsColumnSelection;
BOOL _allowsMultipleSelection;
BOOL _allowsEmptySelection;
-
+
CPArray _sortDescriptors;
//Setting Display Attributes
CGSize _intercellSpacing;
@@ -170,6 +173,7 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
unsigned _selectionHighlightStyle;
CPTableColumn _currentHighlightedTableColumn;
+ CPColor _selectionHighlightColor;
unsigned _gridStyleMask;
CPColor _gridColor;
@@ -205,13 +209,16 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
CPDragOperation _dragOperationDefaultMask;
int _retargetedDropRow;
CPDragOperation _retargetedDropOperation;
-
+
BOOL _disableAutomaticResizing @accessors(property=disableAutomaticResizing);
BOOL _lastColumnShouldSnap;
CPGradient _sourceListActiveGradient;
CPColor _sourceListActiveTopLineColor;
- CPColor _sourceListActiveBottomLineColor;
+ CPColor _sourceListActiveBottomLineColor;
+
+ int _draggedColumnIndex;
+
/*
CPGradient _sourceListInactiveGradient;
CPColor _sourceListInactiveTopLineColor;
@@ -232,26 +239,19 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
_allowsEmptySelection = YES;
_allowsColumnSelection = NO;
_disableAutomaticResizing = NO;
- _tableViewFlags = 0;
//Setting Display Attributes
_selectionHighlightStyle = CPTableViewSelectionHighlightStyleRegular;
[self setUsesAlternatingRowBackgroundColors:NO];
- [self setAlternatingRowBackgroundColors:[[CPColor whiteColor], [CPColor colorWithHexString:@"f5f9fc"]]];
+ [self setAlternatingRowBackgroundColors:
+ [[CPColor whiteColor], [CPColor colorWithRed:245.0 / 255.0 green:249.0 / 255.0 blue:252.0 / 255.0 alpha:1.0]]];
_tableColumns = [];
_tableColumnRanges = [];
_dirtyTableColumnRangeIndex = CPNotFound;
_numberOfHiddenColumns = 0;
- _objectValues = { };
- _dataViewsForTableColumns = { };
- _dataViews= [];
- _numberOfRows = 0;
- _exposedRows = [CPIndexSet indexSet];
- _exposedColumns = [CPIndexSet indexSet];
- _cachedDataViews = { };
_intercellSpacing = _CGSizeMake(0.0, 0.0);
_rowHeight = 23.0;
@@ -265,8 +265,6 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
_cornerView = nil; //[[_CPCornerView alloc] initWithFrame:CGRectMake(0, 0, [CPScroller scrollerWidth], CGRectGetHeight([_headerView frame]))];
_lastSelectedRow = -1;
- _selectedColumnIndexes = [CPIndexSet indexSet];
- _selectedRowIndexes = [CPIndexSet indexSet];
_currentHighlightedTableColumn = nil;
_sortDescriptors = [CPArray array];
@@ -279,10 +277,6 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
_dragOperationDefaultMask = nil;
_destinationDragStyle = CPTableViewDraggingDestinationFeedbackStyleRegular;
- _tableDrawView = [[_CPTableDrawView alloc] initWithTableView:self];
- [_tableDrawView setBackgroundColor:[CPColor clearColor]];
- [self addSubview:_tableDrawView];
-
[self setBackgroundColor:[CPColor whiteColor]];
[self _init];
}
@@ -293,11 +287,47 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
// FIX ME: we have a lot of redundent init stuff in initWithFrame: and initWithCoder: we should move it all into here.
- (void)_init
{
+ _tableViewFlags = 0;
+
+ _selectedColumnIndexes = [CPIndexSet indexSet];
+ _selectedRowIndexes = [CPIndexSet indexSet];
+
_dropOperationFeedbackView = [[_CPDropOperationDrawingView alloc] initWithFrame:_CGRectMakeZero()];
[_dropOperationFeedbackView setTableView:self];
_lastColumnShouldSnap = NO;
+ if (!_alternatingRowBackgroundColors)
+ _alternatingRowBackgroundColors = [[CPColor whiteColor], [CPColor colorWithHexString:@"e4e7ff"]];
+
+ _selectionHighlightColor = [CPColor colorWithHexString:@"5f83b9"];
+
+ _tableColumnRanges = [];
+ _dirtyTableColumnRangeIndex = 0;
+ _numberOfHiddenColumns = 0;
+
+ _objectValues = { };
+ _dataViewsForTableColumns = { };
+ _dataViews= [];
+ _numberOfRows = 0;
+ _exposedRows = [CPIndexSet indexSet];
+ _exposedColumns = [CPIndexSet indexSet];
+ _cachedDataViews = { };
+
+ _tableDrawView = [[_CPTableDrawView alloc] initWithTableView:self];
+ [_tableDrawView setBackgroundColor:[CPColor clearColor]];
+ [self addSubview:_tableDrawView];
+
+ if (!_headerView)
+ _headerView = [[CPTableHeaderView alloc] initWithFrame:CGRectMake(0, 0, [self bounds].size.width, _rowHeight)];
+
+ [_headerView setTableView:self];
+
+ if (!_cornerView)
+ _cornerView = [[_CPCornerView alloc] initWithFrame:CGRectMake(0, 0, [CPScroller scrollerWidth], CGRectGetHeight([_headerView frame]))];
+
+ _draggedColumnIndex = -1;
+
// Gradients for the source list
_sourceListActiveGradient = CGGradientCreateWithColorComponents(CGColorSpaceCreateDeviceRGB(), [89.0/255.0, 153.0/255.0, 209.0/255.0,1.0, 33.0/255.0, 94.0/255.0, 208.0/255.0,1.0], [0,1], 2);
_sourceListActiveTopLineColor = [CPColor colorWithCalibratedRed:(61.0/255.0) green:(123.0/255.0) blue:(218.0/255.0) alpha:1.0];
@@ -378,7 +408,7 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
/*!
Reloads the data for all rows and columns.
-
+
*/
- (void)reloadData
{
@@ -397,9 +427,9 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
//Target-action Behavior
/*!
- Sets the message sent to the target when the user double-clicks an
+ Sets the message sent to the target when the user double-clicks an
uneditable cell or a column header to a given selector.
- @param aSelector The message the receiver sends to its target when the user
+ @param aSelector The message the receiver sends to its target when the user
double-clicks an uneditable cell or a column header.
*/
- (void)setDoubleAction:(SEL)anAction
@@ -535,7 +565,7 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
/*!
Sets the colors for the rows as they alternate. The number of colors can be arbitrary. By deafult these colors are white and light blue.
- @param anArray an array of CPColors
+ @param anArray an array of CPColors
*/
- (void)setAlternatingRowBackgroundColors:(CPArray)alternatingRowBackgroundColors
@@ -563,15 +593,67 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
//early return for IE.
if (aSelectionHighlightStyle == CPTableViewSelectionHighlightStyleSourceList && !CPFeatureIsCompatible(CPHTMLCanvasFeature))
return;
-
+
_selectionHighlightStyle = aSelectionHighlightStyle;
-
+ [self setNeedsDisplay:YES];
+
if (aSelectionHighlightStyle === CPTableViewSelectionHighlightStyleSourceList)
_destinationDragStyle = CPTableViewDraggingDestinationFeedbackStyleSourceList;
else
_destinationDragStyle = CPTableViewDraggingDestinationFeedbackStyleRegular;
}
+/*!
+ Sets the highlight color for a row or column selection
+ @param aColor a CPColor
+*/
+- (void)setSelectionHighlightColor:(CPColor)aColor
+{
+ if (aColor === _selectionHighlightColor)
+ return;
+
+ _selectionHighlightColor = aColor;
+ [self setNeedsDisplay:YES];
+}
+
+/*!
+ Returns the highlight color for a row or column selection.
+*/
+- (CPColor)selectionHighlightColor
+{
+ return _selectionHighlightColor;
+}
+
+/*!
+ Sets the highlight gradient for a row or column selection
+ This is specific to the
+ @param aDictionary a CPDictionary expects three keys to be set:
+ CPSourceListGradient which is a CGGradient
+ CPSourceListTopLineColor which is a CPColor
+ CPSourceListBottomLineColor which is a CPColor
+*/
+- (void)setSelectionGradientColors:(CPDictionary)aDictionary
+{
+ if ([aDictionary valueForKey:"CPSourceListGradient"] === _sourceListActiveGradient && [aDictionary valueForKey:"CPSourceListTopLineColor"] === _sourceListActiveTopLineColor && [aDictionary valueForKey:"CPSourceListBottomLineColor"] === _sourceListActiveBottomLineColor)
+ return;
+
+ _sourceListActiveGradient = [aDictionary valueForKey:CPSourceListGradient];
+ _sourceListActiveTopLineColor = [aDictionary valueForKey:CPSourceListTopLineColor]
+ _sourceListActiveBottomLineColor = [aDictionary valueForKey:CPSourceListBottomLineColor];
+ [self setNeedsDisplay:YES]
+}
+
+/*!
+ Returns a dictionary of containing the keys:
+ CPSourceListGradient
+ CPSourceListTopLineColor
+ CPSourceListBottomLineColor
+*/
+- (CPDictionary)selectionGradientColors
+{
+ return [CPDictionary dictionaryWithObjects:[_sourceListActiveGradient, _sourceListActiveTopLineColor, _sourceListActiveBottomLineColor] forKeys:[CPSourceListGradient, CPSourceListTopLineColor, CPSourceListBottomLineColor]];
+}
+
/*!
Sets the grid color in the non highlighted state.
@param aColor a CPColor
@@ -632,7 +714,7 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
/*!
Removes a given column from the receiver.
- @param aTableColumn The column to remove from the receiver.
+ @param aTableColumn The column to remove from the receiver.
*/
- (void)removeTableColumn:(CPTableColumn)aTableColumn
{
@@ -660,6 +742,15 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
[self setNeedsLayout];
}
+- (void)_setDraggedColumn:(int)aColumnIndex
+{
+ if (_draggedColumnIndex === aColumnIndex)
+ return;
+
+ _draggedColumnIndex = aColumnIndex;
+
+ [self reloadDataForRowIndexes:_exposedRows columnIndexes:[CPIndexSet indexSetWithIndex:aColumnIndex]];
+}
/*!
Moves the column and heading at a given index to a new given index.
@@ -679,15 +770,37 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
else
_dirtyTableColumnRangeIndex = MIN(fromIndex, toIndex, _dirtyTableColumnRangeIndex);
- if (toIndex > fromIndex)
- --toIndex;
-
var tableColumn = _tableColumns[fromIndex];
[_tableColumns removeObjectAtIndex:fromIndex];
[_tableColumns insertObject:tableColumn atIndex:toIndex];
- [self setNeedsLayout];
+ [[self headerView] setNeedsLayout];
+ [[self headerView] setNeedsDisplay:YES];
+
+ var rowIndexes = [CPIndexSet indexSetWithIndexesInRange:CPMakeRange(0, [self numberOfRows])],
+ columnIndexes = [CPIndexSet indexSetWithIndexesInRange:CPMakeRange(fromIndex, toIndex)];
+
+ [self reloadDataForRowIndexes:rowIndexes columnIndexes:columnIndexes];
+}
+
+/*!
+ @ignore
+*/
+- (void)_tableColumnVisibilityDidChange:(CPTableColumn)aColumn
+{
+ var columnIndex = [[self tableColumns] indexOfObjectIdenticalTo:aColumn];
+
+ if (_dirtyTableColumnRangeIndex < 0)
+ _dirtyTableColumnRangeIndex = columnIndex;
+ else
+ _dirtyTableColumnRangeIndex = MIN(columnIndex, _dirtyTableColumnRangeIndex);
+
+ [[self headerView] setNeedsLayout];
+ [[self headerView] setNeedsDisplay:YES];
+
+ var rowIndexes = [CPIndexSet indexSetWithIndexesInRange:CPMakeRange(0, [self numberOfRows])];
+ [self reloadDataForRowIndexes:rowIndexes columnIndexes:[CPIndexSet indexSetWithIndex:columnIndex]];
}
- (CPArray)tableColumns
@@ -760,7 +873,7 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
*/
- (void)selectRowIndexes:(CPIndexSet)rows byExtendingSelection:(BOOL)shouldExtendSelection
{
- if ([rows isEqualToIndexSet:_selectedRowIndexes] ||
+ if ([rows isEqualToIndexSet:_selectedRowIndexes] ||
(([rows firstIndex] != CPNotFound && [rows firstIndex] < 0) || [rows lastIndex] >= [self numberOfRows]))
return;
@@ -805,22 +918,22 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
var count = deselectRows.length;
while (count--)
- {
- var rowIndex = deselectRows[count];
- var view = dataViewsInTableColumn[rowIndex];
- [view unsetThemeState:CPThemeStateSelected];
- }
+ [self _performSelection:NO forRow:deselectRows[count] context:dataViewsInTableColumn];
count = selectRows.length;
while (count--)
- {
- var rowIndex = selectRows[count];
- var view = dataViewsInTableColumn[rowIndex];
- [view setThemeState:CPThemeStateSelected];
- }
+ [self _performSelection:YES forRow:selectRows[count] context:dataViewsInTableColumn];
}
}
+- (void)_performSelection:(BOOL)select forRow:(CPInteger)rowIndex context:(id)context
+{
+ var view = context[rowIndex],
+ selector = select ? @"setThemeState:" : @"unsetThemeState:";
+
+ [view performSelector:CPSelectorFromString(selector) withObject:CPThemeStateSelectedDataView];
+}
+
- (void)_updateHighlightWithOldColumns:(CPIndexSet)oldColumns newColumns:(CPIndexSet)newColumns
{
var firstExposedColumn = [_exposedColumns firstIndex],
@@ -835,7 +948,7 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
[deselectColumnIndexes getIndexes:deselectColumns maxCount:-1 inIndexRange:CPMakeRange(firstExposedColumn, exposedLength)];
[selectColumnIndexes getIndexes:selectColumns maxCount:-1 inIndexRange:CPMakeRange(firstExposedColumn, exposedLength)];
[_exposedRows getIndexes:selectRows maxCount:-1 inIndexRange:nil];
-
+
var rowsCount = selectRows.length,
count = deselectColumns.length;
while (count--)
@@ -843,14 +956,14 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
var columnIndex = deselectColumns[count],
identifier = [_tableColumns[columnIndex] UID],
dataViewsInTableColumn = _dataViewsForTableColumns[identifier];
-
+
for (var i = 0; i < rowsCount; i++)
{
var rowIndex = selectRows[i],
dataView = dataViewsInTableColumn[rowIndex];
- [dataView unsetThemeState:CPThemeStateSelected];
+ [dataView unsetThemeState:CPThemeStateSelectedDataView];
}
-
+
if (_headerView)
{
var headerView = [_tableColumns[columnIndex] headerView];
@@ -864,12 +977,12 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
var columnIndex = selectColumns[count],
identifier = [_tableColumns[columnIndex] UID],
dataViewsInTableColumn = _dataViewsForTableColumns[identifier];
-
+
for (var i = 0; i < rowsCount; i++)
{
var rowIndex = selectRows[i],
dataView = dataViewsInTableColumn[rowIndex];
- [dataView setThemeState:CPThemeStateSelected];
+ [dataView setThemeState:CPThemeStateSelectedDataView];
}
if (_headerView)
{
@@ -976,13 +1089,13 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
{
var destination = [contentBindingInfo objectForKey:CPObservedObjectKey],
keyPath = [contentBindingInfo objectForKey:CPObservedKeyPathKey];
-
+
return [[destination valueForKeyPath:keyPath] count];
}
else if (_dataSource)
return [_dataSource numberOfRowsInTableView:self];
-
+
return 0;
}
@@ -990,12 +1103,44 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
/*
* - preparedCellAtColumn:row:
*/
+
//Editing Cells
-/*
- * - editColumn:row:withEvent:select:
- * - editedColumn
- * - editedRow
+
+/*!
+ Edits the indicated row.
*/
+- (void)editColumn:(CPInteger)columnIndex row:(CPInteger)rowIndex withEvent:(CPEvent)theEvent select:(BOOL)flag
+{
+ if (![self isRowSelected:rowIndex])
+ [[CPException exceptionWithName:@"Error" reason:@"Attempt to edit row="+rowIndex+" when not selected." userInfo:nil] raise];
+
+ // TODO Do something with flag.
+
+ _editingCellIndex = CGPointMake(columnIndex, rowIndex);
+ [self reloadDataForRowIndexes:[CPIndexSet indexSetWithIndex:rowIndex]
+ columnIndexes:[CPIndexSet indexSetWithIndex:columnIndex]];
+}
+
+/*!
+ Returns the column of the currently edited cell, or -1 if none.
+*/
+- (CPInteger)editedColumn
+{
+ if (!_editingCellIndex)
+ return -1;
+ return _editingCellIndex.x;
+}
+
+/*!
+ Returns the row of the currently edited cell, or -1 if none.
+*/
+- (CPInteger)editedRow
+{
+ if (!_editingCellIndex)
+ return -1;
+ return _editingCellIndex.x;
+}
+
//Setting Auxiliary Views
/*
* - setHeaderView:
@@ -1057,6 +1202,8 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
if (_dirtyTableColumnRangeIndex < 0)
return;
+ _numberOfHiddenColumns = 0;
+
var index = _dirtyTableColumnRangeIndex,
count = NUMBER_OF_COLUMNS(),
x = index === 0 ? 0.0 : CPMaxRange(_tableColumnRanges[index - 1]);
@@ -1066,7 +1213,10 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
var tableColumn = _tableColumns[index];
if ([tableColumn isHidden])
+ {
+ _numberOfHiddenColumns += 1;
_tableColumnRanges[index] = CPMakeRange(x, 0.0);
+ }
else
{
@@ -1088,7 +1238,9 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
{
aColumnIndex = +aColumnIndex;
- if (aColumnIndex < 0 || aColumnIndex >= NUMBER_OF_COLUMNS())
+ var column = [[self tableColumns] objectAtIndex:aColumnIndex];
+
+ if ([column isHidden] || aColumnIndex < 0 || aColumnIndex >= NUMBER_OF_COLUMNS())
return _CGRectMakeZero();
UPDATE_COLUMN_RANGES_IF_NECESSARY();
@@ -1241,85 +1393,80 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
return _CGRectMake(tableColumnRange.location, _CGRectGetMinY(rectOfRow), tableColumnRange.length, _CGRectGetHeight(rectOfRow));
}
-//FIX ME: We should refactor this!
- (void)resizeWithOldSuperviewSize:(CGSize)aSize
{
[super resizeWithOldSuperviewSize:aSize];
-
+
if (_disableAutomaticResizing)
return;
var mask = _columnAutoResizingStyle;
if(mask === CPTableViewUniformColumnAutoresizingStyle)
- {
[self _resizeAllColumnUniformlyWithOldSize:aSize];
- }
-
- if(mask === CPTableViewLastColumnOnlyAutoresizingStyle)
- {
+ else if(mask === CPTableViewLastColumnOnlyAutoresizingStyle)
[self sizeLastColumnToFit];
- }
+ else if(mask === CPTableViewFirstColumnOnlyAutoresizingStyle)
+ [self _autoResizeFirstColumn];
+}
- if(mask === CPTableViewFirstColumnOnlyAutoresizingStyle)
- {
- var superview = [self superview];
+- (void)_autoResizeFirstColumn
+{
+ var superview = [self superview];
- if (!superview)
- return;
+ if (!superview)
+ return;
- var superviewSize = [superview bounds].size;
+ var superviewSize = [superview bounds].size;
- UPDATE_COLUMN_RANGES_IF_NECESSARY();
+ UPDATE_COLUMN_RANGES_IF_NECESSARY();
- var count = NUMBER_OF_COLUMNS();
+ var count = NUMBER_OF_COLUMNS(),
+ visColumns = [[CPArray alloc] init],
+ totalWidth = 0,
+ i = 0;
- var visColumns = [[CPArray alloc] init];
- var totalWidth = 0;
+ for(; i < count; i++)
+ {
+ if(![_tableColumns[i] isHidden])
+ {
+ [visColumns addObject:i];
+ totalWidth += [_tableColumns[i] width];
+ }
+ }
- for(var i=0; i < count; i++)
- {
- if(![_tableColumns[i] isHidden])
- {
- [visColumns addObject:i];
- totalWidth += [_tableColumns[i] width];
- }
- }
+ count = [visColumns count];
- count = [visColumns count];
+ //if there are rows
+ if (count > 0)
+ {
+ var columnToResize = _tableColumns[visColumns[0]];
+ var newWidth = superviewSize.width - totalWidth;// - [columnToResize width];
+ newWidth += [columnToResize width];
+ newWidth = (newWidth < [columnToResize minWidth]) ? [columnToResize minWidth] : newWidth;
+ newWidth = (newWidth > [columnToResize maxWidth]) ? [columnToResize maxWidth] : newWidth;
- //if there are rows
- if (count > 0)
- {
- var columnToResize = _tableColumns[visColumns[0]];
- var newWidth = superviewSize.width - totalWidth;// - [columnToResize width];
- newWidth += [columnToResize width];
- newWidth = (newWidth < [columnToResize minWidth]) ? [columnToResize minWidth] : newWidth;
- newWidth = (newWidth > [columnToResize maxWidth]) ? [columnToResize maxWidth] : newWidth;
-
- [columnToResize setWidth:FLOOR(newWidth)];
- }
-
- [self setNeedsLayout];
- }
+ [columnToResize setWidth:FLOOR(newWidth)];
+ }
+ [self setNeedsLayout];
}
- (void)_resizeAllColumnUniformlyWithOldSize:(CGSize)oldSize
{
var superview = [self superview];
-
+
if (!superview)
return;
var superviewSize = [superview bounds].size;
-
+
if (_dirtyTableColumnRangeIndex !== CPNotFound) [self _recalculateTableColumnRanges];//UPDATE_COLUMN_RANGES_IF_NECESSARY();
var count = _tableColumns.length,//NUMBER_OF_COLUMNS(),
visColumns = [[CPArray alloc] init],
buffer = 0.0;
-
+
// Fixme: cache resizable columns because they won't changes betwwen two calls to this method.
for(var i=0; i < count; i++)
{
@@ -1336,15 +1483,15 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
{
var maxXofColumns = CGRectGetMaxX([self rectOfColumn:visColumns[count - 1]]);
- // If the x value of the end of the last column is between the current bounds and the previous bounds we should snap.
+ // If the x value of the end of the last column is between the current bounds and the previous bounds we should snap.
if (!_lastColumnShouldSnap && (maxXofColumns >= superviewSize.width && maxXofColumns <= oldSize.width || maxXofColumns <= superviewSize.width && maxXofColumns >= oldSize.width))
{
//set the snap mask
_lastColumnShouldSnap = YES;
//then we need to make sure everything is set correctly.
[self _resizeAllColumnUniformlyWithOldSize:CGSizeMake(maxXofColumns, 0)];
- }
-
+ }
+
if(!_lastColumnShouldSnap)
return;
@@ -1379,8 +1526,8 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
/*!
Sets the column autoresizing style of the receiver to a given style.
- @param aStyle The column autoresizing style for the receiver.
- CPTableViewNoColumnAutoresizing, CPTableViewUniformColumnAutoresizingStyle,
+ @param aStyle The column autoresizing style for the receiver.
+ CPTableViewNoColumnAutoresizing, CPTableViewUniformColumnAutoresizingStyle,
CPTableViewLastColumnOnlyAutoresizingStyle, CPTableViewFirstColumnOnlyAutoresizingStyle
*/
- (void)setColumnAutoresizingStyle:(unsigned)style
@@ -1435,6 +1582,17 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
_numberOfRows = nil;
_numberOfRows = [self numberOfRows];
+ var oldNumberOfRows = _numberOfRows;
+
+ // remove row indexes from the selection if they no longer exist
+ var hangingSelections = oldNumberOfRows - _numberOfRows;
+
+ if (hangingSelections > 0)
+ {
+ [_selectedRowIndexes removeIndexesInRange:CPMakeRange(_numberOfRows, hangingSelections)];
+ [self _noteSelectionDidChange];
+ }
+
[self tile];
}
@@ -1653,16 +1811,17 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
- (void)_didClickTableColumn:(int)clickedColumn modifierFlags:(unsigned)modifierFlags
{
[self _sendDelegateDidClickColumn:clickedColumn];
-
+
if (_allowsColumnSelection)
{
+ [self _noteSelectionIsChanging];
if (modifierFlags & CPCommandKeyMask)
{
if ([self isColumnSelected:clickedColumn])
[self deselectColumn:clickedColumn];
else if ([self allowsMultipleSelection] == YES)
[self selectColumnIndexes:[CPIndexSet indexSetWithIndex:clickedColumn] byExtendingSelection:YES];
-
+
return;
}
else if (modifierFlags & CPShiftKeyMask)
@@ -1670,60 +1829,60 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
// should be from clickedColumn to lastClickedColum with extending:(direction == previous selection)
var startColumn = MIN(clickedColumn, [_selectedColumnIndexes lastIndex]),
endColumn = MAX(clickedColumn, [_selectedColumnIndexes firstIndex]);
-
- [self selectColumnIndexes:[CPIndexSet indexSetWithIndexesInRange:CPMakeRange(startColumn, endColumn - startColumn + 1)]
+
+ [self selectColumnIndexes:[CPIndexSet indexSetWithIndexesInRange:CPMakeRange(startColumn, endColumn - startColumn + 1)]
byExtendingSelection:YES];
-
+
return;
}
else
[self selectColumnIndexes:[CPIndexSet indexSetWithIndex:clickedColumn] byExtendingSelection:NO];
}
-
+
[self _changeSortDescriptorsForClickOnColumn:clickedColumn];
}
// From GNUSTEP
- (void)_changeSortDescriptorsForClickOnColumn:(int)column
{
- var tableColumn = [_tableColumns objectAtIndex:column],
+ var tableColumn = [_tableColumns objectAtIndex:column],
newMainSortDescriptor = [tableColumn sortDescriptorPrototype];
-
+
if (!newMainSortDescriptor)
return;
-
- var oldMainSortDescriptor = nil,
+
+ var oldMainSortDescriptor = nil,
oldSortDescriptors = [self sortDescriptors],
newSortDescriptors = [CPArray arrayWithArray:oldSortDescriptors],
-
+
e = [newSortDescriptors objectEnumerator],
descriptor = nil,
outdatedDescriptors = [CPArray array];
if ([_sortDescriptors count] > 0)
oldMainSortDescriptor = [[self sortDescriptors] objectAtIndex: 0];
-
+
// Remove every main descriptor equivalents (normally only one)
while ((descriptor = [e nextObject]) != nil)
{
if ([[descriptor key] isEqual: [newMainSortDescriptor key]])
[outdatedDescriptors addObject:descriptor];
}
-
+
// Invert the sort direction when the same column header is clicked twice
if ([[newMainSortDescriptor key] isEqual:[oldMainSortDescriptor key]])
newMainSortDescriptor = [oldMainSortDescriptor reversedSortDescriptor];
-
+
[newSortDescriptors removeObjectsInArray:outdatedDescriptors];
[newSortDescriptors insertObject:newMainSortDescriptor atIndex:0];
-
+
// Update indicator image & highlighted column before
- var image = [newMainSortDescriptor ascending] ? [CPTableView _defaultTableHeaderSortImage] : [CPTableView _defaultTableHeaderReverseSortImage];
+ var image = [newMainSortDescriptor ascending] ? [CPTableView _defaultTableHeaderSortImage] : [CPTableView _defaultTableHeaderReverseSortImage];
[self setIndicatorImage:nil inTableColumn:_currentHighlightedTableColumn];
- [self setIndicatorImage:image inTableColumn:tableColumn];
+ [self setIndicatorImage:image inTableColumn:tableColumn];
[self setHighlightedTableColumn:tableColumn];
-
+
[self setSortDescriptors:newSortDescriptors];
}
@@ -1751,19 +1910,19 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
}
- (void)setHighlightedTableColumn:(CPTableColumn)aTableColumn
-{
+{
if (_currentHighlightedTableColumn == aTableColumn)
return;
-
+
if (_headerView)
{
if (_currentHighlightedTableColumn != nil)
[[_currentHighlightedTableColumn headerView] unsetThemeState:CPThemeStateSelected];
-
+
if (aTableColumn != nil)
[[aTableColumn headerView] setThemeState:CPThemeStateSelected];
}
-
+
_currentHighlightedTableColumn = aTableColumn;
}
@@ -1782,7 +1941,7 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
return [[CPImage alloc] initWithContentsOfFile:@"Frameworks/AppKit/Resources/GenericFile.png" size:CGSizeMake(32,32)];
}
-- (CPView)dragViewForRowsWithIndexes:(CPIndexSet)theDraggedRows tableColumns:(CPArray)theTableColumns event:(CPEvent)theDragEvent offset:(CPPoint)dragViewOffset
+- (CPView)dragViewForRowsWithIndexes:(CPIndexSet)theDraggedRows tableColumns:(CPArray)theTableColumns event:(CPEvent)theDragEvent offset:(CPPointPointer)dragViewOffset
{
var bounds = [self bounds],
view = [[CPView alloc] initWithFrame:bounds];
@@ -1790,16 +1949,16 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
[view setAlphaValue:0.7];
// We have to fetch all the data views for the selected rows and columns
- // After that we can copy these add them to a transparent drag view and use that drag view
+ // After that we can copy these add them to a transparent drag view and use that drag view
// to make it appear we are dragging images of those rows (as you would do in regular Cocoa)
var columnIndex = [theTableColumns count];
- while (columnIndex--)
+ while (columnIndex--)
{
var tableColumn = [theTableColumns objectAtIndex:columnIndex],
row = [theDraggedRows firstIndex];
while (row !== CPNotFound)
- {
+ {
var dataView = [self _newDataViewForRow:row tableColumn:tableColumn];
[dataView setFrame:[self frameOfDataViewAtColumn:columnIndex row:row]];
@@ -1818,6 +1977,55 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
return view;
}
+/*!
+ @ignore
+ // Fetches all the data views (from the datasource) for the column and it's visible rows
+ // Copy the dataviews add them to a transparent drag view and use that drag view
+ // to make it appear we are dragging images of those rows (as you would do in regular Cocoa)
+*/
+- (CPView)_dragViewForColumn:(int)theColumnIndex event:(CPEvent)theDragEvent offset:(CPPointPointer)theDragViewOffset
+{
+ var dragView = [[CPView alloc] initWithFrame:CPRectMakeZero()];
+ tableColumn = [[self tableColumns] objectAtIndex:theColumnIndex],
+ bounds = CPRectMake(0.0, 0.0, [tableColumn width], CPRectGetHeight([self _exposedRect]) + 23.0),
+ columnRect = [self rectOfColumn:theColumnIndex],
+ headerView = [tableColumn headerView];
+
+ row = [_exposedRows firstIndex];
+ while (row !== CPNotFound)
+ {
+ var dataView = [self _newDataViewForRow:row tableColumn:tableColumn],
+ dataViewFrame = [self frameOfDataViewAtColumn:theColumnIndex row:row];
+
+ // Only one column is ever dragged so we just place the view at
+ dataViewFrame.origin.x = 0.0;
+
+ // Offset by table header height - scroll position
+ dataViewFrame.origin.y = ( CPRectGetMinY(dataViewFrame) - CPRectGetMinY([self _exposedRect]) ) + 23.0;
+ [dataView setFrame:dataViewFrame];
+
+ [dataView setObjectValue:[self _objectValueForTableColumn:tableColumn row:row]];
+ [dragView addSubview:dataView];
+
+ row = [_exposedRows indexGreaterThanIndex:row];
+ }
+
+ // Add the column header view
+ var headerFrame = [headerView frame];
+ headerFrame.origin = CPPointMakeZero();
+
+ columnHeaderView = [[_CPTableColumnHeaderView alloc] initWithFrame:headerFrame];
+ [columnHeaderView setStringValue:[headerView stringValue]];
+ [columnHeaderView setThemeState:[headerView themeState]];
+ [dragView addSubview:columnHeaderView];
+
+ [dragView setBackgroundColor:[CPColor whiteColor]];
+ [dragView setAlphaValue:0.7];
+ [dragView setFrame:bounds];
+
+ return dragView;
+}
+
- (void)setDraggingSourceOperationMask:(CPDragOperation)mask forLocal:(BOOL)isLocal
{
//ignoral local for the time being since only one capp app can run at a time...
@@ -1834,12 +2042,12 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
if(row > [self numberOfRows] && operation === CPTableViewDropOn)
{
var numberOfRows = [self numberOfRows] + 1;
- var reason = @"Attempt to set dropRow=" + row +
+ var reason = @"Attempt to set dropRow=" + row +
" dropOperation=CPTableViewDropOn when [0 - " + numberOfRows + "] is valid range of rows."
[[CPException exceptionWithName:@"Error" reason:reason userInfo:nil] raise];
}
-
+
_retargetedDropRow = row;
_retargetedDropOperation = operation;
@@ -2058,8 +2266,12 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
for (; columnIndex < columnsCount; ++columnIndex)
{
var column = columnArray[columnIndex],
- tableColumn = _tableColumns[column],
- tableColumnUID = [tableColumn UID];
+ tableColumn = _tableColumns[column];
+
+ if ([tableColumn isHidden] || columnIndex === _draggedColumnIndex)
+ continue;
+
+ var tableColumnUID = [tableColumn UID];
if (!_dataViewsForTableColumns[tableColumnUID])
_dataViewsForTableColumns[tableColumnUID] = [];
@@ -2078,15 +2290,15 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
[dataView setFrame:[self frameOfDataViewAtColumn:column row:row]];
[dataView setObjectValue:[self _objectValueForTableColumn:tableColumn row:row]];
- //This gives the table column an opportunity to apply the bindings.
+ //This gives the table column an opportunity to apply the bindings.
//It will override the value set in the data source, if there is a data source.
//It will do nothing if there is no value binding set.
[tableColumn prepareDataView:dataView forRow:row];
-
+
if (isColumnSelected || [self isRowSelected:row])
- [dataView setThemeState:CPThemeStateSelected];
+ [dataView setThemeState:CPThemeStateSelectedDataView];
else
- [dataView unsetThemeState:CPThemeStateSelected];
+ [dataView unsetThemeState:CPThemeStateSelectedDataView];
if (_implementedDelegateMethods & CPTableViewDelegate_tableView_willDisplayView_forTableColumn_row_)
[_delegate tableView:self willDisplayView:dataView forTableColumn:tableColumn row:row];
@@ -2135,21 +2347,21 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
columnsCount = columnArray.length;
for (; columnIndex < columnsCount; ++columnIndex)
- {
+ {
var column = columnArray[columnIndex],
tableColumn = _tableColumns[column],
tableColumnUID = [tableColumn UID],
dataViewsForTableColumn = _dataViewsForTableColumns[tableColumnUID],
columnRange = _tableColumnRanges[column];
-
+
var rowIndex = 0,
- rowsCount = rowArray.length;
+ rowsCount = rowArray.length;
for (; rowIndex < rowsCount; ++rowIndex)
{
var row = rowArray[rowIndex],
- dataView = dataViewsForTableColumn[row];
-
+ dataView = dataViewsForTableColumn[row];
+
[dataView setFrame:[self frameOfDataViewAtColumn:column row:row]];
}
}
@@ -2170,13 +2382,16 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
var dataView = [_delegate tableView:self dataViewForTableColumn:aTableColumn row:aRow];
[aTableColumn setDataView:dataView];
}
-
-
+
+
return [aTableColumn _newDataViewForRow:aRow];
}
- (void)_enqueueReusableDataView:(CPView)aDataView
{
+ if (!aDataView)
+ return;
+
// FIXME: yuck!
var identifier = aDataView.identifier;
@@ -2205,15 +2420,24 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
}
- (void)_drawRect:(CGRect)aRect
-{
+{
// FIX ME: All three of these methods will likely need to be rewritten for 1.0
// We've got grid drawing in highlightSelection and crap everywhere.
-
+
var exposedRect = [self _exposedRect];
[self drawBackgroundInClipRect:exposedRect];
[self drawGridInClipRect:exposedRect];
[self highlightSelectionInClipRect:exposedRect];
+
+ if (_draggedColumnIndex === -1)
+ return;
+
+ var context = [[CPGraphicsContext currentContext] graphicsPort],
+ columnRect = [self rectOfColumn:_draggedColumnIndex];
+
+ CGContextSetFillColor(context, [CPColor grayColor]);
+ CGContextFillRect(context, columnRect);
}
- (void)drawBackgroundInClipRect:(CGRect)aRect
@@ -2221,7 +2445,6 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
if (!_usesAlternatingRowBackgroundColors)
return;
-
var rowColors = [self alternatingRowBackgroundColors],
colorCount = [rowColors count];
@@ -2359,6 +2582,9 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
- (void)highlightSelectionInClipRect:(CGRect)aRect
{
+ if (_selectionHighlightStyle === CPTableViewSelectionHighlightStyleNone)
+ return;
+
var context = [[CPGraphicsContext currentContext] graphicsPort],
indexes = [],
rectSelector = @selector(rectOfRow:);
@@ -2387,34 +2613,33 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
if (!count)
return;
-
- var drawGradient = (_selectionHighlightStyle === CPTableViewSelectionHighlightStyleSourceList && [_selectedRowIndexes count] >= 1);
-
- var deltaHeight = 0.5 * (_gridStyleMask & CPTableViewSolidHorizontalGridLineMask);
+
+ var drawGradient = (_selectionHighlightStyle === CPTableViewSelectionHighlightStyleSourceList && [_selectedRowIndexes count] >= 1),
+ deltaHeight = 0.5 * (_gridStyleMask & CPTableViewSolidHorizontalGridLineMask);
CGContextBeginPath(context);
while (count--)
{
var rowRect = CGRectIntersection(objj_msgSend(self, rectSelector, indexes[count]), aRect);
CGContextAddRect(context, rowRect);
-
+
if (drawGradient)
{
var minX = _CGRectGetMinX(rowRect),
minY = _CGRectGetMinY(rowRect),
maxX = _CGRectGetMaxX(rowRect),
maxY = _CGRectGetMaxY(rowRect) - deltaHeight;
-
+
CGContextDrawLinearGradient(context, _sourceListActiveGradient, rowRect.origin, CGPointMake(minX, maxY), 0);
CGContextClosePath(context);
-
+
CGContextBeginPath(context);
CGContextMoveToPoint(context, minX, minY);
CGContextAddLineToPoint(context, maxX, minY);
CGContextClosePath(context);
CGContextSetStrokeColor(context, _sourceListActiveTopLineColor);
CGContextStrokePath(context);
-
+
CGContextBeginPath(context);
CGContextMoveToPoint(context, minX, maxY);
CGContextAddLineToPoint(context, maxX, maxY - 1);
@@ -2423,15 +2648,15 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
CGContextStrokePath(context);
}
}
-
+
CGContextClosePath(context);
-
+
if (!drawGradient)
{
- [[CPColor selectionColor] setFill];
+ [_selectionHighlightColor setFill];
CGContextFillPath(context);
}
-
+
CGContextBeginPath(context);
gridStyleMask = [self gridStyleMask];
for(var i=0; i < count2; i++)
@@ -2450,19 +2675,18 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
exposedRange = CPMakeRange(firstExposedColumn, [exposedColumns lastIndex] - firstExposedColumn + 1);
[exposedColumns getIndexes:exposedColumnIndexes maxCount:-1 inIndexRange:exposedRange];
var exposedColumnCount = [exposedColumnIndexes count];
-
+
for(var c = firstExposedColumn; c < exposedColumnCount; c++)
{
- //console.log(columnIndexes);
var colRect = [self rectOfColumn:exposedColumnIndexes[c]],
colX = CGRectGetMaxX(colRect) + 0.5;
- //console.log(colX);
+
CGContextMoveToPoint(context, colX, minY);
CGContextAddLineToPoint(context, colX, maxY);
}
}
-
+
//if the row after the current row is not selected then there is no need to draw the bottom grid line white.
if([indexes containsObject:indexes[i]+1])
{
@@ -2556,9 +2780,9 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
else
_selectionAnchorRow = row;
-
- //set ivars for startTrackingPoint and time...
- _startTrackingPoint = aPoint;
+
+ //set ivars for startTrackingPoint and time...
+ _startTrackingPoint = aPoint;
_startTrackingTimestamp = new Date();
if (_implementedDataSourceMethods & CPTableViewDataSource_tableView_setObjectValue_forTableColumn_row_)
@@ -2580,7 +2804,10 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
{
// Prevent CPControl from eating the mouse events when we are in a drag session
if (![_draggedRowIndexes count])
+ {
+ [self autoscroll:anEvent];
[super trackMouse:anEvent];
+ }
else
[CPApp sendEvent:anEvent];
}
@@ -2592,11 +2819,11 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
{
var row = [self rowAtPoint:aPoint];
- // begin the drag is the datasource lets us, we've move at least +-3px vertical or horizontal,
+ // begin the drag is the datasource lets us, we've move at least +-3px vertical or horizontal,
// or we're dragging from selected rows and we haven't begun a drag session
if(!_isSelectingSession && _implementedDataSourceMethods & CPTableViewDataSource_tableView_writeRowsWithIndexes_toPasteboard_)
{
- if (row >= 0 && (ABS(_startTrackingPoint.x - aPoint.x) > 3 || (_verticalMotionCanDrag && ABS(_startTrackingPoint.y - aPoint.y) > 3)) ||
+ if (row >= 0 && (ABS(_startTrackingPoint.x - aPoint.x) > 3 || (_verticalMotionCanDrag && ABS(_startTrackingPoint.y - aPoint.y) > 3)) ||
([_selectedRowIndexes containsIndex:row]))
{
if ([_selectedRowIndexes containsIndex:row])
@@ -2613,33 +2840,33 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
var currentEvent = [CPApp currentEvent],
offset = CPPointMakeZero(),
tableColumns = [_tableColumns objectsAtIndexes:_exposedColumns];
-
+
// We deviate from the default Cocoa implementation here by asking for a view in stead of an image
// We support both, but the view prefered over the image because we can mimic the rows we are dragging
// by re-creating the data views for the dragged rows
- var view = [self dragViewForRowsWithIndexes:_draggedRowIndexes
- tableColumns:tableColumns
- event:currentEvent
+ var view = [self dragViewForRowsWithIndexes:_draggedRowIndexes
+ tableColumns:tableColumns
+ event:currentEvent
offset:offset];
-
+
if (!view)
{
- var image = [self dragImageForRowsWithIndexes:_draggedRowIndexes
- tableColumns:tableColumns
- event:currentEvent
+ var image = [self dragImageForRowsWithIndexes:_draggedRowIndexes
+ tableColumns:tableColumns
+ event:currentEvent
offset:offset];
view = [[CPImageView alloc] initWithFrame:CPMakeRect(0, 0, [image size].width, [image size].height)];
[view setImage:image];
}
-
+
var bounds = [view bounds];
var viewLocation = CPPointMake(aPoint.x - CGRectGetWidth(bounds)/2 + offset.x, aPoint.y - CGRectGetHeight(bounds)/2 + offset.y);
[self dragView:view at:viewLocation offset:CPPointMakeZero() event:[CPApp currentEvent] pasteboard:pboard source:self slideBack:YES];
_startTrackingPoint = nil;
-
+
return NO;
}
-
+
// The delegate disallowed the drag so clear the dragged row indexes
_draggedRowIndexes = [CPIndexSet indexSet];
}
@@ -2715,10 +2942,7 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
shouldEdit = [_delegate tableView:self shouldEditTableColumn:column row:rowIndex];
if (shouldEdit)
{
- _editingCellIndex = CGPointMake(columnIndex, rowIndex);
- [self reloadDataForRowIndexes:[CPIndexSet indexSetWithIndex:rowIndex]
- columnIndexes:[CPIndexSet indexSetWithIndex:columnIndex]];
-
+ [self editColumn:columnIndex row:rowIndex withEvent:nil select:YES];
return;
}
}
@@ -2743,17 +2967,17 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
if(_retargetedDropRow !== nil)
row = _retargetedDropRow;
-
- var draggedTypes = [self registeredDraggedTypes],
+
+ var draggedTypes = [self registeredDraggedTypes],
count = [draggedTypes count],
i = 0;
-
- for (; i < count; i++)
- {
- if ([[[sender draggingPasteboard] types] containsObject:[draggedTypes objectAtIndex: i]])
- return [self _validateDrop:sender proposedRow:row proposedDropOperation:dropOperation];
+
+ for (; i < count; i++)
+ {
+ if ([[[sender draggingPasteboard] types] containsObject:[draggedTypes objectAtIndex: i]])
+ return [self _validateDrop:sender proposedRow:row proposedDropOperation:dropOperation];
}
-
+
return CPDragOperationNone;
}
@@ -2793,7 +3017,7 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
*/
- (CPTableViewDropOperation)_proposedDropOperationAtPoint:(CGPoint)theDragPoint
{
- if(_retargetedDropOperation !== nil)
+ if(_retargetedDropOperation !== nil)
return _retargetedDropOperation;
var row = [self _proposedRowAtPoint:theDragPoint],
@@ -2803,13 +3027,13 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
// This probably doesn't work if the row height is smaller than or around 5.0
if ([self intercellSpacing].height < 5.0)
rowRect = CPRectInset(rowRect, 0.0, 5.0 - [self intercellSpacing].height);
-
+
// If the altered row rect contains the drag point we show the drop on
- // We don't show the drop on indicator if we are dragging below the last row
+ // We don't show the drop on indicator if we are dragging below the last row
// in that case we always want to show the drop above indicator
- if (CGRectContainsPoint(rowRect, theDragPoint) && row < _numberOfRows)
+ if (CGRectContainsPoint(rowRect, theDragPoint) && row < _numberOfRows)
return CPTableViewDropOn;
-
+
return CPTableViewDropAbove;
}
@@ -2821,18 +3045,18 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
// We don't use rowAtPoint here because the drag indicator can appear below the last row
// and rowAtPoint doesn't return rows that are larger than numberOfRows
var row = FLOOR(dragPoint.y / ( _rowHeight + _intercellSpacing.height ));
-
+
// Determine if the mouse is currently closer to this row or the row below it
var lowerRow = row + 1,
rect = [self rectOfRow:row],
lowerRect = [self rectOfRow:lowerRow];
-
+
if (ABS(CPRectGetMinY(lowerRect) - dragPoint.y) < ABS(dragPoint.y - CPRectGetMinY(rect)))
row = lowerRow;
if (row >= [self numberOfRows])
row = [self numberOfRows];
-
+
return row;
}
@@ -2848,7 +3072,7 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
{
if (theRowIndex >= [self numberOfRows])
theRowIndex = [self numberOfRows] - 1;
-
+
return [self rectOfRow:theRowIndex];
}
@@ -2869,38 +3093,31 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
var row = [self _proposedRowAtPoint:location],
dragOperation = [self _validateDrop:sender proposedRow:row proposedDropOperation:dropOperation];
exposedClipRect = [self exposedClipRect];
-
+
if(_retargetedDropRow !== nil)
row = _retargetedDropRow;
-
+
if (dropOperation === CPTableViewDropOn && row >= [self numberOfRows])
row = [self numberOfRows] - 1;
var rect = CPRectMakeZero();
-
+
if (row === -1)
rect = exposedClipRect;
-
+
else if (dropOperation === CPTableViewDropAbove)
rect = [self _rectForDropHighlightViewBetweenUpperRow:row - 1 andLowerRow:row offset:location];
-
- else
+
+ else
rect = [self _rectForDropHighlightViewOnRow:row];
-
+
[_dropOperationFeedbackView setDropOperation:row !== -1 ? dropOperation : CPDragOperationNone];
[_dropOperationFeedbackView setHidden:(dragOperation == CPDragOperationNone)];
[_dropOperationFeedbackView setFrame:rect];
[_dropOperationFeedbackView setCurrentRow:row];
[self addSubview:_dropOperationFeedbackView];
-
- // FIXME : Maybe we should do this in a timer outside this method.
- // Problem: we don't know when the scroll ends or when the next -draggingUpdated is called.
- if (row > 0 && location.y - CGRectGetMinY(exposedClipRect) < _rowHeight)
- [self scrollRowToVisible:row - 1];
- else if (row < numberOfRows && CGRectGetMaxY(exposedClipRect) - location.y < _rowHeight)
- [self scrollRowToVisible:row + 1];
-
+
return dragOperation;
}
@@ -2953,7 +3170,7 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
we're using this because we drag views instead of images so we can get the rows themselves to actually drag
*/
- (void)draggedView:(CPImage)aView endedAt:(CGPoint)aLocation operation:(CPDragOperation)anOperation
-{
+{
[self _draggingEnded];
[self draggedImage:aView endedAt:aLocation operation:anOperation];
}
@@ -2990,7 +3207,7 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
else if (_allowsMultipleSelection)
{
newSelection = [CPIndexSet indexSetWithIndexesInRange:CPMakeRange(MIN(aRow, _selectionAnchorRow), ABS(aRow - _selectionAnchorRow) + 1)];
- shouldExtendSelection = [self mouseDownFlags] & CPShiftKeyMask &&
+ shouldExtendSelection = [self mouseDownFlags] & CPShiftKeyMask &&
((_lastSelectedRow == [_selectedRowIndexes lastIndex] && aRow > _lastSelectedRow) ||
(_lastSelectedRow == [_selectedRowIndexes firstIndex] && aRow < _lastSelectedRow));
}
@@ -3027,9 +3244,9 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
[newSelection removeIndex:index];
}
}
-
+
_lastSelectedRow = ([newSelection count] > 0) ? aRow : -1;
-
+
// if empty selection is not allowed and the new selection has nothing selected, abort
if (!_allowsEmptySelection && [newSelection count] === 0)
return;
@@ -3068,7 +3285,7 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
- (void)keyDown:(CPEvent)anEvent
{
- [self interpretKeyEvents:[CPArray arrayWithObject:anEvent]];
+ [self interpretKeyEvents:[anEvent]];
}
- (void)moveDown:(id)sender
@@ -3128,10 +3345,10 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
if([[self selectedRowIndexes] count] > 0)
{
var extend = NO;
-
+
if(([anEvent modifierFlags] & CPShiftKeyMask) && _allowsMultipleSelection)
extend = YES;
-
+
var i = [[self selectedRowIndexes] firstIndex];
if(i > 0)
i--; //set index to the prev row before the first row selected
@@ -3143,24 +3360,24 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
if([self numberOfRows] > 0)
var i = [self numberOfRows] - 1; //select the first row
}
-
-
+
+
if(_implementedDelegateMethods & CPTableViewDelegate_tableView_shouldSelectRow_)
{
-
+
while((![_delegate tableView:self shouldSelectRow:i]) && i > 0)
{
//check to see if the row can be selected if it can't be then see if the prev row can be selected
i--;
}
-
+
//if the index still can be selected after the loop then just return
if(![_delegate tableView:self shouldSelectRow:i])
return;
}
-
+
[self selectRowIndexes:[CPIndexSet indexSetWithIndex:i] byExtendingSelection:extend];
-
+
if(i >= 0)
[self scrollRowToVisible:i];
}
@@ -3225,53 +3442,32 @@ var CPTableViewDataSourceKey = @"CPTableViewDataSourceKey",
_allowsEmptySelection = [aCoder decodeBoolForKey:CPTableViewEmptySelectionKey];
_allowsColumnSelection = [aCoder decodeBoolForKey:CPTableViewColumnSelectionKey];
- _tableViewFlags = 0;
-
//Setting Display Attributes
_selectionHighlightStyle = CPTableViewSelectionHighlightStyleRegular;
- _usesAlternatingRowBackgroundColors = [aCoder decodeBoolForKey:CPTableViewUsesAlternatingBackgroundKey];
- [self setAlternatingRowBackgroundColors:[[CPColor whiteColor], [CPColor colorWithHexString:@"e4e7ff"]]];
-
- _tableColumns = [aCoder decodeObjectForKey:CPTableViewTableColumnsKey];
+ _tableColumns = [aCoder decodeObjectForKey:CPTableViewTableColumnsKey] || [];
[_tableColumns makeObjectsPerformSelector:@selector(setTableView:) withObject:self];
- _tableColumnRanges = [];
- _dirtyTableColumnRangeIndex = 0;
- _numberOfHiddenColumns = 0;
-
- _objectValues = { };
- _dataViewsForTableColumns = { };
- _dataViews= [];
- _numberOfRows = 0;
- _exposedRows = [CPIndexSet indexSet];
- _exposedColumns = [CPIndexSet indexSet];
- _cachedDataViews = { };
- _rowHeight = [aCoder decodeFloatForKey:CPTableViewRowHeightKey];
-
- if ([aCoder containsValueForKey:CPTableViewIntercellSpacingKey])
- _intercellSpacing = [aCoder decodeSizeForKey:CPTableViewIntercellSpacingKey];
+ if ([aCoder containsValueForKey:CPTableViewRowHeightKey])
+ _rowHeight = [aCoder decodeFloatForKey:CPTableViewRowHeightKey];
else
- _intercellSpacing = _CGSizeMake(0.0, 0.0);
-
+ _rowHeight = 23.0;
+
+ _intercellSpacing = [aCoder decodeSizeForKey:CPTableViewIntercellSpacingKey] || _CGSizeMake(0.0, 0.0);
+
_gridColor = [aCoder decodeObjectForKey:CPTableViewGridColorKey] || [CPColor grayColor];
_gridStyleMask = [aCoder decodeIntForKey:CPTableViewGridStyleMaskKey] || CPTableViewGridNone;
- _alternatingRowBackgroundColors = [aCoder decodeObjectForKey:CPTableViewAlternatingRowColorsKey];
_usesAlternatingRowBackgroundColors = [aCoder decodeObjectForKey:CPTableViewUsesAlternatingBackgroundKey]
-
+ _alternatingRowBackgroundColors =
+ [[CPColor whiteColor], [CPColor colorWithRed:245.0 / 255.0 green:249.0 / 255.0 blue:252.0 / 255.0 alpha:1.0]];
+
_headerView = [aCoder decodeObjectForKey:CPTableViewHeaderViewKey];
_cornerView = [aCoder decodeObjectForKey:CPTableViewCornerViewKey];
- _selectedColumnIndexes = [CPIndexSet indexSet];
- _selectedRowIndexes = [CPIndexSet indexSet];
-
_dataSource = [aCoder decodeObjectForKey:CPTableViewDataSourceKey];
_delegate = [aCoder decodeObjectForKey:CPTableViewDelegateKey];
- _tableDrawView = [[_CPTableDrawView alloc] initWithTableView:self];
- [_tableDrawView setBackgroundColor:[CPColor clearColor]];
- [self addSubview:_tableDrawView];
[self _init];
[self viewWillMoveToSuperview:[self superview]];
@@ -3289,7 +3485,7 @@ var CPTableViewDataSourceKey = @"CPTableViewDataSourceKey",
[aCoder encodeFloat:_rowHeight forKey:CPTableViewRowHeightKey];
[aCoder encodeSize:_intercellSpacing forKey:CPTableViewIntercellSpacingKey];
-
+
[aCoder encodeBool:_allowsMultipleSelection forKey:CPTableViewMultipleSelectionKey];
[aCoder encodeBool:_allowsEmptySelection forKey:CPTableViewEmptySelectionKey];
[aCoder encodeBool:_allowsColumnReordering forKey:CPTableViewColumnReorderingKey];
@@ -3297,10 +3493,10 @@ var CPTableViewDataSourceKey = @"CPTableViewDataSourceKey",
[aCoder encodeBool:_allowsColumnSelection forKey:CPTableViewColumnSelectionKey];
[aCoder encodeObject:_tableColumns forKey:CPTableViewTableColumnsKey];
-
+
[aCoder encodeObject:_gridColor forKey:CPTableViewGridColorKey];
[aCoder encodeInt:_gridStyleMask forKey:CPTableViewGridStyleMaskKey];
-
+
[aCoder encodeBool:_usesAlternatingRowBackgroundColors forKey:CPTableViewUsesAlternatingBackgroundKey];
[aCoder encodeObject:_alternatingRowBackgroundColors forKey:CPTableViewAlternatingRowColorsKey]
@@ -3310,20 +3506,6 @@ var CPTableViewDataSourceKey = @"CPTableViewDataSourceKey",
@end
-@implementation CPColor (tableview)
-
-+ (CPColor)selectionColor
-{
- return [CPColor colorWithHexString:@"5f83b9"];
-}
-
-+ (CPColor)selectionColorSourceView
-{
- return [CPColor colorWithPatternImage:[[CPImage alloc] initByReferencingFile:@"Resources/tableviewselection.png" size:CGSizeMake(6,22)]];
-}
-
-@end
-
@implementation CPIndexSet (tableview)
- (void)removeMatches:otherSet
@@ -3352,23 +3534,24 @@ var CPTableViewDataSourceKey = @"CPTableViewDataSourceKey",
unsigned dropOperation @accessors;
CPTableView tableView @accessors;
int currentRow @accessors;
+ BOOL isBlinking @accessors;
}
- (void)drawRect:(CGRect)aRect
{
- if(tableView._destinationDragStyle === CPTableViewDraggingDestinationFeedbackStyleNone)
+ if(tableView._destinationDragStyle === CPTableViewDraggingDestinationFeedbackStyleNone || isBlinking)
return;
-
+
var context = [[CPGraphicsContext currentContext] graphicsPort];
CGContextSetStrokeColor(context, [CPColor colorWithHexString:@"4886ca"]);
CGContextSetLineWidth(context, 3);
-
+
if (currentRow === -1)
{
CGContextStrokeRect(context, [self bounds]);
}
-
+
else if (dropOperation === CPTableViewDropOn)
{
//if row is selected don't fill and stroke white
@@ -3387,7 +3570,7 @@ var CPTableViewDataSourceKey = @"CPTableViewDataSourceKey",
}
CGContextStrokeRoundedRectangleInRect(context, newRect, 8, YES, YES, YES, YES);
- }
+ }
else if (dropOperation === CPTableViewDropAbove)
{
//reposition the view up a tad
@@ -3422,7 +3605,28 @@ var CPTableViewDataSourceKey = @"CPTableViewDataSourceKey",
CGContextStrokePath(context);
//CGContextStrokeLineSegments(context, [aRect.origin.x + 8, aRect.origin.y + 8, 300 , aRect.origin.y + 8]);
}
-
+}
+- (void)blink
+{
+ if (dropOperation !== CPTableViewDropOn)
+ return;
+
+ isBlinking = YES;
+
+ var showCallback = function() {
+ objj_msgSend(self, "setHidden:", NO)
+ isBlinking = NO;
+ }
+
+ var hideCallback = function() {
+ objj_msgSend(self, "setHidden:", YES)
+ isBlinking = YES;
+ }
+
+ objj_msgSend(self, "setHidden:", YES);
+ [CPTimer scheduledTimerWithTimeInterval:0.1 callback:showCallback repeats:NO];
+ [CPTimer scheduledTimerWithTimeInterval:0.19 callback:hideCallback repeats:NO];
+ [CPTimer scheduledTimerWithTimeInterval:0.27 callback:showCallback repeats:NO];
}
@end
diff --git a/AppKit/CPTextField.j b/AppKit/CPTextField.j
index 7459fa772..346301121 100644
--- a/AppKit/CPTextField.j
+++ b/AppKit/CPTextField.j
@@ -997,7 +997,7 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
return bounds;
}
-- (CGRect)bezelRectForBounds:(CFRect)bounds
+- (CGRect)bezelRectForBounds:(CGRect)bounds
{
var bezelInset = [self currentValueForThemeAttribute:@"bezel-inset"];
@@ -1087,6 +1087,22 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
}
}
+- (void)takeValueFromKeyPath:(CPString)aKeyPath ofObjects:(CPArray)objects
+{
+ var count = objects.length,
+ value = [objects[0] valueForKeyPath:aKeyPath];
+
+ [self setStringValue:value];
+ [self setPlaceholderString:@""];
+
+ while (count-- > 1)
+ if (value !== [objects[count] valueForKeyPath:aKeyPath])
+ {
+ [self setPlaceholderString:@"Multiple Values"];
+ [self setStringValue:@""];
+ }
+}
+
@end
var secureStringForString = function(aString)
diff --git a/AppKit/CPTheme.j b/AppKit/CPTheme.j
index 77bac886d..4b37e6d7a 100644
--- a/AppKit/CPTheme.j
+++ b/AppKit/CPTheme.j
@@ -242,6 +242,7 @@ CPThemeStateNormal = CPThemeStates["normal"] = 0;
CPThemeStateDisabled = CPThemeState("disabled");
CPThemeStateHighlighted = CPThemeState("highlighted");
CPThemeStateSelected = CPThemeState("selected");
+CPThemeStateSelectedDataView = CPThemeState("selectedDataView");
CPThemeStateBezeled = CPThemeState("bezeled");
CPThemeStateBordered = CPThemeState("bordered");
CPThemeStateEditable = CPThemeState("editable");
diff --git a/AppKit/CPToolbar.j b/AppKit/CPToolbar.j
index f78f891b6..b45d70211 100644
--- a/AppKit/CPToolbar.j
+++ b/AppKit/CPToolbar.j
@@ -329,7 +329,11 @@ var CPToolbarConfigurationsByIdentifier = nil;
return _itemsSortedByVisibilityPriority;
}
-- (void)validateVisibleToolbarItems
+/*!
+ Validates the visible toolbar items by sending a validate message to
+ each visible toolbar item.
+*/
+- (void)validateVisibleItems
{
var toolbarItems = [self visibleItems],
count = [toolbarItems count];
diff --git a/AppKit/CPToolbarItem.j b/AppKit/CPToolbarItem.j
index 57e33cdfc..e5148576e 100644
--- a/AppKit/CPToolbarItem.j
+++ b/AppKit/CPToolbarItem.j
@@ -449,6 +449,9 @@ CPToolbarItemVisibilityPriorityUser
- (void)validate
{
+ var action = [self action],
+ target = [self target];
+
// View items do not do any target-action analysis.
if (_view)
{
@@ -458,13 +461,9 @@ CPToolbarItemVisibilityPriorityUser
return;
}
- var action = [self action];
-
if (!action)
return [self setEnabled:NO];
- var target = [self target];
-
if (target && ![target respondsToSelector:action])
return [self setEnabled:NO];
diff --git a/AppKit/CPView.j b/AppKit/CPView.j
index c3b2499b8..3085a06fe 100644
--- a/AppKit/CPView.j
+++ b/AppKit/CPView.j
@@ -94,7 +94,8 @@ var DOMElementPrototype = nil,
BackgroundTrivialColor = 0,
BackgroundVerticalThreePartImage = 1,
BackgroundHorizontalThreePartImage = 2,
- BackgroundNinePartImage = 3;
+ BackgroundNinePartImage = 3,
+ BackgroundTransparentColor = 4;
#endif
var CPViewFlags = { },
@@ -139,6 +140,7 @@ var CPViewFlags = { },
BOOL _isHidden;
BOOL _hitTests;
+ BOOL _clipsToBounds;
BOOL _postsFrameChangedNotifications;
BOOL _postsBoundsChangedNotifications;
@@ -277,6 +279,7 @@ var CPViewFlags = { },
_autoresizingMask = CPViewNotSizable;
_autoresizesSubviews = YES;
+ _clipsToBounds = YES;
_opacity = 1.0;
_isHidden = NO;
@@ -835,28 +838,33 @@ var CPViewFlags = { },
if (_backgroundType !== BackgroundTrivialColor)
{
- var images = [[_backgroundColor patternImage] imageSlices];
-
- if (_backgroundType === BackgroundVerticalThreePartImage)
+ if (_backgroundType === BackgroundTransparentColor)
{
- CPDOMDisplayServerSetStyleSize(_DOMImageParts[1], size.width, size.height - _DOMImageSizes[0].height - _DOMImageSizes[2].height);
+ CPDOMDisplayServerSetStyleSize(_DOMImageParts[0], size.width, size.height);
}
-
- else if (_backgroundType === BackgroundHorizontalThreePartImage)
+ else
{
- CPDOMDisplayServerSetStyleSize(_DOMImageParts[1], size.width - _DOMImageSizes[0].width - _DOMImageSizes[2].width, size.height);
- }
+ var images = [[_backgroundColor patternImage] imageSlices];
- else if (_backgroundType === BackgroundNinePartImage)
- {
- var width = size.width - _DOMImageSizes[0].width - _DOMImageSizes[2].width,
- height = size.height - _DOMImageSizes[0].height - _DOMImageSizes[6].height;
+ if (_backgroundType === BackgroundVerticalThreePartImage)
+ {
+ CPDOMDisplayServerSetStyleSize(_DOMImageParts[1], size.width, size.height - _DOMImageSizes[0].height - _DOMImageSizes[2].height);
+ }
+ else if (_backgroundType === BackgroundHorizontalThreePartImage)
+ {
+ CPDOMDisplayServerSetStyleSize(_DOMImageParts[1], size.width - _DOMImageSizes[0].width - _DOMImageSizes[2].width, size.height);
+ }
+ else if (_backgroundType === BackgroundNinePartImage)
+ {
+ var width = size.width - _DOMImageSizes[0].width - _DOMImageSizes[2].width,
+ height = size.height - _DOMImageSizes[0].height - _DOMImageSizes[6].height;
- CPDOMDisplayServerSetStyleSize(_DOMImageParts[1], width, _DOMImageSizes[0].height);
- CPDOMDisplayServerSetStyleSize(_DOMImageParts[3], _DOMImageSizes[3].width, height);
- CPDOMDisplayServerSetStyleSize(_DOMImageParts[4], width, height);
- CPDOMDisplayServerSetStyleSize(_DOMImageParts[5], _DOMImageSizes[5].width, height);
- CPDOMDisplayServerSetStyleSize(_DOMImageParts[7], width, _DOMImageSizes[7].height);
+ CPDOMDisplayServerSetStyleSize(_DOMImageParts[1], width, _DOMImageSizes[0].height);
+ CPDOMDisplayServerSetStyleSize(_DOMImageParts[3], _DOMImageSizes[3].width, height);
+ CPDOMDisplayServerSetStyleSize(_DOMImageParts[4], width, height);
+ CPDOMDisplayServerSetStyleSize(_DOMImageParts[5], _DOMImageSizes[5].width, height);
+ CPDOMDisplayServerSetStyleSize(_DOMImageParts[7], width, _DOMImageSizes[7].height);
+ }
}
}
#endif
@@ -1188,6 +1196,23 @@ var CPViewFlags = { },
return _isHidden;
}
+- (void)setClipsToBounds:(BOOL)shouldClip
+{
+ if (_clipsToBounds === shouldClip)
+ return;
+
+ _clipsToBounds = shouldClip;
+
+#if PLATFORM(DOM)
+ _DOMElement.style.overflow = _clipsToBounds ? "hidden" : "visible";
+#endif
+}
+
+- (BOOL)clipsToBounds
+{
+ return _clipsToBounds;
+}
+
/*!
Sets the opacity of the receiver. The value must be in the range of 0.0 to 1.0, where 0.0 is
completely transparent and 1.0 is completely opaque.
@@ -1361,7 +1386,7 @@ var CPViewFlags = { },
}
else
{
- _backgroundType = BackgroundTrivialColor;
+ _backgroundType = colorNeedsDOMElement ? BackgroundTransparentColor : BackgroundTrivialColor;
amount = (colorNeedsDOMElement ? 1 : 0) - _DOMImageParts.length;
}
@@ -1384,7 +1409,7 @@ var CPViewFlags = { },
_DOMElement.removeChild(_DOMImageParts.pop());
}
- if (_backgroundType === BackgroundTrivialColor)
+ if (_backgroundType === BackgroundTrivialColor || _backgroundType === BackgroundTransparentColor)
{
var colorCSS = colorExists ? [_backgroundColor cssString] : "";
diff --git a/AppKit/CPViewAnimation.j b/AppKit/CPViewAnimation.j
index 692523584..b1bc4d414 100644
--- a/AppKit/CPViewAnimation.j
+++ b/AppKit/CPViewAnimation.j
@@ -1,5 +1,5 @@
/*
- * CPFlashView.j
+ * CPViewAnimation.j
* AppKit
*
* Created by Klaas Pieter Annema on September 3, 2009.
@@ -22,6 +22,8 @@
@import
+#include "CoreGraphics/CGGeometry.h"
+
CPViewAnimationTargetKey = @"CPViewAnimationTarget";
CPViewAnimationStartFrameKey = @"CPViewAnimationStartFrame";
CPViewAnimationEndFrameKey = @"CPViewAnimationEndFrame";
@@ -69,7 +71,7 @@ CPViewAnimationFadeOutEffect = @"CPViewAnimationFadeOut";
[super startAnimation];
}
-- (void)setCurrentProgress:(NSAnimationProgress)progress
+- (void)setCurrentProgress:(CPAnimationProgress)progress
{
[super setCurrentProgress:progress];
@@ -80,14 +82,14 @@ CPViewAnimationFadeOutEffect = @"CPViewAnimationFadeOut";
view = [self _targetView:dictionary]
startFrame = [self _startFrame:dictionary]
endFrame = [self _endFrame:dictionary]
- differenceFrame = CPRectMakeZero();
+ differenceFrame = _CGRectMakeZero();
differenceFrame.origin.x = endFrame.origin.x - startFrame.origin.x;
differenceFrame.origin.y = endFrame.origin.y - startFrame.origin.y;
differenceFrame.size.width = endFrame.size.width - startFrame.size.width;
differenceFrame.size.height = endFrame.size.height - startFrame.size.height;
- var intermediateFrame = CPRectMakeZero();
+ var intermediateFrame = _CGRectMakeZero();
intermediateFrame.origin.x = startFrame.origin.x + differenceFrame.origin.x * progress;
intermediateFrame.origin.y = startFrame.origin.y + differenceFrame.origin.y * progress;
intermediateFrame.size.width = startFrame.size.width + differenceFrame.size.width * progress;
@@ -103,7 +105,7 @@ CPViewAnimationFadeOutEffect = @"CPViewAnimationFadeOut";
[view setAlphaValue:1.0 + ( 0.0 - 1.0 ) * progress];
if (progress === 1.0)
- [view setHidden:CPRectIsNull(endFrame) || [view alphaValue] === 0.0];
+ [view setHidden:_CGRectIsNull(endFrame) || [view alphaValue] === 0.0];
}
}
@@ -124,7 +126,7 @@ CPViewAnimationFadeOutEffect = @"CPViewAnimationFadeOut";
else if (effect === CPViewAnimationFadeOutEffect)
[view setAlphaValue:0.0];
- [view setHidden:CPRectIsNull(endFrame) || [view alphaValue] === 0.0];
+ [view setHidden:_CGRectIsNull(endFrame) || [view alphaValue] === 0.0];
}
[super stopAnimation];
@@ -139,7 +141,7 @@ CPViewAnimationFadeOutEffect = @"CPViewAnimationFadeOut";
return targetView;
}
-- (CPRect)_startFrame:(CPDictionary)dictionary
+- (CGRect)_startFrame:(CPDictionary)dictionary
{
var startFrame = [dictionary valueForKey:CPViewAnimationStartFrameKey];
if (!startFrame)
@@ -148,7 +150,7 @@ CPViewAnimationFadeOutEffect = @"CPViewAnimationFadeOut";
return startFrame;
}
-- (CPRect)_endFrame:(CPDictionary)dictionary
+- (CGRect)_endFrame:(CPDictionary)dictionary
{
var endFrame = [dictionary valueForKey:CPViewAnimationEndFrameKey];
if (!endFrame)
diff --git a/AppKit/CPWebView.j b/AppKit/CPWebView.j
index 38ddfb5fa..bf36a7773 100644
--- a/AppKit/CPWebView.j
+++ b/AppKit/CPWebView.j
@@ -69,11 +69,13 @@ CPWebViewScrollNative = 2;
CPString _url;
CPString _html;
-
+
Function _loadCallback;
-
+
int _scrollMode;
CGSize _scrollSize;
+
+ int _loadHTMLStringTimer;
}
- (id)initWithFrame:(CPRect)frameRect frameName:(CPString)frameName groupName:(CPString)groupName
@@ -110,6 +112,7 @@ CPWebViewScrollNative = 2;
_iframe.style.width = "100%";
_iframe.style.height = "100%";
_iframe.style.borderWidth = "0px";
+ _iframe.frameBorder = "0";
[self setDrawsBackground:YES];
@@ -171,7 +174,32 @@ CPWebViewScrollNative = 2;
[self _resizeWebFrame];
}
-- (BOOL)_resizeWebFrame
+- (void)_attachScrollEventIfNecessary
+{
+ if (_scrollMode !== CPWebViewScrollAppKit)
+ return;
+
+ var win = null;
+ try { win = [self DOMWindow]; } catch (e) {}
+
+ if (win && win.addEventListener)
+ {
+ var scrollEventHandler = function(anEvent)
+ {
+ var frameBounds = [self bounds],
+ frameCenter = CGPointMake(CGRectGetMidX(frameBounds), CGRectGetMidY(frameBounds)),
+ windowOrigin = [self convertPoint:frameCenter toView:nil],
+ globalOrigin = [[self window] convertBaseToBridge:windowOrigin];
+
+ anEvent._overrideLocation = globalOrigin;
+ [[[self window] platformWindow] scrollEvent:anEvent];
+ };
+
+ win.addEventListener("DOMMouseScroll", scrollEventHandler, false);
+ }
+}
+
+- (void)_resizeWebFrame
{
if (_scrollMode === CPWebViewScrollAppKit)
{
@@ -181,13 +209,14 @@ CPWebViewScrollNative = 2;
}
else
{
- [_frameView setFrameSize:[_scrollView contentSize]];
+ var visibleRect = [_frameView visibleRect];
+ [_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) {}
- if (win && win.document)
+ if (win && win.document && win.document.body)
{
var width = win.document.body.scrollWidth,
height = win.document.body.scrollHeight;
@@ -203,6 +232,8 @@ CPWebViewScrollNative = 2;
[_frameView setFrameSize:CGSizeMake(800, 1600)];
}
+
+ [_frameView scrollRectToVisible:visibleRect];
}
}
}
@@ -217,7 +248,10 @@ CPWebViewScrollNative = 2;
- (void)_setScrollMode:(int)aScrollMode
{
- _scrollMode = aScrollMode;
+ if (CPBrowserIsEngine(CPInternetExplorerBrowserEngine))
+ _scrollMode = CPWebViewScrollNative;
+ else
+ _scrollMode = aScrollMode;
_ignoreLoadStart = YES;
_ignoreLoadEnd = YES;
@@ -256,6 +290,8 @@ CPWebViewScrollNative = 2;
[self _setScrollMode:CPWebViewScrollAppKit];
+ [_frameView setFrameSize:[_scrollView contentSize]];
+
[self _startedLoading];
_ignoreLoadStart = YES;
@@ -293,8 +329,15 @@ CPWebViewScrollNative = 2;
// clear the iframe
_iframe.src = "";
+ if (_loadHTMLStringTimer !== nil)
+ {
+ window.clearTimeout(_loadHTMLStringTimer);
+ _loadHTMLStringTimer = nil;
+ }
+
// need to give the browser a chance to reset iframe, otherwise we'll be document.write()-ing the previous document
- window.setTimeout(function() {
+ _loadHTMLStringTimer = window.setTimeout(function()
+ {
var win = [self DOMWindow];
win.document.write(_html);
@@ -315,7 +358,8 @@ CPWebViewScrollNative = 2;
- (void)_finishedLoading
{
[self _resizeWebFrame];
-
+ [self _attachScrollEventIfNecessary];
+
[[CPNotificationCenter defaultCenter] postNotificationName:CPWebViewProgressFinishedNotification object:self];
if ([_frameLoadDelegate respondsToSelector:@selector(webView:didFinishLoadForFrame:)])
diff --git a/AppKit/CPWindow/CPWindow.j b/AppKit/CPWindow/CPWindow.j
index 7a916d9eb..f06953ab1 100644
--- a/AppKit/CPWindow/CPWindow.j
+++ b/AppKit/CPWindow/CPWindow.j
@@ -372,6 +372,15 @@ CPTexturedBackgroundWindowMask
[self setPlatformWindow:[CPPlatformWindow primaryPlatformWindow]];
else
{
+ // give zero sized borderless bridge windows a default size if we're not in the browser so they show up in NativeHost.
+ if ((aStyleMask & CPBorderlessBridgeWindowMask) && aContentRect.size.width === 0 && aContentRect.size.height === 0)
+ {
+ var visibleFrame = [[[CPScreen alloc] init] visibleFrame];
+ _frame.size.height = MIN(768.0, visibleFrame.size.height);
+ _frame.size.width = MIN(1024.0, visibleFrame.size.width);
+ _frame.origin.x = (visibleFrame.size.width - _frame.size.width) / 2;
+ _frame.origin.y = (visibleFrame.size.height - _frame.size.height) / 2;
+ }
[self setPlatformWindow:[[CPPlatformWindow alloc] initWithContentRect:_frame]];
[self platformWindow]._only = self;
}
@@ -883,6 +892,23 @@ CPTexturedBackgroundWindowMask
return _contentView;
}
+/*!
+ Applies an alpha value to the window.
+ @param aValue the alpha value to apply
+*/
+- (void)setAlphaValue:(float)aValue
+{
+ [_windowView setAlphaValue:aValue];
+}
+
+/*!
+ Returns the alpha value of the window.
+*/
+- (float)alphaValue
+{
+ return [_windowView alphaValue];
+}
+
/*!
Sets the window's background color.
@param aColor the new color for the background
@@ -1907,7 +1933,8 @@ CPTexturedBackgroundWindowMask
[keyWindow makeKeyWindow];
else
{
- var menuWindow = [CPApp mainMenu]._menuWindow;
+ var mainMenu = [CPApp mainMenu],
+ menuWindow = mainMenu ? mainMenu._menuWindow : nil;
for (var i = 0; i < windowCount; i++)
{
var currentWindow = allWindows[i];
@@ -1935,7 +1962,8 @@ CPTexturedBackgroundWindowMask
[mainWindow makeMainWindow];
else
{
- var menuWindow = [CPApp mainMenu]._menuWindow;
+ var mainMenu = [CPApp mainMenu],
+ menuWindow = mainMenu ? mainMenu._menuWindow : nil;
for (var i = 0; i < windowCount; i++)
{
var currentWindow = allWindows[i];
diff --git a/AppKit/Cib/CPCibLoading.j b/AppKit/Cib/CPCibLoading.j
index aa7007556..22543eddc 100644
--- a/AppKit/Cib/CPCibLoading.j
+++ b/AppKit/Cib/CPCibLoading.j
@@ -37,12 +37,12 @@ var CPCibOwner = @"CPCibOwner";
@implementation CPBundle (CPCibLoading)
-+ (void)loadCibFile:(CPString)anAbsolutePath externalNameTable:(CPDictionary)aNameTable
++ (CPCib)loadCibFile:(CPString)anAbsolutePath externalNameTable:(CPDictionary)aNameTable
{
- [[[CPCib alloc] initWithContentsOfURL:anAbsolutePath] instantiateCibWithExternalNameTable:aNameTable];
+ return [[[CPCib alloc] initWithContentsOfURL:anAbsolutePath] instantiateCibWithExternalNameTable:aNameTable];
}
-+ (void)loadCibNamed:(CPString)aName owner:(id)anOwner
++ (CPCib)loadCibNamed:(CPString)aName owner:(id)anOwner
{
if (![aName hasSuffix:@".cib"])
aName = [aName stringByAppendingString:@".cib"];
@@ -51,24 +51,24 @@ var CPCibOwner = @"CPCibOwner";
var bundle = anOwner ? [CPBundle bundleForClass:[anOwner class]] : [CPBundle mainBundle],
path = [bundle pathForResource:aName];
- [self loadCibFile:path externalNameTable:[CPDictionary dictionaryWithObject:anOwner forKey:CPCibOwner]];
+ return [self loadCibFile:path externalNameTable:[CPDictionary dictionaryWithObject:anOwner forKey:CPCibOwner]];
}
-- (void)loadCibFile:(CPString)aFileName externalNameTable:(CPDictionary)aNameTable
+- (CPCib)loadCibFile:(CPString)aFileName externalNameTable:(CPDictionary)aNameTable
{
- [[[CPCib alloc] initWithContentsOfURL:aFileName] instantiateCibWithExternalNameTable:aNameTable];
+ return [[[CPCib alloc] initWithContentsOfURL:aFileName] instantiateCibWithExternalNameTable:aNameTable];
}
-+ (void)loadCibFile:(CPString)anAbsolutePath externalNameTable:(CPDictionary)aNameTable loadDelegate:aDelegate
++ (CPCib)loadCibFile:(CPString)anAbsolutePath externalNameTable:(CPDictionary)aNameTable loadDelegate:aDelegate
{
- [[CPCib alloc]
+ return ([[CPCib alloc]
initWithContentsOfURL:anAbsolutePath
loadDelegate:[[_CPCibLoadDelegate alloc]
initWithLoadDelegate:aDelegate
- externalNameTable:aNameTable]];
+ externalNameTable:aNameTable]]);
}
-+ (void)loadCibNamed:(CPString)aName owner:(id)anOwner loadDelegate:(id)aDelegate
++ (CPCib)loadCibNamed:(CPString)aName owner:(id)anOwner loadDelegate:(id)aDelegate
{
if (![aName hasSuffix:@".cib"])
aName = [aName stringByAppendingString:@".cib"];
@@ -77,17 +77,17 @@ var CPCibOwner = @"CPCibOwner";
var bundle = anOwner ? [CPBundle bundleForClass:[anOwner class]] : [CPBundle mainBundle],
path = [bundle pathForResource:aName];
- [self loadCibFile:path externalNameTable:[CPDictionary dictionaryWithObject:anOwner forKey:CPCibOwner] loadDelegate:aDelegate];
+ return [self loadCibFile:path externalNameTable:[CPDictionary dictionaryWithObject:anOwner forKey:CPCibOwner] loadDelegate:aDelegate];
}
-- (void)loadCibFile:(CPString)aFileName externalNameTable:(CPDictionary)aNameTable loadDelegate:(id)aDelegate
+- (CPCib)loadCibFile:(CPString)aFileName externalNameTable:(CPDictionary)aNameTable loadDelegate:(id)aDelegate
{
- [[CPCib alloc]
+ return ([[CPCib alloc]
initWithCibNamed:aFileName
bundle:self
loadDelegate:[[_CPCibLoadDelegate alloc]
initWithLoadDelegate:aDelegate
- externalNameTable:aNameTable]];
+ externalNameTable:aNameTable]]);
}
@end
diff --git a/AppKit/Platform/CPPlatformWindow.j b/AppKit/Platform/CPPlatformWindow.j
index 4ebfa8f81..a0f46cc52 100644
--- a/AppKit/Platform/CPPlatformWindow.j
+++ b/AppKit/Platform/CPPlatformWindow.j
@@ -41,6 +41,7 @@ var PrimaryPlatformWindow = NULL;
DOMElement _DOMBodyElement;
DOMElement _DOMFocusElement;
+ DOMElement _DOMEventGuard;
CPArray _windowLevels;
CPDictionary _windowLayers;
@@ -73,6 +74,15 @@ var PrimaryPlatformWindow = NULL;
return [CPSet set];
}
++ (BOOL)supportsMultipleInstances
+{
+#if PLATFORM(DOM)
+ return !CPBrowserIsEngine(CPInternetExplorerBrowserEngine);
+#else
+ return NO;
+#endif
+}
+
+ (CPPlatformWindow)primaryPlatformWindow
{
return PrimaryPlatformWindow;
diff --git a/AppKit/Platform/DOM/CPPlatformWindow+DOM.j b/AppKit/Platform/DOM/CPPlatformWindow+DOM.j
index 30f560581..a0b9403bb 100644
--- a/AppKit/Platform/DOM/CPPlatformWindow+DOM.j
+++ b/AppKit/Platform/DOM/CPPlatformWindow+DOM.j
@@ -130,8 +130,6 @@ var CPDOMEventGetClickCount,
StopDOMEventPropagation,
StopContextMenuDOMEventPropagation;
-var _DOMEventGuard;
-
//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.
@@ -280,7 +278,7 @@ var supportsNativeDragAndDrop = [CPPlatform supportsDragAndDrop];
_DOMBodyElement = theDocument.getElementById("cappuccino-body") || theDocument.body;
// FIXME: Always do this?
- if ([CPPlatform supportsDragAndDrop])
+ if (supportsNativeDragAndDrop)
_DOMBodyElement.style["-khtml-user-select"] = "none";
_DOMBodyElement.webkitTouchCallout = "none";
@@ -469,7 +467,7 @@ var supportsNativeDragAndDrop = [CPPlatform supportsDragAndDrop];
[PlatformWindows addObject:self];
// FIXME: cpSetFrame?
- _DOMWindow.document.write("");
+ _DOMWindow.document.write("");
_DOMWindow.document.close();
if (![CPPlatform isBrowser])
@@ -516,6 +514,11 @@ var supportsNativeDragAndDrop = [CPPlatform supportsDragAndDrop];
DOMDragElement.style.left = -_CGRectGetWidth(draggedWindowFrame) + "px";
DOMDragElement.style.top = -_CGRectGetHeight(draggedWindowFrame) + "px";
+ var parentNode = DOMDragElement.parentNode;
+
+ if (parentNode)
+ parentNode.removeChild(DOMDragElement);
+
_DOMBodyElement.appendChild(DOMDragElement);
var draggingOffset = [dragServer draggingOffset];
@@ -848,12 +851,13 @@ var supportsNativeDragAndDrop = [CPPlatform supportsDragAndDrop];
if(!aDOMEvent)
aDOMEvent = window.event;
+ var location = nil;
if (CPFeatureIsCompatible(CPJavaScriptMouseWheelValues_8_15))
{
- var x = 0.0,
- y = 0.0,
+ var x = aDOMEvent._offsetX || 0.0,
+ y = aDOMEvent._offsetY || 0.0,
element = aDOMEvent.target;
-
+
while (element.nodeType !== 1)
element = element.parentNode;
@@ -867,11 +871,13 @@ var supportsNativeDragAndDrop = [CPPlatform supportsDragAndDrop];
} while (element = element.offsetParent);
}
- var location = _CGPointMake((x + ((aDOMEvent.clientX - 8) / 15)), (y + ((aDOMEvent.clientY - 8) / 15)));
+ location = _CGPointMake((x + ((aDOMEvent.clientX - 8) / 15)), (y + ((aDOMEvent.clientY - 8) / 15)));
}
+ else if (aDOMEvent._overrideLocation)
+ location = aDOMEvent._overrideLocation;
else
- var location = _CGPointMake(aDOMEvent.clientX, aDOMEvent.clientY);
-
+ location = _CGPointMake(aDOMEvent.clientX, aDOMEvent.clientY);
+
var deltaX = 0.0,
deltaY = 0.0,
windowNumber = 0,
@@ -880,7 +886,7 @@ var supportsNativeDragAndDrop = [CPPlatform supportsDragAndDrop];
(aDOMEvent.ctrlKey ? CPControlKeyMask : 0) |
(aDOMEvent.altKey ? CPAlternateKeyMask : 0) |
(aDOMEvent.metaKey ? CPCommandKeyMask : 0);
-
+
StopDOMEventPropagation = YES;
var theWindow = [self hitTest:location];
@@ -1189,6 +1195,7 @@ var supportsNativeDragAndDrop = [CPPlatform supportsDragAndDrop];
[_windowLevels insertObject:aLevel atIndex:insertionIndex];
layer._DOMElement.style.zIndex = aLevel;
+
_DOMBodyElement.appendChild(layer._DOMElement);
}
diff --git a/AppKit/Resources/action_button.png b/AppKit/Resources/action_button.png
new file mode 100644
index 000000000..2af0dfc48
Binary files /dev/null and b/AppKit/Resources/action_button.png differ
diff --git a/AppKit/Themes/Aristo/Resources/HUD/button-bezel-center.png b/AppKit/Themes/Aristo/Resources/HUD/button-bezel-center.png
index 6b3e348c1..cc9401c73 100644
Binary files a/AppKit/Themes/Aristo/Resources/HUD/button-bezel-center.png and b/AppKit/Themes/Aristo/Resources/HUD/button-bezel-center.png differ
diff --git a/AppKit/Themes/Aristo/Resources/HUD/button-bezel-disabled-center.png b/AppKit/Themes/Aristo/Resources/HUD/button-bezel-disabled-center.png
new file mode 100644
index 000000000..dd4ce2152
Binary files /dev/null and b/AppKit/Themes/Aristo/Resources/HUD/button-bezel-disabled-center.png differ
diff --git a/AppKit/Themes/Aristo/Resources/HUD/button-bezel-disabled-left.png b/AppKit/Themes/Aristo/Resources/HUD/button-bezel-disabled-left.png
new file mode 100644
index 000000000..a615b9382
Binary files /dev/null and b/AppKit/Themes/Aristo/Resources/HUD/button-bezel-disabled-left.png differ
diff --git a/AppKit/Themes/Aristo/Resources/HUD/button-bezel-disabled-right.png b/AppKit/Themes/Aristo/Resources/HUD/button-bezel-disabled-right.png
new file mode 100644
index 000000000..6f14f35d8
Binary files /dev/null and b/AppKit/Themes/Aristo/Resources/HUD/button-bezel-disabled-right.png differ
diff --git a/AppKit/Themes/Aristo/Resources/HUD/button-bezel-highlighted-center.png b/AppKit/Themes/Aristo/Resources/HUD/button-bezel-highlighted-center.png
index 0f35e8c4b..be25a32af 100644
Binary files a/AppKit/Themes/Aristo/Resources/HUD/button-bezel-highlighted-center.png and b/AppKit/Themes/Aristo/Resources/HUD/button-bezel-highlighted-center.png differ
diff --git a/AppKit/Themes/Aristo/Resources/HUD/button-bezel-highlighted-left.png b/AppKit/Themes/Aristo/Resources/HUD/button-bezel-highlighted-left.png
index fe9f27411..a4b766ac2 100644
Binary files a/AppKit/Themes/Aristo/Resources/HUD/button-bezel-highlighted-left.png and b/AppKit/Themes/Aristo/Resources/HUD/button-bezel-highlighted-left.png differ
diff --git a/AppKit/Themes/Aristo/Resources/HUD/button-bezel-highlighted-right.png b/AppKit/Themes/Aristo/Resources/HUD/button-bezel-highlighted-right.png
index 809339ae4..cd709f319 100644
Binary files a/AppKit/Themes/Aristo/Resources/HUD/button-bezel-highlighted-right.png and b/AppKit/Themes/Aristo/Resources/HUD/button-bezel-highlighted-right.png differ
diff --git a/AppKit/Themes/Aristo/Resources/HUD/button-bezel-left.png b/AppKit/Themes/Aristo/Resources/HUD/button-bezel-left.png
index 6c10bf51e..674aacd37 100644
Binary files a/AppKit/Themes/Aristo/Resources/HUD/button-bezel-left.png and b/AppKit/Themes/Aristo/Resources/HUD/button-bezel-left.png differ
diff --git a/AppKit/Themes/Aristo/Resources/HUD/button-bezel-right.png b/AppKit/Themes/Aristo/Resources/HUD/button-bezel-right.png
index 91439ae90..88a8540cc 100644
Binary files a/AppKit/Themes/Aristo/Resources/HUD/button-bezel-right.png and b/AppKit/Themes/Aristo/Resources/HUD/button-bezel-right.png differ
diff --git a/AppKit/Themes/Aristo/Resources/HUD/default-button-bezel-center.png b/AppKit/Themes/Aristo/Resources/HUD/default-button-bezel-center.png
new file mode 100644
index 000000000..bc5b3a93b
Binary files /dev/null and b/AppKit/Themes/Aristo/Resources/HUD/default-button-bezel-center.png differ
diff --git a/AppKit/Themes/Aristo/Resources/HUD/default-button-bezel-disabled-center.png b/AppKit/Themes/Aristo/Resources/HUD/default-button-bezel-disabled-center.png
new file mode 100644
index 000000000..8289aed50
Binary files /dev/null and b/AppKit/Themes/Aristo/Resources/HUD/default-button-bezel-disabled-center.png differ
diff --git a/AppKit/Themes/Aristo/Resources/HUD/default-button-bezel-disabled-left.png b/AppKit/Themes/Aristo/Resources/HUD/default-button-bezel-disabled-left.png
new file mode 100644
index 000000000..b0e2c0ac5
Binary files /dev/null and b/AppKit/Themes/Aristo/Resources/HUD/default-button-bezel-disabled-left.png differ
diff --git a/AppKit/Themes/Aristo/Resources/HUD/default-button-bezel-disabled-right.png b/AppKit/Themes/Aristo/Resources/HUD/default-button-bezel-disabled-right.png
new file mode 100644
index 000000000..25dac55c3
Binary files /dev/null and b/AppKit/Themes/Aristo/Resources/HUD/default-button-bezel-disabled-right.png differ
diff --git a/AppKit/Themes/Aristo/Resources/HUD/default-button-bezel-highlighted-center.png b/AppKit/Themes/Aristo/Resources/HUD/default-button-bezel-highlighted-center.png
new file mode 100644
index 000000000..79e37a1a4
Binary files /dev/null and b/AppKit/Themes/Aristo/Resources/HUD/default-button-bezel-highlighted-center.png differ
diff --git a/AppKit/Themes/Aristo/Resources/HUD/default-button-bezel-highlighted-left.png b/AppKit/Themes/Aristo/Resources/HUD/default-button-bezel-highlighted-left.png
new file mode 100644
index 000000000..19b884419
Binary files /dev/null and b/AppKit/Themes/Aristo/Resources/HUD/default-button-bezel-highlighted-left.png differ
diff --git a/AppKit/Themes/Aristo/Resources/HUD/default-button-bezel-highlighted-right.png b/AppKit/Themes/Aristo/Resources/HUD/default-button-bezel-highlighted-right.png
new file mode 100644
index 000000000..da0cb9a8a
Binary files /dev/null and b/AppKit/Themes/Aristo/Resources/HUD/default-button-bezel-highlighted-right.png differ
diff --git a/AppKit/Themes/Aristo/Resources/HUD/default-button-bezel-left.png b/AppKit/Themes/Aristo/Resources/HUD/default-button-bezel-left.png
new file mode 100644
index 000000000..dd02f1725
Binary files /dev/null and b/AppKit/Themes/Aristo/Resources/HUD/default-button-bezel-left.png differ
diff --git a/AppKit/Themes/Aristo/Resources/HUD/default-button-bezel-right.png b/AppKit/Themes/Aristo/Resources/HUD/default-button-bezel-right.png
new file mode 100644
index 000000000..e32647f97
Binary files /dev/null and b/AppKit/Themes/Aristo/Resources/HUD/default-button-bezel-right.png differ
diff --git a/AppKit/Themes/Aristo/Resources/HUD/horizontal-track-center.png b/AppKit/Themes/Aristo/Resources/HUD/horizontal-track-center.png
new file mode 100644
index 000000000..b565d8e6a
Binary files /dev/null and b/AppKit/Themes/Aristo/Resources/HUD/horizontal-track-center.png differ
diff --git a/AppKit/Themes/Aristo/Resources/HUD/horizontal-track-disabled-center.png b/AppKit/Themes/Aristo/Resources/HUD/horizontal-track-disabled-center.png
new file mode 100644
index 000000000..31da63ab7
Binary files /dev/null and b/AppKit/Themes/Aristo/Resources/HUD/horizontal-track-disabled-center.png differ
diff --git a/AppKit/Themes/Aristo/Resources/HUD/horizontal-track-disabled-left.png b/AppKit/Themes/Aristo/Resources/HUD/horizontal-track-disabled-left.png
new file mode 100644
index 000000000..e395935df
Binary files /dev/null and b/AppKit/Themes/Aristo/Resources/HUD/horizontal-track-disabled-left.png differ
diff --git a/AppKit/Themes/Aristo/Resources/HUD/horizontal-track-disabled-right.png b/AppKit/Themes/Aristo/Resources/HUD/horizontal-track-disabled-right.png
new file mode 100644
index 000000000..d752a54ec
Binary files /dev/null and b/AppKit/Themes/Aristo/Resources/HUD/horizontal-track-disabled-right.png differ
diff --git a/AppKit/Themes/Aristo/Resources/HUD/horizontal-track-left.png b/AppKit/Themes/Aristo/Resources/HUD/horizontal-track-left.png
new file mode 100644
index 000000000..05ff0804e
Binary files /dev/null and b/AppKit/Themes/Aristo/Resources/HUD/horizontal-track-left.png differ
diff --git a/AppKit/Themes/Aristo/Resources/HUD/horizontal-track-right.png b/AppKit/Themes/Aristo/Resources/HUD/horizontal-track-right.png
new file mode 100644
index 000000000..db4488023
Binary files /dev/null and b/AppKit/Themes/Aristo/Resources/HUD/horizontal-track-right.png differ
diff --git a/AppKit/Themes/Aristo/Resources/HUD/knob-highlighted.png b/AppKit/Themes/Aristo/Resources/HUD/knob-highlighted.png
new file mode 100644
index 000000000..5c4387a55
Binary files /dev/null and b/AppKit/Themes/Aristo/Resources/HUD/knob-highlighted.png differ
diff --git a/AppKit/Themes/Aristo/Resources/HUD/knob.png b/AppKit/Themes/Aristo/Resources/HUD/knob.png
new file mode 100755
index 000000000..bad25cf31
Binary files /dev/null and b/AppKit/Themes/Aristo/Resources/HUD/knob.png differ
diff --git a/AppKit/Themes/Aristo/Resources/HUD/segmented-control-bezel-center.png b/AppKit/Themes/Aristo/Resources/HUD/segmented-control-bezel-center.png
new file mode 100644
index 000000000..455b25dec
Binary files /dev/null and b/AppKit/Themes/Aristo/Resources/HUD/segmented-control-bezel-center.png differ
diff --git a/AppKit/Themes/Aristo/Resources/HUD/segmented-control-bezel-disabled-center.png b/AppKit/Themes/Aristo/Resources/HUD/segmented-control-bezel-disabled-center.png
new file mode 100644
index 000000000..a32359e5c
Binary files /dev/null and b/AppKit/Themes/Aristo/Resources/HUD/segmented-control-bezel-disabled-center.png differ
diff --git a/AppKit/Themes/Aristo/Resources/HUD/segmented-control-bezel-disabled-divider.png b/AppKit/Themes/Aristo/Resources/HUD/segmented-control-bezel-disabled-divider.png
new file mode 100644
index 000000000..a07b15d5c
Binary files /dev/null and b/AppKit/Themes/Aristo/Resources/HUD/segmented-control-bezel-disabled-divider.png differ
diff --git a/AppKit/Themes/Aristo/Resources/HUD/segmented-control-bezel-disabled-left.png b/AppKit/Themes/Aristo/Resources/HUD/segmented-control-bezel-disabled-left.png
new file mode 100644
index 000000000..cca119c66
Binary files /dev/null and b/AppKit/Themes/Aristo/Resources/HUD/segmented-control-bezel-disabled-left.png differ
diff --git a/AppKit/Themes/Aristo/Resources/HUD/segmented-control-bezel-disabled-right.png b/AppKit/Themes/Aristo/Resources/HUD/segmented-control-bezel-disabled-right.png
new file mode 100644
index 000000000..9f3a03b7d
Binary files /dev/null and b/AppKit/Themes/Aristo/Resources/HUD/segmented-control-bezel-disabled-right.png differ
diff --git a/AppKit/Themes/Aristo/Resources/HUD/segmented-control-bezel-divider.png b/AppKit/Themes/Aristo/Resources/HUD/segmented-control-bezel-divider.png
new file mode 100644
index 000000000..6811fc89a
Binary files /dev/null and b/AppKit/Themes/Aristo/Resources/HUD/segmented-control-bezel-divider.png differ
diff --git a/AppKit/Themes/Aristo/Resources/HUD/segmented-control-bezel-highlighted-center.png b/AppKit/Themes/Aristo/Resources/HUD/segmented-control-bezel-highlighted-center.png
new file mode 100644
index 000000000..ac04df7bb
Binary files /dev/null and b/AppKit/Themes/Aristo/Resources/HUD/segmented-control-bezel-highlighted-center.png differ
diff --git a/AppKit/Themes/Aristo/Resources/HUD/segmented-control-bezel-highlighted-disabled-center.png b/AppKit/Themes/Aristo/Resources/HUD/segmented-control-bezel-highlighted-disabled-center.png
new file mode 100644
index 000000000..06105ca17
Binary files /dev/null and b/AppKit/Themes/Aristo/Resources/HUD/segmented-control-bezel-highlighted-disabled-center.png differ
diff --git a/AppKit/Themes/Aristo/Resources/HUD/segmented-control-bezel-highlighted-disabled-divider.png b/AppKit/Themes/Aristo/Resources/HUD/segmented-control-bezel-highlighted-disabled-divider.png
new file mode 100644
index 000000000..513282884
Binary files /dev/null and b/AppKit/Themes/Aristo/Resources/HUD/segmented-control-bezel-highlighted-disabled-divider.png differ
diff --git a/AppKit/Themes/Aristo/Resources/HUD/segmented-control-bezel-highlighted-disabled-left.png b/AppKit/Themes/Aristo/Resources/HUD/segmented-control-bezel-highlighted-disabled-left.png
new file mode 100644
index 000000000..e8bf1b6b0
Binary files /dev/null and b/AppKit/Themes/Aristo/Resources/HUD/segmented-control-bezel-highlighted-disabled-left.png differ
diff --git a/AppKit/Themes/Aristo/Resources/HUD/segmented-control-bezel-highlighted-disabled-right copy.png b/AppKit/Themes/Aristo/Resources/HUD/segmented-control-bezel-highlighted-disabled-right copy.png
new file mode 100644
index 000000000..23587f095
Binary files /dev/null and b/AppKit/Themes/Aristo/Resources/HUD/segmented-control-bezel-highlighted-disabled-right copy.png differ
diff --git a/AppKit/Themes/Aristo/Resources/HUD/segmented-control-bezel-highlighted-disabled-right.png b/AppKit/Themes/Aristo/Resources/HUD/segmented-control-bezel-highlighted-disabled-right.png
new file mode 100644
index 000000000..73880f0de
Binary files /dev/null and b/AppKit/Themes/Aristo/Resources/HUD/segmented-control-bezel-highlighted-disabled-right.png differ
diff --git a/AppKit/Themes/Aristo/Resources/HUD/segmented-control-bezel-highlighted-divider.png b/AppKit/Themes/Aristo/Resources/HUD/segmented-control-bezel-highlighted-divider.png
new file mode 100644
index 000000000..6811fc89a
Binary files /dev/null and b/AppKit/Themes/Aristo/Resources/HUD/segmented-control-bezel-highlighted-divider.png differ
diff --git a/AppKit/Themes/Aristo/Resources/HUD/segmented-control-bezel-highlighted-left.png b/AppKit/Themes/Aristo/Resources/HUD/segmented-control-bezel-highlighted-left.png
new file mode 100644
index 000000000..56ac58d65
Binary files /dev/null and b/AppKit/Themes/Aristo/Resources/HUD/segmented-control-bezel-highlighted-left.png differ
diff --git a/AppKit/Themes/Aristo/Resources/HUD/segmented-control-bezel-highlighted-right.png b/AppKit/Themes/Aristo/Resources/HUD/segmented-control-bezel-highlighted-right.png
new file mode 100644
index 000000000..2941208e8
Binary files /dev/null and b/AppKit/Themes/Aristo/Resources/HUD/segmented-control-bezel-highlighted-right.png differ
diff --git a/AppKit/Themes/Aristo/Resources/HUD/segmented-control-bezel-left.png b/AppKit/Themes/Aristo/Resources/HUD/segmented-control-bezel-left.png
new file mode 100644
index 000000000..61b659212
Binary files /dev/null and b/AppKit/Themes/Aristo/Resources/HUD/segmented-control-bezel-left.png differ
diff --git a/AppKit/Themes/Aristo/Resources/HUD/segmented-control-bezel-pushed-center.png b/AppKit/Themes/Aristo/Resources/HUD/segmented-control-bezel-pushed-center.png
new file mode 100644
index 000000000..aa78a13bc
Binary files /dev/null and b/AppKit/Themes/Aristo/Resources/HUD/segmented-control-bezel-pushed-center.png differ
diff --git a/AppKit/Themes/Aristo/Resources/HUD/segmented-control-bezel-pushed-highlighted-center.png b/AppKit/Themes/Aristo/Resources/HUD/segmented-control-bezel-pushed-highlighted-center.png
new file mode 100644
index 000000000..dc64067fe
Binary files /dev/null and b/AppKit/Themes/Aristo/Resources/HUD/segmented-control-bezel-pushed-highlighted-center.png differ
diff --git a/AppKit/Themes/Aristo/Resources/HUD/segmented-control-bezel-pushed-highlighted-left.png b/AppKit/Themes/Aristo/Resources/HUD/segmented-control-bezel-pushed-highlighted-left.png
new file mode 100644
index 000000000..c81b5aba0
Binary files /dev/null and b/AppKit/Themes/Aristo/Resources/HUD/segmented-control-bezel-pushed-highlighted-left.png differ
diff --git a/AppKit/Themes/Aristo/Resources/HUD/segmented-control-bezel-pushed-highlighted-right.png b/AppKit/Themes/Aristo/Resources/HUD/segmented-control-bezel-pushed-highlighted-right.png
new file mode 100644
index 000000000..6eb94808d
Binary files /dev/null and b/AppKit/Themes/Aristo/Resources/HUD/segmented-control-bezel-pushed-highlighted-right.png differ
diff --git a/AppKit/Themes/Aristo/Resources/HUD/segmented-control-bezel-pushed-left.png b/AppKit/Themes/Aristo/Resources/HUD/segmented-control-bezel-pushed-left.png
new file mode 100644
index 000000000..a1c5e0323
Binary files /dev/null and b/AppKit/Themes/Aristo/Resources/HUD/segmented-control-bezel-pushed-left.png differ
diff --git a/AppKit/Themes/Aristo/Resources/HUD/segmented-control-bezel-pushed-right.png b/AppKit/Themes/Aristo/Resources/HUD/segmented-control-bezel-pushed-right.png
new file mode 100644
index 000000000..949864422
Binary files /dev/null and b/AppKit/Themes/Aristo/Resources/HUD/segmented-control-bezel-pushed-right.png differ
diff --git a/AppKit/Themes/Aristo/Resources/HUD/segmented-control-bezel-right.png b/AppKit/Themes/Aristo/Resources/HUD/segmented-control-bezel-right.png
new file mode 100644
index 000000000..12e90829c
Binary files /dev/null and b/AppKit/Themes/Aristo/Resources/HUD/segmented-control-bezel-right.png differ
diff --git a/AppKit/Themes/Aristo/Resources/HUD/slider-circular-bezel.png b/AppKit/Themes/Aristo/Resources/HUD/slider-circular-bezel.png
new file mode 100644
index 000000000..69d5c29a9
Binary files /dev/null and b/AppKit/Themes/Aristo/Resources/HUD/slider-circular-bezel.png differ
diff --git a/AppKit/Themes/Aristo/Resources/HUD/slider-circular-disabled-bezel.png b/AppKit/Themes/Aristo/Resources/HUD/slider-circular-disabled-bezel.png
new file mode 100644
index 000000000..9c54fa23e
Binary files /dev/null and b/AppKit/Themes/Aristo/Resources/HUD/slider-circular-disabled-bezel.png differ
diff --git a/AppKit/Themes/Aristo/Resources/HUD/slider-circular-disabled-knob.png b/AppKit/Themes/Aristo/Resources/HUD/slider-circular-disabled-knob.png
new file mode 100644
index 000000000..5c0d8bd11
Binary files /dev/null and b/AppKit/Themes/Aristo/Resources/HUD/slider-circular-disabled-knob.png differ
diff --git a/AppKit/Themes/Aristo/Resources/HUD/slider-circular-knob.png b/AppKit/Themes/Aristo/Resources/HUD/slider-circular-knob.png
new file mode 100644
index 000000000..050ffefe6
Binary files /dev/null and b/AppKit/Themes/Aristo/Resources/HUD/slider-circular-knob.png differ
diff --git a/AppKit/Themes/Aristo/Resources/HUD/vertical-track-bottom.png b/AppKit/Themes/Aristo/Resources/HUD/vertical-track-bottom.png
new file mode 100644
index 000000000..bdec63744
Binary files /dev/null and b/AppKit/Themes/Aristo/Resources/HUD/vertical-track-bottom.png differ
diff --git a/AppKit/Themes/Aristo/Resources/HUD/vertical-track-center.png b/AppKit/Themes/Aristo/Resources/HUD/vertical-track-center.png
new file mode 100644
index 000000000..2fbcce41e
Binary files /dev/null and b/AppKit/Themes/Aristo/Resources/HUD/vertical-track-center.png differ
diff --git a/AppKit/Themes/Aristo/Resources/HUD/vertical-track-disabled-bottom.png b/AppKit/Themes/Aristo/Resources/HUD/vertical-track-disabled-bottom.png
new file mode 100644
index 000000000..efc622a82
Binary files /dev/null and b/AppKit/Themes/Aristo/Resources/HUD/vertical-track-disabled-bottom.png differ
diff --git a/AppKit/Themes/Aristo/Resources/HUD/vertical-track-disabled-center.png b/AppKit/Themes/Aristo/Resources/HUD/vertical-track-disabled-center.png
new file mode 100644
index 000000000..25675211c
Binary files /dev/null and b/AppKit/Themes/Aristo/Resources/HUD/vertical-track-disabled-center.png differ
diff --git a/AppKit/Themes/Aristo/Resources/HUD/vertical-track-disabled-top.png b/AppKit/Themes/Aristo/Resources/HUD/vertical-track-disabled-top.png
new file mode 100644
index 000000000..12abe0927
Binary files /dev/null and b/AppKit/Themes/Aristo/Resources/HUD/vertical-track-disabled-top.png differ
diff --git a/AppKit/Themes/Aristo/Resources/HUD/vertical-track-top.png b/AppKit/Themes/Aristo/Resources/HUD/vertical-track-top.png
new file mode 100644
index 000000000..a27c09e56
Binary files /dev/null and b/AppKit/Themes/Aristo/Resources/HUD/vertical-track-top.png differ
diff --git a/AppKit/Themes/Aristo/ThemeDescriptors.j b/AppKit/Themes/Aristo/ThemeDescriptors.j
old mode 100644
new mode 100755
index eb7e8f50e..d1d77ee49
--- a/AppKit/Themes/Aristo/ThemeDescriptors.j
+++ b/AppKit/Themes/Aristo/ThemeDescriptors.j
@@ -439,7 +439,7 @@
isVertical:NO]);
[button setValue:CPLeftTextAlignment forThemeAttribute:@"alignment" inState:CPThemeStateBordered];
- [button setValue:[CPFont boldSystemFontOfSize:12.0] forThemeAttribute:@"font" inState:CPThemeStateBordered];
+ [button setValue:[CPFont systemFontOfSize:12.0] forThemeAttribute:@"font" inState:CPThemeStateBordered];
[button setValue:CGInsetMake(0.0, 0.0, 0.0, 20.0) forThemeAttribute:@"content-inset" inState:CPThemeStateBordered];
[button setValue:bezelColor forThemeAttribute:@"bezel-color" inState:CPThemeStateBordered];
[button setValue:bezelColorSelected forThemeAttribute:@"bezel-color" inState:CPThemeStateBordered | CPThemeStateSelected];
@@ -493,7 +493,7 @@
isVertical:NO]);
[button setValue:CPLeftTextAlignment forThemeAttribute:@"alignment" inState:CPThemeStateBordered];
- [button setValue:[CPFont boldSystemFontOfSize:12.0] forThemeAttribute:@"font" inState:CPThemeStateBordered];
+ [button setValue:[CPFont systemFontOfSize:12.0] forThemeAttribute:@"font" inState:CPThemeStateBordered];
[button setValue:CGInsetMake(0.0, 0.0, 0.0, 20.0) forThemeAttribute:@"content-inset" inState:CPThemeStateBordered];
[button setValue:bezelColor forThemeAttribute:@"bezel-color" inState:CPThemeStateBordered];
[button setValue:bezelColorSelected forThemeAttribute:@"bezel-color" inState:CPThemeStateBordered | CPThemeStateSelected];
@@ -721,7 +721,7 @@
+ (CPButtonBar)themedButtonBar
{
- var buttonBar = [[CPButtonBar alloc] initWithFrame:CGRectMake(0.0, 0.0, 140.0, 26.0)],
+ var buttonBar = [[CPButtonBar alloc] initWithFrame:CGRectMake(0.0, 0.0, 147.0, 26.0)],
color = [CPColor colorWithPatternImage:[_CPCibCustomResource imageResourceWithName:"buttonbar-bezel.png" size:CGSizeMake(1.0, 26.0)]];
[buttonBar setHasResizeControl:YES];
@@ -761,8 +761,13 @@
[buttonBar setValue:buttonBezelColor forThemeAttribute:@"button-bezel-color"];
[buttonBar setValue:buttonBezelHighlightedColor forThemeAttribute:@"button-bezel-color" inState:CPThemeStateHighlighted];
[buttonBar setValue:buttonBezelDisabledColor forThemeAttribute:@"button-bezel-color" inState:CPThemeStateDisabled];
+ [buttonBar setValue:[CPColor blackColor] forThemeAttribute:@"button-text-color"];
- [buttonBar setButtons:[[CPButtonBar plusButton], [CPButtonBar minusButton], [self themedPullDownMenu]]];
+ var popup = [CPButtonBar actionPopupButton];
+ [popup addItemWithTitle:"Item 1"];
+ [popup addItemWithTitle:"Item 2"];
+
+ [buttonBar setButtons:[[CPButtonBar plusButton], [CPButtonBar minusButton], popup]];
return buttonBar;
}
@@ -783,38 +788,186 @@
return [CPColor blackColor];
}
-+ (CPButton)themedButton
++ (CPPopUpButton)themedSegmentedControl
{
- var button = [[CPButton alloc] initWithFrame:CGRectMake(0.0, 0.0, 60.0, 20.0)],
+ var segmentedControl = [[CPSegmentedControl alloc] initWithFrame:CGRectMake(0.0, 0.0, 0.0, 24.0)];
+
+ [segmentedControl setTrackingMode:CPSegmentSwitchTrackingSelectAny];
+ [segmentedControl setSegmentCount:3];
+
+ [segmentedControl setWidth:40.0 forSegment:0];
+ [segmentedControl setLabel:@"foo" forSegment:0];
+ [segmentedControl setTag:1 forSegment:0];
+
+ [segmentedControl setWidth:60.0 forSegment:1];
+ [segmentedControl setLabel:@"bar" forSegment:1];
+ [segmentedControl setTag:2 forSegment:1];
+
+ [segmentedControl setWidth:35.0 forSegment:2];
+ [segmentedControl setLabel:@"1" forSegment:2];
+ [segmentedControl setTag:3 forSegment:2];
+
+ //various colors
+ var centerBezelColor = PatternColor([_CPCibCustomResource imageResourceWithName:@"HUD/segmented-control-bezel-center.png" size:CGSizeMake(1.0, 24.0)]),
+ dividerBezelColor = PatternColor([_CPCibCustomResource imageResourceWithName:@"HUD/segmented-control-bezel-divider.png" size:CGSizeMake(1.0, 24.0)]),
+ centerHighlightedBezelColor = PatternColor([_CPCibCustomResource imageResourceWithName:@"HUD/segmented-control-bezel-highlighted-center.png" size:CGSizeMake(1.0, 24.0)]),
+ dividerHighlightedBezelColor = PatternColor([_CPCibCustomResource imageResourceWithName:@"HUD/segmented-control-bezel-highlighted-divider.png" size:CGSizeMake(1.0, 24.0)]),
+ leftHighlightedBezelColor = PatternColor([_CPCibCustomResource imageResourceWithName:@"HUD/segmented-control-bezel-highlighted-left.png" size:CGSizeMake(4.0, 24.0)]),
+ rightHighlightedBezelColor = PatternColor([_CPCibCustomResource imageResourceWithName:@"HUD/segmented-control-bezel-highlighted-right.png" size:CGSizeMake(4.0, 24.0)]),
+ inactiveCenterBezelColor = PatternColor([_CPCibCustomResource imageResourceWithName:@"HUD/segmented-control-bezel-disabled-center.png" size:CGSizeMake(1.0, 24.0)]),
+ inactiveDividerBezelColor = PatternColor([_CPCibCustomResource imageResourceWithName:@"HUD/segmented-control-bezel-disabled-divider.png" size:CGSizeMake(1.0, 24.0)]),
+ inactiveLeftBezelColor = PatternColor([_CPCibCustomResource imageResourceWithName:@"HUD/segmented-control-bezel-disabled-left.png" size:CGSizeMake(4.0, 24.0)]),
+ inactiveRightBezelColor = PatternColor([_CPCibCustomResource imageResourceWithName:@"HUD/segmented-control-bezel-disabled-right.png" size:CGSizeMake(4.0, 24.0)]),
+ inactiveHighlightedCenterBezelColor = PatternColor([_CPCibCustomResource imageResourceWithName:@"HUD/segmented-control-bezel-highlighted-disabled-center.png" size:CGSizeMake(1.0, 24.0)]),
+ inactiveHighlightedDividerBezelColor = PatternColor([_CPCibCustomResource imageResourceWithName:@"HUD/segmented-control-bezel-highlighted-disabled-divider.png" size:CGSizeMake(1.0, 24.0)]),
+ inactiveHighlightedLeftBezelColor = PatternColor([_CPCibCustomResource imageResourceWithName:@"HUD/segmented-control-bezel-highlighted-disabled-left.png" size:CGSizeMake(4.0, 24.0)]),
+ inactiveHighlightedRightBezelColor = PatternColor([_CPCibCustomResource imageResourceWithName:@"HUD/segmented-control-bezel-highlighted-disabled-right.png" size:CGSizeMake(4.0, 24.0)]),
+ leftBezelColor = PatternColor([_CPCibCustomResource imageResourceWithName:@"HUD/segmented-control-bezel-left.png" size:CGSizeMake(4.0, 24.0)]),
+ rightBezelColor = PatternColor([_CPCibCustomResource imageResourceWithName:@"HUD/segmented-control-bezel-right.png" size:CGSizeMake(4.0, 24.0)]),
+ pushedCenterBezelColor = PatternColor([_CPCibCustomResource imageResourceWithName:@"HUD/segmented-control-bezel-pushed-center.png" size:CGSizeMake(1.0, 24.0)]),
+ pushedLeftBezelColor = PatternColor([_CPCibCustomResource imageResourceWithName:@"HUD/segmented-control-bezel-pushed-left.png" size:CGSizeMake(4.0, 24.0)]),
+ pushedRightBezelColor = PatternColor([_CPCibCustomResource imageResourceWithName:@"HUD/segmented-control-bezel-pushed-right.png" size:CGSizeMake(4.0, 24.0)]);
+ pushedHighlightedCenterBezelColor = PatternColor([_CPCibCustomResource imageResourceWithName:@"HUD/segmented-control-bezel-pushed-highlighted-center.png" size:CGSizeMake(1.0, 24.0)]),
+ pushedHighlightedLeftBezelColor = PatternColor([_CPCibCustomResource imageResourceWithName:@"HUD/segmented-control-bezel-pushed-highlighted-left.png" size:CGSizeMake(4.0, 24.0)]),
+ pushedHighlightedRightBezelColor = PatternColor([_CPCibCustomResource imageResourceWithName:@"HUD/segmented-control-bezel-pushed-highlighted-right.png" size:CGSizeMake(4.0, 24.0)]);
+
+ [segmentedControl setValue:centerBezelColor forThemeAttribute:@"center-segment-bezel-color" inState:CPThemeStateNormal];
+ [segmentedControl setValue:inactiveCenterBezelColor forThemeAttribute:@"center-segment-bezel-color" inState:CPThemeStateDisabled];
+ [segmentedControl setValue:inactiveHighlightedCenterBezelColor forThemeAttribute:@"center-segment-bezel-color" inState:CPThemeStateSelected|CPThemeStateDisabled];
+ [segmentedControl setValue:centerHighlightedBezelColor forThemeAttribute:@"center-segment-bezel-color" inState:CPThemeStateSelected];
+ [segmentedControl setValue:pushedCenterBezelColor forThemeAttribute:@"center-segment-bezel-color" inState:CPThemeStateHighlighted];
+ [segmentedControl setValue:pushedHighlightedCenterBezelColor forThemeAttribute:@"center-segment-bezel-color" inState:CPThemeStateHighlighted|CPThemeStateSelected];
+
+ [segmentedControl setValue:dividerBezelColor forThemeAttribute:@"divider-bezel-color" inState:CPThemeStateNormal];
+ [segmentedControl setValue:inactiveDividerBezelColor forThemeAttribute:@"divider-bezel-color" inState:CPThemeStateDisabled];
+ [segmentedControl setValue:inactiveHighlightedDividerBezelColor forThemeAttribute:@"divider-bezel-color" inState:CPThemeStateSelected|CPThemeStateDisabled];
+ [segmentedControl setValue:dividerHighlightedBezelColor forThemeAttribute:@"divider-bezel-color" inState:CPThemeStateSelected];
+ [segmentedControl setValue:dividerBezelColor forThemeAttribute:@"divider-bezel-color" inState:CPThemeStateHighlighted];
+
+ [segmentedControl setValue:rightBezelColor forThemeAttribute:@"right-segment-bezel-color" inState:CPThemeStateNormal];
+ [segmentedControl setValue:inactiveRightBezelColor forThemeAttribute:@"right-segment-bezel-color" inState:CPThemeStateDisabled];
+ [segmentedControl setValue:inactiveHighlightedRightBezelColor forThemeAttribute:@"right-segment-bezel-color" inState:CPThemeStateSelected|CPThemeStateDisabled];
+ [segmentedControl setValue:rightHighlightedBezelColor forThemeAttribute:@"right-segment-bezel-color" inState:CPThemeStateSelected];
+ [segmentedControl setValue:pushedRightBezelColor forThemeAttribute:@"right-segment-bezel-color" inState:CPThemeStateHighlighted];
+ [segmentedControl setValue:pushedHighlightedRightBezelColor forThemeAttribute:@"right-segment-bezel-color" inState:CPThemeStateHighlighted|CPThemeStateSelected];
+
+ [segmentedControl setValue:leftBezelColor forThemeAttribute:@"left-segment-bezel-color" inState:CPThemeStateNormal];
+ [segmentedControl setValue:inactiveLeftBezelColor forThemeAttribute:@"left-segment-bezel-color" inState:CPThemeStateDisabled];
+ [segmentedControl setValue:inactiveHighlightedLeftBezelColor forThemeAttribute:@"left-segment-bezel-color" inState:CPThemeStateSelected|CPThemeStateDisabled];
+ [segmentedControl setValue:leftHighlightedBezelColor forThemeAttribute:@"left-segment-bezel-color" inState:CPThemeStateSelected];
+ [segmentedControl setValue:pushedLeftBezelColor forThemeAttribute:@"left-segment-bezel-color" inState:CPThemeStateHighlighted];
+ [segmentedControl setValue:pushedHighlightedLeftBezelColor forThemeAttribute:@"left-segment-bezel-color" inState:CPThemeStateHighlighted|CPThemeStateSelected];
+
+ [segmentedControl setValue:CGInsetMake(0.0, 4.0, 0.0, 4.0) forThemeAttribute:@"content-inset" inState:CPThemeStateNormal];
+
+ [segmentedControl setValue:CGInsetMake(0.0, 0.0, 0.0, 0.0) forThemeAttribute:@"bezel-inset" inState:CPThemeStateNormal];
+
+ [segmentedControl setValue:[CPFont boldSystemFontOfSize:12.0] forThemeAttribute:@"font"];
+ [segmentedControl setValue:[CPColor colorWithCalibratedWhite:255.0 / 255.0 alpha:1.0] forThemeAttribute:@"text-color"];
+ [segmentedControl setValue:[CPColor colorWithCalibratedWhite:0.0 / 255.0 alpha:1.0] forThemeAttribute:@"text-shadow-color"];
+ [segmentedControl setValue:CGSizeMake(-1.0, -1.0) forThemeAttribute:@"text-shadow-offset"];
+ [segmentedControl setValue:CPLineBreakByTruncatingTail forThemeAttribute:@"line-break-mode"];
+
+ [segmentedControl setValue:1.0 forThemeAttribute:@"divider-thickness"];
+ [segmentedControl setValue:24.0 forThemeAttribute:@"default-height"];
+
+ return segmentedControl;
+}
+
++ (CPButton)button
+{
+ var button = [[CPButton alloc] initWithFrame:CGRectMake(0.0, 0.0, 60.0, 24.0)],
bezelColor = [CPColor colorWithPatternImage:[[CPThreePartImage alloc] initWithImageSlices:
[
- [_CPCibCustomResource imageResourceWithName:"HUD/button-bezel-left.png" size:CGSizeMake(13.0, 20.0)],
- [_CPCibCustomResource imageResourceWithName:"HUD/button-bezel-center.png" size:CGSizeMake(1.0, 20.0)],
- [_CPCibCustomResource imageResourceWithName:"HUD/button-bezel-right.png" size:CGSizeMake(13.0, 20.0)]
+ [_CPCibCustomResource imageResourceWithName:"HUD/button-bezel-left.png" size:CGSizeMake(4.0, 24.0)],
+ [_CPCibCustomResource imageResourceWithName:"HUD/button-bezel-center.png" size:CGSizeMake(1.0, 24.0)],
+ [_CPCibCustomResource imageResourceWithName:"HUD/button-bezel-right.png" size:CGSizeMake(4.0, 24.0)]
]
isVertical:NO]],
highlightedBezelColor = [CPColor colorWithPatternImage:[[CPThreePartImage alloc] initWithImageSlices:
[
- [_CPCibCustomResource imageResourceWithName:"HUD/button-bezel-highlighted-left.png" size:CGSizeMake(13.0, 20.0)],
- [_CPCibCustomResource imageResourceWithName:"HUD/button-bezel-highlighted-center.png" size:CGSizeMake(1.0, 20.0)],
- [_CPCibCustomResource imageResourceWithName:"HUD/button-bezel-highlighted-right.png" size:CGSizeMake(13.0, 20.0)]
+ [_CPCibCustomResource imageResourceWithName:"HUD/button-bezel-highlighted-left.png" size:CGSizeMake(4.0, 24.0)],
+ [_CPCibCustomResource imageResourceWithName:"HUD/button-bezel-highlighted-center.png" size:CGSizeMake(1.0, 24.0)],
+ [_CPCibCustomResource imageResourceWithName:"HUD/button-bezel-highlighted-right.png" size:CGSizeMake(4.0, 24.0)]
+ ]
+ isVertical:NO]],
+
+ defaultBezelColor = [CPColor colorWithPatternImage:[[CPThreePartImage alloc] initWithImageSlices:
+ [
+ [_CPCibCustomResource imageResourceWithName:"HUD/default-button-bezel-left.png" size:CGSizeMake(4.0, 24.0)],
+ [_CPCibCustomResource imageResourceWithName:"HUD/default-button-bezel-center.png" size:CGSizeMake(1.0, 24.0)],
+ [_CPCibCustomResource imageResourceWithName:"HUD/default-button-bezel-right.png" size:CGSizeMake(4.0, 24.0)]
+ ]
+ isVertical:NO]],
+
+ defaultHighlightedBezelColor = [CPColor colorWithPatternImage:[[CPThreePartImage alloc] initWithImageSlices:
+ [
+ [_CPCibCustomResource imageResourceWithName:"HUD/default-button-bezel-highlighted-left.png" size:CGSizeMake(4.0, 24.0)],
+ [_CPCibCustomResource imageResourceWithName:"HUD/default-button-bezel-highlighted-center.png" size:CGSizeMake(1.0, 24.0)],
+ [_CPCibCustomResource imageResourceWithName:"HUD/default-button-bezel-highlighted-right.png" size:CGSizeMake(4.0, 24.0)]
+ ]
+ isVertical:NO]],
+
+ defaultDisabledBezelColor = [CPColor colorWithPatternImage:[[CPThreePartImage alloc] initWithImageSlices:
+ [
+ [_CPCibCustomResource imageResourceWithName:"HUD/default-button-bezel-disabled-left.png" size:CGSizeMake(4.0, 24.0)],
+ [_CPCibCustomResource imageResourceWithName:"HUD/default-button-bezel-disabled-center.png" size:CGSizeMake(1.0, 24.0)],
+ [_CPCibCustomResource imageResourceWithName:"HUD/default-button-bezel-disabled-right.png" size:CGSizeMake(4.0, 24.0)]
+ ]
+ isVertical:NO]],
+
+ disabledBezelColor = [CPColor colorWithPatternImage:[[CPThreePartImage alloc] initWithImageSlices:
+ [
+ [_CPCibCustomResource imageResourceWithName:"HUD/button-bezel-disabled-left.png" size:CGSizeMake(4.0, 24.0)],
+ [_CPCibCustomResource imageResourceWithName:"HUD/button-bezel-disabled-center.png" size:CGSizeMake(1.0, 24.0)],
+ [_CPCibCustomResource imageResourceWithName:"HUD/button-bezel-disabled-right.png" size:CGSizeMake(4.0, 24.0)]
]
isVertical:NO]];
- [button setTitle:@"Cancel"];
+ [button setValue:[CPFont boldSystemFontOfSize:12.0] forThemeAttribute:@"font" inState:CPThemeStateBordered];
- [button setValue:[CPFont systemFontOfSize:11.0] forThemeAttribute:@"font" inState:CPThemeStateBordered];
- [button setValue:[CPColor whiteColor] forThemeAttribute:@"text-color"];
+ [button setValue:[CPColor colorWithCalibratedWhite:255.0 / 255.0 alpha:1.0] forThemeAttribute:@"text-color"];
+ [button setValue:[CPColor colorWithCalibratedWhite:0.0 / 255.0 alpha:1.0] forThemeAttribute:@"text-shadow-color" inState:CPThemeStateBordered];
+ [button setValue:[CPColor colorWithCalibratedWhite:0.0 / 255.0 alpha:0.6] forThemeAttribute:@"text-shadow-color" inState:CPThemeStateBordered|CPThemeStateDisabled];
+ [button setValue:CGSizeMake(-1.0,-1.0) forThemeAttribute:@"text-shadow-offset" inState:CPThemeStateBordered];
[button setValue:CPLineBreakByTruncatingTail forThemeAttribute:@"line-break-mode"];
-
+
[button setValue:bezelColor forThemeAttribute:@"bezel-color" inState:CPThemeStateBordered];
[button setValue:highlightedBezelColor forThemeAttribute:@"bezel-color" inState:CPThemeStateBordered|CPThemeStateHighlighted];
- [button setValue:CGInsetMake(2.0, 5.0, 4.0, 5.0) forThemeAttribute:@"content-inset" inState:CPThemeStateBordered];
+ [button setValue:CGInsetMake(0.0, 5.0, 0.0, 5.0) forThemeAttribute:@"content-inset" inState:CPThemeStateBordered];
- [button setValue:CGSizeMake(0.0, 20.0) forThemeAttribute:@"min-size"];
- [button setValue:CGSizeMake(-1.0, 20.0) forThemeAttribute:@"max-size"];
+ [button setValue:[CPColor colorWithCalibratedWhite:0.97 alpha:1.0] forThemeAttribute:@"text-color" inState:CPThemeStateDisabled];
+ [button setValue:disabledBezelColor forThemeAttribute:@"bezel-color" inState:CPThemeStateBordered|CPThemeStateDisabled];
+ [button setValue:defaultDisabledBezelColor forThemeAttribute:@"bezel-color" inState:CPThemeStateBordered|CPThemeStateDefault|CPThemeStateDisabled];
+
+ [button setValue:defaultBezelColor forThemeAttribute:@"bezel-color" inState:CPThemeStateBordered|CPThemeStateDefault];
+ [button setValue:defaultHighlightedBezelColor forThemeAttribute:@"bezel-color" inState:CPThemeStateBordered|CPThemeStateHighlighted|CPThemeStateDefault];
+ [button setValue:[CPColor colorWithCalibratedRed:250.0/255.0 green:250.0/255.0 blue:250.0/255.0 alpha:1.0] forThemeAttribute:@"text-color" inState:CPThemeStateDefault];
+ [button setValue:[CPColor colorWithCalibratedRed:250.0/255.0 green:250.0/255.0 blue:250.0/255.0 alpha:0.6] forThemeAttribute:@"text-color" inState:CPThemeStateDisabled|CPThemeStateDefault];
+
+ [button setValue:CGSizeMake(0.0, 24.0) forThemeAttribute:@"min-size"];
+ [button setValue:CGSizeMake(-1.0, 24.0) forThemeAttribute:@"max-size"];
+
+ return button;
+}
+
++ (CPButton)themedStandardButton
+{
+ var button = [self button];
+
+ [button setTitle:@"Cancel"];
+
+ return button;
+}
+
++ (CPButton)themedDefaultButton
+{
+ var button = [self button];
+
+ [button setTitle:@"OK"];
+ [button setDefaultButton:YES];
return button;
}
@@ -931,6 +1084,96 @@
return scroller;
}
++ (CPSlider)themedHorizontalSlider
+{
+ var slider = [[CPSlider alloc] initWithFrame:CGRectMake(0.0, 0.0, 50.0, 24.0)],
+ trackColor = [CPColor colorWithPatternImage:[[CPThreePartImage alloc] initWithImageSlices:
+ [
+ [_CPCibCustomResource imageResourceWithName:"HUD/horizontal-track-left.png" size:CGSizeMake(4.0, 5.0)],
+ [_CPCibCustomResource imageResourceWithName:"HUD/horizontal-track-center.png" size:CGSizeMake(1.0, 5.0)],
+ [_CPCibCustomResource imageResourceWithName:"HUD/horizontal-track-right.png" size:CGSizeMake(4.0, 5.0)]
+ ]
+ isVertical:NO]],
+
+ trackDisabledColor = [CPColor colorWithPatternImage:[[CPThreePartImage alloc] initWithImageSlices:
+ [
+ [_CPCibCustomResource imageResourceWithName:"HUD/horizontal-track-disabled-left.png" size:CGSizeMake(4.0, 5.0)],
+ [_CPCibCustomResource imageResourceWithName:"HUD/horizontal-track-disabled-center.png" size:CGSizeMake(1.0, 5.0)],
+ [_CPCibCustomResource imageResourceWithName:"HUD/horizontal-track-disabled-right.png" size:CGSizeMake(4.0, 5.0)]
+ ]
+ isVertical:NO]];
+
+ [slider setValue:5.0 forThemeAttribute:@"track-width"];
+ [slider setValue:trackColor forThemeAttribute:@"track-color"];
+ [slider setValue:trackDisabledColor forThemeAttribute:@"track-color" inState:CPThemeStateDisabled];
+
+ var knobColor = [CPColor colorWithPatternImage:[_CPCibCustomResource imageResourceWithName:"HUD/knob.png" size:CGSizeMake(23.0, 24.0)]],
+ knobHighlightedColor = [CPColor colorWithPatternImage:[_CPCibCustomResource imageResourceWithName:"HUD/knob-highlighted.png" size:CGSizeMake(23.0, 24.0)]],
+ knobDisabledColor = [CPColor colorWithPatternImage:[_CPCibCustomResource imageResourceWithName:"HUD/knob-disabled.png" size:CGSizeMake(23.0, 24.0)]];
+
+ [slider setValue:CGSizeMake(23.0, 24.0) forThemeAttribute:@"knob-size"];
+ [slider setValue:knobColor forThemeAttribute:@"knob-color"];
+ [slider setValue:knobHighlightedColor forThemeAttribute:@"knob-color" inState:CPThemeStateHighlighted];
+ [slider setValue:knobDisabledColor forThemeAttribute:@"knob-color" inState:CPThemeStateDisabled];
+
+ return slider;
+}
+
++ (CPSlider)themedVerticalSlider
+{
+ var slider = [[CPSlider alloc] initWithFrame:CGRectMake(0.0, 0.0, 24.0, 50.0)],
+ trackColor = [CPColor colorWithPatternImage:[[CPThreePartImage alloc] initWithImageSlices:
+ [
+ [_CPCibCustomResource imageResourceWithName:"HUD/vertical-track-top.png" size:CGSizeMake(5.0, 6.0)],
+ [_CPCibCustomResource imageResourceWithName:"HUD/vertical-track-center.png" size:CGSizeMake(5.0, 1.0)],
+ [_CPCibCustomResource imageResourceWithName:"HUD/vertical-track-bottom.png" size:CGSizeMake(5.0, 4.0)]
+ ]
+ isVertical:YES]],
+ trackDisabledColor = [CPColor colorWithPatternImage:[[CPThreePartImage alloc] initWithImageSlices:
+ [
+ [_CPCibCustomResource imageResourceWithName:"HUD/vertical-track-disabled-top.png" size:CGSizeMake(5.0, 6.0)],
+ [_CPCibCustomResource imageResourceWithName:"HUD/vertical-track-disabled-center.png" size:CGSizeMake(5.0, 1.0)],
+ [_CPCibCustomResource imageResourceWithName:"HUD/vertical-track-disabled-bottom.png" size:CGSizeMake(5.0, 4.0)]
+ ]
+ isVertical:YES]];
+
+ [slider setValue:5.0 forThemeAttribute:@"track-width"];
+ [slider setValue:trackColor forThemeAttribute:@"track-color" inState:CPThemeStateVertical];
+ [slider setValue:trackDisabledColor forThemeAttribute:@"track-color" inState:CPThemeStateDisabled];
+
+ var knobColor = [CPColor colorWithPatternImage:[_CPCibCustomResource imageResourceWithName:"HUD/knob.png" size:CGSizeMake(23.0, 24.0)]],
+ knobHighlightedColor = [CPColor colorWithPatternImage:[_CPCibCustomResource imageResourceWithName:"HUD/knob-highlighted.png" size:CGSizeMake(23.0, 24.0)]],
+ knobDisabledColor = [CPColor colorWithPatternImage:[_CPCibCustomResource imageResourceWithName:"HUD/knob-disabled.png" size:CGSizeMake(23.0, 24.0)]];
+
+ [slider setValue:CGSizeMake(23.0, 24.0) forThemeAttribute:@"knob-size"];
+ [slider setValue:knobColor forThemeAttribute:@"knob-color"];
+ [slider setValue:knobHighlightedColor forThemeAttribute:@"knob-color" inState:CPThemeStateHighlighted];
+ [slider setValue:knobDisabledColor forThemeAttribute:@"knob-color" inState:CPThemeStateDisabled];
+
+ return slider;
+}
++ (CPSlider)themedCircularSlider
+{
+ var slider = [[CPSlider alloc] initWithFrame:CGRectMake(0.0, 0.0, 34.0, 34.0)],
+ trackColor = PatternColor([_CPCibCustomResource imageResourceWithName:"HUD/slider-circular-bezel.png" size:CGSizeMake(34.0, 34.0)]),
+ trackDisabledColor = PatternColor([_CPCibCustomResource imageResourceWithName:"HUD/slider-circular-disabled-bezel.png" size:CGSizeMake(34.0, 34.0)]);
+
+ [slider setSliderType:CPCircularSlider];
+ [slider setValue:trackColor forThemeAttribute:@"track-color" inState:CPThemeStateCircular];
+ [slider setValue:trackDisabledColor forThemeAttribute:@"track-color" inState:CPThemeStateDisabled|CPThemeStateCircular];
+
+ var knobColor = [CPColor colorWithPatternImage:[_CPCibCustomResource imageResourceWithName:"HUD/slider-circular-knob.png" size:CGSizeMake(5.0, 5.0)]],
+ knobDisabledColor = [CPColor colorWithPatternImage:[_CPCibCustomResource imageResourceWithName:"HUD/slider-circular-disabled-knob.png" size:CGSizeMake(5.0, 5.0)]],
+ knobHighlightedColor = knobColor;
+
+ [slider setValue:CGSizeMake(5.0, 5.0) forThemeAttribute:@"knob-size" inState:CPThemeStateCircular];
+ [slider setValue:knobColor forThemeAttribute:@"knob-color" inState:CPThemeStateCircular];
+ [slider setValue:knobDisabledColor forThemeAttribute:@"knob-color" inState:CPThemeStateDisabled|CPThemeStateCircular];
+ [slider setValue:knobHighlightedColor forThemeAttribute:@"knob-color" inState:CPThemeStateCircular|CPThemeStateHighlighted];
+
+ return slider;
+}
+
@end
function PatternColor(anImage)
diff --git a/AppKit/_CPCornerView.j b/AppKit/_CPCornerView.j
index 81c4a86e5..a5e4f9a65 100644
--- a/AppKit/_CPCornerView.j
+++ b/AppKit/_CPCornerView.j
@@ -20,20 +20,6 @@
return self;
}
-- (void)drawRect:(CGRect)aRect
-{
- var context = [[CPGraphicsContext currentContext] graphicsPort];
-
- CGContextSetStrokeColor(context, [CPColor colorWithHexString:@"dce0e2"]);
-
- var points = [
- CGPointMake(aRect.origin.x, aRect.origin.y + 0.5),
- CGPointMake(aRect.origin.x, aRect.origin.y + aRect.size.height)
- ];
-
- CGContextStrokeLineSegments(context, points, 2);
-}
-
- (id)initWithCoder:(CPCoder)aCoder
{
self = [super initWithCoder:aCoder];
diff --git a/AppKit/_CPImageAndTextView.j b/AppKit/_CPImageAndTextView.j
index 695598a4d..cee931360 100644
--- a/AppKit/_CPImageAndTextView.j
+++ b/AppKit/_CPImageAndTextView.j
@@ -63,6 +63,7 @@ var HORIZONTAL_MARGIN = 3.0,
CPCellImagePosition _imagePosition;
CPImageScaling _imageScaling;
+ BOOL _shouldDimImage;
CPImage _image;
CPString _text;
@@ -211,6 +212,17 @@ var HORIZONTAL_MARGIN = 3.0,
return _imageScaling;
}
+- (void)setDimsImage:(BOOL)shouldDim
+{
+ var shouldDimImage = !!shouldDimImage;
+
+ if (_shouldDimImage !== shouldDimImage)
+ {
+ _shouldDimImage = shouldDim;
+ [self setNeedsLayout];
+ }
+}
+
- (void)setTextColor:(CPColor)aTextColor
{
if (_textColor === aTextColor)
@@ -572,6 +584,11 @@ var HORIZONTAL_MARGIN = 3.0,
imageHeight *= scale;
}
+ if (CPFeatureIsCompatible(CPOpacityRequiresFilterFeature))
+ imageStyle.filter = @"alpha(opacity=" + _shouldDimImage ? 35 : 100 + ")";
+ else
+ imageStyle.opacity = _shouldDimImage ? 0.35 : 1.0;
+
_DOMImageElement.width = imageWidth;
_DOMImageElement.height = imageHeight;
imageStyle.width = MAX(imageWidth, 0) + "px";
diff --git a/CommonJS/lib/cappuccino/nativehost.js b/CommonJS/lib/cappuccino/nativehost.js
new file mode 100644
index 000000000..8def87642
--- /dev/null
+++ b/CommonJS/lib/cappuccino/nativehost.js
@@ -0,0 +1,70 @@
+var FILE = require("file");
+var OS = require("os");
+
+var NATIVEHOST_SOURCE = FILE.path(module.path).dirname().dirname().dirname().join("support", "NativeHost.app");
+
+exports.buildNativeHost = function(rootPath, buildNative, options) {
+ options = options || {};
+ options.index = options.index || "index.html";
+
+ rootPath = FILE.path(rootPath);
+ buildNative = FILE.path(buildNative);
+
+ if (buildNative.exists())
+ buildNative.rmtree();
+
+ buildNative.dirname().mkdirs();
+ // FIXME: Narwhal doesn't preserve permissions
+ // FILE.copyTree(NATIVEHOST_SOURCE, buildNative);
+ OS.system(["cp", "-r", NATIVEHOST_SOURCE, buildNative]);
+ FILE.chmod(buildNative.join("Contents", "MacOS", "NativeHost"), 0755);
+
+ var rootBaseName = rootPath.basename();
+ var buildClientDirectory = buildNative.join("Contents", "Resources", rootBaseName);
+
+ FILE.mkdirs(FILE.dirname(buildClientDirectory));
+ // FILE.copyTree(rootPath, buildClientDirectory);
+ OS.system(["cp", "-r", rootPath, buildClientDirectory]);
+
+ var defaultBundleName = buildNative.basename().match(/^(.*)(\.app)?$/)[1];
+
+ function mergePlist(plist, path) {
+ var otherPlist = CFPropertyList.readPropertyListFromFile(String(path));
+
+ otherPlist.keys().forEach(function(key) {
+ var value = otherPlist.valueForKey(key);
+ plist.setValueForKey(key, value);
+
+ if (key === "CPBundleName")
+ plist.setValueForKey("CFBundleName", value);
+
+ if (key === "CFBundleIconFile") {
+ var iconPath = rootPath.join("Resources", value);
+ if (iconPath.isFile())
+ iconPath.copy(buildNative.join("Contents", "Resources", value));
+ else
+ print("Warning: CFBundleIconFile references " + value + " but does not exist in the resources directory.");
+ }
+
+ if (key === "CFBundleExecutable") {
+ buildNative.join("Contents", "MacOS", "NativeHost").rename(value);
+ // FIXME:
+ FILE.chmod(buildNative.join("Contents", "MacOS", value), 0755);
+ }
+ });
+ }
+
+ CFPropertyList.modifyPlist(buildNative.join("Contents", "Info.plist"), function(plist) {
+
+ plist.setValueForKey("CFBundleName", defaultBundleName);
+ plist.setValueForKey("NHInitialResource", FILE.join(rootBaseName, options.index));
+
+ // merge Cappuccino plist
+ var cappPlistPath = rootPath.join("Info.plist");
+ if (cappPlistPath.isFile())
+ mergePlist(plist, cappPlistPath);
+
+ if (options.extraPlistPath)
+ mergePlist(plist, options.extraPlistPath);
+ });
+}
diff --git a/CommonJS/lib/cappuccino/objj-flatten-additions.js b/CommonJS/lib/cappuccino/objj-flatten-additions.js
index 2b4781e62..4c69f133e 100644
--- a/CommonJS/lib/cappuccino/objj-flatten-additions.js
+++ b/CommonJS/lib/cappuccino/objj-flatten-additions.js
@@ -1,6 +1,7 @@
var URLCache = { };
+var CFHTTPRequest_open = CFHTTPRequest.prototype.open;
CFHTTPRequest.prototype.open = function(/*String*/ method, /*String*/ url, /*Boolean*/ async, /*String*/ user, /*String*/ password)
{
var cachedRequest = CFHTTPRequest._lookupCachedRequest(url);
@@ -13,7 +14,7 @@ CFHTTPRequest.prototype.open = function(/*String*/ method, /*String*/ url, /*Boo
ObjectiveJ.determineAndDispatchHTTPRequestEvents(self);
};
}
- return this._nativeRequest.open(method, url, async, user, password);
+ return CFHTTPRequest_open.apply(this, arguments);
}
CFHTTPRequest._cacheRequest = function(/*CFURL|String*/ aURL, /*Number*/ status, /*Object*/ headers, /*String*/ body)
diff --git a/Foundation/CPArray+KVO.j b/Foundation/CPArray+KVO.j
index f0269b968..03274b748 100644
--- a/Foundation/CPArray+KVO.j
+++ b/Foundation/CPArray+KVO.j
@@ -23,6 +23,7 @@
@import "CPArray.j"
@import "CPNull.j"
+
@implementation CPObject (CPArrayKVO)
- (id)mutableArrayValueForKey:(id)aKey
@@ -33,12 +34,12 @@
- (id)mutableArrayValueForKeyPath:(id)aKeyPath
{
var dotIndex = aKeyPath.indexOf(".");
-
+
if (dotIndex < 0)
return [self mutableArrayValueForKey:aKeyPath];
var firstPart = aKeyPath.substring(0, dotIndex),
- lastPart = aKeyPath.substring(dotIndex+1);
+ lastPart = aKeyPath.substring(dotIndex + 1);
return [[self valueForKeyPath:firstPart] valueForKeyPath:lastPart];
}
@@ -49,34 +50,34 @@
{
id _proxyObject;
id _key;
-
+
SEL _insertSEL;
Function _insert;
-
+
SEL _removeSEL;
Function _remove;
-
+
SEL _replaceSEL;
Function _replace;
-
+
SEL _insertManySEL;
Function _insertMany;
-
+
SEL _removeManySEL;
Function _removeMany;
-
+
SEL _replaceManySEL;
Function _replaceMany;
-
+
SEL _objectAtIndexSEL;
Function _objectAtIndex;
-
+
SEL _countSEL;
Function _count;
-
+
SEL _accessSEL;
Function _access;
-
+
SEL _setSEL;
Function _set;
}
@@ -96,15 +97,15 @@
return array;
}
--(id)initWithKey:(id)aKey forProxyObject:(id)anObject
+- (id)initWithKey:(id)aKey forProxyObject:(id)anObject
{
self = [super init];
_key = aKey;
_proxyObject = anObject;
-
+
var capitalizedKey = _key.charAt(0).toUpperCase() + _key.substring(1);
-
+
_insertSEL = sel_getName(@"insertObject:in"+capitalizedKey+"AtIndex:");
if ([_proxyObject respondsToSelector:_insertSEL])
_insert = [_proxyObject methodForSelector:_insertSEL];
@@ -112,7 +113,7 @@
_removeSEL = sel_getName(@"removeObjectFrom"+capitalizedKey+"AtIndex:");
if ([_proxyObject respondsToSelector:_removeSEL])
_remove = [_proxyObject methodForSelector:_removeSEL];
-
+
_replaceSEL = sel_getName(@"replaceObjectFrom"+capitalizedKey+"AtIndex:withObject:");
if ([_proxyObject respondsToSelector:_replaceSEL])
_replace = [_proxyObject methodForSelector:_replaceSEL];
@@ -124,11 +125,11 @@
_removeManySEL = sel_getName(@"removeObjectsFrom"+capitalizedKey+"AtIndexes:");
if ([_proxyObject respondsToSelector:_removeManySEL])
_remove = [_proxyObject methodForSelector:_removeManySEL];
-
+
_replaceManySEL = sel_getName(@"replaceObjectsFrom"+capitalizedKey+"AtIndexes:withObjects:");
if ([_proxyObject respondsToSelector:_replaceManySEL])
_replace = [_proxyObject methodForSelector:_replaceManySEL];
-
+
_objectAtIndexSEL = sel_getName(@"objectIn"+capitalizedKey+"AtIndex:");
if ([_proxyObject respondsToSelector:_objectAtIndexSEL])
_objectAtIndex = [_proxyObject methodForSelector:_objectAtIndexSEL];
@@ -150,16 +151,17 @@
- (id)copy
{
- var theCopy = [],
+ var i = 0,
+ theCopy = [],
count = [self count];
- for (var i=0; i= 0)
{
[self[index] addObserver:anObserver forKeyPath:aKeyPath options:options context:context];
@@ -468,7 +483,7 @@ kvoOperators["sum"] = function sumOperator(self, _cmd, param)
- (void)removeObserver:(id)anObserver fromObjectsAtIndexes:(CPIndexSet)indexes forKeyPath:(CPString)aKeyPath
{
var index = [indexes firstIndex];
-
+
while (index >= 0)
{
[self[index] removeObserver:anObserver forKeyPath:aKeyPath];
@@ -477,7 +492,7 @@ kvoOperators["sum"] = function sumOperator(self, _cmd, param)
}
}
--(void)addObserver:(id)observer forKeyPath:(CPString)aKeyPath options:(unsigned)options context:(id)context
+- (void)addObserver:(id)observer forKeyPath:(CPString)aKeyPath options:(unsigned)options context:(id)context
{
if ([isa instanceMethodForSelector:_cmd] === [CPArray instanceMethodForSelector:_cmd])
[CPException raise:CPInvalidArgumentException reason:"Unsupported method on CPArray"];
diff --git a/Foundation/CPArray.j b/Foundation/CPArray.j
index 81711e4d2..e10f8e8b0 100755
--- a/Foundation/CPArray.j
+++ b/Foundation/CPArray.j
@@ -20,11 +20,11 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+@import "CPEnumerator.j"
+@import "CPException.j"
@import "CPObject.j"
@import "CPRange.j"
-@import "CPEnumerator.j"
@import "CPSortDescriptor.j"
-@import "CPException.j"
/* @ignore */
@@ -37,7 +37,7 @@
- (id)initWithArray:(CPArray)anArray
{
self = [super init];
-
+
if (self)
{
_array = anArray;
@@ -67,13 +67,13 @@
- (id)initWithArray:(CPArray)anArray
{
self = [super init];
-
+
if (self)
{
_array = anArray;
_index = [_array count];
}
-
+
return self;
}
@@ -87,7 +87,7 @@
@end
-/*!
+/*!
@class CPArray
@brief A mutable array backed by a JavaScript Array.
@ingroup foundation
@@ -145,10 +145,10 @@
{
var i = 2,
array = [[self alloc] init],
- argument;
+ count = arguments.length;
- for(; i < arguments.length && (argument = arguments[i]) != nil; ++i)
- array.push(argument);
+ for (; i < count; ++i)
+ array.push(arguments[i]);
return array;
}
@@ -182,10 +182,10 @@
- (id)initWithArray:(CPArray)anArray
{
self = [super init];
-
+
if (self)
[self setArray:anArray];
-
+
return self;
}
@@ -203,22 +203,22 @@
return [self initWithArray:anArray];
self = [super init];
-
+
if (self)
{
var index = 0,
count = [anArray count];
-
- for(; index < count; ++index)
+
+ for (; index < count; ++index)
{
if (anArray[index].isa)
self[index] = [anArray[index] copy];
// Do a deep/shallow copy?
else
- self[index] = anArray;
+ self[index] = anArray[index];
}
}
-
+
return self;
}
@@ -229,12 +229,12 @@
{
// The arguments array contains self and _cmd, so the first object is at position 2.
var i = 2,
- argument;
-
- for(; i < arguments.length && (argument = arguments[i]) != nil; ++i)
- push(argument);
+ count = arguments.length;
- return self;
+ for (; i < count; ++i)
+ push(arguments[i]);
+
+ return self;
}
/*!
@@ -246,12 +246,12 @@
- (id)initWithObjects:(id)objects count:(unsigned)aCount
{
self = [super init];
-
+
if (self)
{
var index = 0;
-
- for(; index < aCount; ++index)
+
+ for (; index < aCount; ++index)
push(objects[index]);
}
@@ -278,97 +278,88 @@
/*!
Returns the index of \c anObject in this array.
- If the object is \c nil or not in the array,
+ If the object is not in the array,
returns \c CPNotFound. It first attempts to find
- a match using \c -isEqual:, then \c ==.
+ a match using \c -isEqual:, then \c ===.
@param anObject the object to search for
*/
- (int)indexOfObject:(id)anObject
{
- if (anObject === nil)
- return CPNotFound;
-
- var i = 0,
+ var i = 0,
count = length;
// Only use -isEqual: if our object is a CPObject.
- if (anObject.isa)
+ if (anObject && anObject.isa)
{
- for(; i < count; ++i)
- if([self[i] isEqual:anObject])
+ for (; i < count; ++i)
+ if ([self[i] isEqual:anObject])
return i;
}
- // If indexOf exists, use it since it's probably
+ // If indexOf exists, use it since it's probably
// faster than anything we can implement.
else if (self.indexOf)
return indexOf(anObject);
// Last resort, do a straight forward linear O(N) search.
else
- for(; i < count; ++i)
- if(self[i] == anObject)
+ for (; i < count; ++i)
+ if (self[i] === anObject)
return i;
-
+
return CPNotFound;
}
/*!
Returns the index of \c anObject in the array
within \c aRange. It first attempts to find
- a match using \c -isEqual:, then \c ==.
+ a match using \c -isEqual:, then \c ===.
@param anObject the object to search for
@param aRange the range to search within
@return the index of the object, or \c CPNotFound if it was not found.
*/
- (int)indexOfObject:(id)anObject inRange:(CPRange)aRange
{
- if (anObject === nil || anObject === undefined)
- return CPNotFound;
-
- var i = aRange.location,
+ var i = aRange.location,
count = MIN(CPMaxRange(aRange), length);
-
+
// Only use isEqual: if our object is a CPObject.
- if (anObject.isa)
+ if (anObject && anObject.isa)
{
- for(; i < count; ++i)
- if([self[i] isEqual:anObject])
+ for (; i < count; ++i)
+ if ([self[i] isEqual:anObject])
return i;
}
// Last resort, do a straight forward linear O(N) search.
else
- for(; i < count; ++i)
- if(self[i] == anObject)
+ for (; i < count; ++i)
+ if (self[i] === anObject)
return i;
-
+
return CPNotFound;
}
/*!
- Returns the index of \c anObject in the array. The test for equality is done using only \c ==.
+ Returns the index of \c anObject in the array. The test for equality is done using only \c ===.
@param anObject the object to search for
@return the index of the object in the array. \c CPNotFound if the object is not in the array.
*/
- (int)indexOfObjectIdenticalTo:(id)anObject
{
- if (anObject === nil)
- return CPNotFound;
-
- // If indexOf exists, use it since it's probably
+ // If indexOf exists, use it since it's probably
// faster than anything we can implement.
if (self.indexOf)
return indexOf(anObject);
-
+
// Last resort, do a straight forward linear O(N) search.
else
{
- var index = 0,
+ var index = 0,
count = length;
-
- for(; index < count; ++index)
- if(self[index] === anObject)
+
+ for (; index < count; ++index)
+ if (self[index] === anObject)
return index;
}
-
+
return CPNotFound;
}
@@ -382,36 +373,33 @@
*/
- (int)indexOfObjectIdenticalTo:(id)anObject inRange:(CPRange)aRange
{
- if (anObject === nil)
- return CPNotFound;
-
- // If indexOf exists, use it since it's probably
+ // If indexOf exists, use it since it's probably
// faster than anything we can implement.
if (self.indexOf)
{
var index = indexOf(anObject, aRange.location);
-
+
if (CPLocationInRange(index, aRange))
return index;
}
-
+
// Last resort, do a straight forward linear O(N) search.
else
{
- var index = aRange.location,
+ var index = aRange.location,
count = MIN(CPMaxRange(aRange), length);
-
- for(; index < count; ++index)
- if(self[index] == anObject)
+
+ for (; index < count; ++index)
+ if (self[index] == anObject)
return index;
}
-
+
return CPNotFound;
}
/*!
Returns the index of \c anObject in the array, which must be sorted in the same order as
- calling sortUsingSelector: with the selector passed to this method would result in.
+ calling sortUsingSelector: with the selector passed to this method would result in.
@param anObject the object to search for
@param aSelector the comparison selector to call on each item in the list, the same
selector should have been used to sort the array (or to maintain its sorted order).
@@ -419,12 +407,12 @@
*/
- (unsigned)indexOfObject:(id)anObject sortedBySelector:(SEL)aSelector
{
- return [self indexOfObject:anObject sortedByFunction: function(lhs, rhs) { objj_msgSend(lhs, aSelector, rhs); }];
+ return [self indexOfObject:anObject sortedByFunction:function(lhs, rhs) { objj_msgSend(lhs, aSelector, rhs); }];
}
/*!
Returns the index of \c anObject in the array, which must be sorted in the same order as
- calling sortUsingFunction: with the selector passed to this method would result in.
+ calling sortUsingFunction: with the selector passed to this method would result in.
The function will be called like so:
aFunction(anObject, currentObjectInArrayForComparison)
@@ -441,7 +429,7 @@
/*!
Returns the index of \c anObject in the array, which must be sorted in the same order as
- calling sortUsingFunction: with the selector passed to this method would result in.
+ calling sortUsingFunction: with the selector passed to this method would result in.
The function will be called like so:
aFunction(anObject, currentObjectInArrayForComparison, context)
@@ -460,13 +448,17 @@
- (unsigned)_indexOfObject:(id)anObject sortedByFunction:(Function)aFunction context:(id)aContext
{
- if (!aFunction || anObject === undefined)
+ if (!aFunction)
return CPNotFound;
if (length === 0)
return -1;
- var mid, c, first = 0, last = length - 1;
+ var mid,
+ c,
+ first = 0,
+ last = length - 1;
+
while (first <= last)
{
mid = FLOOR((first + last) / 2);
@@ -478,19 +470,19 @@
last = mid - 1;
else
{
- while (mid < length - 1 && aFunction(anObject, self[mid+1], aContext) == CPOrderedSame)
+ while (mid < length - 1 && aFunction(anObject, self[mid + 1], aContext) == CPOrderedSame)
mid++;
return mid;
}
}
- return -first-1;
+ return -first - 1;
}
/*!
Returns the index of \c anObject in the array, which must be sorted in the same order as
- calling sortUsingDescriptors: with the descriptors passed to this method would result in.
+ calling sortUsingDescriptors: with the descriptors passed to this method would result in.
@param anObject the object to search for
@param descriptors the array of descriptors to use to compare each item in the array that we search. the same
descriptors should have been used to sort the array (or to maintain its sorted order).
@@ -498,14 +490,15 @@
*/
- (unsigned)indexOfObject:(id)anObject sortedByDescriptors:(CPArray)descriptors
{
+ var count = [descriptors count];
+
return [self indexOfObject:anObject sortedByFunction:function(lhs, rhs)
{
var i = 0,
- count = [descriptors count],
result = CPOrderedSame;
while (i < count)
- if((result = [descriptors[i++] compareObject:lhs withObject:rhs]) != CPOrderedSame)
+ if ((result = [descriptors[i++] compareObject:lhs withObject:rhs]) != CPOrderedSame)
return result;
return result;
@@ -539,9 +532,10 @@
- (id)lastObject
{
var count = [self count];
-
- if (!count) return nil;
-
+
+ if (!count)
+ return nil;
+
return self[count - 1];
}
@@ -567,7 +561,7 @@
var index = CPNotFound,
objects = [];
- while((index = [indexes indexGreaterThanIndex:index]) !== CPNotFound)
+ while ((index = [indexes indexGreaterThanIndex:index]) !== CPNotFound)
[objects addObject:[self objectAtIndex:index]];
return objects;
@@ -603,11 +597,11 @@
{
if (!aSelector)
[CPException raise:CPInvalidArgumentException reason:"makeObjectsPerformSelector: 'aSelector' can't be nil"];
-
- var index = 0,
+
+ var index = 0,
count = length;
-
- for(; index < count; ++index)
+
+ for (; index < count; ++index)
objj_msgSend(self[index], aSelector);
}
@@ -622,10 +616,10 @@
if (!aSelector)
[CPException raise:CPInvalidArgumentException reason:"makeObjectsPerformSelector:withObject 'aSelector' can't be nil"];
- var index = 0,
+ var index = 0,
count = length;
-
- for(; index < count; ++index)
+
+ for (; index < count; ++index)
objj_msgSend(self[index], aSelector, anObject);
}
@@ -638,7 +632,7 @@
count = length,
argumentsArray = [nil, aSelector].concat(objects || []);
- for(; index < count; ++index)
+ for (; index < count; ++index)
{
argumentsArray[0] = self[index];
objj_msgSend.apply(this, argumentsArray);
@@ -656,12 +650,12 @@
{
if (![anArray count] || ![self count])
return nil;
-
+
var i = 0,
count = [self count];
- for(; i < count; ++i)
- if([anArray containsObject:self[i]])
+ for (; i < count; ++i)
+ if ([anArray containsObject:self[i]])
return self[i];
return nil;
@@ -677,20 +671,20 @@
if (anArray === nil || length !== anArray.length)
return NO;
-
+
var index = 0,
count = [self count];
-
- for(; index < count; ++index)
+
+ for (; index < count; ++index)
{
var lhs = self[index],
rhs = anArray[index];
-
+
// If they're not equal, and either doesn't have an isa, or they're !isEqual (not isEqual)
if (lhs !== rhs && (lhs && !lhs.isa || rhs && !rhs.isa || ![lhs isEqual:rhs]))
return NO;
}
-
+
return YES;
}
@@ -698,8 +692,8 @@
{
if (self === anObject)
return YES;
-
- if(![anObject isKindOfClass:[CPArray class]])
+
+ if (![anObject isKindOfClass:[CPArray class]])
return NO;
return [self isEqualToArray:anObject];
@@ -714,14 +708,9 @@
*/
- (CPArray)arrayByAddingObject:(id)anObject
{
- if (anObject === nil || anObject === undefined)
- [CPException raise:CPInvalidArgumentException
- reason:"arrayByAddingObject: object can't be nil"];
-
var array = [self copy];
-
array.push(anObject);
-
+
return array;
}
@@ -734,17 +723,17 @@
return slice(0).concat(anArray);
}
-/*
+/*
- (CPArray)filteredArrayUsingPredicate:(CPPredicate)aPredicate
{
- var i= 0,
+ var i= 0,
count = [self count],
array = [CPArray array];
-
- for(; i= [self count] + indexesCount)
- [CPException raise:CPRangeException reason:"the last index (" + lastIndex + ") must be less than the sum of the original count (" + [self count] + ") and the insertion count (" + indexesCount + ")."];
-
+
+ if (lastIndex >= [self count] + indexesCount)
+ [CPException raise:CPRangeException reason:"the last index (" + lastIndex + ") must be less than the sum of the original count (" + [self count] + ") and the insertion count (" + indexesCount + ")."];
+
var index = 0,
currentIndex = [indexes firstIndex];
-
+
for (; index < objectsCount; ++index, currentIndex = [indexes indexGreaterThanIndex:currentIndex])
[self insertObject:objects[index] atIndex:currentIndex];
}
- (unsigned)insertObject:(id)anObject inArraySortedByDescriptors:(CPArray)descriptors
{
+ var count = [descriptors count];
+
var index = [self _indexOfObject:anObject sortedByFunction:function(lhs, rhs)
{
var i = 0,
- count = [descriptors count],
result = CPOrderedSame;
while (i < count)
@@ -1018,7 +1008,7 @@
} context:nil];
if (index < 0)
- index = -index-1;
+ index = -index - 1;
[self insertObject:anObject atIndex:index];
return index;
@@ -1042,10 +1032,10 @@
*/
- (void)replaceObjectsAtIndexes:(CPIndexSet)anIndexSet withObjects:(CPArray)objects
{
- var i = 0,
+ var i = 0,
index = [anIndexSet firstIndex];
-
- while(index != CPNotFound)
+
+ while (index != CPNotFound)
{
[self replaceObjectAtIndex:index withObject:objects[i++]];
index = [anIndexSet indexGreaterThanIndex:index];
@@ -1086,8 +1076,9 @@
*/
- (void)setArray:(CPArray)anArray
{
- if(self == anArray) return;
-
+ if (self == anArray)
+ return;
+
splice.apply(self, [0, length].concat(anArray));
}
@@ -1125,7 +1116,7 @@
- (void)removeObject:(id)anObject inRange:(CPRange)aRange
{
var index;
-
+
while ((index = [self indexOfObject:anObject inRange:aRange]) != CPNotFound)
{
[self removeObjectAtIndex:index];
@@ -1149,7 +1140,7 @@
- (void)removeObjectsAtIndexes:(CPIndexSet)anIndexSet
{
var index = [anIndexSet lastIndex];
-
+
while (index != CPNotFound)
{
[self removeObjectAtIndex:index];
@@ -1178,7 +1169,7 @@
{
var index,
count = [self count];
-
+
while ((index = [self indexOfObjectIdenticalTo:anObject inRange:aRange]) !== CPNotFound)
{
[self removeObjectAtIndex:index];
@@ -1194,7 +1185,7 @@
{
var index = 0,
count = [anArray count];
-
+
for (; index < count; ++index)
[self removeObject:anArray[index]];
}
@@ -1223,16 +1214,17 @@
- (CPArray)sortUsingDescriptors:(CPArray)descriptors
{
+ var count = [descriptors count];
+
sort(function(lhs, rhs)
{
var i = 0,
- count = [descriptors count],
result = CPOrderedSame;
-
- while(i < count)
- if((result = [descriptors[i++] compareObject:lhs withObject:rhs]) != CPOrderedSame)
+
+ while (i < count)
+ if ((result = [descriptors[i++] compareObject:lhs withObject:rhs]) != CPOrderedSame)
return result;
-
+
return result;
});
}
diff --git a/Foundation/CPAttributedString.j b/Foundation/CPAttributedString.j
index 82e7f93a7..f61b5c0e1 100644
--- a/Foundation/CPAttributedString.j
+++ b/Foundation/CPAttributedString.j
@@ -20,12 +20,13 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-@import "CPObject.j"
-@import "CPString.j"
@import "CPDictionary.j"
+@import "CPObject.j"
@import "CPRange.j"
+@import "CPString.j"
-/*!
+
+/*!
@class CPAttributedString
@ingroup foundation
@brief A mutable character string with attributes.
@@ -62,13 +63,13 @@
Creates a new attributed string from an existing attributed string.
@param aString is the attributed string to initialise from.
@return a new CPAttributedString containing the string \c aString.
-*/
+*/
- (id)initWithAttributedString:(CPAttributedString)aString
{
var string = [self initWithString:"" attributes:nil];
-
+
[string setAttributedString:aString];
-
+
return string;
}
@@ -79,16 +80,19 @@
@param attributes is a dictionary of string attributes.
@return a new CPAttributedString containing the string \c aString
with associated attributes, \c attributes.
-*/
+*/
- (id)initWithString:(CPString)aString attributes:(CPDictionary)attributes
{
self = [super init];
-
- if (!attributes)
- attributes = [CPDictionary dictionary];
- _string = ""+aString;
- _rangeEntries = [makeRangeEntry(CPMakeRange(0, _string.length), attributes)];
+ if (self)
+ {
+ if (!attributes)
+ attributes = [CPDictionary dictionary];
+
+ _string = ""+aString;
+ _rangeEntries = [makeRangeEntry(CPMakeRange(0, _string.length), attributes)];
+ }
return self;
}
@@ -98,7 +102,7 @@
Returns a string containing the receiver's character data without
attributes.
@return a string of type CPString.
-*/
+*/
- (CPString)string
{
return _string;
@@ -108,17 +112,17 @@
Returns a string containing the receiver's character data without
attributes.
@return a string of type CPString.
-*/
+*/
- (CPString)mutableString
{
return [self string];
-}
+}
/*!
Get the length of the string.
@return an unsigned integer equivalent to the number of characters in the
string.
-*/
+*/
- (unsigned)length
{
return _string.length;
@@ -149,7 +153,7 @@
/*!
Returns a dictionary of attributes for the character at a given index. The
range in which this character resides in which the attributes are the
- same, can be returned if desired.
+ same, can be returned if desired.
@note there is no guarantee that the range returned is in fact the complete
range of the particular attributes. To ensure this use
\c attributesAtIndex:longestEffectiveRange:inRange: instead. Note
@@ -160,10 +164,10 @@
that is set (upon return) to the range over which the attributes are the
same as those at index, \c anIndex. If not required pass
\c nil.
- @return a CPDictionary containing the attributes associated with the
+ @return a CPDictionary containing the attributes associated with the
character at index \c anIndex. Returns \c nil if index
is out of bounds.
-*/
+*/
- (CPDictionary)attributesAtIndex:(unsigned)anIndex effectiveRange:(CPRangePointer)aRange
{
//find the range entry that contains anIndex.
@@ -178,7 +182,7 @@
aRange.location = matchingRange.range.location;
aRange.length = matchingRange.range.length;
}
-
+
return matchingRange.attributes;
}
@@ -199,17 +203,17 @@
to the range over which the attributes apply.
@param rangeLimit a range limiting the search for the attributes' applicable
range.
- @return a CPDictionary containing the attributes associated with the
+ @return a CPDictionary containing the attributes associated with the
character at index \c anIndex. Returns \c nil if index
is out of bounds.
-*/
+*/
- (CPDictionary)attributesAtIndex:(unsigned)anIndex longestEffectiveRange:(CPRangePointer)aRange inRange:(CPRange)rangeLimit
-{
+{
var startingEntryIndex = [self _indexOfEntryWithIndex:anIndex];
if (startingEntryIndex == CPNotFound)
return nil;
-
+
if (!aRange)
return _rangeEntries[startingEntryIndex].attributes;
@@ -217,7 +221,7 @@
{
aRange.location = rangeLimit.location;
aRange.length = rangeLimit.length;
-
+
return _rangeEntries[startingEntryIndex].attributes;
}
@@ -257,7 +261,7 @@
else
break;
}
-
+
aRange.length = MIN(CPMaxRange(currentEntry.range), CPMaxRange(rangeLimit)) - aRange.location;
return comparisonDict;
@@ -265,7 +269,7 @@
/*!
Returns the specified named attribute for the given character index and, if
- required, the range over which the attribute applies.
+ required, the range over which the attribute applies.
@note there is no guarantee that the range returned is in fact the complete
range of a particular attribute. To ensure this use
\c -attribute:atIndex:longestEffectiveRange:inRange: instead but
@@ -278,7 +282,7 @@
\c nil.
@return the named attribute or \c nil is the attribute does not
exist.
-*/
+*/
- (id)attribute:(CPString)attribute atIndex:(unsigned)index effectiveRange:(CPRangePointer)aRange
{
if (!attribute)
@@ -320,7 +324,7 @@
{
//find the range entry that contains anIndex.
var startingEntryIndex = [self _indexOfEntryWithIndex:anIndex];
-
+
if (startingEntryIndex == CPNotFound || !attribute)
return nil;
@@ -331,7 +335,7 @@
{
aRange.location = rangeLimit.location;
aRange.length = rangeLimit.length;
-
+
return [_rangeEntries[startingEntryIndex].attributes objectForKey:attribute];
}
@@ -371,7 +375,7 @@
else
break;
}
-
+
aRange.length = MIN(CPMaxRange(currentEntry.range), CPMaxRange(rangeLimit)) - aRange.location;
return comparisonAttribute;
@@ -386,10 +390,10 @@
*/
- (BOOL)isEqualToAttributedString:(CPAttributedString)aString
{
- if(!aString)
+ if (!aString)
return NO;
- if(_string != [aString string])
+ if (_string != [aString string])
return NO;
var myRange = CPMakeRange(),
@@ -407,7 +411,7 @@
else
comparisonAttributes = [aString attributesAtIndex:CPMaxRange(comparisonRange) effectiveRange:comparisonRange];
}
-
+
return YES;
}
@@ -422,10 +426,10 @@
{
if (anObject == self)
return YES;
-
+
if ([anObject isKindOfClass:[self class]])
return [self isEqualToAttributedString:anObject];
-
+
return NO;
}
@@ -440,7 +444,7 @@
- (CPAttributedString)attributedSubstringFromRange:(CPRange)aRange
{
if (!aRange || CPMaxRange(aRange) > _string.length || aRange.location < 0)
- [CPException raise:CPRangeException
+ [CPException raise:CPRangeException
reason:"tried to get attributedSubstring for an invalid range: "+(aRange?CPStringFromRange(aRange):"nil")];
var newString = [[CPAttributedString alloc] initWithString:_string.substring(aRange.location, CPMaxRange(aRange))],
@@ -449,7 +453,7 @@
lastIndex = CPMaxRange(aRange);
newString._rangeEntries = [];
-
+
while (currentRangeEntry && CPMaxRange(currentRangeEntry.range) < lastIndex)
{
var newEntry = copyRangeEntry(currentRangeEntry);
@@ -468,10 +472,10 @@
if (currentRangeEntry)
{
var newRangeEntry = copyRangeEntry(currentRangeEntry);
-
+
newRangeEntry.range.length = CPMaxRange(aRange) - newRangeEntry.range.location;
newRangeEntry.range.location -= aRange.location;
-
+
if (newRangeEntry.range.location < 0)
{
newRangeEntry.range.length += newRangeEntry.range.location;
@@ -480,12 +484,12 @@
newString._rangeEntries.push(newRangeEntry);
}
-
+
return newString;
}
//Changing Characters
-/*!
+/*!
Replaces the characters in the receiver with those of the specified string
over the range, \c aRange. If the range has a length of 0 then
the specified string is inserted at the range location. The new characters
@@ -505,10 +509,10 @@
if (!aString)
aString = "";
-
+
var startingIndex = [self _indexOfEntryWithIndex:aRange.location],
startingRangeEntry = _rangeEntries[startingIndex],
- endingIndex = [self _indexOfEntryWithIndex:MAX(CPMaxRange(aRange)-1, 0)],
+ endingIndex = [self _indexOfEntryWithIndex:MAX(CPMaxRange(aRange) - 1, 0)],
endingRangeEntry = _rangeEntries[endingIndex],
additionalLength = aString.length - aRange.length;
@@ -527,10 +531,10 @@
}
endingIndex = startingIndex + 1;
-
+
while(endingIndex < _rangeEntries.length)
_rangeEntries[endingIndex++].range.location+=additionalLength;
-
+
[self endEditing];
}
@@ -545,9 +549,9 @@
//Changing Attributes
/*!
- Sets the attributes of the specified character range.
+ Sets the attributes of the specified character range.
- @note This process removes the attributes already associated with the
+ @note This process removes the attributes already associated with the
character range. If you wish to retain the current attributes use
\c -addAttributes:range:.
@param aDictionary a CPDictionary of attributes (names and values) to set
@@ -576,11 +580,11 @@
}
/*!
- Add a collection of attributes to the specified character range.
+ Add a collection of attributes to the specified character range.
@note Attributes currently associated with the characters in the range are
untouched. To remove all previous attributes when adding use
- \c -setAttributes:range:.
+ \c -setAttributes:range:.
@param aDictionary a CPDictionary of attributes (names and values) to add.
@param aRange a CPRange indicating the range of characters to add the
attributes to.
@@ -600,7 +604,7 @@
{
var keys = [aDictionary allKeys],
count = [keys count];
-
+
while (count--)
[_rangeEntries[current].attributes setObject:[aDictionary objectForKey:keys[count]] forKey:keys[count]];
@@ -703,8 +707,8 @@
{
var entryCopy = copyRangeEntry(otherRangeEntries[index++]);
entryCopy.range.location += anIndex;
-
- _rangeEntries.splice(entryIndexOfNextEntry-1+index, 0, entryCopy);
+
+ _rangeEntries.splice(entryIndexOfNextEntry - 1 + index, 0, entryCopy);
}
//necessary?
@@ -724,10 +728,10 @@
- (void)replaceCharactersInRange:(CPRange)aRange withAttributedString:(CPAttributedString)aString
{
[self beginEditing];
-
+
[self deleteCharactersInRange:aRange];
[self insertAttributedString:aString atIndex:aRange.location];
-
+
[self endEditing];
}
@@ -739,11 +743,14 @@
- (void)setAttributedString:(CPAttributedString)aString
{
[self beginEditing];
-
+
_string = aString._string;
_rangeEntries = [];
-
- for (var i=0, count = aString._rangeEntries.length; i= _rangeEntries.length)
- end = _rangeEntries.length -1;
+ end = _rangeEntries.length - 1;
while (current < end)
{
var a = _rangeEntries[current],
- b = _rangeEntries[current+1];
+ b = _rangeEntries[current + 1];
if ([a.attributes isEqualToDictionary:b.attributes])
{
a.range.length = CPMaxRange(b.range) - a.range.location;
- _rangeEntries.splice(current+1, 1);
+ _rangeEntries.splice(current + 1, 1);
end--;
}
else
@@ -821,7 +828,8 @@
CPAttributedString already implements mutable methods and
this class only exists for source compatability.
*/
-@implementation CPMutableAttributedString : CPAttributedString {}
+@implementation CPMutableAttributedString : CPAttributedString
+
@end
var isEqual = function isEqual(a, b)
@@ -849,11 +857,11 @@ var splitRangeEntry = function splitRangeEntryAtIndex(/*RangeEntry*/aRangeEntry,
{
var newRangeEntry = copyRangeEntry(aRangeEntry),
cachedIndex = CPMaxRange(aRangeEntry.range);
-
+
aRangeEntry.range.length = anIndex - aRangeEntry.range.location;
newRangeEntry.range.location = anIndex;
newRangeEntry.range.length = cachedIndex - anIndex;
newRangeEntry.attributes = [newRangeEntry.attributes copy];
-
+
return [aRangeEntry, newRangeEntry];
}
diff --git a/Foundation/CPBundle.j b/Foundation/CPBundle.j
index bef8fdb69..39aae0b29 100644
--- a/Foundation/CPBundle.j
+++ b/Foundation/CPBundle.j
@@ -20,8 +20,9 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-@import "CPObject.j"
@import "CPDictionary.j"
+@import "CPObject.j"
+
/*!
@class CPBundle
diff --git a/Foundation/CPCoder.j b/Foundation/CPCoder.j
index a9cd1bf97..0d8bc04da 100644
--- a/Foundation/CPCoder.j
+++ b/Foundation/CPCoder.j
@@ -20,28 +20,27 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-@import "CPObject.j"
@import "CPException.j"
+@import "CPObject.j"
-/*!
+/*!
@class CPCoder
@ingroup foundation
@brief Defines methods for use when archiving & restoring (enc/decoding).
- Top-level class defining methods for use when archiving (encoding) objects to a byte array
- or file, and when restoring (decoding) objects.
+ Top-level class defining methods for use when archiving (encoding) objects to a byte array
+ or file, and when restoring (decoding) objects.
*/
@implementation CPCoder : CPObject
{
-
}
/*!
Returns a flag indicating whether the receiver supports keyed coding. The default implementation returns
\c NO. Subclasses supporting keyed coding must override this to return \c YES.
*/
--(BOOL)allowsKeyedCoding
+- (BOOL)allowsKeyedCoding
{
return NO;
}
@@ -53,7 +52,7 @@
@param aType the structure or object type
@param anObject the object to be encoded
*/
--(void)encodeValueOfObjCType:(CPString)aType at:(id)anObject
+- (void)encodeValueOfObjCType:(CPString)aType at:(id)anObject
{
CPInvalidAbstractInvocation();
}
@@ -62,7 +61,7 @@
Encodes a data object. Subclasses must override this method.
@param aData the object to be encoded.
*/
--(void)encodeDataObject:(CPData)aData
+- (void)encodeDataObject:(CPData)aData
{
CPInvalidAbstractInvocation();
}
@@ -71,7 +70,7 @@
Encodes an object. Subclasses must override this method.
@param anObject the object to be encoded
*/
--(void)encodeObject:(id)anObject
+- (void)encodeObject:(id)anObject
{
// [self encodeValueOfObjCType:@encode(id) at:object];
}
@@ -110,7 +109,7 @@
Encodes a property list. Not yet implemented.
@param aPropertyList the property list to be encoded
*/
--(void)encodePropertyList:(id)aPropertyList
+- (void)encodePropertyList:(id)aPropertyList
{
// [self encodeValueOfObjCType:@encode(id) at:&propertyList];
}
@@ -119,7 +118,7 @@
Encodes the root object of a group of Obj-J objects.
@param rootObject the root object to be encoded.
*/
--(void)encodeRootObject:(id)anObject
+- (void)encodeRootObject:(id)anObject
{
[self encodeObject:anObject];
}
@@ -128,18 +127,18 @@
Encodes an object.
@param anObject the object to be encoded.
*/
--(void)encodeBycopyObject:(id)anObject
+- (void)encodeBycopyObject:(id)anObject
{
- [self encodeObject:object];
+ [self encodeObject:anObject];
}
/*!
Encodes an object.
@param anObject the object to be encoded.
*/
--(void)encodeConditionalObject:(id)anObject
+- (void)encodeConditionalObject:(id)anObject
{
- [self encodeObject:object];
+ [self encodeObject:anObject];
}
@end
diff --git a/Foundation/CPCountedSet.j b/Foundation/CPCountedSet.j
index a99b94a98..86b4753af 100644
--- a/Foundation/CPCountedSet.j
+++ b/Foundation/CPCountedSet.j
@@ -22,7 +22,8 @@
@import "CPSet.j"
-/*!
+
+/*!
@class CPCountedSet
@ingroup foundation
@brief An mutable collection which may contain a specific object
@@ -37,11 +38,11 @@
{
if (!_counts)
_counts = {};
-
+
[super addObject:anObject];
-
+
var UID = [anObject UID];
-
+
if (_counts[UID] === undefined)
_counts[UID] = 1;
else
@@ -52,16 +53,16 @@
{
if (!_counts)
return;
-
+
var UID = [anObject UID];
-
+
if (_counts[UID] === undefined)
return;
-
+
else
{
--_counts[UID];
-
+
if (_counts[UID] === 0)
{
delete _counts[UID];
@@ -84,17 +85,17 @@
{
if (!_counts)
_counts = {};
-
+
var UID = [anObject UID];
-
+
if (_counts[UID] === undefined)
return 0;
-
+
return _counts[UID];
}
-/*
+/*
Eventually we should see what these are supposed to do, and then do that.
diff --git a/Foundation/CPData.j b/Foundation/CPData.j
index 2d73b5a42..0a75abd36 100644
--- a/Foundation/CPData.j
+++ b/Foundation/CPData.j
@@ -23,6 +23,7 @@
@import "CPObject.j"
@import "CPString.j"
+
/*!
@class CPData
@ingroup foundation
diff --git a/Foundation/CPDate.j b/Foundation/CPDate.j
index e4bc13273..6340ef48c 100644
--- a/Foundation/CPDate.j
+++ b/Foundation/CPDate.j
@@ -24,7 +24,7 @@
@import "CPString.j"
-var CPDateReferenceDate = new Date(Date.UTC(2001,1,1,0,0,0,0));
+var CPDateReferenceDate = new Date(Date.UTC(2001, 1, 1, 0, 0, 0, 0));
/*!
@class CPDate
@@ -64,12 +64,12 @@ var CPDateReferenceDate = new Date(Date.UTC(2001,1,1,0,0,0,0));
+ (id)distantPast
{
- return new Date(-10000,1,1,0,0,0,0);
+ return new Date(-10000, 1, 1, 0, 0, 0, 0);
}
+ (id)distantFuture
{
- return new Date(10000,1,1,0,0,0,0);
+ return new Date(10000, 1, 1, 0, 0, 0, 0);
}
- (id)initWithTimeIntervalSinceNow:(CPTimeInterval)seconds
@@ -110,7 +110,7 @@ var CPDateReferenceDate = new Date(Date.UTC(2001,1,1,0,0,0,0));
[CPException raise:CPInvalidArgumentException
reason:"initWithString: the string must be of YYYY-MM-DD HH:MM:SS ±HHMM format"];
- var date = new Date(d[1], d[2]-1, d[3]),
+ var date = new Date(d[1], d[2] - 1, d[3]),
timeZoneOffset = (Number(d[8]) * 60 + Number(d[9])) * (d[7] === '-' ? -1 : 1);
date.setHours(d[4]);
@@ -180,7 +180,7 @@ var CPDateReferenceDate = new Date(Date.UTC(2001,1,1,0,0,0,0));
var hours = Math.floor(self.getTimezoneOffset() / 60),
minutes = self.getTimezoneOffset() - hours * 60;
- return [CPString stringWithFormat:@"%04d-%02d-%02d %02d:%02d:%02d +%02d%02d", self.getFullYear(), self.getMonth()+1, self.getDate(), self.getHours(), self.getMinutes(), self.getSeconds(), hours, minutes];
+ return [CPString stringWithFormat:@"%04d-%02d-%02d %02d:%02d:%02d +%02d%02d", self.getFullYear(), self.getMonth() + 1, self.getDate(), self.getHours(), self.getMinutes(), self.getSeconds(), hours, minutes];
}
- (id)copy
diff --git a/Foundation/CPDictionary.j b/Foundation/CPDictionary.j
index f805282f2..4fd2d46d8 100755
--- a/Foundation/CPDictionary.j
+++ b/Foundation/CPDictionary.j
@@ -21,9 +21,9 @@
*/
@import "CPArray.j"
-@import "CPObject.j"
@import "CPEnumerator.j"
@import "CPException.j"
+@import "CPObject.j"
/* @ignore */
@@ -36,20 +36,20 @@
- (id)initWithDictionary:(CPDictionary)aDictionary
{
self = [super init];
-
+
if (self)
{
_keyEnumerator = [aDictionary keyEnumerator];
_dictionary = aDictionary;
}
-
+
return self;
}
- (id)nextObject
{
var key = [_keyEnumerator nextObject];
-
+
if (!key)
return nil;
@@ -58,7 +58,7 @@
@end
-/*!
+/*!
@class CPDictionary
@ingroup foundation
@brief A mutable key-value pair collection.
@@ -145,29 +145,33 @@
*/
+ (id)dictionaryWithJSObject:(JSObject)object recursively:(BOOL)recursively
{
- var dictionary = [[self alloc] init];
-
- for (var key in object)
+ var key = "",
+ dictionary = [[self alloc] init];
+
+ for (key in object)
{
if (!object.hasOwnProperty(key))
continue;
var value = object[key];
-
+
if (value === null)
{
[dictionary setObject:[CPNull null] forKey:key];
continue;
}
-
+
if (recursively)
{
if (value.constructor === Object)
value = [CPDictionary dictionaryWithJSObject:value recursively:YES];
else if ([value isKindOfClass:CPArray])
{
- var newValue = [];
- for (var i = 0, count = value.length; i < count; i++)
+ var newValue = [],
+ i = 0,
+ count = value.length;
+
+ for (; i < count; i++)
{
var thisValue = value[i];
@@ -183,7 +187,7 @@
[dictionary setObject:value forKey:key];
}
-
+
return dictionary;
}
@@ -193,22 +197,22 @@
@param ... key for the first object and ongoing value-key pairs for more objects.
@throws CPInvalidArgumentException if the number of objects and keys is different
@return the new CPDictionary
-
+
Assuming that there's no object retaining in Cappuccino, you can create
dictionaries same way as with alloc and initWithObjectsAndKeys:
var dict = [CPDictionary dictionaryWithObjectsAndKeys:
@"value1", @"key1",
@"value2", @"key2"];
-
+
Note, that there's no final nil like in Objective-C/Cocoa.
-
+
@see [CPDictionary initWithObjectsAndKeys:]
*/
+ (id)dictionaryWithObjectsAndKeys:(id)firstObject, ...
{
arguments[0] = [self alloc];
arguments[1] = @selector(initWithObjectsAndKeys:);
-
+
return objj_msgSend.apply(this, arguments);
}
@@ -221,10 +225,10 @@
{
var key = "",
dictionary = [[CPDictionary alloc] init];
-
+
for (key in aDictionary._buckets)
[dictionary setObject:[aDictionary objectForKey:key] forKey:key];
-
+
return dictionary;
}
@@ -240,16 +244,16 @@
self = [super init];
if ([objects count] != [keyArray count])
- [CPException raise:CPInvalidArgumentException reason:"Counts are different.("+[objects count]+"!="+[keyArray count]+")"];
+ [CPException raise:CPInvalidArgumentException reason:"Counts are different.(" + [objects count] + "!=" + [keyArray count] + ")"];
if (self)
{
var i = [keyArray count];
-
+
while (i--)
[self setObject:objects[i] forKey:keyArray[i]];
}
-
+
return self;
}
@@ -259,29 +263,29 @@
@param ... key for the first object and ongoing value-key pairs for more objects.
@throws CPInvalidArgumentException if the number of objects and keys is different
@return the new CPDictionary
-
+
You can create dictionaries this way:
var dict = [[CPDictionary alloc] initWithObjectsAndKeys:
@"value1", @"key1",
@"value2", @"key2"];
-
+
Note, that there's no final nil like in Objective-C/Cocoa.
*/
- (id)initWithObjectsAndKeys:(id)firstObject, ...
{
var argCount = arguments.length;
-
+
if (argCount % 2 !== 0)
[CPException raise:CPInvalidArgumentException reason:"Key-value count is mismatched. (" + argCount + " arguments passed)"];
self = [super init];
-
+
if (self)
{
// The arguments array contains self and _cmd, so the first object is at position 2.
var index = 2;
-
- for(; index < argCount; index += 2)
+
+ for (; index < argCount; index += 2)
{
var value = arguments[index];
@@ -316,7 +320,7 @@
*/
- (CPArray)allKeys
{
- return _keys;
+ return [_keys copy];
}
/*!
@@ -326,7 +330,7 @@
{
var index = _keys.length,
values = [];
-
+
while (index--)
values.push(self.valueForKey(_keys[index]));
@@ -350,7 +354,7 @@
}
/*!
- Compare the receiver to this dictionary, and return whether or not they are equal.
+ Compare the receiver to this dictionary, and return whether or not they are equal.
*/
- (BOOL)isEqualToDictionary:(CPDictionary)aDictionary
{
@@ -372,10 +376,10 @@
if (lhsObject === rhsObject)
continue;
-
+
if (lhsObject && lhsObject.isa && rhsObject && rhsObject.isa && [lhsObject respondsToSelector:@selector(isEqual:)] && [lhsObject isEqual:rhsObject])
continue;
-
+
return NO;
}
@@ -399,9 +403,9 @@
var i= 0,
keys= CPArray.array(),
count= this.count();
-
- while((i= this._objects.indexOfObjectInRage(0, count-i))!=CPNotFound) keys.addObject(this._keys[i]);
-
+
+ while ((i= this._objects.indexOfObjectInRage(0, count-i))!=CPNotFound) keys.addObject(this._keys[i]);
+
return keys;
}
@@ -412,7 +416,7 @@
{
return aSelector.apply(dictionary.objectForKey(this), [dictionary.objectForKey(rhs)]);
};
-
+
return this._keys.sortedArrayUsingSelector(objectSelector);
}
*/
@@ -424,7 +428,7 @@
- (id)objectForKey:(CPString)aKey
{
var object = _buckets[aKey];
-
+
return (object === undefined) ? nil : object;
}
/*
@@ -432,20 +436,20 @@
{
var i= keys.length,
objects= CPArray.array();
-
- while(i--)
+
+ while (i--)
{
var object= this.objectForKey(keys[i]);
objects.addObject(object==nil?aNotFoundMarker:object);
}
-
+
return objects;
}
-
+
Instance.valueForKey(aKey)
{
- if(aKey.length && aKey[0]=="@") return this.objectForKey(aKey.substr(1));
-
+ if (aKey.length && aKey[0]=="@") return this.objectForKey(aKey.substr(1));
+
return base.valueForKey(aKey);
}
*/
@@ -475,7 +479,7 @@
var index = keysForRemoval.length;
while (index--)
- self.removeValueForKey(keysForRemoval[index]);
+ [self removeObjectForKey:keysForRemoval[index]];
}
/*
@@ -483,11 +487,11 @@
{
this._keys= CPArray.arrayWithArray(aDictionary.allKeys());
this._objects= CPArray.arrayWithArray(aDictionary.allValues());
-
+
this._dictionary= { };
-
+
var i= this._keys.count();
- while(i--) this._dictionary[this._keys[i]]= { object: this._objects[i], index: i };
+ while (i--) this._dictionary[this._keys[i]]= { object: this._objects[i], index: i };
}
*/
/*!
@@ -507,10 +511,10 @@
{
if (!aDictionary)
return;
-
+
var keys = [aDictionary allKeys],
index = [keys count];
-
+
while (index--)
{
var key = keys[index];
diff --git a/Foundation/CPEnumerator.j b/Foundation/CPEnumerator.j
index 51d25b92a..50efcb571 100755
--- a/Foundation/CPEnumerator.j
+++ b/Foundation/CPEnumerator.j
@@ -22,15 +22,12 @@
@import "CPObject.j"
-/*!
-
-*/
-/*!
+/*!
@class CPEnumerator
@ingroup foundation
@brief Defines an interface for enumerators.
-
+
CPEnumerator is a superclass (with useless method bodies)
that defines an interface for subclasses to follow. The purpose of an
enumerator is to be a convenient system for traversing over the elements
diff --git a/Foundation/CPException.j b/Foundation/CPException.j
index 28abb60ec..770c6ad63 100755
--- a/Foundation/CPException.j
+++ b/Foundation/CPException.j
@@ -30,7 +30,7 @@ CPUnsupportedMethodException = "CPUnsupportedMethodException";
CPRangeException = "CPRangeException";
CPInternalInconsistencyException = "CPInternalInconsistencyException";
-/*!
+/*!
@class CPException
@ingroup foundation
@brief Used to implement exception handling (creating & raising).
@@ -40,7 +40,7 @@ CPInternalInconsistencyException = "CPInternalInconsistencyException";
// some code here...
if (input == nil)
[CPException raise:"MyException" reason:"You didn't do something right."];
-
+
// code that gets executed if no exception was raised
*/
@@ -96,7 +96,7 @@ if (input == nil)
message = aReason;
_userInfo = aUserInfo;
}
-
+
return self;
}
@@ -165,14 +165,14 @@ var CPExceptionNameKey = "CPExceptionNameKey",
- (id)initWithCoder:(CPCoder)aCoder
{
self = [super init];
-
+
if (self)
{
name = [aCoder decodeObjectForKey:CPExceptionNameKey];
message = [aCoder decodeObjectForKey:CPExceptionReasonKey];
_userInfo = [aCoder decodeObjectForKey:CPExceptionUserInfoKey];
}
-
+
return self;
}
diff --git a/Foundation/CPFunctionOperation.j b/Foundation/CPFunctionOperation.j
index 795058737..f9f98c911 100644
--- a/Foundation/CPFunctionOperation.j
+++ b/Foundation/CPFunctionOperation.j
@@ -23,22 +23,24 @@
@import "CPOperation.j"
-/*!
+/*!
@class CPFunctionOperation
@brief Represents an operation using a JavaScript function that can be run in an CPOperationQueue
*/
-@implementation CPFunctionOperation : CPOperation
+@implementation CPFunctionOperation : CPOperation
{
CPArray _functions;
}
-- (void)main
+- (void)main
{
- if (_functions && [_functions count] > 0)
+ if (_functions && [_functions count] > 0)
{
- var i = 0;
- for (i = 0; i < [_functions count]; i++)
+ var i = 0,
+ count = [_functions count];
+
+ for (; i < count; i++)
{
var func = [_functions objectAtIndex:i];
func();
@@ -46,9 +48,9 @@
}
}
-- (id)init
+- (id)init
{
- if (self = [super init])
+ if (self = [super init])
{
_functions = [];
}
@@ -58,7 +60,7 @@
/*!
Adds the specified JS function to the receiver’s list of functions to perform.
*/
-- (void)addExecutionFunction:(JSObject)jsFunction
+- (void)addExecutionFunction:(JSObject)jsFunction
{
[_functions addObject:jsFunction];
}
@@ -66,7 +68,7 @@
/*!
Returns an array containing the functions associated with the receiver.
*/
-- (CPArray)executionFunctions
+- (CPArray)executionFunctions
{
return _functions;
}
@@ -74,12 +76,12 @@
/*!
Creates and returns an NSFunctionOperation object and adds the specified function to it.
*/
-+ (id)functionOperationWithFunction:(JSObject)jsFunction
++ (id)functionOperationWithFunction:(JSObject)jsFunction
{
functionOp = [[CPFunctionOperation alloc] init];
[functionOp addExecutionFunction:jsFunction];
-
+
return functionOp;
}
-@end
\ No newline at end of file
+@end
diff --git a/Foundation/CPIndexSet.j b/Foundation/CPIndexSet.j
index 60e6736e9..266c7273e 100644
--- a/Foundation/CPIndexSet.j
+++ b/Foundation/CPIndexSet.j
@@ -20,14 +20,15 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-@import "CPRange.j"
@import "CPObject.j"
+@import "CPRange.j"
+
#define _CPMaxRange(aRange) ((aRange).location + (aRange).length)
#define _CPMakeRange(aLocation, aLength) { location:(aLocation), length:aLength }
#define _CPMakeRangeCopy(aRange) { location:(aRange).location, length:(aRange).length }
-/*!
+/*!
@class CPIndexSet
@ingroup foundation
@brief A collection of unique integers.
@@ -179,7 +180,7 @@
return NO;
// If we have less total indexes than aRange, we can't possibly contain aRange.
- if(_count < aRange.length)
+ if (_count < aRange.length)
return NO;
// Search for first location
@@ -203,7 +204,7 @@
{
var otherCount = anIndexSet._count;
- if(otherCount <= 0)
+ if (otherCount <= 0)
return YES;
// If we have less total indexes than anIndexSet, we can't possibly contain aRange.
@@ -692,7 +693,7 @@
var i = _ranges.length - 1,
shifted = CPMakeRange(CPNotFound, 0);
- for(; i >= 0; --i)
+ for (; i >= 0; --i)
{
var range = _ranges[i],
maximum = CPMaxRange(range);
@@ -700,7 +701,7 @@
if (anIndex > maximum)
break;
- // If our index is within our range, but not the first index,
+ // If our index is within our range, but not the first index,
// then this range will be split.
if (anIndex > range.location && anIndex < maximum)
{
diff --git a/Foundation/CPInvocation.j b/Foundation/CPInvocation.j
index 19e8c2cb1..da66a2a68 100644
--- a/Foundation/CPInvocation.j
+++ b/Foundation/CPInvocation.j
@@ -20,11 +20,11 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-@import "CPObject.j"
@import "CPException.j"
+@import "CPObject.j"
-/*!
+/*!
@class CPInvocation
@ingroup foundation
@brief An object representation of a message.
@@ -57,13 +57,13 @@
- (id)initWithMethodSignature:(CPMethodSignature)aMethodSignature
{
self = [super init];
-
+
if (self)
{
_arguments = [];
_methodSignature = aMethodSignature;
}
-
+
return self;
}
@@ -174,13 +174,13 @@ var CPInvocationArguments = @"CPInvocationArguments",
- (id)initWithCoder:(CPCoder)aCoder
{
self = [super init];
-
+
if (self)
{
_returnValue = [aCoder decodeObjectForKey:CPInvocationReturnValue];
_arguments = [aCoder decodeObjectForKey:CPInvocationArguments];
}
-
+
return self;
}
diff --git a/Foundation/CPInvocationOperation.j b/Foundation/CPInvocationOperation.j
index e98fc6c49..0c1bdfda6 100644
--- a/Foundation/CPInvocationOperation.j
+++ b/Foundation/CPInvocationOperation.j
@@ -19,32 +19,32 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-@import
-@import
+@import "CPInvocation.j"
+@import "CPObject.j"
@import "CPOperation.j"
-/*!
+/*!
@class CPInvocationOperation
@brief Represents an operation using an invocation that can be run in an CPOperationQueue
*/
-@implementation CPInvocationOperation : CPOperation
+@implementation CPInvocationOperation : CPOperation
{
CPInvocation _invocation;
}
-- (void)main
+- (void)main
{
- if (_invocation)
+ if (_invocation)
{
[_invocation invoke];
}
}
-- (id)init
+- (id)init
{
- if (self = [super init])
+ if (self = [super init])
{
_invocation = nil;
}
@@ -55,13 +55,13 @@
Returns a CPInvocationOperation object initialized with the specified invocation object.
@param inv the invocation
*/
-- (id)initWithInvocation:(CPInvocation)inv
+- (id)initWithInvocation:(CPInvocation)inv
{
- if (self = [self init])
+ if (self = [self init])
{
_invocation = inv;
}
-
+
return self;
}
@@ -71,20 +71,20 @@
@param sel the selector that should be called on the target
@param arg the arguments
*/
-- (id)initWithTarget:(id)target selector:(SEL)sel object:(id)arg
+- (id)initWithTarget:(id)target selector:(SEL)sel object:(id)arg
{
var inv = [[CPInvocation alloc] initWithMethodSignature:nil];
[inv setTarget:target];
[inv setSelector:sel];
[inv setArgument:arg atIndex:2];
-
+
return [self initWithInvocation:inv];
}
/*!
Returns the receiver’s invocation object.
*/
-- (CPInvocation)invocation
+- (CPInvocation)invocation
{
return _invocation;
}
@@ -92,16 +92,14 @@
/*!
Returns the result of the invocation or method.
*/
-- (id)result
+- (id)result
{
- if ([self isFinished] && _invocation)
+ if ([self isFinished] && _invocation)
{
return [_invocation returnValue];
}
-
+
return nil;
}
-
-
-@end
\ No newline at end of file
+@end
diff --git a/Foundation/CPJSONPConnection.j b/Foundation/CPJSONPConnection.j
index 8ec76e0e7..c95a362c5 100644
--- a/Foundation/CPJSONPConnection.j
+++ b/Foundation/CPJSONPConnection.j
@@ -19,15 +19,15 @@
* 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
+
+@import "CPObject.j"
CPJSONPConnectionCallbacks = {};
CPJSONPCallbackReplacementString = @"${JSONP_CALLBACK}";
-/*!
+/*!
@ingroup foundation
@brief Allows cross domain connections using JSONP protocol.
@@ -43,23 +43,23 @@ CPJSONPCallbackReplacementString = @"${JSONP_CALLBACK}";
{
CPURLRequest _request;
id _delegate;
-
+
CPString _callbackParameter;
DOMElement _scriptTag;
}
/*! @deprecated */
-+ (CPJSONPConnection)sendRequest:(CPURLRequest)aRequest callback:(CPString)callbackParameter delegate:(id)aDelegate
++ (CPJSONPConnection)sendRequest:(CPURLRequest)aRequest callback:(CPString)callbackParameter delegate:(id)aDelegate
{
return [self connectionWithRequest:aRequest callback:callbackParameter delegate:aDelegate];
}
+ (CPJSONPConnection)connectionWithRequest:(CPURLRequest)aRequest callback:(CPString)callbackParameter delegate:(id)aDelegate
{
- return [[[self class] alloc] initWithRequest:aRequest callback:callbackParameter delegate:aDelegate startImmediately:YES];;
+ return [[[self class] alloc] initWithRequest:aRequest callback:callbackParameter delegate:aDelegate startImmediately:YES];
}
-- (id)initWithRequest:(CPURLRequest)aRequest callback:(CPString)aString delegate:(id)aDelegate
+- (id)initWithRequest:(CPURLRequest)aRequest callback:(CPString)aString delegate:(id)aDelegate
{
return [self initWithRequest:aRequest callback:aString delegate:aDelegate startImmediately: NO];
}
@@ -67,18 +67,18 @@ CPJSONPCallbackReplacementString = @"${JSONP_CALLBACK}";
- (id)initWithRequest:(CPURLRequest)aRequest callback:(CPString)aString delegate:(id)aDelegate startImmediately:(BOOL)shouldStartImmediately
{
self = [super init];
-
+
_request = aRequest;
_delegate = aDelegate;
-
+
_callbackParameter = aString;
-
+
if (!_callbackParameter && [[_request URL] absoluteString].indexOf(CPJSONPCallbackReplacementString) < 0)
[CPException raise:CPInvalidArgumentException reason:@"JSONP source specified without callback parameter or CPJSONPCallbackReplacementString in URL."];
- if(shouldStartImmediately)
+ if (shouldStartImmediately)
[self start];
-
+
return self;
}
@@ -88,9 +88,14 @@ CPJSONPCallbackReplacementString = @"${JSONP_CALLBACK}";
{
CPJSONPConnectionCallbacks["callback"+[self UID]] = function(data)
{
- [_delegate connection:self didReceiveData:data];
+ if ([_delegate respondsToSelector:@selector(connection:didReceiveData:)])
+ [_delegate connection:self didReceiveData:data];
+
+ if ([_delegate respondsToSelector:@selector(connectionDidFinishLoading:)])
+ [_delegate connectionDidFinishLoading:self];
+
[self removeScriptTag];
-
+
[[CPRunLoop currentRunLoop] limitDateForMode:CPDefaultRunLoopMode];
};
@@ -108,17 +113,19 @@ CPJSONPCallbackReplacementString = @"${JSONP_CALLBACK}";
}
else
return;
-
+
_scriptTag = document.createElement("script");
_scriptTag.setAttribute("type", "text/javascript");
_scriptTag.setAttribute("charset", "utf-8");
_scriptTag.setAttribute("src", source);
-
+
head.appendChild(_scriptTag);
}
catch (exception)
{
- [_delegate connection: self didFailWithError: exception];
+ if ([_delegate respondsToSelector:@selector(connection:didFailWithError:)])
+ [_delegate connection: self didFailWithError: exception];
+
[self removeScriptTag];
}
}
@@ -126,12 +133,12 @@ CPJSONPCallbackReplacementString = @"${JSONP_CALLBACK}";
- (void)removeScriptTag
{
var head = document.getElementsByTagName("head").item(0);
-
+
if(_scriptTag && _scriptTag.parentNode == head)
head.removeChild(_scriptTag);
- CPJSONPConnectionCallbacks["callback"+[self UID]] = nil;
- delete CPJSONPConnectionCallbacks["callback"+[self UID]];
+ CPJSONPConnectionCallbacks["callback" + [self UID]] = nil;
+ delete CPJSONPConnectionCallbacks["callback" + [self UID]];
}
- (void)cancel
diff --git a/Foundation/CPKeyValueCoding.j b/Foundation/CPKeyValueCoding.j
index 36ef5b48c..104a6931f 100644
--- a/Foundation/CPKeyValueCoding.j
+++ b/Foundation/CPKeyValueCoding.j
@@ -25,6 +25,7 @@
@import "CPNull.j"
@import "CPObject.j"
+
var CPObjectAccessorsForClass = nil,
CPObjectModifiersForClass = nil;
@@ -44,41 +45,41 @@ CPUnknownUserInfoKey = @"CPUnknownUserInfoKey";
{
if (!CPObjectAccessorsForClass)
CPObjectAccessorsForClass = [CPDictionary dictionary];
-
+
var UID = [isa UID],
selector = nil,
accessors = [CPObjectAccessorsForClass objectForKey:UID];
-
+
if (accessors)
{
selector = [accessors objectForKey:aKey];
-
+
if (selector)
return selector === [CPNull null] ? nil : selector;
}
else
{
accessors = [CPDictionary dictionary];
-
+
[CPObjectAccessorsForClass setObject:accessors forKey:UID];
}
var capitalizedKey = aKey.charAt(0).toUpperCase() + aKey.substr(1);
-
- if ([self instancesRespondToSelector:selector = CPSelectorFromString("get" + capitalizedKey)] ||
- [self instancesRespondToSelector:selector = CPSelectorFromString(aKey)] ||
- [self instancesRespondToSelector:selector = CPSelectorFromString("is" + capitalizedKey)] ||
- [self instancesRespondToSelector:selector = CPSelectorFromString("_get" + capitalizedKey)] ||
- [self instancesRespondToSelector:selector = CPSelectorFromString("_" + aKey)] ||
+
+ if ([self instancesRespondToSelector:selector = CPSelectorFromString("get" + capitalizedKey)] ||
+ [self instancesRespondToSelector:selector = CPSelectorFromString(aKey)] ||
+ [self instancesRespondToSelector:selector = CPSelectorFromString("is" + capitalizedKey)] ||
+ [self instancesRespondToSelector:selector = CPSelectorFromString("_get" + capitalizedKey)] ||
+ [self instancesRespondToSelector:selector = CPSelectorFromString("_" + aKey)] ||
[self instancesRespondToSelector:selector = CPSelectorFromString("_is" + capitalizedKey)])
{
[accessors setObject:selector forKey:aKey];
-
+
return selector;
}
-
+
[accessors setObject:[CPNull null] forKey:aKey];
-
+
return nil;
}
@@ -87,25 +88,25 @@ CPUnknownUserInfoKey = @"CPUnknownUserInfoKey";
{
if (!CPObjectModifiersForClass)
CPObjectModifiersForClass = [CPDictionary dictionary];
-
+
var UID = [isa UID],
selector = nil,
modifiers = [CPObjectModifiersForClass objectForKey:UID];
-
+
if (modifiers)
{
selector = [modifiers objectForKey:aKey];
-
+
if (selector)
return selector === [CPNull null] ? nil : selector;
}
else
{
modifiers = [CPDictionary dictionary];
-
+
[CPObjectModifiersForClass setObject:modifiers forKey:UID];
}
-
+
if (selector)
return selector === [CPNull null] ? nil : selector;
@@ -115,12 +116,12 @@ CPUnknownUserInfoKey = @"CPUnknownUserInfoKey";
[self instancesRespondToSelector:selector = CPSelectorFromString("_set" + capitalizedKey)])
{
[modifiers setObject:selector forKey:aKey];
-
+
return selector;
}
-
+
[modifiers setObject:[CPNull null] forKey:aKey];
-
+
return nil;
}
@@ -128,30 +129,30 @@ CPUnknownUserInfoKey = @"CPUnknownUserInfoKey";
- (CPString)_ivarForKey:(CPString)aKey
{
var ivar = '_' + aKey;
-
+
if (typeof self[ivar] != "undefined")
return ivar;
var isKey = "is" + aKey.charAt(0).toUpperCase() + aKey.substr(1);
- ivar = '_' + isKey;
-
+ ivar = '_' + isKey;
+
if (typeof self[ivar] != "undefined")
return ivar;
-
+
ivar = aKey;
-
+
if (typeof self[ivar] != "undefined")
return ivar;
-
+
ivar = isKey;
-
+
if (typeof self[ivar] != "undefined")
return ivar;
return nil;
}
-
+
- (id)valueForKey:(CPString)aKey
{
var theClass = [self class],
@@ -159,18 +160,18 @@ CPUnknownUserInfoKey = @"CPUnknownUserInfoKey";
if (selector)
return objj_msgSend(self, selector);
-
- if([theClass accessInstanceVariablesDirectly])
+
+ if ([theClass accessInstanceVariablesDirectly])
{
var ivar = [self _ivarForKey:aKey];
-
+
if (ivar)
return self[ivar];
}
-
+
return [self valueForUndefinedKey:aKey];
}
-
+
- (id)valueForKeyPath:(CPString)aKeyPath
{
var firstDotIndex = aKeyPath.indexOf(".");
@@ -179,7 +180,7 @@ CPUnknownUserInfoKey = @"CPUnknownUserInfoKey";
return [self valueForKey:aKeyPath];
var firstKeyComponent = aKeyPath.substring(0, firstDotIndex),
- remainingKeyPath = aKeyPath.substring(firstDotIndex+1),
+ remainingKeyPath = aKeyPath.substring(firstDotIndex + 1),
value = [self valueForKey:firstKeyComponent];
return [value valueForKeyPath:remainingKeyPath];
@@ -190,7 +191,7 @@ CPUnknownUserInfoKey = @"CPUnknownUserInfoKey";
var index = 0,
count = keys.length,
dictionary = [CPDictionary dictionary];
-
+
for (; index < count; ++index)
{
var key = keys[index],
@@ -201,7 +202,7 @@ CPUnknownUserInfoKey = @"CPUnknownUserInfoKey";
else
[dictionary setObject:value forKey:key];
}
-
+
return dictionary;
}
@@ -211,7 +212,7 @@ CPUnknownUserInfoKey = @"CPUnknownUserInfoKey";
reason:[self description] + " is not key value coding-compliant for the key " + aKey
userInfo:[CPDictionary dictionaryWithObjects:[self, aKey] forKeys:[CPTargetObjectUserInfoKey, CPUnknownUserInfoKey]]] raise];
}
-
+
- (void)setValue:(id)aValue forKeyPath:(CPString)aKeyPath
{
if (!aKeyPath) aKeyPath = "self";
@@ -221,12 +222,12 @@ CPUnknownUserInfoKey = @"CPUnknownUserInfoKey";
count = keys.length - 1,
owner = self;
- for(; i < count; ++i)
+ for (; i < count; ++i)
owner = [owner valueForKey:keys[i]];
-
+
[owner setValue:aValue forKey:keys[i]];
}
-
+
- (void)setValue:(id)aValue forKey:(CPString)aKey
{
var theClass = [self class],
@@ -234,26 +235,26 @@ CPUnknownUserInfoKey = @"CPUnknownUserInfoKey";
if (selector)
return objj_msgSend(self, selector, aValue);
-
- if([theClass accessInstanceVariablesDirectly])
+
+ if ([theClass accessInstanceVariablesDirectly])
{
var ivar = [self _ivarForKey:aKey];
-
+
if (ivar)
{
[self willChangeValueForKey:aKey];
-
+
self[ivar] = aValue;
-
+
[self didChangeValueForKey:aKey];
return;
}
}
-
+
[self setValue:aValue forUndefinedKey:aKey];
}
-
+
- (void)setValue:(id)aValue forUndefinedKey:(CPString)aKey
{
[[CPException exceptionWithName:CPUndefinedKeyException
@@ -267,7 +268,10 @@ CPUnknownUserInfoKey = @"CPUnknownUserInfoKey";
- (id)valueForKey:(CPString)aKey
{
- return [self objectForKey:aKey];
+ if ([aKey hasPrefix:@"@"])
+ return [super valueForKey:aKey.substr(1)];
+
+ return [self objectForKey:aKey];
}
- (void)setValue:(id)aValue forKey:(CPString)aKey
diff --git a/Foundation/CPKeyValueObserving.j b/Foundation/CPKeyValueObserving.j
index 3867c9f13..bee35ec8f 100644
--- a/Foundation/CPKeyValueObserving.j
+++ b/Foundation/CPKeyValueObserving.j
@@ -224,52 +224,69 @@ var kvoNewAndOld = CPKeyValueObservingOptionNew|CPKeyValueObservingOptionOld,
- (void)_replaceClass
{
var currentClass = _nativeClass,
- kvoClassName = "$KVO_"+class_getName(_nativeClass),
+ kvoClassName = "$KVO_" + class_getName(_nativeClass),
existingKVOClass = objj_lookUpClass(kvoClassName);
-
+
if (existingKVOClass)
{
_targetObject.isa = existingKVOClass;
return;
}
-
+
var kvoClass = objj_allocateClassPair(currentClass, kvoClassName);
-
+
objj_registerClassPair(kvoClass);
-
+
//copy in the methods from our model subclass
var methodList = _CPKVOModelSubclass.method_list,
- count = methodList.length;
+ count = methodList.length,
+ i = 0;
- for (var i=0; i O(N^2)), so to avoid it,
- // we keep track of whether observers are added or removed, and only do our
+ // we keep track of whether observers are added or removed, and only do our
// rigorous testing in those cases.
var observerRemovalCount = _observerRemovalCount,
object = [aNotification object],
@@ -286,18 +286,18 @@ var _CPNotificationCenterPostNotification = function(/* CPNotificationCenter */
{
var currentObservers = observers,
count = observers.length;
-
+
while (count--)
{
var observer = observers[count];
-
- // if there wasn't removal of an observer during this posting, or there
- // was but we are still in the observer list...
+
+ // if there wasn't removal of an observer during this posting, or there
+ // was but we are still in the observer list...
if ((observerRemovalCount === _observerRemovalCount) || [currentObservers indexOfObjectIdenticalTo:observer] !== CPNotFound)
[observer postNotification:aNotification];
}
}
-
+
// Now do the same for the nil object observers...
observers = [[_objectObservers objectForKey:[[CPNull null] UID]] copy];
@@ -312,8 +312,8 @@ var _CPNotificationCenterPostNotification = function(/* CPNotificationCenter */
{
var observer = observers[count];
- // if there wasn't removal of an observer during this posting, or there
- // was but we are still in the observer list...
+ // if there wasn't removal of an observer during this posting, or there
+ // was but we are still in the observer list...
if ((observerRemovalCount === _observerRemovalCount) || [currentObservers indexOfObjectIdenticalTo:observer] !== CPNotFound)
[observer postNotification:aNotification];
}
@@ -349,7 +349,7 @@ var _CPNotificationCenterPostNotification = function(/* CPNotificationCenter */
return _observer;
}
--(void)postNotification:(CPNotification)aNotification
+- (void)postNotification:(CPNotification)aNotification
{
[_observer performSelector:_selector withObject:aNotification];
}
diff --git a/Foundation/CPNull.j b/Foundation/CPNull.j
index 43ba1cbc9..0eaca5773 100644
--- a/Foundation/CPNull.j
+++ b/Foundation/CPNull.j
@@ -25,7 +25,7 @@
var CPNullSharedNull = nil;
-/*!
+/*!
@class CPNull
@ingroup foundation
@brief An object representation of \c nil.
@@ -41,7 +41,7 @@ var CPNullSharedNull = nil;
{
if (CPNullSharedNull)
return CPNullSharedNull;
-
+
return [super alloc];
}*/
/*!
@@ -53,8 +53,27 @@ var CPNullSharedNull = nil;
{
if (!CPNullSharedNull)
CPNullSharedNull = [[CPNull alloc] init];
-
+
return CPNullSharedNull;
}
+/*!
+ Returns CPNull null.
+ @param aCoder the coder from which to do nothing
+ @return [CPNull null]
+*/
+- (id)initWithCoder:(CPCoder)aCoder
+{
+ return [CPNull null];
+}
+
+/*!
+ Writes out nothing to the specified coder.
+ @param aCoder the coder to which nothing will
+ be written
+*/
+- (void)encodeWithCoder:(CPCoder)aCoder
+{
+}
+
@end
diff --git a/Foundation/CPNumber.j b/Foundation/CPNumber.j
index 3b95e242d..a0bbef39e 100644
--- a/Foundation/CPNumber.j
+++ b/Foundation/CPNumber.j
@@ -27,15 +27,15 @@
var __placeholder = new Number(),
CPNumberUIDs = new CFMutableDictionary();
-/*!
+/*!
@class CPNumber
@ingroup foundation
@brief A bridged object to native Javascript numbers.
This class primarily exists for source compatability. The JavaScript
\c Number type can be changed on the fly based on context,
- so there is no need to call any of these methods.
-
+ so there is no need to call any of these methods.
+
In other words, native JavaScript numbers are bridged to CPNumber,
so you can use them interchangeably (including operators and methods).
*/
@@ -93,7 +93,7 @@ var __placeholder = new Number(),
{
if (aChar.charCodeAt)
return aChar.charCodeAt(0);
-
+
return aChar;
}
@@ -126,7 +126,7 @@ var __placeholder = new Number(),
{
if (aChar.charCodeAt)
return aChar.charCodeAt(0);
-
+
return aChar;
}
@@ -164,7 +164,7 @@ var __placeholder = new Number(),
{
if (aChar.charCodeAt)
return aChar.charCodeAt(0);
-
+
return aChar;
}
@@ -217,14 +217,14 @@ FIXME: Do we need this?
*/
- (CPDecimal)decimalValue
{
- objj_throw_exception("decimalValue: NOT YET IMPLEMENTED");
+ throw new Error("decimalValue: NOT YET IMPLEMENTED");
}
- (CPString)descriptionWithLocale:(CPDictionary)aDictionary
{
if (!aDictionary) return toString();
-
- objj_throw_exception("descriptionWithLocale: NOT YET IMPLEMENTED");
+
+ throw new Error("descriptionWithLocale: NOT YET IMPLEMENTED");
}
- (CPString)description
@@ -273,7 +273,7 @@ FIXME: Do we need this?
return toString();
}
-- (unsigned char)unsignedCharValue
+- (unsigned char)unsignedCharValue
{
return String.fromCharCode(self);
}
@@ -306,7 +306,7 @@ FIXME: Do we need this?
{
if (self > aNumber) return CPOrderedDescending;
else if (self < aNumber) return CPOrderedAscending;
-
+
return CPOrderedSame;
}
diff --git a/Foundation/CPObjJRuntime.j b/Foundation/CPObjJRuntime.j
index 76cfb8f76..019888d19 100644
--- a/Foundation/CPObjJRuntime.j
+++ b/Foundation/CPObjJRuntime.j
@@ -20,8 +20,6 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-@import "CPLog.j"
-
function CPStringFromSelector(aSelector)
{
@@ -44,7 +42,7 @@ function CPStringFromClass(aClass)
}
CPOrderedAscending = -1;
-CPOrderedSame = 0;
+CPOrderedSame = 0;
CPOrderedDescending = 1;
CPNotFound = -1;
diff --git a/Foundation/CPObject.j b/Foundation/CPObject.j
index b6c276ee6..c518f4f70 100644
--- a/Foundation/CPObject.j
+++ b/Foundation/CPObject.j
@@ -24,27 +24,27 @@
@class CPObject
@ingroup foundation
@brief The root class from which most classes are subclassed.
-
+
CPObject is the root class for most Cappuccino classes. Like in Objective-C,
you have to declare parent class explicitly in Objective-J, so your custom
classes should almost always subclass CPObject or one of its children.
-
+
CPObject provides facilities for class allocation and initialization,
querying runtime about parent classes and available selectors, using KVC
(key-value coding).
-
+
When you subclass CPObject, most of the time you override one selector - init.
It is called for default initialization of custom object. You must call
parent class init in your overriden code:
- (id)init
{
self = [super init];
- if(self) {
+ if (self) {
... provide default initialization code for your object ...
}
return self;
}
-
+
One more useful thing to override is description(). This selector
is used to provide developer-readable information about object. description
selector is often used with CPLog debugging:
@@ -58,7 +58,7 @@
CPLog(@"Got some class: %@", inst);
would output:
\c Got \c some \c class: \c
-
+
@todo document KVC usage.
*/
@implementation CPObject
@@ -164,11 +164,11 @@ CPLog(@"Got some class: %@", inst);
+ (BOOL)isSubclassOfClass:(Class)aClass
{
var theClass = self;
-
- for(; theClass; theClass = theClass.super_class)
- if(theClass === aClass)
+
+ for (; theClass; theClass = theClass.super_class)
+ if (theClass === aClass)
return YES;
-
+
return NO;
}
@@ -231,6 +231,23 @@ CPLog(@"Got some class: %@", inst);
return !!class_getInstanceMethod(isa, aSelector);
}
+/*!
+ Tests whether the receiver implements to the provided selector regardless of inheritance.
+ @param aSelector the selector for which to test the receiver
+ @return \c YES if the receiver implements the selector
+*/
+- (BOOL)implementsSelector:(SEL)aSelector
+{
+ var methods = class_copyMethodList(isa),
+ count = methods.length;
+
+ while (count--)
+ if (method_getName(methods[count]) === aSelector)
+ return YES;
+
+ return NO;
+}
+
// Obtaining method information
/*!
@@ -332,25 +349,25 @@ CPLog(@"Got some class: %@", inst);
- (void)forward:(SEL)aSelector :(marg_list)args
{
var signature = [self methodSignatureForSelector:aSelector];
-
+
if (signature)
{
invocation = [CPInvocation invocationWithMethodSignature:signature];
-
+
[invocation setTarget:self];
[invocation setSelector:aSelector];
-
+
var index = 2,
count = args.length;
-
+
for (; index < count; ++index)
[invocation setArgument:args[index] atIndex:index];
-
+
[self forwardInvocation:invocation];
-
+
return [invocation returnValue];
}
-
+
[self doesNotRecognizeSelector:aSelector];
}
@@ -436,7 +453,7 @@ CPLog(@"Got some class: %@", inst);
+ (id)setVersion:(int)aVersion
{
version = aVersion;
-
+
return self;
}
diff --git a/Foundation/CPOperation.j b/Foundation/CPOperation.j
index e24617ae7..710dc5961 100644
--- a/Foundation/CPOperation.j
+++ b/Foundation/CPOperation.j
@@ -19,7 +19,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-@import
+@import "CPObject.j"
/*!
Operations receive very low priority for execution.
@@ -57,13 +57,13 @@ CPOperationQueuePriorityHigh = 4;
CPOperationQueuePriorityVeryHigh = 8;
-/*!
+/*!
@class CPOperation
@brief Represents an operation that can be run in an CPOperationQueue
It should be subclassed an the subclass should implement its own main method to do the actual work.
*/
-@implementation CPOperation : CPObject
+@implementation CPOperation : CPObject
{
CPArray operations;
BOOL _cancelled;
@@ -75,15 +75,14 @@ CPOperationQueuePriorityVeryHigh = 8;
CPArray _dependencies;
}
-
-- (void)main
+- (void)main
{
// should be overridden in child class
}
-- (id)init
+- (id)init
{
- if (self = [super init])
+ if (self = [super init])
{
_cancelled = NO;
_executing = NO;
@@ -98,15 +97,15 @@ CPOperationQueuePriorityVeryHigh = 8;
/*!
Starts the operation (runs the main method), sets all the status flags and runs the completion function if it's set
*/
-- (void)start
+- (void)start
{
- if (!_cancelled)
+ if (!_cancelled)
{
[self willChangeValueForKey:@"isExecuting"];
_executing = YES;
[self didChangeValueForKey:@"isExecuting"];
[self main];
- if (_completionFunction)
+ if (_completionFunction)
{
_completionFunction();
}
@@ -123,7 +122,7 @@ CPOperationQueuePriorityVeryHigh = 8;
Indicates if this operation has been cancelled
@return if this operation has been cancelled
*/
-- (BOOL)isCancelled
+- (BOOL)isCancelled
{
return _cancelled;
}
@@ -132,7 +131,7 @@ CPOperationQueuePriorityVeryHigh = 8;
Indicates if this operation is currently executing
@return if this operation is currently executing
*/
-- (BOOL)isExecuting
+- (BOOL)isExecuting
{
return _executing;
}
@@ -141,7 +140,7 @@ CPOperationQueuePriorityVeryHigh = 8;
Indicates if this operation has finished running
@return if this operation has finished running
*/
-- (BOOL)isFinished
+- (BOOL)isFinished
{
return _finished;
}
@@ -150,7 +149,7 @@ CPOperationQueuePriorityVeryHigh = 8;
Just added for Cocoa compatibility
@return always false
*/
-- (BOOL)isConcurrent
+- (BOOL)isConcurrent
{
return NO;
}
@@ -159,8 +158,8 @@ CPOperationQueuePriorityVeryHigh = 8;
Indicates if this operation is ready to be executed. Takes the "isFinished" state of dependent operations into account
@return if this operation is ready to run
*/
-- (BOOL)isReady
-{
+- (BOOL)isReady
+{
return _ready;
}
@@ -168,7 +167,7 @@ CPOperationQueuePriorityVeryHigh = 8;
The JS function that should be run after the main method
@return JS function
*/
-- (JSObject)completionFunction
+- (JSObject)completionFunction
{
return _completionFunction;
}
@@ -176,7 +175,7 @@ CPOperationQueuePriorityVeryHigh = 8;
/*!
Sets the JS function that should be run after the main method
*/
-- (void)setCompletionFunction:(JSObject)aJavaScriptFunction
+- (void)setCompletionFunction:(JSObject)aJavaScriptFunction
{
_completionFunction = aJavaScriptFunction;
}
@@ -185,7 +184,7 @@ CPOperationQueuePriorityVeryHigh = 8;
Makes the receiver dependent on the completion of the specified operation.
@param anOperation the operation that the receiver should depend on
*/
-- (void)addDependency:(CPOperation)anOperation
+- (void)addDependency:(CPOperation)anOperation
{
[self willChangeValueForKey:@"dependencies"];
[anOperation addObserver:self
@@ -201,12 +200,12 @@ CPOperationQueuePriorityVeryHigh = 8;
Removes the receiver’s dependence on the specified operation.
@param anOperation the operation that the receiver should no longer depend on
*/
-- (void)removeDependency:(CPOperation)anOperation
+- (void)removeDependency:(CPOperation)anOperation
{
[self willChangeValueForKey:@"dependencies"];
[_dependencies removeObject:anOperation];
[anOperation removeObserver:self
- forKeyPath:@"isFinished"];
+ forKeyPath:@"isFinished"];
[self didChangeValueForKey:@"dependencies"];
[self _updateIsReadyState];
}
@@ -215,7 +214,7 @@ CPOperationQueuePriorityVeryHigh = 8;
The operations that the receiver depends on
@return array of operations
*/
-- (CPArray)dependencies
+- (CPArray)dependencies
{
return _dependencies;
}
@@ -223,14 +222,14 @@ CPOperationQueuePriorityVeryHigh = 8;
/*!
Just added for Cocoa compatibility, doesn't do anything
*/
-- (void)waitUntilFinished
+- (void)waitUntilFinished
{
}
/*!
Advises the operation object that it should stop executing its task.
*/
-- (void)cancel
+- (void)cancel
{
[self willChangeValueForKey:@"isCancelled"];
_cancelled = YES;
@@ -241,7 +240,7 @@ CPOperationQueuePriorityVeryHigh = 8;
Sets the priority of the operation when used in an operation queue.
@param priority the priority
*/
-- (void)setQueuePriority:(int)priority
+- (void)setQueuePriority:(int)priority
{
_queuePriority = priority;
}
@@ -250,7 +249,7 @@ CPOperationQueuePriorityVeryHigh = 8;
The priority of the operation when used in an operation queue.
@return the priority
*/
-- (int)queuePriority
+- (int)queuePriority
{
return _queuePriority;
}
@@ -261,28 +260,28 @@ CPOperationQueuePriorityVeryHigh = 8;
change:(CPDictionary)change
context:(void)context
{
- if (keyPath == @"isFinished")
+ if (keyPath == @"isFinished")
{
[self _updateIsReadyState];
}
}
-- (void)_updateIsReadyState
+- (void)_updateIsReadyState
{
var newReady = YES;
- if (_dependencies && [_dependencies count] > 0)
+ if (_dependencies && [_dependencies count] > 0)
{
var i = 0;
- for (i = 0; i < [_dependencies count]; i++)
+ for (i = 0; i < [_dependencies count]; i++)
{
- if (![[_dependencies objectAtIndex:i] isFinished])
+ if (![[_dependencies objectAtIndex:i] isFinished])
{
newReady = NO;
}
}
}
-
- if (newReady != _ready)
+
+ if (newReady != _ready)
{
[self willChangeValueForKey:@"isReady"];
_ready = newReady;
diff --git a/Foundation/CPOperationQueue.j b/Foundation/CPOperationQueue.j
index ac4e4842b..b849cdd43 100644
--- a/Foundation/CPOperationQueue.j
+++ b/Foundation/CPOperationQueue.j
@@ -19,29 +19,29 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-@import
-@import "CPOperation.j"
-@import "CPInvocationOperation.j"
@import "CPFunctionOperation.j"
+@import "CPInvocationOperation.j"
+@import "CPObject.j"
+@import "CPOperation.j"
// the global queue (mainQueue)
var cpOperationMainQueue = nil;
-/*!
+/*!
@class CPOperationQueue
@brief Represents an operation queue that can run CPOperations
*/
-@implementation CPOperationQueue : CPObject
+@implementation CPOperationQueue : CPObject
{
CPArray _operations;
BOOL _suspended;
CPString _name @accessors(property=name);
- CPTimer _timer;
+ CPTimer _timer;
}
-- (id)init
+- (id)init
{
- if (self = [super init])
+ if (self = [super init])
{
_operations = [[CPArray alloc] init];
_suspended = NO;
@@ -55,35 +55,37 @@ var cpOperationMainQueue = nil;
return self;
}
-- (void)_runNextOpsInQueue
+- (void)_runNextOpsInQueue
{
- if (!_suspended && [self operationCount] > 0)
+ if (!_suspended && [self operationCount] > 0)
{
- var i = 0;
- for (i = 0; i < [_operations count]; i++)
+ var i = 0,
+ count = [_operations count];
+
+ for (; i < count; i++)
{
var op = [_operations objectAtIndex:i];
- if ([op isReady] && ![op isCancelled] && ![op isFinished] && ![op isExecuting])
+ if ([op isReady] && ![op isCancelled] && ![op isFinished] && ![op isExecuting])
{
[op start];
- }
+ }
}
}
}
-- (void)_enableTimer:(BOOL)enable
+- (void)_enableTimer:(BOOL)enable
{
- if (!enable)
+ if (!enable)
{
- if (_timer)
+ if (_timer)
{
[_timer invalidate];
_timer = nil;
}
- }
- else
+ }
+ else
{
- if (!_timer)
+ if (!_timer)
{
_timer = [CPTimer scheduledTimerWithTimeInterval:0.01
target:self
@@ -98,7 +100,7 @@ var cpOperationMainQueue = nil;
Adds the specified operation object to the receiver.
@param anOperation the operation that should be scheduled for execution
*/
-- (void)addOperation:(CPOperation)anOperation
+- (void)addOperation:(CPOperation)anOperation
{
[self willChangeValueForKey:@"operations"];
[self willChangeValueForKey:@"operationCount"];
@@ -112,70 +114,72 @@ var cpOperationMainQueue = nil;
Adds the specified array of operations to the queue.
@param ops The array of CPOperation objects that you want to add to the receiver.
@param wait If YES, the method only returns once all of the specified operations finish executing. If NO, the operations are added to the queue and control returns immediately to the caller.
-*/
-- (void)addOperations:(CPArray)ops waitUntilFinished:(BOOL)wait
+*/
+- (void)addOperations:(CPArray)ops waitUntilFinished:(BOOL)wait
{
- if (ops)
+ if (ops)
{
- if (wait)
+ if (wait)
{
[self _sortOpsByPriority:ops];
[self _runOpsSynchronously:ops];
- }
-
+ }
+
[_operations addObjectsFromArray:ops];
[self _sortOpsByPriority:_operations];
- }
+ }
}
/*!
Wraps the given js function in a CPOperation and adds it to the queue
@param aFunction the JS function to add
*/
-- (void)addOperationWithFunction:(JSObject)aFunction
+- (void)addOperationWithFunction:(JSObject)aFunction
{
[self addOperation:[CPFunctionOperation functionOperationWithFunction:aFunction]];
}
-- (CPArray)operations
+- (CPArray)operations
{
return _operations;
}
-- (int)operationCount
+- (int)operationCount
{
- if (_operations)
+ if (_operations)
{
return [_operations count];
}
-
+
return 0;
}
/*!
Cancels all queued and executing operations.
*/
-- (void)cancelAllOperations
+- (void)cancelAllOperations
{
- if (_operations)
+ if (_operations)
{
- var i = 0;
- for (i = 0; i < [_operations count]; i++)
- {
- [[_operations objectAtIndex:i] cancel];
- }
+ var i = 0,
+ count = [_operations count];
+
+ for (; i < count; i++)
+ {
+ [[_operations objectAtIndex:i] cancel];
+ }
}
}
/*!
Blocks until all of the receiver’s queued and executing operations finish executing.
*/
-- (void)waitUntilAllOperationsAreFinished
+- (void)waitUntilAllOperationsAreFinished
{
// lets first stop the timer so it won't interfere
[self _enableTimer:NO];
[self _runOpsSynchronously:_operations];
- if (!_suspended)
+ if (!_suspended)
{
[self _enableTimer:YES];
}
@@ -186,7 +190,7 @@ var cpOperationMainQueue = nil;
Returns the maximum number of concurrent operations that the receiver can execute.
Always returns 1 because JS doesn't have threads
*/
-- (int)maxConcurrentOperationCount
+- (int)maxConcurrentOperationCount
{
return 1;
}
@@ -195,7 +199,7 @@ var cpOperationMainQueue = nil;
Modifies the execution of pending operations
@param suspend if YES, queue execution is suspended. If NO, it is resumed
*/
-- (void)setSuspended:(BOOL)suspend
+- (void)setSuspended:(BOOL)suspend
{
_suspended = suspend;
[self _enableTimer:!suspend];
@@ -204,62 +208,64 @@ var cpOperationMainQueue = nil;
/*!
Returns a Boolean value indicating whether the receiver is scheduling queued operations for execution.
*/
-- (BOOL)isSuspended
+- (BOOL)isSuspended
{
return _suspended;
}
-- (void)_sortOpsByPriority:(CPArray)someOps
+- (void)_sortOpsByPriority:(CPArray)someOps
{
- if (someOps)
+ if (someOps)
{
- [someOps sortUsingFunction:function(lhs, rhs)
+ [someOps sortUsingFunction:function(lhs, rhs)
{
- if ([lhs queuePriority] < [rhs queuePriority])
+ if ([lhs queuePriority] < [rhs queuePriority])
{
return 1;
- }
- else
+ }
+ else
{
- if ([lhs queuePriority] > [rhs queuePriority])
+ if ([lhs queuePriority] > [rhs queuePriority])
{
return -1;
- }
- else
+ }
+ else
{
return 0;
}
}
- }
+ }
context:nil];
}
}
-- (void)_runOpsSynchronously:(CPArray)ops
+- (void)_runOpsSynchronously:(CPArray)ops
{
- if (ops)
+ if (ops)
{
var keepGoing = YES;
- while (keepGoing)
+ while (keepGoing)
{
- var i = 0;
+ var i = 0,
+ count = [ops count];
+
keepGoing = NO;
-
+
// start the ones that are ready
- for (i = 0; i < [ops count]; i++)
+ for (; i < count; i++)
{
var op = [ops objectAtIndex:i];
- if ([op isReady] && ![op isCancelled] && ![op isFinished] && ![op isExecuting])
+ if ([op isReady] && ![op isCancelled] && ![op isFinished] && ![op isExecuting])
{
[op start];
- }
+ }
}
-
+
// make sure they are all done
- for (i = 0; i < [ops count]; i++)
+ for (i = 0; i < count; i++)
{
var op = [ops objectAtIndex:i];
- if (![op isFinished] && ![op isCancelled])
+ if (![op isFinished] && ![op isCancelled])
{
keepGoing = YES;
}
@@ -271,23 +277,23 @@ var cpOperationMainQueue = nil;
/*!
Convenience method for one system wide singelton queue. Returns the same queue as currentQueue.
*/
-+ (CPOperationQueue)mainQueue
++ (CPOperationQueue)mainQueue
{
- if (!cpOperationMainQueue)
+ if (!cpOperationMainQueue)
{
cpOperationMainQueue = [[CPOperationQueue alloc] init];
[cpOperationMainQueue setName:@"main"];
}
-
+
return cpOperationMainQueue;
}
/*!
Convenience method for one system wide singelton queue. Returns the same queue as mainQueue.
*/
-+ (CPOperationQueue)currentQueue
++ (CPOperationQueue)currentQueue
{
return [CPOperationQueue mainQueue];
}
-@end
\ No newline at end of file
+@end
diff --git a/Foundation/CPProxy.j b/Foundation/CPProxy.j
index 2d5fba736..2b4054c83 100644
--- a/Foundation/CPProxy.j
+++ b/Foundation/CPProxy.j
@@ -133,7 +133,7 @@
return [invocation returnValue];
}
--(BOOL)isMemberOfClass:(Class)aClass
+- (BOOL)isMemberOfClass:(Class)aClass
{
var signature = [self methodSignatureForSelector:_cmd],
invocation = [CPInvocation invocationWithMethodSignature:signature];
diff --git a/Foundation/CPRange.j b/Foundation/CPRange.j
index 6a0b1b5ce..b91a878d3 100755
--- a/Foundation/CPRange.j
+++ b/Foundation/CPRange.j
@@ -105,7 +105,7 @@ function CPLocationInRange(aLocation, aRange)
}
/*!
- Creates a new range with the minimum \c location and a \c length
+ Creates a new range with the minimum \c location and a \c length
that extends to the maximum \c length.
@param lhsRange the first CPRange
@param rhsRange the second CPRange
@@ -129,7 +129,7 @@ function CPIntersectionRange(lhsRange, rhsRange)
{
if(CPMaxRange(lhsRange) < rhsRange.location || CPMaxRange(rhsRange) < lhsRange.location)
return CPMakeRange(0, 0);
-
+
var location = MAX(lhsRange.location, rhsRange.location);
return CPMakeRange(location, MIN(CPMaxRange(lhsRange), CPMaxRange(rhsRange)) - location);
}
@@ -166,10 +166,11 @@ function CPStringFromRange(aRange)
function CPRangeFromString(aString)
{
var comma = aString.indexOf(',');
-
+
return { location:parseInt(aString.substr(1, comma - 1)), length:parseInt(aString.substring(comma + 1, aString.length)) };
}
/*!
@}
*/
+
diff --git a/Foundation/CPRunLoop.j b/Foundation/CPRunLoop.j
index 0884e4915..89ad9337a 100644
--- a/Foundation/CPRunLoop.j
+++ b/Foundation/CPRunLoop.j
@@ -20,8 +20,8 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-@import "CPObject.j"
@import "CPArray.j"
+@import "CPObject.j"
@import "CPString.j"
/*!
@@ -53,7 +53,7 @@ var _CPRunLoopPerformPool = [],
{
if (!aPerform || _CPRunLoopPerformPool.length >= _CPRunLoopPerformPoolCapacity)
return;
-
+
_CPRunLoopPerformPool.push(aPerform);
}
@@ -62,24 +62,24 @@ var _CPRunLoopPerformPool = [],
if (_CPRunLoopPerformPool.length)
{
var perform = _CPRunLoopPerformPool.pop();
-
+
perform._target = aTarget;
perform._selector = aSelector;
perform._argument = anArgument;
perform._order = anOrder;
perform._runLoopModes = modes;
perform._isValid = YES;
-
+
return perform;
}
-
+
return [[self alloc] initWithSelector:aSelector target:aTarget argument:anArgument order:anOrder modes:modes];
}
- (id)initWithSelector:(SEL)aSelector target:(SEL)aTarget argument:(id)anArgument order:(unsigned)anOrder modes:(CPArray)modes
{
self = [super init];
-
+
if (self)
{
_selector = aSelector;
@@ -89,7 +89,7 @@ var _CPRunLoopPerformPool = [],
_runLoopModes = modes;
_isValid = YES;
}
-
+
return self;
}
@@ -117,14 +117,14 @@ var _CPRunLoopPerformPool = [],
{
if (!_isValid)
return YES;
-
+
if ([_runLoopModes containsObject:aRunLoopMode])
{
[_target performSelector:_selector withObject:_argument];
-
+
return YES;
}
-
+
return NO;
}
@@ -157,6 +157,7 @@ var CPRunLoopLastNativeRunLoop = 0;
CPDate _effectiveDate;
CPArray _orderedPerforms;
+ int _runLoopInsuranceTimer;
}
/*
@@ -173,16 +174,16 @@ var CPRunLoopLastNativeRunLoop = 0;
- (id)init
{
self = [super init];
-
+
if (self)
{
_orderedPerforms = [];
-
+
_timersForModes = {};
_nativeTimersForModes = {};
_nextTimerFireDatesForModes = {};
}
-
+
return self;
}
@@ -219,7 +220,7 @@ var CPRunLoopLastNativeRunLoop = 0;
while (count--)
if (anOrder < [_orderedPerforms[count] order])
break;
-
+
_orderedPerforms.splice(count + 1, 0, perform);
}
@@ -232,11 +233,11 @@ var CPRunLoopLastNativeRunLoop = 0;
- (void)cancelPerformSelector:(SEL)aSelector target:(id)aTarget argument:(id)anArgument
{
var count = _orderedPerforms.length;
-
+
while (count--)
{
var perform = _orderedPerforms[count];
-
+
if ([perform selector] === aSelector && [perform target] == aTarget && [perform argument] == anArgument)
[_orderedPerforms[count] invalidate];
}
@@ -260,13 +261,24 @@ var CPRunLoopLastNativeRunLoop = 0;
_timersForModes[aMode].push(aTimer);
else
_timersForModes[aMode] = [aTimer];
-
+
_didAddTimer = YES;
-
+
if (!aTimer._lastNativeRunLoopsForModes)
aTimer._lastNativeRunLoopsForModes = {};
-
+
aTimer._lastNativeRunLoopsForModes[aMode] = CPRunLoopLastNativeRunLoop;
+
+
+ // FIXME: Hack for not doing this in CommonJS
+ if ([CFBundle.environments() indexOfObject:("Browser")] !== CPNotFound)
+ {
+ if (!_runLoopInsuranceTimer)
+ _runLoopInsuranceTimer = window.setNativeTimeout(function()
+ {
+ [self limitDateForMode:CPDefaultRunLoopMode];
+ }, 0);
+ }
}
/*!
@@ -277,102 +289,112 @@ var CPRunLoopLastNativeRunLoop = 0;
//simple locking to try to prevent concurrent iterating over timers
if (_runLoopLock)
return;
-
+
_runLoopLock = YES;
-
+
+ // FIXME: Hack for not doing this in CommonJS
+ if ([CFBundle.environments() indexOfObject:("Browser")] !== CPNotFound)
+ {
+ if (_runLoopInsuranceTimer)
+ {
+ window.clearNativeTimeout(_runLoopInsuranceTimer);
+ _runLoopInsuranceTimer = nil;
+ }
+ }
+
var now = _effectiveDate ? [_effectiveDate laterDate:[CPDate date]] : [CPDate date],
nextFireDate = nil,
nextTimerFireDate = _nextTimerFireDatesForModes[aMode];
-
+
// Perform Timers if necessary
if (_didAddTimer || nextTimerFireDate && nextTimerFireDate <= now)
{
_didAddTimer = NO;
-
+
// Cancel existing window.setTimeout
if (_nativeTimersForModes[aMode] !== nil)
{
window.clearNativeTimeout(_nativeTimersForModes[aMode]);
-
+
_nativeTimersForModes[aMode] = nil;
}
-
+
// Empty timers to avoid catastrophe if a timer is added during a timer fire.
var timers = _timersForModes[aMode],
index = timers.length;
-
+
_timersForModes[aMode] = nil;
-
- // Loop through timers looking for ones that had fired
+
+ // Loop through timers looking for ones that had fired
while (index--)
{
var timer = timers[index];
-
+
if (timer._lastNativeRunLoopsForModes[aMode] < CPRunLoopLastNativeRunLoop && timer._isValid && timer._fireDate <= now)
[timer fire];
-
+
// Timer may or may not still be valid
if (timer._isValid)
nextFireDate = (nextFireDate === nil) ? timer._fireDate : [nextFireDate earlierDate:timer._fireDate];
-
+
else
{
// FIXME: Is there an issue with reseting the fire date in -fire? or adding it back to the run loop?...
timer._lastNativeRunLoopsForModes[aMode] = 0;
-
+
timers.splice(index, 1);
}
}
-
+
// Timers may have been added during the firing of timers
- // They do NOT get a shot at firing, because they certainly
+ // They do NOT get a shot at firing, because they certainly
// haven't gone through one native timer.
var newTimers = _timersForModes[aMode];
-
+
if (newTimers && newTimers.length)
{
index = newTimers.length;
-
+
while (index--)
{
var timer = newTimers[index];
-
+
if ([timer isValid])
nextFireDate = (nextFireDate === nil) ? timer._fireDate : [nextFireDate earlierDate:timer._fireDate];
else
newTimers.splice(index, 1);
}
-
+
_timersForModes[aMode] = newTimers.concat(timers);
}
else
_timersForModes[aMode] = timers;
-
+
_nextTimerFireDatesForModes[aMode] = nextFireDate;
-
+
//initiate a new window.setTimeout if there are any timers
if (_nextTimerFireDatesForModes[aMode] !== nil)
_nativeTimersForModes[aMode] = window.setNativeTimeout(function() { _effectiveDate = nextFireDate; _nativeTimersForModes[aMode] = nil; ++CPRunLoopLastNativeRunLoop; [self limitDateForMode:aMode]; _effectiveDate = nil; }, MAX(0, [nextFireDate timeIntervalSinceNow] * 1000));
}
-
+
// Run loop performers
var performs = _orderedPerforms,
index = performs.length;
-
+
_orderedPerforms = [];
-
+
while (index--)
{
var perform = performs[index];
-
+
if ([perform fireInMode:CPDefaultRunLoopMode])
{
[_CPRunLoopPerform _poolPerform:perform];
-
+
performs.splice(index, 1);
}
}
-
+
if (_orderedPerforms.length)
{
_orderedPerforms = _orderedPerforms.concat(performs);
@@ -380,9 +402,9 @@ var CPRunLoopLastNativeRunLoop = 0;
}
else
_orderedPerforms = performs;
-
+
_runLoopLock = NO;
-
+
return nextFireDate;
}
diff --git a/Foundation/CPSet.j b/Foundation/CPSet.j
index 7026a376e..0a1e5f821 100644
--- a/Foundation/CPSet.j
+++ b/Foundation/CPSet.j
@@ -23,11 +23,11 @@
*
* TODO: Needs to implement CPCoding, CPCopying.
*/
-
-@import "CPObject.j"
+
@import "CPArray.j"
-@import "CPNumber.j"
@import "CPEnumerator.j"
+@import "CPNumber.j"
+@import "CPObject.j"
/*!
@class CPSet
@@ -79,7 +79,7 @@
/*
Creates and returns a set containing the objects in a given argument list.
@param anObject The first object to add to the new set.
- @param ... A comma-separated list of objects, ending with nil, to add to the new set. If the same object appears more than once objects, it is added only once to the returned set.
+ @param ... A comma-separated list of objects, ending with nil, to add to the new set. If the same object appears more than once objects, it is added only once to the returned set.
*/
+ (id)setWithObjects:(id)anObject, ...
{
@@ -87,9 +87,9 @@
argLength = arguments.length,
i = 2;
- for(; i < argLength && ((argument = arguments[i]) !== nil); ++i)
+ for (; i < argLength && ((argument = arguments[i]) !== nil); ++i)
[set addObject:argument];
-
+
return set;
}
@@ -112,7 +112,7 @@
_count = 0;
_contents = {};
}
-
+
return self;
}
@@ -121,21 +121,21 @@
@param array An array of objects to add to the new set. If the same object appears more than once in array, it is represented only once in the returned set.
*/
- (id)initWithArray:(CPArray)anArray
-{
+{
if (self = [self init])
{
var count = anArray.length;
-
+
while (count--)
[self addObject:anArray[count]];
}
-
+
return self;
}
/*
Initializes a newly allocated set with members taken from the specified list of objects.
- @param objects A array of objects to add to the new set. If the same object appears more than once objects, it is added only once to the returned set.
+ @param objects A array of objects to add to the new set. If the same object appears more than once objects, it is added only once to the returned set.
@param count The number of objects from objects to add to the new set.
*/
- (id)initWithObjects:(id)objects count:(unsigned)count
@@ -155,10 +155,10 @@
var argLength = arguments.length,
i = 2;
- for(; i < argLength && (argument = arguments[i]) != nil; ++i)
+ for (; i < argLength && (argument = arguments[i]) != nil; ++i)
[self addObject:argument];
}
-
+
return self;
}
@@ -179,10 +179,11 @@
if (!aSet)
return self;
-
- var contents = aSet._contents;
-
- for (var property in contents)
+
+ var contents = aSet._contents,
+ property;
+
+ for (property in contents)
{
if (contents.hasOwnProperty(property))
{
@@ -192,7 +193,7 @@
[self addObject:contents[property]];
}
}
-
+
return self;
}
@@ -201,14 +202,15 @@
*/
- (CPArray)allObjects
{
- var array = [];
-
- for (var property in _contents)
+ var array = [],
+ property;
+
+ for (property in _contents)
{
if (_contents.hasOwnProperty(property))
array.push(_contents[property]);
}
-
+
return array;
}
@@ -217,12 +219,14 @@
*/
- (id)anyObject
{
- for (var property in _contents)
+ var property;
+
+ for (property in _contents)
{
if (_contents.hasOwnProperty(property))
return _contents[property];
}
-
+
return nil;
}
@@ -236,7 +240,7 @@
if (obj !== undefined && [obj isEqual:anObject])
return YES;
-
+
return NO;
}
@@ -277,7 +281,7 @@
@param set The set with which to compare the receiver.
*/
- (BOOL)isEqualToSet:(CPSet)set
-{
+{
// If both are subsets of each other, they are equal
return self === set || ([self count] === [set count] && [set isSubsetOfSet:self]);
}
@@ -288,14 +292,17 @@
*/
- (BOOL)isSubsetOfSet:(CPSet)set
{
- var items = [self allObjects];
- for (var i = 0; i < items.length; i++)
+ var items = [self allObjects],
+ i = 0,
+ count = items.length;
+
+ for (; i < count; i++)
{
// If at least one item is not in both sets, self isn't a subset
if (![set containsObject:items[i]])
return NO;
}
-
+
return YES;
}
@@ -315,8 +322,11 @@
*/
- (void)makeObjectsPerformSelector:(SEL)aSelector withObject:(id)argument
{
- var items = [self allObjects];
- for (var i = 0; i < items.length; i++)
+ var items = [self allObjects],
+ i = 0,
+ count = items.length;
+
+ for (; i < count; i++)
{
[items[i] performSelector:aSelector withObject:argument];
}
@@ -330,7 +340,7 @@
{
if ([self containsObject:object])
return object;
-
+
return nil;
}
@@ -432,8 +442,11 @@
*/
- (void)intersectSet:(CPSet)set
{
- var items = [self allObjects];
- for (var i = 0, count = items.length; i < count; i++)
+ var items = [self allObjects],
+ i = 0,
+ count = items.length;
+
+ for (; i < count; i++)
{
if (![set containsObject:items[i]])
[self removeObject:items[i]];
@@ -446,8 +459,11 @@
*/
- (void)minusSet:(CPSet)set
{
- var items = [set allObjects];
- for (var i = 0; i < items.length; i++)
+ var items = [set allObjects],
+ i = 0,
+ count = items.length;
+
+ for (; i < count; i++)
{
if ([self containsObject:items[i]])
[self removeObject:items[i]];
@@ -460,13 +476,21 @@
*/
- (void)unionSet:(CPSet)set
{
- var items = [set allObjects];
- for (var i = 0, count = items.length; i < count; i++)
+ var items = [set allObjects],
+ i = 0,
+ count = items.length;
+
+ for (; i < count; i++)
{
[self addObject:items[i]];
}
}
+- (CPString)description
+{
+ return @"{(" + [self allObjects].join(", ") + ")}";
+}
+
@end
@implementation CPSet (CPCopying)
@@ -509,5 +533,5 @@ var CPSetObjectsKey = @"CPSetObjectsKey";
*/
@implementation CPMutableSet : CPSet
-@end
+@end
diff --git a/Foundation/CPSortDescriptor.j b/Foundation/CPSortDescriptor.j
index c7b78c840..8c246bd4c 100755
--- a/Foundation/CPSortDescriptor.j
+++ b/Foundation/CPSortDescriptor.j
@@ -43,7 +43,7 @@ CPOrderedSame = 0;
*/
CPOrderedDescending = 1;
-/*!
+/*!
@class CPSortDescriptor
@ingroup foundation
@brief Holds attributes necessary to describe how to sort a set of objects.
@@ -85,20 +85,20 @@ CPOrderedDescending = 1;
Initializes the sort descriptor
@param aKey the property key path to sort
@param isAscending the sort order
- @param aSelector this method gets called to compare objects. The method will take one argument
+ @param aSelector this method gets called to compare objects. The method will take one argument
(the object to compare against itself, and must return a CPComparisonResult.
*/
- (id)initWithKey:(CPString)aKey ascending:(BOOL)isAscending selector:(SEL)aSelector
{
self = [super init];
-
+
if (self)
{
_key = aKey;
_ascending = isAscending;
_selector = aSelector;
}
-
+
return self;
}
@@ -149,3 +149,30 @@ CPOrderedDescending = 1;
}
@end
+
+var CPSortDescriptorKeyKey = @"CPSortDescriptorKeyKey", // Don't you just love naming schemes ;)
+ CPSortDescriptorAscendingKey = @"CPSortDescriptorAscendingKey",
+ CPSortDescriptorSelectorKey = @"CPSortDescriptorSelectorKey";
+
+@implementation CPSortDescriptor (CPCoding)
+
+- (id)initWithCoder:(CPCoder)aCoder
+{
+ if (self = [super init])
+ {
+ _key = [aCoder decodeObjectForKey:CPSortDescriptorKeyKey];
+ _ascending = [aCoder decodeBoolForKey:CPSortDescriptorAscendingKey];
+ _selector = CPSelectorFromString([aCoder decodeObjectForKey:CPSortDescriptorSelectorKey]);
+ }
+
+ return self;
+}
+
+- (void)encodeWithCoder:(CPCoder)aCoder
+{
+ [aCoder encodeObject:_key forKey:CPSortDescriptorKeyKey];
+ [aCoder encodeBool:_ascending forKey:CPSortDescriptorAscendingKey];
+ [aCoder encodeObject:CPStringFromSelector(_selector) forKey:CPSortDescriptorSelectorKey];
+}
+
+@end
diff --git a/Foundation/CPString.j b/Foundation/CPString.j
index 51154a43c..abbe70c2d 100644
--- a/Foundation/CPString.j
+++ b/Foundation/CPString.j
@@ -20,8 +20,8 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-@import "CPObject.j"
@import "CPException.j"
+@import "CPObject.j"
@import "CPSortDescriptor.j"
@import "CPValue.j"
@@ -65,7 +65,7 @@ var CPStringRegexSpecialCharacters = [
CPStringRegexEscapeExpression = new RegExp("(\\" + CPStringRegexSpecialCharacters.join("|\\") + ")", 'g'),
CPStringRegexTrimWhitespace = new RegExp("(^\\s+|\\s+$)", 'g');
-/*!
+/*!
@class CPString
@ingroup foundation
@brief An immutable string (collection of characters).
@@ -103,7 +103,7 @@ var CPStringRegexSpecialCharacters = [
+ (id)stringWithHash:(unsigned)aHash
{
var hashString = parseInt(aHash, 10).toString(16);
- return "000000".substring(0, MAX(6-hashString.length, 0)) + hashString;
+ return "000000".substring(0, MAX(6 - hashString.length, 0)) + hashString;
}
/*!
@@ -147,7 +147,7 @@ var CPStringRegexSpecialCharacters = [
}
/*!
- Creates a new string using C printf-style formatting. First argument should be a constant format string,
+ Creates a new string using C printf-style formatting. First argument should be a constant format string,
like ' "float val = %f" ', remaining arguments should be the variables to print the values of, comma-separated.
@param format the format to be used, printf-style
@return the initialized CPString
@@ -238,8 +238,8 @@ var CPStringRegexSpecialCharacters = [
while ((difference -= substring.length) >= 0)
string += substring;
-
- if (-difference < substring.length)
+
+ if (-difference < substring.length)
string += substring.substring(0, -difference);
return string;
@@ -329,7 +329,7 @@ var CPStringRegexSpecialCharacters = [
/*!
Finds the range of characters in the receiver
- where the specified string exists in the given range
+ where the specified string exists in the given range
of the receiver.The search is subject to the options specified in the
specified mask which can be a combination of:
@@ -374,7 +374,7 @@ var CPStringRegexSpecialCharacters = [
}
/*!
- Returns a new string in which all occurrences of a target string in the reciever are replaced by
+ Returns a new string in which all occurrences of a target string in the reciever are replaced by
another given string.
@param target The string to replace.
@param replacement the string with which to replace the \c target
@@ -403,7 +403,7 @@ var CPStringRegexSpecialCharacters = [
regExp;
if (options & CPCaseInsensitiveSearch)
- regExp = new RegExp(target, "gi");
+ regExp = new RegExp(target, "gi");
else
regExp = new RegExp(target, "g");
@@ -411,7 +411,7 @@ var CPStringRegexSpecialCharacters = [
}
/*
- Returns a new string in which the characters in a specified range of the receiver
+ Returns a new string in which the characters in a specified range of the receiver
are replaced by a given string.
@param range A range of characters in the receiver.
@param replacement The string with which to replace the characters in \c range.
@@ -442,7 +442,6 @@ var CPStringRegexSpecialCharacters = [
return [self compare:aString options:nil];
}
-
/*
Compares the receiver to the specified string.
@param aString the string with which to compare
@@ -463,18 +462,18 @@ var CPStringRegexSpecialCharacters = [
{
var lhs = self,
rhs = aString;
-
+
if (aMask & CPCaseInsensitiveSearch)
{
lhs = lhs.toLowerCase();
rhs = rhs.toLowerCase();
}
-
+
if (lhs < rhs)
return CPOrderedAscending;
else if (lhs > rhs)
return CPOrderedDescending;
-
+
return CPOrderedSame;
}
@@ -559,7 +558,7 @@ var CPStringRegexSpecialCharacters = [
lhs = self,
rhs = aString,
min = MIN([lhs length], [rhs length]);
-
+
if (aMask & CPCaseInsensitiveSearch)
{
lhs = [lhs lowercaseString];
@@ -580,10 +579,13 @@ var CPStringRegexSpecialCharacters = [
*/
- (CPString)capitalizedString
{
- var parts = self.split(/\b/g); // split on word boundaries
- for (var i = 0; i < parts.length; i++)
+ var parts = self.split(/\b/g), // split on word boundaries
+ i = 0,
+ count = parts.length;
+
+ for (; i < count; i++)
{
- if (i == 0 || (/\s$/).test(parts[i-1])) // only capitalize if previous token was whitespace
+ if (i == 0 || (/\s$/).test(parts[i - 1])) // only capitalize if previous token was whitespace
parts[i] = parts[i].substring(0, 1).toUpperCase() + parts[i].substring(1).toLowerCase();
else
parts[i] = parts[i].toLowerCase();
@@ -615,8 +617,8 @@ var CPStringRegexSpecialCharacters = [
return parseFloat(self, 10);
}
/*!
- Returns \c YES on encountering one of "Y", "y", "T", "t", or
- a digit 1-9. Returns \c NO otherwise. This method skips the initial
+ Returns \c YES on encountering one of "Y", "y", "T", "t", or
+ a digit 1-9. Returns \c NO otherwise. This method skips the initial
whitespace characters, +,- followed by Zeroes.
*/
@@ -678,7 +680,7 @@ var CPStringRegexSpecialCharacters = [
- (CPString)lastPathComponent
{
var components = [self pathComponents];
- return components[components.length -1];
+ return components[components.length - 1];
}
/*!
@@ -690,12 +692,12 @@ var CPStringRegexSpecialCharacters = [
{
var path = self,
start = length - 1;
-
+
while (path.charAt(start) === '/')
start--;
-
+
path = path.substr(0, path.lastIndexOf('/', start));
-
+
if (path === "" && charAt(0) === '/')
return '/';
@@ -758,11 +760,12 @@ var CPStringRegexSpecialCharacters = [
*/
+ (CPString)UUID
{
- var g = @"";
-
- for(var i = 0; i < 32; i++)
+ var g = @"",
+ i = 0;
+
+ for (; i < 32; i++)
g += FLOOR(RAND() * 0xF).toString(0xF);
-
+
return g;
}
diff --git a/Foundation/CPTimer.j b/Foundation/CPTimer.j
index e1ec83ce5..6e14ba46a 100644
--- a/Foundation/CPTimer.j
+++ b/Foundation/CPTimer.j
@@ -20,13 +20,14 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-@import "CPObject.j"
-@import "CPInvocation.j"
@import "CPDate.j"
+@import "CPInvocation.j"
+@import "CPObject.j"
@import "CPRunLoop.j"
+
/*!
- @class CPTimer
+ @class CPTimer
@ingroup foundation
@brief A timer object that can send a message after the given time interval.
@@ -36,7 +37,7 @@
CPTimeInterval _timeInterval;
CPInvocation _invocation;
Function _callback;
-
+
BOOL _repeats;
BOOL _isValid;
CPDate _fireDate;
@@ -46,13 +47,13 @@
/*!
Returns a new NSTimer object and adds it to the current NSRunLoop object in the default mode.
*/
-+ (CPTimer)scheduledTimerWithTimeInterval:(CPTimeInterval)seconds invocation:(CPInvocation)anInvocation repeats:(BOOL)shouldRepeat
++ (CPTimer)scheduledTimerWithTimeInterval:(CPTimeInterval)seconds invocation:(CPInvocation)anInvocation repeats:(BOOL)shouldRepeat
{
var timer = [[self alloc] initWithFireDate:[CPDate dateWithTimeIntervalSinceNow:seconds] interval:seconds invocation:anInvocation repeats:shouldRepeat];
//add to the runloop
[[CPRunLoop currentRunLoop] addTimer:timer forMode:CPDefaultRunLoopMode];
-
+
return timer;
}
@@ -65,27 +66,27 @@
//add to the runloop
[[CPRunLoop currentRunLoop] addTimer:timer forMode:CPDefaultRunLoopMode];
-
+
return timer;
}
/*!
Returns a new NSTimer object and adds it to the current NSRunLoop object in the default mode.
*/
-+ (CPTimer)scheduledTimerWithTimeInterval:(CPTimeInterval)seconds callback:(Function)aFunction repeats:(BOOL)shouldRepeat
++ (CPTimer)scheduledTimerWithTimeInterval:(CPTimeInterval)seconds callback:(Function)aFunction repeats:(BOOL)shouldRepeat
{
var timer = [[self alloc] initWithFireDate:[CPDate dateWithTimeIntervalSinceNow:seconds] interval:seconds callback:aFunction repeats:shouldRepeat];
//add to the runloop
[[CPRunLoop currentRunLoop] addTimer:timer forMode:CPDefaultRunLoopMode];
-
+
return timer;
}
/*!
Returns a new NSTimer that, when added to a run loop, will fire after seconds.
*/
-+ (CPTimer)timerWithTimeInterval:(CPTimeInterval)seconds invocation:(CPInvocation)anInvocation repeats:(BOOL)shouldRepeat
++ (CPTimer)timerWithTimeInterval:(CPTimeInterval)seconds invocation:(CPInvocation)anInvocation repeats:(BOOL)shouldRepeat
{
return [[self alloc] initWithFireDate:[CPDate dateWithTimeIntervalSinceNow:seconds] interval:seconds invocation:anInvocation repeats:shouldRepeat];
}
@@ -101,7 +102,7 @@
/*!
Returns a new NSTimer that, when added to a run loop, will fire after seconds.
*/
-+ (CPTimer)timerWithTimeInterval:(CPTimeInterval)seconds callback:(Function)aFunction repeats:(BOOL)shouldRepeat
++ (CPTimer)timerWithTimeInterval:(CPTimeInterval)seconds callback:(Function)aFunction repeats:(BOOL)shouldRepeat
{
return [[self alloc] initWithFireDate:[CPDate dateWithTimeIntervalSinceNow:seconds] interval:seconds callback:aFunction repeats:shouldRepeat];
}
@@ -112,8 +113,8 @@
- (id)initWithFireDate:(CPDate)aDate interval:(CPTimeInterval)seconds invocation:(CPInvocation)anInvocation repeats:(BOOL)shouldRepeat
{
self = [super init];
-
- if (self)
+
+ if (self)
{
_timeInterval = seconds;
_invocation = anInvocation;
@@ -121,7 +122,7 @@
_isValid = YES;
_fireDate = aDate;
}
-
+
return self;
}
@@ -131,16 +132,16 @@
- (id)initWithFireDate:(CPDate)aDate interval:(CPTimeInterval)seconds target:(id)aTarget selector:(SEL)aSelector userInfo:(id)userInfo repeats:(BOOL)shouldRepeat
{
var invocation = [CPInvocation invocationWithMethodSignature:1];
-
+
[invocation setTarget:aTarget];
[invocation setSelector:aSelector];
[invocation setArgument:self atIndex:2];
-
+
self = [self initWithFireDate:aDate interval:seconds invocation:invocation repeats:shouldRepeat];
if (self)
_userInfo = userInfo;
-
+
return self;
}
@@ -150,8 +151,8 @@
- (id)initWithFireDate:(CPDate)aDate interval:(CPTimeInterval)seconds callback:(Function)aFunction repeats:(BOOL)shouldRepeat
{
self = [super init];
-
- if (self)
+
+ if (self)
{
_timeInterval = seconds;
_callback = aFunction;
@@ -159,14 +160,14 @@
_isValid = YES;
_fireDate = aDate;
}
-
+
return self;
}
/*!
Returns the receiver’s time interval.
*/
-- (CPTimeInterval)timeInterval
+- (CPTimeInterval)timeInterval
{
return _timeInterval;
}
@@ -174,15 +175,15 @@
/*!
Returns the date at which the receiver will fire.
*/
-- (CPDate)fireDate
+- (CPDate)fireDate
{
- return _fireDate;
+ return _fireDate;
}
/*!
Resets the receiver to fire next at a given date.
*/
-- (void)setFireDate:(CPDate)aDate
+- (void)setFireDate:(CPDate)aDate
{
_fireDate = aDate;
}
@@ -205,7 +206,7 @@
if (_repeats)
_fireDate = [CPDate dateWithTimeIntervalSinceNow:_timeInterval];
-
+
else
[self invalidate];
}
@@ -213,7 +214,7 @@
/*!
Returns a Boolean value that indicates whether the receiver is currently valid.
*/
-- (BOOL)isValid
+- (BOOL)isValid
{
return _isValid;
}
@@ -221,7 +222,7 @@
/*!
Stops the receiver from ever firing again and requests its removal from its NSRunLoop object.
*/
-- (void)invalidate
+- (void)invalidate
{
_isValid = NO;
_userInfo = nil;
@@ -246,14 +247,14 @@ var _CPTimerBridgeTimer = function(codeOrFunction, aDelay, shouldRepeat, functio
{
var timeoutID = CPTimersTimeoutID++,
theFunction = nil;
-
+
if (typeof codeOrFunction === "string")
theFunction = function() { new Function(codeOrFunction)(); if (!shouldRepeat) CPTimersForTimeoutIDs[timeoutID] = nil; }
else
{
if (!functionArgs)
functionArgs = [];
-
+
theFunction = function() { codeOrFunction.apply(window, functionArgs); if (!shouldRepeat) CPTimersForTimeoutIDs[timeoutID] = nil; }
}
@@ -270,10 +271,10 @@ window.setTimeout = function(codeOrFunction, aDelay)
window.clearTimeout = function(aTimeoutID)
{
var timer = CPTimersForTimeoutIDs[aTimeoutID];
-
+
if (timer)
[timer invalidate];
-
+
CPTimersForTimeoutIDs[aTimeoutID] = nil;
}
diff --git a/Foundation/CPURL.j b/Foundation/CPURL.j
index 25dbb7d5a..1486baad3 100644
--- a/Foundation/CPURL.j
+++ b/Foundation/CPURL.j
@@ -1,5 +1,26 @@
+/*
+ * CPURL.j
+ * Foundation
+ *
+ * Created by Francisco Tolmasky.
+ * Copyright 2008, 280 North, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
-@import
+@import "CPObject.j"
CPURLNameKey = @"CPURLNameKey";
CPURLLocalizedNameKey = @"CPURLLocalizedNameKey";
@@ -44,7 +65,7 @@ CPURLCustomIconKey = @"CPURLCustomIconKey";
- (id)initWithScheme:(CPString)aScheme host:(CPString)aHost path:(CPString)aPath
{
var URLString = (aScheme ? aScheme + ":" : "") + (aHost ? aHost + "//" : "") + (aPath || "");
-
+
return [self initWithString:URLString];
}
@@ -94,6 +115,12 @@ CPURLCustomIconKey = @"CPURLCustomIconKey";
return [self absoluteURL].path();
}
+- (CPArray)pathComponents
+{
+ var path = self.pathComponents();
+ return [path copy];
+}
+
// if absolute, returns the same as path
- (CPString)relativePath
{
diff --git a/Foundation/CPURLConnection.j b/Foundation/CPURLConnection.j
index 0d8c7b2a7..d6f260226 100644
--- a/Foundation/CPURLConnection.j
+++ b/Foundation/CPURLConnection.j
@@ -31,45 +31,45 @@ var CPURLConnectionDelegate = nil;
/*!
@class CPURLConnection
@ingroup foundation
- @brief Provides loading of a URL request.
+ @brief Provides loading of a URL request.
An interface to downloading content at a specified URL. Using one of the
class methods, you can obtain the data.
-
+
@delegate -(void)connection:(CPURLConnection)connection didFailWithError:(id)error;
Called when the connection encounters an error.
@param connection the connection that had an error
@param error the error, which is either a javascript DOMException or an http
status code (javascript number/CPNumber)
-
+
@delegate -(void)connection:(CPURLConnection)connection didReceiveResponse:(CPHTTPURLResponse)response;
Called when the connection receives a response.
@param connection the connection that received a response
@param response the received response
-
+
@delegate -(void)connection:(CPURLConnection)connection didReceiveData:(CPString)data;
Called when the connection has received data.
@param connection the connection that received data
@param data the received data
-
+
@delegate -(void)connectionDidFinishLoading:(CPURLConnection)connection;
Called when the URL has finished loading.
@param connection the connection that finished loading
-
+
Class Delegate Method:
-
+
@delegate -(void)connectionDidReceiveAuthenticationChallenge:(id)connection
The class delegate allows you to set global behavior for when authentication challenges (401 status codes) are returned.
-
+
The recommended way to handle this method is to store a reference to the connection, and then use whatever
- method you have to authenticate yourself. Once you've authenticated yourself, you should cancel
+ method you have to authenticate yourself. Once you've authenticated yourself, you should cancel
and then start the connection:
-
+
[connection cancel];
[connection start];
-
+
@param connection the connection that received the authentication challenge.
*/
@implementation CPURLConnection : CPObject
@@ -116,7 +116,7 @@ var CPURLConnectionDelegate = nil;
catch (anException)
{
}
-
+
return nil;
}
@@ -141,13 +141,13 @@ var CPURLConnectionDelegate = nil;
- (id)initWithRequest:(CPURLRequest)aRequest delegate:(id)aDelegate startImmediately:(BOOL)shouldStartImmediately
{
self = [super init];
-
+
if (self)
{
_request = aRequest;
_delegate = aDelegate;
_isCanceled = NO;
-
+
var URL = [_request URL],
scheme = [URL scheme];
@@ -187,7 +187,7 @@ var CPURLConnectionDelegate = nil;
_isCanceled = NO;
try
- {
+ {
_HTTPRequest.open([_request HTTPMethod], [[_request URL] absoluteString], YES);
_HTTPRequest.onreadystatechange = function() { [self _readyStateDidChange]; }
@@ -214,7 +214,7 @@ var CPURLConnectionDelegate = nil;
- (void)cancel
{
_isCanceled = YES;
-
+
try
{
_HTTPRequest.abort();
@@ -238,24 +238,22 @@ var CPURLConnectionDelegate = nil;
var statusCode = _HTTPRequest.status(),
URL = [_request URL];
- if ([_delegate respondsToSelector:@selector(connection:didReceiveResponse:)])
+ if (statusCode === 401 && [CPURLConnectionDelegate respondsToSelector:@selector(connectionDidReceiveAuthenticationChallenge:)])
+ [CPURLConnectionDelegate connectionDidReceiveAuthenticationChallenge:self];
+ else
{
- if (_isLocalFileConnection)
- [_delegate connection:self didReceiveResponse:[[CPURLResponse alloc] initWithURL:URL]];
- else
+ if ([_delegate respondsToSelector:@selector(connection:didReceiveResponse:)])
{
- var response = [[CPHTTPURLResponse alloc] initWithURL:URL];
-
- [response _setStatusCode:statusCode];
-
- [_delegate connection:self didReceiveResponse:response];
+ if (_isLocalFileConnection)
+ [_delegate connection:self didReceiveResponse:[[CPURLResponse alloc] initWithURL:URL]];
+ else
+ {
+ var response = [[CPHTTPURLResponse alloc] initWithURL:URL];
+ [response _setStatusCode:statusCode];
+ [_delegate connection:self didReceiveResponse:response];
+ }
}
- }
- if (!_isCanceled)
- {
- if (statusCode === 401 && [CPURLConnectionDelegate respondsToSelector:@selector(connectionDidReceiveAuthenticationChallenge:)])
- [CPURLConnectionDelegate connectionDidReceiveAuthenticationChallenge:self];
- else
+ if (!_isCanceled)
{
if ([_delegate respondsToSelector:@selector(connection:didReceiveData:)])
[_delegate connection:self didReceiveData:_HTTPRequest.responseText()];
@@ -292,4 +290,4 @@ var CPURLConnectionDelegate = nil;
return [self _HTTPRequest];
}
-@end
\ No newline at end of file
+@end
diff --git a/Foundation/CPURLRequest.j b/Foundation/CPURLRequest.j
index 5d6b7fc9b..28b4e4dc4 100644
--- a/Foundation/CPURLRequest.j
+++ b/Foundation/CPURLRequest.j
@@ -23,7 +23,7 @@
@import "CPObject.j"
-/*!
+/*!
@class CPURLRequest
@ingroup foundation
@brief Contains data obtained during a request made with CPURLConnection.
@@ -34,7 +34,7 @@
@implementation CPURLRequest : CPObject
{
CPURL _URL;
-
+
// FIXME: this should be CPData
CPString _HTTPBody;
CPString _HTTPMethod;
@@ -59,7 +59,7 @@
- (id)initWithURL:(CPURL)aURL
{
self = [super init];
-
+
if (self)
{
[self setURL:aURL];
@@ -67,12 +67,12 @@
_HTTPBody = @"";
_HTTPMethod = @"GET";
_HTTPHeaderFields = [CPDictionary dictionary];
-
- [self setValue:"Thu, 1 Jan 1970 00:00:00 GMT" forHTTPHeaderField:"If-Modified-Since"];
+
+ [self setValue:"Thu, 01 Jan 1970 00:00:00 GMT" forHTTPHeaderField:"If-Modified-Since"];
[self setValue:"no-cache" forHTTPHeaderField:"Cache-Control"];
[self setValue:"XMLHttpRequest" forHTTPHeaderField:"X-Requested-With"];
}
-
+
return self;
}
diff --git a/Foundation/CPURLResponse.j b/Foundation/CPURLResponse.j
index ed524d940..6d0c0bf5e 100644
--- a/Foundation/CPURLResponse.j
+++ b/Foundation/CPURLResponse.j
@@ -44,10 +44,10 @@
- (id)initWithURL:(CPURL)aURL
{
self = [super init];
-
+
if (self)
_URL = aURL;
-
+
return self;
}
@@ -57,13 +57,13 @@
}
/*
Creating a Response
-initWithURL:MIMEType:expectedContentLength:textEncodingName:
+initWithURL:MIMEType:expectedContentLength:textEncodingName:
Getting the Response Properties
-expectedContentLength
-suggestedFilename
-MIMEType
-textEncodingName
-URL
+expectedContentLength
+suggestedFilename
+MIMEType
+textEncodingName
+URL
*/
@end
diff --git a/Foundation/CPUndoManager.j b/Foundation/CPUndoManager.j
index 7d9c8d8f0..f07247589 100644
--- a/Foundation/CPUndoManager.j
+++ b/Foundation/CPUndoManager.j
@@ -20,15 +20,15 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-@import "CPObject.j"
@import "CPInvocation.j"
+@import "CPObject.j"
@import "CPProxy.j"
var CPUndoManagerNormal = 0,
CPUndoManagerUndoing = 1,
CPUndoManagerRedoing = 2;
-
+
CPUndoManagerCheckpointNotification = @"CPUndoManagerCheckpointNotification";
CPUndoManagerDidOpenUndoGroupNotification = @"CPUndoManagerDidOpenUndoGroupNotification";
CPUndoManagerDidRedoChangeNotification = @"CPUndoManagerDidRedoChangeNotification";
@@ -53,7 +53,7 @@ var _CPUndoGroupingPool = [],
{
if (!anUndoGrouping || _CPUndoGroupingPool.length >= _CPUndoGroupingPoolCapacity)
return;
-
+
_CPUndoGroupingPool.push(anUndoGrouping);
}
@@ -62,28 +62,28 @@ var _CPUndoGroupingPool = [],
if (_CPUndoGroupingPool.length)
{
var grouping = _CPUndoGroupingPool.pop();
-
+
grouping._parent = anUndoGrouping;
-
+
if (grouping._invocations.length)
grouping._invocations = [];
-
+
return grouping;
}
-
+
return [[self alloc] initWithParent:anUndoGrouping];
}
- (id)initWithParent:(_CPUndoGrouping)anUndoGrouping
{
self = [super init];
-
+
if (self)
{
_parent = anUndoGrouping;
_invocations = [];
}
-
+
return self;
}
@@ -134,13 +134,13 @@ var _CPUndoGroupingParentKey = @"_CPUndoGroupingParentKey",
- (id)initWithCoder:(CPCoder)aCoder
{
self = [super init];
-
+
if (self)
{
_parent = [aCoder decodeObjectForKey:_CPUndoGroupingParentKey];
_invocations = [aCoder decodeObjectForKey:_CPUndoGroupingInvocationsKey];
}
-
+
return self;
}
@@ -152,7 +152,7 @@ var _CPUndoGroupingParentKey = @"_CPUndoGroupingParentKey",
@end
-/*!
+/*!
@class CPUndoManager
@ingroup foundation
@brief A general mechanism for user action "undo".
@@ -193,21 +193,21 @@ var _CPUndoGroupingParentKey = @"_CPUndoGroupingParentKey",
- (id)init
{
self = [super init];
-
+
if (self)
{
_redoStack = [];
_undoStack = [];
-
+
_state = CPUndoManagerNormal;
-
+
[self setRunLoopModes:[CPDefaultRunLoopMode]];
[self setGroupsByEvent:YES];
_undoManagerProxy = [_CPUndoManagerProxy alloc];
_undoManagerProxy._undoManager = self;
}
-
+
return self;
}
@@ -258,7 +258,7 @@ var _CPUndoGroupingParentKey = @"_CPUndoGroupingParentKey",
- (id)prepareWithInvocationTarget:(id)aTarget
{
_preparedTarget = aTarget;
-
+
return _undoManagerProxy;
}
@@ -270,7 +270,7 @@ var _CPUndoGroupingParentKey = @"_CPUndoGroupingParentKey",
{
if ([_preparedTarget respondsToSelector:aSelector])
return 1;
-
+
return nil;//[_preparedTarget methodSignatureForSelector:selector];
}
@@ -317,8 +317,8 @@ if (_currentGroup == nil)
{
if (_undoStack.length > 0)
return YES;
-
- return [_currentGrouping actions].length > 0;
+
+ return [[_currentGrouping invocations] count] > 0;
}
// Preform Undo and Redo
@@ -337,7 +337,7 @@ if (_currentGroup == nil)
Performs an undo on the last undo group.
*/
- (void)undoNestedGroup
-{
+{
if ([_undoStack count] <= 0)
return;
@@ -373,7 +373,7 @@ if (_currentGroup == nil)
// Don't do anything if we have no redos.
if ([_redoStack count] <= 0)
return;
-
+
/* if (_state == NSUndoManagerUndoing)
[NSException raise:NSInternalInconsistencyException
format:@"redo called while undoing"];
@@ -386,19 +386,19 @@ if (_currentGroup == nil)
[defaultCenter postNotificationName:CPUndoManagerWillRedoChangeNotification
object:self];
-
+
var oldUndoGrouping = _currentGrouping,
undoGrouping = _redoStack.pop();
-
+
_currentGrouping = nil;
_state = CPUndoManagerRedoing;
[self _beginUndoGrouping];
[undoGrouping invoke];
[self endUndoGrouping];
-
+
[_CPUndoGrouping _poolUndoGrouping:undoGrouping];
-
+
_currentGrouping = oldUndoGrouping;
_state = CPUndoManagerNormal;
@@ -452,31 +452,31 @@ if (_currentGroup == nil)
object:self];
var parent = [_currentGrouping parent];
-
+
if (!parent && [_currentGrouping invocations].length > 0)
{
[defaultCenter
postNotificationName:CPUndoManagerWillCloseUndoGroupNotification
object:self];
-
+
// Put this group on the redo stack if we are currently undoing, otherwise
// put it on the undo stack. That way, "undos" become "redos".
var stack = _state === CPUndoManagerUndoing ? _redoStack : _undoStack;
-
+
stack.push(_currentGrouping);
-
+
if (_levelsOfUndo > 0 && stack.length > _levelsOfUndo)
- stack.splice(0, 1);
+ stack.splice(0, 1);
}
-
+
// Nested Undo Grouping
else
{
[parent addInvocationsFromArray:[_currentGrouping invocations]];
-
+
[_CPUndoGrouping _poolUndoGrouping:_currentGrouping];
}
-
+
_currentGrouping = parent;
}
@@ -491,7 +491,7 @@ if (_currentGroup == nil)
if (_disableCount <= 0)
[CPException raise:CPInternalInconsistencyException
reason:"enableUndoRegistration. There are no disable messages in effect right now."];
-
+
_disableCount--;
}
@@ -527,10 +527,10 @@ if (_currentGroup == nil)
{
var grouping = _currentGrouping,
level = _currentGrouping != nil;
-
+
while (grouping = [grouping parent])
++level;
-
+
return level;
}
@@ -586,27 +586,27 @@ if (_currentGroup == nil)
- (void)removeAllActionsWithTarget:(id)aTarget
{
[_currentGrouping removeInvocationsWithTarget:aTarget];
-
+
var index = _redoStack.length;
-
+
while (index--)
{
var grouping = _redoStack[index];
-
+
[grouping removeInvocationsWithTarget:aTarget];
-
+
if (![grouping invocations].length)
_redoStack.splice(index, 1);
}
index = _undoStack.length;
-
+
while (index--)
{
var grouping = _undoStack[index];
-
+
[grouping removeInvocationsWithTarget:aTarget];
-
+
if (![grouping invocations].length)
_undoStack.splice(index, 1);
}
@@ -739,7 +739,7 @@ var CPUndoManagerRedoStackKey = @"CPUndoManagerRedoStackKey",
CPUndoManagerLevelsOfUndoKey = @"CPUndoManagerLevelsOfUndoKey";
CPUndoManagerActionNameKey = @"CPUndoManagerActionNameKey";
CPUndoManagerCurrentGroupingKey = @"CPUndoManagerCurrentGroupingKey";
-
+
CPUndoManagerRunLoopModesKey = @"CPUndoManagerRunLoopModesKey";
CPUndoManagerGroupsByEventKey = @"CPUndoManagerGroupsByEventKey";
@@ -748,22 +748,22 @@ var CPUndoManagerRedoStackKey = @"CPUndoManagerRedoStackKey",
- (id)initWithCoder:(CPCoder)aCoder
{
self = [super init];
-
+
if (self)
{
_redoStack = [aCoder decodeObjectForKey:CPUndoManagerRedoStackKey];
_undoStack = [aCoder decodeObjectForKey:CPUndoManagerUndoStackKey];
-
+
_levelsOfUndo = [aCoder decodeObjectForKey:CPUndoManagerLevelsOfUndoKey];
_actionName = [aCoder decodeObjectForKey:CPUndoManagerActionNameKey];
_currentGrouping = [aCoder decodeObjectForKey:CPUndoManagerCurrentGroupingKey];
-
+
_state = CPUndoManagerNormal;
-
+
[self setRunLoopModes:[aCoder decodeObjectForKey:CPUndoManagerRunLoopModesKey]];
[self setGroupsByEvent:[aCoder decodeBoolForKey:CPUndoManagerGroupsByEventKey]];
}
-
+
return self;
}
@@ -771,10 +771,10 @@ var CPUndoManagerRedoStackKey = @"CPUndoManagerRedoStackKey",
{
[aCoder encodeObject:_redoStack forKey:CPUndoManagerRedoStackKey];
[aCoder encodeObject:_undoStack forKey:CPUndoManagerUndoStackKey];
-
+
[aCoder encodeInt:_levelsOfUndo forKey:CPUndoManagerLevelsOfUndoKey];
[aCoder encodeObject:_actionName forKey:CPUndoManagerActionNameKey];
-
+
[aCoder encodeObject:_currentGrouping forKey:CPUndoManagerCurrentGroupingKey];
[aCoder encodeObject:_runLoopModes forKey:CPUndoManagerRunLoopModesKey];
diff --git a/Foundation/CPUserSessionManager.j b/Foundation/CPUserSessionManager.j
index b15d1e916..5feca31ff 100644
--- a/Foundation/CPUserSessionManager.j
+++ b/Foundation/CPUserSessionManager.j
@@ -20,8 +20,8 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-@import
-@import
+@import "CPObject.j"
+@import "CPString.j"
CPUserSessionUndeterminedStatus = 0;
@@ -36,7 +36,7 @@ var CPDefaultUserSessionManager = nil;
@implementation CPUserSessionManager : CPObject
{
CPUserSessionStatus _status;
-
+
CPString _userIdentifier;
}
@@ -51,10 +51,10 @@ var CPDefaultUserSessionManager = nil;
- (id)init
{
self = [super init];
-
+
if (self)
_status = CPUserSessionUndeterminedStatus;
-
+
return self;
}
@@ -67,9 +67,9 @@ var CPDefaultUserSessionManager = nil;
{
if (_status == aStatus)
return;
-
+
_status = aStatus;
-
+
[[CPNotificationCenter defaultCenter]
postNotificationName:CPUserSessionManagerStatusDidChangeNotification
object:self];
@@ -87,9 +87,9 @@ var CPDefaultUserSessionManager = nil;
{
if (_userIdentifier == anIdentifier)
return;
-
+
_userIdentifier = anIdentifier;
-
+
[[CPNotificationCenter defaultCenter]
postNotificationName:CPUserSessionManagerUserIdentifierDidChangeNotification
object:self];
diff --git a/Foundation/CPValue.j b/Foundation/CPValue.j
index 1c6de7a92..70ea751ad 100644
--- a/Foundation/CPValue.j
+++ b/Foundation/CPValue.j
@@ -20,11 +20,11 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-@import "CPObject.j"
@import "CPCoder.j"
+@import "CPObject.j"
-/*!
+/*!
@class CPValue
@ingroup foundation
@brief A generic "value". Can be subclassed to hold specific data types.
@@ -54,10 +54,10 @@
- (id)initWithJSObject:(JSObject)aJSObject
{
self = [super init];
-
+
if (self)
_JSObject = aJSObject;
-
+
return self;
}
@@ -83,7 +83,7 @@ var CPValueValueKey = @"CPValueValueKey";
- (id)initWithCoder:(CPCoder)aCoder
{
self = [super init];
-
+
if (self)
_JSObject = JSON.parse([aCoder decodeObjectForKey:CPValueValueKey]);
diff --git a/Foundation/CPWebDAVManager.j b/Foundation/CPWebDAVManager.j
index fb17b72a2..6b821fb08 100644
--- a/Foundation/CPWebDAVManager.j
+++ b/Foundation/CPWebDAVManager.j
@@ -1,3 +1,24 @@
+/*
+ * CPWebDAVManager.j
+ * Foundation
+ *
+ * Created by Francisco Tolmasky.
+ * Copyright 2008, 280 North, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
var setURLResourceValuesForKeysFromProperties = function(aURL, keys, properties)
{
diff --git a/Foundation/Foundation.j b/Foundation/Foundation.j
index 2d4fb3ebb..03709afa5 100755
--- a/Foundation/Foundation.j
+++ b/Foundation/Foundation.j
@@ -35,7 +35,6 @@
@import "CPKeyedUnarchiver.j"
@import "CPKeyValueCoding.j"
@import "CPKeyValueObserving.j"
-@import "CPLog.j"
@import "CPNotification.j"
@import "CPNotificationCenter.j"
@import "CPNull.j"
diff --git a/Objective-J/CFBundle.js b/Objective-J/CFBundle.js
index 7f75d3d1d..8c7044e73 100644
--- a/Objective-J/CFBundle.js
+++ b/Objective-J/CFBundle.js
@@ -635,9 +635,9 @@ function decompileStaticFile(/*Bundle*/ aBundle, /*String*/ aString, /*String*/
if (CFBundleSupportedSpriteType === CFBundleMHTMLUncachedSpriteType)
{
- var exclamationIndex = URLString.indexOf("!"),
- firstPart = URLString.substring(0, exclamationIndex),
- lastPart = URLString.substring(exclamationIndex);
+ var exclamationIndex = mappedURLString.indexOf("!"),
+ firstPart = mappedURLString.substring(0, exclamationIndex),
+ lastPart = mappedURLString.substring(exclamationIndex);
mappedURLString = firstPart + "?" + CFCacheBuster + lastPart;
}
diff --git a/Objective-J/CFDictionary.js b/Objective-J/CFDictionary.js
index a9c0ccb74..8c10b7fdf 100644
--- a/Objective-J/CFDictionary.js
+++ b/Objective-J/CFDictionary.js
@@ -75,7 +75,7 @@ CFDictionary.prototype.containsValue = function(/*id*/ anObject)
count = keys.length;
for (; index < count; ++index)
- if (buckets[keys] === anObject)
+ if (buckets[keys[index]] === anObject)
return YES;
return NO;
@@ -106,8 +106,8 @@ CFDictionary.prototype.countOfValue = function(/*id*/ anObject)
countOfValue = 0;
for (; index < count; ++index)
- if (buckets[keys] === anObject)
- return ++countOfValue;
+ if (buckets[keys[index]] === anObject)
+ ++countOfValue;
return countOfValue;
}
diff --git a/Objective-J/CFHTTPRequest.js b/Objective-J/CFHTTPRequest.js
index d4f9cba76..d4007f585 100644
--- a/Objective-J/CFHTTPRequest.js
+++ b/Objective-J/CFHTTPRequest.js
@@ -92,15 +92,23 @@ if (!NativeRequest)
GLOBAL(CFHTTPRequest) = function()
{
+ this._isOpen = false;
+ this._requestHeaders = {};
+ this._mimeType = null;
+
this._eventDispatcher = new EventDispatcher(this);
this._nativeRequest = new NativeRequest();
var self = this;
-
- this._nativeRequest.onreadystatechange = function()
+ this._stateChangeHandler = function()
{
determineAndDispatchHTTPRequestEvents(self);
}
+
+ this._nativeRequest.onreadystatechange = this._stateChangeHandler;
+
+ if (CFHTTPRequest.AuthenticationDelegate !== nil)
+ this._eventDispatcher.addEventListener("HTTP403", function(){CFHTTPRequest.AuthenticationDelegate(self)});
}
CFHTTPRequest.UninitializedState = 0;
@@ -109,6 +117,9 @@ CFHTTPRequest.LoadedState = 2;
CFHTTPRequest.InteractiveState = 3;
CFHTTPRequest.CompleteState = 4;
+//override to forward all CFHTTPRequest authorization failures to a single function
+CFHTTPRequest.AuthenticationDelegate = nil;
+
CFHTTPRequest.prototype.status = function()
{
try
@@ -177,7 +188,7 @@ CFHTTPRequest.prototype.responseText = function()
CFHTTPRequest.prototype.setRequestHeader = function(/*String*/ aHeader, /*Object*/ aValue)
{
- return this._nativeRequest.setRequestHeader(aHeader, aValue);
+ this._requestHeaders[aHeader] = aValue;
}
CFHTTPRequest.prototype.getResponseHeader = function(/*String*/ aHeader)
@@ -192,17 +203,40 @@ CFHTTPRequest.prototype.getAllResponseHeaders = function()
CFHTTPRequest.prototype.overrideMimeType = function(/*String*/ aMimeType)
{
- if ("overrideMimeType" in this._nativeRequest)
- return this._nativeRequest.overrideMimeType(aMimeType);
+ this._mimeType = aMimeType;
}
CFHTTPRequest.prototype.open = function(/*String*/ aMethod, /*String*/ aURL, /*Boolean*/ isAsynchronous, /*String*/ aUser, /*String*/ aPassword)
{
+ this._isOpen = true;
+ this._URL = aURL;
+ this._async = isAsynchronous;
+ this._method = aMethod;
+ this._user = aUser;
+ this._password = aPassword;
return this._nativeRequest.open(aMethod, aURL, isAsynchronous, aUser, aPassword);
}
CFHTTPRequest.prototype.send = function(/*Object*/ aBody)
{
+ for (var i in this._requestHeaders)
+ {
+ if (this._requestHeaders.hasOwnProperty(i))
+ this._nativeRequest.setRequestHeader(i, this._requestHeaders[i]);
+ }
+
+ if (!this._isOpen)
+ {
+ delete this._nativeRequest.onreadystatechange;
+ this._nativeRequest.open(this._method, this._URL, this._async, this._user, this._password);
+ this._nativeRequest.onreadystatechange = this._stateChangeHandler;
+ }
+
+ if (this._mimeType && "overrideMimeType" in this._nativeRequest)
+ this._nativeRequest.overrideMimeType(this._mimeType);
+
+ this._isOpen = false;
+
try
{
return this._nativeRequest.send(aBody);
@@ -216,6 +250,7 @@ CFHTTPRequest.prototype.send = function(/*Object*/ aBody)
CFHTTPRequest.prototype.abort = function()
{
+ this._isOpen = false;
return this._nativeRequest.abort();
}
@@ -236,20 +271,20 @@ function determineAndDispatchHTTPRequestEvents(/*CFHTTPRequest*/ aRequest)
eventDispatcher.dispatchEvent({ type:"readystatechange", request:aRequest});
var nativeRequest = aRequest._nativeRequest,
- readyState = ["uninitialized", "loading", "loaded", "interactive", "complete"][aRequest.readyState()];
+ readyStates = ["uninitialized", "loading", "loaded", "interactive", "complete"];
- eventDispatcher.dispatchEvent({ type:readyState, request:aRequest});
-
- if (readyState === "complete")
+ if (readyStates[aRequest.readyState()] === "complete")
{
var status = "HTTP" + aRequest.status();
-
eventDispatcher.dispatchEvent({ type:status, request:aRequest });
var result = aRequest.success() ? "success" : "failure";
-
eventDispatcher.dispatchEvent({ type:result, request:aRequest });
+
+ eventDispatcher.dispatchEvent({ type:readyStates[aRequest.readyState()], request:aRequest});
}
+ else
+ eventDispatcher.dispatchEvent({ type:readyStates[aRequest.readyState()], request:aRequest});
}
function FileRequest(/*CFURL*/ aURL, onsuccess, onfailure)
diff --git a/Objective-J/CFPropertyList.js b/Objective-J/CFPropertyList.js
index 1533f4863..39ba97e13 100644
--- a/Objective-J/CFPropertyList.js
+++ b/Objective-J/CFPropertyList.js
@@ -91,6 +91,16 @@ CFPropertyList.writePropertyListToFile = function(/*CFPropertyList*/ aPropertyLi
{
return FILE.write(aFilePath, CFPropertyList.stringFromPropertyList(aPropertyList, aFormat), { charset:"UTF-8" });
}
+CFPropertyList.modifyPlist = function(/*String*/ aFilePath, /*Function*/ aCallback, /*String*/ aFormat)
+{
+ var string = FILE.read(aFilePath, { charset:"UTF-8" });
+ var format = CFPropertyList.sniffedFormatOfString(string);
+ var plist = CFPropertyList.propertyListFromString(string, format);
+
+ aCallback(plist);
+
+ CFPropertyList.writePropertyListToFile(plist, aFilePath, aFormat || format);
+}
#endif
function serializePropertyList(/*CFPropertyList*/ aPropertyList, /*Object*/ serializers)
diff --git a/Objective-J/CommonJS/lib/objective-j.js b/Objective-J/CommonJS/lib/objective-j.js
index 1134dc857..444c47806 100644
--- a/Objective-J/CommonJS/lib/objective-j.js
+++ b/Objective-J/CommonJS/lib/objective-j.js
@@ -182,5 +182,11 @@ exports.fullVersionString = function() {
);
}
+global.ObjectiveJ = {};
+
+for (key in exports)
+ if (Object.prototype.hasOwnProperty.call(exports, key))
+ global.ObjectiveJ[key] = exports[key];
+
if (require.main == module.id)
exports.run(system.args);
diff --git a/Objective-J/CommonJS/lib/objective-j/jake/bundletask.js b/Objective-J/CommonJS/lib/objective-j/jake/bundletask.js
index 9cf34552b..13e3d7a8b 100644
--- a/Objective-J/CommonJS/lib/objective-j/jake/bundletask.js
+++ b/Objective-J/CommonJS/lib/objective-j/jake/bundletask.js
@@ -453,7 +453,9 @@ BundleTask.prototype.resourcesPath = function()
// Don't sprite images larger than 32KB, IE 8 doesn't like it.
BundleTask.isSpritable = function(aResourcePath) {
- return isImage(aResourcePath) && FILE.size(aResourcePath) < 32768;
+ return isImage(aResourcePath) && FILE.size(aResourcePath) < 32768 &&
+ ("data:" + mimeType(aResourcePath) + ";base64," +
+ base64.encode(FILE.read(aResourcePath, "b"))).length < 32768;
}
BundleTask.prototype.defineResourceTask = function(aResourcePath, aDestinationPath)
diff --git a/Objective-J/Preprocessor.js b/Objective-J/Preprocessor.js
index b95b4e61b..d66d47144 100644
--- a/Objective-J/Preprocessor.js
+++ b/Objective-J/Preprocessor.js
@@ -244,19 +244,19 @@ Preprocessor.prototype.accessors = function(tokens)
value = true;
if (!IS_WORD(name))
- throw new SyntaxError(this.error_message("*** @property attribute name not valid."));
+ throw new SyntaxError(this.error_message("*** @accessors attribute name not valid."));
if ((token = tokens.skip_whitespace()) == TOKEN_EQUAL)
{
value = tokens.skip_whitespace();
if (!IS_WORD(value))
- throw new SyntaxError(this.error_message("*** @property attribute value not valid."));
+ throw new SyntaxError(this.error_message("*** @accessors attribute value not valid."));
if (name == "setter")
{
if ((token = tokens.next()) != TOKEN_COLON)
- throw new SyntaxError(this.error_message("*** @property setter attribute requires argument with \":\" at end of selector name."));
+ throw new SyntaxError(this.error_message("*** @accessors setter attribute requires argument with \":\" at end of selector name."));
value += ":";
}
@@ -270,7 +270,7 @@ Preprocessor.prototype.accessors = function(tokens)
break;
if (token != TOKEN_COMMA)
- throw new SyntaxError(this.error_message("*** Expected ',' or ')' in @property attribute list."));
+ throw new SyntaxError(this.error_message("*** Expected ',' or ')' in @accessors attribute list."));
}
return attributes;
diff --git a/Objective-J/Runtime.js b/Objective-J/Runtime.js
index fda9ad563..1df7ab26f 100644
--- a/Objective-J/Runtime.js
+++ b/Objective-J/Runtime.js
@@ -386,7 +386,7 @@ DISPLAY_NAME(objj_registerClassPair);
GLOBAL(class_createInstance) = function(/*Class*/ aClass)
{
if (!aClass)
- objj_exception_throw(new objj_exception(OBJJNilClassException, "*** Attempting to create object with Nil class."));
+ throw new Error("*** Attempting to create object with Nil class.");
var object = new aClass.allocator();
diff --git a/Tests/AppKit/CPPopUpButtonTest.j b/Tests/AppKit/CPPopUpButtonTest.j
new file mode 100644
index 000000000..c45085633
--- /dev/null
+++ b/Tests/AppKit/CPPopUpButtonTest.j
@@ -0,0 +1,23 @@
+
+@import
+@import
+
+@implementation CPPopUpButtonTest : OJTestCase
+{
+ CPPopUpButton button;
+}
+
+- (void)setUp
+{
+ button = [CPPopUpButton new];
+}
+
+- (void)testItemTitles
+{
+ [self assert:[] equals:[button itemTitles]];
+ [button addItem:[[CPMenuItem alloc] initWithTitle:"Option A" action:nil keyEquivalent:nil]];
+ [button addItem:[[CPMenuItem alloc] initWithTitle:"Option B" action:nil keyEquivalent:nil]];
+ [self assert:["Option A", "Option B"] equals:[button itemTitles]];
+}
+
+@end
diff --git a/Tests/Foundation/CPArrayPerformance.j b/Tests/Foundation/CPArrayPerformance.j
new file mode 100644
index 000000000..a41c16dce
--- /dev/null
+++ b/Tests/Foundation/CPArrayPerformance.j
@@ -0,0 +1,56 @@
+@import
+@import
+@import
+@import
+
+@implementation CPArrayPerformance : OJTestCase
+
+- (void)testSortUsingDescriptorsSpeed
+{
+
+ var ELEMENTS = 1000,
+ REPEATS = 10,
+ array = [];
+ for (var i=0; i
+@import
+@import
+
+@implementation CPNullTest : OJTestCase
+
+- (void)testArchiving
+{
+ [self assert:[CPKeyedUnarchiver unarchiveObjectWithData:[CPKeyedArchiver archivedDataWithRootObject:[CPNull null]]] equals:[CPNull null]];
+}
+
+@end
\ No newline at end of file
diff --git a/Tests/Foundation/CPObjectTest.j b/Tests/Foundation/CPObjectTest.j
new file mode 100644
index 000000000..729e01c9e
--- /dev/null
+++ b/Tests/Foundation/CPObjectTest.j
@@ -0,0 +1,45 @@
+@import
+
+@implementation CPObjectTest : OJTestCase
+{
+}
+
+- (void)testImplementsSelector
+{
+ var receiver = [[Receiver alloc] init];
+
+ [self assertTrue:[receiver implementsSelector:@selector(implementedInReceiverAndSuper)]];
+ [self assertTrue:[receiver implementsSelector:@selector(implementedInReceiverOnly)]];
+
+ [self assertFalse:[receiver implementsSelector:@selector(implementedInSuperOnly)]];
+ [self assertFalse:[receiver implementsSelector:@selector(notImplementedInSuperNorReceiver)]];
+
+}
+
+@end
+
+@implementation SuperReceiver : CPObject
+{
+}
+
+- (void)implementedInReceiverAndSuper
+{
+}
+
+- (void)implementedInSuperOnly
+{
+}
+@end
+
+@implementation Receiver : SuperReceiver
+{
+}
+
+- (void)implementedInReceiverAndSuper
+{
+}
+
+- (void)implementedInReceiverOnly
+{
+}
+@end
diff --git a/Tests/Foundation/CPSetTest.j b/Tests/Foundation/CPSetTest.j
index 905d8fdb8..e8f4fd162 100644
--- a/Tests/Foundation/CPSetTest.j
+++ b/Tests/Foundation/CPSetTest.j
@@ -56,4 +56,17 @@
[self assertFalse:[set containsObject:nil]];
}
+- (void)testDescription
+{
+ [self assert:@"{()}" equals:[set description]];
+ [set addObject:"horizon"];
+ [set addObject:"surfer"];
+ [set addObject:"7"];
+ var desc = [set description];
+ // Ordering may not be guaranteed.
+ [self assertTrue:desc.match(new RegExp("{\(.*horizon.*\)}"))];
+ [self assertTrue:desc.match(new RegExp("{\(.*surfer.*\)}"))];
+ [self assertTrue:desc.match(new RegExp("{\(.*7.*\)}"))];
+}
+
@end
diff --git a/Tests/Manual/CPBrowserTest/AppController.j b/Tests/Manual/CPBrowserTest/AppController.j
index d70984352..9a002c9b2 100644
--- a/Tests/Manual/CPBrowserTest/AppController.j
+++ b/Tests/Manual/CPBrowserTest/AppController.j
@@ -29,6 +29,16 @@
- (CPArray)children
{
return [[Node withValue:1],
+ [Node withValue:2],
+ [Node withValue:3],
+ [Node withValue:2],
+ [Node withValue:3],
+ [Node withValue:2],
+ [Node withValue:3],
+ [Node withValue:2],
+ [Node withValue:3],
+ [Node withValue:2],
+ [Node withValue:3],
[Node withValue:2],
[Node withValue:3],
[Node withValue:4]];
diff --git a/Tests/Manual/CPBrowserTest/CPBrowser.j b/Tests/Manual/CPBrowserTest/CPBrowser.j
deleted file mode 120000
index 00538b439..000000000
--- a/Tests/Manual/CPBrowserTest/CPBrowser.j
+++ /dev/null
@@ -1 +0,0 @@
-../../../AppKit/CPBrowser.j
\ No newline at end of file
diff --git a/Tests/Manual/LoadTimeTest/AppController.j b/Tests/Manual/LoadTimeTest/AppController.j
index bd1f94618..bdb9a6c30 100644
--- a/Tests/Manual/LoadTimeTest/AppController.j
+++ b/Tests/Manual/LoadTimeTest/AppController.j
@@ -28,7 +28,7 @@
if (data.length < 10)
{
// reload with data in the query string
- window.location.href = [window.location.protocol, "//", window.location.host, window.location.port, window.location.pathname, "?", encodeURIComponent(JSON.stringify(data))].join("");
+ window.location.href = [window.location.protocol, "//", window.location.host, window.location.pathname, "?", encodeURIComponent(JSON.stringify(data))].join("");
}
else
{
@@ -48,7 +48,16 @@
loadStdev = Math.sqrt(loadStdev / data.length);
launchStdev = Math.sqrt(launchStdev / data.length);
-
+
+ if (window.parent.BCOMM) {
+ window.parent.BCOMM.finishTest({
+ loadAvg : loadAvg,
+ launchAvg : launchAvg,
+ loadStdev : loadStdev,
+ launchStdev : launchStdev
+ });
+ }
+
var theWindow = [[CPWindow alloc] initWithContentRect:CGRectMakeZero() styleMask:CPBorderlessBridgeWindowMask],
contentView = [theWindow contentView];
diff --git a/Tests/Manual/TableCibTest/Resources/MainMenu.cib b/Tests/Manual/TableCibTest/Resources/MainMenu.cib
index 94613c585..b13ff6731 100644
--- a/Tests/Manual/TableCibTest/Resources/MainMenu.cib
+++ b/Tests/Manual/TableCibTest/Resources/MainMenu.cib
@@ -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;4E;K;30;_CPCibObjectDataNamesValuesKeyD;K;6;CP$UIDd;1;5E;K;30;_CPCibObjectDataClassesKeysKeyD;K;6;CP$UIDd;1;6E;K;32;_CPCibObjectDataClassesValuesKeyD;K;6;CP$UIDd;1;7E;K;30;_CPCibObjectDataConnectionsKeyD;K;6;CP$UIDd;1;8E;K;28;_CPCibObjectDataFrameworkKeyD;K;6;CP$UIDd;1;9E;K;26;_CPCibObjectDataNextOidKeyD;K;6;CP$UIDd;2;10E;K;30;_CPCibObjectDataObjectsKeysKeyD;K;6;CP$UIDd;2;11E;K;32;_CPCibObjectDataObjectsValuesKeyD;K;6;CP$UIDd;2;12E;K;26;_CPCibObjectDataOidKeysKeyD;K;6;CP$UIDd;2;13E;K;28;_CPCibObjectDataOidValuesKeyD;K;6;CP$UIDd;2;14E;K;28;_CPCibObjectDataFileOwnerKeyD;K;6;CP$UIDd;2;16E;K;33;_CPCibObjectDataVisibleWindowsKeyD;K;6;CP$UIDd;2;18E;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;20E;D;K;6;CP$UIDd;2;16E;D;K;6;CP$UIDd;2;22E;D;K;6;CP$UIDd;2;24E;D;K;6;CP$UIDd;2;26E;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;1;0E;D;K;6;CP$UIDd;1;0E;D;K;6;CP$UIDd;1;0E;D;K;6;CP$UIDd;2;32E;D;K;6;CP$UIDd;2;33E;D;K;6;CP$UIDd;2;35E;D;K;6;CP$UIDd;2;36E;D;K;6;CP$UIDd;2;37E;E;E;D;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;2;38E;D;K;6;CP$UIDd;2;39E;D;K;6;CP$UIDd;2;40E;D;K;6;CP$UIDd;2;41E;D;K;6;CP$UIDd;2;42E;D;K;6;CP$UIDd;2;43E;D;K;6;CP$UIDd;2;44E;D;K;6;CP$UIDd;2;45E;D;K;6;CP$UIDd;2;46E;D;K;6;CP$UIDd;2;47E;D;K;6;CP$UIDd;2;48E;D;K;6;CP$UIDd;2;49E;D;K;6;CP$UIDd;2;50E;D;K;6;CP$UIDd;2;51E;D;K;6;CP$UIDd;2;52E;D;K;6;CP$UIDd;2;53E;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;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;2;55E;D;K;6;CP$UIDd;2;56E;D;K;6;CP$UIDd;2;57E;E;E;S;16;IBCocoaFrameworkD;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;20E;D;K;6;CP$UIDd;2;22E;D;K;6;CP$UIDd;2;26E;D;K;6;CP$UIDd;2;24E;D;K;6;CP$UIDd;1;0E;D;K;6;CP$UIDd;2;29E;D;K;6;CP$UIDd;2;31E;D;K;6;CP$UIDd;2;27E;D;K;6;CP$UIDd;1;0E;D;K;6;CP$UIDd;1;0E;D;K;6;CP$UIDd;2;32E;D;K;6;CP$UIDd;2;33E;D;K;6;CP$UIDd;2;35E;D;K;6;CP$UIDd;2;36E;D;K;6;CP$UIDd;2;37E;E;E;D;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;2;35E;D;K;6;CP$UIDd;2;26E;D;K;6;CP$UIDd;2;24E;D;K;6;CP$UIDd;2;31E;D;K;6;CP$UIDd;2;33E;D;K;6;CP$UIDd;2;26E;D;K;6;CP$UIDd;2;16E;D;K;6;CP$UIDd;2;35E;D;K;6;CP$UIDd;2;27E;D;K;6;CP$UIDd;2;20E;D;K;6;CP$UIDd;2;26E;D;K;6;CP$UIDd;2;35E;D;K;6;CP$UIDd;2;26E;D;K;6;CP$UIDd;2;16E;D;K;6;CP$UIDd;2;16E;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;15E;K;27;_CPCibCustomObjectClassNameD;K;6;CP$UIDd;2;58E;E;D;K;10;$classnameS;5;CPSetK;8;$classesA;S;5;CPSetS;8;CPObjectE;E;D;K;6;$classD;K;6;CP$UIDd;2;17E;K;15;CPSetObjectsKeyD;K;6;CP$UIDd;2;59E;E;D;K;10;$classnameS;13;CPTableColumnK;8;$classesA;S;13;CPTableColumnS;8;CPObjectE;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;26;CPTableColumnIdentifierKeyD;K;6;CP$UIDd;2;60E;K;21;CPTableColumnWidthKeyD;K;6;CP$UIDd;2;61E;K;24;CPTableColumnMinWidthKeyD;K;6;CP$UIDd;2;62E;K;24;CPTableColumnMaxWidthKeyD;K;6;CP$UIDd;2;63E;K;26;CPTableColumnHeaderViewKeyD;K;6;CP$UIDd;2;65E;K;24;CPTableColumnDataViewKeyD;K;6;CP$UIDd;2;67E;K;28;CPTableColumnResizingMaskKeyD;K;6;CP$UIDd;1;0E;E;D;K;10;$classnameS;17;CPTableHeaderViewK;8;$classesA;S;17;CPTableHeaderViewS;6;CPViewS;11;CPResponderS;8;CPObjectE;E;D;K;6;$classD;K;6;CP$UIDd;2;21E;K;27;CPResponderNextResponderKeyD;K;6;CP$UIDd;2;68E;K;14;CPViewFrameKeyD;K;6;CP$UIDd;2;69E;K;15;CPViewBoundsKeyD;K;6;CP$UIDd;2;69E;K;18;CPViewSuperviewKeyD;K;6;CP$UIDd;2;68E;K;19;CPViewThemeStateKeyD;K;6;CP$UIDd;2;70E;K;29;CPTableHeaderViewTableViewKeyD;K;6;CP$UIDd;2;35E;E;D;K;10;$classnameS;6;CPViewK;8;$classesA;S;6;CPViewS;11;CPResponderS;8;CPObjectE;E;D;K;6;$classD;K;6;CP$UIDd;2;23E;K;14;CPViewFrameKeyD;K;6;CP$UIDd;2;71E;K;15;CPViewBoundsKeyD;K;6;CP$UIDd;2;71E;K;17;CPViewSubviewsKeyD;K;6;CP$UIDd;2;72E;K;19;CPViewThemeStateKeyD;K;6;CP$UIDd;2;70E;E;D;K;10;$classnameS;12;CPScrollViewK;8;$classesA;S;12;CPScrollViewS;6;CPViewS;11;CPResponderS;8;CPObjectE;E;D;K;6;$classD;K;6;CP$UIDd;2;25E;K;27;CPResponderNextResponderKeyD;K;6;CP$UIDd;2;24E;K;14;CPViewFrameKeyD;K;6;CP$UIDd;2;73E;K;15;CPViewBoundsKeyD;K;6;CP$UIDd;2;74E;K;17;CPViewSubviewsKeyD;K;6;CP$UIDd;2;75E;K;18;CPViewSuperviewKeyD;K;6;CP$UIDd;2;24E;K;22;CPViewAutoresizingMaskD;K;6;CP$UIDd;2;76E;K;19;CPViewThemeStateKeyD;K;6;CP$UIDd;2;70E;K;23;CPScrollViewContentViewD;K;6;CP$UIDd;2;78E;K;29;CPScrollViewHeaderClipViewKeyD;K;6;CP$UIDd;2;68E;K;21;CPScrollViewVScrollerD;K;6;CP$UIDd;2;32E;K;21;CPScrollViewHScrollerD;K;6;CP$UIDd;2;29E;K;23;CPScrollViewVLineScrollD;K;6;CP$UIDd;2;79E;K;23;CPScrollViewVPageScrollD;K;6;CP$UIDd;2;79E;K;23;CPScrollViewHLineScrollD;K;6;CP$UIDd;2;79E;K;23;CPScrollViewHPageScrollD;K;6;CP$UIDd;2;79E;K;24;CPScrollViewHasVScrollerD;K;6;CP$UIDd;2;80E;K;24;CPScrollViewHasHScrollerD;K;6;CP$UIDd;2;80E;K;29;CPScrollViewAutohidesScrollerD;K;6;CP$UIDd;2;80E;K;25;CPScrollViewCornerViewKeyD;K;6;CP$UIDd;2;82E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;26;CPTableColumnIdentifierKeyD;K;6;CP$UIDd;2;83E;K;21;CPTableColumnWidthKeyD;K;6;CP$UIDd;2;84E;K;24;CPTableColumnMinWidthKeyD;K;6;CP$UIDd;2;79E;K;24;CPTableColumnMaxWidthKeyD;K;6;CP$UIDd;2;85E;K;26;CPTableColumnHeaderViewKeyD;K;6;CP$UIDd;2;86E;K;24;CPTableColumnDataViewKeyD;K;6;CP$UIDd;2;87E;K;28;CPTableColumnResizingMaskKeyD;K;6;CP$UIDd;1;0E;E;D;K;10;$classnameS;10;CPScrollerK;8;$classesA;S;10;CPScrollerS;9;CPControlS;6;CPViewS;11;CPResponderS;8;CPObjectE;E;D;K;6;$classD;K;6;CP$UIDd;2;28E;K;27;CPResponderNextResponderKeyD;K;6;CP$UIDd;2;26E;K;14;CPViewFrameKeyD;K;6;CP$UIDd;2;88E;K;15;CPViewBoundsKeyD;K;6;CP$UIDd;2;89E;K;18;CPViewSuperviewKeyD;K;6;CP$UIDd;2;26E;K;22;CPViewAutoresizingMaskD;K;6;CP$UIDd;2;90E;K;19;CPViewThemeStateKeyD;K;6;CP$UIDd;2;91E;K;17;CPControlValueKeyD;K;6;CP$UIDd;2;92E;K;18;CPControlTargetKeyD;K;6;CP$UIDd;2;26E;K;18;CPControlActionKeyD;K;6;CP$UIDd;2;93E;K;24;CPControlSendActionOnKeyD;K;6;CP$UIDd;2;94E;K;21;CPScrollerControlSizeD;K;6;CP$UIDd;2;95E;K;24;CPScrollerKnobProportionD;K;6;CP$UIDd;2;96E;E;D;K;10;$classnameS;20;_CPCibWindowTemplateK;8;$classesA;S;20;_CPCibWindowTemplateS;8;CPObjectE;E;D;K;6;$classD;K;6;CP$UIDd;2;30E;K;30;_CPCibWindowTemplateMaxSizeKeyD;K;6;CP$UIDd;2;97E;K;32;_CPCibWindowTemplateViewClassKeyD;K;6;CP$UIDd;1;0E;K;34;_CPCibWindowTemplateWindowClassKeyD;K;6;CP$UIDd;2;98E;K;33;_CPCibWindowTemplateWindowRectKeyD;K;6;CP$UIDd;2;99E;K;30;_CPCibWindowTempatStyleMaskKeyD;K;6;CP$UIDd;3;100E;K;34;_CPCibWindowTemplateWindowTitleKeyD;K;6;CP$UIDd;3;101E;K;33;_CPCibWindowTemplateWindowViewKeyD;K;6;CP$UIDd;2;24E;E;D;K;6;$classD;K;6;CP$UIDd;2;28E;K;27;CPResponderNextResponderKeyD;K;6;CP$UIDd;2;26E;K;14;CPViewFrameKeyD;K;6;CP$UIDd;3;102E;K;15;CPViewBoundsKeyD;K;6;CP$UIDd;3;103E;K;18;CPViewSuperviewKeyD;K;6;CP$UIDd;2;26E;K;22;CPViewAutoresizingMaskD;K;6;CP$UIDd;2;90E;K;19;CPViewThemeStateKeyD;K;6;CP$UIDd;3;104E;K;17;CPControlValueKeyD;K;6;CP$UIDd;2;95E;K;18;CPControlTargetKeyD;K;6;CP$UIDd;2;26E;K;18;CPControlActionKeyD;K;6;CP$UIDd;3;105E;K;24;CPControlSendActionOnKeyD;K;6;CP$UIDd;2;94E;K;21;CPScrollerControlSizeD;K;6;CP$UIDd;2;95E;K;24;CPScrollerKnobProportionD;K;6;CP$UIDd;3;106E;E;D;K;6;$classD;K;6;CP$UIDd;2;19E;K;26;CPTableColumnIdentifierKeyD;K;6;CP$UIDd;3;107E;K;21;CPTableColumnWidthKeyD;K;6;CP$UIDd;3;108E;K;24;CPTableColumnMinWidthKeyD;K;6;CP$UIDd;2;62E;K;24;CPTableColumnMaxWidthKeyD;K;6;CP$UIDd;2;63E;K;26;CPTableColumnHeaderViewKeyD;K;6;CP$UIDd;3;109E;K;24;CPTableColumnDataViewKeyD;K;6;CP$UIDd;3;110E;K;28;CPTableColumnResizingMaskKeyD;K;6;CP$UIDd;1;0E;E;D;K;10;$classnameS;11;CPTableViewK;8;$classesA;S;11;CPTableViewS;9;CPControlS;6;CPViewS;11;CPResponderS;8;CPObjectE;E;D;K;6;$classD;K;6;CP$UIDd;2;34E;K;27;CPResponderNextResponderKeyD;K;6;CP$UIDd;2;78E;K;14;CPViewFrameKeyD;K;6;CP$UIDd;3;111E;K;15;CPViewBoundsKeyD;K;6;CP$UIDd;3;111E;K;18;CPViewSuperviewKeyD;K;6;CP$UIDd;2;78E;K;19;CPViewThemeStateKeyD;K;6;CP$UIDd;2;70E;K;24;CPControlSendActionOnKeyD;K;6;CP$UIDd;2;94E;K;24;CPTableViewDataSourceKeyD;K;6;CP$UIDd;1;0E;K;22;CPTableViewDelegateKeyD;K;6;CP$UIDd;1;0E;K;23;CPTableViewRowHeightKeyD;K;6;CP$UIDd;3;112E;K;30;CPTableViewIntercellSpacingKeyD;K;6;CP$UIDd;3;113E;K;31;CPTableViewMultipleSelectionKeyD;K;6;CP$UIDd;3;114E;K;28;CPTableViewEmptySelectionKeyD;K;6;CP$UIDd;2;80E;K;30;CPTableViewColumnReorderingKeyD;K;6;CP$UIDd;2;80E;K;28;CPTableViewColumnResizingKeyD;K;6;CP$UIDd;2;80E;K;29;CPTableViewColumnSelectionKeyD;K;6;CP$UIDd;2;80E;K;26;CPTableViewTableColumnsKeyD;K;6;CP$UIDd;3;115E;K;23;CPTableViewGridColorKeyD;K;6;CP$UIDd;3;117E;K;27;CPTableViewGridStyleMaskKeyD;K;6;CP$UIDd;1;0E;K;39;CPTableViewUsesAlternatingBackgroundKeyD;K;6;CP$UIDd;2;80E;K;34;CPTableViewAlternatingRowColorsKeyD;K;6;CP$UIDd;3;118E;K;24;CPTableViewCornerViewKeyD;K;6;CP$UIDd;2;82E;K;24;CPTableViewHeaderViewKeyD;K;6;CP$UIDd;2;22E;E;D;K;6;$classD;K;6;CP$UIDd;2;15E;K;27;_CPCibCustomObjectClassNameD;K;6;CP$UIDd;2;58E;E;D;K;6;$classD;K;6;CP$UIDd;2;15E;K;27;_CPCibCustomObjectClassNameD;K;6;CP$UIDd;3;119E;E;S;16;Table Column (2)S;12;File's OwnerS;17;Table Header ViewS;12;Content ViewS;33;Bordered Scroll View (Table View)S;16;Table Column (3)S;19;Horizontal ScrollerS;15;Window (Window)S;29;Text Field Cell (Text Cell)-1S;29;Text Field Cell (Text Cell)-2S;27;Text Field Cell (Text Cell)S;17;Vertical ScrollerS;16;Table Column (1)S;29;Table View (Column 1, Two, 3)S;11;ApplicationS;14;App ControllerD;K;10;$classnameS;20;CPCibOutletConnectorK;8;$classesA;S;20;CPCibOutletConnectorS;14;CPCibConnectorS;8;CPObjectE;E;D;K;6;$classD;K;6;CP$UIDd;2;54E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;2;16E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;2;37E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;120E;E;D;K;6;$classD;K;6;CP$UIDd;2;54E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;2;37E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;2;31E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;121E;E;D;K;6;$classD;K;6;CP$UIDd;2;54E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;2;35E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;2;37E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;122E;E;S;13;CPApplicationD;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;2;31E;E;E;S;1;2d;3;154d;2;40d;4;1000D;K;10;$classnameS;24;_CPTableColumnHeaderViewK;8;$classesA;S;24;_CPTableColumnHeaderViewS;6;CPViewS;11;CPResponderS;8;CPObjectE;E;D;K;6;$classD;K;6;CP$UIDd;2;64E;K;14;CPViewFrameKeyD;K;6;CP$UIDd;3;123E;K;15;CPViewBoundsKeyD;K;6;CP$UIDd;3;123E;K;17;CPViewSubviewsKeyD;K;6;CP$UIDd;3;124E;K;19;CPViewThemeStateKeyD;K;6;CP$UIDd;2;70E;K;38;_CPTableColumnHeaderViewStringValueKeyD;K;6;CP$UIDd;3;125E;K;32;_CPTableColumnHeaderViewImageKeyD;K;6;CP$UIDd;1;0E;K;31;_CPTableColumnHeaderViewFontKeyD;K;6;CP$UIDd;3;127E;E;D;K;10;$classnameS;11;CPTextFieldK;8;$classesA;S;11;CPTextFieldS;9;CPControlS;6;CPViewS;11;CPResponderS;8;CPObjectE;E;D;K;6;$classD;K;6;CP$UIDd;2;66E;K;14;CPViewFrameKeyD;K;6;CP$UIDd;3;123E;K;15;CPViewBoundsKeyD;K;6;CP$UIDd;3;123E;K;19;CPViewThemeStateKeyD;K;6;CP$UIDd;3;128E;K;12;$atext-colorD;K;6;CP$UIDd;3;130E;K;11;$aalignmentD;K;6;CP$UIDd;2;95E;K;17;CPControlValueKeyD;K;6;CP$UIDd;3;131E;K;24;CPControlSendActionOnKeyD;K;6;CP$UIDd;3;132E;K;24;CPTextFieldIsEditableKeyD;K;6;CP$UIDd;1;0E;K;26;CPTextFieldIsSelectableKeyD;K;6;CP$UIDd;1;0E;K;29;CPTextFieldDrawsBackgroundKeyD;K;6;CP$UIDd;1;0E;K;29;CPTextFieldBackgroundColorKeyD;K;6;CP$UIDd;1;0E;K;31;CPTextFieldPlaceholderStringKeyD;K;6;CP$UIDd;3;131E;E;D;K;6;$classD;K;6;CP$UIDd;2;77E;K;27;CPResponderNextResponderKeyD;K;6;CP$UIDd;2;26E;K;14;CPViewFrameKeyD;K;6;CP$UIDd;3;136E;K;15;CPViewBoundsKeyD;K;6;CP$UIDd;3;137E;K;17;CPViewSubviewsKeyD;K;6;CP$UIDd;3;138E;K;18;CPViewSuperviewKeyD;K;6;CP$UIDd;2;26E;K;22;CPViewAutoresizingMaskD;K;6;CP$UIDd;2;90E;K;21;CPViewBackgroundColorD;K;6;CP$UIDd;3;135E;K;19;CPViewThemeStateKeyD;K;6;CP$UIDd;2;70E;K;24;CPScrollViewDocumentViewD;K;6;CP$UIDd;2;22E;E;S;19;{{0, 0}, {516, 23}}S;6;normalS;20;{{0, 0}, {558, 348}}D;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;2;26E;E;E;S;22;{{20, 20}, {518, 308}}S;20;{{0, 0}, {518, 308}}D;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;2;78E;D;K;6;CP$UIDd;2;32E;D;K;6;CP$UIDd;2;29E;D;K;6;CP$UIDd;2;68E;D;K;6;CP$UIDd;2;82E;E;E;d;2;36D;K;10;$classnameS;10;CPClipViewK;8;$classesA;S;10;CPClipViewS;6;CPViewS;11;CPResponderS;8;CPObjectE;E;D;K;6;$classD;K;6;CP$UIDd;2;77E;K;27;CPResponderNextResponderKeyD;K;6;CP$UIDd;2;26E;K;14;CPViewFrameKeyD;K;6;CP$UIDd;3;133E;K;15;CPViewBoundsKeyD;K;6;CP$UIDd;3;111E;K;17;CPViewSubviewsKeyD;K;6;CP$UIDd;3;134E;K;18;CPViewSuperviewKeyD;K;6;CP$UIDd;2;26E;K;22;CPViewAutoresizingMaskD;K;6;CP$UIDd;2;90E;K;21;CPViewBackgroundColorD;K;6;CP$UIDd;3;135E;K;19;CPViewThemeStateKeyD;K;6;CP$UIDd;2;70E;K;24;CPScrollViewDocumentViewD;K;6;CP$UIDd;2;35E;E;d;2;10T;D;K;10;$classnameS;13;_CPCornerViewK;8;$classesA;S;13;_CPCornerViewS;6;CPViewS;11;CPResponderS;8;CPObjectE;E;D;K;6;$classD;K;6;CP$UIDd;2;81E;K;27;CPResponderNextResponderKeyD;K;6;CP$UIDd;2;26E;K;14;CPViewFrameKeyD;K;6;CP$UIDd;3;139E;K;15;CPViewBoundsKeyD;K;6;CP$UIDd;3;140E;K;18;CPViewSuperviewKeyD;K;6;CP$UIDd;2;26E;K;22;CPViewAutoresizingMaskD;K;6;CP$UIDd;2;90E;K;21;CPViewBackgroundColorD;K;6;CP$UIDd;3;141E;K;19;CPViewThemeStateKeyD;K;6;CP$UIDd;2;70E;E;S;1;3d;3;188d;22;3.4028234663852886e+38D;K;6;$classD;K;6;CP$UIDd;2;64E;K;14;CPViewFrameKeyD;K;6;CP$UIDd;3;123E;K;15;CPViewBoundsKeyD;K;6;CP$UIDd;3;123E;K;17;CPViewSubviewsKeyD;K;6;CP$UIDd;3;142E;K;19;CPViewThemeStateKeyD;K;6;CP$UIDd;2;70E;K;38;_CPTableColumnHeaderViewStringValueKeyD;K;6;CP$UIDd;2;83E;K;32;_CPTableColumnHeaderViewImageKeyD;K;6;CP$UIDd;1;0E;K;31;_CPTableColumnHeaderViewFontKeyD;K;6;CP$UIDd;3;127E;E;D;K;6;$classD;K;6;CP$UIDd;2;66E;K;14;CPViewFrameKeyD;K;6;CP$UIDd;3;123E;K;15;CPViewBoundsKeyD;K;6;CP$UIDd;3;123E;K;19;CPViewThemeStateKeyD;K;6;CP$UIDd;3;128E;K;12;$atext-colorD;K;6;CP$UIDd;3;143E;K;11;$aalignmentD;K;6;CP$UIDd;2;95E;K;17;CPControlValueKeyD;K;6;CP$UIDd;3;131E;K;24;CPControlSendActionOnKeyD;K;6;CP$UIDd;3;132E;K;24;CPTextFieldIsEditableKeyD;K;6;CP$UIDd;1;0E;K;26;CPTextFieldIsSelectableKeyD;K;6;CP$UIDd;1;0E;K;29;CPTextFieldDrawsBackgroundKeyD;K;6;CP$UIDd;1;0E;K;29;CPTextFieldBackgroundColorKeyD;K;6;CP$UIDd;1;0E;K;31;CPTextFieldPlaceholderStringKeyD;K;6;CP$UIDd;3;131E;E;S;19;{{1, 1}, {516, 15}}S;19;{{0, 0}, {516, 15}}d;1;8S;8;disabledd;1;1S;29;_horizontalScrollerDidScroll:d;1;4d;1;0f;18;0.9866156787762906S;28;{1.79769e+308, 1.79769e+308}S;8;CPWindowS;24;{{335, 128}, {558, 348}}d;1;7S;6;WindowS;22;{{502, 16}, {15, 275}}S;19;{{0, 0}, {15, 275}}S;17;disabled+verticalS;27;_verticalScrollerDidScroll:f;18;0.9482758620689655S;1;1d;3;101D;K;6;$classD;K;6;CP$UIDd;2;64E;K;14;CPViewFrameKeyD;K;6;CP$UIDd;3;123E;K;15;CPViewBoundsKeyD;K;6;CP$UIDd;3;123E;K;17;CPViewSubviewsKeyD;K;6;CP$UIDd;3;144E;K;19;CPViewThemeStateKeyD;K;6;CP$UIDd;2;70E;K;38;_CPTableColumnHeaderViewStringValueKeyD;K;6;CP$UIDd;3;145E;K;32;_CPTableColumnHeaderViewImageKeyD;K;6;CP$UIDd;1;0E;K;31;_CPTableColumnHeaderViewFontKeyD;K;6;CP$UIDd;3;127E;E;D;K;6;$classD;K;6;CP$UIDd;2;66E;K;14;CPViewFrameKeyD;K;6;CP$UIDd;3;123E;K;15;CPViewBoundsKeyD;K;6;CP$UIDd;3;123E;K;19;CPViewThemeStateKeyD;K;6;CP$UIDd;3;128E;K;12;$atext-colorD;K;6;CP$UIDd;3;146E;K;11;$aalignmentD;K;6;CP$UIDd;2;95E;K;17;CPControlValueKeyD;K;6;CP$UIDd;3;131E;K;24;CPControlSendActionOnKeyD;K;6;CP$UIDd;3;132E;K;24;CPTextFieldIsEditableKeyD;K;6;CP$UIDd;1;0E;K;26;CPTextFieldIsSelectableKeyD;K;6;CP$UIDd;1;0E;K;29;CPTextFieldDrawsBackgroundKeyD;K;6;CP$UIDd;1;0E;K;29;CPTextFieldBackgroundColorKeyD;K;6;CP$UIDd;1;0E;K;31;CPTextFieldPlaceholderStringKeyD;K;6;CP$UIDd;3;131E;E;S;20;{{0, 0}, {516, 290}}d;2;23S;6;{0, 0}F;D;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;2;33E;D;K;6;CP$UIDd;2;20E;D;K;6;CP$UIDd;2;27E;E;E;D;K;10;$classnameS;7;CPColorK;8;$classesA;S;7;CPColorS;8;CPObjectE;E;D;K;6;$classD;K;6;CP$UIDd;3;116E;K;20;CPColorComponentsKeyD;K;6;CP$UIDd;3;147E;E;D;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;3;135E;D;K;6;CP$UIDd;3;148E;E;E;S;13;AppControllerS;8;delegateS;9;theWindowS;10;dataSourceS;16;{{0, 0}, {0, 0}}D;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;3;150E;E;E;S;3;TwoD;K;10;$classnameS;6;CPFontK;8;$classesA;S;6;CPFontS;8;CPObjectE;E;D;K;6;$classD;K;6;CP$UIDd;3;126E;K;13;CPFontNameKeyD;K;6;CP$UIDd;3;151E;K;13;CPFontSizeKeyD;K;6;CP$UIDd;3;152E;K;15;CPFontIsBoldKeyD;K;6;CP$UIDd;3;114E;E;S;11;placeholderD;K;10;$classnameS;17;_CPThemeAttributeK;8;$classesA;S;17;_CPThemeAttributeS;8;CPObjectE;E;D;K;6;$classD;K;6;CP$UIDd;3;129E;K;4;nameD;K;6;CP$UIDd;3;153E;K;5;stateD;K;6;CP$UIDd;3;154E;K;5;valueD;K;6;CP$UIDd;3;135E;E;S;0;d;4;3072S;20;{{1, 1}, {516, 290}}D;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;2;35E;E;E;D;K;6;$classD;K;6;CP$UIDd;3;116E;K;20;CPColorComponentsKeyD;K;6;CP$UIDd;3;155E;E;S;21;{{1, 291}, {516, 17}}S;19;{{0, 0}, {516, 17}}D;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;2;22E;E;E;S;22;{{502, 285}, {16, 23}}S;18;{{0, 0}, {16, 23}}D;K;6;$classD;K;6;CP$UIDd;3;116E;K;22;CPColorPatternImageKeyD;K;6;CP$UIDd;3;157E;E;D;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;3;158E;E;E;D;K;6;$classD;K;6;CP$UIDd;3;129E;K;4;nameD;K;6;CP$UIDd;3;153E;K;5;stateD;K;6;CP$UIDd;3;154E;K;5;valueD;K;6;CP$UIDd;3;135E;E;D;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;3;159E;E;E;S;8;Column 1D;K;6;$classD;K;6;CP$UIDd;3;129E;K;4;nameD;K;6;CP$UIDd;3;153E;K;5;stateD;K;6;CP$UIDd;3;154E;K;5;valueD;K;6;CP$UIDd;3;135E;E;D;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;3;160E;D;K;6;CP$UIDd;3;160E;D;K;6;CP$UIDd;3;160E;D;K;6;CP$UIDd;2;92E;E;E;D;K;6;$classD;K;6;CP$UIDd;3;116E;K;20;CPColorComponentsKeyD;K;6;CP$UIDd;3;161E;E;D;K;10;$classnameS;19;_CPImageAndTextViewK;8;$classesA;S;19;_CPImageAndTextViewS;6;CPViewS;11;CPResponderS;8;CPObjectE;E;D;K;6;$classD;K;6;CP$UIDd;3;149E;K;27;CPResponderNextResponderKeyD;K;6;CP$UIDd;2;65E;K;14;CPViewFrameKeyD;K;6;CP$UIDd;3;162E;K;15;CPViewBoundsKeyD;K;6;CP$UIDd;3;163E;K;18;CPViewSuperviewKeyD;K;6;CP$UIDd;2;65E;K;22;CPViewAutoresizingMaskD;K;6;CP$UIDd;3;164E;K;19;CPViewThemeStateKeyD;K;6;CP$UIDd;2;70E;E;S;5;Ariald;2;11S;10;text-colorS;8;selectedD;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;2;92E;D;K;6;CP$UIDd;2;92E;D;K;6;CP$UIDd;2;92E;D;K;6;CP$UIDd;2;92E;E;E;D;K;10;$classnameS;7;CPImageK;8;$classesA;S;7;CPImageS;8;CPObjectE;E;D;K;6;$classD;K;6;CP$UIDd;3;156E;K;10;CPFilenameD;K;6;CP$UIDd;3;165E;K;6;CPSizeD;K;6;CP$UIDd;3;166E;E;D;K;6;$classD;K;6;CP$UIDd;3;149E;K;27;CPResponderNextResponderKeyD;K;6;CP$UIDd;2;86E;K;14;CPViewFrameKeyD;K;6;CP$UIDd;3;162E;K;15;CPViewBoundsKeyD;K;6;CP$UIDd;3;163E;K;18;CPViewSuperviewKeyD;K;6;CP$UIDd;2;86E;K;22;CPViewAutoresizingMaskD;K;6;CP$UIDd;3;164E;K;19;CPViewThemeStateKeyD;K;6;CP$UIDd;2;70E;E;D;K;6;$classD;K;6;CP$UIDd;3;149E;K;27;CPResponderNextResponderKeyD;K;6;CP$UIDd;3;109E;K;14;CPViewFrameKeyD;K;6;CP$UIDd;3;162E;K;15;CPViewBoundsKeyD;K;6;CP$UIDd;3;163E;K;18;CPViewSuperviewKeyD;K;6;CP$UIDd;3;109E;K;22;CPViewAutoresizingMaskD;K;6;CP$UIDd;3;164E;K;19;CPViewThemeStateKeyD;K;6;CP$UIDd;2;70E;E;f;3;0.5D;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;3;167E;D;K;6;CP$UIDd;3;168E;D;K;6;CP$UIDd;2;92E;D;K;6;CP$UIDd;2;92E;E;E;S;19;{{5, 1}, {-10, -1}}S;19;{{0, 0}, {-10, -1}}d;2;18S;102;file:/usr/local/narwhal/packages/cappuccino/Frameworks/Debug/AppKit/Resources/tableview-headerview.pngS;7;{1, 23}f;18;0.8941176470588236f;18;0.9058823529411765E;K;9;$archiverS;15;CPKeyedArchiverK;8;$versionS;6;100000E;
\ No newline at end of file
+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;4E;K;30;_CPCibObjectDataNamesValuesKeyD;K;6;CP$UIDd;1;5E;K;30;_CPCibObjectDataClassesKeysKeyD;K;6;CP$UIDd;1;6E;K;32;_CPCibObjectDataClassesValuesKeyD;K;6;CP$UIDd;1;7E;K;30;_CPCibObjectDataConnectionsKeyD;K;6;CP$UIDd;1;8E;K;28;_CPCibObjectDataFrameworkKeyD;K;6;CP$UIDd;1;9E;K;26;_CPCibObjectDataNextOidKeyD;K;6;CP$UIDd;2;10E;K;30;_CPCibObjectDataObjectsKeysKeyD;K;6;CP$UIDd;2;11E;K;32;_CPCibObjectDataObjectsValuesKeyD;K;6;CP$UIDd;2;12E;K;26;_CPCibObjectDataOidKeysKeyD;K;6;CP$UIDd;2;13E;K;28;_CPCibObjectDataOidValuesKeyD;K;6;CP$UIDd;2;14E;K;28;_CPCibObjectDataFileOwnerKeyD;K;6;CP$UIDd;2;16E;K;33;_CPCibObjectDataVisibleWindowsKeyD;K;6;CP$UIDd;2;18E;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;19E;D;K;6;CP$UIDd;2;16E;D;K;6;CP$UIDd;2;21E;D;K;6;CP$UIDd;2;23E;D;K;6;CP$UIDd;2;25E;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;1;0E;D;K;6;CP$UIDd;1;0E;D;K;6;CP$UIDd;2;32E;D;K;6;CP$UIDd;1;0E;D;K;6;CP$UIDd;2;33E;D;K;6;CP$UIDd;2;34E;D;K;6;CP$UIDd;2;35E;D;K;6;CP$UIDd;2;37E;E;E;D;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;2;38E;D;K;6;CP$UIDd;2;39E;D;K;6;CP$UIDd;2;40E;D;K;6;CP$UIDd;2;41E;D;K;6;CP$UIDd;2;42E;D;K;6;CP$UIDd;2;43E;D;K;6;CP$UIDd;2;44E;D;K;6;CP$UIDd;2;45E;D;K;6;CP$UIDd;2;46E;D;K;6;CP$UIDd;2;47E;D;K;6;CP$UIDd;2;48E;D;K;6;CP$UIDd;2;49E;D;K;6;CP$UIDd;2;50E;D;K;6;CP$UIDd;2;51E;D;K;6;CP$UIDd;2;52E;D;K;6;CP$UIDd;2;53E;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;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;2;55E;D;K;6;CP$UIDd;2;56E;D;K;6;CP$UIDd;2;57E;E;E;S;16;IBCocoaFrameworkD;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;19E;D;K;6;CP$UIDd;2;21E;D;K;6;CP$UIDd;2;23E;D;K;6;CP$UIDd;1;0E;D;K;6;CP$UIDd;2;25E;D;K;6;CP$UIDd;2;29E;D;K;6;CP$UIDd;2;27E;D;K;6;CP$UIDd;2;31E;D;K;6;CP$UIDd;1;0E;D;K;6;CP$UIDd;2;32E;D;K;6;CP$UIDd;1;0E;D;K;6;CP$UIDd;2;35E;D;K;6;CP$UIDd;2;33E;D;K;6;CP$UIDd;2;34E;D;K;6;CP$UIDd;2;37E;E;E;D;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;2;16E;D;K;6;CP$UIDd;2;29E;D;K;6;CP$UIDd;2;27E;D;K;6;CP$UIDd;2;35E;D;K;6;CP$UIDd;2;16E;D;K;6;CP$UIDd;2;23E;D;K;6;CP$UIDd;2;25E;D;K;6;CP$UIDd;2;23E;D;K;6;CP$UIDd;2;32E;D;K;6;CP$UIDd;2;29E;D;K;6;CP$UIDd;2;21E;D;K;6;CP$UIDd;2;29E;D;K;6;CP$UIDd;2;16E;D;K;6;CP$UIDd;2;23E;D;K;6;CP$UIDd;2;23E;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;15E;K;27;_CPCibCustomObjectClassNameD;K;6;CP$UIDd;2;58E;E;D;K;10;$classnameS;5;CPSetK;8;$classesA;S;5;CPSetS;8;CPObjectE;E;D;K;6;$classD;K;6;CP$UIDd;2;17E;K;15;CPSetObjectsKeyD;K;6;CP$UIDd;2;59E;E;D;K;6;$classD;K;6;CP$UIDd;2;15E;K;27;_CPCibCustomObjectClassNameD;K;6;CP$UIDd;2;60E;E;D;K;10;$classnameS;13;CPTableColumnK;8;$classesA;S;13;CPTableColumnS;8;CPObjectE;E;D;K;6;$classD;K;6;CP$UIDd;2;20E;K;26;CPTableColumnIdentifierKeyD;K;6;CP$UIDd;2;61E;K;21;CPTableColumnWidthKeyD;K;6;CP$UIDd;2;62E;K;24;CPTableColumnMinWidthKeyD;K;6;CP$UIDd;2;63E;K;24;CPTableColumnMaxWidthKeyD;K;6;CP$UIDd;2;64E;K;26;CPTableColumnHeaderViewKeyD;K;6;CP$UIDd;2;66E;K;24;CPTableColumnDataViewKeyD;K;6;CP$UIDd;2;68E;K;28;CPTableColumnResizingMaskKeyD;K;6;CP$UIDd;2;69E;K;24;CPTableColumnIsHiddenKeyD;K;6;CP$UIDd;1;0E;K;28;CPSortDescriptorPrototypeKeyD;K;6;CP$UIDd;1;0E;E;D;K;10;$classnameS;12;CPScrollViewK;8;$classesA;S;12;CPScrollViewS;6;CPViewS;11;CPResponderS;8;CPObjectE;E;D;K;6;$classD;K;6;CP$UIDd;2;22E;K;27;CPResponderNextResponderKeyD;K;6;CP$UIDd;2;27E;K;14;CPViewFrameKeyD;K;6;CP$UIDd;2;70E;K;15;CPViewBoundsKeyD;K;6;CP$UIDd;2;71E;K;17;CPViewSubviewsKeyD;K;6;CP$UIDd;2;72E;K;18;CPViewSuperviewKeyD;K;6;CP$UIDd;2;27E;K;22;CPViewAutoresizingMaskD;K;6;CP$UIDd;2;73E;K;19;CPViewThemeStateKeyD;K;6;CP$UIDd;2;74E;K;23;CPScrollViewContentViewD;K;6;CP$UIDd;2;76E;K;29;CPScrollViewHeaderClipViewKeyD;K;6;CP$UIDd;2;77E;K;21;CPScrollViewVScrollerD;K;6;CP$UIDd;2;34E;K;21;CPScrollViewHScrollerD;K;6;CP$UIDd;2;31E;K;23;CPScrollViewVLineScrollD;K;6;CP$UIDd;2;63E;K;23;CPScrollViewVPageScrollD;K;6;CP$UIDd;2;63E;K;23;CPScrollViewHLineScrollD;K;6;CP$UIDd;2;63E;K;23;CPScrollViewHPageScrollD;K;6;CP$UIDd;2;63E;K;24;CPScrollViewHasVScrollerD;K;6;CP$UIDd;2;78E;K;24;CPScrollViewHasHScrollerD;K;6;CP$UIDd;2;78E;K;29;CPScrollViewAutohidesScrollerD;K;6;CP$UIDd;2;78E;K;25;CPScrollViewCornerViewKeyD;K;6;CP$UIDd;2;80E;E;D;K;10;$classnameS;20;_CPCibWindowTemplateK;8;$classesA;S;20;_CPCibWindowTemplateS;8;CPObjectE;E;D;K;6;$classD;K;6;CP$UIDd;2;24E;K;30;_CPCibWindowTemplateMaxSizeKeyD;K;6;CP$UIDd;2;81E;K;32;_CPCibWindowTemplateViewClassKeyD;K;6;CP$UIDd;1;0E;K;34;_CPCibWindowTemplateWindowClassKeyD;K;6;CP$UIDd;2;82E;K;33;_CPCibWindowTemplateWindowRectKeyD;K;6;CP$UIDd;2;83E;K;30;_CPCibWindowTempatStyleMaskKeyD;K;6;CP$UIDd;2;84E;K;34;_CPCibWindowTemplateWindowTitleKeyD;K;6;CP$UIDd;2;85E;K;33;_CPCibWindowTemplateWindowViewKeyD;K;6;CP$UIDd;2;27E;E;D;K;10;$classnameS;6;CPViewK;8;$classesA;S;6;CPViewS;11;CPResponderS;8;CPObjectE;E;D;K;6;$classD;K;6;CP$UIDd;2;26E;K;14;CPViewFrameKeyD;K;6;CP$UIDd;2;86E;K;15;CPViewBoundsKeyD;K;6;CP$UIDd;2;86E;K;17;CPViewSubviewsKeyD;K;6;CP$UIDd;2;87E;K;19;CPViewThemeStateKeyD;K;6;CP$UIDd;2;74E;E;D;K;10;$classnameS;11;CPTableViewK;8;$classesA;S;11;CPTableViewS;9;CPControlS;6;CPViewS;11;CPResponderS;8;CPObjectE;E;D;K;6;$classD;K;6;CP$UIDd;2;28E;K;27;CPResponderNextResponderKeyD;K;6;CP$UIDd;2;76E;K;14;CPViewFrameKeyD;K;6;CP$UIDd;2;88E;K;15;CPViewBoundsKeyD;K;6;CP$UIDd;2;88E;K;18;CPViewSuperviewKeyD;K;6;CP$UIDd;2;76E;K;19;CPViewThemeStateKeyD;K;6;CP$UIDd;2;74E;K;24;CPControlSendActionOnKeyD;K;6;CP$UIDd;2;89E;K;24;CPTableViewDataSourceKeyD;K;6;CP$UIDd;1;0E;K;22;CPTableViewDelegateKeyD;K;6;CP$UIDd;1;0E;K;23;CPTableViewRowHeightKeyD;K;6;CP$UIDd;2;90E;K;30;CPTableViewIntercellSpacingKeyD;K;6;CP$UIDd;2;91E;K;31;CPTableViewMultipleSelectionKeyD;K;6;CP$UIDd;2;92E;K;28;CPTableViewEmptySelectionKeyD;K;6;CP$UIDd;2;78E;K;30;CPTableViewColumnReorderingKeyD;K;6;CP$UIDd;2;78E;K;28;CPTableViewColumnResizingKeyD;K;6;CP$UIDd;2;78E;K;29;CPTableViewColumnSelectionKeyD;K;6;CP$UIDd;2;78E;K;26;CPTableViewTableColumnsKeyD;K;6;CP$UIDd;2;93E;K;23;CPTableViewGridColorKeyD;K;6;CP$UIDd;2;95E;K;27;CPTableViewGridStyleMaskKeyD;K;6;CP$UIDd;2;96E;K;39;CPTableViewUsesAlternatingBackgroundKeyD;K;6;CP$UIDd;2;78E;K;34;CPTableViewAlternatingRowColorsKeyD;K;6;CP$UIDd;2;97E;K;24;CPTableViewCornerViewKeyD;K;6;CP$UIDd;2;80E;K;24;CPTableViewHeaderViewKeyD;K;6;CP$UIDd;2;37E;E;D;K;10;$classnameS;10;CPScrollerK;8;$classesA;S;10;CPScrollerS;9;CPControlS;6;CPViewS;11;CPResponderS;8;CPObjectE;E;D;K;6;$classD;K;6;CP$UIDd;2;30E;K;27;CPResponderNextResponderKeyD;K;6;CP$UIDd;2;23E;K;14;CPViewFrameKeyD;K;6;CP$UIDd;2;98E;K;15;CPViewBoundsKeyD;K;6;CP$UIDd;2;99E;K;18;CPViewSuperviewKeyD;K;6;CP$UIDd;2;23E;K;22;CPViewAutoresizingMaskD;K;6;CP$UIDd;3;100E;K;19;CPViewThemeStateKeyD;K;6;CP$UIDd;3;101E;K;17;CPControlValueKeyD;K;6;CP$UIDd;3;102E;K;18;CPControlTargetKeyD;K;6;CP$UIDd;2;23E;K;18;CPControlActionKeyD;K;6;CP$UIDd;3;103E;K;24;CPControlSendActionOnKeyD;K;6;CP$UIDd;2;89E;K;21;CPScrollerControlSizeD;K;6;CP$UIDd;3;104E;K;24;CPScrollerKnobProportionD;K;6;CP$UIDd;3;105E;E;D;K;6;$classD;K;6;CP$UIDd;2;20E;K;26;CPTableColumnIdentifierKeyD;K;6;CP$UIDd;3;106E;K;21;CPTableColumnWidthKeyD;K;6;CP$UIDd;3;107E;K;24;CPTableColumnMinWidthKeyD;K;6;CP$UIDd;3;108E;K;24;CPTableColumnMaxWidthKeyD;K;6;CP$UIDd;3;109E;K;26;CPTableColumnHeaderViewKeyD;K;6;CP$UIDd;3;110E;K;24;CPTableColumnDataViewKeyD;K;6;CP$UIDd;3;111E;K;28;CPTableColumnResizingMaskKeyD;K;6;CP$UIDd;2;69E;K;24;CPTableColumnIsHiddenKeyD;K;6;CP$UIDd;1;0E;K;28;CPSortDescriptorPrototypeKeyD;K;6;CP$UIDd;1;0E;E;D;K;6;$classD;K;6;CP$UIDd;2;15E;K;27;_CPCibCustomObjectClassNameD;K;6;CP$UIDd;2;58E;E;D;K;6;$classD;K;6;CP$UIDd;2;30E;K;27;CPResponderNextResponderKeyD;K;6;CP$UIDd;2;23E;K;14;CPViewFrameKeyD;K;6;CP$UIDd;3;112E;K;15;CPViewBoundsKeyD;K;6;CP$UIDd;3;113E;K;18;CPViewSuperviewKeyD;K;6;CP$UIDd;2;23E;K;22;CPViewAutoresizingMaskD;K;6;CP$UIDd;3;100E;K;19;CPViewThemeStateKeyD;K;6;CP$UIDd;3;114E;K;17;CPControlValueKeyD;K;6;CP$UIDd;3;104E;K;18;CPControlTargetKeyD;K;6;CP$UIDd;2;23E;K;18;CPControlActionKeyD;K;6;CP$UIDd;3;115E;K;24;CPControlSendActionOnKeyD;K;6;CP$UIDd;2;89E;K;21;CPScrollerControlSizeD;K;6;CP$UIDd;3;104E;K;24;CPScrollerKnobProportionD;K;6;CP$UIDd;3;116E;E;D;K;6;$classD;K;6;CP$UIDd;2;20E;K;26;CPTableColumnIdentifierKeyD;K;6;CP$UIDd;3;117E;K;21;CPTableColumnWidthKeyD;K;6;CP$UIDd;3;118E;K;24;CPTableColumnMinWidthKeyD;K;6;CP$UIDd;3;108E;K;24;CPTableColumnMaxWidthKeyD;K;6;CP$UIDd;3;109E;K;26;CPTableColumnHeaderViewKeyD;K;6;CP$UIDd;3;119E;K;24;CPTableColumnDataViewKeyD;K;6;CP$UIDd;3;120E;K;28;CPTableColumnResizingMaskKeyD;K;6;CP$UIDd;2;69E;K;24;CPTableColumnIsHiddenKeyD;K;6;CP$UIDd;1;0E;K;28;CPSortDescriptorPrototypeKeyD;K;6;CP$UIDd;1;0E;E;D;K;10;$classnameS;17;CPTableHeaderViewK;8;$classesA;S;17;CPTableHeaderViewS;6;CPViewS;11;CPResponderS;8;CPObjectE;E;D;K;6;$classD;K;6;CP$UIDd;2;36E;K;27;CPResponderNextResponderKeyD;K;6;CP$UIDd;2;77E;K;14;CPViewFrameKeyD;K;6;CP$UIDd;3;121E;K;15;CPViewBoundsKeyD;K;6;CP$UIDd;3;121E;K;18;CPViewSuperviewKeyD;K;6;CP$UIDd;2;77E;K;19;CPViewThemeStateKeyD;K;6;CP$UIDd;2;74E;K;29;CPTableHeaderViewTableViewKeyD;K;6;CP$UIDd;2;29E;E;S;14;App ControllerS;12;File's OwnerS;16;Table Column (3)S;33;Bordered Scroll View (Table View)S;15;Window (Window)S;12;Content ViewS;29;Table View (Column 1, Two, 3)S;19;Horizontal ScrollerS;29;Text Field Cell (Text Cell)-2S;29;Text Field Cell (Text Cell)-1S;16;Table Column (1)S;27;Text Field Cell (Text Cell)S;11;ApplicationS;17;Vertical ScrollerS;16;Table Column (2)S;17;Table Header ViewD;K;10;$classnameS;20;CPCibOutletConnectorK;8;$classesA;S;20;CPCibOutletConnectorS;14;CPCibConnectorS;8;CPObjectE;E;D;K;6;$classD;K;6;CP$UIDd;2;54E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;2;16E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;2;19E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;122E;E;D;K;6;$classD;K;6;CP$UIDd;2;54E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;2;19E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;2;25E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;123E;E;D;K;6;$classD;K;6;CP$UIDd;2;54E;K;24;_CPCibConnectorSourceKeyD;K;6;CP$UIDd;2;29E;K;29;_CPCibConnectorDestinationKeyD;K;6;CP$UIDd;2;19E;K;23;_CPCibConnectorLabelKeyD;K;6;CP$UIDd;3;124E;E;S;13;CPApplicationD;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;2;25E;E;E;S;13;AppControllerS;1;3d;3;188d;2;10d;22;3.4028234663852886e+38D;K;10;$classnameS;24;_CPTableColumnHeaderViewK;8;$classesA;S;24;_CPTableColumnHeaderViewS;6;CPViewS;11;CPResponderS;8;CPObjectE;E;D;K;6;$classD;K;6;CP$UIDd;2;65E;K;14;CPViewFrameKeyD;K;6;CP$UIDd;3;125E;K;15;CPViewBoundsKeyD;K;6;CP$UIDd;3;125E;K;17;CPViewSubviewsKeyD;K;6;CP$UIDd;3;126E;K;19;CPViewThemeStateKeyD;K;6;CP$UIDd;2;74E;K;38;_CPTableColumnHeaderViewStringValueKeyD;K;6;CP$UIDd;2;61E;K;32;_CPTableColumnHeaderViewImageKeyD;K;6;CP$UIDd;1;0E;K;31;_CPTableColumnHeaderViewFontKeyD;K;6;CP$UIDd;3;128E;E;D;K;10;$classnameS;11;CPTextFieldK;8;$classesA;S;11;CPTextFieldS;9;CPControlS;6;CPViewS;11;CPResponderS;8;CPObjectE;E;D;K;6;$classD;K;6;CP$UIDd;2;67E;K;14;CPViewFrameKeyD;K;6;CP$UIDd;3;125E;K;15;CPViewBoundsKeyD;K;6;CP$UIDd;3;125E;K;19;CPViewThemeStateKeyD;K;6;CP$UIDd;3;129E;K;6;$afontD;K;6;CP$UIDd;3;131E;K;12;$atext-colorD;K;6;CP$UIDd;3;132E;K;17;$aline-break-modeD;K;6;CP$UIDd;2;89E;K;20;$avertical-alignmentD;K;6;CP$UIDd;2;69E;K;11;$aalignmentD;K;6;CP$UIDd;3;104E;K;15;$acontent-insetD;K;6;CP$UIDd;3;134E;K;17;CPControlValueKeyD;K;6;CP$UIDd;3;135E;K;24;CPControlSendActionOnKeyD;K;6;CP$UIDd;3;136E;K;24;CPTextFieldIsEditableKeyD;K;6;CP$UIDd;1;0E;K;26;CPTextFieldIsSelectableKeyD;K;6;CP$UIDd;1;0E;K;29;CPTextFieldDrawsBackgroundKeyD;K;6;CP$UIDd;1;0E;K;29;CPTextFieldBackgroundColorKeyD;K;6;CP$UIDd;1;0E;K;31;CPTextFieldPlaceholderStringKeyD;K;6;CP$UIDd;3;135E;E;d;1;2S;22;{{20, 20}, {518, 308}}S;20;{{0, 0}, {518, 308}}D;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;2;76E;D;K;6;CP$UIDd;2;34E;D;K;6;CP$UIDd;2;31E;D;K;6;CP$UIDd;2;77E;D;K;6;CP$UIDd;2;80E;E;E;d;2;36S;6;normalD;K;10;$classnameS;10;CPClipViewK;8;$classesA;S;10;CPClipViewS;6;CPViewS;11;CPResponderS;8;CPObjectE;E;D;K;6;$classD;K;6;CP$UIDd;2;75E;K;27;CPResponderNextResponderKeyD;K;6;CP$UIDd;2;23E;K;14;CPViewFrameKeyD;K;6;CP$UIDd;3;137E;K;15;CPViewBoundsKeyD;K;6;CP$UIDd;2;88E;K;17;CPViewSubviewsKeyD;K;6;CP$UIDd;3;138E;K;18;CPViewSuperviewKeyD;K;6;CP$UIDd;2;23E;K;22;CPViewAutoresizingMaskD;K;6;CP$UIDd;3;100E;K;21;CPViewBackgroundColorD;K;6;CP$UIDd;3;139E;K;19;CPViewThemeStateKeyD;K;6;CP$UIDd;2;74E;K;24;CPScrollViewDocumentViewD;K;6;CP$UIDd;2;29E;E;D;K;6;$classD;K;6;CP$UIDd;2;75E;K;27;CPResponderNextResponderKeyD;K;6;CP$UIDd;2;23E;K;14;CPViewFrameKeyD;K;6;CP$UIDd;3;140E;K;15;CPViewBoundsKeyD;K;6;CP$UIDd;3;141E;K;17;CPViewSubviewsKeyD;K;6;CP$UIDd;3;142E;K;18;CPViewSuperviewKeyD;K;6;CP$UIDd;2;23E;K;22;CPViewAutoresizingMaskD;K;6;CP$UIDd;3;100E;K;21;CPViewBackgroundColorD;K;6;CP$UIDd;3;139E;K;19;CPViewThemeStateKeyD;K;6;CP$UIDd;2;74E;K;24;CPScrollViewDocumentViewD;K;6;CP$UIDd;2;37E;E;T;D;K;10;$classnameS;13;_CPCornerViewK;8;$classesA;S;13;_CPCornerViewS;6;CPViewS;11;CPResponderS;8;CPObjectE;E;D;K;6;$classD;K;6;CP$UIDd;2;79E;K;27;CPResponderNextResponderKeyD;K;6;CP$UIDd;2;23E;K;14;CPViewFrameKeyD;K;6;CP$UIDd;3;143E;K;15;CPViewBoundsKeyD;K;6;CP$UIDd;3;144E;K;18;CPViewSuperviewKeyD;K;6;CP$UIDd;2;23E;K;22;CPViewAutoresizingMaskD;K;6;CP$UIDd;3;100E;K;19;CPViewThemeStateKeyD;K;6;CP$UIDd;2;74E;E;S;28;{1.79769e+308, 1.79769e+308}S;8;CPWindowS;24;{{335, 128}, {558, 348}}d;1;7S;6;WindowS;20;{{0, 0}, {558, 348}}D;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;2;23E;E;E;S;20;{{0, 0}, {516, 290}}d;1;4d;2;23S;6;{0, 0}F;D;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;2;32E;D;K;6;CP$UIDd;2;35E;D;K;6;CP$UIDd;2;21E;E;E;D;K;10;$classnameS;7;CPColorK;8;$classesA;S;7;CPColorS;8;CPObjectE;E;D;K;6;$classD;K;6;CP$UIDd;2;94E;K;20;CPColorComponentsKeyD;K;6;CP$UIDd;3;145E;E;d;1;3D;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;3;139E;D;K;6;CP$UIDd;3;146E;E;E;S;19;{{1, 1}, {516, 15}}S;19;{{0, 0}, {516, 15}}d;1;8S;8;disabledd;1;1S;29;_horizontalScrollerDidScroll:d;1;0f;18;0.9866156787762906S;1;1d;3;101d;2;40d;4;1000D;K;6;$classD;K;6;CP$UIDd;2;65E;K;14;CPViewFrameKeyD;K;6;CP$UIDd;3;125E;K;15;CPViewBoundsKeyD;K;6;CP$UIDd;3;125E;K;17;CPViewSubviewsKeyD;K;6;CP$UIDd;3;147E;K;19;CPViewThemeStateKeyD;K;6;CP$UIDd;2;74E;K;38;_CPTableColumnHeaderViewStringValueKeyD;K;6;CP$UIDd;3;148E;K;32;_CPTableColumnHeaderViewImageKeyD;K;6;CP$UIDd;1;0E;K;31;_CPTableColumnHeaderViewFontKeyD;K;6;CP$UIDd;3;128E;E;D;K;6;$classD;K;6;CP$UIDd;2;67E;K;14;CPViewFrameKeyD;K;6;CP$UIDd;3;125E;K;15;CPViewBoundsKeyD;K;6;CP$UIDd;3;125E;K;19;CPViewThemeStateKeyD;K;6;CP$UIDd;3;129E;K;6;$afontD;K;6;CP$UIDd;3;149E;K;12;$atext-colorD;K;6;CP$UIDd;3;150E;K;17;$aline-break-modeD;K;6;CP$UIDd;2;89E;K;20;$avertical-alignmentD;K;6;CP$UIDd;2;69E;K;11;$aalignmentD;K;6;CP$UIDd;3;104E;K;15;$acontent-insetD;K;6;CP$UIDd;3;151E;K;17;CPControlValueKeyD;K;6;CP$UIDd;3;135E;K;24;CPControlSendActionOnKeyD;K;6;CP$UIDd;3;136E;K;24;CPTextFieldIsEditableKeyD;K;6;CP$UIDd;1;0E;K;26;CPTextFieldIsSelectableKeyD;K;6;CP$UIDd;1;0E;K;29;CPTextFieldDrawsBackgroundKeyD;K;6;CP$UIDd;1;0E;K;29;CPTextFieldBackgroundColorKeyD;K;6;CP$UIDd;1;0E;K;31;CPTextFieldPlaceholderStringKeyD;K;6;CP$UIDd;3;135E;E;S;22;{{502, 16}, {15, 275}}S;19;{{0, 0}, {15, 275}}S;17;disabled+verticalS;27;_verticalScrollerDidScroll:f;18;0.9482758620689655S;1;2d;3;154D;K;6;$classD;K;6;CP$UIDd;2;65E;K;14;CPViewFrameKeyD;K;6;CP$UIDd;3;125E;K;15;CPViewBoundsKeyD;K;6;CP$UIDd;3;125E;K;17;CPViewSubviewsKeyD;K;6;CP$UIDd;3;152E;K;19;CPViewThemeStateKeyD;K;6;CP$UIDd;2;74E;K;38;_CPTableColumnHeaderViewStringValueKeyD;K;6;CP$UIDd;3;153E;K;32;_CPTableColumnHeaderViewImageKeyD;K;6;CP$UIDd;1;0E;K;31;_CPTableColumnHeaderViewFontKeyD;K;6;CP$UIDd;3;128E;E;D;K;6;$classD;K;6;CP$UIDd;2;67E;K;14;CPViewFrameKeyD;K;6;CP$UIDd;3;125E;K;15;CPViewBoundsKeyD;K;6;CP$UIDd;3;125E;K;19;CPViewThemeStateKeyD;K;6;CP$UIDd;3;129E;K;6;$afontD;K;6;CP$UIDd;3;154E;K;12;$atext-colorD;K;6;CP$UIDd;3;155E;K;17;$aline-break-modeD;K;6;CP$UIDd;2;89E;K;20;$avertical-alignmentD;K;6;CP$UIDd;2;69E;K;11;$aalignmentD;K;6;CP$UIDd;3;104E;K;15;$acontent-insetD;K;6;CP$UIDd;3;156E;K;17;CPControlValueKeyD;K;6;CP$UIDd;3;135E;K;24;CPControlSendActionOnKeyD;K;6;CP$UIDd;3;136E;K;24;CPTextFieldIsEditableKeyD;K;6;CP$UIDd;1;0E;K;26;CPTextFieldIsSelectableKeyD;K;6;CP$UIDd;1;0E;K;29;CPTextFieldDrawsBackgroundKeyD;K;6;CP$UIDd;1;0E;K;29;CPTextFieldBackgroundColorKeyD;K;6;CP$UIDd;1;0E;K;31;CPTextFieldPlaceholderStringKeyD;K;6;CP$UIDd;3;135E;E;S;19;{{0, 0}, {516, 23}}S;8;delegateS;9;theWindowS;10;dataSourceS;16;{{0, 0}, {0, 0}}D;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;3;158E;E;E;D;K;10;$classnameS;6;CPFontK;8;$classesA;S;6;CPFontS;8;CPObjectE;E;D;K;6;$classD;K;6;CP$UIDd;3;127E;K;13;CPFontNameKeyD;K;6;CP$UIDd;3;159E;K;13;CPFontSizeKeyD;K;6;CP$UIDd;3;160E;K;15;CPFontIsBoldKeyD;K;6;CP$UIDd;2;78E;E;S;11;placeholderD;K;10;$classnameS;17;_CPThemeAttributeK;8;$classesA;S;17;_CPThemeAttributeS;8;CPObjectE;E;D;K;6;$classD;K;6;CP$UIDd;3;130E;K;4;nameD;K;6;CP$UIDd;3;161E;K;5;stateD;K;6;CP$UIDd;3;162E;K;5;valueD;K;6;CP$UIDd;3;128E;E;D;K;6;$classD;K;6;CP$UIDd;3;130E;K;4;nameD;K;6;CP$UIDd;3;163E;K;6;valuesD;K;6;CP$UIDd;3;165E;E;D;K;10;$classnameS;21;_CPKeyedArchiverValueK;8;$classesA;S;21;_CPKeyedArchiverValueS;7;CPValueS;8;CPObjectE;E;D;K;6;$classD;K;6;CP$UIDd;3;133E;K;15;CPValueValueKeyD;K;6;CP$UIDd;3;166E;E;S;0;d;4;3072S;20;{{1, 1}, {516, 290}}D;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;2;29E;E;E;D;K;6;$classD;K;6;CP$UIDd;2;94E;K;20;CPColorComponentsKeyD;K;6;CP$UIDd;3;167E;E;S;21;{{1, 291}, {516, 17}}S;19;{{0, 0}, {516, 17}}D;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;2;37E;E;E;S;22;{{502, 285}, {16, 23}}S;18;{{0, 0}, {16, 23}}D;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;3;168E;D;K;6;CP$UIDd;3;168E;D;K;6;CP$UIDd;3;168E;D;K;6;CP$UIDd;3;102E;E;E;D;K;6;$classD;K;6;CP$UIDd;2;94E;K;20;CPColorComponentsKeyD;K;6;CP$UIDd;3;169E;E;D;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;3;170E;E;E;S;8;Column 1D;K;6;$classD;K;6;CP$UIDd;3;130E;K;4;nameD;K;6;CP$UIDd;3;161E;K;5;stateD;K;6;CP$UIDd;3;162E;K;5;valueD;K;6;CP$UIDd;3;128E;E;D;K;6;$classD;K;6;CP$UIDd;3;130E;K;4;nameD;K;6;CP$UIDd;3;163E;K;6;valuesD;K;6;CP$UIDd;3;171E;E;D;K;6;$classD;K;6;CP$UIDd;3;133E;K;15;CPValueValueKeyD;K;6;CP$UIDd;3;166E;E;D;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;3;172E;E;E;S;3;TwoD;K;6;$classD;K;6;CP$UIDd;3;130E;K;4;nameD;K;6;CP$UIDd;3;161E;K;5;stateD;K;6;CP$UIDd;3;162E;K;5;valueD;K;6;CP$UIDd;3;128E;E;D;K;6;$classD;K;6;CP$UIDd;3;130E;K;4;nameD;K;6;CP$UIDd;3;163E;K;6;valuesD;K;6;CP$UIDd;3;173E;E;D;K;6;$classD;K;6;CP$UIDd;3;133E;K;15;CPValueValueKeyD;K;6;CP$UIDd;3;166E;E;D;K;10;$classnameS;19;_CPImageAndTextViewK;8;$classesA;S;19;_CPImageAndTextViewS;6;CPViewS;11;CPResponderS;8;CPObjectE;E;D;K;6;$classD;K;6;CP$UIDd;3;157E;K;27;CPResponderNextResponderKeyD;K;6;CP$UIDd;2;66E;K;14;CPViewFrameKeyD;K;6;CP$UIDd;3;174E;K;15;CPViewBoundsKeyD;K;6;CP$UIDd;3;175E;K;18;CPViewSuperviewKeyD;K;6;CP$UIDd;2;66E;K;22;CPViewAutoresizingMaskD;K;6;CP$UIDd;3;176E;K;19;CPViewThemeStateKeyD;K;6;CP$UIDd;2;74E;E;S;17;Arial, sans-serifd;2;12S;4;fontS;16;selectedDataViewS;10;text-colorD;K;10;$classnameS;19;CPMutableDictionaryK;8;$classesA;S;19;CPMutableDictionaryS;12;CPDictionaryS;8;CPObjectE;E;D;K;6;$classD;K;6;CP$UIDd;3;164E;K;10;CP.objectsD;K;16;selectedDataViewD;K;6;CP$UIDd;3;139E;K;6;normalD;K;6;CP$UIDd;3;177E;E;E;S;39;{"top":0,"right":0,"bottom":0,"left":5}D;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;3;102E;D;K;6;CP$UIDd;3;102E;D;K;6;CP$UIDd;3;102E;D;K;6;CP$UIDd;3;102E;E;E;f;18;0.8980392156862745D;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;3;178E;D;K;6;CP$UIDd;3;179E;D;K;6;CP$UIDd;3;180E;D;K;6;CP$UIDd;3;102E;E;E;D;K;6;$classD;K;6;CP$UIDd;3;157E;K;27;CPResponderNextResponderKeyD;K;6;CP$UIDd;3;110E;K;14;CPViewFrameKeyD;K;6;CP$UIDd;3;174E;K;15;CPViewBoundsKeyD;K;6;CP$UIDd;3;175E;K;18;CPViewSuperviewKeyD;K;6;CP$UIDd;3;110E;K;22;CPViewAutoresizingMaskD;K;6;CP$UIDd;3;176E;K;19;CPViewThemeStateKeyD;K;6;CP$UIDd;2;74E;E;D;K;6;$classD;K;6;CP$UIDd;3;164E;K;10;CP.objectsD;K;16;selectedDataViewD;K;6;CP$UIDd;3;139E;K;6;normalD;K;6;CP$UIDd;3;181E;E;E;D;K;6;$classD;K;6;CP$UIDd;3;157E;K;27;CPResponderNextResponderKeyD;K;6;CP$UIDd;3;119E;K;14;CPViewFrameKeyD;K;6;CP$UIDd;3;174E;K;15;CPViewBoundsKeyD;K;6;CP$UIDd;3;175E;K;18;CPViewSuperviewKeyD;K;6;CP$UIDd;3;119E;K;22;CPViewAutoresizingMaskD;K;6;CP$UIDd;3;176E;K;19;CPViewThemeStateKeyD;K;6;CP$UIDd;2;74E;E;D;K;6;$classD;K;6;CP$UIDd;3;164E;K;10;CP.objectsD;K;16;selectedDataViewD;K;6;CP$UIDd;3;139E;K;6;normalD;K;6;CP$UIDd;3;182E;E;E;S;18;{{5, 0}, {-10, 0}}S;18;{{0, 0}, {-10, 0}}d;2;18D;K;6;$classD;K;6;CP$UIDd;2;94E;K;20;CPColorComponentsKeyD;K;6;CP$UIDd;3;183E;E;f;18;0.9607843137254902f;18;0.9764705882352941f;18;0.9882352941176471D;K;6;$classD;K;6;CP$UIDd;2;94E;K;20;CPColorComponentsKeyD;K;6;CP$UIDd;3;184E;E;D;K;6;$classD;K;6;CP$UIDd;2;94E;K;20;CPColorComponentsKeyD;K;6;CP$UIDd;3;185E;E;D;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;3;186E;D;K;6;CP$UIDd;3;186E;D;K;6;CP$UIDd;3;186E;D;K;6;CP$UIDd;3;102E;E;E;D;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;3;186E;D;K;6;CP$UIDd;3;186E;D;K;6;CP$UIDd;3;186E;D;K;6;CP$UIDd;3;102E;E;E;D;K;6;$classD;K;6;CP$UIDd;1;3E;K;10;CP.objectsA;D;K;6;CP$UIDd;3;186E;D;K;6;CP$UIDd;3;186E;D;K;6;CP$UIDd;3;186E;D;K;6;CP$UIDd;3;102E;E;E;f;3;0.2E;K;9;$archiverS;15;CPKeyedArchiverK;8;$versionS;6;100000E;
\ No newline at end of file
diff --git a/Tests/Manual/TableCibTest/Resources/MainMenu.xib b/Tests/Manual/TableCibTest/Resources/MainMenu.xib
index 01d7aae19..42934a3ea 100644
--- a/Tests/Manual/TableCibTest/Resources/MainMenu.xib
+++ b/Tests/Manual/TableCibTest/Resources/MainMenu.xib
@@ -2,17 +2,17 @@
1050
- 10C540
- 740
- 1038.25
- 458.00
+ 10D573
+ 759
+ 1038.29
+ 460.00
23
- -694157312
+ -157286400
+ 3
4
15
0
@@ -531,6 +532,7 @@
0
+ IBCocoaFramework