Compare commits

..
131 Commits
Author SHA1 Message Date
Tom Robinson 4080fd91b2 Auto run all LoadTimeTests 2010-05-25 13:21:05 -07:00
Tom Robinson 82c71617d1 Merge branch 'master' into commonjs 2010-05-15 12:14:22 -07:00
Francisco Ryan Tolmasky I 8dd61155bf Merge branch 'master' of github.com:280north/cappuccino 2010-05-12 19:23:06 -07:00
Francisco Ryan Tolmasky I 5a89dfe8f4 Fix for identifying when we can use platform windows.
Reviewed by me.
2010-05-12 19:22:31 -07:00
Ross Boucher 80b70ec6b9 Can't sprited resources whos resulting dataURL is larger than 32k, not resources which themselves are over 32k. 2010-05-12 19:08:30 -07:00
Francisco Ryan Tolmasky I ac81ab458c Fix for same html appearing multiple times in CPWebView when using loadHTMLString: many times in succession.
Reviewed by me.
2010-05-12 18:41:14 -07:00
Ross Boucher 23b76874df A few IE fixes for web view. 2010-05-12 18:23:33 -07:00
Randall Luecke bc54fcf6c0 Merge branch 'master' of git://github.com/280north/cappuccino 2010-05-12 19:46:34 -05:00
Randall Luecke e0a3a683a5 access ivars directly from within CPTableHeaderView class. 2010-05-12 19:44:07 -05:00
Randall Luecke c31786c4c1 Refactored autoresizing 2010-05-12 19:01:28 -05:00
Ross Boucher 13a5c7f215 indexOf is not a safe operation on arrays. 2010-05-12 16:51:28 -07:00
Klaas Pieter AnnemaandRoss Boucher ee2f361425 Reimplemented setImageDimsWhenDisabled: on CPButton to only dim the image instead of the entire button 2010-05-12 16:51:28 -07:00
Scott KyleandRoss Boucher 9eab2071dc In CPImageView, performDragOperation: should return a BOOL 2010-05-12 16:51:28 -07:00
Randall Luecke 61d7fe04e8 If we tell the tableview not to draw a selection then we shouldn't draw it... 2010-05-12 18:43:56 -05:00
Randall Luecke d3161422db Updated TableTest adding a checkbox as a dataview for a column. 2010-05-12 17:14:25 -05:00
Tom Robinson c6b3db44da Preliminary CommonJS module support in loader. Passes 8 of 11 CommonJS module tests. 2010-05-12 13:47:32 -07:00
Ross Boucher d1ae1bd41f Menu window's should open in the same platform window as the view they are attached to. 2010-05-12 10:36:48 -07:00
Francisco Ryan Tolmasky I 6384bed9cc Properly handle window.location= links as well.
Reviewed by me.
2010-05-12 09:45:58 -07:00
Francisco Ryan Tolmasky I be75e4948d Merge branch 'master' of github.com:280north/cappuccino 2010-05-12 08:54:15 -07:00
Francisco Ryan Tolmasky I 337f5d9e73 Correctly handle targeted links in NativeHost.
Reviewed by me.
2010-05-12 08:53:50 -07:00
Ross Boucher 4afa2bfada clean up style issues 2010-05-11 23:20:02 -07:00
Randall Luecke b94174f9e1 Updated TableTest to provide a test case for tables that do not sit at (0,0) of a window. 2010-05-11 19:43:01 -05:00
Randall Luecke bf71045381 Fixed bug where column reordering would be off if the table didn't sit at (0,0) on a window. 2010-05-11 19:39:51 -05:00
Francisco Ryan Tolmasky I 0ade0e1361 Merge branch 'master' of github.com:280north/cappuccino 2010-05-11 14:05:51 -07:00
Ross Boucher 0f02e0d8dd Revert "added enumerateWithBlock: to CPArray"
This reverts commit 39bb8e3418.
2010-05-11 12:40:37 -07:00
klaaspieterandRandall Luecke 7c786407a5 Merge remote branch 'klaaspieter/column-reordering'
Conflicts:
	AppKit/CPTableHeaderView.j
2010-05-11 01:18:56 -05:00
Klaas Pieter AnnemaandRandall Luecke 79ba8fecd5 made column reordering work with scrolled content 2010-05-11 00:25:54 -05:00
Klaas Pieter AnnemaandRandall Luecke 213c81ed4d made table column reordering work in non full-bridged apps 2010-05-11 00:25:47 -05:00
Klaas Pieter AnnemaandRandall Luecke d7432c376d fixed a bug where column reordering would break when the last column was hidden 2010-05-11 00:25:39 -05:00
Klaas Pieter AnnemaandRandall Luecke b8c7d6ea86 some cleanup 2010-05-11 00:25:30 -05:00
Randall Luecke 983f0a92b2 - fixed a out of bounds error when clicking in the table header outside of any column
- made the dragged table column appear gray
- gave the tablecolumn drag view a white background

Conflicts:

	AppKit/CPTableView.j
2010-05-11 00:25:19 -05:00
Klaas Pieter AnnemaandRandall Luecke 256cc902eb - switch columns when the dragged column is more than halfway over the previous/next column
- constrain the horizontal coordinates within the header view
2010-05-11 00:24:16 -05:00
Klaas Pieter AnnemaandRandall Luecke f7b766cc4a - made the _dragViewForTableColumn:event:offset: method private
- removed the multiple column support from _dragViewForTableColumn:event:offset: (Cocoa doesn't allow multiple column selection / dragging)
- made the dragview the size of the dragged column
2010-05-11 00:24:03 -05:00
Klaas Pieter AnnemaandRandall Luecke dca66f300d - gave the drag column a proper 'image' representation
- constrained the drags y coordinates
- made sure a drag is never out of bounds
2010-05-11 00:23:55 -05:00
Klaas Pieter AnnemaandRandall Luecke fd9dac8122 - refactored mouse interaction
- implemented basic column reordering
2010-05-11 00:23:40 -05:00
Klaas Pieter AnnemaandRandall Luecke 8b168e76af refactored CPTableHeaderView mouse interaction 2010-05-11 00:18:21 -05:00
Randall Luecke 5b518797d7 fixed CPTableView moveColumn:
Conflicts:

	AppKit/CPTableView.j
2010-05-11 00:18:05 -05:00
Randall Luecke e5275514dd OutlineView items auto expand when hovering over them. 2010-05-11 00:05:12 -05:00
cacaodevandRandall Luecke 0d35b38282 CPOutlineView: Fix a bug where newly expanded items would have a white disclosure control.
In CPTableView, add a method for data view selection. Use it in CPOutlineView for disclosure selection and do not subclass the entire -selectRows:... method.
               Darken disclosure control when pressed depending on the selected state.
2010-05-10 15:03:06 -05:00
Randall Luecke 837dcbf19d Merge branch 'master' of git://github.com/280north/cappuccino 2010-05-10 15:02:19 -05:00
Ross BoucherandRandall Luecke e68d70cf1d Make mouse wheel events work in CPWebView in Firefox 3+ 2010-05-09 21:46:02 -05:00
Klaas Pieter Annema e5873caf04 fixed a typo in objectValueForTableColumn:row: 2010-05-07 09:38:23 +02:00
Ross Boucher c43b80cb91 Make mouse wheel events work in CPWebView in Firefox 3+ 2010-05-06 12:41:01 -07:00
Ross Boucher 542e491bb4 whitespace cleanup. 2010-05-06 11:26:56 -07:00
Klaas Pieter AnnemaandRoss Boucher 9c9eb519df call willChange* and didChange* methods on the actual classes 2010-05-06 11:23:49 -07:00
Ross Boucher 90975c96f9 Updates for scrolling behavior in webview. 2010-05-05 14:05:09 -07:00
Klaas Pieter Annema 2fd85ab78f made column reordering work with scrolled content 2010-05-05 14:08:06 +02:00
Klaas Pieter Annema a0cf7d5787 made table column reordering work in non full-bridged apps 2010-05-05 12:56:23 +02:00
Klaas Pieter Annema e7fc9d9912 fixed a bug where column reordering would break when the last column was hidden 2010-05-05 12:25:09 +02:00
Klaas Pieter Annema bdb0fb1310 some cleanup 2010-05-05 12:24:05 +02:00
Klaas Pieter Annema 006f7e0c15 - fixed a out of bounds error when clicking in the table header outside of any column
- made the dragged table column appear gray
- gave the tablecolumn drag view a white background
2010-05-05 12:23:55 +02:00
Klaas Pieter Annema 93afa11ef9 - switch columns when the dragged column is more than halfway over the previous/next column
- constrain the horizontal coordinates within the header view
2010-05-05 12:23:07 +02:00
Klaas Pieter Annema 040e7bc9ee - made the _dragViewForTableColumn:event:offset: method private
- removed the multiple column support from _dragViewForTableColumn:event:offset: (Cocoa doesn't allow multiple column selection / dragging)
- made the dragview the size of the dragged column
2010-05-05 12:23:00 +02:00
Klaas Pieter Annema 6bb8514253 - gave the drag column a proper 'image' representation
- constrained the drags y coordinates
- made sure a drag is never out of bounds
2010-05-05 12:22:53 +02:00
Klaas Pieter Annema 85283cff38 - refactored mouse interaction
- implemented basic column reordering
2010-05-05 12:22:42 +02:00
Klaas Pieter Annema ef68408fff refactored CPTableHeaderView mouse interaction 2010-05-05 12:22:36 +02:00
Klaas Pieter Annema 71104e4902 fixed CPTableView moveColumn: 2010-05-05 12:22:16 +02:00
Klaas Pieter Annema 65362e727a Merge branch 'master' of git://github.com/280north/cappuccino 2010-05-05 12:03:51 +02:00
Ross Boucher 5044ce4236 Add a doctype when creating new platform windows. 2010-05-04 22:55:06 -07:00
Francisco Ryan Tolmasky I b4aca3410f Merge branch 'master' of github.com:280north/cappuccino 2010-05-04 22:08:08 -07:00
Ross Boucher b5971eae95 Missed this, it's no longer needed. 2010-05-04 19:09:06 -07:00
Tom Robinson 4b775796be Add a test for capp gen, press, and flatten. 2010-05-04 15:41:50 -07:00
Tom Robinson e97af776a0 Fix press/flatten due to changes to CFHTTPRequest. 2010-05-04 15:40:35 -07:00
Ross Boucher e83e5b7c29 Only send open if we aren't already open 2010-05-04 15:04:51 -07:00
Francisco Ryan Tolmasky I 179ef85f4e Final timer fix.
Reviewed by me.
2010-05-04 14:49:31 -07:00
Ross Boucher 5b4603b6a7 add missing ivar declaration to CPPlatformWindow 2010-05-04 13:53:56 -07:00
Francisco Ryan Tolmasky I fc2560eb32 Fix for native drag and drop breaking across different window starts.
Reviewed by me.
2010-05-04 10:28:51 -07:00
Francisco Ryan Tolmasky I 2c23c0ffa7 Disable new timer stuff for CommonJS.
Reviewed by me.
2010-05-04 10:09:16 -07:00
Klaas Pieter Annema fda974458e Merge branch 'master' of git://github.com/280north/cappuccino 2010-05-04 15:55:17 +02:00
Francisco Ryan Tolmasky I efe4d5f339 Merge branch 'master' of github.com:280north/cappuccino 2010-05-04 03:32:51 -07:00
Francisco Ryan Tolmasky I 032fe7cc0c Fix for timers not working if they are created outside of a run loop.
Reviewed by me.
2010-05-04 03:32:16 -07:00
Randall Luecke 50c519ec69 Fixed issue with CPWebView where document.body didn't exist when reloaded quickly. 2010-05-03 17:34:12 -04:00
Tom Robinson af566ec08a Fix LoadTimeTest, location.host includes the port. 2010-05-03 00:25:35 -07:00
Ross Boucher cb7879eecf Make CFHTTPRequests re-fireable. 2010-05-02 12:58:36 -07:00
Ross Boucher b1825334dd If the vertical status changes, or the pane splitter status changes, we need to update the image value. 2010-05-01 20:40:38 -07:00
Ross Boucher 09727909b3 Fix for menuless windows. Closes #640. 2010-05-01 14:47:43 -07:00
Ross Boucher f98d3bd44b Add global 403 handler for CFHTTPRequest, to make it easier to catch authentication challenges. 2010-05-01 11:57:32 -07:00
Ross Boucher 1545f7b60a Return the cib created in CibLoading.j methods. 2010-04-29 15:38:33 -07:00
Ross Boucher 2453e403ef Make nil a completely valid object in a CPArray.
Closes #630.
2010-04-29 12:04:44 -07:00
Klaas Pieter Annema 2bb16c3617 Merge branch 'master' of git://github.com/280north/cappuccino 2010-04-29 14:28:16 +02:00
Klaas Pieter Annema 4ef9202e92 made the tableview handle hiding and showing of columns properly 2010-04-29 14:22:46 +02:00
Tom Robinson 22668b6b43 Use 127.0.0.1 instead of localhost in case localhost != loopback. 2010-04-28 02:23:07 -07:00
Francisco Ryan Tolmasky I f9c786f3eb Merge branch 'master' of git@github.com:280north/cappuccino 2010-04-28 02:06:48 -07:00
Francisco Ryan Tolmasky I 0f2ee1966e Only create main menu in code if no cib is loaded.
Reviewed by me.
2010-04-28 02:06:01 -07:00
Tom Robinson 62e520a6a5 Some more NativeHost building enhancements. 2010-04-28 01:45:04 -07:00
Ross Boucher 2f9cf6bc9b Add action buttons to button bars. 2010-04-27 22:11:17 -07:00
Ross Boucher e03cfe8287 Missing printResults() in Jakefile for ThemeDescriptor template
Conflicts:

	Tools/capp/Resources/Templates/ThemeDescriptor/Jakefile
2010-04-27 13:16:17 -07:00
Tom Robinson 0d97dfacd6 give zero sized borderless bridge windows a default size if we're not in the browser so they show up in NativeHost. 2010-04-27 12:56:24 -07:00
Francisco Ryan Tolmasky I 6ac0191451 Show main menu in cibless apps.
Remaining: Make a main menu with quit for desktop version, without for web version.

Reviewed by me.
2010-04-27 11:33:00 -07:00
Ross Boucher f5b360f66c Move a lot of common initialization code into the _init method. 2010-04-27 10:49:50 -07:00
Ross Boucher 1d5c21fa72 If we decode a scroll view without a header clip view, create one. 2010-04-27 10:49:50 -07:00
Klaas Pieter Annema 015aca9165 Merge branch 'master' of git://github.com/280north/cappuccino 2010-04-27 10:36:12 +02:00
Francisco Ryan Tolmasky I d3e1c39e35 Merge branch 'master' of git@github.com:280north/cappuccino 2010-04-27 01:05:14 -07:00
Francisco Ryan Tolmasky I ae47509aa7 Add convinience methods for dealing with multiple objects and controls.
Reviewed by me.
2010-04-27 01:04:46 -07:00
Tom Robinson 5ff798306f Copy CFBundleIconFile in NativeHost building. 2010-04-26 23:19:05 -07:00
Ross Boucher c41ffc14c7 checkboxes and radio buttons shouldn't be bold. 2010-04-26 21:36:45 -07:00
Ross Boucher 1e7a3bef0d Fix a potential infinite loop in CPBrowser. 2010-04-26 12:56:52 -07:00
Nicholas Small 243f564396 Fix typo in new autoscroll stuff. 2010-04-26 11:11:42 -04:00
Tom Robinson dae1e44a8f Merge Cappuccino Info.plist into NativeHost's Info.plist. 2010-04-25 23:22:16 -07:00
Tom Robinson 67bcc29baf NativeHost. 2010-04-25 22:33:31 -07:00
Ross Boucher cdb089778c autoscroll when drag selecting. 2010-04-25 15:43:23 -07:00
Ross Boucher 5e43a02ffa Fix some faulty validation logic. 2010-04-25 15:43:22 -07:00
Ross Boucher 7395d13c3e Typo in CPJSONPConnection. 2010-04-25 15:43:22 -07:00
Tom Robinson f6000468db Missing printResults function in ThemeDescriptor Jakefile. 2010-04-25 14:58:27 -07:00
Stephen IerodiaconouandRoss Boucher 09e52d82bf Code style clean up, as per style guide 2010-04-24 15:06:12 -07:00
Ross Boucher 0e98f44a93 Fix for IE transparent backgrounds not being resized.
Closes #604.
2010-04-24 14:51:10 -07:00
Ross Boucher 6d595c1344 Collection view should tile itself to be the height of its superview if inside a clip view. 2010-04-24 11:10:58 -07:00
Ross Boucher 5f6f997095 Only attempt to scroll views, not windows. 2010-04-24 11:10:36 -07:00
Ross Boucher 6662fabcb8 Tests for the bug exposed in the previous cparray commit. 2010-04-23 16:43:22 -07:00
Stephen IerodiaconouandRoss Boucher 7577cf8645 Fix error in initWithArray:copyItems: 2010-04-23 16:42:55 -07:00
Ross Boucher 8340791824 Don't let color wells work if they are disabled.
Closes #626.
2010-04-23 16:34:47 -07:00
Ross Boucher 14f0d16fae Update scrollWheel: to propagate unused scroll deltas to parent scroll views. 2010-04-23 16:16:46 -07:00
cacaodevandRoss Boucher e1ad4a2fce CPTableView: remove custom scrolling now that it's handled in the CPDragServer + CPClipView 2010-04-23 14:31:25 -07:00
Ross Boucher f67580e2b2 Add support for automatically scrolling during drag and drop operations. 2010-04-23 14:00:47 -07:00
Ross Boucher 31f408478a Update to scrolling behavior. 2010-04-23 12:03:25 -07:00
Klaas Pieter Annema fd93b6e5f7 Merge branch 'master' of git://github.com/280north/cappuccino 2010-04-23 16:34:59 +02:00
Klaas Pieter Annema 39bb8e3418 added enumerateWithBlock: to CPArray 2010-04-23 16:34:40 +02:00
Randall Luecke ab6d5d6a90 Added connectionDidFinsihLoading delegate to CPJSONPConnection 2010-04-23 01:29:46 -04:00
Ross Boucher 6b3600d67b Slight update to button bar theme values. 2010-04-22 11:50:06 -07:00
Francisco Ryan Tolmasky I bf8ff44b84 Merge branch 'master' of git@github.com:280north/cappuccino 2010-04-21 22:56:21 -07:00
Francisco Ryan Tolmasky I 72a3888062 Add ObjectiveJ global to CommonJS so that references to it aren't broken in Cappuccino.
Reviewed by me.
2010-04-21 22:55:46 -07:00
Ross Boucher 4479233bea Return nil fonts if they are the aristo default, so that the theme default is used instead of the arist default (for custom themes). 2010-04-21 20:57:53 -07:00
Alexander LjungbergandRoss Boucher a7021e6b66 Fixed a parameter type typo. 2010-04-21 15:48:47 -07:00
Alexander LjungbergandRoss Boucher 0f5dd9d469 [CPSet description] with unit test. 2010-04-21 15:48:39 -07:00
Alexander LjungbergandRoss Boucher 388f008189 Fixed: CPCollectionView frameForItemsAtIndexes used the deprecated method rectForItemAtIndex causing warnings. 2010-04-21 15:47:48 -07:00
Alexander LjungbergandRoss Boucher 639a32ea7e CPWindow alpha value support. 2010-04-21 15:47:25 -07:00
Alexander LjungbergandRoss Boucher 5838f1aec8 Implemented CPCoding for CPNull. 2010-04-21 15:36:29 -07:00
Ross Boucher d2399b6157 Add support for not clipping to bounds in cpview. 2010-04-21 14:15:05 -07:00
Ross Boucher b1282b4362 Fix an infinite recursion bug in CPBrowser, and add support for looking up a column/row by location. 2010-04-21 12:58:31 -07:00
Francisco Ryan Tolmasky I bbd402fcff Partial fix for HTML5 drag and drop with collection views.
Reviewed by me.
2010-04-20 23:51:18 -07:00
Tom Robinson a18fb1b686 Add manifest generation options to press and flatten, since manifests need to be updated after each is run. 2010-04-12 13:47:38 -07:00
150 changed files with 7306 additions and 1133 deletions
+65 -57
View File
@@ -132,6 +132,8 @@ CPRunContinuesResponse = -1002;
{ {
self = [super init]; self = [super init];
CPApp = self;
if (self) if (self)
{ {
_eventListeners = []; _eventListeners = [];
@@ -139,63 +141,6 @@ CPRunContinuesResponse = -1002;
_windows = []; _windows = [];
[_windows addObject:nil]; [_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; return self;
@@ -1188,10 +1133,73 @@ var _CPAppBootstrapperActions = nil;
return YES; return YES;
} }
else
[self loadCiblessBrowserMainMenu];
return NO; 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 + (void)cibDidFinishLoading:(CPCib)aCib
{ {
[self performActions]; [self performActions];
+77 -21
View File
@@ -64,14 +64,14 @@
+ (CPImage)branchImage + (CPImage)branchImage
{ {
return [[CPImage alloc] initWithContentsOfFile:[[CPBundle bundleForClass:[self class]] return [[CPImage alloc] initWithContentsOfFile:[[CPBundle bundleForClass:[CPBrowser class]]
pathForResource:"browser-leaf.png"] pathForResource:"browser-leaf.png"]
size:CGSizeMake(9,9)]; size:CGSizeMake(9,9)];
} }
+ (CPImage)highlightedBranchImage + (CPImage)highlightedBranchImage
{ {
return [[CPImage alloc] initWithContentsOfFile:[[CPBundle bundleForClass:[self class]] return [[CPImage alloc] initWithContentsOfFile:[[CPBundle bundleForClass:[CPBrowser class]]
pathForResource:"browser-leaf-highlighted.png"] pathForResource:"browser-leaf-highlighted.png"]
size:CGSizeMake(9,9)]; size:CGSizeMake(9,9)];
} }
@@ -213,8 +213,6 @@
[table setAllowsEmptySelection:_allowsEmptySelection]; [table setAllowsEmptySelection:_allowsEmptySelection];
[table registerForDraggedTypes:[self registeredDraggedTypes]]; [table registerForDraggedTypes:[self registeredDraggedTypes]];
[self setNextResponder:table];
[self _addTableColumnsToTableView:table forColumnIndex:index]; [self _addTableColumnsToTableView:table forColumnIndex:index];
var delegate = [[_CPBrowserTableDelegate alloc] init]; var delegate = [[_CPBrowserTableDelegate alloc] init];
@@ -314,6 +312,39 @@
[_contentView setFrameSize:CGSizeMake(xOrigin, height)]; [_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 // ITEMS
- (id)itemAtRow:(int)row inColumn:(int)column - (id)itemAtRow:(int)row inColumn:(int)column
@@ -357,6 +388,10 @@
// CLICK EVENTS // CLICK EVENTS
- (void)trackMouse:(CPEvent)anEvent
{
}
- (void)_column:(unsigned)columnIndex clickedRow:(unsigned)rowIndex - (void)_column:(unsigned)columnIndex clickedRow:(unsigned)rowIndex
{ {
[self setLastColumn:columnIndex]; [self setLastColumn:columnIndex];
@@ -382,6 +417,15 @@
[self sendAction:_doubleAction to:_target]; [self sendAction:_doubleAction to:_target];
} }
- (void)keyDown:(CPEvent)anEvent
{
var column = [self selectedColumn];
if (column === -1)
return;
[_tableViews[column] keyDown:anEvent];
}
// SIZING // SIZING
- (float)columnContentWidthForColumnWidth:(float)aWidth - (float)columnContentWidthForColumnWidth:(float)aWidth
@@ -526,6 +570,9 @@
- (CPIndexSet)selectedRowIndexesInColumn:(unsigned)column - (CPIndexSet)selectedRowIndexesInColumn:(unsigned)column
{ {
if (column < 0 || column > [self lastColumn] +1)
return [CPIndexSet indexSet];
return [[self tableViewInColumn:column] selectedRowIndexes]; return [[self tableViewInColumn:column] selectedRowIndexes];
} }
@@ -551,8 +598,6 @@
[[self tableViewInColumn:column] selectRowIndexes:indexSet byExtendingSelection:NO]; [[self tableViewInColumn:column] selectRowIndexes:indexSet byExtendingSelection:NO];
[self setNextResponder:[self tableViewInColumn:[self lastColumn]]];
[self scrollColumnToVisible:column]; [self scrollColumnToVisible:column];
if ([_delegate respondsToSelector:@selector(browserSelectionDidChange:)]) if ([_delegate respondsToSelector:@selector(browserSelectionDidChange:)])
@@ -604,6 +649,8 @@
@end @end
var _CPBrowserResizeControlBackgroundImage = nil;
@implementation _CPBrowserResizeControl : CPView @implementation _CPBrowserResizeControl : CPView
{ {
CGPoint _mouseDownX; CGPoint _mouseDownX;
@@ -612,6 +659,26 @@
unsigned _width; 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 - (void)mouseDown:(CPEvent)anEvent
{ {
_mouseDownX = [anEvent locationInWindow].x; _mouseDownX = [anEvent locationInWindow].x;
@@ -626,9 +693,11 @@
[_browser setWidth:_width + deltaX ofColumn:_index]; [_browser setWidth:_width + deltaX ofColumn:_index];
} }
@end - (void)mouseUp:(CPEvent)anEvent
{
}
var _CPBrowserResizeControlBackgroundImage = nil; @end
@implementation _CPBrowserScrollView : CPScrollView @implementation _CPBrowserScrollView : CPScrollView
{ {
@@ -636,24 +705,11 @@ var _CPBrowserResizeControlBackgroundImage = nil;
CPBrowser _browser @accessors; 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 - (void)initWithFrame:(CGRect)aFrame
{ {
if (self = [super initWithFrame:aFrame]) if (self = [super initWithFrame:aFrame])
{ {
_resizeControl = [[_CPBrowserResizeControl alloc] initWithFrame:CGRectMakeZero()]; _resizeControl = [[_CPBrowserResizeControl alloc] initWithFrame:CGRectMakeZero()];
[_resizeControl setBackgroundColor:[CPColor colorWithPatternImage:[[self class] backgroundImage]]];
[self addSubview:_resizeControl]; [self addSubview:_resizeControl];
} }
+1
View File
@@ -530,6 +530,7 @@ CPButtonStateMixed = CPThemeState("mixed");
[contentView setTextShadowOffset:[self currentValueForThemeAttribute:@"text-shadow-offset"]]; [contentView setTextShadowOffset:[self currentValueForThemeAttribute:@"text-shadow-offset"]];
[contentView setImagePosition:[self currentValueForThemeAttribute:@"image-position"]]; [contentView setImagePosition:[self currentValueForThemeAttribute:@"image-position"]];
[contentView setImageScaling:[self currentValueForThemeAttribute:@"image-scaling"]]; [contentView setImageScaling:[self currentValueForThemeAttribute:@"image-scaling"]];
[contentView setDimsImage:[self hasThemeState:CPThemeStateDisabled] && _imageDimsWhenDisabled];
} }
} }
+54 -24
View File
@@ -14,8 +14,9 @@
+ (id)plusButton + (id)plusButton
{ {
var button = [[CPButton alloc] initWithFrame:CGRectMake(0, 0, 35, 25)], 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 setImage:image];
[button setImagePosition:CPImageOnly]; [button setImagePosition:CPImageOnly];
@@ -25,14 +26,30 @@
+ (id)minusButton + (id)minusButton
{ {
var button = [[CPButton alloc] initWithFrame:CGRectMake(0, 0, 35, 25)], 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 setImage:image];
[button setImagePosition:CPImageOnly]; [button setImagePosition:CPImageOnly];
return button; 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 + (CPString)themeClass
{ {
return @"button-bar"; return @"button-bar";
@@ -40,8 +57,8 @@
+ (id)themeAttributes + (id)themeAttributes
{ {
return [CPDictionary dictionaryWithObjects:[CGInsetMake(0.0, 0.0, 0.0, 0.0), CGSizeMakeZero(), [CPNull null], [CPNull null], [CPNull null]] 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"]]; forKeys:[@"resize-control-inset", @"resize-control-size", @"resize-control-color", @"bezel-color", @"button-bezel-color", @"button-text-color"]];
} }
- (id)initWithFrame:(CGRect)aFrame - (id)initWithFrame:(CGRect)aFrame
@@ -82,24 +99,7 @@
_buttons = [CPArray arrayWithArray:buttons]; _buttons = [CPArray arrayWithArray:buttons];
for (var i = 0, count = [_buttons count]; i < count; i++) for (var i = 0, count = [_buttons count]; i < count; i++)
{ [_buttons[i] setBordered:YES];
var button = _buttons[i];
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]; [self setNeedsLayout];
} }
@@ -176,6 +176,11 @@
{ {
[self setBackgroundColor:[self currentValueForThemeAttribute:@"bezel-color"]]; [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], var buttonsNotHidden = [CPArray arrayWithArray:_buttons],
count = [buttonsNotHidden count]; count = [buttonsNotHidden count];
@@ -184,13 +189,23 @@
[buttonsNotHidden removeObject:buttonsNotHidden[count]]; [buttonsNotHidden removeObject:buttonsNotHidden[count]];
var currentButtonOffset = _resizeControlIsLeftAligned ? CGRectGetMaxX([self bounds]) + 1 : -1, 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++) for (var i = 0, count = [buttonsNotHidden count]; i < count; i++)
{ {
var button = buttonsNotHidden[i], var button = buttonsNotHidden[i],
width = CGRectGetWidth([button frame]); width = CGRectGetWidth([button frame]);
if (availableWidth > width)
availableWidth -=width;
else
break;
if (_resizeControlIsLeftAligned) if (_resizeControlIsLeftAligned)
{ {
[button setFrame:CGRectMake(currentButtonOffset - width, 1, width, height)]; [button setFrame:CGRectMake(currentButtonOffset - width, 1, width, height)];
@@ -202,6 +217,16 @@
currentButtonOffset += width - 1; 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]; [self addSubview:button];
} }
@@ -216,6 +241,12 @@
} }
} }
- (void)setFrameSize:(CGSize)aSize
{
[super setFrameSize:aSize];
[self setNeedsLayout];
}
@end @end
var CPButtonBarHasResizeControlKey = @"CPButtonBarHasResizeControlKey", var CPButtonBarHasResizeControlKey = @"CPButtonBarHasResizeControlKey",
@@ -246,4 +277,3 @@ var CPButtonBarHasResizeControlKey = @"CPButtonBarHasResizeControlKey",
} }
@end @end
+23
View File
@@ -61,4 +61,27 @@
return self; 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 @end
+28 -6
View File
@@ -190,17 +190,39 @@
- (BOOL)autoscroll:(CPEvent)anEvent - (BOOL)autoscroll:(CPEvent)anEvent
{ {
var bounds = [self bounds], 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; 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; if (![superview isKindOfClass:[CPScrollView class]] || [superview hasHorizontalScroller])
newRect.size = CPSizeMake(10, 10); {
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 @end
+19 -2
View File
@@ -426,8 +426,17 @@
x += itemSize.width + _horizontalMargin; 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; _tileWidth = width;
[self setFrameSize:CGSizeMake(width, y + itemSize.height + _verticalMargin)]; [self setFrameSize:CGSizeMake(width, proposedHeight)];
_tileWidth = -1.0; _tileWidth = -1.0;
} }
@@ -590,6 +599,14 @@
- (void)mouseDragged:(CPEvent)anEvent - (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:)]) if (![_delegate respondsToSelector:@selector(collectionView:dragTypesForItemsAtIndexes:)])
return; return;
@@ -701,7 +718,7 @@
count = [indexArray count]; count = [indexArray count];
for (; index < count; ++index) for (; index < count; ++index)
frame = CGRectUnion(frame, [self rectForItemAtIndex:indexArray[index]]); frame = CGRectUnion(frame, [self frameForItemAtIndex:indexArray[index]]);
return frame; return frame;
} }
+7 -1
View File
@@ -231,11 +231,17 @@ var _CPColorWellDidBecomeExclusiveNotification = @"_CPColorWellDidBecomeExclusiv
- (void)mouseDown:(CPEvent)anEvent - (void)mouseDown:(CPEvent)anEvent
{ {
if (![self isEnabled])
return;
[self drawBezelWithHighlight:YES]; [self drawBezelWithHighlight:YES];
} }
- (void)mouseDragged:(CPEvent)anEvent - (void)mouseDragged:(CPEvent)anEvent
{ {
if (![self isEnabled])
return;
[self drawBezelWithHighlight:CGRectContainsPoint([self bounds], [self convertPoint:[anEvent locationInWindow] fromView:nil])]; [self drawBezelWithHighlight:CGRectContainsPoint([self bounds], [self convertPoint:[anEvent locationInWindow] fromView:nil])];
} }
@@ -243,7 +249,7 @@ var _CPColorWellDidBecomeExclusiveNotification = @"_CPColorWellDidBecomeExclusiv
{ {
[self drawBezelWithHighlight:NO]; [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; return;
[self activate:YES]; [self activate:YES];
+4 -17
View File
@@ -210,10 +210,10 @@ var CPDocumentUntitledCount = 0;
@throws CPUnsupportedMethodException if this method hasn't been overriden by the subclass @throws CPUnsupportedMethodException if this method hasn't been overriden by the subclass
@return the document data @return the document data
*/ */
- (CPData)dataOfType:(CPString)aType - (CPData)dataOfType:(CPString)aType error:({CPError})anError
{ {
[CPException raise:CPUnsupportedMethodException [CPException raise:CPUnsupportedMethodException
reason:"dataOfType: must be overridden by the document subclass."]; reason:"dataOfType:error: must be overridden by the document subclass."];
} }
/*! /*!
@@ -473,21 +473,8 @@ var CPDocumentUntitledCount = 0;
*/ */
- (void)saveToURL:(CPURL)anAbsoluteURL ofType:(CPString)aTypeName forSaveOperation:(CPSaveOperationType)aSaveOperation delegate:(id)aDelegate didSaveSelector:(SEL)aDidSaveSelector contextInfo:(id)aContextInfo - (void)saveToURL:(CPURL)anAbsoluteURL ofType:(CPString)aTypeName forSaveOperation:(CPSaveOperationType)aSaveOperation delegate:(id)aDelegate didSaveSelector:(SEL)aDidSaveSelector contextInfo:(id)aContextInfo
{ {
if (anAbsoluteURL.isLocalStorageURL()) var data = [self dataOfType:[self fileType] error:nil],
[[CPDocumentController sharedDocumentController] _addLocalDocumentURL:anAbsoluteURL]; oldChangeCount = _changeCount;
var data = nil;
if ([self respondsToSelector:@selector(dataOfType:error:)])
{
CPLog.warn("[" + CPStringFromClass([self class]) + " " + CPStringFromSelector(@selector(dataOfType:error:)) + "] is deprecated, please implement " + CPStringFromSelector(@selector(dataOfType:)) + " instead and simply throw exceptions when necessary.");
data = [self dataOfType:[self fileType] error:nil];
}
else
data = [self dataOfType:[self fileType]];
var oldChangeCount = _changeCount;
_writeRequest = [CPURLRequest requestWithURL:anAbsoluteURL]; _writeRequest = [CPURLRequest requestWithURL:anAbsoluteURL];
+3 -58
View File
@@ -38,7 +38,6 @@ var CPSharedDocumentController = nil;
{ {
CPArray _documents; CPArray _documents;
CPArray _documentTypes; CPArray _documentTypes;
CPArray _localDocumentURLs;
} }
/*! /*!
@@ -63,27 +62,11 @@ var CPSharedDocumentController = nil;
if (self) if (self)
{ {
_documents = [[CPArray alloc] init];
if (!CPSharedDocumentController) if (!CPSharedDocumentController)
CPSharedDocumentController = self; CPSharedDocumentController = self;
_localDocumentURLs = [CPSet set];
if (window.localStorage)
{
var localDocumentURLs = localStorage.getItem(CPDocumentControllerLocalDocumentURLsKey);
if (localDocumentURLs)
{
localDocumentURLs = JSON.parse(localDocumentURLs);
var count = [localDocumentURLs count];
while (count--)
[_localDocumentURLs addObject:new CFURL(localDocumentURLs[count])];
}
}
_documents = [];
_documentTypes = [[[CPBundle mainBundle] infoDictionary] objectForKey:@"CPBundleDocumentTypes"]; _documentTypes = [[[CPBundle mainBundle] infoDictionary] objectForKey:@"CPBundleDocumentTypes"];
} }
return self; return self;
@@ -236,7 +219,7 @@ var CPSharedDocumentController = nil;
Opens a new document in the application. Opens a new document in the application.
@param aSender the requesting object @param aSender the requesting object
*/ */
- (@action)newDocument:(id)aSender - (CFAction)newDocument:(id)aSender
{ {
[self openUntitledDocumentOfType:[[_documentTypes objectAtIndex:0] objectForKey:@"CPBundleTypeName"] display:YES]; [self openUntitledDocumentOfType:[[_documentTypes objectAtIndex:0] objectForKey:@"CPBundleTypeName"] display:YES];
} }
@@ -472,41 +455,3 @@ var CPSharedDocumentController = nil;
} }
@end @end
var CPDocumentControllerLocalDocumentURLsKey = @"Cappuccino.CPDocumentController.documentURLs";
@implementation CPDocumentController (LocalStorage)
- (void)_addLocalDocumentURL:(CPURL)aURL
{
if (!window.localStorage)
return;
[_localDocumentURLs addObject:aURL];
var stringURLs = [],
URL = nil,
URLEnumerator = [_localDocumentURLs objectEnumerator];
while (URL = [URLEnumerator nextObject])
stringURLs.push(URL + "");
localStorage.setItem(CPDocumentControllerLocalDocumentURLsKey, JSON.stringify(stringURLs));
}
- (void)_removeLocalDocumentURL:(CPURL)aURL
{
if (!window.localStorage)
return;
[_localDocumentURLs removeObject:aURL];
localStorage.setItem(CPDocumentControllerLocalDocumentURLsKey, JSON.stringify([self allObjects]));
}
- (CPSet)localDocumentURLs
{
return [_localDocumentURLs copy];
}
@end
+92 -29
View File
@@ -40,29 +40,10 @@ CPDragOperationEvery = -1;
#define DRAGGING_WINDOW(anObject) ([anObject isKindOfClass:[CPWindow class]] ? anObject : [anObject window]) #define DRAGGING_WINDOW(anObject) ([anObject isKindOfClass:[CPWindow class]] ? anObject : [anObject window])
var CPDragServerPreviousEvent = nil, var CPDragServerPreviousEvent = nil,
CPDragServerAutoscrollInterval = nil; CPDragServerPeriodicUpdateInterval = 0.05;
/*
var CPDragServerAutoscroll = function()
{
[CPDragServerSource autoscroll:CPDragServerPreviousEvent];
}
if (CPDragServerAutoscrollInterval === nil) var CPSharedDragServer = nil;
{
if ([CPDragServerSource respondsToSelector:@selector(autoscroll:)])
CPDragServerAutoscrollInterval = setInterval(CPDragServerAutoscroll, 100);
}
CPDragServerPreviousEvent = anEvent;
if (CPDragServerAutoscrollInterval !== nil)
clearInterval(CPDragServerAutoscrollInterval);
CPDragServerAutoscrollInterval = nil;
*/
var CPSharedDragServer = nil;
var CPDragServerSource = nil; var CPDragServerSource = nil;
var CPDragServerDraggingInfo = nil; var CPDragServerDraggingInfo = nil;
@@ -150,10 +131,13 @@ var CPDraggingSource_draggedImage_movedTo_ = 1 << 0,
CGPoint _draggingLocation; CGPoint _draggingLocation;
id _draggingDestination; id _draggingDestination;
BOOL _draggingDestinationWantsPeriodicUpdates;
CGPoint _startDragLocation; CGPoint _startDragLocation;
BOOL _shouldSlideBack; BOOL _shouldSlideBack;
unsigned _dragOperation; unsigned _dragOperation;
CPTimer _draggingUpdateTimer;
} }
/* /*
@@ -234,6 +218,9 @@ var CPDraggingSource_draggedImage_movedTo_ = 1 << 0,
- (CPDragOperation)draggingUpdatedInPlatformWindow:(CPPlatformWindow)aPlatformWindow location:(CGPoint)aLocation - (CPDragOperation)draggingUpdatedInPlatformWindow:(CPPlatformWindow)aPlatformWindow location:(CGPoint)aLocation
{ {
[_draggingUpdateTimer invalidate];
_draggingUpdateTimer = nil;
var dragOperation = CPDragOperationCopy; var dragOperation = CPDragOperationCopy;
// We have to convert base to bridge since the drag event comes from the source window, not the drag window. // 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]]; var draggingDestination = [aPlatformWindow _dragHitTest:aLocation pasteboard:[CPDragServerDraggingInfo draggingPasteboard]];
@@ -243,25 +230,89 @@ var CPDraggingSource_draggedImage_movedTo_ = 1 << 0,
if(draggingDestination !== _draggingDestination) if(draggingDestination !== _draggingDestination)
{ {
if (_draggingDestination && [_draggingDestination respondsToSelector:@selector(draggingExited:)]) if ([_draggingDestination respondsToSelector:@selector(draggingExited:)])
[_draggingDestination draggingExited:CPDragServerDraggingInfo]; [_draggingDestination draggingExited:CPDragServerDraggingInfo];
_draggingDestination = draggingDestination; _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]; dragOperation = [_draggingDestination draggingEntered:CPDragServerDraggingInfo];
} }
else if (_draggingDestination && [_draggingDestination respondsToSelector:@selector(draggingUpdated:)]) else if ([_draggingDestination respondsToSelector:@selector(draggingUpdated:)])
dragOperation = [_draggingDestination draggingUpdated:CPDragServerDraggingInfo]; dragOperation = [_draggingDestination draggingUpdated:CPDragServerDraggingInfo];
if (!_draggingDestination) if (!_draggingDestination)
dragOperation = CPDragOperationNone; 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; 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 - (void)draggingEndedInPlatformWindow:(CPPlatformWindow)aPlatformWindow globalLocation:(CGPoint)aLocation operation:(CPDragOperation)anOperation
{ {
[_draggingUpdateTimer invalidate];
_draggingUpdateTimer = nil;
[_draggedView removeFromSuperview]; [_draggedView removeFromSuperview];
if (![CPPlatform supportsDragAndDrop]) if (![CPPlatform supportsDragAndDrop])
@@ -404,13 +455,25 @@ var CPDraggingSource_draggedImage_movedTo_ = 1 << 0,
// Stop tracking events. // Stop tracking events.
return; return;
} }
else if (type === CPKeyDown)
[self draggingSourceUpdatedWithGlobalLocation:platformWindowLocation]; {
_dragOperation = [self draggingUpdatedInPlatformWindow:platformWindow location:platformWindowLocation]; 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. // If we're not a mouse up, then we're going to want to grab the next event.
[CPApp setTarget:self selector:@selector(trackDragging:) [CPApp setTarget:self selector:@selector(trackDragging:)
forNextEventMatchingMask:CPMouseMovedMask | CPLeftMouseDraggedMask | CPLeftMouseUpMask forNextEventMatchingMask:CPMouseMovedMask | CPLeftMouseDraggedMask | CPLeftMouseUpMask | CPKeyDownMask
untilDate:nil inMode:0 dequeue:NO]; untilDate:nil inMode:0 dequeue:NO];
} }
+3 -1
View File
@@ -365,7 +365,7 @@ var LEFT_SHADOW_INSET = 3.0,
return _isEditable; return _isEditable;
} }
- (void)performDragOperation:(CPDraggingInfo)aSender - (BOOL)performDragOperation:(CPDraggingInfo)aSender
{ {
var images = [CPKeyedUnarchiver unarchiveObjectWithData:[[aSender draggingPasteboard] dataForType:CPImagesPboardType]]; var images = [CPKeyedUnarchiver unarchiveObjectWithData:[[aSender draggingPasteboard] dataForType:CPImagesPboardType]];
@@ -374,6 +374,8 @@ var LEFT_SHADOW_INSET = 3.0,
[self setImage:images[0]]; [self setImage:images[0]];
[self sendAction:[self action] to:[self target]]; [self sendAction:[self action] to:[self target]];
} }
return YES;
} }
@end @end
+6
View File
@@ -747,6 +747,9 @@ var _CPMenuBarVisible = NO,
} }
// Show it. // Show it.
if ([CPPlatform isBrowser])
[menuWindow setPlatformWindow:[[aView window] platformWindow]];
[menuWindow orderFront:self]; [menuWindow orderFront:self];
// Track it. // Track it.
@@ -816,6 +819,9 @@ var _CPMenuBarVisible = NO,
[menuWindow setFrameOrigin:CGRectIntersection(unconstrainedFrame, constraintRect).origin]; [menuWindow setFrameOrigin:CGRectIntersection(unconstrainedFrame, constraintRect).origin];
} }
if ([CPPlatform isBrowser])
[menuWindow setPlatformWindow:[[aView window] platformWindow]];
[menuWindow orderFront:self]; [menuWindow orderFront:self];
[[_CPMenuManager sharedMenuManager] [[_CPMenuManager sharedMenuManager]
+44 -35
View File
@@ -85,6 +85,8 @@ CPOutlineViewDropOnItemIndex = -1;
BOOL _shouldRetargetChildIndex; BOOL _shouldRetargetChildIndex;
CPInteger _retargedChildIndex; CPInteger _retargedChildIndex;
CPTimer _dragHoverTimer;
id _dropItem;
} }
- (id)initWithFrame:(CGRect)aFrame - (id)initWithFrame:(CGRect)aFrame
@@ -108,6 +110,7 @@ CPOutlineViewDropOnItemIndex = -1;
_retargedChildIndex = nil; _retargedChildIndex = nil;
_shouldRetargetChildIndex = NO; _shouldRetargetChildIndex = NO;
_startHoverTime = nil;
[self setIndentationPerLevel:16.0]; [self setIndentationPerLevel:16.0];
[self setIndentationMarkerFollowsDataView:YES]; [self setIndentationMarkerFollowsDataView:YES];
@@ -382,43 +385,14 @@ CPOutlineViewDropOnItemIndex = -1;
return frame; 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 [super _performSelection:select forRow:rowIndex context:context];
var previousSelectedRows = [];
[[self selectedRowIndexes] getIndexes:previousSelectedRows maxCount:-1 inIndexRange:nil];
var index = [previousSelectedRows count]; var control = _disclosureControlsForRows[rowIndex],
while (index--) selector = select ? @"setThemeState:" : @"unsetThemeState:";
{
var rowIndex = previousSelectedRows[index],
item = [self itemAtRow:rowIndex];
if (![self isExpandable:item]) [control performSelector:CPSelectorFromString(selector) withObject:CPThemeStateSelected];
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];
}
} }
- (void)setDelegate:(id)aDelegate - (void)setDelegate:(id)aDelegate
@@ -534,6 +508,29 @@ CPOutlineViewDropOnItemIndex = -1;
- (void)setDropItem:(id)theItem dropChildIndex:(int)theIndex - (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; _retargetedItem = theItem;
_shouldRetargetItem = YES; _shouldRetargetItem = YES;
@@ -541,6 +538,14 @@ CPOutlineViewDropOnItemIndex = -1;
_shouldRetargetChildIndex = YES; _shouldRetargetChildIndex = YES;
} }
- (void)_draggingEnded
{
[super _draggingEnded];
_dropItem = nil;
[_dragHoverTimer invalidate];
_dragHoverTimer = nil;
}
- (id)_parentItemForUpperRow:(int)theUpperRowIndex andLowerRow:(int)theLowerRowIndex atMouseOffset:(CPPoint)theOffset - (id)_parentItemForUpperRow:(int)theUpperRowIndex andLowerRow:(int)theLowerRowIndex atMouseOffset:(CPPoint)theOffset
{ {
if (_shouldRetargetItem) if (_shouldRetargetItem)
@@ -619,6 +624,8 @@ CPOutlineViewDropOnItemIndex = -1;
_disclosureControlsForRows[row] = control; _disclosureControlsForRows[row] = control;
[control setState:[self isItemExpanded:item] ? CPOnState : CPOffState]; [control setState:[self isItemExpanded:item] ? CPOnState : CPOffState];
var selector = [self isRowSelected:row] ? @"setThemeState:" : @"unsetThemeState:";
[control performSelector:CPSelectorFromString(selector) withObject:CPThemeStateSelected];
[control setFrame:frame]; [control setFrame:frame];
[self addSubview:control]; [self addSubview:control];
@@ -1080,8 +1087,10 @@ var _loadItemInfoForItem = function(/*CPOutlineView*/ anOutlineView, /*id*/ anIt
CGContextAddLineToPoint(context, 0.0, 0.0); CGContextAddLineToPoint(context, 0.0, 0.0);
CGContextClosePath(context); CGContextClosePath(context);
var isHighlighted = [self hasThemeState:CPThemeStateHighlighted];
var color = [self hasThemeState:CPThemeStateSelected] ? (isHighlighted ? [CPColor lightGrayColor] : [CPColor whiteColor]) : (isHighlighted ? [CPColor blackColor] : [CPColor grayColor]);
CGContextSetFillColor(context, [self isHighlighted] ? [CPColor whiteColor] : [CPColor grayColor]); CGContextSetFillColor(context, color);
CGContextFillPath(context); CGContextFillPath(context);
} }
+17
View File
@@ -703,6 +703,23 @@ CPPopUpButtonStatePullsDown = CPThemeState("pulls-down");
[self sendAction:[self action] to:[self target]]; [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 @end
var CPPopUpButtonMenuKey = @"CPPopUpButtonMenuKey", var CPPopUpButtonMenuKey = @"CPPopUpButtonMenuKey",
+30 -9
View File
@@ -445,9 +445,7 @@
- (CPView)_headerView - (CPView)_headerView
{ {
var headerClipViewSubviews = [_headerClipView subviews]; return [_headerClipView documentView];
return [headerClipViewSubviews count] ? headerClipViewSubviews[0] : nil;
} }
- (CGRect)_cornerViewFrame - (CGRect)_cornerViewFrame
@@ -670,15 +668,32 @@
*/ */
- (void)scrollWheel:(CPEvent)anEvent - (void)scrollWheel:(CPEvent)anEvent
{ {
var documentFrame = [[self documentView] frame], [self _respondToScrollWheelEventWithDeltaX:[anEvent deltaX] * _horizontalLineScroll
contentBounds = [_contentView bounds]; 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! // We want integral bounds!
contentBounds.origin.x = ROUND(contentBounds.origin.x + [anEvent deltaX] * _horizontalLineScroll); contentBounds.origin.x = ROUND(contentBounds.origin.x + deltaX);
contentBounds.origin.y = ROUND(contentBounds.origin.y + [anEvent deltaY] * _verticalLineScroll); contentBounds.origin.y = ROUND(contentBounds.origin.y + deltaY);
[_contentView scrollToPoint:contentBounds.origin]; var constrainedOrigin = [_contentView constrainScrollPoint:CGPointCreateCopy(contentBounds.origin)];
[_headerClipView scrollToPoint:CGPointMake(contentBounds.origin.x, 0.0)]; 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 - (void)keyDown:(CPEvent)anEvent
@@ -760,6 +775,12 @@ var CPScrollViewContentViewKey = "CPScrollViewContentView",
_contentView = [aCoder decodeObjectForKey:CPScrollViewContentViewKey]; _contentView = [aCoder decodeObjectForKey:CPScrollViewContentViewKey];
_headerClipView = [aCoder decodeObjectForKey:CPScrollViewHeaderClipViewKey]; _headerClipView = [aCoder decodeObjectForKey:CPScrollViewHeaderClipViewKey];
if (!_headerClipView)
{
_headerClipView = [[CPClipView alloc] init];
[self addSubview:_headerClipView];
}
_verticalScroller = [aCoder decodeObjectForKey:CPScrollViewVScrollerKey]; _verticalScroller = [aCoder decodeObjectForKey:CPScrollViewVScrollerKey];
_horizontalScroller = [aCoder decodeObjectForKey:CPScrollViewHScrollerKey]; _horizontalScroller = [aCoder decodeObjectForKey:CPScrollViewHScrollerKey];
+12
View File
@@ -396,6 +396,18 @@ CPCircularSlider = 1;
_sendActionOn &= ~CPLeftMouseDraggedMask; _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 @end
var CPSliderMinValueKey = "CPSliderMinValueKey", var CPSliderMinValueKey = "CPSliderMinValueKey",
+1 -2
View File
@@ -217,10 +217,9 @@ var CPSplitViewHorizontalImage = nil,
_DOMDividerElements[_drawingDivider].style.backgroundRepeat = "repeat"; _DOMDividerElements[_drawingDivider].style.backgroundRepeat = "repeat";
CPDOMDisplayServerAppendChild(_DOMElement, _DOMDividerElements[_drawingDivider]); CPDOMDisplayServerAppendChild(_DOMElement, _DOMDividerElements[_drawingDivider]);
[self _setupDOMDivider];
} }
[self _setupDOMDivider];
CPDOMDisplayServerSetStyleLeftTop(_DOMDividerElements[_drawingDivider], NULL, _CGRectGetMinX(aRect), _CGRectGetMinY(aRect)); CPDOMDisplayServerSetStyleLeftTop(_DOMDividerElements[_drawingDivider], NULL, _CGRectGetMinX(aRect), _CGRectGetMinY(aRect));
CPDOMDisplayServerSetStyleSize(_DOMDividerElements[_drawingDivider], _CGRectGetWidth(aRect), _CGRectGetHeight(aRect)); CPDOMDisplayServerSetStyleSize(_DOMDividerElements[_drawingDivider], _CGRectGetWidth(aRect), _CGRectGetHeight(aRect));
#endif #endif
+7
View File
@@ -348,7 +348,14 @@ CPTableColumnUserResizingMask = 1 << 1;
- (void)setHidden:(BOOL)shouldBeHidden - (void)setHidden:(BOOL)shouldBeHidden
{ {
shouldBeHidden = !!shouldBeHidden
if (_isHidden === shouldBeHidden)
return;
_isHidden = shouldBeHidden; _isHidden = shouldBeHidden;
[[self headerView] setHidden:shouldBeHidden];
[[self tableView] _tableColumnVisibilityDidChange:self];
} }
- (BOOL)isHidden - (BOOL)isHidden
+282 -129
View File
@@ -26,7 +26,7 @@
@implementation _CPTableColumnHeaderView : CPView @implementation _CPTableColumnHeaderView : CPView
{ {
_CPImageAndTextView _textField; _CPImageAndTextView _textField;
} }
- (void)initWithFrame:(CGRect)frame - (void)initWithFrame:(CGRect)frame
@@ -147,25 +147,32 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal
@implementation CPTableHeaderView : CPView @implementation CPTableHeaderView : CPView
{ {
int _resizedColumn @accessors(readonly, property=resizedColumn); CPPoint _mouseDownLocation;
int _draggedColumn @accessors(readonly, property=draggedColumn); CPPoint _previousTrackingLocation;
int _pressedColumn @accessors(readonly, property=pressedColumn); int _activeColumn;
int _pressedColumn;
float _draggedDistance @accessors(readonly, property=draggedDistance); BOOL _isResizing;
float _lastLocation; BOOL _isDragging;
float _columnOldWidth; BOOL _isTrackingColumn;
CPTableView _tableView @accessors(property=tableView); float _columnOldWidth;
CPTableView _tableView @accessors(property=tableView);
} }
- (void)_init - (void)_init
{ {
_resizedColumn = -1; _mouseDownLocation = CPPointMakeZero();
_draggedColumn = -1; _previousTrackingLocation = CPPointMakeZero();
_activeColumn = -1;
_pressedColumn = -1; _pressedColumn = -1;
_draggedDistance = 0.0;
_lastLocation = nil; _isResizing = NO;
_columnOldWidth = nil; _isDragging = NO;
_isTrackingColumn = NO;
_columnOldWidth = 0.0;
[self setBackgroundColor:[CPColor colorWithPatternImage:CPAppKitImage("tableview-headerview.png", CGSizeMake(1.0, 22.0))]]; [self setBackgroundColor:[CPColor colorWithPatternImage:CPAppKitImage("tableview-headerview.png", CGSizeMake(1.0, 22.0))]];
} }
@@ -182,26 +189,18 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal
- (int)columnAtPoint:(CGPoint)aPoint - (int)columnAtPoint:(CGPoint)aPoint
{ {
return [_tableView columnAtPoint:CGPointMake(aPoint.x, 0)]; return [_tableView columnAtPoint:CGPointMake(aPoint.x, aPoint.y)];
} }
- (CGRect)headerRectOfColumn:(int)aColumnIndex - (CGRect)headerRectOfColumn:(int)aColumnIndex
{ {
var tableColumns = [_tableView tableColumns]; var headerRect = [self bounds],
columnRect = [_tableView rectOfColumn:aColumnIndex];
if (aColumnIndex < 0 || aColumnIndex > [tableColumns count]) headerRect.origin.x = CPRectGetMinX(columnRect);
[CPException raise:"invalid" reason:"tried to get headerRectOfColumn: on invalid column"]; headerRect.size.width = CPRectGetWidth(columnRect);
// UPDATE COLUMN RANGES ? return headerRect;
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;
} }
- (CGRect)_cursorRectForColumn:(int)column - (CGRect)_cursorRectForColumn:(int)column
@@ -236,104 +235,280 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal
- (void)mouseDown:(CPEvent)theEvent - (void)mouseDown:(CPEvent)theEvent
{ {
var mouseLocation = [self convertPoint:[theEvent locationInWindow] fromView:nil], [self trackMouse:theEvent];
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];
}
} }
- (void)trackMouseWithEvent:(CPEvent)theEvent - (void)trackMouse:(CPEvent)theEvent
{ {
var type = [theEvent type]; var type = [theEvent type],
currentLocation = [self convertPoint:[theEvent locationInWindow] fromView:nil];
if (type == CPLeftMouseUp) // Take the right columns resize tracking area into account
{ currentLocation.x -= 5.0;
var location = [self convertPoint:[theEvent locationInWindow] fromView:nil],
clickedColumn = [self columnAtPoint:location];
[self _setPressedColumn:-1]; var columnIndex = [self columnAtPoint:currentLocation],
shouldResize = [self shouldResizeTableColumn:columnIndex at:CPPointMake(currentLocation.x + 5.0, currentLocation.y)];
if (clickedColumn != -1)
[_tableView _didClickTableColumn:clickedColumn modifierFlags:[theEvent modifierFlags]];
return;
}
[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];
if (type === CPLeftMouseUp) if (type === CPLeftMouseUp)
{ {
[self _updateResizeCursor:anEvent]; 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];
[tableColumn _postDidResizeNotificationWithOldWidth:_columnOldWidth]; _isTrackingColumn = NO;
[tableColumn setDisableResizingPosting:NO]; }
[_tableView setDisableAutomaticResizing:NO];
_resizedColumn = -1; [self _updateResizeCursor:[CPApp currentEvent]];
_lastLocation = nil;
_columnOldWidth = nil;
_activeColumn = CPNotFound;
return; return;
} }
if (type === CPLeftMouseDown)
{
if (columnIndex === -1)
return;
_mouseDownLocation = currentLocation;
_activeColumn = columnIndex;
[_tableView _sendDelegateDidMouseDownInHeader:columnIndex];
if (shouldResize)
[self startResizingTableColumn:columnIndex at:currentLocation];
else
{
[self startTrackingTableColumn:columnIndex at:currentLocation];
_isTrackingColumn = YES;
}
}
else if (type === CPLeftMouseDragged) else if (type === CPLeftMouseDragged)
{ {
var newWidth = [tableColumn width] + location.x - _lastLocation.x; if (shouldResize)
[self continueResizingTableColumn:_activeColumn at:currentLocation];
if (newWidth < [tableColumn minWidth])
[[CPCursor resizeRightCursor] set];
else if (newWidth > [tableColumn maxWidth])
[[CPCursor resizeLeftCursor] set];
else else
{ {
_tableView._lastColumnShouldSnap = NO; if (_activeColumn === columnIndex && CPRectContainsPoint([self headerRectOfColumn:columnIndex], currentLocation))
[tableColumn setWidth:newWidth]; {
// FIXME: there has to be a better way to do this... if (_isTrackingColumn && _pressedColumn !== -1)
// We should refactor the auto resizing crap. {
// We need to figure out the exact cocoa behavior here though. if (![self continueTrackingTableColumn:columnIndex at:currentLocation])
_lastLocation = location; return; // Stop tracking the column, because it's being dragged
} else
[self startTrackingTableColumn:columnIndex at:currentLocation];
[[CPCursor resizeLeftRightCursor] set]; } else if (_isTrackingColumn && _pressedColumn !== -1)
[self setNeedsLayout]; [self stopTrackingTableColumn:_activeColumn at:currentLocation];
[self setNeedsDisplay:YES];
} }
} }
[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 - (void)_updateResizeCursor:(CPEvent)theEvent
@@ -365,12 +540,6 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal
[[CPCursor arrowCursor] set]; [[CPCursor arrowCursor] set];
} }
- (void)viewDidMoveToWindow
{
//if ([_tableView allowsColumnResizing])
// [[self window] setAcceptsMouseMovedEvents:YES];
}
- (void)mouseEntered:(CPEvent)theEvent - (void)mouseEntered:(CPEvent)theEvent
{ {
[self _updateResizeCursor:theEvent]; [self _updateResizeCursor:theEvent];
@@ -450,26 +619,11 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal
CGContextClosePath(context); CGContextClosePath(context);
CGContextStrokePath(context); CGContextStrokePath(context);
/* if (_isDragging)
var maxY = CGRectGetMaxY([self bounds]);
// draw normal gradient for remaining space
if (supportsCanvasGradient)
{ {
aRect.origin.x = columnMaxX - 0.5; CGContextSetFillColor(context, [CPColor grayColor]);
aRect.size.width -= columnMaxX; CGContextFillRect(context, [self headerRectOfColumn:_activeColumn])
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);
*/
} }
@end @end
@@ -496,4 +650,3 @@ var CPTableHeaderViewTableViewKey = @"CPTableHeaderViewTableViewKey";
} }
@end @end
+233 -122
View File
@@ -86,7 +86,7 @@ CPTableViewSolidVerticalGridLineMask = 1 << 0;
CPTableViewSolidHorizontalGridLineMask = 1 << 1; CPTableViewSolidHorizontalGridLineMask = 1 << 1;
CPTableViewNoColumnAutoresizing = 0; CPTableViewNoColumnAutoresizing = 0;
CPTableViewUniformColumnAutoresizingStyle = 1; CPTableViewUniformColumnAutoresizingStyle = 1; // FIX ME: This is FUBAR
CPTableViewSequentialColumnAutoresizingStyle = 2; CPTableViewSequentialColumnAutoresizingStyle = 2;
CPTableViewReverseSequentialColumnAutoresizingStyle = 3; CPTableViewReverseSequentialColumnAutoresizingStyle = 3;
CPTableViewLastColumnOnlyAutoresizingStyle = 4; CPTableViewLastColumnOnlyAutoresizingStyle = 4;
@@ -212,6 +212,9 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
CPGradient _sourceListActiveGradient; CPGradient _sourceListActiveGradient;
CPColor _sourceListActiveTopLineColor; CPColor _sourceListActiveTopLineColor;
CPColor _sourceListActiveBottomLineColor; CPColor _sourceListActiveBottomLineColor;
int _draggedColumnIndex;
/* /*
CPGradient _sourceListInactiveGradient; CPGradient _sourceListInactiveGradient;
CPColor _sourceListInactiveTopLineColor; CPColor _sourceListInactiveTopLineColor;
@@ -232,7 +235,6 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
_allowsEmptySelection = YES; _allowsEmptySelection = YES;
_allowsColumnSelection = NO; _allowsColumnSelection = NO;
_disableAutomaticResizing = NO; _disableAutomaticResizing = NO;
_tableViewFlags = 0;
//Setting Display Attributes //Setting Display Attributes
_selectionHighlightStyle = CPTableViewSelectionHighlightStyleRegular; _selectionHighlightStyle = CPTableViewSelectionHighlightStyleRegular;
@@ -245,28 +247,13 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
_dirtyTableColumnRangeIndex = CPNotFound; _dirtyTableColumnRangeIndex = CPNotFound;
_numberOfHiddenColumns = 0; _numberOfHiddenColumns = 0;
_objectValues = { };
_dataViewsForTableColumns = { };
_dataViews= [];
_numberOfRows = 0;
_exposedRows = [CPIndexSet indexSet];
_exposedColumns = [CPIndexSet indexSet];
_cachedDataViews = { };
_intercellSpacing = _CGSizeMake(0.0, 0.0); _intercellSpacing = _CGSizeMake(0.0, 0.0);
_rowHeight = 23.0; _rowHeight = 23.0;
[self setGridColor:[CPColor colorWithHexString:@"dce0e2"]]; [self setGridColor:[CPColor colorWithHexString:@"dce0e2"]];
[self setGridStyleMask:CPTableViewGridNone]; [self setGridStyleMask:CPTableViewGridNone];
_headerView = [[CPTableHeaderView alloc] initWithFrame:CGRectMake(0, 0, [self bounds].size.width, _rowHeight)];
[_headerView setTableView:self];
_cornerView = [[_CPCornerView alloc] initWithFrame:CGRectMake(0, 0, [CPScroller scrollerWidth], CGRectGetHeight([_headerView frame]))];
_lastSelectedRow = -1; _lastSelectedRow = -1;
_selectedColumnIndexes = [CPIndexSet indexSet];
_selectedRowIndexes = [CPIndexSet indexSet];
_currentHighlightedTableColumn = nil; _currentHighlightedTableColumn = nil;
_sortDescriptors = [CPArray array]; _sortDescriptors = [CPArray array];
@@ -279,10 +266,6 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
_dragOperationDefaultMask = nil; _dragOperationDefaultMask = nil;
_destinationDragStyle = CPTableViewDraggingDestinationFeedbackStyleRegular; _destinationDragStyle = CPTableViewDraggingDestinationFeedbackStyleRegular;
_tableDrawView = [[_CPTableDrawView alloc] initWithTableView:self];
[_tableDrawView setBackgroundColor:[CPColor clearColor]];
[self addSubview:_tableDrawView];
[self setBackgroundColor:[CPColor whiteColor]]; [self setBackgroundColor:[CPColor whiteColor]];
[self _init]; [self _init];
} }
@@ -293,11 +276,45 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
// FIX ME: we have a lot of redundent init stuff in initWithFrame: and initWithCoder: we should move it all into here. // FIX ME: we have a lot of redundent init stuff in initWithFrame: and initWithCoder: we should move it all into here.
- (void)_init - (void)_init
{ {
_tableViewFlags = 0;
_selectedColumnIndexes = [CPIndexSet indexSet];
_selectedRowIndexes = [CPIndexSet indexSet];
_dropOperationFeedbackView = [[_CPDropOperationDrawingView alloc] initWithFrame:_CGRectMakeZero()]; _dropOperationFeedbackView = [[_CPDropOperationDrawingView alloc] initWithFrame:_CGRectMakeZero()];
[_dropOperationFeedbackView setTableView:self]; [_dropOperationFeedbackView setTableView:self];
_lastColumnShouldSnap = NO; _lastColumnShouldSnap = NO;
if (!_alternatingRowBackgroundColors)
_alternatingRowBackgroundColors = [[CPColor whiteColor], [CPColor colorWithHexString:@"e4e7ff"]];
_tableColumnRanges = [];
_dirtyTableColumnRangeIndex = 0;
_numberOfHiddenColumns = 0;
_objectValues = { };
_dataViewsForTableColumns = { };
_dataViews= [];
_numberOfRows = 0;
_exposedRows = [CPIndexSet indexSet];
_exposedColumns = [CPIndexSet indexSet];
_cachedDataViews = { };
_tableDrawView = [[_CPTableDrawView alloc] initWithTableView:self];
[_tableDrawView setBackgroundColor:[CPColor clearColor]];
[self addSubview:_tableDrawView];
if (!_headerView)
_headerView = [[CPTableHeaderView alloc] initWithFrame:CGRectMake(0, 0, [self bounds].size.width, _rowHeight)];
[_headerView setTableView:self];
if (!_cornerView)
_cornerView = [[_CPCornerView alloc] initWithFrame:CGRectMake(0, 0, [CPScroller scrollerWidth], CGRectGetHeight([_headerView frame]))];
_draggedColumnIndex = -1;
// Gradients for the source list // Gradients for the source list
_sourceListActiveGradient = CGGradientCreateWithColorComponents(CGColorSpaceCreateDeviceRGB(), [89.0/255.0, 153.0/255.0, 209.0/255.0,1.0, 33.0/255.0, 94.0/255.0, 208.0/255.0,1.0], [0,1], 2); _sourceListActiveGradient = CGGradientCreateWithColorComponents(CGColorSpaceCreateDeviceRGB(), [89.0/255.0, 153.0/255.0, 209.0/255.0,1.0, 33.0/255.0, 94.0/255.0, 208.0/255.0,1.0], [0,1], 2);
_sourceListActiveTopLineColor = [CPColor colorWithCalibratedRed:(61.0/255.0) green:(123.0/255.0) blue:(218.0/255.0) alpha:1.0]; _sourceListActiveTopLineColor = [CPColor colorWithCalibratedRed:(61.0/255.0) green:(123.0/255.0) blue:(218.0/255.0) alpha:1.0];
@@ -660,6 +677,15 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
[self setNeedsLayout]; [self setNeedsLayout];
} }
- (void)_setDraggedColumn:(int)aColumnIndex
{
if (_draggedColumnIndex === aColumnIndex)
return;
_draggedColumnIndex = aColumnIndex;
[self reloadDataForRowIndexes:_exposedRows columnIndexes:[CPIndexSet indexSetWithIndex:aColumnIndex]];
}
/*! /*!
Moves the column and heading at a given index to a new given index. Moves the column and heading at a given index to a new given index.
@@ -679,15 +705,37 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
else else
_dirtyTableColumnRangeIndex = MIN(fromIndex, toIndex, _dirtyTableColumnRangeIndex); _dirtyTableColumnRangeIndex = MIN(fromIndex, toIndex, _dirtyTableColumnRangeIndex);
if (toIndex > fromIndex)
--toIndex;
var tableColumn = _tableColumns[fromIndex]; var tableColumn = _tableColumns[fromIndex];
[_tableColumns removeObjectAtIndex:fromIndex]; [_tableColumns removeObjectAtIndex:fromIndex];
[_tableColumns insertObject:tableColumn atIndex:toIndex]; [_tableColumns insertObject:tableColumn atIndex:toIndex];
[self setNeedsLayout]; [[self headerView] setNeedsLayout];
[[self headerView] setNeedsDisplay:YES];
var rowIndexes = [CPIndexSet indexSetWithIndexesInRange:CPMakeRange(0, [self numberOfRows])],
columnIndexes = [CPIndexSet indexSetWithIndexesInRange:CPMakeRange(fromIndex, toIndex)];
[self reloadDataForRowIndexes:rowIndexes columnIndexes:columnIndexes];
}
/*!
@ignore
*/
- (void)_tableColumnVisibilityDidChange:(CPTableColumn)aColumn
{
var columnIndex = [[self tableColumns] indexOfObjectIdenticalTo:aColumn];
if (_dirtyTableColumnRangeIndex < 0)
_dirtyTableColumnRangeIndex = columnIndex;
else
_dirtyTableColumnRangeIndex = MIN(columnIndex, _dirtyTableColumnRangeIndex);
[[self headerView] setNeedsLayout];
[[self headerView] setNeedsDisplay:YES];
var rowIndexes = [CPIndexSet indexSetWithIndexesInRange:CPMakeRange(0, [self numberOfRows])];
[self reloadDataForRowIndexes:rowIndexes columnIndexes:[CPIndexSet indexSetWithIndex:columnIndex]];
} }
- (CPArray)tableColumns - (CPArray)tableColumns
@@ -805,22 +853,22 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
var count = deselectRows.length; var count = deselectRows.length;
while (count--) while (count--)
{ [self _performSelection:NO forRow:deselectRows[count] context:dataViewsInTableColumn];
var rowIndex = deselectRows[count];
var view = dataViewsInTableColumn[rowIndex];
[view unsetThemeState:CPThemeStateSelected];
}
count = selectRows.length; count = selectRows.length;
while (count--) while (count--)
{ [self _performSelection:YES forRow:selectRows[count] context:dataViewsInTableColumn];
var rowIndex = selectRows[count];
var view = dataViewsInTableColumn[rowIndex];
[view setThemeState:CPThemeStateSelected];
}
} }
} }
- (void)_performSelection:(BOOL)select forRow:(CPInteger)rowIndex context:(id)context
{
var view = context[rowIndex],
selector = select ? @"setThemeState:" : @"unsetThemeState:";
[view performSelector:CPSelectorFromString(selector) withObject:CPThemeStateSelected];
}
- (void)_updateHighlightWithOldColumns:(CPIndexSet)oldColumns newColumns:(CPIndexSet)newColumns - (void)_updateHighlightWithOldColumns:(CPIndexSet)oldColumns newColumns:(CPIndexSet)newColumns
{ {
var firstExposedColumn = [_exposedColumns firstIndex], var firstExposedColumn = [_exposedColumns firstIndex],
@@ -1044,6 +1092,8 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
if (_dirtyTableColumnRangeIndex < 0) if (_dirtyTableColumnRangeIndex < 0)
return; return;
_numberOfHiddenColumns = 0;
var index = _dirtyTableColumnRangeIndex, var index = _dirtyTableColumnRangeIndex,
count = NUMBER_OF_COLUMNS(), count = NUMBER_OF_COLUMNS(),
x = index === 0 ? 0.0 : CPMaxRange(_tableColumnRanges[index - 1]); x = index === 0 ? 0.0 : CPMaxRange(_tableColumnRanges[index - 1]);
@@ -1053,7 +1103,10 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
var tableColumn = _tableColumns[index]; var tableColumn = _tableColumns[index];
if ([tableColumn isHidden]) if ([tableColumn isHidden])
{
_numberOfHiddenColumns += 1;
_tableColumnRanges[index] = CPMakeRange(x, 0.0); _tableColumnRanges[index] = CPMakeRange(x, 0.0);
}
else else
{ {
@@ -1075,7 +1128,9 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
{ {
aColumnIndex = +aColumnIndex; aColumnIndex = +aColumnIndex;
if (aColumnIndex < 0 || aColumnIndex >= NUMBER_OF_COLUMNS()) var column = [[self tableColumns] objectAtIndex:aColumnIndex];
if ([column isHidden] || aColumnIndex < 0 || aColumnIndex >= NUMBER_OF_COLUMNS())
return _CGRectMakeZero(); return _CGRectMakeZero();
UPDATE_COLUMN_RANGES_IF_NECESSARY(); UPDATE_COLUMN_RANGES_IF_NECESSARY();
@@ -1228,7 +1283,6 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
return _CGRectMake(tableColumnRange.location, _CGRectGetMinY(rectOfRow), tableColumnRange.length, _CGRectGetHeight(rectOfRow)); return _CGRectMake(tableColumnRange.location, _CGRectGetMinY(rectOfRow), tableColumnRange.length, _CGRectGetHeight(rectOfRow));
} }
//FIX ME: We should refactor this!
- (void)resizeWithOldSuperviewSize:(CGSize)aSize - (void)resizeWithOldSuperviewSize:(CGSize)aSize
{ {
[super resizeWithOldSuperviewSize:aSize]; [super resizeWithOldSuperviewSize:aSize];
@@ -1239,57 +1293,53 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
var mask = _columnAutoResizingStyle; var mask = _columnAutoResizingStyle;
if(mask === CPTableViewUniformColumnAutoresizingStyle) if(mask === CPTableViewUniformColumnAutoresizingStyle)
{
[self _resizeAllColumnUniformlyWithOldSize:aSize]; [self _resizeAllColumnUniformlyWithOldSize:aSize];
} else if(mask === CPTableViewLastColumnOnlyAutoresizingStyle)
if(mask === CPTableViewLastColumnOnlyAutoresizingStyle)
{
[self sizeLastColumnToFit]; [self sizeLastColumnToFit];
} else if(mask === CPTableViewFirstColumnOnlyAutoresizingStyle)
[self _autoResizeFirstColumn];
}
if(mask === CPTableViewFirstColumnOnlyAutoresizingStyle) - (void)_autoResizeFirstColumn
{ {
var superview = [self superview]; var superview = [self superview];
if (!superview) if (!superview)
return; return;
var superviewSize = [superview bounds].size; var superviewSize = [superview bounds].size;
UPDATE_COLUMN_RANGES_IF_NECESSARY(); UPDATE_COLUMN_RANGES_IF_NECESSARY();
var count = NUMBER_OF_COLUMNS(); var count = NUMBER_OF_COLUMNS(),
visColumns = [[CPArray alloc] init],
totalWidth = 0,
i = 0;
var visColumns = [[CPArray alloc] init]; for(; i < count; i++)
var totalWidth = 0; {
if(![_tableColumns[i] isHidden])
{
[visColumns addObject:i];
totalWidth += [_tableColumns[i] width];
}
}
for(var i=0; i < count; i++) count = [visColumns count];
{
if(![_tableColumns[i] isHidden])
{
[visColumns addObject:i];
totalWidth += [_tableColumns[i] width];
}
}
count = [visColumns count]; //if there are rows
if (count > 0)
{
var columnToResize = _tableColumns[visColumns[0]];
var newWidth = superviewSize.width - totalWidth;// - [columnToResize width];
newWidth += [columnToResize width];
newWidth = (newWidth < [columnToResize minWidth]) ? [columnToResize minWidth] : newWidth;
newWidth = (newWidth > [columnToResize maxWidth]) ? [columnToResize maxWidth] : newWidth;
//if there are rows [columnToResize setWidth:FLOOR(newWidth)];
if (count > 0) }
{
var columnToResize = _tableColumns[visColumns[0]];
var newWidth = superviewSize.width - totalWidth;// - [columnToResize width];
newWidth += [columnToResize width];
newWidth = (newWidth < [columnToResize minWidth]) ? [columnToResize minWidth] : newWidth;
newWidth = (newWidth > [columnToResize maxWidth]) ? [columnToResize maxWidth] : newWidth;
[columnToResize setWidth:FLOOR(newWidth)];
}
[self setNeedsLayout];
}
[self setNeedsLayout];
} }
- (void)_resizeAllColumnUniformlyWithOldSize:(CGSize)oldSize - (void)_resizeAllColumnUniformlyWithOldSize:(CGSize)oldSize
@@ -1768,7 +1818,7 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
return [[CPImage alloc] initWithContentsOfFile:@"Frameworks/AppKit/Resources/GenericFile.png" size:CGSizeMake(32,32)]; return [[CPImage alloc] initWithContentsOfFile:@"Frameworks/AppKit/Resources/GenericFile.png" size:CGSizeMake(32,32)];
} }
- (CPView)dragViewForRowsWithIndexes:(CPIndexSet)theDraggedRows tableColumns:(CPArray)theTableColumns event:(CPEvent)theDragEvent offset:(CPPoint)dragViewOffset - (CPView)dragViewForRowsWithIndexes:(CPIndexSet)theDraggedRows tableColumns:(CPArray)theTableColumns event:(CPEvent)theDragEvent offset:(CPPointPointer)dragViewOffset
{ {
var bounds = [self bounds], var bounds = [self bounds],
view = [[CPView alloc] initWithFrame:bounds]; view = [[CPView alloc] initWithFrame:bounds];
@@ -1804,6 +1854,55 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
return view; return view;
} }
/*!
@ignore
// Fetches all the data views (from the datasource) for the column and it's visible rows
// Copy the dataviews add them to a transparent drag view and use that drag view
// to make it appear we are dragging images of those rows (as you would do in regular Cocoa)
*/
- (CPView)_dragViewForColumn:(int)theColumnIndex event:(CPEvent)theDragEvent offset:(CPPointPointer)theDragViewOffset
{
var dragView = [[CPView alloc] initWithFrame:CPRectMakeZero()];
tableColumn = [[self tableColumns] objectAtIndex:theColumnIndex],
bounds = CPRectMake(0.0, 0.0, [tableColumn width], CPRectGetHeight([self _exposedRect]) + 23.0),
columnRect = [self rectOfColumn:theColumnIndex],
headerView = [tableColumn headerView];
row = [_exposedRows firstIndex];
while (row !== CPNotFound)
{
var dataView = [self _newDataViewForRow:row tableColumn:tableColumn],
dataViewFrame = [self frameOfDataViewAtColumn:theColumnIndex row:row];
// Only one column is ever dragged so we just place the view at
dataViewFrame.origin.x = 0.0;
// Offset by table header height - scroll position
dataViewFrame.origin.y = ( CPRectGetMinY(dataViewFrame) - CPRectGetMinY([self _exposedRect]) ) + 23.0;
[dataView setFrame:dataViewFrame];
[dataView setObjectValue:[self _objectValueForTableColumn:tableColumn row:row]];
[dragView addSubview:dataView];
row = [_exposedRows indexGreaterThanIndex:row];
}
// Add the column header view
var headerFrame = [headerView frame];
headerFrame.origin = CPPointMakeZero();
columnHeaderView = [[_CPTableColumnHeaderView alloc] initWithFrame:headerFrame];
[columnHeaderView setStringValue:[headerView stringValue]];
[columnHeaderView setThemeState:[headerView themeState]];
[dragView addSubview:columnHeaderView];
[dragView setBackgroundColor:[CPColor whiteColor]];
[dragView setAlphaValue:0.7];
[dragView setFrame:bounds];
return dragView;
}
- (void)setDraggingSourceOperationMask:(CPDragOperation)mask forLocal:(BOOL)isLocal - (void)setDraggingSourceOperationMask:(CPDragOperation)mask forLocal:(BOOL)isLocal
{ {
//ignoral local for the time being since only one capp app can run at a time... //ignoral local for the time being since only one capp app can run at a time...
@@ -2044,8 +2143,12 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
for (; columnIndex < columnsCount; ++columnIndex) for (; columnIndex < columnsCount; ++columnIndex)
{ {
var column = columnArray[columnIndex], var column = columnArray[columnIndex],
tableColumn = _tableColumns[column], tableColumn = _tableColumns[column];
tableColumnUID = [tableColumn UID];
if ([tableColumn isHidden] || columnIndex === _draggedColumnIndex)
continue;
var tableColumnUID = [tableColumn UID];
if (!_dataViewsForTableColumns[tableColumnUID]) if (!_dataViewsForTableColumns[tableColumnUID])
_dataViewsForTableColumns[tableColumnUID] = []; _dataViewsForTableColumns[tableColumnUID] = [];
@@ -2158,6 +2261,9 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
- (void)_enqueueReusableDataView:(CPView)aDataView - (void)_enqueueReusableDataView:(CPView)aDataView
{ {
if (!aDataView)
return;
// FIXME: yuck! // FIXME: yuck!
var identifier = aDataView.identifier; var identifier = aDataView.identifier;
@@ -2195,6 +2301,15 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
[self drawBackgroundInClipRect:exposedRect]; [self drawBackgroundInClipRect:exposedRect];
[self drawGridInClipRect:exposedRect]; [self drawGridInClipRect:exposedRect];
[self highlightSelectionInClipRect:exposedRect]; [self highlightSelectionInClipRect:exposedRect];
if (_draggedColumnIndex === -1)
return;
var context = [[CPGraphicsContext currentContext] graphicsPort],
columnRect = [self rectOfColumn:_draggedColumnIndex];
CGContextSetFillColor(context, [CPColor grayColor]);
CGContextFillRect(context, columnRect);
} }
- (void)drawBackgroundInClipRect:(CGRect)aRect - (void)drawBackgroundInClipRect:(CGRect)aRect
@@ -2202,7 +2317,6 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
if (!_usesAlternatingRowBackgroundColors) if (!_usesAlternatingRowBackgroundColors)
return; return;
var rowColors = [self alternatingRowBackgroundColors], var rowColors = [self alternatingRowBackgroundColors],
colorCount = [rowColors count]; colorCount = [rowColors count];
@@ -2340,6 +2454,9 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
- (void)highlightSelectionInClipRect:(CGRect)aRect - (void)highlightSelectionInClipRect:(CGRect)aRect
{ {
if (_selectionHighlightStyle === CPTableViewDraggingDestinationFeedbackStyleNone)
return;
var context = [[CPGraphicsContext currentContext] graphicsPort], var context = [[CPGraphicsContext currentContext] graphicsPort],
indexes = [], indexes = [],
rectSelector = @selector(rectOfRow:); rectSelector = @selector(rectOfRow:);
@@ -2369,9 +2486,8 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
if (!count) if (!count)
return; return;
var drawGradient = (_selectionHighlightStyle === CPTableViewSelectionHighlightStyleSourceList && [_selectedRowIndexes count] >= 1); var drawGradient = (_selectionHighlightStyle === CPTableViewSelectionHighlightStyleSourceList && [_selectedRowIndexes count] >= 1),
deltaHeight = 0.5 * (_gridStyleMask & CPTableViewSolidHorizontalGridLineMask);
var deltaHeight = 0.5 * (_gridStyleMask & CPTableViewSolidHorizontalGridLineMask);
CGContextBeginPath(context); CGContextBeginPath(context);
while (count--) while (count--)
@@ -2434,10 +2550,9 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
for(var c = firstExposedColumn; c < exposedColumnCount; c++) for(var c = firstExposedColumn; c < exposedColumnCount; c++)
{ {
//console.log(columnIndexes);
var colRect = [self rectOfColumn:exposedColumnIndexes[c]], var colRect = [self rectOfColumn:exposedColumnIndexes[c]],
colX = CGRectGetMaxX(colRect) + 0.5; colX = CGRectGetMaxX(colRect) + 0.5;
//console.log(colX);
CGContextMoveToPoint(context, colX, minY); CGContextMoveToPoint(context, colX, minY);
CGContextAddLineToPoint(context, colX, maxY); CGContextAddLineToPoint(context, colX, maxY);
} }
@@ -2561,7 +2676,10 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
{ {
// Prevent CPControl from eating the mouse events when we are in a drag session // Prevent CPControl from eating the mouse events when we are in a drag session
if (![_draggedRowIndexes count]) if (![_draggedRowIndexes count])
{
[self autoscroll:anEvent];
[super trackMouse:anEvent]; [super trackMouse:anEvent];
}
else else
[CPApp sendEvent:anEvent]; [CPApp sendEvent:anEvent];
} }
@@ -2875,13 +2993,6 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
[_dropOperationFeedbackView setCurrentRow:row]; [_dropOperationFeedbackView setCurrentRow:row];
[self addSubview:_dropOperationFeedbackView]; [self addSubview:_dropOperationFeedbackView];
// FIXME : Maybe we should do this in a timer outside this method.
// Problem: we don't know when the scroll ends or when the next -draggingUpdated is called.
if (row > 0 && location.y - CGRectGetMinY(exposedClipRect) < _rowHeight)
[self scrollRowToVisible:row - 1];
else if (row < numberOfRows && CGRectGetMaxY(exposedClipRect) - location.y < _rowHeight)
[self scrollRowToVisible:row + 1];
return dragOperation; return dragOperation;
} }
@@ -3049,7 +3160,7 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
- (void)keyDown:(CPEvent)anEvent - (void)keyDown:(CPEvent)anEvent
{ {
[self interpretKeyEvents:[CPArray arrayWithObject:anEvent]]; [self interpretKeyEvents:[anEvent]];
} }
- (void)moveDown:(id)sender - (void)moveDown:(id)sender
@@ -3187,34 +3298,18 @@ var CPTableViewDataSourceKey = @"CPTableViewDataSourceKey",
_allowsEmptySelection = [aCoder decodeBoolForKey:CPTableViewEmptySelectionKey]; _allowsEmptySelection = [aCoder decodeBoolForKey:CPTableViewEmptySelectionKey];
_allowsColumnSelection = [aCoder decodeBoolForKey:CPTableViewColumnSelectionKey]; _allowsColumnSelection = [aCoder decodeBoolForKey:CPTableViewColumnSelectionKey];
_tableViewFlags = 0;
//Setting Display Attributes //Setting Display Attributes
_selectionHighlightStyle = CPTableViewSelectionHighlightStyleRegular; _selectionHighlightStyle = CPTableViewSelectionHighlightStyleRegular;
_usesAlternatingRowBackgroundColors = [aCoder decodeBoolForKey:CPTableViewUsesAlternatingBackgroundKey]; _tableColumns = [aCoder decodeObjectForKey:CPTableViewTableColumnsKey] || [];
[self setAlternatingRowBackgroundColors:[[CPColor whiteColor], [CPColor colorWithHexString:@"e4e7ff"]]];
_tableColumns = [aCoder decodeObjectForKey:CPTableViewTableColumnsKey];
[_tableColumns makeObjectsPerformSelector:@selector(setTableView:) withObject:self]; [_tableColumns makeObjectsPerformSelector:@selector(setTableView:) withObject:self];
_tableColumnRanges = []; if ([aCoder containsValueForKey:CPTableViewRowHeightKey])
_dirtyTableColumnRangeIndex = 0; _rowHeight = [aCoder decodeFloatForKey:CPTableViewRowHeightKey];
_numberOfHiddenColumns = 0;
_objectValues = { };
_dataViewsForTableColumns = { };
_dataViews= [];
_numberOfRows = 0;
_exposedRows = [CPIndexSet indexSet];
_exposedColumns = [CPIndexSet indexSet];
_cachedDataViews = { };
_rowHeight = [aCoder decodeFloatForKey:CPTableViewRowHeightKey];
if ([aCoder containsValueForKey:CPTableViewIntercellSpacingKey])
_intercellSpacing = [aCoder decodeSizeForKey:CPTableViewIntercellSpacingKey];
else else
_intercellSpacing = _CGSizeMake(0.0, 0.0); _rowHeight = 23.0;
_intercellSpacing = [aCoder decodeSizeForKey:CPTableViewIntercellSpacingKey] || _CGSizeMake(0.0, 0.0);
_gridColor = [aCoder decodeObjectForKey:CPTableViewGridColorKey] || [CPColor grayColor]; _gridColor = [aCoder decodeObjectForKey:CPTableViewGridColorKey] || [CPColor grayColor];
_gridStyleMask = [aCoder decodeIntForKey:CPTableViewGridStyleMaskKey] || CPTableViewGridNone; _gridStyleMask = [aCoder decodeIntForKey:CPTableViewGridStyleMaskKey] || CPTableViewGridNone;
@@ -3225,15 +3320,9 @@ var CPTableViewDataSourceKey = @"CPTableViewDataSourceKey",
_headerView = [aCoder decodeObjectForKey:CPTableViewHeaderViewKey]; _headerView = [aCoder decodeObjectForKey:CPTableViewHeaderViewKey];
_cornerView = [aCoder decodeObjectForKey:CPTableViewCornerViewKey]; _cornerView = [aCoder decodeObjectForKey:CPTableViewCornerViewKey];
_selectedColumnIndexes = [CPIndexSet indexSet];
_selectedRowIndexes = [CPIndexSet indexSet];
_dataSource = [aCoder decodeObjectForKey:CPTableViewDataSourceKey]; _dataSource = [aCoder decodeObjectForKey:CPTableViewDataSourceKey];
_delegate = [aCoder decodeObjectForKey:CPTableViewDelegateKey]; _delegate = [aCoder decodeObjectForKey:CPTableViewDelegateKey];
_tableDrawView = [[_CPTableDrawView alloc] initWithTableView:self];
[_tableDrawView setBackgroundColor:[CPColor clearColor]];
[self addSubview:_tableDrawView];
[self _init]; [self _init];
[self viewWillMoveToSuperview:[self superview]]; [self viewWillMoveToSuperview:[self superview]];
@@ -3314,11 +3403,12 @@ var CPTableViewDataSourceKey = @"CPTableViewDataSourceKey",
unsigned dropOperation @accessors; unsigned dropOperation @accessors;
CPTableView tableView @accessors; CPTableView tableView @accessors;
int currentRow @accessors; int currentRow @accessors;
BOOL isBlinking @accessors;
} }
- (void)drawRect:(CGRect)aRect - (void)drawRect:(CGRect)aRect
{ {
if(tableView._destinationDragStyle === CPTableViewDraggingDestinationFeedbackStyleNone) if(tableView._destinationDragStyle === CPTableViewDraggingDestinationFeedbackStyleNone || isBlinking)
return; return;
var context = [[CPGraphicsContext currentContext] graphicsPort]; var context = [[CPGraphicsContext currentContext] graphicsPort];
@@ -3384,7 +3474,28 @@ var CPTableViewDataSourceKey = @"CPTableViewDataSourceKey",
CGContextStrokePath(context); CGContextStrokePath(context);
//CGContextStrokeLineSegments(context, [aRect.origin.x + 8, aRect.origin.y + 8, 300 , aRect.origin.y + 8]); //CGContextStrokeLineSegments(context, [aRect.origin.x + 8, aRect.origin.y + 8, 300 , aRect.origin.y + 8]);
} }
}
- (void)blink
{
if (dropOperation !== CPTableViewDropOn)
return;
isBlinking = YES;
var showCallback = function() {
objj_msgSend(self, "setHidden:", NO)
isBlinking = NO;
}
var hideCallback = function() {
objj_msgSend(self, "setHidden:", YES)
isBlinking = YES;
}
objj_msgSend(self, "setHidden:", YES);
[CPTimer scheduledTimerWithTimeInterval:0.1 callback:showCallback repeats:NO];
[CPTimer scheduledTimerWithTimeInterval:0.19 callback:hideCallback repeats:NO];
[CPTimer scheduledTimerWithTimeInterval:0.27 callback:showCallback repeats:NO];
} }
@end @end
+17 -1
View File
@@ -997,7 +997,7 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
return bounds; return bounds;
} }
- (CGRect)bezelRectForBounds:(CFRect)bounds - (CGRect)bezelRectForBounds:(CGRect)bounds
{ {
var bezelInset = [self currentValueForThemeAttribute:@"bezel-inset"]; 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 @end
var secureStringForString = function(aString) var secureStringForString = function(aString)
+3 -4
View File
@@ -449,6 +449,9 @@ CPToolbarItemVisibilityPriorityUser
- (void)validate - (void)validate
{ {
var action = [self action],
target = [self target];
// View items do not do any target-action analysis. // View items do not do any target-action analysis.
if (_view) if (_view)
{ {
@@ -458,13 +461,9 @@ CPToolbarItemVisibilityPriorityUser
return; return;
} }
var action = [self action];
if (!action) if (!action)
return [self setEnabled:NO]; return [self setEnabled:NO];
var target = [self target];
if (target && ![target respondsToSelector:action]) if (target && ![target respondsToSelector:action])
return [self setEnabled:NO]; return [self setEnabled:NO];
+45 -20
View File
@@ -94,7 +94,8 @@ var DOMElementPrototype = nil,
BackgroundTrivialColor = 0, BackgroundTrivialColor = 0,
BackgroundVerticalThreePartImage = 1, BackgroundVerticalThreePartImage = 1,
BackgroundHorizontalThreePartImage = 2, BackgroundHorizontalThreePartImage = 2,
BackgroundNinePartImage = 3; BackgroundNinePartImage = 3,
BackgroundTransparentColor = 4;
#endif #endif
var CPViewFlags = { }, var CPViewFlags = { },
@@ -139,6 +140,7 @@ var CPViewFlags = { },
BOOL _isHidden; BOOL _isHidden;
BOOL _hitTests; BOOL _hitTests;
BOOL _clipsToBounds;
BOOL _postsFrameChangedNotifications; BOOL _postsFrameChangedNotifications;
BOOL _postsBoundsChangedNotifications; BOOL _postsBoundsChangedNotifications;
@@ -277,6 +279,7 @@ var CPViewFlags = { },
_autoresizingMask = CPViewNotSizable; _autoresizingMask = CPViewNotSizable;
_autoresizesSubviews = YES; _autoresizesSubviews = YES;
_clipsToBounds = YES;
_opacity = 1.0; _opacity = 1.0;
_isHidden = NO; _isHidden = NO;
@@ -835,28 +838,33 @@ var CPViewFlags = { },
if (_backgroundType !== BackgroundTrivialColor) if (_backgroundType !== BackgroundTrivialColor)
{ {
var images = [[_backgroundColor patternImage] imageSlices]; if (_backgroundType === BackgroundTransparentColor)
if (_backgroundType === BackgroundVerticalThreePartImage)
{ {
CPDOMDisplayServerSetStyleSize(_DOMImageParts[1], size.width, size.height - _DOMImageSizes[0].height - _DOMImageSizes[2].height); CPDOMDisplayServerSetStyleSize(_DOMImageParts[0], size.width, size.height);
} }
else
else if (_backgroundType === BackgroundHorizontalThreePartImage)
{ {
CPDOMDisplayServerSetStyleSize(_DOMImageParts[1], size.width - _DOMImageSizes[0].width - _DOMImageSizes[2].width, size.height); var images = [[_backgroundColor patternImage] imageSlices];
}
else if (_backgroundType === BackgroundNinePartImage) if (_backgroundType === BackgroundVerticalThreePartImage)
{ {
var width = size.width - _DOMImageSizes[0].width - _DOMImageSizes[2].width, CPDOMDisplayServerSetStyleSize(_DOMImageParts[1], size.width, size.height - _DOMImageSizes[0].height - _DOMImageSizes[2].height);
height = size.height - _DOMImageSizes[0].height - _DOMImageSizes[6].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[1], width, _DOMImageSizes[0].height);
CPDOMDisplayServerSetStyleSize(_DOMImageParts[3], _DOMImageSizes[3].width, height); CPDOMDisplayServerSetStyleSize(_DOMImageParts[3], _DOMImageSizes[3].width, height);
CPDOMDisplayServerSetStyleSize(_DOMImageParts[4], width, height); CPDOMDisplayServerSetStyleSize(_DOMImageParts[4], width, height);
CPDOMDisplayServerSetStyleSize(_DOMImageParts[5], _DOMImageSizes[5].width, height); CPDOMDisplayServerSetStyleSize(_DOMImageParts[5], _DOMImageSizes[5].width, height);
CPDOMDisplayServerSetStyleSize(_DOMImageParts[7], width, _DOMImageSizes[7].height); CPDOMDisplayServerSetStyleSize(_DOMImageParts[7], width, _DOMImageSizes[7].height);
}
} }
} }
#endif #endif
@@ -1188,6 +1196,23 @@ var CPViewFlags = { },
return _isHidden; 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 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. completely transparent and 1.0 is completely opaque.
@@ -1361,7 +1386,7 @@ var CPViewFlags = { },
} }
else else
{ {
_backgroundType = BackgroundTrivialColor; _backgroundType = colorNeedsDOMElement ? BackgroundTransparentColor : BackgroundTrivialColor;
amount = (colorNeedsDOMElement ? 1 : 0) - _DOMImageParts.length; amount = (colorNeedsDOMElement ? 1 : 0) - _DOMImageParts.length;
} }
@@ -1384,7 +1409,7 @@ var CPViewFlags = { },
_DOMElement.removeChild(_DOMImageParts.pop()); _DOMElement.removeChild(_DOMImageParts.pop());
} }
if (_backgroundType === BackgroundTrivialColor) if (_backgroundType === BackgroundTrivialColor || _backgroundType === BackgroundTransparentColor)
{ {
var colorCSS = colorExists ? [_backgroundColor cssString] : ""; var colorCSS = colorExists ? [_backgroundColor cssString] : "";
+4 -55
View File
@@ -50,7 +50,7 @@ var CPViewControllerCachedCibs;
CPView _view; CPView _view;
id _representedObject @accessors(property=representedObject); id _representedObject @accessors(property=representedObject);
CPString _title; CPString _title @accessors(property=title);
CPString _cibName @accessors(property=cibName, readonly); CPString _cibName @accessors(property=cibName, readonly);
CPBundle _cibBundle @accessors(property=cibBundle, readonly); CPBundle _cibBundle @accessors(property=cibBundle, readonly);
@@ -78,9 +78,7 @@ var CPViewControllerCachedCibs;
- (id)initWithCibName:(CPString)aCibNameOrNil bundle:(CPBundle)aCibBundleOrNil owner:(id)anOwner - (id)initWithCibName:(CPString)aCibNameOrNil bundle:(CPBundle)aCibBundleOrNil owner:(id)anOwner
{ {
return [self initWithCibName:aCibNameOrNil return [self initWithCibName:aCibNameOrNil bundle:aCibBundleOrNil externalNameTable:[CPDictionary dictionaryWithObject:anOwner forKey:CPCibOwner]];
bundle:aCibBundleOrNil
externalNameTable:[CPDictionary dictionaryWithObject:anOwner forKey:CPCibOwner]];
} }
/*! /*!
@@ -99,34 +97,13 @@ var CPViewControllerCachedCibs;
{ {
// Don't load the cib until someone actually requests the view. The user may just be intending to use setView:. // Don't load the cib until someone actually requests the view. The user may just be intending to use setView:.
_cibName = aCibNameOrNil; _cibName = aCibNameOrNil;
_cibBundle = aCibBundleOrNil; _cibBundle = aCibBundleOrNil || [CPBundle mainBundle];
if (!_cibBundle)
{
var owner = [anExternalNameTable objectForKey:CPCibOwner];
_cibBundle = owner ? [CPBundle bundleForClass:[owner class]] : [CPBundle mainBundle];
}
_cibExternalNameTable = anExternalNameTable || [CPDictionary dictionaryWithObject:self forKey:CPCibOwner]; _cibExternalNameTable = anExternalNameTable || [CPDictionary dictionaryWithObject:self forKey:CPCibOwner];
} }
return self; return self;
} }
- (void)setTitle:(CPString)aTitle
{
_title = aTitle;
if (self._navigationItem)
[_navigationItem setTitle:aTitle];
}
- (CPString)title
{
return _title;
}
/*! /*!
Programmatically creates the view that the controller manages. Programmatically creates the view that the controller manages.
You should never call this method directly. The view controller calls this method when the view property is requested but is nil. You should never call this method directly. The view controller calls this method when the view property is requested but is nil.
@@ -147,9 +124,9 @@ var CPViewControllerCachedCibs;
// check if a cib is already cached for the current _cibName // check if a cib is already cached for the current _cibName
var cib = [CPViewControllerCachedCibs objectForKey:_cibName]; var cib = [CPViewControllerCachedCibs objectForKey:_cibName];
// If the cib isn't cached yet : fetch it and cache it
if (!cib) if (!cib)
{ {
// if the cib isn't cached yet : fetch it and cache it
cib = [[CPCib alloc] initWithContentsOfURL:[_cibBundle pathForResource:_cibName + @".cib"]]; cib = [[CPCib alloc] initWithContentsOfURL:[_cibBundle pathForResource:_cibName + @".cib"]];
[CPViewControllerCachedCibs setObject:cib forKey:_cibName]; [CPViewControllerCachedCibs setObject:cib forKey:_cibName];
} }
@@ -215,34 +192,6 @@ var CPViewControllerCachedCibs;
_view = aView; _view = aView;
} }
- (CPNavigationItem)navigationItem
{
var navigationItem = self._navigationItem;
if (!navigationItem)
navigationItem = [[CPNavigationItem alloc] initWithTitle:[self title]];
self._navigationItem = navigationItem;
return navigationItem;
}
- (void)viewWillAppear:(BOOL)isAnimated
{
}
- (void)viewDidAppear:(BOOL)isAnimated
{
}
- (void)viewWillDisappear:(BOOL)isAnimated
{
}
- (void)viewDidDisappear:(BOOL)isAnimated
{
}
@end @end
+49 -5
View File
@@ -74,6 +74,8 @@ CPWebViewScrollNative = 2;
int _scrollMode; int _scrollMode;
CGSize _scrollSize; CGSize _scrollSize;
int _loadHTMLStringTimer;
} }
- (id)initWithFrame:(CPRect)frameRect frameName:(CPString)frameName groupName:(CPString)groupName - (id)initWithFrame:(CPRect)frameRect frameName:(CPString)frameName groupName:(CPString)groupName
@@ -110,6 +112,7 @@ CPWebViewScrollNative = 2;
_iframe.style.width = "100%"; _iframe.style.width = "100%";
_iframe.style.height = "100%"; _iframe.style.height = "100%";
_iframe.style.borderWidth = "0px"; _iframe.style.borderWidth = "0px";
_iframe.frameBorder = "0";
[self setDrawsBackground:YES]; [self setDrawsBackground:YES];
@@ -171,7 +174,32 @@ CPWebViewScrollNative = 2;
[self _resizeWebFrame]; [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) if (_scrollMode === CPWebViewScrollAppKit)
{ {
@@ -181,13 +209,14 @@ CPWebViewScrollNative = 2;
} }
else 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 // try to get the document size so we can correctly set the frame
var win = null; var win = null;
try { win = [self DOMWindow]; } catch (e) {} try { win = [self DOMWindow]; } catch (e) {}
if (win && win.document) if (win && win.document && win.document.body)
{ {
var width = win.document.body.scrollWidth, var width = win.document.body.scrollWidth,
height = win.document.body.scrollHeight; height = win.document.body.scrollHeight;
@@ -203,6 +232,8 @@ CPWebViewScrollNative = 2;
[_frameView setFrameSize:CGSizeMake(800, 1600)]; [_frameView setFrameSize:CGSizeMake(800, 1600)];
} }
[_frameView scrollRectToVisible:visibleRect];
} }
} }
} }
@@ -217,7 +248,10 @@ CPWebViewScrollNative = 2;
- (void)_setScrollMode:(int)aScrollMode - (void)_setScrollMode:(int)aScrollMode
{ {
_scrollMode = aScrollMode; if (CPBrowserIsEngine(CPInternetExplorerBrowserEngine))
_scrollMode = CPWebViewScrollNative;
else
_scrollMode = aScrollMode;
_ignoreLoadStart = YES; _ignoreLoadStart = YES;
_ignoreLoadEnd = YES; _ignoreLoadEnd = YES;
@@ -256,6 +290,8 @@ CPWebViewScrollNative = 2;
[self _setScrollMode:CPWebViewScrollAppKit]; [self _setScrollMode:CPWebViewScrollAppKit];
[_frameView setFrameSize:[_scrollView contentSize]];
[self _startedLoading]; [self _startedLoading];
_ignoreLoadStart = YES; _ignoreLoadStart = YES;
@@ -293,8 +329,15 @@ CPWebViewScrollNative = 2;
// clear the iframe // clear the iframe
_iframe.src = ""; _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 // 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]; var win = [self DOMWindow];
win.document.write(_html); win.document.write(_html);
@@ -315,6 +358,7 @@ CPWebViewScrollNative = 2;
- (void)_finishedLoading - (void)_finishedLoading
{ {
[self _resizeWebFrame]; [self _resizeWebFrame];
[self _attachScrollEventIfNecessary];
[[CPNotificationCenter defaultCenter] postNotificationName:CPWebViewProgressFinishedNotification object:self]; [[CPNotificationCenter defaultCenter] postNotificationName:CPWebViewProgressFinishedNotification object:self];
+30 -2
View File
@@ -372,6 +372,15 @@ CPTexturedBackgroundWindowMask
[self setPlatformWindow:[CPPlatformWindow primaryPlatformWindow]]; [self setPlatformWindow:[CPPlatformWindow primaryPlatformWindow]];
else 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 setPlatformWindow:[[CPPlatformWindow alloc] initWithContentRect:_frame]];
[self platformWindow]._only = self; [self platformWindow]._only = self;
} }
@@ -883,6 +892,23 @@ CPTexturedBackgroundWindowMask
return _contentView; 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. Sets the window's background color.
@param aColor the new color for the background @param aColor the new color for the background
@@ -1907,7 +1933,8 @@ CPTexturedBackgroundWindowMask
[keyWindow makeKeyWindow]; [keyWindow makeKeyWindow];
else else
{ {
var menuWindow = [CPApp mainMenu]._menuWindow; var mainMenu = [CPApp mainMenu],
menuWindow = mainMenu ? mainMenu._menuWindow : nil;
for (var i = 0; i < windowCount; i++) for (var i = 0; i < windowCount; i++)
{ {
var currentWindow = allWindows[i]; var currentWindow = allWindows[i];
@@ -1935,7 +1962,8 @@ CPTexturedBackgroundWindowMask
[mainWindow makeMainWindow]; [mainWindow makeMainWindow];
else else
{ {
var menuWindow = [CPApp mainMenu]._menuWindow; var mainMenu = [CPApp mainMenu],
menuWindow = mainMenu ? mainMenu._menuWindow : nil;
for (var i = 0; i < windowCount; i++) for (var i = 0; i < windowCount; i++)
{ {
var currentWindow = allWindows[i]; var currentWindow = allWindows[i];
+14 -14
View File
@@ -37,12 +37,12 @@ var CPCibOwner = @"CPCibOwner";
@implementation CPBundle (CPCibLoading) @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"]) if (![aName hasSuffix:@".cib"])
aName = [aName stringByAppendingString:@".cib"]; aName = [aName stringByAppendingString:@".cib"];
@@ -51,24 +51,24 @@ var CPCibOwner = @"CPCibOwner";
var bundle = anOwner ? [CPBundle bundleForClass:[anOwner class]] : [CPBundle mainBundle], var bundle = anOwner ? [CPBundle bundleForClass:[anOwner class]] : [CPBundle mainBundle],
path = [bundle pathForResource:aName]; 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 initWithContentsOfURL:anAbsolutePath
loadDelegate:[[_CPCibLoadDelegate alloc] loadDelegate:[[_CPCibLoadDelegate alloc]
initWithLoadDelegate:aDelegate 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"]) if (![aName hasSuffix:@".cib"])
aName = [aName stringByAppendingString:@".cib"]; aName = [aName stringByAppendingString:@".cib"];
@@ -77,17 +77,17 @@ var CPCibOwner = @"CPCibOwner";
var bundle = anOwner ? [CPBundle bundleForClass:[anOwner class]] : [CPBundle mainBundle], var bundle = anOwner ? [CPBundle bundleForClass:[anOwner class]] : [CPBundle mainBundle],
path = [bundle pathForResource:aName]; 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 initWithCibNamed:aFileName
bundle:self bundle:self
loadDelegate:[[_CPCibLoadDelegate alloc] loadDelegate:[[_CPCibLoadDelegate alloc]
initWithLoadDelegate:aDelegate initWithLoadDelegate:aDelegate
externalNameTable:aNameTable]]; externalNameTable:aNameTable]]);
} }
@end @end
+10
View File
@@ -41,6 +41,7 @@ var PrimaryPlatformWindow = NULL;
DOMElement _DOMBodyElement; DOMElement _DOMBodyElement;
DOMElement _DOMFocusElement; DOMElement _DOMFocusElement;
DOMElement _DOMEventGuard;
CPArray _windowLevels; CPArray _windowLevels;
CPDictionary _windowLayers; CPDictionary _windowLayers;
@@ -73,6 +74,15 @@ var PrimaryPlatformWindow = NULL;
return [CPSet set]; return [CPSet set];
} }
+ (BOOL)supportsMultipleInstances
{
#if PLATFORM(DOM)
return !CPBrowserIsEngine(CPInternetExplorerBrowserEngine);
#else
return NO;
#endif
}
+ (CPPlatformWindow)primaryPlatformWindow + (CPPlatformWindow)primaryPlatformWindow
{ {
return PrimaryPlatformWindow; return PrimaryPlatformWindow;
+15 -8
View File
@@ -130,8 +130,6 @@ var CPDOMEventGetClickCount,
StopDOMEventPropagation, StopDOMEventPropagation,
StopContextMenuDOMEventPropagation; StopContextMenuDOMEventPropagation;
var _DOMEventGuard;
//right now we hard code q, w, r and t as keys to propogate //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 //these aren't normal keycodes, they are with modifier key codes
//might be mac only, we should investigate futher later. //might be mac only, we should investigate futher later.
@@ -280,7 +278,7 @@ var supportsNativeDragAndDrop = [CPPlatform supportsDragAndDrop];
_DOMBodyElement = theDocument.getElementById("cappuccino-body") || theDocument.body; _DOMBodyElement = theDocument.getElementById("cappuccino-body") || theDocument.body;
// FIXME: Always do this? // FIXME: Always do this?
if ([CPPlatform supportsDragAndDrop]) if (supportsNativeDragAndDrop)
_DOMBodyElement.style["-khtml-user-select"] = "none"; _DOMBodyElement.style["-khtml-user-select"] = "none";
_DOMBodyElement.webkitTouchCallout = "none"; _DOMBodyElement.webkitTouchCallout = "none";
@@ -469,7 +467,7 @@ var supportsNativeDragAndDrop = [CPPlatform supportsDragAndDrop];
[PlatformWindows addObject:self]; [PlatformWindows addObject:self];
// FIXME: cpSetFrame? // 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(); _DOMWindow.document.close();
if (![CPPlatform isBrowser]) if (![CPPlatform isBrowser])
@@ -516,6 +514,11 @@ var supportsNativeDragAndDrop = [CPPlatform supportsDragAndDrop];
DOMDragElement.style.left = -_CGRectGetWidth(draggedWindowFrame) + "px"; DOMDragElement.style.left = -_CGRectGetWidth(draggedWindowFrame) + "px";
DOMDragElement.style.top = -_CGRectGetHeight(draggedWindowFrame) + "px"; DOMDragElement.style.top = -_CGRectGetHeight(draggedWindowFrame) + "px";
var parentNode = DOMDragElement.parentNode;
if (parentNode)
parentNode.removeChild(DOMDragElement);
_DOMBodyElement.appendChild(DOMDragElement); _DOMBodyElement.appendChild(DOMDragElement);
var draggingOffset = [dragServer draggingOffset]; var draggingOffset = [dragServer draggingOffset];
@@ -848,10 +851,11 @@ var supportsNativeDragAndDrop = [CPPlatform supportsDragAndDrop];
if(!aDOMEvent) if(!aDOMEvent)
aDOMEvent = window.event; aDOMEvent = window.event;
var location = nil;
if (CPFeatureIsCompatible(CPJavaScriptMouseWheelValues_8_15)) if (CPFeatureIsCompatible(CPJavaScriptMouseWheelValues_8_15))
{ {
var x = 0.0, var x = aDOMEvent._offsetX || 0.0,
y = 0.0, y = aDOMEvent._offsetY || 0.0,
element = aDOMEvent.target; element = aDOMEvent.target;
while (element.nodeType !== 1) while (element.nodeType !== 1)
@@ -867,10 +871,12 @@ var supportsNativeDragAndDrop = [CPPlatform supportsDragAndDrop];
} while (element = element.offsetParent); } 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 else
var location = _CGPointMake(aDOMEvent.clientX, aDOMEvent.clientY); location = _CGPointMake(aDOMEvent.clientX, aDOMEvent.clientY);
var deltaX = 0.0, var deltaX = 0.0,
deltaY = 0.0, deltaY = 0.0,
@@ -1189,6 +1195,7 @@ var supportsNativeDragAndDrop = [CPPlatform supportsDragAndDrop];
[_windowLevels insertObject:aLevel atIndex:insertionIndex]; [_windowLevels insertObject:aLevel atIndex:insertionIndex];
layer._DOMElement.style.zIndex = aLevel; layer._DOMElement.style.zIndex = aLevel;
_DOMBodyElement.appendChild(layer._DOMElement); _DOMBodyElement.appendChild(layer._DOMElement);
} }
Binary file not shown.

After

Width:  |  Height:  |  Size: 506 B

+9 -4
View File
@@ -439,7 +439,7 @@
isVertical:NO]); isVertical:NO]);
[button setValue:CPLeftTextAlignment forThemeAttribute:@"alignment" inState:CPThemeStateBordered]; [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:CGInsetMake(0.0, 0.0, 0.0, 20.0) forThemeAttribute:@"content-inset" inState:CPThemeStateBordered];
[button setValue:bezelColor forThemeAttribute:@"bezel-color" inState:CPThemeStateBordered]; [button setValue:bezelColor forThemeAttribute:@"bezel-color" inState:CPThemeStateBordered];
[button setValue:bezelColorSelected forThemeAttribute:@"bezel-color" inState:CPThemeStateBordered | CPThemeStateSelected]; [button setValue:bezelColorSelected forThemeAttribute:@"bezel-color" inState:CPThemeStateBordered | CPThemeStateSelected];
@@ -493,7 +493,7 @@
isVertical:NO]); isVertical:NO]);
[button setValue:CPLeftTextAlignment forThemeAttribute:@"alignment" inState:CPThemeStateBordered]; [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:CGInsetMake(0.0, 0.0, 0.0, 20.0) forThemeAttribute:@"content-inset" inState:CPThemeStateBordered];
[button setValue:bezelColor forThemeAttribute:@"bezel-color" inState:CPThemeStateBordered]; [button setValue:bezelColor forThemeAttribute:@"bezel-color" inState:CPThemeStateBordered];
[button setValue:bezelColorSelected forThemeAttribute:@"bezel-color" inState:CPThemeStateBordered | CPThemeStateSelected]; [button setValue:bezelColorSelected forThemeAttribute:@"bezel-color" inState:CPThemeStateBordered | CPThemeStateSelected];
@@ -721,7 +721,7 @@
+ (CPButtonBar)themedButtonBar + (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)]]; color = [CPColor colorWithPatternImage:[_CPCibCustomResource imageResourceWithName:"buttonbar-bezel.png" size:CGSizeMake(1.0, 26.0)]];
[buttonBar setHasResizeControl:YES]; [buttonBar setHasResizeControl:YES];
@@ -761,8 +761,13 @@
[buttonBar setValue:buttonBezelColor forThemeAttribute:@"button-bezel-color"]; [buttonBar setValue:buttonBezelColor forThemeAttribute:@"button-bezel-color"];
[buttonBar setValue:buttonBezelHighlightedColor forThemeAttribute:@"button-bezel-color" inState:CPThemeStateHighlighted]; [buttonBar setValue:buttonBezelHighlightedColor forThemeAttribute:@"button-bezel-color" inState:CPThemeStateHighlighted];
[buttonBar setValue:buttonBezelDisabledColor forThemeAttribute:@"button-bezel-color" inState:CPThemeStateDisabled]; [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; return buttonBar;
} }
+17
View File
@@ -63,6 +63,7 @@ var HORIZONTAL_MARGIN = 3.0,
CPCellImagePosition _imagePosition; CPCellImagePosition _imagePosition;
CPImageScaling _imageScaling; CPImageScaling _imageScaling;
BOOL _shouldDimImage;
CPImage _image; CPImage _image;
CPString _text; CPString _text;
@@ -211,6 +212,17 @@ var HORIZONTAL_MARGIN = 3.0,
return _imageScaling; return _imageScaling;
} }
- (void)setDimsImage:(BOOL)shouldDim
{
var shouldDimImage = !!shouldDimImage;
if (_shouldDimImage !== shouldDimImage)
{
_shouldDimImage = shouldDim;
[self setNeedsLayout];
}
}
- (void)setTextColor:(CPColor)aTextColor - (void)setTextColor:(CPColor)aTextColor
{ {
if (_textColor === aTextColor) if (_textColor === aTextColor)
@@ -572,6 +584,11 @@ var HORIZONTAL_MARGIN = 3.0,
imageHeight *= scale; imageHeight *= scale;
} }
if (CPFeatureIsCompatible(CPOpacityRequiresFilterFeature))
imageStyle.filter = @"alpha(opacity=" + _shouldDimImage ? 35 : 100 + ")";
else
imageStyle.opacity = _shouldDimImage ? 0.35 : 1.0;
_DOMImageElement.width = imageWidth; _DOMImageElement.width = imageWidth;
_DOMImageElement.height = imageHeight; _DOMImageElement.height = imageHeight;
imageStyle.width = MAX(imageWidth, 0) + "px"; imageStyle.width = MAX(imageWidth, 0) + "px";
+13
View File
@@ -10,6 +10,8 @@ var FILE = require("file");
var OS = require("os"); var OS = require("os");
var UTIL = require("util"); var UTIL = require("util");
var CACHEMANIFEST = require("objective-j/cache-manifest");
var stream = require("term").stream; var stream = require("term").stream;
var parser = new (require("args").Parser)(); var parser = new (require("args").Parser)();
@@ -49,6 +51,10 @@ parser.option("-c", "--compressor", "compressor")
.set() .set()
.help("Select a compressor to use (closure-compiler, yuicompressor, shrinksafe), or \"none\" (default: shrinksafe)"); .help("Select a compressor to use (closure-compiler, yuicompressor, shrinksafe), or \"none\" (default: shrinksafe)");
parser.option("--manifest", "manifest")
.set(true)
.help("Generate HTML5 cache manifest.");
parser.option("-v", "--verbose", "verbose") parser.option("-v", "--verbose", "verbose")
.def(false) .def(false)
.set(true) .set(true)
@@ -126,6 +132,13 @@ function main(args)
}); });
rewriteMainHTML(outputPath.join(options.index)); rewriteMainHTML(outputPath.join(options.index));
if (options.manifest) {
CACHEMANIFEST.generateManifest(outputPath, {
index : outputPath.join(options.index),
exclude : Object.keys(flattener.filesToCache).map(function(path) { return outputPath.join(path).toString(); })
});
}
} }
// ObjectiveJFlattener inherits from ObjectiveJRuntimeAnalyzer // ObjectiveJFlattener inherits from ObjectiveJRuntimeAnalyzer
+17
View File
@@ -10,6 +10,8 @@ require("narwhal").ensureEngine("rhino");
var FILE = require("file"); var FILE = require("file");
var OS = require("os"); var OS = require("os");
var CACHEMANIFEST = require("objective-j/cache-manifest");
var stream = require("term").stream; var stream = require("term").stream;
var parser = new (require("args").Parser)(); var parser = new (require("args").Parser)();
@@ -31,11 +33,20 @@ parser.option("-f", "--force", "force")
.set(true) .set(true)
.help("Force overwriting OUTPUT_PROJECT if it exists"); .help("Force overwriting OUTPUT_PROJECT if it exists");
parser.option("--index", "index")
.def("index.html")
.set()
.help("The root HTML file to modify (default: index.html) (NOTE: currently only used by '--manifest' option)");
parser.option("-p", "--pngcrush", "png") parser.option("-p", "--pngcrush", "png")
.def(false) .def(false)
.set(true) .set(true)
.help("Run pngcrush on all PNGs (pngcrush must be installed!)"); .help("Run pngcrush on all PNGs (pngcrush must be installed!)");
parser.option("--manifest", "manifest")
.set(true)
.help("Generate HTML5 cache manifest.");
parser.option("-v", "--verbose", "verbose") parser.option("-v", "--verbose", "verbose")
.def(false) .def(false)
.set(true) .set(true)
@@ -146,6 +157,12 @@ function press(rootPath, outputPath, options) {
if (options.png) { if (options.png) {
pngcrushDirectory(outputPath); pngcrushDirectory(outputPath);
} }
if (options.manifest) {
CACHEMANIFEST.generateManifest(outputPath, {
index : outputPath.join(options.index)
});
}
} }
function pressEnvironment(rootPath, outputFiles, environment, options) { function pressEnvironment(rootPath, outputFiles, environment, options) {
+70
View File
@@ -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 URLCache = { };
var CFHTTPRequest_open = CFHTTPRequest.prototype.open;
CFHTTPRequest.prototype.open = function(/*String*/ method, /*String*/ url, /*Boolean*/ async, /*String*/ user, /*String*/ password) CFHTTPRequest.prototype.open = function(/*String*/ method, /*String*/ url, /*Boolean*/ async, /*String*/ user, /*String*/ password)
{ {
var cachedRequest = CFHTTPRequest._lookupCachedRequest(url); var cachedRequest = CFHTTPRequest._lookupCachedRequest(url);
@@ -13,7 +14,7 @@ CFHTTPRequest.prototype.open = function(/*String*/ method, /*String*/ url, /*Boo
ObjectiveJ.determineAndDispatchHTTPRequestEvents(self); 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) CFHTTPRequest._cacheRequest = function(/*CFURL|String*/ aURL, /*Number*/ status, /*Object*/ headers, /*String*/ body)
+61 -72
View File
@@ -145,10 +145,10 @@
{ {
var i = 2, var i = 2,
array = [[self alloc] init], array = [[self alloc] init],
argument; count = arguments.length;
for(; i < arguments.length && (argument = arguments[i]) != nil; ++i) for (; i < count; ++i)
array.push(argument); array.push(arguments[i]);
return array; return array;
} }
@@ -209,13 +209,13 @@
var index = 0, var index = 0,
count = [anArray count]; count = [anArray count];
for(; index < count; ++index) for (; index < count; ++index)
{ {
if (anArray[index].isa) if (anArray[index].isa)
self[index] = [anArray[index] copy]; self[index] = [anArray[index] copy];
// Do a deep/shallow copy? // Do a deep/shallow copy?
else else
self[index] = anArray; self[index] = anArray[index];
} }
} }
@@ -229,10 +229,10 @@
{ {
// The arguments array contains self and _cmd, so the first object is at position 2. // The arguments array contains self and _cmd, so the first object is at position 2.
var i = 2, var i = 2,
argument; count = arguments.length;
for(; i < arguments.length && (argument = arguments[i]) != nil; ++i) for (; i < count; ++i)
push(argument); push(arguments[i]);
return self; return self;
} }
@@ -251,7 +251,7 @@
{ {
var index = 0; var index = 0;
for(; index < aCount; ++index) for (; index < aCount; ++index)
push(objects[index]); push(objects[index]);
} }
@@ -278,24 +278,21 @@
/*! /*!
Returns the index of \c anObject in this array. 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 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 @param anObject the object to search for
*/ */
- (int)indexOfObject:(id)anObject - (int)indexOfObject:(id)anObject
{ {
if (anObject === nil)
return CPNotFound;
var i = 0, var i = 0,
count = length; count = length;
// Only use -isEqual: if our object is a CPObject. // Only use -isEqual: if our object is a CPObject.
if (anObject.isa) if (anObject && anObject.isa)
{ {
for(; i < count; ++i) for (; i < count; ++i)
if([self[i] isEqual:anObject]) if ([self[i] isEqual:anObject])
return i; return i;
} }
// If indexOf exists, use it since it's probably // If indexOf exists, use it since it's probably
@@ -304,8 +301,8 @@
return indexOf(anObject); return indexOf(anObject);
// Last resort, do a straight forward linear O(N) search. // Last resort, do a straight forward linear O(N) search.
else else
for(; i < count; ++i) for (; i < count; ++i)
if(self[i] == anObject) if (self[i] === anObject)
return i; return i;
return CPNotFound; return CPNotFound;
@@ -314,45 +311,39 @@
/*! /*!
Returns the index of \c anObject in the array Returns the index of \c anObject in the array
within \c aRange. It first attempts to find 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 anObject the object to search for
@param aRange the range to search within @param aRange the range to search within
@return the index of the object, or \c CPNotFound if it was not found. @return the index of the object, or \c CPNotFound if it was not found.
*/ */
- (int)indexOfObject:(id)anObject inRange:(CPRange)aRange - (int)indexOfObject:(id)anObject inRange:(CPRange)aRange
{ {
if (anObject === nil)
return CPNotFound;
var i = aRange.location, var i = aRange.location,
count = MIN(CPMaxRange(aRange), length); count = MIN(CPMaxRange(aRange), length);
// Only use isEqual: if our object is a CPObject. // Only use isEqual: if our object is a CPObject.
if (anObject.isa) if (anObject && anObject.isa)
{ {
for(; i < count; ++i) for (; i < count; ++i)
if([self[i] isEqual:anObject]) if ([self[i] isEqual:anObject])
return i; return i;
} }
// Last resort, do a straight forward linear O(N) search. // Last resort, do a straight forward linear O(N) search.
else else
for(; i < count; ++i) for (; i < count; ++i)
if(self[i] == anObject) if (self[i] === anObject)
return i; return i;
return CPNotFound; 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 @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. @return the index of the object in the array. \c CPNotFound if the object is not in the array.
*/ */
- (int)indexOfObjectIdenticalTo:(id)anObject - (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. // faster than anything we can implement.
if (self.indexOf) if (self.indexOf)
@@ -364,8 +355,8 @@
var index = 0, var index = 0,
count = length; count = length;
for(; index < count; ++index) for (; index < count; ++index)
if(self[index] === anObject) if (self[index] === anObject)
return index; return index;
} }
@@ -382,9 +373,6 @@
*/ */
- (int)indexOfObjectIdenticalTo:(id)anObject inRange:(CPRange)aRange - (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. // faster than anything we can implement.
if (self.indexOf) if (self.indexOf)
@@ -401,8 +389,8 @@
var index = aRange.location, var index = aRange.location,
count = MIN(CPMaxRange(aRange), length); count = MIN(CPMaxRange(aRange), length);
for(; index < count; ++index) for (; index < count; ++index)
if(self[index] == anObject) if (self[index] == anObject)
return index; return index;
} }
@@ -419,7 +407,7 @@
*/ */
- (unsigned)indexOfObject:(id)anObject sortedBySelector:(SEL)aSelector - (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); }];
} }
/*! /*!
@@ -460,13 +448,17 @@
- (unsigned)_indexOfObject:(id)anObject sortedByFunction:(Function)aFunction context:(id)aContext - (unsigned)_indexOfObject:(id)anObject sortedByFunction:(Function)aFunction context:(id)aContext
{ {
if (!aFunction || anObject === undefined) if (!aFunction)
return CPNotFound; return CPNotFound;
if (length === 0) if (length === 0)
return -1; return -1;
var mid, c, first = 0, last = length - 1; var mid,
c,
first = 0,
last = length - 1;
while (first <= last) while (first <= last)
{ {
mid = FLOOR((first + last) / 2); mid = FLOOR((first + last) / 2);
@@ -485,7 +477,7 @@
} }
} }
return -first-1; return -first - 1;
} }
/*! /*!
@@ -505,7 +497,7 @@
result = CPOrderedSame; result = CPOrderedSame;
while (i < count) 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;
return result; return result;
@@ -519,7 +511,8 @@
{ {
var count = [self count]; var count = [self count];
if (!count) return nil; if (!count)
return nil;
return self[count - 1]; return self[count - 1];
} }
@@ -546,7 +539,7 @@
var index = CPNotFound, var index = CPNotFound,
objects = []; objects = [];
while((index = [indexes indexGreaterThanIndex:index]) !== CPNotFound) while ((index = [indexes indexGreaterThanIndex:index]) !== CPNotFound)
[objects addObject:[self objectAtIndex:index]]; [objects addObject:[self objectAtIndex:index]];
return objects; return objects;
@@ -586,7 +579,7 @@
var index = 0, var index = 0,
count = length; count = length;
for(; index < count; ++index) for (; index < count; ++index)
objj_msgSend(self[index], aSelector); objj_msgSend(self[index], aSelector);
} }
@@ -604,7 +597,7 @@
var index = 0, var index = 0,
count = length; count = length;
for(; index < count; ++index) for (; index < count; ++index)
objj_msgSend(self[index], aSelector, anObject); objj_msgSend(self[index], aSelector, anObject);
} }
@@ -617,7 +610,7 @@
count = length, count = length,
argumentsArray = [nil, aSelector].concat(objects || []); argumentsArray = [nil, aSelector].concat(objects || []);
for(; index < count; ++index) for (; index < count; ++index)
{ {
argumentsArray[0] = self[index]; argumentsArray[0] = self[index];
objj_msgSend.apply(this, argumentsArray); objj_msgSend.apply(this, argumentsArray);
@@ -639,8 +632,8 @@
var i = 0, var i = 0,
count = [self count]; count = [self count];
for(; i < count; ++i) for (; i < count; ++i)
if([anArray containsObject:self[i]]) if ([anArray containsObject:self[i]])
return self[i]; return self[i];
return nil; return nil;
@@ -660,7 +653,7 @@
var index = 0, var index = 0,
count = [self count]; count = [self count];
for(; index < count; ++index) for (; index < count; ++index)
{ {
var lhs = self[index], var lhs = self[index],
rhs = anArray[index]; rhs = anArray[index];
@@ -678,7 +671,7 @@
if (self === anObject) if (self === anObject)
return YES; return YES;
if(![anObject isKindOfClass:[CPArray class]]) if (![anObject isKindOfClass:[CPArray class]])
return NO; return NO;
return [self isEqualToArray:anObject]; return [self isEqualToArray:anObject];
@@ -693,12 +686,7 @@
*/ */
- (CPArray)arrayByAddingObject:(id)anObject - (CPArray)arrayByAddingObject:(id)anObject
{ {
if (anObject === nil || anObject === undefined)
[CPException raise:CPInvalidArgumentException
reason:"arrayByAddingObject: object can't be nil"];
var array = [self copy]; var array = [self copy];
array.push(anObject); array.push(anObject);
return array; return array;
@@ -720,8 +708,8 @@
count = [self count], count = [self count],
array = [CPArray array]; array = [CPArray array];
for(; i<count; ++i) for (; i<count; ++i)
if(aPredicate.evaluateWithObject(self[i])) if (aPredicate.evaluateWithObject(self[i]))
array.push(self[i]); array.push(self[i]);
return array; return array;
@@ -820,7 +808,7 @@
count = [self count], count = [self count],
description = '('; description = '(';
for(; index < count; ++index) for (; index < count; ++index)
{ {
if (index === 0) if (index === 0)
description += '\n'; description += '\n';
@@ -853,7 +841,7 @@
count = [self count], count = [self count],
array = []; array = [];
for(; index < count; ++index) for (; index < count; ++index)
if (self[index].isa && [self[index] isKindOfClass:[CPString class]] && [filterTypes containsObject:[self[index] pathExtension]]) if (self[index].isa && [self[index] isKindOfClass:[CPString class]] && [filterTypes containsObject:[self[index] pathExtension]])
array.push(self[index]); array.push(self[index]);
@@ -871,7 +859,7 @@
var i = 0, var i = 0,
count = [self count]; count = [self count];
for(; i < count; ++i) for (; i < count; ++i)
[self[i] setValue:aValue forKey:aKey]; [self[i] setValue:aValue forKey:aKey];
} }
@@ -886,7 +874,7 @@
count = [self count], count = [self count],
array = []; array = [];
for(; i < count; ++i) for (; i < count; ++i)
array.push([self[i] valueForKey:aKey]); array.push([self[i] valueForKey:aKey]);
return array; return array;
@@ -966,12 +954,12 @@
var indexesCount = [indexes count], var indexesCount = [indexes count],
objectsCount = [objects 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."]; [CPException raise:CPRangeException reason:"the counts of the passed-in array (" + objectsCount + ") and index set (" + indexesCount + ") must be identical."];
var lastIndex = [indexes lastIndex]; var lastIndex = [indexes lastIndex];
if(lastIndex >= [self 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 + ")."]; [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, var index = 0,
@@ -990,14 +978,14 @@
result = CPOrderedSame; result = CPOrderedSame;
while (i < count) 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;
return result; return result;
} context:nil]; } context:nil];
if (index < 0) if (index < 0)
index = -index-1; index = -index - 1;
[self insertObject:anObject atIndex:index]; [self insertObject:anObject atIndex:index];
return index; return index;
@@ -1024,7 +1012,7 @@
var i = 0, var i = 0,
index = [anIndexSet firstIndex]; index = [anIndexSet firstIndex];
while(index != CPNotFound) while (index != CPNotFound)
{ {
[self replaceObjectAtIndex:index withObject:objects[i++]]; [self replaceObjectAtIndex:index withObject:objects[i++]];
index = [anIndexSet indexGreaterThanIndex:index]; index = [anIndexSet indexGreaterThanIndex:index];
@@ -1065,7 +1053,8 @@
*/ */
- (void)setArray:(CPArray)anArray - (void)setArray:(CPArray)anArray
{ {
if(self == anArray) return; if (self == anArray)
return;
splice.apply(self, [0, length].concat(anArray)); splice.apply(self, [0, length].concat(anArray));
} }
@@ -1208,8 +1197,8 @@
count = [descriptors count], count = [descriptors count],
result = CPOrderedSame; result = CPOrderedSame;
while(i < count) 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;
return result; return result;
+10 -3
View File
@@ -56,7 +56,7 @@ CPJSONPCallbackReplacementString = @"${JSONP_CALLBACK}";
+ (CPJSONPConnection)connectionWithRequest:(CPURLRequest)aRequest callback:(CPString)callbackParameter delegate:(id)aDelegate + (CPJSONPConnection)connectionWithRequest:(CPURLRequest)aRequest callback:(CPString)callbackParameter delegate:(id)aDelegate
{ {
return [[[self class] alloc] initWithRequest:aRequest callback:callbackParameter delegate:aDelegate startImmediately:YES];; return [[[self class] alloc] initWithRequest:aRequest callback:callbackParameter delegate:aDelegate startImmediately:YES];
} }
- (id)initWithRequest:(CPURLRequest)aRequest callback:(CPString)aString delegate:(id)aDelegate - (id)initWithRequest:(CPURLRequest)aRequest callback:(CPString)aString delegate:(id)aDelegate
@@ -88,7 +88,12 @@ CPJSONPCallbackReplacementString = @"${JSONP_CALLBACK}";
{ {
CPJSONPConnectionCallbacks["callback"+[self UID]] = function(data) CPJSONPConnectionCallbacks["callback"+[self UID]] = function(data)
{ {
[_delegate connection:self didReceiveData:data]; if ([_delegate respondsToSelector:@selector(connection:didReceiveData:)])
[_delegate connection:self didReceiveData:data];
if ([_delegate respondsToSelector:@selector(connectionDidFinishLoading:)])
[_delegate connectionDidFinishLoading:self];
[self removeScriptTag]; [self removeScriptTag];
[[CPRunLoop currentRunLoop] limitDateForMode:CPDefaultRunLoopMode]; [[CPRunLoop currentRunLoop] limitDateForMode:CPDefaultRunLoopMode];
@@ -118,7 +123,9 @@ CPJSONPCallbackReplacementString = @"${JSONP_CALLBACK}";
} }
catch (exception) catch (exception)
{ {
[_delegate connection: self didFailWithError: exception]; if ([_delegate respondsToSelector:@selector(connection:didFailWithError:)])
[_delegate connection: self didFailWithError: exception];
[self removeScriptTag]; [self removeScriptTag];
} }
} }
+24
View File
@@ -480,6 +480,12 @@ var kvoNewAndOld = CPKeyValueObservingOptionNew|CPKeyValueObservingOptionOld,
- (void)willChangeValueForKey:(CPString)aKey - (void)willChangeValueForKey:(CPString)aKey
{ {
var superClass = [self class],
methodSelector = @selector(willChangeValueForKey:),
methodImp = class_getMethodImplementation(superClass, methodSelector);
methodImp(self, methodSelector, aKey);
if (!aKey) if (!aKey)
return; return;
@@ -490,6 +496,12 @@ var kvoNewAndOld = CPKeyValueObservingOptionNew|CPKeyValueObservingOptionOld,
- (void)didChangeValueForKey:(CPString)aKey - (void)didChangeValueForKey:(CPString)aKey
{ {
var superClass = [self class],
methodSelector = @selector(didChangeValueForKey:),
methodImp = class_getMethodImplementation(superClass, methodSelector);
methodImp(self, methodSelector, aKey);
if (!aKey) if (!aKey)
return; return;
@@ -498,6 +510,12 @@ var kvoNewAndOld = CPKeyValueObservingOptionNew|CPKeyValueObservingOptionOld,
- (void)willChange:(CPKeyValueChange)change valuesAtIndexes:(CPIndexSet)indexes forKey:(CPString)aKey - (void)willChange:(CPKeyValueChange)change valuesAtIndexes:(CPIndexSet)indexes forKey:(CPString)aKey
{ {
var superClass = [self class],
methodSelector = @selector(willChange:valuesAtIndexes:forKey:),
methodImp = class_getMethodImplementation(superClass, methodSelector);
methodImp(self, methodSelector, change, indexes, aKey);
if (!aKey) if (!aKey)
return; return;
@@ -508,6 +526,12 @@ var kvoNewAndOld = CPKeyValueObservingOptionNew|CPKeyValueObservingOptionOld,
- (void)didChange:(CPKeyValueChange)change valuesAtIndexes:(CPIndexSet)indexes forKey:(CPString)aKey - (void)didChange:(CPKeyValueChange)change valuesAtIndexes:(CPIndexSet)indexes forKey:(CPString)aKey
{ {
var superClass = [self class],
methodSelector = @selector(didChange:valuesAtIndexes:forKey:),
methodImp = class_getMethodImplementation(superClass, methodSelector);
methodImp(self, methodSelector, change, indexes, aKey);
if (!aKey) if (!aKey)
return; return;
+19
View File
@@ -57,4 +57,23 @@ var CPNullSharedNull = nil;
return CPNullSharedNull; return CPNullSharedNull;
} }
/*!
Returns CPNull null.
@param aCoder the coder from which to do nothing
@return [CPNull null]
*/
- (id)initWithCoder:(CPCoder)aCoder
{
return [CPNull null];
}
/*!
Writes out nothing to the specified coder.
@param aCoder the coder to which nothing will
be written
*/
- (void)encodeWithCoder:(CPCoder)aCoder
{
}
@end @end
+22
View File
@@ -157,6 +157,7 @@ var CPRunLoopLastNativeRunLoop = 0;
CPDate _effectiveDate; CPDate _effectiveDate;
CPArray _orderedPerforms; CPArray _orderedPerforms;
int _runLoopInsuranceTimer;
} }
/* /*
@@ -267,6 +268,17 @@ var CPRunLoopLastNativeRunLoop = 0;
aTimer._lastNativeRunLoopsForModes = {}; aTimer._lastNativeRunLoopsForModes = {};
aTimer._lastNativeRunLoopsForModes[aMode] = CPRunLoopLastNativeRunLoop; aTimer._lastNativeRunLoopsForModes[aMode] = CPRunLoopLastNativeRunLoop;
// FIXME: Hack for not doing this in CommonJS
if ([CFBundle.environments() indexOfObject:("Browser")] !== CPNotFound)
{
if (!_runLoopInsuranceTimer)
_runLoopInsuranceTimer = window.setNativeTimeout(function()
{
[self limitDateForMode:CPDefaultRunLoopMode];
}, 0);
}
} }
/*! /*!
@@ -280,6 +292,16 @@ var CPRunLoopLastNativeRunLoop = 0;
_runLoopLock = YES; _runLoopLock = YES;
// FIXME: Hack for not doing this in CommonJS
if ([CFBundle.environments() indexOfObject:("Browser")] !== CPNotFound)
{
if (_runLoopInsuranceTimer)
{
window.clearNativeTimeout(_runLoopInsuranceTimer);
_runLoopInsuranceTimer = nil;
}
}
var now = _effectiveDate ? [_effectiveDate laterDate:[CPDate date]] : [CPDate date], var now = _effectiveDate ? [_effectiveDate laterDate:[CPDate date]] : [CPDate date],
nextFireDate = nil, nextFireDate = nil,
nextTimerFireDate = _nextTimerFireDatesForModes[aMode]; nextTimerFireDate = _nextTimerFireDatesForModes[aMode];
+5
View File
@@ -467,6 +467,11 @@
} }
} }
- (CPString)description
{
return @"{(" + [self allObjects].join(", ") + ")}";
}
@end @end
@implementation CPSet (CPCopying) @implementation CPSet (CPCopying)
+46 -66
View File
@@ -92,15 +92,23 @@ if (!NativeRequest)
GLOBAL(CFHTTPRequest) = function() GLOBAL(CFHTTPRequest) = function()
{ {
this._isOpen = false;
this._requestHeaders = {};
this._mimeType = null;
this._eventDispatcher = new EventDispatcher(this); this._eventDispatcher = new EventDispatcher(this);
this._nativeRequest = new NativeRequest(); this._nativeRequest = new NativeRequest();
var self = this; var self = this;
this._stateChangeHandler = function()
this._nativeRequest.onreadystatechange = function()
{ {
determineAndDispatchHTTPRequestEvents(self); determineAndDispatchHTTPRequestEvents(self);
} }
this._nativeRequest.onreadystatechange = this._stateChangeHandler;
if (CFHTTPRequest.AuthenticationDelegate !== nil)
this._eventDispatcher.addEventListener("HTTP403", function(){CFHTTPRequest.AuthenticationDelegate(self)});
} }
CFHTTPRequest.UninitializedState = 0; CFHTTPRequest.UninitializedState = 0;
@@ -109,6 +117,9 @@ CFHTTPRequest.LoadedState = 2;
CFHTTPRequest.InteractiveState = 3; CFHTTPRequest.InteractiveState = 3;
CFHTTPRequest.CompleteState = 4; CFHTTPRequest.CompleteState = 4;
//override to forward all CFHTTPRequest authorization failures to a single function
CFHTTPRequest.AuthenticationDelegate = nil;
CFHTTPRequest.prototype.status = function() CFHTTPRequest.prototype.status = function()
{ {
try try
@@ -177,8 +188,7 @@ CFHTTPRequest.prototype.responseText = function()
CFHTTPRequest.prototype.setRequestHeader = function(/*String*/ aHeader, /*Object*/ aValue) CFHTTPRequest.prototype.setRequestHeader = function(/*String*/ aHeader, /*Object*/ aValue)
{ {
if (!this._URL) this._requestHeaders[aHeader] = aValue;
return this._nativeRequest.setRequestHeader(aHeader, aValue);
} }
CFHTTPRequest.prototype.getResponseHeader = function(/*String*/ aHeader) CFHTTPRequest.prototype.getResponseHeader = function(/*String*/ aHeader)
@@ -193,70 +203,39 @@ CFHTTPRequest.prototype.getAllResponseHeaders = function()
CFHTTPRequest.prototype.overrideMimeType = function(/*String*/ aMimeType) CFHTTPRequest.prototype.overrideMimeType = function(/*String*/ aMimeType)
{ {
if ("overrideMimeType" in this._nativeRequest) this._mimeType = aMimeType;
return this._nativeRequest.overrideMimeType(aMimeType);
} }
CFHTTPRequest.prototype.open = function(/*String*/ aMethod, /*String*/ aURL, /*Boolean*/ isAsynchronous, /*String*/ aUser, /*String*/ aPassword) CFHTTPRequest.prototype.open = function(/*String*/ aMethod, /*String*/ aURL, /*Boolean*/ isAsynchronous, /*String*/ aUser, /*String*/ aPassword)
{ {
aURL = makeAbsoluteURL(aURL); this._isOpen = true;
this._URL = aURL;
if (aURL.isStorageURL()) this._async = isAsynchronous;
{ this._method = aMethod;
this._URL = aURL; this._user = aUser;
this._method = aMethod; this._password = aPassword;
this._isAsynchronous = isAsynchronous; return this._nativeRequest.open(aMethod, aURL, isAsynchronous, aUser, aPassword);
return;
}
else if (this._URL)
{
delete this._URL;
delete this._method;
delete this._isAsynchronous;
}
return this._nativeRequest.open(aMethod, aURL + "", isAsynchronous, aUser, aPassword);
}
function sendStorage(/*CFHTTPRequest*/ aRequest, /*String*/ aBody)
{
var method = aRequest._method.toUpperCase(),
eventDispatcher = aRequest._eventDispatcher;
if (method === "GET")
{
var item = localStorage.getItem(aRequest._URL);
if (item === undefined)
eventDispatcher.dispatchEvent({ type:"failure", request:aRequest });
else
eventDispatcher.dispatchEvent({ type:"success", request:aRequest });
}
else if (method === "POST" || method === "PUT")
{
try
{
localStorage.setItem(aRequest._URL, aBody);
eventDispatcher.dispatchEvent({ type:"success", request:aRequest });
}
catch (anException)
{
eventDispatcher.dispatchEvent({ type:"failure", request:aRequest });
}
}
else
eventDispatcher.dispatchEvent({ type:"failure", request:aRequest });
} }
CFHTTPRequest.prototype.send = function(/*Object*/ aBody) CFHTTPRequest.prototype.send = function(/*Object*/ aBody)
{ {
if (this._URL) for (var i in this._requestHeaders)
return sendStorage(this, aBody); {
if (this._requestHeaders.hasOwnProperty(i))
this._nativeRequest.setRequestHeader(i, this._requestHeaders[i]);
}
if (!this._isOpen)
{
delete this._nativeRequest.onreadystatechange;
this._nativeRequest.open(this._method, this._URL, this._async, this._user, this._password);
this._nativeRequest.onreadystatechange = this._stateChangeHandler;
}
if (this._mimeType && "overrideMimeType" in this._nativeRequest)
this._nativeRequest.overrideMimeType(this._mimeType);
this._isOpen = false;
try try
{ {
@@ -271,6 +250,7 @@ CFHTTPRequest.prototype.send = function(/*Object*/ aBody)
CFHTTPRequest.prototype.abort = function() CFHTTPRequest.prototype.abort = function()
{ {
this._isOpen = false;
return this._nativeRequest.abort(); return this._nativeRequest.abort();
} }
@@ -291,20 +271,20 @@ function determineAndDispatchHTTPRequestEvents(/*CFHTTPRequest*/ aRequest)
eventDispatcher.dispatchEvent({ type:"readystatechange", request:aRequest}); eventDispatcher.dispatchEvent({ type:"readystatechange", request:aRequest});
var nativeRequest = aRequest._nativeRequest, var nativeRequest = aRequest._nativeRequest,
readyState = ["uninitialized", "loading", "loaded", "interactive", "complete"][aRequest.readyState()]; readyStates = ["uninitialized", "loading", "loaded", "interactive", "complete"];
eventDispatcher.dispatchEvent({ type:readyState, request:aRequest}); if (readyStates[aRequest.readyState()] === "complete")
if (readyState === "complete")
{ {
var status = "HTTP" + aRequest.status(); var status = "HTTP" + aRequest.status();
eventDispatcher.dispatchEvent({ type:status, request:aRequest }); eventDispatcher.dispatchEvent({ type:status, request:aRequest });
var result = aRequest.success() ? "success" : "failure"; var result = aRequest.success() ? "success" : "failure";
eventDispatcher.dispatchEvent({ type:result, request:aRequest }); eventDispatcher.dispatchEvent({ type:result, request:aRequest });
eventDispatcher.dispatchEvent({ type:readyStates[aRequest.readyState()], request:aRequest});
} }
else
eventDispatcher.dispatchEvent({ type:readyStates[aRequest.readyState()], request:aRequest});
} }
function FileRequest(/*CFURL*/ aURL, onsuccess, onfailure) function FileRequest(/*CFURL*/ aURL, onsuccess, onfailure)
+10
View File
@@ -91,6 +91,16 @@ CFPropertyList.writePropertyListToFile = function(/*CFPropertyList*/ aPropertyLi
{ {
return FILE.write(aFilePath, CFPropertyList.stringFromPropertyList(aPropertyList, aFormat), { charset:"UTF-8" }); return FILE.write(aFilePath, CFPropertyList.stringFromPropertyList(aPropertyList, aFormat), { charset:"UTF-8" });
} }
CFPropertyList.modifyPlist = function(/*String*/ aFilePath, /*Function*/ aCallback, /*String*/ aFormat)
{
var string = FILE.read(aFilePath, { charset:"UTF-8" });
var format = CFPropertyList.sniffedFormatOfString(string);
var plist = CFPropertyList.propertyListFromString(string, format);
aCallback(plist);
CFPropertyList.writePropertyListToFile(plist, aFilePath, aFormat || format);
}
#endif #endif
function serializePropertyList(/*CFPropertyList*/ aPropertyList, /*Object*/ serializers) function serializePropertyList(/*CFPropertyList*/ aPropertyList, /*Object*/ serializers)
-21
View File
@@ -498,27 +498,6 @@ CFURL.prototype.authority = function()
DISPLAY_NAME(CFURL.prototype.authority); DISPLAY_NAME(CFURL.prototype.authority);
CFURL.prototype.isStorageURL = function()
{
return this.isLocalStorageURL() || this.isSessionStorageURL();
}
DISPLAY_NAME(CFURL.prototype.isStorageURL);
CFURL.prototype.isLocalStorageURL = function()
{
return this.scheme() === "storage.local";
}
DISPLAY_NAME(CFURL.prototype.isLocalStorageURL);
CFURL.prototype.isSessionStorageURL = function()
{
return this.scheme() === "storage.session";
}
DISPLAY_NAME(CFURL.prototype.isSessionStorageURL);
CFURL.prototype.hasDirectoryPath = function() CFURL.prototype.hasDirectoryPath = function()
{ {
var hasDirectoryPath = this._hasDirectoryPath; var hasDirectoryPath = this._hasDirectoryPath;
+6
View File
@@ -182,5 +182,11 @@ exports.fullVersionString = function() {
); );
} }
global.ObjectiveJ = {};
for (key in exports)
if (Object.prototype.hasOwnProperty.call(exports, key))
global.ObjectiveJ[key] = exports[key];
if (require.main == module.id) if (require.main == module.id)
exports.run(system.args); exports.run(system.args);
@@ -2,12 +2,14 @@
var FILE = require("file"); var FILE = require("file");
var MD5 = require("md5"); var MD5 = require("md5");
var FileList = require("jake").FileList, var FileList = require("jake").FileList;
var BundleTask = require("objective-j/jake/bundletask").BundleTask; var BundleTask = require("objective-j/jake/bundletask").BundleTask;
exports.generateManifest = function(productPath, indexFilePath) exports.generateManifest = function(productPath, options)
{ {
indexFilePath = indexFilePath || FILE.join(productPath, "index.html"); options = options || {};
indexFilePath = options.index || FILE.join(productPath, "index.html");
if (!FILE.isFile(indexFilePath)) { if (!FILE.isFile(indexFilePath)) {
print("Warning: Skipping cache manifest generation, no index file at "+indexFilePath); print("Warning: Skipping cache manifest generation, no index file at "+indexFilePath);
@@ -33,21 +35,28 @@ exports.generateManifest = function(productPath, indexFilePath)
list.exclude("**/LICENSE"); list.exclude("**/LICENSE");
list.exclude("**/MHTML*"); list.exclude("**/MHTML*");
list.exclude("**/CommonJS.environment/*"); list.exclude("**/CommonJS.environment/*");
list.exclude("**/*.cur"); // FIXME: sprite these?
// FIXME: bleh. heuristic for whether index file includes debug frameworks // FIXME: bleh. heuristic for whether index file includes debug frameworks
if (index.indexOf('"Frameworks/Debug"') < 0) if (index.indexOf('"Frameworks/Debug"') < 0)
list.exclude("**/Frameworks/Debug/*"); list.exclude("**/Frameworks/Debug/*");
if (options.exclude)
options.exclude.forEach(list.exclude.bind(list));
list.forEach(function(path) { list.forEach(function(path) {
if (FILE.isFile(path)) { if (FILE.isFile(path)) {
var relative = FILE.relative(productPath, path);
// FIXME: check the actual sprited images file // FIXME: check the actual sprited images file
if (BundleTask.isSpritable(path)) // check index for references to file (for spinner.gif, etc)
if (BundleTask.isSpritable(path) && index.indexOf(relative) < 0)
return; return;
// include hash of each file in comments to expire when any file changes // include hash of each file in comments to expire when any file changes
var hash = MD5.hash(FILE.read(path, "b")).decodeToString("base16"); var hash = MD5.hash(FILE.read(path, "b")).decodeToString("base16");
manifestOut.print("# " + hash); manifestOut.print("# " + hash);
manifestOut.print(FILE.relative(productPath, path)); manifestOut.print(relative);
} }
}); });
@@ -130,7 +130,7 @@ ApplicationTask.prototype.defineCacheManifestTask = function()
// TODO: can we conditionally generate based on outdated files? // TODO: can we conditionally generate based on outdated files?
var manifestPath = FILE.join(productPath, "app.manifest"); var manifestPath = FILE.join(productPath, "app.manifest");
Jake.task(manifestPath, function() { Jake.task(manifestPath, function() {
require("../cache-manifest").generateManifest(productPath, indexFilePath); require("../cache-manifest").generateManifest(productPath, { index : indexFilePath });
}); });
this.enhance([manifestPath]); this.enhance([manifestPath]);
@@ -453,7 +453,9 @@ BundleTask.prototype.resourcesPath = function()
// Don't sprite images larger than 32KB, IE 8 doesn't like it. // Don't sprite images larger than 32KB, IE 8 doesn't like it.
BundleTask.isSpritable = function(aResourcePath) { BundleTask.isSpritable = function(aResourcePath) {
return isImage(aResourcePath) && FILE.size(aResourcePath) < 32768; return isImage(aResourcePath) && FILE.size(aResourcePath) < 32768 &&
("data:" + mimeType(aResourcePath) + ";base64," +
base64.encode(FILE.read(aResourcePath, "b"))).length < 32768;
} }
BundleTask.prototype.defineResourceTask = function(aResourcePath, aDestinationPath) BundleTask.prototype.defineResourceTask = function(aResourcePath, aDestinationPath)
+100 -1
View File
@@ -35,7 +35,11 @@ function Executable(/*String*/ aCode, /*Array*/ fileDependencies, /*CFURL|String
this._function = aFunction || NULL; this._function = aFunction || NULL;
this._URL = makeAbsoluteURL(aURL || new CFURL("(Anonymous" + (AnonymousExecutableCount++) + ")")); this._URL = makeAbsoluteURL(aURL || new CFURL("(Anonymous" + (AnonymousExecutableCount++) + ")"));
this._fileDependencies = fileDependencies; this._fileDependencies = fileDependencies || [];
#ifndef COMMONJS
this._fileDependencies.push.apply(this._fileDependencies, parseRequireFileDependencies(aCode));
#endif
if (fileDependencies.length) if (fileDependencies.length)
{ {
@@ -53,6 +57,23 @@ function Executable(/*String*/ aCode, /*Array*/ fileDependencies, /*CFURL|String
exports.Executable = Executable; exports.Executable = Executable;
function parseRequireFileDependencies(aCode)
{
var dependencies = [];
if (aCode)
{
var pattern = /(?:^|[^\w.])require\s*\(\s*["']([^"']+)["']\s*\)/g;
while (match = pattern.exec(aCode))
{
var id = match[1];
if (!(/\.[^\/]+$/).test(id))
id += ".js";
dependencies.push(new FileDependency(new CFURL(id), (/^[.\/]/).test(id)));
}
}
return dependencies;
}
Executable.prototype.path = function() Executable.prototype.path = function()
{ {
return this.URL().path(); return this.URL().path();
@@ -73,6 +94,8 @@ Executable.prototype.functionParameters = function()
#ifdef COMMONJS #ifdef COMMONJS
functionParameters = functionParameters.concat("require", "exports", "module", "system", "print", "window"); functionParameters = functionParameters.concat("require", "exports", "module", "system", "print", "window");
#else
functionParameters = functionParameters.concat("require", "exports", "module");
#endif #endif
return functionParameters; return functionParameters;
@@ -86,11 +109,65 @@ Executable.prototype.functionArguments = function()
#ifdef COMMONJS #ifdef COMMONJS
functionArguments = functionArguments.concat(Executable.commonJSArguments()); functionArguments = functionArguments.concat(Executable.commonJSArguments());
#else
functionArguments = functionArguments.concat(this.getCommonJSRequire(), this.getCommonJSExports(), this.getCommonJSModule());
#endif #endif
return functionArguments; return functionArguments;
} }
Executable.prototype.getCommonJSRequire = function()
{
if (!this._commonJSRequire)
{
var executor = this.fileExecuter();
var importer = this.fileImporter();
var req = function(id)
{
if (!(/\.[^\/]+$/).test(id))
id += ".js";
return executor(id, (id.charAt(0) === "." || id.charAt(0) === "/"), NO);
}
req.async = function(id, callback) {
if (!(/\.[^\/]+$/).test(id))
id += ".js";
importer(id, (id.charAt(0) === "." || id.charAt(0) === "/"), function() {
callback(req(id));
});
};
req.paths = OBJJ_INCLUDE_PATHS;
this._commonJSRequire = req;
}
return this._commonJSRequire;
}
Executable.prototype.getCommonJSExports = function()
{
if (!this._commonJSExports)
this._commonJSExports = {};
return this._commonJSExports;
}
Executable.prototype.setCommonJSExports = function(commonJSExports)
{
if (this._commonJSExports)
throw "CommonJS exports for " + this.URL() + " already set.";
this._commonJSExports = commonJSExports;
}
Executable.prototype.getCommonJSModule = function()
{
if (!this._commonJSModule)
this._commonJSModule = {
path : this.path(),
url : this.URL().toString()
};
return this._commonJSModule;
}
DISPLAY_NAME(Executable.prototype.functionArguments); DISPLAY_NAME(Executable.prototype.functionArguments);
#ifdef COMMONJS #ifdef COMMONJS
@@ -350,14 +427,36 @@ Executable.fileExecuterForURL = function(/*CFURL|String*/ aURL)
{ {
cachedFileExecuter = function(/*CFURL*/ aURL, /*BOOL*/ isQuoted, /*BOOL*/ shouldForce) cachedFileExecuter = function(/*CFURL*/ aURL, /*BOOL*/ isQuoted, /*BOOL*/ shouldForce)
{ {
// CommonJS "exports" support:
// this is a little hacky. we use the internaly created "exports" if it executes synchronously,
// otherwise we have to create our own exports object that we can return immediately
// then set it on the executable right before it is eventually executed.
var commonJSExports = {},
hasSetExports = false,
hasReturnedExports = false;
Executable.fileExecutableSearcherForURL(referenceURL)(aURL, isQuoted, Executable.fileExecutableSearcherForURL(referenceURL)(aURL, isQuoted,
function(/*FileExecutable*/ aFileExecutable) function(/*FileExecutable*/ aFileExecutable)
{ {
if (!aFileExecutable.hasLoadedFileDependencies()) if (!aFileExecutable.hasLoadedFileDependencies())
throw "No executable loaded for file at URL " + aURL; throw "No executable loaded for file at URL " + aURL;
if (hasReturnedExports && !hasSetExports)
{
aFileExecutable.setCommonJSExports(commonJSExports);
hasSetExports = true;
}
aFileExecutable.execute(shouldForce); aFileExecutable.execute(shouldForce);
if (!hasReturnedExports)
{
commonJSExports = aFileExecutable.getCommonJSExports();
}
}); });
hasReturnedExports = true;
return commonJSExports;
} }
cachedFileExecuters[referenceURLString] = cachedFileExecuter; cachedFileExecuters[referenceURLString] = cachedFileExecuter;
+17 -13
View File
@@ -21,8 +21,8 @@
- (void)testsInsertObjectsAtIndexes - (void)testsInsertObjectsAtIndexes
{ {
var array = [CPMutableArray arrayWithObjects:@"one", @"two", @"three", @"four", nil], var array = [CPMutableArray arrayWithObjects:@"one", @"two", @"three", @"four"],
newAdditions = [CPArray arrayWithObjects:@"a", @"b", nil], newAdditions = [CPArray arrayWithObjects:@"a", @"b"],
indexes = [CPMutableIndexSet indexSetWithIndex:1]; indexes = [CPMutableIndexSet indexSetWithIndex:1];
[indexes addIndex:3]; [indexes addIndex:3];
@@ -31,8 +31,8 @@
[self assert:array equals:[@"one", @"a", @"two", @"b", @"three", @"four"]]; [self assert:array equals:[@"one", @"a", @"two", @"b", @"three", @"four"]];
var array = [CPMutableArray arrayWithObjects:@"one", @"two", @"three", @"four", nil], var array = [CPMutableArray arrayWithObjects:@"one", @"two", @"three", @"four"],
newAdditions = [CPArray arrayWithObjects:@"a", @"b", nil], newAdditions = [CPArray arrayWithObjects:@"a", @"b"],
indexes = [CPMutableIndexSet indexSetWithIndex:5]; indexes = [CPMutableIndexSet indexSetWithIndex:5];
[indexes addIndex:4]; [indexes addIndex:4];
@@ -41,8 +41,8 @@
[self assert:array equals:[@"one", @"two", @"three", @"four", @"a", @"b"]]; [self assert:array equals:[@"one", @"two", @"three", @"four", @"a", @"b"]];
var array = [CPMutableArray arrayWithObjects: @"one", @"two", @"three", @"four", nil], var array = [CPMutableArray arrayWithObjects: @"one", @"two", @"three", @"four"],
newAdditions = [CPArray arrayWithObjects: @"a", @"b", @"c", nil], newAdditions = [CPArray arrayWithObjects: @"a", @"b", @"c"],
indexes = [CPMutableIndexSet indexSetWithIndex:1]; indexes = [CPMutableIndexSet indexSetWithIndex:1];
[indexes addIndex:2]; [indexes addIndex:2];
@@ -53,8 +53,8 @@
[self assert:array equals:[@"one", @"a", @"b", @"two", @"c", @"three", @"four"]]; [self assert:array equals:[@"one", @"a", @"b", @"two", @"c", @"three", @"four"]];
var array = [CPMutableArray arrayWithObjects: @"one", @"two", @"three", @"four", nil], var array = [CPMutableArray arrayWithObjects: @"one", @"two", @"three", @"four"],
newAdditions = [CPArray arrayWithObjects: @"a", @"b", @"c", nil], newAdditions = [CPArray arrayWithObjects: @"a", @"b", @"c"],
indexes = [CPMutableIndexSet indexSetWithIndex:1]; indexes = [CPMutableIndexSet indexSetWithIndex:1];
[indexes addIndex:2]; [indexes addIndex:2];
@@ -64,10 +64,9 @@
[self assert:array equals:[@"one", @"a", @"b", @"two", @"three", @"four", @"c"]]; [self assert:array equals:[@"one", @"a", @"b", @"two", @"three", @"four", @"c"]];
//
var array = [CPMutableArray arrayWithObjects:@"one", @"two", @"three", @"four", nil], var array = [CPMutableArray arrayWithObjects:@"one", @"two", @"three", @"four"],
newAdditions = [CPArray arrayWithObjects:@"a", @"b", nil], newAdditions = [CPArray arrayWithObjects:@"a", @"b"],
indexes = [CPMutableIndexSet indexSetWithIndex:5]; indexes = [CPMutableIndexSet indexSetWithIndex:5];
[indexes addIndex:6]; [indexes addIndex:6];
@@ -91,7 +90,7 @@
[array removeObjectsAtIndexes: indexes]; [array removeObjectsAtIndexes: indexes];
[self assert:array equals:[@"one", @"two", @"four"]]; [self assert:array equals:[@"one", @"two", @"four", nil]];
} }
- (void)testIndexOfObjectSortedByFunction - (void)testIndexOfObjectSortedByFunction
@@ -212,10 +211,15 @@
- (void)testInitWithArrayCopyItems - (void)testInitWithArrayCopyItems
{ {
var a = [[CopyableObject new], 2, 3]; var a = [[CopyableObject new], 2, 3, {empty:true}];
var b = [[CPArray alloc] initWithArray:a copyItems:YES]; var b = [[CPArray alloc] initWithArray:a copyItems:YES];
[self assert:a notEqual:b]; [self assert:a notEqual:b];
[self assert:a[0] notEqual:b[0]];
[self assert:a[1] equals:b[1]];
[self assert:a[2] equals:b[2]];
[self assertTrue:a[3] === b[3]];
} }
- (void)testIsEqualToArray - (void)testIsEqualToArray
+12
View File
@@ -0,0 +1,12 @@
@import <Foundation/CPNull.j>
@import <Foundation/CPKeyedArchiver.j>
@import <Foundation/CPKeyedUnarchiver.j>
@implementation CPNullTest : OJTestCase
- (void)testArchiving
{
[self assert:[CPKeyedUnarchiver unarchiveObjectWithData:[CPKeyedArchiver archivedDataWithRootObject:[CPNull null]]] equals:[CPNull null]];
}
@end
+13
View File
@@ -56,4 +56,17 @@
[self assertFalse:[set containsObject:nil]]; [self assertFalse:[set containsObject:nil]];
} }
- (void)testDescription
{
[self assert:@"{()}" equals:[set description]];
[set addObject:"horizon"];
[set addObject:"surfer"];
[set addObject:"7"];
var desc = [set description];
// Ordering may not be guaranteed.
[self assertTrue:desc.match(new RegExp("{\(.*horizon.*\)}"))];
[self assertTrue:desc.match(new RegExp("{\(.*surfer.*\)}"))];
[self assertTrue:desc.match(new RegExp("{\(.*7.*\)}"))];
}
@end @end
@@ -29,6 +29,16 @@
- (CPArray)children - (CPArray)children
{ {
return [[Node withValue:1], return [[Node withValue:1],
[Node withValue:2],
[Node withValue:3],
[Node withValue:2],
[Node withValue:3],
[Node withValue:2],
[Node withValue:3],
[Node withValue:2],
[Node withValue:3],
[Node withValue:2],
[Node withValue:3],
[Node withValue:2], [Node withValue:2],
[Node withValue:3], [Node withValue:3],
[Node withValue:4]]; [Node withValue:4]];
-1
View File
@@ -1 +0,0 @@
../../../AppKit/CPBrowser.j
+12
View File
@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CPApplicationDelegateClass</key>
<string>AppController</string>
<key>CPBundleName</key>
<string>TestApp</string>
<key>CPPrincipalClass</key>
<string>CPApplication</string>
</dict>
</plist>
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

@@ -0,0 +1,101 @@
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<!--
index-debug.html
TestApp
Created by You on May 11, 2010.
Copyright 2010, Your Company All rights reserved.
-->
<head>
<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7" />
<meta http-equiv="X-UA-Compatible" content="chrome=1" />
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="black" />
<link rel="apple-touch-icon" href="Resources/icon.png" />
<link rel="apple-touch-startup-image" href="Resources/default.png" />
<title>TestApp</title>
<script type="text/javascript">
OBJJ_MAIN_FILE = "main.j";
OBJJ_INCLUDE_PATHS = ["Frameworks/Debug", "Frameworks", "SomethingElse"];
</script>
<script src="Frameworks/Debug/Objective-J/Objective-J.js" type="text/javascript" charset="UTF-8"></script>
<script type="text/javascript">
objj_msgSend_reset();
// DEBUG OPTIONS:
// Uncomment to enable printing of backtraces on exceptions:
//objj_msgSend_decorate(objj_backtrace_decorator);
// Uncomment to enable runtime type checking:
//objj_msgSend_decorate(objj_typecheck_decorator);
// Uncomment (along with both above) to print backtraces on type check errors:
//objj_typecheck_prints_backtrace = true;
// Uncomment to disable the default logger (CPLogConsole if window.console exists, CPLogPopup otherwise):
//CPLogUnregister(CPLogDefault);
// Uncomment to enable a specific logger:
CPLogRegister(CPLogConsole);
//CPLogRegister(CPLogPopup);
</script>
<style type="text/css">
body{margin:0; padding:0;}
#container {position: absolute; top:50%; left:50%;}
#content {width:800px; text-align:center; margin-left: -400px; height:50px; margin-top:-25px; line-height: 50px;}
#content {font-family: "Helvetica", "Arial", sans-serif; font-size: 18px; color: black; text-shadow: 0px 1px 0px white; }
#loadgraphic {margin-right: 0.2em; margin-bottom:-2px;}
</style>
<!--[if lt IE 7]>
<STYLE type="text/css">
#container { position: relative; top: 50%; }
#content { position: relative;}
</STYLE>
<![endif]-->
</head>
<body style="">
<div id="cappuccino-body">
<div id="loadingcontainer" style="background-color: #eeeeee; overflow:hidden; width:100%; height:100%; position: absolute; top: 0; left: 0;">
<script type="text/javascript">
document.write("<div id='container'><p id='content'>" +
"<img id='loadgraphic' width='16' height='16' src='Resources/spinner.gif' /> " +
"Loading TestApp...</p></div>");
</script>
<noscript>
<div id="container">
<div style="width: 440px; padding: 10px 25px 20px 25px; font-family: sans-serif; background-color: #ffffff; position: relative; left: -245px; top: -120px; text-align: center; -moz-border-radius: 20px; -webkit-border-radius: 20px; color: #555555">
<p style="line-height: 1.4em;">JavaScript is required for this site to work correctly but is either disabled or not supported by your browser.</p>
<p style="font-size:120%; padding:10px;"><a href="http://cappuccino.org/noscript">Show me how to enable JavaScript</a></p>
<p style="font-size:80%;">You may want to upgrade to a newer browser while you're at it:</p>
<ul style="margin:0;padding:0; text-align: center; font-size:80%;" >
<li style="display: inline;"><a href="http://www.apple.com/safari/download/">Safari</a></li>
<li style="display: inline;"><a href="http://www.mozilla.com/en-US/firefox/">Firefox</a></li>
<li style="display: inline;"><a href="http://www.google.com/chrome/">Chrome</a></li>
<li style="display: inline;"><a href="http://www.opera.com/download/">Opera</a></li>
<li style="display: inline;"><a href="http://www.microsoft.com/windows/downloads/ie/getitnow.mspx">Internet Explorer</a></li>
</ul>
</div>
</div>
</noscript>
</div>
</div>
</body>
</html>
+79
View File
@@ -0,0 +1,79 @@
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<!--
index.html
TestApp
Created by You on May 11, 2010.
Copyright 2010, Your Company All rights reserved.
-->
<head>
<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7" />
<meta http-equiv="X-UA-Compatible" content="chrome=1" />
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="black" />
<link rel="apple-touch-icon" href="Resources/icon.png" />
<link rel="apple-touch-startup-image" href="Resources/default.png" />
<title>TestApp</title>
<script type="text/javascript">
OBJJ_MAIN_FILE = "main.j";
</script>
<script type="text/javascript" src="Frameworks/Objective-J/Objective-J.js" charset="UTF-8"></script>
<style type="text/css">
body{margin:0; padding:0;}
#container {position: absolute; top:50%; left:50%;}
#content {width:800px; text-align:center; margin-left: -400px; height:50px; margin-top:-25px; line-height: 50px;}
#content {font-family: "Helvetica", "Arial", sans-serif; font-size: 18px; color: black; text-shadow: 0px 1px 0px white; }
#loadgraphic {margin-right: 0.2em; margin-bottom:-2px;}
</style>
<!--[if lt IE 7]>
<STYLE type="text/css">
#container { position: relative; top: 50%; }
#content { position: relative;}
</STYLE>
<![endif]-->
</head>
<body style="">
<div id="cappuccino-body">
<div id="loadingcontainer" style="background-color: #eeeeee; overflow:hidden; width:100%; height:100%; position: absolute; top: 0; left: 0;">
<script type="text/javascript">
document.write("<div id='container'><p id='content'>" +
"<img id='loadgraphic' width='16' height='16' src='Resources/spinner.gif' /> " +
"Loading TestApp...</p></div>");
</script>
<noscript>
<div id="container">
<div style="width: 440px; padding: 10px 25px 20px 25px; font-family: sans-serif; background-color: #ffffff; position: relative; left: -245px; top: -120px; text-align: center; -moz-border-radius: 20px; -webkit-border-radius: 20px; color: #555555">
<p style="line-height: 1.4em;">JavaScript is required for this site to work correctly but is either disabled or not supported by your browser.</p>
<p style="font-size:120%; padding:10px;"><a href="http://cappuccino.org/noscript">Show me how to enable JavaScript</a></p>
<p style="font-size:80%;">You may want to upgrade to a newer browser while you're at it:</p>
<ul style="margin:0;padding:0; text-align: center; font-size:80%;" >
<li style="display: inline;"><a href="http://www.apple.com/safari/download/">Safari</a></li>
<li style="display: inline;"><a href="http://www.mozilla.com/en-US/firefox/">Firefox</a></li>
<li style="display: inline;"><a href="http://www.google.com/chrome/">Chrome</a></li>
<li style="display: inline;"><a href="http://www.opera.com/download/">Opera</a></li>
<li style="display: inline;"><a href="http://www.microsoft.com/windows/downloads/ie/getitnow.mspx">Internet Explorer</a></li>
</ul>
</div>
</div>
</noscript>
</div>
</div>
</body>
</html>
@@ -0,0 +1,5 @@
exports.stdio = {
print : function() {
throw "shouldn't be using system.stdio.print"
}
}
+87
View File
@@ -0,0 +1,87 @@
/*
* AppController.j
* TestApp
*
* Created by You on May 11, 2010.
* Copyright 2010, Your Company All rights reserved.
*/
// @import <Foundation/Foundation.j>
var url = window.location.toString();
var dir = url.substring(0, url.lastIndexOf("/"));
var testNames = [
"absolute",
"cyclic",
"determinism", // failing
"exactExports",
"hasOwnProperty", // failing
"method",
"missing", // failing
"monkeys",
"nested",
"relative",
"transitive"
];
// ObjectiveJ.asyncLoader = false;
print = function() {
test.logs.push(Array.prototype.join.apply(arguments, [","]));
console.warn.apply(console, arguments);
}
var tests = [];
var test = { pass : true, logs : [] };
var pause = false;
function main(args, namedArgs)
{
var hash = window.location.hash.substring(1);
if (hash) {
tests = JSON.parse(decodeURIComponent(hash))
}
var index = tests.length;
test.name = testNames[index];
function next() {
window.clearNativeTimeout(timeout);
tests.push(test);
if (index < testNames.length - 1) {
window.location.hash = "#" + encodeURIComponent(JSON.stringify(tests));
window.location.reload();
} else {
alert(tests.map(function(test) {
return test.logs.map(function(log) {
return test.name + ": " + log;
}).join("\n") + "\n" +
"== " + (test.pass ? "PASS" : "FAIL") + " ==\n";
}).join("\n"));
}
}
var timeout = window.setNativeTimeout(function() {
test.pass = false;
if (pause) alert(test.name + ": timed out")
next();
}, 1000);
try {
console.log("running: " + test.name);
var testDir = dir + "/tests/" + test.name;
require.paths.unshift(dir + "/lib", testDir);
require.async(testDir + "/program", function() {
if (pause) alert(test.name + ": completed");
next();
});
} catch (e) {
test.pass = false;
print(test.name+ ": exception=" + e);
}
}
@@ -0,0 +1 @@
exports.foo = function() {};
@@ -0,0 +1,5 @@
var test = require('test');
var a = require('submodule/a');
var b = require('b');
test.assert(a.foo().foo === b.foo, 'require works with absolute identifiers');
test.print('DONE', 'info');
@@ -0,0 +1,3 @@
exports.foo = function () {
return require('b');
};
@@ -0,0 +1,15 @@
exports.print = typeof print !== "undefined" ? print : function () {
var system = require("system");
var stdio = system.stdio;
stdio.print.apply(stdio, arguments);
};
exports.assert = function (guard, message) {
if (guard) {
exports.print('PASS ' + message, 'pass');
} else {
exports.print('FAIL ' + message, 'fail');
}
};
@@ -0,0 +1,4 @@
exports.a = function () {
return b;
};
var b = require('b');
@@ -0,0 +1,4 @@
var a = require('a');
exports.b = function () {
return a;
};
@@ -0,0 +1,10 @@
var test = require('test');
var a = require('a');
var b = require('b');
test.assert(a.a, 'a exists');
test.assert(b.b, 'b exists')
test.assert(a.a().b === b.b, 'a gets b');
test.assert(b.b().a === a.a, 'b gets a');
test.print('DONE', 'info');
@@ -0,0 +1,15 @@
exports.print = typeof print !== "undefined" ? print : function () {
var system = require("system");
var stdio = system.stdio;
stdio.print.apply(stdio, arguments);
};
exports.assert = function (guard, message) {
if (guard) {
exports.print('PASS ' + message, 'pass');
} else {
exports.print('FAIL ' + message, 'fail');
}
};
@@ -0,0 +1,3 @@
var test = require('test');
require('submodule/a');
test.print('DONE', 'info');
@@ -0,0 +1,9 @@
var test = require('test');
var pass = false;
var test = require('test');
try {
require('a');
} catch (exception) {
pass = true;
}
test.assert(pass, 'require does not fall back to relative modules when absolutes are not available.')
@@ -0,0 +1,2 @@
@@ -0,0 +1,15 @@
exports.print = typeof print !== "undefined" ? print : function () {
var system = require("system");
var stdio = system.stdio;
stdio.print.apply(stdio, arguments);
};
exports.assert = function (guard, message) {
if (guard) {
exports.print('PASS ' + message, 'pass');
} else {
exports.print('FAIL ' + message, 'fail');
}
};
@@ -0,0 +1,3 @@
exports.program = function () {
return require('program');
};
@@ -0,0 +1,4 @@
var test = require('test');
var a = require('a');
test.assert(a.program() === exports, 'exact exports');
test.print('DONE', 'info');
@@ -0,0 +1,15 @@
exports.print = typeof print !== "undefined" ? print : function () {
var system = require("system");
var stdio = system.stdio;
stdio.print.apply(stdio, arguments);
};
exports.assert = function (guard, message) {
if (guard) {
exports.print('PASS ' + message, 'pass');
} else {
exports.print('FAIL ' + message, 'fail');
}
};
@@ -0,0 +1,4 @@
var hasOwnProperty = require('hasOwnProperty');
var toString = require('toString');
var test = require('test');
test.print('DONE', 'info');
@@ -0,0 +1,15 @@
exports.print = typeof print !== "undefined" ? print : function () {
var system = require("system");
var stdio = system.stdio;
stdio.print.apply(stdio, arguments);
};
exports.assert = function (guard, message) {
if (guard) {
exports.print('PASS ' + message, 'pass');
} else {
exports.print('FAIL ' + message, 'fail');
}
};
@@ -0,0 +1,12 @@
exports.foo = function () {
return this;
};
exports.set = function (x) {
this.x = x;
};
exports.get = function () {
return this.x;
};
exports.getClosed = function () {
return exports.x;
};
@@ -0,0 +1,8 @@
var test = require('test');
var a = require('a');
var foo = a.foo;
test.assert(a.foo() == a, 'calling a module member');
test.assert(foo() == (function (){return this})(), 'members not implicitly bound');
a.set(10);
test.assert(a.get() == 10, 'get and set')
test.print('DONE', 'info');
@@ -0,0 +1,15 @@
exports.print = typeof print !== "undefined" ? print : function () {
var system = require("system");
var stdio = system.stdio;
stdio.print.apply(stdio, arguments);
};
exports.assert = function (guard, message) {
if (guard) {
exports.print('PASS ' + message, 'pass');
} else {
exports.print('FAIL ' + message, 'fail');
}
};
@@ -0,0 +1,8 @@
var test = require('test');
try {
require('bogus');
test.print('FAIL require throws error when module missing', 'fail');
} catch (exception) {
test.print('PASS require throws error when module missing', 'pass');
}
test.print('DONE', 'info');
@@ -0,0 +1,15 @@
exports.print = typeof print !== "undefined" ? print : function () {
var system = require("system");
var stdio = system.stdio;
stdio.print.apply(stdio, arguments);
};
exports.assert = function (guard, message) {
if (guard) {
exports.print('PASS ' + message, 'pass');
} else {
exports.print('FAIL ' + message, 'fail');
}
};
@@ -0,0 +1 @@
require('program').monkey = 10;
@@ -0,0 +1,4 @@
var a = require('a');
var test = require('test');
test.assert(exports.monkey == 10, 'monkeys permitted');
test.print('DONE', 'info');
@@ -0,0 +1,15 @@
exports.print = typeof print !== "undefined" ? print : function () {
var system = require("system");
var stdio = system.stdio;
stdio.print.apply(stdio, arguments);
};
exports.assert = function (guard, message) {
if (guard) {
exports.print('PASS ' + message, 'pass');
} else {
exports.print('FAIL ' + message, 'fail');
}
};
@@ -0,0 +1,3 @@
exports.foo = function () {
return 1;
};
@@ -0,0 +1,3 @@
var test = require('test');
test.assert(require('a/b/c/d').foo() == 1, 'nested module identifier');
test.print('DONE', 'info');
@@ -0,0 +1,15 @@
exports.print = typeof print !== "undefined" ? print : function () {
var system = require("system");
var stdio = system.stdio;
stdio.print.apply(stdio, arguments);
};
exports.assert = function (guard, message) {
if (guard) {
exports.print('PASS ' + message, 'pass');
} else {
exports.print('FAIL ' + message, 'fail');
}
};
@@ -0,0 +1,5 @@
var test = require('test');
var a = require('submodule/a');
var b = require('submodule/b');
test.assert(a.foo == b.foo, 'a and b share foo through a relative require');
test.print('DONE', 'info');
@@ -0,0 +1 @@
exports.foo = require('./b').foo;
@@ -0,0 +1,2 @@
exports.foo = function () {
};
@@ -0,0 +1,15 @@
exports.print = typeof print !== "undefined" ? print : function () {
var system = require("system");
var stdio = system.stdio;
stdio.print.apply(stdio, arguments);
};
exports.assert = function (guard, message) {
if (guard) {
exports.print('PASS ' + message, 'pass');
} else {
exports.print('FAIL ' + message, 'fail');
}
};
@@ -0,0 +1 @@
exports.foo = require('b').foo;
@@ -0,0 +1 @@
exports.foo = require('c').foo;
@@ -0,0 +1,3 @@
exports.foo = function () {
return 1;
};
@@ -0,0 +1,3 @@
var test = require('test');
test.assert(require('a').foo() == 1, 'transitive');
test.print('DONE', 'info');

Some files were not shown because too many files have changed in this diff Show More