Merge branch 'master' of git://github.com/280north/cappuccino into bindings-merge
Conflicts: AppKit/CPTableView.j Foundation/CPArray+KVO.j Foundation/CPArray.j
No files matched your search
@@ -30,7 +30,12 @@
|
||||
|
||||
#import "CoreGraphics/CGGeometry.h"
|
||||
|
||||
|
||||
/*!
|
||||
@ingroup appkit
|
||||
@class CPAccordionViewItem
|
||||
|
||||
<p>A CPAccordionViewItem represents a single section of a CPAccordionView.</p>
|
||||
*/
|
||||
@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
|
||||
|
||||
<p>CPAccordionView provides a container for CPAccordionViewItem objects and manages layout state
|
||||
for all sublayout items.</p>
|
||||
|
||||
<strong>Example</strong><br />
|
||||
<pre>
|
||||
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];
|
||||
</pre>
|
||||
*/
|
||||
@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];
|
||||
|
||||
@@ -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:
|
||||
|
||||
|
||||
<pre>
|
||||
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<count; i++)
|
||||
toEncode[i] = encodeURIComponent(toEncode[i]);
|
||||
|
||||
|
||||
var hash = [toEncode componentsJoinedByString:@"/"];
|
||||
|
||||
|
||||
window.location.hash = @"#" + hash;
|
||||
}
|
||||
|
||||
- (void)_reloadArguments
|
||||
{
|
||||
_fullArgsString = window.location.hash;
|
||||
|
||||
|
||||
if (_fullArgsString.length)
|
||||
{
|
||||
var args = _fullArgsString.substring(1).split("/");
|
||||
@@ -1006,18 +951,18 @@ CPRunContinuesResponse = -1002;
|
||||
|
||||
- (void)_willBecomeActive
|
||||
{
|
||||
[[CPNotificationCenter defaultCenter] postNotificationName:CPApplicationWillBecomeActiveNotification
|
||||
object:self
|
||||
[[CPNotificationCenter defaultCenter] postNotificationName:CPApplicationWillBecomeActiveNotification
|
||||
object:self
|
||||
userInfo:nil];
|
||||
}
|
||||
|
||||
- (void)_didBecomeActive
|
||||
{
|
||||
if (![self keyWindow] && _previousKeyWindow &&
|
||||
if (![self keyWindow] && _previousKeyWindow &&
|
||||
[[self windows] indexOfObjectIdenticalTo:_previousKeyWindow] !== CPNotFound)
|
||||
[_previousKeyWindow makeKeyWindow];
|
||||
|
||||
if (![self mainWindow] && _previousMainWindow &&
|
||||
if (![self mainWindow] && _previousMainWindow &&
|
||||
[[self windows] indexOfObjectIdenticalTo:_previousMainWindow] !== CPNotFound)
|
||||
[_previousMainWindow makeMainWindow];
|
||||
|
||||
@@ -1031,15 +976,15 @@ CPRunContinuesResponse = -1002;
|
||||
_previousKeyWindow = nil;
|
||||
_previousMainWindow = nil;
|
||||
|
||||
[[CPNotificationCenter defaultCenter] postNotificationName:CPApplicationDidBecomeActiveNotification
|
||||
object:self
|
||||
[[CPNotificationCenter defaultCenter] postNotificationName:CPApplicationDidBecomeActiveNotification
|
||||
object:self
|
||||
userInfo:nil];
|
||||
}
|
||||
|
||||
- (void)_willResignActive
|
||||
{
|
||||
[[CPNotificationCenter defaultCenter] postNotificationName:CPApplicationWillResignActiveNotification
|
||||
object:self
|
||||
[[CPNotificationCenter defaultCenter] postNotificationName:CPApplicationWillResignActiveNotification
|
||||
object:self
|
||||
userInfo:nil];
|
||||
}
|
||||
|
||||
@@ -1060,8 +1005,8 @@ CPRunContinuesResponse = -1002;
|
||||
[_previousMainWindow resignMainWindow];
|
||||
}
|
||||
|
||||
[[CPNotificationCenter defaultCenter] postNotificationName:CPApplicationDidResignActiveNotification
|
||||
object:self
|
||||
[[CPNotificationCenter defaultCenter] postNotificationName:CPApplicationDidResignActiveNotification
|
||||
object:self
|
||||
userInfo:nil];
|
||||
}
|
||||
|
||||
@@ -1089,7 +1034,7 @@ var _CPRunModalLoop = function(anEvent)
|
||||
|
||||
var theWindow = [anEvent window],
|
||||
modalSession = CPApp._currentSession;
|
||||
|
||||
|
||||
if (theWindow == modalSession._window || [theWindow worksWhenModal])
|
||||
[theWindow sendEvent:anEvent];
|
||||
}
|
||||
@@ -1188,10 +1133,73 @@ var _CPAppBootstrapperActions = nil;
|
||||
|
||||
return YES;
|
||||
}
|
||||
else
|
||||
[self loadCiblessBrowserMainMenu];
|
||||
|
||||
return NO;
|
||||
}
|
||||
|
||||
+ (void)loadCiblessBrowserMainMenu
|
||||
{
|
||||
var 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]];
|
||||
|
||||
[CPApp setMainMenu:mainMenu];
|
||||
}
|
||||
|
||||
+ (void)cibDidFinishLoading:(CPCib)aCib
|
||||
{
|
||||
[self performActions];
|
||||
|
||||
@@ -64,14 +64,14 @@
|
||||
|
||||
+ (CPImage)branchImage
|
||||
{
|
||||
return [[CPImage alloc] initWithContentsOfFile:[[CPBundle bundleForClass:[self class]]
|
||||
return [[CPImage alloc] initWithContentsOfFile:[[CPBundle bundleForClass:[CPBrowser class]]
|
||||
pathForResource:"browser-leaf.png"]
|
||||
size:CGSizeMake(9,9)];
|
||||
}
|
||||
|
||||
+ (CPImage)highlightedBranchImage
|
||||
{
|
||||
return [[CPImage alloc] initWithContentsOfFile:[[CPBundle bundleForClass:[self class]]
|
||||
return [[CPImage alloc] initWithContentsOfFile:[[CPBundle bundleForClass:[CPBrowser class]]
|
||||
pathForResource:"browser-leaf-highlighted.png"]
|
||||
size:CGSizeMake(9,9)];
|
||||
}
|
||||
@@ -213,8 +213,6 @@
|
||||
[table setAllowsEmptySelection:_allowsEmptySelection];
|
||||
[table registerForDraggedTypes:[self registeredDraggedTypes]];
|
||||
|
||||
[self setNextResponder:table];
|
||||
|
||||
[self _addTableColumnsToTableView:table forColumnIndex:index];
|
||||
|
||||
var delegate = [[_CPBrowserTableDelegate alloc] init];
|
||||
@@ -314,6 +312,39 @@
|
||||
[_contentView setFrameSize:CGSizeMake(xOrigin, height)];
|
||||
}
|
||||
|
||||
- (unsigned)rowAtPoint:(CGPoint)aPoint
|
||||
{
|
||||
var column = [self columnAtPoint:aPoint];
|
||||
if (column === -1)
|
||||
return -1;
|
||||
|
||||
var tableView = _tableViews[column];
|
||||
return [tableView rowAtPoint:[tableView convertPoint:aPoint fromView:self]];
|
||||
}
|
||||
|
||||
- (unsigned)columnAtPoint:(CGPoint)aPoint
|
||||
{
|
||||
var adjustedPoint = [_contentView convertPoint:aPoint fromView:self];
|
||||
|
||||
for (var i = 0, count = _tableViews.length; i < count; i++)
|
||||
{
|
||||
var frame = [[_tableViews[i] enclosingScrollView] frame];
|
||||
if (CGRectContainsPoint(frame, adjustedPoint))
|
||||
return i;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
- (CGRect)rectOfRow:(unsigned)aRow inColumn:(unsigned)aColumn
|
||||
{
|
||||
var tableView = _tableViews[aColumn],
|
||||
rect = [tableView rectOfRow:aRow];
|
||||
|
||||
rect.origin = [self convertPoint:rect.origin fromView:tableView];
|
||||
return rect;
|
||||
}
|
||||
|
||||
// ITEMS
|
||||
|
||||
- (id)itemAtRow:(int)row inColumn:(int)column
|
||||
@@ -357,6 +388,10 @@
|
||||
|
||||
// CLICK EVENTS
|
||||
|
||||
- (void)trackMouse:(CPEvent)anEvent
|
||||
{
|
||||
}
|
||||
|
||||
- (void)_column:(unsigned)columnIndex clickedRow:(unsigned)rowIndex
|
||||
{
|
||||
[self setLastColumn:columnIndex];
|
||||
@@ -382,6 +417,15 @@
|
||||
[self sendAction:_doubleAction to:_target];
|
||||
}
|
||||
|
||||
- (void)keyDown:(CPEvent)anEvent
|
||||
{
|
||||
var column = [self selectedColumn];
|
||||
if (column === -1)
|
||||
return;
|
||||
|
||||
[_tableViews[column] keyDown:anEvent];
|
||||
}
|
||||
|
||||
// SIZING
|
||||
|
||||
- (float)columnContentWidthForColumnWidth:(float)aWidth
|
||||
@@ -526,6 +570,9 @@
|
||||
|
||||
- (CPIndexSet)selectedRowIndexesInColumn:(unsigned)column
|
||||
{
|
||||
if (column < 0 || column > [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];
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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];
|
||||
|
||||
@@ -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];
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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];
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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]
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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];
|
||||
}
|
||||
|
||||
@@ -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];
|
||||
|
||||
@@ -581,7 +581,7 @@ var CPSearchFieldSearchImage = nil,
|
||||
|
||||
- (void)_sendPartialString
|
||||
{
|
||||
[[self target] performSelector:[self action] withObject:self];
|
||||
[self _sendAction:self];
|
||||
}
|
||||
|
||||
- (void)_searchFieldCancel:(id)sender
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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)
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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];
|
||||
|
||||
@@ -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];
|
||||
|
||||
|
||||
@@ -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] : "";
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* CPFlashView.j
|
||||
* CPViewAnimation.j
|
||||
* AppKit
|
||||
*
|
||||
* Created by Klaas Pieter Annema on September 3, 2009.
|
||||
@@ -22,6 +22,8 @@
|
||||
|
||||
@import <AppKit/CPAnimation.j>
|
||||
|
||||
#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)
|
||||
|
||||
@@ -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:)])
|
||||
|
||||
@@ -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];
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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("<html><head></head><body style = 'background-color:transparent;'></body></html>");
|
||||
_DOMWindow.document.write("<!DOCTYPE html><html lang='en'><head></head><body style='background-color:transparent;'></body></html>");
|
||||
_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);
|
||||
}
|
||||
|
||||
|
||||
|
After Width: | Height: | Size: 506 B |
|
Before Width: | Height: | Size: 141 B After Width: | Height: | Size: 170 B |
|
After Width: | Height: | Size: 170 B |
|
After Width: | Height: | Size: 254 B |
|
After Width: | Height: | Size: 257 B |
|
Before Width: | Height: | Size: 151 B After Width: | Height: | Size: 173 B |
|
Before Width: | Height: | Size: 588 B After Width: | Height: | Size: 256 B |
|
Before Width: | Height: | Size: 566 B After Width: | Height: | Size: 261 B |
|
Before Width: | Height: | Size: 600 B After Width: | Height: | Size: 259 B |
|
Before Width: | Height: | Size: 572 B After Width: | Height: | Size: 260 B |
|
After Width: | Height: | Size: 185 B |
|
After Width: | Height: | Size: 182 B |
|
After Width: | Height: | Size: 261 B |
|
After Width: | Height: | Size: 271 B |
|
After Width: | Height: | Size: 157 B |
|
After Width: | Height: | Size: 248 B |
|
After Width: | Height: | Size: 242 B |
|
After Width: | Height: | Size: 282 B |
|
After Width: | Height: | Size: 278 B |
|
After Width: | Height: | Size: 130 B |
|
After Width: | Height: | Size: 129 B |
|
After Width: | Height: | Size: 182 B |
|
After Width: | Height: | Size: 189 B |
|
After Width: | Height: | Size: 185 B |
|
After Width: | Height: | Size: 193 B |
|
After Width: | Height: | Size: 3.7 KiB |
|
After Width: | Height: | Size: 3.6 KiB |
|
After Width: | Height: | Size: 140 B |
|
After Width: | Height: | Size: 140 B |
|
After Width: | Height: | Size: 124 B |
|
After Width: | Height: | Size: 228 B |
|
After Width: | Height: | Size: 227 B |
|
After Width: | Height: | Size: 124 B |
|
After Width: | Height: | Size: 159 B |
|
After Width: | Height: | Size: 159 B |
|
After Width: | Height: | Size: 124 B |
|
After Width: | Height: | Size: 241 B |
|
After Width: | Height: | Size: 2.9 KiB |
|
After Width: | Height: | Size: 245 B |
|
After Width: | Height: | Size: 124 B |
|
After Width: | Height: | Size: 244 B |
|
After Width: | Height: | Size: 251 B |
|
After Width: | Height: | Size: 226 B |
|
After Width: | Height: | Size: 146 B |
|
After Width: | Height: | Size: 145 B |
|
After Width: | Height: | Size: 226 B |
|
After Width: | Height: | Size: 226 B |
|
After Width: | Height: | Size: 227 B |
|
After Width: | Height: | Size: 227 B |
|
After Width: | Height: | Size: 227 B |
|
After Width: | Height: | Size: 1.5 KiB |
|
After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 199 B |
|
After Width: | Height: | Size: 199 B |
|
After Width: | Height: | Size: 184 B |
|
After Width: | Height: | Size: 126 B |
|
After Width: | Height: | Size: 184 B |
|
After Width: | Height: | Size: 126 B |
|
After Width: | Height: | Size: 211 B |
|
After Width: | Height: | Size: 204 B |
@@ -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)
|
||||
|
||||
@@ -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];
|
||||
|
||||
@@ -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";
|
||||
|
||||
@@ -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);
|
||||
});
|
||||
}
|
||||
@@ -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)
|
||||
|
||||
@@ -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<count; i++)
|
||||
for (; i < count; i++)
|
||||
[theCopy addObject:[self objectAtIndex:i]];
|
||||
|
||||
return theCopy;
|
||||
}
|
||||
|
||||
-(id)_representedObject
|
||||
- (id)_representedObject
|
||||
{
|
||||
if (_access)
|
||||
return _access(_proxyObject, _accessSEL);
|
||||
@@ -167,7 +169,7 @@
|
||||
return [_proxyObject valueForKey:_key];
|
||||
}
|
||||
|
||||
-(void)_setRepresentedObject:(id)anObject
|
||||
- (void)_setRepresentedObject:(id)anObject
|
||||
{
|
||||
if (_set)
|
||||
return _set(_proxyObject, _setSEL, anObject);
|
||||
@@ -224,7 +226,7 @@
|
||||
|
||||
- (id)objectAtIndex:(unsigned)anIndex
|
||||
{
|
||||
if(_objectAtIndex)
|
||||
if (_objectAtIndex)
|
||||
return _objectAtIndex(_proxyObject, _objectAtIndexSEL, anIndex);
|
||||
|
||||
return [[self _representedObject] objectAtIndex:anIndex];
|
||||
@@ -236,7 +238,7 @@
|
||||
return _insert(_proxyObject, _insertSEL, anObject, [self count]);
|
||||
|
||||
var target = [[self _representedObject] copy];
|
||||
|
||||
|
||||
[target addObject:anObject];
|
||||
[self _setRepresentedObject:target];
|
||||
}
|
||||
@@ -256,40 +258,40 @@
|
||||
return _insert(_proxyObject, _insertSEL, anObject, anIndex);
|
||||
|
||||
var target = [[self _representedObject] copy];
|
||||
|
||||
|
||||
[target insertObject:anObject atIndex:anIndex];
|
||||
[self _setRepresentedObject:target];
|
||||
}
|
||||
|
||||
- (void)removeLastObject
|
||||
{
|
||||
if(_remove)
|
||||
return _remove(_proxyObject, _removeSEL, [self count]-1);
|
||||
if (_remove)
|
||||
return _remove(_proxyObject, _removeSEL, [self count] - 1);
|
||||
|
||||
var target = [[self _representedObject] copy];
|
||||
|
||||
|
||||
[target removeLastObject];
|
||||
[self _setRepresentedObject:target];
|
||||
}
|
||||
|
||||
- (void)removeObjectAtIndex:(unsigned)anIndex
|
||||
{
|
||||
if(_remove)
|
||||
return _remove(_proxyObject, _removeSEL, anIndex);
|
||||
if (_remove)
|
||||
return _remove(_proxyObject, _removeSEL, anIndex);
|
||||
|
||||
var target = [[self _representedObject] copy];
|
||||
|
||||
|
||||
[target removeObjectAtIndex:anIndex];
|
||||
[self _setRepresentedObject:target];
|
||||
}
|
||||
|
||||
- (void)replaceObjectAtIndex:(unsigned)anIndex withObject:(id)anObject
|
||||
{
|
||||
if(_replace)
|
||||
if (_replace)
|
||||
return _replace(_proxyObject, _replaceSEL, anIndex, anObject);
|
||||
|
||||
var target = [[self _representedObject] copy];
|
||||
|
||||
|
||||
[target replaceObjectAtIndex:anIndex withObject:anObject];
|
||||
[self _setRepresentedObject:target];
|
||||
}
|
||||
@@ -310,7 +312,7 @@
|
||||
|
||||
if (aKey == "@count")
|
||||
return length;
|
||||
|
||||
|
||||
return nil;
|
||||
}
|
||||
else
|
||||
@@ -318,17 +320,17 @@
|
||||
var newArray = [],
|
||||
enumerator = [self objectEnumerator],
|
||||
object;
|
||||
|
||||
|
||||
while ((object = [enumerator nextObject]) !== nil)
|
||||
{
|
||||
var value = [object valueForKey:aKey];
|
||||
|
||||
|
||||
if (value === nil || value === undefined)
|
||||
value = [CPNull null];
|
||||
|
||||
|
||||
newArray.push(value);
|
||||
}
|
||||
|
||||
|
||||
return newArray;
|
||||
}
|
||||
}
|
||||
@@ -340,23 +342,37 @@
|
||||
var dotIndex = aKeyPath.indexOf("."),
|
||||
operator,
|
||||
parameter;
|
||||
|
||||
|
||||
if (dotIndex !== -1)
|
||||
{
|
||||
operator = aKeyPath.substring(1, dotIndex);
|
||||
parameter = aKeyPath.substring(dotIndex+1);
|
||||
parameter = aKeyPath.substring(dotIndex + 1);
|
||||
}
|
||||
else
|
||||
operator = aKeyPath.substring(1);
|
||||
|
||||
if (kvoOperators[operator])
|
||||
return kvoOperators[operator](self, _cmd, parameter);
|
||||
|
||||
|
||||
return nil;
|
||||
}
|
||||
else
|
||||
{
|
||||
return [super valueForKeyPath:aKeyPath];
|
||||
var newArray = [],
|
||||
enumerator = [self objectEnumerator],
|
||||
object;
|
||||
|
||||
while ((object = [enumerator nextObject]) !== nil)
|
||||
{
|
||||
var value = [object valueForKeyPath:aKeyPath];
|
||||
|
||||
if (value === nil || value === undefined)
|
||||
value = [CPNull null];
|
||||
|
||||
newArray.push(value);
|
||||
}
|
||||
|
||||
return newArray;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -364,7 +380,7 @@
|
||||
{
|
||||
var enumerator = [self objectEnumerator],
|
||||
object;
|
||||
|
||||
|
||||
while (object = [enumerator nextObject])
|
||||
[object setValue:aValue forKey:aKey];
|
||||
}
|
||||
@@ -373,12 +389,11 @@
|
||||
{
|
||||
var enumerator = [self objectEnumerator],
|
||||
object;
|
||||
|
||||
|
||||
while (object = [enumerator nextObject])
|
||||
[object setValue:aValue forKeyPath:aKeyPath];
|
||||
}
|
||||
|
||||
|
||||
@end
|
||||
|
||||
var kvoOperators = [];
|
||||
@@ -395,8 +410,8 @@ kvoOperators["avg"] = function avgOperator(self, _cmd, param)
|
||||
|
||||
if (!length)
|
||||
return 0;
|
||||
|
||||
while(index--)
|
||||
|
||||
while (index--)
|
||||
average += [objects[index] doubleValue];
|
||||
|
||||
return average / length;
|
||||
@@ -445,7 +460,7 @@ kvoOperators["sum"] = function sumOperator(self, _cmd, param)
|
||||
index = [objects count],
|
||||
sum = 0.0;
|
||||
|
||||
while(index--)
|
||||
while (index--)
|
||||
sum += [objects[index] doubleValue];
|
||||
|
||||
return sum;
|
||||
@@ -456,7 +471,7 @@ kvoOperators["sum"] = function sumOperator(self, _cmd, param)
|
||||
- (void)addObserver:(id)anObserver toObjectsAtIndexes:(CPIndexSet)indexes forKeyPath:(CPString)aKeyPath options:(unsigned)options context:(id)context
|
||||
{
|
||||
var index = [indexes firstIndex];
|
||||
|
||||
|
||||
while (index >= 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"];
|
||||
|
||||
@@ -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:
|
||||
<pre>
|
||||
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:
|
||||
<pre>
|
||||
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<count; ++i)
|
||||
if(aPredicate.evaluateWithObject(self[i]))
|
||||
|
||||
for (; i<count; ++i)
|
||||
if (aPredicate.evaluateWithObject(self[i]))
|
||||
array.push(self[i]);
|
||||
|
||||
|
||||
return array;
|
||||
}
|
||||
*/
|
||||
@@ -769,9 +758,9 @@
|
||||
- (CPArray)sortedArrayUsingDescriptors:(CPArray)descriptors
|
||||
{
|
||||
var sorted = [self copy];
|
||||
|
||||
|
||||
[sorted sortUsingDescriptors:descriptors];
|
||||
|
||||
|
||||
return sorted;
|
||||
}
|
||||
|
||||
@@ -794,9 +783,9 @@
|
||||
- (CPArray)sortedArrayUsingFunction:(Function)aFunction context:(id)aContext
|
||||
{
|
||||
var sorted = [self copy];
|
||||
|
||||
|
||||
[sorted sortUsingFunction:aFunction context:aContext];
|
||||
|
||||
|
||||
return sorted;
|
||||
}
|
||||
|
||||
@@ -807,7 +796,7 @@
|
||||
- (CPArray)sortedArrayUsingSelector:(SEL)aSelector
|
||||
{
|
||||
var sorted = [self copy]
|
||||
|
||||
|
||||
[sorted sortUsingSelector:aSelector];
|
||||
|
||||
return sorted;
|
||||
@@ -841,7 +830,7 @@
|
||||
count = [self count],
|
||||
description = '(';
|
||||
|
||||
for(; index < count; ++index)
|
||||
for (; index < count; ++index)
|
||||
{
|
||||
if (index === 0)
|
||||
description += '\n';
|
||||
@@ -873,11 +862,11 @@
|
||||
var index = 0,
|
||||
count = [self count],
|
||||
array = [];
|
||||
|
||||
for(; index < count; ++index)
|
||||
|
||||
for (; index < count; ++index)
|
||||
if (self[index].isa && [self[index] isKindOfClass:[CPString class]] && [filterTypes containsObject:[self[index] pathExtension]])
|
||||
array.push(self[index]);
|
||||
|
||||
|
||||
return array;
|
||||
}
|
||||
|
||||
@@ -891,8 +880,8 @@
|
||||
{
|
||||
var i = 0,
|
||||
count = [self count];
|
||||
|
||||
for(; i < count; ++i)
|
||||
|
||||
for (; i < count; ++i)
|
||||
[self[i] setValue:aValue forKey:aKey];
|
||||
}
|
||||
|
||||
@@ -906,10 +895,10 @@
|
||||
var i = 0,
|
||||
count = [self count],
|
||||
array = [];
|
||||
|
||||
for(; i < count; ++i)
|
||||
|
||||
for (; i < count; ++i)
|
||||
array.push([self[i] valueForKey:aKey]);
|
||||
|
||||
|
||||
return array;
|
||||
}
|
||||
|
||||
@@ -923,10 +912,10 @@
|
||||
{
|
||||
return slice(0);
|
||||
}
|
||||
|
||||
|
||||
@end
|
||||
|
||||
@implementation CPArray(CPMutableArray)
|
||||
@implementation CPArray (CPMutableArray)
|
||||
|
||||
// Creating arrays
|
||||
/*!
|
||||
@@ -986,28 +975,29 @@
|
||||
{
|
||||
var indexesCount = [indexes count],
|
||||
objectsCount = [objects count];
|
||||
|
||||
if(indexesCount !== objectsCount)
|
||||
|
||||
if (indexesCount !== objectsCount)
|
||||
[CPException raise:CPRangeException reason:"the counts of the passed-in array (" + objectsCount + ") and index set (" + indexesCount + ") must be identical."];
|
||||
|
||||
|
||||
var lastIndex = [indexes lastIndex];
|
||||
|
||||
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 + ")."];
|
||||
|
||||
|
||||
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;
|
||||
});
|
||||
}
|
||||
|
||||