Compare commits

...
316 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
Francisco Ryan Tolmasky I 6a72e1b6ff Merge branch 'master' of git@github.com:280north/cappuccino 2010-04-12 12:22:25 -07:00
Francisco Ryan Tolmasky I b3141f1a62 Add CPApplicationWillTerminateNotification.
Reviewed by me.
2010-04-12 12:21:45 -07:00
Randall Luecke aea8f1f0dc Added proper background color to the tableview. 2010-04-12 02:09:46 -04:00
Francisco Ryan Tolmasky I 8aecf880e5 Merge branch 'master' of git@github.com:280north/cappuccino 2010-04-09 22:22:55 -07:00
Francisco Ryan Tolmasky I 7d5ce51910 Upped the version number to 0.8.1.
Reviewed by me.
2010-04-09 22:22:35 -07:00
Ross Boucher cfc8ccafce Remove typo. 2010-04-09 14:56:54 -07:00
Kelly McDonaldandRoss Boucher e11dfc2875 CPDragServer was checking the selector on the delegate of draggedImage:endAt:operation: but calling draggedImage:endedAt:operation:. I changed so that it uses endedAt to better reflect what is done in cocoa 2010-04-09 14:56:43 -07:00
Ross Boucher b3ef31ad05 Fixed: [CPArray isEqualToArray:nil] threw an exception instead of returning NO.
Conflicts:

	Foundation/CPArray.j
	Tests/Foundation/CPArrayTest.j
2010-04-09 14:51:46 -07:00
Ross Boucher 70410d6311 Fix the buttonNumber method of CPEvent.
Closes #70.
2010-04-09 14:38:08 -07:00
Ross Boucher 4cc7dec35b Throw syntax error for # followed by anything other than pragma. 2010-04-09 14:34:02 -07:00
Ross Boucher 47ecd40c4f Made the pre-processor capable of recognizing and ignoring Xcode's '#pragma mark' mark-ups
Conflicts:

	Objective-J/Preprocessor.js
2010-04-09 14:26:29 -07:00
saikatandRoss Boucher 489f2bcfa0 Reverting 1c9763eaa8 - autoresizing the contentview breaks sizetofit 2010-04-09 14:18:20 -07:00
Ross Boucher 16590e0603 Closes #590.
Closes #594.
2010-04-09 14:17:11 -07:00
Paul BaumgartandRoss Boucher f50cda9abc change CPAccordionItem to CPAccordionViewItem in CPAccordionView
selector types. Closes gh-596.
2010-04-09 13:58:05 -07:00
Francisco Ryan Tolmasky I 7543968203 Merge branch 'master' of git@github.com:280north/cappuccino 2010-04-08 23:59:00 -07:00
Francisco Ryan Tolmasky I 54685b1f36 One additional fix for IE not loading in certain occasions.
Reviewed by me.
2010-04-08 23:58:47 -07:00
Francisco Ryan Tolmasky I abdc601d92 Fix for IE not loading bug.
Reviewed by me.
2010-04-08 23:58:31 -07:00
Tom Robinson 9f50f08065 Add automated HTML5 cache manifest generation. Disabled by default. 2010-04-07 22:46:23 -07:00
Tom Robinson aabb1fa6f2 Move CPCursor test out of Resources. 2010-04-07 16:03:42 -07:00
Tom Robinson 4b770714bd Update starter task to include version of bootstrap which installs Cappuccino packages. 2010-04-06 12:54:23 -07:00
Ross Boucher 8175dbca53 Updates to the Jakefile and capp gen. 2010-04-06 12:26:35 -07:00
Tom Robinson c91332afb4 Add the other MobileSafari meta/link tags. 2010-04-05 20:09:04 -07:00
Tom Robinson 08fb1b33b4 Add viewport tag to templates. Fixes drawing errors on MobileSafari. 2010-04-05 18:14:04 -07:00
Ross Boucher cd6b6afc65 Don't convert text fields to bold default system font. 2010-04-05 10:38:20 -07:00
Tom Robinson cd4a70ea78 Add hook to CPApplicationMain to notify parent frame (if app is in a child frame of same origin) 2010-04-04 18:39:47 -07:00
Tom Robinson eb24ba9835 Re-enable flatten compression by default. 2010-04-01 23:48:48 -07:00
Tom Robinson 468869821f Add charset attributes to all external script tags, including flatten. Fixes unicode bugs in flatten. 2010-04-01 23:41:08 -07:00
Tom Robinson 0c85dbf9b0 Add some charset options, and disable compressor by default. 2010-04-01 23:15:47 -07:00
Tom Robinson 2db47e413e Add comrpessor support to flatten. 2010-04-01 12:01:16 -07:00
Tom Robinson b8fddc98bf Fixes flatten, splitting mode. Also escape dollar signs before replacing. 2010-04-01 11:12:08 -07:00
Tom Robinson 467f798147 Fixes flatten, non-splitting mode. 2010-04-01 11:11:58 -07:00
Ross Boucher 374f3d13f1 Convert default IB fonts to default Cappuccino fonts 2010-03-31 21:31:09 -07:00
Tom Robinson b0a35a183f Only enable debug logger in browsers, not command line utilities. 2010-03-31 17:28:46 -07:00
Francisco Ryan Tolmasky I 74e349ed33 Merge branch 'master' of git@github.com:280north/cappuccino 2010-03-31 17:05:32 -07:00
Francisco Ryan Tolmasky I c57aa2ac5e Fix for menu bar being broken if displayed after a window is ordered front in IE.
Reviewed by me.
2010-03-31 17:04:35 -07:00
Ross Boucher acac29dcda Merge branch 'master' of github.com:280north/cappuccino 2010-03-31 16:37:16 -07:00
Paul BaumgartandTom Robinson 675969af6d Add some dependency checking to bootstrap.sh: make sure correct JVM is
being used and ensure other dependencies are installed and on the $PATH.
2010-03-31 15:00:09 -07:00
Tom Robinson ce32177e1d Use "CommonJS" task as the dependency for "test" task for now. 2010-03-31 13:53:09 -07:00
Randall Luecke e956d61a08 Fixed bug introduced by renaming of private class. 2010-03-31 16:41:13 -04:00
Alexander LjungbergandRoss Boucher 068cdb9817 CPNull valueForKey:X returns CPNull for any value of X, paralleling [nil valueForKey:X]. Verified against Cocoa through empirical testing. 2010-03-31 13:17:42 -07:00
Randall Luecke 0ec7d4cd9a Made drag feedback view in the tableview more correct, fixed encoding issues.
Conflicts:

	AppKit/CPTableView.j
2010-03-31 16:11:10 -04:00
Nicholas Small 6a8126337c Added right click responder methods and context menu support. 2010-03-31 15:56:18 -04:00
Ross Boucher 12db25a829 Fix for a potential error in IE when setting a width to a negative value. 2010-03-31 12:11:21 -07:00
Ross Boucher a347bfb8b1 Sprite images recursively. 2010-03-31 11:10:17 -07:00
Francisco Ryan Tolmasky I 9255af210c Fix for loading Cappuccino apps locally on Windows.
Reviewed by me.
2010-03-30 16:28:42 -07:00
Tom Robinson 0b3264a99d Enable default logger in debug frameworks. Add configurable options to index-debug.html. 2010-03-30 14:12:59 -07:00
Ross Boucher 2bf16da441 These menu key equivs were incorrect. 2010-03-30 11:10:36 -07:00
Ross Boucher 5c4d890100 Fix a nil variable error that caused problems in Firefox 2. 2010-03-30 10:52:48 -07:00
Francisco Ryan Tolmasky I 99282026fa One more fix for image spriting.
Reviewed by me.
2010-03-30 00:45:11 -07:00
Francisco Ryan Tolmasky I 8f4b2a7cfd Fail more gracefully when main cib is not found.
Reviewed by me.
2010-03-29 23:20:31 -07:00
Randall Luecke c78feda3d6 Fixed nib2cib bug with cornerview where resources were not loaded from the correct location. 2010-03-30 01:45:36 -04:00
Francisco Ryan Tolmasky I a279d62c88 Merge branch 'master' of git@github.com:280north/cappuccino 2010-03-28 11:40:38 -07:00
Francisco Ryan Tolmasky I 8d1f787179 Fix for a few minor regressions:
1. Split out flatten specific code to get file size back down.
2. Fix for non-native string URL not working with the URLCache (typeof x !=== "string")
3. Fix for slight IE performance regression.

Reviewed by me.
2010-03-28 11:39:36 -07:00
Ross Boucher 7ab41cf195 If there is no key window or no main window make the first opened window those things. 2010-03-28 09:03:33 -07:00
Ross Boucher df728b7a21 Support terminating method signatures with ;. Closes #416. 2010-03-28 08:51:35 -07:00
Francisco Ryan Tolmasky I cba26faf9b Fix for HelloWorld not flattening correctly.
Reviewed by me.
2010-03-27 19:31:16 -07:00
Francisco Ryan Tolmasky I c4c1cffc01 Merge branch 'master' of git@github.com:280north/cappuccino 2010-03-27 18:53:03 -07:00
Francisco Ryan Tolmasky I 321706e5c6 Fix for user code errors during load not being reported (Cappuccino failing silently).
Reviewed by me.
2010-03-27 18:52:19 -07:00
Ross Boucher 47bf4c0baa Finish split view cursor implementation.
Closes #494.
2010-03-27 15:47:10 -07:00
Alexander LjungbergandRoss Boucher fc628c1221 CPSplitView resize cursors now require [[self window] setAcceptsMouseMovedEvents:YES]; to be called manually pending a CPTrackingArea based implementation. 2010-03-27 15:47:10 -07:00
Ross Boucher eb6a03704a Proper resize cursors for CPSplitView. Also enables resize cursor for additionalEffectiveRectOfDividerAtIndex areas.
Conflicts:

	AppKit/CPSplitView.j
2010-03-27 15:47:10 -07:00
Francisco Ryan Tolmasky I 7b855e6c68 Merge branch 'master' of git@github.com:280north/cappuccino 2010-03-27 13:56:35 -07:00
Francisco Ryan Tolmasky I fe0818c612 Don't generate image files if there aren't any.
Reviewed by me.
2010-03-27 13:54:07 -07:00
Ross Boucher 74dabcae8a Update the CPDictionary test suite. 2010-03-27 13:52:44 -07:00
Emmanuel MaillardandRoss Boucher daf7870bab - add containsKey: method 2010-03-27 13:41:32 -07:00
Ross Boucher 64da7f8775 define out DOM code from _CPImageAndTextView.
Closes #562.
2010-03-27 13:37:13 -07:00
aburkhalterandRoss Boucher 6cfa11a94d Initial boilerplate and file for putting the untested (at least not directly) CPView.j under test. Initial test to confirm we can actually create the object and a test demonstrating issue #562. 2010-03-27 13:33:04 -07:00
Ross Boucher db3c6c1463 A few minor updates to the pathExtension patch. 2010-03-27 13:25:44 -07:00
Emmanuel MaillardandRoss Boucher 65a669a9a1 - correct pathExtension and stringByDeletingPathExtension 2010-03-27 13:23:55 -07:00
Emmanuel MaillardandRoss Boucher 33f56bb203 - implement stringByDeletingPathExtension 2010-03-27 13:23:32 -07:00
Emmanuel MaillardandRoss Boucher 1ff873e170 - add tests for pathExtension and stringByDeletingPathExtension 2010-03-27 13:22:36 -07:00
Ross Boucher b0e0156880 Fix support for initial first responder. 2010-03-27 13:08:47 -07:00
Ross Boucher 896f36dffb A better (but not perfect) way to handle the browser's first responder state. 2010-03-27 11:27:44 -07:00
Ross Boucher eae975652e Add default line break mode. 2010-03-26 16:59:02 -07:00
Ross Boucher e46d1a793c autoresize the cpbrowser test browser. 2010-03-26 16:41:33 -07:00
Ross Boucher 1c9763eaa8 CPBox should autoresize its content view. 2010-03-26 16:41:23 -07:00
Ross Boucher 686370ac0e Add convenience accessors for the browser's selected items. 2010-03-26 15:52:53 -07:00
Ross Boucher e4ca057e4c Fix import directives. 2010-03-26 14:27:46 -07:00
Ross Boucher ac5a0e3dfc Add CPBrowser manual test app. 2010-03-26 14:00:51 -07:00
Ross Boucher a580b522e3 Add initial CPBrowser implementation. 2010-03-26 14:00:30 -07:00
Ross Boucher af53c271c7 Fix a few naming convention violations.
Make dragView.... use the columns its passed, rather than computing from scratch.
2010-03-26 13:59:41 -07:00
Ross Boucher 4476dad395 Whitespace fix. 2010-03-26 10:36:08 -07:00
Emmanuel MaillardandRoss Boucher b7b2dd2915 - CGPathAddQuadCurveToPoint fix for an unknown variable when using a transformation matrix 2010-03-26 10:36:08 -07:00
Francisco Ryan Tolmasky I efb6a0f5c6 Merge branch 'master' of git@github.com:280north/cappuccino 2010-03-26 01:31:39 -07:00
Francisco Ryan Tolmasky I deba653661 Fix for unrecognized selector in CPURL's initWithCoder:.
Reviewed by me.
2010-03-26 01:30:50 -07:00
Ross Boucher eb831dc4ac Typo. Closes #572. 2010-03-25 10:40:37 -07:00
Scott KyleandRoss Boucher b0d355a71c Some somewhat minor style fixes 2010-03-24 19:46:38 -07:00
Ross Boucher af11b4e423 Fix for pattern images not being displayed correctly under the new background color system 2010-03-23 14:32:24 -07:00
Ross Boucher 0cf86318ce Make semi-transparent background colors work in browsers that don't support RGBA.
Closes #569.
2010-03-23 14:26:32 -07:00
Ross Boucher 4175b762c3 Disable new syntax check while we work out the build issue some people are having. 2010-03-23 13:29:55 -07:00
Ross Boucher 3ddcb5f118 Remove duplicate method declaration. 2010-03-23 13:29:43 -07:00
Ross Boucher d0ad865976 Add the with{} back in for Class methods, instead take the disallowed list from objj_class. 2010-03-23 11:21:59 -07:00
Ross Boucher 7013b34897 Add a few additional syntax checks.
Throw an error if a method uses a parameter name that is also an ivar name.
Stop using with{} block for class methods.
2010-03-23 11:21:59 -07:00
Ross Boucher bbbae36e6a Missing - on a method. 2010-03-23 11:21:59 -07:00
Francisco Ryan Tolmasky I 34c3a9530b Fixed a bug where CPKeyedUnarchiver would incorrectly unarchive 0 as null.
Reviewed by me.
2010-03-23 02:06:44 -07:00
Francisco Ryan Tolmasky I 78cb522874 Temporarily revert "Make semi-transparent background colors work in browsers that don't support RGBA."
This fix was making lots of resources not show up.

This reverts commit f8c13f1e30.
2010-03-23 01:22:59 -07:00
Francisco Ryan Tolmasky I e8a0d2acf6 Merge branch 'master' of git@github.com:280north/cappuccino 2010-03-23 00:04:59 -07:00
Ross Boucher f8c13f1e30 Make semi-transparent background colors work in browsers that don't support RGBA.
Closes #569.
2010-03-22 19:00:49 -07:00
Randall Luecke 4b272a76fd Merge branch 'master' of git://github.com/280north/cappuccino 2010-03-22 19:27:13 -04:00
Randall Luecke f73d96af08 Fixed black background of dragview in Opera and IE. 2010-03-22 19:24:32 -04:00
Scott KyleandRoss Boucher bb0835e2f3 CPImageView should send action on drop, as in Cocoa 2010-03-22 16:15:02 -07:00
Ross Boucher ef4c108b9e Date test wasn't accurately accounting for daylight savings time. 2010-03-22 15:08:29 -07:00
Ross Boucher 319b9ed00f Use === not ==. 2010-03-22 14:53:49 -07:00
Alan RogersandRoss Boucher 35b62ca53f Updated test and fix for gh issue #539 2010-03-22 14:53:07 -07:00
Alan RogersandRoss Boucher 4e1e6f3c0b Little fix for CPDictionary, we should not try and recursively convert null JSON objects. 2010-03-22 14:52:55 -07:00
Alan RogersandRoss Boucher c8f3445fa6 Adding a unit test to verify fix to +[CPDictionary dictionaryWithJSObject:(JSObject)object recursively:(BOOL)recursively] 2010-03-22 14:52:49 -07:00
Emmanuel MaillardandRoss Boucher 7aa1ae6bd4 - fix typo 2010-03-22 14:43:53 -07:00
Emmanuel MaillardandRoss Boucher 58179939bb - fix a typo in documentation 2010-03-22 14:43:31 -07:00
Scott KyleandRoss Boucher 5d3eae9022 deleteBackwards: => deleteBackward: 2010-03-22 14:30:48 -07:00
aburkhalterandRoss Boucher 05f8a10b3d Trivial syntax fixes. 2010-03-22 14:29:27 -07:00
Francisco Ryan Tolmasky I 6843df410a Fix for empty data URLs, MHTML, etc. files being created when no image resources exist, causing a useless xhr.
Reviewed by me.
2010-03-21 14:30:31 -07:00
Randall Luecke f324577014 Fixed default height in tableheader for Nib2Cib. 2010-03-21 02:54:14 -04:00
Tom Robinson df8357e1fc Add --split option to flatten. Asynchronously load multiple flattened files. 2010-03-20 23:38:40 -07:00
Tom Robinson 35d14939c4 Fix for flatten in Firefox (silly security restriction makes onreadystatechange not readable) 2010-03-20 22:32:11 -07:00
Francisco Ryan Tolmasky I f2c19ad403 Slight fix for collectionView:canDragItemsAtIndexes:withEvent: not passing the correct event.
Reviewed by me.
2010-03-20 20:58:08 -07:00
Francisco Ryan Tolmasky I ed9fee3038 Added collectionView:canDragItemAtIndexes:forEvent:.
Reviewed by me.
2010-03-20 20:56:37 -07:00
Francisco Ryan Tolmasky I 58e31b9cb4 Merge branch 'master' of git@github.com:280north/cappuccino 2010-03-19 12:25:39 -07:00
Francisco Ryan Tolmasky I 401ee3fd94 Added itemAtIndex: to CPCollectionView and updates API names.
Reviewed by me.
2010-03-19 12:24:07 -07:00
Randall Luecke 43b601af9b Fixed TableTest for IE. 2010-03-17 21:07:47 -04:00
Francisco Ryan Tolmasky I 5581dd71fa Merge branch 'master' of git@github.com:280north/cappuccino 2010-03-17 01:17:50 -07:00
Tom Robinson d8fb849691 Refactor objj_eval to work in the browser. Move from CommonJS-specific code to Objective-J proper. 2010-03-16 23:57:37 -07:00
Tom Robinson 5f4281b851 Add default theme to flattened app, "-P" option for specifying other inlined files. 2010-03-16 22:38:30 -07:00
Tom Robinson 24ab176236 Make asyncLoader a configurable option on exports. 2010-03-16 22:38:30 -07:00
Tom Robinson 9c342ca19c Fix objj_eval (used in objj REPL, etc). 2010-03-16 22:38:30 -07:00
Randall Luecke 3ee3acc948 Fixed failed TableCibTest in Firefox. 2010-03-17 00:11:36 -04:00
Randall Luecke 9bdc5fa0fe Various nib2cib improvements on the tableview. 2010-03-16 22:49:38 -04:00
Randall Luecke d7a7d8e2ae Merge branch 'master' of git://github.com/280north/cappuccino 2010-03-16 22:47:40 -04:00
Ross Boucher 5a9682b1bd Remove two calls to a dead function. 2010-03-16 18:13:57 -07:00
Randall Luecke 3c97903ed0 Fixed Nib2Cib selection color for the tableview. 2010-03-16 19:34:04 -04:00
Ross Boucher c9cf21be80 Fix for sizeWithFont: in Internet Explorer. 2010-03-16 16:01:44 -07:00
Tom Robinson f0818d94e9 Typo in window.clearNativeInterval. 2010-03-16 15:44:45 -07:00
Francisco Ryan Tolmasky I 831555cf5a Merge branch 'master' of git@github.com:280north/cappuccino 2010-03-15 02:33:36 -07:00
Randall Luecke e0483e316e Fixed bug with nib2cib tableviews loading incorrect resources. 2010-03-14 17:24:36 -04:00
Ross Boucher c1fe45cbcd Add a way to tell a CPSplitView about a button bar for a specific divider index,
which mitigates the need to use additional effective rect delegate method when
using a split view + button bar.
2010-03-14 12:32:52 -07:00
Ross Boucher ef7ad8ee8e A few minor bug fixes for key/main window handling. 2010-03-13 22:49:06 -08:00
Ross Boucher 0ed7d46926 Add encoding support for CPButtonBar. 2010-03-13 22:49:06 -08:00
Tom Robinson ac69879fba Update flatten to use new file/function caching system. 2010-03-13 21:42:51 -08:00
Tom Robinson 50e779ef5a Add CFHTTPRequest and FileExecutable hooks for inlining files and module functions (for flatten). Removed hook used by flatten. 2010-03-13 21:35:15 -08:00
Tom Robinson 0032af1468 Merge branch 'master' of github.com:280north/cappuccino 2010-03-13 19:05:10 -08:00
Ross Boucher cf1c369dc3 Rewrite of CPButtonBar. Now it will automatically layout the buttons, and the position
and visibility of the resize control is configurable.

Also has class methods for plusButton and minusButton. API subject to change.
2010-03-13 17:37:28 -08:00
Tom Robinson ece7996895 Cleanup flatten, use resourceAtURL instead of manually walking path. 2010-03-13 01:17:47 -08:00
Randall Luecke 3cdfc1192a Fixes flickering issues with CPTableView if you hold the command key and drag. Closes #544 2010-03-13 00:07:00 -05:00
Ross Boucher 8b8998a2b9 Don't encode the search/cancel buttons. They add bloat and complicate the process. 2010-03-12 19:46:05 -08:00
Tom Robinson 677cf9e1df Change FileRequest to always use CFHTTPRequest and make async/sync configurable. Preparation for "flatten" changes. 2010-03-12 19:40:27 -08:00
Ross Boucher a08d4c6a06 Whitespace error. 2010-03-12 18:55:44 -08:00
aburkhalterandRoss Boucher e1e344dad1 Missing semi-colon. 2010-03-12 18:54:05 -08:00
aburkhalterandRoss Boucher b9427f84ae Fixes testShiftIndexesStartingAtIndex. Upward shifting no longer throws. 2010-03-12 18:53:58 -08:00
Andrew BurkhalterandRoss Boucher dc9d79bc3d Adding failing test demonstrating that CPIndexSet throws with negative delta (e.g. shifting indexes at starting point upwards). Simple downward shift example included and working successfully.
Misc method reorganization with test suite so it's a bit more intuitive.
2010-03-12 18:50:35 -08:00
Ross Boucher 503ce5502e Fix nib2cib support for CPSearchField 2010-03-12 18:49:37 -08:00
Tom Robinson 0e4d476d76 Add guard div to protect against iframes consuming events during tracking. 2010-03-12 17:25:19 -08:00
Francisco Ryan Tolmasky I cc2d579bc9 Merge branch '0.8.0' of git@github.com:280north/cappuccino 2010-03-12 03:33:21 -08:00
Tom Robinson 94bf2a36cf Updated flatten to work with new loader changes. 2010-03-11 15:56:58 -08:00
Tom Robinson 63127bf9c3 Fix CFBundle path deprecation warning and absoluteString not found. 2010-03-11 14:35:06 -08:00
Ross Boucher 033765e866 temporary fix for whiteSpace style issue in IE. 2010-03-11 14:28:31 -08:00
Ross Boucher 1634e4562a Update the template files to more modern standards. 2010-03-11 14:28:22 -08:00
Ross Boucher ed66d78585 Update the template files to more modern standards. 2010-03-11 14:27:15 -08:00
Ross Boucher 39e1514620 temporary fix for whiteSpace style issue in IE. 2010-03-11 14:18:24 -08:00
Randall Luecke 10b7eb83f1 Fixed previous commit so it doesn't break buttons in the tableview. 2010-03-09 23:52:08 -05:00
Randall Luecke 672be3991d Merge branch '0.8.0' of git://github.com/280north/cappuccino into 0.8.0 2010-03-09 23:49:03 -05:00
Randall Luecke b350c2be91 Fixed previous commit so it doesn't break buttons in the tableview. 2010-03-09 19:19:25 -05:00
Tom Robinson 68ab5bd4e7 Typo in CI script. 2010-03-09 16:12:13 -08:00
Tom Robinson bd21153300 Typo in CI script. 2010-03-09 16:07:39 -08:00
Tom Robinson 9cca7ead17 Factor out nightly build portion of CI script so not all branches push builds 2010-03-09 15:35:53 -08:00
Tom Robinson 4b1bf1fe65 Factor out nightly build portion of CI script so not all branches push builds 2010-03-09 15:32:13 -08:00
Randall Luecke 6d353f378d Fixed bug where editable tableview would not honor setEditable:NO for columns unless resized. closes #426 2010-03-09 14:43:12 -05:00
Randall Luecke cc2bb8f496 Fixed bug where editable tableview would not honor setEditable:NO for columns unless resized. closes #426 2010-03-09 14:39:26 -05:00
cacaodevandRandall Luecke 20853e3ad7 CPTableView & al. : change CPThemeStateHighlighted to CPThemeStateSelected to avoid conflicts with CPControl -highlight: method. 2010-03-09 11:43:37 -05:00
appdenandRandall Luecke 67def34e29 Added semi-colons to global vars and removed accidental gloabl variable. 2010-03-09 03:22:02 -05:00
appdenandRandall Luecke 54549b61e1 Added semi-colons to global vars and removed accidental gloabl variable. 2010-03-09 03:20:00 -05:00
Tom Robinson 3e7c3e952b Merge branch '0.8.0' of github.com:280north/cappuccino into 0.8.0 2010-03-08 19:03:14 -08:00
Francisco Ryan Tolmasky I e6411d7d90 Fix for classes declared in subfolders reporting wrong bundle (fictional).
Reviewed by me.
2010-03-08 18:27:43 -08:00
Francisco Ryan Tolmasky I 9e7d0d3183 Merge branch 'master' of git@github.com:280north/cappuccino 2010-03-08 18:23:36 -08:00
Francisco Ryan Tolmasky I 3ae4b1cf19 Fix for classes declared in subfolders reporting wrong bundle (fictional).
Reviewed by me.
2010-03-08 18:22:53 -08:00
Ross Boucher 2841223c9d Create the args and namedArgs objects in Bootstrap.js, pass them along up to CPApplication. 2010-03-08 15:14:09 -08:00
Tom Robinson ba713b8b06 Use getCappuccinoVersion() in various Jakefiles instead of hardcoded versions. 2010-03-08 15:10:08 -08:00
Tom Robinson c53bff288a Add a central version.json file. Change package building to insert version, revision, and timestamp. Auto-push tags. 2010-03-08 15:10:08 -08:00
Ross Boucher d85e8798c2 Create the args and namedArgs objects in Bootstrap.js, pass them along up to CPApplication. 2010-03-08 15:00:52 -08:00
Randall Luecke 6dbb4eedb7 Merge branch 'master' of git://github.com/280north/cappuccino 2010-03-08 10:56:56 -05:00
Francisco Ryan Tolmasky I 33b4b94426 Fix for loading bundles generating multiple did load callbacks.
Reviewed by me.
2010-03-08 01:03:52 -08:00
Randall Luecke 8410198c37 Merge branch 'master' of git://github.com/280north/cappuccino 2010-03-08 00:58:28 -05:00
Randall Luecke 4c4b42833a Added -selectedColumn to the tableview. 2010-03-08 00:00:28 -05:00
Randall Luecke 519a9300e2 Merge branch 'master' of git://github.com/280north/cappuccino 2010-03-07 23:39:41 -05:00
Randall Luecke 7522751fd2 Merge branch 'master' of git://github.com/280north/cappuccino 2010-03-07 20:50:29 -05:00
Randall Luecke f2165af48f Merge branch 'master' of git://github.com/280north/cappuccino 2010-03-07 10:30:17 -05:00
Randall Luecke e3a65a1847 Added preparatory support for group items in CPOutlineView. 2010-03-06 18:46:49 -05:00
253 changed files with 11271 additions and 2107 deletions
+1
View File
@@ -26,6 +26,7 @@
@import "CPApplication.j" @import "CPApplication.j"
@import "CPBezierPath.j" @import "CPBezierPath.j"
@import "CPBox.j" @import "CPBox.j"
@import "CPBrowser.j"
@import "CPButton.j" @import "CPButton.j"
@import "CPButtonBar.j" @import "CPButtonBar.j"
@import "CPCheckBox.j" @import "CPCheckBox.j"
+3 -3
View File
@@ -96,12 +96,12 @@
return _items; return _items;
} }
- (void)addItem:(CPAccordionItem)anItem - (void)addItem:(CPAccordionViewItem)anItem
{ {
[self insertItem:anItem atIndex:_items.length]; [self insertItem:anItem atIndex:_items.length];
} }
- (void)insertItem:(CPAccordionItem)anItem atIndex:(CPInteger)anIndex - (void)insertItem:(CPAccordionViewItem)anItem atIndex:(CPInteger)anIndex
{ {
// FIXME: SHIFT ITEMS RIGHT // FIXME: SHIFT ITEMS RIGHT
[_expandedItemIndexes addIndex:anIndex]; [_expandedItemIndexes addIndex:anIndex];
@@ -122,7 +122,7 @@
[self setNeedsLayout]; [self setNeedsLayout];
} }
- (void)removeItem:(CPAccordionItem)anItem - (void)removeItem:(CPAccordionViewItem)anItem
{ {
[self removeItemAtIndex:[_items indexOfObjectIdenticalTo:anItem]]; [self removeItemAtIndex:[_items indexOfObjectIdenticalTo:anItem]];
} }
+126 -159
View File
@@ -31,6 +31,7 @@
@import "CPCibLoading.j" @import "CPCibLoading.j"
@import "CPPlatform.j" @import "CPPlatform.j"
#include "Platform/Platform.h"
var CPMainCibFile = @"CPMainCibFile", var CPMainCibFile = @"CPMainCibFile",
CPMainCibFileHumanFriendly = @"Main cib file base name"; CPMainCibFileHumanFriendly = @"Main cib file base name";
@@ -131,6 +132,8 @@ CPRunContinuesResponse = -1002;
{ {
self = [super init]; self = [super init];
CPApp = self;
if (self) if (self)
{ {
_eventListeners = []; _eventListeners = [];
@@ -138,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;
@@ -213,84 +159,45 @@ CPRunContinuesResponse = -1002;
if (_delegate == aDelegate) if (_delegate == aDelegate)
return; return;
var defaultCenter = [CPNotificationCenter defaultCenter]; var defaultCenter = [CPNotificationCenter defaultCenter],
delegateNotifications =
[
CPApplicationWillFinishLaunchingNotification, @selector(applicationWillFinishLaunching:),
CPApplicationDidFinishLaunchingNotification, @selector(applicationDidFinishLaunching:),
CPApplicationWillBecomeActiveNotification, @selector(applicationWillBecomeActive:),
CPApplicationDidBecomeActiveNotification, @selector(applicationDidBecomeActive:),
CPApplicationWillResignActiveNotification, @selector(applicationWillResignActive:),
CPApplicationDidResignActiveNotification, @selector(applicationDidResignActive:),
CPApplicationWillTerminateNotification, @selector(applicationWillTerminate:)
],
count = [delegateNotifications count];
if (_delegate) if (_delegate)
{ {
[defaultCenter var index = 0;
removeObserver:_delegate
name:CPApplicationWillFinishLaunchingNotification
object:self];
[defaultCenter for (; index < count; index += 2)
removeObserver:_delegate {
name:CPApplicationDidFinishLaunchingNotification var notificationName = delegateNotifications[index],
object:self]; selector = delegateNotifications[index + 1];
[defaultCenter if ([_delegate respondsToSelector:selector])
removeObserver:_delegate [defaultCenter removeObserver:_delegate name:notificationName object:self];
name:CPApplicationWillBecomeActiveNotification }
object:self];
[defaultCenter
removeObserver:_delegate
name:CPApplicationDidBecomeActiveNotification
object:self];
[defaultCenter
removeObserver:_delegate
name:CPApplicationWillResignActiveNotification
object:self];
[defaultCenter
removeObserver:_delegate
name:CPApplicationDidResignActiveNotification
object:self];
} }
_delegate = aDelegate; _delegate = aDelegate;
if ([_delegate respondsToSelector:@selector(applicationWillFinishLaunching:)]) var index = 0;
[defaultCenter
addObserver:_delegate
selector:@selector(applicationWillFinishLaunching:)
name:CPApplicationWillFinishLaunchingNotification
object:self];
if ([_delegate respondsToSelector:@selector(applicationDidFinishLaunching:)]) for (; index < count; index += 2)
[defaultCenter {
addObserver:_delegate var notificationName = delegateNotifications[index],
selector:@selector(applicationDidFinishLaunching:) selector = delegateNotifications[index + 1];
name:CPApplicationDidFinishLaunchingNotification
object:self];
if ([_delegate respondsToSelector:@selector(applicationWillBecomeActive:)]) if ([_delegate respondsToSelector:selector])
[defaultCenter [defaultCenter addObserver:_delegate selector:selector name:notificationName object:self];
addObserver:_delegate }
selector:@selector(applicationWillBecomeActive:)
name:CPApplicationWillBecomeActiveNotification
object:self];
if ([_delegate respondsToSelector:@selector(applicationDidBecomeActive:)])
[defaultCenter
addObserver:_delegate
selector:@selector(applicationDidBecomeActive:)
name:CPApplicationDidBecomeActiveNotification
object:self];
if ([_delegate respondsToSelector:@selector(applicationWillResignActive:)])
[defaultCenter
addObserver:_delegate
selector:@selector(applicationWillResignActive:)
name:CPApplicationWillResignActiveNotification
object:self];
if ([_delegate respondsToSelector:@selector(applicationDidResignActive:)])
[defaultCenter
addObserver:_delegate
selector:@selector(applicationDidResignActive:)
name:CPApplicationDidResignActiveNotification
object:self];
} }
/*! /*!
@@ -369,6 +276,10 @@ CPRunContinuesResponse = -1002;
- (void)terminate:(id)aSender - (void)terminate:(id)aSender
{ {
[[CPNotificationCenter defaultCenter]
postNotificationName:CPApplicationWillTerminateNotification
object:self];
if (![CPPlatform isBrowser]) if (![CPPlatform isBrowser])
{ {
[[CPDocumentController sharedDocumentController] closeAllDocumentsWithDelegate:self [[CPDocumentController sharedDocumentController] closeAllDocumentsWithDelegate:self
@@ -862,8 +773,7 @@ CPRunContinuesResponse = -1002;
return windowController; return windowController;
var theDocument = [windowController document]; var theDocument = [windowController document];
if (theDocument !== delegate && [theDocument respondsToSelector:anAction])
if (theDocument != delegate && [theDocument respondsToSelector:anAction])
return theDocument; return theDocument;
return nil; return nil;
@@ -874,7 +784,7 @@ CPRunContinuesResponse = -1002;
Checks for a target in the following order: Checks for a target in the following order:
<ol> <ol>
<li>a responder from the key window</li> <li>a responder from the key window</li>
<li>a responder frmo the main window</li> <li>a responder from the main window</li>
<li>the CPApplication instance</li> <li>the CPApplication instance</li>
<li>the application delegate</li> <li>the application delegate</li>
<li>the document controller</li> <li>the document controller</li>
@@ -913,8 +823,6 @@ CPRunContinuesResponse = -1002;
- (void)setCallback:(Function)aCallback forNextEventMatchingMask:(unsigned int)aMask untilDate:(CPDate)anExpiration inMode:(CPString)aMode dequeue:(BOOL)shouldDequeue - (void)setCallback:(Function)aCallback forNextEventMatchingMask:(unsigned int)aMask untilDate:(CPDate)anExpiration inMode:(CPString)aMode dequeue:(BOOL)shouldDequeue
{ {
_eventListeners.push(_CPEventListenerMake(aMask, aCallback)); _eventListeners.push(_CPEventListenerMake(aMask, aCallback));
if (_eventListeners.length == 3) objj_debug_print_backtrace();
} }
- (CPEvent)setTarget:(id)aTarget selector:(SEL)aSelector forNextEventMatchingMask:(unsigned int)aMask untilDate:(CPDate)anExpiration inMode:(CPString)aMode dequeue:(BOOL)shouldDequeue - (CPEvent)setTarget:(id)aTarget selector:(SEL)aSelector forNextEventMatchingMask:(unsigned int)aMask untilDate:(CPDate)anExpiration inMode:(CPString)aMode dequeue:(BOOL)shouldDequeue
@@ -973,10 +881,9 @@ CPRunContinuesResponse = -1002;
[self endSheet:sheet returnCode:0]; [self endSheet:sheet returnCode:0];
} }
- (CPArray)arguments - (CPArray)arguments
{ {
if(_fullArgsString != window.location.hash) if(_fullArgsString !== window.location.hash)
[self _reloadArguments]; [self _reloadArguments];
return _args; return _args;
@@ -1009,12 +916,18 @@ CPRunContinuesResponse = -1002;
- (void)_reloadArguments - (void)_reloadArguments
{ {
_fullArgsString = window.location.hash; _fullArgsString = window.location.hash;
var args = _fullArgsString.replace("#", "").split("/").slice(0);
for(var i=0, count = args.length; i<count; i++) if (_fullArgsString.length)
args[i] = decodeURIComponent(args[i]); {
var args = _fullArgsString.substring(1).split("/");
_args = args; for (var i = 0, count = args.length; i < count; i++)
args[i] = decodeURIComponent(args[i]);
_args = args;
}
else
_args = [];
} }
- (CPDictionary)namedArguments - (CPDictionary)namedArguments
@@ -1058,7 +971,7 @@ CPRunContinuesResponse = -1002;
else if ([self mainWindow]) else if ([self mainWindow])
[[self mainWindow] makeKeyAndOrderFront:self]; [[self mainWindow] makeKeyAndOrderFront:self];
else else
[[[self mainMenu] window] makeKeyWindow]; //FIXME this may not actually work [[self mainMenu]._menuWindow makeKeyWindow]; //FIXME this may not actually work
_previousKeyWindow = nil; _previousKeyWindow = nil;
_previousMainWindow = nil; _previousMainWindow = nil;
@@ -1135,6 +1048,13 @@ var _CPRunModalLoop = function(anEvent)
function CPApplicationMain(args, namedArgs) function CPApplicationMain(args, namedArgs)
{ {
#if PLATFORM(DOM)
// hook to allow recorder, etc to manipulate things before starting AppKit
if (window.parent !== window && typeof window.parent._childAppIsStarting === "function")
window.parent._childAppIsStarting(window);
#endif
var mainBundle = [CPBundle mainBundle], var mainBundle = [CPBundle mainBundle],
principalClass = [mainBundle principalClass]; principalClass = [mainBundle principalClass];
@@ -1143,29 +1063,8 @@ function CPApplicationMain(args, namedArgs)
[principalClass sharedApplication]; [principalClass sharedApplication];
//FIXME? if ([args containsObject:"debug"])
if (!args) CPLogRegister(CPLogPopup);
{
var args = [CPApp arguments];
if([args containsObject:"debug"])
CPLogRegister(CPLogPopup);
}
if (!namedArgs)
{
var searchParams = window.location.search.substring(1).split("&");
namedArgs = [CPDictionary dictionary];
for(var i=0; i<searchParams.length; i++)
{
var index = searchParams[i].indexOf('=');
if(index == -1)
[namedArgs setObject: "" forKey:searchParams[i]];
else
[namedArgs setObject: searchParams[i].substring(index+1) forKey: searchParams[i].substring(0, index)];
}
}
CPApp._args = args; CPApp._args = args;
CPApp._namedArgs = namedArgs; CPApp._namedArgs = namedArgs;
@@ -1234,15 +1133,83 @@ 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];
} }
+ (void)cibDidFailToLoad:(CPCib)aCib
{
throw new Error("Could not load main cib file (Did you forget to nib2cib it?).");
}
+ (void)reset + (void)reset
{ {
_CPAppBootstrapperActions = nil; _CPAppBootstrapperActions = nil;
+952
View File
@@ -0,0 +1,952 @@
/*
* CPBrowser.j
* AppKit
*
* Created by Ross Boucher.
* Copyright 2010, 280 North, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@import "CPControl.j"
@import "CPImage.j"
@import "CPTableView.j"
@import "CPScrollView.j"
/*!
@ingroup appkit
@class CPBrowser
*/
@implementation CPBrowser : CPControl
{
id _delegate;
CPString _pathSeparator;
CPView _contentView;
CPScrollView _horizontalScrollView;
CPView _prototypeView;
CPArray _tableViews;
CPArray _tableDelegates;
id _rootItem;
BOOL _delegateSupportsImages;
SEL _doubleAction @accessors(property=doubleAction);
BOOL _allowsMultipleSelection;
BOOL _allowsEmptySelection;
Class _tableViewClass @accessors(property=tableViewClass);
float _rowHeight;
float _imageWidth;
float _leafWidth;
float _minColumnWidth;
float _defaultColumnWidth @accessors(property=defaultColumnWidth);
CPArray _columnWidths;
}
+ (CPImage)branchImage
{
return [[CPImage alloc] initWithContentsOfFile:[[CPBundle bundleForClass:[CPBrowser class]]
pathForResource:"browser-leaf.png"]
size:CGSizeMake(9,9)];
}
+ (CPImage)highlightedBranchImage
{
return [[CPImage alloc] initWithContentsOfFile:[[CPBundle bundleForClass:[CPBrowser class]]
pathForResource:"browser-leaf-highlighted.png"]
size:CGSizeMake(9,9)];
}
- (id)initWithFrame:(CGRect)aFrame
{
if (self = [super initWithFrame:aFrame])
{
_rowHeight = 23.0;
_defaultColumnWidth = 140.0;
_minColumnWidth = 80.0;
_imageWidth = 23.0;
_leafWidth = 13.0;
_columnWidths = [];
_pathSeparator = "/";
_tableViews = [];
_tableDelegates = [];
_allowsMultipleSelection = YES;
_allowsEmptySelection = YES;
_tableViewClass = [_CPBrowserTableView class];
_prototypeView = [[CPTextField alloc] initWithFrame:CGRectMakeZero()];
[_prototypeView setVerticalAlignment:CPCenterVerticalTextAlignment];
[_prototypeView setValue:[CPColor whiteColor] forThemeAttribute:"text-color" inState:CPThemeStateSelected];
[_prototypeView setLineBreakMode:CPLineBreakByTruncatingTail];
_horizontalScrollView = [[CPScrollView alloc] initWithFrame:[self bounds]];
[_horizontalScrollView setHasVerticalScroller:NO];
[_horizontalScrollView setAutohidesScrollers:YES];
[_horizontalScrollView setAutoresizingMask:CPViewWidthSizable|CPViewHeightSizable];
_contentView = [[CPView alloc] initWithFrame:CGRectMake(0, 0, 0, CGRectGetHeight([self bounds]))];
[_contentView setAutoresizingMask:CPViewHeightSizable];
[_horizontalScrollView setDocumentView:_contentView];
[self addSubview:_horizontalScrollView];
}
return self;
}
- (void)setPrototypeView:(CPView)aPrototypeView
{
_prototypeView = [CPKeyedUnarchiver unarchiveObjectWithData:
[CPKeyedArchiver archivedDataWithRootObject:aPrototypeView]];
}
- (CPView)prototypeView
{
return [CPKeyedUnarchiver unarchiveObjectWithData:
[CPKeyedArchiver archivedDataWithRootObject:_prototypeView]];
}
- (void)setDelegate:(id)anObject
{
_delegate = anObject;
_delegateSupportsImages = [_delegate respondsToSelector:@selector(browser:imageValueForItem:)];
[self loadColumnZero];
}
- (id)delegate
{
return _delegate;
}
- (CPTableView)tableViewInColumn:(unsigned)index
{
return _tableViews[index];
}
- (unsigned)columnOfTableView:(CPTableView)aTableView
{
return [_tableViews indexOfObject:aTableView];
}
- (void)loadColumnZero
{
if ([_delegate respondsToSelector:@selector(rootItemForBrowser:)])
_rootItem = [_delegate rootItemForBrowser:self];
else
_rootItem = nil;
[self setLastColumn:-1];
[self addColumn];
}
- (void)setLastColumn:(int)columnIndex
{
if (columnIndex >= _tableViews.length)
return;
var oldValue = _tableViews.length - 1;
// unloads all later columns.
var indexPlusOne = columnIndex + 1;
[[_tableViews.slice(indexPlusOne) valueForKey:"enclosingScrollView"]
makeObjectsPerformSelector:@selector(removeFromSuperview)];
_tableViews = _tableViews.slice(0, indexPlusOne);
_tableDelegates = _tableDelegates.slice(0, indexPlusOne);
if ([_delegate respondsToSelector:@selector(browser:didChangeLastColumn:toColumn:)])
[_delegate browser:self didChangeLastColumn:oldValue toColumn:columnIndex];
[self tile];
}
- (int)lastColumn
{
return _tableViews.length - 1;
}
- (void)addColumn
{
var lastIndex = [self lastColumn],
lastColumn = _tableViews[lastIndex],
selectionIndexes = [lastColumn selectedRowIndexes];
if (lastIndex >= 0 && [selectionIndexes count] > 1)
[CPException raise:CPInvalidArgumentException
reason:"Can't add column, column "+lastIndex+" has invalid selection."];
var index = lastIndex+1,
item = index === 0 ? _rootItem : [_tableDelegates[lastIndex] childAtIndex:[selectionIndexes firstIndex]];
if (index > 0 && item && [self isLeafItem:item])
return;
var table = [[_tableViewClass alloc] initWithFrame:CGRectMakeZero() browser:self];
[table setHeaderView:nil];
[table setCornerView:nil];
[table setAllowsMultipleSelection:_allowsMultipleSelection];
[table setAllowsEmptySelection:_allowsEmptySelection];
[table registerForDraggedTypes:[self registeredDraggedTypes]];
[self _addTableColumnsToTableView:table forColumnIndex:index];
var delegate = [[_CPBrowserTableDelegate alloc] init];
[delegate _setDelegate:_delegate];
[delegate _setBrowser:self];
[delegate _setIndex:index];
[delegate _setItem:item];
_tableViews[index] = table;
_tableDelegates[index] = delegate;
[table setDelegate:delegate];
[table setDataSource:delegate];
[table setTarget:delegate];
[table setAction:@selector(_tableViewClicked:)];
[table setDoubleAction:@selector(_tableViewDoubleClicked:)];
[table setDraggingDestinationFeedbackStyle:CPTableViewDraggingDestinationFeedbackStyleRegular];
var scrollView = [[_CPBrowserScrollView alloc] initWithFrame:CGRectMakeZero()];
[scrollView _setBrowser:self];
[scrollView setDocumentView:table];
[scrollView setHasHorizontalScroller:NO];
[scrollView setAutoresizingMask:CPViewHeightSizable];
[_contentView addSubview:scrollView];
[self tile];
[self scrollColumnToVisible:index];
}
- (void)_addTableColumnsToTableView:(CPTableView)aTableView forColumnIndex:(unsigned)index
{
if (_delegateSupportsImages)
{
var column = [[CPTableColumn alloc] initWithIdentifier:@"Image"],
view = [[CPImageView alloc] initWithFrame:CGRectMakeZero()];
[view setImageScaling:CPScaleProportionally];
[column setDataView:view];
[column setResizingMask:CPTableColumnNoResizing];
[aTableView addTableColumn:column];
}
var column = [[CPTableColumn alloc] initWithIdentifier:@"Content"];
[column setDataView:_prototypeView];
[column setResizingMask:CPTableColumnNoResizing];
[aTableView addTableColumn:column];
var column = [[CPTableColumn alloc] initWithIdentifier:@"Leaf"],
view = [[_CPBrowserLeafView alloc] initWithFrame:CGRectMakeZero()];
[view setBranchImage:[[self class] branchImage]];
[view setHighlightedBranchImage:[[self class] highlightedBranchImage]];
[column setDataView:view];
[column setResizingMask:CPTableColumnNoResizing];
[aTableView addTableColumn:column];
}
- (void)reloadColumn:(int)column
{
[[self tableViewInColumn:column] reloadData];
}
- (void)tile
{
var xOrigin = 0,
scrollerWidth = [CPScroller scrollerWidth],
height = CGRectGetHeight([_contentView bounds]);
for (var i = 0, count = _tableViews.length; i < count; i++)
{
var tableView = _tableViews[i],
scrollView = [tableView enclosingScrollView],
width = [self widthOfColumn:i],
tableHeight = CGRectGetHeight([tableView bounds]);
[[tableView tableColumnWithIdentifier:"Image"] setWidth:_imageWidth];
[[tableView tableColumnWithIdentifier:"Content"] setWidth:width - (_leafWidth + _delegateSupportsImages ? _imageWidth : 0) - scrollerWidth - scrollerWidth];
[[tableView tableColumnWithIdentifier:"Leaf"] setWidth:_leafWidth];
[tableView setRowHeight:_rowHeight];
[tableView setFrameSize:CGSizeMake(width - scrollerWidth, tableHeight)];
[scrollView setFrameOrigin:CGPointMake(xOrigin, 0)];
[scrollView setFrameSize:CGSizeMake(width, height)];
xOrigin += width;
}
[_contentView setFrameSize:CGSizeMake(xOrigin, height)];
}
- (unsigned)rowAtPoint:(CGPoint)aPoint
{
var column = [self columnAtPoint:aPoint];
if (column === -1)
return -1;
var tableView = _tableViews[column];
return [tableView rowAtPoint:[tableView convertPoint:aPoint fromView:self]];
}
- (unsigned)columnAtPoint:(CGPoint)aPoint
{
var adjustedPoint = [_contentView convertPoint:aPoint fromView:self];
for (var i = 0, count = _tableViews.length; i < count; i++)
{
var frame = [[_tableViews[i] enclosingScrollView] frame];
if (CGRectContainsPoint(frame, adjustedPoint))
return i;
}
return -1;
}
- (CGRect)rectOfRow:(unsigned)aRow inColumn:(unsigned)aColumn
{
var tableView = _tableViews[aColumn],
rect = [tableView rectOfRow:aRow];
rect.origin = [self convertPoint:rect.origin fromView:tableView];
return rect;
}
// ITEMS
- (id)itemAtRow:(int)row inColumn:(int)column
{
return [_tableDelegates[column] childAtIndex:row];
}
- (BOOL)isLeafItem:(id)item
{
return [_delegate respondsToSelector:@selector(browser:isLeafItem:)] && [_delegate browser:self isLeafItem:item];
}
- (id)parentForItemsInColumn:(int)column
{
return [_tableDelegates[column] _item];
}
- (CPSet)selectedItems
{
var selectedColumn = [self selectedColumn],
selectedIndexes = [self selectedRowIndexesInColumn:selectedColumn],
set = [CPSet set],
index = [selectedIndexes firstIndex];
while (index !== CPNotFound)
{
[set addObject:[self itemAtRow:index inColumn:selectedColumn]];
index = [selectedIndexes indexGreaterThanIndex:index];
}
return set;
}
- (id)selectedItem
{
var selectedColumn = [self selectedColumn],
selectedRow = [self selectedRowInColumn:selectedColumn];
return [self itemAtRow:selectedRow inColumn:selectedColumn];
}
// CLICK EVENTS
- (void)trackMouse:(CPEvent)anEvent
{
}
- (void)_column:(unsigned)columnIndex clickedRow:(unsigned)rowIndex
{
[self setLastColumn:columnIndex];
if (rowIndex >= 0)
[self addColumn];
[self doClick:self];
}
- (void)sendAction
{
[self sendAction:_action to:_target];
}
- (void)doClick:(id)sender
{
[self sendAction:_action to:_target];
}
- (void)doDoubleClick:(id)sender
{
[self sendAction:_doubleAction to:_target];
}
- (void)keyDown:(CPEvent)anEvent
{
var column = [self selectedColumn];
if (column === -1)
return;
[_tableViews[column] keyDown:anEvent];
}
// SIZING
- (float)columnContentWidthForColumnWidth:(float)aWidth
{
return aWidth - (_leafWidth + _delegateSupportsImages ? _imageWidth : 0) - [CPScroller scrollerWidth];
}
- (float)columnWidthForColumnContentWidth:(float)aWidth
{
return aWidth + (_leafWidth + _delegateSupportsImages ? _imageWidth : 0) + [CPScroller scrollerWidth];
}
- (void)setImageWidth:(float)aWidth
{
_imageWidth = aWidth;
[self tile];
}
- (float)imageWidth
{
return _imageWidth;
}
- (void)setMinColumnWidth:(float)minWidth
{
_minColumnWidth = minWidth;
[self tile];
}
- (float)minColumnWidth
{
return _minColumnWidth;
}
- (void)setWidth:(float)aWidth ofColumn:(unsigned)column
{
_columnWidths[column] = aWidth;
if ([_delegate respondsToSelector:@selector(browser:didResizeColumn:)])
[_delegate browser:self didResizeColumn:column];
[self tile];
}
- (float)widthOfColumn:(unsigned)column
{
var width = _columnWidths[column];
if (width == null)
width = _defaultColumnWidth;
return MAX([CPScroller scrollerWidth], MAX(_minColumnWidth, width));
}
- (void)setRowHeight:(float)aHeight
{
_rowHeight = aHeight;
}
- (float)rowHeight
{
return _rowHeight;
}
// SCROLLERS
- (void)scrollColumnToVisible:(unsigned)columnIndex
{
[_contentView scrollRectToVisible:[[[self tableViewInColumn:columnIndex] enclosingScrollView] frame]];
}
(void)scrollRowToVisible:(unsigned)rowIndex inColumn:(unsigned)columnIndex
{
[self scrollColumnToVisible:columnIndex];
[[self tableViewInColumn:columnIndex] scrollRowToVisible:rowIndex];
}
- (BOOL)autohidesScroller
{
return [_horizontalScrollView autohidesScrollers];
}
- (void)setAutohidesScroller:(BOOL)shouldHide
{
[_horizontalScrollView setAutohidesScrollers:shouldHide];
}
// SELECTION
- (unsigned)selectedRowInColumn:(unsigned)columnIndex
{
if (columnIndex > [self lastColumn] || columnIndex < 0)
return -1;
return [_tableViews[columnIndex] selectedRow];
}
- (unsigned)selectedColumn
{
var column = [self lastColumn],
row = [self selectedRowInColumn:column];
if (row >= 0)
return column;
else
return column - 1;
}
- (void)selectRow:(unsigned)row inColumn:(unsigned)column
{
var selectedIndexes = row === -1 ? [CPIndexSet indexSet] : [CPIndexSet indexSetWithIndex:row];
[self selectRowIndexes:selectedIndexes inColumn:column];
}
- (BOOL)allowsMultipleSelection
{
return _allowsMultipleSelection;
}
- (void)setAllowsMultipleSelection:(BOOL)shouldAllow
{
if (_allowsMultipleSelection === shouldAllow)
return;
_allowsMultipleSelection = shouldAllow;
[_tableViews makeObjectsPerformSelector:@selector(setAllowsMultipleSelection:) withObject:shouldAllow];
}
- (BOOL)allowsEmptySelection
{
return _allowsEmptySelection;
}
- (void)setAllowsEmptySelection:(BOOL)shouldAllow
{
if (_allowsEmptySelection === shouldAllow)
return;
_allowsEmptySelection = shouldAllow;
[_tableViews makeObjectsPerformSelector:@selector(setAllowsEmptySelection:) withObject:shouldAllow];
}
- (CPIndexSet)selectedRowIndexesInColumn:(unsigned)column
{
if (column < 0 || column > [self lastColumn] +1)
return [CPIndexSet indexSet];
return [[self tableViewInColumn:column] selectedRowIndexes];
}
- (void)selectRowIndexes:(CPIndexSet)indexSet inColumn:(unsigned)column
{
if (column < 0 || column > [self lastColumn] + 1)
return;
if ([_delegate respondsToSelector:@selector(browser:selectionIndexesForProposedSelection:inColumn:)])
indexSet = [_delegate browser:self selectionIndexesForProposedSelection:indexSet inColumn:column];
if ([_delegate respondsToSelector:@selector(browser:shouldSelectRowIndexes:inColumn:)] &&
![_delegate browser:self shouldSelectRowIndexes:indexSet inColumn:column])
return;
if ([_delegate respondsToSelector:@selector(browserSelectionIsChanging:)])
[_delegate browserSelectionIsChanging:self];
if (column > [self lastColumn])
[self addColumn];
[self setLastColumn:column];
[[self tableViewInColumn:column] selectRowIndexes:indexSet byExtendingSelection:NO];
[self scrollColumnToVisible:column];
if ([_delegate respondsToSelector:@selector(browserSelectionDidChange:)])
[_delegate browserSelectionDidChange:self];
}
- (void)setBackgroundColor:(CPColor)aColor
{
[super setBackgroundColor:aColor];
[_contentView setBackgroundColor:aColor];
}
- (BOOL)acceptsFirstResponder
{
return YES;
}
// DRAG AND DROP
- (void)registerForDraggedTypes:(CPArray)types
{
[super registerForDraggedTypes:types];
[_tableViews makeObjectsPerformSelector:@selector(registerForDraggedTypes:) withObject:types];
}
- (BOOL)canDragRowsWithIndexes:(CPIndexSet)rowIndexes inColumn:(int)columnIndex withEvent:(CPEvent)dragEvent
{
if ([_delegate respondsToSelector:@selector(browser:canDragRowsWithIndexes:inColumn:withEvent:)])
return [_delegate browser:self canDragRowsWithIndexes:rowIndexes inColumn:columnIndex withEvent:dragEvent];
return YES;
}
- (CPImage)draggingImageForRowsWithIndexes:(CPIndexSet)rowIndexes inColumn:(int)columnIndex withEvent:(CPEvent)dragEvent offset:(CGPoint)dragImageOffset
{
if ([_delegate respondsToSelector:@selector(browser:draggingImageForRowsWithIndexes:inColumn:withEvent:offset:)])
return [_delegate browser:self draggingImageForRowsWithIndexes:rowIndexes inColumn:columnIndex withEvent:dragEvent offset:dragImageOffset];
return nil;
}
- (CPView)draggingViewForRowsWithIndexes:(CPIndexSet)rowIndexes inColumn:(int)columnIndex withEvent:(CPEvent)dragEvent offset:(CGPoint)dragImageOffset
{
if ([_delegate respondsToSelector:@selector(browser:draggingViewForRowsWithIndexes:inColumn:withEvent:offset:)])
return [_delegate browser:self draggingViewForRowsWithIndexes:rowIndexes inColumn:columnIndex withEvent:dragEvent offset:dragImageOffset];
return nil;
}
@end
var _CPBrowserResizeControlBackgroundImage = nil;
@implementation _CPBrowserResizeControl : CPView
{
CGPoint _mouseDownX;
CPBrowser _browser;
unsigned _index;
unsigned _width;
}
+ (CPImage)backgroundImage
{
if (!_CPBrowserResizeControlBackgroundImage)
{
var path = [[CPBundle bundleForClass:[self class]] pathForResource:"browser-resize-control.png"];
_CPBrowserResizeControlBackgroundImage = [[CPImage alloc] initWithContentsOfFile:path
size:CGSizeMake(15, 14)];
}
return _CPBrowserResizeControlBackgroundImage;
}
- (id)initWithFrame:(CGRect)aFrame
{
if (self = [super initWithFrame:aFrame])
[self setBackgroundColor:[CPColor colorWithPatternImage:[[self class] backgroundImage]]];
return self;
}
- (void)mouseDown:(CPEvent)anEvent
{
_mouseDownX = [anEvent locationInWindow].x;
_browser = [[self superview] _browser];
_index = [_browser columnOfTableView:[[self superview] documentView]];
_width = [_browser widthOfColumn:_index];
}
- (void)mouseDragged:(CPEvent)anEvent
{
var deltaX = [anEvent locationInWindow].x - _mouseDownX;
[_browser setWidth:_width + deltaX ofColumn:_index];
}
- (void)mouseUp:(CPEvent)anEvent
{
}
@end
@implementation _CPBrowserScrollView : CPScrollView
{
_CPBrowserResizeControl _resizeControl;
CPBrowser _browser @accessors;
}
- (void)initWithFrame:(CGRect)aFrame
{
if (self = [super initWithFrame:aFrame])
{
_resizeControl = [[_CPBrowserResizeControl alloc] initWithFrame:CGRectMakeZero()];
[self addSubview:_resizeControl];
}
return self;
}
- (void)reflectScrolledClipView:(CPClipView)aClipView
{
[super reflectScrolledClipView:aClipView];
var frame = [_verticalScroller frame];
frame.size.height = CGRectGetHeight([self bounds]) - 14.0 - frame.origin.y;
[_verticalScroller setFrameSize:frame.size];
var resizeFrame = CGRectMake(CGRectGetMinX(frame), CGRectGetMaxY(frame), [CPScroller scrollerWidth], 14.0);
[_resizeControl setFrame:resizeFrame];
}
@end
@implementation _CPBrowserTableView : CPTableView
{
CPBrowser _browser;
}
- (id)initWithFrame:(CGRect)aFrame browser:(CPBrowser)aBrowser
{
if (self = [super initWithFrame:aFrame])
_browser = aBrowser;
return self;
}
- (BOOL)acceptsFirstResponder
{
return NO;
}
- (void)mouseDown:(CPEvent)anEvent
{
[super mouseDown:anEvent];
[[self window] makeFirstResponder:_browser];
}
- (CPView)browserView
{
return _browser;
}
- (BOOL)canDragRowsWithIndexes:(CPIndexSet)rowIndexes atPoint:(CGPoint)mouseDownPoint
{
return [_browser canDragRowsWithIndexes:rowIndexes inColumn:[_browser columnOfTableView:self] withEvent:[CPApp currentEvent]];
}
- (CPImage)dragImageForRowsWithIndexes:(CPIndexSet)dragRows tableColumns:(CPArray)theTableColumns event:(CPEvent)dragEvent offset:(CPPointPointer)dragImageOffset
{
return [_browser draggingImageForRowsWithIndexes:dragRows inColumn:[_browser columnOfTableView:self] withEvent:dragEvent offset:dragImageOffset] ||
[super dragImageForRowsWithIndexes:dragRows tableColumns:theTableColumns event:dragEvent offset:dragImageOffset];
}
- (CPView)dragViewForRowsWithIndexes:(CPIndexSet)dragRows tableColumns:(CPArray)theTableColumns event:(CPEvent)dragEvent offset:(CPPoint)dragViewOffset
{
var count = theTableColumns.length;
while (count--)
{
if ([theTableColumns[count] identifier] === "Leaf")
[theTableColumns removeObject:theTableColumns[count]];
}
return [_browser draggingViewForRowsWithIndexes:dragRows inColumn:[_browser columnOfTableView:self] withEvent:dragEvent offset:dragViewOffset] ||
[super dragViewForRowsWithIndexes:dragRows tableColumns:theTableColumns event:dragEvent offset:dragViewOffset];
}
- (void)moveUp:(id)sender
{
[super moveUp:sender];
[_browser selectRow:[self selectedRow] inColumn:[_browser selectedColumn]];
}
- (void)moveDown:(id)sender
{
[super moveDown:sender];
[_browser selectRow:[self selectedRow] inColumn:[_browser selectedColumn]];
}
- (void)moveLeft:(id)sender
{
var previousColumn = [_browser selectedColumn] - 1,
selectedRow = [_browser selectedRowInColumn:previousColumn];
[_browser selectRow:selectedRow inColumn:previousColumn];
}
- (void)moveRight:(id)sender
{
[_browser selectRow:0 inColumn:[_browser selectedColumn] + 1];
}
@end
@implementation _CPBrowserTableDelegate : CPObject
{
CPBrowser _browser @accessors;
unsigned _index @accessors;
id _delegate @accessors;
id _item @accessors;
}
- (unsigned)numberOfRowsInTableView:(CPTableView)aTableView
{
return [_delegate browser:_browser numberOfChildrenOfItem:_item];
}
- (void)tableView:(CPTableView)aTableView objectValueForTableColumn:(CPTableColumn)column row:(unsigned)row
{
if ([column identifier] === "Image")
return [_delegate browser:_browser imageValueForItem:[self childAtIndex:row]];
else if ([column identifier] === "Leaf")
return ![_browser isLeafItem:[self childAtIndex:row]];
else
return [_delegate browser:_browser objectValueForItem:[self childAtIndex:row]];
}
- (void)_tableViewDoubleClicked:(CPTableView)aTableView
{
[_browser doDoubleClick:self];
}
- (void)_tableViewClicked:(CPTableView)aTableView
{
var selectedIndexes = [aTableView selectedRowIndexes];
[_browser _column:_index clickedRow:[selectedIndexes count] === 1 ? [selectedIndexes firstIndex] : -1];
}
- (id)childAtIndex:(unsigned)index
{
return [_delegate browser:_browser child:index ofItem:_item];
}
- (BOOL)tableView:(CPTableView)aTableView acceptDrop:(id)info row:(int)row dropOperation:(CPTableViewDropOperation)operation
{
if ([_delegate respondsToSelector:@selector(browser:acceptDrop:atRow:column:dropOperation:)])
return [_delegate browser:_browser acceptDrop:info atRow:row column:_index dropOperation:operation];
else
return NO;
}
- (CPDragOperation)tableView:(CPTableView)aTableView validateDrop:(id)info proposedRow:(int)row proposedDropOperation:(CPTableViewDropOperation)operation
{
if ([_delegate respondsToSelector:@selector(browser:validateDrop:proposedRow:column:dropOperation:)])
[_delegate browser:_browser validateDrop:info proposedRow:row column:_index dropOperation:operation];
else
return CPDragOperationNone;
}
- (BOOL)tableView:(CPTableView)aTableView writeRowsWithIndexes:(CPIndexSet)rowIndexes toPasteboard:(CPPasteboard)pboard
{
if ([_delegate respondsToSelector:@selector(browser:writeRowsWithIndexes:inColumn:toPasteboard:)])
return [_delegate browser:_browser writeRowsWithIndexes:rowIndexes inColumn:_index toPasteboard:pboard];
else
return NO;
}
- (BOOL)respondsToSelector:(SEL)aSelector
{
if (aSelector === @selector(browser:writeRowsWithIndexes:inColumn:toPasteboard:))
return [_delegate respondsToSelector:@selector(browser:writeRowsWithIndexes:inColumn:toPasteboard:)];
else
return [super respondsToSelector:aSelector];
}
@end
@implementation _CPBrowserLeafView : CPView
{
BOOL _isLeaf @accessors(readonly, property=isLeaf);
CPImage _branchImage @accessors(property=branchImage);
CPImage _highlightedBranchImage @accessors(property=highlightedBranchImage);
}
- (BOOL)objectValue
{
return _isLeaf;
}
- (void)setObjectValue:(id)aValue
{
_isLeaf = !!aValue;
[self setNeedsLayout];
}
- (CGRect)rectForEphemeralSubviewNamed:(CPString)aName
{
if (aName === "image-view")
return CGRectInset([self bounds], 1, 1);
return [super rectForEphemeralSubviewNamed:aName];
}
- (CPView)createEphemeralSubviewNamed:(CPString)aName
{
if (aName === "image-view")
return [[CPImageView alloc] initWithFrame:CGRectMakeZero()];
return [super createEphemeralSubviewNamed:aName];
}
- (void)layoutSubviews
{
var imageView = [self layoutEphemeralSubviewNamed:@"image-view"
positioned:CPWindowAbove
relativeToEphemeralSubviewNamed:nil];
var isHighlighted = [self themeState] & CPThemeStateSelected;
[imageView setImage: _isLeaf ? (isHighlighted ? _highlightedBranchImage : _branchImage) : nil];
[imageView setImageScaling:CPScaleNone];
}
- (void)encodeWithCoder:(CPCoder)aCoder
{
[super encodeWithCoder:aCoder];
[aCoder encodeBool:_isLeaf forKey:"_CPBrowserLeafViewIsLeafKey"];
[aCoder encodeObject:_branchImage forKey:"_CPBrowserLeafViewBranchImageKey"];
[aCoder encodeObject:_highlightedBranchImage forKey:"_CPBrowserLeafViewHighlightedBranchImageKey"];
}
- (void)initWithCoder:(CPCoder)aCoder
{
if (self = [super initWithCoder:aCoder])
{
_isLeaf = [aCoder decodeBoolForKey:"_CPBrowserLeafViewIsLeafKey"];
_branchImage = [aCoder decodeObjectForKey:"_CPBrowserLeafViewBranchImageKey"];
_highlightedBranchImage = [aCoder decodeObjectForKey:"_CPBrowserLeafViewHighlightedBranchImageKey"];
}
return self;
}
@end
+2 -4
View File
@@ -502,8 +502,6 @@ CPButtonStateMixed = CPThemeState("mixed");
} }
else else
return [[_CPImageAndTextView alloc] initWithFrame:_CGRectMakeZero()]; return [[_CPImageAndTextView alloc] initWithFrame:_CGRectMakeZero()];
return [super createEphemeralSubviewNamed:aName];
} }
- (void)layoutSubviews - (void)layoutSubviews
@@ -512,8 +510,7 @@ CPButtonStateMixed = CPThemeState("mixed");
positioned:CPWindowBelow positioned:CPWindowBelow
relativeToEphemeralSubviewNamed:@"content-view"]; relativeToEphemeralSubviewNamed:@"content-view"];
if (bezelView) [bezelView setBackgroundColor:[self currentValueForThemeAttribute:@"bezel-color"]];
[bezelView setBackgroundColor:[self currentValueForThemeAttribute:@"bezel-color"]];
var contentView = [self layoutEphemeralSubviewNamed:@"content-view" var contentView = [self layoutEphemeralSubviewNamed:@"content-view"
positioned:CPWindowAbove positioned:CPWindowAbove
@@ -533,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];
} }
} }
+235 -27
View File
@@ -4,18 +4,50 @@
#include "CoreGraphics/CGGeometry.h" #include "CoreGraphics/CGGeometry.h"
@implementation CPButtonBar : CPControl @implementation CPButtonBar : CPView
{ {
BOOL _hasResizeControl;
BOOL _resizeControlIsLeftAligned;
CPArray _buttons;
} }
- (id)initWithFrame:(CGRect)aFrame + (id)plusButton
{ {
self = [super initWithFrame:aFrame]; var button = [[CPButton alloc] initWithFrame:CGRectMake(0, 0, 35, 25)],
image = [[CPImage alloc] initWithContentsOfFile:[[CPBundle bundleForClass:[CPButtonBar class]] pathForResource:@"plus_button.png"] size:CGSizeMake(11, 12)];
if (self) [button setBordered:NO];
[self setNeedsLayout]; [button setImage:image];
[button setImagePosition:CPImageOnly];
return self; return button;
}
+ (id)minusButton
{
var button = [[CPButton alloc] initWithFrame:CGRectMake(0, 0, 35, 25)],
image = [[CPImage alloc] initWithContentsOfFile:[[CPBundle bundleForClass:[CPButtonBar class]] pathForResource:@"minus_button.png"] size:CGSizeMake(11, 4)];
[button setBordered:NO];
[button setImage:image];
[button setImagePosition:CPImageOnly];
return button;
}
+ (id)actionPopupButton
{
var button = [[CPPopUpButton alloc] initWithFrame:CGRectMake(0, 0, 35, 25)],
image = [[CPImage alloc] initWithContentsOfFile:[[CPBundle bundleForClass:[CPButtonBar class]] pathForResource:@"action_button.png"] size:CGSizeMake(22, 14)];
[button addItemWithTitle:nil];
[[button lastItem] setImage:image];
[button setImagePosition:CPImageOnly];
[button setValue:CGInsetMake(0, 0, 0, 0) forThemeAttribute:"content-inset"];
[button setPullsDown:YES];
return button;
} }
+ (CPString)themeClass + (CPString)themeClass
@@ -25,47 +57,223 @@
+ (id)themeAttributes + (id)themeAttributes
{ {
return [CPDictionary dictionaryWithObjects:[[CPNull null]] return [CPDictionary dictionaryWithObjects:[CGInsetMake(0.0, 0.0, 0.0, 0.0), CGSizeMakeZero(), [CPNull null], [CPNull null], [CPNull null], [CPNull null]]
forKeys:[@"bezel-color"]]; forKeys:[@"resize-control-inset", @"resize-control-size", @"resize-control-color", @"bezel-color", @"button-bezel-color", @"button-text-color"]];
}
- (id)initWithFrame:(CGRect)aFrame
{
self = [super initWithFrame:aFrame];
if (self)
{
_buttons = [];
[self setNeedsLayout];
}
return self;
}
- (void)awakeFromCib
{
var view = [self superview],
subview = self;
while (view)
{
if ([view isKindOfClass:[CPSplitView class]])
{
var viewIndex = [[view subviews] indexOfObject:subview];
[view setButtonBar:self forDividerAtIndex:viewIndex];
break;
}
subview = view;
view = [view superview];
}
}
- (void)setButtons:(CPArray)buttons
{
_buttons = [CPArray arrayWithArray:buttons];
for (var i = 0, count = [_buttons count]; i < count; i++)
[_buttons[i] setBordered:YES];
[self setNeedsLayout];
}
- (CPArray)buttons
{
return [CPArray arrayWithArray:_buttons];
}
- (void)setHasResizeControl:(BOOL)shouldHaveResizeControl
{
if (_hasResizeControl === shouldHaveResizeControl)
return;
_hasResizeControl = !!shouldHaveResizeControl;
[self setNeedsLayout];
}
- (BOOL)hasResizeControl
{
return _hasResizeControl;
}
- (void)setResizeControlIsLeftAligned:(BOOL)shouldBeLeftAligned
{
if (_resizeControlIsLeftAligned === shouldBeLeftAligned)
return;
_resizeControlIsLeftAligned = !!shouldBeLeftAligned;
[self setNeedsLayout];
}
- (BOOL)resizeControlIsLeftAligned
{
return _resizeControlIsLeftAligned;
}
- (CGRect)resizeControlFrame
{
var inset = [self currentValueForThemeAttribute:@"resize-control-inset"],
size = [self currentValueForThemeAttribute:@"resize-control-size"],
currentSize = [self bounds],
leftOrigin = _resizeControlIsLeftAligned ? 0 : currentSize.size.width - size.width - inset.right - inset.left;
return CGRectMake(leftOrigin, 0, size.width + inset.left + inset.right, size.height + inset.top + inset.bottom);
} }
- (CGRect)rectForEphemeralSubviewNamed:(CPString)aName - (CGRect)rectForEphemeralSubviewNamed:(CPString)aName
{ {
if (aName === "bezel-view") if (aName === "resize-control-view")
return [self bounds]; {
var inset = [self currentValueForThemeAttribute:@"resize-control-inset"],
size = [self currentValueForThemeAttribute:@"resize-control-size"],
currentSize = [self bounds];
if (_resizeControlIsLeftAligned)
return CGRectMake(inset.left, inset.top, size.width, size.height);
else
return CGRectMake(currentSize.size.width - size.width - inset.right, inset.top, size.width, size.height);
}
return [super rectForEphemeralSubviewNamed:aName]; return [super rectForEphemeralSubviewNamed:aName];
} }
- (CPView)createEphemeralSubviewNamed:(CPString)aName - (CPView)createEphemeralSubviewNamed:(CPString)aName
{ {
if (aName === "bezel-view") if (aName === "resize-control-view")
{ return [[CPView alloc] initWithFrame:CGRectMakeZero()];
var view = [[CPView alloc] initWithFrame:_CGRectMakeZero()];
[view setHitTests:NO];
return view;
}
return [super createEphemeralSubviewNamed:aName]; return [super createEphemeralSubviewNamed:aName];
} }
- (void)layoutSubviews - (void)layoutSubviews
{ {
var bezelView = [self layoutEphemeralSubviewNamed:@"bezel-view" [self setBackgroundColor:[self currentValueForThemeAttribute:@"bezel-color"]];
positioned:CPWindowBelow
relativeToEphemeralSubviewNamed:@""];
if (bezelView) var normalColor = [self valueForThemeAttribute:@"button-bezel-color" inState:CPThemeStateNormal],
[bezelView setBackgroundColor:[self currentValueForThemeAttribute:@"bezel-color"]]; highlightedColor = [self valueForThemeAttribute:@"button-bezel-color" inState:CPThemeStateHighlighted],
disabledColor = [self valueForThemeAttribute:@"button-bezel-color" inState:CPThemeStateDisabled],
textColor = [self valueForThemeAttribute:@"button-text-color" inState:CPThemeStateNormal];
var buttonsNotHidden = [CPArray arrayWithArray:_buttons],
count = [buttonsNotHidden count];
while (count--)
if ([buttonsNotHidden[count] isHidden])
[buttonsNotHidden removeObject:buttonsNotHidden[count]];
var currentButtonOffset = _resizeControlIsLeftAligned ? CGRectGetMaxX([self bounds]) + 1 : -1,
bounds = [self bounds],
height = CGRectGetHeight(bounds) - 1,
frameWidth = CGRectGetWidth(bounds),
resizeRect = _hasResizeControl ? [self rectForEphemeralSubviewNamed:"resize-control-view"] : CGRectMakeZero(),
resizeWidth = CGRectGetWidth(resizeRect),
availableWidth = frameWidth - resizeWidth - 1;
for (var i = 0, count = [buttonsNotHidden count]; i < count; i++)
{
var button = buttonsNotHidden[i],
width = CGRectGetWidth([button frame]);
if (availableWidth > width)
availableWidth -=width;
else
break;
if (_resizeControlIsLeftAligned)
{
[button setFrame:CGRectMake(currentButtonOffset - width, 1, width, height)];
currentButtonOffset -= width - 1;
}
else
{
[button setFrame:CGRectMake(currentButtonOffset, 1, width, height)];
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];
}
if (_hasResizeControl)
{
var resizeControlView = [self layoutEphemeralSubviewNamed:@"resize-control-view"
positioned:CPWindowAbove
relativeToEphemeralSubviewNamed:nil];
[resizeControlView setAutoresizingMask: _resizeControlIsLeftAligned ? CPViewMaxXMargin : CPViewMinXMargin];
[resizeControlView setBackgroundColor:[self currentValueForThemeAttribute:@"resize-control-color"]];
}
} }
- (void)addSubview:(CPView)aSubview - (void)setFrameSize:(CGSize)aSize
{ {
[super addSubview:aSubview]; [super setFrameSize:aSize];
[self setNeedsLayout];
[aSubview setAutoresizingMask:CPViewMinXMargin]; }
@end
var CPButtonBarHasResizeControlKey = @"CPButtonBarHasResizeControlKey",
CPButtonBarResizeControlIsLeftAlignedKey = @"CPButtonBarResizeControlIsLeftAlignedKey",
CPButtonBarButtonsKey = @"CPButtonBarButtonsKey";
@implementation CPButtonBar (CPCoding)
- (void)encodeWithCoder:(CPCoder)aCoder
{
[super encodeWithCoder:aCoder];
[aCoder encodeBool:_hasResizeControl forKey:CPButtonBarHasResizeControlKey];
[aCoder encodeBool:_resizeControlIsLeftAligned forKey:CPButtonBarResizeControlIsLeftAlignedKey];
[aCoder encodeObject:_buttons forKey:CPButtonBarButtonsKey];
}
- (id)initWithCoder:(CPCoder)aCoder
{
if (self = [super initWithCoder:aCoder])
{
_buttons = [aCoder decodeObjectForKey:CPButtonBarButtonsKey] || [];
_hasResizeControl = [aCoder decodeBoolForKey:CPButtonBarHasResizeControlKey];
_resizeControlIsLeftAligned = [aCoder decodeBoolForKey:CPButtonBarResizeControlIsLeftAlignedKey];
}
return self;
} }
@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
+40 -10
View File
@@ -120,9 +120,13 @@
[super setBoundsOrigin:aPoint]; [super setBoundsOrigin:aPoint];
var superview = [self superview]; var superview = [self superview],
if([superview isKindOfClass:[CPScrollView class]]) // This is hack to avoid having to import CPScrollView.
// FIXME: Should CPScrollView be finding out about this on its own somehow?
scrollViewClass = objj_getClass("CPScrollView");
if([superview isKindOfClass:scrollViewClass])
[superview reflectScrolledClipView:self]; [superview reflectScrolledClipView:self];
} }
@@ -173,26 +177,52 @@
return; return;
// ... and we're in a scroll view of course. // ... and we're in a scroll view of course.
var superview = [self superview]; var superview = [self superview],
if ([superview isKindOfClass:[CPScrollView class]]) // This is hack to avoid having to import CPScrollView.
// FIXME: Should CPScrollView be finding out about this on its own somehow?
scrollViewClass = objj_getClass("CPScrollView");
if ([superview isKindOfClass:scrollViewClass])
[superview reflectScrolledClipView:self]; [superview reflectScrolledClipView:self];
} }
- (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
+73 -31
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;
@@ -597,6 +614,10 @@
if (![_selectionIndexes count]) if (![_selectionIndexes count])
return; return;
if ([_delegate respondsToSelector:@selector(collectionView:canDragItemsAtIndexes:withEvent:)] &&
![_delegate collectionView:self canDragItemsAtIndexes:_selectionIndexes withEvent:_mouseDownEvent])
return;
// Set up the pasteboard // Set up the pasteboard
var dragTypes = [_delegate collectionView:self dragTypesForItemsAtIndexes:_selectionIndexes]; var dragTypes = [_delegate collectionView:self dragTypesForItemsAtIndexes:_selectionIndexes];
@@ -676,41 +697,42 @@
return _delegate; return _delegate;
} }
- (CPCollectionViewItem)itemAtIndex:(unsigned)anIndex
{
return [_items objectAtIndex:anIndex];
}
- (CGRect)frameForItemAtIndex:(unsigned)anIndex
{
return [[[self itemAtIndex:anIndex] view] frame];
}
- (CGRect)frameForItemsAtIndexes:(CPIndexSet)anIndexSet
{
var indexArray = [],
frame = CGRectNull;
[anIndexSet getIndexes:indexArray maxCount:-1 inIndexRange:nil];
var index = 0,
count = [indexArray count];
for (; index < count; ++index)
frame = CGRectUnion(frame, [self frameForItemAtIndex:indexArray[index]]);
return frame;
}
@end @end
@implementation CPCollectionView (KeyboardInteraction) @implementation CPCollectionView (KeyboardInteraction)
- (CGRect)rectForItemAtIndex:(int)index
{
// Don't re-compute anything just grab the current frame
// This allows subclasses to override tile without messing this up.
return [[_items[index] view] frame];
}
- (CGRect)rectForItemsAtIndexes:(CPIndexSet)indexSet
{
var indexArray = [],
rect = nil;
[indexSet getIndexes:indexArray maxCount:-1 inIndexRange:nil];
for (var i = 0, count = indexArray.length; i < count; ++i)
{
var index = indexArray[i];
if (rect == nil)
rect = [self rectForItemAtIndex:index];
else
rect = CGRectUnion(rect, [self rectForItemAtIndex:index]);
}
return rect;
}
- (void)_scrollToSelection - (void)_scrollToSelection
{ {
var rect = [self rectForItemsAtIndexes:[self selectionIndexes]]; var frame = [self frameForItemsAtIndexes:[self selectionIndexes]];
if (rect)
[self scrollRectToVisible:rect]; if (!CGRectIsNull(frame))
[self scrollRectToVisible:frame];
} }
- (void)moveLeft:(id)sender - (void)moveLeft:(id)sender
@@ -753,7 +775,7 @@
[self _scrollToSelection]; [self _scrollToSelection];
} }
- (void)deleteBackwards:(id)sender - (void)deleteBackward:(id)sender
{ {
if ([[self delegate] respondsToSelector:@selector(collectionView:shouldDeleteItemsAtIndexes:)]) if ([[self delegate] respondsToSelector:@selector(collectionView:shouldDeleteItemsAtIndexes:)])
{ {
@@ -775,6 +797,26 @@
@end @end
@implementation CPCollectionView (Deprecated)
- (CGRect)rectForItemAtIndex:(int)anIndex
{
_CPReportLenientDeprecation([self class], _cmd, @selector(frameForItemAtIndex:));
// Don't re-compute anything just grab the current frame
// This allows subclasses to override tile without messing this up.
return [self frameForItemAtIndex:anIndex];
}
- (CGRect)rectForItemsAtIndexes:(CPIndexSet)anIndexSet
{
_CPReportLenientDeprecation([self class], _cmd, @selector(frameForItemsAtIndexes:));
return [self frameForItemsAtIndexes:anIndexSet];
}
@end
var CPCollectionViewMinItemSizeKey = @"CPCollectionViewMinItemSizeKey", var CPCollectionViewMinItemSizeKey = @"CPCollectionViewMinItemSizeKey",
CPCollectionViewMaxItemSizeKey = @"CPCollectionViewMaxItemSizeKey", CPCollectionViewMaxItemSizeKey = @"CPCollectionViewMaxItemSizeKey",
CPCollectionViewVerticalMarginKey = @"CPCollectionViewVerticalMarginKey", CPCollectionViewVerticalMarginKey = @"CPCollectionViewVerticalMarginKey",
+9 -55
View File
@@ -438,50 +438,15 @@ var cachedBlackColor,
{ {
_components = components; _components = components;
if (!CPFeatureIsCompatible(CPCSSRGBAFeature) && _components[3] != 1.0 && window.Base64 && window.CRC32) var hasAlpha = CPFeatureIsCompatible(CPCSSRGBAFeature) && _components[3] != 1.0;
{
var bytes = [0x89,0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x1,0x8,0x3,0x0,0x0,0x0,0x28,0xcb,0x34,0xbb,0x0,0x0,0x3,0x0,0x50,0x4c,0x54,0x45,0xff,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x17,0x89,0x99,0x55,0x0,0x0,0x0,0x1,0x74,0x52,0x4e,0x53,0x0,0x40,0xe6,0xd8,0x66,0x0,0x0,0x0,0x10,0x49,0x44,0x41,0x54,0x78,0xda,0x62,0x60,0x0,0x0,0x0,0x0,0xff,0xff,0x3,0x0,0x0,0x2,0x0,0x1,0x24,0x7f,0x24,0xf1,0x0,0x0,0x0,0x0,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82,0xff];
var r_off = 41;
var g_off = 42;
var b_off = 43;
var a_off = 821;
var plte_crc_off = 809;
var trns_crc_off = 822;
var plte_type_off = 37;
var trns_type_off = 817;
bytes[r_off] = Math.round(_components[0]*255); _cssString = (hasAlpha ? "rgba(" : "rgb(") +
bytes[g_off] = Math.round(_components[1]*255); parseInt(_components[0] * 255.0) + ", " +
bytes[b_off] = Math.round(_components[2]*255); parseInt(_components[1] * 255.0) + ", " +
bytes[a_off] = Math.round(_components[3]*255); parseInt(_components[2] * 255.0) +
(hasAlpha ? (", " + _components[3]) : "") + ")";
// calculate new CRCs
var new_plte_crc = integerToBytes(CRC32.getCRC(bytes, plte_type_off, 4+768), 4);
var new_trns_crc = integerToBytes(CRC32.getCRC(bytes, trns_type_off, 4+1), 4);
// overwrite old CRCs with new ones
for (var i = 0; i < 4; i++)
{
bytes[plte_crc_off+i] = new_plte_crc[i];
bytes[trns_crc_off+i] = new_trns_crc[i];
}
// Base64 encode, strip whitespace and build data URL
var base64image = Base64.encode(bytes); //.replace(/[\s]/g, "");
_cssString = "url(\"data:image/png;base64," + base64image + "\")";
}
else
{
var hasAlpha = CPFeatureIsCompatible(CPCSSRGBAFeature) && _components[3] != 1.0;
_cssString = (hasAlpha ? "rgba(" : "rgb(") +
parseInt(_components[0] * 255.0) + ", " +
parseInt(_components[1] * 255.0) + ", " +
parseInt(_components[2] * 255.0) +
(hasAlpha ? (", " + _components[3]) : "") + ")";
}
} }
return self; return self;
} }
@@ -494,6 +459,7 @@ var cachedBlackColor,
{ {
_patternImage = anImage; _patternImage = anImage;
_cssString = "url(\"" + [_patternImage filename] + "\")"; _cssString = "url(\"" + [_patternImage filename] + "\")";
_components = [0.0, 0.0, 0.0, 1.0];
} }
return self; return self;
@@ -736,7 +702,7 @@ var CPColorComponentsKey = @"CPColorComponentsKey",
var hexCharacters = "0123456789ABCDEF"; var hexCharacters = "0123456789ABCDEF";
// HACK: prevent these from becoming globals. workaround for obj-j "function foo(){}" behavior // HACK: prevent these from becoming globals. workaround for obj-j "function foo(){}" behavior
var hexToRGB, integerToBytes, rgbToHex, byteToHex; var hexToRGB, rgbToHex, byteToHex;
/*! /*!
Used for the CPColor \c +colorWithHexString: implementation Used for the CPColor \c +colorWithHexString: implementation
@@ -764,18 +730,6 @@ function hexToRGB(hex)
return [red, green, blue, 1.0]; return [red, green, blue, 1.0];
} }
function integerToBytes(integer, length) {
if (!length)
length = (integer == 0) ? 1 : Math.round((Math.log(integer)/Math.log(2))/8+0.5);
var bytes = new Array(length);
for (var i = length-1; i >= 0; i--) {
bytes[i] = integer & 255;
integer = integer >> 8
}
return bytes;
}
function rgbToHex(r,g,b) { function rgbToHex(r,g,b) {
return byteToHex(r) + byteToHex(g) + byteToHex(b); return byteToHex(r) + byteToHex(g) + byteToHex(b);
} }
+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];
+1 -3
View File
@@ -65,8 +65,6 @@ CPInputTypeCanBeChangedFeature = 1 << 25;
CPHTML5DragAndDropSourceYOffBy1 = 1 << 26; CPHTML5DragAndDropSourceYOffBy1 = 1 << 26;
var USER_AGENT = "", var USER_AGENT = "",
PLATFORM_ENGINE = CPUnknownBrowserEngine, PLATFORM_ENGINE = CPUnknownBrowserEngine,
PLATFORM_FEATURES = 0; PLATFORM_FEATURES = 0;
@@ -75,7 +73,7 @@ var USER_AGENT = "",
PLATFORM_FEATURES |= CPInputTypeCanBeChangedFeature; PLATFORM_FEATURES |= CPInputTypeCanBeChangedFeature;
if (typeof window != "undfined" && typeof window.navigator != "undefined") if (typeof window !== "undefined" && typeof window.navigator !== "undefined")
USER_AGENT = window.navigator.userAgent; USER_AGENT = window.navigator.userAgent;
// Opera // Opera
+2 -2
View File
@@ -488,10 +488,10 @@ var CPDocumentUntitledCount = 0;
[_writeRequest setValue:@"close" forHTTPHeaderField:@"Connection"]; [_writeRequest setValue:@"close" forHTTPHeaderField:@"Connection"];
if (aSaveOperation == CPSaveOperation) if (aSaveOperation === CPSaveOperation)
[_writeRequest setValue:@"true" forHTTPHeaderField:@"x-cappuccino-overwrite"]; [_writeRequest setValue:@"true" forHTTPHeaderField:@"x-cappuccino-overwrite"];
if (aSaveOperation != CPSaveToOperation) if (aSaveOperation !== CPSaveToOperation)
[self updateChangeCount:CPChangeCleared]; [self updateChangeCount:CPChangeCleared];
// FIXME: Oh man is this every looking for trouble, we need to handle login at the Cappuccino level, with HTTP Errors. // FIXME: Oh man is this every looking for trouble, we need to handle login at the Cappuccino level, with HTTP Errors.
+96 -33
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;
@@ -127,7 +108,7 @@ var CPDragServerDraggingInfo = nil;
@end @end
var CPDraggingSource_draggedImage_movedTo_ = 1 << 0, var CPDraggingSource_draggedImage_movedTo_ = 1 << 0,
CPDraggingSource_draggedImage_endAt_operation_ = 1 << 1, CPDraggingSource_draggedImage_endedAt_operation_ = 1 << 1,
CPDraggingSource_draggedView_movedTo_ = 1 << 2, CPDraggingSource_draggedView_movedTo_ = 1 << 2,
CPDraggingSource_draggedView_endedAt_operation_ = 1 << 3; CPDraggingSource_draggedView_endedAt_operation_ = 1 << 3;
@@ -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,31 +230,95 @@ 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])
[_draggedWindow orderOut:self]; [_draggedWindow orderOut:self];
if (_implementedDraggingSourceMethods & CPDraggingSource_draggedImage_endAt_operation_) if (_implementedDraggingSourceMethods & CPDraggingSource_draggedImage_endedAt_operation_)
[_draggingSource draggedImage:[_draggedView image] endedAt:aLocation operation:anOperation]; [_draggingSource draggedImage:[_draggedView image] endedAt:aLocation operation:anOperation];
else if (_implementedDraggingSourceMethods & CPDraggingSource_draggedView_endedAt_operation_) else if (_implementedDraggingSourceMethods & CPDraggingSource_draggedView_endedAt_operation_)
[_draggingSource draggedView:_draggedView endedAt:aLocation operation:anOperation]; [_draggingSource draggedView:_draggedView endedAt:aLocation operation:anOperation];
@@ -342,8 +393,8 @@ var CPDraggingSource_draggedImage_movedTo_ = 1 << 0,
if ([_draggingSource respondsToSelector:@selector(draggedImage:movedTo:)]) if ([_draggingSource respondsToSelector:@selector(draggedImage:movedTo:)])
_implementedDraggingSourceMethods |= CPDraggingSource_draggedImage_movedTo_; _implementedDraggingSourceMethods |= CPDraggingSource_draggedImage_movedTo_;
if ([_draggingSource respondsToSelector:@selector(draggedImage:endAt:operation:)]) if ([_draggingSource respondsToSelector:@selector(draggedImage:endedAt:operation:)])
_implementedDraggingSourceMethods |= CPDraggingSource_draggedImage_endAt_operation_; _implementedDraggingSourceMethods |= CPDraggingSource_draggedImage_endedAt_operation_;
} }
else else
{ {
@@ -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];
} }
+4 -1
View File
@@ -345,7 +345,10 @@ var _CPEventPeriodicEventPeriod = 0,
*/ */
- (int)buttonNumber - (int)buttonNumber
{ {
return _buttonNumber; if (_type === CPRightMouseDown || _type === CPRightMouseUp || _type === CPRightMouseDragged)
return 1;
return 0;
} }
/*! /*!
+1 -1
View File
@@ -51,7 +51,7 @@ var CPSharedFontManager = nil,
// Changing the Default Font Conversion Classes // Changing the Default Font Conversion Classes
/*! /*!
Sets the class that will be used to create the applcation's Sets the class that will be used to create the application's
font manager. font manager.
*/ */
+ (void)setFontManagerFactory:(Class)aClass + (void)setFontManagerFactory:(Class)aClass
+6 -1
View File
@@ -365,12 +365,17 @@ 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]];
if ([images count]) if ([images count])
{
[self setImage:images[0]]; [self setImage:images[0]];
[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]
+2 -2
View File
@@ -227,8 +227,8 @@ var SelectionColor = nil,
CGContextClosePath(context); CGContextClosePath(context);
CGContextSetShadowWithColor(context, CGSizeMake(0.0, 1.0), 1.1, _shadowColor); CGContextSetShadowWithColor(context, CGSizeMake(0.0, 1.0), 1.1, _shadowColor || [CPColor whiteColor]);
CGContextSetFillColor(context, _color); CGContextSetFillColor(context, _color || [CPColor blackColor]);
CGContextFillPath(context); CGContextFillPath(context);
} }
+56 -37
View File
@@ -52,9 +52,10 @@ var CPOutlineViewDataSource_outlineView_setObjectValue_forTableColumn_byItem_
var CPOutlineViewDelegate_outlineView_dataViewForTableColumn_item_ = 1 << 1, var CPOutlineViewDelegate_outlineView_dataViewForTableColumn_item_ = 1 << 1,
CPOutlineViewDelegate_outlineView_shouldSelectItem_ = 1 << 2; CPOutlineViewDelegate_outlineView_shouldSelectItem_ = 1 << 2,
CPOutlineViewDelegate_outlineView_heightOfRowByItem_ = 1 << 3, CPOutlineViewDelegate_outlineView_heightOfRowByItem_ = 1 << 3,
CPOutlineViewDelegate_outlineView_willDisplayView_forTableColumn_item_ = 1 << 4; CPOutlineViewDelegate_outlineView_willDisplayView_forTableColumn_item_ = 1 << 4,
CPOutlineViewDelegate_outlineView_isGroupItem_ = 1 << 5;
CPOutlineViewDropOnItemIndex = -1; CPOutlineViewDropOnItemIndex = -1;
@@ -84,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
@@ -107,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];
@@ -381,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
@@ -469,6 +444,9 @@ CPOutlineViewDropOnItemIndex = -1;
if ([_outlineViewDelegate respondsToSelector:@selector(outlineView:willDisplayView:forTableColumn:item:)]) if ([_outlineViewDelegate respondsToSelector:@selector(outlineView:willDisplayView:forTableColumn:item:)])
_implementedOutlineViewDelegateMethods |= CPOutlineViewDelegate_outlineView_willDisplayView_forTableColumn_item_; _implementedOutlineViewDelegateMethods |= CPOutlineViewDelegate_outlineView_willDisplayView_forTableColumn_item_;
if ([_outlineViewDelegate respondsToSelector:@selector(outlineView:isGroupItem:)])
_implementedOutlineViewDelegateMethods |= CPOutlineViewDelegate_outlineView_isGroupItem_;
if ([_outlineViewDelegate respondsToSelector:@selector(outlineViewColumnDidMove:)]) if ([_outlineViewDelegate respondsToSelector:@selector(outlineViewColumnDidMove:)])
[defaultCenter [defaultCenter
addObserver:_outlineViewDelegate addObserver:_outlineViewDelegate
@@ -530,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;
@@ -537,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)
@@ -615,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];
@@ -1020,7 +1031,13 @@ var _loadItemInfoForItem = function(/*CPOutlineView*/ anOutlineView, /*id*/ anIt
} }
} }
- (BOOL)tableView:(CPTableView)aTableView isGroupRow:(int)row
{
if ((_outlineView._implementedOutlineViewDelegateMethods & CPOutlineViewDelegate_outlineView_isGroupItem_))
return [_outlineView._outlineViewDelegate outlineView:_outlineView isGroupItem:[_outlineView itemAtRow:theRow]];
return NO;
}
@end @end
@@ -1070,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",
+18
View File
@@ -152,6 +152,15 @@ CPDownArrowKeyCode = 40;
[_nextResponder performSelector:_cmd withObject:anEvent]; [_nextResponder performSelector:_cmd withObject:anEvent];
} }
/*!
Notifies the receiver that the user has clicked the right mouse down in its area.
@param anEvent contains information about the right click
*/
- (void)rightMouseDown:(CPEvent)anEvent
{
[_nextResponder performSelector:_cmd withObject:anEvent];
}
/*! /*!
Notifies the receiver that the user has initiated a drag Notifies the receiver that the user has initiated a drag
over it. A drag is a mouse movement while the left button is down. over it. A drag is a mouse movement while the left button is down.
@@ -171,6 +180,15 @@ CPDownArrowKeyCode = 40;
[_nextResponder performSelector:_cmd withObject:anEvent]; [_nextResponder performSelector:_cmd withObject:anEvent];
} }
/*!
Notifies the receiver that the user has released the right mouse button.
@param anEvent contains information about the release
*/
- (void)rightMouseUp:(CPEvent)anEvent
{
[_nextResponder performSelector:_cmd withObject:anEvent];
}
/*! /*!
Notifies the receiver that the user has moved the mouse (with no buttons down). Notifies the receiver that the user has moved the mouse (with no buttons down).
@param anEvent contains information about the movement @param anEvent contains information about the movement
+5 -1
View File
@@ -1,8 +1,8 @@
@import <Foundation/CPObject.j> @import <Foundation/CPObject.j>
#import "CoreGraphics/CGGeometry.h" #import "CoreGraphics/CGGeometry.h"
#import "Platform/Platform.h"
@implementation CPScreen : CPObject @implementation CPScreen : CPObject
{ {
@@ -10,7 +10,11 @@
- (CGRect)visibleFrame - (CGRect)visibleFrame
{ {
#if PLATFORM(DOM)
return _CGRectMake(window.screen.availLeft, window.screen.availTop, window.screen.availWidth, window.screen.availHeight); return _CGRectMake(window.screen.availLeft, window.screen.availTop, window.screen.availWidth, window.screen.availHeight);
#else
return _CGRectMakeZero();
#endif
} }
@end @end
+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];
+2 -3
View File
@@ -235,7 +235,7 @@ NAMES_FOR_PARTS[CPScrollerKnob] = @"knob";
*/ */
- (void)checkSpaceForParts - (void)checkSpaceForParts
{ {
var bounds = [self bounds]; var bounds = [self bounds];
// Assume we won't be needing the arrows. // Assume we won't be needing the arrows.
if (_knobProportion === 1.0) if (_knobProportion === 1.0)
@@ -290,8 +290,7 @@ NAMES_FOR_PARTS[CPScrollerKnob] = @"knob";
_partRects[CPScrollerDecrementLine] = _CGRectMakeZero(); _partRects[CPScrollerDecrementLine] = _CGRectMakeZero();
_partRects[CPScrollerKnobSlot] = _CGRectMake(trackInset.left, 0, width - trackInset.left - trackInset.right, height); _partRects[CPScrollerKnobSlot] = _CGRectMake(trackInset.left, 0, width - trackInset.left - trackInset.right, height);
} }
} }
else else
{ {
var decrementLineSize = [self currentValueForThemeAttribute:"decrement-line-size"], var decrementLineSize = [self currentValueForThemeAttribute:"decrement-line-size"],
+50 -74
View File
@@ -24,26 +24,10 @@
#include "Platform/Platform.h" #include "Platform/Platform.h"
/*! CPSearchFieldRecentsTitleMenuItemTag = 1000;
@global CPSearchFieldRecentsMenuItemTag = 1001;
@group Menu tags CPSearchFieldClearRecentsMenuItemTag = 1002;
*/ CPSearchFieldNoRecentsMenuItemTag = 1003;
CPSearchFieldRecentsTitleMenuItemTag = 1000;
/*!
@global
@group Menu tags
*/
CPSearchFieldRecentsMenuItemTag = 1001;
/*!
@global
@group Menu tags
*/
CPSearchFieldClearRecentsMenuItemTag = 1002;
/*!
@global
@group Menu tags
*/
CPSearchFieldNoRecentsMenuItemTag = 1003;
var CPSearchFieldSearchImage = nil, var CPSearchFieldSearchImage = nil,
CPSearchFieldFindImage = nil, CPSearchFieldFindImage = nil,
@@ -79,16 +63,15 @@ var CPSearchFieldSearchImage = nil,
return; return;
var bundle = [CPBundle bundleForClass:self]; var bundle = [CPBundle bundleForClass:self];
CPSearchFieldSearchImage = [[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPSearchField/CPSearchFieldSearch.png"]]; CPSearchFieldSearchImage = [[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPSearchField/CPSearchFieldSearch.png"] size:CGSizeMake(25, 22)];
CPSearchFieldFindImage = [[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPSearchField/CPSearchFieldFind.png"]]; CPSearchFieldFindImage = [[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPSearchField/CPSearchFieldFind.png"] size:CGSizeMake(25, 22)];
CPSearchFieldCancelImage = [[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPSearchField/CPSearchFieldCancel.png"]]; CPSearchFieldCancelImage = [[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPSearchField/CPSearchFieldCancel.png"] size:CGSizeMake(22, 22)];
CPSearchFieldCancelPressedImage = [[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPSearchField/CPSearchFieldCancelPressed.png"]]; CPSearchFieldCancelPressedImage = [[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPSearchField/CPSearchFieldCancelPressed.png"] size:CGSizeMake(22, 22)];
} }
- (id)initWithFrame:(CPRect)frame - (id)initWithFrame:(CGRect)frame
{ {
self = [super initWithFrame:frame]; if (self = [super initWithFrame:frame])
if (self != nil)
{ {
_recentSearches = [CPArray array]; _recentSearches = [CPArray array];
_maximumRecents = 10; _maximumRecents = 10;
@@ -96,47 +79,33 @@ var CPSearchFieldSearchImage = nil,
_sendsSearchStringImmediately = NO; _sendsSearchStringImmediately = NO;
_recentsAutosaveName = nil; _recentsAutosaveName = nil;
[self setBezeled:YES]; [self _initWithFrame:frame];
[self setBezelStyle:CPTextFieldRoundedBezel];
[self setBordered:YES];
[self setEditable:YES];
[self setDelegate:self];
_cancelButton = [[CPButton alloc] initWithFrame:CPMakeRect(frame.size.width - 27,(frame.size.height-22)/2,22,22)];
[self resetCancelButton];
[_cancelButton setHidden:YES];
[_cancelButton setAutoresizingMask:CPViewMinXMargin];
[self addSubview:_cancelButton];
_searchButton = [[CPButton alloc] initWithFrame:CPMakeRect(5,(frame.size.height-25)/2,25,25)];
[self resetSearchButton];
[self addSubview:_searchButton];
#if PLATFORM(DOM) #if PLATFORM(DOM)
_cancelButton._DOMElement.style.cursor = "default"; _cancelButton._DOMElement.style.cursor = "default";
_searchButton._DOMElement.style.cursor = "default"; _searchButton._DOMElement.style.cursor = "default";
#endif #endif
} }
return self; return self;
} }
- (id)copy - (void)_initWithFrame:(CGRect)frame
{ {
var copy = [super copy]; [self setBezeled:YES];
[self setBezelStyle:CPTextFieldRoundedBezel];
[self setBordered:YES];
[self setEditable:YES];
[self setDelegate:self];
[copy setCancelButton:[_cancelButton copy]]; _cancelButton = [[CPButton alloc] initWithFrame:CGRectMake(frame.size.width - 27,(frame.size.height-22)/2,22,22)];
[copy setSearchButton:[_searchButton copy]]; [self resetCancelButton];
[copy setSendsWholeSearchString:[_sendsWholeSearchString copy]]; [_cancelButton setHidden:YES];
[copy setSendsSearchStringImmediately:[_sendsSearchStringImmediately copy]]; [_cancelButton setAutoresizingMask:CPViewMinXMargin];
[copy setMaximumRecents:_maximumRecents]; [self addSubview:_cancelButton];
if (_recentsAutosaveName)
[copy setrecentsAutosaveName:[_recentsAutosaveName copy]];
if (_searchMenuTemplate)
[copy setSearchMenutemplate:[_searchMenuTemplate copy]];
return copy; _searchButton = [[CPButton alloc] initWithFrame:CGRectMake(5,(frame.size.height-25)/2,25,25)];
[self resetSearchButton];
[self addSubview:_searchButton];
} }
// Managing Buttons // Managing Buttons
@@ -695,9 +664,7 @@ var CPSearchFieldSearchImage = nil,
@end @end
var CPSearchButtonKey = @"CPSearchButtonKey", var CPRecentsAutosaveNameKey = @"CPRecentsAutosaveNameKey",
CPCancelButtonKey = @"CPCancelButtonKey",
CPRecentsAutosaveNameKey = @"CPRecentsAutosaveNameKey",
CPSendsWholeSearchStringKey = @"CPSendsWholeSearchStringKey", CPSendsWholeSearchStringKey = @"CPSendsWholeSearchStringKey",
CPSendsSearchStringImmediatelyKey = @"CPSendsSearchStringImmediatelyKey", CPSendsSearchStringImmediatelyKey = @"CPSendsSearchStringImmediatelyKey",
CPMaximumRecentsKey = @"CPMaximumRecentsKey", CPMaximumRecentsKey = @"CPMaximumRecentsKey",
@@ -707,13 +674,20 @@ var CPSearchButtonKey = @"CPSearchButtonKey",
- (void)encodeWithCoder:(CPCoder)coder - (void)encodeWithCoder:(CPCoder)coder
{ {
[_searchButton removeFromSuperview];
[_cancelButton removeFromSuperview];
[super encodeWithCoder:coder]; [super encodeWithCoder:coder];
[coder encodeObject:_searchButton forKey:CPSearchButtonKey]; if (_searchButton)
[coder encodeObject:_cancelButton forKey:CPCancelButtonKey]; [self addSubview:_searchButton];
if (_cancelButton)
[self addSubview:_cancelButton];
[coder encodeBool:_sendsWholeSearchString forKey:CPSendsWholeSearchStringKey]; [coder encodeBool:_sendsWholeSearchString forKey:CPSendsWholeSearchStringKey];
[coder encodeBool:_sendsSearchStringImmediately forKey:CPSendsSearchStringImmediatelyKey]; [coder encodeBool:_sendsSearchStringImmediately forKey:CPSendsSearchStringImmediatelyKey];
[coder encodeInt:_maximumRecents forKey:CPMaximumRecentsKey]; [coder encodeInt:_maximumRecents forKey:CPMaximumRecentsKey];
if (_recentsAutosaveName) if (_recentsAutosaveName)
[coder encodeObject:_recentsAutosaveName forKey:CPRecentsAutosaveNameKey]; [coder encodeObject:_recentsAutosaveName forKey:CPRecentsAutosaveNameKey];
if (_searchMenuTemplate) if (_searchMenuTemplate)
@@ -722,19 +696,21 @@ var CPSearchButtonKey = @"CPSearchButtonKey",
- (id)initWithCoder:(CPCoder)coder - (id)initWithCoder:(CPCoder)coder
{ {
self = [super initWithCoder:coder]; if (self = [super initWithCoder:coder])
{
[self _initWithFrame:[self frame]];
_searchButton = [coder decodeObjectForKey:CPSearchButtonKey]; _recentsAutosaveName = [coder decodeObjectForKey:CPRecentsAutosaveNameKey];
_cancelButton = [coder decodeObjectForKey:CPCancelButtonKey]; _sendsWholeSearchString = [coder decodeBoolForKey:CPSendsWholeSearchStringKey];
_recentsAutosaveName = [coder decodeObjectForKey:CPRecentsAutosaveNameKey]; _sendsSearchStringImmediately = [coder decodeBoolForKey:CPSendsSearchStringImmediatelyKey];
_sendsWholeSearchString = [coder decodeBoolForKey:CPSendsWholeSearchStringKey]; _maximumRecents = [coder decodeIntForKey:CPMaximumRecentsKey];
_sendsSearchStringImmediately = [coder decodeBoolForKey:CPSendsSearchStringImmediatelyKey];
_maximumRecents = [coder decodeIntForKey:CPMaximumRecentsKey];
var template = [coder decodeObjectForKey:CPSearchMenuTemplateKey];
if (template)
[self setSearchMenuTemplate:template];
[self setDelegate:self]; var template = [coder decodeObjectForKey:CPSearchMenuTemplateKey];
if (template)
[self setSearchMenuTemplate:template];
[self setDelegate:self];
}
return self; return self;
} }
+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",
+153 -20
View File
@@ -20,6 +20,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/ */
@import "CPButtonBar.j"
@import "CPImage.j" @import "CPImage.j"
@import "CPView.j" @import "CPView.j"
@@ -55,6 +56,8 @@ var CPSplitViewHorizontalImage = nil,
int _drawingDivider; int _drawingDivider;
BOOL _needsResizeSubviews; BOOL _needsResizeSubviews;
CPArray _buttonBars;
} }
/* /*
@@ -77,6 +80,7 @@ var CPSplitViewHorizontalImage = nil,
_currentDivider = CPNotFound; _currentDivider = CPNotFound;
_DOMDividerElements = []; _DOMDividerElements = [];
_buttonBars = [];
[self _setVertical:YES]; [self _setVertical:YES];
} }
@@ -209,19 +213,13 @@ var CPSplitViewHorizontalImage = nil,
{ {
_DOMDividerElements[_drawingDivider] = document.createElement("div"); _DOMDividerElements[_drawingDivider] = document.createElement("div");
if(_isVertical)
_DOMDividerElements[_drawingDivider].style.cursor = [[CPCursor resizeLeftRightCursor] _cssString];
else
_DOMDividerElements[_drawingDivider].style.cursor = [[CPCursor resizeUpDownCursor] _cssString];
_DOMDividerElements[_drawingDivider].style.position = "absolute"; _DOMDividerElements[_drawingDivider].style.position = "absolute";
_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
@@ -279,15 +277,25 @@ var CPSplitViewHorizontalImage = nil,
var frame = [_subviews[anIndex] frame], var frame = [_subviews[anIndex] frame],
startPosition = frame.origin[_originComponent] + frame.size[_sizeComponent], startPosition = frame.origin[_originComponent] + frame.size[_sizeComponent],
effectiveRect = [self effectiveRectOfDividerAtIndex:anIndex], effectiveRect = [self effectiveRectOfDividerAtIndex:anIndex],
buttonBar = _buttonBars[anIndex],
buttonBarRect = null,
additionalRect = null; additionalRect = null;
if (buttonBar != null)
{
buttonBarRect = [buttonBar resizeControlFrame];
buttonBarRect.origin = [self convertPoint:buttonBarRect.origin fromView:buttonBar];
}
if ([_delegate respondsToSelector:@selector(splitView:effectiveRect:forDrawnRect:ofDividerAtIndex:)]) if ([_delegate respondsToSelector:@selector(splitView:effectiveRect:forDrawnRect:ofDividerAtIndex:)])
effectiveRect = [_delegate splitView:self effectiveRect:effectiveRect forDrawnRect:effectiveRect ofDividerAtIndex:anIndex]; effectiveRect = [_delegate splitView:self effectiveRect:effectiveRect forDrawnRect:effectiveRect ofDividerAtIndex:anIndex];
if ([_delegate respondsToSelector:@selector(splitView:additionalEffectiveRectOfDividerAtIndex:)]) if ([_delegate respondsToSelector:@selector(splitView:additionalEffectiveRectOfDividerAtIndex:)])
additionalRect = [_delegate splitView:self additionalEffectiveRectOfDividerAtIndex:anIndex]; additionalRect = [_delegate splitView:self additionalEffectiveRectOfDividerAtIndex:anIndex];
return CGRectContainsPoint(effectiveRect, aPoint) || (additionalRect && CGRectContainsPoint(additionalRect, aPoint)); return CGRectContainsPoint(effectiveRect, aPoint) ||
(additionalRect && CGRectContainsPoint(additionalRect, aPoint)) ||
(buttonBarRect && CGRectContainsPoint(buttonBarRect, aPoint));
} }
- (CPView)hitTest:(CGPoint)aPoint - (CPView)hitTest:(CGPoint)aPoint
@@ -320,6 +328,7 @@ var CPSplitViewHorizontalImage = nil,
if (_currentDivider != CPNotFound) if (_currentDivider != CPNotFound)
{ {
_currentDivider = CPNotFound; _currentDivider = CPNotFound;
[self _updateResizeCursor:anEvent];
[self _postNotificationDidResize]; [self _postNotificationDidResize];
} }
@@ -380,6 +389,8 @@ var CPSplitViewHorizontalImage = nil,
var point = [self convertPoint:[anEvent locationInWindow] fromView:nil]; var point = [self convertPoint:[anEvent locationInWindow] fromView:nil];
[self setPosition:(point[_originComponent] + _initialOffset) ofDividerAtIndex:_currentDivider]; [self setPosition:(point[_originComponent] + _initialOffset) ofDividerAtIndex:_currentDivider];
// Cursor might change if we reach a resize limit.
[self _updateResizeCursor:anEvent];
} }
[CPApp setTarget:self selector:@selector(trackDivider:) forNextEventMatchingMask:CPLeftMouseDraggedMask | CPLeftMouseUpMask untilDate:nil inMode:nil dequeue:YES]; [CPApp setTarget:self selector:@selector(trackDivider:) forNextEventMatchingMask:CPLeftMouseDraggedMask | CPLeftMouseUpMask untilDate:nil inMode:nil dequeue:YES];
@@ -391,6 +402,74 @@ var CPSplitViewHorizontalImage = nil,
[self trackDivider:anEvent]; [self trackDivider:anEvent];
} }
- (void)viewDidMoveToWindow
{
// Enable split view resize cursors. Commented out pending CPTrackingArea implementation.
//[[self window] setAcceptsMouseMovedEvents:YES];
}
- (void)mouseEntered:(CPEvent)anEvent
{
// Tracking code handles cursor by itself.
if (_currentDivider == CPNotFound)
[self _updateResizeCursor:anEvent];
}
- (void)mouseMoved:(CPEvent)anEvent
{
if (_currentDivider == CPNotFound)
[self _updateResizeCursor:anEvent];
}
- (void)mouseExited:(CPEvent)anEvent
{
if (_currentDivider == CPNotFound)
// FIXME: we should use CPCursor push/pop (if previous currentCursor != arrow).
[[CPCursor arrowCursor] set];
}
- (void)_updateResizeCursor:(CPEvent)anEvent
{
var point = [self convertPoint:[anEvent locationInWindow] fromView:nil];
if ([anEvent type] === CPLeftMouseUp && ![[self window] acceptsMouseMovedEvents])
{
[[CPCursor arrowCursor] set];
return;
}
for (var i = 0, count = [_subviews count] - 1; i < count; i++)
{
// If we are currently tracking, keep the resize cursor active even outside of hit areas.
if (_currentDivider === i || (_currentDivider == CPNotFound && [self cursorAtPoint:point hitDividerAtIndex:i]))
{
var frame = [_subviews[i] frame],
startPosition = frame.origin[_originComponent] + frame.size[_sizeComponent],
canShrink = [self _realPositionForPosition:startPosition-1 ofDividerAtIndex:i] < startPosition,
canGrow = [self _realPositionForPosition:startPosition+1 ofDividerAtIndex:i] > startPosition,
cursor = [CPCursor arrowCursor];
if (_isVertical && canShrink && canGrow)
cursor = [CPCursor resizeLeftRightCursor];
else if (_isVertical && canShrink)
cursor = [CPCursor resizeLeftCursor];
else if (_isVertical && canGrow)
cursor = [CPCursor resizeRightCursor];
else if (canShrink && canGrow)
cursor = [CPCursor resizeUpDownCursor];
else if (canShrink)
cursor = [CPCursor resizeUpCursor];
else if (canGrow)
cursor = [CPCursor resizeDownCursor];
[cursor set];
return;
}
}
[[CPCursor arrowCursor] set];
}
- (float)maxPossiblePositionOfDividerAtIndex:(int)dividerIndex - (float)maxPossiblePositionOfDividerAtIndex:(int)dividerIndex
{ {
var frame = [_subviews[dividerIndex + 1] frame]; var frame = [_subviews[dividerIndex + 1] frame];
@@ -413,10 +492,8 @@ var CPSplitViewHorizontalImage = nil,
return 0; return 0;
} }
- (void)setPosition:(float)position ofDividerAtIndex:(int)dividerIndex - (int)_realPositionForPosition:(float)position ofDividerAtIndex:(int)dividerIndex
{ {
[self _adjustSubviewsWithCalculatedSize];
// not sure where this should override other positions? // not sure where this should override other positions?
if ([_delegate respondsToSelector:@selector(splitView:constrainSplitPosition:ofSubviewAt:)]) if ([_delegate respondsToSelector:@selector(splitView:constrainSplitPosition:ofSubviewAt:)])
position = [_delegate splitView:self constrainSplitPosition:position ofSubviewAt:dividerIndex]; position = [_delegate splitView:self constrainSplitPosition:position ofSubviewAt:dividerIndex];
@@ -432,19 +509,28 @@ var CPSplitViewHorizontalImage = nil,
if([_delegate respondsToSelector:@selector(splitView:constrainMaxCoordinate:ofSubviewAt:)]) if([_delegate respondsToSelector:@selector(splitView:constrainMaxCoordinate:ofSubviewAt:)])
actualMax = [_delegate splitView:self constrainMaxCoordinate:proposedMax ofSubviewAt:dividerIndex]; actualMax = [_delegate splitView:self constrainMaxCoordinate:proposedMax ofSubviewAt:dividerIndex];
var frame = [self frame], var viewA = _subviews[dividerIndex],
viewA = _subviews[dividerIndex], realPosition = MAX(MIN(position, actualMax), actualMin);
frameA = [viewA frame],
viewB = _subviews[dividerIndex + 1],
frameB = [viewB frame];
var realPosition = MAX(MIN(position, actualMax), actualMin);
if (position < proposedMin + (actualMin - proposedMin) / 2) if (position < proposedMin + (actualMin - proposedMin) / 2)
if ([_delegate respondsToSelector:@selector(splitView:canCollapseSubview:)]) if ([_delegate respondsToSelector:@selector(splitView:canCollapseSubview:)])
if ([_delegate splitView:self canCollapseSubview:viewA]) if ([_delegate splitView:self canCollapseSubview:viewA])
realPosition = proposedMin; realPosition = proposedMin;
return realPosition;
}
- (void)setPosition:(float)position ofDividerAtIndex:(int)dividerIndex
{
[self _adjustSubviewsWithCalculatedSize];
var realPosition = [self _realPositionForPosition:position ofDividerAtIndex:dividerIndex];
var viewA = _subviews[dividerIndex],
frameA = [viewA frame],
viewB = _subviews[dividerIndex + 1],
frameB = [viewB frame];
frameA.size[_sizeComponent] = realPosition - frameA.origin[_originComponent]; frameA.size[_sizeComponent] = realPosition - frameA.origin[_originComponent];
[_subviews[dividerIndex] setFrame:frameA]; [_subviews[dividerIndex] setFrame:frameA];
@@ -553,6 +639,47 @@ var CPSplitViewHorizontalImage = nil,
object:self]; object:self];
} }
/*!
Set the button bar who's resize control should act as a control for this splitview.
Each divider can have at most one button bar assigned to it, and that button bar must be
a subview of one of the split view's subviews.
Calling this method with nil as the button bar will remove any currently assigned button bar
for the divider at that index. Indexes will not be adjusted as new subviews are added, so you
should usually call this method after adding all the desired subviews to the split view.
This method will automatically configure the hasResizeControl and resizeControlIsLeftAligned
parameters of the button bar, and will override any currently set values.
*/
- (void)setButtonBar:(CPButtonBar)aButtonBar forDividerAtIndex:(unsigned)dividerIndex
{
if (!aButtonBar)
{
_buttonBars[dividerIndex] = nil;
return;
}
var view = [aButtonBar superview],
subview = aButtonBar;
while (view && view !== self)
{
subview = view;
view = [view superview];
}
if (view !== self)
[CPException raise:CPInvalidArgumentException
reason:@"CPSplitView button bar must be a subview of the split view."];
var viewIndex = [[self subviews] indexOfObject:subview];
[aButtonBar setHasResizeControl:YES];
[aButtonBar setResizeControlIsLeftAligned:dividerIndex < viewIndex];
_buttonBars[dividerIndex] = aButtonBar;
}
- (void)_postNotificationWillResize - (void)_postNotificationWillResize
{ {
[[CPNotificationCenter defaultCenter] postNotificationName:CPSplitViewWillResizeSubviewsNotification object:self]; [[CPNotificationCenter defaultCenter] postNotificationName:CPSplitViewWillResizeSubviewsNotification object:self];
@@ -567,7 +694,8 @@ var CPSplitViewHorizontalImage = nil,
var CPSplitViewDelegateKey = "CPSplitViewDelegateKey", var CPSplitViewDelegateKey = "CPSplitViewDelegateKey",
CPSplitViewIsVerticalKey = "CPSplitViewIsVerticalKey", CPSplitViewIsVerticalKey = "CPSplitViewIsVerticalKey",
CPSplitViewIsPaneSplitterKey = "CPSplitViewIsPaneSplitterKey"; CPSplitViewIsPaneSplitterKey = "CPSplitViewIsPaneSplitterKey",
CPSplitViewButtonBarsKey = "CPSplitViewButtonBarsKey";
@implementation CPSplitView (CPCoding) @implementation CPSplitView (CPCoding)
@@ -585,7 +713,9 @@ var CPSplitViewDelegateKey = "CPSplitViewDelegateKey",
_DOMDividerElements = []; _DOMDividerElements = [];
_delegate = [aCoder decodeObjectForKey:CPSplitViewDelegateKey];; _buttonBars = [aCoder decodeObjectForKey:CPSplitViewButtonBarsKey] || [];
_delegate = [aCoder decodeObjectForKey:CPSplitViewDelegateKey];
_isPaneSplitter = [aCoder decodeBoolForKey:CPSplitViewIsPaneSplitterKey]; _isPaneSplitter = [aCoder decodeBoolForKey:CPSplitViewIsPaneSplitterKey];
[self _setVertical:[aCoder decodeBoolForKey:CPSplitViewIsVerticalKey]]; [self _setVertical:[aCoder decodeBoolForKey:CPSplitViewIsVerticalKey]];
@@ -602,6 +732,9 @@ var CPSplitViewDelegateKey = "CPSplitViewDelegateKey",
{ {
[super encodeWithCoder:aCoder]; [super encodeWithCoder:aCoder];
//FIXME how should we handle this?
//[aCoder encodeObject:_buttonBars forKey:CPSplitViewButtonBarsKey];
[aCoder encodeConditionalObject:_delegate forKey:CPSplitViewDelegateKey]; [aCoder encodeConditionalObject:_delegate forKey:CPSplitViewDelegateKey];
[aCoder encodeBool:_isVertical forKey:CPSplitViewIsVerticalKey]; [aCoder encodeBool:_isVertical forKey:CPSplitViewIsVerticalKey];
+9 -2
View File
@@ -81,8 +81,8 @@ CPTableColumnUserResizingMask = 1 << 1;
var textDataView = [CPTextField new]; var textDataView = [CPTextField new];
[textDataView setLineBreakMode:CPLineBreakByTruncatingTail]; [textDataView setLineBreakMode:CPLineBreakByTruncatingTail];
[textDataView setValue:[CPColor colorWithHexString:@"333333"] forThemeAttribute:@"text-color"]; [textDataView setValue:[CPColor colorWithHexString:@"333333"] forThemeAttribute:@"text-color"];
[textDataView setValue:[CPColor whiteColor] forThemeAttribute:@"text-color" inState:CPThemeStateHighlighted]; [textDataView setValue:[CPColor whiteColor] forThemeAttribute:@"text-color" inState:CPThemeStateSelected];
[textDataView setValue:[CPFont boldSystemFontOfSize:12] forThemeAttribute:@"font" inState:CPThemeStateHighlighted]; [textDataView setValue:[CPFont boldSystemFontOfSize:12] forThemeAttribute:@"font" inState:CPThemeStateSelected];
[textDataView setValue:CPCenterVerticalTextAlignment forThemeAttribute:@"vertical-alignment"]; [textDataView setValue:CPCenterVerticalTextAlignment forThemeAttribute:@"vertical-alignment"];
[self setDataView:textDataView]; [self setDataView:textDataView];
} }
@@ -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
+297 -148
View File
@@ -24,11 +24,9 @@
@import "CPTableView.j" @import "CPTableView.j"
@import "CPView.j" @import "CPView.j"
var CPThemeStatePressed = CPThemeState("pressed");
@implementation _CPTableColumnHeaderView : CPView @implementation _CPTableColumnHeaderView : CPView
{ {
_CPImageAndTextView _textField; _CPImageAndTextView _textField;
} }
- (void)initWithFrame:(CGRect)frame - (void)initWithFrame:(CGRect)frame
@@ -62,11 +60,11 @@ var CPThemeStatePressed = CPThemeState("pressed");
{ {
var themeState = [self themeState]; var themeState = [self themeState];
if(themeState & CPThemeStateHighlighted && themeState & CPThemeStatePressed) if(themeState & CPThemeStateSelected && themeState & CPThemeStateHighlighted)
[self setBackgroundColor:[CPColor colorWithPatternImage:CPAppKitImage("tableview-headerview-highlighted-pressed.png", CGSizeMake(1.0, 22.0))]]; [self setBackgroundColor:[CPColor colorWithPatternImage:CPAppKitImage("tableview-headerview-highlighted-pressed.png", CGSizeMake(1.0, 22.0))]];
else if (themeState & CPThemeStateHighlighted) else if (themeState & CPThemeStateSelected)
[self setBackgroundColor:[CPColor colorWithPatternImage:CPAppKitImage("tableview-headerview-highlighted.png", CGSizeMake(1.0, 22.0))]]; [self setBackgroundColor:[CPColor colorWithPatternImage:CPAppKitImage("tableview-headerview-highlighted.png", CGSizeMake(1.0, 22.0))]];
else if (themeState & CPThemeStatePressed) else if (themeState & CPThemeStateHighlighted)
[self setBackgroundColor:[CPColor colorWithPatternImage:CPAppKitImage("tableview-headerview-pressed.png", CGSizeMake(1.0, 22.0))]]; [self setBackgroundColor:[CPColor colorWithPatternImage:CPAppKitImage("tableview-headerview-pressed.png", CGSizeMake(1.0, 22.0))]];
else else
[self setBackgroundColor:[CPColor colorWithPatternImage:CPAppKitImage("tableview-headerview.png", CGSizeMake(1.0, 22.0))]]; [self setBackgroundColor:[CPColor colorWithPatternImage:CPAppKitImage("tableview-headerview.png", CGSizeMake(1.0, 22.0))]];
@@ -149,58 +147,60 @@ 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)initWithFrame:(CGRect)aFrame - (void)_init
{
_mouseDownLocation = CPPointMakeZero();
_previousTrackingLocation = CPPointMakeZero();
_activeColumn = -1;
_pressedColumn = -1;
_isResizing = NO;
_isDragging = NO;
_isTrackingColumn = NO;
_columnOldWidth = 0.0;
[self setBackgroundColor:[CPColor colorWithPatternImage:CPAppKitImage("tableview-headerview.png", CGSizeMake(1.0, 22.0))]];
}
- (id)initWithFrame:(CGRect)aFrame
{ {
self = [super initWithFrame:aFrame]; self = [super initWithFrame:aFrame];
if (self) if (self)
{ [self _init];
_resizedColumn = -1;
_draggedColumn = -1;
_pressedColumn = -1;
_draggedDistance = 0.0;
_lastLocation = nil;
_columnOldWidth = nil;
[self setBackgroundColor:[CPColor colorWithPatternImage:CPAppKitImage("tableview-headerview.png", CGSizeMake(1.0, 22.0))]];
}
return self; return self;
} }
- (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
@@ -221,13 +221,13 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal
if (_pressedColumn != -1) if (_pressedColumn != -1)
{ {
var headerView = [_tableView._tableColumns[_pressedColumn] headerView]; var headerView = [_tableView._tableColumns[_pressedColumn] headerView];
[headerView unsetThemeState:CPThemeStatePressed]; [headerView unsetThemeState:CPThemeStateHighlighted];
} }
if (column != -1) if (column != -1)
{ {
var headerView = [_tableView._tableColumns[column] headerView]; var headerView = [_tableView._tableColumns[column] headerView];
[headerView setThemeState:CPThemeStatePressed]; [headerView setThemeState:CPThemeStateHighlighted];
} }
_pressedColumn = column; _pressedColumn = column;
@@ -235,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
@@ -364,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];
@@ -449,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
@@ -481,12 +636,7 @@ var CPTableHeaderViewTableViewKey = @"CPTableHeaderViewTableViewKey";
{ {
if (self = [super initWithCoder:aCoder]) if (self = [super initWithCoder:aCoder])
{ {
_resizedColumn = -1; [self _init];
_draggedColumn = -1;
_pressedColumn = -1;
_draggedDistance = 0.0;
_lastLocation = nil;
_columnOldWidth = nil;
_tableView = [aCoder decodeObjectForKey:CPTableHeaderViewTableViewKey]; _tableView = [aCoder decodeObjectForKey:CPTableHeaderViewTableViewKey];
} }
@@ -500,4 +650,3 @@ var CPTableHeaderViewTableViewKey = @"CPTableHeaderViewTableViewKey";
} }
@end @end
+292 -193
View File
@@ -67,29 +67,29 @@ var CPTableViewDelegate_selectionShouldChangeInTableView_
CPTableViewDelegate_tableViewSelectionIsChanging_ = 1 << 19; CPTableViewDelegate_tableViewSelectionIsChanging_ = 1 << 19;
//CPTableViewDraggingDestinationFeedbackStyles //CPTableViewDraggingDestinationFeedbackStyles
CPTableViewDraggingDestinationFeedbackStyleNone = -1, CPTableViewDraggingDestinationFeedbackStyleNone = -1;
CPTableViewDraggingDestinationFeedbackStyleRegular = 0, CPTableViewDraggingDestinationFeedbackStyleRegular = 0;
CPTableViewDraggingDestinationFeedbackStyleSourceList = 1; CPTableViewDraggingDestinationFeedbackStyleSourceList = 1;
//CPTableViewDropOperations //CPTableViewDropOperations
CPTableViewDropOn = 0, CPTableViewDropOn = 0;
CPTableViewDropAbove = 1; CPTableViewDropAbove = 1;
// TODO: add docs // TODO: add docs
CPTableViewSelectionHighlightStyleNone = -1, CPTableViewSelectionHighlightStyleNone = -1;
CPTableViewSelectionHighlightStyleRegular = 0, CPTableViewSelectionHighlightStyleRegular = 0;
CPTableViewSelectionHighlightStyleSourceList = 1; CPTableViewSelectionHighlightStyleSourceList = 1;
CPTableViewGridNone = 0; CPTableViewGridNone = 0;
CPTableViewSolidVerticalGridLineMask = 1 << 0; 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;
CPTableViewFirstColumnOnlyAutoresizingStyle = 5; CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
@@ -194,15 +194,17 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
SEL _doubleAction; SEL _doubleAction;
unsigned _columnAutoResizingStyle; unsigned _columnAutoResizingStyle;
int _lastTrackedRowIndex;
CGPoint _originalMouseDownPoint; CGPoint _originalMouseDownPoint;
BOOL _verticalMotionCanDrag; BOOL _verticalMotionCanDrag;
unsigned _destinationDragStyle; unsigned _destinationDragStyle;
BOOL _isSelectingSession; BOOL _isSelectingSession;
CPIndexSet _draggedRowIndexes; CPIndexSet _draggedRowIndexes;
_dropOperationDrawingView _dropOperationFeedbackView;
CPDragOperation _dragOperationDefaultMask; _CPDropOperationDrawingView _dropOperationFeedbackView;
int _retargetedDropRow; CPDragOperation _dragOperationDefaultMask;
CPDragOperation _retargetedDropOperation; int _retargetedDropRow;
CPDragOperation _retargetedDropOperation;
BOOL _disableAutomaticResizing @accessors(property=disableAutomaticResizing); BOOL _disableAutomaticResizing @accessors(property=disableAutomaticResizing);
BOOL _lastColumnShouldSnap; BOOL _lastColumnShouldSnap;
@@ -210,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;
@@ -230,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;
@@ -243,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];
@@ -276,16 +265,9 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
_retargetedDropOperation = nil; _retargetedDropOperation = nil;
_dragOperationDefaultMask = nil; _dragOperationDefaultMask = nil;
_destinationDragStyle = CPTableViewDraggingDestinationFeedbackStyleRegular; _destinationDragStyle = CPTableViewDraggingDestinationFeedbackStyleRegular;
_dropOperationFeedbackView = [[_dropOperationDrawingView alloc] initWithFrame:_CGRectMakeZero()];
[self addSubview:_dropOperationFeedbackView];
[_dropOperationFeedbackView setHidden:YES];
[_dropOperationFeedbackView setTableView:self];
_tableDrawView = [[_CPTableDrawView alloc] initWithTableView:self]; [self setBackgroundColor:[CPColor whiteColor]];
[_tableDrawView setBackgroundColor:[CPColor clearColor]];
[self addSubview:_tableDrawView];
[self _init]; [self _init];
} }
return self; return self;
@@ -294,8 +276,44 @@ 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 setTableView:self];
_lastColumnShouldSnap = NO; _lastColumnShouldSnap = NO;
_backgroundColor = [CPColor whiteColor];
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);
@@ -659,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.
@@ -678,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
@@ -804,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:CPThemeStateHighlighted];
}
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:CPThemeStateHighlighted];
}
} }
} }
- (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],
@@ -847,13 +896,13 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
{ {
var rowIndex = selectRows[i], var rowIndex = selectRows[i],
dataView = dataViewsInTableColumn[rowIndex]; dataView = dataViewsInTableColumn[rowIndex];
[dataView unsetThemeState:CPThemeStateHighlighted]; [dataView unsetThemeState:CPThemeStateSelected];
} }
if (_headerView) if (_headerView)
{ {
var headerView = [_tableColumns[columnIndex] headerView]; var headerView = [_tableColumns[columnIndex] headerView];
[headerView unsetThemeState:CPThemeStateHighlighted]; [headerView unsetThemeState:CPThemeStateSelected];
} }
} }
@@ -868,16 +917,21 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
{ {
var rowIndex = selectRows[i], var rowIndex = selectRows[i],
dataView = dataViewsInTableColumn[rowIndex]; dataView = dataViewsInTableColumn[rowIndex];
[dataView setThemeState:CPThemeStateHighlighted]; [dataView setThemeState:CPThemeStateSelected];
} }
if (_headerView) if (_headerView)
{ {
var headerView = [_tableColumns[columnIndex] headerView]; var headerView = [_tableColumns[columnIndex] headerView];
[headerView setThemeState:CPThemeStateHighlighted]; [headerView setThemeState:CPThemeStateSelected];
} }
} }
} }
- (int)selectedColumn
{
[_selectedColumnIndexes lastIndex];
}
- (CPIndexSet)selectedColumnIndexes - (CPIndexSet)selectedColumnIndexes
{ {
return _selectedColumnIndexes; return _selectedColumnIndexes;
@@ -1038,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]);
@@ -1047,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
{ {
@@ -1069,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();
@@ -1222,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];
@@ -1233,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
@@ -1738,10 +1794,10 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
if (_headerView) if (_headerView)
{ {
if (_currentHighlightedTableColumn != nil) if (_currentHighlightedTableColumn != nil)
[[_currentHighlightedTableColumn headerView] unsetThemeState:CPThemeStateHighlighted]; [[_currentHighlightedTableColumn headerView] unsetThemeState:CPThemeStateSelected];
if (aTableColumn != nil) if (aTableColumn != nil)
[[aTableColumn headerView] setThemeState:CPThemeStateHighlighted]; [[aTableColumn headerView] setThemeState:CPThemeStateSelected];
} }
_currentHighlightedTableColumn = aTableColumn; _currentHighlightedTableColumn = aTableColumn;
@@ -1757,56 +1813,37 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
return YES; return YES;
} }
- (CPImage)dragImageForRowsWithIndexes:(CPIndexSet)dragRows - (CPImage)dragImageForRowsWithIndexes:(CPIndexSet)dragRows tableColumns:(CPArray)theTableColumns event:(CPEvent)dragEvent offset:(CPPointPointer)dragImageOffset
tableColumns:(CPArray)theTableColumns
event:(CPEvent)dragEvent
offset:(CPPointPointer)dragImageOffset
{ {
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 - (CPView)dragViewForRowsWithIndexes:(CPIndexSet)theDraggedRows tableColumns:(CPArray)theTableColumns event:(CPEvent)theDragEvent offset:(CPPointPointer)dragViewOffset
tableColumns:(CPArray)theTableColumns
event:(CPEvent)theDragEvent
offset:(CPPoint)dragViewOffset
{ {
var bounds = [self bounds], var bounds = [self bounds],
view = [[CPView alloc] initWithFrame:bounds]; view = [[CPView alloc] initWithFrame:bounds];
[view setBackgroundColor:[CPColor clearColor]];
[view setAlphaValue:0.7]; [view setAlphaValue:0.7];
// We have to fetch all the data views for the selected rows and columns // We have to fetch all the data views for the selected rows and columns
// After that we can copy these add them to a transparent drag view and use that drag view // After that we can copy these add them to a transparent drag view and use that drag view
// to make it appear we are dragging images of those rows (as you would do in regular Cocoa) // to make it appear we are dragging images of those rows (as you would do in regular Cocoa)
var firstExposedColumn = [_exposedColumns firstIndex], var columnIndex = [theTableColumns count];
firstExposedRow = [_exposedRows firstIndex],
exposedColumnsLength = [_exposedColumns lastIndex] - firstExposedColumn + 1,
exposedRowsLength = [_exposedRows lastIndex] - firstExposedRow + 1,
columns = [],
rows = [];
[_exposedColumns getIndexes:columns maxCount:-1 inIndexRange:CPMakeRange(firstExposedColumn, exposedColumnsLength)];
[theDraggedRows getIndexes:rows maxCount:-1 inIndexRange:CPMakeRange(firstExposedRow, exposedRowsLength)];
var columnIndex = [columns count];
while (columnIndex--) while (columnIndex--)
{ {
var column = columns[columnIndex], var tableColumn = [theTableColumns objectAtIndex:columnIndex],
tableColumn = [_tableColumns objectAtIndex:column], row = [theDraggedRows firstIndex];
rowIndex = [rows count];
while (rowIndex--) while (row !== CPNotFound)
{ {
var row = rows[rowIndex];
var dataView = [self _newDataViewForRow:row tableColumn:tableColumn]; var dataView = [self _newDataViewForRow:row tableColumn:tableColumn];
[dataView setBackgroundColor:[CPColor clearColor]]; [dataView setFrame:[self frameOfDataViewAtColumn:columnIndex row:row]];
[dataView setFrame:[self frameOfDataViewAtColumn:column row:row]];
[dataView setObjectValue:[self _objectValueForTableColumn:tableColumn row:row]]; [dataView setObjectValue:[self _objectValueForTableColumn:tableColumn row:row]];
[view addSubview:dataView]; [view addSubview:dataView];
row = [theDraggedRows indexGreaterThanIndex:row];
} }
} }
@@ -1817,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...
@@ -1991,7 +2077,7 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
// Now clear all the leftovers // Now clear all the leftovers
// FIXME: this could be faster! // FIXME: this could be faster!
for (identifier in _cachedDataViews) for (var identifier in _cachedDataViews)
{ {
var dataViews = _cachedDataViews[identifier], var dataViews = _cachedDataViews[identifier],
count = dataViews.length; count = dataViews.length;
@@ -2057,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] = [];
@@ -2078,9 +2168,9 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
[dataView setObjectValue:[self _objectValueForTableColumn:tableColumn row:row]]; [dataView setObjectValue:[self _objectValueForTableColumn:tableColumn row:row]];
if (isColumnSelected || [self isRowSelected:row]) if (isColumnSelected || [self isRowSelected:row])
[dataView setThemeState:CPThemeStateHighlighted]; [dataView setThemeState:CPThemeStateSelected];
else else
[dataView unsetThemeState:CPThemeStateHighlighted]; [dataView unsetThemeState:CPThemeStateSelected];
if (_implementedDelegateMethods & CPTableViewDelegate_tableView_willDisplayView_forTableColumn_row_) if (_implementedDelegateMethods & CPTableViewDelegate_tableView_willDisplayView_forTableColumn_row_)
[_delegate tableView:self willDisplayView:dataView forTableColumn:tableColumn row:row]; [_delegate tableView:self willDisplayView:dataView forTableColumn:tableColumn row:row];
@@ -2149,12 +2239,12 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
} }
} }
- (void)_commitDataViewObjectValue:(CPTextView)sender - (void)_commitDataViewObjectValue:(id)sender
{ {
[_dataSource tableView:self [_dataSource tableView:self setObjectValue:[sender objectValue] forTableColumn:sender.tableViewEditedColumnObj row:sender.tableViewEditedRowIndex];
setObjectValue:[sender objectValue]
forTableColumn:sender.tableViewEditedColumnObj if ([sender respondsToSelector:@selector(setEditable:)])
row:sender.tableViewEditedRowIndex]; [sender setEditable:NO];
} }
- (CPView)_newDataViewForRow:(CPInteger)aRow tableColumn:(CPTableColumn)aTableColumn - (CPView)_newDataViewForRow:(CPInteger)aRow tableColumn:(CPTableColumn)aTableColumn
@@ -2171,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;
@@ -2208,20 +2301,21 @@ 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
{ {
if (!_usesAlternatingRowBackgroundColors) if (!_usesAlternatingRowBackgroundColors)
{
var context = [[CPGraphicsContext currentContext] graphicsPort];
CGContextSetFillColor(context, _backgroundColor);
CGContextFillRect(context, aRect);
return; return;
}
var rowColors = [self alternatingRowBackgroundColors], var rowColors = [self alternatingRowBackgroundColors],
colorCount = [rowColors count]; colorCount = [rowColors count];
@@ -2360,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:);
@@ -2389,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--)
@@ -2454,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);
} }
@@ -2581,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];
} }
@@ -2649,8 +2747,11 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
} }
_isSelectingSession = YES; _isSelectingSession = YES;
if(row >= 0) if(row >= 0 && row !== _lastTrackedRowIndex)
{
_lastTrackedRowIndex = row;
[self _updateSelectionWithMouseAtRow:row]; [self _updateSelectionWithMouseAtRow:row];
}
if ((_implementedDataSourceMethods & CPTableViewDataSource_tableView_setObjectValue_forTableColumn_row_) if ((_implementedDataSourceMethods & CPTableViewDataSource_tableView_setObjectValue_forTableColumn_row_)
&& !_trackingPointMovedOutOfClickSlop) && !_trackingPointMovedOutOfClickSlop)
@@ -2760,7 +2861,7 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
*/ */
- (void)draggingExited:(id)sender - (void)draggingExited:(id)sender
{ {
[_dropOperationFeedbackView setHidden:YES]; [_dropOperationFeedbackView removeFromSuperview];
} }
/* /*
@@ -2776,7 +2877,7 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
_retargetedDropOperation = nil; _retargetedDropOperation = nil;
_retargetedDropRow = nil; _retargetedDropRow = nil;
_draggedRowIndexes = [CPIndexSet indexSet]; _draggedRowIndexes = [CPIndexSet indexSet];
[_dropOperationFeedbackView setHidden:YES]; [_dropOperationFeedbackView removeFromSuperview];
} }
/* /*
@ignore @ignore
@@ -2892,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;
} }
@@ -2909,7 +3003,7 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
{ {
// FIX ME: is there anything else that needs to happen here? // FIX ME: is there anything else that needs to happen here?
// actual validation is called in dragginUpdated: // actual validation is called in dragginUpdated:
[_dropOperationFeedbackView setHidden:YES]; [_dropOperationFeedbackView removeFromSuperview];
return (_implementedDataSourceMethods & CPTableViewDataSource_tableView_validateDrop_proposedRow_proposedDropOperation_); return (_implementedDataSourceMethods & CPTableViewDataSource_tableView_validateDrop_proposedRow_proposedDropOperation_);
} }
@@ -3066,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
@@ -3185,6 +3279,7 @@ var CPTableViewDataSourceKey = @"CPTableViewDataSourceKey",
CPTableViewGridColorKey = @"CPTableViewGridColorKey", CPTableViewGridColorKey = @"CPTableViewGridColorKey",
CPTableViewGridStyleMaskKey = @"CPTableViewGridStyleMaskKey", CPTableViewGridStyleMaskKey = @"CPTableViewGridStyleMaskKey",
CPTableViewUsesAlternatingBackgroundKey = @"CPTableViewUsesAlternatingBackgroundKey", CPTableViewUsesAlternatingBackgroundKey = @"CPTableViewUsesAlternatingBackgroundKey",
CPTableViewAlternatingRowColorsKey = @"CPTableViewAlternatingRowColorsKey",
CPTableViewHeaderViewKey = @"CPTableViewHeaderViewKey", CPTableViewHeaderViewKey = @"CPTableViewHeaderViewKey",
CPTableViewCornerViewKey = @"CPTableViewCornerViewKey"; CPTableViewCornerViewKey = @"CPTableViewCornerViewKey";
@@ -3203,50 +3298,31 @@ 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;
_alternatingRowBackgroundColors = [aCoder decodeObjectForKey:CPTableViewAlternatingRowColorsKey];
_usesAlternatingRowBackgroundColors = [aCoder decodeObjectForKey:CPTableViewUsesAlternatingBackgroundKey]
_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]];
@@ -3277,6 +3353,7 @@ var CPTableViewDataSourceKey = @"CPTableViewDataSourceKey",
[aCoder encodeInt:_gridStyleMask forKey:CPTableViewGridStyleMaskKey]; [aCoder encodeInt:_gridStyleMask forKey:CPTableViewGridStyleMaskKey];
[aCoder encodeBool:_usesAlternatingRowBackgroundColors forKey:CPTableViewUsesAlternatingBackgroundKey]; [aCoder encodeBool:_usesAlternatingRowBackgroundColors forKey:CPTableViewUsesAlternatingBackgroundKey];
[aCoder encodeObject:_alternatingRowBackgroundColors forKey:CPTableViewAlternatingRowColorsKey]
[aCoder encodeObject:_cornerView forKey:CPTableViewCornerViewKey]; [aCoder encodeObject:_cornerView forKey:CPTableViewCornerViewKey];
[aCoder encodeObject:_headerView forKey:CPTableViewHeaderViewKey]; [aCoder encodeObject:_headerView forKey:CPTableViewHeaderViewKey];
@@ -3321,16 +3398,17 @@ var CPTableViewDataSourceKey = @"CPTableViewDataSourceKey",
@end @end
@implementation _dropOperationDrawingView : CPView @implementation _CPDropOperationDrawingView : CPView
{ {
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];
@@ -3396,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
+20 -4
View File
@@ -813,7 +813,7 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
if (![CPPlatform isBrowser]) if (![CPPlatform isBrowser])
{ {
[self copy:sender]; [self copy:sender];
[self deleteBackwards:sender]; [self deleteBackward:sender];
} }
} }
@@ -826,7 +826,7 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
if (![[pasteboard types] containsObject:CPStringPboardType]) if (![[pasteboard types] containsObject:CPStringPboardType])
return; return;
[self deleteBackwards:sender]; [self deleteBackward:sender];
var selectedRange = [self selectedRange], var selectedRange = [self selectedRange],
stringValue = [self stringValue], stringValue = [self stringValue],
@@ -912,7 +912,7 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
[self selectText:sender]; [self selectText:sender];
} }
- (void)deleteBackwards:(id)sender - (void)deleteBackward:(id)sender
{ {
var selectedRange = [self selectedRange], var selectedRange = [self selectedRange],
stringValue = [self stringValue], stringValue = [self stringValue],
@@ -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];
+100 -30
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;
@@ -243,6 +245,11 @@ var CPViewFlags = { },
return [CPSet setWithObjects:@"boundsOrigin", @"boundsSize"]; return [CPSet setWithObjects:@"boundsOrigin", @"boundsSize"];
} }
+ (CPMenu)defaultMenu
{
return nil;
}
- (id)init - (id)init
{ {
return [self initWithFrame:CGRectMakeZero()]; return [self initWithFrame:CGRectMakeZero()];
@@ -272,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;
@@ -668,7 +676,7 @@ var CPViewFlags = { },
return _tag; return _tag;
} }
- (void)viewWithTag:(CPInteger)aTag - (CPView)viewWithTag:(CPInteger)aTag
{ {
if ([self tag] == aTag) if ([self tag] == aTag)
return self; return self;
@@ -830,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
@@ -1183,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.
@@ -1199,7 +1229,7 @@ var CPViewFlags = { },
if (CPFeatureIsCompatible(CPOpacityRequiresFilterFeature)) if (CPFeatureIsCompatible(CPOpacityRequiresFilterFeature))
{ {
if (anAlphaValue == 1.0) if (anAlphaValue === 1.0)
try { _DOMElement.style.removeAttribute("filter") } catch (anException) { } try { _DOMElement.style.removeAttribute("filter") } catch (anException) { }
else else
_DOMElement.style.filter = "alpha(opacity=" + anAlphaValue * 100 + ")"; _DOMElement.style.filter = "alpha(opacity=" + anAlphaValue * 100 + ")";
@@ -1309,6 +1339,22 @@ var CPViewFlags = { },
[super mouseDown:anEvent]; [super mouseDown:anEvent];
} }
- (void)rightMouseDown:(CPEvent)anEvent
{
var menu = [self menuForEvent:anEvent];
if (menu)
[CPMenu popUpContextMenu:menu withEvent:anEvent forView:self];
else if ([[self nextResponder] isKindOfClass:CPView])
[super rightMouseDown:anEvent];
else
[[[anEvent window] platformWindow] _propagateContextMenuDOMEvent:YES];
}
- (CPMenu)menuForEvent:(CPEvent)anEvent
{
return [self menu] || [[self class] defaultMenu];
}
/*! /*!
Sets the background color of the receiver. Sets the background color of the receiver.
@param aColor the new color for the receiver's background @param aColor the new color for the receiver's background
@@ -1322,28 +1368,30 @@ var CPViewFlags = { },
#if PLATFORM(DOM) #if PLATFORM(DOM)
var patternImage = [_backgroundColor patternImage], var patternImage = [_backgroundColor patternImage],
colorExists = _backgroundColor && ([_backgroundColor patternImage] || [_backgroundColor alphaComponent] > 0.0),
colorHasAlpha = colorExists && [_backgroundColor alphaComponent] < 1.0,
supportsRGBA = CPFeatureIsCompatible(CPCSSRGBAFeature),
colorNeedsDOMElement = colorHasAlpha && !supportsRGBA,
amount = 0; amount = 0;
if ([patternImage isThreePartImage]) if ([patternImage isThreePartImage])
{ {
_backgroundType = [patternImage isVertical] ? BackgroundVerticalThreePartImage : BackgroundHorizontalThreePartImage; _backgroundType = [patternImage isVertical] ? BackgroundVerticalThreePartImage : BackgroundHorizontalThreePartImage;
amount = 3 - _DOMImageParts.length; amount = 3 - _DOMImageParts.length;
} }
else if ([patternImage isNinePartImage]) else if ([patternImage isNinePartImage])
{ {
_backgroundType = BackgroundNinePartImage; _backgroundType = BackgroundNinePartImage;
amount = 9 - _DOMImageParts.length; amount = 9 - _DOMImageParts.length;
} }
else else
{ {
_backgroundType = BackgroundTrivialColor; _backgroundType = colorNeedsDOMElement ? BackgroundTransparentColor : BackgroundTrivialColor;
amount = (colorNeedsDOMElement ? 1 : 0) - _DOMImageParts.length;
amount = 0 - _DOMImageParts.length;
} }
if (amount > 0) if (amount > 0)
{
while (amount--) while (amount--)
{ {
var DOMElement = DOMElementPrototype.cloneNode(false); var DOMElement = DOMElementPrototype.cloneNode(false);
@@ -1353,20 +1401,34 @@ var CPViewFlags = { },
_DOMImageParts.push(DOMElement); _DOMImageParts.push(DOMElement);
_DOMElement.appendChild(DOMElement); _DOMElement.appendChild(DOMElement);
} }
}
else else
{ {
amount = -amount; amount = -amount;
while (amount--) while (amount--)
_DOMElement.removeChild(_DOMImageParts.pop()); _DOMElement.removeChild(_DOMImageParts.pop());
} }
if (_backgroundType == BackgroundTrivialColor) if (_backgroundType === BackgroundTrivialColor || _backgroundType === BackgroundTransparentColor)
{
var colorCSS = colorExists ? [_backgroundColor cssString] : "";
// Opera doesn't like DOM properties set to nil. if (colorNeedsDOMElement)
// https://trac.280north.com/ticket/7 {
_DOMElement.style.background = _backgroundColor ? [_backgroundColor cssString] : ""; _DOMElement.style.background = "";
_DOMImageParts[0].style.background = [_backgroundColor cssString];
if (CPFeatureIsCompatible(CPOpacityRequiresFilterFeature))
_DOMImageParts[0].style.filter = "alpha(opacity=" + [_backgroundColor alphaComponent] * 100 + ")";
else
_DOMImageParts[0].style.opacity = [_backgroundColor alphaComponent];
var size = [self bounds].size;
CPDOMDisplayServerSetStyleSize(_DOMImageParts[0], size.width, size.height);
}
else
_DOMElement.style.background = colorCSS;
}
else else
{ {
var slices = [patternImage imageSlices], var slices = [patternImage imageSlices],
@@ -1381,6 +1443,14 @@ var CPViewFlags = { },
CPDOMDisplayServerSetStyleSize(_DOMImageParts[count], size.width, size.height); CPDOMDisplayServerSetStyleSize(_DOMImageParts[count], size.width, size.height);
_DOMImageParts[count].style.background = image ? "url(\"" + [image filename] + "\")" : ""; _DOMImageParts[count].style.background = image ? "url(\"" + [image filename] + "\")" : "";
if (!supportsRGBA)
{
if (CPFeatureIsCompatible(CPOpacityRequiresFilterFeature))
try { _DOMImageParts[count].style.removeAttribute("filter") } catch (anException) { }
else
_DOMImageParts[count].style.opacity = 1.0;
}
} }
if (_backgroundType == BackgroundNinePartImage) if (_backgroundType == BackgroundNinePartImage)
+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];
+83 -27
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;
} }
@@ -472,9 +481,6 @@ CPTexturedBackgroundWindowMask
- (void)awakeFromCib - (void)awakeFromCib
{ {
if (_initialFirstResponder)
[self makeFirstResponder:_initialFirstResponder];
_keyViewLoopIsDirty = ![self _hasKeyViewLoop]; _keyViewLoopIsDirty = ![self _hasKeyViewLoop];
} }
@@ -738,6 +744,15 @@ CPTexturedBackgroundWindowMask
{ {
[_platformWindow orderFront:self]; [_platformWindow orderFront:self];
[_platformWindow order:CPWindowAbove window:self relativeTo:nil]; [_platformWindow order:CPWindowAbove window:self relativeTo:nil];
if (_firstResponder === self || !_firstResponder)
[self makeFirstResponder:[self initialFirstResponder]];
if (!CPApp._keyWindow)
[self makeKeyWindow];
if (!CPApp._mainWindow)
[self makeMainWindow];
} }
/* /*
@@ -877,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
@@ -1161,6 +1193,16 @@ CPTexturedBackgroundWindowMask
return YES; return YES;
} }
- (id)initialFirstResponder
{
return _initialFirstResponder;
}
- (void)setInitialFirstResponder:(id)aResponder
{
_initialFirstResponder = aResponder;
}
/*! /*!
Attempts to make the \c aResponder the first responder. Before trying Attempts to make the \c aResponder the first responder. Before trying
to make it the first responder, the receiver will ask the current first responder to make it the first responder, the receiver will ask the current first responder
@@ -1170,7 +1212,7 @@ CPTexturedBackgroundWindowMask
*/ */
- (BOOL)makeFirstResponder:(CPResponder)aResponder - (BOOL)makeFirstResponder:(CPResponder)aResponder
{ {
if (_firstResponder == aResponder) if (_firstResponder === aResponder)
return YES; return YES;
if(![_firstResponder resignFirstResponder]) if(![_firstResponder resignFirstResponder])
@@ -1331,43 +1373,57 @@ CPTexturedBackgroundWindowMask
case CPScrollWheel: return [[_windowView hitTest:point] scrollWheel:anEvent]; case CPScrollWheel: return [[_windowView hitTest:point] scrollWheel:anEvent];
case CPLeftMouseUp: if (!_leftMouseDownView) case CPLeftMouseUp:
return [[_windowView hitTest:point] mouseUp:anEvent]; case CPRightMouseUp: var hitTestedView = _leftMouseDownView,
selector = type == CPRightMouseUp ? @selector(rightMouseUp:) : @selector(mouseUp:);
[_leftMouseDownView mouseUp:anEvent] if (!hitTestedView)
hitTestedView = [_windowView hitTest:point];
[hitTestedView performSelector:selector withObject:anEvent];
_leftMouseDownView = nil; _leftMouseDownView = nil;
return; return;
case CPLeftMouseDown: _leftMouseDownView = [_windowView hitTest:point]; case CPLeftMouseDown:
case CPRightMouseDown: _leftMouseDownView = [_windowView hitTest:point];
if (_leftMouseDownView != _firstResponder && [_leftMouseDownView acceptsFirstResponder]) if (_leftMouseDownView != _firstResponder && [_leftMouseDownView acceptsFirstResponder])
[self makeFirstResponder:_leftMouseDownView]; [self makeFirstResponder:_leftMouseDownView];
[CPApp activateIgnoringOtherApps:YES]; [CPApp activateIgnoringOtherApps:YES];
var theWindow = [anEvent window]; var theWindow = [anEvent window],
selector = type == CPRightMouseDown ? @selector(rightMouseDown:) : @selector(mouseDown:);
if ([theWindow isKeyWindow] || [theWindow becomesKeyOnlyIfNeeded] && ![_leftMouseDownView needsPanelToBecomeKey]) if ([theWindow isKeyWindow] || [theWindow becomesKeyOnlyIfNeeded] && ![_leftMouseDownView needsPanelToBecomeKey])
return [_leftMouseDownView mouseDown:anEvent]; return [_leftMouseDownView performSelector:selector withObject:anEvent];
else else
{ {
// FIXME: delayed ordering? // FIXME: delayed ordering?
[self makeKeyAndOrderFront:self]; [self makeKeyAndOrderFront:self];
if ([_leftMouseDownView acceptsFirstMouse:anEvent]) if ([_leftMouseDownView acceptsFirstMouse:anEvent])
return [_leftMouseDownView mouseDown:anEvent] return [_leftMouseDownView performSelector:selector withObject:anEvent];
} }
break; break;
case CPLeftMouseDragged: if (!_leftMouseDownView)
case CPLeftMouseDragged:
case CPRightMouseDragged: if (!_leftMouseDownView)
return [[_windowView hitTest:point] mouseDragged:anEvent]; return [[_windowView hitTest:point] mouseDragged:anEvent];
return [_leftMouseDownView mouseDragged:anEvent]; var selector;
if (type == CPRightMouseDragged)
{
selector = @selector(rightMouseDragged:)
if (![_leftMouseDownView respondsToSelector:selector])
selector = nil;
}
case CPRightMouseUp: return [_rightMouseDownView mouseUp:anEvent]; if (!selector)
case CPRightMouseDown: _rightMouseDownView = [_windowView hitTest:point]; selector = @selector(mouseDragged:)
return [_rightMouseDownView mouseDown:anEvent];
case CPRightMouseDragged: return [_rightMouseDownView mouseDragged:anEvent]; return [_leftMouseDownView performSelector:selector withObject:anEvent];
case CPMouseMoved: if (!_acceptsMouseMovedEvents) case CPMouseMoved: if (!_acceptsMouseMovedEvents)
return; return;
@@ -1494,10 +1550,11 @@ CPTexturedBackgroundWindowMask
*/ */
- (void)resignKeyWindow - (void)resignKeyWindow
{ {
if (_firstResponder != self && [_firstResponder respondsToSelector:@selector(resignKeyWindow)]) if (_firstResponder !== self && [_firstResponder respondsToSelector:@selector(resignKeyWindow)])
[_firstResponder resignKeyWindow]; [_firstResponder resignKeyWindow];
CPApp._keyWindow = nil; if (CPApp._keyWindow === self)
CPApp._keyWindow = nil;
[[CPNotificationCenter defaultCenter] [[CPNotificationCenter defaultCenter]
postNotificationName:CPWindowDidResignKeyNotification postNotificationName:CPWindowDidResignKeyNotification
@@ -1858,7 +1915,8 @@ CPTexturedBackgroundWindowMask
postNotificationName:CPWindowDidResignMainNotification postNotificationName:CPWindowDidResignMainNotification
object:self]; object:self];
CPApp._mainWindow = nil; if (CPApp._mainWindow === self)
CPApp._mainWindow = nil;
} }
- (void)_updateMainAndKeyWindows - (void)_updateMainAndKeyWindows
@@ -1866,9 +1924,6 @@ CPTexturedBackgroundWindowMask
var allWindows = [CPApp orderedWindows], var allWindows = [CPApp orderedWindows],
windowCount = [allWindows count]; windowCount = [allWindows count];
if (!windowCount)
return;
if ([self isKeyWindow]) if ([self isKeyWindow])
{ {
var keyWindow = [CPApp keyWindow]; var keyWindow = [CPApp keyWindow];
@@ -1878,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];
@@ -1893,11 +1949,10 @@ CPTexturedBackgroundWindowMask
} }
if (![CPApp keyWindow]) if (![CPApp keyWindow])
[keyWindow makeKeyWindow]; [menuWindow makeKeyWindow];
} }
} }
if ([self isMainWindow]) if ([self isMainWindow])
{ {
var mainWindow = [CPApp mainWindow]; var mainWindow = [CPApp mainWindow];
@@ -1907,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];
@@ -71,9 +71,10 @@ var _CPToolbarViewBackgroundColor = nil;
[self addSubview:_toolbarBackgroundView positioned:CPWindowBelow relativeTo:nil]; [self addSubview:_toolbarBackgroundView positioned:CPWindowBelow relativeTo:nil];
} }
var frame = CGRectMakeZero(); var frame = CGRectMakeZero(),
toolbarOffset = [self toolbarOffset];
frame.origin = CGPointMakeCopy([self toolbarOffset]); frame.origin = CGPointMake(toolbarOffset.width, toolbarOffset.height);
frame.size = [_toolbarView frame].size; frame.size = [_toolbarView frame].size;
[_toolbarBackgroundView setFrame:frame]; [_toolbarBackgroundView setFrame:frame];
+4 -3
View File
@@ -36,6 +36,7 @@ var _CPWindowViewResizeIndicatorImage = nil;
CGSize _resizeIndicatorOffset; CGSize _resizeIndicatorOffset;
CPView _toolbarView; CPView _toolbarView;
CGSize _toolbarOffset;
// BOOL _isAnimatingToolbar; // BOOL _isAnimatingToolbar;
@@ -80,8 +81,8 @@ var _CPWindowViewResizeIndicatorImage = nil;
if (self) if (self)
{ {
_styleMask = aStyleMask; _styleMask = aStyleMask;
_resizeIndicatorOffset = CGSizeMake(0.0, 0.0); _resizeIndicatorOffset = CGSizeMakeZero();
_toolbarOffset = CGSizeMake(0.0, 0.0); _toolbarOffset = CGSizeMakeZero();
} }
return self; return self;
@@ -269,7 +270,7 @@ var _CPWindowViewResizeIndicatorImage = nil;
- (CGSize)toolbarOffset - (CGSize)toolbarOffset
{ {
return CGSizeMakeZero(); return _toolbarOffset;
} }
- (CPColor)toolbarLabelColor - (CPColor)toolbarLabelColor
-19
View File
@@ -322,25 +322,6 @@
return _documents; return _documents;
} }
- (void)setViewController:(CPViewController)aViewController
{
var containerView = [self viewControllerContainerView] || [[self window] contentView],
view = [_viewController view],
frame = view ? [view frame] : [containerView bounds];
[view removeFromSuperview];
_viewController = aViewController;
view = [_viewController view];
if (view)
{
[view setFrame:frame];
[containerView addSubview:view];
}
}
- (void)setViewControllerContainerView:(CPView)aView - (void)setViewControllerContainerView:(CPView)aView
{ {
_viewControllerContainerView = aView; _viewControllerContainerView = aView;
+6 -1
View File
@@ -171,12 +171,17 @@ var CPCibObjectDataKey = @"CPCibObjectDataKey";
- (void)connection:(CPURLConnection)aConnection didReceiveData:(CPString)data - (void)connection:(CPURLConnection)aConnection didReceiveData:(CPString)data
{ {
// FIXME: Why aren't we getting connection:didFailWithError:
if (!data)
return [self connection:aConnection didFailWithError:nil];
_data = [CPData dataWithRawString:data]; _data = [CPData dataWithRawString:data];
} }
- (void)connection:(CPURLConnection)aConnection didFailWithError:(CPError)anError - (void)connection:(CPURLConnection)aConnection didFailWithError:(CPError)anError
{ {
alert("cib: connection failed."); if ([_loadDelegate respondsToSelector:@selector(cibDidFailToLoad:)])
[_loadDelegate cibDidFailToLoad:self];
_loadDelegate = nil; _loadDelegate = nil;
} }
+19 -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
@@ -118,4 +118,9 @@ var CPCibOwner = @"CPCibOwner";
[_loadDelegate cibDidFinishLoading:aCib]; [_loadDelegate cibDidFinishLoading:aCib];
} }
- (void)cibDidFailToLoad:(CPCib)aCib
{
[_loadDelegate cibDidFailToLoad:aCib];
}
@end @end
+1 -2
View File
@@ -777,8 +777,7 @@ if (_DOMContentsElement && aLayer._zPosition > _DOMContentsElement.style.zIndex)
@ignore @ignore
*/ */
+ (void)runLoopUpdateLayers + (void)runLoopUpdateLayers
{if (window.oops) {alert(window.latest); objj_debug_print_backtrace();} {
window.loop = true;
for (UID in CALayerRegisteredRunLoopUpdates) for (UID in CALayerRegisteredRunLoopUpdates)
{ {
var layer = CALayerRegisteredRunLoopUpdates[UID], var layer = CALayerRegisteredRunLoopUpdates[UID],
+1 -1
View File
@@ -210,7 +210,7 @@ function CGPathAddQuadCurveToPoint(aPath, aTransform, cpx, cpy, x, y)
if (aTransform) if (aTransform)
{ {
cp = _CGPointApplyAffineTransform(control, aTransform); cp = _CGPointApplyAffineTransform(cp, aTransform);
end = _CGPointApplyAffineTransform(end, aTransform); end = _CGPointApplyAffineTransform(end, aTransform);
} }
+1 -1
View File
@@ -20,7 +20,7 @@ appKitTask = framework ("AppKit", function(appKitTask)
appKitTask.setEmail("feedback @nospam@ 280north.com"); appKitTask.setEmail("feedback @nospam@ 280north.com");
appKitTask.setSummary("AppKit classes for Cappuccino"); appKitTask.setSummary("AppKit classes for Cappuccino");
appKitTask.setIdentifier("com.280n.AppKit"); appKitTask.setIdentifier("com.280n.AppKit");
appKitTask.setVersion("0.8.0"); appKitTask.setVersion(getCappuccinoVersion());
appKitTask.setLicense(BundleTask.License.LGPL_v2_1); appKitTask.setLicense(BundleTask.License.LGPL_v2_1);
appKitTask.setSources(AppKitFiles); appKitTask.setSources(AppKitFiles);
appKitTask.setResources(new FileList("Resources/**/*")); appKitTask.setResources(new FileList("Resources/**/*"));
+11
View File
@@ -41,11 +41,13 @@ var PrimaryPlatformWindow = NULL;
DOMElement _DOMBodyElement; DOMElement _DOMBodyElement;
DOMElement _DOMFocusElement; DOMElement _DOMFocusElement;
DOMElement _DOMEventGuard;
CPArray _windowLevels; CPArray _windowLevels;
CPDictionary _windowLayers; CPDictionary _windowLayers;
BOOL _mouseIsDown; BOOL _mouseIsDown;
BOOL _mouseDownIsRightClick;
CPWindow _mouseDownWindow; CPWindow _mouseDownWindow;
CPTimeInterval _lastMouseUp; CPTimeInterval _lastMouseUp;
CPTimeInterval _lastMouseDown; CPTimeInterval _lastMouseDown;
@@ -72,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;
+10 -3
View File
@@ -40,6 +40,16 @@ var screenNeedsInitialization = NO,
return; return;
screenNeedsInitialization = [CPPlatform isBrowser]; screenNeedsInitialization = [CPPlatform isBrowser];
// We do this here because doing it later breaks IE.
if (document.documentElement)
document.documentElement.style.overflow = "hidden";
if ([CPPlatform isBrowser])
window.onunload = function()
{
[CPApp terminate:nil];
}
} }
+ (BOOL)isBrowser + (BOOL)isBrowser
@@ -121,9 +131,6 @@ var screenNeedsInitialization = NO,
bodyElement.style.overflow = "hidden"; bodyElement.style.overflow = "hidden";
if (document.documentElement)
document.documentElement.style.overflow = "hidden";
[[CPNotificationCenter defaultCenter] [[CPNotificationCenter defaultCenter]
postNotificationName:CPPlatformDidClearBodyElementNotification postNotificationName:CPPlatformDidClearBodyElementNotification
object:self]; object:self];
+58 -35
View File
@@ -22,9 +22,10 @@
#include "../CoreGraphics/CGGeometry.h" #include "../CoreGraphics/CGGeometry.h"
var DOMSpanElement = nil, var DOMFixedWidthSpanElement = nil,
DOMIFrameElement = nil, DOMFlexibleWidthSpanElement = nil,
DefaultFont = nil; DOMIFrameElement = nil,
DefaultFont = nil;
@implementation CPPlatformString : CPBasePlatformString @implementation CPPlatformString : CPBasePlatformString
{ {
@@ -37,25 +38,30 @@ var DOMSpanElement = nil,
+ (void)createDOMElements + (void)createDOMElements
{ {
var style;
DOMIFrameElement = document.createElement("iframe"); DOMIFrameElement = document.createElement("iframe");
// necessary for Safari caching bug: // necessary for Safari caching bug:
DOMIFrameElement.name = "iframe_" + FLOOR(RAND() * 10000); DOMIFrameElement.name = "iframe_" + FLOOR(RAND() * 10000);
DOMIFrameElement.style.position = "absolute";
DOMIFrameElement.style.left = "-100px";
DOMIFrameElement.style.top = "-100px";
DOMIFrameElement.style.width = "1px";
DOMIFrameElement.style.height = "1px";
DOMIFrameElement.style.borderWidth = "0px";
DOMIFrameElement.style.overflow = "hidden";
DOMIFrameElement.style.zIndex = 100000000000;
DOMIFrameElement.className = "cpdontremove"; DOMIFrameElement.className = "cpdontremove";
style = DOMIFrameElement.style;
style.position = "absolute";
style.left = "-100px";
style.top = "-100px";
style.width = "1px";
style.height = "1px";
style.borderWidth = "0px";
style.overflow = "hidden";
style.zIndex = 100000000000;
var bodyElement = [CPPlatform mainBodyElement]; var bodyElement = [CPPlatform mainBodyElement];
bodyElement.appendChild(DOMIFrameElement); bodyElement.appendChild(DOMIFrameElement);
var DOMIFrameDocument = (DOMIFrameElement.contentDocument || DOMIFrameElement.contentWindow.document); var DOMIFrameDocument = (DOMIFrameElement.contentDocument || DOMIFrameElement.contentWindow.document);
DOMIFrameDocument.write("<html><head></head><body></body></html>"); DOMIFrameDocument.write('<!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"><head></head><body></body></html>');
DOMIFrameDocument.close(); DOMIFrameDocument.close();
// IE needs this wide <div> to prevent unwanted text wrapping: // IE needs this wide <div> to prevent unwanted text wrapping:
@@ -65,14 +71,39 @@ var DOMSpanElement = nil,
DOMIFrameDocument.body.appendChild(DOMDivElement); DOMIFrameDocument.body.appendChild(DOMDivElement);
DOMSpanElement = DOMIFrameDocument.createElement("span"); DOMFlexibleWidthSpanElement = DOMIFrameDocument.createElement("span");
DOMSpanElement.style.position = "absolute"; style = DOMFlexibleWidthSpanElement.style;
DOMSpanElement.style.whiteSpace = "pre"; style.position = "absolute";
DOMSpanElement.style.visibility = "visible"; style.visibility = "visible";
DOMSpanElement.style.padding = "0px"; style.padding = "0px";
DOMSpanElement.style.margin = "0px"; style.margin = "0px";
style.whiteSpace = "pre";
DOMDivElement.appendChild(DOMSpanElement); DOMFixedWidthSpanElement = DOMIFrameDocument.createElement("span");
style = DOMFixedWidthSpanElement.style;
style.display = "block";
style.position = "absolute";
style.visibility = "visible";
style.padding = "0px";
style.margin = "0px";
style.width = "1px";
style.wordWrap = "break-word";
try
{
style.whiteSpace = "pre";
style.whiteSpace = "-o-pre-wrap";
style.whiteSpace = "-pre-wrap";
style.whiteSpace = "-moz-pre-wrap";
style.whiteSpace = "pre-wrap";
}
catch(e)
{
//some versions of IE throw exceptions for unsupported properties.
style.whiteSpace = "pre";
}
DOMDivElement.appendChild(DOMFlexibleWidthSpanElement);
DOMDivElement.appendChild(DOMFixedWidthSpanElement);
} }
+ (CGSize)sizeOfString:(CPString)aString withFont:(CPFont)aFont forWidth:(float)aWidth + (CGSize)sizeOfString:(CPString)aString withFont:(CPFont)aFont forWidth:(float)aWidth
@@ -88,31 +119,23 @@ var DOMSpanElement = nil,
if (!DOMIFrameElement) if (!DOMIFrameElement)
[self createDOMElements]; [self createDOMElements];
var style = DOMSpanElement.style; var span;
if (!aWidth) if (!aWidth)
{ span = DOMFlexibleWidthSpanElement;
style.width = "";
style.whiteSpace = "pre";
}
else else
{ {
style.width = ROUND(aWidth) + "px"; span = DOMFixedWidthSpanElement;
style.wordWrap = "break-word"; span.style.width = ROUND(aWidth) + "px";
style.whiteSpace = "-o-pre-wrap";
style.whiteSpace = "-pre-wrap";
style.whiteSpace = "-moz-pre-wrap";
style.whiteSpace = "pre-wrap";
} }
style.font = [aFont cssString]; span.style.font = [aFont cssString];
if (CPFeatureIsCompatible(CPJavascriptInnerTextFeature)) if (CPFeatureIsCompatible(CPJavascriptInnerTextFeature))
DOMSpanElement.innerText = aString; span.innerText = aString;
else if (CPFeatureIsCompatible(CPJavascriptTextContentFeature)) else if (CPFeatureIsCompatible(CPJavascriptTextContentFeature))
DOMSpanElement.textContent = aString; span.textContent = aString;
return _CGSizeMake(DOMSpanElement.clientWidth, DOMSpanElement.clientHeight); return _CGSizeMake(span.clientWidth, span.clientHeight);
} }
@end @end
+72 -12
View File
@@ -127,7 +127,8 @@ var PlatformWindows = [CPSet set];
// Define up here so compressor knows about em. // Define up here so compressor knows about em.
var CPDOMEventGetClickCount, var CPDOMEventGetClickCount,
CPDOMEventStop, CPDOMEventStop,
StopDOMEventPropagation; StopDOMEventPropagation,
StopContextMenuDOMEventPropagation;
//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
@@ -255,6 +256,19 @@ var supportsNativeDragAndDrop = [CPPlatform supportsDragAndDrop];
// Make sure the pastboard element is blurred. // Make sure the pastboard element is blurred.
_DOMPasteboardElement.blur(); _DOMPasteboardElement.blur();
// Create a full screen div to protect against iframes and other elements from consuming events during tracking
// FIXME: multiple windows
_DOMEventGuard = theDocument.createElement("div");
_DOMEventGuard.style.position = "absolute";
_DOMEventGuard.style.top = "0px";
_DOMEventGuard.style.left = "0px";
_DOMEventGuard.style.width = "100%";
_DOMEventGuard.style.height = "100%";
_DOMEventGuard.style.zIndex = "999";
_DOMEventGuard.style.display = "none";
_DOMEventGuard.className = "cpdontremove";
_DOMBodyElement.appendChild(_DOMEventGuard);
} }
- (void)registerDOMWindow - (void)registerDOMWindow
@@ -264,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";
@@ -297,6 +311,10 @@ var supportsNativeDragAndDrop = [CPPlatform supportsDragAndDrop];
mouseEventImplementation = class_getMethodImplementation(theClass, mouseEventSelector), mouseEventImplementation = class_getMethodImplementation(theClass, mouseEventSelector),
mouseEventCallback = function (anEvent) { mouseEventImplementation(self, nil, anEvent); }, mouseEventCallback = function (anEvent) { mouseEventImplementation(self, nil, anEvent); },
contextMenuEventSelector = @selector(contextMenuEvent:),
contextMenuEventImplementation = class_getMethodImplementation(theClass, contextMenuEventSelector),
contextMenuEventCallback = function (anEvent) { return contextMenuEventImplementation(self, nil, anEvent); },
scrollEventSelector = @selector(scrollEvent:), scrollEventSelector = @selector(scrollEvent:),
scrollEventImplementation = class_getMethodImplementation(theClass, scrollEventSelector), scrollEventImplementation = class_getMethodImplementation(theClass, scrollEventSelector),
scrollEventCallback = function (anEvent) { scrollEventImplementation(self, nil, anEvent); }, scrollEventCallback = function (anEvent) { scrollEventImplementation(self, nil, anEvent); },
@@ -320,6 +338,7 @@ var supportsNativeDragAndDrop = [CPPlatform supportsDragAndDrop];
theDocument.addEventListener("mouseup", mouseEventCallback, NO); theDocument.addEventListener("mouseup", mouseEventCallback, NO);
theDocument.addEventListener("mousedown", mouseEventCallback, NO); theDocument.addEventListener("mousedown", mouseEventCallback, NO);
theDocument.addEventListener("mousemove", mouseEventCallback, NO); theDocument.addEventListener("mousemove", mouseEventCallback, NO);
theDocument.addEventListener("contextmenu", contextMenuEventCallback, NO);
theDocument.addEventListener("beforecopy", copyEventCallback, NO); theDocument.addEventListener("beforecopy", copyEventCallback, NO);
theDocument.addEventListener("beforecut", copyEventCallback, NO); theDocument.addEventListener("beforecut", copyEventCallback, NO);
@@ -347,6 +366,7 @@ var supportsNativeDragAndDrop = [CPPlatform supportsDragAndDrop];
theDocument.removeEventListener("mouseup", mouseEventCallback, NO); theDocument.removeEventListener("mouseup", mouseEventCallback, NO);
theDocument.removeEventListener("mousedown", mouseEventCallback, NO); theDocument.removeEventListener("mousedown", mouseEventCallback, NO);
theDocument.removeEventListener("mousemove", mouseEventCallback, NO); theDocument.removeEventListener("mousemove", mouseEventCallback, NO);
theDocument.removeEventListener("contextmenu", contextMenuEventCallback, NO);
theDocument.removeEventListener("keyup", keyEventCallback, NO); theDocument.removeEventListener("keyup", keyEventCallback, NO);
theDocument.removeEventListener("keydown", keyEventCallback, NO); theDocument.removeEventListener("keydown", keyEventCallback, NO);
@@ -379,6 +399,7 @@ var supportsNativeDragAndDrop = [CPPlatform supportsDragAndDrop];
theDocument.attachEvent("onmousedown", mouseEventCallback); theDocument.attachEvent("onmousedown", mouseEventCallback);
theDocument.attachEvent("onmousemove", mouseEventCallback); theDocument.attachEvent("onmousemove", mouseEventCallback);
theDocument.attachEvent("ondblclick", mouseEventCallback); theDocument.attachEvent("ondblclick", mouseEventCallback);
theDocument.attachEvent("oncontextmenu", contextMenuEventCallback);
theDocument.attachEvent("onkeyup", keyEventCallback); theDocument.attachEvent("onkeyup", keyEventCallback);
theDocument.attachEvent("onkeydown", keyEventCallback); theDocument.attachEvent("onkeydown", keyEventCallback);
@@ -401,6 +422,7 @@ var supportsNativeDragAndDrop = [CPPlatform supportsDragAndDrop];
theDocument.detachEvent("onmousedown", mouseEventCallback); theDocument.detachEvent("onmousedown", mouseEventCallback);
theDocument.detachEvent("onmousemove", mouseEventCallback); theDocument.detachEvent("onmousemove", mouseEventCallback);
theDocument.detachEvent("ondblclick", mouseEventCallback); theDocument.detachEvent("ondblclick", mouseEventCallback);
theDocument.detachEvent("oncontextmenu", contextMenuEventCallback);
theDocument.detachEvent("onkeyup", keyEventCallback); theDocument.detachEvent("onkeyup", keyEventCallback);
theDocument.detachEvent("onkeydown", keyEventCallback); theDocument.detachEvent("onkeydown", keyEventCallback);
@@ -445,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])
@@ -492,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];
@@ -789,7 +816,6 @@ var supportsNativeDragAndDrop = [CPPlatform supportsDragAndDrop];
} }
} }
- (void)_checkPasteboardElement - (void)_checkPasteboardElement
{ {
var value = _DOMPasteboardElement.value; var value = _DOMPasteboardElement.value;
@@ -825,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)
@@ -844,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,
@@ -1032,11 +1061,12 @@ var supportsNativeDragAndDrop = [CPPlatform supportsDragAndDrop];
{ {
if(_mouseIsDown) if(_mouseIsDown)
{ {
event = _CPEventFromNativeMouseEvent(aDOMEvent, CPLeftMouseUp, location, modifierFlags, timestamp, windowNumber, nil, -1, CPDOMEventGetClickCount(_lastMouseUp, timestamp, location), 0); event = _CPEventFromNativeMouseEvent(aDOMEvent, _mouseDownIsRightClick ? CPRightMouseUp : CPLeftMouseUp, location, modifierFlags, timestamp, windowNumber, nil, -1, CPDOMEventGetClickCount(_lastMouseUp, timestamp, location), 0);
_mouseIsDown = NO; _mouseIsDown = NO;
_lastMouseUp = event; _lastMouseUp = event;
_mouseDownWindow = nil; _mouseDownWindow = nil;
_mouseDownIsRightClick = NO;
} }
if(_DOMEventMode) if(_DOMEventMode)
@@ -1076,7 +1106,12 @@ var supportsNativeDragAndDrop = [CPPlatform supportsDragAndDrop];
_DOMBodyElement.style["-khtml-user-drag"] = "element"; _DOMBodyElement.style["-khtml-user-drag"] = "element";
} }
event = _CPEventFromNativeMouseEvent(aDOMEvent, CPLeftMouseDown, location, modifierFlags, timestamp, windowNumber, nil, -1, CPDOMEventGetClickCount(_lastMouseDown, timestamp, location), 0); var button = aDOMEvent.button;
_mouseDownIsRightClick = button == 2 || (button == 0 && modifierFlags & CPControlKeyMask);
StopContextMenuDOMEventPropagation = YES;
event = _CPEventFromNativeMouseEvent(aDOMEvent, _mouseDownIsRightClick ? CPRightMouseDown : CPLeftMouseDown, location, modifierFlags, timestamp, windowNumber, nil, -1, CPDOMEventGetClickCount(_lastMouseDown, timestamp, location), 0);
_mouseIsDown = YES; _mouseIsDown = YES;
_lastMouseDown = event; _lastMouseDown = event;
@@ -1087,7 +1122,7 @@ var supportsNativeDragAndDrop = [CPPlatform supportsDragAndDrop];
if (_DOMEventMode) if (_DOMEventMode)
return; return;
event = _CPEventFromNativeMouseEvent(aDOMEvent, _mouseIsDown ? CPLeftMouseDragged : CPMouseMoved, location, modifierFlags, timestamp, windowNumber, nil, -1, 1, 0); event = _CPEventFromNativeMouseEvent(aDOMEvent, _mouseIsDown ? (_mouseDownIsRightClick ? CPRightMouseDragged : CPLeftMouseDragged) : CPMouseMoved, location, modifierFlags, timestamp, windowNumber, nil, -1, 1, 0);
} }
var isDragging = [[CPDragServer sharedDragServer] isDragging]; var isDragging = [[CPDragServer sharedDragServer] isDragging];
@@ -1102,10 +1137,21 @@ var supportsNativeDragAndDrop = [CPPlatform supportsDragAndDrop];
if (StopDOMEventPropagation && (!supportsNativeDragAndDrop || type !== "mousedown" && !isDragging)) if (StopDOMEventPropagation && (!supportsNativeDragAndDrop || type !== "mousedown" && !isDragging))
CPDOMEventStop(aDOMEvent, self); CPDOMEventStop(aDOMEvent, self);
// if there are any tracking event listeners then show the event guard so we don't lose events to iframes
_DOMEventGuard.style.display = (CPApp._eventListeners.length === 0) ? "none" : "";
[[CPRunLoop currentRunLoop] limitDateForMode:CPDefaultRunLoopMode]; [[CPRunLoop currentRunLoop] limitDateForMode:CPDefaultRunLoopMode];
} }
(CPArray)orderedWindowsAtLevel:(int)aLevel - (void)contextMenuEvent:(DOMEvent)aDOMEvent
{
if (StopContextMenuDOMEventPropagation)
CPDOMEventStop(aDOMEvent, self);
return !StopContextMenuDOMEventPropagation;
}
- (CPArray)orderedWindowsAtLevel:(int)aLevel
{ {
var layer = [self layerAtLevel:aLevel create:NO]; var layer = [self layerAtLevel:aLevel create:NO];
@@ -1149,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);
} }
@@ -1246,6 +1293,19 @@ var supportsNativeDragAndDrop = [CPPlatform supportsDragAndDrop];
return !StopDOMEventPropagation; return !StopDOMEventPropagation;
} }
- (void)_propagateContextMenuDOMEvent:(BOOL)aFlag
{
if (aFlag && CPBrowserIsEngine(CPGeckoBrowserEngine))
StopDOMEventPropagation = !aFlag;
StopContextMenuDOMEventPropagation = !aFlag;
}
- (BOOL)_willPropagateContextMenuDOMEvent
{
return StopContextMenuDOMEventPropagation;
}
- (CPWindow)hitTest:(CPPoint)location - (CPWindow)hitTest:(CPPoint)location
{ {
if (self._only) if (self._only)
-18
View File
@@ -1,18 +0,0 @@
<html>
<head>
</head>
<body>
<div>Test custom cursors with .cur images.</div>
<div style="width: 20px; height: 20px; margin: 10px; background: #ddd; cursor: url(disappearingItemCursor.cur), default">disappearingItemCursor</div>
<div style="width: 20px; height: 20px; margin: 10px; background: #ddd; cursor: url(closedHandCursor.cur), default">closedHandCursor</div>
<div style="width: 20px; height: 20px; margin: 10px; background: #ddd; cursor: url(contextMenuCursor.cur), default">contextMenuCursor</div>
<div style="width: 20px; height: 20px; margin: 10px; background: #ddd; cursor: url(dragCopyCursor.cur), default">dragCopyCursor</div>
<div style="width: 20px; height: 20px; margin: 10px; background: #ddd; cursor: url(dragLinkCursor.cur), default">dragLinkCursor</div>
<div style="width: 20px; height: 20px; margin: 10px; background: #ddd; cursor: url(openHandCursor.cur), default">openHandCursor</div>
<div style="width: 20px; height: 20px; margin: 10px; background: #ddd; cursor: url(resizeDownCursor.cur), default">resizeDownCursor</div>
<div style="width: 20px; height: 20px; margin: 10px; background: #ddd; cursor: url(resizeLeftCursor.cur), default">resizeLeftCursor</div>
<div style="width: 20px; height: 20px; margin: 10px; background: #ddd; cursor: url(resizeRightCursor.cur), default">resizeRightCursor</div>
<div style="width: 20px; height: 20px; margin: 10px; background: #ddd; cursor: url(resizeUpCursor.cur), default">resizeUpCursor</div>
</body>
</html>
Binary file not shown.

After

Width:  |  Height:  |  Size: 506 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 304 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 321 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 162 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 115 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 159 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 340 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 134 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 120 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 118 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 118 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 134 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 118 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 117 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 118 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 118 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 187 B

+47 -10
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,17 +721,54 @@
+ (CPButtonBar)themedButtonBar + (CPButtonBar)themedButtonBar
{ {
var buttonBar = [[CPButtonBar alloc] initWithFrame:CGRectMake(0.0, 0.0, 100.0, 26.0)], var buttonBar = [[CPButtonBar alloc] initWithFrame:CGRectMake(0.0, 0.0, 147.0, 26.0)],
color = [CPColor colorWithPatternImage:[[CPThreePartImage alloc] initWithImageSlices: color = [CPColor colorWithPatternImage:[_CPCibCustomResource imageResourceWithName:"buttonbar-bezel.png" size:CGSizeMake(1.0, 26.0)]];
[
[_CPCibCustomResource imageResourceWithName:"buttonbar-bezel.png" size:CGSizeMake(1.0, 26.0)], [buttonBar setHasResizeControl:YES];
[_CPCibCustomResource imageResourceWithName:"buttonbar-bezel.png" size:CGSizeMake(1.0, 26.0)],
[_CPCibCustomResource imageResourceWithName:"buttonbar-bezel-right.png" size:CGSizeMake(13.0, 26.0)]
]
isVertical:NO]];
[buttonBar setValue:color forThemeAttribute:@"bezel-color"]; [buttonBar setValue:color forThemeAttribute:@"bezel-color"];
var resizeColor = [CPColor colorWithPatternImage:[_CPCibCustomResource imageResourceWithName:"buttonbar-resize-control.png" size:CGSizeMake(5.0, 10.0)]];
[buttonBar setValue:CGSizeMake(5.0, 10.0) forThemeAttribute:@"resize-control-size"];
[buttonBar setValue:CGInsetMake(9.0, 4.0, 7.0, 4.0) forThemeAttribute:@"resize-control-inset"];
[buttonBar setValue:resizeColor forThemeAttribute:@"resize-control-color"];
var buttonBezelColor = [CPColor colorWithPatternImage:[[CPThreePartImage alloc] initWithImageSlices:
[
[_CPCibCustomResource imageResourceWithName:"buttonbar-button-bezel-left.png" size:CGSizeMake(2.0, 25.0)],
[_CPCibCustomResource imageResourceWithName:"buttonbar-button-bezel-center.png" size:CGSizeMake(1.0, 25.0)],
[_CPCibCustomResource imageResourceWithName:"buttonbar-button-bezel-right.png" size:CGSizeMake(2.0, 25.0)]
]
isVertical:NO]],
buttonBezelHighlightedColor = [CPColor colorWithPatternImage:[[CPThreePartImage alloc] initWithImageSlices:
[
[_CPCibCustomResource imageResourceWithName:"buttonbar-button-bezel-highlighted-left.png" size:CGSizeMake(2.0, 25.0)],
[_CPCibCustomResource imageResourceWithName:"buttonbar-button-bezel-highlighted-center.png" size:CGSizeMake(1.0, 25.0)],
[_CPCibCustomResource imageResourceWithName:"buttonbar-button-bezel-highlighted-right.png" size:CGSizeMake(2.0, 25.0)]
]
isVertical:NO]],
buttonBezelDisabledColor = [CPColor colorWithPatternImage:[[CPThreePartImage alloc] initWithImageSlices:
[
[_CPCibCustomResource imageResourceWithName:"buttonbar-button-bezel-disabled-left.png" size:CGSizeMake(2.0, 25.0)],
[_CPCibCustomResource imageResourceWithName:"buttonbar-button-bezel-disabled-center.png" size:CGSizeMake(1.0, 25.0)],
[_CPCibCustomResource imageResourceWithName:"buttonbar-button-bezel-disabled-right.png" size:CGSizeMake(2.0, 25.0)]
]
isVertical:NO]];
[buttonBar setValue:buttonBezelColor forThemeAttribute:@"button-bezel-color"];
[buttonBar setValue:buttonBezelHighlightedColor forThemeAttribute:@"button-bezel-color" inState:CPThemeStateHighlighted];
[buttonBar setValue:buttonBezelDisabledColor forThemeAttribute:@"button-bezel-color" inState:CPThemeStateDisabled];
[buttonBar setValue:[CPColor blackColor] forThemeAttribute:@"button-text-color"];
var popup = [CPButtonBar actionPopupButton];
[popup addItemWithTitle:"Item 1"];
[popup addItemWithTitle:"Item 2"];
[buttonBar setButtons:[[CPButtonBar plusButton], [CPButtonBar minusButton], popup]];
return buttonBar; return buttonBar;
} }
+1 -1
View File
@@ -10,7 +10,7 @@ blendKitTask = framework ("BlendKit", function(blendKitTask)
blendKitTask.setBuildPath(FILE.join($BUILD_DIR, $CONFIGURATION)); blendKitTask.setBuildPath(FILE.join($BUILD_DIR, $CONFIGURATION));
blendKitTask.setIdentifier("com.280n.BlendKit"); blendKitTask.setIdentifier("com.280n.BlendKit");
blendKitTask.setVersion("0.8.0"); blendKitTask.setVersion(getCappuccinoVersion());
blendKitTask.setAuthor("280 North, Inc."); blendKitTask.setAuthor("280 North, Inc.");
blendKitTask.setEmail("feedback @nospam@ 280north.com"); blendKitTask.setEmail("feedback @nospam@ 280north.com");
blendKitTask.setSummary("BlendKit classes for Cappuccino"); blendKitTask.setSummary("BlendKit classes for Cappuccino");
+16 -4
View File
@@ -5,11 +5,16 @@
{ {
} }
- (void)_init
{
[self setBackgroundColor:[CPColor colorWithPatternImage:CPAppKitImage("tableview-headerview.png", CGSizeMake(1.0, 23.0))]];
}
- (id)initWithFrame:(CGRect)aFrame - (id)initWithFrame:(CGRect)aFrame
{ {
if (self = [super initWithFrame:aFrame]) if (self = [super initWithFrame:aFrame])
{ {
[self setBackgroundColor:[CPColor colorWithPatternImage:CPAppKitImage("tableview-headerview.png", CGSizeMake(1.0, 23.0))]]; [self _init];
} }
return self; return self;
@@ -22,9 +27,6 @@
CGContextSetStrokeColor(context, [CPColor colorWithHexString:@"dce0e2"]); CGContextSetStrokeColor(context, [CPColor colorWithHexString:@"dce0e2"]);
var points = [ var points = [
CGPointMake(aRect.origin.x, aRect.origin.y),
CGPointMake(aRect.origin.x + aRect.size.width, aRect.origin.y),
CGPointMake(aRect.origin.x, aRect.origin.y + 0.5), CGPointMake(aRect.origin.x, aRect.origin.y + 0.5),
CGPointMake(aRect.origin.x, aRect.origin.y + aRect.size.height) CGPointMake(aRect.origin.x, aRect.origin.y + aRect.size.height)
]; ];
@@ -32,4 +34,14 @@
CGContextStrokeLineSegments(context, points, 2); CGContextStrokeLineSegments(context, points, 2);
} }
- (id)initWithCoder:(CPCoder)aCoder
{
self = [super initWithCoder:aCoder];
{
[self _init];
}
return self;
}
@end @end
+39 -35
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)
@@ -333,6 +345,7 @@ var HORIZONTAL_MARGIN = 3.0,
// Create or destroy the DOM Text Element as necessary // Create or destroy the DOM Text Element as necessary
if (needsDOMTextElement !== hasDOMTextElement) if (needsDOMTextElement !== hasDOMTextElement)
{
if (hasDOMTextElement) if (hasDOMTextElement)
{ {
_DOMElement.removeChild(_DOMTextElement); _DOMElement.removeChild(_DOMTextElement);
@@ -361,6 +374,7 @@ var HORIZONTAL_MARGIN = 3.0,
// We have to set all these values now. // We have to set all these values now.
_flags |= _CPImageAndTextViewTextChangedFlag | _CPImageAndTextViewFontChangedFlag | _CPImageAndTextViewLineBreakModeChangedFlag; _flags |= _CPImageAndTextViewTextChangedFlag | _CPImageAndTextViewFontChangedFlag | _CPImageAndTextViewLineBreakModeChangedFlag;
} }
}
var textStyle = hasDOMTextElement ? _DOMTextElement.style : nil; var textStyle = hasDOMTextElement ? _DOMTextElement.style : nil;
@@ -369,6 +383,7 @@ var HORIZONTAL_MARGIN = 3.0,
hasDOMTextShadowElement = !!_DOMTextShadowElement; hasDOMTextShadowElement = !!_DOMTextShadowElement;
if (needsDOMTextShadowElement !== hasDOMTextShadowElement) if (needsDOMTextShadowElement !== hasDOMTextShadowElement)
{
if (hasDOMTextShadowElement) if (hasDOMTextShadowElement)
{ {
_DOMElement.removeChild(_DOMTextShadowElement); _DOMElement.removeChild(_DOMTextShadowElement);
@@ -386,6 +401,7 @@ var HORIZONTAL_MARGIN = 3.0,
shadowStyle.font = [_font ? _font : [CPFont systemFontOfSize:12.0] cssString]; shadowStyle.font = [_font ? _font : [CPFont systemFontOfSize:12.0] cssString];
shadowStyle.position = "absolute"; shadowStyle.position = "absolute";
shadowStyle.whiteSpace = textStyle.whiteSpace; shadowStyle.whiteSpace = textStyle.whiteSpace;
shadowStyle.wordWrap = textStyle.wordWrap;
shadowStyle.color = [_textShadowColor cssString]; shadowStyle.color = [_textShadowColor cssString];
shadowStyle.zIndex = 150; shadowStyle.zIndex = 150;
@@ -394,7 +410,6 @@ var HORIZONTAL_MARGIN = 3.0,
if (document.attachEvent) if (document.attachEvent)
{ {
shadowStyle.overflow = textStyle.overflow; shadowStyle.overflow = textStyle.overflow;
shadowStyle.wordWrap = textStyle.wordWrap;
} }
else else
{ {
@@ -408,6 +423,7 @@ var HORIZONTAL_MARGIN = 3.0,
_flags |= _CPImageAndTextViewTextChangedFlag; //sigh... _flags |= _CPImageAndTextViewTextChangedFlag; //sigh...
} }
}
var shadowStyle = hasDOMTextShadowElement ? _DOMTextShadowElement.style : nil; var shadowStyle = hasDOMTextShadowElement ? _DOMTextShadowElement.style : nil;
@@ -447,9 +463,7 @@ var HORIZONTAL_MARGIN = 3.0,
case CPLineBreakByClipping: textStyle.overflow = "hidden"; case CPLineBreakByClipping: textStyle.overflow = "hidden";
textStyle.textOverflow = "clip"; textStyle.textOverflow = "clip";
textStyle.whiteSpace = "pre"; textStyle.whiteSpace = "pre";
textStyle.wordWrap = "normal";
if (document.attachEvent)
textStyle.wordWrap = "normal";
break; break;
@@ -459,26 +473,23 @@ var HORIZONTAL_MARGIN = 3.0,
case CPLineBreakByTruncatingTail: textStyle.textOverflow = "ellipsis"; case CPLineBreakByTruncatingTail: textStyle.textOverflow = "ellipsis";
textStyle.whiteSpace = "nowrap"; textStyle.whiteSpace = "nowrap";
textStyle.overflow = "hidden"; textStyle.overflow = "hidden";
textStyle.wordWrap = "normal";
if (document.attachEvent)
textStyle.wordWrap = "normal";
break; break;
case CPLineBreakByCharWrapping: case CPLineBreakByCharWrapping:
case CPLineBreakByWordWrapping: if (document.attachEvent) case CPLineBreakByWordWrapping: textStyle.wordWrap = "break-word";
{ try {
textStyle.whiteSpace = "pre"; textStyle.whiteSpace = "pre";
textStyle.wordWrap = "break-word";
}
else
{
textStyle.whiteSpace = "-o-pre-wrap"; textStyle.whiteSpace = "-o-pre-wrap";
textStyle.whiteSpace = "-pre-wrap"; textStyle.whiteSpace = "-pre-wrap";
textStyle.whiteSpace = "-moz-pre-wrap"; textStyle.whiteSpace = "-moz-pre-wrap";
textStyle.whiteSpace = "pre-wrap"; textStyle.whiteSpace = "pre-wrap";
} }
catch (e) {
//internet explorer doesn't like these properties
textStyle.whiteSpace = "pre";
}
textStyle.overflow = "hidden"; textStyle.overflow = "hidden";
textStyle.textOverflow = "clip"; textStyle.textOverflow = "clip";
@@ -490,7 +501,6 @@ var HORIZONTAL_MARGIN = 3.0,
{ {
if (document.attachEvent) if (document.attachEvent)
{ {
shadowStyle.wordWrap = textStyle.wordWrap;
shadowStyle.overflow = textStyle.overflow; shadowStyle.overflow = textStyle.overflow;
} }
else else
@@ -499,6 +509,7 @@ var HORIZONTAL_MARGIN = 3.0,
shadowStyle.overflowY = textStyle.overflowY; shadowStyle.overflowY = textStyle.overflowY;
} }
shadowStyle.wordWrap = textStyle.wordWrap;
shadowStyle.whiteSpace = textStyle.whiteSpace; shadowStyle.whiteSpace = textStyle.whiteSpace;
shadowStyle.textOverflow = textStyle.textOverflow; shadowStyle.textOverflow = textStyle.textOverflow;
} }
@@ -510,6 +521,7 @@ var HORIZONTAL_MARGIN = 3.0,
// Create or destroy DOM Image element // Create or destroy DOM Image element
if (needsDOMImageElement !== hasDOMImageElement) if (needsDOMImageElement !== hasDOMImageElement)
{
if (hasDOMImageElement) if (hasDOMImageElement)
{ {
_DOMElement.removeChild(_DOMImageElement); _DOMElement.removeChild(_DOMImageElement);
@@ -540,7 +552,7 @@ var HORIZONTAL_MARGIN = 3.0,
hasDOMImageElement = YES; hasDOMImageElement = YES;
} }
#endif }
var size = [self bounds].size, var size = [self bounds].size,
textRect = _CGRectMake(0.0, 0.0, size.width, size.height); textRect = _CGRectMake(0.0, 0.0, size.width, size.height);
@@ -572,60 +584,52 @@ var HORIZONTAL_MARGIN = 3.0,
imageHeight *= scale; imageHeight *= scale;
} }
#if PLATFORM(DOM) 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 = imageWidth + "px"; imageStyle.width = MAX(imageWidth, 0) + "px";
imageStyle.height = imageHeight + "px"; imageStyle.height = MAX(imageHeight, 0) + "px";
#endif
if (_imagePosition === CPImageBelow) if (_imagePosition === CPImageBelow)
{ {
#if PLATFORM(DOM)
imageStyle.left = FLOOR(centerX - imageWidth / 2.0) + "px"; imageStyle.left = FLOOR(centerX - imageWidth / 2.0) + "px";
imageStyle.top = FLOOR(size.height - imageHeight) + "px"; imageStyle.top = FLOOR(size.height - imageHeight) + "px";
#endif
textRect.size.height = size.height - imageHeight - VERTICAL_MARGIN; textRect.size.height = size.height - imageHeight - VERTICAL_MARGIN;
} }
else if (_imagePosition === CPImageAbove) else if (_imagePosition === CPImageAbove)
{ {
#if PLATFORM(DOM)
CPDOMDisplayServerSetStyleLeftTop(_DOMImageElement, NULL, FLOOR(centerX - imageWidth / 2.0), 0); CPDOMDisplayServerSetStyleLeftTop(_DOMImageElement, NULL, FLOOR(centerX - imageWidth / 2.0), 0);
#endif
textRect.origin.y += imageHeight + VERTICAL_MARGIN; textRect.origin.y += imageHeight + VERTICAL_MARGIN;
textRect.size.height = size.height - imageHeight - VERTICAL_MARGIN; textRect.size.height = size.height - imageHeight - VERTICAL_MARGIN;
} }
else if (_imagePosition === CPImageLeft) else if (_imagePosition === CPImageLeft)
{ {
#if PLATFORM(DOM)
imageStyle.top = FLOOR(centerY - imageHeight / 2.0) + "px"; imageStyle.top = FLOOR(centerY - imageHeight / 2.0) + "px";
imageStyle.left = "0px"; imageStyle.left = "0px";
#endif
textRect.origin.x = imageWidth + HORIZONTAL_MARGIN; textRect.origin.x = imageWidth + HORIZONTAL_MARGIN;
textRect.size.width -= imageWidth + HORIZONTAL_MARGIN; textRect.size.width -= imageWidth + HORIZONTAL_MARGIN;
} }
else if (_imagePosition === CPImageRight) else if (_imagePosition === CPImageRight)
{ {
#if PLATFORM(DOM)
imageStyle.top = FLOOR(centerY - imageHeight / 2.0) + "px"; imageStyle.top = FLOOR(centerY - imageHeight / 2.0) + "px";
imageStyle.left = FLOOR(size.width - imageWidth) + "px"; imageStyle.left = FLOOR(size.width - imageWidth) + "px";
#endif
textRect.size.width -= imageWidth + HORIZONTAL_MARGIN; textRect.size.width -= imageWidth + HORIZONTAL_MARGIN;
} }
else if (_imagePosition === CPImageOnly) else if (_imagePosition === CPImageOnly)
{ {
#if PLATFORM(DOM)
imageStyle.top = FLOOR(centerY - imageHeight / 2.0) + "px"; imageStyle.top = FLOOR(centerY - imageHeight / 2.0) + "px";
imageStyle.left = FLOOR(centerX - imageWidth / 2.0) + "px"; imageStyle.left = FLOOR(centerX - imageWidth / 2.0) + "px";
#endif
} }
} }
#if PLATFORM(DOM)
if (hasDOMTextElement) if (hasDOMTextElement)
{ {
var textRectX = _CGRectGetMinX(textRect), var textRectX = _CGRectGetMinX(textRect),
@@ -659,8 +663,8 @@ var HORIZONTAL_MARGIN = 3.0,
textStyle.top = ROUND(textRectY) + "px"; textStyle.top = ROUND(textRectY) + "px";
textStyle.left = ROUND(textRectX) + "px"; textStyle.left = ROUND(textRectX) + "px";
textStyle.width = ROUND(textRectWidth) + "px"; textStyle.width = MAX(ROUND(textRectWidth), 0) + "px";
textStyle.height = ROUND(textRectHeight) + "px"; textStyle.height = MAX(ROUND(textRectHeight), 0) + "px";
if (shadowStyle) if (shadowStyle)
{ {
@@ -669,8 +673,8 @@ var HORIZONTAL_MARGIN = 3.0,
shadowStyle.top = ROUND(textRectY + _textShadowOffset.height) + "px"; shadowStyle.top = ROUND(textRectY + _textShadowOffset.height) + "px";
shadowStyle.left = ROUND(textRectX + _textShadowOffset.width) + "px"; shadowStyle.left = ROUND(textRectX + _textShadowOffset.width) + "px";
shadowStyle.width = ROUND(textRectWidth) + "px"; shadowStyle.width = MAX(ROUND(textRectWidth), 0) + "px";
shadowStyle.height = ROUND(textRectHeight) + "px"; shadowStyle.height = MAX(ROUND(textRectHeight), 0) + "px";
} }
} }
#endif #endif
+5 -1
View File
@@ -8,7 +8,7 @@ new FileList("**/*").exclude("Jakefile").forEach(function(aFilename)
if (!FILE.isFile(aFilename)) if (!FILE.isFile(aFilename))
return; return;
var buildFilename = FILE.join($BUILD_CONFIGURATION_DIR, "CommonJS", "cappuccino", aFilename); var buildFilename = FILE.join($BUILD_CJS_CAPPUCCINO, aFilename);
filedir (buildFilename, [aFilename], function () filedir (buildFilename, [aFilename], function ()
{ {
@@ -27,3 +27,7 @@ new FileList("**/*").exclude("Jakefile").forEach(function(aFilename)
task ("build", buildFilename); task ("build", buildFilename);
CLOBBER.include(buildFilename); CLOBBER.include(buildFilename);
}); });
task ("build", function() {
setPackageMetadata(FILE.join($BUILD_CJS_CAPPUCCINO, "package.json"));
});
+213 -103
View File
@@ -8,6 +8,9 @@ require("narwhal").ensureEngine("rhino");
var FILE = require("file"); var FILE = require("file");
var OS = require("os"); var OS = require("os");
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)();
@@ -24,6 +27,10 @@ parser.option("-F", "--framework", "frameworks")
.push() .push()
.help("Add a frameworks directory, relative to INPUT_PROJECT (default: ['Frameworks'])"); .help("Add a frameworks directory, relative to INPUT_PROJECT (default: ['Frameworks'])");
parser.option("-P", "--path", "paths")
.push()
.help("Add a path (relative to the application root) to inline.");
parser.option("-f", "--force", "force") parser.option("-f", "--force", "force")
.def(false) .def(false)
.set(true) .set(true)
@@ -34,6 +41,20 @@ parser.option("--index", "index")
.set() .set()
.help("The root HTML file to modify (default: index.html)"); .help("The root HTML file to modify (default: index.html)");
parser.option("-s", "--split", "number", "split")
.natural()
.def(0)
.help("Split into multiple files");
parser.option("-c", "--compressor", "compressor")
.def("shrinksafe")
.set()
.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)
@@ -81,151 +102,240 @@ function main(args)
var flattener = new ObjectiveJFlattener(rootPath); var flattener = new ObjectiveJFlattener(rootPath);
flattener.options = options;
flattener.setIncludePaths(frameworks); flattener.setIncludePaths(frameworks);
flattener.setEnvironments([environment, "ObjJ"]); flattener.setEnvironments([environment, "ObjJ"]);
print("Loading application.");
flattener.load(mainPath); flattener.load(mainPath);
flattener.finishLoading();
var rootResources = flattener.require("objective-j").StaticResource.rootResources(); print("Loading default theme.");
flattener.require("objective-j").objj_eval("("+(function() {
var blend = [[CPThemeBlend alloc] initWithContentsOfURL:[[CPBundle bundleForClass:[CPApplication class]] pathForResource:[CPApplication defaultThemeName] + ".blend"]];
[blend loadWithDelegate:nil];
})+")")();
var root = rootResources["file:"]; var applicationJSs = flattener.buildApplicationJS();
// FIXME: shouldn't have to do this manually
var components = rootPath.split("/").slice(0, -1);
components[0] = "/";
var node = root;
while (components.length) {
node = node.children()[components.shift()];
}
applicationRoot = node;
print(applicationRoot.toString());
var applicationJS = flattener.buildApplicationJS(applicationRoot);
FILE.copyTree(rootPath, outputPath); FILE.copyTree(rootPath, outputPath);
outputPath.join("Application.js").write(applicationJS); applicationJSs.forEach(function(applicationJS, n) {
var name = "Application"+(n||"")+".js";
if (options.compressor === "none") {
print("skipping compression: " + name);
} else {
print("compressing: " + name);
applicationJS = require("minify/"+options.compressor).compress(applicationJS, { charset : "UTF-8", useServer : true });
}
outputPath.join(name).write(applicationJS, { charset : "UTF-8" });
});
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
function ObjectiveJFlattener(rootPath) { function ObjectiveJFlattener(rootPath) {
ObjectiveJRuntimeAnalyzer.apply(this, arguments); ObjectiveJRuntimeAnalyzer.apply(this, arguments);
this.resourceBuffer = []; this.filesToCache = {};
this.bundleBuffer = []; this.fileCacheBuffer = [];
this.functionsBuffer = []; this.functionsBuffer = [];
this._outputBundles = {};
} }
ObjectiveJFlattener.prototype = Object.create(ObjectiveJRuntimeAnalyzer.prototype); ObjectiveJFlattener.prototype = Object.create(ObjectiveJRuntimeAnalyzer.prototype);
ObjectiveJFlattener.prototype.buildApplicationJS = function(applicationRoot) { ObjectiveJFlattener.prototype.buildApplicationJS = function() {
this.serializeStaticResources(applicationRoot);
this.serializeStaticFileExecutables();
var buffer = [] this.setupFileCache();
this.serializeFunctions();
this.serializeFileCache();
buffer.push("(function(){"); var additions = FILE.read(FILE.join(FILE.dirname(module.path), "..", "..", "cappuccino", "lib", "cappuccino", "objj-flatten-additions.js"), { charset:"UTF-8" });
buffer.push("var appURL = new CFURL('.', ObjectiveJ.pageURL);") var applicationJSs = [];
buffer.push(this.bundleBuffer.join("\n")); if (this.options.split === 0) {
var buffer = [];
buffer.push("var baseURL = new CFURL(\".\", ObjectiveJ.pageURL);");
buffer.push(additions);
buffer.push(this.fileCacheBuffer.join("\n"));
buffer.push(this.functionsBuffer.join("\n"));
buffer.push("ObjectiveJ.bootstrap();");
applicationJSs.push(buffer.join("\n"));
} else {
var appFilesCount = this.options.split;
buffer.push("var nodeStack = [];"); var buffers = [];
buffer.push("var applicationRoot = ObjectiveJ.StaticResource.resourceAtURL(appURL, true);"); for (var i = 0; i <= appFilesCount; i++)
buffer.push("var currentNode = null;"); buffers.push([]);
buffer.push("var newNode;");
buffer.push(this.resourceBuffer.join("\n")); var chunks = this.fileCacheBuffer.concat(this.functionsBuffer).sort(function(chunkA, chunkB) {
return chunkA.length - chunkB.length;
});
buffer.push("})();"); // try to equally distribute the chunks. could be better but good enough for now.
var n = 0;
while (chunks.length) {
buffers[(n++ % appFilesCount) + 1].push(chunks.pop());
}
buffer.push(this.functionsBuffer.join("\n")); buffers[0].push("var baseURL = new CFURL(\".\", ObjectiveJ.pageURL);");
buffers[0].push(additions);
buffer.push("ObjectiveJ.bootstrap();"); buffers[0].push("var appFilesCount = " + appFilesCount +";");
buffers[0].push("for (var i = 1; i <= appFilesCount; i++) {");
buffers[0].push(" var script = document.createElement(\"script\");");
buffers[0].push(" script.src = \"Application\"+i+\".js\";");
buffers[0].push(" script.charset = \"UTF-8\";");
buffers[0].push(" script.onload = function() { if (--appFilesCount === 0) ObjectiveJ.bootstrap(); };");
buffers[0].push(" document.getElementsByTagName(\"head\")[0].appendChild(script);");
buffers[0].push("}");
return buffer.join("\n"); buffers.forEach(function(buffer) {
applicationJSs.push(buffer.join("\n"));
});
}
return applicationJSs;
} }
ObjectiveJFlattener.prototype.serializeStaticFileExecutables = function() { ObjectiveJFlattener.prototype.serializeFunctions = function() {
this.require("objective-j").FileExecutable.allFileExecutables().forEach(function(aFileExecutable) { var inlineFunctions = true;//this.options.inlineFunctions;
var deps = aFileExecutable.fileDependencies().map(function(dependency) {
return "new ObjectiveJ.FileDependency(new CFURL("+JSON.stringify(dependency.path())+"),"+JSON.stringify(dependency.isLocal())+")"
}).join(",");
var func = aFileExecutable._function.toString(); var outputFiles = {};
// HACK
func = func.replace(", require, exports, module, system, print, window", "");
this.functionsBuffer.push("var path = "+JSON.stringify(this.rootPath.relative(aFileExecutable.path()).toString())+";"); var _cachedExecutableFunctions = {};
this.functionsBuffer.push("new ObjectiveJ.FileExecutable(path,"+
"new ObjectiveJ.Executable(null, ["+deps+"], path, "+func+"));"); this.require("objective-j").FileExecutable.allFileExecutables().forEach(function(executable) {
var path = executable.path();
if (inlineFunctions)
{
// stringify the function, replacing arguments
var functionString = executable._function.toString().replace(", require, exports, module, system, print, window", ""); // HACK
var relative = this.rootPath.relative(path).toString();
this.functionsBuffer.push("ObjectiveJ.FileExecutable._cacheFunction(new CFURL("+JSON.stringify(relative)+", baseURL),\n"+functionString+");");
}
var bundle = this.context.global.CFBundle.bundleContainingURL(path);
if (bundle && bundle.infoDictionary())
{
var executablePath = bundle.executablePath(),
relativeToBundle = FILE.relative(FILE.join(bundle.path(), ""), path);
if (executablePath)
{
if (inlineFunctions)
{
// remove the code since we're inlining the functions
executable._code = "alert("+JSON.stringify(relativeToBundle)+");";
}
if (!outputFiles[executablePath])
{
outputFiles[executablePath] = [];
outputFiles[executablePath].push("@STATIC;1.0;");
}
var fileContents = executable.toMarkedString();
outputFiles[executablePath].push("p;" + relativeToBundle.length + ";" + relativeToBundle);
outputFiles[executablePath].push("t;" + fileContents.length + ";" + fileContents);
// stream.print("Adding \0green(" + this.rootPath.relative(path) + "\0) to \0cyan(" + this.rootPath.relative(executablePath) + "\0)");
}
}
else
CPLog.warn("No bundle (or info dictionary for) " + rootPath.relative(path));
}, this);
for (var executablePath in outputFiles)
{
var relative = this.rootPath.relative(executablePath).toString();
var contents = outputFiles[executablePath].join("");
this.filesToCache[relative] = contents;
}
}
ObjectiveJFlattener.prototype.serializeFileCache = function() {
for (var relative in this.filesToCache) {
var contents = this.filesToCache[relative];
print("caching: " + relative + " => " + (contents == null ? 404 : 200));
if (contents == null)
this.fileCacheBuffer.push("CFHTTPRequest._cacheRequest(new CFURL("+JSON.stringify(relative)+", baseURL), 404);");
else
this.fileCacheBuffer.push("CFHTTPRequest._cacheRequest(new CFURL("+JSON.stringify(relative)+", baseURL), 200, {}, "+JSON.stringify(contents)+");");
}
}
ObjectiveJFlattener.prototype.setupFileCache = function() {
var paths = {};
UTIL.update(paths, this.requestedURLs);
this.options.paths.forEach(function(relativePath) {
paths[this.rootPath.join(relativePath)] = true;
}, this);
Object.keys(paths).forEach(function(absolute) {
var relative = this.rootPath.relative(absolute).toString();
if (relative.indexOf("..") === 0)
{
print("skipping (parent of app root): " + absolute);
return;
}
if (FILE.isFile(absolute))
{
// if (this.options.maxCachedSize && FILE.size(absolute) > this.options.maxCachedSize)
// {
// print("skipping (larger than "+this.options.maxCachedSize+" bytes): " + absolute);
// return;
// }
var contents = FILE.read(absolute, { charset : "UTF-8" });
this.filesToCache[relative] = contents;
} else {
this.filesToCache[relative] = null;
}
}, this); }, this);
} }
ObjectiveJFlattener.prototype.serializeStaticResources = function(node, depth) {
depth = depth || 0;
var bundle = this.context.global.CFBundle.bundleContainingURL(node.URL());
if (!bundle) {
stream.print("\0yellow(Warning:\0) No bundle for path: \0cyan("+node.URL()+"\0)");
}
else if (!this._outputBundles[bundle.path()]) {
this._outputBundles[bundle.path()] = bundle;
stream.print("Writing bundle: \0cyan("+bundle.path()+"\0)");
print(bundle.infoDictionary())
var relative = this.rootPath.relative(bundle.path()).toString();
this.bundleBuffer.push("var bundle = new CFBundle("+(relative ? JSON.stringify(relative) : "appURL")+");");
this.bundleBuffer.push("bundle._loadStatus = " + (1<<4) + ";");
if (bundle.infoDictionary()) {
this.bundleBuffer.push("bundle._infoDictionary = CFPropertyList.propertyListFromString(" +
JSON.stringify(CPPropertyListCreateData(bundle.infoDictionary()).rawString()) + ");");
}
}
// not the root node:
if (depth > 0) {
this.resourceBuffer.push("newNode = new ObjectiveJ.StaticResource(" +
JSON.stringify(node.name()) +
", currentNode, " +
JSON.stringify(node.isDirectory()) + ", " +
JSON.stringify(node.isResolved()) + ");");
} else {
this.resourceBuffer.push("newNode = applicationRoot;");
}
// var contents = node.contents();
// if (contents) {
// this.resourceBuffer.push("newNode._contents = " + JSON.stringify(contents) + ";");
// }
if (!node.children())
return;
this.resourceBuffer.push("nodeStack.push(currentNode);");
this.resourceBuffer.push("currentNode = newNode;");
var children = node.children();
for (var name in children) {
this.serializeStaticResources(children[name], depth+1);
}
this.resourceBuffer.push("currentNode = nodeStack.pop();");
}
// "$1" is the matching indentation // "$1" is the matching indentation
var scriptTagsBefore = '$1<script type = "text/javascript">\n$1 OBJJ_AUTO_BOOTSTRAP = false;\n$1</script>'; var scriptTagsBefore =
var scriptTagsAfter = '$1<script type = "text/javascript" src = "Application.js"></script>'; '$1<script type = "text/javascript">\n'+
'$1 OBJJ_AUTO_BOOTSTRAP = false;\n'+
'$1</script>';
var scriptTagsAfter =
'$1<script type="text/javascript" src="Application.js" charset="UTF-8"></script>';
// enable CPLog:
// scriptTagsAfter = '$1<script type="text/javascript">\n$1 CPLogRegister(CPLogConsole);\n$1</script>\n' + scriptTagsAfter;
function rewriteMainHTML(indexHTMLPath) { function rewriteMainHTML(indexHTMLPath) {
if (indexHTMLPath.isFile()) { if (indexHTMLPath.isFile()) {
var indexHTML = indexHTMLPath.read(); var indexHTML = indexHTMLPath.read({ charset : "UTF-8" });
// inline the Application.js if it's smallish
var applicationJSPath = indexHTMLPath.dirname().join("Application.js");
if (applicationJSPath.size() < 10*1024) {
// escape any dollar signs by replacing them with two
// then indent by splitting/joining on newlines
scriptTagsAfter =
'$1<script type="text/javascript">\n'+
'$1 ' + applicationJSPath.read({ charset : "UTF-8" }).replace(/\$/g, "$$$$").split("\n").join("\n$1 ")+'\n'+
'$1</script>';
}
// attempt to find Objective-J script tag and add ours // attempt to find Objective-J script tag and add ours
var newIndexHTML = indexHTML.replace(/([ \t]+)<script[^>]+Objective-J\.js[^>]+>(?:\s*<\/script>)?/, var newIndexHTML = indexHTML.replace(/([ \t]+)<script[^>]+Objective-J\.js[^>]+>(?:\s*<\/script>)?/,
@@ -233,7 +343,7 @@ function rewriteMainHTML(indexHTMLPath) {
if (newIndexHTML !== indexHTML) { if (newIndexHTML !== indexHTML) {
stream.print("\0green(Modified: "+indexHTMLPath+".\0)"); stream.print("\0green(Modified: "+indexHTMLPath+".\0)");
indexHTMLPath.write(newIndexHTML); indexHTMLPath.write(newIndexHTML, { charset : "UTF-8" });
return; return;
} }
} else { } else {
+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) {
+23
View File
@@ -0,0 +1,23 @@
var FILE = require("file");
var sprintf = require("printf").sprintf;
var pkg = null;
function getPackage() {
if (!pkg)
pkg = JSON.parse(FILE.path(module.path).dirname().dirname().join("package.json").read({ charset : "UTF-8" }));
return pkg;
}
exports.version = function() { return getPackage()["version"]; }
exports.revision = function() { return getPackage()["cappuccino-revision"]; }
exports.timestamp = function() { return new Date(getPackage()["cappuccino-timestamp"]); }
exports.fullVersionString = function() {
return sprintf("cappuccino %s (%04d-%02d-%02d %s)",
exports.version(),
exports.timestamp().getUTCFullYear(),
exports.timestamp().getUTCMonth()+1,
exports.timestamp().getUTCDate(),
exports.revision().slice(0,6)
);
}
+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);
});
}
@@ -5,6 +5,8 @@ var Context = require("interpreter").Context;
ObjectiveJRuntimeAnalyzer = function(rootPath) ObjectiveJRuntimeAnalyzer = function(rootPath)
{ {
this.rootPath = rootPath; this.rootPath = rootPath;
this.rootURL = new CFURL(String(rootPath));
this.context = new Context(); this.context = new Context();
this.scope = setupObjectiveJ(this.context); this.scope = setupObjectiveJ(this.context);
@@ -28,6 +30,19 @@ ObjectiveJRuntimeAnalyzer = function(rootPath)
var url = this.executableURL(); var url = this.executableURL();
return url ? url.absoluteURL().path() : null; return url ? url.absoluteURL().path() : null;
} }
this.require("cappuccino/objj-flatten-additions");
if (!this.context.global.CFHTTPRequest._lookupCachedRequest)
print("Warning: CFHTTPRequest._lookupCachedRequest. Need to import objj-flatten-additions module.");
var requestedURLs = this.requestedURLs = {};
var _lookupCachedRequest = this.context.global.CFHTTPRequest._lookupCachedRequest;
this.context.global.CFHTTPRequest._lookupCachedRequest = function(aURL) {
var path = new CFURL(aURL, this.rootURL).absoluteURL().path();
requestedURLs[path] = true;
return _lookupCachedRequest.apply(null, arguments);
}
} }
ObjectiveJRuntimeAnalyzer.prototype.setIncludePaths = function(includePaths) { ObjectiveJRuntimeAnalyzer.prototype.setIncludePaths = function(includePaths) {
@@ -0,0 +1,58 @@
var URLCache = { };
var CFHTTPRequest_open = CFHTTPRequest.prototype.open;
CFHTTPRequest.prototype.open = function(/*String*/ method, /*String*/ url, /*Boolean*/ async, /*String*/ user, /*String*/ password)
{
var cachedRequest = CFHTTPRequest._lookupCachedRequest(url);
if (cachedRequest)
{
var self = this;
this._nativeRequest = cachedRequest;
this._nativeRequest.onreadystatechange = function()
{
ObjectiveJ.determineAndDispatchHTTPRequestEvents(self);
};
}
return CFHTTPRequest_open.apply(this, arguments);
}
CFHTTPRequest._cacheRequest = function(/*CFURL|String*/ aURL, /*Number*/ status, /*Object*/ headers, /*String*/ body)
{
URLCache[aURL] = new MockXMLHttpRequest(status, headers, body);
}
CFHTTPRequest._lookupCachedRequest = function(/*CFURL|String*/ aURL)
{
return URLCache[aURL];
}
function MockXMLHttpRequest(status, headers, body)
{
this.readyState = CFHTTPRequest.UninitializedState;
this.status = status || 200;
this.statusText = "";
this.responseText = body || "";
this._responseHeaders = headers || {};
};
MockXMLHttpRequest.prototype.open = function(method, url, async, user, password)
{
this.readyState = CFHTTPRequest.LoadingState;
this.async = async;
};
MockXMLHttpRequest.prototype.send = function(body)
{
var self = this;
self.responseText = self.responseText.toString();
function complete() {
for (self.readyState = CFHTTPRequest.LoadedState; self.readyState <= CFHTTPRequest.CompleteState; self.readyState++)
self.onreadystatechange();
}
(self.async ? ObjectiveJ.Asynchronous(complete) : complete)();
};
MockXMLHttpRequest.prototype.onreadystatechange = function() {};
MockXMLHttpRequest.prototype.abort = function() {};
MockXMLHttpRequest.prototype.setRequestHeader = function(header, value) {};
MockXMLHttpRequest.prototype.getAllResponseHeaders = function() { return this._responseHeaders; };
MockXMLHttpRequest.prototype.getResponseHeader = function(header) { return this._responseHeaders[header]; };
MockXMLHttpRequest.prototype.overrideMimeType = function(mimetype) {};
-1
View File
@@ -4,7 +4,6 @@
"description": "Cappuccino module", "description": "Cappuccino module",
"keywords": ["objective-j", "objj", "objective j", "capp", "cappuccino"], "keywords": ["objective-j", "objj", "objective j", "capp", "cappuccino"],
"author": "280 North, Inc. (http://280north.com/)", "author": "280 North, Inc. (http://280north.com/)",
"version": "0.8.0",
"objj-frameworks": ["Frameworks"], "objj-frameworks": ["Frameworks"],
"objj-debug-frameworks": ["Frameworks/Debug"], "objj-debug-frameworks": ["Frameworks/Debug"],
"contributors": [ "contributors": [
+91 -71
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); }];
} }
/*! /*!
@@ -454,10 +442,23 @@
*/ */
- (unsigned)indexOfObject:(id)anObject sortedByFunction:(Function)aFunction context:(id)aContext - (unsigned)indexOfObject:(id)anObject sortedByFunction:(Function)aFunction context:(id)aContext
{ {
if (!aFunction || anObject === undefined) var result = [self _indexOfObject:anObject sortedByFunction:aFunction context:aContext];
return result >= 0 ? result : CPNotFound;
}
- (unsigned)_indexOfObject:(id)anObject sortedByFunction:(Function)aFunction context:(id)aContext
{
if (!aFunction)
return CPNotFound; return CPNotFound;
var mid, c, first = 0, last = length - 1; if (length === 0)
return -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);
@@ -476,7 +477,7 @@
} }
} }
return CPNotFound; return -first - 1;
} }
/*! /*!
@@ -496,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;
@@ -510,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];
} }
@@ -537,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;
@@ -577,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);
} }
@@ -595,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);
} }
@@ -608,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);
@@ -630,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;
@@ -645,13 +647,13 @@
if (self === anArray) if (self === anArray)
return YES; return YES;
if(length != anArray.length) if (anArray === nil || length !== anArray.length)
return NO; return NO;
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];
@@ -669,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];
@@ -684,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;
@@ -711,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;
@@ -811,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';
@@ -844,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]);
@@ -862,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];
} }
@@ -877,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;
@@ -957,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,
@@ -972,6 +969,28 @@
[self insertObject:objects[index] atIndex:currentIndex]; [self insertObject:objects[index] atIndex:currentIndex];
} }
- (unsigned)insertObject:(id)anObject inArraySortedByDescriptors:(CPArray)descriptors
{
var index = [self _indexOfObject:anObject sortedByFunction:function(lhs, rhs)
{
var i = 0,
count = [descriptors count],
result = CPOrderedSame;
while (i < count)
if ((result = [descriptors[i++] compareObject:lhs withObject:rhs]) != CPOrderedSame)
return result;
return result;
} context:nil];
if (index < 0)
index = -index - 1;
[self insertObject:anObject atIndex:index];
return index;
}
/*! /*!
Replaces the element at \c anIndex with \c anObject. Replaces the element at \c anIndex with \c anObject.
The current element at position \c anIndex will be removed from the array. The current element at position \c anIndex will be removed from the array.
@@ -993,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];
@@ -1034,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));
} }
@@ -1177,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;
+11
View File
@@ -154,6 +154,12 @@
var value = object[key]; var value = object[key];
if (value === null)
{
[dictionary setObject:[CPNull null] forKey:key];
continue;
}
if (recursively) if (recursively)
{ {
if (value.constructor === Object) if (value.constructor === Object)
@@ -521,6 +527,11 @@
return self.toString(); return self.toString();
} }
- (BOOL)containsKey:(id)aKey
{
var value = [self objectForKey:aKey];
return ((value !== nil) && (value !== undefined));
}
@end @end
@implementation CPDictionary (CPCoding) @implementation CPDictionary (CPCoding)
+3
View File
@@ -739,7 +739,10 @@
shifts = []; shifts = [];
for (; j < count; ++j) for (; j < count; ++j)
{
[shifts addObject:_ranges[j]]; [shifts addObject:_ranges[j]];
_count -= _ranges[j].length;
}
if ((j = i + 1) < count) if ((j = i + 1) < count)
{ {
+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];
} }
} }
+9
View File
@@ -277,5 +277,14 @@ CPUnknownUserInfoKey = @"CPUnknownUserInfoKey";
@end @end
@implementation CPNull (KeyValueCoding)
- (id)valueForKey:(CPString)aKey
{
return self;
}
@end
@import "CPKeyValueObserving.j" @import "CPKeyValueObserving.j"
@import "CPArray+KVO.j" @import "CPArray+KVO.j"
+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;
+11 -5
View File
@@ -163,9 +163,15 @@ var CPArrayClass = Ni
@param data the data from which to read the graph @param data the data from which to read the graph
@return the unarchived object @return the unarchived object
*/ */
+ (id)unarchiveObjectWithData:(CPData)data + (id)unarchiveObjectWithData:(CPData)aData
{ {
var unarchiver = [[self alloc] initForReadingWithData:data], if (!aData)
{
CPLog.error("Null data passed to -[CPKeyedUnarchiver unarchiveObjectWithData:].");
return nil;
}
var unarchiver = [[self alloc] initForReadingWithData:aData],
object = [unarchiver decodeObjectForKey:@"root"]; object = [unarchiver decodeObjectForKey:@"root"];
[unarchiver finishDecoding]; [unarchiver finishDecoding];
@@ -200,7 +206,7 @@ var CPArrayClass = Ni
- (CPDictionary)_decodeDictionaryOfObjectsForKey:(CPString)aKey - (CPDictionary)_decodeDictionaryOfObjectsForKey:(CPString)aKey
{ {
var object = _plistObject.valueForKey(aKey), var object = _plistObject.valueForKey(aKey),
objectClass = object && object.isa; objectClass = (object != nil) && object.isa;
if (objectClass === CPDictionaryClass || objectClass === CPMutableDictionaryClass) if (objectClass === CPDictionaryClass || objectClass === CPMutableDictionaryClass)
{ {
@@ -315,7 +321,7 @@ var CPArrayClass = Ni
- (id)decodeObjectForKey:(CPString)aKey - (id)decodeObjectForKey:(CPString)aKey
{ {
var object = _plistObject.valueForKey(aKey), var object = _plistObject.valueForKey(aKey),
objectClass = object && object.isa; objectClass = (object != nil) && object.isa;
if (objectClass === CPDictionaryClass || objectClass === CPMutableDictionaryClass) if (objectClass === CPDictionaryClass || objectClass === CPMutableDictionaryClass)
return _CPKeyedUnarchiverDecodeObjectAtIndex(self, object.valueForKey(_CPKeyedArchiverUIDKey)); return _CPKeyedUnarchiverDecodeObjectAtIndex(self, object.valueForKey(_CPKeyedArchiverUIDKey));
@@ -519,7 +525,7 @@ var _CPKeyedUnarchiverDecodeObjectAtIndex = function(self, anIndex)
// If this object is a member of _CPKeyedArchiverValue, then we know // If this object is a member of _CPKeyedArchiverValue, then we know
// that it is a wrapper for a primitive JavaScript object. // that it is a wrapper for a primitive JavaScript object.
if (object && (object.isa === _CPKeyedArchiverValueClass)) if ((object != nil) && (object.isa === _CPKeyedArchiverValueClass))
object = [object JSObject]; object = [object JSObject];
return object; return object;
+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
+1 -1
View File
@@ -61,7 +61,7 @@
- (void)forwardInvocation:(CPInvocation)anInvocation - (void)forwardInvocation:(CPInvocation)anInvocation
{ {
[CPException raise:CPInvalidArgumentException [CPException raise:CPInvalidArgumentException
reason:@"-methodSignatureForSelector: called on abstract CPProxy class."]; reason:@"-forwardInvocation: called on abstract CPProxy class."];
} }
// FIXME: This should be moved to the runtime? // FIXME: This should be moved to the runtime?
+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)
+18
View File
@@ -664,6 +664,9 @@ var CPStringRegexSpecialCharacters = [
*/ */
- (CPString)pathExtension - (CPString)pathExtension
{ {
if (lastIndexOf('.') === CPNotFound)
return "";
return substr(lastIndexOf('.') + 1); return substr(lastIndexOf('.') + 1);
} }
@@ -699,6 +702,21 @@ var CPStringRegexSpecialCharacters = [
return path; return path;
} }
/*!
Deletes the extension of a string.
*/
- (CPString)stringByDeletingPathExtension
{
var extension = [self pathExtension];
if (extension === "")
return self;
if (lastIndexOf('.') < 1)
return self;
return substr(0, [self length] - (extension.length + 1));
}
- (CPString)stringByStandardizingPath - (CPString)stringByStandardizingPath
{ {
return objj_standardize_path(self); return objj_standardize_path(self);
+2 -2
View File
@@ -196,8 +196,8 @@ var CPURLURLStringKey = @"CPURLURLStringKey",
- (id)initWithCoder:(CPCoder)aCoder - (id)initWithCoder:(CPCoder)aCoder
{ {
return [self initWithURLString:[aCoder decodeObjectForKey:CPURLURLStringKey] return [self initWithString:[aCoder decodeObjectForKey:CPURLURLStringKey]
baseURL:[aCoder decodeObjectForKey:CPURLBaseURLKey]]; relativeToURL:[aCoder decodeObjectForKey:CPURLBaseURLKey]];
} }
- (void)encodeWithCoder:(CPCoder)aCoder - (void)encodeWithCoder:(CPCoder)aCoder
+1 -1
View File
@@ -34,7 +34,7 @@ foundationTask = framework ("Foundation", function(foundationTask)
foundationTask.setEmail("feedback @nospam@ 280north.com"); foundationTask.setEmail("feedback @nospam@ 280north.com");
foundationTask.setSummary("Foundation classes for Cappuccino"); foundationTask.setSummary("Foundation classes for Cappuccino");
foundationTask.setIdentifier("com.280n.Foundation"); foundationTask.setIdentifier("com.280n.Foundation");
foundationTask.setVersion("0.8.0"); foundationTask.setVersion(getCappuccinoVersion());
foundationTask.setLicense(BundleTask.License.LGPL_v2_1); foundationTask.setLicense(BundleTask.License.LGPL_v2_1);
foundationTask.setSources(new FileList("**/*.j")); foundationTask.setSources(new FileList("**/*.j"));
foundationTask.setResources(new FileList("Resources/**/*")); foundationTask.setResources(new FileList("Resources/**/*"));
+49 -53
View File
@@ -107,14 +107,16 @@ task ("documentation", function()
// Downloads // Downloads
task ("downloads", ["starter_download", "tools_download"]); task ("downloads", ["starter_download"]);
$STARTER_README = FILE.join('Tools', 'READMEs', 'STARTER-README'); $STARTER_README = FILE.join('Tools', 'READMEs', 'STARTER-README');
$STARTER_BOOTSTRAP = 'bootstrap.sh';
$STARTER_DOWNLOAD = FILE.join($BUILD_DIR, 'Cappuccino', 'Starter'); $STARTER_DOWNLOAD = FILE.join($BUILD_DIR, 'Cappuccino', 'Starter');
$STARTER_DOWNLOAD_APPLICATION = FILE.join($STARTER_DOWNLOAD, 'NewApplication'); $STARTER_DOWNLOAD_APPLICATION = FILE.join($STARTER_DOWNLOAD, 'NewApplication');
$STARTER_DOWNLOAD_README = FILE.join($STARTER_DOWNLOAD, 'README'); $STARTER_DOWNLOAD_README = FILE.join($STARTER_DOWNLOAD, 'README');
$STARTER_DOWNLOAD_BOOTSTRAP = FILE.join($STARTER_DOWNLOAD, 'bootstrap.sh');
task ("starter_download", [$STARTER_DOWNLOAD_APPLICATION, $STARTER_DOWNLOAD_README, "documentation"], function() task ("starter_download", [$STARTER_DOWNLOAD_APPLICATION, $STARTER_DOWNLOAD_README, $STARTER_DOWNLOAD_BOOTSTRAP, "documentation"], function()
{ {
if (FILE.exists($DOCUMENTATION_BUILD)) if (FILE.exists($DOCUMENTATION_BUILD))
{ {
@@ -130,8 +132,8 @@ filedir ($STARTER_DOWNLOAD_APPLICATION, ["CommonJS"], function()
if (OS.system(["capp", "gen", $STARTER_DOWNLOAD_APPLICATION, "-t", "Application", "--noconfig"])) if (OS.system(["capp", "gen", $STARTER_DOWNLOAD_APPLICATION, "-t", "Application", "--noconfig"]))
// FIXME: uncomment this: we get conversion errors // FIXME: uncomment this: we get conversion errors
//OS.exit(1); // rake abort if ($? != 0) OS.exit(1); // rake abort if ($? != 0)
{} //{}
// No tools means no objective-j gem // No tools means no objective-j gem
// FILE.rm(FILE.join($STARTER_DOWNLOAD_APPLICATION, 'Rakefile')) // FILE.rm(FILE.join($STARTER_DOWNLOAD_APPLICATION, 'Rakefile'))
}); });
@@ -141,36 +143,11 @@ filedir ($STARTER_DOWNLOAD_README, [$STARTER_README], function()
cp($STARTER_README, $STARTER_DOWNLOAD_README); cp($STARTER_README, $STARTER_DOWNLOAD_README);
}); });
$TOOLS_README = FILE.join('Tools', 'READMEs', 'TOOLS-README'); filedir ($STARTER_DOWNLOAD_BOOTSTRAP, [$STARTER_BOOTSTRAP], function()
$TOOLS_EDITORS = FILE.join('Tools', 'Editors');
$TOOLS_INSTALLER = FILE.join('Tools', 'Install', 'install-tools');
$TOOLS_DOWNLOAD = FILE.join($BUILD_DIR, 'Cappuccino', 'Tools');
$TOOLS_DOWNLOAD_EDITORS = FILE.join($TOOLS_DOWNLOAD, 'Editors');
$TOOLS_DOWNLOAD_README = FILE.join($TOOLS_DOWNLOAD, 'README');
$TOOLS_DOWNLOAD_INSTALLER = FILE.join($TOOLS_DOWNLOAD, 'install-tools');
$TOOLS_DOWNLOAD_COMMONJS = FILE.join($BUILD_DIR, "Cappuccino", "Tools", "CommonJS", "objective-j");
task ("tools_download", [$TOOLS_DOWNLOAD_EDITORS, $TOOLS_DOWNLOAD_README, $TOOLS_DOWNLOAD_INSTALLER, $TOOLS_DOWNLOAD_COMMONJS]);
filedir ($TOOLS_DOWNLOAD_EDITORS, [$TOOLS_EDITORS], function()
{ {
cp_r(FILE.join($TOOLS_EDITORS, '.'), $TOOLS_DOWNLOAD_EDITORS); var bootstrap = FILE.read($STARTER_BOOTSTRAP, { charset : "UTF-8" }).replace('install_capp=""', 'install_capp="yes"');
}); FILE.write($STARTER_DOWNLOAD_BOOTSTRAP, bootstrap, { charset : "UTF-8" });
OS.system(["chmod", "+x", $STARTER_DOWNLOAD_BOOTSTRAP]);
filedir ($TOOLS_DOWNLOAD_README, [$TOOLS_README], function()
{
cp($TOOLS_README, $TOOLS_DOWNLOAD_README);
});
filedir ($TOOLS_DOWNLOAD_INSTALLER, [$TOOLS_INSTALLER], function()
{
cp($TOOLS_INSTALLER, $TOOLS_DOWNLOAD_INSTALLER);
});
filedir ($TOOLS_DOWNLOAD_COMMONJS, ["CommonJS"], function()
{
rm_rf($TOOLS_DOWNLOAD_COMMONJS);
cp_r($COMMONJS_PRODUCT, $TOOLS_DOWNLOAD_COMMONJS);
}); });
// Deployment // Deployment
@@ -240,14 +217,21 @@ task ("demos", function()
return !demo.excluded(); return !demo.excluded();
}).forEach(function(demo) }).forEach(function(demo)
{ {
var outputPath = FILE.join(demosDir, demo.name().replace(/\s/g, "-")+".zip"); // copy frameworks into the demos
OS.system("cd "+OS.enquote(FILE.dirname(demo.path()))+"; zip -ry -8 "+OS.enquote(outputPath)+" "+OS.enquote(demo.path())); cp_r(FILE.join($STARTER_DOWNLOAD_APPLICATION, "Frameworks"), FILE.join(demo.path(), "Frameworks"));
rm_rf(FILE.join(demo.path(), "Frameworks", "Debug"));
var outputPath = demo.name().replace(/\s/g, "-")+".zip";
OS.system("cd "+OS.enquote(FILE.dirname(demo.path()))+" && zip -ry -8 "+OS.enquote(outputPath)+" "+OS.enquote(FILE.basename(demo.path())));
// remove the frameworks
rm_rf(FILE.join(demo.path(), "Frameworks"));
}); });
}); });
// Testing // Testing
task("test", ["build", "test-only"]); task("test", ["CommonJS", "test-only"]);
task("test-only", function() task("test-only", function()
{ {
@@ -281,20 +265,22 @@ function pushPackage(path, remote, branch)
{ {
branch = branch || "master"; branch = branch || "master";
var pushPackagesPath = FILE.path(".push-package");
pushPackagesPath.mkdirs();
var packagePath = pushPackagesPath.join(remote.replace(/[^\w]/g, "_"));
stream.print("Pushing \0blue(" + path + "\0) to "+branch+" of \0blue(" + remote + "\0)"); stream.print("Pushing \0blue(" + path + "\0) to "+branch+" of \0blue(" + remote + "\0)");
FILE.mkdirs(".push-package"); if (packagePath.isDirectory())
OS.system(buildCmd([["cd", packagePath], ["git", "fetch"]]));
var pushPackageDir = FILE.join(".push-package", remote.replace(/[^\w]/g, "_"));
if (FILE.exists(pushPackageDir))
OS.system(buildCmd([["cd", pushPackageDir], ["git", "fetch"]]));
else else
OS.system(["git", "clone", remote, pushPackageDir]); OS.system(["git", "clone", remote, packagePath]);
if (OS.system(buildCmd([["cd", pushPackageDir], ["git", "checkout", "origin/"+branch]]))) { if (OS.system(buildCmd([["cd", packagePath], ["git", "checkout", "origin/"+branch]]))) {
if (OS.system(buildCmd([ if (OS.system(buildCmd([
["cd", pushPackageDir], ["cd", packagePath],
["git", "symbolic-ref", "HEAD", "refs/heads/"+branch], ["git", "symbolic-ref", "HEAD", "refs/heads/"+branch],
["rm", ".git/index"], ["rm", ".git/index"],
["git", "clean", "-fdx"] ["git", "clean", "-fdx"]
@@ -302,20 +288,30 @@ function pushPackage(path, remote, branch)
throw "pushPackage failed"; throw "pushPackage failed";
} }
if (OS.system("cd "+OS.enquote(pushPackageDir)+" && git rm --ignore-unmatch -r * && rm -rf *")) if (OS.system("cd "+OS.enquote(packagePath)+" && git rm --ignore-unmatch -r * && rm -rf *"))
throw "pushPackage failed"; throw "pushPackage failed";
if (OS.system("cp -R "+OS.enquote(path)+"/* "+OS.enquote(pushPackageDir)+"/.")) if (OS.system("cp -R "+OS.enquote(path)+"/* "+OS.enquote(packagePath)+"/."))
throw "pushPackage failed"; throw "pushPackage failed";
OS.system(buildCmd([ var pkg = JSON.parse(packagePath.join("package.json").read({ charset : "UTF-8" }));
["cd", pushPackageDir],
stream.print(" Version: \0purple(" + pkg["version"] + "\0)");
stream.print(" Revision: \0purple(" + pkg["cappuccino-revision"] + "\0)");
stream.print(" Timestamp: \0purple(" + pkg["cappuccino-timestamp"] + "\0)");
var cmd = [
["cd", packagePath],
["git", "add", "."], ["git", "add", "."],
["git", "commit", "-m", "Pushed on " + new Date()] ["git", "commit", "-m", "version="+pkg.version+"; revision="+pkg["cappuccino-revision"]+"; timestamp="+pkg["cappuccino-timestamp"]+";"]
])); ];
if (pkg["cappuccino-revision"])
cmd.push(["git", "tag", "rev-"+pkg["cappuccino-revision"].slice(0,6)]);
OS.system(buildCmd(cmd));
if (OS.system(buildCmd([ if (OS.system(buildCmd([
["cd", pushPackageDir], ["cd", packagePath],
["git", "push", "origin", "HEAD:"+branch] ["git", "push", "--tags", "origin", "HEAD:"+branch]
]))) ])))
throw "pushPackage failed"; throw "pushPackage failed";
} }
+30 -1
View File
@@ -81,7 +81,36 @@ function resolveMainBundleURL()
Executable.fileImporterForURL(mainBundleURL)(mainFileURL.lastPathComponent(), YES, function() Executable.fileImporterForURL(mainBundleURL)(mainFileURL.lastPathComponent(), YES, function()
{ {
disableCFURLCaching(); disableCFURLCaching();
afterDocumentLoad(main); afterDocumentLoad(function()
{
var hashString = window.location.hash.substring(1),
args = [];
if (hashString.length)
{
args = hashString.split("/");
for (var i = 0, count = args.length; i < count; i++)
args[i] = decodeURIComponent(args[i]);
}
var namedArgsArray = window.location.search.substring(1).split("&"),
namedArgs = new CFMutableDictionary();
for (var i = 0, count = namedArgsArray.length; i < count; i++)
{
var thisArg = namedArgsArray[i].split("=");
if (!thisArg[0])
continue;
if (thisArg[1] == null)
thisArg[1] = true;
namedArgs.setValueForKey(decodeURIComponent(thisArg[0]), decodeURIComponent(thisArg[1]));
}
main(args, namedArgs);
});
}); });
}); });
} }
+60 -6
View File
@@ -49,6 +49,7 @@ GLOBAL(CFBundle) = function(/*CFURL|String*/ aURL)
this._resourcesDirectoryURL = new CFURL("Resources/", aURL); this._resourcesDirectoryURL = new CFURL("Resources/", aURL);
this._staticResource = NULL; this._staticResource = NULL;
this._isValid = NO;
this._loadStatus = CFBundleUnloaded; this._loadStatus = CFBundleUnloaded;
this._loadRequests = []; this._loadRequests = [];
@@ -58,34 +59,47 @@ GLOBAL(CFBundle) = function(/*CFURL|String*/ aURL)
this._eventDispatcher = new EventDispatcher(this); this._eventDispatcher = new EventDispatcher(this);
} }
DISPLAY_NAME(CFBundle);
CFBundle.environments = function() CFBundle.environments = function()
{ {
// Passed in by GCC. // Passed in by GCC.
return ENVIRONMENTS; return ENVIRONMENTS;
} }
DISPLAY_NAME(CFBundle.environments);
CFBundle.bundleContainingURL = function(/*CFURL|String*/ aURL) CFBundle.bundleContainingURL = function(/*CFURL|String*/ aURL)
{ {
aURL = new CFURL(".", makeAbsoluteURL(aURL)); aURL = new CFURL(".", makeAbsoluteURL(aURL));
while (aURL.path() !== "/") var previousURLString,
{ URLString = aURL.absoluteString();
var bundle = CFBundlesForURLStrings[aURL.absoluteString()];
if (bundle) while (!previousURLString || previousURLString !== URLString)
{
var bundle = CFBundlesForURLStrings[URLString];
if (bundle && bundle._isValid)
return bundle; return bundle;
aURL = new CFURL("..", aURL); aURL = new CFURL("..", aURL);
previousURLString = URLString;
URLString = aURL.absoluteString();
} }
return NULL; return NULL;
} }
DISPLAY_NAME(CFBundle.bundleContainingURL);
CFBundle.mainBundle = function() CFBundle.mainBundle = function()
{ {
return new CFBundle(mainBundleURL); return new CFBundle(mainBundleURL);
} }
DISPLAY_NAME(CFBundle.mainBundle);
function addClassToBundle(aClass, aBundle) function addClassToBundle(aClass, aBundle)
{ {
if (aBundle) if (aBundle)
@@ -97,16 +111,22 @@ CFBundle.bundleForClass = function(/*Class*/ aClass)
return CFBundlesForClasses[aClass.name] || CFBundle.mainBundle(); return CFBundlesForClasses[aClass.name] || CFBundle.mainBundle();
} }
DISPLAY_NAME(CFBundle.bundleForClass);
CFBundle.prototype.bundleURL = function() CFBundle.prototype.bundleURL = function()
{ {
return this._bundleURL; return this._bundleURL;
} }
DISPLAY_NAME(CFBundle.prototype.bundleURL);
CFBundle.prototype.resourcesDirectoryURL = function() CFBundle.prototype.resourcesDirectoryURL = function()
{ {
return this._resourcesDirectoryURL; return this._resourcesDirectoryURL;
} }
DISPLAY_NAME(CFBundle.prototype.resourcesDirectoryURL);
CFBundle.prototype.resourceURL = function(/*String*/ aResourceName, /*String*/ aType, /*String*/ aSubDirectory) CFBundle.prototype.resourceURL = function(/*String*/ aResourceName, /*String*/ aType, /*String*/ aSubDirectory)
{ {
if (aType) if (aType)
@@ -120,6 +140,8 @@ CFBundle.prototype.resourceURL = function(/*String*/ aResourceName, /*String*/ a
return resourceURL.absoluteURL(); return resourceURL.absoluteURL();
} }
DISPLAY_NAME(CFBundle.prototype.resourceURL);
CFBundle.prototype.mostEligibleEnvironmentURL = function() CFBundle.prototype.mostEligibleEnvironmentURL = function()
{ {
if (this._mostEligibleEnvironmentURL === undefined) if (this._mostEligibleEnvironmentURL === undefined)
@@ -128,6 +150,8 @@ CFBundle.prototype.mostEligibleEnvironmentURL = function()
return this._mostEligibleEnvironmentURL; return this._mostEligibleEnvironmentURL;
} }
DISPLAY_NAME(CFBundle.prototype.mostEligibleEnvironmentURL);
CFBundle.prototype.executableURL = function() CFBundle.prototype.executableURL = function()
{ {
if (this._executableURL === undefined) if (this._executableURL === undefined)
@@ -143,16 +167,22 @@ CFBundle.prototype.executableURL = function()
return this._executableURL; return this._executableURL;
} }
DISPLAY_NAME(CFBundle.prototype.executableURL);
CFBundle.prototype.infoDictionary = function() CFBundle.prototype.infoDictionary = function()
{ {
return this._infoDictionary; return this._infoDictionary;
} }
DISPLAY_NAME(CFBundle.prototype.infoDictionary);
CFBundle.prototype.valueForInfoDictionaryKey = function(/*String*/ aKey) CFBundle.prototype.valueForInfoDictionaryKey = function(/*String*/ aKey)
{ {
return this._infoDictionary.valueForKey(aKey); return this._infoDictionary.valueForKey(aKey);
} }
DISPLAY_NAME(CFBundle.prototype.valueForInfoDictionaryKey);
CFBundle.prototype.hasSpritedImages = function() CFBundle.prototype.hasSpritedImages = function()
{ {
var environments = this._infoDictionary.valueForKey("CPBundleEnvironmentsWithImageSprites") || [], var environments = this._infoDictionary.valueForKey("CPBundleEnvironmentsWithImageSprites") || [],
@@ -166,11 +196,15 @@ CFBundle.prototype.hasSpritedImages = function()
return NO; return NO;
} }
DISPLAY_NAME(CFBundle.prototype.hasSpritedImages);
CFBundle.prototype.environments = function() CFBundle.prototype.environments = function()
{ {
return this._infoDictionary.valueForKey("CPBundleEnvironments") || ["ObjJ"]; return this._infoDictionary.valueForKey("CPBundleEnvironments") || ["ObjJ"];
} }
DISPLAY_NAME(CFBundle.prototype.environments);
CFBundle.prototype.mostEligibleEnvironment = function(/*Array*/ environments) CFBundle.prototype.mostEligibleEnvironment = function(/*Array*/ environments)
{ {
environments = environments || this.environments(); environments = environments || this.environments();
@@ -194,11 +228,15 @@ CFBundle.prototype.mostEligibleEnvironment = function(/*Array*/ environments)
return NULL; return NULL;
} }
DISPLAY_NAME(CFBundle.prototype.mostEligibleEnvironment);
CFBundle.prototype.isLoading = function() CFBundle.prototype.isLoading = function()
{ {
return this._loadStatus & CFBundleLoading; return this._loadStatus & CFBundleLoading;
} }
DISPLAY_NAME(CFBundle.prototype.isLoading);
CFBundle.prototype.load = function(/*BOOL*/ shouldExecute) CFBundle.prototype.load = function(/*BOOL*/ shouldExecute)
{ {
if (this._loadStatus !== CFBundleUnloaded) if (this._loadStatus !== CFBundleUnloaded)
@@ -223,7 +261,13 @@ CFBundle.prototype.load = function(/*BOOL*/ shouldExecute)
function onsuccess(/*Event*/ anEvent) function onsuccess(/*Event*/ anEvent)
{ {
self._loadStatus &= ~CFBundleLoadingInfoPlist; self._loadStatus &= ~CFBundleLoadingInfoPlist;
self._infoDictionary = anEvent.request.responsePropertyList();
var infoDictionary = anEvent.request.responsePropertyList();
self._isValid = !!infoDictionary || CFBundle.mainBundle() === self;
if (infoDictionary)
self._infoDictionary = infoDictionary;
if (!self._infoDictionary) if (!self._infoDictionary)
{ {
@@ -240,6 +284,7 @@ CFBundle.prototype.load = function(/*BOOL*/ shouldExecute)
function onfailure() function onfailure()
{ {
self._isValid = CFBundle.mainBundle() === self;
self._loadStatus = CFBundleUnloaded; self._loadStatus = CFBundleUnloaded;
finishBundleLoadingWithError(self, new Error("Could not load bundle at \"" + self.bundleURL() + "\"")); finishBundleLoadingWithError(self, new Error("Could not load bundle at \"" + self.bundleURL() + "\""));
@@ -249,6 +294,8 @@ CFBundle.prototype.load = function(/*BOOL*/ shouldExecute)
}); });
} }
DISPLAY_NAME(CFBundle.prototype.load);
function finishBundleLoadingWithError(/*CFBundle*/ aBundle, /*Event*/ anError) function finishBundleLoadingWithError(/*CFBundle*/ aBundle, /*Event*/ anError)
{ {
resolveStaticResource(aBundle._staticResource); resolveStaticResource(aBundle._staticResource);
@@ -390,12 +437,13 @@ function loadSpritedImagesForBundle(/*Bundle*/ aBundle, success, failure)
CFTotalBytesLoaded += anEvent.request.responseText().length; CFTotalBytesLoaded += anEvent.request.responseText().length;
decompileStaticFile(aBundle, anEvent.request.responseText(), spritedImagesURL); decompileStaticFile(aBundle, anEvent.request.responseText(), spritedImagesURL);
aBundle._loadStatus &= ~CFBundleLoadingSpritedImages; aBundle._loadStatus &= ~CFBundleLoadingSpritedImages;
success();
} }
catch(anException) catch(anException)
{ {
failure(anException); failure(anException);
} }
success();
}, failure); }, failure);
} }
@@ -615,16 +663,22 @@ CFBundle.prototype.addEventListener = function(/*String*/ anEventName, /*Functio
this._eventDispatcher.addEventListener(anEventName, anEventListener); this._eventDispatcher.addEventListener(anEventName, anEventListener);
} }
DISPLAY_NAME(CFBundle.prototype.addEventListener);
CFBundle.prototype.removeEventListener = function(/*String*/ anEventName, /*Function*/ anEventListener) CFBundle.prototype.removeEventListener = function(/*String*/ anEventName, /*Function*/ anEventListener)
{ {
this._eventDispatcher.removeEventListener(anEventName, anEventListener); this._eventDispatcher.removeEventListener(anEventName, anEventListener);
} }
DISPLAY_NAME(CFBundle.prototype.removeEventListener);
CFBundle.prototype.onerror = function(/*Event*/ anEvent) CFBundle.prototype.onerror = function(/*Event*/ anEvent)
{ {
throw anEvent.error; throw anEvent.error;
} }
DISPLAY_NAME(CFBundle.prototype.onerror);
CFBundle.prototype.bundlePath = function() CFBundle.prototype.bundlePath = function()
{ {
return this._bundleURL.absoluteURL().path(); return this._bundleURL.absoluteURL().path();
+68 -44
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,7 +188,7 @@ CFHTTPRequest.prototype.responseText = function()
CFHTTPRequest.prototype.setRequestHeader = function(/*String*/ aHeader, /*Object*/ aValue) CFHTTPRequest.prototype.setRequestHeader = function(/*String*/ aHeader, /*Object*/ aValue)
{ {
return this._nativeRequest.setRequestHeader(aHeader, aValue); this._requestHeaders[aHeader] = aValue;
} }
CFHTTPRequest.prototype.getResponseHeader = function(/*String*/ aHeader) CFHTTPRequest.prototype.getResponseHeader = function(/*String*/ aHeader)
@@ -192,17 +203,40 @@ 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(/*...*/) CFHTTPRequest.prototype.open = function(/*String*/ aMethod, /*String*/ aURL, /*Boolean*/ isAsynchronous, /*String*/ aUser, /*String*/ aPassword)
{ {
return this._nativeRequest.open(arguments[0], arguments[1], arguments[2], arguments[3], arguments[4]); this._isOpen = true;
this._URL = aURL;
this._async = isAsynchronous;
this._method = aMethod;
this._user = aUser;
this._password = aPassword;
return this._nativeRequest.open(aMethod, aURL, isAsynchronous, aUser, aPassword);
} }
CFHTTPRequest.prototype.send = function(/*Object*/ aBody) CFHTTPRequest.prototype.send = function(/*Object*/ aBody)
{ {
for (var i in this._requestHeaders)
{
if (this._requestHeaders.hasOwnProperty(i))
this._nativeRequest.setRequestHeader(i, this._requestHeaders[i]);
}
if (!this._isOpen)
{
delete this._nativeRequest.onreadystatechange;
this._nativeRequest.open(this._method, this._URL, this._async, this._user, this._password);
this._nativeRequest.onreadystatechange = this._stateChangeHandler;
}
if (this._mimeType && "overrideMimeType" in this._nativeRequest)
this._nativeRequest.overrideMimeType(this._mimeType);
this._isOpen = false;
try try
{ {
return this._nativeRequest.send(aBody); return this._nativeRequest.send(aBody);
@@ -216,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();
} }
@@ -236,61 +271,50 @@ 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)
{ {
#ifdef BROWSER
var request = new CFHTTPRequest(); var request = new CFHTTPRequest();
request.onsuccess = Asynchronous(onsuccess);
request.onfailure = Asynchronous(onfailure);
if (aURL.pathExtension() === "plist") if (aURL.pathExtension() === "plist")
request.overrideMimeType("text/xml"); request.overrideMimeType("text/xml");
request.open("GET", aURL.absoluteString(), YES); if (exports.asyncLoader)
{
request.onsuccess = Asynchronous(onsuccess);
request.onfailure = Asynchronous(onfailure);
}
else
{
request.onsuccess = onsuccess;
request.onfailure = onfailure;
}
request.open("GET", aURL.absoluteString(), exports.asyncLoader);
request.send(""); request.send("");
}
#ifdef BROWSER
exports.asyncLoader = YES;
#else #else
var FILE = require("file"), exports.asyncLoader = NO;
filePath = aURL.absoluteURL().path();
if (!FILE.exists(filePath))
return onfailure();
this._responseText = FILE.read(filePath, { charset:"UTF-8" });
onsuccess({ type:"success", request:this });
#endif #endif
}
#ifdef COMMONJS // FIXME: Get rid of these when we no longer need Mock requests in flatten.
FileRequest.prototype.responseText = function() exports.Asynchronous = Asynchronous;
{ exports.determineAndDispatchHTTPRequestEvents = determineAndDispatchHTTPRequestEvents;
return this._responseText;
}
FileRequest.prototype.responseXML = function()
{
return new DOMParser().parseFromString(anXMLString, "text/xml");
}
FileRequest.prototype.responsePropertyList = function()
{
return CFPropertyList.propertyListFromString(this.responseText());
}
#endif
+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)
+25 -7
View File
@@ -314,7 +314,7 @@ function resolveURL(aURL)
resolvedPathComponents.splice(basePathComponents.length - 1, 1); resolvedPathComponents.splice(basePathComponents.length - 1, 1);
// If this doesn't start with a "..", then we're simply appending to already standardized paths. // If this doesn't start with a "..", then we're simply appending to already standardized paths.
if (pathComponents.length && pathComponents[0] === "..") if (pathComponents.length && (pathComponents[0] === ".." || pathComponents[0] === "."))
standardizePathComponents(resolvedPathComponents, YES); standardizePathComponents(resolvedPathComponents, YES);
resolvedParts.pathComponents = resolvedPathComponents; resolvedParts.pathComponents = resolvedPathComponents;
@@ -352,19 +352,26 @@ function standardizePathComponents(/*Array*/ pathComponents, /*BOOL*/ inPlace)
var index = 0, var index = 0,
resultIndex = 0, resultIndex = 0,
count = pathComponents.length, count = pathComponents.length,
result = inPlace ? pathComponents : []; result = inPlace ? pathComponents : [],
startsWithPeriod = NO;
for (; index < count; ++index) for (; index < count; ++index)
{ {
var component = pathComponents[index]; var component = pathComponents[index];
if (component === "" || component === ".") if (component === "")
continue; continue;
if (component === ".")
{
startsWithPeriod = resultIndex === 0;
continue;
}
if (component !== ".." || resultIndex === 0 || result[resultIndex - 1] === "..") if (component !== ".." || resultIndex === 0 || result[resultIndex - 1] === "..")
{ {
//if (resultIndex !== index) result[resultIndex] = component;
result[resultIndex] = component;
resultIndex++; resultIndex++;
@@ -375,6 +382,9 @@ function standardizePathComponents(/*Array*/ pathComponents, /*BOOL*/ inPlace)
--resultIndex; --resultIndex;
} }
if (startsWithPeriod && resultIndex === 0)
result[resultIndex++] = ".";
result.length = resultIndex; result.length = resultIndex;
return result; return result;
@@ -505,10 +515,11 @@ CFURL.prototype.hasDirectoryPath = function()
var lastPathComponent = this.lastPathComponent(); var lastPathComponent = this.lastPathComponent();
hasDirectoryPath = lastPathComponent === "." || lastPathComponent === ".."; hasDirectoryPath = lastPathComponent === "." || lastPathComponent === "..";
this._hasDirectoryPath = hasDirectoryPath; this._hasDirectoryPath = hasDirectoryPath;
} }
return this._hasDirectoryPath; return hasDirectoryPath;
} }
DISPLAY_NAME(CFURL.prototype.hasDirectoryPath); DISPLAY_NAME(CFURL.prototype.hasDirectoryPath);
@@ -646,7 +657,14 @@ CFURL.prototype.asDirectoryPathURL = function()
if (this.hasDirectoryPath()) if (this.hasDirectoryPath())
return this; return this;
return new CFURL(this.lastPathComponent() + "/", this); var lastPathComponent = this.lastPathComponent();
// We do this because on Windows the path may start with C: and be
// misinterpreted as a scheme.
if (lastPathComponent !== "/")
lastPathComponent = "./" + lastPathComponent;
return new CFURL(lastPathComponent + "/", this);
} }
DISPLAY_NAME(CFURL.prototype.asDirectoryPathURL); DISPLAY_NAME(CFURL.prototype.asDirectoryPathURL);
+7
View File
@@ -357,3 +357,10 @@ function _CPLogInitPopup(logWindow)
}, false); }, false);
} }
#endif #endif
#if COMMONJS
CPLogDefault = CPLogPrint;
#else
CPLogDefault = (typeof window === "object" && window.console) ? CPLogConsole : CPLogPopup;
#endif
+36 -26
View File
@@ -1,5 +1,7 @@
var FILE = require("file"); var FILE = require("file");
var sprintf = require("printf").sprintf;
var window = exports.window = require("browser/window"); var window = exports.window = require("browser/window");
if (system.engine === "rhino") if (system.engine === "rhino")
@@ -77,6 +79,12 @@ exports.run = function(args)
// copy the args since we're going to modify them // copy the args since we're going to modify them
var argv = args.slice(1); var argv = args.slice(1);
if (argv[0] === "--version")
{
print(exports.fullVersionString());
return;
}
while (argv.length && argv[0].indexOf('-I') === 0) while (argv.length && argv[0].indexOf('-I') === 0)
OBJJ_INCLUDE_PATHS.unshift.apply(OBJJ_INCLUDE_PATHS, argv.shift().substr(2).split(':')); OBJJ_INCLUDE_PATHS.unshift.apply(OBJJ_INCLUDE_PATHS, argv.shift().substr(2).split(':'));
} }
@@ -140,37 +148,12 @@ exports.repl = function()
} }
} }
exports.objj_eval = function(/*String*/ aString)
{
// We need this while code still refers to window.
Executable.setCommonJSArguments(require, exports, module, system, print, window);
var executable = exports.preprocess(aString, "", 0);
if (!executable.hasLoadedFileDependencies())
executable.loadFileDependencies();
// A bit of a hack. Executable compiles the code itself into a function, but we want
// the raw code to eval here.
var code = executable._code;
// Not clear why these should be global, varing them doesn't seem to take effect with evaluateString.
global.objj_executeFile = Executable.fileExecuterForURL(FILE.cwd());
global.objj_importFile = Executable.fileImporterForURL(FILE.cwd());
if (typeof system !== "undefined" && system.engine === "rhino")
return Packages.org.mozilla.javascript.Context.getCurrentContext().evaluateString(global, code, "objj_eval", 0, NULL);
return eval(code);
}
Executable.setCommonJSParameters("require", "exports", "module", "system", "print", "window");
// creates a narwhal factory function in the objj module scope // creates a narwhal factory function in the objj module scope
exports.make_narwhal_factory = function(path) exports.make_narwhal_factory = function(path)
{ {
return function(require, exports, module, system, print) return function(require, exports, module, system, print)
{ {
Executable.setCommonJSParameters("require", "exports", "module", "system", "print", "window");
Executable.setCommonJSArguments(require, exports, module, system, print, window); Executable.setCommonJSArguments(require, exports, module, system, print, window);
Executable.fileImporterForURL(FILE.dirname(path))(path, YES); Executable.fileImporterForURL(FILE.dirname(path))(path, YES);
} }
@@ -178,5 +161,32 @@ exports.make_narwhal_factory = function(path)
} // end "with" } // end "with"
var pkg = null;
function getPackage() {
if (!pkg)
pkg = JSON.parse(FILE.path(module.path).dirname().dirname().join("package.json").read({ charset : "UTF-8" }));
return pkg;
}
exports.version = function() { return getPackage()["version"]; }
exports.revision = function() { return getPackage()["cappuccino-revision"]; }
exports.timestamp = function() { return new Date(getPackage()["cappuccino-timestamp"]); }
exports.fullVersionString = function() {
return sprintf("objective-j %s (%04d-%02d-%02d %s)",
exports.version(),
exports.timestamp().getUTCFullYear(),
exports.timestamp().getUTCMonth()+1,
exports.timestamp().getUTCDate(),
exports.revision().slice(0,6)
);
}
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);

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