Compare commits

...
1143 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
Francisco Ryan Tolmasky I 3fc99095e2 Fix bug in keyed unarchiving.
Reviewed by me.
2010-03-07 23:48:23 -08:00
Randall Luecke 8410198c37 Merge branch 'master' of git://github.com/280north/cappuccino 2010-03-08 00:58:28 -05:00
Francisco Ryan Tolmasky I d1b325052d Fixed incorrect import.
Reviewed by me.
2010-03-07 21:56:29 -08: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
Tom Robinson 91dda1f759 Remove warning from press. 2010-03-07 18:24:45 -08:00
Tom Robinson 65e12269d1 Fix flatten 2010-03-07 18:24:45 -08:00
Francisco Ryan Tolmasky I 9d2474b142 Merge branch 'master' of git@github.com:280north/cappuccino 2010-03-07 17:57:36 -08:00
Ross Boucher e804d44934 Slight error in my sprintf change. Fixed here. 2010-03-07 17:54:57 -08:00
Francisco Ryan Tolmasky I 961628d8d3 Fix for count global and also cleaned up display names in CFDictionary.
Reviewed by me.
2010-03-07 17:53:44 -08:00
Randall Luecke 7522751fd2 Merge branch 'master' of git://github.com/280north/cappuccino 2010-03-07 20:50:29 -05:00
Ross Boucher e3dc9fd96b Make sprintf no longer global, instead ObjectiveJ.sprintf. 2010-03-07 17:41:33 -08:00
Ross Boucher c3ac076d13 Remove base64 globals, move to CFData. Update tests. 2010-03-07 17:22:29 -08:00
Francisco Ryan Tolmasky I 1e02511022 Merge branch 'master' of git@github.com:280north/cappuccino 2010-03-07 17:20:56 -08:00
Francisco Ryan Tolmasky I 071a772208 Fix for drawRect: not working in IE 8 anymore. (Close chrome meta tag).
Reviewed by me.
2010-03-07 17:20:26 -08:00
Ross Boucher 78711163c5 Update the README to more accurately reflect the process. 2010-03-07 17:03:29 -08:00
Ross Boucher 3f005ff476 Add a "demos" task which downloads the demos repo and zips each demo as part of the deploy process. 2010-03-07 17:03:28 -08:00
Emmanuel MaillardandRoss Boucher ddd399631f - correct CPEmptyRange documentation 2010-03-07 17:03:28 -08:00
Francisco Ryan Tolmasky I c0ce830456 Merge branch 'master' of git@github.com:280north/cappuccino 2010-03-07 16:55:33 -08:00
Francisco Ryan Tolmasky I 481555f11f Further perfomance improvements.
Reviewed by me.
2010-03-07 16:54:43 -08:00
Tom Robinson 20327d8fb6 Move CPLog css file inline, remove redundant ANSI control sequence stuff, automatically use command line tool name in CPLog title. 2010-03-07 16:18:26 -08:00
Francisco Ryan Tolmasky I a377e15368 Added display names to Executables and FileExecutables.
Reviewed by me.
2010-03-07 15:51:49 -08:00
Francisco Ryan Tolmasky I 52ca9628fd Added display names to CFURL.
Reviewed by me.
2010-03-07 15:44:59 -08:00
Francisco Ryan Tolmasky I db1454c4fe Add display names to runtime methods.
Reviewed by me.
2010-03-07 15:36:32 -08:00
Francisco Ryan Tolmasky I 6845bd4598 Merge branch 'master' of git@github.com:280north/cappuccino 2010-03-07 14:34:12 -08:00
Francisco Ryan Tolmasky I f02286e3f5 Update press to support new fileExecutableSearcher style.
Reviewed by me.
2010-03-07 14:33:39 -08:00
Ross Boucher d473c251e6 Update undo/redo key equivalents to match the new menu code from a while ago. 2010-03-07 14:10:18 -08:00
Francisco Ryan Tolmasky I 64a401125d Further performance improvements and better debug values for CFDictionary and CFMutableDictionary.
Reviewed by me.
2010-03-07 12:49:37 -08:00
Francisco Ryan Tolmasky I 68ae1af13f Some performance improvements in CPKeyedUnarchiver.
Reviewed by me.
2010-03-07 12:24:59 -08:00
Randall Luecke f2165af48f Merge branch 'master' of git://github.com/280north/cappuccino 2010-03-07 10:30:17 -05:00
Francisco Ryan Tolmasky I 62b1dbbc74 Merge branch 'master' of git@github.com:280north/cappuccino 2010-03-07 03:58:48 -08:00
Francisco Ryan Tolmasky I 0881d86998 A number of performance improvements in the loader.
Reviewed by me.
2010-03-07 03:58:21 -08:00
Tom Robinson aff4883222 Initial fixes for "flatten". Loads everything correct but AppKit does not start completely. 2010-03-07 02:16:01 -08:00
Tom Robinson fbed77fc64 Fix press yet again. 2010-03-07 00:53:08 -08:00
Francisco Ryan Tolmasky I 276e8b948d Removed remaining Rakefiles.
Reviewed by me.
2010-03-06 22:32:52 -08:00
Francisco Ryan Tolmasky I 2edcfbda35 Updated version strings in preparation for 0.8.0 Release Candidate.
Reviewed by me.
2010-03-06 22:30:51 -08:00
Tom Robinson 22cdd6e04d Cleanup nib2cib logging. 2010-03-06 21:21:08 -08:00
Tom Robinson 3518813145 Switch nib2cib to use more robust args parsing. 2010-03-06 21:21:08 -08:00
Tom Robinson a453412d5b Strip invalid characters from plist before attempting to parse (so far just ESC) 2010-03-06 21:21:08 -08:00
Ross Boucher 55b438e8c1 Use sudo to update jake packages if sudo-install was the task.
Closes #525.
2010-03-06 20:17:51 -08:00
Tom Robinson ce749302a5 Fix nib2cib .nib support. Also use array form of OS.popen to avoid path escaping issues. 2010-03-06 19:34:56 -08:00
Francisco Ryan Tolmasky I 3356175f3e Merge branch 'master' of git@github.com:280north/cappuccino 2010-03-06 16:54:31 -08:00
Francisco Ryan Tolmasky I 50ff20ba33 Further reduction of CFURL creation and caching of method values.
Reviewed by me.
2010-03-06 16:53:24 -08:00
Francisco Ryan Tolmasky I d3ba51104e Create much fewer CFURLs.
Reviewed by me.
2010-03-06 16:20:20 -08:00
Francisco Ryan Tolmasky I 981c184c20 A few performance improvements in Objective-J loading.
Reviewed by me.
2010-03-06 16:01:03 -08:00
Randall Luecke e3a65a1847 Added preparatory support for group items in CPOutlineView. 2010-03-06 18:46:49 -05:00
Ross Boucher 64eb440ea3 nib2cib will now launch a rhino process in order to get the size of images. 2010-03-06 15:39:46 -08:00
Ross Boucher 994383f73a Remove print statement. 2010-03-06 15:32:07 -08:00
Francisco Ryan Tolmasky I 89bd5f5b93 Fixed remaining failing CPURL tests and removed prints from CFURL tests.
Reviewed by me.
2010-03-06 12:10:57 -08:00
Francisco Ryan Tolmasky I ae25f489ad Add back in accidentally removed "baseURL".
Reviewed by me.
2010-03-06 11:40:24 -08:00
Francisco Ryan Tolmasky I 510eaabcfb Fix some MHTML generation stuff.
Reviewed by me.
2010-03-06 01:57:10 -08:00
Francisco Ryan Tolmasky I 875e177219 Added global versions of objj_importFile and objj_executeFile, as well as objj_import with a deprecation warning.
Reviewed by me.
2010-03-06 01:26:27 -08:00
Francisco Ryan Tolmasky I f8f62e1473 Merge branch 'master' into URL 2010-03-06 01:15:07 -08:00
Ross Boucher c1a70a3aa2 Closes #528.
Update CPScrollView to use more modern key command parsing.
2010-03-06 01:07:46 -08:00
Ross Boucher c514fd7a08 Fix an issue where window levels weren't kept in sync with dom window layers.
Closes #507.
2010-03-06 00:57:59 -08:00
Ross Boucher 3cefc86fbf Whitespace fix. 2010-03-06 00:55:39 -08:00
Ross Boucher 0c66606d1d Closes #517.
Adds missing delegate accessor.
2010-03-06 00:01:36 -08:00
Francisco Ryan Tolmasky I 05fc35a5b9 Merge branch 'master' of git@github.com:280north/cappuccino into URL 2010-03-05 23:59:05 -08:00
Tom Robinson 2425838ea6 Add install-symlinks Jake task. 2010-03-05 23:30:39 -08:00
Francisco Ryan Tolmasky I 20d117e129 Further movement to CFURL.
Reviewed by me.
2010-03-05 22:56:15 -08:00
Francisco Ryan Tolmasky I 8f08c33bcc Update CPBundle to better support CPURLs.
Reviewed by me.
2010-03-05 22:44:59 -08:00
Francisco Ryan Tolmasky I d7f0bf6a24 Support root level apps.
Reviewed by me.
2010-03-05 22:34:04 -08:00
Francisco Ryan Tolmasky I 5afe6fea3c Better support for exotic main file locations.
Reviewed by me.
2010-03-05 21:54:22 -08:00
Francisco Ryan Tolmasky I 9441739839 Fixed incorrect method call.
Reviewed by me.
2010-03-05 21:23:25 -08:00
Francisco Ryan Tolmasky I 8727d96a06 Merge branch 'master' into URL 2010-03-05 21:14:07 -08:00
Francisco Ryan Tolmasky I b2ffe7e509 Further cleaning and bringing CPURL up to speed with CFURL.
Reviewed by me.
2010-03-05 21:11:53 -08:00
Randall Luecke 119c950b53 Merge branch 'master' of git://github.com/280north/cappuccino 2010-03-05 23:39:31 -05:00
Ross Boucher 29a0de3636 Fix document title's not being synced properly. 2010-03-05 20:09:23 -08:00
Francisco Ryan Tolmasky I aa3e3c7e71 Better support for MHTML URLs.
Reviewed by me.
2010-03-05 16:34:27 -08:00
Francisco Ryan Tolmasky I eb00953c60 Merge branch 'master' into URL 2010-03-05 16:06:42 -08:00
Francisco Ryan Tolmasky I c4b255ae46 Performance improvements to CFURL internals.
Reviewed by me.
2010-03-05 16:06:05 -08:00
Ross Boucher d3547dd892 Merge branch 'master' into keywindows 2010-03-05 14:45:56 -08:00
Ross Boucher 7d1c7b2907 Add missing accessor to CPImageView, and fix nib2cib support for image scaling.
Closes #523.
2010-03-05 13:46:41 -08:00
Randall Luecke d0999fa5d5 Additional fixes for drag and drop in the TableView after OutlineView merge. 2010-03-05 16:20:24 -05:00
Ross Boucher c478afee0f Add a missing import to CPTheme.
Closes #527.
2010-03-05 12:38:59 -08:00
Paul BaumgartandRoss Boucher ab196e75c1 Fix missing throw in Preprocessor to report an error on unmatched brackets. Closes gh-524 2010-03-05 12:34:57 -08:00
saikatandRoss Boucher 50b5c21fcf Fixes calling selectText in the text field's delegate's controlTextDidFocus: method. 2010-03-05 11:06:00 -08:00
saikatandRoss Boucher 47bc7e812d Fix for issue #511 - disabling a menu item in the menu item's action 2010-03-05 11:05:56 -08:00
saikatandRoss Boucher ad5f574fb7 Fix for issue #511 - disabling a menu item in the menu item's action 2010-03-05 10:49:42 -08:00
saikatandRoss Boucher 9537a62ab1 Fixes calling selectText in the text field's delegate's controlTextDidFocus: method. 2010-03-05 10:49:23 -08:00
Randall Luecke dc7bd3355d Fixed wrong import for outlineview test. 2010-03-05 03:59:37 -05:00
Randall Luecke d76d9bcfad Fixed bugs with drag and drop in tableview after outlineview drag and drop merge. 2010-03-05 03:37:19 -05:00
klaaspieterandRandall Luecke 440eed77cf Merge commit 'klaaspieter/outlineview' into outlineview
Conflicts:
	AppKit/CPDragServer.j
	AppKit/CPTableView.j
	Tests/Manual/TableTest/AppController.j
2010-03-05 02:40:47 -05:00
Francisco Ryan Tolmasky I b906fbea29 Merge branch 'master' into URL 2010-03-04 15:04:08 -08:00
Ross Boucher af148137d6 Merge branch 'master' into keywindows 2010-03-04 14:33:09 -08:00
Randall Luecke 64357fde0d Fixed bug where you could drag non-existant rows. Closes #520 and #521 2010-03-04 14:04:15 -05:00
Ross Boucher 7512a45cda Add #if PLATFORM(DOM) protection to several additional classes. 2010-03-03 21:20:00 -08:00
Ross Boucher e034abef82 Add a test for the initWithItems:copy: fix. 2010-03-03 20:38:56 -08:00
Scott KyleandRoss Boucher 0b5db9c4bd Fix CPArray initWithArray: copyItems: to actually work 2010-03-03 20:36:49 -08:00
Ross Boucher 3cd763aabb Add #if PLATFORM(DOM) in a missing place in CPView. 2010-03-03 19:42:16 -08:00
Ross Boucher 1a881fb501 Merge branch 'master' into keywindows 2010-03-03 14:43:43 -08:00
Ross Boucher 2f68804279 Revert "fix for scroller still being drawn below resize indicator on the first reflect of the clipview."
This reverts commit fa63551b42.
2010-03-03 14:43:25 -08:00
Ross Boucher 60d15e2983 Revert "fix for scrollviews being drawn below window resize indicator."
This reverts commit 18a0deb678.
2010-03-03 14:43:19 -08:00
Ross Boucher 628488f7aa Revert "fix for scroller still being drawn below resize indicator on the first reflect of the clipview."
This reverts commit fa63551b42.
2010-03-03 14:42:29 -08:00
Ross Boucher 149308bc89 Revert "fix for scrollviews being drawn below window resize indicator."
This reverts commit 18a0deb678.
2010-03-03 14:42:15 -08:00
Francisco Ryan Tolmasky I b4fa971007 Merge branch 'master' into URL 2010-03-03 11:40:08 -08:00
Tom Robinson b30f10ca46 Enquote NARWHALOPT package paths to fix building in directories with spaces.
Bump jake version to 0.1.5
2010-03-03 10:50:53 -08:00
Ross Boucher da725f6ffc Merge branch 'master' of github.com:280north/cappuccino into keywindows 2010-03-03 09:40:25 -08:00
Tom Robinson b0d62a8608 Add option to automatically upgrade packages for CI server, etc. 2010-03-03 09:08:02 -08:00
Tom Robinson 3da2d3718b Bump required Narwhal version to 0.2.2 2010-03-03 09:03:20 -08:00
Francisco Ryan Tolmasky I 4bd6aca0c0 Cache URLs for performance improvement.
Reviewed by me.
2010-03-03 02:36:40 -08:00
Francisco Ryan Tolmasky I e90c84ee81 Merge branch 'master' into URL 2010-03-03 01:43:40 -08:00
Francisco Ryan Tolmasky I 45b8f83cdd Revert "Revert "Revert "Enquote NARWHALOPT package paths to fix building in directories with spaces."""
This reverts commit cb939baca0.
2010-03-03 01:41:13 -08:00
Francisco Ryan Tolmasky I c8e0aa9cb4 Merge branch 'master' into URL 2010-03-03 01:36:15 -08:00
Francisco Ryan Tolmasky I 7a486db45f Update to reverted jake version.
Reviewed by me.
2010-03-03 01:35:02 -08:00
Francisco Ryan Tolmasky I 4634c6cf3b Merge branch 'master' into URL 2010-03-03 01:05:56 -08:00
Francisco Ryan Tolmasky I eb57d14673 Further migration from file paths to CFURLs.
Reviewed by me.
2010-03-03 01:04:25 -08:00
Tom Robinson cb939baca0 Revert "Revert "Enquote NARWHALOPT package paths to fix building in directories with spaces.""
This reverts commit db8a277960.
2010-03-02 17:33:39 -08:00
Tom Robinson db8a277960 Revert "Enquote NARWHALOPT package paths to fix building in directories with spaces."
This reverts commit 783159ee44.
2010-03-02 16:38:24 -08:00
Ross Boucher 398d61097c Typo in miniaturize: 2010-03-02 15:27:40 -08:00
Ross Boucher 4a43e4fda6 Overhaul of the key/main window status, esp. with respect to assigning new values after a window
closes or after a window is minimized, and with app activation/deactivation.
2010-03-02 15:16:10 -08:00
Tom Robinson 783159ee44 Enquote NARWHALOPT package paths to fix building in directories with spaces. 2010-03-02 11:47:29 -08:00
luddepandRoss Boucher fa63551b42 fix for scroller still being drawn below resize indicator on the first reflect of the clipview. 2010-03-02 11:44:31 -08:00
luddepandRoss Boucher 18a0deb678 fix for scrollviews being drawn below window resize indicator. 2010-03-02 11:44:25 -08:00
cacaodevandRoss Boucher f7c46855b8 Added missing @imports in AppKit.j 2010-03-02 11:29:09 -08:00
Ross Boucher e67539c3b1 Merge branch 'master' of github.com:280north/cappuccino 2010-03-02 11:20:38 -08:00
Ross Boucher b8d06521b2 Fix a bogus Regex in json2.js. Closes #513. 2010-03-02 11:20:02 -08:00
Tom Robinson 3225d980c5 Bump required Jake version to 0.1.3 to fix build problems with Rhino. 2010-03-02 02:09:49 -08:00
Tom Robinson 9c3a579ff8 Exit with error from capp gen 2010-03-02 01:40:00 -08:00
Tom Robinson 92b5b34d17 Add --index option to flatten to specify an alternate index.html file. 2010-03-02 00:52:19 -08:00
Ross Boucher 47e8696b9f Missing string close. 2010-03-02 00:51:46 -08:00
Tom Robinson 7938384162 Fix "capp gen -l" 2010-03-01 18:31:00 -08:00
Ross Boucher 01aec1f78e If the mainWindow tries to become main again, just return early. 2010-03-01 18:07:38 -08:00
Nicholas Small 67f35c7b74 Update deprecated sendSynchronousRequest:returningResponse:error: to sendSynchronousRequest:returningResponse: 2010-03-01 17:03:00 -05:00
Ross Boucher d600df4585 Make doxygen recursive. 2010-03-01 12:14:27 -08:00
Francisco Ryan Tolmasky I f3a0710059 Merge branch 'master' into URL 2010-02-27 13:36:56 -08:00
Ross Boucher 203e0d150b Update table headers to return the cursor to normal if the window doesn't accept mousemoved events. 2010-02-27 12:22:52 -08:00
Ross Boucher efd699a044 Add -isEqual: and -description to CPFont. Add a unit test for -isEqual:
Closes #506.
Closes #505.
2010-02-27 12:00:44 -08:00
Ross Boucher dbe0ca0adc Expand macros in the documentation generation. 2010-02-27 10:31:05 -08:00
Francisco Ryan Tolmasky I 5316cabf30 Fix for capp config <key> <value> not working.
Reviewed by me.
2010-02-26 23:35:27 -08:00
cacaodevandRandall Luecke 9a16921a32 CPTableHeaderView: Avoid vertical lines disapearring when autoresizing the table.
Fix cursor updates disabled when table autoresizing is NoAutoresizing.
                   nil check table headerView before sending a message to itself or to a table column header view.

Conflicts:

	AppKit/CPTableHeaderView.j
2010-02-26 11:35:49 -05:00
Tom Robinson f5edf2a4c2 Cleanup press and flatten arguments. 2010-02-25 19:50:06 -08:00
Ross Boucher cfdcfdbc99 Update the default jakefiles with bug fixes and convenience tasks. 2010-02-25 16:34:47 -08:00
Tom Robinson ad99dca6ac Move tools to cappuccino package's "bin" directory 2010-02-25 15:32:24 -08:00
Francisco Ryan Tolmasky I fbcc81056b Merge branch 'master' into URL
Conflicts:
	Objective-J/FileExecutable.js
2010-02-25 13:59:00 -08:00
Francisco Ryan Tolmasky I 756877b94c Removed some unecessary uses of sprintf.
Reviewed by me.
2010-02-25 12:38:50 -08:00
Ross Boucher 68d30c8802 Replace the old support for window.update_progress with OBJJ_PROGRESS_CALLBACK.
Function gets passed float from 0 to 1, the total size, and the last loaded bundle path, in that order.
2010-02-25 11:39:08 -08:00
Tom Robinson 555b83a359 "flatten" now inlines functions 2010-02-25 00:57:21 -08:00
Tom Robinson ff43be6d7b Added LoadTimeTest app to test load times. 2010-02-25 00:57:21 -08:00
Tom Robinson 7defbce1dd Fix more incorrect type annotations 2010-02-24 22:45:34 -08:00
Ross Boucher ef5aead17d Disabled resize cursor support in CPTableViewHeader 2010-02-24 21:22:07 -08:00
Ross Boucher 585b70a6a9 Fix whitespace errors. 2010-02-24 20:10:08 -08:00
Scott KyleandRoss Boucher b24a78bdd5 CPTableView delegate method tableView:setObjectValue:forTableColumn:row: is now being called for cells with CPButton data views, as it should. Fixes bug #466 2010-02-24 20:06:24 -08:00
Ross Boucher f305621ade Merge branch 'master' of github.com:280north/cappuccino 2010-02-24 17:47:09 -08:00
Ross Boucher 24198a7890 Add a missing import, exposed by press. 2010-02-24 17:46:47 -08:00
Tom Robinson 2d477b38bc Fix bootstrap when run within another sea and check for writability of /usr/local, defaulting to $HOME/narwhal 2010-02-24 16:16:27 -08:00
Paul BaumgartandTom Robinson 48afc5639e re-factor shell_config_file to make bootstrap.sh self-contained 2010-02-24 15:47:22 -08:00
Francisco Ryan Tolmasky I 7b932fbf4a Merge branch 'master' into URL 2010-02-24 11:26:46 -08:00
Francisco Ryan Tolmasky I 39f3e7b292 Fix for menus not redrawing correctly after closing in non-Safari browsers.
Closes #495.

Reviewed by me.
2010-02-24 02:56:38 -08:00
Randall Luecke 49f3038737 Merge branch 'master' of git://github.com/280north/cappuccino 2010-02-24 02:27:32 -05:00
Randall Luecke f7a40a071b Added proper resize cursor support for CPSplitView and cleaned up some whitespace. 2010-02-24 02:24:36 -05:00
Tom Robinson 3a1ebcaf3f Allow interleaved arguments in "capp gen" (requires latest Narwhal) 2010-02-23 20:07:17 -08:00
Tom Robinson 3da1c4381c Setup automated builds. 2010-02-23 18:06:23 -08:00
Tom Robinson 9ff73e5e63 Make "capp" print usage if more than one file argument is given 2010-02-23 17:04:56 -08:00
Tom Robinson f3633c050b Add OBJJ_AUTO_BOOTSTRAP option to disable auto-bootstrapping. Fixes flatten race condition. 2010-02-23 15:41:52 -08:00
Francisco Ryan Tolmasky I 1ba828da18 Beginning transition from string paths to CFURLs.
Reviewed by me.
2010-02-23 15:11:10 -08:00
Ross Boucher 109725d613 Fix whitespace issues from the previous commit. 2010-02-23 11:34:58 -08:00
Klaas Pieter AnnemaandRoss Boucher 4bc8f01376 made sure the dragserver doesn't call prepareDrag if the last drag update returned CPDragOperationNone 2010-02-23 11:25:10 -08:00
Ross Boucher df20a6d6df Add a couple tests for bugs reported from Pivotal. They aren't ideal, though, because of the CPApp issue. 2010-02-23 11:07:53 -08:00
cacaodevandRoss Boucher e32963384e _CPKVCArray -indexOfObject: typo 2010-02-23 11:07:53 -08:00
Tom Robinson 03a9865ccb Remove warning from bootstrap.sh about narwhal-jsc failing on 10.5 2010-02-22 22:06:44 -08:00
Francisco Ryan Tolmasky I 7674b3aec6 Merge branch 'master' of git@github.com:280north/cappuccino 2010-02-22 18:50:00 -08:00
Francisco Ryan Tolmasky I 9c9a5bcd51 Fix for stream undefined.
Reviewed by me.
2010-02-22 18:48:13 -08:00
Tom Robinson 8948f7f43c Fix broken flatten bit due to loader changes. Refactor flatten into ObjectiveJFlattener which inherits from ObjectiveJRuntimeAnalyzer. 2010-02-22 18:41:19 -08:00
Tom Robinson ef4e86a124 Remove StaticResource.prototype.type() 2010-02-22 18:39:50 -08:00
Francisco Ryan Tolmasky I b9edc357f3 Fix for absolute paths working with <> includes.
Reviewed by me.
2010-02-22 14:50:25 -08:00
Francisco Ryan Tolmasky I 9353d0f95c Merge branch 'master' of git@github.com:280north/cappuccino 2010-02-22 14:30:46 -08:00
Francisco Ryan Tolmasky I 7defdd2a00 Fix for some files showing up as anonymous.
Reviewed by tlrobinson.
2010-02-22 14:27:30 -08:00
Tom Robinson 621e79fe33 Fixes press, objj-analysis-tools, etc broken due to changes to loader 2010-02-22 12:54:17 -08:00
Ross Boucher e759c5343b Add a missing import in CPButton, and a test to ensure you can create one on the command line. 2010-02-22 11:07:11 -08:00
Francisco Ryan Tolmasky I d879b25458 Re-enabled menu bar button support.
Closes #410.

Reviewed by me.
2010-02-22 02:12:11 -08:00
Francisco Ryan Tolmasky I ccffde6966 Merge branch 'master' of git@github.com:280north/cappuccino 2010-02-22 00:56:23 -08:00
Francisco Ryan Tolmasky I 1524f80418 Fix for toolbar item's sending their views as senders for actions (should be the item itself).
Closes #493.

Reviewed by me.
2010-02-22 00:49:35 -08:00
Tom Robinson bcbeb888f6 Various bootstrap.sh improvements (noprompt mode, etc) 2010-02-22 00:00:40 -08:00
Francisco Ryan Tolmasky I 7730aeb652 Merge branch 'master' of git@github.com:280north/cappuccino 2010-02-21 23:30:58 -08:00
Francisco Ryan Tolmasky I 272f938f2e Fix for CPData naming issues, added test cases, and fixed isEqual: for CPDictionary.
Reviewed by me.
2010-02-21 23:29:41 -08:00
Randall Luecke 5570a346c4 Imported CPOutlineView.j in AppKit. 2010-02-22 00:26:50 -05:00
Ross Boucher 2b90652a16 Add chrome frame tag for the benefit of those people who may have installed it. 2010-02-21 17:01:33 -08:00
Ross Boucher a58dd4678c Move NibApp to manual tests. 2010-02-21 17:01:33 -08:00
Randall Luecke 25f4574093 TableView now renders white background by default (like cocoa) thereby fixing a bug where Opera rendered the tableview with a black background if you did no specify alternating row colors. 2010-02-21 19:53:40 -05:00
Tom Robinson 733b9b731d Cleanup Jakefiles, enquote arguments, add built packages bin to PATH so ojtest runs / uses the correct Cappuccino, etc. 2010-02-21 15:42:56 -08:00
Francisco Ryan Tolmasky I 20637fc5e0 Added missing licenses and removed a bit of unused code.
Reviewed by me.
2010-02-21 13:52:51 -08:00
Francisco Ryan Tolmasky I c33e2ee51f Fixed a bug with objj_debug_typecheck incorrectly misidentifying empty string as not a CPString. Also fixed a number of type declarations after running with objj_msgSend_decorate(objj_typecheck_decorator); turned on.
Reviewed by me.
2010-02-21 13:37:20 -08:00
Francisco Ryan Tolmasky I 7ef59418dd Merge branch 'master' of git@github.com:280north/cappuccino 2010-02-21 13:10:55 -08:00
Francisco Ryan Tolmasky I 0805e58a94 Fix for objj_msgSend_reset errors when running debug.
Reviewed by me.
2010-02-21 13:10:31 -08:00
Ross Boucher 6ddeff2b21 Fix the remaining tests that were failing. 2010-02-21 13:02:52 -08:00
Francisco Ryan Tolmasky I 7433c38d92 Pulled @each out into a separate feature branch, so as to not conflict with the 0.8 work: http://github.com/280north/cappuccino/tree/@each .
Reviewed by me.
2010-02-21 12:31:13 -08:00
Tom Robinson 5f930ec840 Fix for press interpreting "." as "/" 2010-02-20 23:01:06 -08:00
Randall Luecke 0dd36b2275 Merge branch 'master' of git://github.com/280north/cappuccino 2010-02-20 17:46:09 -05:00
Randall Luecke 629428739d Fixed error when headerview was set to nil on the CPTableView. 2010-02-20 17:44:45 -05:00
Francisco Ryan Tolmasky I 7d7281480a Typo in last commit and forgot one change.
Reviewed by me.
2010-02-20 02:42:57 -08:00
Francisco Ryan Tolmasky I 666e2c0190 Updated press for changed names.
Reviewed by me.
2010-02-20 02:36:14 -08:00
Francisco Ryan Tolmasky I 3968d35cac Once again fix for Fix for accounting for non-Cappuccino libraries placing things on
Object.prototype and Don't recreate sprited resources every time, and fix a bug where two
bundle tasks in the same jakefile would conflict when creating sprited
resources.

Reviewed by me.
2010-02-20 02:24:54 -08:00
Francisco Ryan Tolmasky I 551677d6fd Removed no longer used file, and renamed HTTPRequest.js to CFHTTPRequest.js to match the class name change in the previous commit.
Reviewed by me.
2010-02-20 01:08:15 -08:00
Francisco Ryan Tolmasky I 85b029fad0 Merge branch 'master' of git@github.com:280north/cappuccino 2010-02-20 01:05:04 -08:00
Francisco Ryan Tolmasky I 841ed9ea89 Major cleanup of globals and exports. Removed many accidental globals and no more need for eval in the initialization process. Also fixes Theme Showcase.
Reviewed by me.
2010-02-20 01:04:17 -08:00
Randall Luecke 74fd7eb793 Merge branch 'master' of git://github.com/280north/cappuccino 2010-02-20 03:59:40 -05:00
BlairDuncanandRandall Luecke 26df9e861f Fix for cursor showing resize indicator when column isn't user resizable. 2010-02-20 03:58:38 -05:00
Tom Robinson 338860d05b Allow additional frameworks to be copied by capp gen. Use args parser. 2010-02-19 18:27:43 -08:00
Ross Boucher b7df6c1480 Fix support for MHTML. This uses feature detection to determine if DataURLs, and then if MHTML is supported, and falls back on the original unsprited images.
Closes #376.
2010-02-19 16:48:57 -08:00
Tom Robinson b2179f14ab Cleanup Jakefiles:
* require common.jake first
* require Objective-J/Cappuccino stuff only when needed (automatically requiring these caused too many problems)
* remove useless shebangs, cleanup whitespace
2010-02-19 16:09:39 -08:00
Paul BaumgartandRoss Boucher 99b43fed7f Add support for sudo-install on systems with sudo compiled w/ --with-secure-path 2010-02-19 13:01:11 -08:00
Paul BaumgartandRoss Boucher 25dfcd38a7 Fix case on require() parameter ("OS" -> "os") 2010-02-19 13:00:31 -08:00
Tom Robinson a6d2c42402 Only log errors in setupEnvironment. 2010-02-19 02:43:39 -08:00
Francisco Ryan Tolmasky I fd8271396d Fix for accounting for non-Cappuccino libraries placing things on Object.prototype.
Reviewed by me.
2010-02-19 02:08:34 -08:00
Francisco Ryan Tolmasky I 19ca6a342e Merge branch 'master' of git@github.com:280north/cappuccino 2010-02-19 00:43:18 -08:00
Francisco Ryan Tolmasky I 7819e174f1 Added setString: to CPData which sits on top of setSerializedPlistObject:.
Reviewed by me.
2010-02-19 00:42:23 -08:00
Randall Luecke 7cd6d026a2 Merge branch 'master' of git://github.com/280north/cappuccino 2010-02-19 03:24:59 -05:00
Randall Luecke c48d306195 Initial refactor/rewrite of auto resizing columns. 2010-02-19 03:23:29 -05:00
Francisco Ryan Tolmasky I 3a9845f784 Don't recreate sprited resources every time, and fix a bug where two bundle tasks in the same jakefile would conflict when creating sprited resources.
Reviewed by me.
2010-02-18 23:32:11 -08:00
Francisco Ryan Tolmasky I 94d3053232 Added CommonJS extensions to CFPropertyList.
Reviewed by me.
2010-02-18 15:28:30 -08:00
Francisco Ryan Tolmasky I b078169adf Fix for slight name change.
Reviewed by me.
2010-02-18 14:05:33 -08:00
Francisco Ryan Tolmasky I 38c4dd408c Fix for CPBundle loading all code. Fixes external frameworks with nib2cib.
Reviewed by me.
2010-02-18 13:55:30 -08:00
Francisco Ryan Tolmasky I 8beb9dfed0 Merge branch 'master' of git@github.com:280north/cappuccino 2010-02-18 11:18:17 -08:00
Francisco Ryan Tolmasky I eef9549e96 Fix for HelloWorld/ not working when HelloWorld/index.html does.
Closes #483.

Reviewed by me.
2010-02-18 11:17:21 -08:00
Randall Luecke 82ac98ddc7 Initial refactoring of init with a fix for gradients not being initialized correctly. Initial refactoring of uniform column auto resizing to prep for a rewrite. 2010-02-18 11:09:07 -05:00
cacaodevandRandall Luecke 3d52ffcbdc CPTableView: fix shiftKey+selection to match cocoa behavior. closes issue #433 2010-02-18 02:30:57 -05:00
Randall Luecke 3fad4635b0 Updated tabletest to include new source list selection styles, also cleaned up the tableview a bit, and made the default selection style of the outlineview use the source list gradient. 2010-02-18 02:21:40 -05:00
cacaodevandRandall Luecke b0b19328a8 CPTableView: CPTableViewSelectionHighlightStyleSourceList for canvas browsers. Removed references to selectionHighlightColor. 2010-02-18 01:27:06 -05:00
Francisco Ryan Tolmasky I 9fd79488f8 Merge branch 'master' of git@github.com:280north/cappuccino 2010-02-17 21:13:14 -08:00
Francisco Ryan Tolmasky I cebe31857a Fix for image loading problem.
Reviewed by me.
2010-02-17 21:12:14 -08:00
Ross Boucher 1961829414 Correct a use of global. to be GLOBAL_NAMESPACE. at least until we have a better solution. 2010-02-17 19:31:11 -08:00
Ross Boucher 3e5bdec033 Merge branch 'master' of github.com:280north/cappuccino 2010-02-17 19:22:02 -08:00
Ross Boucher 5789021a76 modify the copyright date 2010-02-17 19:20:44 -08:00
Tom Robinson 6bf0319c51 Add ojdepcheck tool to print out missing @imports 2010-02-17 18:09:55 -08:00
Tom Robinson 8f519caa77 Remove old shrinksafe jars 2010-02-17 18:02:32 -08:00
Ross Boucher a38be80a86 Revert "A better fix for the IE bug. Rather than introduce the secondary global and the eval, just refer to the actual global object (works in any javascript env)."
This reverts commit d40619aca0.
2010-02-17 17:37:46 -08:00
Ross Boucher 81b72fc571 Throw a syntax error if we don't recognize the @accessors syntax. 2010-02-17 17:27:37 -08:00
Ross Boucher 91681d7846 Move more constants to CPControl.j 2010-02-17 17:06:09 -08:00
Ross Boucher d40619aca0 A better fix for the IE bug. Rather than introduce the secondary global and the eval, just refer to the actual global object (works in any javascript env). 2010-02-17 16:55:07 -08:00
Ross Boucher 1328bc732f Move around some imports and constant declarations. 2010-02-17 16:29:57 -08:00
Ross Boucher 060f65b27e Use CPLog instead of console 2010-02-17 16:24:04 -08:00
Tom Robinson 364669f527 Remove formatting from capp usage message for now. 2010-02-17 16:15:10 -08:00
Ross Boucher f4042b9d4b Fix an error in IE6 with XMLHttpRequest being undefined 2010-02-17 16:09:58 -08:00
Ross Boucher c750b696d2 Merge branch 'master' of github.com:280north/cappuccino 2010-02-17 16:08:58 -08:00
Ross Boucher 02cdee6c75 Fix a missing import. 2010-02-17 16:08:11 -08:00
Tom Robinson c4a824b5db More bootstrap improvements: follow narwhal symlinks to actual installation 2010-02-17 15:18:07 -08:00
Tom Robinson 7f31c0632d flatten: build nodes relative to cwd 2010-02-17 14:57:33 -08:00
Francisco Tolmasky 96ee92695c Merge branch 'jake'
Conflicts:
	Tools/press/objj-analysis-tools.j
2010-02-17 13:50:18 -08:00
Francisco Ryan Tolmasky I 80b252a744 Merge branch 'loader' into jake 2010-02-17 13:40:22 -08:00
Francisco Ryan Tolmasky I 4f50f8b83f Fix for IE Bug that caused stack overflow at line 0 when loading Objective-J every time.
Reviewed by me.
2010-02-17 13:39:15 -08:00
Francisco Ryan Tolmasky I df895b9529 Treat extensionless files as Objective-J.
Reviewed by ross.
2010-02-16 19:31:31 -08:00
Tom Robinson f9e9e51352 A couple fixes in flatten 2010-02-16 18:21:36 -08:00
Ross Boucher 27e99344bd Make nib2cib quieter by default. Prints only fatal error messages.
Pass the -v flag to print warnings, and -vv or --verbose to print all messages.

Closes #475.
2010-02-16 16:59:44 -08:00
Ross Boucher 32572844fd Merge branch 'loader' of github.com:280north/cappuccino into loader 2010-02-16 16:37:24 -08:00
Ross Boucher a77e67e578 Add support for keyboard navigation in CPCollectionView 2010-02-16 16:36:40 -08:00
Francisco Ryan Tolmasky I fb9cd1ef93 Don't Objective-J preprocess non-.j files.
Reviewed by me.
2010-02-16 16:23:03 -08:00
Ross Boucher 93722f6a7d Fix a bug where any @ added accessors to ivar declarations.
Closes #474.
2010-02-16 15:50:04 -08:00
Francisco Ryan Tolmasky I 76da7466ec Fix for CPDictionary CPFastEnumeration.
Reviewed by me.
2010-02-16 13:51:02 -08:00
Stephen IerodiaconouandRoss Boucher 6b3c95f09f Fix for issue #473. Call setEnabled from _CPToolbarItemView updateFromItem. 2010-02-16 10:43:48 -08:00
Francisco Ryan Tolmasky I 81110ddba7 Further performance improvements.
Reviewed by me.
2010-02-16 02:41:15 -08:00
Francisco Ryan Tolmasky I 64fd9f615c Additional performance improvements to CPFastEnumeration.
Reviewed by me.
2010-02-16 02:04:31 -08:00
Randall Luecke 213df88766 Merge branch 'loader' of git://github.com/280north/cappuccino into loader 2010-02-16 03:58:22 -05:00
Tom Robinson a26750d4f4 Fixed objj arguments parsing 2010-02-16 00:57:50 -08:00
Randall Luecke 72edd7376e temp fix for auto resizing when user manually resizes. Uniform resizing is still broken. 2010-02-16 03:56:17 -05:00
Randall Luecke 948e9ae139 Merge branch 'loader' of git://github.com/280north/cappuccino into loader 2010-02-16 03:43:22 -05:00
Francisco Ryan Tolmasky I ae357d1a2b Support for post and pre order CPFastEnumration for CPTreeNode. In order and level order remain.
Reviewed by me.
2010-02-16 00:41:20 -08:00
Randall Luecke 59756ff1b3 Made the hit test area for the column resizing a bit smaller. 2010-02-16 03:40:05 -05:00
Klaas Pieter Annema 2908e453e8 Merge branch 'jake' into outlineview 2010-02-16 09:39:49 +01:00
Klaas Pieter Annema 7b1ffc885f Merge branch 'jake' of git://github.com/280north/cappuccino into jake 2010-02-16 09:39:32 +01:00
Randall Luecke 95364b1d31 Tableview fixes including setMaxWidth reset on columns, added grid line to cornerview, cleaned up width validation in sizeLastColumnToFit, and cleaned up TableTest. 2010-02-16 03:00:49 -05:00
Ross Boucher f3257c0847 Add trunaction defaults to the table view cells 2010-02-15 23:05:23 -08:00
Ross Boucher eb0fc35c8f Merge branch 'loader' of github.com:280north/cappuccino into loader 2010-02-15 23:05:10 -08:00
Ross Boucher 3dccd93093 Fix a typo. Closes #380. 2010-02-15 23:04:47 -08:00
Francisco Ryan Tolmasky I 8929199082 Add CPFastEnumeration support for CPEnumerator.
Reviewed by me.
2010-02-15 22:48:28 -08:00
Klaas Pieter Annema 20f6a57b3a - made the proposed drag row calculations more accurate when a tableview has non-default row height or inter-cell spacing
- fixed a bug in the dragged row at point calculation
2010-02-16 07:45:19 +01:00
Francisco Ryan Tolmasky I db949728dd Add CPFastEnumeration support to CPSet and CPNull.
Reviewed by me.
2010-02-15 22:44:52 -08:00
Francisco Ryan Tolmasky I 92d28e468e Autogenerate the index parameter for Fast Enumeration, and add Fast Enumeration support to CPIndexSet.
Reviewed by me.
2010-02-15 22:34:50 -08:00
Francisco Ryan Tolmasky I f95c3ca46a Adds fast enumeration to Cappuccino. Currently support for Arrays, dictionaries, single objects, and nil.
Closes #472.

Reviewed by me.
2010-02-15 21:46:50 -08:00
Ross Boucher 477b6bcdc5 Merge branch 'loader' of github.com:280north/cappuccino into loader 2010-02-15 21:28:58 -08:00
Ross Boucher 3e40deba5f Fix a lot of style issues.
Change a 1px value.
Closes #444.
2010-02-15 21:27:27 -08:00
Tom Robinson 7d9bd25270 Disable bootstrap installing prebuilt packages 2010-02-15 21:26:49 -08:00
Tom Robinson c201990cb0 Switch compressor to use CommonJS packages for ShrinkSafe, etc. 2010-02-15 21:26:02 -08:00
Tom Robinson 289df53fb4 Disable bootstrap installing prebuilt packages 2010-02-15 21:26:02 -08:00
Ross Boucher 62788423a1 Add missing accessors. Closes #452. 2010-02-15 18:32:45 -08:00
Ross Boucher 8617990206 Add much better support for CPTableView to nib2cib. 2010-02-15 17:28:35 -08:00
cacaodevandRandall Luecke 2d8f2b328f Fixed a bug where column selection code was trying to highlight unexposed data views 2010-02-15 11:09:16 -05:00
Francisco Ryan Tolmasky I 833896e267 Renaming file to match class renaming.
Reviewed by me.
2010-02-14 19:17:56 -08:00
Francisco Ryan Tolmasky I f12b4520f6 Some renaming.
Reviewed by me.
2010-02-14 19:17:50 -08:00
Randall Luecke 2564003c85 Added new aristo resources for CPTableView sorting. 2010-02-14 21:37:03 -05:00
cacaodevandRandall Luecke c36b8f2257 CPTableView: -setHighlightedTableColumn: argument should be a CPTableColumn 2010-02-14 21:33:47 -05:00
cacaodevandRandall Luecke d413fbe0ed Fix for indentations not respected when resizing an outlineview column. Closes issue #470 2010-02-14 21:33:32 -05:00
Randall Luecke 4237000fc9 TableView:
Set a CPThemeStateHighlighted for both selecting and sorting.
Do not change sort descriptors when selecting with a modifier flag.

Conflicts:

	AppKit/CPTableView.j
2010-02-14 21:33:20 -05:00
cacaodevandRandall Luecke 5131aff352 Column sorting : Sort descriptors, sort indicator image, highlighted column.
Column resizing : Fixed bug where last column could not be resized.
                  Left arrow cursor when reaching maxWidth.
                  Moved table selection code to CPTableView.
                  Disable automatic resizing when user is resizing column
		  Partially fixed uniform resizing not prop. to columns width.
2010-02-14 21:32:07 -05:00
Francisco Ryan Tolmasky I f77f52802c Fix for new loader not working when app lives in the root directory of a website.
Reviewed by me.
2010-02-14 16:26:54 -08:00
Francisco Ryan Tolmasky I d52ab34421 Better Cib loading that doesn't make assumptions about the asynchronisity of the load.
Reviewed by me.
2010-02-14 12:23:47 -08:00
Francisco Ryan Tolmasky I 81e4c26b38 Fix for properly handling XMLHTTPRequests with files that don't exist when using file:// URL's in FireFox.
Reviewed by me.
2010-02-14 12:22:37 -08:00
Ross Boucher 1eed1901e9 Add some documentation to CPTableColum's setDataView: method.
Closes #315.
2010-02-13 22:33:36 -08:00
Ross Boucher a8b1c7bce1 Fix a number of segmented control bugs. Among other things, the disabled state is respected per segment.
Closes #386.

Also fixes the error where right side of segments would often not be visible.
Also fixes the error which caused the right and left bezel images to not show as disabled ever.
2010-02-13 20:40:32 -08:00
Alexander LjungbergandRoss Boucher ac3d035ce7 Fixed: CPTableView deselectRow: changed the column selection rather than the row selection. 2010-02-13 20:08:12 -08:00
Ross Boucher c8575cac05 Revert "Fix the collection view resizing behavior."
This reverts commit 9b01561127.
2010-02-13 20:04:18 -08:00
Francisco Ryan Tolmasky I 8d63c059c5 Fixed scope issues when running Cappuccino under CommonJS.
Reviewed by me.
2010-02-13 16:57:09 -08:00
Francisco Ryan Tolmasky I bc53288fca Fix for failing CPAttributedString test.
Reviewed by me.
2010-02-13 16:14:18 -08:00
Francisco Ryan Tolmasky I 474d4281f1 Actual fix for pasteboard exception for strings.
Reviewed by me.
2010-02-13 14:39:44 -08:00
Ross Boucher 73babcd7d6 Merge branch 'loader' of github.com:280north/cappuccino into loader 2010-02-13 14:24:35 -08:00
Ross Boucher 5fe208d6a0 Update to the last scroller fix, slightly different approach. 2010-02-13 13:55:23 -08:00
Tom Robinson 94ca0ed71b Read as binary then decode to string to workaround narwhal-rhino bug of adding newlines on read() 2010-02-13 13:54:38 -08:00
Ross Boucher a323cfe08c Allow developers to choose to enable the HTML5 drag and drop support, even though its off by default. 2010-02-13 13:38:56 -08:00
Ross Boucher 29c3654928 Merge branch 'loader' of github.com:280north/cappuccino into loader 2010-02-13 13:25:31 -08:00
Ross Boucher 27fefed0d8 Recaluclate the orientation of a scroller on frame change.
Closes #454.
2010-02-13 13:24:31 -08:00
Tom Robinson 235d974ce1 Beginning of "flatten" tool. 2010-02-13 13:13:47 -08:00
Tom Robinson cb1d3168e3 press cleanup, refactor setting environments and include paths into analyzer. 2010-02-13 13:13:47 -08:00
Tom Robinson 64dc25dfb6 Export rootNode. 2010-02-13 13:13:47 -08:00
Ross Boucher 9a7484e57d Fix Typo. Closes #463. 2010-02-13 12:06:52 -08:00
Ross Boucher b89ee3e4c1 Use longform RegEx creation in json2.js to fix a bug in Opera 9.2.
Closes #323.
2010-02-12 21:51:06 -08:00
Ross Boucher ec5645d380 Only change button heights if the button isn't bordered.
Closes #157.
2010-02-12 21:36:32 -08:00
Ross Boucher a0abf1e221 Fix a slight bug with default values in nib2cib segmented controls.
Closes #215.
2010-02-12 21:29:19 -08:00
Ross Boucher 0e558d54e5 Move CPControl constants to that file (from CPTextField).
Respect line break mode in NSControl nib2cib.

Closes #420.
2010-02-12 21:16:44 -08:00
Ross Boucher 004cc5fe5a Store a conversion table of views/objects we're replacing and restore connections to those replaced objects. (nib2cib) 2010-02-12 20:31:36 -08:00
Ross Boucher 0b22b1d022 Correctly convert NSButtons set as checkboxs and radiogroups to CPCheckBoxes and CPRadios.
Closes #365.
2010-02-12 20:05:34 -08:00
Ross Boucher 24ecf31bd3 Merge branch 'loader' of github.com:280north/cappuccino into loader 2010-02-12 14:18:19 -08:00
Ross Boucher c37c80771c Fix broken tests with CPData. 2010-02-12 14:17:58 -08:00
Francisco Ryan Tolmasky I a017c0c4a8 Fix for failing CPDictionary tests.
Reviewed by me.
2010-02-12 14:09:40 -08:00
Francisco Ryan Tolmasky I 3a35ab449b Fixed failing KVO tests.
Reviewed by me.
2010-02-12 13:46:26 -08:00
Ross Boucher da84964a33 Fix two problems with KVC:
- valueForKeyPath: looped over individual components, which meant classes couldn't override valueForKeyPath: to do multi-part keys (needed for operators)
- CPArray's valueForKeyPath: implementation was incorrectly parsing the operator if it was a simple key
2010-02-12 12:53:15 -08:00
Klaas Pieter Annema 65051855ee fixed a bug where the tableview would draw a row to many 2010-02-12 13:02:55 +01:00
Ross Boucher 72c36789c6 Accidental global var.
Closes #462.
2010-02-11 09:35:36 -08:00
Klaas Pieter Annema bc07bd16bd implemented outlineView:willDisplayView:forTableColumn:row delegate method 2010-02-11 16:47:49 +01:00
Klaas Pieter Annema bf691fa552 removed incorrect implementation of imageDimsWhenDisabled 2010-02-11 12:47:27 +01:00
Ross Boucher 47ddfec1f9 Merge branch 'loader' of github.com:280north/cappuccino into loader 2010-02-10 19:56:33 -08:00
Ross Boucher fb8ba655e1 Do not enforce min/max size in setFrame:display:animate: only do so in the other setFrame* variants.
Closes #284.
2010-02-10 19:55:40 -08:00
Tom Robinson d64f56817d Remove unused imports etc from press 2010-02-10 19:35:53 -08:00
Tom Robinson 9363708e49 Move push-package dir to .push-package and add to .gitignore 2010-02-10 19:19:00 -08:00
Ross Boucher 65a2e4d6b0 Merge branch 'loader' of github.com:280north/cappuccino into loader 2010-02-10 18:33:03 -08:00
Randall LueckeandRoss Boucher 138d7bd9a2 Added _ in front of CG calls to last commit... 2010-02-10 18:19:13 -08:00
Randall LueckeandRoss Boucher 97fe09fbdd Added proper support for hiding scroller elements when CPScroller is resized too small to display all of them. 2010-02-10 18:19:07 -08:00
Tom Robinson 487412fa22 objj repl respects -I args. Closes gh-235 2010-02-10 18:17:41 -08:00
Klaas Pieter Annema ea47baa1fc implemented imageDimsWhenDisabled on CPButton 2010-02-10 16:19:51 +01:00
Klaas Pieter Annema 90cd519916 added viewDidLoad to CPViewController 2010-02-10 12:13:17 +01:00
Klaas Pieter Annema 669d18b218 added missing exception when a viewcontroller has no view after loadView 2010-02-10 11:46:40 +01:00
Tom Robinson fbcd2b3174 Merge branch 'loader' of git@github.com:280north/cappuccino into loader 2010-02-10 00:49:11 -08:00
Tom Robinson 99a839456d Remove --flatten and --nostrip command line flags from press. 2010-02-10 00:34:51 -08:00
Tom Robinson 0d9d60466d It's alive! press appears to be working completely (minus removed --flatten feature) 2010-02-10 00:31:00 -08:00
Francisco Ryan Tolmasky I 5a031efa7a Fixed issues with imports that had ".." in the paths.
Reviewed by me.
2010-02-10 00:03:46 -08:00
Tom Robinson 1f64fce47c First pass at fixing "press" output stage. 2010-02-09 17:25:11 -08:00
Tom Robinson 04529897dc Add setCode to Executable; use toMarkedString() in compiler; more robust function wrapper stripping in compressor 2010-02-09 14:55:50 -08:00
Tom Robinson 7837e1ad81 Fixed Executable's toMarkedString() 2010-02-09 14:49:54 -08:00
Francisco Ryan Tolmasky I c7c60b2b94 Added toMarkedString to Executable.
Reviewed by me.
2010-02-09 13:57:47 -08:00
Francisco Ryan Tolmasky I f9c2805379 Removed reference to MARKER_TEXT.
Reviewed by me.
2010-02-09 13:40:04 -08:00
Tom Robinson 035d772a4a Respect previously set OBJJ_MAIN_FILE 2010-02-09 11:46:25 -08:00
Alexander LjungbergandRoss Boucher f89c2e0ba9 Fixed: CPDates compared equal to nil and CPNull. 2010-02-09 10:59:59 -08:00
Philipe FatioandRoss Boucher 94ce055bc2 CPWindow's makeFirstResponder: return type was void, changed to BOOL 2010-02-09 10:49:04 -08:00
Klaas Pieter Annema 9b3d4d4453 Merge branch 'jake' into outlineview 2010-02-09 15:01:10 +01:00
Klaas Pieter Annema 329e4dc3c3 Merge branch 'jake' of git://github.com/280north/cappuccino into jake
Conflicts:
	AppKit/CPTableColumn.j
	AppKit/CPTableView.j
2010-02-09 14:57:37 +01:00
Klaas Pieter Annema d96e939eed made sure the dragserver doesn't call prepareDrag if the last drag update returned CPDragOperationNone 2010-02-09 14:43:02 +01:00
Klaas Pieter Annema c8437895dc fixed setDropItem:dropChildIndex behavior 2010-02-09 14:42:11 +01:00
Francisco Ryan Tolmasky I 95ba648dae Fix for keys being wrong in cplutil conversion, and making sure to use the right radix with parseInt when reading plists.
Reviewed by me.
2010-02-09 02:18:52 -08:00
Francisco Ryan Tolmasky I 9f847e5a24 Merge branch 'jake' into loader 2010-02-09 01:03:37 -08:00
Francisco Ryan Tolmasky I a4eec5fef8 Fix for UID returning different values every time for CPString.
Reviewed by me.
2010-02-09 01:02:49 -08:00
Tom Robinson e51bf3f0c1 More upgrading of press to new load system. Analysis is complete, need to build resulting files. 2010-02-08 23:47:29 -08:00
Tom Robinson b907ea59f4 Export a few more properties from Objective-J for use in "press" 2010-02-08 23:45:59 -08:00
Tom Robinson cebff75992 Change jakefile to throw exception if there's a syntax error, etc in one of the optionally required modules. 2010-02-08 23:44:44 -08:00
Alexander LjungbergandRandall Luecke a3f9b65501 Implemented [CPDate copy] with unit test. Also whitespace cleanup in CPDate. 2010-02-09 01:57:24 -05:00
Nicholas Small 1f7afe7a49 Merge branch 'jake' of github.com:280north/cappuccino into loader 2010-02-08 10:51:30 -05:00
Nicholas Small ceecaa0184 Fixed missing { in objj-analysis-tools.j 2010-02-08 10:50:44 -05:00
Klaas Pieter Annema 78b4bbb06e implement setDropItem:dropChildIndex on CPOutlineView 2010-02-08 16:49:07 +01:00
Klaas Pieter Annema 0375e7a881 - further improved outline view drag & drop for multiple parent situations 2010-02-08 14:44:21 +01:00
Klaas Pieter Annema ebc831663b Merge branch 'jake' into outlineview
Conflicts:
	AppKit/CPTableView.j
2010-02-08 11:34:16 +01:00
Klaas Pieter Annema 65ceb96e4f Merge branch 'jake' of git://github.com/280north/cappuccino into jake
Conflicts:
	AppKit/CPTableColumn.j
	AppKit/CPTableView.j
2010-02-08 11:33:33 +01:00
Klaas Pieter Annema 57ef2d2229 removed log statements 2010-02-08 11:14:50 +01:00
Klaas Pieter Annema 8759b175bd various fixes to outline view drag & drop 2010-02-08 11:14:03 +01:00
Tom Robinson 13f86b0cd4 Refactor objj-analysis-tools a bit. 2010-02-08 01:44:55 -08:00
Tom Robinson c0fad49375 Merge branch 'loader' of github.com:280north/cappuccino into loader 2010-02-08 01:12:22 -08:00
Derek HammerandTom Robinson 579cc98e4f Adding the --symlink and --build flags. capp gen -l something is now just an alias for capp gen --symlink --build something. This allows for easy copying of built Frameworks for those hacking on Cappuccino 2010-02-08 01:04:22 -08:00
Randall Luecke 4a98417ee8 Added call to auto resizing after user manually resizes the columns. 2010-02-08 02:20:38 -05:00
Randall Luecke 4a5e90b5cb Fixed column resizing mask types. 2010-02-08 02:16:06 -05:00
cacaodevandRandall Luecke 36a85e935b TableView : Column resizing. Works with column resizingMasks.
TODO: Automatic table resizing should only resize columns marked with TableColumnAutoresizingMask.
TODO: When implemented, use CPTrackingArea instead of mouse moved events.
2010-02-08 01:19:10 -05:00
chandlerkentandRandall Luecke 9034203a4f Fixed a bug where CPTableView doesn't scroll to the top index when using the arrow keys. 2010-02-08 00:49:08 -05:00
Randall Luecke 24e8f8aa43 Restyled tableview to match new Aristo art. Added a bit of a padding to the dataviews and headerviews. 2010-02-07 23:55:40 -05:00
Ross Boucher 632251b16c Infinite recursion error. 2010-02-06 18:31:20 -08:00
Ross Boucher 2406cbe7ed Merge branch 'jake' into loader 2010-02-06 17:47:03 -08:00
Ross Boucher e6a0caa164 cplutil wasn't converting.
CFPropertyList couldn't output XML correctly.
2010-02-06 17:46:32 -08:00
Francisco Ryan Tolmasky I cd3e2fbbb8 Fix for cplutil.
Reviewed by me.
2010-02-06 17:14:37 -08:00
Randall Luecke 47bd6e5ce3 Further cleanup of code and logs in the tableview. 2010-02-06 17:53:40 -05:00
Randall Luecke f590c63e33 Cleaned up tableview logs. 2010-02-06 17:36:20 -05:00
Randall Luecke e8b74ece72 Fixed tableview begin drag/drop behavior to be more cocoa like. 2010-02-06 17:29:19 -05:00
Tom Robinson 3d45699bc7 Merge branch 'loader' of github.com:280north/cappuccino into loader
Conflicts:
	Objective-J/CPLog.js
2010-02-06 14:01:56 -08:00
Tom Robinson ae987f19dc Fixed CPLogRegisterRange and added dup checking and unregister function 2010-02-06 14:00:58 -08:00
Francisco Ryan Tolmasky I 09786cb8d2 Fix CPLog additions breaking build.
Reviewed by me.
2010-02-06 01:57:44 -08:00
Tom Robinson 17072f9ed4 Move CPLog to Objective-J 2010-02-05 22:27:13 -08:00
Tom Robinson 82d3d1abc5 Merge branch 'loader' of github.com:280north/cappuccino into loader 2010-02-05 21:12:08 -08:00
Tom Robinson 2cc40a7961 Add sprintf.js to Objective-J 2010-02-05 21:11:47 -08:00
Francisco Ryan Tolmasky I c523e706e9 Better error reporting.
Reviewed by me.
2010-02-05 20:18:18 -08:00
Klaas Pieter Annema cdca8047b9 Merge branch 'jake' into outlineview
Conflicts:
	AppKit/CPTableView.j
2010-02-05 15:14:40 +01:00
Klaas Pieter Annema 09b8a3394e Merge branch 'jake' of git://github.com/280north/cappuccino into jake
Conflicts:
	AppKit/CPTableColumn.j
2010-02-05 12:15:34 +01:00
Klaas Pieter Annema ed1a7a4bc9 - removed variable row heights from CPTableView (can be found in variabletableview branch)
- fixed a bug where it was not possible to drag unselectable rows #445
2010-02-05 12:11:39 +01:00
Klaas Pieter Annema 0696fb405e improved CPTableView's drop row logic for the lowest possible row 2010-02-05 11:51:06 +01:00
Randall Luecke 265a410342 Changed the default text color for table column data views to match Aristo. 2010-02-04 21:27:06 -05:00
Nicholas Small cbd0d6e6a2 Better nib2cib and CPCoder support for CPTableView. 2010-02-04 15:25:16 -05:00
Nicholas Small 25e0a59d5b Merge branch 'loader' of github.com:280north/cappuccino into loader 2010-02-04 14:14:36 -05:00
Nicholas Small ab34ee882e Add a few flags to NSTableView and CPCoder support for gridColor and gridStyleMask in CPTableView. 2010-02-04 14:14:31 -05:00
Ross Boucher 4f05657236 Merge branch 'jake' into loader
Conflicts:
	Objective-J/Preprocessor.js
2010-02-04 11:10:39 -08:00
Klaas Pieter Annema 7720200679 - improved the CPOutlineView drag & drop support in cases where more than 1 parent is possible
- improved the outline view test project
2010-02-04 16:56:48 +01:00
Klaas Pieter Annema 117ec9970c - reduced the number of rows on the tableview sample so it works with the variable row heights
- made CPTableView ask for the rect of the drop highlight so CPOutlineView can adjust this
- re factored some stuff in CPOutlineView's table delegate
2010-02-04 14:20:12 +01:00
Klaas Pieter Annema 766073f77a reverted some of my drop highlight changes 2010-02-04 13:09:10 +01:00
Klaas Pieter Annema 5f0a60f61c Merge branch 'jake' of git://github.com/280north/cappuccino into jake 2010-02-04 10:35:47 +01:00
Tom Robinson d608d34166 Fixed "phase 1" of press for new loader 2010-02-04 01:00:55 -08:00
Tom Robinson 8bc1c7445d export fileExecuterForPath (and use exports.fileExecuterForPath internally so it can be overridden for press, etc) 2010-02-03 23:50:16 -08:00
Tom Robinson 985b906c94 Merge branch 'loader' of git@github.com:280north/cappuccino into loader 2010-02-03 22:21:55 -08:00
Randall Luecke e8ac94f8da Improved logic for drawing highlighted grid lines. 2010-02-04 00:41:15 -05:00
Randall Luecke 9465dd6941 Merge branch 'jake' of git://github.com/280north/cappuccino into jake 2010-02-04 00:23:19 -05:00
Randall Luecke 28a00fff23 Fixed drawing bug where a the bottom grid line for the selected rows would be drawn white. 2010-02-04 00:19:59 -05:00
Francisco Ryan Tolmasky I c418481981 Don't require trashing Objective-J when changes are made for them to be picked up.
Reviewed by me.
2010-02-03 20:37:24 -08:00
Randall Luecke 2b87b9f3fc Styled the test for the tableview headers, also added more rows to tabletest for performance testing. 2010-02-03 22:34:13 -05:00
Ross Boucher 683eb993e8 Fix for a broken dirname method on File. 2010-02-03 16:17:12 -08:00
Ross Boucher e19d6a58c9 Merge branch 'loader' of github.com:280north/cappuccino into loader 2010-02-03 14:58:16 -08:00
Alexander LjungbergandRoss Boucher 2dccee05bc Fixed: CPWindow setFrame:display: failed with an "unrecognized selector" exception. 2010-02-03 14:58:01 -08:00
Francisco Ryan Tolmasky I ac2885afc6 Support base tag again.
Reviewed by me.
2010-02-03 14:31:02 -08:00
Nicholas Small 972909902e Added ApplicationTask#setFrameworks path. The default is local frameworks, you could also use ENV.CAPP_BUILD or pass capp to use the installed frameworks. 2010-02-03 11:43:48 -05:00
Klaas Pieter Annema b07f2ed186 improved the location of the drag feedback view 2010-02-03 15:25:28 +01:00
Klaas Pieter Annema ee6160e796 - fixed some issues with variable sized
- made CPOutlineView return the last index when dragging the row outside of it's bounds
2010-02-03 15:06:42 +01:00
Klaas Pieter Annema 5940e6913d Merge branch 'jake' of git://github.com/280north/cappuccino into jake 2010-02-03 10:16:45 +01:00
Klaas Pieter Annema c85e33c034 Fixed a bug where the CPTextField value was not updated properly when the update happened in the same 'runloop' iteration as becomeFirstResponder 2010-02-03 10:11:32 +01:00
Francisco Ryan Tolmasky I 21ef259e1f Fix for being too strict when accepting PLISTs and also fixes a regression with erroring when parsing code with shebangs(!).
Closes #69.

Reviewed by me.
2010-02-03 00:31:37 -08:00
Ross Boucher 2b66683167 Update the documentation config based on feedback from:
http://cappnotes.worldofkrauss.com/sectins/objective-j-categories/8-miscellaneous/14-api-documentation-fixes.html

If you have graphviz installed, graphs will now be generated.
Ruby and doxygen are prereqs for building the docs.
2010-02-02 18:35:42 -08:00
Ross Boucher 851a0e3d24 Fix a preprocess.js typo.
Closes #440.
2010-02-02 14:52:55 -08:00
Klaas Pieter Annema 8b32f561ec added selectedRow to CPTableView 2010-02-02 15:57:15 +01:00
Klaas Pieter Annema 1571b6daa2 fixed CPTableView's header view reliance on row height 2010-02-02 15:44:23 +01:00
Klaas Pieter Annema 2d69509d5e - implemented CPTableView heightOfRow: delegate method
- implemented CPOutlineView heightForItem: delegate method
- made CPTableView work correctly with variable sized rows
2010-02-02 14:15:22 +01:00
Klaas Pieter Annema 8edf05c000 made sure the outline view returns a dataview if it's delegate doesn't implement dataViewForTableColumn:item: or if that method returned nil 2010-02-02 11:37:57 +01:00
Klaas Pieter Annema 0e6cef0268 implement outlineview expandItem:expandChildren: 2010-02-02 11:23:24 +01:00
Klaas Pieter Annema 60e4d8e080 Merge remote branch 'cappuccino/jake' into jake
Conflicts:
	AppKit/CPOutlineView.j
	AppKit/CPTableView.j
2010-02-02 10:24:13 +01:00
Randall Luecke 6b58986ec3 Added better artwork for pressed header images for the tableview. 2010-02-02 01:56:53 -05:00
Randall Luecke e88ec01fca Fixed bug where the first click on the CPTableView wouldn't select a row if drag and drop was supported. 2010-02-01 23:26:24 -05:00
Francisco Ryan Tolmasky I 8284498722 Merge branch 'jake' into loader
Conflicts:
	AppKit/Platform/DOM/CPPlatformString.j
2010-02-01 20:19:20 -08:00
Tom Robinson e088280a5f Implement description and toString for class objects. 2010-02-01 17:38:13 -08:00
Klaas Pieter Annema 7f78c323e9 implemented outlineView:shouldSelectItem delegate method 2010-02-01 19:08:22 +01:00
Klaas Pieter Annema 77303c1aeb - implemented CPTableView's dataViewForTableColumn:row: delegate method
- implemented CPOutlineView's dataViewForTableColumn:item: delegate method
2010-02-01 19:00:48 +01:00
Randall Luecke cc74f941c6 Better "fix" for Safari breaking the outlineview... This bug still needs a reduction though. 2010-02-01 11:44:24 -05:00
Randall Luecke 775c1c1c8b Fixed the outline view again... 2010-02-01 11:11:51 -05:00
cacaodevandRandall Luecke 35a7456302 Fixes rows drawing when alternatingRowBackgroundColors > 2. TableTest showing 3 row colors 2010-02-01 10:59:23 -05:00
Klaas Pieter Annema 4006b35a5e fixed a bug where the outline view would send drag & drop datasource messages to it's datasource when they are not implemented 2010-02-01 12:39:22 +01:00
Tom Robinson b562280503 press cleanup 2010-02-01 02:33:41 -08:00
Klaas Pieter Annema e3a075a6a6 - implemented CPOutlineView drag & drop
- improved CPTableView drag & drop feedback
2010-02-01 11:22:57 +01:00
Klaas Pieter Annema 8c534c6d33 Merge branch 'outlineview' into jake 2010-02-01 11:17:15 +01:00
Klaas Pieter Annema 82be6c243c Merge branch 'jake' into enstore_jake
Conflicts:
	AppKit/CPTableView.j
2010-02-01 11:07:42 +01:00
Klaas Pieter Annema 5b8ee5dd1b Merge branch 'jake' of git://github.com/280north/cappuccino into jake
Conflicts:
	AppKit/CPTableView.j
2010-02-01 11:03:27 +01:00
Randall Luecke 050a132bd5 Initial documentation of CPTableView. 2010-02-01 03:40:09 -05:00
Randall Luecke 146bff6766 Initial documentation of CPTableView 2010-02-01 03:27:03 -05:00
Francisco Ryan Tolmasky I cd98bce331 Turned off logging by default, removed unecessary logs, and fixed bug where turning of logs broke the build.
Reviewed by me.
2010-01-31 23:59:58 -08:00
Randall Luecke a2d3723c7a Merge branch 'jake-table' into jake 2010-02-01 02:38:32 -05:00
Randall Luecke ecb88a87ad Added proper grid drawing for highlighted rows. Closing issues #369 Also fixing bug where top row would not draw its background when clipped 2010-02-01 02:33:04 -05:00
Ross Boucher 3f2813932a Merge branch 'jake' of git@github.com:280north/cappuccino into jake 2010-01-31 23:07:11 -08:00
Ross Boucher c2223e3942 Closes #429. This should actually resolve the issue by simply removing the potential race condition entirely. 2010-01-31 23:06:23 -08:00
Randall Luecke 2dc0839d36 Fixed bug where CPButtonBar would not display anything until resized. Closes issue #151. 2010-02-01 00:58:30 -05:00
Tom Robinson 97ef1d1781 Added persistent history to objj repl. 2010-01-31 19:41:58 -08:00
Francisco Ryan Tolmasky I e64a9a7ab9 Fix for objj command line tool not working.
Reviewed by me.
2010-01-31 18:36:36 -08:00
Francisco Ryan Tolmasky I d4f3f83212 Fix for nib2cib not working with new loader.
Reviewed by me.
2010-01-31 17:28:51 -08:00
Randall Luecke 1488f3ed58 Merge branch 'jake' of git://github.com/280north/cappuccino into jake 2010-01-31 19:02:20 -05:00
Randall Luecke 26945bde42 Removed commented out code and fixed a bug where the pressed state was still set when you drag the mouse from outside the bounds of the header and let go. 2010-01-31 18:58:32 -05:00
Ross Boucher c911dd8aa6 Slight order change. This really should not matter. 2010-01-31 15:37:06 -08:00
Ross Boucher 1c81e0eee0 Closes #429. Doesn't necessarily address the root cause however.
The problem stems from a bug in Safari which is allowing callbacks
to interrupt running code (which should be impossible in JavaScript).
The change essentially makes it so that in the case where this happens,
which is rare, we'll end up accidentally creating an extra iframe.
This isn't ideal, but it also isn't harmful, versus the current
situation where code will simply break.
2010-01-31 15:13:07 -08:00
Ross Boucher 5366713790 Closes #429. Doesn't necessarily address the root cause however.
The problem stems from a bug in Safari which is allowing callbacks
to interrupt running code (which should be impossible in JavaScript).
The change essentially makes it so that in the case where this happens,
which is rare, we'll end up accidentally creating an extra iframe.
This isn't ideal, but it also isn't harmful, versus the current
situation where code will simply break.
2010-01-31 15:07:23 -08:00
Ross Boucher e9940d060a Merge branch 'loader' of git@github.com:280north/cappuccino into loader 2010-01-31 14:01:32 -08:00
Ross Boucher 605e905f3e Missing a local assignment of the task variable in one of our jake additions. Causes failures on non cappuccino builds. 2010-01-31 14:00:12 -08:00
cacaodevandRandall Luecke 11d30566bf CPTableHeaderView: change background in -layoutSubviews instead of -setThemeState: ; Added a CPThemeStatePressed used privately, makes things easier for custom headers 2010-01-31 16:31:25 -05:00
Francisco Ryan Tolmasky I 0942f9fac3 Replaced instances of non-compressable words.
Reviewed by me.
2010-01-31 13:14:51 -08:00
Francisco Ryan Tolmasky I 7b303b6529 Removed unused functions.
Reviewed by me.
2010-01-31 12:48:26 -08:00
Ross Boucher 6a9040989d Merge branch 'jake' into loader 2010-01-31 12:32:41 -08:00
Ross Boucher 840e9c7671 When removing an item from the collection view, we now unconditionally unhighlight it.
We also reapply highlights after reloading finishes.

Closes #248.
2010-01-31 12:29:38 -08:00
Randall Luecke 1d9e2f8169 Changed drawn gradients to aristo art. 2010-01-31 01:55:45 -05:00
Francisco Ryan Tolmasky I 8c9f302b67 Added debug stuff.
Reviewed by me.
2010-01-30 21:08:18 -08:00
Ross Boucher 44f23cd8ac Merge branch 'loader' of git@github.com:280north/cappuccino into loader 2010-01-30 19:24:47 -08:00
Ross Boucher c88f781509 Fix for Cib connections not being available in IE. 2010-01-30 19:23:45 -08:00
Francisco Ryan Tolmasky I 3dc578d585 Fix for using setTimeout instead of setNativeTimeout and assuming bundled directories are themselves not bundles.
Reviewed by me.
2010-01-30 19:11:12 -08:00
Francisco Ryan Tolmasky I 238d8ff0be Merge branch 'jake' into loader 2010-01-30 18:09:17 -08:00
Francisco Ryan Tolmasky I ca5dd0071c Various IE fixes.
Reviewed by me.
2010-01-30 18:08:19 -08:00
cacaodevandRandall Luecke 86fa759f9f CPTableHeaderView.j: Gradient headers for canvas capable browsers | Bg images for others. Column selection with pressed state.
AppController.j:	Modified left table in TestTable to test column selection.
CPTableView.j:          Added missing ivar; Fixed -deselectRow|Column:
2010-01-30 13:05:48 -05:00
Francisco Ryan Tolmasky I 0bcf8a6626 Trailing comma fix.
Reviewed by me.
2010-01-30 01:14:32 -08:00
Francisco Ryan Tolmasky I d735cd98e7 Fix for FireFox not working.
Reviewed by me.
2010-01-30 00:35:59 -08:00
Francisco Ryan Tolmasky I e25a550d3f Merge branch 'cheese' into loader 2010-01-29 22:33:32 -08:00
Francisco Ryan Tolmasky I 8a2206656d Fix for responseXML not working correctly from remote.
Reviewed by me.
2010-01-29 22:31:34 -08:00
Ross Boucher ac68d670a2 Slight error in the sizing for the previous progress bar commit 2010-01-29 22:11:43 -08:00
Ross Boucher e6539bbed5 MHTML cache testing 2010-01-29 22:11:18 -08:00
Ross Boucher 9db0694677 Remove unused images. 2010-01-29 21:45:03 -08:00
Francisco Ryan Tolmasky I a4d73330cc Data URLs.
Reviewed by me.
2010-01-29 21:43:23 -08:00
Francisco Ryan Tolmasky I ea6a983e9b Merge branch 'jake' of git@github.com:280north/cappuccino into loader 2010-01-29 17:53:36 -08:00
Francisco Ryan Tolmasky I 79cd8603a2 Removed now unecessary CommonJS files.
Reviewed by me.
2010-01-29 16:37:53 -08:00
Francisco Ryan Tolmasky I 02cb054b71 Removed unused plist file.
Reviewed by me.
2010-01-29 16:21:27 -08:00
Ross Boucher 007cfd589f Merge branch 'jake' of git@github.com:280north/cappuccino into jake 2010-01-29 15:18:10 -08:00
Ross Boucher 90d24fd6bf Temporary update for progress indicators for 0.8 2010-01-29 15:17:21 -08:00
Francisco Ryan Tolmasky I 4b7310d0cb More consistent naming scheme.
Reviewed by me.
2010-01-29 15:16:22 -08:00
Francisco Ryan Tolmasky I 59660032e1 nib2cib fixes.
Reviewed by me.
2010-01-29 13:22:44 -08:00
Francisco Ryan Tolmasky I d9c47ec763 Updated environments and removed environment collections. Also creates separate files for different forms of spriting.
Reviewed by me.
2010-01-29 10:54:47 -08:00
Klaas Pieter Annema a18ea750a6 Fixed a bug where CPOutlineView would not call super's implementation of selectRowIndexes:byExtendingSelection: 2010-01-29 18:01:46 +01:00
Klaas Pieter AnnemaandRandall Luecke c423411639 made sure CPControl's trackMouse: doesn't eat mouse events when the tableview is in a drag session #431 2010-01-29 11:36:13 -05:00
Francisco Ryan Tolmasky I b5ad030e40 Further blend work.
Reviewed by me.
2010-01-29 08:04:00 -08:00
Klaas Pieter Annema bfdbe2a34a updated the collection view sample to actually move the dragged items 2010-01-29 16:46:56 +01:00
Klaas Pieter Annema ec5dcb47c9 - fixed a bug where the tableview would send the wrong concluded dropped row to it's datasource
- implemented CPCollectioView drop on behavior
2010-01-29 14:58:45 +01:00
Klaas Pieter Annema 436f1d1541 improved the way drop highlights are shown 2010-01-29 14:24:44 +01:00
Klaas Pieter Annema 05873a030f Merge branch 'jake' into enstore_jake 2010-01-29 12:19:59 +01:00
Klaas Pieter Annema 78083eea48 made sure CPControl's trackMouse: doesn't eat mouse events when the tableview is in a drag session #431 2010-01-29 12:14:08 +01:00
Klaas Pieter Annema 7715da02e7 Merge remote branch 'cappuccino/jake' into jake
Conflicts:
	AppKit/CPTableView.j
	AppKit/CPViewAnimation.j
2010-01-29 12:12:50 +01:00
Klaas Pieter Annema 6798a5777a added the cpoutlineview test app 2010-01-29 10:57:34 +01:00
Klaas Pieter Annema 2f3ad961e7 Merge remote branch 'cappuccino/jake' into enstore_jake
Conflicts:
	AppKit/CPTableView.j
2010-01-29 10:56:30 +01:00
Klaas Pieter Annema dba047187f improved the way a CPTableView renders the drag & drop highlight between rows 2010-01-29 10:47:49 +01:00
Ross Boucher 03e63f29dc Merge branch 'jake' of git@github.com:280north/cappuccino into jake 2010-01-29 00:13:33 -08:00
Ross Boucher b4cd9c4c45 Remove HTML5 drag and drop support from browsers. 2010-01-29 00:12:51 -08:00
Randall Luecke b9b2649db9 Cleaned up merge and removed unnessisary selectionIsChanging notification. 2010-01-29 01:37:57 -05:00
Derek HammerandRandall Luecke df98483b06 Removing extraneous selection did change notifications 2010-01-29 01:28:09 -05:00
cacaodevandRandall Luecke 37fbeaad02 CPTableView -dragViewForRowsWithIndexes:
- Change the way dragViewOffset is computed to conform to cocoa
- Drag exposed rows only
2010-01-29 01:22:38 -05:00
Francisco Ryan Tolmasky I 794d8a754c Make blendtask work with new system.
Reviewed by me.
2010-01-28 16:24:18 -08:00
Ross Boucher b081debf88 Missing #include for the platform header.
Closes #412.
2010-01-28 15:49:03 -08:00
Nicholas Small 36c6c9bfa6 Merge branch 'jake' of github.com:280north/cappuccino into jake 2010-01-28 17:59:08 -05:00
Nicholas Small bda5ea1c59 Rewrote CPFlashView implementation to be fully cross-browser and standards compliant. 2010-01-28 17:58:50 -05:00
Nicholas Small 5ccf6eefc0 Changed CPFlashMovie -fileName to -filename. 2010-01-28 17:58:08 -05:00
Francisco Ryan Tolmasky I 06261559fc Improvements for CommonJS.
Reviewed by me.
2010-01-28 14:19:23 -08:00
Klaas Pieter Annema 477d2f9d82 fixed the disclosure triangle highlighting behavior 2010-01-28 20:10:14 +01:00
Klaas Pieter Annema 0cb66ddc6e set the default CPTableColumn dataview's center vertical-alignment (because it looks better) 2010-01-28 18:52:01 +01:00
Klaas Pieter Annema 99df7f6acb - further implemented CPOutlineView drag & drop support
- implemented a work around in CPPlatformWindow+DOM.j for the javascript drop event never being fired
2010-01-28 16:54:50 +01:00
Tom Robinson 0791fa0ad3 Eliminate a couple accidental globals. 2010-01-28 00:18:40 -08:00
Tom Robinson 9811327672 press whitespace cleanup 2010-01-27 22:37:26 -08:00
Tom Robinson 60f2eaadf5 Modify press to inspect cibs for dependent classes. 2010-01-27 22:36:28 -08:00
Tom Robinson 5478c640cc Refactor of press's objj-analysis-tools in prep for inspecting cibs. 2010-01-27 22:35:19 -08:00
Tom Robinson 7fe3b115f1 Remove legacy image spriting code from press. 2010-01-27 20:46:35 -08:00
Tom Robinson 3ee63b754c Remove theme bundle loading in press for now. 2010-01-27 17:54:28 -08:00
Tom Robinson 378b6c12f3 Merge branch 'jake' of git@github.com:280north/cappuccino into jake 2010-01-27 17:54:03 -08:00
Tom Robinson ee5817e480 Cleanup objj arguments story. objj-executable and "objj path/to/main.j" are now consistent. 2010-01-27 17:53:05 -08:00
Ross Boucher a354b4acd5 Temporary fix for 0.8 for copy/paste behavior in CPTextField.
Closes #407.
2010-01-27 16:36:39 -08:00
Tom Robinson 8e87a4a941 Make bootstrap warning very explicit. 2010-01-27 10:17:36 -08:00
Francisco Ryan Tolmasky I 42712166e9 Added FileRequest abstraction on top of HTTPRequest to allow synchronous loading in CommonJS.
Reviewed by me.
2010-01-27 07:50:37 -08:00
Francisco Ryan Tolmasky I 2bc31de69d Removed alerts.
Reviewd by me.
2010-01-27 04:01:11 -08:00
Francisco Ryan Tolmasky I fcfeb29be5 Changed #define from RHINO to COMMONJS. Re-enabled recently added document-load-waiting.
Reviewed by me.
2010-01-27 03:58:49 -08:00
Francisco Ryan Tolmasky I a64a270e25 Merge branch 'jake' of git@github.com:280north/cappuccino into loader 2010-01-27 03:17:16 -08:00
Francisco Ryan Tolmasky I 96eebc7d1d Fix for accidentally removing Executable.fileDependencies.
Reviewed by me.
2010-01-27 03:16:46 -08:00
Francisco Ryan Tolmasky I 38fd675f51 Performance improvements and bug fixes.
Reviewed by me.
2010-01-27 02:55:56 -08:00
Tom Robinson 35adaee1bb Initial press cib analysis 2010-01-27 02:27:32 -08:00
Klaas Pieter Annema def314b5ad removed log statements from cptableview 2010-01-27 11:05:31 +01:00
Klaas Pieter Annema 913a18eaaf completed tableview merge 2010-01-27 10:40:51 +01:00
unknown d82b39de19 Remove filename causing problems on Windows as well as line endings in press. 2010-01-27 01:21:32 -08:00
Klaas Pieter Annema cde5d8709c Merge remote branch 'cappuccino/jake' into enstore_jake
Conflicts:
	AppKit/CPTableView.j
2010-01-27 10:08:48 +01:00
Francisco Ryan Tolmasky I ec210c49c5 Beginnings of new loader.
Reviewed by me.
2010-01-27 00:43:54 -08:00
Tom Robinson 07f320def9 Fixed jake tasks for pushing packages to package repo. 2010-01-27 00:08:42 -08:00
Tom Robinson f5fe15d6cb Merge branch 'jake' of git@github.com:280north/cappuccino into jake 2010-01-26 23:50:41 -08:00
Nicholas Small da146b0873 Move table view header resources into AppKit/Resources. 2010-01-26 10:53:07 -05:00
Paul BaumgartandRoss Boucher 3b7a77ae0c Minor fix: change emdash to regular hyphen. 2010-01-25 22:21:26 -08:00
tlrobinson 9cb1e28ad1 bootstrap option to install Cappuccino/Objective-J packages. 2010-01-25 20:43:37 -08:00
Ross Boucher 9db7701691 Fixes a bug when changing splitPane status for a CPSplitView.
Closes #419.
2010-01-25 17:03:24 -08:00
Tom Robinson 27aca4c84a bootstrap.sh warning about shell config 2010-01-25 14:19:30 -08:00
Tom Robinson 4e50244dca Handle more bootstrap.sh edge cases. 2010-01-25 14:14:34 -08:00
Tom Robinson 0c21724270 Give debug frameworks higher priority in objj. 2010-01-25 13:35:27 -08:00
Tom Robinson 09306aa2cd Fixed cplutil and updated to use args parser, added lint option, etc. 2010-01-25 12:49:11 -08:00
Randall Luecke 1170673b92 selection did change is no longer posted if selectionShouldChangeInTableView returns NO. Closes 372. Keyboard navigation in tableview now honors selectionShouldChange. 2010-01-24 20:01:58 -05:00
Ross Boucher 712a991c86 Fix a bug introduced by the new document.body code when opening a second platform window. 2010-01-24 15:48:25 -08:00
Ross Boucher e3cdcbc5ab Add CPSpaceKeyCode. Closes #424. 2010-01-24 15:24:59 -08:00
luddepandRoss Boucher 62379b21c1 Quick fix for @"Aristo" being hardcoded in CPAlert.j 2010-01-24 01:17:20 -08:00
Ross Boucher cfde67742c Merge branch 'jake' of git@github.com:280north/cappuccino into jake 2010-01-24 01:15:35 -08:00
Ross Boucher 9b01561127 Fix the collection view resizing behavior. 2010-01-24 01:15:10 -08:00
Randall Luecke fb89450b90 Refactored keyboard navigation for CPTableView 2010-01-24 03:39:58 -05:00
Ross Boucher 5a8d491f10 Check the Info.plist for a CPDefaultTheme key for the name of the default theme.
Closes #418.
2010-01-24 00:34:35 -08:00
Ross Boucher 7ffb44e394 Merge branch 'jake' of git@github.com:280north/cappuccino into jake 2010-01-24 00:10:28 -08:00
Ross Boucher 34a5d9e61b Fix spacing issues in CPViewAnimation. 2010-01-24 00:10:04 -08:00
Randall Luecke e1d43e3651 Merge branch 'jake-table' into jake 2010-01-24 02:39:31 -05:00
Klaas Pieter AnnemaandRandall Luecke c291ad83f1 Implemented visual feedback when dragging in CPTableView
Conflicts:

	AppKit/CPTableView.j
2010-01-24 02:37:25 -05:00
Klaas Pieter AnnemaandRoss Boucher c6a4eb28a8 added cpviewanimation 2010-01-23 23:31:40 -08:00
Randall Luecke dd4735026a Reset position of the tableview in tabletest 2010-01-24 02:31:01 -05:00
Ross Boucher dc0439227e Add an accessor for the filename on CPFlashMovie 2010-01-23 23:28:39 -08:00
Ross Boucher 00f470763f Make CPFlashMovie CPCoding compliant. 2010-01-23 18:08:45 -08:00
Klaas Pieter Annema 05b1cfca31 Merge branch 'jake_original' into jake
Conflicts:
	AppKit/CPTableView.j
2010-01-23 11:38:08 +01:00
cacaodevandRandall Luecke e40696a7af CPTableView: drag & drop improvements
- Default dragView containing dragged rows, works with discrete rows
- scroll-as-you-drag feature
- draggingEntered returns a drag operation. Rearranged a bit the code.
- fixed dragPoint/target row
- Modified test app so you can drag in both ways and also move indexes internally
2010-01-23 02:56:59 -05:00
Ross Boucher bc030c42d9 Merge branch 'jake' of git@github.com:280north/cappuccino into jake 2010-01-22 19:43:21 -08:00
Ross Boucher 7ce72a31c5 Rather than throwing out the entire cappuccino body, throw out a specific div if that div is available.
("cappuccino-body"). This let's external libraries, esp. flash ones, add things to the body without
Cappuccino getting rid of them as soon as the page loads.

Closes #421.
2010-01-22 19:40:33 -08:00
Tom Robinson cf8989938c Improved sizeOfString IE workaround 2010-01-22 18:38:25 -08:00
Klaas Pieter Annema e09b63183c added cpviewanimation 2010-01-22 20:44:58 +01:00
Klaas Pieter Annema 76717c7177 converted spaces to tabs 2010-01-22 20:37:17 +01:00
Klaas Pieter Annema 6749fa57ad started implementing CPOutlineView drag & drop support 2010-01-22 20:25:14 +01:00
Klaas Pieter Annema 050b75a2df Implemented visual feedback when dragging in CPTableView 2010-01-22 20:17:34 +01:00
Randall Luecke 3f730c94ce Merge branch 'jake' of git://github.com/280north/cappuccino into jake 2010-01-22 10:51:48 -05:00
Randall Luecke 22c931729b Removed additional references to disabled HUD scrollbar knobs. 2010-01-22 10:50:29 -05:00
Klaas Pieter Annema cb658826a3 Merge branch 'jake' into enstore_jake 2010-01-22 10:15:34 +01:00
Ross Boucher 3f8c311ea2 Bring windows forward when opening a sheet.
Closes #391.
2010-01-21 23:24:03 -08:00
Randall Luecke 22aa4d359e Hard coded header view resources into the CPTableView 2010-01-22 02:09:22 -05:00
Ross Boucher c2880ec8e4 Remove support for HTML5 drag and drop from Chrome, because it doesn't work.
We should eventually try and figure out a more specific test for this.
2010-01-21 23:02:12 -08:00
Ross Boucher 108822d4e1 Merge branch 'jake' of git@github.com:280north/cappuccino into jake 2010-01-21 22:33:06 -08:00
Randall Luecke f79a926b10 Removed references to disabled scroller knob in HUD CPScroller. 2010-01-22 01:22:03 -05:00
cacaodevandRoss Boucher 4eef234736 Fix a bug where drop was always failing in webkit nighties 2010-01-21 22:04:35 -08:00
Klaas Pieter Annema 5abbdfc094 Merge branch 'jake' into enstore_jake 2010-01-21 15:01:21 +01:00
Klaas Pieter Annema c44715bef4 added CPSpaceKeyCode to CPResponder 2010-01-21 11:59:28 +01:00
Randall Luecke b5f55100e9 Merge branch 'jake' of git://github.com/280north/cappuccino into jake 2010-01-20 23:19:18 -05:00
Tom Robinson 4e0404fce6 IE sizeOfString temporary fix. 2010-01-20 17:12:46 -08:00
Tom Robinson f1874eca8a Don't use sudo in jake install by default, add "sudo-install" task. 2010-01-20 15:18:51 -08:00
Tom Robinson 2e1d6f2412 Migrate to use INTERPRETER.Context 2010-01-19 16:58:41 -08:00
Tom Robinson 0395287906 Press bundle callbacks for theme/cib --flatten support. 2010-01-19 15:00:43 -08:00
Francisco Ryan Tolmasky I bda8a5fd6c Merge branch 'jake' of git@github.com:280north/cappuccino into jake 2010-01-19 14:46:05 -08:00
Alexander LjungbergandFrancisco Ryan Tolmasky I ded413481c Fixed: under certain circumstances controls would not be drawn despite a call to setNeedsDisplay:YES. A typical symptom of this was custom CPViews' drawRect never being called. The error was caused by _CPDisplayServer throwing away its remaining work whenever the display code of a control called setNeedsLayout. 2010-01-19 14:45:47 -08:00
Tom Robinson a5a6c07b08 Move manual tests to Manual sub dir 2010-01-19 13:16:16 -08:00
Nicholas Small 204df99375 Make CPPanel -becomesKeyOnlyIfNeeded and CPView -needsPanelToBecomeKey work. 2010-01-15 17:23:56 -05:00
Randall Luecke 55dd67a0ad Merge branch 'jake' of git://github.com/280north/cappuccino into jake 2010-01-14 15:02:53 -05:00
tlrobinson 6040ee4ffc Fixed args case "objj -Ifoo bar.j" 2010-01-14 12:01:51 -08:00
Randall Luecke 544ed99d98 Merge branch 'jake' of git://github.com/280north/cappuccino into jake 2010-01-14 14:26:02 -05:00
tlrobinson 7546640fba Correct the args parsing in objj to provide the script name at args[0] instead of "objj" 2010-01-14 11:24:39 -08:00
Francisco Ryan Tolmasky I daf5b88834 Merge branch 'jake' of git@github.com:280north/cappuccino into jake 2010-01-13 22:40:01 -08:00
Francisco Ryan Tolmasky I c36f975bbf More support for toolbar items and nib2cib. Added support for CPToolbarShowColorsItem.
Reviewed by me.
2010-01-13 22:39:15 -08:00
Scott KyleandRoss Boucher a5e34d9153 Added CGGeometry to CPTableColumn since it's called from sizeToFit 2010-01-13 20:08:00 -08:00
Ross Boucher 57a63440f9 Remove unnecessary comments. 2010-01-13 20:04:23 -08:00
Francisco Ryan Tolmasky I e25a227e4d Fix for updating target/action of toolbar items.
Reviewed by me.
2010-01-13 20:03:01 -08:00
Randall Luecke db7b340b32 Fixed outline view again after scoping fix. 2010-01-13 22:34:39 -05:00
Randall Luecke 7683755137 Fixed scoping issues with last commit. 2010-01-13 22:22:44 -05:00
Randall Luecke 8de71663c2 Fixes for the CPTableView drag operation (selection and drag and drop) after the nasty fix for the outlineview fix for Safari. 2010-01-13 21:30:10 -05:00
cacaodevandRandall Luecke 211a7c7939 Make built-in data views highlightable 2010-01-13 19:36:21 -05:00
Randall Luecke 82ce66af16 Further hack to fix the CPOutlineView which is broken in Safari. 2010-01-13 19:30:11 -05:00
Tom Robinson df4bc13122 A splash of color in the build tools... 2010-01-13 12:58:26 -08:00
Tom Robinson 8f3661d5a4 Partial support for theme/additional bundles in press. 2010-01-13 12:57:31 -08:00
Tom Robinson bb31ac11ca Delete OUTPUT_DIRECTORY if exists and --force on 2010-01-13 03:48:04 -08:00
Tom Robinson 4ef0065c66 Print identifiers in alphabetical order for clarity. 2010-01-13 03:46:27 -08:00
Tom Robinson 476d168a46 Merge branch 'jake' of github.com:280north/cappuccino into jake 2010-01-13 01:57:52 -08:00
Tom Robinson 093c6cdca3 More robust handing of string passed to CPURLRequest instead of CPURLs. 2010-01-13 01:57:04 -08:00
Tom Robinson 345f5e14de Refactor hardcoded Aristo.blend into CPApplication +defaultThemeName 2010-01-13 01:53:23 -08:00
Paul BaumgartandFrancisco Ryan Tolmasky I 5ddfef7eb7 Convert relative paths to absolute when specifying an install_directory for narwhal. 2010-01-13 00:57:44 -08:00
Francisco Ryan Tolmasky I 81d784b5dc Added missing license.
Reviewed by me.
2010-01-12 22:55:58 -08:00
Francisco Ryan Tolmasky I b0b9a7a294 Merge branch 'jake' of git@github.com:280north/cappuccino into jake 2010-01-12 22:55:50 -08:00
Francisco Ryan Tolmasky I e76ee3c96e A few more changes for CPToolbar nib2cib support and added beginnings of search field support.
Reviewed by me.
2010-01-12 22:54:35 -08:00
Francisco Ryan Tolmasky I 24b495ca43 Temporary fix for CPTableView being broken.
Reviewed by me.
2010-01-12 22:52:34 -08:00
Tom Robinson ff4fd1411e Add --force option, change shorthand --flatten to -l 2010-01-12 22:48:29 -08:00
Francisco Ryan Tolmasky I 03eed5f4f9 Got rid of unecessary code/files.
Reviewed by me.
2010-01-12 19:05:22 -08:00
Francisco Ryan Tolmasky I 1c89968b69 nib2cib support for the new CPToolbar/CPToolbarItem, also improved classes to pick up item property changes (i.e, setLabel:, setAction:, etc.) after the toolbar has been initialized
Conflicts:

	Tools/nib2cib/NSAppKit.j
	Tools/nib2cib/NSToolbarItem.j
2010-01-12 19:02:43 -08:00
Tom Robinson 01ce469a0f Convert objj-analysis-tools.j line endings to Unix style 2010-01-12 18:46:44 -08:00
Tom Robinson c6347a3cf1 Remove relativeToRootPath 2010-01-12 18:42:03 -08:00
Tom Robinson bf7e581445 Add URLMap to pressed --flattened bundles. 2010-01-12 17:24:20 -08:00
Tom Robinson 0fe9253d3b Add some git hooks 2010-01-12 13:05:05 -08:00
Tom Robinson 6a9042fd9c make narwhal-jsc version check optional 2010-01-12 13:01:11 -08:00
Tom Robinson 9e62fdc0b8 added missing CPNull imports 2010-01-12 12:28:32 -08:00
Tom Robinson a33b70f8bd Cleanup of common.jake to properly load built packages, etc. 2010-01-12 03:54:26 -08:00
Tom Robinson bfc06ed81f Merge branch 'jake' of github.com:280north/cappuccino into jake 2010-01-12 02:14:41 -08:00
Francisco Ryan Tolmasky I c3c8ac7ff0 Fix for missing parenthesis causing syntax error.
Reviewed by me.
2010-01-12 01:49:06 -08:00
Ross Boucher bfd0c00708 Merge branch 'jake' of git@github.com:280north/cappuccino into jake 2010-01-11 22:37:29 -08:00
Ross Boucher ef0c84072b Fix the platform identifying code.
Fix the longstanding IE refresh bug by ensuring document is ready.
Closes #98.
2010-01-11 22:33:08 -08:00
Nicholas Small 066972ff75 Some fixes for last commit. Thanks to Jesse Ross. 2010-01-11 16:43:49 -05:00
Nicholas Small 608853d4fa Added -setFlashVars: and -setParameters: to CPFlashView. Closes #59. 2010-01-11 14:13:05 -05:00
Francisco Ryan Tolmasky I 1774305c2d Merge branch 'jake' of git@github.com:280north/cappuccino into jake 2010-01-10 12:19:08 -08:00
Francisco Ryan Tolmasky I 3295966022 Updated Jake package version number.
Reviewed by me.
2010-01-10 12:18:13 -08:00
Randall Luecke 8f43f5a4a1 Added resource for drag and drop image. 2010-01-10 00:37:42 -06:00
Tom Robinson 379f40c1be Cleanup build dir checking, print deprecation warning for STEAM_BUILD 2010-01-09 15:35:31 -08:00
Randall Luecke c2282af879 Removed called to super on keyDown which was invoking a scroll in addition to calling scrollRowToVisible. 2010-01-09 14:21:07 -06:00
Tom Robinson d057b1909f Point to TextMate bundle 2010-01-08 15:36:36 -08:00
Ross Boucher 2ba4e99114 Merge commit 'luddep/font-improvements' into fonts 2010-01-08 09:43:39 -08:00
Ross Boucher f61a6ba5ff Fix an issue where _CPImageAndTextView, if it had an image, wouldn't show the image if it hadn't already been loaded. In other words, it now listens for image load events and redisplays. 2010-01-08 09:34:43 -08:00
luddep 34a6389a92 CPFont now supports multiple font families. Closes #255. 2010-01-08 18:05:33 +01:00
Francisco Ryan Tolmasky I b675adbbb0 Fix for text being gone in buttons.
Reviewed by me.
2010-01-08 04:03:48 -08:00
Ross Boucher e46da0e2f2 Merge branch 'jake' of git@github.com:280north/cappuccino into jake 2010-01-07 22:33:57 -08:00
Francisco Ryan Tolmasky I 44b257a749 Removed spaces at the end of lines.
Reviewed by me.
2010-01-07 22:23:32 -08:00
luddepandRoss Boucher fe2599eb35 buttons now momentarily go the the pressed state when clicked programmatically. Closes #187 2010-01-07 22:17:05 -08:00
Randall Luecke d791a189bc added support for HUD scroll bars 2010-01-08 00:15:32 -06:00
Randall Luecke bbc521a2f3 removed call to scrollRowToVisible: the bug is in clipviews and should not be fixed in the tableview itself. 2010-01-08 00:05:24 -06:00
Francisco Ryan Tolmasky I 56f6da606c Missing licenses on a few files.
Reviewed by me.
2010-01-07 19:33:28 -08:00
Francisco Ryan Tolmasky I 3e098b7479 Merge branch 'jake' of git@github.com:280north/cappuccino into jake 2010-01-07 19:30:53 -08:00
Francisco Ryan Tolmasky I 7e2fe6d5be Fix for white flash when loading Cappuccino apps.
Reviewed by boucher.
2010-01-07 19:30:17 -08:00
Randall Luecke c4b2cf9394 Patch for inline editing in CPTableView and clean up of doubleAction: 2010-01-07 20:35:27 -06:00
Randall Luecke 9ac823833a Fix for TableView drag being started while sometimes selecting 2010-01-07 19:42:31 -06:00
Francisco Ryan Tolmasky I 60132c085c Merge branch 'jake' of git@github.com:280north/cappuccino into jake 2010-01-07 17:12:41 -08:00
Francisco Ryan Tolmasky I 5e14e65eb0 Fix for CPArray test not passing.
Reviewed by me.
2010-01-07 16:36:25 -08:00
Randall Luecke 64063fb77d Support for drag and drop in TableTest 2010-01-07 18:31:59 -06:00
Randall Luecke aa309ef27c Implementation of drag and drop, auto resizing columns, keyboard support, scrollToVisible for columns and rows, double click action, deselectAll, and various other bug fixes and features. 2010-01-07 17:34:02 -06:00
Scott KyleandRoss Boucher 4c81c9e21e Fixed typo "Janurary" 2010-01-07 12:26:51 -08:00
Francisco Ryan Tolmasky I f4912eb23b Merge branch 'jake' of git@github.com:280north/cappuccino into jake 2010-01-06 22:51:31 -08:00
Francisco Ryan Tolmasky I 7f85b8b33f Tiny bit more support for toolbars in nib2cib.
Reviewed by me.
2010-01-06 21:08:01 -08:00
Tom Robinson 85c68f78da Update for compatibility with latest narwhal. Switch back to 280north/narwhal 2010-01-06 20:00:37 -08:00
Francisco Ryan Tolmasky I af03085d5f Fix for incorrect menu logic.
Reviewed by me.
2010-01-05 19:20:47 -08:00
Francisco Ryan Tolmasky I b7d747ee17 Fixed a bug in CPTreeNode's KVO implementation.
Reviewed by me.
2010-01-05 15:49:16 -08:00
Francisco Ryan Tolmasky I b6f100888a Merge branch 'jake' of git@github.com:280north/cappuccino into jake 2010-01-05 11:15:45 -08:00
Francisco Ryan Tolmasky I 3cfd392e3e Added new automatic undo API to CPUndoManager.
Added archiving support for CPTreeNode.

Reviewd by me.
2010-01-05 11:14:56 -08:00
Ross Boucher 7ed98a8655 Fix a typo pointed out by Bruno on the mailing list. 2010-01-05 09:50:02 -05:00
Ross Boucher d78eb4a4e5 Fix an undefined notification variable 2010-01-04 19:11:10 -05:00
Randall LueckeandRoss Boucher a3d168b646 left unnessisary line... whoops 2010-01-04 10:24:45 -05:00
Randall LueckeandRoss Boucher 5018df511b fix for window overlapping the menu bar if the user dragged it up there. 2010-01-04 10:24:38 -05:00
Ross Boucher 09345a9d53 Use a notificaiton rather than a direct call for windowDidResize:
Closes #393.
2010-01-04 10:21:16 -05:00
Francisco Ryan Tolmasky I 8b17cd3cde Merge branch 'jake' of git@github.com:280north/cappuccino into jake 2009-12-31 01:24:51 -08:00
Francisco Ryan Tolmasky I 403fcd8fff Preparing for options fix in Narhwal.
Reviewed by me.
2009-12-30 23:52:55 -08:00
tlrobinson 409be4020b Temporarily use tlrobinson/narwhal/master in bootstrap. 2009-12-29 13:35:48 -08:00
Nicholas Small 24801a220c Merge branch 'jake' of github.com:280north/cappuccino into jake 2009-12-26 19:12:31 -05:00
Nicholas Small 19b9f4e1c1 Enabling an accordion item will cause it to expand. 2009-12-26 19:11:33 -05:00
Francisco Ryan Tolmasky I 48d584df58 Fixed typo in setSubviews:.
Reviewed by me.
2009-12-26 01:20:16 -08:00
Francisco Ryan Tolmasky I dd999a29fd Added applyChange:toKeyPath: and inverseChangedDictionary to support "automatic" undo with KVO.
Reviewed by me.
2009-12-24 19:15:38 -08:00
Francisco Ryan Tolmasky I 75fdfb5a0b Improved observable arrays to support indexOfObject:, indexOfObjectIdenticalTo:, and removeObjectIdenticalTo:.
Reviewed by me.
2009-12-24 18:45:20 -08:00
Francisco Ryan Tolmasky I 6b4db4e9ae Merge branch 'jake' of git@github.com:280north/cappuccino into jake 2009-12-23 19:32:43 -08:00
Francisco Ryan Tolmasky I 2571b24f22 Removed TextMate and Xcode files since the ones being used now have their own repos. Linked to them in the README.
Reviewed by me.
2009-12-23 19:31:51 -08:00
Nicholas Small 855a9eea44 Merge branch 'jake' of github.com:280north/cappuccino into jake 2009-12-23 16:51:46 -05:00
Nicholas Small 189e299592 Added CPAccordionView -setEnabled:forItemAtIndex: 2009-12-23 16:50:56 -05:00
Ross Boucher 6cbaa35849 Add CPOperation to Foundation 2009-12-23 11:30:10 -05:00
Ross Boucher cb1cfa4d94 Better support for recursing in CPDictionaryWithJSObject: 2009-12-20 20:32:17 -05:00
Ross Boucher 5bbf893a37 Merge branch 'jake' of git@github.com:280north/cappuccino into jake 2009-12-20 20:11:59 -05:00
Ross Boucher 3ddbfb5dea Encode the header clip view in the CPCoder methods.
Closes 363.
2009-12-20 20:11:22 -05:00
Francisco Ryan Tolmasky I 5352d062d5 Fix for boundsOrigin and boundsSize being affected by bounds. Also changed UID to return a string instead of a Number.
Reviewed by me.
2009-12-20 17:02:06 -08:00
Randall LueckeandFrancisco Ryan Tolmasky I e15cbfca33 fix bug in CPPlatformWindow where the visible frame for the platform window would offset itself for the menu bar height, even though no menu bar would be displayed because it's not the primaryPlatformWindow 2009-12-20 15:44:39 -08:00
Francisco Ryan Tolmasky I 51b58f911e Merge branch 'jake' of git@github.com:280north/cappuccino into jake 2009-12-20 13:01:11 -08:00
Francisco Ryan Tolmasky I 7acfbb9eed Added [CPView setSubviews:] which allows you to add multiple subviews, remove multiple subviews, and reorder multple subviews.
Reviewed by me.
2009-12-20 13:00:25 -08:00
Ross Boucher 4bf9853a25 Merge branch 'jake' of git@github.com:280north/cappuccino into jake 2009-12-20 13:13:15 -05:00
Ross Boucher 58c6db0a8f Fix the logic behind CPURLConnection's _isLocalFileConnection 2009-12-20 13:12:29 -05:00
tlrobinson aed52a7829 Improved bootstrap.sh further. Prompt to delete existing installations, etc. 2009-12-19 23:16:37 -08:00
Ross Boucher a1e24a3f95 Fix a bug where keyPaths which had a component evaluating to self would send notifications containing the wrong keypath in the observation.
Includes test case.
2009-12-19 17:47:02 -05:00
Ross Boucher 11cff29916 Merge branch 'jake' of git@github.com:280north/cappuccino into jake 2009-12-19 15:32:52 -05:00
Ross Boucher f184b9bcc4 Add a few KVO tests around arrays 2009-12-19 15:32:23 -05:00
tlrobinson bab0024e0c Cleanup some build scripts 2009-12-19 04:31:11 -08:00
aburkhalterandtlrobinson deed92cff7 Toll-free bridge Error to CPException. Add rhinoException in objj_exception for better error reporting. 2009-12-19 03:49:22 -08:00
Francisco Ryan Tolmasky I a9bc949679 Actual fix for disabled items in CPMenu. Previous fix still selected disabled items and showed submenus for disabled items.
Reviewed by me.
2009-12-18 22:31:12 -08:00
Randall LueckeandRoss Boucher 1411410f4e fixed bug in CPMenu where action would be sent when the user clicked on a disabled menu item. 2009-12-18 18:43:03 -05:00
Ross Boucher 648fbe1b10 Add sendsActionOnEndEditing to the CPCoding methods for CPControl 2009-12-18 15:54:44 -05:00
Ross Boucher 7042f89620 Fix a return type error. Closes #358. 2009-12-17 00:57:09 -05:00
Ross Boucher e235fffb5e Correct HTML escaping and unescaping in Objective-J/plist. Closes 361. 2009-12-17 00:54:00 -05:00
Ross Boucher 6aadd13450 Update CPColorPanel to handle drag and drop correctly, which broke with native drag and drop. Closes 364. 2009-12-17 00:25:49 -05:00
Ross Boucher 349de098af Merge branch 'jake' of git@github.com:280north/cappuccino into jake
Conflicts:
	AppKit/CPMenuItem/CPMenuItem.j
2009-12-16 19:00:48 -05:00
Ross Boucher 5527e585f6 Make Windows handle key equivalents in menus correctly. Make the menu display the string properly on Windows too. 2009-12-16 18:58:21 -05:00
Francisco Ryan Tolmasky I a6e9814dfc Merge branch 'jake' of git@github.com:280north/cappuccino into jake 2009-12-16 15:03:27 -08:00
Francisco Ryan Tolmasky I f01a7d3933 Fix for menu items incorrectly leaving out shift symbol if the key equivalent is uppercase.
Reviewed by me.
2009-12-16 15:02:35 -08:00
Nicholas Small d2cd3b899f Fix CPTabViewItem -tabView. 2009-12-16 00:22:35 -05:00
Francisco Ryan Tolmasky I ac2c0d5d84 Update CPUndoManager to post checkpoint notifications and only create run loop performs if undos actually take place.
Reviewed by me.
2009-12-15 16:37:47 -08:00
Ross Boucher f0d0b512ca Merge branch 'jake' of git@github.com:280north/cappuccino into jake 2009-12-13 18:30:16 -08:00
Ross Boucher c859ffd0f7 Support for copy/paste/cut and selectedRange/setSelectedRange in CPTextField.
Improvements to the Pasteboard integration code from yesterday.
2009-12-13 18:29:25 -08:00
Tom Robinson 4eb57f3cc5 Merge branch 'jake' of github.com:280north/cappuccino into jake 2009-12-13 15:02:38 -08:00
Tom Robinson 6218bfaf9e Rewrite/cleanup of press. Incomplete, but press --flatten "works" for some value of "work". 2009-12-13 15:01:19 -08:00
Ross Boucher 4d5cdcaeae Fix for the pasteboard changes breaking everything. 2009-12-12 18:36:48 -08:00
Ross Boucher 6ad62a6f2f Add support for native pasteboards to webtop 2009-12-12 14:15:45 -08:00
Ross Boucher 37d4b151d7 Merge branch 'jake' of git@github.com:280north/cappuccino into jake 2009-12-11 16:55:36 -08:00
Ross Boucher 37c1d804f6 Fix for text shadows sometimes being the wrong color.
Closes #359.
2009-12-11 16:54:38 -08:00
Francisco Ryan Tolmasky I d200df3e9c Typo in last commit.
Reviewed by me.
2009-12-11 12:03:25 -08:00
Francisco Ryan Tolmasky I eb43e416ae Added CPProxy class to support better undo proxying in CPUndoManager.
Closes #370.
Closes #371.

Reviewed by me.
2009-12-11 11:38:26 -08:00
Francisco Ryan Tolmasky I e6244f71bd Merge branch 'jake' of git@github.com:280north/cappuccino into jake 2009-12-11 11:16:37 -08:00
Francisco Ryan Tolmasky I 403277ed06 Further refined KVO tests.
Reviewed by me.
2009-12-11 11:16:17 -08:00
Ross Boucher dbe8a59c3c Merge branch 'jake' of git@github.com:280north/cappuccino into jake 2009-12-11 10:58:40 -08:00
Ross Boucher a98de54db4 A few additions for pretty printing things and getting better error messages 2009-12-11 10:58:07 -08:00
Francisco Ryan Tolmasky I 7edb7266f2 Added test for old dependent values in KVO.
Reviewed by me.
2009-12-11 10:54:17 -08:00
Nicholas Small d14e077511 Make CPTableView selection notifications behave the same as in Cocoa. 2009-12-10 03:07:22 -05:00
Francisco Ryan Tolmasky I 211c14e316 Merge branch 'jake' of git@github.com:280north/cappuccino into jake 2009-12-07 18:59:57 -08:00
Francisco Ryan Tolmasky I 4fbc140551 Better descriptions for CPArray.
Reviewed by me.
2009-12-07 18:54:01 -08:00
Ross Boucher ee8e65c80d Fix for alt+character key events not propagating correctly.
Closes #354.
2009-12-05 16:58:26 -08:00
Ross Boucher 1db2e0282a Typo in the new platform window code for cursors 2009-12-04 18:41:57 -08:00
Ross Boucher 2351f73c76 Make the new cursor stuff work across platform windows 2009-12-04 18:07:53 -08:00
Ross Boucher 20a38c3aac Merge branch 'jake' of git@github.com:280north/cappuccino into jake 2009-12-04 16:49:22 -08:00
Ross Boucher bca25d0f5f Fix for windows being super floaty 2009-12-04 16:48:43 -08:00
Ross Boucher b26853e4d7 Fix for a path issue with non flattened source files in jake 2009-12-04 16:47:50 -08:00
Francisco Ryan Tolmasky I 39049f82fc Fix for nib2cib incorrectly requiring at least 2 arguments.
Reviewed by me.
2009-12-04 15:02:59 -08:00
Francisco Ryan Tolmasky I a30250f758 Merge branch 'menus' into jake
Closes #73.
Closes #75.
Closes #121.
Closes #130.
Closes #197.

Reviewed by me.
2009-12-04 12:39:49 -08:00
Francisco Ryan Tolmasky I 629737cda3 Apply positioning heuristics to +[CPMenu popUpMenu...] as well.
Reviewed by me.
2009-12-04 12:12:53 -08:00
Francisco Ryan Tolmasky I ec41411675 Fix for disabled menu item shadows, and slighlty better positioning for pop up menus.
Reviewed by me.
2009-12-04 11:55:01 -08:00
Francisco Ryan Tolmasky I becdf2bfeb Fix for menus not having the proper font.
Reviewed by me.
2009-12-04 11:35:40 -08:00
Ross Boucher 1e723945f8 Should have removed rather than commented out these lines 2009-12-04 11:25:20 -08:00
Ross Boucher dfb7599bb6 Remove the cursor hack from CPImageAndTextView, set the cursor globally to the default in CPApplication 2009-12-04 11:22:57 -08:00
Ross Boucher e1d3363ad9 A couple fixes to the CPCursor stuff 2009-12-04 11:12:13 -08:00
cacaodevandRoss Boucher c36c750c5d CPCursor implementation tested in WebKit/FF/IE/Opera. See comments in the file for more details. 2009-12-04 11:02:57 -08:00
Francisco Ryan Tolmasky I c7581c0847 Merge branch 'jake' into menus
Conflicts:
	AppKit/CPMenu.j
2009-12-03 22:50:13 -08:00
Ross Boucher 936d65291f Temporary fix until Francisco merges in the menu branch. 2009-12-03 19:31:52 -08:00
Francisco Ryan Tolmasky I a64030ad93 Merge branch 'jake' into menus 2009-12-03 19:25:38 -08:00
cacaodevandRoss Boucher 01d60ad4e9 CPSearchField changes from issue #194 2009-12-03 19:24:43 -08:00
Francisco Ryan Tolmasky I 06b64c6a87 Fix for a few edge cases, and added showsStateColumn support to nib2cib.
Reviewed by me.
2009-12-03 19:24:03 -08:00
Francisco Ryan Tolmasky I 0eff4e2bc0 Fix for moving to a base menu resetting the child menu.
Reviewed by me.
2009-12-03 17:58:49 -08:00
Ross Boucher 44d6139db2 Fix for some resizing issues in CPWebView. 2009-12-03 17:39:44 -08:00
Francisco Ryan Tolmasky I 506e3004b7 Merge branch 'jake' into menus 2009-12-03 17:02:02 -08:00
Francisco Ryan Tolmasky I 9ce4c7a468 Don't highlight items while scrolling.
Reviewed by me.
2009-12-03 16:59:10 -08:00
Ross Boucher 2fc724e469 Merge branch 'jake' of git@github.com:280north/cappuccino into jake 2009-12-03 16:29:46 -08:00
Ross Boucher afb69a7f03 Set the created window to not be at 0,0. We need real cascading support. 2009-12-03 16:29:08 -08:00
Ross Boucher cd2dd9f12d Remove dead variables 2009-12-03 16:28:56 -08:00
Francisco Ryan Tolmasky I 29963f74d6 Made menu positioning smarter.
Reviewed by me.
2009-12-03 16:24:35 -08:00
Francisco Ryan Tolmasky I 565a017ebd Merge branch 'jake' into menus 2009-12-03 11:21:35 -08:00
Derek HammerandFrancisco Ryan Tolmasky I 0b85847524 Adding reset to CPAppBootstrapper so that application can be restarted programmatically 2009-12-03 11:20:44 -08:00
Francisco Ryan Tolmasky I cfc46edfb8 Fix for properly positioning pop up button menus.
Reviewed by me.
2009-12-03 01:27:53 -08:00
Francisco Ryan Tolmasky I f250373673 Fix for actions not being sent in submenus.
Reviewed by me.
2009-12-03 00:42:13 -08:00
Francisco Ryan Tolmasky I b0acc13da7 Fix for exceptions when not on a menu item.
Reviewed by me.
2009-12-02 23:08:33 -08:00
Francisco Ryan Tolmasky I d705af8965 Added support for indentation levels in menu items.
Reviewed by me.
2009-12-02 20:41:52 -08:00
Francisco Ryan Tolmasky I a401dfddff Merge branch 'jake' into menus 2009-12-02 20:19:14 -08:00
Francisco Ryan Tolmasky I f579fd925e Fixed state columns not showing up.
Reviewed by me.
2009-12-02 20:18:25 -08:00
Ross Boucher e6d86eaa9b Throw an exception for -1 indexes in CPArray objectAtIndex: 2009-12-02 19:19:18 -08:00
Francisco Ryan Tolmasky I 348e45a5cd Some cleanup and a fix for custom views in menus.
Reviewed by me.
2009-12-02 18:40:47 -08:00
Ross Boucher 2120e9cf2a Potential fix for a drawing issue in IE. 2009-12-02 18:27:18 -08:00
Ross Boucher 3002acc895 Change for the way in which we detect full bridge window close 2009-12-02 18:26:55 -08:00
Francisco Ryan Tolmasky I 0b3c313280 Fix for highlight look in menu bars.
Reviewed by me.
2009-12-02 18:12:50 -08:00
Francisco Ryan Tolmasky I 982ab4b4fa Merge branch 'jake' into menus 2009-12-02 17:18:11 -08:00
Ross Boucher a0ee2f384b Merge branch 'jake' of git@github.com:280north/cappuccino into jake 2009-12-02 17:15:17 -08:00
Ross Boucher 56a739655f A whole bunch of textfield and key event fixes. 2009-12-02 17:14:47 -08:00
Francisco Ryan Tolmasky I 150ee44da0 Added background highlight to menu bar and fixed highligh turning off after stopping tracking in menu bar.
Reviewed by me.
2009-12-02 16:39:38 -08:00
Francisco Ryan Tolmasky I 78795e3167 Preliminary menu bar support.
Reviewed by me.
2009-12-02 15:57:52 -08:00
tlrobinson b0dd3cd818 Fix nib2cib. 2009-12-01 20:02:55 -08:00
Francisco Ryan Tolmasky I ef12ec54d7 Added new view for menu bar items.
Reviewed by me.
2009-12-01 19:19:24 -08:00
Francisco Ryan Tolmasky I 495b774965 A bit of cleanup.
Reviewed by me.
2009-12-01 17:49:15 -08:00
Ross Boucher 1381bb5c54 Prevent CPViewController from loading the same cibs lots of times. I think the solution should be made generic and put into CPCib though. Closes #348. 2009-12-01 09:25:49 -08:00
Ross Boucher f1d4794dd1 Merge branch 'jake' of git@github.com:280north/cappuccino into jake 2009-12-01 09:14:45 -08:00
Thomas BalthazarandRoss Boucher d58473c270 Fix for GHissue #348 : CPViewController should cache the cib 2009-12-01 09:14:30 -08:00
Francisco Ryan Tolmasky I 7adf32f36e Changed menu bar background image.
Reviewed by me.
2009-11-30 23:41:16 -08:00
Francisco Ryan Tolmasky I 5c3beb4160 Fix for _minimumWidth not being defined in the CPMenu class, resulting in minimum widths being applied globally, and menus appearing in strange places in desktop mode.
Reviewed by me.
2009-11-30 23:20:56 -08:00
Francisco Ryan Tolmasky I b82c307007 Added -setMinimumWidth/minimumWidth to CPMenu.
Reviewed by me.
2009-11-30 23:08:05 -08:00
Francisco Ryan Tolmasky I a7010e7598 Accidentally broke normal menu items.
Reviewed by me.
2009-11-30 22:43:36 -08:00
Francisco Ryan Tolmasky I f850cbf780 Better handling of submenu actions.
Reviewed by me.
2009-11-30 22:30:41 -08:00
Tom Robinson 4581fe4f22 Cleanup command line tool args (change objj to include command at args[0]) 2009-11-30 21:45:01 -08:00
Francisco Ryan Tolmasky I 35df54ae99 Merge branch 'jake' into menus 2009-11-30 21:29:27 -08:00
Francisco Ryan Tolmasky I f8a5f91687 Fix for nib2cib leaving cells as targets for menu items.
Reviewed by me.
2009-11-30 21:28:42 -08:00
Francisco Ryan Tolmasky I 4b71557584 Added -popUpMenuPositioningItem:atLocation:inView:callback: and began porting existing uses to it.
Reviewed by me.
2009-11-30 20:54:53 -08:00
Tom Robinson feda903f2f Remove unused junk 2009-11-30 18:45:40 -08:00
Tom Robinson 150e264f0d Remove bake. 2009-11-30 17:21:16 -08:00
Tom Robinson b592f6ae92 Remove submodules 2009-11-30 17:15:37 -08:00
Francisco Ryan Tolmasky I 37ba8fb57d Merge branch 'jake' into menus 2009-11-30 02:02:48 -08:00
Francisco Ryan Tolmasky I 72f80cdbed Cleaned up menu constraints.
Reviewed by me.
2009-11-30 02:01:44 -08:00
Francisco Ryan Tolmasky I c070f20669 Better constraint support, and better support for moving out of submenus.
Reviewed by me.
2009-11-29 19:54:15 -08:00
Ross Boucher a4d5165a3d Fix for style issues. 2009-11-26 19:53:36 -05:00
Abhinav GuptaandRoss Boucher 4fdddfb585 Fixed CPString's commonPrefixWithString to be faster. 2009-11-26 19:49:41 -05:00
Abhinav GuptaandRoss Boucher 0575e96b60 Added commonPrefixWithString method to CPString and tests for it. 2009-11-26 18:13:01 -05:00
Ross Boucher d0a8749986 Fix a type in CPOutlineView. Closes #265. 2009-11-25 00:09:55 -05:00
Ross Boucher 44fbf8afe2 Add support for encoding dates, courtesy of luddep. 2009-11-24 23:02:38 -05:00
Ross Boucher 1eb9202233 A few style guideline changes. 2009-11-24 22:56:18 -05:00
Alexander LjungbergandRoss Boucher b7da92d225 CPDate initWithString: now takes proper international format strings like NSDate. Similarly CPDate description generates such strings. 2009-11-24 22:42:02 -05:00
Ross Boucher e4f6d0db1f Fixes an issue with HUD style alert panels. Closes #343. 2009-11-24 22:13:20 -05:00
Ross Boucher 0a8bd9f687 Remove the "Cancelled" message that Safari shows when an XHR is cancelled during startup. Closes #344. 2009-11-24 18:38:25 -05:00
Ross Boucher f2608998f9 Fixes a typo in CPRectContainsRect by simply calling out to CGRectContainsRect. We should explore simply removing this method entirely. Includes test cases. Closes #345. 2009-11-24 18:30:31 -05:00
Ross Boucher ffb08d32ce Fix an issue with storing 0 in a CPSet. Includes test cases. Closes #337. 2009-11-24 16:06:32 -05:00
Francisco Ryan Tolmasky I 119e776ddc Make scrolling work in submenus.
Reviewed by me.
2009-11-23 23:35:58 -08:00
Francisco Ryan Tolmasky I 652930d5aa Merge branch 'jake' into menus 2009-11-22 16:43:43 -08:00
Francisco Ryan Tolmasky I e3babe97e4 Update to fix menu item sizes breaking on second open.
Reviewed by me.
2009-11-20 23:34:21 -08:00
Ross Boucher 72d01865ae Add about panel 2009-11-20 18:06:16 -08:00
Ross Boucher b9664681a3 Better error reporting for narwhal-jsc 2009-11-19 15:29:20 -08:00
Ross Boucher fd5c545189 Merge branch 'jake' of git@github.com:280north/cappuccino into jake 2009-11-19 14:54:51 -08:00
Ross Boucher 0639f4b00f Exit from subjake if the subjake returns non zero status code. Don't exit in the compiler (required for building in Atlas to not kill the process) 2009-11-19 14:48:18 -08:00
Tom Robinson ab49986238 Add --clone option to bootstrap, and prompt for location 2009-11-19 14:18:49 -08:00
Francisco Ryan Tolmasky I a4fdc50d1d Move these back into their own folders.
Reviewed by me.
2009-11-19 14:04:16 -08:00
Francisco Ryan Tolmasky I ed228b6183 Merge branch 'jake' into menus 2009-11-19 14:02:34 -08:00
Francisco Ryan Tolmasky I e0e675531a Temporarily move these out into the main folder.
Reviewed by me.
2009-11-19 14:02:16 -08:00
Francisco Ryan Tolmasky I 44e0879224 Merge branch 'jake' of git@github.com:280north/cappuccino into jake 2009-11-19 13:26:36 -08:00
Francisco Ryan Tolmasky I 1e6fa93ea2 Fix for NSScrollView breaking nib2cib.
Reviewed by me.
2009-11-19 13:26:02 -08:00
Tom Robinson 2aaed6bffd Replace outdated objj-executable with Narwhal magic. 2009-11-19 00:17:12 -08:00
Francisco Ryan Tolmasky I 2d367a8b47 Fix for not being able to drag window from spaces in toolbar.
Reviewed by me.
2009-11-18 22:08:57 -08:00
Francisco Ryan Tolmasky I 52c18abc5e Fix for class_addMethod with a root class.
Reviewed by me.
2009-11-18 21:56:10 -08:00
Ross Boucher 595c70ed56 Merge branch 'jake' of git@github.com:280north/cappuccino into jake 2009-11-18 14:28:33 -08:00
Alexander LjungbergandRoss Boucher 9faec8decd Fixed: calling setIsPaneSplitter: on a CPTableView would change the divider width but the subviews would not change size to match. 2009-11-18 14:22:58 -08:00
Tom Robinson 90dc1f6cf8 Reorder shell config file checks. 2009-11-18 01:34:01 -08:00
Francisco Ryan Tolmasky I ba01976151 Added target and action to radio groups.
Reviewed by me.
2009-11-17 19:52:20 -08:00
Francisco Ryan Tolmasky I 4d7f5a8a09 Fix for fixing state after turning setAllowsMixedState to NO.
Reviewed by me.
2009-11-17 19:17:58 -08:00
Ross Boucher 2d01fa6f94 Merge branch 'jake' of git@github.com:280north/cappuccino into jake 2009-11-17 17:04:12 -08:00
Ross Boucher 970f848b84 Make CPAlert slightly (but only slightly) more externally hackable 2009-11-17 17:03:42 -08:00
Tom Robinson 31feec0465 Flush stdin after writing file to ShrinkSafe process (fixes building in Rhino) 2009-11-17 17:02:07 -08:00
Francisco Ryan Tolmasky I 2466c14300 Merge branch 'jake' of git@github.com:280north/cappuccino into jake 2009-11-17 14:49:30 -08:00
Francisco Ryan Tolmasky I 49927fcfb7 Fix for building projects where source files are in nested subfolders.
Reviewed by me.
2009-11-17 14:46:54 -08:00
Ross Boucher f612683dfb Taking this out for now. 2009-11-17 10:26:58 -08:00
Ross Boucher 11e6ad2153 Adding a simple way to set a function for the target/action 2009-11-17 09:28:44 -08:00
Klaas Pieter AnnemaandRoss Boucher d041c69e0d Added a check if the window is loaded in CPWindowController 2009-11-17 09:19:05 -08:00
Randall LueckeandRoss Boucher b394052145 fixed tableview typo 2009-11-17 09:16:30 -08:00
Francisco Ryan Tolmasky I e94ddb4179 First pass at submenus.
Reviewed by me.
2009-11-12 18:20:16 -08:00
581 changed files with 35872 additions and 21079 deletions
+1
View File
@@ -4,3 +4,4 @@ Build
Demos
./Aristo
WebSite
.push-package
-12
View File
@@ -1,12 +0,0 @@
[submodule "External/narwhal"]
path = External/narwhal
url = git://github.com/tlrobinson/narwhal.git
[submodule "External/jack"]
path = External/jack
url = git://github.com/tlrobinson/jack.git
[submodule "External/browserjs"]
path = External/browserjs
url = git://github.com/tlrobinson/browserjs.git
[submodule "External/ojunit"]
path = External/ojunit
url = git://github.com/280north/ojunit.git
+5
View File
@@ -26,6 +26,7 @@
@import "CPApplication.j"
@import "CPBezierPath.j"
@import "CPBox.j"
@import "CPBrowser.j"
@import "CPButton.j"
@import "CPButtonBar.j"
@import "CPCheckBox.j"
@@ -43,6 +44,7 @@
@import "CPCompatibility.j"
@import "CPControl.j"
@import "CPCookie.j"
@import "CPCursor.j"
@import "CPDocument.j"
@import "CPDocumentController.j"
@import "CPEvent.j"
@@ -56,6 +58,7 @@
@import "CPMenu.j"
@import "CPMenuItem.j"
@import "CPOpenPanel.j"
@import "CPOutlineView.j"
@import "CPPanel.j"
@import "CPPasteboard.j"
@import "CPPopUpButton.j"
@@ -76,7 +79,9 @@
@import "CPTextField.j"
@import "CPToolbar.j"
@import "CPToolbarItem.j"
@import "CPTreeNode.j"
@import "CPView.j"
@import "CPViewAnimation.j"
@import "CPViewController.j"
@import "CPWebView.j"
@import "CPWindow.j"
+24 -4
View File
@@ -96,12 +96,12 @@
return _items;
}
- (void)addItem:(CPAccordionItem)anItem
- (void)addItem:(CPAccordionViewItem)anItem
{
[self insertItem:anItem atIndex:_items.length];
}
- (void)insertItem:(CPAccordionItem)anItem atIndex:(CPInteger)anIndex
- (void)insertItem:(CPAccordionViewItem)anItem atIndex:(CPInteger)anIndex
{
// FIXME: SHIFT ITEMS RIGHT
[_expandedItemIndexes addIndex:anIndex];
@@ -122,7 +122,7 @@
[self setNeedsLayout];
}
- (void)removeItem:(CPAccordionItem)anItem
- (void)removeItem:(CPAccordionViewItem)anItem
{
[self removeItemAtIndex:[_items indexOfObjectIdenticalTo:anItem]];
}
@@ -197,6 +197,20 @@
return indexSet;
}
- (void)setEnabled:(BOOL)isEnabled forItemAtIndex:(CPInteger)anIndex
{
var itemView = _itemViews[anIndex];
if (!itemView)
return;
if (!isEnabled)
[self collapseItemAtIndex:anIndex];
else
[self expandItemAtIndex:anIndex];
[itemView setEnabled:isEnabled];
}
- (void)_invalidateItemsStartingAtIndex:(CPInteger)anIndex
{
if (_dirtyItemIndex === CPNotFound)
@@ -301,6 +315,12 @@
[_headerView setStringValue:aLabel];
}
- (void)setEnabled:(BOOL)isEnabled
{
if ([_headerView respondsToSelector:@selector(setEnabled:)])
[_headerView setEnabled:isEnabled];
}
- (void)setContentView:(CPView)aView
{
if (_contentView === aView)
@@ -312,7 +332,7 @@
_contentView = aView;
[_contentView addObserver:self forKeyPath:@"frame" options:0 context:NULL];
[_contentView addObserver:self forKeyPath:@"frame" options:CPKeyValueObservingOptionOld | CPKeyValueObservingOptionNew context:NULL];
[self addSubview:_contentView];
+6 -2
View File
@@ -148,8 +148,9 @@ var CPAlertWarningImage,
var button = _buttons[i];
[button setFrameSize:CGSizeMake([button frame].size.width, (styleMask == CPHUDBackgroundWindowMask) ? 20.0 : 24.0)];
[button setBezelStyle:(styleMask & CPHUDBackgroundWindowMask) ? CPHUDBezelStyle : CPRoundedBezelStyle];
[button setTheme:(_windowStyle === CPHUDBackgroundWindowMask) ? [CPTheme themeNamed:"Aristo-HUD"] : [CPTheme defaultTheme]];
[[_alertPanel contentView] addSubview:button];
}
@@ -161,6 +162,7 @@ var CPAlertWarningImage,
[_messageLabel setFont:[CPFont boldSystemFontOfSize:13.0]];
[_messageLabel setLineBreakMode:CPLineBreakByWordWrapping];
[_messageLabel setAlignment:CPJustifiedTextAlignment];
[_messageLabel setAutoresizingMask:CPViewWidthSizable|CPViewHeightSizable];
_alertImageView = [[CPImageView alloc] initWithFrame:CGRectMake(15.0, 12.0, 32.0, 32.0)];
}
@@ -262,7 +264,9 @@ var CPAlertWarningImage,
[button setTag:_buttonCount];
[button setAction:@selector(_notifyDelegate:)];
[button setBezelStyle:(_windowStyle == CPHUDBackgroundWindowMask) ? CPHUDBezelStyle : CPRoundRectBezelStyle];
[button setTheme:(_windowStyle === CPHUDBackgroundWindowMask) ? [CPTheme themeNamed:"Aristo-HUD"] : [CPTheme defaultTheme]];
[button setAutoresizingMask:CPViewMinXMargin | CPViewMinYMargin];
[[_alertPanel contentView] addSubview:button];
if (_buttonCount == 0)
+412 -201
View File
@@ -31,6 +31,7 @@
@import "CPCibLoading.j"
@import "CPPlatform.j"
#include "Platform/Platform.h"
var CPMainCibFile = @"CPMainCibFile",
CPMainCibFileHumanFriendly = @"Main cib file base name";
@@ -40,6 +41,10 @@ CPApp = nil;
CPApplicationWillFinishLaunchingNotification = @"CPApplicationWillFinishLaunchingNotification";
CPApplicationDidFinishLaunchingNotification = @"CPApplicationDidFinishLaunchingNotification";
CPApplicationWillTerminateNotification = @"CPApplicationWillTerminateNotification";
CPApplicationWillBecomeActiveNotification = @"CPApplicationWillBecomeActiveNotification";
CPApplicationDidBecomeActiveNotification = @"CPApplicationDidBecomeActiveNotification";
CPApplicationWillResignActiveNotification = @"CPApplicationWillResignActiveNotification";
CPApplicationDidResignActiveNotification = @"CPApplicationDidResignActiveNotification";
CPTerminateNow = YES;
CPTerminateCancel = NO;
@@ -49,7 +54,7 @@ CPRunStoppedResponse = -1000;
CPRunAbortedResponse = -1001;
CPRunContinuesResponse = -1002;
/*!
/*!
@ingroup appkit
@class CPApplication
@@ -57,7 +62,7 @@ CPRunContinuesResponse = -1002;
Every GUI application has exactly one instance of CPApplication (or of a custom subclass of
CPApplication). Your program's main() function can create that instance by calling the
\c CPApplicationMain function. A simple example looks like this:
<pre>
function main(args, namedArgs)
{
@@ -77,25 +82,32 @@ CPRunContinuesResponse = -1002;
@implementation CPApplication : CPResponder
{
CPArray _eventListeners;
CPEvent _currentEvent;
CPArray _windows;
CPWindow _keyWindow;
CPWindow _mainWindow;
CPWindow _previousKeyWindow;
CPWindow _previousMainWindow;
CPMenu _mainMenu;
CPDocumentController _documentController;
CPModalSession _currentSession;
//
id _delegate;
BOOL _finishedLaunching;
BOOL _isActive;
CPDictionary _namedArgs;
CPArray _args;
CPString _fullArgsString;
CPImage _applicationIconImage;
CPPanel _aboutPanel;
}
/*!
@@ -107,7 +119,7 @@ CPRunContinuesResponse = -1002;
{
if (!CPApp)
CPApp = [[CPApplication alloc] init];
return CPApp;
}
@@ -119,73 +131,18 @@ CPRunContinuesResponse = -1002;
- (id)init
{
self = [super init];
CPApp = self;
if (self)
{
_eventListeners = [];
_windows = [];
[_windows addObject:nil];
// FIXME: This should be read from the cib.
_mainMenu = [[CPMenu alloc] initWithTitle:@"MainMenu"];
// FIXME: We should implement autoenabling.
[_mainMenu setAutoenablesItems:NO];
var bundle = [CPBundle bundleForClass:[CPApplication class]],
newMenuItem = [[CPMenuItem alloc] initWithTitle:@"New" action:@selector(newDocument:) keyEquivalent:@"N"];
[newMenuItem setImage:[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPApplication/New.png"] size:CGSizeMake(16.0, 16.0)]];
[newMenuItem setAlternateImage:[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPApplication/NewHighlighted.png"] size:CGSizeMake(16.0, 16.0)]];
[_mainMenu addItem:newMenuItem];
var openMenuItem = [[CPMenuItem alloc] initWithTitle:@"Open" action:@selector(openDocument:) keyEquivalent:@"O"];
[openMenuItem setImage:[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPApplication/Open.png"] size:CGSizeMake(16.0, 16.0)]];
[openMenuItem setAlternateImage:[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPApplication/OpenHighlighted.png"] size:CGSizeMake(16.0, 16.0)]];
[_mainMenu addItem:openMenuItem];
var saveMenu = [[CPMenu alloc] initWithTitle:@"Save"],
saveMenuItem = [[CPMenuItem alloc] initWithTitle:@"Save" action:@selector(saveDocument:) keyEquivalent:nil];
[saveMenuItem setImage:[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPApplication/Save.png"] size:CGSizeMake(16.0, 16.0)]];
[saveMenuItem setAlternateImage:[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPApplication/SaveHighlighted.png"] size:CGSizeMake(16.0, 16.0)]];
[saveMenu addItem:[[CPMenuItem alloc] initWithTitle:@"Save" action:@selector(saveDocument:) keyEquivalent:@"S"]];
[saveMenu addItem:[[CPMenuItem alloc] initWithTitle:@"Save As" action:@selector(saveDocumentAs:) keyEquivalent:nil]];
[saveMenuItem setSubmenu:saveMenu];
[_mainMenu addItem:saveMenuItem];
var editMenuItem = [[CPMenuItem alloc] initWithTitle:@"Edit" action:nil keyEquivalent:nil],
editMenu = [[CPMenu alloc] initWithTitle:@"Edit"],
undoMenuItem = [[CPMenuItem alloc] initWithTitle:@"Undo" action:@selector(undo:) keyEquivalent:CPUndoKeyEquivalent],
redoMenuItem = [[CPMenuItem alloc] initWithTitle:@"Redo" action:@selector(redo:) keyEquivalent:CPRedoKeyEquivalent];
[undoMenuItem setKeyEquivalentModifierMask:CPUndoKeyEquivalentModifierMask];
[redoMenuItem setKeyEquivalentModifierMask:CPRedoKeyEquivalentModifierMask];
[editMenu addItem:undoMenuItem];
[editMenu addItem:redoMenuItem];
[editMenu addItem:[[CPMenuItem alloc] initWithTitle:@"Cut" action:@selector(cut:) keyEquivalent:@"X"]],
[editMenu addItem:[[CPMenuItem alloc] initWithTitle:@"Copy" action:@selector(copy:) keyEquivalent:@"C"]],
[editMenu addItem:[[CPMenuItem alloc] initWithTitle:@"Paste" action:@selector(paste:) keyEquivalent:@"V"]];
[editMenuItem setSubmenu:editMenu];
[editMenuItem setHidden:YES];
[_mainMenu addItem:editMenuItem];
[_mainMenu addItem:[CPMenuItem separatorItem]];
}
return self;
}
@@ -201,37 +158,46 @@ CPRunContinuesResponse = -1002;
{
if (_delegate == aDelegate)
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)
{
[defaultCenter
removeObserver:_delegate
name:CPApplicationWillFinishLaunchingNotification
object:self];
var index = 0;
[defaultCenter
removeObserver:_delegate
name:CPApplicationDidFinishLaunchingNotification
object:self];
for (; index < count; index += 2)
{
var notificationName = delegateNotifications[index],
selector = delegateNotifications[index + 1];
if ([_delegate respondsToSelector:selector])
[defaultCenter removeObserver:_delegate name:notificationName object:self];
}
}
_delegate = aDelegate;
if ([_delegate respondsToSelector:@selector(applicationWillFinishLaunching:)])
[defaultCenter
addObserver:_delegate
selector:@selector(applicationWillFinishLaunching:)
name:CPApplicationWillFinishLaunchingNotification
object:self];
if ([_delegate respondsToSelector:@selector(applicationDidFinishLaunching:)])
[defaultCenter
addObserver:_delegate
selector:@selector(applicationDidFinishLaunching:)
name:CPApplicationDidFinishLaunchingNotification
object:self];
var index = 0;
for (; index < count; index += 2)
{
var notificationName = delegateNotifications[index],
selector = delegateNotifications[index + 1];
if ([_delegate respondsToSelector:selector])
[defaultCenter addObserver:_delegate selector:selector name:notificationName object:self];
}
}
/*!
@@ -250,27 +216,35 @@ CPRunContinuesResponse = -1002;
*/
- (void)finishLaunching
{
// At this point we clear the window.status to eliminate Safari's "Cancelled" error message
// The message shouldn't be displayed, because only an XHR is cancelled, but it is a usability issue.
// We do it here so that applications can change it in willFinish or didFinishLaunching
window.status = " ";
// We also want to set the default cursor on the body, so that buttons and things don't have an iBeam
[[CPCursor arrowCursor] set];
var bundle = [CPBundle mainBundle],
types = [bundle objectForInfoDictionaryKey:@"CPBundleDocumentTypes"];
if ([types count] > 0)
_documentController = [CPDocumentController sharedDocumentController];
var delegateClassName = [bundle objectForInfoDictionaryKey:@"CPApplicationDelegateClass"];
if (delegateClassName)
{
var delegateClass = objj_getClass(delegateClassName);
if (delegateClass)
if ([_documentController class] == delegateClass)
[self setDelegate:_documentController];
else
[self setDelegate:[[delegateClass alloc] init]];
}
var defaultCenter = [CPNotificationCenter defaultCenter];
[defaultCenter
postNotificationName:CPApplicationWillFinishLaunchingNotification
object:self];
@@ -302,11 +276,92 @@ CPRunContinuesResponse = -1002;
- (void)terminate:(id)aSender
{
[[CPDocumentController sharedDocumentController] closeAllDocumentsWithDelegate:self
didCloseAllSelector:@selector(_documentController:didCloseAll:context:)
contextInfo:nil];
[[CPNotificationCenter defaultCenter]
postNotificationName:CPApplicationWillTerminateNotification
object:self];
if (![CPPlatform isBrowser])
{
[[CPDocumentController sharedDocumentController] closeAllDocumentsWithDelegate:self
didCloseAllSelector:@selector(_documentController:didCloseAll:context:)
contextInfo:nil];
}
else
{
[[[self keyWindow] platformWindow] _propagateCurrentDOMEvent:YES];
}
}
- (void)setApplicationIconImage:(CPImage)anImage
{
_applicationIconImage = anImage;
}
- (CPImage)applicationIconImage
{
if (_applicationIconImage)
return _applicationIconImage;
var imagePath = [[CPBundle mainBundle] objectForInfoDictionaryKey:@"CPApplicationIcon"];
if (imagePath)
_applicationIconImage = [[CPImage alloc] initWithContentsOfFile:imagePath];
return _applicationIconImage;
}
- (void)orderFrontStandardAboutPanel:(id)sender
{
[self orderFrontStandardAboutPanelWithOptions:nil];
}
- (void)orderFrontStandardAboutPanelWithOptions:(CPDictionary)options
{
if (!_aboutPanel)
{
var mainInfo = [[CPBundle mainBundle] infoDictionary],
applicationTitle = [options objectForKey:"ApplicationName"] || [mainInfo objectForKey:@"CPBundleName"],
applicationIcon = [options objectForKey:@"ApplicationIcon"] || [self applicationIconImage],
version = [options objectForKey:@"Version"] || [mainInfo objectForKey:@"CPBundleVersion"],
applicationVersion = [options objectForKey:@"ApplicationVersion"] || [mainInfo objectForKey:@"CPBundleShortVersionString"],
copyright = [options objectForKey:@"Copyright"] || [mainInfo objectForKey:@"CPHumanReadableCopyright"];
var aboutPanelController = [[CPWindowController alloc] initWithWindowCibName:@"AboutPanel"],
aboutPanel = [aboutPanelController window],
contentView = [aboutPanel contentView],
imageView = [contentView viewWithTag:1],
applicationLabel = [contentView viewWithTag:2],
versionLabel = [contentView viewWithTag:3],
copyrightLabel = [contentView viewWithTag:4],
standardPath = [[CPBundle bundleForClass:[self class]] pathForResource:@"standardApplicationIcon.png"];
// FIXME move this into the CIB eventually
[applicationLabel setFont:[CPFont boldSystemFontOfSize:14.0]];
[applicationLabel setAlignment:CPCenterTextAlignment];
[versionLabel setAlignment:CPCenterTextAlignment];
[copyrightLabel setAlignment:CPCenterTextAlignment];
[imageView setImage:applicationIcon || [[CPImage alloc] initWithContentsOfFile:standardPath
size:CGSizeMake(256, 256)]];
[applicationLabel setStringValue:applicationTitle || ""];
if (applicationVersion && version)
[versionLabel setStringValue:@"Version " + applicationVersion + " (" + version + ")"];
else if (applicationVersion || version)
[versionLabel setStringValue:@"Version " + (applicationVersion || version)];
else
[versionLabel setStringValue:@""];
[copyrightLabel setStringValue:copyright || ""];
[aboutPanel center];
_aboutPanel = aboutPanel;
}
[_aboutPanel orderFront:self];
}
- (void)_documentController:(NSDocumentController *)docController didCloseAll:(BOOL)didCloseAll context:(Object)info
{
// callback method for terminate:
@@ -330,7 +385,27 @@ CPRunContinuesResponse = -1002;
- (void)activateIgnoringOtherApps:(BOOL)shouldIgnoreOtherApps
{
[self _willBecomeActive];
[CPPlatform activateIgnoringOtherApps:shouldIgnoreOtherApps];
_isActive = YES;
[self _willResignActive];
}
- (void)deactivate
{
[self _willResignActive];
[CPPlatform deactivate];
_isActive = NO;
[self _didResignActive];
}
- (void)isActive
{
return _isActive;
}
- (void)hideOtherApplications:(id)aSender
@@ -369,10 +444,10 @@ CPRunContinuesResponse = -1002;
return;
// raise exception;
}
_currentSession._state = aCode;
_currentSession = _currentSession._previous;
// if (aCode == CPRunAbortedResponse)
[self _removeRunModalLoop];
}
@@ -381,12 +456,12 @@ CPRunContinuesResponse = -1002;
- (void)_removeRunModalLoop
{
var count = _eventListeners.length;
while (count--)
if (_eventListeners[count]._callback === _CPRunModalLoop)
{
_eventListeners.splice(count, 1);
return;
}
}
@@ -424,12 +499,12 @@ CPRunContinuesResponse = -1002;
{
aModalSession._previous = _currentSession;
_currentSession = aModalSession;
var theWindow = aModalSession._window;
[theWindow center];
[theWindow makeKeyAndOrderFront:self];
// [theWindow._bridge _obscureWindowsBelowModalWindow];
[CPApp setCallback:_CPRunModalLoop forNextEventMatchingMask:CPAnyEventMask untilDate:nil inMode:0 dequeue:NO];
@@ -443,7 +518,7 @@ CPRunContinuesResponse = -1002;
{
if (!_currentSession)
return nil;
return _currentSession._window;
}
@@ -462,18 +537,33 @@ CPRunContinuesResponse = -1002;
{
_currentEvent = anEvent;
var willPropagate = [[[anEvent window] platformWindow] _willPropagateCurrentDOMEvent];
// temporarily pretend we won't propagate the event. we'll restore the saved value later
// we do this outside the if so that changes user code might make in _handleKeyEquiv. are preserved
[[[anEvent window] platformWindow] _propagateCurrentDOMEvent:NO];
// Check if this is a candidate for key equivalent...
if ([anEvent _couldBeKeyEquivalent] && [self _handleKeyEquivalent:anEvent])
{
[[[anEvent window] platformWindow] _propagateCurrentDOMEvent:NO];
var characters = [anEvent characters],
modifierFlags = [anEvent modifierFlags];
// Unconditionally propagate on these keys to solve browser copy paste bugs
if ((characters == "c" || characters == "x" || characters == "v") && (modifierFlags & CPPlatformActionKeyMask))
[[[anEvent window] platformWindow] _propagateCurrentDOMEvent:YES];
return;
}
// if we make it this far, then restore the original willPropagate value
[[[anEvent window] platformWindow] _propagateCurrentDOMEvent:willPropagate];
if (_eventListeners.length)
{
if (_eventListeners[_eventListeners.length - 1]._mask & (1 << [anEvent type]))
_eventListeners.pop()._callback(anEvent);
return;
}
@@ -520,6 +610,14 @@ CPRunContinuesResponse = -1002;
return _windows;
}
/*!
Returns an array of visible CPWindow objects, ordered by their front to back order on the screen.
*/
- (CPArray)orderedWindows
{
return CPWindowObjectList();
}
- (void)hide:(id)aSender
{
[CPPlatform hide:self];
@@ -559,16 +657,6 @@ CPRunContinuesResponse = -1002;
[[CPColorPanel sharedColorPanel] orderFront:self];
}
- (void)orderFrontStandardAboutPanel:(id)aSender
{
[self orderFrontStandardAboutPanelWithOptions:nil];
}
- (void)orderFrontStandardAboutPanelWithOptions:(CPDictionary)aDictionary
{
// FIXME: Implement.
}
// Posting Actions
/*!
Tries to perform the action with an argument. Performs
@@ -586,11 +674,11 @@ CPRunContinuesResponse = -1002;
if ([super tryToPerform:anAction with:anObject])
return YES;
if([_delegate respondsToSelector:anAction])
{
[_delegate performSelector:anAction withObject:anObject];
return YES;
}
@@ -607,12 +695,12 @@ CPRunContinuesResponse = -1002;
- (BOOL)sendAction:(SEL)anAction to:(id)aTarget from:(id)aSender
{
var target = [self targetForAction:anAction to:aTarget from:aSender];
if (!target)
return NO;
[target performSelector:anAction withObject:aSender];
return YES;
}
@@ -631,10 +719,10 @@ CPRunContinuesResponse = -1002;
{
if (!anAction)
return nil;
if (aTarget)
return aTarget;
return [self targetForAction:anAction];
}
@@ -659,36 +747,35 @@ CPRunContinuesResponse = -1002;
{
var responder = [aWindow firstResponder],
checkWindow = YES;
while (responder)
{
if ([responder respondsToSelector:anAction])
return responder;
if (responder == aWindow)
checkWindow = NO;
responder = [responder nextResponder];
}
if (checkWindow && [aWindow respondsToSelector:anAction])
return aWindow;
var delegate = [aWindow delegate];
if ([delegate respondsToSelector:anAction])
return delegate;
var windowController = [aWindow windowController];
if ([windowController respondsToSelector:anAction])
return windowController;
var theDocument = [windowController document];
if (theDocument != delegate && [theDocument respondsToSelector:anAction])
if (theDocument !== delegate && [theDocument respondsToSelector:anAction])
return theDocument;
return nil;
}
@@ -697,7 +784,7 @@ CPRunContinuesResponse = -1002;
Checks for a target in the following order:
<ol>
<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 application delegate</li>
<li>the document controller</li>
@@ -710,34 +797,32 @@ CPRunContinuesResponse = -1002;
{
if (!anAction)
return nil;
var target = [self _targetForWindow:[self keyWindow] action:anAction];
if (target)
return target;
target = [self _targetForWindow:[self mainWindow] action:anAction];
if (target)
return target;
if ([self respondsToSelector:anAction])
return self;
if ([_delegate respondsToSelector:anAction])
return _delegate;
if ([_documentController respondsToSelector:anAction])
return _documentController;
return nil;
}
- (void)setCallback:(Function)aCallback forNextEventMatchingMask:(unsigned int)aMask untilDate:(CPDate)anExpiration inMode:(CPString)aMode dequeue:(BOOL)shouldDequeue
{
_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
@@ -761,29 +846,30 @@ CPRunContinuesResponse = -1002;
@param aContextInfo
*/
- (void)beginSheet:(CPWindow)aSheet modalForWindow:(CPWindow)aWindow modalDelegate:(id)aModalDelegate didEndSelector:(SEL)aDidEndSelector contextInfo:(id)aContextInfo
{
{
var styleMask = [aSheet styleMask];
if (!(styleMask & CPDocModalWindowMask))
{
[CPException raise:CPInternalInconsistencyException reason:@"Currently only CPDocModalWindowMask style mask is supported for attached sheets"];
return;
}
[aWindow orderFront:self];
[aWindow _attachSheet:aSheet modalDelegate:aModalDelegate didEndSelector:aDidEndSelector contextInfo:aContextInfo];
}
- (void)endSheet:(CPWindow)sheet returnCode:(int)returnCode
{
var count = [_windows count];
while (--count >= 0)
{
var aWindow = [_windows objectAtIndex:count];
var context = aWindow._sheetContext;
if (context != nil && context["sheet"] === sheet)
{
context["returnCode"] = returnCode;
context["returnCode"] = returnCode;
[aWindow _detachSheetWindow];
return;
}
@@ -795,12 +881,11 @@ CPRunContinuesResponse = -1002;
[self endSheet:sheet returnCode:0];
}
- (CPArray)arguments
{
if(_fullArgsString != window.location.hash)
if(_fullArgsString !== window.location.hash)
[self _reloadArguments];
return _args;
}
@@ -810,33 +895,39 @@ CPRunContinuesResponse = -1002;
{
_args = [];
window.location.hash = @"#";
return;
}
if([args class] != CPArray)
args = [CPArray arrayWithObject:args];
_args = args;
var toEncode = [_args copy];
for(var i=0, count = toEncode.length; i<count; i++)
toEncode[i] = encodeURIComponent(toEncode[i]);
var hash = [toEncode componentsJoinedByString:@"/"];
window.location.hash = @"#" + hash;
}
- (void)_reloadArguments
{
_fullArgsString = window.location.hash;
var args = _fullArgsString.replace("#", "").split("/").slice(0);
for(var i=0, count = args.length; i<count; i++)
args[i] = decodeURIComponent(args[i]);
_args = args;
if (_fullArgsString.length)
{
var args = _fullArgsString.substring(1).split("/");
for (var i = 0, count = args.length; i < count; i++)
args[i] = decodeURIComponent(args[i]);
_args = args;
}
else
_args = [];
}
- (CPDictionary)namedArguments
@@ -858,10 +949,71 @@ CPRunContinuesResponse = -1002;
return !![_documentController openDocumentWithContentsOfURL:aURL display:YES error:NULL];
}
- (void)_willBecomeActive
{
[[CPNotificationCenter defaultCenter] postNotificationName:CPApplicationWillBecomeActiveNotification
object:self
userInfo:nil];
}
- (void)_didBecomeActive
{
if (![self keyWindow] && _previousKeyWindow &&
[[self windows] indexOfObjectIdenticalTo:_previousKeyWindow] !== CPNotFound)
[_previousKeyWindow makeKeyWindow];
if (![self mainWindow] && _previousMainWindow &&
[[self windows] indexOfObjectIdenticalTo:_previousMainWindow] !== CPNotFound)
[_previousMainWindow makeMainWindow];
if ([self keyWindow])
[[self keyWindow] orderFront:self];
else if ([self mainWindow])
[[self mainWindow] makeKeyAndOrderFront:self];
else
[[self mainMenu]._menuWindow makeKeyWindow]; //FIXME this may not actually work
_previousKeyWindow = nil;
_previousMainWindow = nil;
[[CPNotificationCenter defaultCenter] postNotificationName:CPApplicationDidBecomeActiveNotification
object:self
userInfo:nil];
}
- (void)_willResignActive
{
[[CPNotificationCenter defaultCenter] postNotificationName:CPApplicationWillResignActiveNotification
object:self
userInfo:nil];
}
- (void)_didResignActive
{
if (self._activeMenu)
[self._activeMenu cancelTracking];
if ([self keyWindow])
{
_previousKeyWindow = [self keyWindow];
[_previousKeyWindow resignKeyWindow];
}
if ([self mainWindow])
{
_previousMainWindow = [self mainWindow];
[_previousMainWindow resignMainWindow];
}
[[CPNotificationCenter defaultCenter] postNotificationName:CPApplicationDidResignActiveNotification
object:self
userInfo:nil];
}
+ (CPString)defaultThemeName
{
// FIXME: don't hardcode
return ([[CPBundle mainBundle] objectForInfoDictionaryKey:"CPDefaultTheme"] || @"Aristo");
}
@end
@@ -882,7 +1034,7 @@ var _CPRunModalLoop = function(anEvent)
var theWindow = [anEvent window],
modalSession = CPApp._currentSession;
if (theWindow == modalSession._window || [theWindow worksWhenModal])
[theWindow sendEvent:anEvent];
}
@@ -896,6 +1048,13 @@ var _CPRunModalLoop = function(anEvent)
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],
principalClass = [mainBundle principalClass];
@@ -904,29 +1063,8 @@ function CPApplicationMain(args, namedArgs)
[principalClass sharedApplication];
//FIXME?
if (!args)
{
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)];
}
}
if ([args containsObject:"debug"])
CPLogRegister(CPLogPopup);
CPApp._args = args;
CPApp._namedArgs = namedArgs;
@@ -940,7 +1078,7 @@ var _CPAppBootstrapperActions = nil;
{
}
+ (void)actions
+ (CPArray)actions
{
return [@selector(bootstrapPlatform), @selector(loadDefaultTheme), @selector(loadMainCibFile)];
}
@@ -968,16 +1106,16 @@ var _CPAppBootstrapperActions = nil;
+ (BOOL)loadDefaultTheme
{
var blend = [[CPThemeBlend alloc] initWithContentsOfURL:[[CPBundle bundleForClass:[CPApplication class]] pathForResource:@"Aristo.blend"]];
var blend = [[CPThemeBlend alloc] initWithContentsOfURL:[[CPBundle bundleForClass:[CPApplication class]] pathForResource:[CPApplication defaultThemeName] + ".blend"]];
[blend loadWithDelegate:self];
return YES;
}
+ (void)blendDidFinishLoading:(CPBundle)aBundle
+ (void)blendDidFinishLoading:(CPThemeBlend)aThemeBlend
{
[CPTheme setDefaultTheme:[CPTheme themeNamed:@"Aristo"]];
[CPTheme setDefaultTheme:[CPTheme themeNamed:[CPApplication defaultThemeName]]];
[self performActions];
}
@@ -995,13 +1133,86 @@ var _CPAppBootstrapperActions = nil;
return YES;
}
else
[self loadCiblessBrowserMainMenu];
return NO;
}
+ (void)loadCiblessBrowserMainMenu
{
var mainMenu = [[CPMenu alloc] initWithTitle:@"MainMenu"];
// FIXME: We should implement autoenabling.
[mainMenu setAutoenablesItems:NO];
var bundle = [CPBundle bundleForClass:[CPApplication class]],
newMenuItem = [[CPMenuItem alloc] initWithTitle:@"New" action:@selector(newDocument:) keyEquivalent:@"n"];
[newMenuItem setImage:[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPApplication/New.png"] size:CGSizeMake(16.0, 16.0)]];
[newMenuItem setAlternateImage:[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPApplication/NewHighlighted.png"] size:CGSizeMake(16.0, 16.0)]];
[mainMenu addItem:newMenuItem];
var openMenuItem = [[CPMenuItem alloc] initWithTitle:@"Open" action:@selector(openDocument:) keyEquivalent:@"o"];
[openMenuItem setImage:[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPApplication/Open.png"] size:CGSizeMake(16.0, 16.0)]];
[openMenuItem setAlternateImage:[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPApplication/OpenHighlighted.png"] size:CGSizeMake(16.0, 16.0)]];
[mainMenu addItem:openMenuItem];
var saveMenu = [[CPMenu alloc] initWithTitle:@"Save"],
saveMenuItem = [[CPMenuItem alloc] initWithTitle:@"Save" action:@selector(saveDocument:) keyEquivalent:nil];
[saveMenuItem setImage:[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPApplication/Save.png"] size:CGSizeMake(16.0, 16.0)]];
[saveMenuItem setAlternateImage:[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPApplication/SaveHighlighted.png"] size:CGSizeMake(16.0, 16.0)]];
[saveMenu addItem:[[CPMenuItem alloc] initWithTitle:@"Save" action:@selector(saveDocument:) keyEquivalent:@"s"]];
[saveMenu addItem:[[CPMenuItem alloc] initWithTitle:@"Save As" action:@selector(saveDocumentAs:) keyEquivalent:nil]];
[saveMenuItem setSubmenu:saveMenu];
[mainMenu addItem:saveMenuItem];
var editMenuItem = [[CPMenuItem alloc] initWithTitle:@"Edit" action:nil keyEquivalent:nil],
editMenu = [[CPMenu alloc] initWithTitle:@"Edit"],
undoMenuItem = [[CPMenuItem alloc] initWithTitle:@"Undo" action:@selector(undo:) keyEquivalent:CPUndoKeyEquivalent],
redoMenuItem = [[CPMenuItem alloc] initWithTitle:@"Redo" action:@selector(redo:) keyEquivalent:CPRedoKeyEquivalent];
[undoMenuItem setKeyEquivalentModifierMask:CPUndoKeyEquivalentModifierMask];
[redoMenuItem setKeyEquivalentModifierMask:CPRedoKeyEquivalentModifierMask];
[editMenu addItem:undoMenuItem];
[editMenu addItem:redoMenuItem];
[editMenu addItem:[[CPMenuItem alloc] initWithTitle:@"Cut" action:@selector(cut:) keyEquivalent:@"x"]],
[editMenu addItem:[[CPMenuItem alloc] initWithTitle:@"Copy" action:@selector(copy:) keyEquivalent:@"c"]],
[editMenu addItem:[[CPMenuItem alloc] initWithTitle:@"Paste" action:@selector(paste:) keyEquivalent:@"v"]];
[editMenuItem setSubmenu:editMenu];
[editMenuItem setHidden:YES];
[mainMenu addItem:editMenuItem];
[mainMenu addItem:[CPMenuItem separatorItem]];
[CPApp setMainMenu:mainMenu];
}
+ (void)cibDidFinishLoading:(CPCib)aCib
{
[self performActions];
}
+ (void)cibDidFailToLoad:(CPCib)aCib
{
throw new Error("Could not load main cib file (Did you forget to nib2cib it?).");
}
+ (void)reset
{
_CPAppBootstrapperActions = nil;
}
@end
+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
+8 -31
View File
@@ -24,32 +24,11 @@
@import "CGGeometry.j"
@import "CPControl.j"
@import "CPStringDrawing.j"
#include "CoreGraphics/CGGeometry.h"
CPScaleProportionally = 0;
CPScaleToFit = 1;
CPScaleNone = 2;
/* @group CPCellImagePosition */
CPNoImage = 0;
CPImageOnly = 1;
CPImageLeft = 2;
CPImageRight = 3;
CPImageBelow = 4;
CPImageAbove = 5;
CPImageOverlaps = 6;
/* @group CPButtonState */
CPOnState = 1;
CPOffState = 0;
CPMixedState = -1;
/* @group CPBezelStyle */
CPRoundedBezelStyle = 1;
@@ -145,7 +124,7 @@ CPButtonStateMixed = CPThemeState("mixed");
+ (id)themeAttributes
{
return [CPDictionary dictionaryWithObjects:[_CGInsetMakeZero(), _CGInsetMakeZero(), nil]
return [CPDictionary dictionaryWithObjects:[_CGInsetMakeZero(), _CGInsetMakeZero(), [CPNull null]]
forKeys:[@"bezel-inset", @"content-inset", @"bezel-color"]];
}
@@ -192,8 +171,8 @@ CPButtonStateMixed = CPThemeState("mixed");
_allowsMixedState = aFlag;
if (!_allowsMixedState)
[self unsetThemeState:CPButtonStateMixed];
if (!_allowsMixedState && [self state] === CPMixedState)
[self setState:CPOnState];
}
- (void)setObjectValue:(id)anObjectValue
@@ -460,7 +439,7 @@ CPButtonStateMixed = CPThemeState("mixed");
return bounds;
}
- (CGRect)bezelRectForBounds:(CFRect)bounds
- (CGRect)bezelRectForBounds:(CGRect)bounds
{
if (![self isBordered])
return _CGRectMakeZero();
@@ -523,8 +502,6 @@ CPButtonStateMixed = CPThemeState("mixed");
}
else
return [[_CPImageAndTextView alloc] initWithFrame:_CGRectMakeZero()];
return [super createEphemeralSubviewNamed:aName];
}
- (void)layoutSubviews
@@ -532,9 +509,8 @@ CPButtonStateMixed = CPThemeState("mixed");
var bezelView = [self layoutEphemeralSubviewNamed:@"bezel-view"
positioned:CPWindowBelow
relativeToEphemeralSubviewNamed:@"content-view"];
if (bezelView)
[bezelView setBackgroundColor:[self currentValueForThemeAttribute:@"bezel-color"]];
[bezelView setBackgroundColor:[self currentValueForThemeAttribute:@"bezel-color"]];
var contentView = [self layoutEphemeralSubviewNamed:@"content-view"
positioned:CPWindowAbove
@@ -554,6 +530,7 @@ CPButtonStateMixed = CPThemeState("mixed");
[contentView setTextShadowOffset:[self currentValueForThemeAttribute:@"text-shadow-offset"]];
[contentView setImagePosition:[self currentValueForThemeAttribute:@"image-position"]];
[contentView setImageScaling:[self currentValueForThemeAttribute:@"image-scaling"]];
[contentView setDimsImage:[self hasThemeState:CPThemeStateDisabled] && _imageDimsWhenDisabled];
}
}
+242 -24
View File
@@ -4,8 +4,50 @@
#include "CoreGraphics/CGGeometry.h"
@implementation CPButtonBar : CPControl
@implementation CPButtonBar : CPView
{
BOOL _hasResizeControl;
BOOL _resizeControlIsLeftAligned;
CPArray _buttons;
}
+ (id)plusButton
{
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)];
[button setBordered:NO];
[button setImage:image];
[button setImagePosition:CPImageOnly];
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
@@ -15,47 +57,223 @@
+ (id)themeAttributes
{
return [CPDictionary dictionaryWithObjects:[nil]
forKeys:[@"bezel-color"]];
return [CPDictionary dictionaryWithObjects:[CGInsetMake(0.0, 0.0, 0.0, 0.0), CGSizeMakeZero(), [CPNull null], [CPNull null], [CPNull null], [CPNull null]]
forKeys:[@"resize-control-inset", @"resize-control-size", @"resize-control-color", @"bezel-color", @"button-bezel-color", @"button-text-color"]];
}
- (id)initWithFrame:(CGRect)aFrame
{
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
{
if (aName === "bezel-view")
return [self bounds];
if (aName === "resize-control-view")
{
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];
}
- (CPView)createEphemeralSubviewNamed:(CPString)aName
{
if (aName === "bezel-view")
{
var view = [[CPView alloc] initWithFrame:_CGRectMakeZero()];
if (aName === "resize-control-view")
return [[CPView alloc] initWithFrame:CGRectMakeZero()];
[view setHitTests:NO];
return view;
}
return [super createEphemeralSubviewNamed:aName];
}
- (void)layoutSubviews
{
var bezelView = [self layoutEphemeralSubviewNamed:@"bezel-view"
positioned:CPWindowBelow
relativeToEphemeralSubviewNamed:@""];
if (bezelView)
[bezelView setBackgroundColor:[self currentValueForThemeAttribute:@"bezel-color"]];
[self setBackgroundColor:[self currentValueForThemeAttribute:@"bezel-color"]];
var normalColor = [self valueForThemeAttribute:@"button-bezel-color" inState:CPThemeStateNormal],
highlightedColor = [self valueForThemeAttribute:@"button-bezel-color" inState:CPThemeStateHighlighted],
disabledColor = [self valueForThemeAttribute:@"button-bezel-color" inState:CPThemeStateDisabled],
textColor = [self valueForThemeAttribute:@"button-text-color" inState:CPThemeStateNormal];
var buttonsNotHidden = [CPArray arrayWithArray:_buttons],
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];
[aSubview setAutoresizingMask:CPViewMinXMargin];
[super setFrameSize:aSize];
[self setNeedsLayout];
}
@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
+23
View File
@@ -61,4 +61,27 @@
return self;
}
- (void)takeStateFromKeyPath:(CPString)aKeyPath ofObjects:(CPArray)objects
{
var count = objects.length,
value = [objects[0] valueForKeyPath:aKeyPath] ? CPOnState : CPOffState;
[self setAllowsMixedState:NO];
[self setState:value];
while (count-- > 1)
{
if (value !== ([objects[count] valueForKeyPath:aKeyPath] ? CPOnState : CPOffState))
{
[self setAllowsMixedState:YES];
[self setState:CPMixedState];
}
}
}
- (void)takeValueFromKeyPath:(CPString)aKeyPath ofObjects:(CPArray)objects
{
[self takeStateFromKeyPath:aKeyPath ofObjects:objects];
}
@end
+42 -12
View File
@@ -120,9 +120,13 @@
[super setBoundsOrigin:aPoint];
var superview = [self superview];
if([superview isKindOfClass:[CPScrollView class]])
var superview = [self superview],
// 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];
}
@@ -173,26 +177,52 @@
return;
// ... and we're in a scroll view of course.
var superview = [self superview];
if ([superview isKindOfClass:[CPScrollView class]])
var superview = [self superview],
// 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];
}
- (BOOL)autoscroll:(CPEvent)anEvent
{
var bounds = [self bounds],
eventLocation = [self convertPoint:[anEvent locationInWindow] fromView:nil];
eventLocation = [self convertPoint:[anEvent locationInWindow] fromView:nil],
superview = [self superview],
deltaX = 0,
deltaY = 0;
if (CPRectContainsPoint(bounds, eventLocation))
if (CGRectContainsPoint(bounds, eventLocation))
return NO;
var newRect = CGRectMakeZero();
if (![superview isKindOfClass:[CPScrollView class]] || [superview hasVerticalScroller])
{
if (eventLocation.y < CGRectGetMinY(bounds))
deltaY = CGRectGetMinY(bounds) - eventLocation.y;
else if (eventLocation.y > CGRectGetMaxY(bounds))
deltaY = CGRectGetMaxY(bounds) - eventLocation.y;
if (deltaY < -bounds.size.height)
deltaY = -bounds.size.height;
if (deltaY > bounds.size.height)
deltaY = bounds.size.height;
}
newRect.origin = eventLocation;
newRect.size = CPSizeMake(10, 10);
if (![superview isKindOfClass:[CPScrollView class]] || [superview hasHorizontalScroller])
{
if (eventLocation.x < CGRectGetMinX(bounds))
deltaX = CGRectGetMinX(bounds) - eventLocation.x;
else if (eventLocation.x > CGRectGetMaxX(bounds))
deltaX = CGRectGetMaxX(bounds) - eventLocation.x;
if (deltaX < -bounds.size.width)
deltaX = -bounds.size.width;
if (deltaX > bounds.size.width)
deltaX = bounds.size.width;
}
return [_documentView scrollRectToVisible:newRect];
return [self scrollToPoint:CGPointMake(bounds.origin.x - deltaX, bounds.origin.y - deltaY)];
}
@end
+220 -75
View File
@@ -30,16 +30,16 @@
@import "CPCollectionViewItem.j"
/*!
/*!
@ingroup appkit
@class CPCollectionView
This class displays an array as a grid of objects, where each object is represented by a view.
The view is controlled by creating a CPCollectionViewItem and specifying its view, then
This class displays an array as a grid of objects, where each object is represented by a view.
The view is controlled by creating a CPCollectionViewItem and specifying its view, then
setting that item as the collection view prototype.
@par Delegate Methods
@delegate -(void)collectionViewDidChangeSelection:(CPCollectionView)collectionView;
Called when the selection in the collection view has changed.
@param collectionView the collection view who's selection changed
@@ -67,35 +67,35 @@
{
CPArray _content;
CPArray _items;
CPData _itemData;
CPCollectionViewItem _itemPrototype;
CPCollectionViewItem _itemForDragging;
CPMutableArray _cachedItems;
unsigned _maxNumberOfRows;
unsigned _maxNumberOfColumns;
CGSize _minItemSize;
CGSize _maxItemSize;
CPArray _backgroundColors;
float _tileWidth;
BOOL _isSelectable;
BOOL _allowsMultipleSelection;
BOOL _allowsEmptySelection;
CPIndexSet _selectionIndexes;
CGSize _itemSize;
float _horizontalMargin;
float _verticalMargin;
unsigned _numberOfRows;
unsigned _numberOfColumns;
id _delegate;
CPEvent _mouseDownEvent;
@@ -104,14 +104,14 @@
- (id)initWithFrame:(CGRect)aFrame
{
self = [super initWithFrame:aFrame];
if (self)
{
_items = [];
_content = [];
_cachedItems = [];
_itemSize = CGSizeMakeZero();
_minItemSize = CGSizeMakeZero();
_maxItemSize = CGSizeMakeZero();
@@ -120,12 +120,12 @@
_verticalMargin = 5.0;
_tileWidth = -1.0;
_selectionIndexes = [CPIndexSet indexSet];
_allowsEmptySelection = YES;
_isSelectable = YES;
}
return self;
}
@@ -196,8 +196,8 @@
// Setting the Content
/*!
Sets the content of the collection view to the content in \c anArray.
This array can be of any type, and each element will be passed to the \c -setRepresentedObject: method.
Sets the content of the collection view to the content in \c anArray.
This array can be of any type, and each element will be passed to the \c -setRepresentedObject: method.
It's the responsibility of your custom collection view item to interpret the object.
@param anArray the content array
*/
@@ -205,9 +205,9 @@
{
if (_content == anArray)
return;
_content = anArray;
[self reloadContent];
}
@@ -236,13 +236,13 @@
{
if (_isSelectable == isSelectable)
return;
_isSelectable = isSelectable;
if (!_isSelectable)
{
var index = CPNotFound;
while ((index = [_selectionIndexes indexGreaterThanIndex:index]) != CPNotFound)
[_items[index] setSelected:NO];
}
@@ -299,19 +299,19 @@
{
if (_selectionIndexes == anIndexSet || !_isSelectable)
return;
var index = CPNotFound;
while ((index = [_selectionIndexes indexGreaterThanIndex:index]) != CPNotFound)
[_items[index] setSelected:NO];
_selectionIndexes = anIndexSet;
var index = CPNotFound;
while ((index = [_selectionIndexes indexGreaterThanIndex:index]) != CPNotFound)
[_items[index] setSelected:YES];
if ([_delegate respondsToSelector:@selector(collectionViewDidChangeSelection:)])
[_delegate collectionViewDidChangeSelection:self]
}
@@ -321,21 +321,23 @@
*/
- (CPIndexSet)selectionIndexes
{
return _selectionIndexes;
return [_selectionIndexes copy];
}
/* @ignore */
- (void)reloadContent
{
{
// Remove current views
var count = _items.length;
while (count--)
{
[[_items[count] view] removeFromSuperview];
[_items[count] setSelected:NO];
_cachedItems.push(_items[count]);
}
_items = [];
if (!_itemPrototype || !_content)
@@ -348,10 +350,14 @@
for (; index < count; ++index)
{
_items.push([self newItemForRepresentedObject:_content[index]]);
[self addSubview:[_items[index] view]];
}
index = CPNotFound;
while ((index = [_selectionIndexes indexGreaterThanIndex:index]) != CPNotFound)
[_items[index] setSelected:YES];
[self tile];
}
@@ -359,49 +365,49 @@
- (void)tile
{
var width = CGRectGetWidth([self bounds]);
if (![_content count] || width == _tileWidth)
return;
// We try to fit as many views per row as possible. Any remaining space is then
// We try to fit as many views per row as possible. Any remaining space is then
// either proportioned out to the views (if their minSize != maxSize) or used as
// margin
var itemSize = CGSizeMakeCopy(_minItemSize);
_numberOfColumns = MAX(1.0, FLOOR(width / itemSize.width));
if (_maxNumberOfColumns > 0)
_numberOfColumns = MIN(_maxNumberOfColumns, _numberOfColumns);
var remaining = width - _numberOfColumns * itemSize.width,
itemsNeedSizeUpdate = NO;
if (remaining > 0 && itemSize.width < _maxItemSize.width)
itemSize.width = MIN(_maxItemSize.width, itemSize.width + FLOOR(remaining / _numberOfColumns));
// When we ONE column and a non-integral width, the FLOORing above can cause the item width to be smaller than the total width.
if (_maxNumberOfColumns == 1 && itemSize.width < _maxItemSize.width && itemSize.width < width)
itemSize.width = MIN(_maxItemSize.width, width);
if (!CGSizeEqualToSize(_itemSize, itemSize))
{
_itemSize = itemSize;
itemsNeedSizeUpdate = YES;
}
var index = 0,
count = _items.length;
if (_maxNumberOfColumns > 0 && _maxNumberOfRows > 0)
count = MIN(count, _maxNumberOfColumns * _maxNumberOfRows);
_numberOfRows = CEIL(count / _numberOfColumns);
_horizontalMargin = FLOOR((width - _numberOfColumns * itemSize.width) / (_numberOfColumns + 1));
var x = _horizontalMargin,
y = -itemSize.height;
for (; index < count; ++index)
{
if (index % _numberOfColumns == 0)
@@ -409,19 +415,28 @@
x = _horizontalMargin;
y += _verticalMargin + itemSize.height;
}
var view = [_items[index] view];
[view setFrameOrigin:CGPointMake(x, y)];
if (itemsNeedSizeUpdate)
[view setFrameSize:_itemSize];
x += itemSize.width + _horizontalMargin;
}
var superview = [self superview],
proposedHeight = y + itemSize.height + _verticalMargin;
if ([superview isKindOfClass:[CPClipView class]])
{
var superviewSize = [superview bounds].size;
proposedHeight = MAX(superviewSize.height, proposedHeight);
}
_tileWidth = width;
[self setFrameSize:CGSizeMake(width, y + itemSize.height + _verticalMargin)];
[self setFrameSize:CGSizeMake(width, proposedHeight)];
_tileWidth = -1.0;
}
@@ -439,9 +454,9 @@
{
if (_maxNumberOfRows == aMaxNumberOfRows)
return;
_maxNumberOfRows = aMaxNumberOfRows;
[self tile];
}
@@ -461,9 +476,9 @@
{
if (_maxNumberOfColumns == aMaxNumberOfColumns)
return;
_maxNumberOfColumns = aMaxNumberOfColumns;
[self tile];
}
@@ -500,9 +515,9 @@
{
if (CGSizeEqualToSize(_minItemSize, aSize))
return;
_minItemSize = CGSizeMakeCopy(aSize);
[self tile];
}
@@ -522,9 +537,9 @@
{
if (CGSizeEqualToSize(_maxItemSize, aSize))
return;
_maxItemSize = CGSizeMakeCopy(aSize);
[self tile];
}
@@ -584,6 +599,14 @@
- (void)mouseDragged:(CPEvent)anEvent
{
var locationInWindow = [anEvent locationInWindow],
mouseDownLocationInWindow = [_mouseDownEvent locationInWindow];
// FIXME: This is because Safari's drag hysteresis is 3px x 3px
if ((ABS(locationInWindow.x - mouseDownLocationInWindow.x) < 3) &&
(ABS(locationInWindow.y - mouseDownLocationInWindow.y) < 3))
return;
if (![_delegate respondsToSelector:@selector(collectionView:dragTypesForItemsAtIndexes:)])
return;
@@ -591,6 +614,10 @@
if (![_selectionIndexes count])
return;
if ([_delegate respondsToSelector:@selector(collectionView:canDragItemsAtIndexes:withEvent:)] &&
![_delegate collectionView:self canDragItemsAtIndexes:_selectionIndexes withEvent:_mouseDownEvent])
return;
// Set up the pasteboard
var dragTypes = [_delegate collectionView:self dragTypesForItemsAtIndexes:_selectionIndexes];
@@ -638,9 +665,9 @@
{
if (_verticalMargin == aVerticalMargin)
return;
_verticalMargin = aVerticalMargin;
[self tile];
}
@@ -670,6 +697,124 @@
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
@implementation CPCollectionView (KeyboardInteraction)
- (void)_scrollToSelection
{
var frame = [self frameForItemsAtIndexes:[self selectionIndexes]];
if (!CGRectIsNull(frame))
[self scrollRectToVisible:frame];
}
- (void)moveLeft:(id)sender
{
var index = [[self selectionIndexes] firstIndex];
if (index === CPNotFound)
index = [[self items] count];
index = MAX(index - 1, 0);
[self setSelectionIndexes:[CPIndexSet indexSetWithIndex:index]];
[self _scrollToSelection];
}
- (void)moveRight:(id)sender
{
var index = MIN([[self selectionIndexes] firstIndex] + 1, [[self items] count]-1);
[self setSelectionIndexes:[CPIndexSet indexSetWithIndex:index]];
[self _scrollToSelection];
}
- (void)moveDown:(id)sender
{
var index = MIN([[self selectionIndexes] firstIndex] + [self numberOfColumns], [[self items] count]-1);
[self setSelectionIndexes:[CPIndexSet indexSetWithIndex:index]];
[self _scrollToSelection];
}
- (void)moveUp:(id)sender
{
var index = [[self selectionIndexes] firstIndex];
if (index == CPNotFound)
index = [[self items] count];
index = MAX(0, index - [self numberOfColumns]);
[self setSelectionIndexes:[CPIndexSet indexSetWithIndex:index]];
[self _scrollToSelection];
}
- (void)deleteBackward:(id)sender
{
if ([[self delegate] respondsToSelector:@selector(collectionView:shouldDeleteItemsAtIndexes:)])
{
[[self delegate] collectionView:self shouldDeleteItemsAtIndexes:[self selectionIndexes]];
var index = [[self selectionIndexes] firstIndex];
if (index > [[self content] count]-1)
[self setSelectionIndexes:[CPIndexSet indexSetWithIndex:[[self content] count]-1]];
[self _scrollToSelection];
[self setNeedsDisplay:YES];
}
}
- (void)keyDown:(CPEvent)anEvent
{
[self interpretKeyEvents:[anEvent]];
}
@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",
@@ -693,20 +838,20 @@ var CPCollectionViewMinItemSizeKey = @"CPCollectionViewMinItemSizeKey",
_cachedItems = [];
_itemSize = CGSizeMakeZero();
_minItemSize = [aCoder decodeSizeForKey:CPCollectionViewMinItemSizeKey] || CGSizeMakeZero();
_maxItemSize = [aCoder decodeSizeForKey:CPCollectionViewMaxItemSizeKey] || CGSizeMakeZero();
_verticalMargin = [aCoder decodeFloatForKey:CPCollectionViewVerticalMarginKey];
_isSelectable = [aCoder decodeBoolForKey:CPCollectionViewSelectableKey];
[self setBackgroundColors:[aCoder decodeObjectForKey:CPCollectionViewBackgroundColorsKey]];
_tileWidth = -1.0;
_selectionIndexes = [CPIndexSet indexSet];
_allowsEmptySelection = YES;
}
@@ -719,12 +864,12 @@ var CPCollectionViewMinItemSizeKey = @"CPCollectionViewMinItemSizeKey",
if (!CGSizeEqualToSize(_minItemSize, CGSizeMakeZero()))
[aCoder encodeSize:_minItemSize forKey:CPCollectionViewMinItemSizeKey];
if (!CGSizeEqualToSize(_maxItemSize, CGSizeMakeZero()))
[aCoder encodeSize:_maxItemSize forKey:CPCollectionViewMaxItemSizeKey];
[aCoder encodeBool:_isSelectable forKey:CPCollectionViewSelectableKey];
[aCoder encodeFloat:_verticalMargin forKey:CPCollectionViewVerticalMarginKey];
[aCoder encodeObject:_backgroundColors forKey:CPCollectionViewBackgroundColorsKey];
+13 -56
View File
@@ -437,51 +437,16 @@ var cachedBlackColor,
if (self)
{
_components = components;
if (!CPFeatureIsCompatible(CPCSSRGBAFeature) && _components[3] != 1.0 && window.Base64 && window.CRC32)
{
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);
bytes[g_off] = Math.round(_components[1]*255);
bytes[b_off] = Math.round(_components[2]*255);
bytes[a_off] = Math.round(_components[3]*255);
// 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]) : "") + ")";
}
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;
}
@@ -494,6 +459,7 @@ var cachedBlackColor,
{
_patternImage = anImage;
_cssString = "url(\"" + [_patternImage filename] + "\")";
_components = [0.0, 0.0, 0.0, 1.0];
}
return self;
@@ -735,6 +701,9 @@ var CPColorComponentsKey = @"CPColorComponentsKey",
var hexCharacters = "0123456789ABCDEF";
// HACK: prevent these from becoming globals. workaround for obj-j "function foo(){}" behavior
var hexToRGB, rgbToHex, byteToHex;
/*!
Used for the CPColor \c +colorWithHexString: implementation
@ignore
@@ -761,18 +730,6 @@ function hexToRGB(hex)
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) {
return byteToHex(r) + byteToHex(g) + byteToHex(b);
}
+10 -9
View File
@@ -140,7 +140,7 @@ CPColorPickerViewHeight = 370;
Sets the color of the panel, and updates the picker. Also posts a \c CPColorPanelDidChangeNotification.
*/
- (void)setColor:(CPColor)aColor
{
{
_color = aColor;
[_previewView setBackgroundColor: _color];
@@ -518,9 +518,10 @@ var CPColorPanelSwatchesCookie = "CPColorPanelSwatchesCookie";
- (void)mouseUp:(CPEvent)anEvent
{
var point = [self convertPoint:[anEvent locationInWindow] fromView:nil];
var point = [self convertPoint:[anEvent locationInWindow] fromView:nil],
bounds = [self bounds];
if(point.x > [self bounds].size.width - 1 || point.x < 1)
if(!CGRectContainsPoint(bounds, point) || point.x > [self bounds].size.width - 1 || point.x < 1)
return NO;
[_colorPanel setColor: [self colorAtIndex:FLOOR(point.x / 13)] updatePicker: YES];
@@ -563,7 +564,7 @@ var CPColorPanelSwatchesCookie = "CPColorPanelSwatchesCookie";
- (void)pasteboard:(CPPasteboard)aPasteboard provideDataForType:(CPString)aType
{
if(aType == CPColorDragType)
[aPasteboard setData:_dragColor forType:aType];
[aPasteboard setData:[CPKeyedArchiver archivedDataWithRootObject:_dragColor] forType:aType];
}
- (void)performDragOperation:(id <CPDraggingInfo>)aSender
@@ -575,7 +576,7 @@ var CPColorPanelSwatchesCookie = "CPColorPanelSwatchesCookie";
if(![pasteboard availableTypeFromArray:[CPColorDragType]] || location.x > [self bounds].size.width - 1 || location.x < 1)
return NO;
[self setColor:[pasteboard dataForType:CPColorDragType] atIndex: FLOOR(location.x / 13)];
[self setColor:[CPKeyedUnarchiver unarchiveObjectWithData:[pasteboard dataForType:CPColorDragType]] atIndex: FLOOR(location.x / 13)];
}
@end
@@ -612,8 +613,8 @@ var CPColorPanelSwatchesCookie = "CPColorPanelSwatchesCookie";
if(![pasteboard availableTypeFromArray:[CPColorDragType]])
return NO;
var color = [pasteboard dataForType:CPColorDragType];
[_colorPanel setColor: color updatePicker: YES];
var color = [CPKeyedUnarchiver unarchiveObjectWithData:[pasteboard dataForType:CPColorDragType]];
[_colorPanel setColor:color updatePicker:YES];
}
- (BOOL)isOpaque
@@ -625,7 +626,7 @@ var CPColorPanelSwatchesCookie = "CPColorPanelSwatchesCookie";
{
var point = [self convertPoint:[anEvent locationInWindow] fromView:nil];
[[CPPasteboard pasteboardWithName:CPDragPboard] declareTypes:[CPArray arrayWithObject:CPColorDragType] owner:self];
[[CPPasteboard pasteboardWithName:CPDragPboard] declareTypes:[CPColorDragType] owner:self];
var bounds = CPRectMake(0, 0, 15, 15);
@@ -650,7 +651,7 @@ var CPColorPanelSwatchesCookie = "CPColorPanelSwatchesCookie";
- (void)pasteboard:(CPPasteboard)aPasteboard provideDataForType:(CPString)aType
{
if(aType == CPColorDragType)
[aPasteboard setData:[self backgroundColor] forType:aType];
[aPasteboard setData:[CPKeyedArchiver archivedDataWithRootObject:[self backgroundColor]] forType:aType];
}
@end
+4
View File
@@ -23,6 +23,8 @@
@import <Foundation/CPObject.j>
@import "CPColorPanel.j"
#include "Platform/Platform.h"
/*!
@ingroup appkit
@class CPColorPicker
@@ -239,8 +241,10 @@
_blackWheelImage.style.filter = "alpha(opacity=0)"
_blackWheelImage.style.position = "absolute";
#if PLATFORM(DOM)
_DOMElement.appendChild(_wheelImage);
_DOMElement.appendChild(_blackWheelImage);
#endif
[self setWheelSize:aFrame.size];
+7 -1
View File
@@ -231,11 +231,17 @@ var _CPColorWellDidBecomeExclusiveNotification = @"_CPColorWellDidBecomeExclusiv
- (void)mouseDown:(CPEvent)anEvent
{
if (![self isEnabled])
return;
[self drawBezelWithHighlight:YES];
}
- (void)mouseDragged:(CPEvent)anEvent
{
if (![self isEnabled])
return;
[self drawBezelWithHighlight:CGRectContainsPoint([self bounds], [self convertPoint:[anEvent locationInWindow] fromView:nil])];
}
@@ -243,7 +249,7 @@ var _CPColorWellDidBecomeExclusiveNotification = @"_CPColorWellDidBecomeExclusiv
{
[self drawBezelWithHighlight:NO];
if (!CGRectContainsPoint([self bounds], [self convertPoint:[anEvent locationInWindow] fromView:nil]))
if (!CGRectContainsPoint([self bounds], [self convertPoint:[anEvent locationInWindow] fromView:nil]) || ![self isEnabled])
return;
[self activate:YES];
+28 -10
View File
@@ -31,6 +31,11 @@ CPKHTMLBrowserEngine = 3;
CPOperaBrowserEngine = 4;
CPWebKitBrowserEngine = 5;
// Operating Systems
CPMacOperatingSystem = 0;
CPWindowsOperatingSystem = 1;
CPOtherOperatingSystem = 2;
// Features
CPCSSRGBAFeature = 1 << 5;
@@ -60,8 +65,6 @@ CPInputTypeCanBeChangedFeature = 1 << 25;
CPHTML5DragAndDropSourceYOffBy1 = 1 << 26;
var USER_AGENT = "",
PLATFORM_ENGINE = CPUnknownBrowserEngine,
PLATFORM_FEATURES = 0;
@@ -70,7 +73,7 @@ var USER_AGENT = "",
PLATFORM_FEATURES |= CPInputTypeCanBeChangedFeature;
if (typeof window != "undfined" && typeof window.navigator != "undefined")
if (typeof window !== "undefined" && typeof window.navigator !== "undefined")
USER_AGENT = window.navigator.userAgent;
// Opera
@@ -104,7 +107,10 @@ else if (USER_AGENT.indexOf("AppleWebKit/") != -1)
// Features we can only be sure of with WebKit (no known independent tests)
PLATFORM_FEATURES |= CPCSSRGBAFeature;
PLATFORM_FEATURES |= CPHTMLContentEditableFeature;
PLATFORM_FEATURES |= CPHTMLDragAndDropFeature;
if (USER_AGENT.indexOf("Chrome") === -1)
PLATFORM_FEATURES |= CPHTMLDragAndDropFeature;
PLATFORM_FEATURES |= CPJavascriptClipboardEventsFeature;
PLATFORM_FEATURES |= CPJavascriptClipboardAccessFeature;
PLATFORM_FEATURES |= CPJavaScriptShadowFeature;
@@ -183,25 +189,37 @@ function CPFeatureIsCompatible(aFeature)
function CPBrowserIsEngine(anEngine)
{
return PLATFORM_ENGINE == anEngine;
return PLATFORM_ENGINE === anEngine;
}
if (USER_AGENT.indexOf("Mac") != -1)
function CPBrowserIsOperatingSystem(anOperatingSystem)
{
return OPERATING_SYSTEM === anOperatingSystem;
}
OPERATING_SYSTEM = CPOtherOperatingSystem;
if (USER_AGENT.indexOf("Mac") !== -1)
{
OPERATING_SYSTEM = CPMacOperatingSystem;
CPPlatformActionKeyMask = CPCommandKeyMask;
CPUndoKeyEquivalent = @"Z";
CPUndoKeyEquivalent = @"z";
CPRedoKeyEquivalent = @"Z";
CPUndoKeyEquivalentModifierMask = CPCommandKeyMask;
CPRedoKeyEquivalentModifierMask = CPCommandKeyMask | CPShiftKeyMask;
CPRedoKeyEquivalentModifierMask = CPCommandKeyMask;
}
else
{
if (USER_AGENT.indexOf("Windows") !== -1)
OPERATING_SYSTEM = CPWindowsOperatingSystem;
CPPlatformActionKeyMask = CPControlKeyMask;
CPUndoKeyEquivalent = @"Z";
CPRedoKeyEquivalent = @"Y";
CPUndoKeyEquivalent = @"z";
CPRedoKeyEquivalent = @"y";
CPUndoKeyEquivalentModifierMask = CPControlKeyMask;
CPRedoKeyEquivalentModifierMask = CPControlKeyMask;
+49 -42
View File
@@ -27,47 +27,42 @@
#include "CoreGraphics/CGGeometry.h"
#include "Platform/Platform.h"
/*
@global
@group CPTextAlignment
*/
CPLeftTextAlignment = 0;
/*
@global
@group CPTextAlignment
*/
CPRightTextAlignment = 1;
/*
@global
@group CPTextAlignment
*/
CPCenterTextAlignment = 2;
/*
@global
@group CPTextAlignment
*/
CPJustifiedTextAlignment = 3;
/*
@global
@group CPTextAlignment
*/
CPNaturalTextAlignment = 4;
CPLeftTextAlignment = 0;
CPRightTextAlignment = 1;
CPCenterTextAlignment = 2;
CPJustifiedTextAlignment = 3;
CPNaturalTextAlignment = 4;
/*
@global
@group CPControlSize
*/
CPRegularControlSize = 0;
/*
@global
@group CPControlSize
*/
CPSmallControlSize = 1;
/*
@global
@group CPControlSize
*/
CPMiniControlSize = 2;
CPRegularControlSize = 0;
CPSmallControlSize = 1;
CPMiniControlSize = 2;
CPLineBreakByWordWrapping = 0;
CPLineBreakByCharWrapping = 1;
CPLineBreakByClipping = 2;
CPLineBreakByTruncatingHead = 3;
CPLineBreakByTruncatingTail = 4;
CPLineBreakByTruncatingMiddle = 5;
CPTopVerticalTextAlignment = 1,
CPCenterVerticalTextAlignment = 2,
CPBottomVerticalTextAlignment = 3;
CPScaleProportionally = 0;
CPScaleToFit = 1;
CPScaleNone = 2;
CPNoImage = 0;
CPImageOnly = 1;
CPImageLeft = 2;
CPImageRight = 3;
CPImageBelow = 4;
CPImageAbove = 5;
CPImageOverlaps = 6;
CPOnState = 1;
CPOffState = 0;
CPMixedState = -1;
CPControlNormalBackgroundColor = "CPControlNormalBackgroundColor";
CPControlSelectedBackgroundColor = "CPControlSelectedBackgroundColor";
@@ -112,7 +107,7 @@ var CPControlBlackColor = [CPColor blackColor];
CPLineBreakByClipping,
[CPColor blackColor],
[CPFont systemFontOfSize:12.0],
nil,
[CPNull null],
_CGSizeMakeZero(),
CPImageLeft,
CPScaleToFit,
@@ -308,6 +303,12 @@ var CPControlBlackColor = [CPColor blackColor];
[self highlight:YES];
[self setState:[self nextState]];
[self sendAction:[self action] to:[self target]];
[CPTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(unhighlightButtonTimerDidFinish:) userInfo:nil repeats:NO];
}
- (void)unhighlightButtonTimerDidFinish:(id)sender
{
[self highlight:NO];
}
@@ -572,7 +573,9 @@ var CPControlValueKey = "CPControlValueKey",
CPControlTargetKey = "CPControlTargetKey",
CPControlActionKey = "CPControlActionKey",
CPControlSendActionOnKey = "CPControlSendActionOnKey";
CPControlSendActionOnKey = "CPControlSendActionOnKey",
CPControlSendsActionOnEndEditingKey = "CPControlSendsActionOnEndEditingKey";
var __Deprecated__CPImageViewImageKey = @"CPImageViewImageKey";
@@ -595,6 +598,7 @@ var __Deprecated__CPImageViewImageKey = @"CPImageViewImageKey";
[self setAction:[aCoder decodeObjectForKey:CPControlActionKey]];
[self sendActionOn:[aCoder decodeIntForKey:CPControlSendActionOnKey]];
[self setSendsActionOnEndEditing:[aCoder decodeBoolForKey:CPControlSendsActionOnEndEditingKey]];
}
return self;
@@ -608,6 +612,9 @@ var __Deprecated__CPImageViewImageKey = @"CPImageViewImageKey";
{
[super encodeWithCoder:aCoder];
if (_sendsActionOnEndEditing)
[aCoder encodeBool:_sendsActionOnEndEditing forKey:CPControlSendsActionOnEndEditingKey];
if (_value !== nil)
[aCoder encodeObject:_value forKey:CPControlValueKey];
+272
View File
@@ -0,0 +1,272 @@
/*
Testing browsers:
WebKit r50235 (Safari 4.0.3+)
FireFox 3.5
Opera 10.0.0
Implemented class methods:
Webkit : All
IE : All
FireFox Win : All
FireFox Mac : All except closedHandCursor disappearingItemCursor // Firefox mac does not support url cursors
Opera : All except resizeLeftRightCursor resizeUpDownCursor operationNotAllowedCursor dragCopyCursor dragLinkCursor contextualMenuCursor openHandCursor closedHandCursor disappearingItemCursor // Opera does not support url cursors so these won't work with images
*/
#include "Platform/Platform.h"
var currentCursor = nil,
cursorStack = [],
cursors = {},
cursorURLFormat = nil;
@implementation CPCursor : CPObject
{
CPString _cssString;
BOOL _isSetOnMouseEntered @accessors(readwrite, getter=isSetOnMouseEntered, setter=setOnMouseEntered:);
BOOL _isSetOnMouseExited @accessors(readwrite, getter=isSetOnMouseExited, setter=setOnMouseExited:);
}
+ (CPCursor)currentCursor
{
return currentCursor;
}
- (id)initWithCSSString:(CPString)aString
{
if (self = [super init])
_cssString = aString;
return self;
}
+ (CPCursor)cursorWithCSSString:(CPString)cssString
{
var cursor = cursors[cssString];
if (typeof cursor == 'undefined')
{
cursor = [[CPCursor alloc] initWithCSSString:cssString];
cursors[cssString] = cursor;
}
return cursor;
}
+ (CPCursor)cursorWithImageNamed:(CPString)imageName
{
if (!cursorURLFormat)
{
cursorURLFormat = @"url(" + [[CPBundle bundleForClass:self] resourcePath] + @"/CPCursor/%@.cur)";
if (CPBrowserIsEngine(CPGeckoBrowserEngine))
cursorURLFormat += ", default";
}
var url = [CPString stringWithFormat:cursorURLFormat, imageName];
return [[CPCursor alloc] initWithCSSString:url];
}
- (CPString)_cssString
{
return _cssString;
}
+ (CPCursor)arrowCursor
{
return [CPCursor cursorWithCSSString:@"default"]; // WebKit | FF | opera | IE
}
+ (CPCursor)crosshairCursor
{
return [CPCursor cursorWithCSSString:@"crosshair"]; // WebKit | FF | opera | IE
}
+ (CPCursor)IBeamCursor
{
return [CPCursor cursorWithCSSString:@"text"]; // WebKit | FF | opera | IE
}
+ (CPCursor)pointingHandCursor
{
return [CPCursor cursorWithCSSString:@"pointer"]; // WebKit | FF | opera | IE
}
+ (CPCursor)resizeDownCursor
{
if (CPBrowserIsEngine(CPInternetExplorerBrowserEngine))
return [CPCursor cursorWithImageNamed:CPStringFromSelector(_cmd)];
return [CPCursor cursorWithCSSString:"s-resize"]; // WebKit | FF | opera
}
+ (CPCursor)resizeUpCursor
{
if (CPBrowserIsEngine(CPInternetExplorerBrowserEngine))
return [CPCursor cursorWithImageNamed:CPStringFromSelector(_cmd)];
return [CPCursor cursorWithCSSString:@"n-resize"]; // WebKit | FF | opera
}
+ (CPCursor)resizeLeftCursor
{
if (CPBrowserIsEngine(CPInternetExplorerBrowserEngine))
return [CPCursor cursorWithImageNamed:CPStringFromSelector(_cmd)];
return [CPCursor cursorWithCSSString:@"w-resize"]; // WebKit | FF | opera
}
+ (CPCursor)resizeRightCursor
{
if (CPBrowserIsEngine(CPInternetExplorerBrowserEngine))
return [CPCursor cursorWithImageNamed:CPStringFromSelector(_cmd)];
return [CPCursor cursorWithCSSString:@"e-resize"]; // WebKit | FF | opera
}
+ (CPCursor)resizeLeftRightCursor
{
return [CPCursor cursorWithCSSString:@"col-resize"]; // WebKit | FF | IE
}
+ (CPCursor)resizeUpDownCursor
{
return [CPCursor cursorWithCSSString:@"row-resize"]; // WebKit | FF | IE
}
+ (CPCursor)operationNotAllowedCursor
{
return [CPCursor cursorWithCSSString:@"not-allowed"]; // WebKit | FF | IE
}
+ (CPCursor)dragCopyCursor
{
if (CPBrowserIsEngine(CPInternetExplorerBrowserEngine))
return [CPCursor cursorWithImageNamed:CPStringFromSelector(_cmd)];
return [CPCursor cursorWithCSSString:@"copy"]; // WebKit | FF
}
+ (CPCursor)dragLinkCursor
{
if (CPBrowserIsEngine(CPInternetExplorerBrowserEngine))
return [CPCursor cursorWithImageNamed:CPStringFromSelector(_cmd)];
return [CPCursor cursorWithCSSString:@"alias"]; // WebKit | FF
}
+ (CPCursor)contextualMenuCursor
{
if (CPBrowserIsEngine(CPInternetExplorerBrowserEngine))
return [CPCursor cursorWithImageNamed:CPStringFromSelector(_cmd)];
return [CPCursor cursorWithCSSString:@"context-menu"]; // WebKit | FF Mac . Not impl FF Win.
}
+ (CPCursor)openHandCursor
{
if (CPBrowserIsEngine(CPWebKitBrowserEngine))
return [CPCursor cursorWithCSSString:@"-webkit-grab"];
else if (CPBrowserIsEngine(CPGeckoBrowserEngine) || CPBrowserIsEngine(CPOperaBrowserEngine))
return [CPCursor cursorWithCSSString:@"move"];
return [CPCursor cursorWithImageNamed:CPStringFromSelector(_cmd)]; // WebKit only. move in FFMac|Opera
}
+ (CPCursor)closedHandCursor
{
if (CPBrowserIsEngine(CPWebKitBrowserEngine))
return [CPCursor cursorWithCSSString:@"-webkit-grabbing"];
return [CPCursor cursorWithImageNamed:CPStringFromSelector(_cmd)]; // WebKit only
}
+ (CPCursor)disappearingItemCursor
{
return [CPCursor cursorWithImageNamed:CPStringFromSelector(_cmd)]; // None
}
+ (void)hide
{
[self _setCursorCSS:"none"]; // Not supported in IE
}
+ (void)unhide
{
[self _setCursorCSS:[currentCursor _cssString]]
}
+ (void)setHiddenUntilMouseMoves:(BOOL)flag
{
if (flag)
[CPCursor hide];
else
[CPCursor unhide];
}
- (id)initWithImage:(CPImage)image hotSpot:(CPPoint)hotSpot
{
return [self initWithCSSString:"url(" + [image filename] + ")"];
}
- (void)mouseEntered:(CPEvent)event
{
}
- (void)mouseExited:(CPEvent)event
{
}
- (void)set
{
currentCursor = self;
#if PLATFORM(DOM)
[[self class] _setCursorCSS:_cssString];
#endif
}
+ (void)_setCursorCSS:(CPString)aString
{
#if PLATFORM(DOM)
var platformWindows = [[CPPlatformWindow visiblePlatformWindows] allObjects];
for (var i = 0, count = [platformWindows count]; i < count; i++)
platformWindows[i]._DOMBodyElement.style.cursor = aString;
#endif
}
- (void)push
{
currentCursor = cursorStack.push(self);
}
- (void)pop
{
[CPCursor pop];
}
+ (void)pop
{
if (cursorStack.length > 1)
{
cursorStack.pop();
currentCursor = cursorStack[cursorStack.length - 1];
}
}
- (id)initWithCoder:(CPCoder)coder
{
if (self = [super init])
_cssString = [coder decodeObjectForKey:@"CPCursorNameKey"];
return self;
}
- (void)encodeWithCoder:(CPCoder)coder
{
[coder encodeObject:_cssString forKey:@"CPCursorNameKey"];
}
@end
+10 -7
View File
@@ -280,7 +280,11 @@ var CPDocumentUntitledCount = 0;
else if (viewController)
{
var view = [viewController view],
theWindow = [[CPWindow alloc] initWithContentRect:[view frame] styleMask:CPTitledWindowMask | CPClosableWindowMask | CPMiniaturizableWindowMask | CPResizableWindowMask];
viewFrame = [view frame];
viewFrame.origin = CGPointMake(50, 50);
var theWindow = [[CPWindow alloc] initWithContentRect:viewFrame styleMask:CPTitledWindowMask | CPClosableWindowMask | CPMiniaturizableWindowMask | CPResizableWindowMask];
windowController = [[CPWindowController alloc] initWithWindow:theWindow];
}
@@ -480,14 +484,14 @@ var CPDocumentUntitledCount = 0;
else
[_writeRequest setHTTPMethod:@"PUT"];
[_writeRequest setHTTPBody:[data string]];
[_writeRequest setHTTPBody:[data rawString]];
[_writeRequest setValue:@"close" forHTTPHeaderField:@"Connection"];
if (aSaveOperation == CPSaveOperation)
if (aSaveOperation === CPSaveOperation)
[_writeRequest setValue:@"true" forHTTPHeaderField:@"x-cappuccino-overwrite"];
if (aSaveOperation != CPSaveToOperation)
if (aSaveOperation !== CPSaveToOperation)
[self updateChangeCount:CPChangeCleared];
// FIXME: Oh man is this every looking for trouble, we need to handle login at the Cappuccino level, with HTTP Errors.
@@ -563,7 +567,7 @@ var CPDocumentUntitledCount = 0;
// READ
if (aConnection == _readConnection)
{
[self readFromData:[CPData dataWithString:aData] ofType:session.fileType error:nil];
[self readFromData:[CPData dataWithRawString:aData] ofType:session.fileType error:nil];
objj_msgSend(session.delegate, session.didReadSelector, self, YES, session.contextInfo);
}
@@ -884,8 +888,7 @@ var CPDocumentUntitledCount = 0;
[_canCloseAlert setDelegate:self];
[_canCloseAlert setAlertStyle:CPWarningAlertStyle];
[_canCloseAlert setTitle:@"Unsaved Document"];
[_canCloseAlert setMessageText:sprintf(@"Do you want to save the changes you've made to the document \"%@\"?",
[self displayName] || [self fileName])];
[_canCloseAlert setMessageText:@"Do you want to save the changes you've made to the document \"" + ([self displayName] || [self fileName]) + "\"?"];
[_canCloseAlert addButtonWithTitle:@"Save"];
[_canCloseAlert addButtonWithTitle:@"Cancel"];
+114 -38
View File
@@ -40,29 +40,10 @@ CPDragOperationEvery = -1;
#define DRAGGING_WINDOW(anObject) ([anObject isKindOfClass:[CPWindow class]] ? anObject : [anObject window])
var CPDragServerPreviousEvent = nil,
CPDragServerAutoscrollInterval = nil;
/*
var CPDragServerAutoscroll = function()
{
[CPDragServerSource autoscroll:CPDragServerPreviousEvent];
}
var CPDragServerPreviousEvent = nil,
CPDragServerPeriodicUpdateInterval = 0.05;
if (CPDragServerAutoscrollInterval === nil)
{
if ([CPDragServerSource respondsToSelector:@selector(autoscroll:)])
CPDragServerAutoscrollInterval = setInterval(CPDragServerAutoscroll, 100);
}
CPDragServerPreviousEvent = anEvent;
if (CPDragServerAutoscrollInterval !== nil)
clearInterval(CPDragServerAutoscrollInterval);
CPDragServerAutoscrollInterval = nil;
*/
var CPSharedDragServer = nil;
var CPSharedDragServer = nil;
var CPDragServerSource = nil;
var CPDragServerDraggingInfo = nil;
@@ -127,7 +108,7 @@ var CPDragServerDraggingInfo = nil;
@end
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_endedAt_operation_ = 1 << 3;
@@ -150,6 +131,13 @@ var CPDraggingSource_draggedImage_movedTo_ = 1 << 0,
CGPoint _draggingLocation;
id _draggingDestination;
BOOL _draggingDestinationWantsPeriodicUpdates;
CGPoint _startDragLocation;
BOOL _shouldSlideBack;
unsigned _dragOperation;
CPTimer _draggingUpdateTimer;
}
/*
@@ -189,6 +177,11 @@ var CPDraggingSource_draggedImage_movedTo_ = 1 << 0,
return self;
}
- (id)draggingDestination
{
return _draggingDestination;
}
- (CGPoint)draggingLocation
{
return _draggingLocation
@@ -225,6 +218,9 @@ var CPDraggingSource_draggedImage_movedTo_ = 1 << 0,
- (CPDragOperation)draggingUpdatedInPlatformWindow:(CPPlatformWindow)aPlatformWindow location:(CGPoint)aLocation
{
[_draggingUpdateTimer invalidate];
_draggingUpdateTimer = nil;
var dragOperation = CPDragOperationCopy;
// We have to convert base to bridge since the drag event comes from the source window, not the drag window.
var draggingDestination = [aPlatformWindow _dragHitTest:aLocation pasteboard:[CPDragServerDraggingInfo draggingPasteboard]];
@@ -234,33 +230,96 @@ var CPDraggingSource_draggedImage_movedTo_ = 1 << 0,
if(draggingDestination !== _draggingDestination)
{
if (_draggingDestination && [_draggingDestination respondsToSelector:@selector(draggingExited:)])
if ([_draggingDestination respondsToSelector:@selector(draggingExited:)])
[_draggingDestination draggingExited:CPDragServerDraggingInfo];
_draggingDestination = draggingDestination;
if (_draggingDestination && [_draggingDestination respondsToSelector:@selector(draggingEntered:)])
if ([_draggingDestination respondsToSelector:@selector(wantsPeriodicDraggingUpdates)])
_draggingDestinationWantsPeriodicUpdates = [_draggingDestination wantsPeriodicDraggingUpdates];
else
_draggingDestinationWantsPeriodicUpdates = YES;
if ([_draggingDestination respondsToSelector:@selector(draggingEntered:)])
dragOperation = [_draggingDestination draggingEntered:CPDragServerDraggingInfo];
}
else if (_draggingDestination && [_draggingDestination respondsToSelector:@selector(draggingUpdated:)])
else if ([_draggingDestination respondsToSelector:@selector(draggingUpdated:)])
dragOperation = [_draggingDestination draggingUpdated:CPDragServerDraggingInfo];
if (!_draggingDestination)
dragOperation = CPDragOperationNone;
else
{
if (_draggingDestinationWantsPeriodicUpdates)
_draggingUpdateTimer = [CPTimer scheduledTimerWithTimeInterval:CPDragServerPeriodicUpdateInterval
target:self
selector:@selector(_sendPeriodicDraggingUpdate:)
userInfo:[CPDictionary dictionaryWithJSObject:{platformWindow:aPlatformWindow, location:aLocation}]
repeats:NO];
var scrollView = [_draggingDestination isKindOfClass:[CPView class]] ? [_draggingDestination enclosingScrollView] : nil;
if (scrollView)
{
var contentView = [scrollView contentView],
bounds = [contentView bounds],
insetBounds = CGRectInset(bounds, 10, 10)
eventLocation = [contentView convertPoint:_draggingLocation fromView:nil],
deltaX = 0,
deltaY = 0;
if (!CGRectContainsPoint(insetBounds, eventLocation))
{
if ([scrollView hasVerticalScroller])
{
if (eventLocation.y < CGRectGetMinY(insetBounds))
deltaY = CGRectGetMinY(insetBounds) - eventLocation.y;
else if (eventLocation.y > CGRectGetMaxY(insetBounds))
deltaY = CGRectGetMaxY(insetBounds) - eventLocation.y;
if (deltaY < -insetBounds.size.height)
deltaY = -insetBounds.size.height;
if (deltaY > insetBounds.size.height)
deltaY = insetBounds.size.height;
}
if ([scrollView hasHorizontalScroller])
{
if (eventLocation.x < CGRectGetMinX(insetBounds))
deltaX = CGRectGetMinX(insetBounds) - eventLocation.x;
else if (eventLocation.x > CGRectGetMaxX(insetBounds))
deltaX = CGRectGetMaxX(insetBounds) - eventLocation.x;
if (deltaX < -insetBounds.size.width)
deltaX = -insetBounds.size.width;
if (deltaX > insetBounds.size.width)
deltaX = insetBounds.size.width;
}
[contentView scrollToPoint:CGPointMake(bounds.origin.x - deltaX, bounds.origin.y - deltaY)];
}
}
}
return dragOperation;
}
- (void)_sendPeriodicDraggingUpdate:(CPTimer)aTimer
{
var userInfo = [aTimer userInfo];
_dragOperation = [self draggingUpdatedInPlatformWindow:[userInfo objectForKey:@"platformWindow"]
location:[userInfo objectForKey:@"location"]];
}
- (void)draggingEndedInPlatformWindow:(CPPlatformWindow)aPlatformWindow globalLocation:(CGPoint)aLocation operation:(CPDragOperation)anOperation
{
[_draggingUpdateTimer invalidate];
_draggingUpdateTimer = nil;
[_draggedView removeFromSuperview];
if (![CPPlatform supportsDragAndDrop])
[_draggedWindow orderOut:self];
if (_implementedDraggingSourceMethods & CPDraggingSource_draggedImage_endAt_operation_)
if (_implementedDraggingSourceMethods & CPDraggingSource_draggedImage_endedAt_operation_)
[_draggingSource draggedImage:[_draggedView image] endedAt:aLocation operation:anOperation];
else if (_implementedDraggingSourceMethods & CPDraggingSource_draggedView_endedAt_operation_)
[_draggingSource draggedView:_draggedView endedAt:aLocation operation:anOperation];
@@ -296,6 +355,7 @@ var CPDraggingSource_draggedImage_movedTo_ = 1 << 0,
_draggingPasteboard = aPasteboard || [CPPasteboard pasteboardWithName:CPDragPboard];
_draggingSource = aSourceObject;
_draggingDestination = nil;
_shouldSlideBack = slideBack;
// The offset is based on the distance from where we want the view to be initially from where the mouse is initially
// Hence the use of mouseDownEvent's location and view's location in global coordinates.
@@ -310,7 +370,7 @@ var CPDraggingSource_draggedImage_movedTo_ = 1 << 0,
_draggingOffset = _CGSizeMake(mouseDownEventLocation.x - viewLocation.x, mouseDownEventLocation.y - viewLocation.y);
}
else
_draggingOffset = _CGSizeMakerZero();
_draggingOffset = _CGSizeMakeZero();
if ([CPPlatform isBrowser])
[_draggedWindow setPlatformWindow:[aWindow platformWindow]];
@@ -320,7 +380,8 @@ var CPDraggingSource_draggedImage_movedTo_ = 1 << 0,
var mouseLocation = [CPEvent mouseLocation];
// Place it where the mouse pointer is.
[_draggedWindow setFrameOrigin:_CGPointMake(mouseLocation.x - _draggingOffset.width, mouseLocation.y - _draggingOffset.height)];
_startDragLocation = _CGPointMake(mouseLocation.x - _draggingOffset.width, mouseLocation.y - _draggingOffset.height);
[_draggedWindow setFrameOrigin:_startDragLocation];
[_draggedWindow setFrameSize:[aView frame].size];
[[_draggedWindow contentView] addSubview:aView];
@@ -332,8 +393,8 @@ var CPDraggingSource_draggedImage_movedTo_ = 1 << 0,
if ([_draggingSource respondsToSelector:@selector(draggedImage:movedTo:)])
_implementedDraggingSourceMethods |= CPDraggingSource_draggedImage_movedTo_;
if ([_draggingSource respondsToSelector:@selector(draggedImage:endAt:operation:)])
_implementedDraggingSourceMethods |= CPDraggingSource_draggedImage_endAt_operation_;
if ([_draggingSource respondsToSelector:@selector(draggedImage:endedAt:operation:)])
_implementedDraggingSourceMethods |= CPDraggingSource_draggedImage_endedAt_operation_;
}
else
{
@@ -385,19 +446,34 @@ var CPDraggingSource_draggedImage_movedTo_ = 1 << 0,
if (type === CPLeftMouseUp)
{
[self performDragOperationInPlatformWindow:platformWindow];
[self draggingEndedInPlatformWindow:platformWindow globalLocation:platformWindowLocation operation:CPDragOperationNone];
// Make sure we do not finalize (cancel) the drag if the last drag update was disallowed
if (_dragOperation !== CPDragOperationNone)
[self performDragOperationInPlatformWindow:platformWindow];
[self draggingEndedInPlatformWindow:platformWindow globalLocation:platformWindowLocation operation:_dragOperation];
// Stop tracking events.
return;
}
[self draggingSourceUpdatedWithGlobalLocation:platformWindowLocation];
[self draggingUpdatedInPlatformWindow:platformWindow location:platformWindowLocation];
else if (type === CPKeyDown)
{
var keyCode = [anEvent keyCode];
if (keyCode === CPEscapeKeyCode)
{
_dragOperation = CPDragOperationNone;
[self draggingEndedInPlatformWindow:platformWindow globalLocation:CGPointMakeZero() operation:_dragOperation];
return;
}
}
else
{
[self draggingSourceUpdatedWithGlobalLocation:platformWindowLocation];
_dragOperation = [self draggingUpdatedInPlatformWindow:platformWindow location:platformWindowLocation];
}
// If we're not a mouse up, then we're going to want to grab the next event.
[CPApp setTarget:self selector:@selector(trackDragging:)
forNextEventMatchingMask:CPMouseMovedMask | CPLeftMouseDraggedMask | CPLeftMouseUpMask
forNextEventMatchingMask:CPMouseMovedMask | CPLeftMouseDraggedMask | CPLeftMouseUpMask | CPKeyDownMask
untilDate:nil inMode:0 dequeue:NO];
}
+16 -2
View File
@@ -128,7 +128,7 @@ var _CPEventPeriodicEventPeriod = 0,
BOOL _isARepeat;
unsigned _keyCode;
DOMEvent _DOMEvent;
float _deltaX;
float _deltaY;
float _deltaZ;
@@ -285,6 +285,17 @@ var _CPEventPeriodicEventPeriod = 0,
return _CGPointMakeCopy(_location);
}
- (CGPoint)globalLocation
{
var theWindow = [self window],
location = [self locationInWindow];
if (theWindow)
return [theWindow convertBaseToGlobal:location];
return location;
}
/*!
Returns event information as a bit mask
*/
@@ -334,7 +345,10 @@ var _CPEventPeriodicEventPeriod = 0,
*/
- (int)buttonNumber
{
return _buttonNumber;
if (_type === CPRightMouseDown || _type === CPRightMouseUp || _type === CPRightMouseDragged)
return 1;
return 0;
}
/*!
+28 -5
View File
@@ -30,7 +30,7 @@
*/
@implementation CPFlashMovie : CPObject
{
CPString _fileName;
CPString _filename;
}
/*!
@@ -38,9 +38,9 @@
@param aFilename the swf to load
@return the initialized CPFlashMovie
*/
+ (id)flashMovieWithFile:(CPString)aFileName
+ (id)flashMovieWithFile:(CPString)aFilename
{
return [[self alloc] initWithFile:aFileName];
return [[self alloc] initWithFile:aFilename];
}
/*!
@@ -48,14 +48,37 @@
@param aFilename the swf to load
@return the initialized CPFlashMovie
*/
- (id)initWithFile:(CPString)aFileName
- (id)initWithFile:(CPString)aFilename
{
self = [super init];
if (self)
_fileName = aFileName;
_filename = aFilename;
return self;
}
- (CPString)filename
{
return _filename;
}
@end
var CPFlashMovieFilenameKey = "CPFlashMovieFilenameKey";
@implementation CPFlashMovie (CPCoding)
- (id)initWithCoder:(CPCoder)aCoder
{
_filename = [aCoder decodeObjectForKey:CPFlashMovieFilenameKey];
return self;
}
- (void)encodeWithCoder:(CPCoder)aCoder
{
[aCoder encodeObject:_filename forKey:CPFlashMovieFilenameKey];
}
@end
+128 -36
View File
@@ -23,6 +23,9 @@
@import "CPFlashMovie.j"
@import "CPView.j"
#include "Platform/Platform.h"
var IEFlashCLSID = "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000";
/*!
@ingroup appkit
@@ -31,9 +34,13 @@
{
CPFlashMovie _flashMovie;
DOMElement _DOMEmbedElement;
DOMElement _DOMMParamElement;
CPDictionary _params;
CPDictionary _paramElements;
#if PLATFORM(DOM)
DOMElement _DOMParamElement;
DOMElement _DOMObjectElement;
DOMElement _DOMInnerObjectElement;
#endif
}
- (id)initWithFrame:(CGRect)aFrame
@@ -42,35 +49,32 @@
if (self)
{
_DOMObjectElement = document.createElement("object");
_DOMObjectElement.width = "100%";
_DOMObjectElement.height = "100%";
_DOMObjectElement.style.top = "0px";
_DOMObjectElement.style.left = "0px";
_DOMParamElement = document.createElement("param");
_DOMParamElement.name = "movie";
_DOMObjectElement.appendChild(_DOMParamElement);
var param = document.createElement("param");
param.name = "wmode";
param.value = "transparent";
_DOMObjectElement.appendChild(param);
_DOMEmbedElement = document.createElement("embed");
_DOMEmbedElement.type = "application/x-shockwave-flash";
_DOMEmbedElement.setAttribute("wmode", "transparent");
_DOMEmbedElement.width = "100%";
_DOMEmbedElement.height = "100%";
// IE requires this thing to be in the _DOMElement and not the _DOMObjectElement.
_DOMElement.appendChild(_DOMEmbedElement);
_DOMElement.appendChild(_DOMObjectElement);
#if PLATFORM(DOM)
if (!CPBrowserIsEngine(CPInternetExplorerBrowserEngine))
{
_DOMObjectElement = document.createElement(@"object");
_DOMObjectElement.width = @"100%";
_DOMObjectElement.height = @"100%";
_DOMObjectElement.style.top = @"0px";
_DOMObjectElement.style.left = @"0px";
_DOMObjectElement.type = @"application/x-shockwave-flash";
_DOMObjectElement.setAttribute(@"classid", IEFlashCLSID);
_DOMParamElement = document.createElement(@"param");
_DOMParamElement.name = @"movie";
_DOMInnerObjectElement = document.createElement(@"object");
_DOMInnerObjectElement.width = @"100%";
_DOMInnerObjectElement.height = @"100%";
_DOMObjectElement.appendChild(_DOMParamElement);
_DOMObjectElement.appendChild(_DOMInnerObjectElement);
_DOMElement.appendChild(_DOMObjectElement);
}
else
[self _rebuildIEObjects];
#endif
}
return self;
@@ -82,11 +86,15 @@
return;
_flashMovie = aFlashMovie;
_DOMParamElement.value = aFlashMovie._fileName;
if (_DOMEmbedElement)
_DOMEmbedElement.src = aFlashMovie._fileName;
#if PLATFORM(DOM)
if (!CPBrowserIsEngine(CPInternetExplorerBrowserEngine))
{
_DOMParamElement.value = [aFlashMovie filename];
_DOMInnerObjectElement.data = [aFlashMovie filename];
}
else
[self _rebuildIEObjects];
#endif
}
- (CPFlashMovie)flashMovie
@@ -94,6 +102,90 @@
return _flashMovie;
}
- (void)setFlashVars:(CPDictionary)aDictionary
{
var varString = @"",
enumerator = [aDictionary keyEnumerator];
var key;
while (key = [enumerator nextObject])
varString = [varString stringByAppendingFormat:@"&%@=%@", key, [aDictionary objectForKey:key]];
if (!_params)
_params = [CPDictionary dictionary];
[_params setObject:varString forKey:@"flashvars"];
[self setParameters:_params];
}
- (CPDictionary)flashVars
{
return [_params objectForKey:@"flashvars"];
}
- (void)setParameters:(CPDictionary)aDictionary
{
#if PLATFORM(DOM)
if (_paramElements && !CPBrowserIsEngine(CPInternetExplorerBrowserEngine))
{
var elements = [_paramElements allValues],
count = [elements count];
for (var i = 0; i < count; i++)
_DOMObjectElement.removeChild([elements objectAtIndex:i]);
}
#endif
_params = aDictionary;
#if PLATFORM(DOM)
if (!CPBrowserIsEngine(CPInternetExplorerBrowserEngine))
{
_paramElements = [CPDictionary dictionary];
var enumerator = [_params keyEnumerator],
key;
while (key = [enumerator nextObject] && _DOMObjectElement)
{
var param = document.createElement(@"param");
param.name = key;
param.value = [_params objectForKey:key];
_DOMObjectElement.appendChild(param);
[_paramElements setObject:param forKey:key];
}
}
else
[self _rebuildIEObjects];
#endif
}
- (CPDictionary)parameters
{
return _params;
}
#if PLATFORM(DOM)
- (void)_rebuildIEObjects
{
_DOMElement.innerHTML = @"";
if (![_flashMovie filename])
return;
var paramString = [CPString stringWithFormat:@"<param name='movie' value='%@' />", [_flashMovie filename]],
paramEnumerator = [_params keyEnumerator],
key;
while (key = [paramEnumerator nextObject])
paramString = [paramString stringByAppendingFormat:@"<param name='%@' value='%@' />", key, [_params objectForKey:key]];
_DOMObjectElement = document.createElement(@"object");
_DOMElement.appendChild(_DOMObjectElement);
_DOMObjectElement.outerHTML = [CPString stringWithFormat:@"<object classid=%@ width=%@ height=%@>%@</object>", IEFlashCLSID, CGRectGetWidth([self bounds]), CGRectGetHeight([self bounds]), paramString];
}
#endif
- (void)mouseDragged:(CPEvent)anEvent
{
[[[self window] platformWindow] _propagateCurrentDOMEvent:YES];
+17 -4
View File
@@ -20,10 +20,13 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
var _CPFonts = {};
_CPFontSystemFontFace = @"Arial";
var _CPFonts = {},
_CPFontSystemFontFace = @"Arial, sans-serif",
_CPWrapRegExp = new RegExp("\\s*,\\s*", "g");
#define _CPCachedFont(aName, aSize, isBold) _CPFonts[(isBold ? @"bold " : @"") + ROUND(aSize) + @"px '" + aName + @"'"]
#define _CPCreateCSSString(aName, aSize, isBold) (isBold ? @"bold " : @"") + ROUND(aSize) + @"px " + ((aName === _CPFontSystemFontFace) ? aName : (@"\"" + aName.replace(_CPWrapRegExp, '", "') + @"\", " + _CPFontSystemFontFace))
#define _CPCachedFont(aName, aSize, isBold) _CPFonts[_CPCreateCSSString(aName, aSize, isBold)]
/*!
@ingroup appkit
@@ -95,7 +98,7 @@ var _CPFonts = {};
_size = aSize;
_isBold = isBold;
_cssString = (_isBold ? @"bold " : @"") + ROUND(aSize) + @"px '" + aName + @"'";
_cssString = _CPCreateCSSString(_name, _size, _isBold);
_CPFonts[_cssString] = self;
}
@@ -127,6 +130,16 @@ var _CPFonts = {};
return _name;
}
- (BOOL)isEqual:(id)anObject
{
return [anObject isKindOfClass:[CPFont class]] && [anObject cssString] === [self cssString];
}
- (CPString)description
{
return [CPString stringWithFormat:@"%@ %@ %f pt.", [super description], [self familyName], [self size]];
}
@end
var CPFontNameKey = @"CPFontNameKey",
+1 -1
View File
@@ -51,7 +51,7 @@ var CPSharedFontManager = nil,
// 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.
*/
+ (void)setFontManagerFactory:(Class)aClass
+2 -2
View File
@@ -234,9 +234,9 @@ function CPRectContainsPoint(aRect, aPoint)
@param possibleInner the CGRect to test if it fits inside \c possibleOuter.
@return BOOL \c YES if \c possibleInner fits inside \c possibleOuter.
*/
function CPRectContainsRect(lhsRect, rhsRect)
function CPRectContainsRect(possibleOuter, possibleInner)
{
return CPRectEqualToRect(CPUnionRect(lhsRect, rhsRect), rhsRect);
return CGRectContainsRect(possibleOuter, possibleInner);
}
/*!
+89 -27
View File
@@ -19,7 +19,7 @@
* 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 <Foundation/CPBundle.j>
@import <Foundation/CPNotificationCenter.j>
@import <Foundation/CPObject.j>
@@ -28,6 +28,9 @@
@import "CPGeometry.j"
#include "Platform/Platform.h"
CPImageLoadStatusInitialized = 0;
CPImageLoadStatusLoading = 1;
CPImageLoadStatusCompleted = 2;
@@ -38,17 +41,32 @@ CPImageLoadStatusReadError = 6;
CPImageDidLoadNotification = @"CPImageDidLoadNotification";
// Image Names
CPImageNameColorPanel = @"CPImageNameColorPanel";
CPImageNameColorPanelHighlighted = @"CPImageNameColorPanelHighlighted";
var imagesForNames = { },
AppKitImageForNames = { };
AppKitImageForNames[CPImageNameColorPanel] = CGSizeMake(26.0, 29.0);
AppKitImageForNames[CPImageNameColorPanelHighlighted] = CGSizeMake(26.0, 29.0);
function CPImageInBundle(aFilename, aSize, aBundle)
{
if (!aBundle)
aBundle = [CPBundle mainBundle];
if (aSize)
return [[CPImage alloc] initWithContentsOfFile:[aBundle pathForResource:aFilename] size:aSize];
return [[CPImage alloc] initWithContentsOfFile:[aBundle pathForResource:aFilename]];
}
function CPAppKitImage(aFilename, aSize)
{
return CPImageInBundle(aFilename, aSize, [CPBundle bundleForClass:[CPView class]]);
}
/*!
@ingroup appkit
@class CPImage
@@ -74,10 +92,11 @@ function CPImageInBundle(aFilename, aSize, aBundle)
{
CGSize _size;
CPString _filename;
CPString _name;
id _delegate;
unsigned _loadStatus;
Image _image;
}
@@ -97,14 +116,14 @@ function CPImageInBundle(aFilename, aSize, aBundle)
- (id)initByReferencingFile:(CPString)aFilename size:(CGSize)aSize
{
self = [super init];
if (self)
{
_size = CPSizeCreateCopy(aSize);
_filename = aFilename;
_loadStatus = CPImageLoadStatusInitialized;
}
return self;
}
@@ -117,10 +136,10 @@ function CPImageInBundle(aFilename, aSize, aBundle)
- (id)initWithContentsOfFile:(CPString)aFilename size:(CGSize)aSize
{
self = [self initByReferencingFile:aFilename size:aSize];
if (self)
[self load];
return self;
}
@@ -133,10 +152,10 @@ function CPImageInBundle(aFilename, aSize, aBundle)
- (id)initWithContentsOfFile:(CPString)aFilename
{
self = [self initByReferencingFile:aFilename size:CGSizeMake(-1, -1)];
if (self)
[self load];
return self;
}
@@ -165,6 +184,45 @@ function CPImageInBundle(aFilename, aSize, aBundle)
return _size;
}
+ (id)imageNamed:(CPString)aName
{
var image = imagesForNames[aName];
if (image)
return image;
var imageOrSize = AppKitImageForNames[aName];
if (!imageOrSize.isa)
{
imageOrSize = CPAppKitImage("CPImage/" + aName + ".png", imageOrSize);
[imageOrSize setName:aName];
AppKitImageForNames[aName] = imageOrSize;
}
return imageOrSize;
}
- (void)setName:(CPString)aName
{
if (_name === aName)
return;
if (imagesForNames[aName] === self)
imagesForNames[aName] = nil;
_name = aName;
imagesForNames[aName] = self;
}
- (CPString)name
{
return _name;
}
/*!
Sets the receiver's delegate.
@param the delegate
@@ -200,9 +258,10 @@ function CPImageInBundle(aFilename, aSize, aBundle)
{
if (_loadStatus == CPImageLoadStatusLoading || _loadStatus == CPImageLoadStatusCompleted)
return;
_loadStatus = CPImageLoadStatusLoading;
#if PLATFORM(DOM)
_image = new Image();
var isSynchronous = YES;
@@ -219,7 +278,7 @@ function CPImageInBundle(aFilename, aSize, aBundle)
}
[self _derefFromImage];
}
_image.onerror = function ()
{
if (isSynchronous)
@@ -231,7 +290,7 @@ function CPImageInBundle(aFilename, aSize, aBundle)
}
[self _derefFromImage];
}
_image.onabort = function ()
{
if (isSynchronous)
@@ -243,10 +302,13 @@ function CPImageInBundle(aFilename, aSize, aBundle)
}
[self _derefFromImage];
}
_image.src = _filename;
isSynchronous = NO;
// onload and friends may fire after this point but BEFORE the end of the run loop,
// crazy, I know. So don't set isSynchronous here, rather wait a bit longer.
window.setTimeout(function() { isSynchronous = NO; }, 0);
#endif
}
- (BOOL)isThreePartImage
@@ -279,7 +341,7 @@ function CPImageInBundle(aFilename, aSize, aBundle)
[[CPNotificationCenter defaultCenter]
postNotificationName:CPImageDidLoadNotification
object:self];
if ([_delegate respondsToSelector:@selector(imageDidLoad:)])
[_delegate imageDidLoad:self];
}
@@ -288,7 +350,7 @@ function CPImageInBundle(aFilename, aSize, aBundle)
- (void)_imageDidError
{
_loadStatus = CPImageLoadStatusReadError;
if ([_delegate respondsToSelector:@selector(imageDidError:)])
[_delegate imageDidError:self];
}
@@ -297,7 +359,7 @@ function CPImageInBundle(aFilename, aSize, aBundle)
- (void)_imageDidAbort
{
_loadStatus = CPImageLoadStatusCancelled;
if ([_delegate respondsToSelector:@selector(imageDidAbort:)])
[_delegate imageDidAbort:self];
}
@@ -337,7 +399,7 @@ function CPImageInBundle(aFilename, aSize, aBundle)
- (id)initWithImageSlices:(CPArray)imageSlices isVertical:(BOOL)isVertical
{
self = [super init];
if (self)
{
_imageSlices = imageSlices;
@@ -382,13 +444,13 @@ var CPThreePartImageImageSlicesKey = @"CPThreePartImageImageSlicesKey",
- (id)initWithCoder:(CPCoder)aCoder
{
self = [super init];
if (self)
{
_imageSlices = [aCoder decodeObjectForKey:CPThreePartImageImageSlicesKey];
_isVertical = [aCoder decodeBoolForKey:CPThreePartImageIsVerticalKey];
}
return self;
}
@@ -409,10 +471,10 @@ var CPThreePartImageImageSlicesKey = @"CPThreePartImageImageSlicesKey",
- (id)initWithImageSlices:(CPArray)imageSlices
{
self = [super init];
if (self)
_imageSlices = imageSlices;
return self;
}
@@ -445,10 +507,10 @@ var CPNinePartImageImageSlicesKey = @"CPNinePartImageImageSlicesKey";
- (id)initWithCoder:(CPCoder)aCoder
{
self = [super init];
if (self)
_imageSlices = [aCoder decodeObjectForKey:CPNinePartImageImageSlicesKey];
return self;
}
+11 -15
View File
@@ -31,24 +31,10 @@
#include "CoreGraphics/CGGeometry.h"
/*
@global
@group CPImageScaling
*/
CPScaleProportionally = 0;
/*
@global
@group CPImageScaling
*/
CPScaleToFit = 1;
/*
@global
@group CPImageScaling
*/
CPScaleNone = 2;
var CPImageViewShadowBackgroundColor = nil;
var LEFT_SHADOW_INSET = 3.0,
@@ -225,6 +211,11 @@ var LEFT_SHADOW_INSET = 3.0,
[self setNeedsDisplay:YES];
}
- (unsigned)imageScaling
{
return [self currentValueForThemeAttribute:@"image-scaling"];
}
/*!
Toggles the display of the image view.
*/
@@ -374,12 +365,17 @@ var LEFT_SHADOW_INSET = 3.0,
return _isEditable;
}
- (void)performDragOperation:(CPDraggingInfo)aSender
- (BOOL)performDragOperation:(CPDraggingInfo)aSender
{
var images = [CPKeyedUnarchiver unarchiveObjectWithData:[[aSender draggingPasteboard] dataForType:CPImagesPboardType]];
if ([images count])
{
[self setImage:images[0]];
[self sendAction:[self action] to:[self target]];
}
return YES;
}
@end
-2014
View File
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+556
View File
@@ -0,0 +1,556 @@
#include "../CoreGraphics/CGGeometry.h"
#include "../Platform/Platform.h"
@import "_CPMenuWindow.j"
var MENUBAR_HEIGHT = 28.0,
MENUBAR_MARGIN = 10.0,
MENUBAR_LEFT_MARGIN = 10.0,
MENUBAR_RIGHT_MARGIN = 10.0;
var _CPMenuBarWindowBackgroundColor = nil,
_CPMenuBarWindowFont = nil;
@implementation _CPMenuBarWindow : CPPanel
{
CPMenu _menu;
CPView _highlightView;
CPArray _menuItemViews;
CPMenuItem _trackingMenuItem;
CPImageView _iconImageView;
CPTextField _titleField;
CPColor _textColor;
CPColor _titleColor;
CPColor _textShadowColor;
CPColor _titleShadowColor;
CPColor _highlightColor;
CPColor _highlightTextColor;
CPColor _highlightTextShadowColor;
}
+ (void)initialize
{
if (self != [_CPMenuBarWindow class])
return;
var bundle = [CPBundle bundleForClass:self];
_CPMenuBarWindowFont = [CPFont boldSystemFontOfSize:12.0];
}
+ (CPFont)font
{
return _CPMenuBarWindowFont;
}
- (id)init
{
// This only shows up in browser land, so don't bother calculating metrics in desktop.
var contentRect = [[CPPlatformWindow primaryPlatformWindow] contentBounds];
contentRect.size.height = MENUBAR_HEIGHT;
self = [super initWithContentRect:contentRect styleMask:CPBorderlessWindowMask];
if (self)
{
[self setLevel:CPMainMenuWindowLevel];
[self setAutoresizingMask:CPWindowWidthSizable];
var contentView = [self contentView];
[contentView setAutoresizesSubviews:NO];
[self setBecomesKeyOnlyIfNeeded:YES];
//
_iconImageView = [[CPImageView alloc] initWithFrame:CGRectMake(0.0, 0.0, 16.0, 16.0)];
[contentView addSubview:_iconImageView];
_titleField = [[CPTextField alloc] initWithFrame:CGRectMakeZero()];
[_titleField setFont:[CPFont boldSystemFontOfSize:13.0]];
[_titleField setAlignment:CPCenterTextAlignment];
[_titleField setTextShadowOffset:CGSizeMake(0, 1)];
[contentView addSubview:_titleField];
}
return self;
}
- (void)setTitle:(CPString)aTitle
{
#if PLATFORM(DOM)
var bundleName = [[CPBundle mainBundle] objectForInfoDictionaryKey:@"CPBundleName"];
if (![bundleName length])
document.title = aTitle;
else if ([aTitle length])
document.title = aTitle + @" - " + bundleName;
else
document.title = bundleName;
#endif
[_titleField setStringValue:aTitle];
[_titleField sizeToFit];
[self tile];
}
- (void)setIconImage:(CPImage)anImage
{
[_iconImageView setImage:anImage];
[_iconImageView setHidden:anImage == nil];
[self tile];
}
- (void)setIconImageAlphaValue:(float)anAlphaValue
{
[_iconImageView setAlphaValue:anAlphaValue];
}
- (void)setColor:(CPColor)aColor
{
if (!aColor)
{
if (!_CPMenuBarWindowBackgroundColor)
_CPMenuBarWindowBackgroundColor = [CPColor colorWithPatternImage:[[CPImage alloc] initWithContentsOfFile:[[CPBundle bundleForClass:[_CPMenuBarWindow class]] pathForResource:@"_CPMenuBarWindow/_CPMenuBarWindowBackground.png"] size:CGSizeMake(1.0, 28.0)]];
[[self contentView] setBackgroundColor:_CPMenuBarWindowBackgroundColor];
}
else
[[self contentView] setBackgroundColor:aColor];
}
- (void)setTextColor:(CPColor)aColor
{
if (_textColor == aColor)
return;
_textColor = aColor;
[_menuItemViews makeObjectsPerformSelector:@selector(setTextColor:) withObject:_textColor];
}
- (void)setTitleColor:(CPColor)aColor
{
if (_titleColor == aColor)
return;
_titleColor = aColor;
[_titleField setTextColor:aColor ? aColor : [CPColor blackColor]];
}
- (void)setTextShadowColor:(CPColor)aColor
{
if (_textShadowColor == aColor)
return;
_textShadowColor = aColor;
[_menuItemViews makeObjectsPerformSelector:@selector(setTextShadowColor:) withObject:_textShadowColor];
}
- (void)setTitleShadowColor:(CPColor)aColor
{
if (_titleShadowColor == aColor)
return;
_titleShadowColor = aColor;
[_titleField setTextShadowColor:aColor ? aColor : [CPColor whiteColor]];
}
- (void)setHighlightColor:(CPColor)aColor
{
if (_highlightColor == aColor)
return;
_highlightColor = aColor;
}
- (void)setHighlightTextColor:(CPColor)aColor
{
if (_highlightTextColor == aColor)
return;
_highlightTextColor = aColor;
// [_menuItemViews makeObjectsPerformSelector:@selector(setActivateColor:) withObject:_highlightTextColor];
}
- (void)setHighlightTextShadowColor:(CPColor)aColor
{
if (_highlightTextShadowColor == aColor)
return;
_highlightTextShadowColor = aColor;
// [_menuItemViews makeObjectsPerformSelector:@selector(setActivateShadowColor:) withObject:_highlightTextShadowColor];
}
- (void)setMenu:(CPMenu)aMenu
{
if (_menu == aMenu)
return;
var defaultCenter = [CPNotificationCenter defaultCenter];
if (_menu)
{
[defaultCenter
removeObserver:self
name:CPMenuDidAddItemNotification
object:_menu];
[defaultCenter
removeObserver:self
name:CPMenuDidChangeItemNotification
object:_menu];
[defaultCenter
removeObserver:self
name:CPMenuDidRemoveItemNotification
object:_menu];
var items = [_menu itemArray],
count = items.length;
while (count--)
[[items[count] _menuItemView] removeFromSuperview];
}
_menu = aMenu;
if (_menu)
{
[defaultCenter
addObserver:self
selector:@selector(menuDidAddItem:)
name:CPMenuDidAddItemNotification
object:_menu];
[defaultCenter
addObserver:self
selector:@selector(menuDidChangeItem:)
name:CPMenuDidChangeItemNotification
object:_menu];
[defaultCenter
addObserver:self
selector:@selector(menuDidRemoveItem:)
name:CPMenuDidRemoveItemNotification
object:_menu];
}
_menuItemViews = [];
var contentView = [self contentView],
items = [_menu itemArray],
count = items.length;
for (index = 0; index < count; ++index)
{
var item = items[index],
menuItemView = [item _menuItemView];
_menuItemViews.push(menuItemView);
[menuItemView setTextColor:_textColor];
[menuItemView setHidden:[item isHidden]];
[menuItemView synchronizeWithMenuItem];
[contentView addSubview:menuItemView];
}
[self tile];
}
- (void)menuDidChangeItem:(CPNotification)aNotification
{
var menuItem = [_menu itemAtIndex:[[aNotification userInfo] objectForKey:@"CPMenuItemIndex"]],
menuItemView = [menuItem _menuItemView];
[menuItemView setHidden:[menuItem isHidden]];
[menuItemView synchronizeWithMenuItem];
[self tile];
}
- (void)menuDidAddItem:(CPNotification)aNotification
{
var index = [[aNotification userInfo] objectForKey:@"CPMenuItemIndex"],
menuItem = [_menu itemAtIndex:index],
menuItemView = [menuItem _menuItemView];
[_menuItemViews insertObject:menuItemView atIndex:index];
[menuItemView setTextColor:_textColor];
[menuItemView setHidden:[menuItem isHidden]];
[menuItemView synchronizeWithMenuItem];
[[self contentView] addSubview:menuItemView];
[self tile];
}
- (void)menuDidRemoveItem:(CPNotification)aNotification
{
var index = [[aNotification userInfo] objectForKey:@"CPMenuItemIndex"],
menuItemView = [_menuItemViews objectAtIndex:index];
[_menuItemViews removeObjectAtIndex:index];
[menuItemView removeFromSuperview];
[self tile];
}
- (void)mouseDown:(CPEvent)anEvent
{
var constraintRect = CGRectInset([[self platformWindow] visibleFrame], 5.0, 0.0);
constraintRect.size.height -= 5.0;
[[_CPMenuManager sharedMenuManager]
beginTracking:anEvent
menuContainer:self
constraintRect:constraintRect
callback:function(aMenuContainer, aMenu)
{
[aMenu _performActionOfHighlightedItemChain];
[aMenu _highlightItemAtIndex:CPNotFound];
}];
}
- (CPFont)font
{
[CPFont systemFontOfSize:12.0];
}
- (void)tile
{
var items = [_menu itemArray],
index = 0,
count = items.length,
x = MENUBAR_LEFT_MARGIN,
y = 0.0,
isLeftAligned = YES;
for (; index < count; ++index)
{
var item = items[index];
if ([item isSeparatorItem])
{
x = CGRectGetWidth([self frame]) - MENUBAR_RIGHT_MARGIN;
isLeftAligned = NO;
continue;
}
if ([item isHidden])
continue;
var menuItemView = [item _menuItemView],
frame = [menuItemView frame];
if (isLeftAligned)
{
[menuItemView setFrame:CGRectMake(x, 0.0, CGRectGetWidth(frame), MENUBAR_HEIGHT)];
x += CGRectGetWidth([menuItemView frame]);
}
else
{
[menuItemView setFrame:CGRectMake(x - CGRectGetWidth(frame), 0.0, CGRectGetWidth(frame), MENUBAR_HEIGHT)];
x = CGRectGetMinX([menuItemView frame]);
}
}
var bounds = [[self contentView] bounds],
titleFrame = [_titleField frame];
if ([_iconImageView isHidden])
[_titleField setFrameOrigin:CGPointMake((CGRectGetWidth(bounds) - CGRectGetWidth(titleFrame)) / 2.0, (CGRectGetHeight(bounds) - CGRectGetHeight(titleFrame)) / 2.0)];
else
{
var iconFrame = [_iconImageView frame],
iconWidth = CGRectGetWidth(iconFrame),
totalWidth = iconWidth + CGRectGetWidth(titleFrame);
[_iconImageView setFrameOrigin:CGPointMake((CGRectGetWidth(bounds) - totalWidth) / 2.0, (CGRectGetHeight(bounds) - CGRectGetHeight(iconFrame)) / 2.0)];
[_titleField setFrameOrigin:CGPointMake((CGRectGetWidth(bounds) - totalWidth) / 2.0 + iconWidth, (CGRectGetHeight(bounds) - CGRectGetHeight(titleFrame)) / 2.0)];
}
}
- (void)setFrame:(CGRect)aRect display:(BOOL)shouldDisplay animate:(BOOL)shouldAnimate
{
var size = [self frame].size;
[super setFrame:aRect display:shouldDisplay animate:shouldAnimate];
if (!_CGSizeEqualToSize(size, aRect.size))
[self tile];
}
@end
@implementation _CPMenuBarWindow (CPMenuContainer)
- (BOOL)isMenuBar
{
return YES;
}
- (CGRect)globalFrame
{
return [self frame];
}
- (_CPManagerScrollingState)scrollingStateForPoint:(CGPoint)aGlobalLocation
{
return _CPMenuManagerScrollingStateNone;
}
- (CPInteger)itemIndexAtPoint:(CGPoint)aPoint
{
var items = [_menu itemArray],
index = items.length;
while (index--)
{
var item = items[index];
if ([item isHidden] || [item isSeparatorItem])
continue;
if (CGRectContainsPoint([self rectForItemAtIndex:index], aPoint))
return index;
}
return CPNotFound;
}
- (CGRect)rectForItemAtIndex:(CPInteger)anIndex
{
var menuItem = [_menu itemAtIndex:anIndex === CPNotFound ? 0 : anIndex];
return [[menuItem _menuItemView] frame];
}
@end
@implementation _CPMenuBarView : _CPMenuView
{
}
- (CGRect)rectForItemAtIndex:(int)anIndex
{
return [_menuItemViews[anIndex === CPNotFound ? 0 : anIndex] frame];
}
- (int)itemIndexAtPoint:(CGPoint)aPoint
{
var bounds = [self bounds];
if (!CGRectContainsPoint(bounds, aPoint))
return CPNotFound;
var x = aPoint.x,
low = 0,
high = _visibleMenuItemInfos.length - 1;
while (low <= high)
{
var middle = FLOOR(low + (high - low) / 2),
info = _visibleMenuItemInfos[middle],
frame = [info.view frame];
if (x < CGRectGetMinX(frame))
high = middle - 1;
else if (x > CGRectGetMaxX(frame))
low = middle + 1;
else
return info.index;
}
return CPNotFound;
}
- (void)tile
{
var items = [_menu itemArray],
index = 0,
count = items.length,
x = MENUBAR_LEFT_MARGIN,
y = 0.0,
isLeftAligned = YES;
for (; index < count; ++index)
{
var item = items[index];
if ([item isSeparatorItem])
{
x = CGRectGetWidth([self frame]) - MENUBAR_RIGHT_MARGIN;
isLeftAligned = NO;
continue;
}
if ([item isHidden])
continue;
var menuItemView = [item _menuItemView],
frame = [menuItemView frame];
if (isLeftAligned)
{
[menuItemView setFrameOrigin:CGPointMake(x, (MENUBAR_HEIGHT - 1.0 - CGRectGetHeight(frame)) / 2.0)];
x += CGRectGetWidth([menuItemView frame]) + MENUBAR_MARGIN;
}
else
{
[menuItemView setFrameOrigin:CGPointMake(x - CGRectGetWidth(frame), (MENUBAR_HEIGHT - 1.0 - CGRectGetHeight(frame)) / 2.0)];
x = CGRectGetMinX([menuItemView frame]) - MENUBAR_MARGIN;
}
}
var bounds = [[self contentView] bounds],
titleFrame = [_titleField frame];
if ([_iconImageView isHidden])
[_titleField setFrameOrigin:CGPointMake((CGRectGetWidth(bounds) - CGRectGetWidth(titleFrame)) / 2.0, (CGRectGetHeight(bounds) - CGRectGetHeight(titleFrame)) / 2.0)];
else
{
var iconFrame = [_iconImageView frame],
iconWidth = CGRectGetWidth(iconFrame),
totalWidth = iconWidth + CGRectGetWidth(titleFrame);
[_iconImageView setFrameOrigin:CGPointMake((CGRectGetWidth(bounds) - totalWidth) / 2.0, (CGRectGetHeight(bounds) - CGRectGetHeight(iconFrame)) / 2.0)];
[_titleField setFrameOrigin:CGPointMake((CGRectGetWidth(bounds) - totalWidth) / 2.0 + iconWidth, (CGRectGetHeight(bounds) - CGRectGetHeight(titleFrame)) / 2.0)];
}
}
@end
+370
View File
@@ -0,0 +1,370 @@
#include "../CoreGraphics/CGGeometry.h"
@import <Foundation/CPObject.j>
_CPMenuManagerScrollingStateUp = -1,
_CPMenuManagerScrollingStateDown = 1,
_CPMenuManagerScrollingStateNone = 0;
var STICKY_TIME_INTERVAL = 500;
var SharedMenuManager = nil;
@implementation _CPMenuManager: CPObject
{
CPTimeInterval _startTime;
int _scrollingState;
CGPoint _lastGlobalLocation;
CPView _lastMouseOverMenuView;
CGRect _constraintRect;
CPMutableArray _menuContainerStack;
Function _trackingCallback;
}
+ (_CPMenuManager)sharedMenuManager
{
if (!SharedMenuManager)
SharedMenuManager = [[_CPMenuManager alloc] init];
return SharedMenuManager;
}
- (id)init
{
if (SharedMenuManager)
return SharedMenuManager;
return [super init];
}
- (id)trackingMenuContainer
{
return _menuContainerStack[0];
}
- (CPMenu)trackingMenu
{
return [[self trackingMenuContainer] menu];
}
- (void)beginTracking:(CPEvent)anEvent
menuContainer:(id)aMenuContainer
constraintRect:(CGRect)aRect
callback:(Function)aCallback
{
var menu = [aMenuContainer menu];
CPApp._activeMenu = menu;
_startTime = [anEvent timestamp];//new Date();
_scrollingState = _CPMenuManagerScrollingStateNone;
_constraintRect = aRect;
_menuContainerStack = [aMenuContainer];
_trackingCallback = aCallback;
if (menu === [CPApp mainMenu])
{
var globalLocation = [anEvent globalLocation];
// Find which menu window the mouse is currently on top of
var menuLocation = [aMenuContainer convertGlobalToBase:globalLocation];
// Find out the item the mouse is currently on top of
var activeItemIndex = [aMenuContainer itemIndexAtPoint:menuLocation],
activeItem = activeItemIndex !== CPNotFound ? [menu itemAtIndex:activeItemIndex] : nil;
_menuBarButtonItemIndex = activeItemIndex;
_menuBarButtonMenuContainer = aMenuContainer;
if ([activeItem _isMenuBarButton])
return [self trackMenuBarButtonEvent:anEvent];
}
[self trackEvent:anEvent];
}
- (void)trackEvent:(CPEvent)anEvent
{
var type = [anEvent type],
trackingMenu = [self trackingMenu];
// Close Menu Event.
if (type === CPAppKitDefined)
return [self completeTracking]
[CPApp setTarget:self selector:@selector(trackEvent:) forNextEventMatchingMask:CPPeriodicMask | CPMouseMovedMask | CPLeftMouseDraggedMask | CPLeftMouseUpMask | CPAppKitDefinedMask untilDate:nil inMode:nil dequeue:YES];
// Periodic events don't have a valid location.
var globalLocation = type === CPPeriodic ? _lastGlobalLocation : [anEvent globalLocation];
// Remember this for the next periodic event.
_lastGlobalLocation = globalLocation;
// Find which menu window the mouse is currently on top of
var activeMenuContainer = [self menuContainerForPoint:globalLocation],
activeMenu = [activeMenuContainer menu],
menuLocation = [activeMenuContainer convertGlobalToBase:globalLocation];
// Find out the item the mouse is currently on top of
var activeItemIndex = activeMenuContainer ? [activeMenuContainer itemIndexAtPoint:menuLocation] : CPNotFound,
activeItem = activeItemIndex !== CPNotFound ? [activeMenu itemAtIndex:activeItemIndex] : nil;
// If the item isn't enabled its as if we clicked on nothing.
if (![activeItem isEnabled] || [activeItem _isMenuBarButton])
{
activeItemIndex = CPNotFound;
activeItem = nil;
}
var mouseOverMenuView = [activeItem view];
if (type === CPPeriodic)
{
if (_scrollingState === _CPMenuManagerScrollingStateUp)
[activeMenuContainer scrollUp];
else if (_scrollingState === _CPMenuManagerScrollingStateDown)
[activeMenuContainer scrollDown];
}
// If we're over a custom menu view...
if (mouseOverMenuView)
{
if (!_lastMouseOverMenuView)
[activeMenu _highlightItemAtIndex:CPNotFound];
if (_lastMouseOverMenuView != mouseOverMenuView)
{
[mouseOverMenuView mouseExited:anEvent];
// FIXME: Possibly multiple of these?
[_lastMouseOverMenuView mouseEntered:anEvent];
_lastMouseOverMenuView = mouseOverMenuView;
}
var menuContainerWindow = activeMenuContainer;
if (![menuContainerWindow isKindOfClass:[CPWindow class]])
menuContainerWindow = [menuContainerWindow window];
[menuContainerWindow
sendEvent:[CPEvent mouseEventWithType:type location:menuLocation modifierFlags:[anEvent modifierFlags]
timestamp:[anEvent timestamp]
windowNumber:menuContainerWindow
context:nil
eventNumber:0
clickCount:[anEvent clickCount]
pressure:[anEvent pressure]]];
}
else
{
if (_lastMouseOverMenuView)
{
[_lastMouseOverMenuView mouseExited:anEvent];
_lastMouseOverMenuView = nil;
}
[activeMenu _highlightItemAtIndex:activeItemIndex];
if (type === CPMouseMoved || type === CPLeftMouseDragged || type === CPLeftMouseDown)
{
var oldScrollingState = _scrollingState;
_scrollingState = [activeMenuContainer scrollingStateForPoint:globalLocation];
if (_scrollingState !== oldScrollingState)
{
if (_scrollingState === _CPMenuManagerScrollingStateNone)
[CPEvent stopPeriodicEvents];
else if (oldScrollingState === _CPMenuManagerScrollingStateNone)
[CPEvent startPeriodicEventsAfterDelay:0.0 withPeriod:0.04];
}
}
else if (type === CPLeftMouseUp && ([anEvent timestamp] - _startTime > STICKY_TIME_INTERVAL))
[trackingMenu cancelTracking];
}
// If the item has a submenu, show it.
if ([activeItem hasSubmenu])// && [activeItem action] === @selector(submenuAction:))
{
var activeItemRect = [activeMenuContainer rectForItemAtIndex:activeItemIndex];
if ([activeMenuContainer isMenuBar])
var newMenuOrigin = CGPointMake(CGRectGetMinX(activeItemRect), CGRectGetMaxY(activeItemRect));
else
var newMenuOrigin = CGPointMake(CGRectGetMaxX(activeItemRect), CGRectGetMinY(activeItemRect));
newMenuOrigin = [activeMenuContainer convertBaseToGlobal:newMenuOrigin];
[self showMenu:[activeItem submenu] fromMenu:[activeItem menu] atPoint:newMenuOrigin];
}
// This handles both the case where we've moved away from the menu, and where
// we've moved to an item without a submenu.
else
[self showMenu:nil fromMenu:activeMenu atPoint:CGPointMakeZero()];
}
- (void)trackMenuBarButtonEvent:(CPEvent)anEvent
{
var type = [anEvent type];
if (type === CPAppKitDefined)
return [self completeTracking];
var globalLocation = [anEvent globalLocation];
// Find which menu window the mouse is currently on top of
var menu = [self trackingMenu],
trackingMenuContainer = [self trackingMenuContainer],
menuLocation = [trackingMenuContainer convertGlobalToBase:globalLocation];
if ([trackingMenuContainer itemIndexAtPoint:menuLocation] === _menuBarButtonItemIndex)
[menu _highlightItemAtIndex:_menuBarButtonItemIndex];
else
[menu _highlightItemAtIndex:CPNotFound];
[CPApp setTarget:self selector:@selector(trackMenuBarButtonEvent:) forNextEventMatchingMask:CPPeriodicMask | CPMouseMovedMask | CPLeftMouseDraggedMask | CPLeftMouseUpMask | CPAppKitDefinedMask untilDate:nil inMode:nil dequeue:YES];
if (type === CPLeftMouseUp)
[menu cancelTracking];
}
- (void)completeTracking
{
var trackingMenu = [self trackingMenu];
// Stop all periodic events at this point.
[CPEvent stopPeriodicEvents];
// Get the highlighted item from the original menu.
var highlightedItem = [trackingMenu highlightedItem];
// Hide all submenus.
[self showMenu:nil fromMenu:trackingMenu atPoint:nil];
var delegate = [trackingMenu delegate];
if ([delegate respondsToSelector:@selector(menuDidClose:)])
[delegate menuDidClose:trackingMenu];
if (_trackingCallback)
_trackingCallback([self trackingMenuContainer], trackingMenu);
[[CPNotificationCenter defaultCenter]
postNotificationName:CPMenuDidEndTrackingNotification
object:trackingMenu];
CPApp._activeMenu = nil;
}
- (id)menuContainerForPoint:(float)aGlobalLocation
{
var count = [_menuContainerStack count],
firstMenuContainer = _menuContainerStack[0];
// Trivial case.
if (count === 1)
return firstMenuContainer;
var firstMenuWindowIndex = 0,
lastMenuWindowIndex = count - 1;
// If the first menu container is a bar, then it has to fall strictly within its bounds.
if ([firstMenuContainer isMenuBar])
{
if (CGRectContainsPoint([firstMenuContainer globalFrame], aGlobalLocation))
return firstMenuContainer;
firstMenuWindowIndex = 1;
}
var index = count,
x = aGlobalLocation.x,
closerDeltaX = Infinity,
closerMenuContainer = nil;
while (index-- > firstMenuWindowIndex)
{
var menuContainer = _menuContainerStack[index],
menuContainerFrame = [menuContainer globalFrame],
menuContainerMinX = _CGRectGetMinX(menuContainerFrame),
menuContainerMaxX = _CGRectGetMaxX(menuContainerFrame);
// If within the x bounds of this menu container, return it.
if (x < menuContainerMaxX && x >= menuContainerMinX)
return menuContainer;
// If this is either the first or last menu *window*, check to see how close we are to it.
if (index === firstMenuWindowIndex || index === lastMenuWindowIndex)
{
var deltaX = ABS(x < menuContainerMinX ? menuContainerMinX - x : menuContainerMaxX - x);
if (deltaX < closerDeltaX)
{
closerMenuContainer = menuContainer;
closerDeltaX = deltaX;
}
}
}
return closerMenuContainer;
}
- (void)showMenu:(CPMenu)newMenu fromMenu:(CPMenu)baseMenu atPoint:(CGPoint)aGlobalLocation
{
var count = _menuContainerStack.length,
index = count;
// Hide all menus up to the base menu...
while (index--)
{
var menuContainer = _menuContainerStack[index],
menu = [menuContainer menu];
// If we reach the base menu, or this menu is already being shown, break.
if (menu === baseMenu)
break;
// If this menu is already being shown, unhighlight and return.
if (menu === newMenu)//&& [menu supermenu] === baseMenu)
return [newMenu _highlightItemAtIndex:CPNotFound];
[menuContainer orderOut:self];
[menuContainer setMenu:nil];
[_CPMenuWindow poolMenuWindow:menuContainer];
[_menuContainerStack removeObjectAtIndex:index];
}
if (!newMenu)
return;
// Unhighlight any previously highlighted item.
[newMenu _highlightItemAtIndex:CPNotFound];
var menuWindow = [_CPMenuWindow menuWindowWithMenu:newMenu font:[_menuContainerStack[0] font]];
[_menuContainerStack addObject:menuWindow];
[menuWindow setConstraintRect:_constraintRect];
// If our parent menu is a menu bar...
if (baseMenu === [self trackingMenu] && [[self trackingMenuContainer] isMenuBar])
[menuWindow setBackgroundStyle:_CPMenuWindowMenuBarBackgroundStyle];
else
[menuWindow setBackgroundStyle:_CPMenuWindowPopUpBackgroundStyle];
[menuWindow setFrameOrigin:aGlobalLocation];
[menuWindow orderFront:self];
}
@end
+548
View File
@@ -0,0 +1,548 @@
#include "../CoreGraphics/CGGeometry.h"
var _CPMenuWindowPool = [],
_CPMenuWindowPoolCapacity = 5,
_CPMenuWindowBackgroundColors = [];
_CPMenuWindowMenuBarBackgroundStyle = 0;
_CPMenuWindowPopUpBackgroundStyle = 1;
_CPMenuWindowAttachedMenuBackgroundStyle = 2;
var STICKY_TIME_INTERVAL = 500,
TOP_MARGIN = 5.0,
LEFT_MARGIN = 1.0,
RIGHT_MARGIN = 1.0,
BOTTOM_MARGIN = 5.0,
SCROLL_INDICATOR_HEIGHT = 16.0;
/*
@ignore
*/
@implementation _CPMenuWindow : CPWindow
{
_CPMenuView _menuView;
CPClipView _menuClipView;
CPImageView _moreAboveView;
CPImageView _moreBelowView;
CGRect _unconstrainedFrame;
CGRect _constraintRect;
}
+ (id)menuWindowWithMenu:(CPMenu)aMenu font:(CPFont)aFont
{
var menuWindow = nil;
if (_CPMenuWindowPool.length)
{
menuWindow = _CPMenuWindowPool.pop();
// Do this so that coordinates will be accurate.
[menuWindow setFrameOrigin:CGPointMakeZero()];
}
else
menuWindow = [[_CPMenuWindow alloc] init];
[menuWindow setFont:aFont];
[menuWindow setMenu:aMenu];
[menuWindow setMinWidth:[aMenu minimumWidth]];
return menuWindow;
}
+ (void)poolMenuWindow:(_CPMenuWindow)aMenuWindow
{
if (!aMenuWindow || _CPMenuWindowPool.length >= _CPMenuWindowPoolCapacity)
return;
_CPMenuWindowPool.push(aMenuWindow);
}
+ (void)initialize
{
if (self != [_CPMenuWindow class])
return;
var bundle = [CPBundle bundleForClass:self];
_CPMenuWindowMoreAboveImage = [[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"_CPMenuWindow/_CPMenuWindowMoreAbove.png"] size:CGSizeMake(38.0, 18.0)];
_CPMenuWindowMoreBelowImage = [[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"_CPMenuWindow/_CPMenuWindowMoreBelow.png"] size:CGSizeMake(38.0, 18.0)];
}
- (id)initWithContentRect:(CGRect)aRect styleMask:(unsigned)aStyleMask
{
_constraintRect = _CGRectMakeZero();
_unconstrainedFrame = _CGRectMakeZero();
self = [super initWithContentRect:aRect styleMask:CPBorderlessWindowMask];
if (self)
{
[self setLevel:CPPopUpMenuWindowLevel];
[self setHasShadow:YES];
[self setShadowStyle:CPMenuWindowShadowStyle];
[self setAcceptsMouseMovedEvents:YES];
var contentView = [self contentView];
_menuView = [[_CPMenuView alloc] initWithFrame:CGRectMakeZero()];
_menuClipView = [[CPClipView alloc] initWithFrame:CGRectMake(LEFT_MARGIN, TOP_MARGIN, 0.0, 0.0)];
[_menuClipView setDocumentView:_menuView];
[contentView addSubview:_menuClipView];
_moreAboveView = [[CPImageView alloc] initWithFrame:CGRectMakeZero()];
[_moreAboveView setImage:_CPMenuWindowMoreAboveImage];
[_moreAboveView setFrameSize:[_CPMenuWindowMoreAboveImage size]];
[contentView addSubview:_moreAboveView];
_moreBelowView = [[CPImageView alloc] initWithFrame:CGRectMakeZero()];
[_moreBelowView setImage:_CPMenuWindowMoreBelowImage];
[_moreBelowView setFrameSize:[_CPMenuWindowMoreBelowImage size]];
[contentView addSubview:_moreBelowView];
[self setShadowStyle:CPWindowShadowStyleMenu];
}
return self;
}
+ (float)_standardLeftMargin
{
return LEFT_MARGIN;
}
- (void)setFont:(CPFont)aFont
{
[_menuView setFont:aFont];
}
- (CPFont)font
{
return [_menuView font];
}
+ (CPColor)backgroundColorForBackgroundStyle:(_CPMenuWindowBackgroundStyle)aBackgroundStyle
{
var color = _CPMenuWindowBackgroundColors[aBackgroundStyle];
if (!color)
{
var bundle = [CPBundle bundleForClass:[self class]];
if (aBackgroundStyle == _CPMenuWindowPopUpBackgroundStyle)
color = [CPColor colorWithPatternImage:[[CPNinePartImage alloc] initWithImageSlices:
[
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"_CPMenuWindow/_CPMenuWindowRounded0.png"] size:CGSizeMake(4.0, 4.0)],
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"_CPMenuWindow/_CPMenuWindow1.png"] size:CGSizeMake(1.0, 4.0)],
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"_CPMenuWindow/_CPMenuWindowRounded2.png"] size:CGSizeMake(4.0, 4.0)],
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"_CPMenuWindow/_CPMenuWindow3.png"] size:CGSizeMake(4.0, 1.0)],
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"_CPMenuWindow/_CPMenuWindow4.png"] size:CGSizeMake(1.0, 1.0)],
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"_CPMenuWindow/_CPMenuWindow5.png"] size:CGSizeMake(4.0, 1.0)],
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"_CPMenuWindow/_CPMenuWindowRounded6.png"] size:CGSizeMake(4.0, 4.0)],
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"_CPMenuWindow/_CPMenuWindow7.png"] size:CGSizeMake(1.0, 4.0)],
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"_CPMenuWindow/_CPMenuWindowRounded8.png"] size:CGSizeMake(4.0, 4.0)]
]]];
else if (aBackgroundStyle == _CPMenuWindowMenuBarBackgroundStyle)
color = [CPColor colorWithPatternImage:[[CPNinePartImage alloc] initWithImageSlices:
[
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"_CPMenuWindow/_CPMenuWindow3.png"] size:CGSizeMake(4.0, 0.0)],
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"_CPMenuWindow/_CPMenuWindow4.png"] size:CGSizeMake(1.0, 0.0)],
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"_CPMenuWindow/_CPMenuWindow5.png"] size:CGSizeMake(4.0, 0.0)],
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"_CPMenuWindow/_CPMenuWindow3.png"] size:CGSizeMake(4.0, 1.0)],
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"_CPMenuWindow/_CPMenuWindow4.png"] size:CGSizeMake(1.0, 1.0)],
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"_CPMenuWindow/_CPMenuWindow5.png"] size:CGSizeMake(4.0, 1.0)],
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"_CPMenuWindow/_CPMenuWindowRounded6.png"] size:CGSizeMake(4.0, 4.0)],
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"_CPMenuWindow/_CPMenuWindow7.png"] size:CGSizeMake(1.0, 4.0)],
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"_CPMenuWindow/_CPMenuWindowRounded8.png"] size:CGSizeMake(4.0, 4.0)]
]]];
_CPMenuWindowBackgroundColors[aBackgroundStyle] = color;
}
return color;
}
- (void)setBackgroundStyle:(_CPMenuWindowBackgroundStyle)aBackgroundStyle
{
[self setBackgroundColor:[[self class] backgroundColorForBackgroundStyle:aBackgroundStyle]];
}
- (void)setMenu:(CPMenu)aMenu
{
[aMenu _setMenuWindow:self];
[_menuView setMenu:aMenu];
var menuViewSize = [_menuView frame].size;
[self setFrameSize:CGSizeMake(LEFT_MARGIN + menuViewSize.width + RIGHT_MARGIN, TOP_MARGIN + menuViewSize.height + BOTTOM_MARGIN)];
[_menuView scrollPoint:CGPointMake(0.0, 0.0)];
[_menuClipView setFrame:CGRectMake(LEFT_MARGIN, TOP_MARGIN, menuViewSize.width, menuViewSize.height)];
}
- (void)setMinWidth:(float)aWidth
{
var size = [self unconstrainedFrame].size;
[self setFrameSize:CGSizeMake(MAX(size.width, aWidth), size.height)];
}
- (CPMenu)menu
{
return [_menuView menu];
}
- (void)orderFront:(id)aSender
{
[self setFrame:_unconstrainedFrame];
[super orderFront:aSender];
}
- (void)setConstraintRect:(CGRect)aRect
{
_constraintRect = aRect;
[self setFrame:_unconstrainedFrame];
}
- (CGRect)unconstrainedFrame
{
return _CGRectMakeCopy(_unconstrainedFrame);
}
// We need this because if not this will call setFrame: with -frame instead of -unconstrainedFrame, turning
// the constrained frame into the unconstrained frame.
- (void)setFrameOrigin:(CGPoint)aPoint
{
[super setFrame:_CGRectMake(aPoint.x, aPoint.y, _CGRectGetWidth(_unconstrainedFrame), _CGRectGetHeight(_unconstrainedFrame))];
}
- (void)setFrameSize:(CGSize)aSize
{
[super setFrame:_CGRectMake(_CGRectGetMinX(_unconstrainedFrame), _CGRectGetMinY(_unconstrainedFrame), aSize.width, aSize.height)];
}
- (void)setFrame:(CGRect)aFrame display:(BOOL)shouldDisplay animate:(BOOL)shouldAnimate
{
// FIXME: There are integral window issues with platform windows.
// FIXME: This gets called far too often.
_unconstrainedFrame = _CGRectMakeCopy(aFrame);
var constrainedFrame = CGRectIntersection(_unconstrainedFrame, _constraintRect);
// We don't want to simply intersect the visible frame and the unconstrained frame.
// We should be allowing as much of the width to fit as possible (pushing back and forward).
constrainedFrame.origin.x = CGRectGetMinX(_unconstrainedFrame);
constrainedFrame.size.width = CGRectGetWidth(_unconstrainedFrame);
if (CGRectGetWidth(constrainedFrame) > CGRectGetWidth(_constraintRect))
constrainedFrame.size.width = CGRectGetWidth(_constraintRect);
if (CGRectGetMaxX(constrainedFrame) > CGRectGetMaxX(_constraintRect))
constrainedFrame.origin.x -= CGRectGetMaxX(constrainedFrame) - CGRectGetMaxX(_constraintRect);
if (CGRectGetMinX(constrainedFrame) < CGRectGetMinX(_constraintRect))
constrainedFrame.origin.x = CGRectGetMinX(_constraintRect);
[super setFrame:constrainedFrame display:shouldDisplay animate:shouldAnimate];
// This needs to happen before changing the frame.
var menuViewOrigin = CGPointMake(CGRectGetMinX(aFrame) + LEFT_MARGIN, CGRectGetMinY(aFrame) + TOP_MARGIN),
moreAbove = menuViewOrigin.y < CGRectGetMinY(constrainedFrame) + TOP_MARGIN,
moreBelow = menuViewOrigin.y + CGRectGetHeight([_menuView frame]) > CGRectGetMaxY(constrainedFrame) - BOTTOM_MARGIN,
topMargin = TOP_MARGIN,
bottomMargin = BOTTOM_MARGIN,
contentView = [self contentView],
bounds = [contentView bounds];
if (moreAbove)
{
topMargin += SCROLL_INDICATOR_HEIGHT;
var frame = [_moreAboveView frame];
[_moreAboveView setFrameOrigin:CGPointMake((CGRectGetWidth(bounds) - CGRectGetWidth(frame)) / 2.0, (TOP_MARGIN + SCROLL_INDICATOR_HEIGHT - CGRectGetHeight(frame)) / 2.0)];
}
[_moreAboveView setHidden:!moreAbove];
if (moreBelow)
{
bottomMargin += SCROLL_INDICATOR_HEIGHT;
[_moreBelowView setFrameOrigin:CGPointMake((CGRectGetWidth(bounds) - CGRectGetWidth([_moreBelowView frame])) / 2.0, CGRectGetHeight(bounds) - SCROLL_INDICATOR_HEIGHT - BOTTOM_MARGIN)];
}
[_moreBelowView setHidden:!moreBelow];
var clipFrame = CGRectMake(LEFT_MARGIN, topMargin, CGRectGetWidth(constrainedFrame) - LEFT_MARGIN - RIGHT_MARGIN, CGRectGetHeight(constrainedFrame) - topMargin - bottomMargin)
[_menuClipView setFrame:clipFrame];
[_menuView setFrameSize:CGSizeMake(CGRectGetWidth(clipFrame), CGRectGetHeight([_menuView frame]))];
[_menuView scrollPoint:CGPointMake(0.0, [self convertBaseToGlobal:clipFrame.origin].y - menuViewOrigin.y)];
}
- (BOOL)hasMinimumNumberOfVisibleItems
{
var visibleRect = [_menuView visibleRect];
// Clearly if the entire view isn't visible the minimum won't be visible.
if (CGRectIsEmpty(visibleRect))
return NO;
var numberOfUnhiddenItems = [_menuView numberOfUnhiddenItems],
minimumNumberOfVisibleItems = MIN(numberOfUnhiddenItems, 3),
count = 0,
index = [_menuView itemIndexAtPoint:[_menuView convertPoint:[_menuClipView frame].origin fromView:nil]];
for (; index < numberOfUnhiddenItems && count < minimumNumberOfVisibleItems; ++index)
{
var itemRect = [_menuView rectForUnhiddenItemAtIndex:index],
visibleItemRect = CGRectIntersection(visibleRect, itemRect);
// As soon as we get to the first unhidden item that is no longer visible, stop.
if (CGRectIsEmpty(visibleItemRect))
break;
// If the item is *completely* visible, count it.
if (CGRectEqualToRect(visibleItemRect, itemRect))
++count;
}
return count >= minimumNumberOfVisibleItems;
}
- (BOOL)canScrollUp
{
return ![_moreAboveView isHidden];
}
- (BOOL)canScrollDown
{
return ![_moreBelowView isHidden];
}
- (BOOL)canScroll
{
return [self canScrollUp] || [self canScrollDown];
}
- (void)scrollUp
{
if (CGRectGetMinY(_unconstrainedFrame) >= CGRectGetMinY(_constraintRect))
return;
_unconstrainedFrame.origin.y += 10;
[self setFrame:_unconstrainedFrame];
}
- (void)scrollDown
{
if (CGRectGetMaxY(_unconstrainedFrame) <= CGRectGetHeight(_constraintRect))
return;
_unconstrainedFrame.origin.y -= 10;
[self setFrame:_unconstrainedFrame];
}
@end
@implementation _CPMenuWindow (CPMenuContainer)
- (CGRect)globalFrame
{
return [self frame];
}
- (BOOL)isMenuBar
{
return NO;
}
- (_CPManagerScrollingState)scrollingStateForPoint:(CGPoint)aGlobalLocation
{
var frame = [self frame];
if (![self canScroll])
return _CPMenuManagerScrollingStateNone;
// If we're at or above of the top scroll indicator...
if (aGlobalLocation.y < CGRectGetMinY(frame) + TOP_MARGIN + SCROLL_INDICATOR_HEIGHT)
return _CPMenuManagerScrollingStateUp;
// If we're at or below the bottom scroll indicator...
if (aGlobalLocation.y > CGRectGetMaxY(frame) - BOTTOM_MARGIN - SCROLL_INDICATOR_HEIGHT)
return _CPMenuManagerScrollingStateDown;
return _CPMenuManagerScrollingStateNone;
}
- (float)deltaYForItemAtIndex:(int)anIndex
{
return TOP_MARGIN + CGRectGetMinY([_menuView rectForItemAtIndex:anIndex]);
}
- (CGPoint)rectForItemAtIndex:(int)anIndex
{
return [_menuView convertRect:[_menuView rectForItemAtIndex:anIndex] toView:nil];
}
- (int)itemIndexAtPoint:(CGPoint)aPoint
{
// Don't return indexes of items that aren't visible.
if (!CGRectContainsPoint([_menuClipView bounds], [_menuClipView convertPoint:aPoint fromView:nil]))
return NO;
return [_menuView itemIndexAtPoint:[_menuView convertPoint:aPoint fromView:nil]];
}
@end
/*
@ignore
*/
@implementation _CPMenuView : CPView
{
CPArray _menuItemViews;
CPArray _visibleMenuItemInfos;
CPFont _font @accessors(property=font);
}
- (unsigned)numberOfUnhiddenItems
{
return _visibleMenuItemInfos.length;
}
- (CGRect)rectForUnhiddenItemAtIndex:(int)anIndex
{
return [self rectForItemAtIndex:_visibleMenuItemInfos[anIndex].index];
}
- (CGRect)rectForItemAtIndex:(int)anIndex
{
return [_menuItemViews[anIndex === CPNotFound ? 0 : anIndex] frame];
}
- (int)itemIndexAtPoint:(CGPoint)aPoint
{
var x = aPoint.x,
bounds = [self bounds];
if (x < CGRectGetMinX(bounds) || x > CGRectGetMaxX(bounds))
return CPNotFound;
var y = aPoint.y,
low = 0,
high = _visibleMenuItemInfos.length - 1;
while (low <= high)
{
var middle = FLOOR(low + (high - low) / 2),
info = _visibleMenuItemInfos[middle]
frame = [info.view frame];
if (y < CGRectGetMinY(frame))
high = middle - 1;
else if (y > CGRectGetMaxY(frame))
low = middle + 1;
else
return info.index;
}
return CPNotFound;
}
- (void)tile
{
[_menuItemViews makeObjectsPerformSelector:@selector(removeFromSuperview)];
_menuItemViews = [];
_visibleMenuItemInfos = [];
var menu = [self menu];
if (!menu)
return;
var items = [menu itemArray],
index = 0,
count = [items count],
maxWidth = 0,
y = 0,
showsStateColumn = [menu showsStateColumn];
for (; index < count; ++index)
{
var item = items[index],
view = [item _menuItemView];
_menuItemViews.push(view);
if ([item isHidden])
continue;
_visibleMenuItemInfos.push({ view:view, index:index });
[view setFont:_font];
[view setShowsStateColumn:showsStateColumn];
[view synchronizeWithMenuItem];
[view setFrameOrigin:CGPointMake(0.0, y)];
[self addSubview:view];
var size = [view minSize],
width = size.width;
if (maxWidth < width)
maxWidth = width;
y += size.height;
}
for (index = 0; index < count; ++index)
{
var view = _menuItemViews[index];
[view setFrameSize:CGSizeMake(maxWidth, CGRectGetHeight([view frame]))];
}
[self setAutoresizesSubviews:NO];
[self setFrameSize:CGSizeMake(maxWidth, y)];
[self setAutoresizesSubviews:YES];
}
- (void)setMenu:(CPMenu)aMenu
{
[super setMenu:aMenu];
[self tile];
}
@end
@@ -24,9 +24,10 @@
@import <Foundation/CPObject.j>
@import <Foundation/CPString.j>
@import <AppKit/CPImage.j>
@import <AppKit/CPMenu.j>
@import <AppKit/CPView.j>
@import "CPImage.j"
@import "CPMenu.j"
@import "CPView.j"
@import "_CPMenuItemView.j"
/*!
@ingroup appkit
@@ -108,7 +109,9 @@
_keyEquivalent = aKeyEquivalent || @"";
_keyEquivalentModifierMask = CPPlatformActionKeyMask;
_indentationLevel = 0;
_mnemonicLocation = CPNotFound;
}
@@ -448,20 +451,32 @@ CPOffState
*/
- (void)setSubmenu:(CPMenu)aMenu
{
var supermenu = [_submenu supermenu];
if (supermenu == self)
if (_submenu === aMenu)
return;
var supermenu = [_submenu supermenu];
if (supermenu)
return alert("bad");
[_submenu setSupermenu:_menu];
[CPException raise:CPInvalidArgumentException
reason: @"Can't add submenu \"" + [aMenu title] + "\" to item \"" + [self title] + "\", because it is already submenu of \"" + [[aMenu supermenu] title] + "\""];
_submenu = aMenu;
if (_submenu)
{
[_submenu setSupermenu:_menu];
[self setTarget:_menu];
[self setAction:@selector(submenuAction:)];
}
else
{
[self setTarget:nil];
[self setAction:NULL];
}
[_menuItemView setDirty];
[_menu itemChanged:self];
}
@@ -570,6 +585,43 @@ CPControlKeyMask
return _keyEquivalentModifierMask;
}
- (CPString)keyEquivalentStringRepresentation
{
if (![_keyEquivalent length])
return @"";
var string = _keyEquivalent.toUpperCase(),
needsShift = _keyEquivalentModifierMask & CPShiftKeyMask || string === _keyEquivalent;
if (CPBrowserIsOperatingSystem(CPMacOperatingSystem))
{
if (_keyEquivalentModifierMask & CPCommandKeyMask)
string = "⌘" + string;
if (needsShift)
string = "⇧" + string;
if (_keyEquivalentModifierMask & CPAlternateKeyMask)
string = "⌥" + string;
if (_keyEquivalentModifierMask & CPControlKeyMask)
string = "^" + string;
}
else
{
if (needsShift)
string = "Shift-" + string;
if (_keyEquivalentModifierMask & CPAlternateKeyMask)
string = "Alt-" + string;
if (_keyEquivalentModifierMask & CPControlKeyMask || _keyEquivalentModifierMask & CPCommandKeyMask)
string = "Ctrl-" + string;
}
return string;
}
// Managing Mnemonics
/*!
Sets the index of the mnemonic character in the title. The character
@@ -643,7 +695,7 @@ CPControlKeyMask
- (void)setIndentationLevel:(unsigned)aLevel
{
if (aLevel < 0)
[CPException raise:CPInvalidArgumentException reason:"setIndentationLevel: argument must be greater than 0."];
[CPException raise:CPInvalidArgumentException reason:"setIndentationLevel: argument must be greater than or equal to 0."];
_indentationLevel = MIN(15, aLevel);
}
@@ -742,6 +794,16 @@ CPControlKeyMask
return _menuItemView;
}
- (BOOL)_isSelectable
{
return ![self submenu] || [self action] !== @selector(submenuAction:) || [self target] !== [self menu];
}
- (BOOL)_isMenuBarButton
{
return ![self submenu] && [self menu] === [CPApp mainMenu];
}
@end
var CPMenuItemIsSeparatorKey = @"CPMenuItemIsSeparatorKey",
@@ -765,6 +827,8 @@ var CPMenuItemIsSeparatorKey = @"CPMenuItemIsSeparatorKey",
CPMenuItemKeyEquivalentKey = @"CPMenuItemKeyEquivalentKey",
CPMenuItemKeyEquivalentModifierMaskKey = @"CPMenuItemKeyEquivalentModifierMaskKey",
CPMenuItemIndentationLevelKey = @"CPMenuItemIndentationLevelKey",
CPMenuItemRepresentedObjectKey = @"CPMenuItemRepresentedObjectKey",
CPMenuItemViewKey = @"CPMenuItemViewKey";
@@ -804,8 +868,9 @@ var CPMenuItemIsSeparatorKey = @"CPMenuItemIsSeparatorKey",
// CPImage _offStateImage;
// CPImage _mixedStateImage;
_submenu = DEFAULT_VALUE(CPMenuItemSubmenuKey, nil);
// This order matters because setSubmenu: needs _menu to be around.
_menu = DEFAULT_VALUE(CPMenuItemMenuKey, nil);
[self setSubmenu:DEFAULT_VALUE(CPMenuItemSubmenuKey, nil)];
_keyEquivalent = [aCoder decodeObjectForKey:CPMenuItemKeyEquivalentKey] || @"";
_keyEquivalentModifierMask = [aCoder decodeObjectForKey:CPMenuItemKeyEquivalentModifierMaskKey] || 0;
@@ -813,7 +878,9 @@ var CPMenuItemIsSeparatorKey = @"CPMenuItemIsSeparatorKey",
// int _mnemonicLocation;
// BOOL _isAlternate;
// int _indentationLevel;
// Default is 0.
[self setIndentationLevel:[aCoder decodeIntForKey:CPMenuItemIndentationLevelKey] || 0];
// CPString _toolTip;
@@ -856,423 +923,11 @@ var CPMenuItemIsSeparatorKey = @"CPMenuItemIsSeparatorKey",
if (_keyEquivalentModifierMask)
[aCoder encodeObject:_keyEquivalentModifierMask forKey:CPMenuItemKeyEquivalentModifierMaskKey];
if (_indentationLevel > 0)
[aCoder encodeInt:_indentationLevel forKey:CPMenuItemIndentationLevelKey];
ENCODE_IFNOT(CPMenuItemRepresentedObjectKey, _representedObject, nil);
ENCODE_IFNOT(CPMenuItemViewKey, _view, nil);
}
@end
var LEFT_MARGIN = 3.0,
RIGHT_MARGIN = 16.0,
STATE_COLUMN_WIDTH = 14.0,
INDENTATION_WIDTH = 17.0,
VERTICAL_MARGIN = 4.0;
var _CPMenuItemSelectionColor = nil,
_CPMenuItemTextShadowColor = nil,
_CPMenuItemDefaultStateImages = [],
_CPMenuItemDefaultStateHighlightedImages = [];
/*
@ignore
*/
@implementation _CPMenuItemView : CPView
{
CPMenuItem _menuItem;
CPFont _font;
CPColor _textColor;
CPColor _textShadowColor;
CPColor _activateColor;
CPColor _activateShadowColor;
CGSize _minSize;
BOOL _isDirty;
BOOL _showsStateColumn;
BOOL _belongsToMenuBar;
CPImageView _stateView;
_CPImageAndTextView _imageAndTextView;
CPView _submenuView;
}
+ (void)initialize
{
if (self != [_CPMenuItemView class])
return;
_CPMenuItemSelectionColor = [CPColor colorWithCalibratedRed:95.0 / 255.0 green:131.0 / 255.0 blue:185.0 / 255.0 alpha:1.0];
_CPMenuItemTextShadowColor = [CPColor colorWithCalibratedRed:26.0 / 255.0 green: 73.0 / 255.0 blue:109.0 / 255.0 alpha:1.0]
var bundle = [CPBundle bundleForClass:self];
_CPMenuItemDefaultStateImages[CPOffState] = nil;
_CPMenuItemDefaultStateHighlightedImages[CPOffState] = nil;
_CPMenuItemDefaultStateImages[CPOnState] = [[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPMenuItem/CPMenuItemOnState.png"] size:CGSizeMake(14.0, 14.0)];
_CPMenuItemDefaultStateHighlightedImages[CPOnState] = [[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPMenuItem/CPMenuItemOnStateHighlighted.png"] size:CGSizeMake(14.0, 14.0)];
_CPMenuItemDefaultStateImages[CPMixedState] = nil;
_CPMenuItemDefaultStateHighlightedImages[CPMixedState] = nil;
}
+ (float)leftMargin
{
return LEFT_MARGIN + STATE_COLUMN_WIDTH;
}
- (id)initWithFrame:(CGRect)aFrame forMenuItem:(CPMenuItem)aMenuItem
{
self = [super initWithFrame:aFrame];
if (self)
{
_menuItem = aMenuItem;
_showsStateColumn = YES;
_isDirty = YES;
[self setAutoresizingMask:CPViewWidthSizable];
[self synchronizeWithMenuItem];
}
return self;
}
- (CGSize)minSize
{
return _minSize;
}
- (void)setDirty
{
_isDirty = YES;
}
- (void)synchronizeWithMenuItem
{
if (!_isDirty)
return;
_isDirty = NO;
var view = [_menuItem view];
if ([_menuItem isSeparatorItem])
{
var line = [[CPView alloc] initWithFrame:CGRectMake(0.0, 5.0, 10.0, 1.0)];
view = [[CPView alloc] initWithFrame:CGRectMake(0.0, 0.0, 0.0, 10.0)];
[view setAutoresizingMask:CPViewWidthSizable];
[line setAutoresizingMask:CPViewWidthSizable];
[line setBackgroundColor:[CPColor lightGrayColor]];
[view addSubview:line];
}
if (view)
{
[_imageAndTextView removeFromSuperview];
_imageAndTextView = nil;
[_stateView removeFromSuperview];
_stateView = nil;
[_submenuView removeFromSuperview];
_submenuView = nil;
_minSize = [view frame].size;
[self setFrameSize:_minSize];
[self addSubview:view];
return;
}
// State Column
var x = _belongsToMenuBar ? 0.0 : (LEFT_MARGIN + [_menuItem indentationLevel] * INDENTATION_WIDTH);
if (_showsStateColumn)
{
if (!_stateView)
{
_stateView = [[CPImageView alloc] initWithFrame:CGRectMake(x, (CGRectGetHeight([self frame]) - STATE_COLUMN_WIDTH) / 2.0, STATE_COLUMN_WIDTH, STATE_COLUMN_WIDTH)];
[_stateView setAutoresizingMask:CPViewMinYMargin | CPViewMaxYMargin];
[self addSubview:_stateView];
}
var state = [_menuItem state];
switch (state)
{
case CPOffState:
case CPOnState:
case CPMixedState: [_stateView setImage:_CPMenuItemDefaultStateImages[state]];
break;
default: [_stateView setImage:nil];
}
x += STATE_COLUMN_WIDTH;
}
else
{
[_stateView removeFromSuperview];
_stateView = nil;
}
// Image and Title
if (!_imageAndTextView)
{
_imageAndTextView = [[_CPImageAndTextView alloc] initWithFrame:CGRectMake(0.0, 0.0, 0.0, 0.0)];
[_imageAndTextView setImagePosition:CPImageLeft];
[_imageAndTextView setTextShadowOffset:CGSizeMake(0.0, 1.0)];
[self addSubview:_imageAndTextView];
}
var font = [_menuItem font];
if (!font)
font = _font;
[_imageAndTextView setFont:font];
[_imageAndTextView setVerticalAlignment:CPCenterVerticalTextAlignment];
[_imageAndTextView setImage:[_menuItem image]];
[_imageAndTextView setText:[_menuItem title]];
[_imageAndTextView setTextColor:[self textColor]];
[_imageAndTextView setTextShadowColor:[self textShadowColor]];
[_imageAndTextView setTextShadowOffset:CGSizeMake(0, 1)];
[_imageAndTextView setFrameOrigin:CGPointMake(x, VERTICAL_MARGIN)];
[_imageAndTextView sizeToFit];
var frame = [_imageAndTextView frame];
// frame.size.height += 1.0;
// [_imageAndTextView setFrame:frame];
frame.size.height += 2 * VERTICAL_MARGIN;
x += CGRectGetWidth(frame);
// Submenu Arrow
if ([_menuItem hasSubmenu])
{
x += 3.0;
if (!_submenuView)
{
_submenuView = [[_CPMenuItemArrowView alloc] initWithFrame:CGRectMake(0.0, 0.0, 10.0, 10.0)];
[self addSubview:_submenuView];
}
[_submenuView setHidden:NO];
[_submenuView setColor:_belongsToMenuBar ? [self textColor] : nil];
[_submenuView setFrameOrigin:CGPointMake(x, (CGRectGetHeight(frame) - 10.0) / 2.0)];
x += 10.0;
}
else
[_submenuView setHidden:YES];
_minSize = CGSizeMake(x + (_belongsToMenuBar ? 0.0 : RIGHT_MARGIN) + 3.0, CGRectGetHeight(frame));
[self setFrameSize:_minSize];
}
- (CGFloat)overlapOffsetWidth
{
return LEFT_MARGIN + ([[_menuItem menu] showsStateColumn] ? STATE_COLUMN_WIDTH : 0.0);
}
- (void)setShowsStateColumn:(BOOL)shouldShowStateColumn
{
_showsStateColumn = shouldShowStateColumn;
}
- (void)setBelongsToMenuBar:(BOOL)shouldBelongToMenuBar
{
_belongsToMenuBar = shouldBelongToMenuBar;
}
- (void)highlight:(BOOL)shouldHighlight
{
// ASSERT(![_menuItem view]);
if (_belongsToMenuBar)
[_imageAndTextView setImage:shouldHighlight ? [_menuItem alternateImage] : [_menuItem image]];
else if ([_menuItem isEnabled])
{
if (shouldHighlight)
{
[self setBackgroundColor:_CPMenuItemSelectionColor];
[_imageAndTextView setTextColor:[CPColor whiteColor]];
[_imageAndTextView setTextShadowColor:_CPMenuItemTextShadowColor];
}
else
{
[self setBackgroundColor:nil];
[_imageAndTextView setTextColor:[self textColor]];
[_imageAndTextView setTextShadowColor:[self textShadowColor]];
}
var state = [_menuItem state];
switch (state)
{
case CPOffState:
case CPOnState:
case CPMixedState: [_stateView setImage:shouldHighlight ? _CPMenuItemDefaultStateHighlightedImages[state] : _CPMenuItemDefaultStateImages[state]];
break;
default: [_stateView setImage:nil];
}
}
}
- (void)activate:(BOOL)shouldActivate
{
[_imageAndTextView setImage:[_menuItem image]];
if (shouldActivate)
{
[_imageAndTextView setTextColor:[self activateColor] || [CPColor whiteColor]];
[_imageAndTextView setTextShadowColor:[self activateShadowColor] || [CPColor blackColor]];
[_submenuView setColor:[self activateColor] || [CPColor whiteColor]];
}
else
{
[_imageAndTextView setTextColor:[self textColor]];
[_imageAndTextView setTextShadowColor:[self textShadowColor]];
[_submenuView setColor:[self textColor]];
}
}
- (BOOL)eventOnSubmenu:(CPEvent)anEvent
{
if (![_menuItem hasSubmenu])
return NO;
return CGRectContainsPoint([_submenuView frame], [self convertPoint:[anEvent locationInWindow] fromView:nil]);
}
- (BOOL)isHidden
{
return [_menuItem isHidden];
}
- (CPMenuItem)menuItem
{
return _menuItem;
}
- (void)setFont:(CPFont)aFont
{
if (_font == aFont)
return;
_font = aFont;
[self setDirty];
}
- (void)setTextColor:(CPColor)aColor
{
if (_textColor == aColor)
return;
_textColor = aColor;
[_imageAndTextView setTextColor:[self textColor]];
[_submenuView setColor:[self textColor]];
}
- (CPColor)textColor
{
return [_menuItem isEnabled] ? (_textColor ? _textColor : [CPColor colorWithCalibratedRed:70.0 / 255.0 green:69.0 / 255.0 blue:69.0 / 255.0 alpha:1.0]) : [CPColor lightGrayColor];
}
- (void)setTextShadowColor:(CPColor)aColor
{
if (_textShadowColor == aColor)
return;
_textShadowColor = aColor;
[_imageAndTextView setTextShadowColor:[self textShadowColor]];
//[_submenuView setColor:[self textColor]];
}
- (CPColor)textShadowColor
{
return [_menuItem isEnabled] ? (_textShadowColor ? _textShadowColor : [CPColor colorWithWhite:1.0 alpha:0.8]) : [CPColor colorWithWhite:0.8 alpha:0.8];
}
- (void)setActivateColor:(CPColor)aColor
{
_activateColor = aColor;
}
- (CPColor)activateColor
{
return _activateColor;
}
- (void)setActivateShadowColor:(CPColor)aColor
{
_activateShadowColor = aColor;
}
- (CPColor)activateShadowColor
{
return _activateShadowColor;
}
@end
@implementation _CPMenuItemArrowView : CPView
{
CPColor _color;
}
- (void)setColor:(CPColor)aColor
{
if (_color == aColor)
return;
_color = aColor;
[self setNeedsDisplay:YES];
}
- (void)drawRect:(CGRect)aRect
{
var context = [[CPGraphicsContext currentContext] graphicsPort];
CGContextBeginPath(context);
CGContextMoveToPoint(context, 1.0, 4.0);
CGContextAddLineToPoint(context, 9.0, 4.0);
CGContextAddLineToPoint(context, 5.0, 8.0);
CGContextAddLineToPoint(context, 1.0, 4.0);
CGContextClosePath(context);
CGContextSetFillColor(context, _color);
CGContextFillPath(context);
}
@end
+235
View File
@@ -0,0 +1,235 @@
var HORIZONTAL_MARGIN = 8.0,
SUBMENU_INDICATOR_MARGIN = 3.0,
VERTICAL_MARGIN = 4.0;
var SelectionColor = nil,
SUBMENU_INDICATOR_COLOR = nil,
_CPMenuItemSelectionColor = nil,
_CPMenuItemTextShadowColor = nil,
_CPMenuItemDefaultStateImages = [],
_CPMenuItemDefaultStateHighlightedImages = [];
@implementation _CPMenuItemMenuBarView : CPView
{
CPMenuItem _menuItem @accessors(property=menuItem);
CPFont _font;
CPColor _textColor;
CPColor _textShadowColor;
BOOL _isDirty;
_CPImageAndTextView _imageAndTextView;
CPView _submenuIndicatorView;
}
+ (void)initialize
{
if (self !== [_CPMenuItemMenuBarView class])
return;
var bundle = [CPBundle bundleForClass:self];
SelectionColor = [CPColor colorWithPatternImage:[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"_CPMenuBarWindow/_CPMenuBarWindowBackgroundSelected.png"] size:CGSizeMake(1.0, 28.0)]];
SUBMENU_INDICATOR_COLOR = [CPColor grayColor];
_CPMenuItemSelectionColor = [CPColor colorWithCalibratedRed:95.0 / 255.0 green:131.0 / 255.0 blue:185.0 / 255.0 alpha:1.0];
_CPMenuItemTextShadowColor = [CPColor colorWithCalibratedRed:26.0 / 255.0 green: 73.0 / 255.0 blue:109.0 / 255.0 alpha:1.0];
_CPMenuItemDefaultStateImages[CPOffState] = nil;
_CPMenuItemDefaultStateHighlightedImages[CPOffState] = nil;
_CPMenuItemDefaultStateImages[CPOnState] = [[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPMenuItem/CPMenuItemOnState.png"] size:CGSizeMake(14.0, 14.0)];
_CPMenuItemDefaultStateHighlightedImages[CPOnState] = [[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPMenuItem/CPMenuItemOnStateHighlighted.png"] size:CGSizeMake(14.0, 14.0)];
_CPMenuItemDefaultStateImages[CPMixedState] = nil;
_CPMenuItemDefaultStateHighlightedImages[CPMixedState] = nil;
}
+ (id)view
{
return [[self alloc] init];
}
- (id)initWithFrame:(CGRect)aFrame
{
self = [super initWithFrame:aFrame];
if (self)
{
_imageAndTextView = [[_CPImageAndTextView alloc] initWithFrame:CGRectMake(HORIZONTAL_MARGIN, 0.0, 0.0, 0.0)];
[_imageAndTextView setImagePosition:CPImageLeft];
[_imageAndTextView setTextShadowOffset:CGSizeMake(0.0, 1.0)];
[_imageAndTextView setAutoresizingMask:CPViewMinYMargin | CPViewMaxYMargin];
[self addSubview:_imageAndTextView];
_submenuIndicatorView = [[_CPMenuItemMenuBarSubmenuIndicatorView alloc] initWithFrame:CGRectMake(0.0, 0.0, 9.0, 6.0)];
[_submenuIndicatorView setAutoresizingMask:CPViewMinYMargin | CPViewMaxYMargin];
[self addSubview:_submenuIndicatorView];
[self setAutoresizingMask:CPViewWidthSizable | CPViewHeightSizable];
}
return self;
}
- (CPColor)textColor
{
if (![_menuItem isEnabled])
return [CPColor lightGrayColor];
return _textColor || [CPColor colorWithCalibratedRed:70.0 / 255.0 green:69.0 / 255.0 blue:69.0 / 255.0 alpha:1.0];
}
- (CPColor)textShadowColor
{
if (![_menuItem isEnabled])
return [CPColor colorWithWhite:0.8 alpha:0.8];
return _textShadowColor || [CPColor colorWithWhite:1.0 alpha:0.8];
}
- (void)update
{
var x = HORIZONTAL_MARGIN,
height = 0.0;
[_imageAndTextView setFont:[_menuItem font] || [_CPMenuBarWindow font]];
[_imageAndTextView setVerticalAlignment:CPCenterVerticalTextAlignment];
[_imageAndTextView setImage:[_menuItem image]];
[_imageAndTextView setText:[_menuItem title]];
[_imageAndTextView setTextColor:[self textColor]];
[_imageAndTextView setTextShadowColor:[self textShadowColor]];
[_imageAndTextView setTextShadowOffset:CGSizeMake(0.0, 1.0)];
[_imageAndTextView sizeToFit];
var imageAndTextViewFrame = [_imageAndTextView frame];
imageAndTextViewFrame.origin.x = x;
x += CGRectGetWidth(imageAndTextViewFrame);
height = MAX(height, CGRectGetHeight(imageAndTextViewFrame));
var hasSubmenuIndicator = [_menuItem hasSubmenu] && [_menuItem action];
if (hasSubmenuIndicator)
{
[_submenuIndicatorView setHidden:NO];
[_submenuIndicatorView setColor:[self textColor]];
[_submenuIndicatorView setShadowColor:[self textShadowColor]];
var submenuViewFrame = [_submenuIndicatorView frame];
submenuViewFrame.origin.x = x + SUBMENU_INDICATOR_MARGIN;
x = CGRectGetMaxX(submenuViewFrame);
height = MAX(height, CGRectGetHeight(submenuViewFrame));
}
else
[_submenuIndicatorView setHidden:YES];
height += 2.0 * VERTICAL_MARGIN;
imageAndTextViewFrame.origin.y = FLOOR((height - CGRectGetHeight(imageAndTextViewFrame)) / 2.0);
[_imageAndTextView setFrame:imageAndTextViewFrame];
if (hasSubmenuIndicator)
{
submenuViewFrame.origin.y = FLOOR((height - CGRectGetHeight(submenuViewFrame)) / 2.0) + 1.0;
[_submenuIndicatorView setFrame:submenuViewFrame];
}
_minSize = CGSizeMake(x + HORIZONTAL_MARGIN, height);
[self setAutoresizesSubviews:NO];
[self setFrameSize:_minSize];
[self setAutoresizesSubviews:YES];
}
- (void)highlight:(BOOL)shouldHighlight
{
// FIXME: This should probably be even throw.
if (![_menuItem isEnabled])
shouldHighlight = NO;
if (shouldHighlight)
{
if (![_menuItem _isMenuBarButton])
[self setBackgroundColor:SelectionColor];
[_imageAndTextView setImage:[_menuItem alternateImage] || [_menuItem image]];
[_imageAndTextView setTextColor:[CPColor whiteColor]];
[_imageAndTextView setTextShadowColor:_CPMenuItemTextShadowColor];
[_submenuIndicatorView setColor:[CPColor whiteColor]];
[_submenuIndicatorView setShadowColor:[CPColor colorWithWhite:0.1 alpha:0.7]];
}
else
{
[self setBackgroundColor:nil];
[_imageAndTextView setImage:[_menuItem image]];
[_imageAndTextView setTextColor:[self textColor]];
[_imageAndTextView setTextShadowColor:[self textShadowColor]];
[_submenuIndicatorView setColor:[self textColor]];
[_submenuIndicatorView setShadowColor:[self textShadowColor]];
}
}
@end
@implementation _CPMenuItemMenuBarSubmenuIndicatorView : CPView
{
CPColor _color;
CPColor _shadowColor;
}
- (void)setColor:(CPColor)aColor
{
if (_color === aColor)
return;
_color = aColor;
[self setNeedsDisplay:YES];
}
- (void)setShadowColor:(CPColor)aColor
{
if (_shadowColor === aColor)
return;
_shadowColor = aColor;
[self setNeedsDisplay:YES];
}
- (void)drawRect:(CGRect)aRect
{
var context = [[CPGraphicsContext currentContext] graphicsPort],
bounds = [self bounds];
bounds.size.height -= 1.0;
bounds.size.width -= 2.0;
bounds.origin.x += 1.0;
CGContextBeginPath(context);
CGContextMoveToPoint(context, CGRectGetMinX(bounds), CGRectGetMinY(bounds));
CGContextAddLineToPoint(context, CGRectGetMaxX(bounds), CGRectGetMinY(bounds));
CGContextAddLineToPoint(context, CGRectGetMidX(bounds), CGRectGetMaxY(bounds));
CGContextClosePath(context);
CGContextSetShadowWithColor(context, CGSizeMake(0.0, 1.0), 1.1, _shadowColor || [CPColor whiteColor]);
CGContextSetFillColor(context, _color || [CPColor blackColor]);
CGContextFillPath(context);
}
@end
@@ -0,0 +1,38 @@
@import <AppKit/CPView.j>
@implementation _CPMenuItemSeparatorView : CPView
{
}
+ (id)view
{
return [[self alloc] initWithFrame:CGRectMake(0.0, 0.0, 0.0, 10.0)];
}
- (id)initWithFrame:(CGRect)aFrame
{
self = [super initWithFrame:aFrame];
if (self)
[self setAutoresizingMask:CPViewWidthSizable];
return self;
}
- (void)drawRect:(CGRect)aRect
{
var context = [[CPGraphicsContext currentContext] graphicsPort],
bounds = [self bounds];
CGContextBeginPath(context);
CGContextMoveToPoint(context, CGRectGetMinX(bounds), FLOOR(CGRectGetMidY(bounds)) - 0.5);
CGContextAddLineToPoint(context, CGRectGetMaxX(bounds), FLOOR(CGRectGetMidY(bounds)) - 0.5);
CGContextSetStrokeColor(context, [CPColor lightGrayColor]);
CGContextStrokePath(context);
}
@end
+300
View File
@@ -0,0 +1,300 @@
var LEFT_MARGIN = 3.0,
RIGHT_MARGIN = 14.0 + 3.0,
STATE_COLUMN_WIDTH = 14.0,
INDENTATION_WIDTH = 17.0,
VERTICAL_MARGIN = 4.0,
RIGHT_COLUMNS_MARGIN = 30.0,
KEY_EQUIVALENT_MARGIN = 10.0;
var SUBMENU_INDICATOR_COLOR = nil,
_CPMenuItemSelectionColor = nil,
_CPMenuItemTextShadowColor = nil,
_CPMenuItemDefaultStateImages = [],
_CPMenuItemDefaultStateHighlightedImages = [];
@implementation _CPMenuItemStandardView : CPView
{
CPMenuItem _menuItem @accessors(property=menuItem);
CPFont _font;
CPColor _textColor;
CPColor _textShadowColor;
CGSize _minSize @accessors(readonly, property=minSize);
BOOL _isDirty;
CPImageView _stateView;
_CPImageAndTextView _imageAndTextView;
_CPImageAndTextView _keyEquivalentView;
CPView _submenuIndicatorView;
}
+ (void)initialize
{
if (self !== [_CPMenuItemStandardView class])
return;
SUBMENU_INDICATOR_COLOR = [CPColor grayColor];
_CPMenuItemSelectionColor = [CPColor colorWithCalibratedRed:95.0 / 255.0 green:131.0 / 255.0 blue:185.0 / 255.0 alpha:1.0];
_CPMenuItemTextShadowColor = [CPColor colorWithCalibratedRed:26.0 / 255.0 green: 73.0 / 255.0 blue:109.0 / 255.0 alpha:1.0]
var bundle = [CPBundle bundleForClass:self];
_CPMenuItemDefaultStateImages[CPOffState] = nil;
_CPMenuItemDefaultStateHighlightedImages[CPOffState] = nil;
_CPMenuItemDefaultStateImages[CPOnState] = [[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPMenuItem/CPMenuItemOnState.png"] size:CGSizeMake(14.0, 14.0)];
_CPMenuItemDefaultStateHighlightedImages[CPOnState] = [[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPMenuItem/CPMenuItemOnStateHighlighted.png"] size:CGSizeMake(14.0, 14.0)];
_CPMenuItemDefaultStateImages[CPMixedState] = nil;
_CPMenuItemDefaultStateHighlightedImages[CPMixedState] = nil;
}
+ (id)view
{
return [[self alloc] init];
}
+ (float)_standardLeftMargin
{
return LEFT_MARGIN + STATE_COLUMN_WIDTH;
}
- (id)initWithFrame:(CGRect)aFrame
{
self = [super initWithFrame:aFrame];
if (self)
{
_stateView = [[CPImageView alloc] initWithFrame:CGRectMake(0.0, 0.0, 0.0, 0.0)];
[_stateView setImageScaling:CPScaleNone];
[self addSubview:_stateView];
_imageAndTextView = [[_CPImageAndTextView alloc] initWithFrame:CGRectMake(0.0, 0.0, 0.0, 0.0)];
[_imageAndTextView setImagePosition:CPImageLeft];
[_imageAndTextView setTextShadowOffset:CGSizeMake(0.0, 1.0)];
[self addSubview:_imageAndTextView];
_keyEquivalentView = [[_CPImageAndTextView alloc] initWithFrame:CGRectMake(0.0, 0.0, 0.0, 0.0)];
[_keyEquivalentView setImagePosition:CPNoImage];
[_keyEquivalentView setTextShadowOffset:CGSizeMake(0.0, 1.0)];
[_keyEquivalentView setAutoresizingMask:CPViewMinXMargin];
[self addSubview:_keyEquivalentView];
_submenuIndicatorView = [[_CPMenuItemSubmenuIndicatorView alloc] initWithFrame:CGRectMake(0.0, 0.0, 8.0, 10.0)];
[_submenuIndicatorView setColor:SUBMENU_INDICATOR_COLOR];
[_submenuIndicatorView setAutoresizingMask:CPViewMinXMargin];
[self addSubview:_submenuIndicatorView];
[self setAutoresizingMask:CPViewWidthSizable];
}
return self;
}
- (CPColor)textColor
{
if (![_menuItem isEnabled])
return [CPColor lightGrayColor];
return _textColor || [CPColor colorWithCalibratedRed:70.0 / 255.0 green:69.0 / 255.0 blue:69.0 / 255.0 alpha:1.0];
}
- (CPColor)textShadowColor
{
if (![_menuItem isEnabled])
return nil;
return _textShadowColor || [CPColor colorWithWhite:1.0 alpha:0.8];
}
- (void)setFont:(CPFont)aFont
{
_font = aFont;
}
- (void)update
{
var x = LEFT_MARGIN + [_menuItem indentationLevel] * INDENTATION_WIDTH,
height = 0.0,
hasStateColumn = [[_menuItem menu] showsStateColumn];
if (hasStateColumn)
{
[_stateView setHidden:NO];
[_stateView setImage:_CPMenuItemDefaultStateImages[[_menuItem state]] || nil];
x += STATE_COLUMN_WIDTH;
}
else
[_stateView setHidden:YES];
[_imageAndTextView setFont:[_menuItem font] || _font];
[_imageAndTextView setVerticalAlignment:CPCenterVerticalTextAlignment];
[_imageAndTextView setImage:[_menuItem image]];
[_imageAndTextView setText:[_menuItem title]];
[_imageAndTextView setTextColor:[self textColor]];
[_imageAndTextView setTextShadowColor:[self textShadowColor]];
[_imageAndTextView setTextShadowOffset:CGSizeMake(0.0, 1.0)];
[_imageAndTextView sizeToFit];
var imageAndTextViewFrame = [_imageAndTextView frame];
imageAndTextViewFrame.origin.x = x;
x += CGRectGetWidth(imageAndTextViewFrame);
height = MAX(height, CGRectGetHeight(imageAndTextViewFrame));
var hasKeyEquivalent = !![_menuItem keyEquivalent],
hasSubmenu = [_menuItem hasSubmenu];
if (hasKeyEquivalent || hasSubmenu)
x += RIGHT_COLUMNS_MARGIN;
if (hasKeyEquivalent)
{
[_keyEquivalentView setFont:[_menuItem font] || _font];
[_keyEquivalentView setVerticalAlignment:CPCenterVerticalTextAlignment];
[_keyEquivalentView setImage:[_menuItem image]];
[_keyEquivalentView setText:[_menuItem keyEquivalentStringRepresentation]];
[_keyEquivalentView setTextColor:[self textColor]];
[_keyEquivalentView setTextShadowColor:[self textShadowColor]];
[_keyEquivalentView setTextShadowOffset:CGSizeMake(0, 1)];
[_keyEquivalentView setFrameOrigin:CGPointMake(x, VERTICAL_MARGIN)];
[_keyEquivalentView sizeToFit];
var keyEquivalentViewFrame = [_keyEquivalentView frame];
keyEquivalentViewFrame.origin.x = x;
x += CGRectGetWidth(keyEquivalentViewFrame);
height = MAX(height, CGRectGetHeight(keyEquivalentViewFrame));
if (hasSubmenu)
x += RIGHT_COLUMNS_MARGIN;
}
else
[_keyEquivalentView setHidden:YES];
if (hasSubmenu)
{
[_submenuIndicatorView setHidden:NO];
var submenuViewFrame = [_submenuIndicatorView frame];
submenuViewFrame.origin.x = x;
x += CGRectGetWidth(submenuViewFrame);
height = MAX(height, CGRectGetHeight(submenuViewFrame));
}
else
[_submenuIndicatorView setHidden:YES];
height += 2.0 * VERTICAL_MARGIN;
imageAndTextViewFrame.origin.y = FLOOR((height - CGRectGetHeight(imageAndTextViewFrame)) / 2.0);
[_imageAndTextView setFrame:imageAndTextViewFrame];
if (hasStateColumn)
[_stateView setFrameSize:CGSizeMake(STATE_COLUMN_WIDTH, height)];
if (hasKeyEquivalent)
{
keyEquivalentViewFrame.origin.y = FLOOR((height - CGRectGetHeight(keyEquivalentViewFrame)) / 2.0);
[_keyEquivalentView setFrame:keyEquivalentViewFrame];
}
if (hasSubmenu)
{
submenuViewFrame.origin.y = FLOOR((height - CGRectGetHeight(submenuViewFrame)) / 2.0);
[_submenuIndicatorView setFrame:submenuViewFrame];
}
_minSize = CGSizeMake(x + RIGHT_MARGIN, height);
[self setAutoresizesSubviews:NO];
[self setFrameSize:_minSize];
[self setAutoresizesSubviews:YES];
}
- (void)highlight:(BOOL)shouldHighlight
{
// FIXME: This should probably be even throw.
if (![_menuItem isEnabled])
return;
if (shouldHighlight)
{
[self setBackgroundColor:_CPMenuItemSelectionColor];
[_imageAndTextView setImage:[_menuItem alternateImage] || [_menuItem image]];
[_imageAndTextView setTextColor:[CPColor whiteColor]];
[_keyEquivalentView setTextColor:[CPColor whiteColor]];
[_submenuIndicatorView setColor:[CPColor whiteColor]];
[_imageAndTextView setTextShadowColor:_CPMenuItemTextShadowColor];
[_keyEquivalentView setTextShadowColor:_CPMenuItemTextShadowColor];
}
else
{
[self setBackgroundColor:nil];
[_imageAndTextView setImage:[_menuItem image]];
[_imageAndTextView setTextColor:[self textColor]];
[_keyEquivalentView setTextColor:[self textColor]];
[_submenuIndicatorView setColor:SUBMENU_INDICATOR_COLOR];
[_imageAndTextView setTextShadowColor:[self textShadowColor]];
[_keyEquivalentView setTextShadowColor:[self textShadowColor]];
}
if (shouldHighlight)
[_stateView setImage:_CPMenuItemDefaultStateHighlightedImages[[_menuItem state]] || nil];
else
[_stateView setImage:_CPMenuItemDefaultStateImages[[_menuItem state]] || nil];
}
@end
@implementation _CPMenuItemSubmenuIndicatorView : CPView
{
CPColor _color;
}
- (void)setColor:(CPColor)aColor
{
if (_color === aColor)
return;
_color = aColor;
[self setNeedsDisplay:YES];
}
- (void)drawRect:(CGRect)aRect
{
var context = [[CPGraphicsContext currentContext] graphicsPort],
bounds = [self bounds];
CGContextBeginPath(context);
CGContextMoveToPoint(context, CGRectGetMinX(bounds), CGRectGetMinY(bounds));
CGContextAddLineToPoint(context, CGRectGetMaxX(bounds), CGRectGetMidY(bounds));
CGContextAddLineToPoint(context, CGRectGetMinX(bounds), CGRectGetMaxY(bounds));
CGContextClosePath(context);
CGContextSetFillColor(context, _color);
CGContextFillPath(context);
}
@end
+255
View File
@@ -0,0 +1,255 @@
@import "_CPMenuItemSeparatorView.j"
@import "_CPMenuItemStandardView.j"
@import "_CPMenuItemMenuBarView.j"
var LEFT_MARGIN = 3.0,
RIGHT_MARGIN = 16.0,
STATE_COLUMN_WIDTH = 14.0,
INDENTATION_WIDTH = 17.0,
VERTICAL_MARGIN = 4.0;
var _CPMenuItemSelectionColor = nil,
_CPMenuItemTextShadowColor = nil,
_CPMenuItemDefaultStateImages = [],
_CPMenuItemDefaultStateHighlightedImages = [];
/*
@ignore
*/
@implementation _CPMenuItemView : CPView
{
CPMenuItem _menuItem;
CPView _view;
CPFont _font;
CPColor _textColor;
CPColor _textShadowColor;
CGSize _minSize;
BOOL _isDirty;
BOOL _showsStateColumn;
CPImageView _stateView;
_CPImageAndTextView _imageAndTextView;
CPView _submenuView;
}
+ (void)initialize
{
if (self != [_CPMenuItemView class])
return;
_CPMenuItemSelectionColor = [CPColor colorWithCalibratedRed:95.0 / 255.0 green:131.0 / 255.0 blue:185.0 / 255.0 alpha:1.0];
_CPMenuItemTextShadowColor = [CPColor colorWithCalibratedRed:26.0 / 255.0 green: 73.0 / 255.0 blue:109.0 / 255.0 alpha:1.0]
var bundle = [CPBundle bundleForClass:self];
_CPMenuItemDefaultStateImages[CPOffState] = nil;
_CPMenuItemDefaultStateHighlightedImages[CPOffState] = nil;
_CPMenuItemDefaultStateImages[CPOnState] = [[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPMenuItem/CPMenuItemOnState.png"] size:CGSizeMake(14.0, 14.0)];
_CPMenuItemDefaultStateHighlightedImages[CPOnState] = [[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPMenuItem/CPMenuItemOnStateHighlighted.png"] size:CGSizeMake(14.0, 14.0)];
_CPMenuItemDefaultStateImages[CPMixedState] = nil;
_CPMenuItemDefaultStateHighlightedImages[CPMixedState] = nil;
}
+ (float)leftMargin
{
return LEFT_MARGIN + STATE_COLUMN_WIDTH;
}
- (id)initWithFrame:(CGRect)aFrame forMenuItem:(CPMenuItem)aMenuItem
{
self = [super initWithFrame:aFrame];
if (self)
{
_menuItem = aMenuItem;
_showsStateColumn = YES;
_isDirty = YES;
[self setAutoresizingMask:CPViewWidthSizable];
[self synchronizeWithMenuItem];
}
return self;
}
- (CGSize)minSize
{
return _minSize;
}
- (void)setDirty
{
_isDirty = YES;
}
- (void)synchronizeWithMenuItem
{
var menuItemView = [_menuItem view];
if ([_menuItem isSeparatorItem])
{
if (![_view isKindOfClass:[_CPMenuItemSeparatorView class]])
{
[_view removeFromSuperview];
_view = [_CPMenuItemSeparatorView view];
}
}
else if (menuItemView)
{
if (_view !== menuItemView)
{
[_view removeFromSuperview];
_view = menuItemView;
}
}
else if ([_menuItem menu] == [CPApp mainMenu])
{
if (![_view isKindOfClass:[_CPMenuItemMenuBarView class]])
{
[_view removeFromSuperview];
_view = [_CPMenuItemMenuBarView view];
}
[_view setMenuItem:_menuItem];
}
else
{
if (![_view isKindOfClass:[_CPMenuItemStandardView class]])
{
[_view removeFromSuperview];
_view = [_CPMenuItemStandardView view];
}
[_view setMenuItem:_menuItem];
}
if ([_view superview] !== self)
[self addSubview:_view];
if ([_view respondsToSelector:@selector(update)])
[_view update];
_minSize = [_view frame].size;
[self setAutoresizesSubviews:NO];
[self setFrameSize:_minSize];
[self setAutoresizesSubviews:YES];
}
- (void)setShowsStateColumn:(BOOL)shouldShowStateColumn
{
_showsStateColumn = shouldShowStateColumn;
}
- (void)highlight:(BOOL)shouldHighlight
{
if ([_view respondsToSelector:@selector(highlight:)])
[_view highlight:shouldHighlight];
}
- (BOOL)eventOnSubmenu:(CPEvent)anEvent
{
if (![_menuItem hasSubmenu])
return NO;
return CGRectContainsPoint([_submenuView frame], [self convertPoint:[anEvent locationInWindow] fromView:nil]);
}
- (BOOL)isHidden
{
return [_menuItem isHidden];
}
- (CPMenuItem)menuItem
{
return _menuItem;
}
- (void)setFont:(CPFont)aFont
{
if (_font === aFont)
return;
_font = aFont;
if ([_view respondsToSelector:@selector(setFont:)])
[_view setFont:aFont];
[self setDirty];
}
- (void)setTextColor:(CPColor)aColor
{
if (_textColor == aColor)
return;
_textColor = aColor;
[_imageAndTextView setTextColor:[self textColor]];
[_submenuView setColor:[self textColor]];
}
- (CPColor)textColor
{
return nil;
}
- (void)setTextShadowColor:(CPColor)aColor
{
if (_textShadowColor == aColor)
return;
_textShadowColor = aColor;
[_imageAndTextView setTextShadowColor:[self textShadowColor]];
//[_submenuView setColor:[self textColor]];
}
- (CPColor)textShadowColor
{
return [_menuItem isEnabled] ? (_textShadowColor ? _textShadowColor : [CPColor colorWithWhite:1.0 alpha:0.8]) : [CPColor colorWithWhite:0.8 alpha:0.8];
}
@end
@implementation _CPMenuItemArrowView : CPView
{
CPColor _color;
}
- (void)setColor:(CPColor)aColor
{
if (_color == aColor)
return;
_color = aColor;
[self setNeedsDisplay:YES];
}
- (void)drawRect:(CGRect)aRect
{
var context = [[CPGraphicsContext currentContext] graphicsPort];
CGContextBeginPath(context);
CGContextMoveToPoint(context, 1.0, 4.0);
CGContextAddLineToPoint(context, 9.0, 4.0);
CGContextAddLineToPoint(context, 5.0, 8.0);
CGContextAddLineToPoint(context, 1.0, 4.0);
CGContextClosePath(context);
CGContextSetFillColor(context, _color);
CGContextFillPath(context);
}
@end
+423 -179
View File
@@ -50,6 +50,15 @@ var CPOutlineViewDataSource_outlineView_setObjectValue_forTableColumn_byItem_
CPOutlineViewDataSource_outlineView_sortDescriptorsDidChange_ = 1 << 10;
var CPOutlineViewDelegate_outlineView_dataViewForTableColumn_item_ = 1 << 1,
CPOutlineViewDelegate_outlineView_shouldSelectItem_ = 1 << 2,
CPOutlineViewDelegate_outlineView_heightOfRowByItem_ = 1 << 3,
CPOutlineViewDelegate_outlineView_willDisplayView_forTableColumn_item_ = 1 << 4,
CPOutlineViewDelegate_outlineView_isGroupItem_ = 1 << 5;
CPOutlineViewDropOnItemIndex = -1;
@implementation CPOutlineView : CPTableView
{
id _outlineViewDataSource;
@@ -60,6 +69,7 @@ var CPOutlineViewDataSource_outlineView_setObjectValue_forTableColumn_byItem_
BOOL _indentationMarkerFollowsDataView;
CPInteger _implementedOutlineViewDataSourceMethods;
CPInteger _implementedOutlineViewDelegateMethods;
Object _rootItemInfo;
CPMutableArray _itemsForRows;
@@ -69,6 +79,14 @@ var CPOutlineViewDataSource_outlineView_setObjectValue_forTableColumn_byItem_
CPArray _disclosureControlsForRows;
CPData _disclosureControlData;
CPArray _disclosureControlQueue;
BOOL _shouldRetargetItem;
id _retargetedItem;
BOOL _shouldRetargetChildIndex;
CPInteger _retargedChildIndex;
CPTimer _dragHoverTimer;
id _dropItem;
}
- (id)initWithFrame:(CGRect)aFrame
@@ -77,6 +95,9 @@ var CPOutlineViewDataSource_outlineView_setObjectValue_forTableColumn_byItem_
if (self)
{
_selectionHighlightStyle = CPTableViewSelectionHighlightStyleSourceList;
// The root item has weight "0", thus represents the weight solely of its descendants.
_rootItemInfo = { isExpanded:YES, isExpandable:NO, level:-1, row:-1, children:[], weight:0 };
@@ -84,10 +105,18 @@ var CPOutlineViewDataSource_outlineView_setObjectValue_forTableColumn_byItem_
_itemInfosForItems = { };
_disclosureControlsForRows = [];
_retargetedItem = nil;
_shouldRetargetItem = NO;
_retargedChildIndex = nil;
_shouldRetargetChildIndex = NO;
_startHoverTime = nil;
[self setIndentationPerLevel:16.0];
[self setIndentationMarkerFollowsDataView:YES];
[super setDataSource:[[_CPOutlineViewTableViewDataSource alloc] initWithOutlineView:self]];
[super setDelegate:[[_CPOutlineViewTableViewDelegate alloc] initWithOutlineView:self]];
[self setDisclosureControlPrototype:[[CPDisclosureButton alloc] initWithFrame:CGRectMake(0.0, 0.0, 10.0, 10.0)]];
}
@@ -181,20 +210,32 @@ var CPOutlineViewDataSource_outlineView_setObjectValue_forTableColumn_byItem_
- (void)expandItem:(id)anItem
{
if (!anItem)
return;
[self expandItem:anItem expandChildren:NO];
}
var itemInfo = _itemInfosForItems[[anItem UID]];
- (void)expandItem:(id)anItem expandChildren:(BOOL)shouldExpandChildren
{
var itemInfo = null;
if (!anItem)
itemInfo = _rootItemInfo;
else
itemInfo = _itemInfosForItems[[anItem UID]];
if (!itemInfo)
return;
if (itemInfo.isExpanded)
return;
itemInfo.isExpanded = YES;
[self reloadItem:anItem reloadChildren:YES];
if (shouldExpandChildren)
{
var children = itemInfo.children,
childIndex = children.length;
while (childIndex--)
[self expandItem:children[childIndex] expandChildren:YES];
}
}
- (void)collapseItem:(id)anItem
@@ -235,7 +276,7 @@ var CPOutlineViewDataSource_outlineView_setObjectValue_forTableColumn_byItem_
return _itemsForRows[aRow] || nil;
}
- (CPInteger)rowForItem:(id)aItem
- (CPInteger)rowForItem:(id)anItem
{
if (!anItem)
return _rootItemInfo.row;
@@ -324,7 +365,13 @@ var CPOutlineViewDataSource_outlineView_setObjectValue_forTableColumn_byItem_
if (!itemInfo)
return nil;
return itemInfo.parent;
var parent = itemInfo.parent;
// Check if the parent is the root item because we never return the actual root item
if (itemInfo[[parent UID]] === _rootItemInfo)
parent = nil;
return parent;
}
- (CGRect)frameOfOutlineDataViewAtColumn:(CPInteger)aColumn row:(CPInteger)aRow
@@ -338,6 +385,16 @@ var CPOutlineViewDataSource_outlineView_setObjectValue_forTableColumn_byItem_
return frame;
}
- (void)_performSelection:(BOOL)select forRow:(CPInteger)rowIndex context:(id)context
{
[super _performSelection:select forRow:rowIndex context:context];
var control = _disclosureControlsForRows[rowIndex],
selector = select ? @"setThemeState:" : @"unsetThemeState:";
[control performSelector:CPSelectorFromString(selector) withObject:CPThemeStateSelected];
}
- (void)setDelegate:(id)aDelegate
{
if (_outlineViewDelegate === aDelegate)
@@ -372,63 +429,24 @@ var CPOutlineViewDataSource_outlineView_setObjectValue_forTableColumn_byItem_
object:self];
}
_outlineViewDelegate = aDelegate;/*
_implementedDelegateMethods = 0;
_outlineViewDelegate = aDelegate;
_implementedOutlineViewDelegateMethods = 0;
if ([_outlineViewDelegate respondsToSelector:@selector(selectionShouldChangeInTableView:)])
_implementedDelegateMethods |= CPTableViewDelegate_selectionShouldChangeInTableView_;
if ([_outlineViewDelegate respondsToSelector:@selector(outlineView:dataViewForTableColumn:item:)])
_implementedOutlineViewDelegateMethods |= CPOutlineViewDelegate_outlineView_dataViewForTableColumn_item_;
if ([_outlineViewDelegate respondsToSelector:@selector(outlineView:shouldSelectItem:)])
_implementedOutlineViewDelegateMethods |= CPOutlineViewDelegate_outlineView_shouldSelectItem_;
if ([_outlineViewDelegate respondsToSelector:@selector(outlineView:heightOfRowByItem:)])
_implementedOutlineViewDelegateMethods |= CPOutlineViewDelegate_outlineView_heightOfRowByItem_;
if ([_outlineViewDelegate respondsToSelector:@selector(tableView:dataViewForTableColumn:row:)])
_implementedDelegateMethods |= CPTableViewDelegate_tableView_dataViewForTableColumn_row_;
if ([_outlineViewDelegate respondsToSelector:@selector(outlineView:willDisplayView:forTableColumn:item:)])
_implementedOutlineViewDelegateMethods |= CPOutlineViewDelegate_outlineView_willDisplayView_forTableColumn_item_;
if ([_outlineViewDelegate respondsToSelector:@selector(tableView:didClickTableColumn:)])
_implementedDelegateMethods |= CPTableViewDelegate_tableView_didClickTableColumn_;
if ([_outlineViewDelegate respondsToSelector:@selector(outlineView:isGroupItem:)])
_implementedOutlineViewDelegateMethods |= CPOutlineViewDelegate_outlineView_isGroupItem_;
if ([_outlineViewDelegate respondsToSelector:@selector(tableView:didDragTableColumn:)])
_implementedDelegateMethods |= CPTableViewDelegate_tableView_didDragTableColumn_;
if ([_outlineViewDelegate respondsToSelector:@selector(tableView:heightOfRow:)])
_implementedDelegateMethods |= CPTableViewDelegate_tableView_heightOfRow_;
if ([_outlineViewDelegate respondsToSelector:@selector(tableView:isGroupRow:)])
_implementedDelegateMethods |= CPTableViewDelegate_tableView_isGroupRow_;
if ([_outlineViewDelegate respondsToSelector:@selector(tableView:mouseDownInHeaderOfTableColumn:)])
_implementedDelegateMethods |= CPTableViewDelegate_tableView_mouseDownInHeaderOfTableColumn_;
if ([_outlineViewDelegate respondsToSelector:@selector(tableView:nextTypeSelectMatchFromRow:toRow:forString:)])
_implementedDelegateMethods |= CPTableViewDelegate_tableView_nextTypeSelectMatchFromRow_toRow_forString_;
if ([_outlineViewDelegate respondsToSelector:@selector(tableView:selectionIndexesForProposedSelection:)])
_implementedDelegateMethods |= CPTableViewDelegate_tableView_selectionIndexesForProposedSelection_;
if ([_outlineViewDelegate respondsToSelector:@selector(tableView:shouldEditTableColumn:row:)])
_implementedDelegateMethods |= CPTableViewDelegate_tableView_shouldEditTableColumn_row_;
if ([_outlineViewDelegate respondsToSelector:@selector(tableView:shouldSelectRow:)])
_implementedDelegateMethods |= CPTableViewDelegate_tableView_shouldSelectRow_;
if ([_outlineViewDelegate respondsToSelector:@selector(tableView:shouldSelectTableColumn:)])
_implementedDelegateMethods |= CPTableViewDelegate_tableView_shouldSelectTableColumn_;
if ([_outlineViewDelegate respondsToSelector:@selector(tableView:shouldShowViewExpansionForTableColumn:row:)])
_implementedDelegateMethods |= CPTableViewDelegate_tableView_shouldShowViewExpansionForTableColumn_row_;
if ([_outlineViewDelegate respondsToSelector:@selector(tableView:shouldTrackView:forTableColumn:row:)])
_implementedDelegateMethods |= CPTableViewDelegate_tableView_shouldTrackView_forTableColumn_row_;
if ([_outlineViewDelegate respondsToSelector:@selector(tableView:shouldTypeSelectForEvent:withCurrentSearchString:)])
_implementedDelegateMethods |= CPTableViewDelegate_tableView_shouldTypeSelectForEvent_withCurrentSearchString_;
if ([_outlineViewDelegate respondsToSelector:@selector(tableView:toolTipForView:rect:tableColumn:row:mouseLocation:)])
_implementedDelegateMethods |= CPTableViewDelegate_tableView_toolTipForView_rect_tableColumn_row_mouseLocation_;
if ([_outlineViewDelegate respondsToSelector:@selector(tableView:typeSelectStringForTableColumn:row:)])
_implementedDelegateMethods |= CPTableViewDelegate_tableView_typeSelectStringForTableColumn_row_;
if ([_outlineViewDelegate respondsToSelector:@selector(tableView:willDisplayView:forTableColumn:row:)])
_implementedDelegateMethods |= CPTableViewDelegate_tableView_willDisplayView_forTableColumn_row_;
*/
if ([_outlineViewDelegate respondsToSelector:@selector(outlineViewColumnDidMove:)])
[defaultCenter
addObserver:_outlineViewDelegate
@@ -488,6 +506,86 @@ var CPOutlineViewDataSource_outlineView_setObjectValue_forTableColumn_byItem_
return [super frameOfDataViewAtColumn:aColumn row:aRow];
}
- (void)setDropItem:(id)theItem dropChildIndex:(int)theIndex
{
if (_dropItem !== theItem && theIndex < 0 && [self isExpandable:theItem] && ![self isItemExpanded:theItem])
{
if (_dragHoverTimer)
[_dragHoverTimer invalidate];
var autoExpandCallBack = function(){
if (_dropItem)
{
[_dropOperationFeedbackView blink];
[CPTimer scheduledTimerWithTimeInterval:.3 callback:objj_msgSend(self, "expandItem:", _dropItem) repeats:NO]; //[self expandItem:_dropItem];
}
}
_dragHoverTimer = [CPTimer scheduledTimerWithTimeInterval:.8 callback:autoExpandCallBack repeats:NO];
}
if (theIndex >= 0)
{
[_dragHoverTimer invalidate];
_dragHoverTimer = nil;
}
_dropItem = theItem;
_retargetedItem = theItem;
_shouldRetargetItem = YES;
_retargedChildIndex = theIndex;
_shouldRetargetChildIndex = YES;
}
- (void)_draggingEnded
{
[super _draggingEnded];
_dropItem = nil;
[_dragHoverTimer invalidate];
_dragHoverTimer = nil;
}
- (id)_parentItemForUpperRow:(int)theUpperRowIndex andLowerRow:(int)theLowerRowIndex atMouseOffset:(CPPoint)theOffset
{
if (_shouldRetargetItem)
return _retargetedItem;
var lowerLevel = [self levelForRow:theLowerRowIndex]
upperItem = [self itemAtRow:theUpperRowIndex];
upperLevel = [self levelForItem:upperItem];
// If the row above us has a higher level the item can be added to multiple parent items
// Determine which one by looping through all possible parents and return the first
// of which the indentation level is larger than the current x offset
while (upperLevel > lowerLevel)
{
upperLevel = [self levelForItem:upperItem];
// See if this item's indentation level matches the mouse offset
if (theOffset.x > (upperLevel + 1) * [self indentationPerLevel])
return [self parentForItem:upperItem];
// Check the next parent
upperItem = [self parentForItem:upperItem];
}
return [self parentForItem:[self itemAtRow:theLowerRowIndex]];
}
- (CPRect)_rectForDropHighlightViewBetweenUpperRow:(int)theUpperRowIndex andLowerRow:(int)theLowerRowIndex offset:(CPPoint)theOffset
{
// Call super and the update x to reflect the current indentation level
var rect = [super _rectForDropHighlightViewBetweenUpperRow:theUpperRowIndex andLowerRow:theLowerRowIndex offset:theOffset],
parentItem = [self _parentItemForUpperRow:theUpperRowIndex andLowerRow:theLowerRowIndex atMouseOffset:theOffset],
level = [self levelForItem:parentItem];
rect.origin.x = (level + 1) * [self indentationPerLevel];
rect.size.width -= rect.origin.x; // This assumes that the x returned by super is zero
return rect;
}
- (void)_loadDataViewsInRows:(CPIndexSet)rows columns:(CPIndexSet)columns
{
[super _loadDataViewsInRows:rows columns:columns];
@@ -526,6 +624,8 @@ var CPOutlineViewDataSource_outlineView_setObjectValue_forTableColumn_byItem_
_disclosureControlsForRows[row] = control;
[control setState:[self isItemExpanded:item] ? CPOnState : CPOffState];
var selector = [self isRowSelected:row] ? @"setThemeState:" : @"unsetThemeState:";
[control performSelector:CPSelectorFromString(selector) withObject:CPThemeStateSelected];
[control setFrame:frame];
[self addSubview:control];
@@ -618,140 +718,147 @@ var CPOutlineViewDataSource_outlineView_setObjectValue_forTableColumn_byItem_
@end
// FIX ME: We're using with() here because Safari fails if we use anOutlineView._itemInfosForItems or whatever...
var _reloadItem = function(/*CPOutlineView*/ anOutlineView, /*id*/ anItem)
{
if (!anItem)
return;
// Get the existing info if it exists.
var itemInfosForItems = anOutlineView._itemInfosForItems,
dataSource = anOutlineView._outlineViewDataSource,
itemUID = [anItem UID],
itemInfo = itemInfosForItems[itemUID];
// If we're not in the tree, then just bail.
if (!itemInfo)
return [];
// See if the item itself can be swapped out.
var parent = itemInfo.parent,
parentItemInfo = parent ? itemInfosForItems[[parent UID]] : anOutlineView._rootItemInfo,
parentChildren = parentItemInfo.children,
index = [parentChildren indexOfObjectIdenticalTo:anItem],
newItem = [dataSource outlineView:anOutlineView child:index ofItem:parent];
if (anItem !== newItem)
{
itemInfosForItems[[anItem UID]] = nil;
itemInfosForItems[[newItem UID]] = itemInfo;
parentChildren[index] = newItem;
anOutlineView._itemsForRows[itemInfo.row] = newItem;
}
itemInfo.isExpandable = [dataSource outlineView:anOutlineView isItemExpandable:newItem];
itemInfo.isExpanded = itemInfo.isExpandable && itemInfo.isExpanded;
}
var _loadItemInfoForItem = function(/*CPOutlineView*/ anOutlineView, /*id*/ anItem, /*BOOL*/ isIntermediate)
{
var itemInfosForItems = anOutlineView._itemInfosForItems,
dataSource = anOutlineView._outlineViewDataSource;
if (!anItem)
var itemInfo = anOutlineView._rootItemInfo;
else
with(anOutlineView)
{
// Get the existing info if it exists.
var itemUID = [anItem UID],
var itemInfosForItems = _itemInfosForItems,
dataSource = _outlineViewDataSource,
itemUID = [anItem UID],
itemInfo = itemInfosForItems[itemUID];
// If we're not in the tree, then just bail.
if (!itemInfo)
return [];
itemInfo.isExpandable = [dataSource outlineView:anOutlineView isItemExpandable:anItem];
// If we were previously expanded, but now no longer expandable, "de-expand".
// NOTE: we are *not* collapsing, thus no notification is posted.
if (!itemInfo.isExpandable && itemInfo.isExpanded)
// See if the item itself can be swapped out.
var parent = itemInfo.parent,
parentItemInfo = parent ? itemInfosForItems[[parent UID]] : _rootItemInfo,
parentChildren = parentItemInfo.children,
index = [parentChildren indexOfObjectIdenticalTo:anItem],
newItem = [dataSource outlineView:anOutlineView child:index ofItem:parent];
if (anItem !== newItem)
{
itemInfo.isExpanded = NO;
itemInfosForItems[[anItem UID]] = nil;
itemInfosForItems[[newItem UID]] = itemInfo;
parentChildren[index] = newItem;
_itemsForRows[itemInfo.row] = newItem;
}
itemInfo.isExpandable = [dataSource outlineView:anOutlineView isItemExpandable:newItem];
itemInfo.isExpanded = itemInfo.isExpandable && itemInfo.isExpanded;
}
}
// FIX ME: We're using with() here because Safari fails if we use anOutlineView._itemInfosForItems or whatever...
var _loadItemInfoForItem = function(/*CPOutlineView*/ anOutlineView, /*id*/ anItem, /*BOOL*/ isIntermediate)
{
with(anOutlineView)
{
var itemInfosForItems = _itemInfosForItems,
dataSource = _outlineViewDataSource;
if (!anItem)
var itemInfo = _rootItemInfo;
else
{
// Get the existing info if it exists.
var itemUID = [anItem UID],
itemInfo = itemInfosForItems[itemUID];
// If we're not in the tree, then just bail.
if (!itemInfo)
return [];
itemInfo.isExpandable = [dataSource outlineView:anOutlineView isItemExpandable:anItem];
// If we were previously expanded, but now no longer expandable, "de-expand".
// NOTE: we are *not* collapsing, thus no notification is posted.
if (!itemInfo.isExpandable && itemInfo.isExpanded)
{
itemInfo.isExpanded = NO;
itemInfo.children = [];
}
}
// The root item does not count as a descendant.
var weight = itemInfo.weight,
descendants = anItem ? [anItem] : [];
if (itemInfo.isExpanded && (!(_implementedOutlineViewDataSourceMethods & CPOutlineViewDataSource_outlineView_shouldDeferDisplayingChildrenOfItem_) ||
![dataSource outlineView:anOutlineView shouldDeferDisplayingChildrenOfItem:anItem]))
{
var index = 0,
count = [dataSource outlineView:anOutlineView numberOfChildrenOfItem:anItem],
level = itemInfo.level + 1;
itemInfo.children = [];
}
}
// The root item does not count as a descendant.
var weight = itemInfo.weight,
descendants = anItem ? [anItem] : [];
if (itemInfo.isExpanded && (!(anOutlineView._implementedOutlineViewDataSourceMethods & CPOutlineViewDataSource_outlineView_shouldDeferDisplayingChildrenOfItem_) ||
![dataSource outlineView:anOutlineView shouldDeferDisplayingChildrenOfItem:anItem]))
{
var index = 0,
count = [dataSource outlineView:anOutlineView numberOfChildrenOfItem:anItem],
level = itemInfo.level + 1;
itemInfo.children = [];
for (; index < count; ++index)
{
var childItem = [dataSource outlineView:anOutlineView child:index ofItem:anItem],
childItemInfo = itemInfosForItems[[childItem UID]];
if (!childItemInfo)
for (; index < count; ++index)
{
childItemInfo = { isExpanded:NO, isExpandable:NO, children:[], weight:1 };
itemInfosForItems[[childItem UID]] = childItemInfo;
var childItem = [dataSource outlineView:anOutlineView child:index ofItem:anItem],
childItemInfo = itemInfosForItems[[childItem UID]];
if (!childItemInfo)
{
childItemInfo = { isExpanded:NO, isExpandable:NO, children:[], weight:1 };
itemInfosForItems[[childItem UID]] = childItemInfo;
}
itemInfo.children[index] = childItem;
var childDescendants = _loadItemInfoForItem(anOutlineView, childItem, YES);
childItemInfo.parent = anItem;
childItemInfo.level = level;
descendants = descendants.concat(childDescendants);
}
itemInfo.children[index] = childItem;
var childDescendants = _loadItemInfoForItem(anOutlineView, childItem, YES);
childItemInfo.parent = anItem;
childItemInfo.level = level;
descendants = descendants.concat(childDescendants);
}
}
itemInfo.weight = descendants.length;
if (!isIntermediate)
{
// row = -1 is the root item, so just go to row 0 since it is ignored.
var index = MAX(itemInfo.row, 0),
itemsForRows = anOutlineView._itemsForRows;
descendants.unshift(index, weight);
itemsForRows.splice.apply(itemsForRows, descendants);
var count = itemsForRows.length;
for (; index < count; ++index)
itemInfosForItems[[itemsForRows[index] UID]].row = index;
var deltaWeight = itemInfo.weight - weight;
if (deltaWeight !== 0)
itemInfo.weight = descendants.length;
if (!isIntermediate)
{
var parent = itemInfo.parent;
while (parent)
// row = -1 is the root item, so just go to row 0 since it is ignored.
var index = MAX(itemInfo.row, 0),
itemsForRows = _itemsForRows;
descendants.unshift(index, weight);
itemsForRows.splice.apply(itemsForRows, descendants);
var count = itemsForRows.length;
for (; index < count; ++index)
itemInfosForItems[[itemsForRows[index] UID]].row = index;
var deltaWeight = itemInfo.weight - weight;
if (deltaWeight !== 0)
{
var parentItemInfo = itemInfosForItems[[parent UID]];
parentItemInfo.weight += deltaWeight;
parent = parentItemInfo.parent;
var parent = itemInfo.parent;
while (parent)
{
var parentItemInfo = itemInfosForItems[[parent UID]];
parentItemInfo.weight += deltaWeight;
parent = parentItemInfo.parent;
}
if (anItem)
_rootItemInfo.weight += deltaWeight;
}
if (anItem)
anOutlineView._rootItemInfo.weight += deltaWeight;
}
}
}//end of with
return descendants;
}
@@ -780,6 +887,93 @@ var _loadItemInfoForItem = function(/*CPOutlineView*/ anOutlineView, /*id*/ anIt
return [_outlineView._outlineViewDataSource outlineView:_outlineView objectValueForTableColumn:aTableColumn byItem:_outlineView._itemsForRows[aRow]];
}
- (BOOL)tableView:(CPTableView)aTableColumn writeRowsWithIndexes:(CPIndexSet)theIndexes toPasteboard:(CPPasteboard)thePasteboard
{
if (!(_outlineView._implementedOutlineViewDataSourceMethods & CPOutlineViewDataSource_outlineView_writeItems_toPasteboard_))
return NO;
var rowIndexes = [];
[theIndexes getIndexes:rowIndexes maxCount:[theIndexes count] inIndexRange:nil];
var rowIndex = [rowIndexes count],
items = [];
while (rowIndex--)
[items addObject:[_outlineView itemAtRow:[rowIndexes objectAtIndex:rowIndex]]];
return [_outlineView._outlineViewDataSource outlineView:_outlineView writeItems:items toPasteboard:thePasteboard];
}
- (int)_childIndexForDropOperation:(CPTableViewDropOperation)theDropOperation row:(int)theRow offset:(CPPoint)theOffset
{
if (_outlineView._shouldRetargetChildIndex)
return _outlineView._retargedChildIndex;
var childIndex = CPNotFound;
if (theDropOperation === CPTableViewDropAbove)
{
var parentItem = [_outlineView _parentItemForUpperRow:theRow - 1 andLowerRow:theRow atMouseOffset:theOffset],
itemInfo = (parentItem !== nil) ? _outlineView._itemInfosForItems[[parentItem UID]] : _outlineView._rootItemInfo,
children = itemInfo.children;
childIndex = [children indexOfObject:[_outlineView itemAtRow:theRow]];
if (childIndex === CPNotFound)
childIndex = children.length;
}
else if (theDropOperation === CPTableViewDropOn)
childIndex = -1;
return childIndex;
}
- (void)_parentItemForDropOperation:(CPTableViewDropOperation)theDropOperation row:(int)theRow offset:(CPPoint)theOffset
{
if (theDropOperation === CPTableViewDropAbove)
return [_outlineView _parentItemForUpperRow:theRow - 1 andLowerRow:theRow atMouseOffset:theOffset]
return [_outlineView itemAtRow:theRow];
}
- (CPDragOperation)tableView:(CPTableView)aTableView validateDrop:(id < CPDraggingInfo >)theInfo
proposedRow:(int)theRow proposedDropOperation:(CPTableViewDropOperation)theOperation
{
if (!(_outlineView._implementedOutlineViewDataSourceMethods & CPOutlineViewDataSource_outlineView_validateDrop_proposedItem_proposedChildIndex_))
return CPDragOperationNone;
// Make sure the retargeted item and index are reset
_outlineView._retargetedItem = nil;
_outlineView._shouldRetargetItem = NO;
_outlineView._retargedChildIndex = nil;
_outlineView._shouldRetargetChildIndex = NO;
var location = [_outlineView convertPoint:[theInfo draggingLocation] fromView:nil],
parentItem = [self _parentItemForDropOperation:theOperation row:theRow offset:location];
childIndex = [self _childIndexForDropOperation:theOperation row:theRow offset:location];
return [_outlineView._outlineViewDataSource outlineView:_outlineView validateDrop:theInfo proposedItem:parentItem proposedChildIndex:childIndex];
}
- (BOOL)tableView:(CPTableView)aTableView acceptDrop:(id <CPDraggingInfo>)theInfo row:(int)theRow dropOperation:(CPTableViewDropOperation)theOperation
{
if (!(_outlineView._implementedOutlineViewDataSourceMethods & CPOutlineViewDataSource_outlineView_acceptDrop_item_childIndex_))
return NO;
var location = [_outlineView convertPoint:[theInfo draggingLocation] fromView:nil],
parentItem = [self _parentItemForDropOperation:theOperation row:theRow offset:location];
childIndex = [self _childIndexForDropOperation:theOperation row:theRow offset:location];
_outlineView._retargetedItem = nil;
_outlineView._shouldRetargetItem = NO;
_outlineView._retargedChildIndex = nil;
_outlineView._shouldRetargetChildIndex = NO;
return [_outlineView._outlineViewDataSource outlineView:_outlineView acceptDrop:theInfo item:parentItem childIndex:childIndex];
}
@end
@implementation _CPOutlineViewTableViewDelegate : CPObject
@@ -797,6 +991,54 @@ var _loadItemInfoForItem = function(/*CPOutlineView*/ anOutlineView, /*id*/ anIt
return self;
}
- (CPView)tableView:(CPTableView)theTableView dataViewForTableColumn:(CPTableColumn)theTableColumn row:(int)theRow
{
var dataView = nil;
if ((_outlineView._implementedOutlineViewDelegateMethods & CPOutlineViewDelegate_outlineView_dataViewForTableColumn_item_))
dataView = [_outlineView._outlineViewDelegate outlineView:_outlineView
dataViewForTableColumn:theTableColumn
item:[_outlineView itemAtRow:theRow]];
if (!dataView)
dataView = [theTableColumn dataViewForRow:theRow];
return dataView;
}
- (BOOL)tableView:(CPTableView)theTableView shouldSelectRow:(int)theRow
{
if ((_outlineView._implementedOutlineViewDelegateMethods & CPOutlineViewDelegate_outlineView_shouldSelectItem_))
return [_outlineView._outlineViewDelegate outlineView:_outlineView shouldSelectItem:[_outlineView itemAtRow:theRow]];
return YES;
}
- (float)tableView:(CPTableView)theTableView heightOfRow:(int)theRow
{
if ((_outlineView._implementedOutlineViewDelegateMethods & CPOutlineViewDelegate_outlineView_heightOfRowByItem_))
return [_outlineView._outlineViewDelegate outlineView:_outlineView heightOfRowByItem:[_outlineView itemAtRow:theRow]];
return [theTableView rowHeight];
}
- (void)tableView:(CPTableView)aTableView willDisplayView:(id)aView forTableColumn:(CPTableColumn)aTableColumn row:(int)aRowIndex
{
if ((_outlineView._implementedOutlineViewDelegateMethods & CPOutlineViewDelegate_outlineView_willDisplayView_forTableColumn_item_))
{
var item = [_outlineView itemAtRow:aRowIndex];
[_outlineView._outlineViewDelegate outlineView:_outlineView willDisplayView:aView forTableColumn:aTableColumn item:item];
}
}
- (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
@implementation CPDisclosureButton : CPButton
@@ -845,8 +1087,10 @@ var _loadItemInfoForItem = function(/*CPOutlineView*/ anOutlineView, /*id*/ anIt
CGContextAddLineToPoint(context, 0.0, 0.0);
CGContextClosePath(context);
CGContextSetFillColor(context, ([self themeState] & CPThemeState("highlighted")) ? [CPColor blackColor] : [CPColor grayColor]);
var isHighlighted = [self hasThemeState:CPThemeStateHighlighted];
var color = [self hasThemeState:CPThemeStateSelected] ? (isHighlighted ? [CPColor lightGrayColor] : [CPColor whiteColor]) : (isHighlighted ? [CPColor blackColor] : [CPColor grayColor]);
CGContextSetFillColor(context, color);
CGContextFillPath(context);
}
+88 -16
View File
@@ -43,11 +43,14 @@ CPURLPboardType = @"CPURLPboardType";
CPImagesPboardType = @"CPImagesPboardType";
CPVideosPboardType = @"CPVideosPboardType";
UTF8PboardType = @"public.utf8-plain-text";
// Deprecated
CPImagePboardType = @"CPImagePboardType";
var CPPasteboards = nil;
var CPPasteboards = nil,
supportsNativePasteboard = NO;
/*!
@ingroup appkit
@@ -63,6 +66,8 @@ var CPPasteboards = nil;
unsigned _changeCount;
CPString _stateUID;
WebScriptObject _nativePasteboard;
}
/*
@@ -76,6 +81,9 @@ var CPPasteboards = nil;
[self setVersion:1.0];
CPPasteboards = [CPDictionary dictionary];
if (typeof window.cpPasteboardWithName !== "undefined")
supportsNativePasteboard = YES;
}
/*!
@@ -94,7 +102,7 @@ var CPPasteboards = nil;
+ (id)pasteboardWithName:(CPString)aName
{
var pasteboard = [CPPasteboards objectForKey:aName];
if (pasteboard)
return pasteboard;
@@ -118,6 +126,12 @@ var CPPasteboards = nil;
_provided = [CPDictionary dictionary];
_changeCount = 0;
if (supportsNativePasteboard)
{
_nativePasteboard = window.cpPasteboardWithName(aName);
[self _synchronizePasteboard];
}
}
return self;
@@ -146,7 +160,16 @@ var CPPasteboards = nil;
[_owners setObject:anOwner forKey:type];
}
if (_nativePasteboard)
{
var nativeTypes = [types copy];
if ([types containsObject:CPStringPboardType])
nativeTypes.push(UTF8PboardType);
_nativePasteboard.addTypes_(nativeTypes);
}
return ++_changeCount;
}
@@ -157,6 +180,12 @@ var CPPasteboards = nil;
@return the pasteboard's change count
*/
- (unsigned)declareTypes:(CPArray)types owner:(id)anOwner
{
[self _declareTypes:types owner:anOwner updateNativePasteboard:YES];
}
/*! @ignore */
- (unsigned)_declareTypes:(CPArray)types owner:(id)anOwner updateNativePasteboard:(BOOL)shouldUpdate
{
[_types setArray:types];
@@ -167,7 +196,16 @@ var CPPasteboards = nil;
while (count--)
[_owners setObject:anOwner forKey:_types[count]];
if (_nativePasteboard && shouldUpdate)
{
var nativeTypes = [types copy];
if ([types containsObject:CPStringPboardType])
nativeTypes.push(UTF8PboardType);
_nativePasteboard.declareTypes_(nativeTypes);
_changeCount = _nativePasteboard.changeCount();
}
return ++_changeCount;
}
@@ -180,7 +218,10 @@ var CPPasteboards = nil;
- (BOOL)setData:(CPData)aData forType:(CPString)aType
{
[_provided setObject:aData forKey:aType];
if (aType === CPStringPboardType)
[self setData:aData forType:UTF8PboardType];
return YES;
}
@@ -192,7 +233,7 @@ var CPPasteboards = nil;
*/
- (BOOL)setPropertyList:(id)aPropertyList forType:(CPString)aType
{
return [self setData:[CPPropertyListSerialization dataFromPropertyList:aPropertyList format:CPPropertyListXMLFormat_v1_0 errorDescription:nil] forType:aType];
return [self setData:[CPPropertyListSerialization dataFromPropertyList:aPropertyList format:CPPropertyList280NorthFormat_v1_0] forType:aType];
}
/*!
@@ -203,7 +244,7 @@ var CPPasteboards = nil;
*/
- (void)setString:(CPString)aString forType:(CPString)aType
{
return [self setPropertyList:aString forType:aType];
[self setPropertyList:aString forType:aType];
}
// Determining Types
@@ -223,6 +264,7 @@ var CPPasteboards = nil;
*/
- (CPArray)types
{
[self _synchronizePasteboard];
return _types;
}
@@ -251,16 +293,46 @@ var CPPasteboards = nil;
if (owner)
{
[owner pasteboard:self provideDataForType:aType];
++_changeCount;
[owner pasteboard:self provideDataForType:aType];
return [_provided objectForKey:aType];
}
if (aType === CPStringPboardType)
return [self dataForType:UTF8PboardType];
return nil;
}
- (void)_synchronizePasteboard
{
if (_nativePasteboard && _nativePasteboard.changeCount() > _changeCount)
{
var nativeTypes = [_nativePasteboard.types() copy];
if ([nativeTypes containsObject:UTF8PboardType])
nativeTypes.push(CPStringPboardType);
[self _declareTypes:nativeTypes owner:self updateNativePasteboard:NO];
_changeCount = _nativePasteboard.changeCount();
}
}
/*! @ignore
method provided for integration with native pasteboard
*/
- (void)pasteboard:(CPPasteboard)aPasteboard provideDataForType:(CPString)aType
{
if (aType === CPStringPboardType)
{
var string = _nativePasteboard.stringForType_(UTF8PboardType);
[self setString:string forType:CPStringPboardType];
[self setString:string forType:UTF8PboardType];
}
else
[self setString:_nativePasteboard.stringForType_(aType) forType:aType];
}
/*!
Returns the property list for the specified data type
@param aType the requested data type
@@ -271,7 +343,7 @@ var CPPasteboards = nil;
var data = [self dataForType:aType];
if (data)
return [CPPropertyListSerialization propertyListFromData:data format:CPPropertyListXMLFormat_v1_0 errorDescription:nil];
return [CPPropertyListSerialization propertyListFromData:data format:CPPropertyList280NorthFormat_v1_0];
return nil;
}
@@ -343,7 +415,7 @@ var DOMDataTransferPasteboard = nil;
if (type === CPStringPboardType)
_dataTransfer.setData(type, [aPasteboard stringForType:type]);
else
_dataTransfer.setData(type, [[aPasteboard dataForType:type] string]);
_dataTransfer.setData(type, [[aPasteboard dataForType:type] rawString]);
}
}
@@ -357,9 +429,9 @@ var DOMDataTransferPasteboard = nil;
var dataString = _dataTransfer.getData(aType);
if (aType === CPStringPboardType)
return [CPData dataFromPropertyList:dataString format:kCFPropertyList280NorthFormat_v1_0 errorDescription:0];
return [CPData dataFromPropertyList:dataString format:kCFPropertyList280NorthFormat_v1_0];
return [CPData dataWithString:dataString];
return [CPData dataWithRawString:dataString];
}
- (id)propertyListForType:(CPString)aType
@@ -367,7 +439,7 @@ var DOMDataTransferPasteboard = nil;
if (aType === CPStringPboardType)
return _dataTransfer.getData(aType);
return [CPPropertyListSerialization propertyListFromData:[self dataForType:aType] format:CPPropertyListUnknownFormat errorDescription:nil];
return [CPPropertyListSerialization propertyListFromData:[self dataForType:aType] format:CPPropertyListUnknownFormat];
}
@end
+58 -42
View File
@@ -638,21 +638,49 @@ CPPopUpButtonStatePullsDown = CPThemeState("pulls-down");
{
if (![self isEnabled] || ![self numberOfItems])
return;
[self highlight:YES];
var menu = [self menu],
theWindow = [self window],
menuWindow = [_CPMenuWindow menuWindowWithMenu:menu font:[self font]];
[menuWindow setDelegate:self];
[menuWindow setBackgroundStyle:_CPMenuWindowPopUpBackgroundStyle];
// Pull Down Menus show up directly below their buttons.
bounds = [self bounds],
minimumWidth = CGRectGetWidth(bounds);
// FIXME: setFont: should set the font on the menu.
[menu setFont:[self font]];
if ([self pullsDown])
var menuOrigin = [theWindow convertBaseToGlobal:[self convertPoint:CGPointMake(0.0, CGRectGetMaxY([self bounds])) toView:nil]];
// Pop Up Menus attempt to show up "on top" of the selected item.
{
var positionedItem = nil,
location = CGPointMake(0.0, CGRectGetMaxY(bounds));
}
else
{
var contentRect = [self contentRectForBounds:bounds],
positionedItem = [self selectedItem],
standardLeftMargin = [_CPMenuWindow _standardLeftMargin] + [_CPMenuItemStandardView _standardLeftMargin],
location = CGPointMake(CGRectGetMinX(contentRect) - standardLeftMargin, 0.0);
minimumWidth += standardLeftMargin;
}
[menu setMinimumWidth:minimumWidth];
[menu
_popUpMenuPositioningItem:positionedItem
atLocation:location
topY:CGRectGetMinY(bounds)
bottomY:CGRectGetMaxY(bounds)
inView:self
callback:function(aMenu)
{
[self highlight:NO];
var highlightedItem = [aMenu highlightedItem];
if ([highlightedItem _isSelectable])
[self selectItem:highlightedItem];
}];
/*
else
{
// This is confusing, I KNOW, so let me explain it to you.
@@ -660,43 +688,14 @@ CPPopUpButtonStatePullsDown = CPThemeState("pulls-down");
// 1. So calculate where our content is, then calculate where the menu item is.
// 2. Move LEFT by whatever indentation we have (offsetWidths, aka, window margin, item margin, etc).
// 3. MOVE UP by the difference in sizes of the content and menu item, this will only work if the content is vertically centered.
var contentRect = [self convertRect:[self contentRectForBounds:[self bounds]] toView:nil],
var contentRect = [self convertRect:[self contentRectForBounds:bounds] toView:nil],
menuOrigin = [theWindow convertBaseToGlobal:contentRect.origin],
menuItemRect = [menuWindow rectForItemAtIndex:_selectedIndex];
menuOrigin.x -= CGRectGetMinX(menuItemRect) + [menuWindow overlapOffsetWidth] + [[[menu itemAtIndex:_selectedIndex] _menuItemView] overlapOffsetWidth];
menuOrigin.y -= CGRectGetMinY(menuItemRect) + (CGRectGetHeight(menuItemRect) - CGRectGetHeight(contentRect)) / 2.0;
}
[menuWindow setFrameOrigin:menuOrigin];
var menuMaxX = CGRectGetMaxX([menuWindow frame]),
buttonMaxX = [theWindow convertBaseToGlobal:CGPointMake(CGRectGetMaxX([self convertRect:[self bounds] toView:nil]), 0.0)].x;
if (menuMaxX < buttonMaxX)
[menuWindow setMinWidth:CGRectGetWidth([menuWindow frame]) + buttonMaxX - menuMaxX - ([self pullsDown] ? 0.0 : VISIBLE_MARGIN)];
[menuWindow orderFront:self];
[menuWindow beginTrackingWithEvent:anEvent sessionDelegate:self didEndSelector:@selector(menuWindowDidFinishTracking:highlightedItem:)];
}
/*
@ignore
*/
- (void)menuWindowDidFinishTracking:(_CPMenuWindow)aMenuWindow highlightedItem:(CPMenuItem)aMenuItem
{
[_CPMenuWindow poolMenuWindow:aMenuWindow];
[self highlight:NO];
var index = [_menu indexOfItem:aMenuItem];
if (index == CPNotFound)
return;
[self selectItemAtIndex:index];
[CPApp sendAction:[aMenuItem action] to:[aMenuItem target] from:aMenuItem];
}
- (void)_popUpItemAction:(id)aSender
@@ -704,6 +703,23 @@ CPPopUpButtonStatePullsDown = CPThemeState("pulls-down");
[self sendAction:[self action] to:[self target]];
}
- (void)takeValueFromKeyPath:(CPString)aKeyPath ofObjects:(CPArray)objects
{
var count = objects.length,
value = [objects[0] valueForKeyPath:aKeyPath];
[self selectItemWithTag:value];
[self setEnabled:YES];
while (count-- > 1)
{
if (value !== [objects[count] valueForKeyPath:aKeyPath])
{
[[self selectedItem] setState:CPOffState];
}
}
}
@end
var CPPopUpButtonMenuKey = @"CPPopUpButtonMenuKey",
+25 -34
View File
@@ -104,17 +104,14 @@ var CPProgressIndicatorSpinningStyleColors = nil,
for (; start <= end; ++start)
{
CPProgressIndicatorBezelBorderViewPool[start] = [];
CPProgressIndicatorBezelBorderViewPool[start][CPMiniControlSize] = [];
CPProgressIndicatorBezelBorderViewPool[start][CPSmallControlSize] = [];
CPProgressIndicatorBezelBorderViewPool[start][CPRegularControlSize] = [];
}
CPProgressIndicatorClassName = [self className];
CPProgressIndicatorStyleIdentifiers = [];
CPProgressIndicatorStyleIdentifiers[CPProgressIndicatorBarStyle] = @"Bar";
CPProgressIndicatorStyleIdentifiers[CPProgressIndicatorSpinningStyle] = @"Spinny";
CPProgressIndicatorStyleIdentifiers[CPProgressIndicatorHUDBarStyle] = @"HUDBar";
@@ -126,30 +123,20 @@ var CPProgressIndicatorSpinningStyleColors = nil,
CPProgressIndicatorStyleSizes = [];
// Bar Sttyle
var prefix = CPProgressIndicatorClassName + @"BezelBorder" + CPProgressIndicatorStyleIdentifiers[CPProgressIndicatorBarStyle];
var prefixes = [
CPProgressIndicatorClassName + @"BezelBorder" + CPProgressIndicatorStyleIdentifiers[CPProgressIndicatorBarStyle],
CPProgressIndicatorClassName + @"Bar" + CPProgressIndicatorStyleIdentifiers[CPProgressIndicatorBarStyle],
CPProgressIndicatorClassName + @"BezelBorder" + CPProgressIndicatorStyleIdentifiers[CPProgressIndicatorHUDBarStyle],
CPProgressIndicatorClassName + @"Bar" + CPProgressIndicatorStyleIdentifiers[CPProgressIndicatorHUDBarStyle]
];
CPProgressIndicatorStyleSizes[prefix + regularIdentifier] = [_CGSizeMake(3.0, 15.0), _CGSizeMake(1.0, 15.0), _CGSizeMake(3.0, 15.0)];
CPProgressIndicatorStyleSizes[prefix + smallIdentifier] = [_CGSizeMake(3.0, 15.0), _CGSizeMake(1.0, 15.0), _CGSizeMake(3.0, 15.0)];
CPProgressIndicatorStyleSizes[prefix + miniIdentifier] = [_CGSizeMake(3.0, 15.0), _CGSizeMake(1.0, 15.0), _CGSizeMake(3.0, 15.0)];
prefix = CPProgressIndicatorClassName + @"Bar" + CPProgressIndicatorStyleIdentifiers[CPProgressIndicatorBarStyle];
CPProgressIndicatorStyleSizes[prefix + regularIdentifier] = _CGSizeMake(1.0, 9.0);
CPProgressIndicatorStyleSizes[prefix + smallIdentifier] = _CGSizeMake(1.0, 9.0);
CPProgressIndicatorStyleSizes[prefix + miniIdentifier] = _CGSizeMake(1.0, 9.0);
// HUD Bar Style
prefix = CPProgressIndicatorClassName + @"BezelBorder" + CPProgressIndicatorStyleIdentifiers[CPProgressIndicatorHUDBarStyle];
CPProgressIndicatorStyleSizes[prefix + regularIdentifier] = [_CGSizeMake(3.0, 15.0), _CGSizeMake(1.0, 15.0), _CGSizeMake(3.0, 15.0)];
CPProgressIndicatorStyleSizes[prefix + smallIdentifier] = [_CGSizeMake(3.0, 15.0), _CGSizeMake(1.0, 15.0), _CGSizeMake(3.0, 15.0)];
CPProgressIndicatorStyleSizes[prefix + miniIdentifier] = [_CGSizeMake(3.0, 15.0), _CGSizeMake(1.0, 15.0), _CGSizeMake(3.0, 15.0)];
prefix = CPProgressIndicatorClassName + @"Bar" + CPProgressIndicatorStyleIdentifiers[CPProgressIndicatorHUDBarStyle];
CPProgressIndicatorStyleSizes[prefix + regularIdentifier] = _CGSizeMake(1.0, 9.0);
CPProgressIndicatorStyleSizes[prefix + smallIdentifier] = _CGSizeMake(1.0, 9.0);
CPProgressIndicatorStyleSizes[prefix + miniIdentifier] = _CGSizeMake(1.0, 9.0);
for (var i = 0, count = prefixes.length; i<count; i++)
{
var prefix = prefixes[i];
CPProgressIndicatorStyleSizes[prefix + regularIdentifier] = [_CGSizeMake(3.0, 16.0), _CGSizeMake(1.0, 16.0), _CGSizeMake(3.0, 16.0)];
CPProgressIndicatorStyleSizes[prefix + smallIdentifier] = [_CGSizeMake(3.0, 16.0), _CGSizeMake(1.0, 16.0), _CGSizeMake(3.0, 16.0)];
CPProgressIndicatorStyleSizes[prefix + miniIdentifier] = [_CGSizeMake(3.0, 16.0), _CGSizeMake(1.0, 16.0), _CGSizeMake(3.0, 16.0)];
}
}
- (id)initWithFrame:(CGRect)aFrame
@@ -428,21 +415,25 @@ var CPProgressIndicatorSpinningStyleColors = nil,
if (!_barView)
{
_barView = [[CPView alloc] initWithFrame:CGRectMake(2.0, 2.0, 0.0, 9.0)];
[_barView setBackgroundColor:[CPColor redColor]];
_barView = [[CPView alloc] initWithFrame:CGRectMake(0.0, 0.0, 0.0, 16.0)];
[self addSubview:_barView];
}
[_barView setBackgroundColor:_CPControlColorWithPatternImage(
[_barView setBackgroundColor:_CPControlThreePartImagePattern(
NO,
CPProgressIndicatorStyleSizes,
CPProgressIndicatorClassName,
@"Bar",
CPProgressIndicatorStyleIdentifiers[_style],
_CPControlIdentifierForControlSize(_controlSize))];
[_barView setFrameSize:CGSizeMake(CGRectGetWidth([self bounds]) * (_doubleValue - _minValue) / (_maxValue - _minValue) - 4.0, 9.0)];
var width = CGRectGetWidth([self bounds]),
barWidth = width * ((_doubleValue - _minValue) / (_maxValue - _minValue));
if (barWidth > 0.0 && barWidth < 4.0)
barWidth = 4.0;
[_barView setFrameSize:CGSizeMake(barWidth, 16.0)];
}
/* @ignore */
+5
View File
@@ -175,6 +175,9 @@ var CPRadioRadioGroupKey = @"CPRadioRadioGroupKey";
{
CPSet _radios;
CPRadio _selectedRadio;
id _target @accessors(property=target);
SEL _action @accessors(property=action);
}
- (id)init
@@ -213,6 +216,8 @@ var CPRadioRadioGroupKey = @"CPRadioRadioGroupKey";
[_selectedRadio setState:CPOffState];
_selectedRadio = aRadio;
[CPApp sendAction:_action to:_target from:self];
}
- (CPRadio)selectedRadio
+25
View File
@@ -27,6 +27,9 @@ CPDeleteKeyCode = 8;
CPTabKeyCode = 9;
CPReturnKeyCode = 13;
CPEscapeKeyCode = 27;
CPSpaceKeyCode = 32;
CPPageUpKeyCode = 33;
CPPageDownKeyCode = 34;
CPLeftArrowKeyCode = 37;
CPUpArrowKeyCode = 38;
CPRightArrowKeyCode = 39;
@@ -105,6 +108,10 @@ CPDownArrowKeyCode = 40;
switch([event keyCode])
{
case CPPageUpKeyCode: [self doCommandBySelector:@selector(pageUp:)];
break;
case CPPageDownKeyCode: [self doCommandBySelector:@selector(pageDown:)];
break;
case CPLeftArrowKeyCode: [self doCommandBySelector:@selector(moveLeft:)];
break;
case CPRightArrowKeyCode: [self doCommandBySelector:@selector(moveRight:)];
@@ -145,6 +152,15 @@ CPDownArrowKeyCode = 40;
[_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
over it. A drag is a mouse movement while the left button is down.
@@ -164,6 +180,15 @@ CPDownArrowKeyCode = 40;
[_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).
@param anEvent contains information about the movement
+5 -1
View File
@@ -1,8 +1,8 @@
@import <Foundation/CPObject.j>
#import "CoreGraphics/CGGeometry.h"
#import "Platform/Platform.h"
@implementation CPScreen : CPObject
{
@@ -10,7 +10,11 @@
- (CGRect)visibleFrame
{
#if PLATFORM(DOM)
return _CGRectMake(window.screen.availLeft, window.screen.availTop, window.screen.availWidth, window.screen.availHeight);
#else
return _CGRectMakeZero();
#endif
}
@end
+99 -54
View File
@@ -315,7 +315,10 @@
_hasHorizontalScroller = shouldHaveHorizontalScroller;
if (_hasHorizontalScroller && !_horizontalScroller)
[self setHorizontalScroller:[[CPScroller alloc] initWithFrame:CGRectMake(0.0, 0.0, _CGRectGetWidth([self bounds]), [CPScroller scrollerWidth])]];
{
[self setHorizontalScroller:[[CPScroller alloc] initWithFrame:CGRectMake(0.0, 0.0, MAX(_CGRectGetWidth([self bounds]), [CPScroller scrollerWidth]+1), [CPScroller scrollerWidth])]];
[[self horizontalScroller] setFrameSize:CGSizeMake(_CGRectGetWidth([self bounds]), [CPScroller scrollerWidth])];
}
[self reflectScrolledClipView:_contentView];
}
@@ -373,7 +376,10 @@
_hasVerticalScroller = shouldHaveVerticalScroller;
if (_hasVerticalScroller && !_verticalScroller)
[self setVerticalScroller:[[CPScroller alloc] initWithFrame:_CGRectMake(0.0, 0.0, [CPScroller scrollerWidth], _CGRectGetHeight([self bounds]))]];
{
[self setVerticalScroller:[[CPScroller alloc] initWithFrame:_CGRectMake(0.0, 0.0, [CPScroller scrollerWidth], MAX(_CGRectGetHeight([self bounds]), [CPScroller scrollerWidth]+1))]];
[[self verticalScroller] setFrameSize:CGSizeMake([CPScroller scrollerWidth], _CGRectGetHeight([self bounds]))];
}
[self reflectScrolledClipView:_contentView];
}
@@ -439,9 +445,7 @@
- (CPView)_headerView
{
var headerClipViewSubviews = [_headerClipView subviews];
return [headerClipViewSubviews count] ? headerClipViewSubviews[0] : nil;
return [_headerClipView documentView];
}
- (CGRect)_cornerViewFrame
@@ -664,51 +668,78 @@
*/
- (void)scrollWheel:(CPEvent)anEvent
{
var documentFrame = [[self documentView] frame],
contentBounds = [_contentView bounds];
[self _respondToScrollWheelEventWithDeltaX:[anEvent deltaX] * _horizontalLineScroll
deltaY:[anEvent deltaY] * _verticalLineScroll];
}
- (void)_respondToScrollWheelEventWithDeltaX:(float)deltaX deltaY:(float)deltaY
{
var documentFrame = [[self documentView] frame],
contentBounds = [_contentView bounds],
contentFrame = [_contentView frame],
enclosingScrollView = [self enclosingScrollView],
extraX = 0,
extraY = 0;
// We want integral bounds!
contentBounds.origin.x = ROUND(contentBounds.origin.x + [anEvent deltaX] * _horizontalLineScroll);
contentBounds.origin.y = ROUND(contentBounds.origin.y + [anEvent deltaY] * _verticalLineScroll);
contentBounds.origin.x = ROUND(contentBounds.origin.x + deltaX);
contentBounds.origin.y = ROUND(contentBounds.origin.y + deltaY);
[_contentView scrollToPoint:contentBounds.origin];
[_headerClipView scrollToPoint:CGPointMake(contentBounds.origin.x, 0.0)];
var constrainedOrigin = [_contentView constrainScrollPoint:CGPointCreateCopy(contentBounds.origin)];
extraX = ((contentBounds.origin.x - constrainedOrigin.x) / _horizontalLineScroll) * [enclosingScrollView horizontalLineScroll];
extraY = ((contentBounds.origin.y - constrainedOrigin.y) / _verticalLineScroll) * [enclosingScrollView verticalLineScroll];
[_contentView scrollToPoint:constrainedOrigin];
[_headerClipView scrollToPoint:CGPointMake(constrainedOrigin.x, 0.0)];
if (extraX || extraY)
[enclosingScrollView _respondToScrollWheelEventWithDeltaX:extraX deltaY:extraY];
}
- (void)keyDown:(CPEvent)anEvent
{
var keyCode = [anEvent keyCode],
documentFrame = [[self documentView] frame],
[self interpretKeyEvents:[anEvent]];
}
- (void)pageUp:(id)sender
{
var contentBounds = [_contentView bounds];
[self moveByOffset:CGSizeMake(0.0, -(_CGRectGetHeight(contentBounds) - _verticalPageScroll))];
}
- (void)pageDown:(id)sender
{
var contentBounds = [_contentView bounds];
[self moveByOffset:CGSizeMake(0.0, _CGRectGetHeight(contentBounds) - _verticalPageScroll)];
}
- (void)moveLeft:(id)sender
{
[self moveByOffset:CGSizeMake(-_horizontalLineScroll, 0.0)];
}
- (void)moveRight:(id)sender
{
[self moveByOffset:CGSizeMake(_horizontalLineScroll, 0.0)];
}
- (void)moveUp:(id)sender
{
[self moveByOffset:CGSizeMake(0.0, -_verticalLineScroll)];
}
- (void)moveDown:(id)sender
{
[self moveByOffset:CGSizeMake(0.0, _verticalLineScroll)];
}
- (void)moveByOffset:(CGSize)aSize
{
var documentFrame = [[self documentView] frame],
contentBounds = [_contentView bounds];
switch (keyCode)
{
case 33: /*pageup*/
contentBounds.origin.y -= _CGRectGetHeight(contentBounds) - _verticalPageScroll;
break;
case 34: /*pagedown*/
contentBounds.origin.y += _CGRectGetHeight(contentBounds) - _verticalPageScroll;
break;
case 38: /*up arrow*/
contentBounds.origin.y -= _verticalLineScroll;
break;
case 40: /*down arrow*/
contentBounds.origin.y += _verticalLineScroll;
break;
case 37: /*left arrow*/
contentBounds.origin.x -= _horizontalLineScroll;
break;
case 49: /*right arrow*/
contentBounds.origin.x += _horizontalLineScroll;
break;
default: return [super keyDown:anEvent];
}
contentBounds.origin.x += aSize.width;
contentBounds.origin.y += aSize.height;
[_contentView scrollToPoint:contentBounds.origin];
[_headerClipView scrollToPoint:CGPointMake(contentBounds.origin, 0)];
@@ -716,16 +747,18 @@
@end
var CPScrollViewContentViewKey = "CPScrollViewContentView",
CPScrollViewVLineScrollKey = "CPScrollViewVLineScroll",
CPScrollViewHLineScrollKey = "CPScrollViewHLineScroll",
CPScrollViewVPageScrollKey = "CPScrollViewVPageScroll",
CPScrollViewHPageScrollKey = "CPScrollViewHPageScroll",
CPScrollViewHasVScrollerKey = "CPScrollViewHasVScroller",
CPScrollViewHasHScrollerKey = "CPScrollViewHasHScroller",
CPScrollViewVScrollerKey = "CPScrollViewVScroller",
CPScrollViewHScrollerKey = "CPScrollViewHScroller",
CPScrollViewAutohidesScrollerKey = "CPScrollViewAutohidesScroller";
var CPScrollViewContentViewKey = "CPScrollViewContentView",
CPScrollViewHeaderClipViewKey = "CPScrollViewHeaderClipViewKey",
CPScrollViewVLineScrollKey = "CPScrollViewVLineScroll",
CPScrollViewHLineScrollKey = "CPScrollViewHLineScroll",
CPScrollViewVPageScrollKey = "CPScrollViewVPageScroll",
CPScrollViewHPageScrollKey = "CPScrollViewHPageScroll",
CPScrollViewHasVScrollerKey = "CPScrollViewHasVScroller",
CPScrollViewHasHScrollerKey = "CPScrollViewHasHScroller",
CPScrollViewVScrollerKey = "CPScrollViewVScroller",
CPScrollViewHScrollerKey = "CPScrollViewHScroller",
CPScrollViewAutohidesScrollerKey = "CPScrollViewAutohidesScroller",
CPScrollViewCornerViewKey = "CPScrollViewCornerViewKey";
@implementation CPScrollView (CPCoding)
@@ -740,14 +773,23 @@ var CPScrollViewContentViewKey = "CPScrollViewContentView",
_horizontalPageScroll = [aCoder decodeFloatForKey:CPScrollViewHPageScrollKey];
_contentView = [aCoder decodeObjectForKey:CPScrollViewContentViewKey];
_headerClipView = [aCoder decodeObjectForKey:CPScrollViewHeaderClipViewKey];
if (!_headerClipView)
{
_headerClipView = [[CPClipView alloc] init];
[self addSubview:_headerClipView];
}
_verticalScroller = [aCoder decodeObjectForKey:CPScrollViewVScrollerKey];
_horizontalScroller = [aCoder decodeObjectForKey:CPScrollViewHScrollerKey];
_hasVerticalScroller = [aCoder decodeBoolForKey:CPScrollViewHasVScrollerKey];
_hasHorizontalScroller = [aCoder decodeBoolForKey:CPScrollViewHasHScrollerKey];
_autohidesScrollers = [aCoder decodeBoolForKey:CPScrollViewAutohidesScrollerKey];
_cornerView = [aCoder decodeObjectForKey:CPScrollViewCornerViewKey];
// Do to the anything goes nature of decoding, our subviews may not exist yet, so layout at the end of the run loop when we're sure everything is in a correct state.
[[CPRunLoop currentRunLoop] performSelector:@selector(reflectScrolledClipView:) target:self argument:_contentView order:0 modes:[CPDefaultRunLoopMode]];
}
@@ -760,7 +802,8 @@ var CPScrollViewContentViewKey = "CPScrollViewContentView",
[super encodeWithCoder:aCoder];
[aCoder encodeObject:_contentView forKey:CPScrollViewContentViewKey];
[aCoder encodeObject:_headerClipView forKey:CPScrollViewHeaderClipViewKey];
[aCoder encodeObject:_verticalScroller forKey:CPScrollViewVScrollerKey];
[aCoder encodeObject:_horizontalScroller forKey:CPScrollViewHScrollerKey];
@@ -772,6 +815,8 @@ var CPScrollViewContentViewKey = "CPScrollViewContentView",
[aCoder encodeBool:_hasVerticalScroller forKey:CPScrollViewHasVScrollerKey];
[aCoder encodeBool:_hasHorizontalScroller forKey:CPScrollViewHasHScrollerKey];
[aCoder encodeBool:_autohidesScrollers forKey:CPScrollViewAutohidesScrollerKey];
[aCoder encodeObject:_cornerView forKey:CPScrollViewCornerViewKey];
}
@end
+28 -9
View File
@@ -79,7 +79,7 @@ NAMES_FOR_PARTS[CPScrollerKnob] = @"knob";
+ (id)themeAttributes
{
return [CPDictionary dictionaryWithObjects:[ nil, nil, nil, nil,
return [CPDictionary dictionaryWithObjects:[ [CPNull null], [CPNull null], [CPNull null], [CPNull null],
_CGSizeMakeZero(), _CGSizeMakeZero(), _CGInsetMakeZero(), _CGInsetMakeZero(), _CGSizeMakeZero()]
forKeys:[ @"knob-slot-color",
@"decrement-line-color",
@@ -242,14 +242,14 @@ NAMES_FOR_PARTS[CPScrollerKnob] = @"knob";
{
_usableParts = CPNoScrollerParts;
_partRects[CPScrollerDecrementPage] = _CGRectMakeZero();
_partRects[CPScrollerKnob] = _CGRectMakeZero();
_partRects[CPScrollerIncrementPage] = _CGRectMakeZero();
_partRects[CPScrollerDecrementLine] = _CGRectMakeZero();
_partRects[CPScrollerIncrementLine] = _CGRectMakeZero();
_partRects[CPScrollerDecrementPage] = CGRectMakeZero();
_partRects[CPScrollerKnob] = CGRectMakeZero();
_partRects[CPScrollerIncrementPage] = CGRectMakeZero();
_partRects[CPScrollerDecrementLine] = CGRectMakeZero();
_partRects[CPScrollerIncrementLine] = CGRectMakeZero();
// In this case, the slot is the entirety of the scroller.
_partRects[CPScrollerKnobSlot] = _CGRectMakeCopy(bounds);
_partRects[CPScrollerKnobSlot] = CGRectMakeCopy(bounds);
return;
}
@@ -279,9 +279,18 @@ NAMES_FOR_PARTS[CPScrollerKnob] = @"knob";
_partRects[CPScrollerIncrementPage] = _CGRectMake(0.0, knobLocation + knobHeight, width, height - (knobLocation + knobHeight) - effectiveIncrementLineHeight);
_partRects[CPScrollerKnobSlot] = _CGRectMake(trackInset.left, effectiveDecrementLineHeight, width - trackInset.left - trackInset.right, slotHeight);
_partRects[CPScrollerDecrementLine] = _CGRectMake(0.0, 0.0, decrementLineSize.width, decrementLineSize.height);
_partRects[CPScrollerIncrementLine] = _CGRectMake(0.0, height - incrementLineSize.height, incrementLineSize.width, incrementLineSize.height);
_partRects[CPScrollerIncrementLine] = _CGRectMake(0.0, height - incrementLineSize.height, incrementLineSize.width, incrementLineSize.height);
if(height < knobHeight + decrementLineSize.height + incrementLineSize.height + trackInset.top + trackInset.bottom)
_partRects[CPScrollerKnob] = _CGRectMakeZero();
if(height < decrementLineSize.height + incrementLineSize.height - 2)
{
_partRects[CPScrollerIncrementLine] = _CGRectMakeZero();
_partRects[CPScrollerDecrementLine] = _CGRectMakeZero();
_partRects[CPScrollerKnobSlot] = _CGRectMake(trackInset.left, 0, width - trackInset.left - trackInset.right, height);
}
}
else
{
var decrementLineSize = [self currentValueForThemeAttribute:"decrement-line-size"],
@@ -300,6 +309,16 @@ NAMES_FOR_PARTS[CPScrollerKnob] = @"knob";
_partRects[CPScrollerKnobSlot] = _CGRectMake(effectiveDecrementLineWidth, trackInset.top, slotWidth, height - trackInset.top - trackInset.bottom);
_partRects[CPScrollerDecrementLine] = _CGRectMake(0.0, 0.0, decrementLineSize.width, decrementLineSize.height);
_partRects[CPScrollerIncrementLine] = _CGRectMake(width - incrementLineSize.width, 0.0, incrementLineSize.width, incrementLineSize.height);
if(width < knobWidth + decrementLineSize.width + incrementLineSize.width + trackInset.left + trackInset.right)
_partRects[CPScrollerKnob] = _CGRectMakeZero();
if(width < decrementLineSize.width + incrementLineSize.width - 2)
{
_partRects[CPScrollerIncrementLine] = _CGRectMakeZero();
_partRects[CPScrollerDecrementLine] = _CGRectMakeZero();
_partRects[CPScrollerKnobSlot] = _CGRectMake(0.0, 0.0, width, slotHeight);
}
}
}
+203 -191
View File
@@ -24,26 +24,10 @@
#include "Platform/Platform.h"
/*!
@global
@group Menu tags
*/
CPSearchFieldRecentsTitleMenuItemTag = 1000;
/*!
@global
@group Menu tags
*/
CPSearchFieldRecentsMenuItemTag = 1001;
/*!
@global
@group Menu tags
*/
CPSearchFieldClearRecentsMenuItemTag = 1002;
/*!
@global
@group Menu tags
*/
CPSearchFieldNoRecentsMenuItemTag = 1003;
CPSearchFieldRecentsTitleMenuItemTag = 1000;
CPSearchFieldRecentsMenuItemTag = 1001;
CPSearchFieldClearRecentsMenuItemTag = 1002;
CPSearchFieldNoRecentsMenuItemTag = 1003;
var CPSearchFieldSearchImage = nil,
CPSearchFieldFindImage = nil,
@@ -79,67 +63,49 @@ var CPSearchFieldSearchImage = nil,
return;
var bundle = [CPBundle bundleForClass:self];
CPSearchFieldSearchImage = [[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPSearchField/CPSearchFieldSearch.png"]];
CPSearchFieldFindImage = [[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPSearchField/CPSearchFieldFind.png"]];
CPSearchFieldCancelImage = [[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPSearchField/CPSearchFieldCancel.png"]];
CPSearchFieldCancelPressedImage = [[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPSearchField/CPSearchFieldCancelPressed.png"]];
CPSearchFieldSearchImage = [[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPSearchField/CPSearchFieldSearch.png"] size:CGSizeMake(25, 22)];
CPSearchFieldFindImage = [[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPSearchField/CPSearchFieldFind.png"] size:CGSizeMake(25, 22)];
CPSearchFieldCancelImage = [[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPSearchField/CPSearchFieldCancel.png"] size:CGSizeMake(22, 22)];
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 != nil)
{
_recentSearches = [CPArray array];
_maximumRecents = 10;
_sendsWholeSearchString = NO;
_sendsSearchStringImmediately = NO;
[self setBezeled:YES];
[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)];
[_searchButton setBezelStyle:CPRegularSquareBezelStyle];
[_searchButton setAutoresizingMask:CPViewMaxXMargin]
[_searchButton setBordered:NO];
[_searchButton setImageScaling:CPScaleToFit];
if (self = [super initWithFrame:frame])
{
_recentSearches = [CPArray array];
_maximumRecents = 10;
_sendsWholeSearchString = NO;
_sendsSearchStringImmediately = NO;
_recentsAutosaveName = nil;
[self _initWithFrame:frame];
#if PLATFORM(DOM)
_cancelButton._DOMElement.style.cursor = "default";
_searchButton._DOMElement.style.cursor = "default";
#endif
[self setSearchMenuTemplate:[self _searchMenuTemplate]];
[self addSubview:_searchButton];
}
_cancelButton._DOMElement.style.cursor = "default";
_searchButton._DOMElement.style.cursor = "default";
#endif
}
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]];
[copy setSearchButton:[_searchButton copy]];
[copy setrecentsAutosaveName:[_recentsAutosaveName copy]];
[copy setSendsWholeSearchString:[_sendsWholeSearchString copy]];
[copy setSendsSearchStringImmediately:[_sendsSearchStringImmediately copy]];
[copy setMaximumRecents:_maximumRecents];
[copy setSearchMenutemplate:[_searchMenuTemplate copy]];
_cancelButton = [[CPButton alloc] initWithFrame:CGRectMake(frame.size.width - 27,(frame.size.height-22)/2,22,22)];
[self resetCancelButton];
[_cancelButton setHidden:YES];
[_cancelButton setAutoresizingMask:CPViewMinXMargin];
[self addSubview:_cancelButton];
return copy;
_searchButton = [[CPButton alloc] initWithFrame:CGRectMake(5,(frame.size.height-25)/2,25,25)];
[self resetSearchButton];
[self addSubview:_searchButton];
}
// Managing Buttons
@@ -172,11 +138,11 @@ var CPSearchFieldSearchImage = nil,
target,
button = [self searchButton];
if (_searchMenuTemplate == nil)
if (_searchMenuTemplate === nil)
{
searchButtonImage = CPSearchFieldSearchImage;
action = [self action];
target = [self target];
action = @selector(_sendAction:);
target = self;
}
else
{
@@ -185,7 +151,10 @@ var CPSearchFieldSearchImage = nil,
target = self;
}
[button setBordered:NO];
[button setImageScaling:CPScaleToFit];
[button setImage:searchButtonImage];
[button setAutoresizingMask:CPViewMaxXMargin];
[button setTarget:target];
[button setAction:action];
}
@@ -215,11 +184,11 @@ var CPSearchFieldSearchImage = nil,
- (void)resetCancelButton
{
var button = [self cancelButton];
[button setBezelStyle:CPRegularSquareBezelStyle];
[button setBordered:NO];
[button setImageScaling:CPScaleToFit];
[button setImage:CPSearchFieldCancelImage];
[button setAlternateImage:CPSearchFieldCancelPressedImage];
[button setAutoresizingMask:CPViewMinXMargin];
[button setTarget:self];
[button setAction:@selector(_searchFieldCancel:)];
}
@@ -255,7 +224,7 @@ var CPSearchFieldSearchImage = nil,
@param rect The current bounding rectangle for the search button.
Subclasses can override this method to return a new bounding rectangle for the search button. You might use this method to provide a custom layout for the search field control.
*/
- (CPRect)searchButtonRectForBounds:(CPRect)rect // fix
- (CPRect)searchButtonRectForBounds:(CPRect)rect
{
return [_searchButton frame];
}
@@ -290,6 +259,7 @@ var CPSearchFieldSearchImage = nil,
_searchMenuTemplate = menu;
[self resetSearchButton];
[self _loadRecentSearchList];
[self _updateSearchMenu];
}
@@ -370,10 +340,10 @@ var CPSearchFieldSearchImage = nil,
*/
- (void)setRecentSearches:(CPArray)searches
{
var max = MIN([self maximumRecents],[searches count]);
var searches = [searches subarrayWithRange:CPMakeRange(0,max)];
_recentSearches = searches;
var max = MIN([self maximumRecents], [searches count]),
searches = [searches subarrayWithRange:CPMakeRange(0, max)];
_recentSearches = searches;
[self _autosaveRecentSearchList];
}
@@ -392,12 +362,13 @@ var CPSearchFieldSearchImage = nil,
*/
- (void)setRecentsAutosaveName:(CPString)name
{
if (_recentsAutosaveName != nil)
[self _deregisterForAutosaveNotification];
_recentsAutosaveName = name;
if(name != nil)
if (_recentsAutosaveName != nil)
[self _registerForAutosaveNotification];
else
[self _deregisterForAutosaveNotification];
}
// Private methods and subclassing
@@ -425,95 +396,110 @@ var CPSearchFieldSearchImage = nil,
- (void)_updateCancelButtonVisibility
{
[_cancelButton setHidden:([[self stringValue] length] == 0)];
[_cancelButton setHidden:([[self stringValue] length] === 0)];
}
- (void)controlTextDidChange:(CPNotification)aNotification
{
if(!_sendsWholeSearchString)
if (![self sendsWholeSearchString])
{
if(_sendsSearchStringImmediately)
if ([self sendsSearchStringImmediately])
[self _sendPartialString];
else
{
[_partialStringTimer invalidate];
var timeInterval = [CPSearchField _keyboardDelayForPartialSearchString:[self stringValue]];
_partialStringTimer = [CPTimer scheduledTimerWithTimeInterval:timeInterval target:self selector:@selector(_sendPartialString) userInfo:nil repeats:NO];
_partialStringTimer = [CPTimer scheduledTimerWithTimeInterval:timeInterval
target:self
selector:@selector(_sendPartialString)
userInfo:nil
repeats:NO];
}
}
[self _updateCancelButtonVisibility];
}
- (void)_sendAction:(id)sender
{
[self sendAction:[self action] to:[self target]];
}
- (void)sendAction:(SEL)anAction to:(id)anObject
{
[super sendAction:anAction to:anObject];
[_partialStringTimer invalidate];
var current_value = [self objectValue];
if(current_value != nil && current_value != "" && ![_recentSearches containsObject:current_value])
{
[self _addStringToRecentSearches:current_value];
[self _updateSearchMenu];
}
[self _addStringToRecentSearches:[self stringValue]];
[self _updateCancelButtonVisibility];
}
- (void)_addStringToRecentSearches:(CPString)string
{
var newSearches = [CPMutableArray arrayWithArray:_recentSearches];
[newSearches addObject:string];
[self setRecentSearches:newSearches];
if (string === nil || string === @"" || [_recentSearches containsObject:string])
return;
var searches = [CPMutableArray arrayWithArray:_recentSearches];
[searches addObject:string];
[self setRecentSearches:searches];
[self _updateSearchMenu];
}
- (BOOL)trackMouse:(CPEvent)event
{
var rect;
var point;
var location = [event locationInWindow];
var rect,
point,
location = [event locationInWindow];
point = [self convertPoint:location fromView:nil];
rect = [self searchButtonRectForBounds:[self frame]];
if (CPRectContainsPoint(rect,point))
{
return [[self searchButton] trackMouse:event];
}
{
return [[self searchButton] trackMouse:event];
}
rect = [self cancelButtonRectForBounds:[self frame]];
if (CPRectContainsPoint(rect,point))
{
return [[self cancelButton] trackMouse:event];
}
{
return [[self cancelButton] trackMouse:event];
}
return [super trackMouse:event];
}
- (CPMenu)_searchMenuTemplate
- (CPMenu)_defaultSearchMenuTemplate
{
var template, item;
template = [[CPMenu alloc] init];
item = [[CPMenuItem alloc] initWithTitle:@"Recent searches" action:NULL keyEquivalent:@""];
item = [[CPMenuItem alloc] initWithTitle:@"Recent searches"
action:NULL
keyEquivalent:@""];
[item setTag:CPSearchFieldRecentsTitleMenuItemTag];
[item setEnabled:NO];
[template addItem:item];
item = [[CPMenuItem alloc] initWithTitle:@"Recent search item" action:@selector(_searchFieldSearch:) keyEquivalent:@""];
item = [[CPMenuItem alloc] initWithTitle:@"Recent search item"
action:@selector(_searchFieldSearch:)
keyEquivalent:@""];
[item setTag:CPSearchFieldRecentsMenuItemTag];
[item setTarget:self];
[template addItem:item];
item = [[CPMenuItem alloc] initWithTitle:@"Clear recent searches" action:@selector(_searchFieldClearRecents:) keyEquivalent:@""];
item = [[CPMenuItem alloc] initWithTitle:@"Clear recent searches"
action:@selector(_searchFieldClearRecents:)
keyEquivalent:@""];
[item setTag:CPSearchFieldClearRecentsMenuItemTag];
[item setTarget:self];
[template addItem:item];
item = [[CPMenuItem alloc] initWithTitle:@"No recent searches" action:NULL keyEquivalent:@""];
item = [[CPMenuItem alloc] initWithTitle:@"No recent searches"
action:NULL
keyEquivalent:@""];
[item setTag:CPSearchFieldNoRecentsMenuItemTag];
[item setEnabled:NO];
[template addItem:item];
@@ -523,41 +509,56 @@ var CPSearchFieldSearchImage = nil,
- (void)_updateSearchMenu
{
if(_searchMenuTemplate == nil)
if (_searchMenuTemplate === nil)
return;
var i, menu = [[CPMenu alloc] init];
var countOfRecents = [_recentSearches count];
var i, menu = [[CPMenu alloc] init],
countOfRecents = [_recentSearches count],
numberOfItems = [_searchMenuTemplate numberOfItems];
for (i = 0; i < [_searchMenuTemplate numberOfItems]; i++)
for (i = 0; i < numberOfItems; i++)
{
var item = [_searchMenuTemplate itemAtIndex:i];
var tag = [item tag];
var item = [_searchMenuTemplate itemAtIndex:i],
tag = [item tag];
if(tag == CPSearchFieldClearRecentsMenuItemTag && countOfRecents != 0)
if (!(tag === CPSearchFieldRecentsTitleMenuItemTag && countOfRecents === 0) &&
!(tag === CPSearchFieldClearRecentsMenuItemTag && countOfRecents === 0) &&
!(tag === CPSearchFieldNoRecentsMenuItemTag && countOfRecents != 0) &&
!(tag === CPSearchFieldRecentsMenuItemTag))
{
var separator = [CPMenuItem separatorItem];
[menu addItem:separator];
}
var itemAction, itemTarget;
switch (tag)
{
case CPSearchFieldRecentsTitleMenuItemTag : itemAction = NULL; itemTarget = NULL; break;
case CPSearchFieldClearRecentsMenuItemTag : itemAction = @selector(_searchFieldClearRecents:); itemTarget = self; break;
case CPSearchFieldNoRecentsMenuItemTag : itemAction = NULL; itemTarget = NULL; break;
default: itemAction = [item action]; itemTarget = [item target]; break;
}
if (tag === CPSearchFieldClearRecentsMenuItemTag || tag === CPSearchFieldRecentsTitleMenuItemTag)
{
var separator = [CPMenuItem separatorItem];
[separator setEnabled:NO];
[menu addItem:separator];
}
if (!(tag == CPSearchFieldRecentsTitleMenuItemTag && countOfRecents == 0) &&
!(tag == CPSearchFieldClearRecentsMenuItemTag && countOfRecents == 0) &&
!(tag == CPSearchFieldNoRecentsMenuItemTag && countOfRecents != 0) &&
!(tag == CPSearchFieldRecentsMenuItemTag))
{
var templateItem = [[CPMenuItem alloc] initWithTitle:[item title] action:[item action] keyEquivalent:[item keyEquivalent]];
[templateItem setTarget:[item target]];
[templateItem setEnabled:[item isEnabled]];
[templateItem setTag:[item tag]];
var templateItem = [[CPMenuItem alloc] initWithTitle:[item title]
action:itemAction
keyEquivalent:[item keyEquivalent]];
[templateItem setTarget:itemTarget];
[templateItem setEnabled:([item isEnabled] && itemAction != NULL)];
[templateItem setTag:tag];
[menu addItem:templateItem];
}
else if (tag == CPSearchFieldRecentsMenuItemTag)
else if (tag === CPSearchFieldRecentsMenuItemTag)
{
var j;
for (j = 0; j < countOfRecents; j++)
{
var rencentItem = [[CPMenuItem alloc] initWithTitle:[_recentSearches objectAtIndex:j] action:[item action] keyEquivalent:[item keyEquivalent]];
[rencentItem setTarget:[item target]];
var rencentItem = [[CPMenuItem alloc] initWithTitle:[_recentSearches objectAtIndex:j]
action:@selector(_searchFieldSearch:)
keyEquivalent:[item keyEquivalent]];
[rencentItem setTarget:self];
[menu addItem:rencentItem];
}
}
@@ -565,16 +566,15 @@ var CPSearchFieldSearchImage = nil,
_searchMenu = menu;
}
- (void)_showMenu:(id)sender
{
if(_searchMenu == nil || ![self isEnabled])
if (_searchMenu === nil || [_searchMenu numberOfItems] === 0 || ![self isEnabled])
return;
[super selectText:nil];
var aFrame = [[self superview] convertRect:[self frame] toView:nil],
location = CPMakePoint(aFrame.origin.x + 10, aFrame.origin.y + aFrame.size.height - 4);
var origin = CPMakePoint([self frame].origin.x, [self frame].origin.y + [self frame].size.height);
var anEvent = [CPEvent keyEventWithType:CPRightMouseDown location:origin modifierFlags:0 timestamp:[CPDate date] windowNumber:1 context:[[CPGraphicsContext currentContext] graphicsPort] characters:"" charactersIgnoringModifiers:"" isARepeat:NO keyCode:0];
var anEvent = [CPEvent mouseEventWithType:CPRightMouseDown location:location modifierFlags:0 timestamp:[[CPApp currentEvent] timestamp] windowNumber:[[self window] windowNumber] context:nil eventNumber:1 clickCount:1 pressure:0];
[CPMenu popUpContextMenu:_searchMenu withEvent:anEvent forView:sender];
}
@@ -586,16 +586,21 @@ var CPSearchFieldSearchImage = nil,
- (void)_searchFieldCancel:(id)sender
{
[self setObjectValue:nil];
[self setObjectValue:@""];
[self _sendPartialString];
[self _updateCancelButtonVisibility];
[sender setHidden:YES];
}
- (void)_searchFieldSearch:(id)sender
{
[self setObjectValue:[sender title]];
var searchString = [sender title];
if ([sender tag] != CPSearchFieldRecentsMenuItemTag)
[self _addStringToRecentSearches:searchString];
[self setObjectValue:searchString];
[self _sendPartialString];
[self _updateCancelButtonVisibility];
}
@@ -615,57 +620,51 @@ var CPSearchFieldSearchImage = nil,
[[CPNotificationCenter defaultCenter] removeObserver:self name:@"CPAutosavedRecentsChangedNotification" object:nil];
}
- (void)_updateAutosavedRecents:(id)notification
{
var name = [notification object];
var list = [self recentSearches];
[[CPUserDefaults standardUserDefaults] setObject:list forKey:name];
}
- (void)_autosaveRecentSearchList
{
if(_recentsAutosaveName != nil)
if (_recentsAutosaveName != nil)
[[CPNotificationCenter defaultCenter] postNotificationName:@"CPAutosavedRecentsChangedNotification" object:_recentsAutosaveName];
}
- (void)_updateAutosavedRecents:(id)notification
{
var list = [self recentSearches],
name = [notification object],
bundle_name = [[[CPBundle mainBundle] infoDictionary] objectForKey:"CPBundleName"],
cookie_name = [bundle_name lowercaseString] + "." + [notification object],
cookie = [[CPCookie alloc] initWithName:cookie_name],
cookie_value = [list componentsJoinedByString:@","];
[cookie setValue:cookie_value
expires:[[CPDate alloc] initWithTimeIntervalSinceNow:3600*24*365]
domain:(window.location.href.hostname)];
}
- (void)_loadRecentSearchList
{
var list,
name = [self recentsAutosaveName];
list = [[CPUserDefaults standardUserDefaults] objectForKey:name];
_recentSearches = list;
}
if (name === nil)
return;
/*
- (BOOL)trackMouse:(CPEvent)theEvent inRect:(CPRect)cellFrame ofView:(CPView)aTextView untilMouseUp:(BOOL)flag
{
}
var bundle_name = [[[CPBundle mainBundle] infoDictionary] objectForKey:"CPBundleName"],
cookie_name = [bundle_name lowercaseString] + "." + name,
- (BOOL)_trimRecentSearchList
{
}
cookie = [[CPCookie alloc] initWithName:cookie_name];
- (void)_trackButton:(CPButton)button forEvent:(CPEvent)event inRect:(CPRect)rect ofView:(id)view
{
if (cookie != nil)
{
var cookie_value = [cookie value];
list = (cookie_value != @"") ? [cookie_value componentsSeparatedByString:@","] : [CPArray array];
_recentSearches = list;
}
}
- (id)_selectOrEdit:(CPRect)rect inView:(id)view target:(id)target editor:(id)editor event:(id)event start:(int)start end:(int)end
{
}
- (void)resetCursorRect:(CPRect)rect inView:(id)view
{
}
*/
@end
var CPSearchButtonKey = @"CPSearchButtonKey",
CPCancelButtonKey = @"CPCancelButtonKey",
CPRecentsAutosaveNameKey = @"CPRecentsAutosaveNameKey",
var CPRecentsAutosaveNameKey = @"CPRecentsAutosaveNameKey",
CPSendsWholeSearchStringKey = @"CPSendsWholeSearchStringKey",
CPSendsSearchStringImmediatelyKey = @"CPSendsSearchStringImmediatelyKey",
CPMaximumRecentsKey = @"CPMaximumRecentsKey",
@@ -675,32 +674,45 @@ var CPSearchButtonKey = @"CPSearchButtonKey",
- (void)encodeWithCoder:(CPCoder)coder
{
[super encodeWithCoder:coder];
[coder encodeObject:_searchButton forKey:CPSearchButtonKey];
[coder encodeObject:_cancelButton forKey:CPCancelButtonKey];
[coder encodeObject:_recentsAutosaveName forKey:CPRecentsAutosaveNameKey];
[_searchButton removeFromSuperview];
[_cancelButton removeFromSuperview];
[super encodeWithCoder:coder];
if (_searchButton)
[self addSubview:_searchButton];
if (_cancelButton)
[self addSubview:_cancelButton];
[coder encodeBool:_sendsWholeSearchString forKey:CPSendsWholeSearchStringKey];
[coder encodeBool:_sendsSearchStringImmediately forKey:CPSendsSearchStringImmediatelyKey];
[coder encodeInt:_maximumRecents forKey:CPMaximumRecentsKey];
[coder encodeObject:_searchMenuTemplate forKey:CPSearchMenuTemplateKey];
if (_recentsAutosaveName)
[coder encodeObject:_recentsAutosaveName forKey:CPRecentsAutosaveNameKey];
if (_searchMenuTemplate)
[coder encodeObject:_searchMenuTemplate forKey:CPSearchMenuTemplateKey];
}
- (id)initWithCoder:(CPCoder)coder
{
self = [super initWithCoder:coder];
_searchButton = [coder decodeObjectForKey:CPSearchButtonKey];
_cancelButton = [coder decodeObjectForKey:CPCancelButtonKey];
_recentsAutosaveName = [coder decodeObjectForKey:CPRecentsAutosaveNameKey];
_sendsWholeSearchString = [coder decodeBoolForKey:CPSendsWholeSearchStringKey];
_sendsSearchStringImmediately = [coder decodeBoolForKey:CPSendsSearchStringImmediatelyKey];
_maximumRecents = [coder decodeIntForKey:CPMaximumRecentsKey];
[self setSearchMenuTemplate:[coder decodeObjectForKey:CPSearchMenuTemplateKey]];
[self resetCancelButton];
[self setDelegate:self];
if (self = [super initWithCoder:coder])
{
[self _initWithFrame:[self frame]];
_recentsAutosaveName = [coder decodeObjectForKey:CPRecentsAutosaveNameKey];
_sendsWholeSearchString = [coder decodeBoolForKey:CPSendsWholeSearchStringKey];
_sendsSearchStringImmediately = [coder decodeBoolForKey:CPSendsSearchStringImmediatelyKey];
_maximumRecents = [coder decodeIntForKey:CPMaximumRecentsKey];
var template = [coder decodeObjectForKey:CPSearchMenuTemplateKey];
if (template)
[self setSearchMenuTemplate:template];
[self setDelegate:self];
}
return self;
}
@end
@end
+43 -35
View File
@@ -26,20 +26,8 @@
#include "CoreGraphics/CGGeometry.h"
/*
@global
@group CPSegmentSwitchTracking
*/
CPSegmentSwitchTrackingSelectOne = 0;
/*
@global
@group CPSegmentSwitchTracking
*/
CPSegmentSwitchTrackingSelectAny = 1;
/*
@global
@group CPSegmentSwitchTracking
*/
CPSegmentSwitchTrackingMomentary = 2;
/*!
@@ -68,7 +56,7 @@ CPSegmentSwitchTrackingMomentary = 2;
+ (id)themeAttributes
{
return [CPDictionary dictionaryWithObjects:[CPCenterTextAlignment, CPCenterVerticalTextAlignment, CPImageLeft, CPScaleNone, _CGInsetMakeZero(), _CGInsetMakeZero(), nil, nil, nil, nil, 1.0, 24.0]
return [CPDictionary dictionaryWithObjects:[CPCenterTextAlignment, CPCenterVerticalTextAlignment, CPImageLeft, CPScaleNone, _CGInsetMakeZero(), _CGInsetMakeZero(), [CPNull null], [CPNull null], [CPNull null], [CPNull null], 1.0, 24.0]
forKeys:[@"alignment", @"vertical-alignment", @"image-position", @"image-scaling", @"bezel-inset", @"content-inset", @"left-segment-bezel-color", @"right-segment-bezel-color", @"center-segment-bezel-color", @"divider-bezel-color", @"divider-thickness", @"default-height"]];
}
@@ -375,7 +363,10 @@ CPSegmentSwitchTrackingMomentary = 2;
*/
- (void)setEnabled:(BOOL)isEnabled forSegment:(unsigned)aSegment
{
_segments[aSegment].enabled = isEnabled;
if (isEnabled)
_themeStates[aSegment] &= ~CPThemeStateDisabled;
else
_themeStates[aSegment] |= CPThemeStateDisabled;
[self setNeedsLayout];
[self setNeedsDisplay:YES];
@@ -388,7 +379,7 @@ CPSegmentSwitchTrackingMomentary = 2;
*/
- (BOOL)isEnabledForSegment:(unsigned)aSegment
{
return _segments[aSegment].enabled;
return !(_themeStates[aSegment] & CPThemeStateDisabled)
}
/*!
@@ -462,30 +453,28 @@ CPSegmentSwitchTrackingMomentary = 2;
}
else if (aName === "right-segment-bezel")
{
var lastSegmentLeftOffset = [self _leftOffsetForSegment:[self _indexOfLastSegment]];
return CPRectMake(lastSegmentLeftOffset + [self widthForSegment:[self _indexOfLastSegment]] - contentInset.right,
return CPRectMake(CGRectGetWidth([self bounds]) - contentInset.right,
bezelInset.top,
contentInset.right,
height);
}
else if (aName.substring(0, "segment-bezel".length) == "segment-bezel")
else if (aName.indexOf("segment-bezel") === 0)
{
var segment = parseInt(aName.substring("segment-bezel-".length), 10),
frame = CGRectCreateCopy(_segments[segment].frame);
if (segment == 0)
if (segment === 0)
{
frame.origin.x += contentInset.left;
frame.size.width -= contentInset.left;
}
if (segment == _segments.length - 1)
frame.size.width -= contentInset.right;
if (segment === _segments.length - 1)
frame.size.width = CGRectGetWidth([self bounds]) - contentInset.right - frame.origin.x;
return frame;
}
else if (aName.substring(0, "divider-bezel".length) == "divider-bezel")
else if (aName.indexOf("divider-bezel") === 0)
{
var segment = parseInt(aName.substring("divider-bezel-".length), 10),
width = [self widthForSegment:segment],
@@ -494,7 +483,7 @@ CPSegmentSwitchTrackingMomentary = 2;
return CGRectMake(left + width, bezelInset.top, thickness, height);
}
else if (aName.substring(0, "segment-content".length) == "segment-content")
else if (aName.indexOf("segment-content") === 0)
{
var segment = parseInt(aName.substring("segment-content-".length), 10);
@@ -517,8 +506,12 @@ CPSegmentSwitchTrackingMomentary = 2;
if (_segments.length <= 0)
return;
var themeState = _themeStates[0];
themeState |= _themeState & CPThemeStateDisabled;
var leftCapColor = [self valueForThemeAttribute:@"left-segment-bezel-color"
inState:_themeStates[0]];
inState:themeState];
var leftBezelView = [self layoutEphemeralSubviewNamed:@"left-segment-bezel"
positioned:CPWindowBelow
@@ -526,8 +519,12 @@ CPSegmentSwitchTrackingMomentary = 2;
[leftBezelView setBackgroundColor:leftCapColor];
var themeState = _themeStates[_themeStates.length - 1];
themeState |= _themeState & CPThemeStateDisabled;
var rightCapColor = [self valueForThemeAttribute:@"right-segment-bezel-color"
inState:_themeStates[_themeStates.length - 1]];
inState:themeState];
var rightBezelView = [self layoutEphemeralSubviewNamed:@"right-segment-bezel"
positioned:CPWindowBelow
@@ -703,7 +700,16 @@ CPSegmentSwitchTrackingMomentary = 2;
while (count--)
if (CGRectContainsPoint(_segments[count].frame, aPoint))
return count;
if (_segments.length)
{
var adjustedLastFrame = CGRectCreateCopy(_segments[_segments.length - 1].frame);
adjustedLastFrame.size.width = CGRectGetWidth([self bounds]) - adjustedLastFrame.origin.x;
if (CGRectContainsPoint(adjustedLastFrame, aPoint))
return _segments.length - 1;
}
return -1;
}
@@ -734,7 +740,7 @@ CPSegmentSwitchTrackingMomentary = 2;
if (_trackingSegment == -1)
return;
if (CGRectContainsPoint(_segments[_trackingSegment].frame, location))
if (_trackingSegment === [self testSegment:location])
{
if (_trackingMode == CPSegmentSwitchTrackingSelectAny)
{
@@ -765,10 +771,13 @@ CPSegmentSwitchTrackingMomentary = 2;
if (type == CPLeftMouseDown)
{
_trackingHighlighted = YES;
_trackingSegment = [self testSegment:location];
[self drawSegmentBezel:_trackingSegment highlight:YES];
var trackingSegment = [self testSegment:location];
if (trackingSegment > -1 && [self isEnabledForSegment:trackingSegment])
{
_trackingHighlighted = YES;
_trackingSegment = trackingSegment;
[self drawSegmentBezel:_trackingSegment highlight:YES];
}
}
else if (type == CPLeftMouseDragged)
@@ -776,12 +785,11 @@ CPSegmentSwitchTrackingMomentary = 2;
if (_trackingSegment == -1)
return;
var highlighted = CGRectContainsPoint(_segments[_trackingSegment].frame, location);
var highlighted = [self testSegment:location] === _trackingSegment;
if (highlighted != _trackingHighlighted)
{
_trackingHighlighted = highlighted;
[self drawSegmentBezel:_trackingSegment highlight:_trackingHighlighted];
}
}
+13 -1
View File
@@ -49,7 +49,7 @@ CPCircularSlider = 1;
+ (id)themeAttributes
{
return [CPDictionary dictionaryWithObjects:[nil, _CGSizeMakeZero(), 0.0, nil]
return [CPDictionary dictionaryWithObjects:[[CPNull null], _CGSizeMakeZero(), 0.0, [CPNull null]]
forKeys:[@"knob-color", @"knob-size", @"track-width", @"track-color"]];
}
@@ -396,6 +396,18 @@ CPCircularSlider = 1;
_sendActionOn &= ~CPLeftMouseDraggedMask;
}
- (void)takeValueFromKeyPath:(CPString)aKeyPath ofObjects:(CPArray)objects
{
var count = objects.length,
value = [objects[0] valueForKeyPath:aKeyPath];
[self setObjectValue:value];
while (count-- > 1)
if (value !== ([objects[count] valueForKeyPath:aKeyPath]))
return [self setFloatValue:1.0];
}
@end
var CPSliderMinValueKey = "CPSliderMinValueKey",
+25 -9
View File
@@ -45,14 +45,16 @@
CPTextField _saturationLabel;
CPTextField _brightnessLabel;
CPTextField _hexLabel;
#if PLATFORM(DOM)
DOMElement _redValue;
DOMElement _greenValue;
DOMElement _blueValue;
DOMElement _hueValue;
DOMElement _saturationValue;
DOMElement _brightnessValue;
DOMElement _hexValue;
DOMElement _hexValue;
#endif
}
- (id)initWithPickerMask:(int)mask colorPanel:(CPColorPanel)owningColorPanel
@@ -81,7 +83,8 @@
[_redSlider setTarget: self];
[_redSlider setAction: @selector(sliderChanged:)];
[_redSlider setAutoresizingMask: CPViewWidthSizable];
#if PLATFORM(DOM)
var updateFunction = function(aDOMEvent)
{
if(isNaN(this.value))
@@ -147,6 +150,7 @@
redValue._DOMElement.appendChild(_redValue);
[_contentView addSubview: redValue];
#endif
_greenLabel = [[CPTextField alloc] initWithFrame: CPRectMake(0, 58, 15, 20)];
[_greenLabel setStringValue: "G"];
@@ -159,6 +163,7 @@
[_greenSlider setAction: @selector(sliderChanged:)];
[_greenSlider setAutoresizingMask: CPViewWidthSizable];
#if PLATFORM(DOM)
//green value input box
var greenValue = [[CPView alloc] initWithFrame: CPRectMake(aFrame.size.width - 45, 58, 45, 20)];
[greenValue setAutoresizingMask: CPViewMinXMargin];
@@ -168,6 +173,7 @@
greenValue._DOMElement.appendChild(_greenValue);
[_contentView addSubview: greenValue];
#endif
_blueLabel = [[CPTextField alloc] initWithFrame: CPRectMake(0, 81, 15, 20)];
[_blueLabel setStringValue: "B"];
@@ -180,6 +186,7 @@
[_blueSlider setAction: @selector(sliderChanged:)];
[_blueSlider setAutoresizingMask: CPViewWidthSizable];
#if PLATFORM(DOM)
//blue value input box
var blueValue = [[CPView alloc] initWithFrame: CPRectMake(aFrame.size.width - 45, 81, 45, 20)];
[blueValue setAutoresizingMask: CPViewMinXMargin];
@@ -189,7 +196,7 @@
blueValue._DOMElement.appendChild(_blueValue);
[_contentView addSubview: blueValue];
#endif
_hsbLabel = [[CPTextField alloc] initWithFrame: CPRectMake(0, 120, 190, 20)];
[_hsbLabel setStringValue: "Hue, Saturation, Brightness"];
[_hsbLabel setTextColor:[CPColor blackColor]];
@@ -205,6 +212,7 @@
[_hueSlider setAction: @selector(sliderChanged:)];
[_hueSlider setAutoresizingMask: CPViewWidthSizable];
#if PLATFORM(DOM)
//red value input box
var hueValue = [[CPView alloc] initWithFrame: CPRectMake(aFrame.size.width - 45, 145, 45, 20)];
[hueValue setAutoresizingMask: CPViewMinXMargin];
@@ -214,7 +222,7 @@
hueValue._DOMElement.appendChild(_hueValue);
[_contentView addSubview: hueValue];
#endif
_saturationLabel = [[CPTextField alloc] initWithFrame: CPRectMake(0, 168, 15, 20)];
[_saturationLabel setStringValue: "S"];
[_saturationLabel setTextColor:[CPColor blackColor]];
@@ -226,6 +234,7 @@
[_saturationSlider setAction: @selector(sliderChanged:)];
[_saturationSlider setAutoresizingMask: CPViewWidthSizable];
#if PLATFORM(DOM)
//green value input box
var saturationValue = [[CPView alloc] initWithFrame: CPRectMake(aFrame.size.width - 45, 168, 45, 20)];
[saturationValue setAutoresizingMask: CPViewMinXMargin];
@@ -235,7 +244,7 @@
saturationValue._DOMElement.appendChild(_saturationValue);
[_contentView addSubview: saturationValue];
#endif
_brightnessLabel = [[CPTextField alloc] initWithFrame: CPRectMake(0, 191, 15, 20)];
[_brightnessLabel setStringValue: "B"];
[_brightnessLabel setTextColor:[CPColor blackColor]];
@@ -247,6 +256,7 @@
[_brightnessSlider setAction: @selector(sliderChanged:)];
[_brightnessSlider setAutoresizingMask: CPViewWidthSizable];
#if PLATFORM(DOM)
//blue value input box
var brightnessValue = [[CPView alloc] initWithFrame: CPRectMake(aFrame.size.width - 45, 191, 45, 20)];
[brightnessValue setAutoresizingMask: CPViewMinXMargin];
@@ -256,11 +266,12 @@
brightnessValue._DOMElement.appendChild(_brightnessValue);
[_contentView addSubview: brightnessValue];
#endif
_hexLabel = [[CPTextField alloc] initWithFrame: CPRectMake(0, 230, 30, 20)];
[_hexLabel setStringValue: "Hex"];
[_hexLabel setTextColor:[CPColor blackColor]];
#if PLATFORM(DOM)
//hex input box
_hexValue = _redValue.cloneNode(false);
_hexValue.style.top = "228px";
@@ -289,7 +300,8 @@
};
_contentView._DOMElement.appendChild(_hexValue);
#endif
[_contentView addSubview: _rgbLabel];
[_contentView addSubview: _redLabel];
[_contentView addSubview: _greenLabel];
@@ -380,7 +392,9 @@
- (void)updateHex:(CPColor)aColor
{
#if PLATFORM(DOM)
_hexValue.value = [aColor hexString];
#endif
}
- (void)updateRGBSliders:(CPColor)aColor
@@ -394,6 +408,7 @@
- (void)updateLabels
{
#if PLATFORM(DOM)
_hueValue.value = ROUND([_hueSlider floatValue]);
_saturationValue.value = ROUND([_saturationSlider floatValue]);
_brightnessValue.value = ROUND([_brightnessSlider floatValue]);
@@ -401,6 +416,7 @@
_redValue.value = ROUND([_redSlider floatValue] * 255);
_greenValue.value = ROUND([_greenSlider floatValue] * 255);
_blueValue.value = ROUND([_blueSlider floatValue] * 255);
#endif
}
- (CPImage)provideNewButtonImage
+233 -91
View File
@@ -20,6 +20,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@import "CPButtonBar.j"
@import "CPImage.j"
@import "CPView.j"
@@ -43,18 +44,20 @@ var CPSplitViewHorizontalImage = nil,
id _delegate;
BOOL _isVertical;
BOOL _isPaneSplitter;
int _currentDivider;
float _initialOffset;
CPString _originComponent;
CPString _sizeComponent;
CPArray _DOMDividerElements;
CPString _dividerImagePath;
int _drawingDivider;
BOOL _needsResizeSubviews;
CPArray _buttonBars;
}
/*
@@ -75,12 +78,13 @@ var CPSplitViewHorizontalImage = nil,
if (self = [super initWithFrame:aFrame])
{
_currentDivider = CPNotFound;
_DOMDividerElements = [];
_buttonBars = [];
[self _setVertical:YES];
}
return self;
}
@@ -98,13 +102,13 @@ var CPSplitViewHorizontalImage = nil,
{
if (![self _setVertical:shouldBeVertical])
return;
// Just re-adjust evenly.
var frame = [self frame],
dividerThickness = [self dividerThickness];
[self _postNotificationWillResize];
var eachSize = ROUND((frame.size[_sizeComponent] - dividerThickness * (_subviews.length - 1)) / _subviews.length),
index = 0,
count = _subviews.length;
@@ -115,9 +119,9 @@ var CPSplitViewHorizontalImage = nil,
else
for (; index < count; ++index)
[_subviews[index] setFrame:CGRectMake(0, ROUND((eachSize + dividerThickness) * index), frame.size.width, eachSize)];
[self setNeedsDisplay:YES];
[self _postNotificationDidResize];
}
@@ -125,13 +129,13 @@ var CPSplitViewHorizontalImage = nil,
- (BOOL)_setVertical:(BOOL)shouldBeVertical
{
var changed = (_isVertical != shouldBeVertical);
_isVertical = shouldBeVertical;
_originComponent = [self isVertical] ? "x" : "y";
_sizeComponent = [self isVertical] ? "width" : "height";
_dividerImagePath = [self isVertical] ? [CPSplitViewVerticalImage filename] : [CPSplitViewHorizontalImage filename];
return changed;
}
@@ -144,20 +148,21 @@ var CPSplitViewHorizontalImage = nil,
{
if (_isPaneSplitter == shouldBePaneSplitter)
return;
_isPaneSplitter = shouldBePaneSplitter;
#if PLATFORM(DOM)
_DOMDividerElements = [];
#endif
if(_DOMDividerElements[_drawingDivider])
[self _setupDOMDivider]
// The divider changes size when pane splitter mode is toggled, so the
// subviews need to change size too.
_needsResizeSubviews = YES;
[self setNeedsDisplay:YES];
}
- (void)didAddSubview:(CPView)aSubview
{
_needsResizeSubviews = YES;
// [self adjustSubviews];
}
- (BOOL)isSubviewCollapsed:(CPView)subview
@@ -169,9 +174,9 @@ var CPSplitViewHorizontalImage = nil,
{
var frame = [_subviews[aDivider] frame],
rect = CGRectMakeZero();
rect.size = [self frame].size;
rect.size[_sizeComponent] = [self dividerThickness];
rect.origin[_originComponent] = frame.origin[_originComponent] + frame.size[_sizeComponent];
@@ -181,19 +186,19 @@ var CPSplitViewHorizontalImage = nil,
- (CGRect)effectiveRectOfDividerAtIndex:(int)aDivider
{
var realRect = [self rectOfDividerAtIndex:aDivider];
var padding = 2;
realRect.size[_sizeComponent] += padding * 2;
realRect.origin[_originComponent] -= padding;
return realRect;
}
- (void)drawRect:(CGRect)rect
{
var count = [_subviews count] - 1;
while ((count--) > 0)
{
_drawingDivider = count;
@@ -207,29 +212,33 @@ var CPSplitViewHorizontalImage = nil,
if (!_DOMDividerElements[_drawingDivider])
{
_DOMDividerElements[_drawingDivider] = document.createElement("div");
_DOMDividerElements[_drawingDivider].style.cursor = "move";
_DOMDividerElements[_drawingDivider].style.position = "absolute";
_DOMDividerElements[_drawingDivider].style.backgroundRepeat = "repeat";
CPDOMDisplayServerAppendChild(_DOMElement, _DOMDividerElements[_drawingDivider]);
}
if (_isPaneSplitter)
{
_DOMDividerElements[_drawingDivider].style.backgroundColor = "#A5A5A5";
_DOMDividerElements[_drawingDivider].style.backgroundImage = "";
}
else
{
_DOMDividerElements[_drawingDivider].style.backgroundColor = "";
_DOMDividerElements[_drawingDivider].style.backgroundImage = "url('"+_dividerImagePath+"')";
}
}
[self _setupDOMDivider];
CPDOMDisplayServerSetStyleLeftTop(_DOMDividerElements[_drawingDivider], NULL, _CGRectGetMinX(aRect), _CGRectGetMinY(aRect));
CPDOMDisplayServerSetStyleSize(_DOMDividerElements[_drawingDivider], _CGRectGetWidth(aRect), _CGRectGetHeight(aRect));
#endif
}
- (void)_setupDOMDivider
{
if (_isPaneSplitter)
{
_DOMDividerElements[_drawingDivider].style.backgroundColor = "#A5A5A5";
_DOMDividerElements[_drawingDivider].style.backgroundImage = "";
}
else
{
_DOMDividerElements[_drawingDivider].style.backgroundColor = "";
_DOMDividerElements[_drawingDivider].style.backgroundImage = "url('"+_dividerImagePath+"')";
}
}
- (void)viewWillDraw
{
[self _adjustSubviewsWithCalculatedSize];
@@ -239,13 +248,13 @@ var CPSplitViewHorizontalImage = nil,
{
if (!_needsResizeSubviews)
return;
_needsResizeSubviews = NO;
var subviews = [self subviews],
count = subviews.length,
oldSize = CGSizeMakeZero();
if ([self isVertical])
{
oldSize.width += [self dividerThickness] * (count - 1);
@@ -256,10 +265,10 @@ var CPSplitViewHorizontalImage = nil,
oldSize.width = CGRectGetWidth([self frame]);
oldSize.height += [self dividerThickness] * (count - 1);
}
while (count--)
oldSize[_sizeComponent] += [subviews[count] frame].size[_sizeComponent];
[self resizeSubviewsWithOldSize:oldSize];
}
@@ -268,31 +277,41 @@ var CPSplitViewHorizontalImage = nil,
var frame = [_subviews[anIndex] frame],
startPosition = frame.origin[_originComponent] + frame.size[_sizeComponent],
effectiveRect = [self effectiveRectOfDividerAtIndex:anIndex],
buttonBar = _buttonBars[anIndex],
buttonBarRect = 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:)])
effectiveRect = [_delegate splitView:self effectiveRect:effectiveRect forDrawnRect:effectiveRect ofDividerAtIndex:anIndex];
if ([_delegate respondsToSelector:@selector(splitView:additionalEffectiveRectOfDividerAtIndex:)])
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
{
if ([self isHidden] || ![self hitTests] || !CGRectContainsPoint([self frame], aPoint))
return nil;
var point = [self convertPoint:aPoint fromView:[self superview]];
var count = [_subviews count] - 1;
for (var i = 0; i < count; i++)
{
if ([self cursorAtPoint:point hitDividerAtIndex:i])
return self;
}
return [super hitTest:aPoint];
}
@@ -309,12 +328,13 @@ var CPSplitViewHorizontalImage = nil,
if (_currentDivider != CPNotFound)
{
_currentDivider = CPNotFound;
[self _updateResizeCursor:anEvent];
[self _postNotificationDidResize];
}
return;
}
if (type == CPLeftMouseDown)
{
var point = [self convertPoint:[anEvent locationInWindow] fromView:nil];
@@ -331,7 +351,7 @@ var CPSplitViewHorizontalImage = nil,
if ([anEvent clickCount] == 2 &&
[_delegate respondsToSelector:@selector(splitView:canCollapseSubview:)] &&
[_delegate respondsToSelector:@selector(splitView:shouldCollapseSubview:forDoubleClickOnDividerAtIndex:)])
{
{
var minPosition = [self minPossiblePositionOfDividerAtIndex:i],
maxPosition = [self maxPossiblePositionOfDividerAtIndex:i];
@@ -363,14 +383,16 @@ var CPSplitViewHorizontalImage = nil,
if (_currentDivider === CPNotFound)
return;
}
else if (type == CPLeftMouseDragged && _currentDivider != CPNotFound)
{
var point = [self convertPoint:[anEvent locationInWindow] fromView:nil];
[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];
}
@@ -380,13 +402,81 @@ var CPSplitViewHorizontalImage = nil,
[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
{
var frame = [_subviews[dividerIndex + 1] frame];
if (dividerIndex + 1 < [_subviews count] - 1)
return frame.origin[_originComponent] + frame.size[_sizeComponent] - [self dividerThickness];
else
else
return [self frame].size[_sizeComponent] - [self dividerThickness];
}
@@ -395,17 +485,15 @@ var CPSplitViewHorizontalImage = nil,
if (dividerIndex > 0)
{
var frame = [_subviews[dividerIndex - 1] frame];
return frame.origin[_originComponent] + frame.size[_sizeComponent] + [self dividerThickness];
}
else
else
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?
if ([_delegate respondsToSelector:@selector(splitView:constrainSplitPosition:ofSubviewAt:)])
position = [_delegate splitView:self constrainSplitPosition:position ofSubviewAt:dividerIndex];
@@ -414,47 +502,56 @@ var CPSplitViewHorizontalImage = nil,
proposedMin = [self minPossiblePositionOfDividerAtIndex:dividerIndex],
actualMax = proposedMax,
actualMin = proposedMin;
if([_delegate respondsToSelector:@selector(splitView:constrainMinCoordinate:ofSubviewAt:)])
actualMin = [_delegate splitView:self constrainMinCoordinate:proposedMin ofSubviewAt:dividerIndex];
if([_delegate respondsToSelector:@selector(splitView:constrainMaxCoordinate:ofSubviewAt:)])
actualMax = [_delegate splitView:self constrainMaxCoordinate:proposedMax ofSubviewAt:dividerIndex];
var frame = [self frame],
viewA = _subviews[dividerIndex],
frameA = [viewA frame],
viewB = _subviews[dividerIndex + 1],
frameB = [viewB frame];
var viewA = _subviews[dividerIndex],
realPosition = MAX(MIN(position, actualMax), actualMin);
var realPosition = MAX(MIN(position, actualMax), actualMin);
if (position < proposedMin + (actualMin - proposedMin) / 2)
if ([_delegate respondsToSelector:@selector(splitView:canCollapseSubview:)])
if ([_delegate splitView:self canCollapseSubview:viewA])
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];
[_subviews[dividerIndex] setFrame:frameA];
frameB.size[_sizeComponent] = frameB.origin[_originComponent] + frameB.size[_sizeComponent] - realPosition - [self dividerThickness];
frameB.origin[_originComponent] = realPosition + [self dividerThickness];
[_subviews[dividerIndex + 1] setFrame:frameB];
[self setNeedsDisplay:YES];
}
- (void)setFrameSize:(CGSize)aSize
{
[self _adjustSubviewsWithCalculatedSize];
[super setFrameSize:aSize];
[self setNeedsDisplay:YES];
}
- (void)resizeSubviewsWithOldSize:(CPSize)oldSize
{
{
if ([_delegate respondsToSelector:@selector(splitView:resizeSubviewsWithOldSize:)])
{
[_delegate splitView:self resizeSubviewsWithOldSize:oldSize];
@@ -462,7 +559,7 @@ var CPSplitViewHorizontalImage = nil,
}
[self _postNotificationWillResize];
var index = 0,
count = [_subviews count],
bounds = [self bounds],
@@ -512,10 +609,8 @@ var CPSplitViewHorizontalImage = nil,
}
else if (totalSizableSpace && !isSizable)
viewFrame.size[_sizeComponent] = [view frame].size[_sizeComponent];
else
alert("SHOULD NEVER GET HERE");
bounds.origin[_originComponent] += viewFrame.size[_sizeComponent] + dividerThickness;
bounds.origin[_originComponent] += viewFrame.size[_sizeComponent] + dividerThickness;
[view setFrame:viewFrame];
}
@@ -529,7 +624,7 @@ var CPSplitViewHorizontalImage = nil,
[[CPNotificationCenter defaultCenter] removeObserver:_delegate name:CPSplitViewDidResizeSubviewsNotification object:self];
if ([_delegate respondsToSelector:@selector(splitViewWillResizeSubviews:)])
[[CPNotificationCenter defaultCenter] removeObserver:_delegate name:CPSplitViewWillResizeSubviewsNotification object:self];
_delegate = delegate;
if ([_delegate respondsToSelector:@selector(splitViewDidResizeSubviews:)])
@@ -544,6 +639,47 @@ var CPSplitViewHorizontalImage = nil,
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
{
[[CPNotificationCenter defaultCenter] postNotificationName:CPSplitViewWillResizeSubviewsNotification object:self];
@@ -558,7 +694,8 @@ var CPSplitViewHorizontalImage = nil,
var CPSplitViewDelegateKey = "CPSplitViewDelegateKey",
CPSplitViewIsVerticalKey = "CPSplitViewIsVerticalKey",
CPSplitViewIsPaneSplitterKey = "CPSplitViewIsPaneSplitterKey";
CPSplitViewIsPaneSplitterKey = "CPSplitViewIsPaneSplitterKey",
CPSplitViewButtonBarsKey = "CPSplitViewButtonBarsKey";
@implementation CPSplitView (CPCoding)
@@ -569,19 +706,21 @@ var CPSplitViewDelegateKey = "CPSplitViewDelegateKey",
- (id)initWithCoder:(CPCoder)aCoder
{
self = [super initWithCoder:aCoder];
if (self)
{
_currentDivider = CPNotFound;
_DOMDividerElements = [];
_buttonBars = [aCoder decodeObjectForKey:CPSplitViewButtonBarsKey] || [];
_delegate = [aCoder decodeObjectForKey:CPSplitViewDelegateKey];;
_delegate = [aCoder decodeObjectForKey:CPSplitViewDelegateKey];
_isPaneSplitter = [aCoder decodeBoolForKey:CPSplitViewIsPaneSplitterKey];
[self _setVertical:[aCoder decodeBoolForKey:CPSplitViewIsVerticalKey]];
}
return self;
}
@@ -592,9 +731,12 @@ var CPSplitViewDelegateKey = "CPSplitViewDelegateKey",
- (void)encodeWithCoder:(CPCoder)aCoder
{
[super encodeWithCoder:aCoder];
//FIXME how should we handle this?
//[aCoder encodeObject:_buttonBars forKey:CPSplitViewButtonBarsKey];
[aCoder encodeConditionalObject:_delegate forKey:CPSplitViewDelegateKey];
[aCoder encodeBool:_isVertical forKey:CPSplitViewIsVerticalKey];
[aCoder encodeBool:_isPaneSplitter forKey:CPSplitViewIsPaneSplitterKey];
}
+13 -1
View File
@@ -247,6 +247,8 @@ var CPTabViewDidSelectTabViewItemSelector = 1,
[_labelsView tabView:self didAddTabViewItem:aTabViewItem];
[aTabViewItem _setTabView:self];
if ([_tabViewItems count] == 1)
[self selectFirstTabViewItem:self];
@@ -263,9 +265,11 @@ var CPTabViewDidSelectTabViewItemSelector = 1,
var index = [self indexOfTabViewItem:aTabViewItem];
[_tabViewItems removeObjectIdenticalTo:aTabViewItem];
[_labelsView tabView:self didRemoveTabViewItemAtIndex:index];
[aTabViewItem _setTabView:nil];
if (_delegateSelectors & CPTabViewDidChangeNumberOfTabViewItemsSelector)
[_delegate tabViewDidChangeNumberOfTabViewItems:self];
}
@@ -492,6 +496,14 @@ var CPTabViewDidSelectTabViewItemSelector = 1,
return contentRect;
}
/*!
Returns the receiver's delegate.
*/
- (id)delegate
{
return _delegate;
}
/*!
Sets the delegate for this tab view.
@param aDelegate the tab view's delegate
+10
View File
@@ -58,6 +58,8 @@ CPPressedTab = 2;
CPView _view;
CPView _auxiliaryView;
CPTabView _tabView;
}
- (id)init
@@ -168,6 +170,14 @@ CPPressedTab = 2;
return _tabView;
}
/*!
@ignore
*/
- (void)_setTabView:(CPTabView)aView
{
_tabView = aView;
}
@end
var CPTabViewItemIdentifierKey = "CPTabViewItemIdentifierKey",
+82 -44
View File
@@ -27,22 +27,11 @@
@import "CPTableHeaderView.j"
#include "CoreGraphics/CGGeometry.h"
/*
@global
@class CPTableColumn
*/
CPTableColumnNoResizing = 0;
/*
@global
@class CPTableColumn
*/
CPTableColumnAutoresizingMask = 1;
/*
@global
@class CPTableColumn
*/
CPTableColumnUserResizingMask = 2;
CPTableColumnAutoresizingMask = 1 << 0;
CPTableColumnUserResizingMask = 1 << 1;
@implementation CPTableColumn : CPObject
{
@@ -54,12 +43,15 @@ CPTableColumnUserResizingMask = 2;
float _width;
float _minWidth;
float _maxWidth;
unsigned _resizingMask;
id _identifier;
BOOL _isEditable;
CPSortDescriptor _sortDescriptorPrototype;
BOOL _isHidden;
CPString _headerToolTip;
BOOL _disableResizingPosting @accessors(property=disableResizingPosting);
}
- (id)init
@@ -78,15 +70,27 @@ CPTableColumnUserResizingMask = 2;
_width = 100.0;
_minWidth = 10.0;
_maxWidth = 1000000.0;
_resizingMask = CPTableColumnAutoresizingMask | CPTableColumnUserResizingMask;
_disableResizingPosting = NO;
[self setIdentifier:anIdentifier];
[self setHeaderView:[CPTextField new]];
[self setDataView:[CPTextField new]];
var header = [[_CPTableColumnHeaderView alloc] initWithFrame:CGRectMakeZero()];
[self setHeaderView:header];
var textDataView = [CPTextField new];
[textDataView setLineBreakMode:CPLineBreakByTruncatingTail];
[textDataView setValue:[CPColor colorWithHexString:@"333333"] forThemeAttribute:@"text-color"];
[textDataView setValue:[CPColor whiteColor] forThemeAttribute:@"text-color" inState:CPThemeStateSelected];
[textDataView setValue:[CPFont boldSystemFontOfSize:12] forThemeAttribute:@"font" inState:CPThemeStateSelected];
[textDataView setValue:CPCenterVerticalTextAlignment forThemeAttribute:@"vertical-alignment"];
[self setDataView:textDataView];
}
return self;
}
- (void)setTableView:(CPTableView)aTableView
{
_tableView = aTableView;
@@ -117,18 +121,23 @@ CPTableColumnUserResizingMask = 2;
if (tableView)
{
var index = [[tableView tableColumns] indexOfObjectIdenticalTo:self];
// FIXME: THIS IS HORRIBLE. Don't just reload everything when a table column changes, just relayout the changed widths.
tableView._reloadAllRows = YES;
tableView._dirtyTableColumnRangeIndex = tableView._dirtyTableColumnRangeIndex < 0 ? index : MIN(index, tableView._dirtyTableColumnRangeIndex);
var index = [[tableView tableColumns] indexOfObjectIdenticalTo:self],
dirtyTableColumnRangeIndex = tableView._dirtyTableColumnRangeIndex;
if (dirtyTableColumnRangeIndex < 0)
tableView._dirtyTableColumnRangeIndex = index;
else
tableView._dirtyTableColumnRangeIndex = MIN(index, tableView._dirtyTableColumnRangeIndex);
var rows = tableView._exposedRows,
columns = [CPIndexSet indexSetWithIndexesInRange:CPMakeRange(index, [tableView._exposedColumns lastIndex] - index + 1)];
// FIXME: Would be faster with some sort of -setNeedsDisplayInColumns: that updates a dirtyTableColumnForDisplay cache; then marked columns would relayout their data views at display time.
[tableView _layoutDataViewsInRows:rows columns:columns];
[tableView tile];
[[CPNotificationCenter defaultCenter]
postNotificationName:CPTableViewColumnDidResizeNotification
object:tableView
userInfo:[CPDictionary dictionaryWithObjects:[self, oldWidth] forKeys:[@"CPTableColumn", "CPOldWidth"]]];
if (!_disableResizingPosting)
[self _postDidResizeNotificationWithOldWidth:oldWidth];
}
}
@@ -168,7 +177,7 @@ CPTableColumnUserResizingMask = 2;
_maxWidth = aMaxWidth;
var width = [self width],
newWidth = MAX(width, [self maxWidth]);
newWidth = MIN(width, [self maxWidth]);
if (width !== newWidth)
[self setWidth:newWidth];
@@ -184,7 +193,7 @@ CPTableColumnUserResizingMask = 2;
_resizingMask = aResizingMask;
}
- (float)resizingMask
- (unsigned)resizingMask
{
return _resizingMask;
}
@@ -221,6 +230,22 @@ CPTableColumnUserResizingMask = 2;
return _headerView;
}
/*!
This method set's the "prototype" view which will be used to create all table cells in this column.
It creates a snapshot of aView, using keyed archiving, which is then copied over and over for each
individual cell that is shown. As a result, changes made after calling this method won't be reflected.
Example:
[tableColumn setDataView:someView]; // snapshot taken
[[tableColumn dataView] setSomething:x]; //won't work
This doesn't work because the snapshot is taken before the new property is applied. Instead, do:
[someView setSomething:x];
[tableColumn setDataView:someView];
*/
- (void)setDataView:(CPView)aView
{
if (_dataView === aView)
@@ -256,9 +281,9 @@ CPTableColumnUserResizingMask = 2;
var dataView = [self dataViewForRow:aRowIndex],
dataViewUID = [dataView UID];
var x = [self tableView]._cachedDataViews[dataViewUID];
if (x && x.length)
return x.pop();
var x = [self tableView]._cachedDataViews[dataViewUID];
if (x && x.length)
return x.pop();
// if we haven't cached an archive of the data view, do it now
if (!_dataViewData[dataViewUID])
@@ -266,7 +291,8 @@ return x.pop();
// unarchive the data view cache
var newDataView = [CPKeyedUnarchiver unarchiveObjectWithData:_dataViewData[dataViewUID]];
newDataView.identifier = dataViewUID;
newDataView.identifier = dataViewUID;
return newDataView;
}
@@ -322,7 +348,14 @@ newDataView.identifier = dataViewUID;
- (void)setHidden:(BOOL)shouldBeHidden
{
shouldBeHidden = !!shouldBeHidden
if (_isHidden === shouldBeHidden)
return;
_isHidden = shouldBeHidden;
[[self headerView] setHidden:shouldBeHidden];
[[self tableView] _tableColumnVisibilityDidChange:self];
}
- (BOOL)isHidden
@@ -346,6 +379,14 @@ newDataView.identifier = dataViewUID;
return _headerToolTip;
}
- (void)_postDidResizeNotificationWithOldWidth:(float)oldWidth
{
[[CPNotificationCenter defaultCenter]
postNotificationName:CPTableViewColumnDidResizeNotification
object:[self tableView]
userInfo:[CPDictionary dictionaryWithObjects:[self, oldWidth] forKeys:[@"CPTableColumn", "CPOldWidth"]]];
}
@end
var CPTableColumnIdentifierKey = @"CPTableColumnIdentifierKey",
@@ -371,14 +412,11 @@ var CPTableColumnIdentifierKey = @"CPTableColumnIdentifierKey",
_maxWidth = [aCoder decodeFloatForKey:CPTableColumnMaxWidthKey];
[self setIdentifier:[aCoder decodeObjectForKey:CPTableColumnIdentifierKey]];
// [self setHeaderView:[aCoder decodeObjectForKey:CPTableColumnHeaderViewKey]];
// [self setDataView:[aCoder decodeObjectForKey:CPTableColumnDataViewKey]];
[self setHeaderView:[aCoder decodeObjectForKey:CPTableColumnHeaderViewKey]];
[self setDataView:[aCoder decodeObjectForKey:CPTableColumnDataViewKey]];
[self setHeaderView:[aCoder decodeObjectForKey:CPTableColumnHeaderViewKey]];
[self setHeaderView:[CPTextField new]];
[self setDataView:[CPTextField new]];
// _resizingMask = [aCoder decodeBoolForKey:CPTableColumnResizingMaskKey];
_resizingMask = [aCoder decodeBoolForKey:CPTableColumnResizingMaskKey];
}
return self;
@@ -392,10 +430,10 @@ var CPTableColumnIdentifierKey = @"CPTableColumnIdentifierKey",
[aCoder encodeObject:_minWidth forKey:CPTableColumnMinWidthKey];
[aCoder encodeObject:_maxWidth forKey:CPTableColumnMaxWidthKey];
// [aCoder encodeObject:_headerView forKey:CPTableColumnHeaderViewKey];
// [aCoder encodeObject:_dataView forKey:CPTableColumnDataViewKey];
[aCoder encodeObject:_headerView forKey:CPTableColumnHeaderViewKey];
[aCoder encodeObject:_dataView forKey:CPTableColumnDataViewKey];
// [aCoder encodeObject:_resizingMask forKey:CPTableColumnResizingMaskKey];
[aCoder encodeObject:_resizingMask forKey:CPTableColumnResizingMaskKey];
}
@end
+575 -68
View File
@@ -23,123 +23,630 @@
@import "CPTableColumn.j"
@import "CPTableView.j"
@import "CPView.j"
@implementation _CPTableColumnHeaderView : CPView
{
_CPImageAndTextView _textField;
}
- (void)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self)
{
[self _init];
}
return self;
}
- (void)_init
{
_textField = [[_CPImageAndTextView alloc] initWithFrame:CGRectMake(5, 1, CGRectGetWidth([self bounds]) - 10, CGRectGetHeight([self bounds]) - 1)];
[_textField setAutoresizingMask:CPViewWidthSizable|CPViewHeightSizable];
[_textField setLineBreakMode:CPLineBreakByTruncatingTail];
[_textField setTextColor: [CPColor colorWithHexString: @"333333"]];
[_textField setFont:[CPFont boldSystemFontOfSize:12.0]];
[_textField setAlignment:CPLeftTextAlignment];
[_textField setVerticalAlignment:CPCenterVerticalTextAlignment];
[_textField setTextShadowColor:[CPColor whiteColor]];
[_textField setTextShadowOffset:CGSizeMake(0,1)];
[self addSubview:_textField];
}
- (void)layoutSubviews
{
var themeState = [self themeState];
if(themeState & CPThemeStateSelected && themeState & CPThemeStateHighlighted)
[self setBackgroundColor:[CPColor colorWithPatternImage:CPAppKitImage("tableview-headerview-highlighted-pressed.png", CGSizeMake(1.0, 22.0))]];
else if (themeState & CPThemeStateSelected)
[self setBackgroundColor:[CPColor colorWithPatternImage:CPAppKitImage("tableview-headerview-highlighted.png", CGSizeMake(1.0, 22.0))]];
else if (themeState & CPThemeStateHighlighted)
[self setBackgroundColor:[CPColor colorWithPatternImage:CPAppKitImage("tableview-headerview-pressed.png", CGSizeMake(1.0, 22.0))]];
else
[self setBackgroundColor:[CPColor colorWithPatternImage:CPAppKitImage("tableview-headerview.png", CGSizeMake(1.0, 22.0))]];
}
- (void)setStringValue:(CPString)string
{
[_textField setText:string];
}
- (CPString)stringValue
{
return [_textField text];
}
- (void)textField
{
return _textField;
}
- (void)sizeToFit
{
[_textField sizeToFit];
}
- (void)setFont:(CPFont)aFont
{
[_textField setFont:aFont];
}
- (void)setValue:(id)aValue forThemeAttribute:(id)aKey
{
[_textField setValue:aValue forThemeAttribute:aKey];
}
- (void)_setIndicatorImage:(CPImage)anImage
{
if (anImage)
{
[_textField setImage:anImage];
[_textField setImagePosition:CPImageRight];
}
else
{
[_textField setImagePosition:CPNoImage];
}
}
@end
var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringValueKey",
_CPTableColumnHeaderViewFontKey = @"_CPTableColumnHeaderViewFontKey",
_CPTableColumnHeaderViewImageKey = @"_CPTableColumnHeaderViewImageKey";
@implementation _CPTableColumnHeaderView (CPCoding)
- (id)initWithCoder:(CPCoder)aCoder
{
if (self = [super initWithCoder:aCoder])
{
[self _init];
[self _setIndicatorImage:[aCoder decodeObjectForKey:_CPTableColumnHeaderViewImageKey]];
[self setStringValue:[aCoder decodeObjectForKey:_CPTableColumnHeaderViewStringValueKey]];
[self setFont:[aCoder decodeObjectForKey:_CPTableColumnHeaderViewFontKey]];
}
return self;
}
- (void)encodeWithCoder:(CPCoder)aCoder
{
[super encodeWithCoder:aCoder];
[aCoder encodeObject:[_textField text] forKey:_CPTableColumnHeaderViewStringValueKey];
[aCoder encodeObject:[_textField image] forKey:_CPTableColumnHeaderViewImageKey];
[aCoder encodeObject:[_textField font] forKey:_CPTableColumnHeaderViewFontKey];
}
@end
@implementation CPTableHeaderView : CPView
{
int _resizedColumn @accessors(readonly, property=resizedColumn);
int _draggedColumn @accessors(readonly, property=draggedColumn);
float _draggedDistance @accessors(readonly, property=draggedDistance);
CPTableView _tableView @accessors(property=tableView);
CPPoint _mouseDownLocation;
CPPoint _previousTrackingLocation;
int _activeColumn;
int _pressedColumn;
BOOL _isResizing;
BOOL _isDragging;
BOOL _isTrackingColumn;
float _columnOldWidth;
CPTableView _tableView @accessors(property=tableView);
}
- (void)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];
if (self)
{
_resizedColumn = CPNotFound;
_draggedColumn = CPNotFound;
_draggedDistance = 0.0;
}
[self _init];
return self;
}
- (int)columnAtPoint:(CGPoint)aPoint
{
if (!CGRectContainsPoint([self bounds], aPoint))
return CPNotFound;
// at this point, we can essentially ignore height, because all columns have equal heights
// and that height is equal to the height of our own bounds, which we know we are inside of
var index = 0,
count = [[_tableView tableColumns] count],
tableSpacing = [_tableView intercellSpacing],
tableColumns = [_tableView tableColumns],
leftOffset = 0,
pointX = aPoint.x;
for (; index < count; index++)
{
var width = [tableColumns[index] width] + tableSpacing.width;
if (pointX >= leftOffset && pointX < leftOffset + width)
return index;
leftOffset += width;
}
return CPNotFound;
return [_tableView columnAtPoint:CGPointMake(aPoint.x, aPoint.y)];
}
- (CGRect)headerRectOfColumn:(int)aColumnIndex
{
var headerRect = [self bounds],
columnRect = [_tableView rectOfColumn:aColumnIndex];
headerRect.origin.x = CPRectGetMinX(columnRect);
headerRect.size.width = CPRectGetWidth(columnRect);
return headerRect;
}
- (CGRect)_cursorRectForColumn:(int)column
{
if (column == -1 || !([_tableView._tableColumns[column] resizingMask] & CPTableColumnUserResizingMask))
return CGRectMakeZero();
var rect = [self headerRectOfColumn:column];
rect.origin.x = CGRectGetMaxX(rect) - 5;
rect.size.width = 20;
return rect;
}
- (void)_setPressedColumn:(CPInteger)column
{
if (_pressedColumn != -1)
{
var headerView = [_tableView._tableColumns[_pressedColumn] headerView];
[headerView unsetThemeState:CPThemeStateHighlighted];
}
if (column != -1)
{
var headerView = [_tableView._tableColumns[column] headerView];
[headerView setThemeState:CPThemeStateHighlighted];
}
_pressedColumn = column;
}
- (void)mouseDown:(CPEvent)theEvent
{
[self trackMouse:theEvent];
}
- (void)trackMouse:(CPEvent)theEvent
{
var type = [theEvent type],
currentLocation = [self convertPoint:[theEvent locationInWindow] fromView:nil];
// Take the right columns resize tracking area into account
currentLocation.x -= 5.0;
var columnIndex = [self columnAtPoint:currentLocation],
shouldResize = [self shouldResizeTableColumn:columnIndex at:CPPointMake(currentLocation.x + 5.0, currentLocation.y)];
if (type === CPLeftMouseUp)
{
if (shouldResize)
[self stopResizingTableColumn:_activeColumn at:currentLocation];
else if ([self _shouldStopTrackingTableColumn:columnIndex at:currentLocation])
{
[_tableView _didClickTableColumn:columnIndex modifierFlags:[theEvent modifierFlags]];
[self stopTrackingTableColumn:columnIndex at:currentLocation];
_isTrackingColumn = NO;
}
[self _updateResizeCursor:[CPApp currentEvent]];
_activeColumn = CPNotFound;
return;
}
if (type === CPLeftMouseDown)
{
if (columnIndex === -1)
return;
_mouseDownLocation = currentLocation;
_activeColumn = columnIndex;
[_tableView _sendDelegateDidMouseDownInHeader:columnIndex];
if (shouldResize)
[self startResizingTableColumn:columnIndex at:currentLocation];
else
{
[self startTrackingTableColumn:columnIndex at:currentLocation];
_isTrackingColumn = YES;
}
}
else if (type === CPLeftMouseDragged)
{
if (shouldResize)
[self continueResizingTableColumn:_activeColumn at:currentLocation];
else
{
if (_activeColumn === columnIndex && CPRectContainsPoint([self headerRectOfColumn:columnIndex], currentLocation))
{
if (_isTrackingColumn && _pressedColumn !== -1)
{
if (![self continueTrackingTableColumn:columnIndex at:currentLocation])
return; // Stop tracking the column, because it's being dragged
} else
[self startTrackingTableColumn:columnIndex at:currentLocation];
} else if (_isTrackingColumn && _pressedColumn !== -1)
[self stopTrackingTableColumn:_activeColumn at:currentLocation];
}
}
_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],
tableSpacing = [_tableView intercellSpacing],
bounds = [self bounds];
columnIndex = [tableColumns count];
if (aColumnIndex < 0 || aColumnIndex > [tableColumns count])
[CPException raise:"invalid" reason:"tried to get headerRectOfColumn: on invalid column"];
while (columnIndex--)
{
var tableColumn = [tableColumns objectAtIndex:columnIndex];
bounds.size.width = [tableColumns[aColumnIndex] width] + tableSpacing.width;
if (![tableColumn isHidden])
return [self headerRectOfColumn:columnIndex];
}
while (--aColumnIndex >= 0)
bounds.origin.x += [tableColumns[aColumnIndex] width] + tableSpacing.width;
return nil;
}
return bounds;
- (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
{
// never get stuck in resize cursor mode (FIXME take out when we turn on tracking rects)
if (![_tableView allowsColumnResizing] || ([theEvent type] === CPLeftMouseUp && ![[self window] acceptsMouseMovedEvents]))
{
[[CPCursor arrowCursor] set];
return;
}
var mouseLocation = [self convertPoint:[theEvent locationInWindow] fromView:nil],
mouseOverLocation = CGPointMake(mouseLocation.x - 5, mouseLocation.y),
overColumn = [self columnAtPoint:mouseOverLocation];
if (overColumn >= 0 && CGRectContainsPoint([self _cursorRectForColumn:overColumn], mouseLocation))
{
var tableColumn = [[_tableView tableColumns] objectAtIndex:overColumn],
width = [tableColumn width];
if (width == [tableColumn minWidth])
[[CPCursor resizeRightCursor] set];
else if (width == [tableColumn maxWidth])
[[CPCursor resizeLeftCursor] set];
else
[[CPCursor resizeLeftRightCursor] set];
}
else
[[CPCursor arrowCursor] set];
}
- (void)mouseEntered:(CPEvent)theEvent
{
[self _updateResizeCursor:theEvent];
}
- (void)mouseMoved:(CPEvent)theEvent
{
[self _updateResizeCursor:theEvent];
}
- (void)mouseExited:(CPEvent)theEvent
{
// FIXME: we should use CPCursor push/pop (if previous currentCursor != arrow).
[[CPCursor arrowCursor] set];
}
- (void)layoutSubviews
{
var tableColumns = [_tableView tableColumns],
count = [tableColumns count],
columnRect = [self bounds],
spacing = [_tableView intercellSpacing];
for (i = 0; i < count; ++i)
var tableColumns = [_tableView tableColumns],
count = [tableColumns count];
for (var i = 0; i < count; i++)
{
var column = [tableColumns objectAtIndex:i],
headerView = [column headerView];
columnRect.size.width = [column width] + spacing.width;
var frame = [self headerRectOfColumn:i];
frame.size.height -= 0.5;
if (i > 0)
{
frame.origin.x += 0.5;
frame.size.width -= 1;
}
[headerView setFrame:columnRect];
[headerView setFrame:frame];
columnRect.origin.x += [column width] + spacing.width;
[self addSubview:headerView];
if([headerView superview] != self)
[self addSubview:headerView];
}
}
- (void)drawRect:(CGRect)aRect
{
[[_tableView gridColor] setStroke];
if (!_tableView)
return;
var context = [[CPGraphicsContext currentContext] graphicsPort],
exposedColumnIndexes = exposedColumnIndexes = [_tableView columnIndexesInRect:aRect],
columnsArray = [];
exposedColumnIndexes = [_tableView columnIndexesInRect:aRect],
columnsArray = [],
tableColumns = [_tableView tableColumns],
exposedTableColumns = _tableView._exposedColumns,
firstIndex = [exposedTableColumns firstIndex],
exposedRange = CPMakeRange(firstIndex, [exposedTableColumns lastIndex] - firstIndex + 1);
[exposedColumnIndexes getIndexes:columnsArray maxCount:-1 inIndexRange:nil];
CGContextSetLineWidth(context, 1);
CGContextSetStrokeColor(context, [_tableView gridColor]);
[exposedColumnIndexes getIndexes:columnsArray maxCount:-1 inIndexRange:exposedRange];
var columnArrayIndex = 0,
columnArrayCount = columnsArray.length;
columnArrayCount = columnsArray.length,
columnMaxX;
for(; columnArrayIndex < columnArrayCount; ++columnArrayIndex)
CGContextBeginPath(context);
for(; columnArrayIndex < columnArrayCount; columnArrayIndex++)
{
// grab each column rect and add horizontal lines
var columnToStroke = [self headerRectOfColumn:columnArrayIndex];
// grab each column rect and add vertical lines
var columnIndex = columnsArray[columnArrayIndex],
columnToStroke = [self headerRectOfColumn:columnIndex];
CGContextBeginPath(context);
CGContextMoveToPoint(context, ROUND(columnToStroke.origin.x + columnToStroke.size.width) - 0.5, ROUND(columnToStroke.origin.y) - 0.5);
CGContextAddLineToPoint(context, ROUND(columnToStroke.origin.x + columnToStroke.size.width) - 0.5, ROUND(columnToStroke.origin.y + columnToStroke.size.height) - 0.5);
CGContextSetLineWidth(context, 1);
CGContextStrokePath(context);
columnMaxX = CGRectGetMaxX(columnToStroke);
CGContextMoveToPoint(context, ROUND(columnMaxX) + 0.5, ROUND(CGRectGetMinY(columnToStroke)));
CGContextAddLineToPoint(context, ROUND(columnMaxX) + 0.5, ROUND(CGRectGetMaxY(columnToStroke)));
}
CGContextClosePath(context);
CGContextStrokePath(context);
if (_isDragging)
{
CGContextSetFillColor(context, [CPColor grayColor]);
CGContextFillRect(context, [self headerRectOfColumn:_activeColumn])
}
}
@end
var CPTableHeaderViewTableViewKey = @"CPTableHeaderViewTableViewKey";
@implementation CPTableHeaderView (CPCoding)
- (id)initWithCoder:(CPCoder)aCoder
{
if (self = [super initWithCoder:aCoder])
{
[self _init];
_tableView = [aCoder decodeObjectForKey:CPTableHeaderViewTableViewKey];
}
return self;
}
- (void)encodeWithCoder:(CPCoder)aCoder
{
[super encodeWithCoder:aCoder];
[aCoder encodeObject:_tableView forKey:CPTableHeaderViewTableViewKey];
}
@end
+1852 -192
View File
File diff suppressed because it is too large Load Diff
+185 -31
View File
@@ -24,19 +24,12 @@
@import "CPControl.j"
@import "CPStringDrawing.j"
@import "CPCompatibility.j"
@import "_CPImageAndTextView.j"
#include "CoreGraphics/CGGeometry.h"
#include "Platform/Platform.h"
#include "Platform/DOM/CPDOMDisplayServer.h"
CPLineBreakByWordWrapping = 0;
CPLineBreakByCharWrapping = 1;
CPLineBreakByClipping = 2;
CPLineBreakByTruncatingHead = 3;
CPLineBreakByTruncatingTail = 4;
CPLineBreakByTruncatingMiddle = 5;
CPTextFieldSquareBezel = 0; /*! A textfield bezel with a squared corners. */
CPTextFieldRoundedBezel = 1; /*! A textfield bezel with rounded corners. */
@@ -55,11 +48,7 @@ var CPTextFieldDOMInputElement = nil,
CPTextFieldInputIsActive = NO,
CPTextFieldCachedSelectStartFunction = nil,
CPTextFieldCachedDragFunction = nil,
CPTextFieldBlurFunction = nil,
CPTextFieldKeyUpFunction = nil,
CPTextFieldKeyPressFunction = nil,
CPTextFieldKeyDownFunction = nil;
CPTextFieldBlurFunction = nil;
#endif
@@ -173,7 +162,7 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
+ (id)themeAttributes
{
return [CPDictionary dictionaryWithObjects:[_CGInsetMakeZero(), _CGInsetMake(2.0, 2.0, 2.0, 2.0), nil]
return [CPDictionary dictionaryWithObjects:[_CGInsetMakeZero(), _CGInsetMake(2.0, 2.0, 2.0, 2.0), [CPNull null]]
forKeys:[@"bezel-inset", @"content-inset", @"bezel-color"]];
}
@@ -246,10 +235,6 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
CPTextFieldDOMPasswordInputElement.style.outline = "none";
CPTextFieldDOMPasswordInputElement.type = "password";
CPTextFieldDOMPasswordInputElement.attachEvent("on" + CPDOMEventKeyUp, CPTextFieldKeyUpFunction);
CPTextFieldDOMPasswordInputElement.attachEvent("on" + CPDOMEventKeyDown, CPTextFieldKeyDownFunction);
CPTextFieldDOMPasswordInputElement.attachEvent("on" + CPDOMEventKeyPress, CPTextFieldKeyPressFunction);
CPTextFieldDOMPasswordInputElement.onblur = CPTextFieldBlurFunction;
}
@@ -498,6 +483,7 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
window.setTimeout(function()
{
element.focus();
[self textDidFocus:[CPNotification notificationWithName:CPTextFieldDidFocusNotification object:self userInfo:nil]];
CPTextFieldInputOwner = self;
}, 0.0);
@@ -509,14 +495,12 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
if (document.attachEvent)
{
CPTextFieldCachedSelectStartFunction = document.body.onselectstart;
CPTextFieldCachedDragFunction = document.body.ondrag;
CPTextFieldCachedSelectStartFunction = [[self window] platformWindow]._DOMBodyElement.onselectstart;
CPTextFieldCachedDragFunction = [[self window] platformWindow]._DOMBodyElement.ondrag;
document.body.ondrag = function () {};
document.body.onselectstart = function () {};
[[self window] platformWindow]._DOMBodyElement.ondrag = function () {};
[[self window] platformWindow]._DOMBodyElement.onselectstart = function () {};
}
[self textDidFocus:[CPNotification notificationWithName:CPTextFieldDidFocusNotification object:self userInfo:nil]];
#endif
return YES;
@@ -556,8 +540,8 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
CPTextFieldCachedSelectStartFunction = nil;
CPTextFieldCachedDragFunction = nil;
document.body.ondrag = CPTextFieldCachedDragFunction
document.body.onselectstart = CPTextFieldCachedSelectStartFunction
[[self window] platformWindow]._DOMBodyElement.ondrag = CPTextFieldCachedDragFunction;
[[self window] platformWindow]._DOMBodyElement.onselectstart = CPTextFieldCachedSelectStartFunction;
}
#endif
@@ -577,6 +561,14 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
return YES;
}
/*!
Text fields require panels to become key window, so this returns \c YES.
*/
- (BOOL)needsPanelToBecomeKey
{
return YES;
}
- (void)mouseDown:(CPEvent)anEvent
{
// Don't track! (ever?)
@@ -639,6 +631,9 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
else
[[self window] selectNextKeyView:self];
if ([[[self window] firstResponder] respondsToSelector:@selector(selectText:)])
[[[self window] firstResponder] selectText:self];
[[[self window] platformWindow] _propagateCurrentDOMEvent:NO];
}
else
@@ -688,9 +683,10 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
- (void)setObjectValue:(id)aValue
{
[super setObjectValue:aValue];
#if PLATFORM(DOM)
if (CPTextFieldInputOwner === self)
if (CPTextFieldInputOwner === self || [[self window] firstResponder] === self)
[self _inputElement].value = aValue;
#endif
@@ -781,11 +777,151 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
#if PLATFORM(DOM)
var element = [self _inputElement];
if (element.parentNode === _DOMElement && ([self isEditable] || [self isSelectable]))
window.setTimeout(function() { element.select(); }, 0);
if (([self isEditable] || [self isSelectable]))
{
if ([[self window] firstResponder] === self)
window.setTimeout(function() { element.select(); }, 0);
else
{
[[self window] makeFirstResponder:self];
window.setTimeout(function() {[self selectText:sender];}, 0);
}
}
#endif
}
- (void)copy:(id)sender
{
if (![CPPlatform isBrowser])
{
var selectedRange = [self selectedRange];
if (selectedRange.length < 1)
return;
var pasteboard = [CPPasteboard generalPasteboard],
stringValue = [self stringValue],
stringForPasting = [stringValue substringWithRange:selectedRange];
[pasteboard declareTypes:[CPStringPboardType] owner:nil];
[pasteboard setString:stringForPasting forType:CPStringPboardType];
}
}
- (void)cut:(id)sender
{
if (![CPPlatform isBrowser])
{
[self copy:sender];
[self deleteBackward:sender];
}
}
- (void)paste:(id)sender
{
if (![CPPlatform isBrowser])
{
var pasteboard = [CPPasteboard generalPasteboard];
if (![[pasteboard types] containsObject:CPStringPboardType])
return;
[self deleteBackward:sender];
var selectedRange = [self selectedRange],
stringValue = [self stringValue],
pasteString = [pasteboard stringForType:CPStringPboardType],
newValue = [stringValue stringByReplacingCharactersInRange:selectedRange withString:pasteString];
[self setStringValue:newValue];
[self setSelectedRange:CPMakeRange(selectedRange.location+pasteString.length, 0)];
}
}
- (CPRange)selectedRange
{
if ([[self window] firstResponder] !== self)
return CPMakeRange(0, 0);
// we wrap this in try catch because firefox will throw an exception in certain instances
try
{
var inputElement = [self _inputElement],
selectionStart = inputElement.selectionStart,
selectionEnd = inputElement.selectionEnd;
if ([selectionStart isKindOfClass:CPNumber])
return CPMakeRange(selectionStart, selectionEnd - selectionStart);
// browsers which don't support selectionStart/selectionEnd (aka IE).
var theDocument = inputElement.ownerDocument || inputElement.document,
selectionRange = theDocument.selection.createRange(),
range = inputElement.createTextRange();
if (range.inRange(selectionRange))
{
range.setEndPoint('EndToStart', selectionRange);
return CPMakeRange(range.text.length, selectionRange.text.length);
}
}
catch (e)
{
// fall through to the return
}
return CGMakeRange(0, 0);
}
- (void)setSelectedRange:(CPRange)aRange
{
if (![[self window] firstResponder] === self)
return;
var inputElement = [self _inputElement];
try
{
if ([inputElement.selectionStart isKindOfClass:CPNumber])
{
inputElement.selectionStart = aRange.location;
inputElement.selectionEnd = CPMaxRange(aRange);
}
else
{
// browsers which don't support selectionStart/selectionEnd (aka IE).
var theDocument = inputElement.ownerDocument || inputElement.document,
existingRange = theDocument.selection.createRange(),
range = inputElement.createTextRange();
if (range.inRange(existingRange))
{
range.collapse(true);
range.move('character', aRange.location);
range.moveEnd('character', aRange.length);
range.select();
}
}
}
catch (e)
{
}
}
- (void)selectAll:(id)sender
{
[self selectText:sender];
}
- (void)deleteBackward:(id)sender
{
var selectedRange = [self selectedRange],
stringValue = [self stringValue],
newValue = [stringValue stringByReplacingCharactersInRange:selectedRange withString:""];
[self setStringValue:newValue];
[self setSelectedRange:CPMakeRange(selectedRange.location, 0)];
}
#pragma mark Setting the Delegate
- (void)setDelegate:(id)aDelegate
@@ -861,7 +997,7 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
return bounds;
}
- (CGRect)bezelRectForBounds:(CFRect)bounds
- (CGRect)bezelRectForBounds:(CGRect)bounds
{
var bezelInset = [self currentValueForThemeAttribute:@"bezel-inset"];
@@ -902,6 +1038,8 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
var view = [[_CPImageAndTextView alloc] initWithFrame:_CGRectMakeZero()];
//[view setImagePosition:CPNoImage];
[view setHitTests:NO];
return view;
}
@@ -949,6 +1087,22 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
}
}
- (void)takeValueFromKeyPath:(CPString)aKeyPath ofObjects:(CPArray)objects
{
var count = objects.length,
value = [objects[0] valueForKeyPath:aKeyPath];
[self setStringValue:value];
[self setPlaceholderString:@""];
while (count-- > 1)
if (value !== [objects[count] valueForKeyPath:aKeyPath])
{
[self setPlaceholderString:@"Multiple Values"];
[self setStringValue:@""];
}
}
@end
var secureStringForString = function(aString)
+1 -1
View File
@@ -22,7 +22,7 @@
@import <Foundation/CPObject.j>
@import <Foundation/CPString.j>
@import <Foundation/CPKeyedUnarchiver.j>
var CPThemesByName = { },
CPThemeDefaultTheme = nil;
+2 -2
View File
@@ -43,7 +43,7 @@
if (self)
{
_bundle = [[CPBundle alloc] initWithPath:aURL + "/Info.plist"];
_bundle = [[CPBundle alloc] initWithPath:aURL];
}
return self;
@@ -65,7 +65,7 @@
{
var path = [aBundle pathForResource:themes[count]],
unarchiver = [[_CPThemeKeyedUnarchiver alloc]
initForReadingWithData:[CPData dataWithString:objj_files[path].contents]
initForReadingWithData:[[CPURL URLWithString:path] staticResourceData]
bundle:_bundle];
[unarchiver decodeObjectForKey:@"root"];
+207 -119
View File
@@ -58,7 +58,7 @@ var CPToolbarConfigurationsByIdentifier = nil;
/*!
@ingroup appkit
@class CPToolbar
A CPToolbar is displayed at the top of a window with multiple
buttons (tools) that offer the user quick access to features.
@@ -73,7 +73,7 @@ var CPToolbarConfigurationsByIdentifier = nil;
Called to obtain the toolbar's default item identifiers. Required.
@param toolbar the toolbar to obtain identifiers for
@return an array of default item identifiers in the order on the toolbar
@delegate - (CPToolbarItem)toolbar:(CPToolbar)toolbar itemForItemIdentifier:(CPString)itemIdentifier willBeInsertedIntoToolbar:(BOOL)flag;
Called to obtain a toolbar item. Required.
@param toolbar the toolbar the item belongs to
@@ -89,19 +89,19 @@ var CPToolbarConfigurationsByIdentifier = nil;
BOOL _showsBaselineSeparator;
BOOL _allowsUserCustomization;
BOOL _isVisible;
id _delegate;
CPArray _itemIdentifiers;
CPDictionary _identifiedItems;
CPArray _defaultItems;
CPArray _allowedItems;
CPArray _selectableItems;
CPArray _items;
CPArray _itemsSortedByVisibilityPriority;
CPView _toolbarView;
CPWindow _window;
}
@@ -111,7 +111,7 @@ var CPToolbarConfigurationsByIdentifier = nil;
{
if (self != [CPToolbar class])
return;
CPToolbarsByIdentifier = [CPDictionary dictionary];
CPToolbarConfigurationsByIdentifier = [CPDictionary dictionary];
}
@@ -120,13 +120,13 @@ var CPToolbarConfigurationsByIdentifier = nil;
+ (void)_addToolbar:(CPToolbar)toolbar forIdentifier:(CPString)identifier
{
var toolbarsSharingIdentifier = [CPToolbarsByIdentifier objectForKey:identifier];
if (!toolbarsSharingIdentifier)
{
toolbarsSharingIdentifier = []
[CPToolbarsByIdentifier setObject:toolbarsSharingIdentifier forKey:identifier];
}
[toolbarsSharingIdentifier addObject:toolbar];
}
@@ -143,17 +143,17 @@ var CPToolbarConfigurationsByIdentifier = nil;
- (id)initWithIdentifier:(CPString)anIdentifier
{
self = [super init];
if (self)
{
_items = [];
_identifier = anIdentifier;
_isVisible = YES;
[CPToolbar _addToolbar:self forIdentifier:_identifier];
}
return self;
}
@@ -163,7 +163,7 @@ var CPToolbarConfigurationsByIdentifier = nil;
*/
- (void)setDisplayMode:(CPToolbarDisplayMode)aDisplayMode
{
}
/*!
@@ -198,7 +198,7 @@ var CPToolbarConfigurationsByIdentifier = nil;
{
if (_isVisible === aFlag)
return;
_isVisible = aFlag;
[_window _noteToolbarChanged];
@@ -220,11 +220,11 @@ var CPToolbarConfigurationsByIdentifier = nil;
*/
- (void)setDelegate:(id)aDelegate
{
if (_delegate == aDelegate)
if (_delegate === aDelegate)
return;
_delegate = aDelegate;
[self _reloadToolbarItems];
}
@@ -240,57 +240,68 @@ var CPToolbarConfigurationsByIdentifier = nil;
if (!_toolbarView)
{
_toolbarView = [[_CPToolbarView alloc] initWithFrame:CPRectMake(0.0, 0.0, 1200.0, 59.0)];
[_toolbarView setToolbar:self];
[_toolbarView setAutoresizingMask:CPViewWidthSizable];
[_toolbarView reloadToolbarItems];
}
return _toolbarView;
}
/* @ignore */
- (void)_reloadToolbarItems
{
if (!_delegate)
return;
// As of OS X 10.5 (Leopard), toolbar items can be set in IB and a
// toolbar delegate is optional. Toolbar items can be combined from
// both IB and a delegate (see Apple's NSToolbar guide for IB, for more details).
var count = [_itemIdentifiers count];
if (!count)
// _defaultItems may have been loaded from Cib
_itemIdentifiers = [_defaultItems valueForKey:@"itemIdentifier"] || [];
if (_delegate)
{
_itemIdentifiers = [[_delegate toolbarDefaultItemIdentifiers:self] mutableCopy];
count = [_itemIdentifiers count];
var itemIdentifiersFromDelegate = [[_delegate toolbarDefaultItemIdentifiers:self] mutableCopy];
if (itemIdentifiersFromDelegate)
_itemIdentifiers = [_itemIdentifiers arrayByAddingObjectsFromArray:itemIdentifiersFromDelegate];
}
var index = 0,
count = [_itemIdentifiers count];
_items = [];
var index = 0;
for (; index < count; ++index)
{
var identifier = _itemIdentifiers[index],
item = [CPToolbarItem _standardItemWithItemIdentifier:identifier];
// May come from a Cib.
if (!item)
item = [_identifiedItems objectForKey:identifier];
if (!item && _delegate)
item = [_delegate toolbar:self itemForItemIdentifier:identifier willBeInsertedIntoToolbar:YES];
item = [item copy];
if (item == nil)
if (item === nil)
[CPException raise:CPInvalidArgumentException
reason:sprintf(@"_delegate %s returned nil toolbar item returned for identifier %s", _delegate, identifier)];
reason:@"Toolbar delegate " + _delegate + " returned nil toolbar item for identifier \"" + identifier + "\""];
item._toolbar = self;
[_items addObject:item];
}
// _items = [[self _defaultToolbarItems] mutableCopy];
// Store items sorted by priority. We want items to be removed first at the end of the array,
// items to be removed last at the front.
_itemsSortedByVisibilityPriority = [_items sortedArrayUsingFunction:_CPToolbarItemVisibilityPriorityCompare context:NULL];
[_toolbarView reloadToolbarItems];
}
@@ -339,9 +350,9 @@ var CPToolbarConfigurationsByIdentifier = nil;
item = [[_delegate toolbar:self itemForItemIdentifier:identifier willBeInsertedIntoToolbar:toolbar] copy];
if (!item)
[CPException raise:CPInvalidArgumentException
reason:sprintf(@"_delegate %s returned nil toolbar item returned for identifier %s", _delegate, identifier)];
reason:@"Toolbar delegate " + _delegate + " returned nil toolbar item for identifier " + identifier];
}
[_identifiedItems setObject:item forKey:identifier];
}
@@ -350,7 +361,7 @@ var CPToolbarConfigurationsByIdentifier = nil;
/* @ignore */
- (id)_itemsWithIdentifiers:(CPArray)identifiers
{
{
var items = [];
for (var i = 0; i < identifiers.length; i++)
[items addObject:[self _itemForItemIdentifier:identifiers[i] willBeInsertedIntoToolbar:NO]];
@@ -359,28 +370,62 @@ var CPToolbarConfigurationsByIdentifier = nil;
}
/* @ignore */
-(id)_defaultToolbarItems
- (id)_defaultToolbarItems
{
if (!_defaultItems)
if ([_delegate respondsToSelector:@selector(toolbarDefaultItemIdentifiers:)])
_defaultItems = [self _itemsWithIdentifiers:[_delegate toolbarDefaultItemIdentifiers:self]];
if (!_defaultItems && [_delegate respondsToSelector:@selector(toolbarDefaultItemIdentifiers:)])
{
_defaultItems = [];
var identifiers = [_delegate toolbarDefaultItemIdentifiers:self],
index = 0,
count = [identifiers count];
for (; index < count; ++index)
[_defaultItems addObject:[self _itemForItemIdentifier:identifiers[index] willBeInsertedIntoToolbar:NO]];
}
return _defaultItems;
}
/*!
Notifies the toolbar that an item has been changed. This will cause the toolbar to reload its items.
@param anItem the item that has been changed
*/
- (void)toolbarItemDidChange:(CPToolbarItem)anItem
{
if ([_identifiedItems objectForKey:[anItem itemIdentifier]])
[_identifiedItems setObject:anItem forKey:[anItem itemIdentifier]];
var index = 0,
count = [_items count];
for (; index <= count; ++index)
{
var item = _items[index];
if ([item itemIdentifier] === [anItem itemIdentifier])
{
_items[index] = anItem;
_itemsSortedByVisibilityPriority = [_items sortedArrayUsingFunction:_CPToolbarItemVisibilityPriorityCompare context:NULL];
[_toolbarView reloadToolbarItems];
}
}
}
@end
var CPToolbarIdentifierKey = "CPToolbarIdentifierKey",
CPToolbarDisplayModeKey = "CPToolbarDisplayModeKey",
CPToolbarShowsBaselineSeparatorKey = "CPToolbarShowsBaselineSeparatorKey",
CPToolbarAllowsUserCustomizationKey = "CPToolbarAllowsUserCustomizationKey",
CPToolbarIsVisibleKey = "CPToolbarIsVisibleKey",
CPToolbarDelegateKey = "CPToolbarDelegateKey",
CPToolbarIdentifiedItemsKey = "CPToolbarIdentifiedItemsKey",
CPToolbarDefaultItemsKey = "CPToolbarDefaultItemsKey",
CPToolbarAllowedItemsKey = "CPToolbarAllowedItemsKey",
CPToolbarSelectableItemsKey = "CPToolbarSelectableItemsKey";
var CPToolbarIdentifierKey = @"CPToolbarIdentifierKey",
CPToolbarDisplayModeKey = @"CPToolbarDisplayModeKey",
CPToolbarShowsBaselineSeparatorKey = @"CPToolbarShowsBaselineSeparatorKey",
CPToolbarAllowsUserCustomizationKey = @"CPToolbarAllowsUserCustomizationKey",
CPToolbarIsVisibleKey = @"CPToolbarIsVisibleKey",
CPToolbarDelegateKey = @"CPToolbarDelegateKey",
CPToolbarIdentifiedItemsKey = @"CPToolbarIdentifiedItemsKey",
CPToolbarDefaultItemsKey = @"CPToolbarDefaultItemsKey",
CPToolbarAllowedItemsKey = @"CPToolbarAllowedItemsKey",
CPToolbarSelectableItemsKey = @"CPToolbarSelectableItemsKey";
@implementation CPToolbar (CPCoding)
@@ -391,26 +436,39 @@ var CPToolbarIdentifierKey = "CPToolbarIdentifierKey",
- (id)initWithCoder:(CPCoder)aCoder
{
self = [super init];
if (self)
{
_identifier = [aCoder decodeObjectForKey:CPToolbarIdentifierKey];
_displayMode = [aCoder decodeIntForKey:CPToolbarDisplayModeKey];
_showsBaselineSeparator = [aCoder decodeBoolForKey:CPToolbarShowsBaselineSeparatorKey];
_allowsUserCustomization = [aCoder decodeBoolForKey:CPToolbarAllowsUserCustomizationKey];
_isVisible = [aCoder decodeBoolForKey:CPToolbarIsVisibleKey];
_identifiedItems = [aCoder decodeObjectForKey:CPToolbarIdentifiedItemsKey];
_defaultItems = [aCoder decodeObjectForKey:CPToolbarDefaultItemsKey];
_allowedItems = [aCoder decodeObjectForKey:CPToolbarAllowedItemsKey];
_selectableItems = [aCoder decodeObjectForKey:CPToolbarSelectableItemsKey];
_identifier = [aCoder decodeObjectForKey:CPToolbarIdentifierKey];
_displayMode = [aCoder decodeIntForKey:CPToolbarDisplayModeKey];
_showsBaselineSeparator = [aCoder decodeBoolForKey:CPToolbarShowsBaselineSeparatorKey];
_allowsUserCustomization = [aCoder decodeBoolForKey:CPToolbarAllowsUserCustomizationKey];
_isVisible = [aCoder decodeBoolForKey:CPToolbarIsVisibleKey];
_identifiedItems = [aCoder decodeObjectForKey:CPToolbarIdentifiedItemsKey];
_defaultItems = [aCoder decodeObjectForKey:CPToolbarDefaultItemsKey];
_allowedItems = [aCoder decodeObjectForKey:CPToolbarAllowedItemsKey];
_selectableItems = [aCoder decodeObjectForKey:CPToolbarSelectableItemsKey];
[[_identifiedItems allValues] makeObjectsPerformSelector:@selector(_setToolbar:) withObject:self];
_items = [];
[CPToolbar _addToolbar:self forIdentifier:_identifier];
// This won't come from a Cib, but can come from manual encoding.
[self setDelegate:[aCoder decodeObjectForKey:CPToolbarDelegateKey]];
// Because we don't know if a delegate will be set later (it is optional
// as of OS X 10.5), we need to call -_reloadToolbarItems here.
// In order to load any toolbar items that may have been configured in the
// Cib. Unfortunatelly this means that if there is a delegate
// specified, it will be read later and the resulting call to -setDelegate:
// will cause -_reloadToolbarItems] to run again :-(
// FIXME: Can we make this better?
[self _reloadToolbarItems];
}
return self;
}
@@ -420,18 +478,18 @@ var CPToolbarIdentifierKey = "CPToolbarIdentifierKey",
*/
- (void)encodeWithCoder:(CPCoder)aCoder
{
[aCoder encodeObject:_identifier forKey:CPToolbarIdentifierKey];
[aCoder encodeInt:_displayMode forKey:CPToolbarDisplayModeKey];
[aCoder encodeBool:_showsBaselineSeparator forKey:CPToolbarShowsBaselineSeparatorKey];
[aCoder encodeObject:_identifier forKey:CPToolbarIdentifierKey];
[aCoder encodeInt:_displayMode forKey:CPToolbarDisplayModeKey];
[aCoder encodeBool:_showsBaselineSeparator forKey:CPToolbarShowsBaselineSeparatorKey];
[aCoder encodeBool:_allowsUserCustomization forKey:CPToolbarAllowsUserCustomizationKey];
[aCoder encodeBool:_isVisible forKey:CPToolbarIsVisibleKey];
[aCoder encodeObject:_identifiedItems forKey:CPToolbarIdentifiedItemsKey];
[aCoder encodeObject:_defaultItems forKey:CPToolbarDefaultItemsKey];
[aCoder encodeObject:_allowedItems forKey:CPToolbarAllowedItemsKey];
[aCoder encodeObject:_selectableItems forKey:CPToolbarSelectableItemsKey];
[aCoder encodeConditionalObject:_delegate forKey:CPToolbarDelegateKey];
[aCoder encodeBool:_isVisible forKey:CPToolbarIsVisibleKey];
[aCoder encodeObject:_identifiedItems forKey:CPToolbarIdentifiedItemsKey];
[aCoder encodeObject:_defaultItems forKey:CPToolbarDefaultItemsKey];
[aCoder encodeObject:_allowedItems forKey:CPToolbarAllowedItemsKey];
[aCoder encodeObject:_selectableItems forKey:CPToolbarSelectableItemsKey];
[aCoder encodeConditionalObject:_delegate forKey:CPToolbarDelegateKey];
}
@end
@@ -454,10 +512,10 @@ var _CPToolbarItemInfoMake = function(anIndex, aView, aLabel, aMinWidth)
@implementation _CPToolbarView : CPView
{
CPToolbar _toolbar;
CPIndexSet _flexibleWidthIndexes;
CPIndexSet _visibleFlexibleWidthIndexes;
CPDictionary _itemInfos;
JSObject _viewsForToolbarItems;
@@ -467,7 +525,7 @@ var _CPToolbarItemInfoMake = function(anIndex, aView, aLabel, aMinWidth)
CPPopUpButton _additionalItemsButton;
CPColor _labelColor;
CPColor _labelShadowColor;
float _minWidth;
BOOL _FIXME_isHUD;
@@ -475,11 +533,11 @@ var _CPToolbarItemInfoMake = function(anIndex, aView, aLabel, aMinWidth)
+ (void)initialize
{
if (self != [_CPToolbarView class])
if (self !== [_CPToolbarView class])
return;
var bundle = [CPBundle bundleForClass:self];
_CPToolbarViewExtraItemsImage = [[CPImage alloc] initWithContentsOfFile: [bundle pathForResource:"_CPToolbarView/_CPToolbarViewExtraItemsImage.png"] size: CPSizeMake(10.0, 15.0)];
_CPToolbarViewExtraItemsAlternateImage = [[CPImage alloc] initWithContentsOfFile: [bundle pathForResource:"_CPToolbarView/_CPToolbarViewExtraItemsAlternateImage.png"] size:CGSizeMake(10.0, 15.0)];
@@ -488,23 +546,23 @@ var _CPToolbarItemInfoMake = function(anIndex, aView, aLabel, aMinWidth)
- (id)initWithFrame:(CGRect)aFrame
{
self = [super initWithFrame:aFrame];
if (self)
{
_minWidth = 0;
_labelColor = [CPColor blackColor];
_labelShadowColor = [CPColor colorWithWhite:1.0 alpha:0.75];
_additionalItemsButton = [[CPPopUpButton alloc] initWithFrame:CGRectMake(0.0, 0.0, 10.0, 15.0) pullsDown:YES];
[_additionalItemsButton setBordered:NO];
[_additionalItemsButton setImagePosition:CPImageOnly];
[[_additionalItemsButton menu] setShowsStateColumn:NO];
[_additionalItemsButton setAlternateImage:_CPToolbarViewExtraItemsAlternateImage];
}
return self;
}
@@ -551,17 +609,17 @@ var _CPToolbarItemInfoMake = function(anIndex, aView, aLabel, aMinWidth)
minWidth = _minWidth,
// FIXME: This should be a CPSet.
invisibleItemsSortedByPriority = [];
_visibleItems = items;
// We only have hidden items if our actual width is smaller than our
// We only have hidden items if our actual width is smaller than our
// minimum width for hiding items.
if (itemsWidth < minWidth)
{
itemsWidth -= TOOLBAR_EXTRA_ITEMS_WIDTH;
_visibleItems = [_visibleItems copy];
var itemsSortedByVisibilityPriority = [_toolbar itemsSortedByVisibilityPriority],
count = itemsSortedByVisibilityPriority.length;
@@ -620,18 +678,18 @@ var _CPToolbarItemInfoMake = function(anIndex, aView, aLabel, aMinWidth)
[view setHidden:NO];
}
var remainingSpace = itemsWidth - minWidth,
proportionate = 0.0;
// Continue to distribute space proportionately while we have it,
// and there are flexible items left that want it. (Those with max
// Continue to distribute space proportionately while we have it,
// and there are flexible items left that want it. (Those with max
// widths may eventually not want it anymore).
while (remainingSpace && [flexibleItemIndexes count])
{
// Divy out the space.
proportionate += remainingSpace / [flexibleItemIndexes count];
// Reset the remaining space to 0
remainingSpace = 0.0;
@@ -654,7 +712,7 @@ var _CPToolbarItemInfoMake = function(anIndex, aView, aLabel, aMinWidth)
[view setFrameSize:CGSizeMake(constrainedWidth, height)];
}
}
// Now that all the visible items are the correct width, give them their final frames.
var index = 0,
count = _visibleItems.length,
@@ -676,9 +734,9 @@ var _CPToolbarItemInfoMake = function(anIndex, aView, aLabel, aMinWidth)
{
var index = 0,
count = [items count];
_invisibleItems = [];
for (; index < count; ++index)
{
var item = items[index];
@@ -732,18 +790,17 @@ var _CPToolbarItemInfoMake = function(anIndex, aView, aLabel, aMinWidth)
hasNonSeparatorItem = YES;
[_additionalItemsButton addItemWithTitle:[item label]];
var menuItem = [_additionalItemsButton itemArray][index + 1];
[menuItem setImage:[item image]];
[menuItem setTarget:[item target]];
[menuItem setAction:[item action]];
}
}
else
[_additionalItemsButton removeFromSuperview];
}
- (void)reloadToolbarItems
@@ -751,14 +808,14 @@ var _CPToolbarItemInfoMake = function(anIndex, aView, aLabel, aMinWidth)
// Get rid of all our current subviews.
var subviews = [self subviews],
count = subviews.length;
while (count--)
[subviews[count] removeFromSuperview];
// Populate with new subviews.
var items = [_toolbar items],
index = 0;
count = items.length;
_minWidth = TOOLBAR_ITEM_MARGIN;
@@ -774,7 +831,7 @@ var _CPToolbarItemInfoMake = function(anIndex, aView, aLabel, aMinWidth)
_minWidth += [view minSize].width + TOOLBAR_ITEM_MARGIN;
}
[self tile];
}
@@ -785,13 +842,13 @@ var _CPToolbarItemVisibilityPriorityCompare = function(lhs, rhs)
{
var lhsVisibilityPriority = [lhs visibilityPriority],
rhsVisibilityPriority = [rhs visibilityPriority];
if (lhsVisibilityPriority == rhsVisibilityPriority)
return CPOrderedSame;
if (lhsVisibilityPriority > rhsVisibilityPriority)
return CPOrderedAscending;
return CPOrderedDescending;
}
@@ -837,7 +894,16 @@ var TOP_MARGIN = 5.0,
_toolbar = aToolbar;
[_toolbarItem addObserver:self forKeyPath:"enabled" options:0 context:NULL];
var keyPaths = [@"label", @"image", @"alternateImage", @"minSize", @"maxSize", @"target", @"action", @"enabled"],
index = 0,
count = [keyPaths count];
for (; index < count; ++index)
[_toolbarItem
addObserver:self
forKeyPath:keyPaths[index]
options:0
context:NULL];
}
return self;
@@ -918,6 +984,8 @@ var TOP_MARGIN = 5.0,
[_labelField setStringValue:[_toolbarItem label]];
[_labelField sizeToFit]; // FIXME
[self setEnabled:[_toolbarItem isEnabled]];
_labelSize = [_labelField frame].size;
_minSize = CGSizeMake(MAX(_labelSize.width, minSize.width), _labelSize.height + minSize.height + LABEL_MARGIN + TOP_MARGIN);
@@ -957,7 +1025,14 @@ var TOP_MARGIN = 5.0,
- (void)mouseDown:(CPEvent)anEvent
{
if ([_toolbarItem view])
return;
return [[self nextResponder] mouseDown:anEvent];
var identifier = [_toolbarItem itemIdentifier];
if (identifier === CPToolbarSpaceItemIdentifier ||
identifier === CPToolbarFlexibleSpaceItemIdentifier ||
identifier === CPToolbarSeparatorItemIdentifier)
return [[self nextResponder] mouseDown:anEvent];
[super mouseDown:anEvent];
}
@@ -1020,14 +1095,27 @@ var TOP_MARGIN = 5.0,
[_labelField setTextShadowColor:[self FIXME_labelShadowColor]];
}
- (void)sendAction:(SEL)anAction to:(id)aSender
{
[CPApp sendAction:anAction to:aSender from:_toolbarItem];
}
- (void)observeValueForKeyPath:(CPString)aKeyPath
ofObject:(id)anObject
change:(CPDictionary)aChange
context:(id)aContext
{
// FIXME: Not clear if -synchronizeWindowTitleWithDocumentName is the best way to go.
if (aKeyPath === "enabled")
[self setEnabled:[anObject isEnabled]];
else if (aKeyPath === @"target")
[self setTarget:[anObject target]];
else if (aKeyPath === @"action")
[self setAction:[anObject action]];
else
[self updateFromItem];
}
@end
+130 -60
View File
@@ -26,35 +26,18 @@
@import <AppKit/CPImage.j>
@import <AppKit/CPView.j>
/*
@global
@class CPToolbarItem
*/
CPToolbarItemVisibilityPriorityStandard = 0;
/*
@global
@class CPToolbarItem
*/
CPToolbarItemVisibilityPriorityLow = -1000;
/*
@global
@class CPToolbarItem
*/
CPToolbarItemVisibilityPriorityHigh = 1000;
/*
@global
@class CPToolbarItem
*/
CPToolbarItemVisibilityPriorityUser = 2000;
CPToolbarSeparatorItemIdentifier = @"CPToolbarSeparatorItemIdentifier";
CPToolbarSpaceItemIdentifier = @"CPToolbarSpaceItemIdentifier";
CPToolbarFlexibleSpaceItemIdentifier = @"CPToolbarFlexibleSpaceItemIdentifier";
CPToolbarShowColorsItemIdentifier = @"CPToolbarShowColorsItemIdentifier";
CPToolbarShowFontsItemIdentifier = @"CPToolbarShowFontsItemIdentifier";
CPToolbarCustomizeToolbarItemIdentifier = @"CPToolbarCustomizeToolbarItemIdentifier";
CPToolbarPrintItemIdentifier = @"CPToolbarPrintItemIdentifier";
CPToolbarSeparatorItemIdentifier = @"CPToolbarSeparatorItem";
CPToolbarSpaceItemIdentifier = @"CPToolbarSpaceItem";
CPToolbarFlexibleSpaceItemIdentifier = @"CPToolbarFlexibleSpaceItem";
CPToolbarShowColorsItemIdentifier = @"CPToolbarShowColorsItem";
CPToolbarShowFontsItemIdentifier = @"CPToolbarShowFontsItem";
CPToolbarCustomizeToolbarItemIdentifier = @"CPToolbarCustomizeToolbarItem";
CPToolbarPrintItemIdentifier = @"CPToolbarPrintItem";
/*!
@ingroup appkit
@@ -65,9 +48,9 @@ CPToolbarPrintItemIdentifier = @"CPToolbarPrintItemIdentifier";
@implementation CPToolbarItem : CPObject
{
CPString _itemIdentifier;
CPToolbar _toolbar;
CPString _label;
CPString _paletteLabel;
CPString _toolTip;
@@ -77,12 +60,12 @@ CPToolbarPrintItemIdentifier = @"CPToolbarPrintItemIdentifier";
BOOL _isEnabled;
CPImage _image;
CPImage _alternateImage;
CPView _view;
CGSize _minSize;
CGSize _maxSize;
int _visibilityPriority;
BOOL _autovalidates;
@@ -114,6 +97,7 @@ CPToolbarPrintItemIdentifier = @"CPToolbarPrintItemIdentifier";
_maxSize = CGSizeMakeZero();
_visibilityPriority = CPToolbarItemVisibilityPriorityStandard;
_autovalidates = YES;
}
return self;
@@ -136,6 +120,12 @@ CPToolbarPrintItemIdentifier = @"CPToolbarPrintItemIdentifier";
return _toolbar;
}
/* @ignore */
- (void)_setToolbar:(CPToolbar)aToolbar
{
_toolbar = aToolbar;
}
/*!
Returns the item's label
*/
@@ -190,7 +180,7 @@ CPToolbarPrintItemIdentifier = @"CPToolbarPrintItemIdentifier";
- (void)setToolTip:(CPString)aToolTip
{
if ([_view respondsToSelector:@selector(setToolTip:)])
[view setToolTip:aToolTip];
[_view setToolTip:aToolTip];
_toolTip = aToolTip;
}
@@ -315,8 +305,8 @@ CPToolbarPrintItemIdentifier = @"CPToolbarPrintItemIdentifier";
if (!_image)
return;
if (_minSize.width == 0 && _minSize.height == 0 &&
_maxSize.width == 0 && _maxSize.height == 0)
if (_minSize.width === 0 && _minSize.height === 0 &&
_maxSize.width === 0 && _maxSize.height === 0)
{
var imageSize = [_image size];
@@ -395,6 +385,9 @@ CPToolbarPrintItemIdentifier = @"CPToolbarPrintItemIdentifier";
*/
- (void)setMinSize:(CGSize)aMinSize
{
if(!aMinSize.height || !aMinSize.width)
return;
_minSize = CGSizeMakeCopy(aMinSize);
// Try to provide some sanity: Make maxSize >= minSize
@@ -415,6 +408,9 @@ CPToolbarPrintItemIdentifier = @"CPToolbarPrintItemIdentifier";
*/
- (void)setMaxSize:(CGSize)aMaxSize
{
if(!aMaxSize.height || !aMaxSize.width)
return;
_maxSize = CGSizeMakeCopy(aMaxSize);
// Try to provide some sanity: Make minSize <= maxSize
@@ -453,6 +449,9 @@ CPToolbarItemVisibilityPriorityUser
- (void)validate
{
var action = [self action],
target = [self target];
// View items do not do any target-action analysis.
if (_view)
{
@@ -462,13 +461,9 @@ CPToolbarItemVisibilityPriorityUser
return;
}
var action = [self action];
if (!action)
return [self setEnabled:NO];
var target = [self target];
if (target && ![target respondsToSelector:action])
return [self setEnabled:NO];
@@ -495,15 +490,97 @@ CPToolbarItemVisibilityPriorityUser
@end
var CPToolbarItemItemIdentifierKey = @"CPToolbarItemItemIdentifierKey",
CPToolbarItemLabelKey = @"CPToolbarItemLabelKey",
CPToolbarItemPaletteLabelKey = @"CPToolbarItemPaletteLabelKey",
CPToolbarItemToolTipKey = @"CPToolbarItemToolTipKey",
CPToolbarItemTagKey = @"CPToolbarItemTagKey",
CPToolbarItemTargetKey = @"CPToolbarItemTargetKey",
CPToolbarItemActionKey = @"CPToolbarItemActionKey",
CPToolbarItemEnabledKey = @"CPToolbarItemEnabledKey",
CPToolbarItemImageKey = @"CPToolbarItemImageKey",
CPToolbarItemAlternateImageKey = @"CPToolbarItemAlternateImageKey",
CPToolbarItemViewKey = @"CPToolbarItemViewKey",
CPToolbarItemMinSizeKey = @"CPToolbarItemMinSizeKey",
CPToolbarItemMaxSizeKey = @"CPToolbarItemMaxSizeKey",
CPToolbarItemVisibilityPriorityKey = @"CPToolbarItemVisibilityPriorityKey",
CPToolbarItemAutovalidatesKey = @"CPToolbarItemAutovalidatesKey";
@implementation CPToolbarItem (CPCoding)
- (id)initWithCoder:(CPCoder)aCoder
{
self = [super init];
if (self)
{
_itemIdentifier = [aCoder decodeObjectForKey:CPToolbarItemItemIdentifierKey];
_minSize = [aCoder decodeSizeForKey:CPToolbarItemMinSizeKey];
_maxSize = [aCoder decodeSizeForKey:CPToolbarItemMaxSizeKey];
[self setLabel:[aCoder decodeObjectForKey:CPToolbarItemLabelKey]];
[self setPaletteLabel:[aCoder decodeObjectForKey:CPToolbarItemPaletteLabelKey]];
[self setToolTip:[aCoder decodeObjectForKey:CPToolbarItemToolTipKey]];
[self setTag:[aCoder decodeObjectForKey:CPToolbarItemTagKey]];
[self setTarget:[aCoder decodeObjectForKey:CPToolbarItemTargetKey]];
[self setAction:CPSelectorFromString([aCoder decodeObjectForKey:CPToolbarItemActionKey])];
[self setEnabled:[aCoder decodeBoolForKey:CPToolbarItemEnabledKey]];
[self setImage:[aCoder decodeObjectForKey:CPToolbarItemImageKey]];
[self setAlternateImage:[aCoder decodeObjectForKey:CPToolbarItemAlternateImageKey]];
[self setView:[aCoder decodeObjectForKey:CPToolbarItemViewKey]];
[self setVisibilityPriority:[aCoder decodeIntForKey:CPToolbarItemVisibilityPriorityKey]];
[self setAutovalidates:[aCoder decodeBoolForKey:CPToolbarItemAutovalidatesKey]];
}
return self;
}
- (void)encodeWithCoder:(CPCoder)aCoder
{
[aCoder encodeObject:_itemIdentifier forKey:CPToolbarItemItemIdentifierKey];
[aCoder encodeObject:[self label] forKey:CPToolbarItemLabelKey];
[aCoder encodeObject:[self paletteLabel] forKey:CPToolbarItemPaletteLabelKey];
[aCoder encodeObject:[self toolTip] forKey:CPToolbarItemToolTipKey];
[aCoder encodeObject:[self tag] forKey:CPToolbarItemTagKey];
[aCoder encodeObject:[self target] forKey:CPToolbarItemTargetKey];
[aCoder encodeObject:[self action] forKey:CPToolbarItemActionKey];
[aCoder encodeObject:[self isEnabled] forKey:CPToolbarItemEnabledKey];
[aCoder encodeObject:[self image] forKey:CPToolbarItemImageKey];
[aCoder encodeObject:[self alternateImage] forKey:CPToolbarItemAlternateImageKey];
[aCoder encodeObject:[self view] forKey:CPToolbarItemViewKey];
[aCoder encodeSize:[self minSize] forKey:CPToolbarItemMinSizeKey];
[aCoder encodeSize:[self maxSize] forKey:CPToolbarItemMaxSizeKey];
[aCoder encodeObject:[self visibilityPriority] forKey:CPToolbarItemVisibilityPriorityKey];
[aCoder encodeBool:[self autovalidates] forKey:CPToolbarItemAutovalidatesKey];
}
@end
@implementation CPToolbarItem (CPCopying)
- (id)copy
{
var copy = [[[self class] alloc] initWithItemIdentifier:_itemIdentifier];
if (_view)
[copy setView:[CPKeyedUnarchiver unarchiveObjectWithData:[CPKeyedArchiver archivedDataWithRootObject:_view]]];
[copy _setToolbar:_toolbar];
[copy setLabel:_label];
[copy setPaletteLabel:_paletteLabel];
[copy setToolTip:[self toolTip]];
@@ -511,7 +588,7 @@ CPToolbarItemVisibilityPriorityUser
[copy setTag:[self tag]];
[copy setTarget:[self target]];
[copy setAction:[self action]];
[copy setEnabled:[self isEnabled]];
[copy setImage:[self image]];
@@ -519,9 +596,10 @@ CPToolbarItemVisibilityPriorityUser
[copy setMinSize:_minSize];
[copy setMaxSize:_maxSize];
[copy setVisibilityPriority:_visibilityPriority];
[copy setVisibilityPriority:[self visibilityPriority]];
[copy setAutovalidates:[self autovalidates]];
return copy;
}
@@ -534,26 +612,12 @@ CPToolbarItemVisibilityPriorityUser
/* @ignore */
+ (CPToolbarItem)_standardItemWithItemIdentifier:(CPString)anItemIdentifier
{
var item = [[CPToolbarItem alloc] initWithItemIdentifier:anItemIdentifier];
switch (anItemIdentifier)
{
case CPToolbarSeparatorItemIdentifier: [item setMinSize:CGSizeMake(2.0, 0.0)];
[item setMaxSize:CGSizeMake(2.0, 100000.0)];
return item;
case CPToolbarSpaceItemIdentifier: [item setMinSize:CGSizeMake(32.0, 32.0)];
[item setMaxSize:CGSizeMake(32.0, 32.0)];
return item;
case CPToolbarFlexibleSpaceItemIdentifier: [item setMinSize:CGSizeMake(32.0, 32.0)];
[item setMaxSize:CGSizeMake(10000.0, 32.0)];
return item;
case CPToolbarShowColorsItemIdentifier: return nil;
case CPToolbarSeparatorItemIdentifier: return [_CPToolbarSeparatorItem new];
case CPToolbarSpaceItemIdentifier: return [_CPToolbarSpaceItem new];
case CPToolbarFlexibleSpaceItemIdentifier: return [_CPToolbarFlexibleSpaceItem new];
case CPToolbarShowColorsItemIdentifier: return [_CPToolbarShowColorsItem new];
case CPToolbarShowFontsItemIdentifier: return nil;
case CPToolbarCustomizeToolbarItemIdentifier: return nil;
case CPToolbarPrintItemIdentifier: return nil;
@@ -563,3 +627,9 @@ CPToolbarItemVisibilityPriorityUser
}
@end
@import "_CPToolbarFlexibleSpaceItem.j"
@import "_CPToolbarShowColorsItem.j"
@import "_CPToolbarSeparatorItem.j"
@import "_CPToolbarSpaceItem.j"
+45 -8
View File
@@ -7,7 +7,7 @@
id _representedObject @accessors(readonly, property=representedObject);
CPTreeNode _parentNode @accessors(readonly, property=parentNode);
CPMutableArray _childNodes @accessors(readonly, property=childNodes);
CPMutableArray _childNodes;
}
+ (id)treeNodeWithRepresentedObject:(id)anObject
@@ -33,16 +33,23 @@
return [_childNodes count] <= 0;
}
- (CPArray)childNodes
{
return [_childNodes copy];
}
- (CPMutableArray)mutableChildNodes
{
return [self mutableArrayValueForKey:@"childNodes"];
}
- (void)insertObject:(id)anObject inChildNodesAtIndex:(CPInteger)anIndex
- (void)insertObject:(id)aTreeNode inChildNodesAtIndex:(CPInteger)anIndex
{
anObject._parentNode = self;
[[aTreeNode._parentNode mutableChildNodes] removeObjectIdenticalTo:aTreeNode];
[_childNodes addObject:anObject];
aTreeNode._parentNode = self;
[_childNodes insertObject:aTreeNode atIndex:anIndex];
}
- (void)removeObjectFromChildNodesAtIndex:(CPInteger)anIndex
@@ -52,13 +59,14 @@
[_childNodes removeObjectAtIndex:anIndex];
}
- (void)replaceObjectFromChildNodesAtIndex:(CPInteger)anIndex withObject:(id)anObject
- (void)replaceObjectFromChildNodesAtIndex:(CPInteger)anIndex withObject:(id)aTreeNode
{
var oldObject = [_childNodes objectAtIndex:anIndex];
var oldTreeNode = [_childNodes objectAtIndex:anIndex];
oldObject._parentNode = nil;
oldTreeNode._parentNode = nil;
aTreeNode._parentNode = self;
[_childNodes replaceObjectAtIndex:anIndex withObject:anObject];
[_childNodes replaceObjectAtIndex:anIndex withObject:aTreeNode];
}
- (id)objectInChildNodesAtIndex:(CPInteger)anIndex
@@ -80,3 +88,32 @@
}
@end
var CPTreeNodeRepresentedObjectKey = @"CPTreeNodeRepresentedObjectKey",
CPTreeNodeParentNodeKey = @"CPTreeNodeParentNodeKey",
CPTreeNodeChildNodesKey = @"CPTreeNodeChildNodesKey";
@implementation CPTreeNode (CPCoding)
- (id)initWithCoder:(CPCoder)aCoder
{
self = [super init];
if (self)
{
_representedObject = [aCoder decodeObjectForKey:CPTreeNodeRepresentedObjectKey];
_parentNode = [aCoder decodeObjectForKey:CPTreeNodeParentNodeKey];
_childNodes = [aCoder decodeObjectForKey:CPTreeNodeChildNodesKey];
}
return self;
}
- (void)encodeWithCoder:(CPCoder)aCoder
{
[aCoder encodeObject:_representedObject forKey:CPTreeNodeRepresentedObjectKey];
[aCoder encodeConditionalObject:_parentNode forKey:CPTreeNodeParentNodeKey];
[aCoder encodeObject:_childNodes forKey:CPTreeNodeChildNodesKey];
}
@end
+220 -56
View File
@@ -94,7 +94,8 @@ var DOMElementPrototype = nil,
BackgroundTrivialColor = 0,
BackgroundVerticalThreePartImage = 1,
BackgroundHorizontalThreePartImage = 2,
BackgroundNinePartImage = 3;
BackgroundNinePartImage = 3,
BackgroundTransparentColor = 4;
#endif
var CPViewFlags = { },
@@ -139,6 +140,7 @@ var CPViewFlags = { },
BOOL _isHidden;
BOOL _hitTests;
BOOL _clipsToBounds;
BOOL _postsFrameChangedNotifications;
BOOL _postsBoundsChangedNotifications;
@@ -238,6 +240,16 @@ var CPViewFlags = { },
return [CPSet setWithObjects:@"frameOrigin", @"frameSize"];
}
+ (CPSet)keyPathsForValuesAffectingBounds
{
return [CPSet setWithObjects:@"boundsOrigin", @"boundsSize"];
}
+ (CPMenu)defaultMenu
{
return nil;
}
- (id)init
{
return [self initWithFrame:CGRectMakeZero()];
@@ -267,6 +279,7 @@ var CPViewFlags = { },
_autoresizingMask = CPViewNotSizable;
_autoresizesSubviews = YES;
_clipsToBounds = YES;
_opacity = 1.0;
_isHidden = NO;
@@ -308,7 +321,7 @@ var CPViewFlags = { },
*/
- (CPArray)subviews
{
return _subviews;
return [_subviews copy];
}
/*!
@@ -441,7 +454,7 @@ var CPViewFlags = { },
[_superview willRemoveSubview:self];
[[_superview subviews] removeObject:self];
[_superview._subviews removeObject:self];
#if PLATFORM(DOM)
CPDOMDisplayServerRemoveChild(_superview._DOMElement, _DOMElement);
@@ -468,6 +481,75 @@ var CPViewFlags = { },
[self _insertSubview:aView atIndex:index];
}
- (void)setSubviews:(CPArray)newSubviews
{
if (!newSubviews)
[CPException raise:CPInvalidArgumentException reason:"newSubviews cannot be nil in -[CPView setSubviews:]"];
// Trivial Case 0: Same array somehow
if ([_subviews isEqual:newSubviews])
return;
// Trivial Case 1: No current subviews, simply add all new subviews.
if ([_subviews count] === 0)
{
var index = 0,
count = [newSubviews count];
for (; index < count; ++index)
[self addSubview:newSubviews[index]];
return;
}
// Trivial Case 2: No new subviews, simply remove all current subviews.
if ([newSubviews count] === 0)
{
var count = [_subviews count];
while (count--)
[_subviews[count] removeFromSuperview];
return;
}
// Find out the views that were removed.
var removedSubviews = [CPMutableSet setWithArray:_subviews];
[removedSubviews removeObjectsInArray:newSubviews];
[removedSubviews makeObjectsPerformSelector:@selector(removeFromSuperview)];
// Find out which views need to be added.
var addedSubviews = [CPMutableSet setWithArray:newSubviews];
[addedSubviews removeObjectsInArray:_subviews];
var addedSubview = nil,
addedSubviewEnumerator = [addedSubviews objectEnumerator];
while (addedSubview = [addedSubviewEnumerator nextObject])
[self addSubview:addedSubview];
// If the order is fine, no need to reorder.
if ([_subviews isEqual:newSubviews])
return;
_subviews = [newSubviews copy];
#if PLATFORM(DOM)
var index = 0,
count = [_subviews count];
for (; index < count; ++index)
{
var subview = _subviews[index];
CPDOMDisplayServerRemoveChild(_DOMElement, subview._DOMElement);
CPDOMDisplayServerAppendChild(_DOMElement, subview._DOMElement);
}
#endif
}
/* @ignore */
- (void)_setWindow:(CPWindow)aWindow
{
@@ -594,9 +676,9 @@ var CPViewFlags = { },
return _tag;
}
- (void)viewWithTag:(CPInteger)aTag
- (CPView)viewWithTag:(CPInteger)aTag
{
if ([self tag] === aTag)
if ([self tag] == aTag)
return self;
var index = 0,
@@ -756,28 +838,33 @@ var CPViewFlags = { },
if (_backgroundType !== BackgroundTrivialColor)
{
var images = [[_backgroundColor patternImage] imageSlices];
if (_backgroundType === BackgroundVerticalThreePartImage)
if (_backgroundType === BackgroundTransparentColor)
{
CPDOMDisplayServerSetStyleSize(_DOMImageParts[1], size.width, size.height - _DOMImageSizes[0].height - _DOMImageSizes[2].height);
CPDOMDisplayServerSetStyleSize(_DOMImageParts[0], size.width, size.height);
}
else if (_backgroundType === BackgroundHorizontalThreePartImage)
else
{
CPDOMDisplayServerSetStyleSize(_DOMImageParts[1], size.width - _DOMImageSizes[0].width - _DOMImageSizes[2].width, size.height);
}
var images = [[_backgroundColor patternImage] imageSlices];
else if (_backgroundType === BackgroundNinePartImage)
{
var width = size.width - _DOMImageSizes[0].width - _DOMImageSizes[2].width,
height = size.height - _DOMImageSizes[0].height - _DOMImageSizes[6].height;
if (_backgroundType === BackgroundVerticalThreePartImage)
{
CPDOMDisplayServerSetStyleSize(_DOMImageParts[1], size.width, size.height - _DOMImageSizes[0].height - _DOMImageSizes[2].height);
}
else if (_backgroundType === BackgroundHorizontalThreePartImage)
{
CPDOMDisplayServerSetStyleSize(_DOMImageParts[1], size.width - _DOMImageSizes[0].width - _DOMImageSizes[2].width, size.height);
}
else if (_backgroundType === BackgroundNinePartImage)
{
var width = size.width - _DOMImageSizes[0].width - _DOMImageSizes[2].width,
height = size.height - _DOMImageSizes[0].height - _DOMImageSizes[6].height;
CPDOMDisplayServerSetStyleSize(_DOMImageParts[1], width, _DOMImageSizes[0].height);
CPDOMDisplayServerSetStyleSize(_DOMImageParts[3], _DOMImageSizes[3].width, height);
CPDOMDisplayServerSetStyleSize(_DOMImageParts[4], width, height);
CPDOMDisplayServerSetStyleSize(_DOMImageParts[5], _DOMImageSizes[5].width, height);
CPDOMDisplayServerSetStyleSize(_DOMImageParts[7], width, _DOMImageSizes[7].height);
CPDOMDisplayServerSetStyleSize(_DOMImageParts[1], width, _DOMImageSizes[0].height);
CPDOMDisplayServerSetStyleSize(_DOMImageParts[3], _DOMImageSizes[3].width, height);
CPDOMDisplayServerSetStyleSize(_DOMImageParts[4], width, height);
CPDOMDisplayServerSetStyleSize(_DOMImageParts[5], _DOMImageSizes[5].width, height);
CPDOMDisplayServerSetStyleSize(_DOMImageParts[7], width, _DOMImageSizes[7].height);
}
}
}
#endif
@@ -816,6 +903,16 @@ var CPViewFlags = { },
return _CGRectMakeCopy(_bounds);
}
- (CGPoint)boundsOrigin
{
return _CGPointMakeCopy(_bounds.origin);
}
- (CGSize)boundsSize
{
return _CGSizeMakeCopy(_bounds.size);
}
/*!
Sets the location of the receiver inside its frame. The method
posts a CPViewBoundsDidChangeNotification to the
@@ -1099,6 +1196,23 @@ var CPViewFlags = { },
return _isHidden;
}
- (void)setClipsToBounds:(BOOL)shouldClip
{
if (_clipsToBounds === shouldClip)
return;
_clipsToBounds = shouldClip;
#if PLATFORM(DOM)
_DOMElement.style.overflow = _clipsToBounds ? "hidden" : "visible";
#endif
}
- (BOOL)clipsToBounds
{
return _clipsToBounds;
}
/*!
Sets the opacity of the receiver. The value must be in the range of 0.0 to 1.0, where 0.0 is
completely transparent and 1.0 is completely opaque.
@@ -1115,7 +1229,7 @@ var CPViewFlags = { },
if (CPFeatureIsCompatible(CPOpacityRequiresFilterFeature))
{
if (anAlphaValue == 1.0)
if (anAlphaValue === 1.0)
try { _DOMElement.style.removeAttribute("filter") } catch (anException) { }
else
_DOMElement.style.filter = "alpha(opacity=" + anAlphaValue * 100 + ")";
@@ -1202,6 +1316,14 @@ var CPViewFlags = { },
return self;
}
/*!
Returns \c YES if this view requires a panel to become key. Normally only text fields, so this returns \c NO.
*/
- (BOOL)needsPanelToBecomeKey
{
return NO;
}
/*!
Returns \c YES if mouse events aren't needed by the receiver and can be sent to the superview. The
default implementation returns \c NO if the view is opaque.
@@ -1217,6 +1339,22 @@ var CPViewFlags = { },
[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.
@param aColor the new color for the receiver's background
@@ -1225,56 +1363,72 @@ var CPViewFlags = { },
{
if (_backgroundColor == aColor)
return;
_backgroundColor = aColor;
#if PLATFORM(DOM)
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;
if ([patternImage isThreePartImage])
{
_backgroundType = [patternImage isVertical] ? BackgroundVerticalThreePartImage : BackgroundHorizontalThreePartImage;
amount = 3 - _DOMImageParts.length;
}
else if ([patternImage isNinePartImage])
{
_backgroundType = BackgroundNinePartImage;
amount = 9 - _DOMImageParts.length;
amount = 9 - _DOMImageParts.length;
}
else
{
_backgroundType = BackgroundTrivialColor;
amount = 0 - _DOMImageParts.length;
_backgroundType = colorNeedsDOMElement ? BackgroundTransparentColor : BackgroundTrivialColor;
amount = (colorNeedsDOMElement ? 1 : 0) - _DOMImageParts.length;
}
if (amount > 0)
{
while (amount--)
{
var DOMElement = DOMElementPrototype.cloneNode(false);
DOMElement.style.zIndex = -1000;
_DOMImageParts.push(DOMElement);
_DOMElement.appendChild(DOMElement);
}
}
else
{
amount = -amount;
while (amount--)
_DOMElement.removeChild(_DOMImageParts.pop());
}
if (_backgroundType == BackgroundTrivialColor)
// Opera doesn't like DOM properties set to nil.
// https://trac.280north.com/ticket/7
_DOMElement.style.background = _backgroundColor ? [_backgroundColor cssString] : "";
if (_backgroundType === BackgroundTrivialColor || _backgroundType === BackgroundTransparentColor)
{
var colorCSS = colorExists ? [_backgroundColor cssString] : "";
if (colorNeedsDOMElement)
{
_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
{
var slices = [patternImage imageSlices],
@@ -1285,23 +1439,31 @@ var CPViewFlags = { },
{
var image = slices[count],
size = _DOMImageSizes[count] = image ? [image size] : _CGSizeMakeZero();
CPDOMDisplayServerSetStyleSize(_DOMImageParts[count], size.width, size.height);
_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)
{
var width = frameSize.width - _DOMImageSizes[0].width - _DOMImageSizes[2].width,
height = frameSize.height - _DOMImageSizes[0].height - _DOMImageSizes[6].height;
CPDOMDisplayServerSetStyleSize(_DOMImageParts[1], width, _DOMImageSizes[0].height);
CPDOMDisplayServerSetStyleSize(_DOMImageParts[3], _DOMImageSizes[3].width, height);
CPDOMDisplayServerSetStyleSize(_DOMImageParts[4], width, height);
CPDOMDisplayServerSetStyleSize(_DOMImageParts[5], _DOMImageSizes[5].width, height);
CPDOMDisplayServerSetStyleSize(_DOMImageParts[7], width, _DOMImageSizes[7].height);
CPDOMDisplayServerSetStyleLeftTop(_DOMImageParts[0], NULL, 0.0, 0.0);
CPDOMDisplayServerSetStyleLeftTop(_DOMImageParts[1], NULL, _DOMImageSizes[0].width, 0.0);
CPDOMDisplayServerSetStyleRightTop(_DOMImageParts[2], NULL, 0.0, 0.0);
@@ -1315,7 +1477,7 @@ var CPViewFlags = { },
else if (_backgroundType == BackgroundVerticalThreePartImage)
{
CPDOMDisplayServerSetStyleSize(_DOMImageParts[1], frameSize.width, frameSize.height - _DOMImageSizes[0].height - _DOMImageSizes[2].height);
CPDOMDisplayServerSetStyleLeftTop(_DOMImageParts[0], NULL, 0.0, 0.0);
CPDOMDisplayServerSetStyleLeftTop(_DOMImageParts[1], NULL, 0.0, _DOMImageSizes[0].height);
CPDOMDisplayServerSetStyleLeftBottom(_DOMImageParts[2], NULL, 0.0, 0.0);
@@ -1323,7 +1485,7 @@ var CPViewFlags = { },
else if (_backgroundType == BackgroundHorizontalThreePartImage)
{
CPDOMDisplayServerSetStyleSize(_DOMImageParts[1], frameSize.width - _DOMImageSizes[0].width - _DOMImageSizes[2].width, frameSize.height);
CPDOMDisplayServerSetStyleLeftTop(_DOMImageParts[0], NULL, 0.0, 0.0);
CPDOMDisplayServerSetStyleLeftTop(_DOMImageParts[1], NULL, _DOMImageSizes[0].width, 0.0);
CPDOMDisplayServerSetStyleRightTop(_DOMImageParts[2], NULL, 0.0, 0.0);
@@ -1666,8 +1828,9 @@ setBoundsOrigin:
_DOMContentsElement.style.width = ROUND(_CGRectGetWidth(_frame)) + "px";
_DOMContentsElement.style.height = ROUND(_CGRectGetHeight(_frame)) + "px";
#if PLATFORM(DOM)
CPDOMDisplayServerAppendChild(_DOMElement, _DOMContentsElement);
#endif
_graphicsContext = [CPGraphicsContext graphicsContextWithGraphicsPort:graphicsPort flipped:YES];
}
@@ -1863,12 +2026,11 @@ setBoundsOrigin:
- (BOOL)performKeyEquivalent:(CPEvent)anEvent
{
var subviews = [self subviews],
count = [subviews count];
var count = [_subviews count];
// Is reverse iteration correct here? It matches the other (correct) code like hit testing.
while (count--)
if ([subviews[count] performKeyEquivalent:anEvent])
if ([_subviews[count] performKeyEquivalent:anEvent])
return YES;
return NO;
@@ -2046,7 +2208,8 @@ setBoundsOrigin:
var theClass = [self class],
CPViewClass = [CPView class],
attributes = [];
attributes = [],
nullValue = [CPNull null];
for (; theClass && theClass !== CPViewClass; theClass = [theClass superclass])
{
@@ -2070,9 +2233,10 @@ setBoundsOrigin:
while (attributeCount--)
{
var attributeName = attributeKeys[attributeCount];
var attributeName = attributeKeys[attributeCount],
attributeValue = [attributeDictionary objectForKey:attributeName];
attributes.push([attributeDictionary objectForKey:attributeName]);
attributes.push(attributeValue === nullValue ? nil : attributeValue);
attributes.push(attributeName);
}
}
@@ -2200,7 +2364,7 @@ setBoundsOrigin:
return [_themeAttributes[aName] value];
}
- (void)currentValueForThemeAttribute:(CPString)aName
- (id)currentValueForThemeAttribute:(CPString)aName
{
if (!_themeAttributes || !_themeAttributes[aName])
[CPException raise:CPInvalidArgumentException reason:[self className] + " does not contain theme attribute '" + aName + "'"];
+179
View File
@@ -0,0 +1,179 @@
/*
* CPFlashView.j
* AppKit
*
* Created by Klaas Pieter Annema on September 3, 2009.
* Copyright 2009, Sofa BV
*
* 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 <AppKit/CPAnimation.j>
CPViewAnimationTargetKey = @"CPViewAnimationTarget";
CPViewAnimationStartFrameKey = @"CPViewAnimationStartFrame";
CPViewAnimationEndFrameKey = @"CPViewAnimationEndFrame";
CPViewAnimationEffectKey = @"CPViewAnimationEffect";
CPViewAnimationFadeInEffect = @"CPViewAnimationFadeIn";
CPViewAnimationFadeOutEffect = @"CPViewAnimationFadeOut";
@implementation CPViewAnimation : CPAnimation
{
CPArray _viewAnimations;
}
- (id)initWithViewAnimations:(CPArray)viewAnimations
{
if (self = [super initWithDuration:0.5 animationCurve:CPAnimationLinear])
{
[self setViewAnimations:viewAnimations];
}
return self;
}
- (void)startAnimation
{
var animationIndex = [_viewAnimations count];
while (animationIndex--)
{
var dictionary = [_viewAnimations objectAtIndex:animationIndex],
view = [self _targetView:dictionary],
startFrame = [self _startFrame:dictionary];
[view setFrame:startFrame];
var effect = [self _effect:dictionary];
if (effect === CPViewAnimationFadeInEffect)
{
[view setAlphaValue:0.0];
[view setHidden:NO];
}
else if (effect === CPViewAnimationFadeOutEffect)
[view setAlphaValue:1.0];
}
[super startAnimation];
}
- (void)setCurrentProgress:(NSAnimationProgress)progress
{
[super setCurrentProgress:progress];
var animationIndex = [_viewAnimations count];
while (animationIndex--)
{
var dictionary = [_viewAnimations objectAtIndex:animationIndex],
view = [self _targetView:dictionary]
startFrame = [self _startFrame:dictionary]
endFrame = [self _endFrame:dictionary]
differenceFrame = CPRectMakeZero();
differenceFrame.origin.x = endFrame.origin.x - startFrame.origin.x;
differenceFrame.origin.y = endFrame.origin.y - startFrame.origin.y;
differenceFrame.size.width = endFrame.size.width - startFrame.size.width;
differenceFrame.size.height = endFrame.size.height - startFrame.size.height;
var intermediateFrame = CPRectMakeZero();
intermediateFrame.origin.x = startFrame.origin.x + differenceFrame.origin.x * progress;
intermediateFrame.origin.y = startFrame.origin.y + differenceFrame.origin.y * progress;
intermediateFrame.size.width = startFrame.size.width + differenceFrame.size.width * progress;
intermediateFrame.size.height = startFrame.size.height + differenceFrame.size.height * progress;
[view setFrame:intermediateFrame];
// Update the view's alpha value
var effect = [self _effect:dictionary];
if (effect === CPViewAnimationFadeInEffect)
[view setAlphaValue:1.0 * progress];
else if (effect === CPViewAnimationFadeOutEffect)
[view setAlphaValue:1.0 + ( 0.0 - 1.0 ) * progress];
if (progress === 1.0)
[view setHidden:CPRectIsNull(endFrame) || [view alphaValue] === 0.0];
}
}
- (void)stopAnimation
{
var animationIndex = [_viewAnimations count];
while (animationIndex--)
{
var dictionary = [_viewAnimations objectAtIndex:animationIndex],
view = [self _targetView:dictionary],
endFrame = [self _endFrame:dictionary];
[view setFrame:endFrame];
var effect = [self _effect:dictionary];
if (effect === CPViewAnimationFadeInEffect)
[view setAlphaValue:1.0];
else if (effect === CPViewAnimationFadeOutEffect)
[view setAlphaValue:0.0];
[view setHidden:CPRectIsNull(endFrame) || [view alphaValue] === 0.0];
}
[super stopAnimation];
}
- (id)_targetView:(CPDictionary)dictionary
{
var targetView = [dictionary valueForKey:CPViewAnimationTargetKey];
if (!targetView)
[CPException raise:CPInternalInconsistencyException reason:[CPString stringWithFormat:@"view animation: %@ does not have a target view", [dictionary description]]];
return targetView;
}
- (CPRect)_startFrame:(CPDictionary)dictionary
{
var startFrame = [dictionary valueForKey:CPViewAnimationStartFrameKey];
if (!startFrame)
return [[self _targetView:dictionary] frame];
return startFrame;
}
- (CPRect)_endFrame:(CPDictionary)dictionary
{
var endFrame = [dictionary valueForKey:CPViewAnimationEndFrameKey];
if (!endFrame)
return [[self _targetView:dictionary] frame];
return endFrame;
}
- (CPString)_effect:(CPDictionary)dictionary
{
return [dictionary valueForKey:CPViewAnimationEffectKey];
}
- (CPArray)viewAnimations
{
return _viewAnimations;
}
- (void)setViewAnimations:(CPArray)viewAnimations
{
if (viewAnimations != _viewAnimations)
{
[self stopAnimation];
_viewAnimations = [viewAnimations copy];
}
}
@end
+36 -6
View File
@@ -22,6 +22,7 @@
@import <AppKit/CPResponder.j>
var CPViewControllerCachedCibs;
/*! @class CPViewController
The CPViewController class provides the fundamental view-management controller for Cappuccino applications.
@@ -56,6 +57,12 @@
CPDictionary _cibExternalNameTable @accessors(property=cibExternalNameTable, readonly);
}
+ (void)initialize
{
if (self === CPViewController)
CPViewControllerCachedCibs = [CPDictionary dictionary];
}
/*!
Convenience initializer calls -initWithCibName:bundle: with nil for both parameters.
*/
@@ -113,11 +120,16 @@
{
if (_view)
return;
// check if a cib is already cached for the current _cibName
var cib = [CPViewControllerCachedCibs objectForKey:_cibName];
// if (_cibName)
// [CPException raise: reason:];
var cib = [[CPCib alloc] initWithContentsOfURL:[_cibBundle pathForResource:_cibName + @".cib"]];
if (!cib)
{
// if the cib isn't cached yet : fetch it and cache it
cib = [[CPCib alloc] initWithContentsOfURL:[_cibBundle pathForResource:_cibName + @".cib"]];
[CPViewControllerCachedCibs setObject:cib forKey:_cibName];
}
[cib instantiateCibWithExternalNameTable:_cibExternalNameTable];
}
@@ -126,8 +138,6 @@
Returns the view that the controller manages.
If this property is nil, the controller sends loadView to itself to create the view that it manages.
Subclasses should override the loadView method to create any custom views. The default value is nil.
Note: An error will not be thrown if after -loadView, the view property is still nil. -view will simply return nil, but will continue to call -loadView on subsequent calls.
*/
- (CPView)view
{
@@ -143,14 +153,34 @@
if (_view === nil && [cibOwner isKindOfClass:[CPDocument class]])
[self setView:[cibOwner valueForKey:@"view"]];
if (!_view)
{
var reason = [CPString stringWithFormat:@"View for %@ could not be loaded from Cib or no view specified. Override loadView to load the view manually.", self];
[CPException raise:CPInternalInconsistencyException reason:reason];
}
if ([cibOwner respondsToSelector:@selector(viewControllerDidLoadCib:)])
[cibOwner viewControllerDidLoadCib:self];
[self viewDidLoad];
}
return _view;
}
/*!
This method is called after the view controller has loaded its associated views into memory.
This method is called regardless of whether the views were stored in a nib file or created programmatically in the loadView method.
This method is most commonly used to perform additional initialization steps on views that are loaded from nib files.
*/
- (void)viewDidLoad
{
}
/*!
Manually sets the view that the controller manages.
Setting to nil will cause -loadView to be called on all subsequent calls of -view.
+54 -9
View File
@@ -69,11 +69,13 @@ CPWebViewScrollNative = 2;
CPString _url;
CPString _html;
Function _loadCallback;
int _scrollMode;
CGSize _scrollSize;
int _loadHTMLStringTimer;
}
- (id)initWithFrame:(CPRect)frameRect frameName:(CPString)frameName groupName:(CPString)groupName
@@ -110,6 +112,7 @@ CPWebViewScrollNative = 2;
_iframe.style.width = "100%";
_iframe.style.height = "100%";
_iframe.style.borderWidth = "0px";
_iframe.frameBorder = "0";
[self setDrawsBackground:YES];
@@ -150,8 +153,10 @@ CPWebViewScrollNative = 2;
_frameView = [[CPView alloc] initWithFrame:[self bounds]];
[_frameView setAutoresizingMask:CPViewWidthSizable|CPViewHeightSizable];
_scrollView = [[CPScrollView alloc] initWithFrame:[self bounds]];
[_scrollView setAutohidesScrollers:YES];
[_scrollView setAutoresizingMask:CPViewWidthSizable|CPViewHeightSizable];
[_scrollView setDocumentView:_frameView];
@@ -166,11 +171,35 @@ CPWebViewScrollNative = 2;
- (void)setFrameSize:(CPSize)aSize
{
[super setFrameSize:aSize];
[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)
{
@@ -180,13 +209,14 @@ CPWebViewScrollNative = 2;
}
else
{
[_frameView setFrameSize:[_scrollView bounds].size];
var visibleRect = [_frameView visibleRect];
[_frameView setFrameSize:CGSizeMake(CGRectGetMaxX(visibleRect), CGRectGetMaxY(visibleRect))];
// try to get the document size so we can correctly set the frame
var win = null;
try { win = [self DOMWindow]; } catch (e) {}
if (win && win.document)
if (win && win.document && win.document.body)
{
var width = win.document.body.scrollWidth,
height = win.document.body.scrollHeight;
@@ -202,6 +232,8 @@ CPWebViewScrollNative = 2;
[_frameView setFrameSize:CGSizeMake(800, 1600)];
}
[_frameView scrollRectToVisible:visibleRect];
}
}
}
@@ -216,7 +248,10 @@ CPWebViewScrollNative = 2;
- (void)_setScrollMode:(int)aScrollMode
{
_scrollMode = aScrollMode;
if (CPBrowserIsEngine(CPInternetExplorerBrowserEngine))
_scrollMode = CPWebViewScrollNative;
else
_scrollMode = aScrollMode;
_ignoreLoadStart = YES;
_ignoreLoadEnd = YES;
@@ -255,6 +290,8 @@ CPWebViewScrollNative = 2;
[self _setScrollMode:CPWebViewScrollAppKit];
[_frameView setFrameSize:[_scrollView contentSize]];
[self _startedLoading];
_ignoreLoadStart = YES;
@@ -292,8 +329,15 @@ CPWebViewScrollNative = 2;
// clear the iframe
_iframe.src = "";
if (_loadHTMLStringTimer !== nil)
{
window.clearTimeout(_loadHTMLStringTimer);
_loadHTMLStringTimer = nil;
}
// need to give the browser a chance to reset iframe, otherwise we'll be document.write()-ing the previous document
window.setTimeout(function() {
_loadHTMLStringTimer = window.setTimeout(function()
{
var win = [self DOMWindow];
win.document.write(_html);
@@ -314,7 +358,8 @@ CPWebViewScrollNative = 2;
- (void)_finishedLoading
{
[self _resizeWebFrame];
[self _attachScrollEventIfNecessary];
[[CPNotificationCenter defaultCenter] postNotificationName:CPWebViewProgressFinishedNotification object:self];
if ([_frameLoadDelegate respondsToSelector:@selector(webView:didFinishLoadForFrame:)])
+263 -64
View File
@@ -175,6 +175,9 @@ CPWindowBelow = 2;
CPWindowWillCloseNotification = @"CPWindowWillCloseNotification";
CPWindowDidBecomeMainNotification = @"CPWindowDidBecomeMainNotification";
CPWindowDidResignMainNotification = @"CPWindowDidResignMainNotification";
CPWindowDidBecomeKeyNotification = @"CPWindowDidBecomeKeyNotification";
CPWindowDidResignKeyNotification = @"CPWindowDidResignKeyNotification";
CPWindowDidResizeNotification = @"CPWindowDidResizeNotification";
CPWindowDidMoveNotification = @"CPWindowDidMoveNotification";
CPWindowWillBeginSheetNotification = @"CPWindowWillBeginSheetNotification";
CPWindowDidEndSheetNotification = @"CPWindowDidEndSheetNotification";
@@ -333,6 +336,11 @@ var CPWindowSaveImage = nil,
CPWindowSavingImage = [[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPProgressIndicator/CPProgressIndicatorSpinningStyleRegular.gif"] size:CGSizeMake(16.0, 16.0)]
}
- (id)init
{
return [self initWithContentRect:_CGRectMakeZero() styleMask:CPTitledWindowMask];
}
/*!
Initializes the window. The method also takes a style bit mask made up
of any of the following values:
@@ -364,6 +372,15 @@ CPTexturedBackgroundWindowMask
[self setPlatformWindow:[CPPlatformWindow primaryPlatformWindow]];
else
{
// give zero sized borderless bridge windows a default size if we're not in the browser so they show up in NativeHost.
if ((aStyleMask & CPBorderlessBridgeWindowMask) && aContentRect.size.width === 0 && aContentRect.size.height === 0)
{
var visibleFrame = [[[CPScreen alloc] init] visibleFrame];
_frame.size.height = MIN(768.0, visibleFrame.size.height);
_frame.size.width = MIN(1024.0, visibleFrame.size.width);
_frame.origin.x = (visibleFrame.size.width - _frame.size.width) / 2;
_frame.origin.y = (visibleFrame.size.height - _frame.size.height) / 2;
}
[self setPlatformWindow:[[CPPlatformWindow alloc] initWithContentRect:_frame]];
[self platformWindow]._only = self;
}
@@ -464,9 +481,6 @@ CPTexturedBackgroundWindowMask
- (void)awakeFromCib
{
if (_initialFirstResponder)
[self makeFirstResponder:_initialFirstResponder];
_keyViewLoopIsDirty = ![self _hasKeyViewLoop];
}
@@ -608,8 +622,17 @@ CPTexturedBackgroundWindowMask
@param shouldDisplay whether the window should redraw its views
@param shouldAnimate whether the window resize should be animated
*/
- (void)_setClippedFrame:(CGRect)aFrame display:(BOOL)shouldDisplay animate:(BOOL)shouldAnimate
{
aFrame.size.width = MIN(MAX(aFrame.size.width, _minSize.width), _maxSize.width)
aFrame.size.height = MIN(MAX(aFrame.size.height, _minSize.height), _maxSize.height);
[self setFrame:aFrame display:shouldDisplay animate:shouldAnimate];
}
- (void)setFrame:(CGRect)aFrame display:(BOOL)shouldDisplay animate:(BOOL)shouldAnimate
{
aFrame = _CGRectMakeCopy(aFrame);
var value = aFrame.origin.x,
delta = value - FLOOR(value);
@@ -665,16 +688,16 @@ CPTexturedBackgroundWindowMask
if (!_CGSizeEqualToSize(size, newSize))
{
size.width = MIN(MAX(newSize.width, _minSize.width), _maxSize.width);
size.height = MIN(MAX(newSize.height, _minSize.height), _maxSize.height);
size.width = newSize.width;
size.height = newSize.height;
[_windowView setFrameSize:size];
if (_hasShadow)
[_shadowView setFrameSize:_CGSizeMake(SHADOW_MARGIN_LEFT + size.width + SHADOW_MARGIN_RIGHT, SHADOW_MARGIN_BOTTOM + size.height + SHADOW_MARGIN_TOP + SHADOW_DISTANCE)];
if (!_isAnimating && [_delegate respondsToSelector:@selector(windowDidResize:)])
[_delegate windowDidResize:self];
if (!_isAnimating)
[[CPNotificationCenter defaultCenter] postNotificationName:CPWindowDidResizeNotification object:self];
}
if ([self _sharesChromeWithPlatformWindow])
@@ -684,7 +707,7 @@ CPTexturedBackgroundWindowMask
- (void)setFrame:(CGRect)aFrame display:(BOOL)shouldDisplay
{
[super setFrame:aFrame display:shouldDisplay animate:NO];
[self _setClippedFrame:aFrame display:shouldDisplay animate:NO];
}
/*!
@@ -692,7 +715,7 @@ CPTexturedBackgroundWindowMask
*/
- (void)setFrame:(CGRect)aFrame
{
[self setFrame:aFrame display:YES animate:NO];
[self _setClippedFrame:aFrame display:YES animate:NO];
}
/*!
@@ -701,7 +724,7 @@ CPTexturedBackgroundWindowMask
*/
- (void)setFrameOrigin:(CGPoint)anOrigin
{
[self setFrame:_CGRectMake(anOrigin.x, anOrigin.y, _CGRectGetWidth(_frame), _CGRectGetHeight(_frame)) display:YES animate:NO];
[self _setClippedFrame:_CGRectMake(anOrigin.x, anOrigin.y, _CGRectGetWidth(_frame), _CGRectGetHeight(_frame)) display:YES animate:NO];
}
/*!
@@ -710,7 +733,7 @@ CPTexturedBackgroundWindowMask
*/
- (void)setFrameSize:(CGSize)aSize
{
[self setFrame:_CGRectMake(_CGRectGetMinX(_frame), _CGRectGetMinY(_frame), aSize.width, aSize.height) display:YES animate:NO];
[self _setClippedFrame:_CGRectMake(_CGRectGetMinX(_frame), _CGRectGetMinY(_frame), aSize.width, aSize.height) display:YES animate:NO];
}
/*!
@@ -721,6 +744,15 @@ CPTexturedBackgroundWindowMask
{
[_platformWindow orderFront:self];
[_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];
}
/*
@@ -747,12 +779,7 @@ CPTexturedBackgroundWindowMask
[_platformWindow order:CPWindowOut window:self relativeTo:nil];
if ([CPApp keyWindow] == self)
{
[self resignKeyWindow];
CPApp._keyWindow = nil;
}
[self _updateMainAndKeyWindows];
}
/*!
@@ -771,6 +798,11 @@ CPTexturedBackgroundWindowMask
*/
- (void)setLevel:(int)aLevel
{
if (aLevel === _level)
return;
[_platformWindow moveWindow:self fromLevel:_level toLevel:aLevel];
_level = aLevel;
if ([self _sharesChromeWithPlatformWindow])
@@ -860,6 +892,23 @@ CPTexturedBackgroundWindowMask
return _contentView;
}
/*!
Applies an alpha value to the window.
@param aValue the alpha value to apply
*/
- (void)setAlphaValue:(float)aValue
{
[_windowView setAlphaValue:aValue];
}
/*!
Returns the alpha value of the window.
*/
- (float)alphaValue
{
return [_windowView alphaValue];
}
/*!
Sets the window's background color.
@param aColor the new color for the background
@@ -1051,13 +1100,31 @@ CPTexturedBackgroundWindowMask
*/
- (void)setDelegate:(id)aDelegate
{
// FIXME: Unregister for notifications!
var defaultCenter = [CPNotificationCenter defaultCenter];
[defaultCenter removeObserver:_delegate name:CPWindowDidResignKeyNotification object:self];
[defaultCenter removeObserver:_delegate name:CPWindowDidBecomeKeyNotification object:self];
[defaultCenter removeObserver:_delegate name:CPWindowDidBecomeMainNotification object:self];
[defaultCenter removeObserver:_delegate name:CPWindowDidResignMainNotification object:self];
[defaultCenter removeObserver:_delegate name:CPWindowDidMoveNotification object:self];
[defaultCenter removeObserver:_delegate name:CPWindowDidResizeNotification object:self];
_delegate = aDelegate;
_delegateRespondsToWindowWillReturnUndoManagerSelector = [_delegate respondsToSelector:@selector(windowWillReturnUndoManager:)];
var defaultCenter = [CPNotificationCenter defaultCenter];
if ([_delegate respondsToSelector:@selector(windowDidResignKey:)])
[defaultCenter
addObserver:_delegate
selector:@selector(windowDidResignKey:)
name:CPWindowDidResignKeyNotification
object:self];
if ([_delegate respondsToSelector:@selector(windowDidBecomeKey:)])
[defaultCenter
addObserver:_delegate
selector:@selector(windowDidBecomeKey:)
name:CPWindowDidBecomeKeyNotification
object:self];
if ([_delegate respondsToSelector:@selector(windowDidBecomeMain:)])
[defaultCenter
@@ -1079,6 +1146,13 @@ CPTexturedBackgroundWindowMask
selector:@selector(windowDidMove:)
name:CPWindowDidMoveNotification
object:self];
if ([_delegate respondsToSelector:@selector(windowDidResize:)])
[defaultCenter
addObserver:_delegate
selector:@selector(windowDidResize:)
name:CPWindowDidResizeNotification
object:self];
}
/*!
@@ -1119,6 +1193,16 @@ CPTexturedBackgroundWindowMask
return YES;
}
- (id)initialFirstResponder
{
return _initialFirstResponder;
}
- (void)setInitialFirstResponder:(id)aResponder
{
_initialFirstResponder = aResponder;
}
/*!
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
@@ -1126,9 +1210,9 @@ CPTexturedBackgroundWindowMask
\c aResponder accept first responder, then finally tell it to become first responder.
@return \c YES if the attempt was successful. \c NO otherwise.
*/
- (void)makeFirstResponder:(CPResponder)aResponder
- (BOOL)makeFirstResponder:(CPResponder)aResponder
{
if (_firstResponder == aResponder)
if (_firstResponder === aResponder)
return YES;
if(![_firstResponder resignFirstResponder])
@@ -1289,44 +1373,58 @@ CPTexturedBackgroundWindowMask
case CPScrollWheel: return [[_windowView hitTest:point] scrollWheel:anEvent];
case CPLeftMouseUp: if (!_leftMouseDownView)
return [[_windowView hitTest:point] mouseUp:anEvent];
case CPLeftMouseUp:
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;
return;
case CPLeftMouseDown: _leftMouseDownView = [_windowView hitTest:point];
case CPLeftMouseDown:
case CPRightMouseDown: _leftMouseDownView = [_windowView hitTest:point];
if (_leftMouseDownView != _firstResponder && [_leftMouseDownView acceptsFirstResponder])
[self makeFirstResponder:_leftMouseDownView];
[CPApp activateIgnoringOtherApps:YES];
var theWindow = [anEvent window];
var theWindow = [anEvent window],
selector = type == CPRightMouseDown ? @selector(rightMouseDown:) : @selector(mouseDown:);
if ([theWindow isKeyWindow] || [theWindow becomesKeyOnlyIfNeeded])
return [_leftMouseDownView mouseDown:anEvent];
if ([theWindow isKeyWindow] || [theWindow becomesKeyOnlyIfNeeded] && ![_leftMouseDownView needsPanelToBecomeKey])
return [_leftMouseDownView performSelector:selector withObject:anEvent];
else
{
// FIXME: delayed ordering?
[self makeKeyAndOrderFront:self];
if ([_leftMouseDownView acceptsFirstMouse:anEvent])
return [_leftMouseDownView mouseDown:anEvent]
return [_leftMouseDownView performSelector:selector withObject:anEvent];
}
break;
case CPLeftMouseDragged: if (!_leftMouseDownView)
case CPLeftMouseDragged:
case CPRightMouseDragged: if (!_leftMouseDownView)
return [[_windowView hitTest:point] mouseDragged:anEvent];
return [_leftMouseDownView mouseDragged:anEvent];
case CPRightMouseUp: return [_rightMouseDownView mouseUp:anEvent];
case CPRightMouseDown: _rightMouseDownView = [_windowView hitTest:point];
return [_rightMouseDownView mouseDown:anEvent];
case CPRightMouseDragged: return [_rightMouseDownView mouseDragged:anEvent];
var selector;
if (type == CPRightMouseDragged)
{
selector = @selector(rightMouseDragged:)
if (![_leftMouseDownView respondsToSelector:selector])
selector = nil;
}
if (!selector)
selector = @selector(mouseDragged:)
return [_leftMouseDownView performSelector:selector withObject:anEvent];
case CPMouseMoved: if (!_acceptsMouseMovedEvents)
return;
@@ -1396,8 +1494,14 @@ CPTexturedBackgroundWindowMask
*/
- (void)becomeKeyWindow
{
if (_firstResponder != self && [_firstResponder respondsToSelector:@selector(becomeKeyWindow)])
CPApp._keyWindow = self;
if (_firstResponder !== self && [_firstResponder respondsToSelector:@selector(becomeKeyWindow)])
[_firstResponder becomeKeyWindow];
[[CPNotificationCenter defaultCenter]
postNotificationName:CPWindowDidBecomeKeyNotification
object:self];
}
/*!
@@ -1434,13 +1538,10 @@ CPTexturedBackgroundWindowMask
*/
- (void)makeKeyWindow
{
if (![self canBecomeKeyWindow])
if ([CPApp keyWindow] === self || ![self canBecomeKeyWindow])
return;
[CPApp._keyWindow resignKeyWindow];
CPApp._keyWindow = self;
[[CPApp keyWindow] resignKeyWindow];
[self becomeKeyWindow];
}
@@ -1449,11 +1550,15 @@ CPTexturedBackgroundWindowMask
*/
- (void)resignKeyWindow
{
if (_firstResponder != self && [_firstResponder respondsToSelector:@selector(resignKeyWindow)])
if (_firstResponder !== self && [_firstResponder respondsToSelector:@selector(resignKeyWindow)])
[_firstResponder resignKeyWindow];
if ([_delegate respondsToSelector:@selector(windowDidResignKey:)])
[_delegate windowDidResignKey:self];
if (CPApp._keyWindow === self)
CPApp._keyWindow = nil;
[[CPNotificationCenter defaultCenter]
postNotificationName:CPWindowDidResignKeyNotification
object:self];
}
/*!
@@ -1482,7 +1587,7 @@ CPTexturedBackgroundWindowMask
[_inclusiveRegisteredDraggedTypes unionSet:pasteboardTypes];
}
- (void)_noteUnregisteredDraggedTypes:(CPArray)pasteboardTypes
- (void)_noteUnregisteredDraggedTypes:(CPSet)pasteboardTypes
{
if (!pasteboardTypes)
return;
@@ -1642,6 +1747,8 @@ CPTexturedBackgroundWindowMask
[[self platformWindow] miniaturize:sender];
[self _updateMainAndKeyWindows];
[[CPNotificationCenter defaultCenter] postNotificationName:CPWindowDidMiniaturizeNotification object:self];
_isMiniaturized = YES;
@@ -1678,6 +1785,17 @@ CPTexturedBackgroundWindowMask
if (!(_styleMask & CPClosableWindowMask))
return;
if ([self isFullBridge])
{
var event = [CPApp currentEvent];
if ([event type] === CPKeyDown && [event characters] === "w" && ([event modifierFlags] & CPPlatformActionKeyMask))
{
[[self platformWindow] _propagateCurrentDOMEvent:YES];
return;
}
}
// Only send ONE windowShouldClose: message.
if ([_delegate respondsToSelector:@selector(windowShouldClose:)])
{
@@ -1766,13 +1884,10 @@ CPTexturedBackgroundWindowMask
*/
- (void)makeMainWindow
{
if (![self canBecomeMainWindow])
if ([CPApp mainWindow] === self || ![self canBecomeMainWindow])
return;
[CPApp._mainWindow resignMainWindow];
CPApp._mainWindow = self;
[[CPApp mainWindow] resignMainWindow];
[self becomeMainWindow];
}
@@ -1781,9 +1896,11 @@ CPTexturedBackgroundWindowMask
*/
- (void)becomeMainWindow
{
CPApp._mainWindow = self;
[self _synchronizeMenuBarTitleWithWindowTitle];
[self _synchronizeSaveMenuWithDocumentSaving];
[[CPNotificationCenter defaultCenter]
postNotificationName:CPWindowDidBecomeMainNotification
object:self];
@@ -1797,6 +1914,70 @@ CPTexturedBackgroundWindowMask
[[CPNotificationCenter defaultCenter]
postNotificationName:CPWindowDidResignMainNotification
object:self];
if (CPApp._mainWindow === self)
CPApp._mainWindow = nil;
}
- (void)_updateMainAndKeyWindows
{
var allWindows = [CPApp orderedWindows],
windowCount = [allWindows count];
if ([self isKeyWindow])
{
var keyWindow = [CPApp keyWindow];
[self resignKeyWindow];
if (keyWindow && keyWindow !== self && [keyWindow canBecomeKeyWindow])
[keyWindow makeKeyWindow];
else
{
var mainMenu = [CPApp mainMenu],
menuWindow = mainMenu ? mainMenu._menuWindow : nil;
for (var i = 0; i < windowCount; i++)
{
var currentWindow = allWindows[i];
if (currentWindow === self || currentWindow === menuWindow)
continue;
if ([currentWindow isVisible] && [currentWindow canBecomeKeyWindow])
{
[currentWindow makeKeyWindow];
break;
}
}
if (![CPApp keyWindow])
[menuWindow makeKeyWindow];
}
}
if ([self isMainWindow])
{
var mainWindow = [CPApp mainWindow];
[self resignMainWindow];
if (mainWindow && mainWindow !== self && [mainWindow canBecomeMainWindow])
[mainWindow makeMainWindow];
else
{
var mainMenu = [CPApp mainMenu],
menuWindow = mainMenu ? mainMenu._menuWindow : nil;
for (var i = 0; i < windowCount; i++)
{
var currentWindow = allWindows[i];
if (currentWindow === self || currentWindow === menuWindow)
continue;
if ([currentWindow isVisible] && [currentWindow canBecomeMainWindow])
{
[currentWindow makeMainWindow];
break;
}
}
}
}
}
// Managing Toolbars
@@ -1882,8 +2063,8 @@ CPTexturedBackgroundWindowMask
sheetFrame.origin.y = CGRectGetMinY(_frame) + CGRectGetMinY(contentRect);
sheetFrame.origin.x = CGRectGetMinX(_frame) + FLOOR((CGRectGetWidth(_frame) - CGRectGetWidth(sheetFrame)) / 2.0);
[attachedSheet setFrameOrigin:sheetFrame.origin];
[attachedSheet setFrame:sheetFrame display:YES animate:NO];
}
/* @ignore */
@@ -1917,7 +2098,7 @@ CPTexturedBackgroundWindowMask
[CPApp runModalForWindow:aSheet];
[aSheet orderFront:self];
[aSheet setFrame:startFrame];
[aSheet setFrame:startFrame display:YES animate:NO];
_sheetContext["opened"] = YES;
[aSheet _setFrame:endFrame delegate:self duration:0.2 curve:CPAnimationEaseOut];
@@ -1981,7 +2162,8 @@ CPTexturedBackgroundWindowMask
- (void)_setUpMasksForView:(CPView)aView
{
var views = [CPArray arrayWithArray:[aView subviews]];
var views = [aView subviews];
[views addObject:aView];
for (var i = 0, count = [views count]; i < count; i++)
@@ -1996,7 +2178,8 @@ CPTexturedBackgroundWindowMask
- (void)_restoreMasksForView:(CPView)aView
{
var views = [CPArray arrayWithArray:[aView subviews]];
var views = [aView subviews];
[views addObject:aView];
for (var i = 0, count = [views count]; i < count; i++)
@@ -2351,9 +2534,21 @@ var keyViewComparator = function(a, b, context)
*/
- (CPUndoManager)undoManager
{
// If we've ever created an undo manager, return it.
if (_undoManager)
return _undoManager;
// If not, check to see if the document has one.
var documentUndoManager = [[_windowController document] undoManager];
if (documentUndoManager)
return documentUndoManager;
// If not, check to see if the delegate has one.
if (_delegateRespondsToWindowWillReturnUndoManagerSelector)
return [_delegate windowWillReturnUndoManager:self];
// If not, create one.
if (!_undoManager)
_undoManager = [[CPUndoManager alloc] init];
@@ -2459,9 +2654,13 @@ var interpolate = function(fromValue, toValue, progress)
if (value == 1.0)
_window._isAnimating = NO;
[_window setFrameOrigin:CGPointMake(interpolate(CGRectGetMinX(_startFrame), CGRectGetMinX(_targetFrame), value), interpolate(CGRectGetMinY(_startFrame), CGRectGetMinY(_targetFrame), value))];
[_window setFrameSize:CGSizeMake(interpolate(CGRectGetWidth(_startFrame), CGRectGetWidth(_targetFrame), value), interpolate(CGRectGetHeight(_startFrame), CGRectGetHeight(_targetFrame), value))];
var newFrame = CGRectMake(interpolate(CGRectGetMinX(_startFrame), CGRectGetMinX(_targetFrame), value),
interpolate(CGRectGetMinY(_startFrame), CGRectGetMinY(_targetFrame), value),
interpolate(CGRectGetWidth(_startFrame), CGRectGetWidth(_targetFrame), value),
interpolate(CGRectGetHeight(_startFrame), CGRectGetHeight(_targetFrame), value));
[_window setFrame:newFrame display:YES animate:NO];
}
@end
@@ -71,11 +71,12 @@ var _CPToolbarViewBackgroundColor = nil;
[self addSubview:_toolbarBackgroundView positioned:CPWindowBelow relativeTo:nil];
}
var frame = CGRectMakeZero();
frame.origin = CGPointMakeCopy([self toolbarOffset]);
var frame = CGRectMakeZero(),
toolbarOffset = [self toolbarOffset];
frame.origin = CGPointMake(toolbarOffset.width, toolbarOffset.height);
frame.size = [_toolbarView frame].size;
[_toolbarBackgroundView setFrame:frame];
}
+1 -1
View File
@@ -48,7 +48,7 @@ var HUD_TITLEBAR_HEIGHT = 26.0;
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPWindow/HUD/CPWindowHUDBackground2.png"] size:CPSizeMake(6.0, 78.0)],
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPWindow/HUD/CPWindowHUDBackground3.png"] size:CPSizeMake(6.0, 1.0)],
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPWindow/HUD/CPWindowHUDBackground4.png"] size:CPSizeMake(1.0, 1.0)],
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPWindow/HUD/CPWindowHUDBackground4.png"] size:CPSizeMake(5.0, 5.0)],
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPWindow/HUD/CPWindowHUDBackground5.png"] size:CPSizeMake(6.0, 1.0)],
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPWindow/HUD/CPWindowHUDBackground6.png"] size:CPSizeMake(6.0, 6.0)],
+12 -5
View File
@@ -36,7 +36,9 @@ var _CPWindowViewResizeIndicatorImage = nil;
CGSize _resizeIndicatorOffset;
CPView _toolbarView;
CGSize _toolbarOffset;
// BOOL _isAnimatingToolbar;
CGRect _resizeFrame;
CGPoint _mouseDraggedPoint;
@@ -79,8 +81,8 @@ var _CPWindowViewResizeIndicatorImage = nil;
if (self)
{
_styleMask = aStyleMask;
_resizeIndicatorOffset = CGSizeMake(0.0, 0.0);
_toolbarOffset = CGSizeMake(0.0, 0.0);
_resizeIndicatorOffset = CGSizeMakeZero();
_toolbarOffset = CGSizeMakeZero();
}
return self;
@@ -160,10 +162,15 @@ var _CPWindowViewResizeIndicatorImage = nil;
if (!visibleFrame)
visibleFrame = [[CPPlatformWindow primaryPlatformWindow] visibleFrame];
var minPointY = 0;
if([CPMenu menuBarVisible])
minPointY = [[CPApp mainMenu] menuBarHeight];
var restrictedPoint = CGPointMake(0, 0);
restrictedPoint.x = MIN(MAX(aPoint.x, -_frame.size.width + 4.0), CGRectGetMaxX(visibleFrame) - 4.0);
restrictedPoint.y = MIN(MAX(aPoint.y, 0.0), CGRectGetMaxY(visibleFrame) - 8.0);
restrictedPoint.y = MIN(MAX(aPoint.y, minPointY), CGRectGetMaxY(visibleFrame) - 8.0);
return restrictedPoint;
}
@@ -222,7 +229,7 @@ var _CPWindowViewResizeIndicatorImage = nil;
}
}
- (CPImage)showsResizeIndicator
- (BOOL)showsResizeIndicator
{
return _resizeIndicator !== nil;
}
@@ -263,7 +270,7 @@ var _CPWindowViewResizeIndicatorImage = nil;
- (CGSize)toolbarOffset
{
return CGSizeMakeZero();
return _toolbarOffset;
}
- (CPColor)toolbarLabelColor
+9 -20
View File
@@ -144,7 +144,7 @@
{
var theWindow = [self window];
if ([theWindow respondsToSelector:@selector(becomesKeyOnlyIfNeeded)] && [theWindow becomesKeyOnlyIfNeeded])
if ([theWindow respondsToSelector:@selector(becomesKeyOnlyIfNeeded)] && [theWindow becomesKeyOnlyIfNeeded])
[theWindow orderFront:aSender];
else
[theWindow makeKeyAndOrderFront:aSender];
@@ -173,6 +173,14 @@
if (_window === nil && [_cibOwner isKindOfClass:[CPDocument class]])
[self setWindow:[_cibOwner valueForKey:@"window"]];
if (!_window)
{
var reason = [CPString stringWithFormat:@"Window for %@ could not be loaded from Cib or no window specified. \
Override loadWindow to load the window manually.", self];
[CPException raise:CPInternalInconsistencyException reason:reason];
}
[self windowDidLoad];
[_document windowControllerDidLoadCib:self];
@@ -314,25 +322,6 @@
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
{
_viewControllerContainerView = aView;
+8 -3
View File
@@ -60,7 +60,7 @@ var CPCibObjectDataKey = @"CPCibObjectDataKey";
if (self)
{
_data = [CPURLConnection sendSynchronousRequest:[CPURLRequest requestWithURL:aURL] returningResponse:nil error:nil];
_data = [CPURLConnection sendSynchronousRequest:[CPURLRequest requestWithURL:aURL] returningResponse:nil];
_awakenCustomResources = YES;
}
@@ -171,12 +171,17 @@ var CPCibObjectDataKey = @"CPCibObjectDataKey";
- (void)connection:(CPURLConnection)aConnection didReceiveData:(CPString)data
{
_data = [CPData dataWithString:data];
// FIXME: Why aren't we getting connection:didFailWithError:
if (!data)
return [self connection:aConnection didFailWithError:nil];
_data = [CPData dataWithRawString:data];
}
- (void)connection:(CPURLConnection)aConnection didFailWithError:(CPError)anError
{
alert("cib: connection failed.");
if ([_loadDelegate respondsToSelector:@selector(cibDidFailToLoad:)])
[_loadDelegate cibDidFailToLoad:self];
_loadDelegate = nil;
}
+1 -1
View File
@@ -32,7 +32,7 @@
var selectorName = _label,
selectorNameLength = [selectorName length];
if (selectorNameLength && selectorName[selectorNameLength - 1] !== ':')
if (selectorNameLength && selectorName.charAt(selectorNameLength - 1) !== ':')
selectorName += ':';
var selector = CPSelectorFromString(selectorName);
+54 -29
View File
@@ -27,8 +27,6 @@
var CPCibOwner = @"CPCibOwner";
var LoadInfoForCib = {};
@implementation CPObject (CPCibLoading)
- (void)awakeFromCib
@@ -39,12 +37,12 @@ var LoadInfoForCib = {};
@implementation CPBundle (CPCibLoading)
+ (void)loadCibFile:(CPString)anAbsolutePath externalNameTable:(CPDictionary)aNameTable
+ (CPCib)loadCibFile:(CPString)anAbsolutePath externalNameTable:(CPDictionary)aNameTable
{
[[[CPCib alloc] initWithContentsOfURL:anAbsolutePath] instantiateCibWithExternalNameTable:aNameTable];
return [[[CPCib alloc] initWithContentsOfURL:anAbsolutePath] instantiateCibWithExternalNameTable:aNameTable];
}
+ (void)loadCibNamed:(CPString)aName owner:(id)anOwner
+ (CPCib)loadCibNamed:(CPString)aName owner:(id)anOwner
{
if (![aName hasSuffix:@".cib"])
aName = [aName stringByAppendingString:@".cib"];
@@ -53,22 +51,24 @@ var LoadInfoForCib = {};
var bundle = anOwner ? [CPBundle bundleForClass:[anOwner class]] : [CPBundle mainBundle],
path = [bundle pathForResource:aName];
[self loadCibFile:path externalNameTable:[CPDictionary dictionaryWithObject:anOwner forKey:CPCibOwner]];
return [self loadCibFile:path externalNameTable:[CPDictionary dictionaryWithObject:anOwner forKey:CPCibOwner]];
}
- (void)loadCibFile:(CPString)aFileName externalNameTable:(CPDictionary)aNameTable
- (CPCib)loadCibFile:(CPString)aFileName externalNameTable:(CPDictionary)aNameTable
{
[[[CPCib alloc] initWithContentsOfURL:aFileName] instantiateCibWithExternalNameTable:aNameTable];
return [[[CPCib alloc] initWithContentsOfURL:aFileName] instantiateCibWithExternalNameTable:aNameTable];
}
+ (void)loadCibFile:(CPString)anAbsolutePath externalNameTable:(CPDictionary)aNameTable loadDelegate:aDelegate
+ (CPCib)loadCibFile:(CPString)anAbsolutePath externalNameTable:(CPDictionary)aNameTable loadDelegate:aDelegate
{
var cib = [[CPCib alloc] initWithContentsOfURL:anAbsolutePath loadDelegate:self];
LoadInfoForCib[[cib UID]] = { loadDelegate:aDelegate, externalNameTable:aNameTable };
return ([[CPCib alloc]
initWithContentsOfURL:anAbsolutePath
loadDelegate:[[_CPCibLoadDelegate alloc]
initWithLoadDelegate:aDelegate
externalNameTable:aNameTable]]);
}
+ (void)loadCibNamed:(CPString)aName owner:(id)anOwner loadDelegate:(id)aDelegate
+ (CPCib)loadCibNamed:(CPString)aName owner:(id)anOwner loadDelegate:(id)aDelegate
{
if (![aName hasSuffix:@".cib"])
aName = [aName stringByAppendingString:@".cib"];
@@ -77,25 +77,50 @@ var LoadInfoForCib = {};
var bundle = anOwner ? [CPBundle bundleForClass:[anOwner class]] : [CPBundle mainBundle],
path = [bundle pathForResource:aName];
[self loadCibFile:path externalNameTable:[CPDictionary dictionaryWithObject:anOwner forKey:CPCibOwner] loadDelegate:aDelegate];
return [self loadCibFile:path externalNameTable:[CPDictionary dictionaryWithObject:anOwner forKey:CPCibOwner] loadDelegate:aDelegate];
}
- (void)loadCibFile:(CPString)aFileName externalNameTable:(CPDictionary)aNameTable loadDelegate:(id)aDelegate
- (CPCib)loadCibFile:(CPString)aFileName externalNameTable:(CPDictionary)aNameTable loadDelegate:(id)aDelegate
{
var cib = [[CPCib alloc] initWithCibNamed:aFileName bundle:self loadDelegate:[self class]];
LoadInfoForCib[[cib UID]] = { loadDelegate:aDelegate, externalNameTable:aNameTable };
}
+ (void)cibDidFinishLoading:(CPCib)aCib
{
var loadInfo = LoadInfoForCib[[aCib UID]];
delete LoadInfoForCib[[aCib UID]];
[aCib instantiateCibWithExternalNameTable:loadInfo.externalNameTable];
[loadInfo.loadDelegate cibDidFinishLoading:aCib];
return ([[CPCib alloc]
initWithCibNamed:aFileName
bundle:self
loadDelegate:[[_CPCibLoadDelegate alloc]
initWithLoadDelegate:aDelegate
externalNameTable:aNameTable]]);
}
@end
@implementation _CPCibLoadDelegate : CPObject
{
id _loadDelegate;
CPDictionary _externalNameTable;
}
- (id)initWithLoadDelegate:(id)aLoadDelegate externalNameTable:(id)anExternalNameTable
{
self = [self init];
if (self)
{
_loadDelegate = aLoadDelegate;
_externalNameTable = anExternalNameTable;
}
return self;
}
- (void)cibDidFinishLoading:(CPCib)aCib
{
[aCib instantiateCibWithExternalNameTable:_externalNameTable];
[_loadDelegate cibDidFinishLoading:aCib];
}
- (void)cibDidFailToLoad:(CPCib)aCib
{
[_loadDelegate cibDidFailToLoad:aCib];
}
@end
+1 -1
View File
@@ -83,7 +83,7 @@ var _CPCibCustomResourceClassNameKey = @"_CPCibCustomResourceClassNameKey",
if ([aCoder respondsToSelector:@selector(bundle)] &&
(![aCoder respondsToSelector:@selector(awakenCustomResources)] || [aCoder awakenCustomResources]))
if (_className === @"CPImage")
return [[CPImage alloc] initWithContentsOfFile:[[aCoder bundle] pathForResource:_resourceName] size:[_properties objectForKey:@"size"]];
return [[CPImage alloc] initWithContentsOfFile:[[aCoder bundle] pathForResource:_resourceName] size:_properties.valueForKey(@"size")];
return self;
}
+7 -3
View File
@@ -37,7 +37,13 @@
- (void)setCustomClassName:(CPString)aClassName
{
if (_className === aClassName)
return;
_className = aClassName;
[self setNeedsDisplay:YES];
[self setNeedsLayout];
}
@end
@@ -97,9 +103,7 @@ var _CPCibCustomViewClassNameKey = @"_CPCibCustomViewClassNameKey";
[view setBounds:[self bounds]];
// Since the object replacement logic hasn't had a chance to kick in yet, we need to do it manually:
// we need to copy subviews since each time we add a subview to a different view its removed from the original subviews array
var subviews = [[self subviews] copy],
var subviews = [self subviews],
index = 0,
count = subviews.length;
+2 -3
View File
@@ -14,7 +14,7 @@ var _CPCibWindowTemplateMinSizeKey = @"_CPCibWindowTemplateMinS
_CPCibWindowTemplateWindowViewKey = @"_CPCibWindowTemplateWindowViewKey",
_CPCibWindowTemplateWindowAutorecalculatesKeyViewLoop = @"_CPCibWindowTemplateWindowAutorecalculatesKeyViewLoop";
_CPCibWindowTemplateWindowIsFullPlatformWindowKey = @"_CPCibWindowTemplateWindowIsFullPlatformWindowKey";
_CPCibWindowTemplateWindowIsFullPlatformWindowKey = @"_CPCibWindowTemplateWindowIsFullPlatformWindowKey";
@implementation _CPCibWindowTemplate : CPObject
{
@@ -134,9 +134,8 @@ var _CPCibWindowTemplateMinSizeKey = @"_CPCibWindowTemplateMinS
[theWindow setMinSize:_minSize];
if (_maxSize)
[theWindow setMaxSize:_maxSize];
[theWindow setLevel:CPFloatingWindowLevel];
//[result setHidesOnDeactivate:(_wtFlags&0x80000000)?YES:NO];
//[result setHidesOnDeactivate:(_wtFlags&0x80000000)?YES:NO];
[theWindow setTitle:_windowTitle];
// FIXME: we can't autoresize yet...
+1 -2
View File
@@ -777,8 +777,7 @@ if (_DOMContentsElement && aLayer._zPosition > _DOMContentsElement.style.zIndex)
@ignore
*/
+ (void)runLoopUpdateLayers
{if (window.oops) {alert(window.latest); objj_debug_print_backtrace();}
window.loop = true;
{
for (UID in CALayerRegisteredRunLoopUpdates)
{
var layer = CALayerRegisteredRunLoopUpdates[UID],
+1 -1
View File
@@ -210,7 +210,7 @@ function CGPathAddQuadCurveToPoint(aPath, aTransform, cpx, cpy, x, y)
if (aTransform)
{
cp = _CGPointApplyAffineTransform(control, aTransform);
cp = _CGPointApplyAffineTransform(cp, aTransform);
end = _CGPointApplyAffineTransform(end, aTransform);
}
+7 -2
View File
@@ -1,10 +1,15 @@
require("../common.jake");
var framework = require("objective-j/jake").framework;
var BundleTask = require("objective-j/jake").BundleTask;
$BUILD_PATH = FILE.join($BUILD_DIR, $CONFIGURATION, 'AppKit');
AppKitFiles = new FileList("**/*.j").exclude('CoreGraphics/CGContextCanvas.j', 'CoreGraphics/CGContextVML.j', 'Themes/**/*', 'Tools/**/*');
AppKitFiles = new FileList("**/*.j").exclude('CoreGraphics/CGContextCanvas.j', 'CoreGraphics/CGContextVML.j', 'Themes/**/*', 'Tools/**/*', "Platform/DOM/CPPlatform.j", "Platform/DOM/CPPlatformString.j");
FIXME_fileDependency (FILE.join("Platform", "CPPlatform.j"), FILE.join("Platform", "DOM", "CPPlatform.j"));
FIXME_fileDependency (FILE.join("Platform", "CPPlatformString.j"), FILE.join("Platform", "DOM", "CPPlatformString.j"));
appKitTask = framework ("AppKit", function(appKitTask)
{
@@ -15,7 +20,7 @@ appKitTask = framework ("AppKit", function(appKitTask)
appKitTask.setEmail("feedback @nospam@ 280north.com");
appKitTask.setSummary("AppKit classes for Cappuccino");
appKitTask.setIdentifier("com.280n.AppKit");
appKitTask.setVersion("0.7.9");
appKitTask.setVersion(getCappuccinoVersion());
appKitTask.setLicense(BundleTask.License.LGPL_v2_1);
appKitTask.setSources(AppKitFiles);
appKitTask.setResources(new FileList("Resources/**/*"));
+38 -28
View File
@@ -1,72 +1,82 @@
/*
* CPPlatform.j
* AppKit
*
* Created by Francisco Tolmasky.
* 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 <Foundation/CPObject.j>
#include "Platform.h"
@implementation CPPlatform : CPObject
@implementation CPBasePlatform : CPObject
{
}
+ (void)bootstrap
{
#if PLATFORM(DOM)
var body = document.getElementsByTagName("body")[0];
body.innerHTML = ""; // Get rid of anything that might be lingering in the body element.
body.style.overflow = "hidden";
if (document.documentElement)
document.documentElement.style.overflow = "hidden";
#endif
[CPPlatformString bootstrap];
[CPPlatformWindow setPrimaryPlatformWindow:[[CPPlatformWindow alloc] _init]];
}
+ (BOOL)isBrowser
{
return typeof window.cpIsDesktop === "undefined";
return NO;
}
+ (BOOL)supportsDragAndDrop
{
return CPFeatureIsCompatible(CPHTMLDragAndDropFeature);
return NO;
}
+ (BOOL)supportsNativeMainMenu
{
return (typeof window["cpSetMainMenu"] === "function");
return NO;
}
+ (void)terminateApplication
{
if (typeof window["cpTerminate"] === "function")
window.cpTerminate();
}
+ (void)activateIgnoringOtherApps:(BOOL)shouldIgnoreOtherApps
{
#if PLATFORM(DOM)
if (typeof window["cpActivateIgnoringOtherApps"] === "function")
window.cpActivateIgnoringOtherApps(!!shouldIgnoreOtherApps);
#endif
}
+ (void)deactivate
{
}
+ (void)hideOtherApplications:(id)aSender
{
#if PLATFORM(DOM)
if (typeof window["cpHideOtherApplications"] === "function")
window.cpHideOtherApplications();
#endif
}
+ (void)hide:(id)aSender
{
#if PLATFORM(DOM)
if (typeof window["cpHide"] === "function")
window.cpHide();
#endif
}
@end
#if PLATFORM(DOM)
#include "DOM/CPPlatform.j"
#else
@implementation CPPlatform : CPBasePlatform
{
}
@end
#endif
+31 -84
View File
@@ -1,4 +1,24 @@
/*
* CPPlatformString.j
* AppKit
*
* Created by Francisco Tolmasky.
* 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 <Foundation/CPObject.j>
@@ -6,99 +26,26 @@
#include "Platform.h"
#if PLATFORM(DOM)
var DOMIFrameElement = nil,
DOMSpanElement = nil,
DefaultFont = nil;
#endif
@implementation CPPlatformString : CPObject
@implementation CPBasePlatformString : CPObject
{
}
+ (void)bootstrap
{
#if PLATFORM(DOM)
DOMIFrameElement = document.createElement("iframe");
DOMIFrameElement.name = 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.background = "blue";
DOMIFrameElement.style.overflow = "hidden";
DOMIFrameElement.style.zIndex = 100000000000;
document.getElementsByTagName("body")[0].appendChild(DOMIFrameElement);
var DOMIFrameDocument = (DOMIFrameElement.contentDocument || DOMIFrameElement.contentWindow.document);
DOMIFrameDocument.write("<html><head></head><body></body></html>");
DOMIFrameDocument.close();
DOMSpanElement = DOMIFrameDocument.createElement("span");
DOMSpanElement.style.position = "absolute";
DOMSpanElement.style.whiteSpace = "pre";
DOMSpanElement.style.visibility = "visible";
DOMSpanElement.style.padding = "0px";
DOMSpanElement.style.margin = "0px";
DOMSpanElement.style.background = "red";
DOMIFrameDocument.getElementsByTagName("body")[0].appendChild(DOMSpanElement);
#endif
}
+ (CGSize)sizeOfString:(CPString)aString withFont:(CPFont)aFont forWidth:(float)aWidth
{
#if PLATFORM(DOM)
if (!aFont)
{
if (!DefaultFont)
DefaultFont = [CPFont systemFontOfSize:12.0];
aFont = DefaultFont;
}
var style = DOMSpanElement.style;
if (aWidth === NULL)
{
style.width = "";
style.whiteSpace = "pre";
}
else
{
style.width = ROUND(aWidth) + "px";
if (document.attachEvent)
style.wordWrap = "break-word";
else
{
style.whiteSpace = "-o-pre-wrap";
style.whiteSpace = "-pre-wrap";
style.whiteSpace = "-moz-pre-wrap";
style.whiteSpace = "pre-wrap";
}
}
style.font = [aFont cssString];
if (CPFeatureIsCompatible(CPJavascriptInnerTextFeature))
DOMSpanElement.innerText = aString;
else if (CPFeatureIsCompatible(CPJavascriptTextContentFeature))
DOMSpanElement.textContent = aString;
return _CGSizeMake(DOMSpanElement.clientWidth, DOMSpanElement.clientHeight);
#else
return _CGSizeMakeZero();
#endif
}
@end
#if PLATFORM(DOM)
#include "DOM/CPPlatformString.j"
#else
@implementation CPPlatformString : CPBasePlatformString
{
}
@end
#endif
+58 -2
View File
@@ -1,9 +1,31 @@
/*
* CPPlatformWindow.j
* AppKit
*
* Created by Francisco Tolmasky.
* 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 <Foundation/CPObject.j>
#import "Platform.h"
#import "../CoreGraphics/CGGeometry.h"
var PrimaryPlatformWindow = NULL;
@implementation CPPlatformWindow : CPObject
@@ -19,17 +41,23 @@ var PrimaryPlatformWindow = NULL;
DOMElement _DOMBodyElement;
DOMElement _DOMFocusElement;
DOMElement _DOMEventGuard;
CPArray _windowLevels;
CPDictionary _windowLayers;
BOOL _mouseIsDown;
BOOL _mouseDownIsRightClick;
CPWindow _mouseDownWindow;
CPTimeInterval _lastMouseUp;
CPTimeInterval _lastMouseDown;
Object _charCodes;
unsigned _keyCode;
unsigned _lastKey;
BOOL _capsLockActive;
BOOL _ignoreNativeCopyOrCutEvent;
BOOL _ignoreNativePastePreparation;
BOOL _DOMEventMode;
@@ -41,6 +69,20 @@ var PrimaryPlatformWindow = NULL;
#endif
}
+ (CPSet)visiblePlatformWindows
{
return [CPSet set];
}
+ (BOOL)supportsMultipleInstances
{
#if PLATFORM(DOM)
return !CPBrowserIsEngine(CPInternetExplorerBrowserEngine);
#else
return NO;
#endif
}
+ (CPPlatformWindow)primaryPlatformWindow
{
return PrimaryPlatformWindow;
@@ -95,7 +137,7 @@ var PrimaryPlatformWindow = NULL;
frame.origin = CGPointMakeZero();
if ([CPMenu menuBarVisible])
if ([CPMenu menuBarVisible] && [CPPlatformWindow primaryPlatformWindow] === self)
{
var menuBarHeight = [[CPApp mainMenu] menuBarHeight];
@@ -106,7 +148,7 @@ var PrimaryPlatformWindow = NULL;
return frame;
}
- (void)usableContentFrame
- (CGRect)usableContentFrame
{
return [self visibleFrame];
}
@@ -165,6 +207,20 @@ var PrimaryPlatformWindow = NULL;
#endif
}
- (void)moveWindow:(CPWindow)aWindow fromLevel:(int)fromLevel toLevel:(int)toLevel
{
#if PLATFORM(DOM)
if (!aWindow._isVisible)
return;
var fromLayer = [self layerAtLevel:fromLevel create:NO],
toLayer = [self layerAtLevel:toLevel create:YES];
[fromLayer removeWindow:aWindow];
[toLayer insertWindow:aWindow atIndex:CPNotFound];
#endif
}
- (void)setLevel:(CPInteger)aLevel
{
_level = aLevel;
+139
View File
@@ -0,0 +1,139 @@
/*
* CPPlatform+DOM.j
* AppKit
*
* Created by Francisco Tolmasky.
* 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
*/
if (typeof window["CPPlatformEnableHTMLDragAndDrop"] === "undefined")
CPPlatformEnableHTMLDragAndDrop = NO;
CPPlatformDidClearBodyElementNotification = @"CPPlatformDidClearBodyElementNotification";
CPPlatformWillClearBodyElementNotification = @"CPPlatformWillClearBodyElementNotification";
var screenNeedsInitialization = NO,
mainBodyElement = nil,
elementRemovalTest = new RegExp("\\bcpdontremove\\b", "g");
@implementation CPPlatform : CPBasePlatform
{
}
+ (void)initialize
{
if (self !== [CPPlatform class])
return;
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
{
return typeof window.cpIsDesktop === "undefined";
}
+ (BOOL)supportsDragAndDrop
{
return CPFeatureIsCompatible(CPHTMLDragAndDropFeature) && (CPPlatformEnableHTMLDragAndDrop || ![self isBrowser]);
}
+ (BOOL)supportsNativeMainMenu
{
return (typeof window["cpSetMainMenu"] === "function");
}
+ (void)terminateApplication
{
if (typeof window["cpTerminate"] === "function")
window.cpTerminate();
}
+ (void)activateIgnoringOtherApps:(BOOL)shouldIgnoreOtherApps
{
if (typeof window["cpActivateIgnoringOtherApps"] === "function")
window.cpActivateIgnoringOtherApps(!!shouldIgnoreOtherApps);
}
+ (void)deactivate
{
if (typeof window["cpDeactivate"] === "function")
window.cpDeactivate();
}
+ (void)hideOtherApplications:(id)aSender
{
if (typeof window["cpHideOtherApplications"] === "function")
window.cpHideOtherApplications();
}
+ (void)hide:(id)aSender
{
if (typeof window["cpHide"] === "function")
window.cpHide();
}
+ (DOMElement)mainBodyElement
{
if (!mainBodyElement)
mainBodyElement = document.getElementById("cappuccino-body") || document.body;
return mainBodyElement;
}
+ (void)initializeScreenIfNecessary
{
if (!screenNeedsInitialization)
return;
screenNeedsInitialization = NO;
[[CPNotificationCenter defaultCenter]
postNotificationName:CPPlatformWillClearBodyElementNotification
object:self];
var bodyElement = [self mainBodyElement];
// Get rid of any of the original contents of the page.
var children = bodyElement.childNodes,
length = children.length;
while (length--)
{
var element = children[length];
if (!element.className || element.className.match(elementRemovalTest) === null)
bodyElement.removeChild(element);
}
bodyElement.style.overflow = "hidden";
[[CPNotificationCenter defaultCenter]
postNotificationName:CPPlatformDidClearBodyElementNotification
object:self];
}
@end
+141
View File
@@ -0,0 +1,141 @@
/*
* CPPlatformString.j
* AppKit
*
* Created by Francisco Tolmasky.
* 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
*/
#include "../CoreGraphics/CGGeometry.h"
var DOMFixedWidthSpanElement = nil,
DOMFlexibleWidthSpanElement = nil,
DOMIFrameElement = nil,
DefaultFont = nil;
@implementation CPPlatformString : CPBasePlatformString
{
}
+ (void)bootstrap
{
[self createDOMElements];
}
+ (void)createDOMElements
{
var style;
DOMIFrameElement = document.createElement("iframe");
// necessary for Safari caching bug:
DOMIFrameElement.name = "iframe_" + FLOOR(RAND() * 10000);
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];
bodyElement.appendChild(DOMIFrameElement);
var DOMIFrameDocument = (DOMIFrameElement.contentDocument || DOMIFrameElement.contentWindow.document);
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();
// IE needs this wide <div> to prevent unwanted text wrapping:
var DOMDivElement = DOMIFrameDocument.createElement("div");
DOMDivElement.style.position = "absolute";
DOMDivElement.style.width = "100000px";
DOMIFrameDocument.body.appendChild(DOMDivElement);
DOMFlexibleWidthSpanElement = DOMIFrameDocument.createElement("span");
style = DOMFlexibleWidthSpanElement.style;
style.position = "absolute";
style.visibility = "visible";
style.padding = "0px";
style.margin = "0px";
style.whiteSpace = "pre";
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
{
if (!aFont)
{
if (!DefaultFont)
DefaultFont = [CPFont systemFontOfSize:12.0];
aFont = DefaultFont;
}
if (!DOMIFrameElement)
[self createDOMElements];
var span;
if (!aWidth)
span = DOMFlexibleWidthSpanElement;
else
{
span = DOMFixedWidthSpanElement;
span.style.width = ROUND(aWidth) + "px";
}
span.style.font = [aFont cssString];
if (CPFeatureIsCompatible(CPJavascriptInnerTextFeature))
span.innerText = aString;
else if (CPFeatureIsCompatible(CPJavascriptTextContentFeature))
span.textContent = aString;
return _CGSizeMake(span.clientWidth, span.clientHeight);
}
@end
+378 -180
View File
@@ -1,5 +1,5 @@
/*
* _CPDOMWindow.j
* CPPlatformWindow+DOM.j
* AppKit
*
* Created by Francisco Tolmasky.
@@ -66,7 +66,7 @@
* until the first key is released. This can cause a key event to be fired with
* a keyCode for the first key and a charCode for the second key.
*
* Safari in keypress
* Safari 2 in keypress (not supported)
*
* charCode keyCode which
* ENTER: 13 13 13
@@ -117,40 +117,30 @@
@import "CPPlatform.j"
@import "CPPlatformWindow.j"
@import "CPPlatformWindow+DOMKeys.j"
#import "../../CoreGraphics/CGGeometry.h"
var DoubleClick = "dblclick",
MouseDown = "mousedown",
MouseUp = "mouseup",
MouseMove = "mousemove",
MouseDrag = "mousedrag",
KeyUp = "keyup",
KeyDown = "keydown",
KeyPress = "keypress",
Copy = "copy",
Paste = "paste",
Resize = "resize",
ScrollWheel = "mousewheel",
TouchStart = "touchstart",
TouchMove = "touchmove",
TouchEnd = "touchend",
TouchCancel = "touchcancel";
// List of all open native windows
var PlatformWindows = [CPSet set];
// Define up here so compressor knows about em.
var CPDOMEventGetClickCount,
CPDOMEventStop,
StopDOMEventPropagation;
StopDOMEventPropagation,
StopContextMenuDOMEventPropagation;
//right now we hard code q, w, r and t as keys to propogate
//these aren't normal keycodes, they are with modifier key codes
//might be mac only, we should investigate futher later.
var KeyCodesToPrevent = {},
CharacterKeysToPrevent = {},
KeyCodesWithoutKeyPressEvents = { '8':1, '9':1, '16':1, '33':1, '34':1, '35':1, '36':1, '37':1, '38':1, '39':1, '40':1, '46':1, '33':1, '34':1 };
MozKeyCodeToKeyCodeMap = {
61: 187, // =, equals
59: 186 // ;, semicolon
};
var CTRL_KEY_CODE = 17;
KeyCodesToPrevent[CPKeyCodes.A] = YES;
var supportsNativeDragAndDrop = [CPPlatform supportsDragAndDrop];
@@ -239,39 +229,61 @@ var supportsNativeDragAndDrop = [CPPlatform supportsDragAndDrop];
_DOMWindow.blur();
}
- (void)registerDOMWindow
- (void)createDOMElements
{
var theDocument = _DOMWindow.document;
_DOMBodyElement = theDocument.getElementsByTagName("body")[0];
// FIXME: Always do this?
if ([CPPlatform supportsDragAndDrop])
_DOMBodyElement.style["-khtml-user-select"] = "none";
_DOMBodyElement.webkitTouchCallout = "none";
// This guy fixes an issue in Firefox where if you focus the URL field, we stop getting key events
_DOMFocusElement = theDocument.createElement("input");
_DOMFocusElement.style.position = "absolute";
_DOMFocusElement.style.zIndex = "-1000";
_DOMFocusElement.style.opacity = "0";
_DOMFocusElement.style.filter = "alpha(opacity=0)";
_DOMFocusElement.className = "cpdontremove";
_DOMBodyElement.appendChild(_DOMFocusElement);
// Create Native Pasteboard handler.
_DOMPasteboardElement = theDocument.createElement("input");
_DOMPasteboardElement = theDocument.createElement("textarea");
_DOMPasteboardElement.style.position = "absolute";
_DOMPasteboardElement.style.top = "-10000px";
_DOMPasteboardElement.style.zIndex = "99";
_DOMPasteboardElement.style.zIndex = "999";
_DOMPasteboardElement.className = "cpdontremove";
_DOMBodyElement.appendChild(_DOMPasteboardElement);
// Make sure the pastboard element is blurred.
_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
{
var theDocument = _DOMWindow.document;
_DOMBodyElement = theDocument.getElementById("cappuccino-body") || theDocument.body;
// FIXME: Always do this?
if (supportsNativeDragAndDrop)
_DOMBodyElement.style["-khtml-user-select"] = "none";
_DOMBodyElement.webkitTouchCallout = "none";
[self createDOMElements];
[self _addLayers];
var theClass = [self class],
@@ -283,6 +295,14 @@ var supportsNativeDragAndDrop = [CPPlatform supportsDragAndDrop];
resizeEventImplementation = class_getMethodImplementation(theClass, resizeEventSelector),
resizeEventCallback = function (anEvent) { resizeEventImplementation(self, nil, anEvent); },
copyEventSelector = @selector(copyEvent:),
copyEventImplementation = class_getMethodImplementation(theClass, copyEventSelector),
copyEventCallback = function (anEvent) {copyEventImplementation(self, nil, anEvent); },
pasteEventSelector = @selector(pasteEvent:),
pasteEventImplementation = class_getMethodImplementation(theClass, pasteEventSelector),
pasteEventCallback = function (anEvent) {pasteEventImplementation(self, nil, anEvent); },
keyEventSelector = @selector(keyEvent:),
keyEventImplementation = class_getMethodImplementation(theClass, keyEventSelector),
keyEventCallback = function (anEvent) { keyEventImplementation(self, nil, anEvent); },
@@ -291,6 +311,10 @@ var supportsNativeDragAndDrop = [CPPlatform supportsDragAndDrop];
mouseEventImplementation = class_getMethodImplementation(theClass, mouseEventSelector),
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:),
scrollEventImplementation = class_getMethodImplementation(theClass, scrollEventSelector),
scrollEventCallback = function (anEvent) { scrollEventImplementation(self, nil, anEvent); },
@@ -314,6 +338,11 @@ var supportsNativeDragAndDrop = [CPPlatform supportsDragAndDrop];
theDocument.addEventListener("mouseup", mouseEventCallback, NO);
theDocument.addEventListener("mousedown", mouseEventCallback, NO);
theDocument.addEventListener("mousemove", mouseEventCallback, NO);
theDocument.addEventListener("contextmenu", contextMenuEventCallback, NO);
theDocument.addEventListener("beforecopy", copyEventCallback, NO);
theDocument.addEventListener("beforecut", copyEventCallback, NO);
theDocument.addEventListener("beforepaste", pasteEventCallback, NO);
theDocument.addEventListener("keyup", keyEventCallback, NO);
theDocument.addEventListener("keydown", keyEventCallback, NO);
@@ -337,11 +366,16 @@ var supportsNativeDragAndDrop = [CPPlatform supportsDragAndDrop];
theDocument.removeEventListener("mouseup", mouseEventCallback, NO);
theDocument.removeEventListener("mousedown", mouseEventCallback, NO);
theDocument.removeEventListener("mousemove", mouseEventCallback, NO);
theDocument.removeEventListener("contextmenu", contextMenuEventCallback, NO);
theDocument.removeEventListener("keyup", keyEventCallback, NO);
theDocument.removeEventListener("keydown", keyEventCallback, NO);
theDocument.removeEventListener("keypress", keyEventCallback, NO);
theDocument.removeEventListener("beforecopy", copyEventCallback, NO);
theDocument.removeEventListener("beforecut", copyEventCallback, NO);
theDocument.removeEventListener("beforepaste", pasteEventCallback, NO);
theDocument.removeEventListener("touchstart", touchEventCallback, NO);
theDocument.removeEventListener("touchend", touchEventCallback, NO);
theDocument.removeEventListener("touchmove", touchEventCallback, NO);
@@ -354,6 +388,8 @@ var supportsNativeDragAndDrop = [CPPlatform supportsDragAndDrop];
//_DOMWindow.removeEventListener("beforeunload", this, NO);
[PlatformWindows removeObject:self];
self._DOMWindow = nil;
}, NO);
}
@@ -363,6 +399,7 @@ var supportsNativeDragAndDrop = [CPPlatform supportsDragAndDrop];
theDocument.attachEvent("onmousedown", mouseEventCallback);
theDocument.attachEvent("onmousemove", mouseEventCallback);
theDocument.attachEvent("ondblclick", mouseEventCallback);
theDocument.attachEvent("oncontextmenu", contextMenuEventCallback);
theDocument.attachEvent("onkeyup", keyEventCallback);
theDocument.attachEvent("onkeydown", keyEventCallback);
@@ -373,8 +410,8 @@ var supportsNativeDragAndDrop = [CPPlatform supportsDragAndDrop];
_DOMWindow.onmousewheel = scrollEventCallback;
theDocument.onmousewheel = scrollEventCallback;
theDocument.body.ondrag = function () { return NO; };
theDocument.body.onselectstart = function () { return _DOMWindow.event.srcElement === _DOMPasteboardElement; };
_DOMBodyElement.ondrag = function () { return NO; };
_DOMBodyElement.onselectstart = function () { return _DOMWindow.event.srcElement === _DOMPasteboardElement; };
_DOMWindow.attachEvent("onbeforeunload", function()
{
@@ -385,6 +422,7 @@ var supportsNativeDragAndDrop = [CPPlatform supportsDragAndDrop];
theDocument.detachEvent("onmousedown", mouseEventCallback);
theDocument.detachEvent("onmousemove", mouseEventCallback);
theDocument.detachEvent("ondblclick", mouseEventCallback);
theDocument.detachEvent("oncontextmenu", contextMenuEventCallback);
theDocument.detachEvent("onkeyup", keyEventCallback);
theDocument.detachEvent("onkeydown", keyEventCallback);
@@ -395,16 +433,30 @@ var supportsNativeDragAndDrop = [CPPlatform supportsDragAndDrop];
_DOMWindow.onmousewheel = NULL;
theDocument.onmousewheel = NULL;
theDocument.body.ondrag = NULL;
theDocument.body.onselectstart = NULL;
_DOMBodyElement.ondrag = NULL;
_DOMBodyElement.onselectstart = NULL;
//_DOMWindow.removeEvent("beforeunload", this);
[PlatformWindows removeObject:self];
self._DOMWindow = nil;
}, NO);
}
}
+ (CPSet)visiblePlatformWindows
{
if ([[CPPlatformWindow primaryPlatformWindow] isVisible])
{
var set = [CPSet setWithSet:PlatformWindows];
[set addObject:[CPPlatformWindow primaryPlatformWindow]];
return set;
}
else
return PlatformWindows;
}
- (void)orderFront:(id)aSender
{
if (_DOMWindow)
@@ -412,8 +464,10 @@ var supportsNativeDragAndDrop = [CPPlatform supportsDragAndDrop];
_DOMWindow = window.open("", "_blank", "menubar=no,location=no,resizable=yes,scrollbars=no,status=no,left=" + _CGRectGetMinX(_contentRect) + ",top=" + _CGRectGetMinY(_contentRect) + ",width=" + _CGRectGetWidth(_contentRect) + ",height=" + _CGRectGetHeight(_contentRect));
[PlatformWindows addObject:self];
// FIXME: cpSetFrame?
_DOMWindow.document.write("<html><head></head><body style = 'background-color:transparent;'></body></html>");
_DOMWindow.document.write("<!DOCTYPE html><html lang='en'><head></head><body style='background-color:transparent;'></body></html>");
_DOMWindow.document.close();
if (![CPPlatform isBrowser])
@@ -426,6 +480,8 @@ var supportsNativeDragAndDrop = [CPPlatform supportsDragAndDrop];
}
[self registerDOMWindow];
_DOMBodyElement.style.cursor = [[CPCursor currentCursor] _cssString];
}
- (void)orderOut:(id)aSender
@@ -458,11 +514,17 @@ var supportsNativeDragAndDrop = [CPPlatform supportsDragAndDrop];
DOMDragElement.style.left = -_CGRectGetWidth(draggedWindowFrame) + "px";
DOMDragElement.style.top = -_CGRectGetHeight(draggedWindowFrame) + "px";
document.getElementsByTagName("body")[0].appendChild(DOMDragElement);
var parentNode = DOMDragElement.parentNode;
if (parentNode)
parentNode.removeChild(DOMDragElement);
_DOMBodyElement.appendChild(DOMDragElement);
var draggingOffset = [dragServer draggingOffset];
aDOMEvent.dataTransfer.setDragImage(DOMDragElement, draggingOffset.width, draggingOffset.height);
aDOMEvent.dataTransfer.effectAllowed = "all";
[dragServer draggingStartedInPlatformWindow:self globalLocation:[CPPlatform isBrowser] ? location : _CGPointMake(aDOMEvent.screenX, aDOMEvent.screenY)];
}
@@ -538,12 +600,11 @@ var supportsNativeDragAndDrop = [CPPlatform supportsDragAndDrop];
(aDOMEvent.ctrlKey ? CPControlKeyMask : 0) |
(aDOMEvent.altKey ? CPAlternateKeyMask : 0) |
(aDOMEvent.metaKey ? CPCommandKeyMask : 0);
//We want to stop propagation if this is a command key AND this character or keycode has been added to our blacklist
StopDOMEventPropagation = !(modifierFlags & (CPControlKeyMask | CPCommandKeyMask)) ||
//We want to stop propagation if this is a command key AND this character or keycode has been added to our blacklist
StopDOMEventPropagation = !!(!(modifierFlags & (CPControlKeyMask | CPCommandKeyMask)) ||
CharacterKeysToPrevent[String.fromCharCode(aDOMEvent.keyCode || aDOMEvent.charCode).toLowerCase()] ||
KeyCodesToPrevent[aDOMEvent.keyCode];
KeyCodesToPrevent[aDOMEvent.keyCode]);
var isNativePasteEvent = NO,
isNativeCopyOrCutEvent = NO,
@@ -552,56 +613,80 @@ var supportsNativeDragAndDrop = [CPPlatform supportsDragAndDrop];
switch (aDOMEvent.type)
{
case "keydown": // Grab and store the keycode now since it is correct and consistent at this point.
_keyCode = aDOMEvent.keyCode;
if (aDOMEvent.keyCode.keyCode in MozKeyCodeToKeyCodeMap)
_keyCode = MozKeyCodeToKeyCodeMap[aDOMEvent.keyCode];
else
_keyCode = aDOMEvent.keyCode;
var characters = String.fromCharCode(_keyCode).toLowerCase();
overrideCharacters = modifierFlags & CPShiftKeyMask ? characters.toUpperCase() : characters;
// If this could be a native PASTE event, then we need to further examine it before
// sending a CPEvent. Select our element to see if anything gets pasted in it.
if (characters == "v" && (modifierFlags & CPPlatformActionKeyMask))
overrideCharacters = (modifierFlags & CPShiftKeyMask || _capsLockActive) ? characters.toUpperCase() : characters;
// check for caps lock state
if (_keyCode === CPKeyCodes.CAPS_LOCK)
_capsLockActive = YES;
if (modifierFlags & (CPControlKeyMask | CPCommandKeyMask))
{
_DOMPasteboardElement.select();
_DOMPasteboardElement.value = "";
isNativePasteEvent = YES;
//we are simply going to skip all keypress events that use cmd/ctrl key
//this lets us be consistent in all browsers and send on the keydown
//which means we can cancel the event early enough, but only if sendEvent needs to
var eligibleForCopyPaste = [self _validateCopyCutOrPasteEvent:aDOMEvent flags:modifierFlags];
// If this could be a native PASTE event, then we need to further examine it before
// sending a CPEvent. Select our element to see if anything gets pasted in it.
if (characters === "v" && eligibleForCopyPaste)
{
if (!_ignoreNativePastePreparation)
{
_DOMPasteboardElement.select();
_DOMPasteboardElement.value = "";
}
isNativePasteEvent = YES;
}
// However, of this could be a native COPY event, we need to let the normal event-process take place so it
// can capture our internal Cappuccino pasteboard.
else if ((characters == "c" || characters == "x") && eligibleForCopyPaste)
{
isNativeCopyOrCutEvent = YES;
if (_ignoreNativeCopyOrCutEvent)
break;
}
}
else if (CPKeyCodes.firesKeyPressEvent(_keyCode, _lastKey, aDOMEvent.shiftKey, aDOMEvent.ctrlKey, aDOMEvent.altKey))
{
// this branch is taken by events which fire keydown, keypress, and keyup.
// this is the only time we'll ALLOW character keys to propagate (needed for text fields)
StopDOMEventPropagation = NO;
break;
}
else
{
//this branch is taken by "remedial" key events
// In this state we continue to keypress and send the CPEvent
}
// Normally we return now because we let keypress send the actual CPEvent keyDown event, since we don't have
// a complete set of information yet.
// However, of this could be a native COPY event, we need to let the normal event-process take place so it
// can capture our internal Cappuccino pasteboard.
else if ((characters == "c" || characters == "x") && (modifierFlags & CPPlatformActionKeyMask))
isNativeCopyOrCutEvent = YES;
case "keypress":
// we unconditionally break on keypress events with modifiers,
// because we forced the event to be sent on the keydown
if (aDOMEvent.type === "keypress" && (modifierFlags & (CPControlKeyMask | CPCommandKeyMask)))
break;
// Also, certain browsers (IE and Safari), have broken keyboard supportwhere they don't send keypresses for certain events.
// So, allow the keypress event to handle the event if we are not a browser with broken (remedial) key support...
else if (!CPFeatureIsCompatible(CPJavascriptRemedialKeySupport))
return;
// Or, if this is not one of those special keycodes, and also not a ctrl+event
else if (!KeyCodesWithoutKeyPressEvents[_keyCode] && (_keyCode == CTRL_KEY_CODE || !(modifierFlags & CPControlKeyMask)))
return;
// If this is in fact our broke state, continue to keypress and send the keydown.
case "keypress": // If the source of this event is our pasteboard element, then simply let it continue
// as normal, so that the paste event can successfully complete.
if ((aDOMEvent.target || aDOMEvent.srcElement) == _DOMPasteboardElement)
return;
var keyCode = _keyCode,
charCode = aDOMEvent.keyCode || aDOMEvent.charCode,
isARepeat = (_charCodes[keyCode] != nil);
_lastKey = keyCode;
_charCodes[keyCode] = charCode;
var characters = overrideCharacters || String.fromCharCode(charCode),
charactersIgnoringModifiers = characters.toLowerCase();
// Safari won't send proper capitalization during cmd-key events
if (!overrideCharacters && (modifierFlags & CPCommandKeyMask) && (modifierFlags & CPShiftKeyMask))
if (!overrideCharacters && (modifierFlags & CPCommandKeyMask) && ((modifierFlags & CPShiftKeyMask) || _capsLockActive))
characters = characters.toUpperCase();
event = [CPEvent keyEventWithType:CPKeyDown location:location modifierFlags:modifierFlags
@@ -612,7 +697,6 @@ var supportsNativeDragAndDrop = [CPPlatform supportsDragAndDrop];
{
_pasteboardKeyDownEvent = event;
window.setNativeTimeout(function () { [self _checkPasteboardElement] }, 0);
return;
}
break;
@@ -620,12 +704,20 @@ var supportsNativeDragAndDrop = [CPPlatform supportsDragAndDrop];
case "keyup": var keyCode = aDOMEvent.keyCode,
charCode = _charCodes[keyCode];
_keyCode = -1;
_lastKey = -1;
_charCodes[keyCode] = nil;
_ignoreNativeCopyOrCutEvent = NO;
_ignoreNativePastePreparation = NO;
// check for caps lock state
if (keyCode === CPKeyCodes.CAPS_LOCK)
_capsLockActive = NO;
var characters = String.fromCharCode(charCode),
charactersIgnoringModifiers = characters.toLowerCase();
if (!(modifierFlags & CPShiftKeyMask))
if (!(modifierFlags & CPShiftKeyMask) && (modifierFlags & CPCommandKeyMask) && !_capsLockActive)
characters = charactersIgnoringModifiers;
event = [CPEvent keyEventWithType:CPKeyUp location:location modifierFlags:modifierFlags
@@ -633,40 +725,125 @@ var supportsNativeDragAndDrop = [CPPlatform supportsDragAndDrop];
characters:characters charactersIgnoringModifiers:charactersIgnoringModifiers isARepeat:NO keyCode:keyCode];
break;
}
if (event)
if (event && !isNativePasteEvent)
{
event._DOMEvent = aDOMEvent;
[CPApp sendEvent:event];
if (isNativeCopyOrCutEvent)
{
var pasteboard = [CPPasteboard generalPasteboard],
types = [pasteboard types];
// If this is a native copy event, then check if the pasteboard has anything in it.
if (types.length)
{
if ([types indexOfObjectIdenticalTo:CPStringPboardType] != CPNotFound)
_DOMPasteboardElement.value = [pasteboard stringForType:CPStringPboardType];
else
_DOMPasteboardElement.value = [pasteboard _generateStateUID];
_DOMPasteboardElement.select();
window.setNativeTimeout(function() { [self _clearPasteboardElement]; }, 0);
}
return;
[self _primePasteboardElement];
}
}
if (StopDOMEventPropagation)
CPDOMEventStop(aDOMEvent, self);
[[CPRunLoop currentRunLoop] limitDateForMode:CPDefaultRunLoopMode];
[[CPRunLoop currentRunLoop] limitDateForMode:CPDefaultRunLoopMode];
}
- (void)copyEvent:(DOMEvent)aDOMEvent
{
if ([self _validateCopyCutOrPasteEvent:aDOMEvent flags:CPPlatformActionKeyMask] && !_ignoreNativeCopyOrCutEvent)
{
//we have to send out a fake copy or cut event so that we can force the copy/cut mechanisms to take place
var cut = aDOMEvent.type === "beforecut",
keyCode = cut ? CPKeyCodes.X : CPKeyCodes.C,
characters = cut ? "x" : "c",
timestamp = aDOMEvent.timeStamp ? aDOMEvent.timeStamp : new Date(),
windowNumber = [[CPApp keyWindow] windowNumber],
modifierFlags = CPPlatformActionKeyMask;
event = [CPEvent keyEventWithType:CPKeyDown location:location modifierFlags:modifierFlags
timestamp:timestamp windowNumber:windowNumber context:nil
characters:characters charactersIgnoringModifiers:characters isARepeat:NO keyCode:keyCode];
event._DOMEvent = aDOMEvent;
[CPApp sendEvent:event];
[self _primePasteboardElement];
//then we have to IGNORE the real keyboard event to prevent a double copy
//safari also sends the beforecopy event twice, so we additionally check here and prevent two events
_ignoreNativeCopyOrCutEvent = YES;
}
[[CPRunLoop currentRunLoop] limitDateForMode:CPDefaultRunLoopMode];
}
- (void)pasteEvent:(DOMEvent)aDOMEvent
{
if ([self _validateCopyCutOrPasteEvent:aDOMEvent flags:CPPlatformActionKeyMask])
{
_DOMPasteboardElement.focus();
_DOMPasteboardElement.select();
_DOMPasteboardElement.value = "";
_ignoreNativePastePreparation = YES;
}
[[CPRunLoop currentRunLoop] limitDateForMode:CPDefaultRunLoopMode];
}
- (void)_validateCopyCutOrPasteEvent:(DOMEvent)aDOMEvent flags:(unsigned)modifierFlags
{
return (
((aDOMEvent.target || aDOMEvent.srcElement).nodeName.toUpperCase() !== "INPUT" &&
(aDOMEvent.target || aDOMEvent.srcElement).nodeName.toUpperCase() !== "TEXTAREA"
) || aDOMEvent.target === _DOMPasteboardElement
) &&
(modifierFlags & CPPlatformActionKeyMask);
}
- (void)_primePasteboardElement
{
var pasteboard = [CPPasteboard generalPasteboard],
types = [pasteboard types];
if (types.length)
{
if ([types indexOfObjectIdenticalTo:CPStringPboardType] != CPNotFound)
_DOMPasteboardElement.value = [pasteboard stringForType:CPStringPboardType];
else
_DOMPasteboardElement.value = [pasteboard _generateStateUID];
_DOMPasteboardElement.focus();
_DOMPasteboardElement.select();
window.setNativeTimeout(function() { [self _clearPasteboardElement]; }, 0);
}
}
- (void)_checkPasteboardElement
{
var value = _DOMPasteboardElement.value;
if ([value length])
{
var pasteboard = [CPPasteboard generalPasteboard];
if ([pasteboard _stateUID] != value)
{
[pasteboard declareTypes:[CPStringPboardType] owner:self];
[pasteboard setString:value forType:CPStringPboardType];
}
}
[self _clearPasteboardElement];
[CPApp sendEvent:_pasteboardKeyDownEvent];
_pasteboardKeyDownEvent = nil;
[[CPRunLoop currentRunLoop] limitDateForMode:CPDefaultRunLoopMode];
}
- (void)_clearPasteboardElement
{
_DOMPasteboardElement.value = "";
_DOMPasteboardElement.blur();
}
- (void)scrollEvent:(DOMEvent)aDOMEvent
@@ -674,12 +851,13 @@ var supportsNativeDragAndDrop = [CPPlatform supportsDragAndDrop];
if(!aDOMEvent)
aDOMEvent = window.event;
var location = nil;
if (CPFeatureIsCompatible(CPJavaScriptMouseWheelValues_8_15))
{
var x = 0.0,
y = 0.0,
var x = aDOMEvent._offsetX || 0.0,
y = aDOMEvent._offsetY || 0.0,
element = aDOMEvent.target;
while (element.nodeType !== 1)
element = element.parentNode;
@@ -693,11 +871,13 @@ var supportsNativeDragAndDrop = [CPPlatform supportsDragAndDrop];
} while (element = element.offsetParent);
}
var location = _CGPointMake((x + ((aDOMEvent.clientX - 8) / 15)), (y + ((aDOMEvent.clientY - 8) / 15)));
location = _CGPointMake((x + ((aDOMEvent.clientX - 8) / 15)), (y + ((aDOMEvent.clientY - 8) / 15)));
}
else if (aDOMEvent._overrideLocation)
location = aDOMEvent._overrideLocation;
else
var location = _CGPointMake(aDOMEvent.clientX, aDOMEvent.clientY);
location = _CGPointMake(aDOMEvent.clientX, aDOMEvent.clientY);
var deltaX = 0.0,
deltaY = 0.0,
windowNumber = 0,
@@ -706,7 +886,7 @@ var supportsNativeDragAndDrop = [CPPlatform supportsDragAndDrop];
(aDOMEvent.ctrlKey ? CPControlKeyMask : 0) |
(aDOMEvent.altKey ? CPAlternateKeyMask : 0) |
(aDOMEvent.metaKey ? CPCommandKeyMask : 0);
StopDOMEventPropagation = YES;
var theWindow = [self hitTest:location];
@@ -750,7 +930,7 @@ var supportsNativeDragAndDrop = [CPPlatform supportsDragAndDrop];
if (StopDOMEventPropagation)
CPDOMEventStop(aDOMEvent, self);
[[CPRunLoop currentRunLoop] limitDateForMode:CPDefaultRunLoopMode];
}
@@ -760,6 +940,9 @@ var supportsNativeDragAndDrop = [CPPlatform supportsDragAndDrop];
// We should pay attention to mouse down and mouse up in conjunction with this.
//window.liveResize = YES;
if ([CPPlatform isBrowser])
[CPApp._activeMenu cancelTracking];
var oldSize = [self contentRect].size;
[self updateFromNativeContentRect];
@@ -878,11 +1061,12 @@ var supportsNativeDragAndDrop = [CPPlatform supportsDragAndDrop];
{
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;
_lastMouseUp = event;
_mouseDownWindow = nil;
_mouseDownIsRightClick = NO;
}
if(_DOMEventMode)
@@ -922,8 +1106,13 @@ var supportsNativeDragAndDrop = [CPPlatform supportsDragAndDrop];
_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;
_lastMouseDown = event;
}
@@ -933,7 +1122,7 @@ var supportsNativeDragAndDrop = [CPPlatform supportsDragAndDrop];
if (_DOMEventMode)
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];
@@ -948,13 +1137,24 @@ var supportsNativeDragAndDrop = [CPPlatform supportsDragAndDrop];
if (StopDOMEventPropagation && (!supportsNativeDragAndDrop || type !== "mousedown" && !isDragging))
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];
}
(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];
if (!layer)
return [];
@@ -964,7 +1164,7 @@ var supportsNativeDragAndDrop = [CPPlatform supportsDragAndDrop];
- (CPDOMWindowLayer)layerAtLevel:(int)aLevel create:(BOOL)aFlag
{
var layer = [_windowLayers objectForKey:aLevel];
// If the layer doesn't currently exist, and the create flag is true,
// create the layer.
if (!layer && aFlag)
@@ -972,7 +1172,7 @@ var supportsNativeDragAndDrop = [CPPlatform supportsDragAndDrop];
layer = [[CPDOMWindowLayer alloc] initWithLevel:aLevel];
[_windowLayers setObject:layer forKey:aLevel];
// Find the nearest layer. This is similar to a binary search,
// only we know we won't find the value.
var low = 0,
@@ -989,8 +1189,13 @@ var supportsNativeDragAndDrop = [CPPlatform supportsDragAndDrop];
low = middle + 1;
}
[_windowLevels insertObject:aLevel atIndex:_windowLevels[middle] > aLevel ? middle : middle + 1];
var insertionIndex = 0;
if (middle !== undefined)
insertionIndex = _windowLevels[middle] > aLevel ? middle : middle + 1
[_windowLevels insertObject:aLevel atIndex:insertionIndex];
layer._DOMElement.style.zIndex = aLevel;
_DOMBodyElement.appendChild(layer._DOMElement);
}
@@ -999,17 +1204,23 @@ var supportsNativeDragAndDrop = [CPPlatform supportsDragAndDrop];
- (void)order:(CPWindowOrderingMode)aPlace window:(CPWindow)aWindow relativeTo:(CPWindow)otherWindow
{
[CPPlatform initializeScreenIfNecessary];
// Grab the appropriate level for the layer, and create it if
// necessary (if we are not simply removing the window).
var layer = [self layerAtLevel:[aWindow level] create:aPlace != CPWindowOut];
var layer = [self layerAtLevel:[aWindow level] create:aPlace !== CPWindowOut];
// Ignore otherWindow, simply remove this window from it's level.
// If layer is nil, this will be a no-op.
if (aPlace == CPWindowOut)
if (aPlace === CPWindowOut)
return [layer removeWindow:aWindow];
var insertionIndex = CPNotFound;
if (otherWindow)
insertionIndex = aPlace === CPWindowAbove ? otherWindow._index + 1 : otherWindow._index;
// Place the window at the appropriate index.
[layer insertWindow:aWindow atIndex:(otherWindow ? (aPlace == CPWindowAbove ? otherWindow._index + 1 : otherWindow._index) : CPNotFound)];
[layer insertWindow:aWindow atIndex:insertionIndex];
}
- (void)_removeLayers
@@ -1077,8 +1288,29 @@ var supportsNativeDragAndDrop = [CPPlatform supportsDragAndDrop];
StopDOMEventPropagation = !aFlag;
}
- (BOOL)_willPropagateCurrentDOMEvent
{
return !StopDOMEventPropagation;
}
- (void)_propagateContextMenuDOMEvent:(BOOL)aFlag
{
if (aFlag && CPBrowserIsEngine(CPGeckoBrowserEngine))
StopDOMEventPropagation = !aFlag;
StopContextMenuDOMEventPropagation = !aFlag;
}
- (BOOL)_willPropagateContextMenuDOMEvent
{
return StopContextMenuDOMEventPropagation;
}
- (CPWindow)hitTest:(CPPoint)location
{if (self._only) return self._only;
{
if (self._only)
return self._only;
var levels = _windowLevels,
layers = _windowLayers,
levelCount = levels.length,
@@ -1101,37 +1333,6 @@ var supportsNativeDragAndDrop = [CPPlatform supportsDragAndDrop];
return theWindow;
}
- (void)_checkPasteboardElement
{
var value = _DOMPasteboardElement.value;
if ([value length])
{
var pasteboard = [CPPasteboard generalPasteboard];
if ([pasteboard _stateUID] != value)
{
[pasteboard declareTypes:[CPStringPboardType] owner:self];
[pasteboard setString:value forType:CPStringPboardType];
}
}
[self _clearPasteboardElement];
[CPApp sendEvent:_pasteboardKeyDownEvent];
_pasteboardKeyDownEvent = nil;
[[CPRunLoop currentRunLoop] limitDateForMode:CPDefaultRunLoopMode];
}
- (void)_clearPasteboardElement
{
_DOMPasteboardElement.value = "";
_DOMPasteboardElement.blur();
}
/*!
When using command (mac) or control (windows), keys are propagated to the browser by default.
To prevent a character key from propagating (to prevent its default action, and instead use it
@@ -1247,19 +1448,25 @@ var CPDOMEventStop = function(aDOMEvent, aPlatformWindow)
function CPWindowObjectList()
{
var platformWindow = [CPPlatformWindow primaryPlatformWindow],
levels = platformWindow._windowLevels,
layers = platformWindow._windowLayers,
levelCount = levels.length,
var platformWindows = [CPPlatformWindow visiblePlatformWindows],
platformWindowEnumerator = [platformWindows objectEnumerator],
platformWindow = nil,
windowObjects = [];
while (levelCount--)
while (platformWindow = [platformWindowEnumerator nextObject])
{
var windows = [layers objectForKey:levels[levelCount]]._windows,
windowCount = windows.length;
var levels = platformWindow._windowLevels,
layers = platformWindow._windowLayers,
levelCount = levels.length;
while (windowCount--)
windowObjects.push(windows[windowCount]);
while (levelCount--)
{
var windows = [layers objectForKey:levels[levelCount]]._windows,
windowCount = windows.length;
while (windowCount--)
windowObjects.push(windows[windowCount]);
}
}
return windowObjects;
@@ -1267,20 +1474,11 @@ function CPWindowObjectList()
function CPWindowList()
{
var platformWindow = [CPPlatformWindow primaryPlatformWindow],
levels = platformWindow._windowLevels,
layers = platformWindow._windowLayers,
levelCount = levels.length,
windowNumbers = [];
var windowObjectList = CPWindowObjectList(),
windowList = [];
while (levelCount--)
{
var windows = [layers objectForKey:levels[levelCount]]._windows,
windowCount = windows.length;
for (var i = 0, count = [windowObjectList count]; i < count; i++)
windowList.push([windowObjectList[i] windowNumber]);
while (windowCount--)
windowNumbers.push([windows[windowCount] windowNumber]);
}
return windowNumbers;
return windowList;
}
@@ -0,0 +1,231 @@
/*
* CPPlatformWindow+DOMKeys.j
* AppKit
*
* Created by Ross Boucher.
* Copyright 2009, 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
*/
// Keycodes taken and modified from Google Closure, available under Apache 2 License
CPKeyCodes = {
BACKSPACE: 8,
TAB: 9,
NUM_CENTER: 12,
ENTER: 13,
SHIFT: 16,
CTRL: 17,
ALT: 18,
PAUSE: 19,
CAPS_LOCK: 20,
ESC: 27,
SPACE: 32,
PAGE_UP: 33, // also NUM_NORTH_EAST
PAGE_DOWN: 34, // also NUM_SOUTH_EAST
END: 35, // also NUM_SOUTH_WEST
HOME: 36, // also NUM_NORTH_WEST
LEFT: 37, // also NUM_WEST
UP: 38, // also NUM_NORTH
RIGHT: 39, // also NUM_EAST
DOWN: 40, // also NUM_SOUTH
PRINT_SCREEN: 44,
INSERT: 45, // also NUM_INSERT
DELETE: 46, // also NUM_DELETE
ZERO: 48,
ONE: 49,
TWO: 50,
THREE: 51,
FOUR: 52,
FIVE: 53,
SIX: 54,
SEVEN: 55,
EIGHT: 56,
NINE: 57,
QUESTION_MARK: 63, // needs localization
A: 65,
B: 66,
C: 67,
D: 68,
E: 69,
F: 70,
G: 71,
H: 72,
I: 73,
J: 74,
K: 75,
L: 76,
M: 77,
N: 78,
O: 79,
P: 80,
Q: 81,
R: 82,
S: 83,
T: 84,
U: 85,
V: 86,
W: 87,
X: 88,
Y: 89,
Z: 90,
META: 91,
CONTEXT_MENU: 93,
NUM_ZERO: 96,
NUM_ONE: 97,
NUM_TWO: 98,
NUM_THREE: 99,
NUM_FOUR: 100,
NUM_FIVE: 101,
NUM_SIX: 102,
NUM_SEVEN: 103,
NUM_EIGHT: 104,
NUM_NINE: 105,
NUM_MULTIPLY: 106,
NUM_PLUS: 107,
NUM_MINUS: 109,
NUM_PERIOD: 110,
NUM_DIVISION: 111,
F1: 112,
F2: 113,
F3: 114,
F4: 115,
F5: 116,
F6: 117,
F7: 118,
F8: 119,
F9: 120,
F10: 121,
F11: 122,
F12: 123,
NUMLOCK: 144,
SEMICOLON: 186, // needs localization
DASH: 189, // needs localization
EQUALS: 187, // needs localization
COMMA: 188, // needs localization
PERIOD: 190, // needs localization
SLASH: 191, // needs localization
APOSTROPHE: 192, // needs localization
SINGLE_QUOTE: 222, // needs localization
OPEN_SQUARE_BRACKET: 219, // needs localization
BACKSLASH: 220, // needs localization
CLOSE_SQUARE_BRACKET: 221, // needs localization
WIN_KEY: 224,
MAC_FF_META: 224, // Firefox (Gecko) fires this for the meta key instead of 91
WIN_IME: 229
};
/*!
* Returns true if the key fires a keypress event in the current browser.
*
* Accoridng to MSDN [1] IE only fires keypress events for the following keys:
* - Letters: A - Z (uppercase and lowercase)
* - Numerals: 0 - 9
* - Symbols: ! @ # $ % ^ & * ( ) _ - + = < [ ] { } , . / ? \ | ' ` " ~
* - System: ESC, SPACEBAR, ENTER
*
* That's not entirely correct though, for instance there's no distinction
* between upper and lower case letters.
*
* [1] http://msdn2.microsoft.com/en-us/library/ms536939(VS.85).aspx)
*
* Safari is similar to IE, but does not fire keypress for ESC.
*
* Additionally, IE6 does not fire keydown or keypress events for letters when
* the control or alt keys are held down and the shift key is not. IE7 does
* fire keydown in these cases, though, but not keypress.
*
* @param keyCode A key code.
* @param opt_heldKeyCode Key code of a currently-held key.
* @param opt_shiftKey Whether the shift key is held down.
* @param opt_ctrlKey Whether the control key is held down.
* @param opt_altKey Whether the alt key is held down.
* @return Returns YES if it's a key that fires a keypress event.
*/
CPKeyCodes.firesKeyPressEvent = function(keyCode, opt_heldKeyCode, opt_shiftKey, opt_ctrlKey, opt_altKey)
{
if (!CPFeatureIsCompatible(CPJavascriptRemedialKeySupport))
return true;
if (CPBrowserIsOperatingSystem(CPMacOperatingSystem) && opt_altKey)
return CPKeyCodes.isCharacterKey(keyCode);
// Alt but not AltGr which is represented as Alt+Ctrl.
if (opt_altKey && !opt_ctrlKey)
return false;
// Saves Ctrl or Alt + key for IE7, which won't fire keypress.
if (CPBrowserIsEngine(CPInternetExplorerBrowserEngine) && !opt_shiftKey && (opt_ctrlKey || opt_altKey))
return false;
// When Ctrl+<somekey> is held in IE, it only fires a keypress once, but it
// continues to fire keydown events as the event repeats.
if (CPBrowserIsEngine(CPInternetExplorerBrowserEngine) && opt_ctrlKey && opt_heldKeyCode == keyCode)
return false;
switch (keyCode)
{
case CPKeyCodes.ENTER: return true;
case CPKeyCodes.ESC: return !CPBrowserIsEngine(CPWebKitBrowserEngine);
}
return CPKeyCodes.isCharacterKey(keyCode);
};
/*!
* Test for whether or not a given keyCode represents a character key.
*
* @param keyCode A key code.
* @return Returns YES if the keyCode is a character key.
*/
CPKeyCodes.isCharacterKey = function(keyCode)
{
if (keyCode >= CPKeyCodes.ZERO && keyCode <= CPKeyCodes.NINE)
return true;
if (keyCode >= CPKeyCodes.NUM_ZERO && keyCode <= CPKeyCodes.NUM_MULTIPLY)
return true;
if (keyCode >= CPKeyCodes.A && keyCode <= CPKeyCodes.Z)
return true;
switch (keyCode)
{
case CPKeyCodes.SPACE:
case CPKeyCodes.QUESTION_MARK:
case CPKeyCodes.NUM_PLUS:
case CPKeyCodes.NUM_MINUS:
case CPKeyCodes.NUM_PERIOD:
case CPKeyCodes.NUM_DIVISION:
case CPKeyCodes.SEMICOLON:
case CPKeyCodes.DASH:
case CPKeyCodes.EQUALS:
case CPKeyCodes.COMMA:
case CPKeyCodes.PERIOD:
case CPKeyCodes.SLASH:
case CPKeyCodes.APOSTROPHE:
case CPKeyCodes.SINGLE_QUOTE:
case CPKeyCodes.OPEN_SQUARE_BRACKET:
case CPKeyCodes.BACKSLASH:
case CPKeyCodes.CLOSE_SQUARE_BRACKET:
return true;
default:
return false;
}
}
File diff suppressed because one or more lines are too long
Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

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