Compare commits

...
118 Commits
Author SHA1 Message Date
Ross Boucher 16a70c5c8e Update to the starter package readme. 2011-02-22 14:09:09 -08:00
Randall Luecke b78eddd878 Clearer explaination of setPullsDown: of CPPopupButton 2011-02-04 19:01:12 -05:00
Randall Luecke 203942d123 Documentation of CPApplication. 2011-01-30 16:56:56 -05:00
Klaas Pieter Annema 5957e71967 enable nib2cib image support for CPMenuItem 2011-01-28 14:50:42 +01:00
Randall Luecke fdf47eb84e Fix for tableview reloadData call inside setObjectValue: causing additional editing to being. 2011-01-27 14:37:26 -05:00
Paul Baumgart 6963b37f61 Add --clone-http option to bootstrap 2011-01-26 21:09:10 -08:00
Ayal SpitzandPaul Baumgart 379c5294c2 Added a 'clone_http' flag to enable clonging of a git repo via http 2011-01-26 20:57:42 -08:00
Francisco Ryan Tolmasky I fb27f86126 Merge branch 'paulbaumgart-bootstrap-fixes' 2011-01-26 08:03:24 -08:00
Klaas Pieter Annema 133dd39485 don't blur input element more than once 2011-01-26 11:03:09 +01:00
Paul Baumgart d50cbb02e6 Allow users to respond 'yes' to the narwhal install location bootstrap prompt to just use the default location. 2011-01-25 17:39:24 -08:00
Randall Luecke 30695e4110 Document delete key delegate in tableview. 2011-01-25 11:03:12 -05:00
Jürgen Kartnaller 3e79d8324d Fix check for allowsReverseTransformation in reverseTransformedValue 2011-01-25 08:46:40 +01:00
Randall Luecke 71de04787d Fix backspace issue with textfield. Closes #1107. Thanks to Jukart for the patch. 2011-01-24 18:25:18 -05:00
Randall Luecke 81332fa57e Proper theme states for the tableview edit change I made yesterday. 2011-01-24 15:35:10 -05:00
Randall Luecke 191a02a89b Update documentation version number to 0.9. 2011-01-24 14:28:07 -05:00
Ross Boucher f4ae6c450b Update the README a bit. 2011-01-24 10:19:52 -08:00
Alexander Ljungberg f2c53c9f52 Documentation tweaks. 2011-01-24 14:00:15 -03:00
Alexander Ljungberg 090fcab8c6 More globals fixing. 2011-01-24 13:43:55 -03:00
Alexander Ljungberg d3836c2a52 Global fixes. 2011-01-24 13:22:07 -03:00
Alexander Ljungberg ea8c29356d More typo and formatting fixes. 2011-01-24 13:17:48 -03:00
Stephen Ierodiaconou 6a942630e4 Fixing spelling mistakes 2011-01-24 11:05:48 +02:00
Randall Luecke 2aa806e52a Docs for CPControl. 2011-01-24 01:18:40 -05:00
Randall Luecke 04f1b61534 Fixes to tableview inline editing. 2011-01-24 00:56:39 -05:00
Randall Luecke b6119a763e Docs for CPWebView. 2011-01-23 19:05:02 -05:00
Randall Luecke 0876fd6db9 Docs of CPViewAnimation. 2011-01-23 18:10:26 -05:00
Randall Luecke 3d106c0716 Merge branch 'master' of git://github.com/280north/cappuccino 2011-01-23 17:53:20 -05:00
Randall Luecke c390b19d4b Much needed documentation of CPSplitView and some docs for CPWindow. 2011-01-23 17:50:39 -05:00
Francisco Ryan Tolmasky I 6a735ecda9 Merge branch 'master' of github.com:280north/cappuccino 2011-01-23 08:44:01 -08:00
Francisco Ryan Tolmasky I aada884cff A few import fixes.
Reviewed by me.
2011-01-23 08:43:46 -08:00
Paul Baumgart b62789bb18 Check for one of curl or wget. 2011-01-21 17:35:33 -08:00
Paul Baumgart eafec339f1 Minor update to bootstrap to have it check to make sure java is installed. 2011-01-21 16:49:32 -08:00
Alexander Ljungberg ef326dbbb4 Fix an accidental global, whitespace. 2011-01-20 22:33:42 -03:00
Alexander Ljungberg 4bbbcb15f1 Array controller documentation. 2011-01-20 22:27:09 -03:00
Alexander Ljungberg 92cb69b623 Merge branch 'CPArrayControllerFixes' of https://github.com/cacaodev/cappuccino into cacaodev-CPArrayControllerFixes 2011-01-20 22:14:17 -03:00
Alexander Ljungberg 18ea086ffc Removed unused Aristo files. 2011-01-20 22:13:01 -03:00
Alexander Ljungberg 40b04b7956 Merge branch 'master' of github.com:280north/cappuccino into cacaodev-CPTableColumnValueBinder
Conflicts:
	AppKit/CPTableColumn.j
2011-01-20 21:56:30 -03:00
Francisco Ryan Tolmasky I 38dc125fc2 Fix CPSubclassableDictionaryTest.
Reviewed by me.
2011-01-20 09:50:32 -08:00
Francisco Ryan Tolmasky I 378df68995 Merge branch 'master' of github.com:280north/cappuccino 2011-01-20 09:17:29 -08:00
Francisco Ryan Tolmasky I ec330a1090 Fix for pop up not reflecting changes in individual menu items.
Reviewed by me.
2011-01-20 09:07:04 -08:00
Randall Luecke f07543045a Doc fixes and more docs in the tableview. 2011-01-20 03:07:01 -05:00
Paul Baumgart 4458884048 Fallback to wget if curl isn't installed. 2011-01-19 20:28:49 -08:00
Paul Baumgart 7245fb99a6 Check to make sure SSL is working in tusk and advise on how to fix it otherwise. 2011-01-19 20:27:16 -08:00
Paul BaumgartandPaul Baumgart 5d27661354 Update check_build_environment in bootstrap
Newer versions of OpenJDK can handle running Narwhal.
It seems the problem is fixed in versions of OpenJDK 6 >= b18.
This commit checks for a sufficiently recent version of
OpenJDK and only prints an error/exits if the OpenJDK
version is older than 6b18.
2011-01-19 20:26:28 -08:00
Francisco Ryan Tolmasky I b33b2df778 Merge branch 'master' of github.com:280north/cappuccino 2011-01-19 19:30:46 -08:00
Francisco Ryan Tolmasky I d2f27408a5 Additional fix for archived CPPopUpButtons, and backwards compatibility support for old archives/cibs.
Reviewed by me.
2011-01-19 19:29:39 -08:00
cacaodev 235b323658 Add CPTableColumnValueBinder. This binder subclass just reloads the table column when a table column's value binding is updated because of a change in the bound-to object.
TableBindings test.
2011-01-19 19:56:46 +01:00
cacaodev 54c3cc0187 CPArrayController & nib2cib: added _automaticallyRearrangeObjects flag (not used currently).
_sortDescriptors initial value is an emty array (like in cocoa), not nil;
Added shared _init with default values, added missing accessors.
2011-01-19 19:26:21 +01:00
cacaodev 59cc590b51 CPArrayController -setContent: fixed a bug where objects where not rearranged if clearsFilterPredicateOnInsertion == YES and filterPredicate == nil. 2011-01-19 19:26:01 +01:00
Randall Luecke 66a87c472b Remove old resources from the old CPTabView. 2011-01-19 11:15:31 -05:00
Francisco Ryan Tolmasky I 688aed72cb Fix for CPPopUpButton's encoded prior to CPResponder/menu change.
Reviewed by me.
2011-01-18 23:09:43 -08:00
Francisco Ryan Tolmasky I 6310733881 Fix for menu bar color being reset (+ [CPMenu initialize] didn't check the class).
Reviewed by me.
2011-01-18 13:59:57 -08:00
Francisco Ryan Tolmasky I 3fe505b8e5 Merge branch 'master' of github.com:280north/cappuccino 2011-01-18 13:26:14 -08:00
Francisco Ryan Tolmasky I 00915083d4 Quick fix for initWithCapacity: not working on CPMutableArray.
Reviewed by me.
2011-01-18 13:25:43 -08:00
Klaas Pieter Annema 4e1ecbef72 Merge branch 'CPTextField-InterpretKeyEvents' of https://github.com/luuse/cappuccino into luuse-CPTextField-InterpretKeyEvents
Conflicts:
	AppKit/CPSearchField.j
	AppKit/CPTextField.j
2011-01-18 10:07:16 +01:00
Klaas Pieter Annema e4f6214005 Merge branch 'imports' of https://github.com/stevegeek/cappuccino into stevegeek-imports 2011-01-18 09:52:40 +01:00
Klaas Pieter Annema ed98a44116 detect sort descriptors when table column is added 2011-01-18 09:29:29 +01:00
Klaas Pieter Annema 50d36e76ac reverse set sort descriptors in CPTableView 2011-01-18 09:29:28 +01:00
Randall Luecke 818bf475f2 New gradient color to match aristo better. 2011-01-17 23:30:29 -05:00
Randall Luecke 47afb96c4c Drawing fixes for the tableview gradient. 2011-01-17 23:30:04 -05:00
Randall Luecke 467dc3c2d5 OutlineView docs. 2011-01-17 20:13:54 -05:00
Randall Luecke 7e3079add6 Magic enable to outlineview variable item height 2011-01-17 20:07:15 -05:00
Francisco Ryan Tolmasky I 9796f5d5d7 Fix CPPopUpButton menu support.
- Added enumerateObjectsUsingBlock: to CPArray
- Fixed a remaining case of [] being used instead of objectAtIndex: in CPMutableArray.
- Added KVO support for menu items array in menus.
- Changed CPPopUpButton to use KVO to sync up with menu instead of notifications.
- Removed extra menu encoding in CPPopUpButton.
- Removed extra mainMenu object from CPApplication.
- Use setters in CPResponder instead of direct ivar access in initWithCoder:.

Closes #298.
Closes $1059.

Reviewed by me.
2011-01-17 01:31:15 -08:00
Stephen Ierodiaconou 37323b811c Merge branch 'master' of git://github.com/280north/cappuccino into imports
Conflicts:
	Foundation/CPDecimalNumber.j
	Foundation/CPPredicate/CPComparisonPredicate.j
	Foundation/CPPredicate/CPCompoundPredicate.j
	Foundation/CPPredicate/CPExpression.j
	Foundation/CPPredicate/CPExpression_aggregate.j
	Foundation/CPPredicate/CPExpression_constant.j
	Foundation/CPPredicate/CPExpression_function.j
	Foundation/CPPredicate/CPExpression_keypath.j
	Foundation/CPPredicate/CPExpression_self.j
	Foundation/CPPredicate/CPExpression_set.j
	Foundation/CPPredicate/CPExpression_subquery.j
	Foundation/CPPredicate/CPExpression_variable.j
	Foundation/CPPredicate/CPPredicate.j
2011-01-16 10:03:42 +02:00
Randall Luecke 8720a952b0 Fix for scrollview flashing while uniformly resizing columns. Closes #1075 2011-01-16 00:23:14 -05:00
Randall Luecke bf4724d401 Fix for textfield jumping when textfield wasn't the right size or the vertical alignment was something other than center. 2011-01-15 23:15:55 -05:00
Randall Luecke c73e2e1a91 Fix for nib2cib'd textfields jumping when editing 2011-01-15 21:45:37 -05:00
Randall Luecke 630cd121a6 Typo in docs 2011-01-15 20:40:24 -05:00
Randall Luecke 5d88ffbe66 Merge branch 'decimal' of https://github.com/stevegeek/cappuccino into stevegeek-decimal 2011-01-15 20:32:24 -05:00
Randall Luecke bd5aa1c959 Merge branch 'CPPredicate' of https://github.com/cacaodev/cappuccino into cacaodev-CPPredicate 2011-01-15 18:50:12 -05:00
Stephen Ierodiaconou c65bfd22a2 Use native javascript array for mantissa for big performance increase 2011-01-16 01:47:14 +02:00
Randall Luecke e656e0561b removeTableColumn: on the outlineview shouldn't allow removal of outlineTableColumn per cocoa. 2011-01-15 18:31:41 -05:00
Randall Luecke ddbba22533 Only set the outlineview column if it's the first column added. 2011-01-15 18:10:28 -05:00
Randall Luecke 91b5596034 Merge branch 'cacaodev-CPOutlineView' 2011-01-15 17:59:13 -05:00
Stephen Ierodiaconou e0185a0eff Documentation for CPDecimalNumber 2011-01-15 21:58:47 +02:00
Stephen Ierodiaconou 2fe8845842 CPDecimalString returns NaN for a NaN and Fix Compare of NaNs and Cocoa compatable handling of overflow/underflows when no exception 2011-01-15 19:29:55 +02:00
Stephen Ierodiaconou c02128a1fd Instantiate default number handler lazily and fix CPDecimalNumberHandler initialisers and CPDecimalNumberHandler docs 2011-01-15 18:50:47 +02:00
Stephen Ierodiaconou 27ad98e160 Initialiser fixes and docs
Fix tests for new initialisers
2011-01-15 16:40:11 +02:00
Stephen Ierodiaconou fc746db70f Cocoa compatible constructors for CPDecimals 2011-01-15 16:12:06 +02:00
Stephen Ierodiaconou 6a6256bdb4 CPCoding support for CPDecimalNumber and test 2011-01-15 14:15:31 +02:00
Stephen Ierodiaconou 5a0cfc1595 Make default number hanler file global only and Improvements and optimisations for CPDecimalNumber 2011-01-15 11:49:20 +02:00
Stephen Ierodiaconou 32107ab650 Improvements to CPDecimalNumberHandler including docs and archiving/unarchiving and associated test. 2011-01-15 09:38:31 +02:00
Stephen Ierodiaconou 494f615aaa Merge branch 'master' into imports
Conflicts:
	Foundation/CPScanner.j
2011-01-15 09:11:46 +02:00
Francisco Ryan Tolmasky I 5c2ebd546c Don't include a delegate class entry in Info.plist for nib application templates.
Reviewed by me.
2011-01-14 15:42:23 -08:00
cacaodev 72b8ed2faf CPOutlineView: If nil, set outlineTableColumn when the first column is added.
nib2cib: handle indentationPerLevel when the key is not in the xib.
CPoutlineViewCibTest
2011-01-15 00:39:38 +01:00
Alexander Ljungberg 6b8c85df7c Additional testing for outline view archiving. 2011-01-14 19:59:25 -03:00
Alexander Ljungberg cce4e3ded8 Fixed: manual CPBrowser test's click handler threw an exception. 2011-01-14 14:46:37 -03:00
Alexander Ljungberg 0240c648aa Encode delegate when archiving CPBrowser. 2011-01-14 14:36:57 -03:00
Alexander Ljungberg 6019ff9107 Fixed: archiving 'undefined' would cause an exception. 2011-01-14 14:25:11 -03:00
Alexander Ljungberg c4ee83e4c1 Basic CPBrowser CPCoding support. 2011-01-14 13:34:18 -03:00
Alexander Ljungberg 61b0cbb1af Test CPBrowser data loading. 2011-01-14 12:42:38 -03:00
Alexander Ljungberg af30e96b7b Cleanup. 2011-01-14 12:16:51 -03:00
Alexander Ljungberg b7bdec189a Fixed: when an outline view node was expanded, selections below it would not stick to their items if the newly expanded node also had previously expanded children. 2011-01-14 12:10:52 -03:00
Alexander Ljungberg 2a27a87ae6 Fixed: CPOutlineView could not be archived with CPCoding. Closes #1093.
This fixes the exception "[_CPOutlineViewTableViewDataSource encodeWithCoder:] unrecognized selector sent to instance".
2011-01-13 22:18:05 -03:00
Alexander Ljungberg 31ac84f683 Fix non ASCII codes in documentation. 2011-01-13 20:59:28 -03:00
Alexander Ljungberg c41defe864 Merge branch 'master' of github.com:280north/cappuccino 2011-01-13 20:56:58 -03:00
Alexander Ljungberg 6bc109f7fc Optimised: outline view expandItem:expandChildren:YES sent repeated selection change notifications. 2011-01-13 20:51:43 -03:00
Alexander Ljungberg 2d603df83c Fixed: outline view's collapseItem sent up selection notifications in triplicate, each of them at the wrong time. 2011-01-13 20:03:06 -03:00
Alexander Ljungberg dcf440396d Fixed: the outline view was temporarily inconsistent to outside observers while expanding a node.
In particular, a selection did change notification was sent before the rows the selection referred to had had a chance to be loaded.
2011-01-13 18:57:36 -03:00
Randall Luecke 1dc10440b7 Documentaion of CPObjectController. 2011-01-13 00:57:07 -05:00
Randall Luecke 0ef2557ec3 Documentation of CPArrayController. 2011-01-13 00:30:50 -05:00
Randall Luecke 05e69c85c7 More documentation of the tableview, outlineview, and table columns. Wrapped formatted documenation in <pre> tags and added sample code for using custom dataviews 2011-01-12 23:40:28 -05:00
cacaodev 9c6476615d Allow parsing of functions with multiple arguments like multiply:by:(5,2) or FUNCTION('method:arg:', arg1, arg2)
Added a missing CPDate.j import in CPExpression_function that was causing an 'unknown variable CPDate' error in deploy builds.
Added documentation for +expressionForSubquery:...
Added licence headers with credits.
2011-01-12 18:43:09 +01:00
Randall Luecke b393d0597f If selectedRow no longer exists when numberOfRows change reset it to CPNotFound. Closes #1089. 2011-01-12 11:49:36 -05:00
Francisco Ryan Tolmasky I f69e2e8d8f Merge branch 'master' of github.com:280north/cappuccino 2011-01-12 08:41:26 -08:00
Francisco Ryan Tolmasky I 5fd470acea Fix for adding a js object to a CPArray and associated tests.
Reviewed by me.
2011-01-12 08:41:02 -08:00
Alexander Ljungberg 28e660c295 Merge branch 'master' of github.com:280north/cappuccino 2011-01-12 11:02:33 -03:00
Alexander Ljungberg 9a76b4451f Cleanup. 2011-01-12 10:54:47 -03:00
Alexander Ljungberg b50f955cfd Standardise source file header. 2011-01-12 10:52:35 -03:00
Stephen Ierodiaconou 76b5682234 Missing imports in CPSet+KVO 2010-12-26 10:29:46 +02:00
Stephen Ierodiaconou 4aa4f1a62a Some more missing imports 2010-12-26 01:47:26 +02:00
Stephen Ierodiaconou 7ae14e9eb5 CPCharacterSet lint and fixes 2010-12-26 01:34:43 +02:00
Stephen Ierodiaconou bfe03a8874 CPJSONPConnection Missing imports and self check 2010-12-26 01:34:43 +02:00
Stephen Ierodiaconou 66b6b44f86 CPPredicate lint, import fixes, and some bug fixes 2010-12-26 01:34:43 +02:00
Stephen Ierodiaconou b70018bd80 Import fixes and lint 2010-12-26 01:34:37 +02:00
Andreas Falk a302fdfb8f CPTextField should not bother with handling tab to go to the next key
view, CPWindow does that for us.
2010-11-15 19:44:02 +01:00
Andreas bb9e1a830d Add cancelOperation action to clear text when pressing ESC 2010-11-13 15:21:37 +01:00
Andreas 9b7f8ec31e Add -insertTabIgnoringFieldEditor: and -insertNewlineIgnoringFieldEditor: 2010-11-13 15:16:25 +01:00
Andreas 17b40fcb9d Adapt CPTextField to use interpretKeyEvents and actions instead of directly reading from keyDown 2010-11-13 15:14:09 +01:00
172 changed files with 18442 additions and 1636 deletions
-1
View File
@@ -94,4 +94,3 @@
@import "CPWebView.j"
@import "CPWindow.j"
@import "CPWindowController.j"
+1 -1
View File
@@ -69,7 +69,7 @@
@class CPAccordionView
<p>CPAccordionView provides a container for CPAccordionViewItem objects and manages layout state
for all sublayout items.</p>
for all sub-layout items.</p>
<strong>Example</strong><br />
<pre>
+1 -1
View File
@@ -6,7 +6,7 @@
* Copyright 2008, Jake MacMullin.
*
* 11/10/2008 Ross Boucher
* - Make it conform to style guidelines, general cleanup and ehancements
* - Make it conform to style guidelines, general cleanup and enhancements
* 11/10/2010 Antoine Mercadal
* - Enhancements, better compliance with Cocoa API
*
+1
View File
@@ -21,6 +21,7 @@
*/
@import <Foundation/CPObject.j>
@import <Foundation/CPTimer.j>
@import "CAMediaTimingFunction.j"
+145 -8
View File
@@ -57,7 +57,7 @@ CPRunContinuesResponse = -1002;
@ingroup appkit
@class CPApplication
CPApplication is THE way to start up the Cappucino framework for your application to use.
CPApplication is THE way to start up the Cappuccino framework for your application to use.
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:
@@ -90,7 +90,6 @@ CPRunContinuesResponse = -1002;
CPWindow _previousKeyWindow;
CPWindow _previousMainWindow;
CPMenu _mainMenu;
CPDocumentController _documentController;
CPModalSession _currentSession;
@@ -293,11 +292,21 @@ CPRunContinuesResponse = -1002;
}
}
/*!
Sets the applications icon image. This image is used in the default "About" window.
By default this value is pulled from the CPApplicationIcon key in your info.plist file.
@param anImage - The image to set.
*/
- (void)setApplicationIconImage:(CPImage)anImage
{
_applicationIconImage = anImage;
}
/*!
Returns the application icon image. By default this is pulled from the CPApplicationIcon key of info.plist.
@return CPImage - Your application icon image.
*/
- (CPImage)applicationIconImage
{
if (_applicationIconImage)
@@ -310,11 +319,38 @@ CPRunContinuesResponse = -1002;
return _applicationIconImage;
}
/*!
Opens the standard about panel with no options.
*/
- (void)orderFrontStandardAboutPanel:(id)sender
{
[self orderFrontStandardAboutPanelWithOptions:nil];
}
/*!
Opens the standard about panel. This method takes a single argument \c options.
Options is a dictionary that can contain any of the following keys:
<pre>
ApplicationName - The name of your application.
ApplicationIcon - Application icon image.
Version - The full version of your application
ApplicationVersion - The shorter version number of your application.
Copyright - Human readable copyright information.
</pre>
If you choose not the include any of the above keys, they will default
to the following respective keys in your info.plist file.
<pre>
CPBundleName
CPApplicationIcon (through a call to -applicationIconImage, see documentation for that method for more details)
CPBundleVersion
CPBundleShortVersionString
CPHumanReadableCopyright
</pre>
@param options - A dictionary with the aboe listed keys. You can pass nil to default to your plist values.
*/
- (void)orderFrontStandardAboutPanelWithOptions:(CPDictionary)options
{
if (!_aboutPanel)
@@ -530,7 +566,7 @@ CPRunContinuesResponse = -1002;
- (BOOL)_handleKeyEquivalent:(CPEvent)anEvent
{
return [[self keyWindow] performKeyEquivalent:anEvent] ||
[_mainMenu performKeyEquivalent:anEvent];
[[self mainMenu] performKeyEquivalent:anEvent];
}
/*!
@@ -574,6 +610,10 @@ CPRunContinuesResponse = -1002;
[[anEvent window] sendEvent:anEvent];
}
/*!
If the delegate responds to the given selector it will call the method on the delegate,
otherwise the method will be passed to CPResponder.
*/
- (void)doCommandBySelector:(SEL)aSelector
{
if ([_delegate respondsToSelector:aSelector])
@@ -637,7 +677,7 @@ CPRunContinuesResponse = -1002;
*/
- (CPMenu)mainMenu
{
return _mainMenu;
return [self menu];
}
/*!
@@ -645,21 +685,30 @@ CPRunContinuesResponse = -1002;
@param aMenu the menu to set for the application
*/
- (void)setMainMenu:(CPMenu)aMenu
{
[self setMenu:aMenu];
}
- (void)setMenu:(CPMenu)aMenu
{
if ([aMenu _menuName] === "CPMainMenu")
{
if (_mainMenu === aMenu)
if ([self menu] === aMenu)
return;
_mainMenu = aMenu;
[super setMenu:aMenu];
if ([CPPlatform supportsNativeMainMenu])
window.cpSetMainMenu(_mainMenu);
window.cpSetMainMenu([self menu]);
}
else
[aMenu _setMenuName:@"CPMainMenu"];
}
/*!
Opens the shared color panel.
@param aSender
*/
- (void)orderFrontColorPanel:(id)aSender
{
[[CPColorPanel sharedColorPanel] orderFront:self];
@@ -828,16 +877,38 @@ CPRunContinuesResponse = -1002;
return nil;
}
/*!
Fires a callback function when an event matching a given mask occurs.
@param aCallback - A js function to be fired.
@prarm aMask - An event mask for the next event.
@param anExpiration - The date for which this callback expires (not implemented).
@param inMode (not implemented).
@param shouldDequeue (not implemented).
*/
- (void)setCallback:(Function)aCallback forNextEventMatchingMask:(unsigned int)aMask untilDate:(CPDate)anExpiration inMode:(CPString)aMode dequeue:(BOOL)shouldDequeue
{
_eventListeners.push(_CPEventListenerMake(aMask, aCallback));
}
- (CPEvent)setTarget:(id)aTarget selector:(SEL)aSelector forNextEventMatchingMask:(unsigned int)aMask untilDate:(CPDate)anExpiration inMode:(CPString)aMode dequeue:(BOOL)shouldDequeue
/*!
Assigns a target and action for the next event matching a given event mask.
The callback method called will be passed the CPEvent when it fires.
@param aTarget - The target object for the callback.
@param aSelector - The selector which should be called on the target object.
@param aMask - The mask for a given event which should trigger the callback.
@param anExpiration - The date for which the callback expires (not implemented).
@param aMode (not implemented).
@param shouldDequeue (not implemented).
*/
- (void)setTarget:(id)aTarget selector:(SEL)aSelector forNextEventMatchingMask:(unsigned int)aMask untilDate:(CPDate)anExpiration inMode:(CPString)aMode dequeue:(BOOL)shouldDequeue
{
_eventListeners.push(_CPEventListenerMake(aMask, function (anEvent) { objj_msgSend(aTarget, aSelector, anEvent); }));
}
/*!
Returns the last event recieved by your application.
*/
- (CPEvent)currentEvent
{
return _currentEvent;
@@ -867,6 +938,19 @@ CPRunContinuesResponse = -1002;
[aWindow _attachSheet:aSheet modalDelegate:aModalDelegate didEndSelector:aDidEndSelector contextInfo:aContextInfo];
}
/*!
Ends a sheet modal.
The following are predefined return codes:
<pre>
CPRunStoppedResponse
CPRunAbortedResponse
CPRunContinuesResponse
</pre>
@param sheet - The window object (sheet) to dismiss.
@param returnCode - The return code to send to the delegate. You can use one of the return codes above or a custom value that you define.
*/
- (void)endSheet:(CPWindow)sheet returnCode:(int)returnCode
{
var count = [_windows count];
@@ -885,11 +969,31 @@ CPRunContinuesResponse = -1002;
}
}
/*!
Ends a sheet and sends the return code "0".
@param sheet - The CPWindow object (sheet) that should be dismissed.
*/
- (void)endSheet:(CPWindow)sheet
{
// FIX ME: this is wrong: by Cocoa this should be: CPRunStoppedResponse.
[self endSheet:sheet returnCode:0];
}
/*!
Returns and array of slash seperated arugments to your application.
These values are pulled from your window location hash.
For exampled if your application loaded:
<pre>
index.html#280north/cappuccino/issues
</pre>
The follow array would be returned:
<pre>
["280north", "cappuccino", "issues"]
</pre>
@return CPArray - The array of arguments.
*/
- (CPArray)arguments
{
if (_fullArgsString !== window.location.hash)
@@ -898,6 +1002,22 @@ CPRunContinuesResponse = -1002;
return _args;
}
/*!
Sets the arguments of your application.
That is, set the slash seperated values of an array as the window location hash.
For example if you pass an array:
<pre>
["280north", "cappuccino", "issues"]
</pre>
The new window location would be
<pre>
index.html#280north/cappuccino/issues
</pre>
@param args - An array of arguments.
*/
- (void)setArguments:(CPArray)args
{
if (!args || args.length == 0)
@@ -939,6 +1059,23 @@ CPRunContinuesResponse = -1002;
_args = [];
}
/*!
Returns a dictionary of the window location named arguments.
For example if your location was:
<pre>
index.html?owner=280north&repo=cappuccino&type=issues
</pre>
a CPDictionary with the keys:
<pre>
owner, repo, type
</pre>
and respective values:
<pre>
280north, cappuccino, issues
</pre>
Will be returned.
*/
- (CPDictionary)namedArguments
{
return _namedArgs;
+291 -15
View File
@@ -1,5 +1,3 @@
/*
* CPArrayController.j
* AppKit
@@ -29,7 +27,14 @@
@import "CPObjectController.j"
@import "CPKeyValueBinding.j"
/*!
@class CPArrayController
CPArrayController is a bindings compatible class that manages an array.
CPArrayController also provides selection management and sorting capabilities.
*/
@implementation CPArrayController : CPObjectController
{
BOOL _avoidsEmptySelection;
@@ -39,10 +44,12 @@
BOOL _selectsInsertedObjects;
BOOL _alwaysUsesMultipleValuesMarker;
id _selectionIndexes;
id _sortDescriptors;
id _filterPredicate;
id _arrangedObjects;
BOOL _automaticallyRearrangesObjects; // FIXME: Not in use
CPIndexSet _selectionIndexes;
CPArray _sortDescriptors;
CPPredicate _filterPredicate;
CPArray _arrangedObjects;
}
+ (void)initialize
@@ -102,54 +109,168 @@
return [CPSet setWithObjects:"selectionIndexes"];
}
- (id)init
{
self = [super init];
if (self)
{
_sortDescriptors = [CPArray array];
_selectionIndexes = [CPIndexSet indexSet];
_preservesSelection = YES;
_selectsInsertedObjects = YES;
_avoidsEmptySelection = YES;
_clearsFilterPredicateOnInsertion = YES;
_alwaysUsesMultipleValuesMarker = NO;
_automaticallyRearrangesObjects = NO;
_filterRestrictsInsertion = YES; // FIXME: Not in use
[self _init];
}
return self;
}
- (void)_init
{
_sortDescriptors = [CPArray array];
_filterPredicate = nil;
_selectionIndexes = [CPIndexSet indexSet];
_arrangedObjects = nil;
}
- (void)prepareContent
{
[self _setContentArray:[[self newObject]]];
}
/*!
Returns YES if the selection should try to be preserved when the content changes, otherwise NO.
@return BOOL YES if the selection is preserved, otherwise NO.
*/
- (BOOL)preservesSelection
{
return _preservesSelection;
}
/*!
Sets whether the selection is kept when the content changes.
@param BOOL aFlag - YES if the selection should be kept, otherwise NO.
*/
- (void)setPreservesSelection:(BOOL)value
{
_preservesSelection = value;
}
/*!
@return BOOL - Returns YES if new objects are automatically selected, otherwise NO.
*/
- (BOOL)selectsInsertedObjects
{
return _selectsInsertedObjects;
}
/*!
Sets whether the controller will automatically select objects as they are inserted.
@return BOOL - YES if new objects are selected, otherwise NO.
*/
- (void)setSelectsInsertedObjects:(BOOL)value
{
_selectsInsertedObjects = value;
}
/*!
@return BOOL - YES if the controller should try to avoid an empty selection otherwise NO.
*/
- (BOOL)avoidsEmptySelection
{
return _avoidsEmptySelection;
}
/*!
Sets whether the controller should try to avoid an empty selection.
@param BOOL aFlag - YES if the receiver should attempt to avoid an empty selection, otherwise NO.
*/
- (void)setAvoidsEmptySelection:(BOOL)value
{
_avoidsEmptySelection = value;
}
/*!
Whether the receiver will clear its filter predicate when a new object is inserted.
@return BOOL YES if the receiver clears filter predicates on insert
*/
- (BOOL)clearsFilterPredicateOnInsertion
{
return _clearsFilterPredicateOnInsertion;
}
/*!
Sets whether the receiver should clear its filter predicate when a new object is inserted.
@param BOOL YES if the receiver should clear filter predicates on insert
*/
- (void)setClearsFilterPredicateOnInsertion:(BOOL)aFlag
{
_clearsFilterPredicateOnInsertion = aFlag;
}
/*!
Whether the receiver will always return the multiple values marker when multiple
items are selected, even if the items have the same value.
@return BOOL YES if the receiver always uses the multiple values marker
*/
- (BOOL)alwaysUsesMultipleValuesMarker
{
return _alwaysUsesMultipleValuesMarker;
}
/*!
Sets whether the receiver should always return the multiple values marker when multiple
items are selected, even if the items have the same value.
@param BOOL aFlag YES if the receiver should always use the multiple values marker
*/
- (void)setAlwaysUsesMultipleValuesMarker:(BOOL)aFlag
{
_alwaysUsesMultipleValuesMarker = aFlag;
}
/*!
Whether the receiver will rearrange its contents automatically whenever the sort
descriptors or filter predicates are changed.
NOTE: not yet implemented. Cappuccino always act as if this value was YES.
@return BOOL YES if the receiver will automatically rearrange its content on new sort
descriptors or filter predicates
*/
- (BOOL)automaticallyRearrangesObjects
{
return _automaticallyRearrangesObjects;
}
/*!
Sets whether the receiver should rearrange its contents automatically whenever the sort
descriptors or filter predicates are changed.
NOTE: not yet implemented. Cappuccino always act as if this value was YES.
@param BOOL YES if the receiver should automatically rearrange its content on new sort
descriptors or filter predicates
*/
- (void)setAutomaticallyRearrangesObjects:(BOOL)aFlag
{
_automaticallyRearrangesObjects = aFlag;
}
/*!
Sets the controller's content object.
@param id value - the content object of the controller.
*/
- (void)setContent:(id)value
{
if (value === nil)
@@ -185,7 +306,7 @@
// We need to be in control of when notifications fire.
_contentObject = value;
if (_clearsFilterPredicateOnInsertion)
if (_clearsFilterPredicateOnInsertion && _filterPredicate != nil)
[self __setFilterPredicate:nil]; // Causes a _rearrangeObjects.
else
[self _rearrangeObjects];
@@ -199,32 +320,53 @@
[self didChangeValueForKey:@"filterPredicate"];
}
/*!
@ignore
*/
- (void)_setContentArray:(id)anArray
{
[self setContent:anArray];
}
/*!
@ignore
*/
- (void)_setContentSet:(id)aSet
{
[self setContent:[aSet allObjects]];
}
/*!
Returns the content array of the controller.
@return id the content array of the receiver
*/
- (id)contentArray
{
return [self content];
}
/*!
Returns the content of the receiver as a CPSet.
@return id - the content of the controller as a set.
*/
- (id)contentSet
{
return [CPSet setWithArray:[self content]];
}
/*!
Sorts and filters a given array and returns it.
@param CPArray anArray - an array of objects.
@return CPArray - the array of sorted objects.
*/
- (CPArray)arrangeObjects:(CPArray)objects
{
var filterPredicate = [self filterPredicate],
sortDescriptors = [self sortDescriptors];
if (filterPredicate && sortDescriptors)
if (filterPredicate && [sortDescriptors count] > 0)
{
var sortedObjects = [objects filteredArrayUsingPredicate:filterPredicate];
[sortedObjects sortUsingDescriptors:sortDescriptors];
@@ -232,12 +374,15 @@
}
else if (filterPredicate)
return [objects filteredArrayUsingPredicate:filterPredicate];
else if (sortDescriptors)
else if ([sortDescriptors count] > 0)
return [objects sortedArrayUsingDescriptors:sortDescriptors];
return [objects copy];
}
/*!
Triggers the filtering of the objects in the controller.
*/
- (void)rearrangeObjects
{
[self willChangeValueForKey:@"arrangedObjects"];
@@ -271,24 +416,40 @@
[self __setSelectionIndexes:oldSelectionIndexes];
}
/*!
@ignore
*/
- (void)__setArrangedObjects:(id)value
{
if (_arrangedObjects === value)
return;
_arrangedObjects = [[_CPObservableArray alloc] initWithArray:value];
_arrangedObjects = [[_CPObservableArray alloc] initWithArray:value];
}
/*!
Returns an array of the controller's objects sorted and filtered.
@return - array of objects
*/
- (id)arrangedObjects
{
return _arrangedObjects;
}
/*!
Returns the receiver's array of sort descriptors.
@return CPArray an array of sort descriptors
*/
- (CPArray)sortDescriptors
{
return _sortDescriptors;
}
/*!
Sets the sort descriptors for the controller.
@param CPArray descriptors - the new sort descriptors.
*/
- (void)setSortDescriptors:(CPArray)value
{
if (_sortDescriptors === value)
@@ -300,11 +461,23 @@
[self _rearrangeObjects];
}
/*!
Returns the predicate used by the controller to filter the contents of the receiver.
If no predicate is set nil is returned.
@return CPPredicate the predicate used by the controller
*/
- (CPPredicate)filterPredicate
{
return _filterPredicate;
}
/*!
Sets the predicate for the controller to filter the content.
Passing nil will remove an existing prediate.
@param CPPrediate aPredicate - the new predicate.
*/
- (void)setFilterPredicate:(CPPredicate)value
{
[self __setFilterPredicate:value];
@@ -325,28 +498,52 @@
[self _rearrangeObjects];
}
/*!
Returns a BOOL indicating whether the receiver always returns the multiple values marker when multiple objects are selected.
@return BOOL YES is the controller always uses multiple value markers, otherwise NO.
*/
- (BOOL)alwaysUsesMultipleValuesMarker
{
return _alwaysUsesMultipleValuesMarker;
}
//Selection
/*!
Returns the index of the first object in the controller's selection.
@return unsigned - Index of the first selected object.
*/
- (unsigned)selectionIndex
{
return [_selectionIndexes firstIndex];
}
/*!
Sets the selected index
@param unsigned anIndex - the new index to select
@return BOOL - Returns YES if the selection was changed, otherwise NO.
*/
- (BOOL)setSelectionIndex:(unsigned)index
{
return [self setSelectionIndexes:[CPIndexSet indexSetWithIndex:index]];
}
/*!
Returns an index set of the selected indexes.
@return CPIndexSet - The selected indexes.
*/
- (CPIndexSet)selectionIndexes
{
return _selectionIndexes;
}
/*!
Sets the selection indexes of the controller.
@param CPIndexSet indexes - the indexes to select
@return BOOL - Returns YES if the selection changed, otherwise NO.
*/
- (BOOL)setSelectionIndexes:(CPIndexSet)indexes
{
[self _selectionWillChange]
@@ -400,6 +597,10 @@
return YES;
}
/*!
Returns an array of the selected objects.
@return CPArray - the selected objects.
*/
- (CPArray)selectedObjects
{
var objects = [[self arrangedObjects] objectsAtIndexes:[self selectionIndexes]];
@@ -407,6 +608,12 @@
return [_CPObservableArray arrayWithArray:(objects || [])];
}
/*!
Sets the selected objects of the controller.
@param CPArray anArray - the objects to select
@return BOOL - Returns YES if the selection was changed, otherwise NO.
*/
- (BOOL)setSelectedObjects:(CPArray)objects
{
[self willChangeValueForKey:@"selectionIndexes"];
@@ -441,12 +648,20 @@
}
//Moving selection
/*!
Returns YES if the previous object, relative to the current selection, in the controller's content array can be selected.
@return BOOL - YES if the object can be selected, otherwise NO.
*/
- (BOOL)canSelectPrevious
{
return [[self selectionIndexes] firstIndex] > 0
}
/*!
Selects the previous object, relative to the current selection, in the controllers arranged content.
@param id sender - the sender of the message.
*/
- (void)selectPrevious:(id)sender
{
var index = [[self selectionIndexes] firstIndex] - 1;
@@ -455,11 +670,20 @@
[self setSelectionIndexes:[CPIndexSet indexSetWithIndex:index]];
}
/*!
Returns YES if the next object, relative to the current selection, in the controller's content array can be selected.
@return BOOL - YES if the object can be selected, otherwise NO.
*/
- (BOOL)canSelectNext
{
return [[self selectionIndexes] firstIndex] < [[self arrangedObjects] count] - 1;
}
/*!
Selects the next object, relative to the current selection, in the controllers arranged content.
@param id sender - the sender of the message.
*/
- (void)selectNext:(id)sender
{
var index = [[self selectionIndexes] firstIndex] + 1;
@@ -470,6 +694,11 @@
//Add/Remove
/*!
Adds object to the receiver's content collection and the arranged objects array.
@param id anObject - the object to add the controller.
*/
- (void)addObject:(id)object
{
if (![self canAdd])
@@ -503,6 +732,12 @@
[self didChangeValueForKey:@"filterPredicate"];
}
/*!
Adds an object at a given index to the receiver's collection.
@param id anObject - The object to add to the collection.
@param int anIndex - The index to insert the object at.
*/
- (void)insertObject:(id)anObject atArrangedObjectIndex:(int)anIndex
{
if (![self canAdd])
@@ -534,6 +769,11 @@
[self didChangeValueForKey:@"filterPredicate"];
}
/*!
Removes a given object from the receiver's collection.
@param id anObject - The object to remove from the collection.
*/
- (void)removeObject:(id)object
{
[self willChangeValueForKey:@"content"];
@@ -552,6 +792,11 @@
[self didChangeValueForKey:@"content"];
}
/*!
Creates and adds a new object to the receiver's content and arranged objects.
@param id sender - The sender of the message.
*/
- (void)add:(id)sender
{
if (![self canAdd])
@@ -560,6 +805,10 @@
[self insert:sender];
}
/*!
Creates a new object and inserts it into the receiver's content array.
@param id sender - The sender of the message.
*/
- (void)insert:(id)sender
{
if (![self canInsert])
@@ -570,17 +819,29 @@
[self addObject:newObject];
}
/*!
Removes the controller's selected objects from the controller's collection.
@param id sender - The sender of the message.
*/
- (void)remove:(id)sender
{
[self removeObjects:[[self arrangedObjects] objectsAtIndexes:[self selectionIndexes]]];
}
/*!
Removes the objects at the specified indexes in the controller's arranged objects from the content array.
@param CPIndexSet indexes - indexes of the objects to remove.
*/
- (void)removeObjectsAtArrangedObjectIndexes:(CPIndexSet)indexes
{
[self _removeObjects:[[self arrangedObjects] objectsAtIndexes:indexes]];
}
/*!
Adds an array of objects to the controller's collection.
@param CPArray anArray - The array of objects to add to the collection.
*/
- (void)addObjects:(CPArray)objects
{
if (![self canAdd])
@@ -595,11 +856,18 @@
[self setContent:contentArray];
}
/*!
Removes an array of objects from the collection.
@param CPArray anArray - The array of objects to remove
*/
- (void)removeObjects:(CPArray)objects
{
[self _removeObjects:objects];
}
/*!
@ignore
*/
- (void)_removeObjects:(CPArray)objects
{
[self willChangeValueForKey:@"content"];
@@ -631,6 +899,10 @@
[self didChangeValueForKey:@"content"];
}
/*!
Returns a BOOL indicating whether an object can be inserted into the controller's collection.
@return BOOL - YES if an object can be inserted, otherwise NO.
*/
- (BOOL)canInsert
{
return [self isEditable];
@@ -643,7 +915,8 @@ var CPArrayControllerAvoidsEmptySelection = @"CPArrayControllerAvoid
CPArrayControllerFilterRestrictsInsertion = @"CPArrayControllerFilterRestrictsInsertion",
CPArrayControllerPreservesSelection = @"CPArrayControllerPreservesSelection",
CPArrayControllerSelectsInsertedObjects = @"CPArrayControllerSelectsInsertedObjects",
CPArrayControllerAlwaysUsesMultipleValuesMarker = @"CPArrayControllerAlwaysUsesMultipleValuesMarker";
CPArrayControllerAlwaysUsesMultipleValuesMarker = @"CPArrayControllerAlwaysUsesMultipleValuesMarker",
CPArrayControllerAutomaticallyRearrangesObjects = @"CPArrayControllerAutomaticallyRearrangesObjects";
@implementation CPArrayController (CPCoding)
@@ -659,6 +932,8 @@ var CPArrayControllerAvoidsEmptySelection = @"CPArrayControllerAvoid
_preservesSelection = [aCoder decodeBoolForKey:CPArrayControllerPreservesSelection];
_selectsInsertedObjects = [aCoder decodeBoolForKey:CPArrayControllerSelectsInsertedObjects];
_alwaysUsesMultipleValuesMarker = [aCoder decodeBoolForKey:CPArrayControllerAlwaysUsesMultipleValuesMarker];
_automaticallyRearrangesObjects = [aCoder decodeBoolForKey:CPArrayControllerAutomaticallyRearrangesObjects];
_sortDescriptors = [CPArray array];
if (![self content] && [self automaticallyPreparesContent])
[self prepareContent];
@@ -679,6 +954,7 @@ var CPArrayControllerAvoidsEmptySelection = @"CPArrayControllerAvoid
[aCoder encodeBool:_preservesSelection forKey:CPArrayControllerPreservesSelection];
[aCoder encodeBool:_selectsInsertedObjects forKey:CPArrayControllerSelectsInsertedObjects];
[aCoder encodeBool:_alwaysUsesMultipleValuesMarker forKey:CPArrayControllerAlwaysUsesMultipleValuesMarker];
[aCoder encodeBool:_automaticallyRearrangesObjects forKey:CPArrayControllerAutomaticallyRearrangesObjects];
}
- (void)awakeFromCib
+1 -1
View File
@@ -38,7 +38,7 @@ var DefaultLineWidth = 1.0;
@class CPBezierPath
A CPBezierPath allows you to create paths for drawing to the screen using a simpler API than CoreGraphics.
Paths can form any shape, including regular polgyons like squares and triangles; circles, arcs; or complex
Paths can form any shape, including regular polygons like squares and triangles; circles, arcs; or complex
line segments.
A path can be stroked and filled using the relevant method. The currently active fill and stroke color will
+2 -2
View File
@@ -235,8 +235,8 @@ CPGrooveBorder = 3;
switch (_boxType)
{
case CPBoxSeparator:
// NSBox does not include a horitontal flag for the seperator type. We have to determine
// the type of seperator to draw by the width and height of the frame.
// NSBox does not include a horizontal flag for the separator type. We have to determine
// the type of separator to draw by the width and height of the frame.
if (CGRectGetWidth(bounds) === 5.0)
return [self _drawVerticalSeperatorInRect:bounds];
else if (CGRectGetHeight(bounds) === 5.0)
+83 -31
View File
@@ -83,42 +83,47 @@
{
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:CPThemeStateSelectedDataView];
[_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];
[self _init];
}
return self;
}
- (void)_init
{
_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:CPThemeStateSelectedDataView];
[_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];
}
- (void)setPrototypeView:(CPView)aPrototypeView
{
_prototypeView = [CPKeyedUnarchiver unarchiveObjectWithData:
@@ -650,6 +655,53 @@
@end
@implementation CPBrowser (CPCoding)
- (id)initWithCoder:(CPCoder)aCoder
{
self = [super initWithCoder:aCoder];
if (self)
{
[self _init];
_allowsEmptySelection = [aCoder decodeBoolForKey:@"CPBrowserAllowsEmptySelectionKey"];
_allowsMultipleSelection = [aCoder decodeBoolForKey:@"CPBrowserAllowsMultipleSelectionKey"];
_prototypeView = [aCoder decodeObjectForKey:@"CPBrowserPrototypeViewKey"];
_rowHeight = [aCoder decodeFloatForKey:@"CPBrowserRowHeightKey"];
_imageWidth = [aCoder decodeFloatForKey:@"CPBrowserImageWidthKey"];
_minColumnWidth = [aCoder decodeFloatForKey:@"CPBrowserMinColumnWidthKey"];
_columnWidths = [aCoder decodeObjectForKey:@"CPBrowserColumnWidthsKey"];
[self setDelegate:[aCoder decodeObjectForKey:@"CPBrowserDelegateKey"]];
[self setAutohidesScroller:[aCoder decodeBoolForKey:@"CPBrowserAutohidesScrollerKey"]];
}
return self;
}
- (void)encodeWithCoder:(CPCoder)aCoder
{
// Don't encode the subviews, they're transient and will be recreated from data.
var actualSubviews = _subviews;
_subviews = [];
[super encodeWithCoder:aCoder];
_subviews = actualSubviews;
[aCoder encodeBool:[self autohidesScroller] forKey:@"CPBrowserAutohidesScrollerKey"];
[aCoder encodeBool:_allowsEmptySelection forKey:@"CPBrowserAllowsEmptySelectionKey"];
[aCoder encodeBool:_allowsMultipleSelection forKey:@"CPBrowserAllowsMultipleSelectionKey"];
[aCoder encodeObject:_delegate forKey:@"CPBrowserDelegateKey"];
[aCoder encodeObject:_prototypeView forKey:@"CPBrowserPrototypeViewKey"];
[aCoder encodeFloat:_rowHeight forKey:@"CPBrowserRowHeightKey"];
[aCoder encodeFloat:_imageWidth forKey:@"CPBrowserImageWidthKey"];
[aCoder encodeFloat:_minColumnWidth forKey:@"CPBrowserMinColumnWidthKey"];
[aCoder encodeObject:_columnWidths forKey:@"CPBrowserColumnWidthsKey"];
}
@end
var _CPBrowserResizeControlBackgroundImage = nil;
@implementation _CPBrowserResizeControl : CPView
+1 -1
View File
@@ -125,7 +125,7 @@ var cachedBlackColor,
}
/*!
@deprecated in favor of colorWithWhite:apha:
@deprecated in favor of colorWithWhite:alpha:
Creates a new color object with \c white for the RGB components.
For the alpha component, a value of 1.0 is opaque, and 0.0 means completely transparent.
+1 -1
View File
@@ -57,7 +57,7 @@ CPJavascriptRemedialKeySupport = 1 << 16;
CPJavaScriptShadowFeature = 1 << 20;
CPJavaScriptNegativeMouseWheelValues = 1 << 22;
CPJavaScriptMouseWheelValues_8_15 = 1 << 23
CPJavaScriptMouseWheelValues_8_15 = 1 << 23;
CPOpacityRequiresFilterFeature = 1 << 24;
+174 -32
View File
@@ -43,21 +43,21 @@ CPLineBreakByTruncatingHead = 3;
CPLineBreakByTruncatingTail = 4;
CPLineBreakByTruncatingMiddle = 5;
CPTopVerticalTextAlignment = 1,
CPCenterVerticalTextAlignment = 2,
CPTopVerticalTextAlignment = 1;
CPCenterVerticalTextAlignment = 2;
CPBottomVerticalTextAlignment = 3;
CPScaleProportionally = 0;
CPScaleToFit = 1;
CPScaleNone = 2;
CPScaleProportionally = 0;
CPScaleToFit = 1;
CPScaleNone = 2;
CPNoImage = 0;
CPImageOnly = 1;
CPImageLeft = 2;
CPImageRight = 3;
CPImageBelow = 4;
CPImageAbove = 5;
CPImageOverlaps = 6;
CPNoImage = 0;
CPImageOnly = 1;
CPImageLeft = 2;
CPImageRight = 3;
CPImageBelow = 4;
CPImageAbove = 5;
CPImageOverlaps = 6;
CPOnState = 1;
CPOffState = 0;
@@ -72,7 +72,7 @@ CPControlTextDidBeginEditingNotification = "CPControlTextDidBeginEditingNotif
CPControlTextDidChangeNotification = "CPControlTextDidChangeNotification";
CPControlTextDidEndEditingNotification = "CPControlTextDidEndEditingNotification";
var CPControlBlackColor = [CPColor blackColor];
var CPControlBlackColor = [CPColor blackColor];
/*!
@ingroup appkit
@@ -171,7 +171,8 @@ var CPControlBlackColor = [CPColor blackColor];
}
/*!
Sets the receiver's target action
Sets the receiver's target action.
@param anAction Sets the action message that gets sent to the target.
*/
- (void)setAction:(SEL)anAction
@@ -180,7 +181,7 @@ var CPControlBlackColor = [CPColor blackColor];
}
/*!
Returns the receiver's target action
Returns the receiver's target action.
*/
- (SEL)action
{
@@ -189,6 +190,7 @@ var CPControlBlackColor = [CPColor blackColor];
/*!
Sets the receiver's target. The target receives action messages from the receiver.
@param aTarget the object that will receive the message specified by action
*/
- (void)setTarget:(id)aTarget
@@ -206,6 +208,7 @@ var CPControlBlackColor = [CPColor blackColor];
/*!
Causes \c anAction to be sent to \c anObject.
@param anAction the action to send
@param anObject the object to which the action will be sent
*/
@@ -226,6 +229,7 @@ var CPControlBlackColor = [CPColor blackColor];
/*!
Sets the tooltip for the receiver.
@param aToolTip the tooltip
*/
/*
@@ -262,7 +266,7 @@ var CPControlBlackColor = [CPColor blackColor];
/*!
Sets whether the cell can continuously send its action messages.
*/
*/
- (void)setContinuous:(BOOL)flag
{
// Some subclasses should redefine this with CPLeftMouseDraggedMask
@@ -272,6 +276,9 @@ var CPControlBlackColor = [CPColor blackColor];
_sendActionOn &= ~CPPeriodicMask;
}
/*!
Returns YES if the receiver tracks the mouse outside the frame, otherwise NO.
*/
- (BOOL)tracksMouseOutsideOfFrame
{
return NO;
@@ -334,6 +341,11 @@ var CPControlBlackColor = [CPColor blackColor];
return 0;
}
/*!
Perform a click on the receiver.
@param sender - The sender object
*/
- (void)performClick:(id)sender
{
if (![self isEnabled])
@@ -356,11 +368,18 @@ var CPControlBlackColor = [CPColor blackColor];
}
}
/*!
@ignore
Fired when the button timer finished, usually after the user hits enter.
*/
- (void)unhighlightButtonTimerDidFinish:(id)sender
{
[self highlight:NO];
}
/*!
Returns the mask of modifier keys held down when the user clicked.
*/
- (unsigned)mouseDownFlags
{
return _trackingMouseDownFlags;
@@ -411,7 +430,7 @@ var CPControlBlackColor = [CPColor blackColor];
}
/*!
Returns the receiver's object value
Returns the receiver's object value.
*/
- (id)objectValue
{
@@ -419,7 +438,7 @@ var CPControlBlackColor = [CPColor blackColor];
}
/*!
Set's the receiver's object value
Sets the receiver's object value.
*/
- (void)setObjectValue:(id)anObject
{
@@ -430,7 +449,7 @@ var CPControlBlackColor = [CPColor blackColor];
}
/*!
Returns the receiver's float value
Returns the receiver's float value.
*/
- (float)floatValue
{
@@ -439,7 +458,7 @@ var CPControlBlackColor = [CPColor blackColor];
}
/*!
Sets the receiver's float value
Sets the receiver's float value.
*/
- (void)setFloatValue:(float)aValue
{
@@ -447,7 +466,7 @@ var CPControlBlackColor = [CPColor blackColor];
}
/*!
Returns the receiver's double value
Returns the receiver's double value.
*/
- (double)doubleValue
{
@@ -456,7 +475,7 @@ var CPControlBlackColor = [CPColor blackColor];
}
/*!
Set's the receiver's double value
Sets the receiver's double value.
*/
- (void)setDoubleValue:(double)anObject
{
@@ -464,7 +483,7 @@ var CPControlBlackColor = [CPColor blackColor];
}
/*!
Returns the receiver's int value
Returns the receiver's int value.
*/
- (int)intValue
{
@@ -473,7 +492,7 @@ var CPControlBlackColor = [CPColor blackColor];
}
/*!
Set's the receiver's int value
Sets the receiver's int value.
*/
- (void)setIntValue:(int)anObject
{
@@ -481,7 +500,7 @@ var CPControlBlackColor = [CPColor blackColor];
}
/*!
Returns the receiver's int value
Returns the receiver's int value.
*/
- (int)integerValue
{
@@ -490,7 +509,7 @@ var CPControlBlackColor = [CPColor blackColor];
}
/*!
Set's the receiver's int value
Sets the receiver's int value.
*/
- (void)setIntegerValue:(int)anObject
{
@@ -498,7 +517,7 @@ var CPControlBlackColor = [CPColor blackColor];
}
/*!
Returns the receiver's string value
Returns the receiver's string value.
*/
- (CPString)stringValue
{
@@ -506,7 +525,7 @@ var CPControlBlackColor = [CPColor blackColor];
}
/*!
Set's the receiver's string value
Sets the receiver's string value.
*/
- (void)setStringValue:(CPString)anObject
{
@@ -582,96 +601,199 @@ var CPControlBlackColor = [CPColor blackColor];
[[CPNotificationCenter defaultCenter] postNotificationName:CPControlTextDidEndEditingNotification object:self userInfo:[CPDictionary dictionaryWithObject:[note object] forKey:"CPFieldEditor"]];
}
/*!
Sets the text alignment of the control.
<pre>
CPLeftTextAlignment
CPCenterTextAlignment
CPRightTextAlignment
CPJustifiedTextAlignment
CPNaturalTextAlignment
</pre>
*/
- (void)setAlignment:(CPTextAlignment)alignment
{
[self setValue:alignment forThemeAttribute:@"alignment"];
}
/*!
Returns the text alignment of the control.
*/
- (CPTextAlignment)alignment
{
return [self valueForThemeAttribute:@"alignment"];
}
/*!
Set the vertical text alignment of the control.
<pre>
CPTopVerticalTextAlignment
CPCenterVerticalTextAlignment
CPBottomVerticalTextAlignment
</pre>
*/
- (void)setVerticalAlignment:(CPTextVerticalAlignment)alignment
{
[self setValue:alignment forThemeAttribute:@"vertical-alignment"];
}
/*!
Returns the vertical text alignment of the receiver.
*/
- (CPTextVerticalAlignment)verticalAlignment
{
return [self valueForThemeAttribute:@"vertical-alignment"];
}
/*!
Sets the line break mode of the receiver.
<pre>
CPLineBreakByWordWrapping
CPLineBreakByCharWrapping
CPLineBreakByClipping
CPLineBreakByTruncatingHead
CPLineBreakByTruncatingTail
CPLineBreakByTruncatingMiddle
</pre>
*/
- (void)setLineBreakMode:(CPLineBreakMode)mode
{
[self setValue:mode forThemeAttribute:@"line-break-mode"];
}
/*!
Returns the line break mode of the control.
*/
- (CPLineBreakMode)lineBreakMode
{
return [self valueForThemeAttribute:@"line-break-mode"];
}
/*!
Sets the text color of the receiver.
@param aColor - A CPColor object.
*/
- (void)setTextColor:(CPColor)aColor
{
[self setValue:aColor forThemeAttribute:@"text-color"];
}
/*!
Returns the text color of the receiver.
*/
- (CPColor)textColor
{
return [self valueForThemeAttribute:@"text-color"];
}
/*!
Sets the shadow color of the text for the receiver.
*/
- (void)setTextShadowColor:(CPColor)aColor
{
[self setValue:aColor forThemeAttribute:@"text-shadow-color"];
}
/*!
Returns the shadow color of the text for the control.
*/
- (CPColor)textShadowColor
{
return [self valueForThemeAttribute:@"text-shadow-color"];
}
- (void)setTextShadowOffset:(float)offset
/*!
Sets the shadow offset for the text.
@param offset - a CGSize with the x and y offsets.
*/
- (void)setTextShadowOffset:(CGSize)offset
{
[self setValue:offset forThemeAttribute:@"text-shadow-offset"];
}
- (float)textShadowOffset
/*!
Returns the text shadow offset of the receiver.
*/
- (CGSize)textShadowOffset
{
return [self valueForThemeAttribute:@"text-shadow-offset"];
}
/*!
Sets the font of the control.
*/
- (void)setFont:(CPFont)aFont
{
[self setValue:aFont forThemeAttribute:@"font"];
}
/*!
Returns the font of the control.
*/
- (CPFont)font
{
return [self valueForThemeAttribute:@"font"];
}
/*!
Sets the image position of the control.
<pre>
CPNoImage
CPImageOnly
CPImageLeft
CPImageRight
CPImageBelow
CPImageAbove
CPImageOverlaps
</pre>
*/
- (void)setImagePosition:(CPCellImagePosition)position
{
[self setValue:position forThemeAttribute:@"image-position"];
}
/*!
Returns the image position of the receiver.
*/
- (CPCellImagePosition)imagePosition
{
return [self valueForThemeAttribute:@"image-position"];
}
/*!
Sets the image scaling of the control.
<pre>
CPScaleProportionally
CPScaleToFit
CPScaleNone
</pre>
*/
- (void)setImageScaling:(CPImageScaling)scaling
{
[self setValue:scaling forThemeAttribute:@"image-scaling"];
}
/*!
Returns the image scaling of the control.
*/
- (CPImageScaling)imageScaling
{
return [self valueForThemeAttribute:@"image-scaling"];
}
/*!
Sets the enabled status of the control.
Controls that are not enabled can not be used by the user and obtain the CPThemeStateDisabled theme state.
@param BOOL - YES if the control should be enabled, otherwise NO.
*/
- (void)setEnabled:(BOOL)isEnabled
{
if (isEnabled)
@@ -680,16 +802,29 @@ var CPControlBlackColor = [CPColor blackColor];
[self setThemeState:CPThemeStateDisabled];
}
/*!
Returns YES if the receiver is enabled, otherwise NO.
*/
- (BOOL)isEnabled
{
return ![self hasThemeState:CPThemeStateDisabled];
}
/*!
Highlights the receiver.
@param BOOL - YES if the receiver should be highlighted, otherwise NO.
*/
- (void)highlight:(BOOL)shouldHighlight
{
[self setHighlighted:shouldHighlight];
}
/*!
Highlights the receiver.
@param BOOL - YES if the receiver should be highlighted, otherwise NO.
*/
- (void)setHighlighted:(BOOL)isHighlighted
{
if (isHighlighted)
@@ -698,6 +833,9 @@ var CPControlBlackColor = [CPColor blackColor];
[self unsetThemeState:CPThemeStateHighlighted];
}
/*!
Returns YES if the control is highlighted, otherwise NO.
*/
- (BOOL)isHighlighted
{
return [self hasThemeState:CPThemeStateHighlighted];
@@ -721,6 +859,7 @@ var __Deprecated__CPImageViewImageKey = @"CPImageViewImageKey";
/*
Initializes the control by unarchiving it from a coder.
@param aCoder the coder from which to unarchive the control
@return the initialized control
*/
@@ -744,6 +883,7 @@ var __Deprecated__CPImageViewImageKey = @"CPImageViewImageKey";
/*
Archives the control to the provided coder.
@param aCoder the coder to which the control will be archived.
*/
- (void)encodeWithCoder:(CPCoder)aCoder
@@ -753,8 +893,10 @@ var __Deprecated__CPImageViewImageKey = @"CPImageViewImageKey";
if (_sendsActionOnEndEditing)
[aCoder encodeBool:_sendsActionOnEndEditing forKey:CPControlSendsActionOnEndEditingKey];
if (_value !== nil)
[aCoder encodeObject:_value forKey:CPControlValueKey];
var objectValue = [self objectValue];
if (objectValue !== nil)
[aCoder encodeObject:objectValue forKey:CPControlValueKey];
if (_target !== nil)
[aCoder encodeConditionalObject:_target forKey:CPControlTargetKey];
+2 -2
View File
@@ -88,7 +88,7 @@ var CPDocumentUntitledCount = 0;
@class CPDocument
CPDocument is used to represent a document/file in a Cappuccino application.
In a document-based application, generally multiple documents are open simutaneously
In a document-based application, generally multiple documents are open simultaneously
(multiple text documents, slide presentations, spreadsheets, etc.), and multiple
CPDocuments should be used to represent this.
*/
@@ -208,7 +208,7 @@ var CPDocumentUntitledCount = 0;
throws an exception.
@param aType the format of the data
@param anError not used
@throws CPUnsupportedMethodException if this method hasn't been overriden by the subclass
@throws CPUnsupportedMethodException if this method hasn't been overridden by the subclass
@return the document data
*/
- (CPData)dataOfType:(CPString)aType error:({CPError})anError
+2 -2
View File
@@ -24,7 +24,7 @@
@import <Foundation/CPBundle.j>
@import "CPDocument.j"
@import "CPOpenPanel.j";
@import "CPOpenPanel.j"
var CPSharedDocumentController = nil;
@@ -177,7 +177,7 @@ var CPSharedDocumentController = nil;
@param aType the document type
@param aDelegate the delegate to notify
@param aSelector the selector to notify with
@param aContextInfo the context infomration passed to the delegate
@param aContextInfo the context information passed to the delegate
*/
- (CPDocument)makeDocumentWithContentsOfURL:(CPURL)anAbsoluteURL ofType:(CPString)aType delegate:(id)aDelegate didReadSelector:(SEL)aSelector contextInfo:(id)aContextInfo
{
+7 -7
View File
@@ -28,13 +28,13 @@
@import "CPWindow.j"
CPDragOperationNone = 0,
CPDragOperationCopy = 1 << 1,
CPDragOperationLink = 1 << 1,
CPDragOperationGeneric = 1 << 2,
CPDragOperationPrivate = 1 << 3,
CPDragOperationMove = 1 << 4,
CPDragOperationDelete = 1 << 5,
CPDragOperationNone = 0;
CPDragOperationCopy = 1 << 1;
CPDragOperationLink = 1 << 1;
CPDragOperationGeneric = 1 << 2;
CPDragOperationPrivate = 1 << 3;
CPDragOperationMove = 1 << 4;
CPDragOperationDelete = 1 << 5;
CPDragOperationEvery = -1;
#define DRAGGING_WINDOW(anObject) ([anObject isKindOfClass:[CPWindow class]] ? anObject : [anObject window])
+36 -28
View File
@@ -161,21 +161,21 @@ CPEscapeFunctionKey = "\u001B";
CPSpaceFunctionKey = "\u0020";
CPDOMEventDoubleClick = "dblclick",
CPDOMEventMouseDown = "mousedown",
CPDOMEventMouseUp = "mouseup",
CPDOMEventMouseMoved = "mousemove",
CPDOMEventMouseDragged = "mousedrag",
CPDOMEventKeyUp = "keyup",
CPDOMEventKeyDown = "keydown",
CPDOMEventKeyPress = "keypress";
CPDOMEventCopy = "copy";
CPDOMEventPaste = "paste";
CPDOMEventScrollWheel = "mousewheel";
CPDOMEventTouchStart = "touchstart";
CPDOMEventTouchMove = "touchmove";
CPDOMEventTouchEnd = "touchend";
CPDOMEventTouchCancel = "touchcancel";
CPDOMEventDoubleClick = "dblclick";
CPDOMEventMouseDown = "mousedown";
CPDOMEventMouseUp = "mouseup";
CPDOMEventMouseMoved = "mousemove";
CPDOMEventMouseDragged = "mousedrag";
CPDOMEventKeyUp = "keyup";
CPDOMEventKeyDown = "keydown";
CPDOMEventKeyPress = "keypress";
CPDOMEventCopy = "copy";
CPDOMEventPaste = "paste";
CPDOMEventScrollWheel = "mousewheel";
CPDOMEventTouchStart = "touchstart";
CPDOMEventTouchMove = "touchmove";
CPDOMEventTouchEnd = "touchend";
CPDOMEventTouchCancel = "touchcancel";
var _CPEventPeriodicEventPeriod = 0,
_CPEventPeriodicEventTimer = nil,
@@ -211,6 +211,7 @@ var _CPEventPeriodicEventPeriod = 0,
/*!
Creates a new keyboard event.
@param anEventType the event type. Must be one of CPKeyDown, CPKeyUp or CPFlagsChanged
@param aPoint the location of the cursor in the window specified by \c aWindowNumber
@param modifierFlags a bitwise combination of the modifiers specified in the CPEvent globals
@@ -235,7 +236,8 @@ var _CPEventPeriodicEventPeriod = 0,
}
/*!
Creates a new mouse event
Creates a new mouse event.
@param anEventType the event type
@param aPoint the location of the cursor in the window specified by \c aWindowNumber
@param modifierFlags a bitwise combination of the modifiers specified in the CPEvent globals
@@ -257,7 +259,8 @@ var _CPEventPeriodicEventPeriod = 0,
}
/*!
Creates a new custom event
Creates a new custom event.
@param anEventType the event type. Must be one of CPAppKitDefined, CPSystemDefined, CPApplicationDefined or CPPeriodic
@param aLocation the location of the cursor in the window specified by \c aWindowNumber
@param modifierFlags a bitwise combination of the modifiers specified in the CPEvent globals
@@ -349,10 +352,10 @@ var _CPEventPeriodicEventPeriod = 0,
/*!
Returns the location of the mouse (for mouse events).
If this is not a mouse event, it returns \c nil.
If \c window returns \c nil, then
the mouse coordinates will be based on the screen coordinates.
If the receiver is not a mouse event, it returns \c nil.
If \c window returns \c nil, then the mouse coordinates will be based on the screen coordinates.
Otherwise, the coordinates are relative to the window's coordinates.
@return the location of the mouse, or \c nil for non-mouse events.
*/
- (CGPoint)locationInWindow
@@ -372,7 +375,7 @@ var _CPEventPeriodicEventPeriod = 0,
}
/*!
Returns event information as a bit mask
Returns event information as a bit mask.
*/
- (unsigned)modifierFlags
{
@@ -380,7 +383,7 @@ var _CPEventPeriodicEventPeriod = 0,
}
/*!
Returns the time the event occurred
Returns the time the event occurred.
*/
- (CPTimeInterval)timestamp
{
@@ -396,7 +399,7 @@ var _CPEventPeriodicEventPeriod = 0,
}
/*!
Returns the event's associated window
Returns the event's associated window.
*/
- (CPWindow)window
{
@@ -427,7 +430,7 @@ var _CPEventPeriodicEventPeriod = 0,
}
/*!
Returns the number of clicks that caused this event. (mouse only)
Returns the number of clicks that caused this event (mouse only).
*/
- (int)clickCount
{
@@ -435,7 +438,8 @@ var _CPEventPeriodicEventPeriod = 0,
}
/*!
Returns the characters associated with this event (keyboard only)
Returns the characters associated with this event (keyboard only).
@throws CPInternalInconsistencyException if this method is called on a non-key event
*/
- (CPString)characters
@@ -445,6 +449,7 @@ var _CPEventPeriodicEventPeriod = 0,
/*!
Returns the character ignoring any modifiers (except shift).
@throws CPInternalInconsistencyException if this method is called on a non-key event
*/
- (CPString)charactersIgnoringModifiers
@@ -454,6 +459,7 @@ var _CPEventPeriodicEventPeriod = 0,
/*!
Returns \c YES if the keyboard event was caused by the key being held down.
@throws CPInternalInconsistencyException if this method is called on a non-key event
*/
- (BOOL)isARepeat
@@ -463,6 +469,7 @@ var _CPEventPeriodicEventPeriod = 0,
/*!
Returns the key's key code.
@throws CPInternalInconsistencyException if this method is called on a non-key event
*/
- (unsigned short)keyCode
@@ -495,7 +502,7 @@ var _CPEventPeriodicEventPeriod = 0,
return _DOMEvent;
}
// Getting Scroll Wheel Event Infomration
// Getting Scroll Wheel Event Information
/*!
Returns the change in the x-axis for a mouse event.
*/
@@ -586,7 +593,8 @@ var _CPEventPeriodicEventPeriod = 0,
}
/*!
Gene rates periodic events every \c aPeriod seconds.
Generates periodic events every \c aPeriod seconds.
@param aDelay the number of seconds before the first event
@param aPeriod the length of time in seconds between successive events
*/
@@ -599,7 +607,7 @@ var _CPEventPeriodicEventPeriod = 0,
}
/*!
Stops the periodic events from being generated
Stops the periodic events from being generated.
*/
+ (void)stopPeriodicEvents
{
+1 -1
View File
@@ -25,7 +25,7 @@
@import "CGContext.j"
var CPGraphicsContextCurrent = nil;
var CPGraphicsContextCurrent = nil;
/*!
@ingroup appkit
+64 -28
View File
@@ -52,7 +52,7 @@ var _CPMenuBarVisible = NO,
@class CPMenu
Menus provide the user with a list of actions and/or submenus. Submenus themselves are full fledged menus
and so a heirarchical structure appears.
and so a hierarchical structure appears.
*/
@implementation CPMenu : CPObject
{
@@ -80,6 +80,9 @@ var _CPMenuBarVisible = NO,
+ (void)initialize
{
if (self !== CPMenu)
return;
[[self class] setMenuBarAttributes:[CPDictionary dictionary]];
}
@@ -274,22 +277,7 @@ var _CPMenuBarVisible = NO,
*/
- (void)insertItem:(CPMenuItem)aMenuItem atIndex:(unsigned)anIndex
{
var menu = [aMenuItem menu];
if (menu)
if (menu !== self)
[CPException raise:CPInternalInconsistencyException reason:@"Attempted to insert item into menu that was already in another menu."];
else
return;
[aMenuItem setMenu:self];
[_items insertObject:aMenuItem atIndex:anIndex];
[[CPNotificationCenter defaultCenter]
postNotificationName:CPMenuDidAddItemNotification
object:self
userInfo:[CPDictionary dictionaryWithObject:anIndex forKey:@"CPMenuItemIndex"]];
[self insertObject:aMenuItem inItemsAtIndex:anIndex];
}
/*!
@@ -346,16 +334,7 @@ var _CPMenuBarVisible = NO,
*/
- (void)removeItemAtIndex:(unsigned)anIndex
{
if (anIndex < 0 || anIndex >= _items.length)
return;
[_items[anIndex] setMenu:nil];
[_items removeObjectAtIndex:anIndex];
[[CPNotificationCenter defaultCenter]
postNotificationName:CPMenuDidRemoveItemNotification
object:self
userInfo:[CPDictionary dictionaryWithObject:anIndex forKey:@"CPMenuItemIndex"]];
[self removeObjectFromItemsAtIndex:anIndex];
}
/*!
@@ -364,9 +343,11 @@ var _CPMenuBarVisible = NO,
*/
- (void)itemChanged:(CPMenuItem)aMenuItem
{
if ([aMenuItem menu] != self)
if ([aMenuItem menu] !== self)
return;
[aMenuItem setValue:[aMenuItem valueForKey:@"changeCount"] + 1 forKey:@"changeCount"];
[[CPNotificationCenter defaultCenter]
postNotificationName:CPMenuDidChangeItemNotification
object:self
@@ -1035,6 +1016,61 @@ var _CPMenuBarVisible = NO,
@end
@implementation CPMenu (CPKeyValueCoding)
- (CPUInteger)countOfItems
{
return [_items count];
}
- (CPMenuItem)objectInItemsAtIndex:(CPUInteger)anIndex
{
return [_items objectAtIndex:anIndex];
}
- (CPArray)itemsAtIndexes:(CPIndexSet)indexes
{
return [_items objectsAtIndexes:indexes];
}
@end
@implementation CPMenu (CPKeyValueObserving)
- (void)insertObject:(CPMenuItem)aMenuItem inItemsAtIndex:(CPUInteger)anIndex
{
var menu = [aMenuItem menu];
if (menu)
if (menu !== self)
[CPException raise:CPInternalInconsistencyException reason:@"Attempted to insert item into menu that was already in another menu."];
else
return;
[aMenuItem setMenu:self];
[_items insertObject:aMenuItem atIndex:anIndex];
[[CPNotificationCenter defaultCenter]
postNotificationName:CPMenuDidAddItemNotification
object:self
userInfo:[CPDictionary dictionaryWithObject:anIndex forKey:@"CPMenuItemIndex"]];
}
- (void)removeObjectFromItemsAtIndex:(CPUInteger)anIndex
{
if (anIndex < 0 || anIndex >= [_items count])
return;
[[_items objectAtIndex:anIndex] setMenu:nil];
[_items removeObjectAtIndex:anIndex];
[[CPNotificationCenter defaultCenter]
postNotificationName:CPMenuDidRemoveItemNotification
object:self
userInfo:[CPDictionary dictionaryWithObject:anIndex forKey:@"CPMenuItemIndex"]];
}
@end
var CPMenuTitleKey = @"CPMenuTitleKey",
CPMenuNameKey = @"CPMenuNameKey",
+7 -2
View File
@@ -77,6 +77,8 @@
id _representedObject;
CPView _view;
int _changeCount;
_CPMenuItemView _menuItemView;
}
@@ -98,12 +100,14 @@
if (self)
{
_changeCount = 0;
_isSeparator = NO;
_title = aTitle;
_action = anAction;
_isEnabled = YES;
_isHidden = NO;
_tag = 0;
_state = CPOffState;
@@ -445,7 +449,7 @@ CPOffState
return _mixedStateImage;
}
// Managing Subemenus
// Managing Submenus
/*!
Sets the submenu for this item
@param aMenu the submenu
@@ -644,7 +648,7 @@ CPControlKeyMask
}
/*!
Sets the title of the menu item and the mnemonic character. The mnemonic chracter should be preceded by an '&'.
Sets the title of the menu item and the mnemonic character. The mnemonic character should be preceded by an '&'.
@param aTitle the title string with a denoted mnemonic
*/
- (void)setTitleWithMnemonicLocation:(CPString)aTitle
@@ -890,6 +894,7 @@ var CPMenuItemIsSeparatorKey = @"CPMenuItemIsSeparatorKey",
if (self)
{
_changeCount = 0;
_isSeparator = [aCoder containsValueForKey:CPMenuItemIsSeparatorKey] && [aCoder decodeBoolForKey:CPMenuItemIsSeparatorKey];
_title = [aCoder decodeObjectForKey:CPMenuItemTitleKey];
-1
View File
@@ -34,7 +34,6 @@ var _CPMenuItemSelectionColor = nil,
BOOL _isDirty;
BOOL _showsStateColumn;
CPImageView _stateView;
_CPImageAndTextView _imageAndTextView;
CPView _submenuView;
}
+106
View File
@@ -4,7 +4,16 @@
@import "CPController.j"
/*!
@class
CPObjectController is a bindings-compatible controller class.
Properties of the content object of an object of this class can be bound to user interface elements to change and access their values.
The content of an CPObjectController instance is an CPMutableDictionary object by default.
This allows a single CPObjectController instance to be used to manage several properties accessed by key value paths.
The default content object class can be changed by calling setObjectClass:, which a subclass must override.
*/
@implementation CPObjectController : CPController
{
id _contentObject;
@@ -53,11 +62,20 @@
return [CPSet setWithObjects:"editable", "selection"];
}
/*!
@ignore
*/
- (id)init
{
return [self initWithContent:nil];
}
/*!
Inits and returns a CPObjectController object with the given content.
@param id aContent - The object the controller will use.
@return id the CPObjectConroller instance.
*/
- (id)initWithContent:(id)aContent
{
if (self = [super init])
@@ -72,11 +90,19 @@
return self;
}
/*!
Returns the controller's content object.
@return id - The content object of the controller.
*/
- (id)content
{
return _contentObject;
}
/*!
Sets the content object for the controller.
@param id aContent - The new content object for the controller.
*/
- (void)setContent:(id)aContent
{
[self willChangeValueForKey:@"contentObject"];
@@ -88,51 +114,91 @@
[self _selectionDidChange];
}
/*!
@ignore
*/
- (void)_setContentObject:(id)aContent
{
[self setContent:aContent];
}
/*!
@ignore
*/
- (id)_contentObject
{
return [self content];
}
/*!
Sets whether the controller automatically creates and inserts new content objects automatically when loading from a cib file.
If you pass YES and the controller uses prepareContent to create the content object.
The default is NO.
@param BOOL shouldAutomaticallyPrepareContent - YES if the content should be prepared, otherwise NO.
*/
- (void)setAutomaticallyPreparesContent:(BOOL)shouldAutomaticallyPrepareContent
{
_automaticallyPreparesContent = shouldAutomaticallyPrepareContent;
}
/*!
Returns if the controller prepares the content automatically.
@return BOOL - YES if the content is prepared, otherwise NO.
*/
- (BOOL)automaticallyPreparesContent
{
return _automaticallyPreparesContent;
}
/*!
Overridden by a subclass that require control over the creation of new objects.
*/
- (void)prepareContent
{
[self setContent:[self newObject]];
}
/*!
Sets the object class when creating new objects.
@param Class - the class of new objects that will be created.
*/
- (void)setObjectClass:(Class)aClass
{
_objectClass = aClass;
}
/*!
Returns the class of what new objects will be when they are created.
@return Class - The class of new objects.
*/
- (Class)objectClass
{
return _objectClass;
}
/*!
@ignore
*/
- (id)_defaultNewObject
{
return [[[self objectClass] alloc] init];
}
/*!
Creates and returns a new object of the appropriate class.
@return id - The object created.
*/
- (id)newObject
{
return [self _defaultNewObject];
}
/*!
Sets the controller's content object.
@param id anObject - The object to set for the controller.
*/
- (void)addObject:(id)anObject
{
[self setContent:anObject];
@@ -141,6 +207,10 @@
[[binderClass getBinding:@"contentObject" forObject:self] reverseSetValueFor:@"contentObject"];
}
/*!
Removes a given object from the controller.
@param id anObject - The object to remove from the receiver.
*/
- (void)removeObject:(id)anObject
{
if ([self content] === anObject)
@@ -150,54 +220,87 @@
[[binderClass getBinding:@"contentObject" forObject:self] reverseSetValueFor:@"contentObject"];
}
/*!
Creates and adds a sets the object as the controller's content.
@param id aSender - The sender of the message.
*/
- (void)add:(id)aSender
{
// FIXME: This should happen on the next run loop?
[self addObject:[self newObject]];
}
/*!
@return BOOL - YES if you can added to the controller using add:
*/
- (BOOL)canAdd
{
return [self isEditable];
}
/*!
Removes the content object from the controller.
@param id aSender - The sender of the message.
*/
- (void)remove:(id)aSender
{
// FIXME: This should happen on the next run loop?
[self removeObject:[self content]];
}
/*!
@return BOOL - Returns YES if you can remove the controller's content using remove:
*/
- (BOOL)canRemove
{
return [self isEditable] && [[self selectedObjects] count];
}
/*!
Sets whether the controller allows for the editing of the content.
@param BOOL shouldBeEditable - YES if the content should be editable, otherwise NO.
*/
- (void)setEditable:(BOOL)shouldBeEditable
{
_isEditable = shouldBeEditable;
}
/*!
@return BOOL - Returns YES if the content of the controller is editable, otherwise NO.
*/
- (BOOL)isEditable
{
return _isEditable;
}
/*!
@return CPArray - Returns an array of all objects to be affected by editing.
*/
- (CPArray)selectedObjects
{
return [[_CPObservableArray alloc] initWithArray:[_contentObject]];
}
/*!
Returns a proxy object representing the controller's selection.
*/
- (id)selection
{
return _selection;
}
/*!
@ignore
*/
- (void)_selectionWillChange
{
[_selection controllerWillChange];
[self willChangeValueForKey:@"selection"];
}
/*!
@ignore
*/
- (void)_selectionDidChange
{
if (_selection === undefined || _selection === nil)
@@ -207,6 +310,9 @@
[self didChangeValueForKey:@"selection"];
}
/*!
@return id - Returns the keys which are being observed.
*/
- (id)observedKeys
{
return _observedKeys;
+182 -74
View File
@@ -75,15 +75,24 @@ var CPOutlineViewDelegate_outlineView_dataViewForTableColumn_item_
CPOutlineViewDropOnItemIndex = -1;
var CPOutlineViewCoalesceSelectionNotificationStateOff = 0,
CPOutlineViewCoalesceSelectionNotificationStateOn = 1,
CPOutlineViewCoalesceSelectionNotificationStateDid = 2;
/*!
@ingroup appkit
@class CPOutlineView
CPOutlineView is a subclass of CPTableView that inherates the row and column format to display hierarchial data.
The outlineview adds the ability to expand and collapse items. This is useful for browsing a tree like structure such as directories or a filesystem.
CPOutlineView is a subclass of CPTableView that inherits the row and
column format to display hierarchical data. The outlineview adds the
ability to expand and collapse items. This is useful for browsing a tree
like structure such as directories or a filesystem.
Like the tableview, an outlineview uses a data source to supply its data. For this reason you must implement a couple data source methods (documented in setDataSource:)
Like the tableview, an outlineview uses a data source to supply its data.
For this reason you must implement a couple data source methods
(documented in setDataSource:).
Theme states for custom data views are documented in CPTableView.
*/
@implementation CPOutlineView : CPTableView
{
@@ -113,6 +122,8 @@ CPOutlineViewDropOnItemIndex = -1;
CPInteger _retargedChildIndex;
CPTimer _dragHoverTimer;
id _dropItem;
BOOL _coalesceSelectionNotificationState;
}
- (id)initWithFrame:(CGRect)aFrame
@@ -121,7 +132,6 @@ CPOutlineViewDropOnItemIndex = -1;
if (self)
{
_selectionHighlightStyle = CPTableViewSelectionHighlightStyleSourceList;
// The root item has weight "0", thus represents the weight solely of its descendants.
@@ -150,8 +160,10 @@ CPOutlineViewDropOnItemIndex = -1;
return self;
}
/*!
In addition to standard delegation, the outline view also supports data source delegation. This method sets the data source object.
Just like the TableView you have CPTableColumns but instead of rows you deal with items.
<pre>
In addition to standard delegation, the outline view also supports data
source delegation. This method sets the data source object. Just like the
TableView you have CPTableColumns but instead of rows you deal with items.
You must implement these data source methods:
@@ -177,10 +189,11 @@ CPOutlineViewDropOnItemIndex = -1;
Sorting:
- (void)outlineView:(CPOutlineView)outlineView sortDescriptorsDidChange:(CPArray)oldDescriptors;
The outlineview will call this method if you click the tableheader. You should sort the datasource based off of the new sort descriptors and reload the data
The outlineview will call this method if you click the table header. You should sort the datasource based off of the new sort descriptors and reload the data
Drag and Drop:
In order for the outlineview to recieve drops dont forget to first register the tableview for drag types like you do with every other view
In order for the outlineview to receive drops don't forget to first
register the tableview for drag types like you do with every other view
- (BOOL)outlineView:(CPOutlineView)outlineView acceptDrop:(id < CPDraggingInfo >)info item:(id)item childIndex:(CPInteger)index;
Return YES if the operation was successful otherwise return NO.
@@ -188,14 +201,14 @@ CPOutlineViewDropOnItemIndex = -1;
To get this data use the draggingPasteboard method on the CPDraggingInfo object.
- (CPDragOperation)outlineView:(CPOutlineView)outlineView validateDrop:(id < CPDraggingInfo >)info proposedItem:(id)item proposedChildIndex:(CPInteger)index;
Return the drag operation (move, copy, etc) that should be performaned if a registered drag type is over the tableview
Return the drag operation (move, copy, etc) that should be performed if a registered drag type is over the tableview
The data source can retarget a drop if you want by calling -(void)setDropItem:(id)anItem dropChildIndex:(int)anIndex;
- (BOOL)outlineView:(CPOutlineView)outlineView writeItems:(CPArray)items toPasteboard:(CPPasteboard)pboard;
Returns YES if the drop operation is allowed otherwise NO.
This method is invoked by the outlineview after a drag should begin, but before it is started. If you dont want the drag to being return NO.
This method is invoked by the outlineview after a drag should begin, but before it is started. If you don't want the drag to being return NO.
If you want the drag to begin you should return YES and place the drag data on the pboard.
</pre>
*/
- (void)setDataSource:(id)aDataSource
{
@@ -252,6 +265,7 @@ CPOutlineViewDropOnItemIndex = -1;
/*!
Returns the datasource object.
@return id - The data source object
*/
- (id)dataSource
@@ -280,7 +294,7 @@ CPOutlineViewDropOnItemIndex = -1;
}
/*!
Used to find if an item is already expanded.
Used to find if an item is already expanded.
@param anItem - the item you are interest in.
@@ -300,7 +314,7 @@ CPOutlineViewDropOnItemIndex = -1;
}
/*!
Expends a given item.
Expands a given item.
@param anItem - the item to expand.
*/
@@ -327,14 +341,31 @@ CPOutlineViewDropOnItemIndex = -1;
if (!itemInfo)
return;
// to prevent items which are already expanded from firing notifications
// When shouldExpandChildren is YES, we need to make sure we're collecting
// selection notifications so that exactly one IsChanging and one
// DidChange is sent as needed, for the totality of the operation.
var isTopLevel = NO;
if (!_coalesceSelectionNotificationState)
{
isTopLevel = YES;
_coalesceSelectionNotificationState = CPOutlineViewCoalesceSelectionNotificationStateOn;
}
// To prevent items which are already expanded from firing notifications.
if (!itemInfo.isExpanded)
{
[self _noteItemWillExpand:anItem];
var previousRowCount = [self numberOfRows];
itemInfo.isExpanded = YES;
// XXX Shouldn't the items reload before the notification is sent?
[self _noteItemDidExpand:anItem];
[self reloadItem:anItem reloadChildren:YES];
// Shift selection indexes below so that the same items remain selected.
var newRowCount = [_outlineViewDataSource outlineView:self numberOfChildrenOfItem:anItem];
if (newRowCount)
var rowCountDelta = [self numberOfRows] - previousRowCount;
if (rowCountDelta)
{
var selection = [self selectedRowIndexes],
expandIndex = [self rowForItem:anItem] + 1;
@@ -342,14 +373,10 @@ CPOutlineViewDropOnItemIndex = -1;
if ([selection intersectsIndexesInRange:CPMakeRange(expandIndex, _itemsForRows.length)])
{
[self _noteSelectionIsChanging];
[selection shiftIndexesStartingAtIndex:expandIndex by:newRowCount];
[self _setSelectedRowIndexes:selection];
[selection shiftIndexesStartingAtIndex:expandIndex by:rowCountDelta];
[self _setSelectedRowIndexes:selection]; // _noteSelectionDidChange will be suppressed.
}
}
itemInfo.isExpanded = YES;
[self _noteItemDidExpand:anItem];
[self reloadItem:anItem reloadChildren:YES];
}
if (shouldExpandChildren)
@@ -360,6 +387,14 @@ CPOutlineViewDropOnItemIndex = -1;
while (childIndex--)
[self expandItem:children[childIndex] expandChildren:YES];
}
if (isTopLevel)
{
var r = _coalesceSelectionNotificationState;
_coalesceSelectionNotificationState = CPOutlineViewCoalesceSelectionNotificationStateOff;
if (r === CPOutlineViewCoalesceSelectionNotificationStateDid)
[self _noteSelectionDidChange];
}
}
/*!
@@ -380,6 +415,9 @@ CPOutlineViewDropOnItemIndex = -1;
if (!itemInfo.isExpanded)
return;
// Don't spam notifications.
_coalesceSelectionNotificationState = CPOutlineViewCoalesceSelectionNotificationStateOn;
[self _noteItemWillCollapse:anItem];
// Update selections:
// * Deselect items inside the collapsed item.
@@ -392,39 +430,38 @@ CPOutlineViewDropOnItemIndex = -1;
collapseEndIndex++;
var collapseRange = CPMakeRange(collapseTopIndex + 1, collapseEndIndex - collapseTopIndex);
if (collapseRange.length)
{
var selection = [self selectedRowIndexes],
didChange = NO;
var selection = [self selectedRowIndexes];
if ([selection intersectsIndexesInRange:collapseRange])
{
[selection removeIndexesInRange:collapseRange];
[self _noteSelectionIsChanging];
didChange = YES;
// Will call _noteSelectionDidChange
[self _setSelectedRowIndexes:selection];
[selection removeIndexesInRange:collapseRange];
[self _setSelectedRowIndexes:selection]; // _noteSelectionDidChange will be suppressed.
}
// Shift any selected rows below upwards.
if ([selection intersectsIndexesInRange:CPMakeRange(collapseEndIndex + 1, _itemsForRows.length)])
{
// Notify if that wasn't already done above.
if (!didChange)
[self _noteSelectionIsChanging];
didChange = YES;
[self _noteSelectionIsChanging];
[selection shiftIndexesStartingAtIndex:collapseEndIndex + 1 by:-collapseRange.length];
[self _setSelectedRowIndexes:selection]; // _noteSelectionDidChange will be suppressed.
}
if (didChange)
[self _setSelectedRowIndexes:selection];
}
itemInfo.isExpanded = NO;
// XXX Shouldn't the items reload before the notification is sent?
[self _noteItemDidCollapse:anItem];
[self reloadItem:anItem reloadChildren:YES];
// Send selection notifications only after the items have loaded so that
// the new selection is consistent with the actual rows for any observers.
var r = _coalesceSelectionNotificationState;
_coalesceSelectionNotificationState = CPOutlineViewCoalesceSelectionNotificationStateOff;
if (r === CPOutlineViewCoalesceSelectionNotificationStateDid)
[self _noteSelectionDidChange];
}
/*!
@@ -456,7 +493,7 @@ CPOutlineViewDropOnItemIndex = -1;
/*!
Returns the item at a given row index. If no item exists nil is returned.
@param aRow - The rown index you want to find the item at.
@param aRow - The row index you want to find the item at.
@return id - The item at a given index.
*/
- (id)itemAtRow:(CPInteger)aRow
@@ -484,7 +521,8 @@ CPOutlineViewDropOnItemIndex = -1;
}
/*!
Sets the table column you want to display the disclosure button in.
Sets the table column you want to display the disclosure button in. If you
do not want an outline column pass nil.
@param aTableColumn - The CPTableColumn you want to use for hierarchical data.
*/
@@ -510,7 +548,9 @@ CPOutlineViewDropOnItemIndex = -1;
}
/*!
Returns the indentation level of a given item. If the item is nil (the top level root item) CPNotFound is returned. Indentation levels are zero based, thus items that are not indented return 0.
Returns the indentation level of a given item. If the item is nil (the top
level root item) CPNotFound is returned. Indentation levels are zero
based, thus items that are not indented return 0.
@param anItem - The item you want the indentation level for.
@return int - the indentation level of anItem.
@@ -529,9 +569,10 @@ CPOutlineViewDropOnItemIndex = -1;
}
/*!
Returns the indentation level for a given row. If the row is invalid CPNotFound is returned. Rows that are nto indented return 0.
Returns the indentation level for a given row. If the row is invalid
CPNotFound is returned. Rows that are not indented return 0.
@param aRow - the row of the reciever
@param aRow - the row of the receiver
@return int - the indentation level of aRow.
*/
- (CPInteger)levelForRow:(CPInteger)aRow
@@ -566,7 +607,9 @@ CPOutlineViewDropOnItemIndex = -1;
}
/*!
Sets the layout behaviour of disclosure button. If you pass NO the disclosure button will always align itself to the left of the outline column.
Sets the layout behavior of disclosure button. If you pass NO the
disclosure button will always align itself to the left of the outline
column.
@param indentationMarkerShouldFollowDataView - Pass YES if the disclosure control should be indented along with the dataview, otherwise NO.
*/
@@ -582,9 +625,11 @@ CPOutlineViewDropOnItemIndex = -1;
}
/*!
Returns the layout behaviour of the disclosure buttons.
Returns the layout behavior of the disclosure buttons.
@return BOOL - YES if the disclosure control indents itself with the dataview, otherwise NO if the control is always aligned to the left of the outline column
@return BOOL - YES if the disclosure control indents itself with the
dataview, otherwise NO if the control is always aligned to the left of
the outline column
*/
- (BOOL)indentationMarkerFollowsDataView
{
@@ -594,8 +639,9 @@ CPOutlineViewDropOnItemIndex = -1;
/*!
Returns the parent item for a given item. If the item is a top level root object nil is returned.
@param anItem - The item of the reciver.
@return id - The parent item of anItem. If no parent exists (the item is a root item) nil is returned.
@param anItem - The item of the receiver.
@return id - The parent item of anItem. If no parent exists (the item is a
root item) nil is returned.
*/
- (id)parentForItem:(id)anItem
{
@@ -619,7 +665,7 @@ CPOutlineViewDropOnItemIndex = -1;
/*!
@ignore
Returns the frame of the dataview at the row given for the outline column
Returns the frame of the dataview at the row given for the outline column.
*/
- (CGRect)_frameOfOutlineDataViewAtRow:(CPInteger)aRow
{
@@ -634,11 +680,11 @@ CPOutlineViewDropOnItemIndex = -1;
}
/*!
Returns the frame of the disclosure button for the outline column.
If the item is not expandable a CGZeroRect is returned.
Subclasses can return a CGZeroRect to prevent the disclosure control from being displayed.
Returns the frame of the disclosure button for the outline column. If the
item is not expandable a CGZeroRect is returned. Subclasses can return a
CGZeroRect to prevent the disclosure control from being displayed.
@param aRow - The row of the reciever
@param aRow - The row of the receiver
@return CGRect - The rect of the disclosure button at aRow.
*/
- (CGRect)frameOfOutlineDisclosureControlAtRow:(CPInteger)aRow
@@ -654,7 +700,7 @@ CPOutlineViewDropOnItemIndex = -1;
/*!
@ignore
Select or deselect rows, this is overridden because we need to change the color or the outline control
Select or deselect rows, this is overridden because we need to change the color or the outline control.
*/
- (void)_performSelection:(BOOL)select forRow:(CPInteger)rowIndex context:(id)context
{
@@ -667,6 +713,7 @@ CPOutlineViewDropOnItemIndex = -1;
}
/*!
<pre>
Sets the delegate for the outlineview.
The following methods can be implemented:
@@ -679,7 +726,7 @@ CPOutlineViewDropOnItemIndex = -1;
Called when the user resizes a column in the outlineview.
- (void)outlineViewItemDidCollapse:(CPNotification)notification;
Called when the user collapses an item in teh outlineview.
Called when the user collapses an item in the outlineview.
- (void)outlineViewItemDidExpand:(CPNotification)notification;
Called when the user expands an item in the outlineview.
@@ -726,7 +773,14 @@ CPOutlineViewDropOnItemIndex = -1;
Implement this to indicate whether a given item should be rendered using the group item style.
Return YES if the item is a group item, otherwise NO.
@param aDelegate - the delegate object you wish to set for the reciever.
Variable Item Heights
- (int)outlineView:(CPOutlineView)outlineView heightOfRowByItem:(id)anItem;
Implement this method to get custom heights of rows based on the item.
This delegate method will be passed your 'item' object and expects you to return an integer height.
NOTE: this should only be implemented if rows will be different heights, if you want to set a height for ALL of your rows see -setRowHeight:
@param aDelegate - the delegate object you wish to set for the receiver.
<pre>
*/
- (void)setDelegate:(id)aDelegate
{
@@ -899,8 +953,9 @@ CPOutlineViewDropOnItemIndex = -1;
}
/*!
Sets the prototype of the disclosure control. This is used if you want to set a special type of button, instead of the default triangle.
The control must implement CPCoding.
Sets the prototype of the disclosure control. This is used if you want to
set a special type of button, instead of the default triangle. The control
must implement CPCoding.
@param aControl - the control to be used to expand and collapse items.
*/
@@ -910,7 +965,7 @@ CPOutlineViewDropOnItemIndex = -1;
_disclosureControlData = nil;
_disclosureControlQueue = [];
// fIXME: reall?
// fIXME: really?
[self reloadData];
}
@@ -922,9 +977,37 @@ CPOutlineViewDropOnItemIndex = -1;
[self reloadItem:nil reloadChildren:YES];
}
/*!
Adds a new table column to the receiver. If this is the first column added
it will automatically be set to the outline column.
Also see -setOutlineTableColumn:.
NOTE: This behavior deviates from cocoa slightly.
@param CPTableColumn aTableColumn - The table column to add.
*/
- (void)addTableColumn:(CPTableColumn)aTableColumn
{
[super addTableColumn:aTableColumn];
if ([self numberOfColumns] === 1)
_outlineTableColumn = aTableColumn;
}
/*!
@ignore
We overide this because we need a special behaviour for the outline column
*/
- (void)removeTableColumn:(CPTableColumn)aTableColumn
{
if (aTableColumn === [self outlineTableColumn])
CPLog("CPOutlineView cannot remove outlineTableColumn with removeTableColumn:. User setOutlineTableColumn: instead.");
else
[super removeTableColumn:aTableColumn];
}
/*!
@ignore
We override this because we need a special behavior for the outline
column.
*/
- (CGRect)frameOfDataViewAtColumn:(CPInteger)aColumn row:(CPInteger)aRow
{
@@ -938,7 +1021,7 @@ CPOutlineViewDropOnItemIndex = -1;
/*!
@ignore
we need to offset the dataview and add the dislosure triangle
We need to offset the dataview and add the disclosure triangle.
*/
- (CPView)_dragViewForColumn:(int)theColumnIndex event:(CPEvent)theDragEvent offset:(CPPointPointer)theDragViewOffset
{
@@ -998,9 +1081,15 @@ CPOutlineViewDropOnItemIndex = -1;
/*!
Retargets the drop item for the outlineview.
To specify a drop on theItem, you specify item as theItem and index as CPOutlineViewDropOnItemIndex.
To specify a drop between child 1 and 2 of theItem, you specify item as theItem and index as 2.
To specify a drop on an item that can't be expanded theItem, you specify item as someOutlineItem and index as CPOutlineViewDropOnItemIndex.
To specify a drop on theItem, you specify item as theItem and index as
CPOutlineViewDropOnItemIndex.
To specify a drop between child 1 and 2 of theItem, you specify item as
theItem and index as 2.
To specify a drop on an item that can't be expanded theItem, you specify
item as someOutlineItem and index as CPOutlineViewDropOnItemIndex.
@param theItem - The item you want to retarget the drop on.
@param theIndex - The index of the child item you want to retarget the drop between. Pass CPOutlineViewDropOnItemIndex if you want to drop on theItem.
@@ -1110,7 +1199,7 @@ CPOutlineViewDropOnItemIndex = -1;
/*!
@ignore
We need to move the disclosure control too
We need to move the disclosure control too.
*/
- (void)_layoutDataViewsInRows:(CPIndexSet)rows columns:(CPIndexSet)columns
{
@@ -1277,10 +1366,16 @@ CPOutlineViewDropOnItemIndex = -1;
*/
- (void)_noteSelectionIsChanging
{
[[CPNotificationCenter defaultCenter]
postNotificationName:CPOutlineViewSelectionIsChangingNotification
object:self
userInfo:nil];
if (!_coalesceSelectionNotificationState || _coalesceSelectionNotificationState === CPOutlineViewCoalesceSelectionNotificationStateOn)
{
[[CPNotificationCenter defaultCenter]
postNotificationName:CPOutlineViewSelectionIsChangingNotification
object:self
userInfo:nil];
}
if (_coalesceSelectionNotificationState === CPOutlineViewCoalesceSelectionNotificationStateOn)
_coalesceSelectionNotificationState = CPOutlineViewCoalesceSelectionNotificationStateDid;
}
/*!
@@ -1288,10 +1383,16 @@ CPOutlineViewDropOnItemIndex = -1;
*/
- (void)_noteSelectionDidChange
{
[[CPNotificationCenter defaultCenter]
postNotificationName:CPOutlineViewSelectionDidChangeNotification
object:self
userInfo:nil];
if (!_coalesceSelectionNotificationState)
{
[[CPNotificationCenter defaultCenter]
postNotificationName:CPOutlineViewSelectionDidChangeNotification
object:self
userInfo:nil];
}
if (_coalesceSelectionNotificationState === CPOutlineViewCoalesceSelectionNotificationStateOn)
_coalesceSelectionNotificationState = CPOutlineViewCoalesceSelectionNotificationStateDid;
}
/*!
@@ -1651,13 +1752,13 @@ var _loadItemInfoForItem = function(/*CPOutlineView*/ anOutlineView, /*id*/ anIt
return NO;
}
/*- (float)tableView:(CPTableView)theTableView heightOfRow:(int)theRow
- (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
{
@@ -1787,7 +1888,14 @@ var CPOutlineViewIndentationPerLevelKey = @"CPOutlineViewIndentationPerLevelKey"
- (void)encodeWithCoder:(CPCoder)aCoder
{
// Make sure we don't encode our internal delegate and data source.
var internalDelegate = _delegate,
internalDataSource = _dataSource;
_delegate = nil;
_dataSource = nil;
[super encodeWithCoder:aCoder];
_delegate = internalDelegate;
_dataSource = internalDataSource;
[aCoder encodeObject:_outlineTableColumn forKey:CPOutlineViewOutlineTableColumnKey];
[aCoder encodeFloat:_indentationPerLevel forKey:CPOutlineViewIndentationPerLevelKey];
+1 -1
View File
@@ -26,7 +26,7 @@
CPOKButton = 1;
CPCancelButton = 0;
/*!
/*!
@ingroup appkit
@class CPPanel
+228 -200
View File
@@ -26,7 +26,7 @@
@import "CPMenuItem.j"
var VISIBLE_MARGIN = 7.0;
var VISIBLE_MARGIN = 7.0;
CPPopUpButtonStatePullsDown = CPThemeState("pulls-down");
@@ -38,10 +38,8 @@ CPPopUpButtonStatePullsDown = CPThemeState("pulls-down");
*/
@implementation CPPopUpButton : CPButton
{
int _selectedIndex;
CPUInteger _selectedIndex;
CPRectEdge _preferredEdge;
CPMenu _menu;
}
+ (CPString)defaultThemeClass
@@ -49,9 +47,19 @@ CPPopUpButtonStatePullsDown = CPThemeState("pulls-down");
return "popup-button";
}
+ (CPSet)keyPathsForValuesAffectingSelectedIndex
{
return [CPSet setWithObject:@"objectValue"];
}
+ (CPSet)keyPathsForValuesAffectingSelectedTag
{
return [CPSet setWithObject:@"selectedIndex"];
return [CPSet setWithObject:@"objectValue"];
}
+ (CPSet)keyPathsForValuesAffectingSelectedItem
{
return [CPSet setWithObject:@"objectValue"];
}
/*!
@@ -66,7 +74,8 @@ CPPopUpButtonStatePullsDown = CPThemeState("pulls-down");
if (self)
{
_selectedIndex = CPNotFound;
[self selectItemAtIndex:CPNotFound];
_preferredEdge = CPMaxYEdge;
[self setValue:CPImageLeft forThemeAttribute:@"image-position"];
@@ -76,6 +85,14 @@ CPPopUpButtonStatePullsDown = CPThemeState("pulls-down");
[self setMenu:[[CPMenu alloc] initWithTitle:@""]];
[self setPullsDown:shouldPullDown];
var options = CPKeyValueObservingOptionNew |
CPKeyValueObservingOptionOld;/* |
CPKeyValueObservingOptionInitial;
*/
[self addObserver:self forKeyPath:@"menu.items" options:options context:nil];
[self addObserver:self forKeyPath:@"_firstItem.changeCount" options:options context:nil];
[self addObserver:self forKeyPath:@"selectedItem.changeCount" options:options context:nil];
}
return self;
@@ -90,6 +107,9 @@ CPPopUpButtonStatePullsDown = CPThemeState("pulls-down");
/*!
Specifies whether the object is a pull-down or a pop-up menu.
If the button pulls down the menu items represent actions, not states.
So the text in the button will NOT change when the user selects something different.
@param shouldPullDown \c YES makes the pop-up button
a pull-down menu. \c NO makes it a pop-up menu.
*/
@@ -103,7 +123,7 @@ CPPopUpButtonStatePullsDown = CPThemeState("pulls-down");
if (!changed)
return;
var items = [_menu itemArray];
var items = [[self menu] itemArray];
if ([items count] <= 0)
return;
@@ -128,21 +148,21 @@ CPPopUpButtonStatePullsDown = CPThemeState("pulls-down");
*/
- (void)addItem:(CPMenuItem)anItem
{
[_menu addItem:anItem];
[[self menu] addItem:anItem];
}
/*!
Adds a new menu item with the specified title.
@param the new menu item's tite
@param the new menu item's title
*/
- (void)addItemWithTitle:(CPString)aTitle
{
[_menu addItemWithTitle:aTitle action:NULL keyEquivalent:nil];
[[self menu] addItemWithTitle:aTitle action:NULL keyEquivalent:nil];
}
/*!
Adds multiple new menu items with the titles specified in the provided array.
@param titles an arry of names for the new items
@param titles an array of names for the new items
*/
- (void)addItemsWithTitles:(CPArray)titles
{
@@ -155,7 +175,7 @@ CPPopUpButtonStatePullsDown = CPThemeState("pulls-down");
/*!
Inserts a new item with the specified title and index location.
@param aTitle the new itme's title
@param aTitle the new item's title
@param anIndex the item's index in the menu
*/
- (void)insertItemWithTitle:(CPString)aTitle atIndex:(int)anIndex
@@ -167,7 +187,7 @@ CPPopUpButtonStatePullsDown = CPThemeState("pulls-down");
if ([items[count] title] == aTitle)
[self removeItemAtIndex:count];
[_menu insertItemWithTitle:aTitle action:NULL keyEquivalent:nil atIndex:anIndex];
[[self menu] insertItemWithTitle:aTitle action:NULL keyEquivalent:nil atIndex:anIndex];
}
/*!
@@ -175,10 +195,11 @@ CPPopUpButtonStatePullsDown = CPThemeState("pulls-down");
*/
- (void)removeAllItems
{
var count = [_menu numberOfItems];
var menu = [self menu],
count = [menu numberOfItems];
while (count--)
[_menu removeItemAtIndex:0];
[menu removeItemAtIndex:0];
}
/*!
@@ -197,7 +218,7 @@ CPPopUpButtonStatePullsDown = CPThemeState("pulls-down");
*/
- (void)removeItemAtIndex:(int)anIndex
{
[_menu removeItemAtIndex:anIndex];
[[self menu] removeItemAtIndex:anIndex];
[self synchronizeTitleAndSelectedItem];
}
@@ -207,10 +228,12 @@ CPPopUpButtonStatePullsDown = CPThemeState("pulls-down");
*/
- (CPMenuItem)selectedItem
{
if (_selectedIndex < 0 || _selectedIndex > [self numberOfItems] - 1)
var indexOfSelectedItem = [self indexOfSelectedItem];
if (indexOfSelectedItem < 0 || indexOfSelectedItem > [self numberOfItems] - 1)
return nil;
return [_menu itemAtIndex:_selectedIndex];
return [[self menu] itemAtIndex:indexOfSelectedItem];
}
/*!
@@ -229,15 +252,6 @@ CPPopUpButtonStatePullsDown = CPThemeState("pulls-down");
return _selectedIndex;
}
// For us, CPNumber is toll-free bridged to Number, so just return the selected index.
/*!
Returns the selected item's index. If no item is selected, it returns CPNotFound.
*/
- (id)objectValue
{
return _selectedIndex;
}
/*!
@ignore
*/
@@ -268,24 +282,48 @@ CPPopUpButtonStatePullsDown = CPThemeState("pulls-down");
Selects the item at the specified index
@param anIndex the index of the item to select
*/
- (void)selectItemAtIndex:(int)anIndex
- (void)selectItemAtIndex:(CPUInteger)anIndex
{
if (_selectedIndex == anIndex)
[self setObjectValue:anIndex];
}
- (void)setSelectedIndex:(CPUInteger)anIndex
{
[self setObjectValue:anIndex];
}
- (CPUInteger)selectedIndex
{
return [self objectValue];
}
/*!
Selects the item at the specified index
@param anIndex the index of the item to select
*/
- (void)setObjectValue:(int)anIndex
{
var indexOfSelectedItem = [self objectValue];
anIndex = parseInt(+anIndex, 10);
if (indexOfSelectedItem === anIndex)
return;
[self willChangeValueForKey:@"selectedIndex"];
if (_selectedIndex >= 0 && ![self pullsDown])
if (indexOfSelectedItem >= 0 && ![self pullsDown])
[[self selectedItem] setState:CPOffState];
_selectedIndex = anIndex;
if (_selectedIndex >= 0 && ![self pullsDown])
if (indexOfSelectedItem >= 0 && ![self pullsDown])
[[self selectedItem] setState:CPOnState];
[self synchronizeTitleAndSelectedItem];
}
[self didChangeValueForKey:@"selectedIndex"];
- (id)objectValue
{
return _selectedIndex;
}
/*!
@@ -306,84 +344,14 @@ CPPopUpButtonStatePullsDown = CPThemeState("pulls-down");
[self selectItemAtIndex:[self indexOfItemWithTitle:aTitle]];
}
/*!
Sets the object for the selected item. If no item is selected, then this method has no effect.
@param the object set for the selected item
*/
- (void)setObjectValue:(id)aValue
{
[self selectItemAtIndex:[aValue intValue]];
}
// Getting Menu Items
/*!
Returns the button's menu of items.
*/
- (CPMenu)menu
{
return _menu;
}
/*!
Sets the menu for the button
*/
- (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];
}
_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];
}
[self synchronizeTitleAndSelectedItem];
}
/*!
Returns a count of the number of items in the button's menu.
*/
- (int)numberOfItems
{
return [_menu numberOfItems];
return [[self menu] numberOfItems];
}
/*!
@@ -391,7 +359,7 @@ CPPopUpButtonStatePullsDown = CPThemeState("pulls-down");
*/
- (CPArray)itemArray
{
return [_menu itemArray];
return [[self menu] itemArray];
}
/*!
@@ -400,7 +368,7 @@ CPPopUpButtonStatePullsDown = CPThemeState("pulls-down");
*/
- (CPMenuItem)itemAtIndex:(unsigned)anIndex
{
return [_menu itemAtIndex:anIndex];
return [[self menu] itemAtIndex:anIndex];
}
/*!
@@ -409,7 +377,7 @@ CPPopUpButtonStatePullsDown = CPThemeState("pulls-down");
*/
- (CPString)itemTitleAtIndex:(unsigned)anIndex
{
return [[_menu itemAtIndex:anIndex] title];
return [[[self menu] itemAtIndex:anIndex] title];
}
/*!
@@ -434,7 +402,9 @@ CPPopUpButtonStatePullsDown = CPThemeState("pulls-down");
*/
- (CPMenuItem)itemWithTitle:(CPString)aTitle
{
return [_menu itemAtIndex:[_menu indexOfItemWithTitle:aTitle]];
var menu = [self menu];
return [menu itemAtIndex:[menu indexOfItemWithTitle:aTitle]];
}
/*!
@@ -442,7 +412,7 @@ CPPopUpButtonStatePullsDown = CPThemeState("pulls-down");
*/
- (CPMenuItem)lastItem
{
return [[_menu itemArray] lastObject];
return [[[self menu] itemArray] lastObject];
}
// Getting the Indices of Menu Items
@@ -452,7 +422,7 @@ CPPopUpButtonStatePullsDown = CPThemeState("pulls-down");
*/
- (int)indexOfItem:(CPMenuItem)aMenuItem
{
return [_menu indexOfItem:aMenuItem];
return [[self menu] indexOfItem:aMenuItem];
}
/*!
@@ -461,16 +431,16 @@ CPPopUpButtonStatePullsDown = CPThemeState("pulls-down");
*/
- (int)indexOfItemWithTag:(int)aTag
{
return [_menu indexOfItemWithTag:aTag];
return [[self menu] indexOfItemWithTag:aTag];
}
/*!
Returns the index of the item with the specified title or CPNotFound.
@param aTitle the item's titel
@param aTitle the item's title
*/
- (int)indexOfItemWithTitle:(CPString)aTitle
{
return [_menu indexOfItemWithTitle:aTitle];
return [[self menu] indexOfItemWithTitle:aTitle];
}
/*!
@@ -481,7 +451,7 @@ CPPopUpButtonStatePullsDown = CPThemeState("pulls-down");
*/
- (int)indexOfItemWithRepresentedObject:(id)anObject
{
return [_menu indexOfItemWithRepresentedObject:anObject];
return [[self menu] indexOfItemWithRepresentedObject:anObject];
}
/*!
@@ -493,7 +463,7 @@ CPPopUpButtonStatePullsDown = CPThemeState("pulls-down");
*/
- (int)indexOfItemWithTarget:(id)aTarget action:(SEL)anAction
{
return [_menu indexOfItemWithTarget:aTarget action:anAction];
return [[self menu] indexOfItemWithTarget:aTarget action:anAction];
}
// Setting the Cell Edge to Pop out in Restricted Situations
@@ -508,7 +478,7 @@ CPPopUpButtonStatePullsDown = CPThemeState("pulls-down");
}
/*!
Sets the preffered edge of the button to display the
Sets the preferred edge of the button to display the
pop-up when there is a limited amount of screen space.
By default, the pop-up should draw on top of the button.
*/
@@ -529,7 +499,7 @@ CPPopUpButtonStatePullsDown = CPThemeState("pulls-down");
if ([self pullsDown])
{
var items = [_menu itemArray];
var items = [[self menu] itemArray];
if ([items count] <= 0)
[self addItemWithTitle:aTitle];
@@ -577,7 +547,7 @@ CPPopUpButtonStatePullsDown = CPThemeState("pulls-down");
if ([self pullsDown])
{
var items = [_menu itemArray];
var items = [[self menu] itemArray];
if ([items count] > 0)
item = items[0];
@@ -589,73 +559,117 @@ CPPopUpButtonStatePullsDown = CPThemeState("pulls-down");
[super setTitle:[item title]];
}
//
/*!
Called when the menu has a new item added to it.
@param aNotification information about the event
*/
- (void)menuDidAddItem:(CPNotification)aNotification
- (void)observeValueForKeyPath:(CPString)aKeyPath ofObject:(id)anObject change:(CPDictionary)changes context:(id)aContext
{
var index = [[aNotification userInfo] objectForKey:@"CPMenuItemIndex"];
var pullsDown = [self pullsDown];
if (_selectedIndex < 0)
[self selectItemAtIndex:0];
else if (index == _selectedIndex)
if (!pullsDown && aKeyPath === @"selectedItem.changeCount" ||
pullsDown && (aKeyPath === @"_firstItem" || aKeyPath === @"_firstItem.changeCount"))
[self synchronizeTitleAndSelectedItem];
else if (index < _selectedIndex)
++_selectedIndex;
if (index == 0 && [self pullsDown])
// FIXME: This is due to a bug in KVO, we should never get it for "menu".
if (aKeyPath === @"menu")
{
var items = [_menu itemArray];
aKeyPath = @"menu.items";
[items[0] setHidden:YES];
if (items.length > 0)
[items[1] setHidden:NO];
[changes setObject:CPKeyValueChangeSetting forKey:CPKeyValueChangeKindKey];
[changes setObject:[[self menu] itemArray] forKey:CPKeyValueChangeNewKey];
}
var item = [_menu itemArray][index],
action = [item action];
if (!action || (action === @selector(_popUpItemAction:)))
if (aKeyPath === @"menu.items")
{
[item setTarget:self];
[item setAction:@selector(_popUpItemAction:)];
var changeKind = [changes objectForKey:CPKeyValueChangeKindKey],
indexOfSelectedItem = [self indexOfSelectedItem];
if (changeKind === CPKeyValueChangeRemoval)
{
var index = CPNotFound,
indexes = [changes objectForKey:CPKeyValueChangeIndexesKey];
if ([indexes containsIndex:0] && [self pullsDown])
[self _firstItemDidChange];
// See whether the index has changed, despite the actual item not changing.
while ((index = [indexes indexGreaterThanIndex:index]) !== CPNotFound &&
index <= indexOfSelectedItem)
--indexOfSelectedItem;
[self selectItemAtIndex:indexOfSelectedItem];
}
else if (changeKind === CPKeyValueChangeReplacement)
{
var indexes = [changes objectForKey:CPKeyValueChangeIndexesKey];
if (pullsDown && [indexes containsIndex:0] ||
!pullsDown && [indexes containsIndex:indexOfSelectedItem])
[self synchronizeTitleAndSelectedItem];
}
else
{
// No matter what, we want to prepare the new items.
var newItems = [changes objectForKey:CPKeyValueChangeNewKey];
[newItems enumerateObjectsUsingBlock:function(aMenuItem)
{
var action = [aMenuItem action];
if (!action)
[aMenuItem setAction:action = @selector(_popUpItemAction:)];
if (action === @selector(_popUpItemAction:))
[aMenuItem setTarget:self];
}];
if (changeKind === CPKeyValueChangeSetting)
{
[self _firstItemDidChange];
[self selectItemAtIndex:CPNotFound];
[self selectItemAtIndex:MIN([newItems count] - 1, indexOfSelectedItem)];
}
else //if (changeKind === CPKeyValueChangeInsertion)
{
var indexes = [changes objectForKey:CPKeyValueChangeIndexesKey];
if ([self pullsDown] && [indexes containsIndex:0])
{
[self _firstItemDidChange];
if ([self numberOfItems] > 1)
{
var index = CPNotFound,
originalIndex = 0;
while ((index = [indexes indexGreaterThanIndex:index]) !== CPNotFound &&
index <= originalIndex)
++originalIndex;
[[self itemAtIndex:originalIndex] setHidden:NO];
}
}
if (indexOfSelectedItem < 0)
[self selectItemAtIndex:0];
else
{
var index = CPNotFound;
// See whether the index has changed, despite the actual item not changing.
while ((index = [indexes indexGreaterThanIndex:index]) !== CPNotFound &&
index <= indexOfSelectedItem)
++indexOfSelectedItem;
[self selectItemAtIndex:indexOfSelectedItem];
}
}
}
}
}
/*!
Called when a menu item has changed.
@param aNotification information about the event
*/
- (void)menuDidChangeItem:(CPNotification)aNotification
{
var index = [[aNotification userInfo] objectForKey:@"CPMenuItemIndex"];
if ([self pullsDown] && index != 0)
return;
if (![self pullsDown] && index != _selectedIndex)
return;
[self synchronizeTitleAndSelectedItem];
}
/*!
Called when an item was removed from the menu.
@param aNotification information about the event
*/
- (void)menuDidRemoveItem:(CPNotification)aNotification
{
var numberOfItems = [self numberOfItems];
if (numberOfItems <= _selectedIndex && numberOfItems > 0)
[self selectItemAtIndex:numberOfItems - 1];
else
[self synchronizeTitleAndSelectedItem];
// [super observeValueForKeyPath:aKeyPath ofObject:anObject change:changes context:aContext];
}
- (void)mouseDown:(CPEvent)anEvent
@@ -727,7 +741,7 @@ CPPopUpButtonStatePullsDown = CPThemeState("pulls-down");
- (void)rightMouseDown:(CPEvent)anEvent
{
// Disable standard CPView behaviour which incorrectly displays the menu as a 'context menu'.
// Disable standard CPView behavior which incorrectly displays the menu as a 'context menu'.
}
- (void)_popUpItemAction:(id)aSender
@@ -735,6 +749,22 @@ CPPopUpButtonStatePullsDown = CPThemeState("pulls-down");
[self sendAction:[self action] to:[self target]];
}
- (void)_firstItemDidChange
{
[self willChangeValueForKey:@"_firstItem"];
[self didChangeValueForKey:@"_firstItem"];
[[self _firstItem] setHidden:YES];
}
- (CPMenuItem)_firstItem
{
if ([self numberOfItems] <= 0)
return nil;
return [[self menu] itemAtIndex:0];
}
- (void)takeValueFromKeyPath:(CPString)aKeyPath ofObjects:(CPArray)objects
{
var count = objects.length,
@@ -744,19 +774,14 @@ CPPopUpButtonStatePullsDown = CPThemeState("pulls-down");
[self setEnabled:YES];
while (count-- > 1)
{
if (value !== [objects[count] valueForKeyPath:aKeyPath])
{
[[self selectedItem] setState:CPOffState];
}
}
}
@end
var CPPopUpButtonMenuKey = @"CPPopUpButtonMenuKey",
CPPopUpButtonSelectedIndexKey = @"CPPopUpButtonSelectedIndexKey",
CPPopUpButtonPullsDownKey = @"CPPopUpButtonPullsDownKey";
var DEPRECATED_CPPopUpButtonMenuKey = @"CPPopUpButtonMenuKey",
DEPRECATED_CPPopUpButtonSelectedIndexKey = @"CPPopUpButtonSelectedIndexKey";
@implementation CPPopUpButton (CPCoding)
/*!
@@ -772,27 +797,30 @@ var CPPopUpButtonMenuKey = @"CPPopUpButtonMenuKey",
if (self)
{
// Nothing is currently selected
_selectedIndex = -1;
// FIXME: (or not?) _title is nulled in - [CPButton initWithCoder:],
// so we need to do this again.
[self synchronizeTitleAndSelectedItem];
[self setMenu:[aCoder decodeObjectForKey:CPPopUpButtonMenuKey]];
[self selectItemAtIndex:[aCoder decodeObjectForKey:CPPopUpButtonSelectedIndexKey]];
// FIXME: Remove deprecation leniency for 1.0
if ([aCoder containsValueForKey:DEPRECATED_CPPopUpButtonMenuKey])
{
CPLog.warn(self + " was encoded with an older version of Cappuccino. Please nib2cib the original nib again or open and re-save in Atlas.");
[self setMenu:[aCoder decodeObjectForKey:DEPRECATED_CPPopUpButtonMenuKey]];
[self setObjectValue:[aCoder decodeObjectForKey:DEPRECATED_CPPopUpButtonSelectedIndexKey]];
}
var options = CPKeyValueObservingOptionNew |
CPKeyValueObservingOptionOld;/* |
CPKeyValueObservingOptionInitial;
*/
[self addObserver:self forKeyPath:@"menu.items" options:options context:nil];
[self addObserver:self forKeyPath:@"_firstItem.changeCount" options:options context:nil];
[self addObserver:self forKeyPath:@"selectedItem.changeCount" options:options context:nil];
}
return self;
}
/*!
Encodes the data of the pop-up button into a coder
@param aCoder the coder to which the data
will be written
*/
- (void)encodeWithCoder:(CPCoder)aCoder
{
[super encodeWithCoder:aCoder];
[aCoder encodeObject:_menu forKey:CPPopUpButtonMenuKey];
[aCoder encodeInt:_selectedIndex forKey:CPPopUpButtonSelectedIndexKey];
}
@end
+2 -2
View File
@@ -120,7 +120,7 @@ var CPProgressIndicatorSpinningStyleColors = nil,
CPProgressIndicatorStyleSizes = [];
// Bar Sttyle
// Bar Style
var prefixes = [
CPProgressIndicatorClassName + @"BezelBorder" + CPProgressIndicatorStyleIdentifiers[CPProgressIndicatorBarStyle],
CPProgressIndicatorClassName + @"Bar" + CPProgressIndicatorStyleIdentifiers[CPProgressIndicatorBarStyle],
@@ -290,7 +290,7 @@ var CPProgressIndicatorSpinningStyleColors = nil,
}
/*
Not yet impemented.
Not yet implemented.
*/
- (CPControlTint)controlTint
{
+2 -2
View File
@@ -358,8 +358,8 @@ var CPResponderNextResponderKey = @"CPResponderNextResponderKey",
if (self)
{
_nextResponder = [aCoder decodeObjectForKey:CPResponderNextResponderKey];
_menu = [aCoder decodeObjectForKey:CPResponderMenuKey];
[self setNextResponder:[aCoder decodeObjectForKey:CPResponderNextResponderKey]];
[self setMenu:[aCoder decodeObjectForKey:CPResponderMenuKey]];
}
return self;
+2 -2
View File
@@ -506,7 +506,7 @@
}
/*!
Sets whether the scroll view hides its scoll bars when not needed.
Sets whether the scroll view hides its scroll bars when not needed.
@param autohidesScrollers \c YES causes the scroll bars
to be hidden when not needed.
*/
@@ -796,7 +796,7 @@
/*!
Sets the vertical page scroll amount.
@param aPageScroll the new vertcal page scroll amount
@param aPageScroll the new vertical page scroll amount
*/
- (void)setVerticalPageScroll:(float)aPageScroll
{
+3 -3
View File
@@ -181,7 +181,7 @@ var RECENT_SEARCH_PREFIX = @" ";
[_cancelButton setFrame:[self cancelButtonRectForBounds:[self bounds]]];
[_cancelButton setAutoresizingMask:CPViewMinXMargin];
[_cancelButton setTarget:self];
[_cancelButton setAction:@selector(_searchFieldCancel:)];
[_cancelButton setAction:@selector(cancelOperation:)];
[self _updateCancelButtonVisibility];
[self addSubview:_cancelButton];
}
@@ -209,7 +209,7 @@ var RECENT_SEARCH_PREFIX = @" ";
[button setAlternateImage:CPSearchFieldCancelPressedImage];
[button setAutoresizingMask:CPViewMinXMargin];
[button setTarget:self];
[button setAction:@selector(_searchFieldCancel:)];
[button setAction:@selector(cancelOperation:)];
}
// Custom Layout
@@ -677,7 +677,7 @@ var RECENT_SEARCH_PREFIX = @" ";
[_partialStringTimer invalidate];
}
- (void)_searchFieldCancel:(id)sender
- (void)cancelOperation:(id)sender
{
[self setObjectValue:@""];
[self _sendPartialString];
+2 -2
View File
@@ -361,9 +361,9 @@ CPSegmentSwitchTrackingMomentary = 2;
}
/*!
Enables/diables the specified segment.
Enables/disables the specified segment.
@param isEnabled \c YES enables the segment
@param aSegment the segment to enable/disble
@param aSegment the segment to enable/disable
@throws CPRangeException if \c aSegment is out of bounds
*/
- (void)setEnabled:(BOOL)isEnabled forSegment:(unsigned)aSegment
+1 -1
View File
@@ -384,7 +384,7 @@ CPCircularSlider = 1;
/*!
@ignore
shoudl we have _continuous?
should we have _continuous?
*/
- (void)setContinuous:(BOOL)flag
{
+4 -4
View File
@@ -65,7 +65,7 @@
- (id)initView
{
aFrame = CGRectMake(0, 0, CPColorPickerViewWidth, CPColorPickerViewHeight);
aFrame = CGRectMake(0, 0, CPColorPickerViewWidth, CPColorPickerViewHeight);
_contentView = [[CPView alloc] initWithFrame:aFrame];
[_contentView setAutoresizingMask:CPViewWidthSizable | CPViewHeightSizable];
@@ -240,7 +240,7 @@
return (mode == CPSliderColorPickerMode) ? YES : NO;
}
-(void)sliderChanged:(id)sender
- (void)sliderChanged:(id)sender
{
var newColor,
colorPanel = [self colorPanel],
@@ -274,7 +274,7 @@
[colorPanel setColor: newColor];
}
-(void)setColor:(CPColor)aColor
- (void)setColor:(CPColor)aColor
{
[self updateRGBSliders: aColor];
[self updateHSBSliders: aColor];
@@ -282,7 +282,7 @@
[self updateLabels];
}
-(void)updateHSBSliders:(CPColor)aColor
- (void)updateHSBSliders:(CPColor)aColor
{
var hsb = [aColor hsbComponents];
+3 -3
View File
@@ -77,7 +77,7 @@ CPSoundPlayBackStatePause = 2;
Initialize with the sound contents of the URL represented by aFile.
@param aFile CPString the path of the sound
@param byRef ignored (Cocoa compatibibility)
@param byRef ignored (Cocoa compatibility)
*/
- (id)initWithContentsOfFile:(CPString)aFile byReference:(BOOL)byRef
{
@@ -94,7 +94,7 @@ CPSoundPlayBackStatePause = 2;
Initialize with the sound contents of the file located at aURL.
@param aURL CPURL containing the URL of the sound
@param byRef ignored (Cocoa compatibibility)
@param byRef ignored (Cocoa compatibility)
*/
- (id)initWithContentsOfURL:(CPURL)aURL byReference:(BOOL)byRef
{
@@ -105,7 +105,7 @@ CPSoundPlayBackStatePause = 2;
Initialize with the sound contents of someData.
@param someData CPData containing the sound
@param byRef ignored (Cocoa compatibibility)
@param byRef ignored (Cocoa compatibility)
*/
- (id)initWithData:(CPData)someData
{
+112 -2
View File
@@ -33,6 +33,14 @@ var CPSplitViewHorizontalImage = nil,
/*!
@ingroup appkit
@class CPSplitView
CPSplitView is a view that allows you to stack several subviews vertically or horizontally. The user is given divider to resize the subviews.
The divider indices are zero-based. So the divider on the top (or left for vertical dividers) will be index 0.
CPSplitView can be supplied a delegate to provide control over the resizing of the splitview and subviews. Those methods are documented in setDelegate:
CPSplitView will add dividers for each subview you add. So just like adding subviews to a CPView you should call addSubview: to add new resizable subviews in your splitview.
*/
@implementation CPSplitView : CPView
@@ -96,16 +104,28 @@ var CPSplitViewHorizontalImage = nil,
return self;
}
/*!
Returns the thickness of the divider.
@return float - the thickness of the divider.
*/
- (float)dividerThickness
{
return [self currentValueForThemeAttribute:[self isPaneSplitter] ? @"pane-divider-thickness" : @"divider-thickness"];
}
/*!
Returns YES if the dividers are vertical, otherwise NO.
@return YES if vertical, otherwise NO.
*/
- (BOOL)isVertical
{
return _isVertical;
}
/*!
Sets if the splitview dividers are vertical.
@param shouldBeVertical - YES if the splitview dividers should be vertical, otherwise NO.
*/
- (void)setVertical:(BOOL)shouldBeVertical
{
if (![self _setVertical:shouldBeVertical])
@@ -147,11 +167,21 @@ var CPSplitViewHorizontalImage = nil,
return changed;
}
/*!
Use to find if the divider is a larger pane splitter.
@return BOOL - YES if the dividers are the larger pane splitters. Otherwise NO.
*/
- (BOOL)isPaneSplitter
{
return _isPaneSplitter;
}
/*!
Used to set if the split view dividers should be the larger pane splitter.
@param shouldBePaneSplitter - YES if the dividers should be the thicker pane splitter, otherwise NO.
*/
- (void)setIsPaneSplitter:(BOOL)shouldBePaneSplitter
{
if (_isPaneSplitter == shouldBePaneSplitter)
@@ -173,11 +203,22 @@ var CPSplitViewHorizontalImage = nil,
_needsResizeSubviews = YES;
}
/*!
Returns YES if the supplied subview is collapsed, otherwise NO.
@param aSubview - the subview you are interested in.
@return BOOL - YES if the subview is collapsed, otherwise NO.
*/
- (BOOL)isSubviewCollapsed:(CPView)subview
{
return [subview frame].size[_sizeComponent] < 1 ? YES : NO;
}
/*!
Returns the CGRect of the divider at a given index.
@param int - The index of a divider.
@return CGRect - The rect of a divider.
*/
- (CGRect)rectOfDividerAtIndex:(int)aDivider
{
var frame = [_subviews[aDivider] frame],
@@ -191,6 +232,12 @@ var CPSplitViewHorizontalImage = nil,
return rect;
}
/*!
Returns the rect of the divider which the user is able to drag to resize.
@param int - The index of the divider.
@return CGRect - The rect the user can drag.
*/
- (CGRect)effectiveRectOfDividerAtIndex:(int)aDivider
{
var realRect = [self rectOfDividerAtIndex:aDivider],
@@ -212,7 +259,10 @@ var CPSplitViewHorizontalImage = nil,
[self drawDividerInRect:[self rectOfDividerAtIndex:count]];
}
}
/*!
Draws the divider at a given rect.
@param aRect - the rect of the divider to draw.
*/
- (void)drawDividerInRect:(CGRect)aRect
{
#if PLATFORM(DOM)
@@ -485,6 +535,11 @@ var CPSplitViewHorizontalImage = nil,
[[CPCursor arrowCursor] set];
}
/*!
Returns the maximum possible position of a divider at a given index.
@param the index of the divider.
@return float - the max possible position.
*/
- (float)maxPossiblePositionOfDividerAtIndex:(int)dividerIndex
{
var frame = [_subviews[dividerIndex + 1] frame];
@@ -495,6 +550,11 @@ var CPSplitViewHorizontalImage = nil,
return [self frame].size[_sizeComponent] - [self dividerThickness];
}
/*!
Returns the minimum possible position of a divider at a given index.
@param the index of the divider.
@return float - the min possible position.
*/
- (float)minPossiblePositionOfDividerAtIndex:(int)dividerIndex
{
if (dividerIndex > 0)
@@ -535,6 +595,11 @@ var CPSplitViewHorizontalImage = nil,
return realPosition;
}
/*!
Sets the position of a divider at a given index.
@param position - The float value of the position to place the divider.
@param dividerIndex - The index of the divider to position.
*/
- (void)setPosition:(float)position ofDividerAtIndex:(int)dividerIndex
{
[self _adjustSubviewsWithCalculatedSize];
@@ -644,6 +709,48 @@ var CPSplitViewHorizontalImage = nil,
[self _postNotificationDidResize];
}
/*!
Sets the delegate of the receiver.
Possible delegate methods to implement are listed below.
<pre>
- (void)splitViewDidResizeSubviews:(CPSplitView)aSplitView;
Notifies the delegate when the subviews have resized.
- (void)splitViewWillResizeSubviews:(CPSplitView)aSplitView;
Notifies the delegate when the subviews will be resized.
- (CGRect)splitView:(CPSplitView)aSplitView effectiveRect:(CGRect)aRect forDrawnRect:(CGRect)aDrawnRect ofDividerAtIndex:(int)aDividerIndex;
Lets the delegate specify a different rect for which the user can drag the splitView divider.
- (CGRect)splitView:(CPSplitView)aSplitView additionalEffectiveRectOfDividerAtIndex:(int)indexOfDivider;
Lets the delegate specify an additional rect for which the user can drag the splitview divider.
- (BOOL)splitView:(CPSplitView)aSplitView canCollapseSubview:(CPView)aSubview;
Notifies the delegate that the splitview is about to be collapsed. This usually happens when the user
Double clicks on the divider. Return YES if the subview can be collapsed, otherwise NO.
- (BOOL)splitView:(CPSplitView)aSplitView shouldCollapseSubview:(CPView)aSubview;
Notifies the delegate that the splitview is about to be collapsed. This usually happens when the user
Double clicks on the divider. Return YES if the subview should be collapsed, otherwise NO.
- (float)splitView:(CPSplitView)aSpiltView constrainSplitPosition:(float)proposedPosition ofSubviewAt:(int)subviewIndex;
Allows the delegate to constrain the subview beings resized. This method is called continuously as the user resizes the divider.
For example if the subview needs to have a width which is a multiple of a certain number you could return that multiple with this method.
- (float)splitView:(CPSplitView)aSplitView constrainMinCoordinate:(float)proposedMin ofSubviewAt:(int)subviewIndex;
Allows the delegate to constrain the minimum position of a subview.
- (float)splitView:(CPSplitView)aSplitView constrainMaxCoordinate:(float)proposedMax ofSubviewAt:(int)subviewIndex;
Allows the delegate to constrain the maximum position of a subview.
- (void)splitView:(CPSplitView)aSplitView resizeSubviewsWithOldSize:(CGSize)oldSize;
Allows the splitview to specify a custom resizing behavior. This is called when the splitview is resized.
The sum of the views and the sum of the dividers should be equal to the size of the splitview.
</pre>
@param delegate - The delegate of the splitview.
*/
- (void)setDelegate:(id)delegate
{
if ([_delegate respondsToSelector:@selector(splitViewDidResizeSubviews:)])
@@ -676,6 +783,9 @@ var CPSplitViewHorizontalImage = nil,
This method will automatically configure the hasResizeControl and resizeControlIsLeftAligned
parameters of the button bar, and will override any currently set values.
@param CPButtonBar - The supplied button bar.
@param unsigned int - The divider index the button bar will be assigned to.
*/
- (void)setButtonBar:(CPButtonBar)aButtonBar forDividerAtIndex:(unsigned)dividerIndex
{
@@ -741,7 +851,7 @@ var CPSplitViewDelegateKey = "CPSplitViewDelegateKey",
_buttonBars = [aCoder decodeObjectForKey:CPSplitViewButtonBarsKey] || [];
_delegate = [aCoder decodeObjectForKey:CPSplitViewDelegateKey];
[self setDelegate:[aCoder decodeObjectForKey:CPSplitViewDelegateKey]];
_isPaneSplitter = [aCoder decodeBoolForKey:CPSplitViewIsPaneSplitterKey];
[self _setVertical:[aCoder decodeBoolForKey:CPSplitViewIsVerticalKey]];
+1 -1
View File
@@ -152,7 +152,7 @@ var CPStepperButtonsSize = CPSizeMake(19, 13);
}
/*! set the current value of the stepper
@param aValue a float contaning the value
@param aValue a float containing the value
*/
- (void)setDoubleValue:(float)aValue
{
+2 -2
View File
@@ -85,7 +85,7 @@ var CPTabViewDidSelectTabViewItemSelector = 1,
[self _updateItems];
[self _repositionTabs];
[aTabViewItem _setTabView:self];
if (_delegateSelectors & CPTabViewDidChangeNumberOfTabViewItemsSelector)
@@ -110,7 +110,7 @@ var CPTabViewDidSelectTabViewItemSelector = 1,
[self _updateItems];
[self _repositionTabs];
[aTabViewItem _setTabView:nil];
if (_delegateSelectors & CPTabViewDidChangeNumberOfTabViewItemsSelector)
+3 -3
View File
@@ -145,8 +145,8 @@ CPPressedTab = 2;
// Assigning an Auxiliary View
/*!
Sets the tab's auxillary view.
@param anAuxillaryView the new auxillary view
Sets the tab's auxiliary view.
@param anAuxiliaryView the new auxiliary view
*/
- (void)setAuxiliaryView:(CPView)anAuxiliaryView
{
@@ -154,7 +154,7 @@ CPPressedTab = 2;
}
/*!
Returns the tab's auxillary view
Returns the tab's auxiliary view
*/
- (CPView)auxiliaryView
{
+126 -29
View File
@@ -37,9 +37,12 @@ CPTableColumnUserResizingMask = 1 << 1;
@class CPTableColumn
A CPTableColumn contains a dataview to display for its column of the CPTableView.
A CPTableColumn determines its own size constrains and resizing behaviour.
A CPTableColumn determines its own size constrains and resizing behavior.
The default dataview is a CPTextField but you can set it to any view you'd like. See -setDataView:
The default dataview is a CPTextField but you can set it to any view you'd like. See -setDataView: for documentation including theme states.
To customize the text of the column header you can simply call setStringValue: on the headerview of a table column.
For example: [[myTableColumn headerView] setStringValue:"My Title"];
*/
@implementation CPTableColumn : CPObject
{
@@ -62,11 +65,6 @@ CPTableColumnUserResizingMask = 1 << 1;
BOOL _disableResizingPosting @accessors(property=disableResizingPosting);
}
+ (Class)_binderClassForBinding:(CPString)theBinding
{
return [CPBinder class];
}
/*!
@ignore
*/
@@ -197,7 +195,7 @@ CPTableColumnUserResizingMask = 1 << 1;
}
/*!
Sets the minimum width of the column.
Sets the minimum width of the column.
Default value is 10.
*/
- (void)setMinWidth:(float)aMinWidth
@@ -225,7 +223,7 @@ CPTableColumnUserResizingMask = 1 << 1;
}
/*!
Sets the maximum width of the table column.
Sets the maximum width of the table column.
Default value is: 1000000
*/
- (void)setMaxWidth:(float)aMaxWidth
@@ -253,13 +251,15 @@ CPTableColumnUserResizingMask = 1 << 1;
}
/*!
Set the resizing mask of the column.
By default the column can be resized automatically with the tableview and manaully by the user
<pre>
Set the resizing mask of the column.
By default the column can be resized automatically with the tableview and manually by the user
Possible masking values are:
CPTableColumnNoResizing
CPTableColumnAutoresizingMask
CPTableColumnUserResizingMask
</pre>
*/
- (void)setResizingMask:(unsigned)aResizingMask
{
@@ -276,7 +276,7 @@ CPTableColumnUserResizingMask = 1 << 1;
}
/*!
Sizes the column to fix the column header text.
Sizes the column to fix the column header text.
*/
- (void)sizeToFit
{
@@ -294,7 +294,12 @@ CPTableColumnUserResizingMask = 1 << 1;
/*!
Sets the header view for the column.
The headerview handles the display of sort indicators, text, etc
The headerview handles the display of sort indicators, text, etc.
If you do not want a headerview for you table you should call setHeaderView: on your CPTableView instance.
Passing nil here will throw an exception.
In order to customize the text of the column header see - (CPView)headerView;
*/
- (void)setHeaderView:(CPView)aView
{
@@ -310,7 +315,10 @@ CPTableColumnUserResizingMask = 1 << 1;
}
/*!
Returns the headerview for the column
Returns the headerview for the column.
In order to change the text of the headerview for a column you should call setStringValue: on the headerview.
For example: [[myTableColumn headerView] setStringValue:"My Column"];
*/
- (CPView)headerView
{
@@ -318,11 +326,19 @@ CPTableColumnUserResizingMask = 1 << 1;
}
/*!
<pre>
This method sets 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.
When you set a dataview and it is added to the tableview the theme state will be set to CPThemeStateTableDataView
When the dataview becomes selected the theme state will be set to CPThemeStateSelectedDataView.
If the dataview shows up in a group row of the tableview the theme state will be set to CPThemeStateGroupRow.
You should overide setThemeState: and unsetThemeState: to handle these theme state changes in your dataview.
Example:
[tableColumn setDataView:someView]; // snapshot taken
@@ -333,7 +349,37 @@ CPTableColumnUserResizingMask = 1 << 1;
[someView setSomething:x];
[tableColumn setDataView:someView];
REMEMBER: you should implement CPKeyedArchiving otherwise you might see unexpected results
REMEMBER: you should implement CPKeyedArchiving otherwise you might see unexpected results.
This is done by adding the following methods to your class:
- (id)initWithCoder(CPCoder)aCoder;
- (void)encodeWithCoder:(CPCoder)aCoder;
Example:
Say you have two instance variables in your object that need to be set up each time an object is create.
We will call these instance variables "image" and "text".
Your CPCoding methods will look like the following:
- (id)initWithCoder:(CPCoder)aCoder
{
self = [super initWithCoder:aCoder];
if (self)
{
image = [aCoder decodeObjectForKey:"MyDataViewImage"];
text = [aCoder decodeObjectForKey:"MyDataViewText"];
}
return self;
}
- (void)encodeWithCoder:(CPCoder)aCoder
{
[super encodeWithCoder:aCoder];
[aCoder encodeObject:image forKey:"MyDataViewImage"];
[aCoder encodeObject:text forKey:"MyDataViewText"];
}
</pre>
*/
- (void)setDataView:(CPView)aView
{
@@ -355,7 +401,7 @@ CPTableColumnUserResizingMask = 1 << 1;
Returns the CPView object used by the CPTableView to draw values for the receiver.
By default, this method just calls dataView. Subclassers can override if they need to
potentially use different cells for different rows. Subclasses should expect this method
potentially use different "cells" or dataViews for different rows. Subclasses should expect this method
to be invoked with row equal to -1 in cases where no actual row is involved but the table
view needs to get some generic cell info.
*/
@@ -392,7 +438,7 @@ CPTableColumnUserResizingMask = 1 << 1;
//Setting the Identifier
/*
/*!
Sets the receiver identifier to anIdentifier.
*/
- (void)setIdentifier:(id)anIdentifier
@@ -400,7 +446,7 @@ CPTableColumnUserResizingMask = 1 << 1;
_identifier = anIdentifier;
}
/*
/*!
Returns the object used by the data source to identify the attribute corresponding to the receiver.
*/
- (id)identifier
@@ -410,7 +456,7 @@ CPTableColumnUserResizingMask = 1 << 1;
//Controlling Editability
/*
/*!
Controls whether the user can edit cells in the receiver by double-clicking them.
*/
- (void)setEditable:(BOOL)shouldBeEditable
@@ -418,7 +464,7 @@ CPTableColumnUserResizingMask = 1 << 1;
_isEditable = shouldBeEditable;
}
/*
/*!
Returns YES if the user can edit cells associated with the receiver by double-clicking the
column in the NSTableView, NO otherwise.
*/
@@ -428,7 +474,7 @@ CPTableColumnUserResizingMask = 1 << 1;
}
/*!
Sets the sort descriptor prototype for the column.
Sets the sort descriptor prototype for the column.
*/
- (void)setSortDescriptorPrototype:(CPSortDescriptor)aSortDescriptor
{
@@ -444,7 +490,7 @@ CPTableColumnUserResizingMask = 1 << 1;
}
/*!
If NO the tablecolumn will no longer be visisble in the tableview
If NO the tablecolumn will no longer be visible in the tableview
If YES the tablecolumn will be visible in the tableview.
*/
- (void)setHidden:(BOOL)shouldBeHidden
@@ -469,7 +515,7 @@ CPTableColumnUserResizingMask = 1 << 1;
//Setting Tool Tips
/*
/*!
Sets the tooltip string that is displayed when the cursor pauses over the
header cell of the receiver.
*/
@@ -501,7 +547,40 @@ CPTableColumnUserResizingMask = 1 << 1;
@end
@implementation CPTableColumnValueBinder : CPBinder
{
}
- (void)setValueFor:(CPString)aBinding
{
var tableView = [_source tableView],
column = [[tableView tableColumns] indexOfObjectIdenticalTo:_source],
rowIndexes = [CPIndexSet indexSetWithIndexesInRange:CPMakeRange(0, [tableView numberOfRows])],
columnIndexes = [CPIndexSet indexSetWithIndex:column];
[tableView reloadDataForRowIndexes:rowIndexes columnIndexes:columnIndexes];
}
@end
@implementation CPTableColumn (Bindings)
+ (id)_binderClassForBinding:(CPString)aBinding
{
if (aBinding == CPValueBinding)
return [CPTableColumnValueBinder class];
return [super _binderClassForBinding:aBinding];
}
/*!
Binds the receiver to an object.
@param CPString aBinding - The binding you wish to make. Typically CPValueBinding.
@param id anObject - The object to bind the receiver to.
@param CPString aKeyPath - The key path you wish to bind the receiver to.
@param CPDictionary options - A dictionary of options for the binding. This parameter is optional, pass nil if you do not wish to use it.
*/
- (void)bind:(CPString)aBinding toObject:(id)anObject withKeyPath:(CPString)aKeyPath options:(CPDictionary)options
{
[super bind:aBinding toObject:anObject withKeyPath:aKeyPath options:options];
@@ -510,6 +589,9 @@ CPTableColumnUserResizingMask = 1 << 1;
[[self tableView] _establishBindingsIfUnbound:anObject];
}
/*!
@ignore
*/
- (void)prepareDataView:(CPView)aDataView forRow:(unsigned)aRow
{
var bindingsDictionary = [CPBinder allBindingsForObject:self],
@@ -561,11 +643,6 @@ CPTableColumnUserResizingMask = 1 << 1;
// return nil;
//}
- (void)setValue:(CPArray)content
{
[[self tableView] reloadData];
}
@end
var CPTableColumnIdentifierKey = @"CPTableColumnIdentifierKey",
@@ -581,6 +658,9 @@ var CPTableColumnIdentifierKey = @"CPTableColumnIdentifierKey",
@implementation CPTableColumn (CPCoding)
/*!
@ignore
*/
- (id)initWithCoder:(CPCoder)aCoder
{
self = [super init];
@@ -608,6 +688,9 @@ var CPTableColumnIdentifierKey = @"CPTableColumnIdentifierKey",
return self;
}
/*!
@ignore
*/
- (void)encodeWithCoder:(CPCoder)aCoder
{
[aCoder encodeObject:_identifier forKey:CPTableColumnIdentifierKey];
@@ -629,31 +712,45 @@ var CPTableColumnIdentifierKey = @"CPTableColumnIdentifierKey",
@end
@implementation CPTableColumn (NSInCompatibility)
/*!
@ignore
*/
- (void)setHeaderCell:(CPView)aView
{
[CPException raise:CPUnsupportedMethodException
reason:@"setHeaderCell: is not supported. Use -setHeaderView:aView instead."];
}
/*!
@ignore
*/
- (CPView)headerCell
{
[CPException raise:CPUnsupportedMethodException
reason:@"headCell is not supported. Use -headerView instead."];
}
/*!
@ignore
*/
- (void)setDataCell:(CPView)aView
{
[CPException raise:CPUnsupportedMethodException
reason:@"setDataCell: is not supported. Use -setDataView:aView instead."];
}
/*!
@ignore
*/
- (CPView)dataCell
{
[CPException raise:CPUnsupportedMethodException
reason:@"dataCell is not supported. Use -dataView instead."];
}
/*!
@ignore
*/
- (id)dataCellForRow:(int)row
{
[CPException raise:CPUnsupportedMethodException
+1 -1
View File
@@ -604,7 +604,7 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal
[headerView setFrame:frame];
if([headerView superview] != self)
if ([headerView superview] != self)
[self addSubview:headerView];
}
+122 -38
View File
@@ -147,7 +147,9 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
All delegate and data source methods are documented in the setDataSource: and setDelegate: methods.
If you want to display something other than just text in the table you should call setDataView: on CPColumn. More documentation in that class.
If you want to display something other than just text in the table you should call setDataView: on a CPTableColumn object. More documentation in that class including theme states.
Note: CPTableView does not contain its own scrollview. You should be sure you place the tableview in a CPScrollView on your own.
*/
@implementation CPTableView : CPControl
{
@@ -315,7 +317,7 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
/*!
@ignore
FIX ME: we have a lot of redundent init stuff in initWithFrame: and initWithCoder: we should move it all into here.
FIX ME: we have a lot of redundant init stuff in initWithFrame: and initWithCoder: we should move it all into here.
we should do a full audit of all the initializers before 1.0
*/
- (void)_init
@@ -378,15 +380,16 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
}
/*!
<pre>
Sets the receiver's data source to a given object.
The data source implements various methods for handeling the tableview's data when bindings are not used.
The data source implements various methods for handling the tableview's data when bindings are not used.
Methonds include:
Methods include:
- (int)numberOfRowsInTableView:(CPTableView)aTableView;
Returns the number of rows in the tableview
- (id)tableView:(CPTableView)aTableView objectValueForTableColumn:(CPTableColumn)aColumn row:(int)aRowIndex;
Returns the object value for each dataview. Each dataview will be sent a setObjectValue: method which will contai
Returns the object value for each dataview. Each dataview will be sent a setObjectValue: method which will contain
the object you return from this datasource method.
Editing:
@@ -398,15 +401,15 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
The tableview will call this method if you click the tableheader. You should sort the datasource based off of the new sort descriptors and reload the data
Drag and Drop:
In order for the tableview to recieve drops dont forget to first register the tableview for drag types like you do with every other view
In order for the tableview to receive drops don't forget to first register the tableview for drag types like you do with every other view
- (CPDragOperation)tableView:(CPTableView)aTableView validateDrop:(CPDraggingInfo)info proposedRow:(int)row proposedDropOperation:(CPTableViewDropOperation)operation;
Return the drag operation (move, copy, etc) that should be performaned if a registered drag type is over the tableview
Return the drag operation (move, copy, etc) that should be performed if a registered drag type is over the tableview
The data source can retarget a drop if you want by calling -(void)setDropRow:(int)aRow dropOperation:(CPTableViewDropOperation)anOperation;
- (BOOL)tableView:(CPTableView)aTableView writeRowsWithIndexes:(CPIndexSet)rowIndexes toPasteboard:(CPPasteboard)pboard;
Returns YES if the drop operation is allowed otherwise NO.
This method is invoked by the tabeview after a drag should begin, but before it is started. If you dont want the drag to being return NO.
This method is invoked by the tableview after a drag should begin, but before it is started. If you don't want the drag to being return NO.
If you want the drag to begin you should return YES and place the drag data on the pboard.
- (BOOL)tableView:(CPTableView)aTableView acceptDrop:(CPDraggingInfo)info row:(int)row dropOperation:(CPTableViewDropOperation)operation;
@@ -416,7 +419,7 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
- (CPArray)tableView:(CPTableView)aTableView namesOfPromisedFilesDroppedAtDestination:(CPURL)dropDestination forDraggedRowsWithIndexes:(CPIndexSet)indexSet;
NOT YET IMPLEMENTED
</pre>
@param anObject The data source for the receiver. This object must implement numberOfRowsInTableView: and tableView:objectValueForTableColumn:row:
*/
- (void)setDataSource:(id)aDataSource
@@ -576,6 +579,11 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
_allowsMultipleSelection = !!shouldAllowMultipleSelection;
}
/*!
Returns YES if the tableview is allowed to have multiple selections, otherwise NO.
@return BOOL - YES if the tableview is allowed to have multiple selections otherwise NO.
*/
- (BOOL)allowsMultipleSelection
{
return _allowsMultipleSelection;
@@ -622,7 +630,7 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
Sets the width and height between dataviews.
This value is (3.0, 2.0) by default.
@param aSize a CGSize object that degined the space between the cells
@param aSize a CGSize object that defines the space between the cells
*/
- (void)setIntercellSpacing:(CGSize)aSize
{
@@ -701,7 +709,7 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
}
/*!
Sets the colors for the rows as they alternate. The number of colors can be arbitrary. By deafult these colors are white and light blue.
Sets the colors for the rows as they alternate. The number of colors can be arbitrary. By default these colors are white and light blue.
@param anArray an array of CPColors
*/
@@ -722,11 +730,13 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
/*!
Returns an enumerated value for the selection highlight style.
<pre>
Valid values are:
CPTableViewSelectionHighlightStyleNone
CPTableViewSelectionHighlightStyleRegular
CPTableViewSelectionHighlightStyleSourceList
</pre>
*/
- (unsigned)selectionHighlightStyle
{
@@ -734,6 +744,7 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
}
/*!
<pre>
Sets the selection highlight style to an enumerated value.
This value can also affect the way the tableview draws feedback when the user is dragging.
@@ -741,6 +752,7 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
CPTableViewSelectionHighlightStyleNone
CPTableViewSelectionHighlightStyleRegular
CPTableViewSelectionHighlightStyleSourceList
</pre>
*/
- (void)setSelectionHighlightStyle:(unsigned)aSelectionHighlightStyle
{
@@ -778,12 +790,14 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
}
/*!
<pre>
Sets the highlight gradient for a row or column selection
This is specific to the
@param aDictionary a CPDictionary expects three keys to be set:
CPSourceListGradient which is a CGGradient
CPSourceListTopLineColor which is a CPColor
CPSourceListBottomLineColor which is a CPColor
</pre>
*/
- (void)setSelectionGradientColors:(CPDictionary)aDictionary
{
@@ -793,10 +807,12 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
}
/*!
<pre>
Returns a dictionary of containing the keys:
CPSourceListGradient
CPSourceListTopLineColor
CPSourceListBottomLineColor
</pre>
*/
- (CPDictionary)selectionGradientColors
{
@@ -861,6 +877,17 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
else
_dirtyTableColumnRangeIndex = MIN(NUMBER_OF_COLUMNS() - 1, _dirtyTableColumnRangeIndex);
if ([[self sortDescriptors] count] > 0)
{
var mainSortDescriptor = [[self sortDescriptors] objectAtIndex:0];
if (aTableColumn === [self _tableColumnForSortDescriptor:mainSortDescriptor])
{
var image = [mainSortDescriptor ascending] ? [self _tableHeaderSortImage] : [self _tableHeaderReverseSortImage];
[self setIndicatorImage:image inTableColumn:aTableColumn];
}
}
[self tile];
[self setNeedsLayout];
}
@@ -900,7 +927,7 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
/*!
@ignore
Interally used to set a column that will be dragged
Internally used to set a column that will be dragged
*/
- (void)_setDraggedColumn:(CPTableColumn)aColumn
{
@@ -1372,7 +1399,7 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
*/
- (void)editColumn:(CPInteger)columnIndex row:(CPInteger)rowIndex withEvent:(CPEvent)theEvent select:(BOOL)flag
{
// FIX ME: Cocoa documenation says all this should be called in THIS method:
// FIX ME: Cocoa documentation says all this should be called in THIS method:
// sets up the field editor, and sends selectWithFrame:inView:editor:delegate:start:length: and editWithFrame:inView:editor:delegate:event: to the field editor's NSCell object with the NSTableView as the text delegate.
if (![self isRowSelected:rowIndex])
@@ -1384,6 +1411,8 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
// TODO Do something with flag.
_editingCellIndex = CGPointMake(columnIndex, rowIndex);
_editingCellIndex._shouldSelect = flag;
[self reloadDataForRowIndexes:[CPIndexSet indexSetWithIndex:rowIndex]
columnIndexes:[CPIndexSet indexSetWithIndex:columnIndex]];
}
@@ -1433,7 +1462,7 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
}
/*!
Returns the headerview for the receiver. The headerview contains column headerviews for each table column
Returns the headerview for the receiver. The headerview contains column headerviews for each table column.
*/
- (CPView)headerView
{
@@ -1442,8 +1471,11 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
/*!
Sets the headerview for the tableview. This is the container view for the table column header views
Sets the headerview for the tableview. This is the container view for the table column header views.
This view also handles events for resizing and dragging.
If you don't want your tableview to have a headerview you should pass nil. (also see setCornerView:)
If you're looking to customize the header text of a column see CPTableColumn's -(CPView)headerView; method.
*/
- (void)setHeaderView:(CPView)aHeaderView
{
@@ -1887,7 +1919,7 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
i = 0;
// find resizable columns
// FIX ME: we could cache resizableColumns after this loop and reuse it durring the resize
// FIX ME: we could cache resizableColumns after this loop and reuse it during the resize
for (; i < count; i++)
{
var tableColumn = _tableColumns[i];
@@ -1924,9 +1956,17 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
}
}
}
// now that we've reached the end we know there are likely rounding errors
// so we should size the last resized to fit
var delta = superviewWidth - _CGRectGetMaxX([self rectOfColumn:[self numberOfColumns] - 1]),
newSize = [item width] + delta;
[item _tryToResizeToWidth:newSize];
}
/*!
<pre>
Sets the column autoresizing style of the receiver to a given style.
@param aStyle the column autoresizing style for the receiver. Valid values are:
@@ -1934,6 +1974,7 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
CPTableViewUniformColumnAutoresizingStyle
CPTableViewLastColumnOnlyAutoresizingStyle
CPTableViewFirstColumnOnlyAutoresizingStyle
</pre>
*/
- (void)setColumnAutoresizingStyle:(unsigned)style
{
@@ -2002,9 +2043,13 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
if (hangingSelections > 0)
{
var previousSelectionCount = [_selectedRowIndexes count];
[_selectedRowIndexes removeIndexesInRange:CPMakeRange(_numberOfRows, hangingSelections)];
if (![_selectedRowIndexes containsIndex:[self selectedRow]])
_lastSelectedRow = CPNotFound;
// For optimal performance, only send a notification if indices were actually removed.
if (previousSelectionCount > [_selectedRowIndexes count])
[self _noteSelectionDidChange];
@@ -2233,13 +2278,14 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
/*!
<pre>
Sets the delegate of the receiver. The delegate can implement the following methods:
Displaying Cells
- (void)tableView:(CPTableView)aTableView willDisplayView:(id)aView forTableColumn:(CPTableColumn)aTableColumn row:(int)rowIndex;
Called when the tableview is about to display a dataview
- (BOOL)tableView:(CPTableView)tableView isGroupRow:(int)row;
Group rows are a way to seperate a groups of data in a tableview. Return YES if the given row is a group row, otherwise NO.
Group rows are a way to separate a groups of data in a tableview. Return YES if the given row is a group row, otherwise NO.
Editing Cells
- (BOOL)tableView:(CPTableView)aTableView shouldEditTableColumn:(CPTableColumn)aTableColumn row:(int)rowIndex;
@@ -2264,7 +2310,7 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
NOTE: this is only called via user interaction
- (void)tableViewSelectionIsChanging:(CPNotification)aNotification
Inform the delegate that the tableview is in the process of chaning the selection.
Inform the delegate that the tableview is in the process of chaining the selection.
This usually happens when the user is dragging their mouse across rows.
NOTE: this is only called via user interaction
@@ -2278,7 +2324,7 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
Return YES if the column at a given index should move to a new column index, otherwise NO.
- (void)tableView:(CPTableView)tableView didDragTableColumn:(CPTableColumn)tableColumn;
Notifies the delegate that the tableview drag occured. This is send on mouse up.
Notifies the delegate that the tableview drag occurred. This is send on mouse up.
- (void)tableViewColumnDidMove:(CPNotification)aNotification;
Notifies the delegate that a tablecolumn was moved by the user.
@@ -2299,6 +2345,11 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
Called when the user right clicks on the tableview. -1 is passed for the row or column if the user doesn't right click on a real row or column
Return a CPMenu that should be displayed if the user right clicks. If you do not implement this the tableview will just call super on menuForEvent
Delete Key
- (void)tableViewDeleteKeyPressed:(CPTableView)aTableView;
Called when the user presses the delete key. Many times you will want to delete data (or prompt for deletion) when the user hids the delete key.
Your delegate can implement this method to avoid subclassing the tableview to add this behaviour.
</pre>
@param aDelegate the delegate object for the tableview.
*/
@@ -2639,7 +2690,7 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
@param dragRows an index set with the dragged row indexes
@param theTableColumns an array of the table columns which are being dragged
@param dragEvent the event which initiated the drag
@param offset a point at wihch to set the drag image to be offset from the cursor
@param offset a point at which to set the drag image to be offset from the cursor
@return CPImage an image to use for the drag feedback
*/
@@ -2649,12 +2700,14 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
}
/*!
Computes and returns a view to use for dragging
Computes and returns a view to use for dragging. By default this is a slightly transparent copy of the dataviews which are being dragged.
You can override this in a subclass to show different dragging feedback. Additionally you can return nil from this method and implement:
- (CPImage)dragImageForRowsWithIndexes:tableColumns:event:offset: - if you want to return a simple image.
@param dragRows an index set with the dragged row indexes
@param theTableColumns an array of the table columns which are being dragged
@param dragEvent the event which initiated the drag
@param offset a point at wihch to set the drag image to be offset from the cursor
@param offset a point at which to set the drag image to be offset from the cursor
@return CPView a view used as the dragging feedback
*/
@@ -2747,12 +2800,12 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
}
/*!
Sets the default operation mask for the drag behaviour of the table view.
Sets the default operation mask for the drag behavior of the table view.
NOTE: isLocal is not implemented.
*/
- (void)setDraggingSourceOperationMask:(CPDragOperation)mask forLocal:(BOOL)isLocal
{
//ignoral local for the time being since only one capp app can run at a time...
//ignore local for the time being since only one capp app can run at a time...
_dragOperationDefaultMask = mask;
}
@@ -2778,11 +2831,15 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
}
/*!
<pre>
Sets the feedback style for when the table is the destination of a drag operation.
This style is used to determine how the tableview looks when it is the receiver of a drag and drop operation.
Can be:
CPTableViewDraggingDestinationFeedbackStyleNone
CPTableViewDraggingDestinationFeedbackStyleRegular
CPTableViewDraggingDestinationFeedbackStyleSourceList
</pre>
*/
- (void)setDraggingDestinationFeedbackStyle:(CPTableViewDraggingDestinationFeedbackStyle)aStyle
{
@@ -2791,12 +2848,14 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
}
/*!
<pre>
Returns the tableview dragging destination feedback style.
Can be:
CPTableViewDraggingDestinationFeedbackStyleNone
CPTableViewDraggingDestinationFeedbackStyleRegular
CPTableViewDraggingDestinationFeedbackStyleSourceList
</pre>
*/
- (CPTableViewDraggingDestinationFeedbackStyle)draggingDestinationFeedbackStyle
{
@@ -2846,7 +2905,7 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
/*!
Sets the table view's CPSortDescriptors objects in an array.
@param sortDescriptors an array of sort descritors.
@param sortDescriptors an array of sort descriptors.
*/
- (void)setSortDescriptors:(CPArray)sortDescriptors
{
@@ -2883,6 +2942,9 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
[self setIndicatorImage:image inTableColumn:newColumn];
[self _sendDataSourceSortDescriptorsDidChange:oldSortDescriptors];
var binderClass = [[self class] _binderClassForBinding:@"sortDescriptors"];
[[binderClass getBinding:@"sortDescriptors" forObject:self] reverseSetValueFor:@"sortDescriptors"];
}
/*!
@@ -3126,6 +3188,7 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
else
[dataView unsetThemeState:CPThemeStateSelectedDataView];
// FIX ME: for performance reasons we might consider diverging from cocoa and moving this to the reloadData method
if (_implementedDelegateMethods & CPTableViewDelegate_tableView_isGroupRow_)
{
if ([_delegate tableView:self isGroupRow:row])
@@ -3152,15 +3215,13 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
if (isButton || (_editingCellIndex && _editingCellIndex.x === column && _editingCellIndex.y === row))
{
if (!isButton)
_editingCellIndex = undefined;
if (isTextField)
{
[dataView setEditable:YES];
[dataView setSendsActionOnEndEditing:YES];
[dataView setSelectable:YES];
[dataView selectText:nil];
[dataView setBezeled:YES];
[dataView setDelegate:self];
}
@@ -3218,6 +3279,8 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
*/
- (void)_commitDataViewObjectValue:(id)sender
{
_editingCellIndex = nil;
[_dataSource tableView:self setObjectValue:[sender objectValue] forTableColumn:sender.tableViewEditedColumnObj row:sender.tableViewEditedRowIndex];
if ([sender respondsToSelector:@selector(setEditable:)])
@@ -3226,7 +3289,14 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
if ([sender respondsToSelector:@selector(setSelectable:)])
[sender setSelectable:NO];
if ([sender isKindOfClass:[CPTextField class]])
[sender setBezeled:NO];
[self reloadDataForRowIndexes:[CPIndexSet indexSetWithIndex:sender.tableViewEditedRowIndex]
columnIndexes:[CPIndexSet indexSetWithIndex:[_tableColumns indexOfObject:sender.tableViewEditedColumnObj]]];
[[self window] makeFirstResponder:self];
}
/*!
@@ -3243,6 +3313,11 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
if ([dataView respondsToSelector:@selector(setSelectable:)])
[dataView setSelectable:NO];
if ([dataView isKindOfClass:[CPTextField class]])
[dataView setBezeled:NO];
_editingCellIndex = nil;
}
/*!
@@ -3350,6 +3425,8 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
/*!
Draws the background in a given clip rect.
This method should only be overridden if you want something other than a solid color or alternating row colors.
NOTE: this method should not be called directly, instead use setNeedsDisplay:
*/
- (void)drawBackgroundInClipRect:(CGRect)aRect
{
@@ -3403,6 +3480,7 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
/*!
Draws the grid for the tableview based on the set grid mask in a given clip rect.
NOTE: this method should not be called directly, instead use setNeedsDisplay:
*/
- (void)drawGridInClipRect:(CGRect)aRect
{
@@ -3478,6 +3556,8 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
/*!
Draws the selection with the set selection highlight style in a given clip rect.
You can change the highlight style to a source list style gradient in setSelectionHighlightStyle:
NOTE: this method should not be called directly, instead use setNeedsDisplay:
*/
- (void)highlightSelectionInClipRect:(CGRect)aRect
{
@@ -3528,7 +3608,7 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
var normalSelectionHighlightColor = [self selectionHighlightColor];
// dont do these lookups if there are no group rows
// don't do these lookups if there are no group rows
if ([_groupRows count])
{
var topGroupLineColor = [CPColor colorWithCalibratedWhite:212.0 / 255.0 alpha:1.0],
@@ -3566,15 +3646,15 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
CGContextClosePath(context);
CGContextBeginPath(context);
CGContextMoveToPoint(context, minX, minY);
CGContextAddLineToPoint(context, maxX, minY);
CGContextMoveToPoint(context, minX, minY + .5);
CGContextAddLineToPoint(context, maxX, minY + .5);
CGContextClosePath(context);
CGContextSetStrokeColor(context, (shouldUseGroupGradient) ? topGroupLineColor : topLineColor);
CGContextStrokePath(context);
CGContextBeginPath(context);
CGContextMoveToPoint(context, minX, maxY);
CGContextAddLineToPoint(context, maxX, maxY - 1);
CGContextMoveToPoint(context, minX, maxY - .5);
CGContextAddLineToPoint(context, maxX, maxY - .5);
CGContextClosePath(context);
CGContextSetStrokeColor(context, (shouldUseGroupGradient) ? bottomGroupLineColor : bottomLineColor);
CGContextStrokePath(context);
@@ -3712,7 +3792,7 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
*/
- (void)drawRow:(CPInteger)row clipRect:(CGRect)rect
{
// This method does currently nothing in cappuccino. Can be overriden by subclasses.
// This method does currently nothing in cappuccino. Can be overridden by subclasses.
}
@@ -3800,7 +3880,7 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
{
var row = [self rowAtPoint:aPoint];
//if the user clicks outside a row then deslect everything
//if the user clicks outside a row then deselect everything
if (row < 0 && _allowsEmptySelection)
[self selectRowIndexes:[CPIndexSet indexSet] byExtendingSelection:NO];
@@ -3890,7 +3970,7 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
tableColumns = [_tableColumns objectsAtIndexes:_exposedColumns];
// We deviate from the default Cocoa implementation here by asking for a view in stead of an image
// We support both, but the view prefered over the image because we can mimic the rows we are dragging
// We support both, but the view preferred over the image because we can mimic the rows we are dragging
// by re-creating the data views for the dragged rows
var view = [self dragViewForRowsWithIndexes:_draggedRowIndexes
tableColumns:tableColumns
@@ -4048,6 +4128,9 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
[self _draggingEnded];
}
/*!
@ignore
*/
- (void)_draggingEnded
{
_retargetedDropOperation = nil;
@@ -4055,6 +4138,7 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
_draggedRowIndexes = [CPIndexSet indexSet];
[_dropOperationFeedbackView removeFromSuperview];
}
/*
@ignore
*/
@@ -4368,7 +4452,7 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
var character = [anEvent charactersIgnoringModifiers],
modifierFlags = [anEvent modifierFlags];
// Check for the key events manually, as opossed to waiting for CPWindow to sent the actual actio message
// Check for the key events manually, as opposed to waiting for CPWindow to sent the actual action message
// in _processKeyboardUIKey:, because we might not want to handle the arrow events.
if (character === CPUpArrowFunctionKey || character === CPDownArrowFunctionKey)
{
@@ -4394,7 +4478,7 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
/*!
@ignore
Selection behaviour depends on two things:
Selection behavior depends on two things:
_lastSelectedRow and the anchored selection (the last row selected by itself)
*/
- (void)_moveSelectionWithEvent:(CPEvent)theEvent upward:(BOOL)shouldGoUpward
+116 -26
View File
@@ -486,11 +486,15 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
#if PLATFORM(DOM)
var string = [self stringValue],
element = [self _inputElement];
element = [self _inputElement],
font = [self currentValueForThemeAttribute:@"font"];
// generate the font metric
[font _getMetrics];
element.value = string;
element.style.color = [[self currentValueForThemeAttribute:@"text-color"] cssString];
element.style.font = [[self currentValueForThemeAttribute:@"font"] cssString];
element.style.font = [font cssString];
element.style.zIndex = 1000;
switch ([self alignment])
@@ -502,12 +506,32 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
default: element.style.textAlign = "left";
}
var contentRect = [self contentRectForBounds:[self bounds]];
var contentRect = [self contentRectForBounds:[self bounds]],
verticalAlign = [self currentValueForThemeAttribute:"vertical-alignment"];
element.style.top = _CGRectGetMinY(contentRect) + "px";
switch (verticalAlign)
{
case CPTopVerticalTextAlignment:
var topPoint = (_CGRectGetMinY(contentRect) + 1) + "px"; // for the same reason we have a -1 for the left, we also have a + 1 here
break;
case CPCenterVerticalTextAlignment:
var topPoint = (_CGRectGetMidY(contentRect) - (font._lineHeight / 2) + 1) + "px";
break;
case CPBottomVerticalTextAlignment:
var topPoint = (_CGRectGetMaxY(contentRect) - font._lineHeight) + "px";
break;
default:
var topPoint = (_CGRectGetMinY(contentRect) + 1) + "px";
break;
}
element.style.top = topPoint;
element.style.left = (_CGRectGetMinX(contentRect) - 1) + "px"; // why -1?
element.style.width = _CGRectGetWidth(contentRect) + "px";
element.style.height = _CGRectGetHeight(contentRect) + "px";
element.style.height = font._lineHeight + "px"; // private ivar for the line height of the DOM text at this particular size
_DOMElement.appendChild(element);
@@ -561,7 +585,9 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
[self _setStringValue:element.value];
CPTextFieldInputResigning = YES;
element.blur();
if (CPTextFieldInputIsActive)
element.blur();
if (!CPTextFieldInputDidBlur)
CPTextFieldBlurFunction();
@@ -679,30 +705,87 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
- (void)keyDown:(CPEvent)anEvent
{
var characters = [anEvent characters];
// Treat \r and \n the same. See issue #710.
if (characters === CPNewlineCharacter || characters === CPCarriageReturnCharacter)
{
// selectText: has a side effect - it can change first responder of the window
// we have to prevent such behaviour inside this method because target should be able to change first responder after receiving action.
[self selectText:nil];
if ([anEvent _couldBeKeyEquivalent] && [self performKeyEquivalent:anEvent])
return;
if (_isEditing)
{
_isEditing = NO;
[self textDidEndEditing:[CPNotification notificationWithName:CPControlTextDidEndEditingNotification object:self userInfo:nil]];
}
// CPTextField uses an HTML input element to take the input so we need to
// propagate the dom event so the element is updated. This has to be done
// before interpretKeyEvents: though so individual commands have a chance
// to override this (escape to clear the text in a search field for example).
[[[self window] platformWindow] _propagateCurrentDOMEvent:YES];
[self sendAction:[self action] to:[self target]];
[[[self window] platformWindow] _propagateCurrentDOMEvent:NO];
}
else
[[[self window] platformWindow] _propagateCurrentDOMEvent:YES];
[self interpretKeyEvents:[anEvent]];
[[CPRunLoop currentRunLoop] limitDateForMode:CPDefaultRunLoopMode];
}
/*!
Invoke the action specified by aSelector on the current responder.
This is implemented by CPResponder and by default it passes any unrecognized
actions on to the next responder but text fields apparently aren't supposed
to do that according to this documentation by Apple:
http://developer.apple.com/mac/library/documentation/cocoa/reference/NSTextInputClient_Protocol/Reference/Reference.html#//apple_ref/occ/intfm/NSTextInputClient/doCommandBySelector:
*/
- (void)doCommandBySelector:(SEL)aSelector
{
if ([self respondsToSelector:aSelector])
[self performSelector:aSelector];
}
- (void)insertNewline:(id)sender
{
if (_isEditing)
{
_isEditing = NO;
[self textDidEndEditing:[CPNotification notificationWithName:CPControlTextDidEndEditingNotification object:self userInfo:nil]];
}
[self sendAction:[self action] to:[self target]];
[self selectText:nil];
[[[self window] platformWindow] _propagateCurrentDOMEvent:NO];
}
- (void)insertNewlineIgnoringFieldEditor:(id)sender
{
var oldValue = [self stringValue];
[self _inputElement].value += CPNewlineCharacter;
[self _setStringValue:[self _inputElement].value];
if (oldValue !== [self stringValue])
{
if (!_isEditing)
{
_isEditing = YES;
[self textDidBeginEditing:[CPNotification notificationWithName:CPControlTextDidBeginEditingNotification object:self userInfo:nil]];
}
[self textDidChange:[CPNotification notificationWithName:CPControlTextDidChangeNotification object:self userInfo:nil]];
}
}
- (void)insertTabIgnoringFieldEditor:(id)sender
{
var oldValue = [self stringValue];
[self _inputElement].value += CPTabCharacter;
[self _setStringValue:[self _inputElement].value];
if (oldValue !== [self stringValue])
{
if (!_isEditing)
{
_isEditing = YES;
[self textDidBeginEditing:[CPNotification notificationWithName:CPControlTextDidBeginEditingNotification object:self userInfo:nil]];
}
[self textDidChange:[CPNotification notificationWithName:CPControlTextDidChangeNotification object:self userInfo:nil]];
}
}
- (void)textDidBlur:(CPNotification)note
{
// this looks to prevent false propagation of notifications for other objects
@@ -1018,8 +1101,15 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
- (void)deleteBackward:(id)sender
{
var selectedRange = [self selectedRange],
stringValue = [self stringValue],
var selectedRange = [self selectedRange];
if (selectedRange.length < 2)
return;
selectedRange.location += 1;
selectedRange.length -= 1;
var stringValue = [self stringValue],
newValue = [stringValue stringByReplacingCharactersInRange:selectedRange withString:""];
[self setStringValue:newValue];
+6 -6
View File
@@ -179,7 +179,7 @@ var CPThemeStateAutoCompleting = @"CPThemeStateAutoCompleting",
token = [self _inputElement].value;
// Make sure the user typed an actual token to prevent the previous token from being emptied
// If the input area is empty, we want to fallback to the normal behaviour, resigning first responder or select the next or previous key view
// If the input area is empty, we want to fallback to the normal behavior, resigning first responder or select the next or previous key view
if (!token || token === @"")
{
if (DOMEvent && DOMEvent.keyCode === CPTabKeyCode)
@@ -198,7 +198,7 @@ var CPThemeStateAutoCompleting = @"CPThemeStateAutoCompleting",
var objectValue = [self objectValue];
// Remove the uncompleted token and add the token string.
// Explicitely remove the last object because the array contains strings and removeObject uses isEqual to compare objects
// Explicitly remove the last object because the array contains strings and removeObject uses isEqual to compare objects
if (shouldRemoveLastObject)
[objectValue removeObjectAtIndex:_selectedRange.location];
@@ -455,7 +455,7 @@ var CPThemeStateAutoCompleting = @"CPThemeStateAutoCompleting",
- (CPArray)_tokens
{
// We return super here because objectValue uses this method
// If we called self we would loop infinitly
// If we called self we would loop infinitely
return [super objectValue];
}
@@ -633,7 +633,7 @@ var CPThemeStateAutoCompleting = @"CPThemeStateAutoCompleting",
CPTokenFieldTextDidChangeValue = [CPTokenFieldInputOwner stringValue];
// Update the selectedIndex if necesary
// Update the selectedIndex if necessary
var index = [[CPTokenFieldInputOwner autocompleteView] selectedRow];
if (aDOMEvent.keyCode === CPUpArrowKeyCode)
@@ -665,7 +665,7 @@ var CPThemeStateAutoCompleting = @"CPThemeStateAutoCompleting",
aDOMEvent.stopPropagation();
aDOMEvent.cancelBubble = true;
// Only resign first responder if we weren't autocompleting
// Only resign first responder if we weren't auto-completing
if (![CPTokenFieldInputOwner hasThemeState:CPThemeStateAutoCompleting])
{
if (aDOMEvent && aDOMEvent.keyCode === CPReturnKeyCode)
@@ -1129,7 +1129,7 @@ var CPThemeStateAutoCompleting = @"CPThemeStateAutoCompleting",
return [];
}
// // Alows the delegate to provide a string to be displayed as a proxy for the given represented object.
// // Allows the delegate to provide a string to be displayed as a proxy for the given represented object.
// // If you return nil or do not implement this method, then representedObject is displayed as the string.
- (CPString)tokenField:(CPTokenField)tokenField displayStringForRepresentedObject:(id)representedObject
{
+3 -3
View File
@@ -50,8 +50,8 @@ CPToolbarDisplayModeIconOnly = 2;
*/
CPToolbarDisplayModeLabelOnly = 3;
var CPToolbarsByIdentifier = nil;
var CPToolbarConfigurationsByIdentifier = nil;
var CPToolbarsByIdentifier = nil,
CPToolbarConfigurationsByIdentifier = nil;
/*!
@ingroup appkit
@@ -464,7 +464,7 @@ var CPToolbarIdentifierKey = @"CPToolbarIdentifierKey",
// 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
// Cib. Unfortunately 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?
+4 -4
View File
@@ -705,7 +705,7 @@ var CPViewFlags = { },
Sets the frame size of the receiver to the dimensions and origin of the provided rectangle in the coordinate system
of the superview. The method also posts an CPViewFrameDidChangeNotification to the notification
center if the receiver is configured to do so. If the frame is the same as the current frame, the method simply
returns (and no notificaion is posted).
returns (and no notification is posted).
@param aFrame the rectangle specifying the new origin and size of the receiver
*/
- (void)setFrame:(CGRect)aFrame
@@ -1735,7 +1735,7 @@ setBoundsOrigin:
@param aLocation the lower-left corner coordinate of \c anImage
@param mouseOffset the distance from the \c -mouseDown: location and the current location
@param anEvent the \c -mouseDown: that triggered the drag
@param aPastebaord the pasteboard that holds the drag data
@param aPasteboard the pasteboard that holds the drag data
@param aSourceObject the drag operation controller
@param slideBack Whether the image should 'slide back' if the drag is rejected
*/
@@ -1750,7 +1750,7 @@ setBoundsOrigin:
@param aLocation the top-left corner coordinate of \c aView
@param mouseOffset the distance from the \c -mouseDown: location and the current location
@param anEvent the \c -mouseDown: that triggered the drag
@param aPastebaord the pasteboard that holds the drag data
@param aPasteboard the pasteboard that holds the drag data
@param aSourceObject the drag operation controller
@param slideBack Whether the view should 'slide back' if the drag is rejected
*/
@@ -2100,7 +2100,7 @@ setBoundsOrigin:
/*!
Scrolls the clip view to a specified point
@param the clip view to scoll
@param the clip view to scroll
@param the point to scroll to
*/
- (void)scrollClipView:(CPClipView)aClipView toPoint:(CGPoint)aPoint
+35
View File
@@ -31,11 +31,41 @@ CPViewAnimationEffectKey = @"CPViewAnimationEffectKey";
CPViewAnimationFadeInEffect = @"CPViewAnimationFadeInEffect";
CPViewAnimationFadeOutEffect = @"CPViewAnimationFadeOutEffect";
/*!
@class CPViewAnimation
CPViewAnimation is a subclass of CPAnimation that makes it easy to do
basic animations on views.
*/
@implementation CPViewAnimation : CPAnimation
{
CPArray _viewAnimations;
}
/*!
Designated initializer.
This method takes an array of CPDictionaries. Each dictionary should
contain values for the following keys:
<pre>
CPViewAnimationTargetKey - (Required) The view to animate.
CPViewAnimationStartFrameKey - (Optional) The start frame of the target.
CPViewAnimationEndFrameKey - (Optional) The end frame of the target.
CPViewAnimationEffectKey - (Optional) a fade effect to use for the animation.
</pre>
For example:
<pre>
var animation = [CPDictionary dictionaryWithObjects:[myViewToAnimate, aStartFrame, anEndFrame, CPViewAnimationFadeInEffect]
forKeys:[CPViewAnimationTargetKey, CPViewAnimationStartFrameKey, CPViewAnimationEndFrameKey, CPViewAnimationEffectKey]];
</pre>
If you pass nil instead of an array of dictionaries you should later call setViewAnimations:.
@param viewAnimations - An array of CPDictionaries for each animation.
*/
- (id)initWithViewAnimations:(CPArray)viewAnimations
{
if (self = [super initWithDuration:0.5 animationCurve:CPAnimationLinear])
@@ -181,6 +211,11 @@ CPViewAnimationFadeOutEffect = @"CPViewAnimationFadeOutEffect";
return _viewAnimations;
}
/*!
Takes an array of CPDictionaries as documented in initWithViewAnimations:.
@param viewAnimations - An array of dictionaries describing the animation.
*/
- (void)setViewAnimations:(CPArray)viewAnimations
{
if (viewAnimations != _viewAnimations)
+4 -4
View File
@@ -163,7 +163,7 @@ var CPViewControllerCachedCibs;
if (_view === nil && [cibOwner isKindOfClass:[CPDocument class]])
[self setView:[cibOwner valueForKey:@"view"]];
if (!_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];
@@ -182,13 +182,13 @@ var CPViewControllerCachedCibs;
/*!
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 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 cib files.
*/
- (void)viewDidLoad
{
}
+162 -8
View File
@@ -43,6 +43,16 @@ CPWebViewScrollNative = 2;
/*!
@ingroup appkit
@class CPWebView
CPWebView is a class which allows you to display arbitrary HTML or embed a
webpage inside your application.
It's important to note that the same origin policy applies to this view.
That is, if the web page being displayed is not located in the same origin
(protocol, domain, and port) as the application, you will have limited
control over the view and no access to its contents.
*/
@implementation CPWebView : CPView
@@ -236,6 +246,10 @@ CPWebViewScrollNative = 2;
}
}
/*!
Sets the scroll mode of the receiver. Valid options are
CPWebViewScrollAppKit and CPWebViewScrollNative.
*/
- (void)setScrollMode:(int)aScrollMode
{
if (_scrollMode == aScrollMode)
@@ -277,11 +291,22 @@ CPWebViewScrollNative = 2;
parent.appendChild(_iframe);
}
/*!
Loads a string of HTML into the webview.
@param CPString - The string to load.
*/
- (void)loadHTMLString:(CPString)aString
{
[self loadHTMLString:aString baseURL:nil];
}
/*!
Loads a string of HTML into the webview.
@param CPString - The string to load.
@param CPURL - The base url of the string. (not implemented)
*/
- (void)loadHTMLString:(CPString)aString baseURL:(CPURL)URL
{
// FIXME: do something with baseURL?
@@ -365,11 +390,21 @@ CPWebViewScrollNative = 2;
[_frameLoadDelegate webView:self didFinishLoadForFrame:nil]; // FIXME: give this a frame somehow?
}
/*!
Returns the URL of the main frame.
@return CPString - The URL of the main frame.
*/
- (CPString)mainFrameURL
{
return _mainFrameURL;
}
/*!
Sets the URL of the main frame.
@param CPString - the url to set.
*/
- (void)setMainFrameURL:(CPString)URLString
{
if (_mainFrameURL)
@@ -380,6 +415,11 @@ CPWebViewScrollNative = 2;
[self _loadMainFrameURL];
}
/*!
Tells the webview to navigate to the previous page.
@return BOOL - YES if the receiver was able to go back, otherwise NO.
*/
- (BOOL)goBack
{
if (_backwardStack.length > 0)
@@ -396,6 +436,11 @@ CPWebViewScrollNative = 2;
return NO;
}
/*!
Tells the receiver to go forward in page history.
@return - YES if the receiver was able to go forward, otherwise NO.
*/
- (BOOL)goForward
{
if (_forwardStack.length > 0)
@@ -412,11 +457,23 @@ CPWebViewScrollNative = 2;
return NO;
}
/*!
Checks to see if the webview has a history stack you can navigate back
through.
@return BOOL - YES if the receiver can navigate backward through history, otherwise NO.
*/
- (BOOL)canGoBack
{
return (_backwardStack.length > 0);
}
/*!
Checks to see if the webview has a history stack you can navigate forward
through.
@return BOOL - YES if the receiver can navigate forward through history, otherwise NO.
*/
- (BOOL)canGoForward
{
return (_forwardStack.length > 0);
@@ -428,16 +485,30 @@ CPWebViewScrollNative = 2;
return { back: _backwardStack, forward: _forwardStack };
}
/*!
Closes the webview by unloading the webpage. The webview will no longer
respond to load requests or delegate methods once this is called.
*/
- (void)close
{
_iframe.parentNode.removeChild(_iframe);
}
/*!
Returns the window object of the webview.
@return DOMWindow - The window object.
*/
- (DOMWindow)DOMWindow
{
return (_iframe.contentDocument && _iframe.contentDocument.defaultView) || _iframe.contentWindow;
}
/*!
Returns the root Object of the webview as a CPWebScriptObject.
@return CPWebScriptObject - the Object of the webview.
*/
- (CPWebScriptObject)windowScriptObject
{
var win = [self DOMWindow];
@@ -451,17 +522,37 @@ CPWebViewScrollNative = 2;
return _wso;
}
/*!
Evaluates a javascript string in the webview and returns the result of
that evaluation as a string.
@param script - A string of javascript.
@return CPString - The result of the evaluation.
*/
- (CPString)stringByEvaluatingJavaScriptFromString:(CPString)script
{
var result = [self objectByEvaluatingJavaScriptFromString:script];
return result ? String(result) : nil;
}
/*!
Evaluates a string of javascript in the webview and returns the result.
@param script - A string of javascript.
@return JSObject - A JSObject resulting from the evaluation.
*/
- (JSObject)objectByEvaluatingJavaScriptFromString:(CPString)script
{
return [[self windowScriptObject] evaluateWebScript:script];
}
/*!
Gets the computed style for an element.
@param DOMElement - An Element.
@param pseudoElement - A pseudoElement.
@return DOMCSSStyleDeclaration - The computed style for an element.
*/
- (DOMCSSStyleDeclaration)computedStyleForElement:(DOMElement)element pseudoElement:(CPString)pseudoElement
{
var win = [[self windowScriptObject] window];
@@ -474,47 +565,85 @@ CPWebViewScrollNative = 2;
}
/*!
@return BOOL - YES if the webview draws its own background, otherwise NO.
*/
- (BOOL)drawsBackground
{
return _iframe.style.backgroundColor != "";
}
/*!
Sets whether the webview draws its own background.
@param BOOL - YES if the webview should draw its background, otherwise NO.
*/
- (void)setDrawsBackground:(BOOL)drawsBackround
{
_iframe.style.backgroundColor = drawsBackround ? "white" : "";
}
// IBActions
- (IBAction)takeStringURLFrom:(id)sender
/*!
Used with the target/action mechanism to automatically set the webviews
mainFrameURL to the senders stringValue.
@param sender - the sender of the action. Should respond to -stringValue.
*/
- (@action)takeStringURLFrom:(id)sender
{
[self setMainFrameURL:[sender stringValue]];
}
- (IBAction)goBack:(id)sender
/*!
Same as -goBack but takes a sender as a param.
@param sender - the sender of the action.
*/
- (@action)goBack:(id)sender
{
[self goBack];
}
- (IBAction)goForward:(id)sender
/*!
Same as -goForward but takes a sender as a param.
@param sender - the sender of the action.
*/
- (@action)goForward:(id)sender
{
[self goForward];
}
- (IBAction)stopLoading:(id)sender
/*!
Stops loading the webview. (not yet implemented)
@param sender - the sender of the action.
*/
- (@action)stopLoading:(id)sender
{
// FIXME: what to do?
}
- (IBAction)reload:(id)sender
/*!
Reloads the webview.
@param sender - the sender of the action.
*/
- (@action)reload:(id)sender
{
[self _loadMainFrameURL];
}
- (IBAction)print:(id)sender
/*!
Tells the webview to print. If the webview is unable to print due to
browser restrictions the user is alerted to print from the file menu.
@param sender - the sender of the receiver.
*/
- (@action)print:(id)sender
{
try
{
@@ -574,12 +703,19 @@ CPWebViewScrollNative = 2;
@end
/*!
@class CPWebScriptObject
A CPWebScriptObject is an Objective-J wrapper around a scripting object.
*/
@implementation CPWebScriptObject : CPObject
{
Window _window;
}
/*!
Initializes the scripting object with the scripting Window object.
*/
- (id)initWithWindow:(Window)aWindow
{
if (self = [super init])
@@ -589,6 +725,12 @@ CPWebViewScrollNative = 2;
return self;
}
/*!
Call a method with arguments on the receiver.
@param methodName - The method that should be called.
@param args - An array of arguments to pass to the method call.
*/
- (id)callWebScriptMethod:(CPString)methodName withArguments:(CPArray)args
{
// Would using "with" be better here?
@@ -602,15 +744,25 @@ CPWebViewScrollNative = 2;
return undefined;
}
/*!
Evaluates a string of javascript and returns the result.
@param script - The script to run.
@return - The result of the evaluation, which may be 'undefined'.
*/
- (id)evaluateWebScript:(CPString)script
{
try {
return _window.eval(script);
} catch (e) {
// FIX ME: if we fail inside here, shouldn't we return an exception?
}
return undefined;
}
/*!
Returns the receivers Window object.
*/
- (Window)window
{
return _window;
@@ -623,6 +775,7 @@ CPWebViewScrollNative = 2;
/*!
Initializes the web view from the data in a coder.
@param aCoder the coder from which to read the data
@return the initialized web view
*/
@@ -650,6 +803,7 @@ CPWebViewScrollNative = 2;
/*!
Writes out the web view's instance information to a coder.
@param aCoder the coder to which to write the data
*/
- (void)encodeWithCoder:(CPCoder)aCoder
+101 -5
View File
@@ -539,6 +539,12 @@ CPTexturedBackgroundWindowMask
}
}
/*!
Sets the receiver as a full platform window. If you pass YES the CPWindow instance will fill the entire browser content area,
otherwise the CPWindow will be a window inside of your browser window which the user can drag around, and resize (if you allow).
@param BOOL - YES if the window should fill the browser window, otherwise NO.
*/
- (void)setFullPlatformWindow:(BOOL)shouldBeFullPlatformWindow
{
if (![_platformWindow supportsFullPlatformWindows])
@@ -579,6 +585,9 @@ CPTexturedBackgroundWindowMask
}
}
/*!
@return BOOL - YES if the CPWindow fills the browser window, otherwise NO.
*/
- (BOOL)isFullPlatformWindow
{
return _isFullPlatformWindow;
@@ -594,6 +603,18 @@ CPTexturedBackgroundWindowMask
/*!
Returns the frame rectangle used by a window.
Style masks include:
<pre>
CPBorderlessWindowMask
CPTitledWindowMask
CPClosableWindowMask
CPMiniaturizableWindowMask (NOTE: only available in NativeHost)
CPResizableWindowMask
CPTexturedBackgroundWindowMask
CPBorderlessBridgeWindowMask
CPHUDBackgroundWindowMask
</pre>
@param aContentRect the content rectangle of the window
@param aStyleMask the style mask of the window
@return the matching window's frame rectangle
@@ -635,7 +656,7 @@ CPTexturedBackgroundWindowMask
the resize operation, and redraw itself if necessary.
@param aFrame the new size and location for the window
@param shouldDisplay whether the window should redraw its views
@param shouldAnimate whether the window resize should be animated
@param shouldAnimate whether the window resize should be animated.
*/
- (void)_setClippedFrame:(CGRect)aFrame display:(BOOL)shouldDisplay animate:(BOOL)shouldAnimate
{
@@ -644,6 +665,13 @@ CPTexturedBackgroundWindowMask
[self setFrame:aFrame display:shouldDisplay animate:shouldAnimate];
}
/*!
Sets the frame of the window.
@param aFrame - A CGRect of the new frame for the receiver.
@param shouldDisplay - YES if the window should call setNeedsDisplay otherwise NO.
@param shouldAnimate - YES if the window should animate to it's new size and position, otherwise NO.
*/
- (void)setFrame:(CGRect)aFrame display:(BOOL)shouldDisplay animate:(BOOL)shouldAnimate
{
aFrame = _CGRectMakeCopy(aFrame);
@@ -721,6 +749,11 @@ CPTexturedBackgroundWindowMask
}
}
/*!
Sets the window's frame rect.
@param aFrame - The new CGRect of the window.
@param shouldDisplay - YES if the window should call setNeedsDisplay: otherwise NO.
*/
- (void)setFrame:(CGRect)aFrame display:(BOOL)shouldDisplay
{
[self _setClippedFrame:aFrame display:shouldDisplay animate:NO];
@@ -728,6 +761,7 @@ CPTexturedBackgroundWindowMask
/*!
Sets the window's frame rectangle
@param aFrame - The CGRect of the windows new frame
*/
- (void)setFrame:(CGRect)aFrame
{
@@ -1111,6 +1145,17 @@ CPTexturedBackgroundWindowMask
[self _updateShadow];
}
/*!
Sets the shadow style of the receiver.
Values are:
<pre>
CPWindowShadowStyleStandard
CPWindowShadowStyleMenu
CPWindowShadowStylePanel
</pre>
@param aStyle - The new shadow style of the receiver.
*/
- (void)setShadowStyle:(unsigned)aStyle
{
_shadowStyle = aStyle;
@@ -1631,7 +1676,7 @@ CPTexturedBackgroundWindowMask
@param aLocation the lower-left corner coordinate of \c anImage
@param mouseOffset the distance from the \c -mouseDown: location and the current location
@param anEvent the \c -mouseDown: that triggered the drag
@param aPastebaord the pasteboard that holds the drag data
@param aPasteboard the pasteboard that holds the drag data
@param aSourceObject the drag operation controller
@param slideBack Whether the image should 'slide back' if the drag is rejected
*/
@@ -1668,7 +1713,7 @@ CPTexturedBackgroundWindowMask
@param aLocation the lower-left corner coordinate of \c aView
@param mouseOffset the distance from the \c -mouseDown: location and the current location
@param anEvent the \c -mouseDown: that triggered the drag
@param aPastebaord the pasteboard that holds the drag data
@param aPasteboard the pasteboard that holds the drag data
@param aSourceObject the drag operation controller
@param slideBack Whether the view should 'slide back' if the drag is rejected
*/
@@ -1819,7 +1864,7 @@ CPTexturedBackgroundWindowMask
}
/*!
Restores a mimized window to it's original size.
Restores a minimized window to it's original size.
*/
- (void)deminiaturize:(id)sender
{
@@ -2448,16 +2493,31 @@ CPTexturedBackgroundWindowMask
[self makeFirstResponder:[aView previousValidKeyView]];
}
/*!
Sets the default button for the window.
Note: this method is deprecated use setDefaultButton: instead.
@param aButton - The button that should become default.
*/
- (void)setDefaultButtonCell:(CPButton)aButton
{
[self setDefaultButton:aButton];
}
/*!
Returns the default button of the receiver.
NOTE: This method is deprecated. Use defaultButton instead.
*/
- (CPButton)defaultButtonCell
{
return [self defaultButton];
}
/*!
Sets the default button for the window.
This is equivalent to setting the the key equivalent of the button to "return".
Additionally this will turn your button blue (with the Aristo theme).
@param aButton - The button that should become default.
*/
- (void)setDefaultButton:(CPButton)aButton
{
if (_defaultButton === aButton)
@@ -2472,26 +2532,43 @@ CPTexturedBackgroundWindowMask
[_defaultButton setKeyEquivalent:CPCarriageReturnCharacter];
}
/*!
Returns the default button of the receiver.
*/
- (CPButton)defaultButton
{
return _defaultButton;
}
/*!
Sets the default button key equivalent to "return".
*/
- (void)enableKeyEquivalentForDefaultButton
{
_defaultButtonEnabled = YES;
}
/*!
Sets the default button key equivalent to "return".
NOTE: this method is deprecated. Use enableKeyEquivalentForDefaultButton instead.
*/
- (void)enableKeyEquivalentForDefaultButtonCell
{
[self enableKeyEquivalentForDefaultButton];
}
/*!
Removes the key equivalent for the default button.
*/
- (void)disableKeyEquivalentForDefaultButton
{
_defaultButtonEnabled = NO;
}
/*!
Removes the key equivalent for the default button.
Note: this method is deprecated. Use disableKeyEquivalentForDefaultButton instead.
*/
- (void)disableKeyEquivalentForDefaultButtonCell
{
[self disableKeyEquivalentForDefaultButton];
@@ -2603,16 +2680,25 @@ var keyViewComparator = function(lhs, rhs, context)
return _autoresizingMask;
}
/*!
Converts aPoint from the window coordinate system to the global coordinate system.
*/
- (CGPoint)convertBaseToGlobal:(CGPoint)aPoint
{
return [CPPlatform isBrowser] ? [self convertBaseToPlatformWindow:aPoint] : [self convertBaseToScreen:aPoint];
}
/*!
Converts aPoint from the global coordinate system to the window coordinate system.
*/
- (CGPoint)convertGlobalToBase:(CGPoint)aPoint
{
return [CPPlatform isBrowser] ? [self convertPlatformWindowToBase:aPoint] : [self convertScreenToBase:aPoint];
}
/*!
Converts aPoint from the window coordinate system to the coordinate system of the parent platform window.
*/
- (CGPoint)convertBaseToPlatformWindow:(CGPoint)aPoint
{
if ([self _sharesChromeWithPlatformWindow])
@@ -2623,6 +2709,9 @@ var keyViewComparator = function(lhs, rhs, context)
return _CGPointMake(aPoint.x + origin.x, aPoint.y + origin.y);
}
/*!
Converts aPoint from the parent platform window coordinate system to the windows coordinate system.
*/
- (CGPoint)convertPlatformWindowToBase:(CGPoint)aPoint
{
if ([self _sharesChromeWithPlatformWindow])
@@ -2712,12 +2801,19 @@ var keyViewComparator = function(lhs, rhs, context)
@end
@implementation CPWindow (Deprecated)
/*!
Sets the CPWindow to fill the whole browser window.
NOTE: this method has been deprecated in favor of setFullPlatformWindow:
*/
- (void)setFullBridge:(BOOL)shouldBeFullBridge
{
[self setFullPlatformWindow:shouldBeFullBridge];
}
/*!
Returns YES if the window fills the full browser window, otherwise NO.
NOTE: this method has been deprecated in favor of isFullPlatformWindow.
*/
- (BOOL)isFullBridge
{
return [self isFullPlatformWindow];
+2 -2
View File
@@ -62,7 +62,7 @@
/*!
Initializes the controller with a window.
@param aWindow the window to control
@return the initialzed window controller
@return the initialized window controller
*/
- (id)initWithWindow:(CPWindow)aWindow
{
@@ -82,7 +82,7 @@
}
/*!
Initializes the controller with a Capppuccino Interface Builder name.
Initializes the controller with a Cappuccino Interface Builder name.
@param aWindowCibName the cib name of the window to control
@return the initialized window controller
*/
+5 -5
View File
@@ -84,7 +84,7 @@ var _CPCibCustomViewClassNameKey = @"_CPCibCustomViewClassNameKey";
{
#if DEBUG
CPLog("Unknown class \"" + _className + "\" in cib file, using CPView instead.");
#endif
#endif
theClass = [CPView class];
}
@@ -97,16 +97,16 @@ var _CPCibCustomViewClassNameKey = @"_CPCibCustomViewClassNameKey";
}
var view = [[theClass alloc] initWithFrame:[self frame]];
if (view)
{
[view setBounds:[self bounds]];
// Since the object replacement logic hasn't had a chance to kick in yet, we need to do it manually:
var subviews = [self subviews],
index = 0,
count = subviews.length;
for (; index < count; ++index)
[view addSubview:subviews[index]];
@@ -116,7 +116,7 @@ var _CPCibCustomViewClassNameKey = @"_CPCibCustomViewClassNameKey";
[view setHitTests:[self hitTests]];
[view setHidden:[self isHidden]];
[view setAlphaValue:[self alphaValue]];
[_superview replaceSubview:self with:view];
[view setBackgroundColor:[self backgroundColor]];
+3 -3
View File
@@ -12,15 +12,15 @@
- (id)initForReadingWithData:(CPData)data bundle:(CPBundle)aBundle awakenCustomResources:(BOOL)shouldAwakenCustomResources
{
self = [super initForReadingWithData:data];
if (self)
{
_bundle = aBundle;
_awakenCustomResources = shouldAwakenCustomResources;
[self setDelegate:self];
}
return self;
}
+24 -24
View File
@@ -5,19 +5,19 @@
@import "CPWindow.j"
var _CPCibWindowTemplateMinSizeKey = @"_CPCibWindowTemplateMinSizeKey",
_CPCibWindowTemplateMaxSizeKey = @"_CPCibWindowTemplateMaxSizeKey",
_CPCibWindowTemplateViewClassKey = @"_CPCibWindowTemplateViewClassKey",
_CPCibWindowTemplateWindowClassKey = @"_CPCibWindowTemplateWindowClassKey",
_CPCibWindowTemplateWindowRectKey = @"_CPCibWindowTemplateWindowRectKey",
_CPCibWindowTemplateWindowStyleMaskKey = @"_CPCibWindowTempatStyleMaskKey",
_CPCibWindowTemplateWindowTitleKey = @"_CPCibWindowTemplateWindowTitleKey",
_CPCibWindowTemplateWindowViewKey = @"_CPCibWindowTemplateWindowViewKey",
var _CPCibWindowTemplateMinSizeKey = @"_CPCibWindowTemplateMinSizeKey",
_CPCibWindowTemplateMaxSizeKey = @"_CPCibWindowTemplateMaxSizeKey",
_CPCibWindowTemplateWindowAutorecalculatesKeyViewLoop = @"_CPCibWindowTemplateWindowAutorecalculatesKeyViewLoop";
_CPCibWindowTemplateWindowIsFullPlatformWindowKey = @"_CPCibWindowTemplateWindowIsFullPlatformWindowKey";
_CPCibWindowTemplateViewClassKey = @"_CPCibWindowTemplateViewClassKey",
_CPCibWindowTemplateWindowClassKey = @"_CPCibWindowTemplateWindowClassKey",
_CPCibWindowTemplateWindowRectKey = @"_CPCibWindowTemplateWindowRectKey",
_CPCibWindowTemplateWindowStyleMaskKey = @"_CPCibWindowTempatStyleMaskKey",
_CPCibWindowTemplateWindowTitleKey = @"_CPCibWindowTemplateWindowTitleKey",
_CPCibWindowTemplateWindowViewKey = @"_CPCibWindowTemplateWindowViewKey",
_CPCibWindowTemplateWindowAutorecalculatesKeyViewLoop = @"_CPCibWindowTemplateWindowAutorecalculatesKeyViewLoop",
_CPCibWindowTemplateWindowIsFullPlatformWindowKey = @"_CPCibWindowTemplateWindowIsFullPlatformWindowKey";
@implementation _CPCibWindowTemplate : CPObject
{
@@ -60,27 +60,27 @@ var _CPCibWindowTemplateMinSizeKey = @"_CPCibWindowTemplateMinS
- (id)initWithCoder:(CPCoder)aCoder
{
self = [super init];
if (self)
{
if ([aCoder containsValueForKey:_CPCibWindowTemplateMinSizeKey])
_minSize = [aCoder decodeSizeForKey:_CPCibWindowTemplateMinSizeKey];
if ([aCoder containsValueForKey:_CPCibWindowTemplateMaxSizeKey])
_maxSize = [aCoder decodeSizeForKey:_CPCibWindowTemplateMaxSizeKey];
_viewClass = [aCoder decodeObjectForKey:_CPCibWindowTemplateViewClassKey];
_windowClass = [aCoder decodeObjectForKey:_CPCibWindowTemplateWindowClassKey];
_windowRect = [aCoder decodeRectForKey:_CPCibWindowTemplateWindowRectKey];
_windowStyleMask = [aCoder decodeIntForKey:_CPCibWindowTemplateWindowStyleMaskKey];
_windowTitle = [aCoder decodeObjectForKey:_CPCibWindowTemplateWindowTitleKey];
_windowView = [aCoder decodeObjectForKey:_CPCibWindowTemplateWindowViewKey];
_windowAutorecalculatesKeyViewLoop = !![aCoder decodeObjectForKey:_CPCibWindowTemplateWindowAutorecalculatesKeyViewLoop];
_windowIsFullPlatformWindow = !![aCoder decodeObjectForKey:_CPCibWindowTemplateWindowIsFullPlatformWindowKey];
}
return self;
}
@@ -90,13 +90,13 @@ var _CPCibWindowTemplateMinSizeKey = @"_CPCibWindowTemplateMinS
[aCoder encodeSize:_minSize forKey:_CPCibWindowTemplateMinSizeKey];
if (_maxSize)
[aCoder encodeSize:_maxSize forKey:_CPCibWindowTemplateMaxSizeKey];
[aCoder encodeObject:_viewClass forKey:_CPCibWindowTemplateViewClassKey];
[aCoder encodeObject:_windowClass forKey:_CPCibWindowTemplateWindowClassKey];
[aCoder encodeRect:_windowRect forKey:_CPCibWindowTemplateWindowRectKey];
[aCoder encodeInt:_windowStyleMask forKey:_CPCibWindowTemplateWindowStyleMaskKey];
[aCoder encodeObject:_windowTitle forKey:_CPCibWindowTemplateWindowTitleKey];
[aCoder encodeObject:_windowView forKey:_CPCibWindowTemplateWindowViewKey];
@@ -126,13 +126,13 @@ var _CPCibWindowTemplateMinSizeKey = @"_CPCibWindowTemplateMinS
- (id)_cibInstantiate
{
var windowClass = CPClassFromString([self windowClass]);
/* if (!windowClass)
[NSException raise:NSInvalidArgumentException format:@"Unable to locate NSWindow class %@, using NSWindow",_windowClass];
class=[NSWindow class];*/
var theWindow = [[windowClass alloc] initWithContentRect:_windowRect styleMask:_windowStyleMask];
if (_minSize)
[theWindow setMinSize:_minSize];
if (_maxSize)
@@ -147,7 +147,7 @@ var _CPCibWindowTemplateMinSizeKey = @"_CPCibWindowTemplateMinS
[theWindow setContentView:_windowView];
[_windowView setAutoresizesSubviews:YES];
if ([_viewClass isKindOfClass:[CPToolbar class]])
{
[theWindow setToolbar:_viewClass];
+148 -148
View File
@@ -64,54 +64,54 @@ var CALayerRegisteredRunLoopUpdates = nil;
@implementation CALayer : CPObject
{
// Modifying the Layer Geometry
CGRect _frame;
CGRect _bounds;
CGPoint _position;
unsigned _zPosition;
CGPoint _anchorPoint;
CGAffineTransform _affineTransform;
CGAffineTransform _sublayerTransform;
CGAffineTransform _sublayerTransformForSublayers;
CGRect _backingStoreFrame;
CGRect _standardBackingStoreFrame;
BOOL _hasSublayerTransform;
BOOL _hasCustomBackingStoreFrame;
// Style Attributes
float _opacity;
BOOL _isHidden;
CPColor _backgroundColor;
// Managing Layer Hierarchy
CALayer _superlayer;
CPMutableArray _sublayers;
// Updating Layer Display
unsigned _runLoopUpdateMask;
BOOL _needsDisplayOnBoundsChange;
// Modifying the Delegate
id _delegate;
BOOL _delegateRespondsToDisplayLayerSelector;
BOOL _delegateRespondsToDrawLayerInContextSelector;
// DOM Implementation
DOMElement _DOMElement;
DOMElement _DOMContentsElement;
id _contents;
CGContext _context;
CPView _owningView;
CGAffineTransform _transformToLayer;
CGAffineTransform _transformFromLayer;
}
@@ -130,14 +130,14 @@ var CALayerRegisteredRunLoopUpdates = nil;
- (id)init
{
self = [super init];
if (self)
{
_frame = CGRectMakeZero();
_backingStoreFrame = CGRectMakeZero();
_standardBackingStoreFrame = CGRectMakeZero();
_bounds = CGRectMakeZero();
_position = CGPointMakeZero();
_zPosition = 0.0;
@@ -147,15 +147,15 @@ var CALayerRegisteredRunLoopUpdates = nil;
_transformToLayer = CGAffineTransformMakeIdentity(); // FIXME? does it matter?
_transformFromLayer = CGAffineTransformMakeIdentity();
_opacity = 1.0;
_isHidden = NO;
_masksToBounds = NO;
_sublayers = [];
_DOMElement = document.createElement("div");
_DOMElement.style.overflow = "visible";
_DOMElement.style.position = "absolute";
_DOMElement.style.visibility = "visible";
@@ -165,7 +165,7 @@ var CALayerRegisteredRunLoopUpdates = nil;
_DOMElement.style.width = "0px";
_DOMElement.style.height = "0px";
}
return self;
}
@@ -182,20 +182,20 @@ var CALayerRegisteredRunLoopUpdates = nil;
var oldOrigin = _bounds.origin;
_bounds = _CGRectMakeCopy(aBounds);
if (_hasSublayerTransform)
_CALayerUpdateSublayerTransformForSublayers(self);
// _hasSublayerTransform == true will handle this for us.
/*else if (!CGPointEqualToPoint(_bounds.origin, oldOrigin))
{
var index = _sublayers.length;
// FIXME: This should climb the layer tree down.
while (index--)
_CALayerRecalculateGeometry(_sublayers[index], CALayerGeometryPositionMask);
}*/
_CALayerRecalculateGeometry(self, CALayerGeometryBoundsMask);
}
@@ -215,9 +215,9 @@ var CALayerRegisteredRunLoopUpdates = nil;
{
if (CGPointEqualToPoint(_position, aPosition))
return;
_position = _CGPointMakeCopy(aPosition);
_CALayerRecalculateGeometry(self, CALayerGeometryPositionMask);
}
@@ -237,9 +237,9 @@ var CALayerRegisteredRunLoopUpdates = nil;
{
if (_zPosition == aZPosition)
return;
_zPosition = aZPosition;
[self registerRunLoopUpdateWithMask:CALayerZPositionUpdateMask];
}
@@ -252,18 +252,18 @@ var CALayerRegisteredRunLoopUpdates = nil;
anAnchorPoint = _CGPointMakeCopy(anAnchorPoint);
anAnchorPoint.x = MIN(1.0, MAX(0.0, anAnchorPoint.x));
anAnchorPoint.y = MIN(1.0, MAX(0.0, anAnchorPoint.y));
if (CGPointEqualToPoint(_anchorPoint, anAnchorPoint))
return;
_anchorPoint = anAnchorPoint;
if (_hasSublayerTransform)
_CALayerUpdateSublayerTransformForSublayers(self);
if (_owningView)
_position = CGPointMake(_CGRectGetWidth(_bounds) * _anchorPoint.x, _CGRectGetHeight(_bounds) * _anchorPoint.y);
_CALayerRecalculateGeometry(self, CALayerGeometryAnchorPointMask);
}
@@ -283,9 +283,9 @@ var CALayerRegisteredRunLoopUpdates = nil;
{
if (CGAffineTransformEqualToTransform(_affineTransform, anAffineTransform))
return;
_affineTransform = _CGAffineTransformMakeCopy(anAffineTransform);
_CALayerRecalculateGeometry(self, CALayerGeometryAffineTransformMask);
}
@@ -307,16 +307,16 @@ var CALayerRegisteredRunLoopUpdates = nil;
return;
var hadSublayerTransform = _hasSublayerTransform;
_sublayerTransform = _CGAffineTransformMakeCopy(anAffineTransform);
_hasSublayerTransform = !_CGAffineTransformIsIdentity(_sublayerTransform);
if (_hasSublayerTransform)
{
_CALayerUpdateSublayerTransformForSublayers(self);
var index = _sublayers.length;
// FIXME: This should climb the layer tree down.
while (index--)
_CALayerRecalculateGeometry(_sublayers[index], CALayerGeometryParentSublayerTransformMask);
@@ -353,23 +353,23 @@ var CALayerRegisteredRunLoopUpdates = nil;
/*!
Returns the layer's frame.
The frame defines the bounding box of the layer: the smallest
possible rectangle that could fit this layer after transform
The frame defines the bounding box of the layer: the smallest
possible rectangle that could fit this layer after transform
properties are applied in superlayer coordinates.
*/
- (CGRect)frame
{
if (!_frame)
_frame = [self convertRect:_bounds toLayer:_superlayer];
return _frame;
}
/*!
The Backing Store Frame specifies the frame of the actual backing
store used to contain this layer. Naturally, by default it is the
same as the frame, however, users can specify their own custom
Backing Store Frame in order to speed up certain operations, such as
store used to contain this layer. Naturally, by default it is the
same as the frame, however, users can specify their own custom
Backing Store Frame in order to speed up certain operations, such as
live transformation.
@return the backing store frame
*/
@@ -385,7 +385,7 @@ var CALayerRegisteredRunLoopUpdates = nil;
- (void)setBackingStoreFrame:(CGRect)aFrame
{
_hasCustomBackingStoreFrame = (aFrame != nil);
if (aFrame == nil)
aFrame = CGRectMakeCopy(_standardBackingStoreFrame);
else
@@ -393,23 +393,23 @@ var CALayerRegisteredRunLoopUpdates = nil;
if (_superlayer)
{
aFrame = [_superlayer convertRect:aFrame toLayer:nil];
var bounds = [_superlayer bounds],
frame = [_superlayer convertRect:bounds toLayer:nil];
aFrame.origin.x -= _CGRectGetMinX(frame);
aFrame.origin.y -= _CGRectGetMinY(frame);
}
else
aFrame = CGRectMakeCopy(aFrame);
}
if (!CGPointEqualToPoint(_backingStoreFrame.origin, aFrame.origin))
[self registerRunLoopUpdateWithMask:CALayerFrameOriginUpdateMask];
if (!CGSizeEqualToSize(_backingStoreFrame.size, aFrame.size))
[self registerRunLoopUpdateWithMask:CALayerFrameSizeUpdateMask];
_backingStoreFrame = aFrame;
}
@@ -431,9 +431,9 @@ var CALayerRegisteredRunLoopUpdates = nil;
{
if (_contents == contents)
return;
_contents = contents;
[self composite];
}
@@ -445,26 +445,26 @@ var CALayerRegisteredRunLoopUpdates = nil;
{
if (USE_BUFFER && !_contents || !_context)
return;
CGContextClearRect(_context, _CGRectMake(0.0, 0.0, _CGRectGetWidth(_backingStoreFrame), _CGRectGetHeight(_backingStoreFrame)));
// Recomposite
var transform = _transformFromLayer;
if (_superlayer)
{
var superlayerTransform = _CALayerGetTransform(_superlayer, nil),
superlayerOrigin = CGPointApplyAffineTransform(_superlayer._bounds.origin, superlayerTransform);
transform = CGAffineTransformConcat(transform, superlayerTransform);
transform.tx -= superlayerOrigin.x;
transform.ty -= superlayerOrigin.y;
}
transform.tx -= _CGRectGetMinX(_backingStoreFrame);
transform.ty -= _CGRectGetMinY(_backingStoreFrame);
CGContextSaveGState(_context);
CGContextConcatCTM(_context, transform);//_transformFromView);
if (USE_BUFFER)
@@ -485,18 +485,18 @@ var CALayerRegisteredRunLoopUpdates = nil;
if (!_context)
{
_context = CGBitmapGraphicsContextCreate();
_DOMContentsElement = _context.DOMElement;
_DOMContentsElement.style.zIndex = -100;
_DOMContentsElement.style.overflow = "hidden";
_DOMContentsElement.style.position = "absolute";
_DOMContentsElement.style.visibility = "visible";
_DOMContentsElement.width = ROUND(_CGRectGetWidth(_backingStoreFrame));
_DOMContentsElement.height = ROUND(_CGRectGetHeight(_backingStoreFrame));
_DOMContentsElement.style.top = "0px";
_DOMContentsElement.style.left = "0px";
_DOMContentsElement.style.width = ROUND(_CGRectGetWidth(_backingStoreFrame)) + "px";
@@ -504,23 +504,23 @@ var CALayerRegisteredRunLoopUpdates = nil;
_DOMElement.appendChild(_DOMContentsElement);
}
if (USE_BUFFER)
{
if (_delegateRespondsToDisplayLayerSelector)
return [_delegate displayInLayer:self];
if (_CGRectGetWidth(_backingStoreFrame) == 0.0 || _CGRectGetHeight(_backingStoreFrame) == 0.0)
return;
if (!_contents)
_contents = CABackingStoreCreate();
CABackingStoreSetSize(_contents, _bounds.size);
[self drawInContext:CABackingStoreGetContext(_contents)];
}
[self composite];
}
@@ -535,7 +535,7 @@ var CALayerRegisteredRunLoopUpdates = nil;
CGContextSetFillColor(aContext, _backgroundColor);
CGContextFillRect(aContext, _bounds);
}
if (_delegateRespondsToDrawLayerInContextSelector)
[_delegate drawLayer:self inContext:aContext];
}
@@ -559,9 +559,9 @@ var CALayerRegisteredRunLoopUpdates = nil;
{
if (_opacity == anOpacity)
return;
_opacity = anOpacity;
_DOMElement.style.opacity = anOpacity;
_DOMElement.style.filter = "alpha(opacity=" + anOpacity * 100 + ")";
}
@@ -600,7 +600,7 @@ var CALayerRegisteredRunLoopUpdates = nil;
{
if (_masksToBounds == masksToBounds)
return;
_masksToBounds = masksToBounds;
_DOMElement.style.overflow = _masksToBounds ? "hidden" : "visible";
}
@@ -612,7 +612,7 @@ var CALayerRegisteredRunLoopUpdates = nil;
- (void)setBackgroundColor:(CPColor)aColor
{
_backgroundColor = aColor;
[self setNeedsDisplay];
}
@@ -665,10 +665,10 @@ if (_DOMContentsElement && aLayer._zPosition > _DOMContentsElement.style.zIndex)
{
if (_owningView)
[_owningView setLayer:nil];
if (!_superlayer)
return;
_superlayer._DOMElement.removeChild(_DOMElement);
[_superlayer._sublayers removeObject:self];
@@ -684,24 +684,24 @@ if (_DOMContentsElement && aLayer._zPosition > _DOMContentsElement.style.zIndex)
{
if (!aLayer)
return;
var superlayer = [aLayer superlayer];
if (superlayer == self)
{
var index = [_sublayers indexOfObjectIdenticalTo:aLayer];
if (index == anIndex)
return;
[_sublayers removeObjectAtIndex:index];
if (index < anIndex)
--anIndex;
}
else if (superlayer != nil)
[aLayer removeFromSuperlayer];
ADJUST_CONTENTS_ZINDEX(aLayer);
[_sublayers insertObject:aLayer atIndex:anIndex];
@@ -710,9 +710,9 @@ if (_DOMContentsElement && aLayer._zPosition > _DOMContentsElement.style.zIndex)
_DOMElement.appendChild(DOM(aLayer));
else
_DOMElement.insertBefore(DOM(aLayer), _sublayers[anIndex + 1]._DOMElement);
aLayer._superlayer = self;
if (self != superlayer)
_CALayerRecalculateGeometry(aLayer, 0xFFFFFFF);
}
@@ -726,7 +726,7 @@ if (_DOMContentsElement && aLayer._zPosition > _DOMContentsElement.style.zIndex)
- (void)insertSublayer:(CALayer)aLayer below:(CALayer)aSublayer
{
var index = aSublayer ? [_sublayers indexOfObjectIdenticalTo:aSublayer] : 0;
[self insertSublayer:aLayer atIndex:index == CPNotFound ? _sublayers.length : index];
}
@@ -754,16 +754,16 @@ if (_DOMContentsElement && aLayer._zPosition > _DOMContentsElement.style.zIndex)
{
if (aSublayer == aLayer)
return;
// FIXME: EXCEPTION
if (aSublayer._superlayer != self)
{
alert("EXCEPTION");
return;
}
ADJUST_CONTENTS_ZINDEX(aLayer);
[_sublayers replaceObjectAtIndex:[_sublayers indexOfObjectIdenticalTo:aSublayer] withObject:aLayer];
_DOMElement.replaceChild(DOM(aSublayer), DOM(aLayer));
}
@@ -782,13 +782,13 @@ if (_DOMContentsElement && aLayer._zPosition > _DOMContentsElement.style.zIndex)
if (mask & CALayerDOMUpdateMask)
_CALayerUpdateDOM(layer, mask);
if (mask & CALayerDisplayUpdateMask)
[layer display];
else if (mask & CALayerFrameSizeUpdateMask || mask & CALayerCompositeUpdateMask)
[layer composite];
layer._runLoopUpdateMask = 0;
}
window.loop= false;
@@ -803,11 +803,11 @@ if (_DOMContentsElement && aLayer._zPosition > _DOMContentsElement.style.zIndex)
if (CALayerRegisteredRunLoopUpdates == nil)
{
CALayerRegisteredRunLoopUpdates = {};
[[CPRunLoop currentRunLoop] performSelector:@selector(runLoopUpdateLayers)
target:CALayer argument:nil order:0 modes:[CPDefaultRunLoopMode]];
}
_runLoopUpdateMask |= anUpdateMask;
CALayerRegisteredRunLoopUpdates[[self UID]] = self;
}
@@ -846,7 +846,7 @@ if (_DOMContentsElement && aLayer._zPosition > _DOMContentsElement.style.zIndex)
}
/*!
Marks the specified rectange as needing to be redrawn.
Marks the specified rectangle as needing to be redrawn.
@param aRect the area that needs to be redrawn.
*/
- (void)setNeedsDisplayInRect:(CGRect)aRect
@@ -890,8 +890,8 @@ if (_DOMContentsElement && aLayer._zPosition > _DOMContentsElement.style.zIndex)
}
/*!
Converts the rectangle from the receier's coordinate system to the specified layer's coordinate system.
@param aRect the rectange to convert
Converts the rectangle from the receiver's coordinate system to the specified layer's coordinate system.
@param aRect the rectangle to convert
@param aLayer the layer coordinate system to convert to
@return the converted rectangle
*/
@@ -919,21 +919,21 @@ if (_DOMContentsElement && aLayer._zPosition > _DOMContentsElement.style.zIndex)
{
if (_isHidden)
return nil;
var point = CGPointApplyAffineTransform(aPoint, _transformToLayer);
//alert(point.x + " " + point.y);
if (!_CGRectContainsPoint(_bounds, point))
return nil;
var layer = nil,
index = _sublayers.length;
// FIXME: this should take into account zPosition.
while (index--)
if (layer = [_sublayers[index] hitTest:point])
return layer;
return self;
}
@@ -946,12 +946,12 @@ if (_DOMContentsElement && aLayer._zPosition > _DOMContentsElement.style.zIndex)
{
if (_delegate == aDelegate)
return;
_delegate = aDelegate;
_delegateRespondsToDisplayLayerSelector = [_delegate respondsToSelector:@selector(displayLayer:)];
_delegateRespondsToDrawLayerInContextSelector = [_delegate respondsToSelector:@selector(drawLayer:inContext:)];
if (_delegateRespondsToDisplayLayerSelector || _delegateRespondsToDrawLayerInContextSelector)
[self setNeedsDisplay];
}
@@ -968,15 +968,15 @@ if (_DOMContentsElement && aLayer._zPosition > _DOMContentsElement.style.zIndex)
- (void)_setOwningView:(CPView)anOwningView
{
_owningView = anOwningView;
if (_owningView)
{
_owningView = anOwningView;
_bounds.size = CGSizeMakeCopy([_owningView bounds].size);
_position = CGPointMake(_CGRectGetWidth(_bounds) * _anchorPoint.x, _CGRectGetHeight(_bounds) * _anchorPoint.y);
}
_CALayerRecalculateGeometry(self, CALayerGeometryPositionMask | CALayerGeometryBoundsMask);
}
@@ -985,7 +985,7 @@ if (_DOMContentsElement && aLayer._zPosition > _DOMContentsElement.style.zIndex)
{
_bounds.size = CGSizeMakeCopy([_owningView bounds].size);
_position = CGPointMake(_CGRectGetWidth(_bounds) * _anchorPoint.x, _CGRectGetHeight(_bounds) * _anchorPoint.y);
_CALayerRecalculateGeometry(self, CALayerGeometryPositionMask | CALayerGeometryBoundsMask);
}
@@ -993,20 +993,20 @@ if (_DOMContentsElement && aLayer._zPosition > _DOMContentsElement.style.zIndex)
- (void)_update
{
window.loop = true;
var mask = _runLoopUpdateMask;
if (mask & CALayerDOMUpdateMask)
_CALayerUpdateDOM(self, mask);
if (mask & CALayerDisplayUpdateMask)
[self display];
else if (mask & CALayerFrameSizeUpdateMask || mask & CALayerCompositeUpdateMask)
[self composite];
_runLoopUpdateMask = 0;
window.loop = false;
}
@@ -1018,7 +1018,7 @@ function _CALayerUpdateSublayerTransformForSublayers(aLayer)
anchorPoint = aLayer._anchorPoint,
translateX = _CGRectGetWidth(bounds) * anchorPoint.x,
translateY = _CGRectGetHeight(bounds) * anchorPoint.y;
aLayer._sublayerTransformForSublayers = CGAffineTransformConcat(
CGAffineTransformMakeTranslation(-translateX, -translateY),
CGAffineTransformConcat(aLayer._sublayerTransform,
@@ -1028,27 +1028,27 @@ function _CALayerUpdateSublayerTransformForSublayers(aLayer)
function _CALayerUpdateDOM(aLayer, aMask)
{
var DOMElementStyle = aLayer._DOMElement.style;
if (aMask & CALayerZPositionUpdateMask)
DOMElementStyle.zIndex = aLayer._zPosition;
var frame = aLayer._backingStoreFrame;
if (aMask & CALayerFrameOriginUpdateMask)
{
DOMElementStyle.top = ROUND(_CGRectGetMinY(frame)) + "px";
DOMElementStyle.left = ROUND(_CGRectGetMinX(frame)) + "px";
}
if (aMask & CALayerFrameSizeUpdateMask)
{
var width = MAX(0.0, ROUND(_CGRectGetWidth(frame))),
height = MAX(0.0, ROUND(_CGRectGetHeight(frame))),
DOMContentsElement = aLayer._DOMContentsElement;
DOMElementStyle.width = width + "px";
DOMElementStyle.height = height + "px";
if (DOMContentsElement)
{
DOMContentsElement.width = width;
@@ -1070,7 +1070,7 @@ function _CALayerRecalculateGeometry(aLayer, aGeometryChange)
affineTransform = aLayer._affineTransform,
backingStoreFrameSize = _CGSizeMakeCopy(aLayer._backingStoreFrame),
hasCustomBackingStoreFrame = aLayer._hasCustomBackingStoreFrame;
// Go to anchor, transform, go back to bounds.
aLayer._transformFromLayer = CGAffineTransformConcat(
CGAffineTransformMakeTranslation(-width * anchorPoint.x - _CGRectGetMinX(aLayer._bounds), -height * anchorPoint.y - _CGRectGetMinY(aLayer._bounds)),
@@ -1082,68 +1082,68 @@ function _CALayerRecalculateGeometry(aLayer, aGeometryChange)
// aLayer._transformFromLayer = CGAffineTransformConcat(aLayer._transformFromLayer, superlayer._sublayerTransformForSublayers);
_CGAffineTransformConcatTo(aLayer._transformFromLayer, superlayer._sublayerTransformForSublayers, aLayer._transformFromLayer);
}
aLayer._transformToLayer = CGAffineTransformInvert(aLayer._transformFromLayer);
//aLayer._transformFromLayer.tx = ROUND(aLayer._transformFromLayer.tx);
//aLayer._transformFromLayer.ty = ROUND(aLayer._transformFromLayer.ty);
aLayer._frame = nil;
aLayer._standardBackingStoreFrame = [aLayer convertRect:bounds toLayer:nil];
if (superlayer)
{
var bounds = [superlayer bounds],
frame = [superlayer convertRect:bounds toLayer:nil];
aLayer._standardBackingStoreFrame.origin.x -= _CGRectGetMinX(frame);
aLayer._standardBackingStoreFrame.origin.y -= _CGRectGetMinY(frame);
}
// We used to use CGRectIntegral here, but what we actually want, is the largest integral
// rect that would ever contain this box, since for any width/height, there are 2 (4)
// rect that would ever contain this box, since for any width/height, there are 2 (4)
// possible integral rects for it depending on it's position. It's OK that this is sometimes
// bigger than the "optimal" bounding integral rect since that doesn't change drawing.
var origin = aLayer._standardBackingStoreFrame.origin,
size = aLayer._standardBackingStoreFrame.size;
origin.x = FLOOR(origin.x);
origin.y = FLOOR(origin.y);
size.width = CEIL(size.width) + 1.0;
size.height = CEIL(size.height) + 1.0;
// FIXME: This avoids the central issue that a position change is sometimes a display and sometimes
// a div move, and sometimes both.
// Only use this frame if we don't currently have a custom backing store frame.
if (!hasCustomBackingStoreFrame)
{
var backingStoreFrame = CGRectMakeCopy(aLayer._standardBackingStoreFrame);
// These values get rounded in the DOM, so don't both updating them if they're
// These values get rounded in the DOM, so don't both updating them if they're
// not going to be different after rounding.
if (ROUND(_CGRectGetMinX(backingStoreFrame)) != ROUND(_CGRectGetMinX(aLayer._backingStoreFrame)) ||
ROUND(_CGRectGetMinY(backingStoreFrame)) != ROUND(_CGRectGetMinY(aLayer._backingStoreFrame)))
[aLayer registerRunLoopUpdateWithMask:CALayerFrameOriginUpdateMask];
// Any change in size due to a geometry change is purely due to rounding error.
if ((_CGRectGetWidth(backingStoreFrame) != ROUND(_CGRectGetWidth(aLayer._backingStoreFrame)) ||
_CGRectGetHeight(backingStoreFrame) != ROUND(_CGRectGetHeight(aLayer._backingStoreFrame))))
[aLayer registerRunLoopUpdateWithMask:CALayerFrameSizeUpdateMask];
aLayer._backingStoreFrame = backingStoreFrame;
}
if (aGeometryChange & CALayerGeometryBoundsMask && aLayer._needsDisplayOnBoundsChange)
[aLayer setNeedsDisplay];
// We need to recomposite if we have a custom backing store frame, OR
// We need to recompose if we have a custom backing store frame, OR
// If the change is not solely composed of position and anchor points changes.
// Anchor point and position changes simply move the object, requiring
// Anchor point and position changes simply move the object, requiring
// no re-rendering.
else if (hasCustomBackingStoreFrame || (aGeometryChange & ~(CALayerGeometryPositionMask | CALayerGeometryAnchorPointMask)))
[aLayer setNeedsComposite];
var sublayers = aLayer._sublayers,
index = 0,
count = sublayers.length;
@@ -1155,45 +1155,45 @@ function _CALayerRecalculateGeometry(aLayer, aGeometryChange)
function _CALayerGetTransform(fromLayer, toLayer)
{
var transform = CGAffineTransformMakeIdentity();
if (fromLayer)
{
var layer = fromLayer;
// If we have a fromLayer, "climb up" the layer tree until
// If we have a fromLayer, "climb up" the layer tree until
// we hit the root node or we hit the toLayer.
while (layer && layer != toLayer)
{
var transformFromLayer = layer._transformFromLayer;
//transform = CGAffineTransformConcat(transform, layer._transformFromLayer);
_CGAffineTransformConcatTo(transform, transformFromLayer, transform);
layer = layer._superlayer;
}
// If we hit toLayer, then we're done.
if (layer == toLayer)
return transform;
}
var layers = [],
layer = toLayer;
while (layer)
{
layers.push(layer);
layer = layer._superlayer;
}
var index = layers.length;
while (index--)
{
var transformToLayer = layers[index]._transformToLayer;
_CGAffineTransformConcatTo(transform, transformToLayer, transform);
}
return transform;
}
+2 -2
View File
@@ -47,7 +47,7 @@ function CGColorGetConstantColor(aColorName)
}
/*!
This function is for source compatability.
This function is for source compatibility.
*/
function CGColorRetain(aColor)
{
@@ -55,7 +55,7 @@ function CGColorRetain(aColor)
}
/*!
This function is for source compatability.
This function is for source compatibility.
*/
function CGColorRelease()
{
+6 -6
View File
@@ -79,7 +79,7 @@ kCGBlendModePlusLighter = 27;
*/
/*!
This function is just here for source compatability.
This function is just here for source compatibility.
It does nothing.
@group CGContext
*/
@@ -88,7 +88,7 @@ function CGContextRelease()
}
/*!
This function is just here for source compatability.
This function is just here for source compatibility.
It does nothing.
@param aContext a CGContext
@return CGContext the context
@@ -466,7 +466,7 @@ function CGContextTranslateCTM(aContext, tx, ty)
/*!
Sets the current offset, and blur for shadows in core graphics drawing operations
@param aContext the CGContext of the shadow
@param aSize a CGSize indicating the offset of the shaodw
@param aSize a CGSize indicating the offset of the shadow
@param aBlur a float indicating the blur radius
@return void
*/
@@ -483,7 +483,7 @@ function CGContextSetShadow(aContext, aSize, aBlur)
/*!
Sets the current offset, blur, and color for shadows in core graphics drawing operations
@param aContext the CGContext of the shadow
@param aSize a CGSize indicating the offset of the shaodw
@param aSize a CGSize indicating the offset of the shadow
@param aBlur a float indicating the blur radius
@param aColor a CPColor object indicating the color of the shadow
@return void
@@ -652,7 +652,7 @@ function CGContextSetStrokeColor(aContext, aColor)
Fills a rounded rectangle.
@param aContext the CGContext to draw into
@param aRect the base rectangle
@param aRadius the distance from the rectange corner to the rounded corner
@param aRadius the distance from the rectangle corner to the rounded corner
@param ne set it to \c YES for a rounded northeast corner
@param se set it to \c YES for a rounded southeast corner
@param sw set it to \c YES for a rounded southwest corner
@@ -671,7 +671,7 @@ function CGContextFillRoundedRectangleInRect(aContext, aRect, aRadius, ne, se, s
Strokes a rounded rectangle.
@param aContext the CGContext to draw into
@param aRect the base rectangle
@param aRadius the distance from the rectange corner to the rounded corner
@param aRadius the distance from the rectangle corner to the rounded corner
@param ne set it to \c YES for a rounded northeast corner
@param se set it to \c YES for a rounded southeast corner
@param sw set it to \c YES for a rounded southwest corner
Binary file not shown.

Before

Width:  |  Height:  |  Size: 106 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 106 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 118 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 121 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 142 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 245 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 241 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 126 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 180 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 181 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 146 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 322 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 339 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 227 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 307 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.0 KiB

+10 -5
View File
@@ -804,6 +804,7 @@ var themedButtonValues = nil,
// Global for reuse by CPTokenField.
themedTextFieldValues =
[
[@"vertical-alignment", CPTopVerticalTextAlignment, CPThemeStateBezeled],
[@"bezel-color", bezelColor, CPThemeStateBezeled],
[@"bezel-color", bezelFocusedColor, CPThemeStateBezeled | CPThemeStateEditing],
[@"bezel-color", bezelDisabledColor, CPThemeStateBezeled | CPThemeStateDisabled],
@@ -821,8 +822,12 @@ var themedButtonValues = nil,
[@"content-inset", CGInsetMake(0.0, 0.0, 0.0, 5.0), CPThemeStateTableDataView],
[@"text-color", [CPColor colorWithCalibratedWhite:51.0 / 255.0 alpha:1.0], CPThemeStateTableDataView],
[@"text-color", [CPColor whiteColor], CPThemeStateTableDataView | CPThemeStateSelectedTableDataView],
[@"font", [CPFont boldSystemFontOfSize:12.0], CPThemeStateTableDataView | CPThemeStateSelectedTableDataView],
[@"text-color", [CPColor whiteColor], CPThemeStateTableDataView | CPThemeStateSelectedTableDataView],
[@"font", [CPFont boldSystemFontOfSize:12.0], CPThemeStateTableDataView | CPThemeStateSelectedTableDataView],
[@"text-color", [CPColor blackColor], CPThemeStateTableDataView | CPThemeStateEditing],
[@"content-inset", CGInsetMake(7.0, 7.0, 5.0, 8.0), CPThemeStateTableDataView | CPThemeStateEditing],
[@"font", [CPFont systemFontOfSize:12.0], CPThemeStateTableDataView | CPThemeStateEditing],
[@"bezel-inset", CGInsetMake(-2.0, -2.0, -2.0, -2.0), CPThemeStateTableDataView | CPThemeStateEditing],
[@"text-color", [CPColor colorWithCalibratedWhite:125.0 / 255.0 alpha:1.0], CPThemeStateTableDataView | CPThemeStateGroupRow],
[@"text-color", [CPColor colorWithCalibratedWhite:1.0 alpha:1.0], CPThemeStateTableDataView | CPThemeStateGroupRow | CPThemeStateSelectedTableDataView],
@@ -1447,9 +1452,9 @@ var themedButtonValues = nil,
alternatingRowColors = [[CPColor whiteColor], [CPColor colorWithRed:245.0 / 255.0 green:249.0 / 255.0 blue:252.0 / 255.0 alpha:1.0]],
gridColor = [CPColor colorWithHexString:@"dce0e2"],
selectionColor = [CPColor colorWithHexString:@"5f83b9"],
sourceListSelectionColor = [CPDictionary dictionaryWithObjects: [CGGradientCreateWithColorComponents(CGColorSpaceCreateDeviceRGB(), [89.0 / 255.0, 153.0 / 255.0, 209.0 / 255.0,1.0, 33.0 / 255.0, 94.0 / 255.0, 208.0 / 255.0,1.0], [0,1], 2),
[CPColor colorWithCalibratedRed:(61.0 / 255.0) green:(123.0 / 255.0) blue:(218.0 / 255.0) alpha:1.0],
[CPColor colorWithCalibratedRed:(31.0 / 255.0) green:(92.0 / 255.0) blue:(207.0 / 255.0) alpha:1.0]
sourceListSelectionColor = [CPDictionary dictionaryWithObjects: [CGGradientCreateWithColorComponents(CGColorSpaceCreateDeviceRGB(), [98.0 / 255.0, 143.0 / 210.0, 209.0 / 255.0, 1.0, 46.0 / 255.0, 88.0 / 176.0, 208.0 / 255.0,1.0], [0,1], 2),
[CPColor colorWithCalibratedRed:81.0/255.0 green:127.0/255.0 blue:200.0/255.0 alpha:1.0],
[CPColor colorWithCalibratedRed:34.0/255.0 green:63.0/255.0 blue:123.0/255.0 alpha:1.0]
]
forKeys: [CPSourceListGradient, CPSourceListTopLineColor, CPSourceListBottomLineColor]],
+15 -1
View File
@@ -175,6 +175,12 @@ var concat = Array.prototype.concat,
FORWARD_TO_CONCRETE_CLASS();
}
// FIXME: This should be defined in CPMutableArray, not here.
- (id)initWithCapacity:(unsigned)aCapacity
{
FORWARD_TO_CONCRETE_CLASS();
}
// Querying an array
/*!
Returns \c YES if the array contains \c anObject. Otherwise, it returns \c NO.
@@ -517,6 +523,14 @@ var concat = Array.prototype.concat,
objj_msgSend([self objectAtIndex:index], aSelector);
}
- (void)enumerateObjectsUsingBlock:(Function)aFunction
{
var index = 0,
count = [self count];
for (; index < count; ++index)
aFunction([self objectAtIndex:index], index);
}
// Comparing arrays
/*!
@@ -545,7 +559,7 @@ var concat = Array.prototype.concat,
}
/*!
Returns true if anArray contains exactly the same objects as the reciever.
Returns true if anArray contains exactly the same objects as the receiver.
*/
- (BOOL)isEqualToArray:(id)anArray
{
+6 -6
View File
@@ -29,10 +29,10 @@
Initializes an array able to store at least \c aCapacity items. Because CPArray
is backed by JavaScript arrays, this method ends up simply returning a regular array.
*/
- (id)initWithCapacity:(unsigned)aCapacity
/*- (id)initWithCapacity:(unsigned)aCapacity
{
return self;
}
}*/
// Adding and replacing objects
/*!
@@ -136,15 +136,15 @@
@param anIndexSet the set of indices to array positions that will be replaced
@param objects the array of objects to place in the specified indices
*/
- (void)replaceObjectsAtIndexes:(CPIndexSet)anIndexSet withObjects:(CPArray)objects
- (void)replaceObjectsAtIndexes:(CPIndexSet)indexes withObjects:(CPArray)objects
{
var i = 0,
index = [anIndexSet firstIndex];
index = [indexes firstIndex];
while (index !== CPNotFound)
{
[self replaceObjectAtIndex:index withObject:objects[i++]];
index = [anIndexSet indexGreaterThanIndex:index];
[self replaceObjectAtIndex:index withObject:[objects objectAtIndex:i++]];
index = [indexes indexGreaterThanIndex:index];
}
}
+12 -7
View File
@@ -41,14 +41,14 @@ var concat = Array.prototype.concat,
- (id)initWithArray:(CPArray)anArray copyItems:(BOOL)shouldCopyItems
{
if (!shouldCopyItems && anArray.isa === _CPJavaScriptArray)
if (!shouldCopyItems && [anArray isKindOfClass:_CPJavaScriptArray])
return slice.call(anArray, 0);
self = [super init];
var index = 0;
if (anArray.isa === _CPJavaScriptArray)
if ([anArray isKindOfClass:_CPJavaScriptArray])
{
// If we're this far, shouldCopyItems must be YES.
var count = anArray.length;
@@ -90,7 +90,7 @@ var concat = Array.prototype.concat,
- (id)initWithObjects:(CPArray)objects count:(CPUInteger)aCount
{
if (objects.isa === _CPJavaScriptArray)
if ([objects isKindOfClass:_CPJavaScriptArray])
return slice.call(objects, 0);
var array = [],
@@ -102,6 +102,11 @@ var concat = Array.prototype.concat,
return array;
}
- (id)initWithCapacity:(CPUInteger)aCapacity
{
return self;
}
- (BOOL)count
{
return self.length;
@@ -176,7 +181,7 @@ var concat = Array.prototype.concat,
- (CPArray)arrayByAddingObject:(id)anObject
{
// concat flattens arrays, so wrap it in an *additional* array if anObject is an array itself.
if ([anObject isKindOfClass:CPArray])
if (anObject && anObject.isa && [anObject isKindOfClass:_CPJavaScriptArray])
return concat.call(self, [anObject]);
return concat.call(self, anObject);
@@ -187,7 +192,7 @@ var concat = Array.prototype.concat,
if (!anArray)
return [self copy];
return concat.call(self, anArray.isa === _CPJavaScriptArray ? anArray : [anArray _javaScriptArrayCopy]);
return concat.call(self, [anArray isKindOfClass:_CPJavaScriptArray] ? anArray : [anArray _javaScriptArrayCopy]);
}
- (CPArray)subarrayWithRange:(CPRange)aRange
@@ -251,7 +256,7 @@ var concat = Array.prototype.concat,
- (void)setArray:(CPArray)anArray
{
if (anArray.isa === _CPJavaScriptArray)
if ([anArray isKindOfClass:_CPJavaScriptArray])
splice.apply(self, [0, self.length].concat(anArray));
else
@@ -260,7 +265,7 @@ var concat = Array.prototype.concat,
- (void)addObjectsFromArray:(CPArray)anArray
{
if (anArray.isa === _CPJavaScriptArray)
if ([anArray isKindOfClass:_CPJavaScriptArray])
splice.apply(self, [self.length, 0].concat(anArray));
else
+5 -4
View File
@@ -20,19 +20,20 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@import "CPArray.j"
@import "CPDictionary.j"
@import "CPException.j"
@import "CPObject.j"
@import "CPRange.j"
@import "CPString.j"
/*!
@class CPAttributedString
@ingroup foundation
@brief A mutable character string with attributes.
A character string with sets of attributes that apply to single or ranges of
characters. The attributes are containted within a CPDictionary class.
characters. The attributes are contained within a CPDictionary class.
Attributes can be any name/value pair. The data type of the value is not
restricted.
This class is mutable.
@@ -794,11 +795,11 @@
/*!
@class CPMutableAttributedString
@ingroup compatability
@ingroup compatibility
This class is just an empty subclass of CPAttributedString.
CPAttributedString already implements mutable methods and
this class only exists for source compatability.
this class only exists for source compatibility.
*/
@implementation CPMutableAttributedString : CPAttributedString
+2 -3
View File
@@ -21,12 +21,11 @@
*/
@import "CPDictionary.j"
@import "CPObject.j"
@import "CPNotification.j"
@import "CPNotificationCenter.j"
@import "CPObject.j"
CPBundleDidLoadNotification = "CPBundleDidLoadNotification";
CPBundleDidLoadNotification = @"CPBundleDidLoadNotification";
/*!
@class CPBundle
+33 -20
View File
@@ -19,8 +19,11 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@import <Foundation/CPObject.j>
@import <Foundation/CPString.j>
@import "CPArray.j"
@import "CPException.j"
@import "CPObject.j"
@import "CPString.j"
@import "CPURL.j"
// CPCharacterSet is a class cluster. Concrete implementations
// follow after the main abstract class.
@@ -48,7 +51,9 @@ var _builtInCharacterSets = {};
- (id)init
{
self = [super init];
_inverted = NO;
if (self)
_inverted = NO;
return self;
}
@@ -144,11 +149,11 @@ var _builtInCharacterSets = {};
var cs = _builtInCharacterSets[csname];
if (cs == nil)
{
var i,
var i = 0,
ranges = [CPArray array],
rangeArray = eval(csname);
for (i = 0; i < rangeArray.length; i+= 2)
for (; i < rangeArray.length; i+= 2)
{
var loc = rangeArray[i],
length = rangeArray[i + 1],
@@ -185,7 +190,9 @@ var _builtInCharacterSets = {};
// Creates a range character set with multiple ranges.
- (id)initWithRanges:(CPArray)ranges
{
if (self = [super init])
self = [super init];
if (self)
{
_ranges = ranges;
}
@@ -224,9 +231,10 @@ var _builtInCharacterSets = {};
- (BOOL)hasMemberInPlane:(int)plane // TO DO : when inverted
{
// FIXME: range is undefined... don't know what's supposed to be going on here.
// the highest Unicode plane we reach.
// (There are 65536 code points in each plane.)
var maxPlane = Math.floor((range.start + range.length - 1) / 65536); // should iterate _ranges
var maxPlane = Math.floor((range.start + range.length - 1) / 65536); // FIXME: should iterate _ranges
return (plane <= maxPlane);
}
@@ -238,9 +246,9 @@ var _builtInCharacterSets = {};
- (void)addCharactersInString:(CPString)aString // Needs _inverted support
{
var i;
var i = 0;
for (i = 0; i < aString.length; i++)
for (; i < aString.length; i++)
{
var code = aString.charCodeAt(i),
range = CPMakeRange(code,1);
@@ -260,7 +268,9 @@ var _builtInCharacterSets = {};
- (id)initWithString:(CPString)s
{
if (self = [super init])
self = [super init];
if (self)
{
_string = s;
}
@@ -307,8 +317,10 @@ var _builtInCharacterSets = {};
- (void)addCharactersInRange:(CPRange)aRange // Needs _inverted support
{
var i;
for (i = aRange.location; i < aRange.location + aRange.length; i++)
var i = aRange.location,
count = aRange.location + aRange.length;
for (; i < count; i++)
{
var s = String.fromCharCode(i);
@@ -319,9 +331,9 @@ var _builtInCharacterSets = {};
- (void)addCharactersInString:(CPString)aString // Needs _inverted support
{
var i;
var i = 0;
for (i = 0; i < aString.length; i++)
for (; i < aString.length; i++)
{
var s = aString.charAt(i);
@@ -332,19 +344,19 @@ var _builtInCharacterSets = {};
@end
_CPCharacterSetTrimAtBeginning = 1 << 1;
_CPCharacterSetTrimAtEnd = 1 << 2;
_CPCharacterSetTrimAtBeginning = 1 << 1;
_CPCharacterSetTrimAtEnd = 1 << 2;
@implementation CPString (CPCharacterSetAdditions)
/*!
Tokenizes the receiver string using the charactes
Tokenizes the receiver string using the characters
in a given set. For example, if the receiver is:
\c "Baku baku to jest skład."
and the set is [CPCharacterSet whitespaceCharacterSet]
the returned array would contain:
<pre> ["Baku", "baku", "to", "jest", "", "skład."] </pre>
Adjacent occurences of the separator characters produce empty strings in the result.
Adjacent occurrences of the separator characters produce empty strings in the result.
@author Arkadiusz Młynarczyk <arek@tupux.com>
@param A character set containing the characters to use to split the receiver. Must not be nil.
@return An CPArray object containing substrings from the receiver that have been divided by characters in separator.
@@ -356,9 +368,10 @@ _CPCharacterSetTrimAtEnd = 1 << 2;
reason:"componentsSeparatedByCharactersInSet: the separator can't be 'nil'"];
var components = [CPMutableArray array],
componentRange = CPMakeRange(0, 0);
componentRange = CPMakeRange(0, 0),
i = 0;
for (var i = 0; i < self.length; i++)
for (; i < self.length; i++)
{
if ([separator characterIsMember:self.charAt(i)])
{
+1 -2
View File
@@ -23,7 +23,6 @@
@import "CPException.j"
@import "CPObject.j"
/*!
@class CPCoder
@ingroup foundation
@@ -147,7 +146,7 @@
/*!
Called after an object is unarchived in case a different object should be used in place of it.
The defaut method returns \c self. Interested subclasses should override this.
The default method returns \c self. Interested subclasses should override this.
@param aDecoder
@return the original object or it's substitute.
*/
+1 -1
View File
@@ -20,9 +20,9 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@import "CPObject.j"
@import "CPSet.j"
/*!
@class CPCountedSet
@ingroup foundation
-1
View File
@@ -23,7 +23,6 @@
@import "CPObject.j"
@import "CPString.j"
/*!
@class CPData
@ingroup foundation
+1 -1
View File
@@ -22,7 +22,7 @@
@import "CPObject.j"
@import "CPString.j"
@import "CPException.j"
var CPDateReferenceDate = new Date(Date.UTC(2001, 1, 1, 0, 0, 0, 0));
+107 -78
View File
@@ -102,7 +102,7 @@ CPDecimal format:
function CPDecimalMakeWithString(string, locale)
{
if (!string)
return CPDecimalMakeZero();
return CPDecimalMakeNaN();
// Regexp solution as found in JSON spec, with working regexp (I added groupings)
// Test here: http://www.regexplanet.com/simple/index.html
@@ -112,11 +112,11 @@ function CPDecimalMakeWithString(string, locale)
// (?:[eE]([+\-]?)(\d+))? - optional exponent part plus number in group
// group 0: string, 1: sign, 2: integer, 3: decimal, 4: exponent sign, 5: exponent
// Note: this doesnt accept .01 for example, should it?
// If yes simply add '?' after integer part group, ie ([+\-]?)((?:0|[1-9]\d*)?)
// Note: this doesn't accept .01 for example, should it?
// If yes simply add '?' after integer part group, i.e. ([+\-]?)((?:0|[1-9]\d*)?)
var matches = string.match(/^([+\-]?)((?:0|[1-9]\d*))(?:\.(\d*))?(?:[eE]([+\-]?)(\d+))?$/);
if (!matches)
return nil;
return CPDecimalMakeNaN();
var ds = matches[1],
intpart = matches[2],
@@ -143,23 +143,23 @@ function CPDecimalMakeWithString(string, locale)
}
if (exponent > CPDecimalMaxExponent || exponent < CPDecimalMinExponent)
return nil;
return CPDecimalMakeNaN();
// Representation internally starts at most significant digit
var m = [CPArray array],
var m = [],
i = 0;
for (; i < (intpart?intpart.length:0); i++)
{
if (i >= CPDecimalMaxDigits)
break; // truncate
[m addObject:parseInt(intpart.charAt(i))];
Array.prototype.push.call(m, parseInt(intpart.charAt(i)));
}
var j = 0;
for (; j < (decpart?decpart.length:0); j++)
{
if ((i + j) >= CPDecimalMaxDigits)
break; // truncate
[m addObject:parseInt(decpart.charAt(j))];
Array.prototype.push.call(m, parseInt(decpart.charAt(j)));
}
var dcm = {_exponent:exponent, _isNegative:isNegative, _isCompact:NO, _isNaN:NO, _mantissa:m};
@@ -170,14 +170,14 @@ function CPDecimalMakeWithString(string, locale)
/*!
@ingroup foundation
Creates a CPDecimal object from a given matissa and exponent. The sign is taken from the sign of the mantissa. This cant do a full 34 digit mantissa representation as JS's 32 bits or 64bit binary FP numbers cant represent that. So use the CPDecimalMakeWithString if you want longer mantissa.
Creates a CPDecimal object from a given mantissa and exponent. The sign is taken from the sign of the mantissa. This cant do a full 34 digit mantissa representation as JS's 32 bits or 64bit binary FP numbers cant represent that. So use the CPDecimalMakeWithString if you want longer mantissa.
@param mantissa the mantissa (though see above note)
@param exponent the exponent
@return A CPDecimal object, or nil on error.
*/
function CPDecimalMakeWithParts(mantissa, exponent)
{
var m = [CPArray array],
var m = [],
isNegative = NO;
if (mantissa < 0 )
@@ -187,15 +187,15 @@ function CPDecimalMakeWithParts(mantissa, exponent)
}
if (mantissa == 0)
[m addObject: 0];
Array.prototype.push.call(m, 0);
if (exponent > CPDecimalMaxExponent || exponent < CPDecimalMinExponent)
return nil;
return CPDecimalMakeNaN();
// remaining digits are disposed of via truncation
while ((mantissa > 0) && ([m count] < CPDecimalMaxDigits)) // count selector here could be optimised away
while ((mantissa > 0) && (m.length < CPDecimalMaxDigits)) // count selector here could be optimised away
{
[m insertObject:parseInt(mantissa % 10) atIndex:0];
Array.prototype.unshift.call(m, parseInt(mantissa % 10));
mantissa = FLOOR(mantissa / 10);
}
@@ -239,6 +239,27 @@ function CPDecimalMakeNaN()
return d;
}
// private methods
function _CPDecimalMakeMaximum()
{
var s = @"",
i = 0;
for (; i < CPDecimalMaxDigits; i++)
s += "9";
s += "e" + CPDecimalMaxExponent;
return CPDecimalMakeWithString(s);
}
function _CPDecimalMakeMinimum()
{
var s = @"-",
i = 0;
for (; i < CPDecimalMaxDigits; i++)
s += "9";
s += "e" + CPDecimalMaxExponent;
return CPDecimalMakeWithString(s);
}
/*!
@ingroup foundation
Checks to see if a CPDecimal is zero. Can handle uncompacted strings.
@@ -246,7 +267,7 @@ function CPDecimalMakeNaN()
*/
function CPDecimalIsZero(dcm)
{
// exponent doesnt matter as long as mantissa = 0
// exponent doesn't matter as long as mantissa = 0
if (!dcm._isNaN)
{
for (var i = 0; i < dcm._mantissa.length; i++)
@@ -267,10 +288,10 @@ function CPDecimalIsZero(dcm)
function CPDecimalIsOne(dcm)
{
CPDecimalCompact(dcm);
// exponent doesnt matter as long as mantissa = 0
// exponent doesn't matter as long as mantissa = 0
if (!dcm._isNaN)
{
if (dcm._mantissa && ([dcm._mantissa count] == 1) && (dcm._mantissa[0] == 1))
if (dcm._mantissa && (dcm._mantissa.length == 1) && (dcm._mantissa[0] == 1))
return YES;
}
return NO;
@@ -284,12 +305,12 @@ function _CPDecimalSet(t,s)
t._isNegative = s._isNegative;
t._isCompact = s._isCompact;
t._isNaN = s._isNaN;
t._mantissa = [s._mantissa copy];
t._mantissa = Array.prototype.slice.call(s._mantissa, 0);
}
function _CPDecimalSetZero(result)
{
result._mantissa = [CPArray arrayWithObject:0];
result._mantissa = [0];
result._exponent = 0;
result._isNegative = NO;
result._isCompact = YES;
@@ -298,7 +319,7 @@ function _CPDecimalSetZero(result)
function _CPDecimalSetOne(result)
{
result._mantissa = [CPArray arrayWithObject:1];
result._mantissa = [1];
result._exponent = 0;
result._isNegative = NO;
result._isCompact = YES;
@@ -327,13 +348,13 @@ function CPDecimalCopy(dcm)
_isNegative:dcm._isNegative,
_isCompact:dcm._isCompact,
_isNaN:dcm._isNaN,
_mantissa:[dcm._mantissa copy]
_mantissa:Array.prototype.slice.call(dcm._mantissa, 0)
};
}
/*!
@ingroup foundation
Compare two CPDecimal objects. Order is left to right (ie Ascending would
Compare two CPDecimal objects. Order is left to right (i.e. Ascending would
mean left is smaller than right operand).
@param leftOperand the left CPDecimal
@param rightOperand the right CPDecimal
@@ -341,6 +362,9 @@ function CPDecimalCopy(dcm)
*/
function CPDecimalCompare(leftOperand, rightOperand)
{
if (leftOperand._isNaN && rightOperand._isNaN)
return CPOrderedSame;
if (leftOperand._isNegative != rightOperand._isNegative)
{
if (rightOperand._isNegative)
@@ -349,8 +373,8 @@ function CPDecimalCompare(leftOperand, rightOperand)
return CPOrderedAscending;
}
var s1 = leftOperand._exponent + [leftOperand._mantissa count],
s2 = rightOperand._exponent + [rightOperand._mantissa count];
var s1 = leftOperand._exponent + leftOperand._mantissa.length,
s2 = rightOperand._exponent + rightOperand._mantissa.length;
// Sign is the same, quick check size (length + exp)
if (s1 < s2)
@@ -369,7 +393,7 @@ function CPDecimalCompare(leftOperand, rightOperand)
}
// Same size, so check mantissa
var l = MIN([leftOperand._mantissa count], [rightOperand._mantissa count]),
var l = MIN(leftOperand._mantissa.length, rightOperand._mantissa.length),
i = 0;
for (; i < l; i++)
@@ -393,14 +417,14 @@ function CPDecimalCompare(leftOperand, rightOperand)
}
// Same digits, check length
if ([leftOperand._mantissa count] > [rightOperand._mantissa count])
if (leftOperand._mantissa.length > rightOperand._mantissa.length)
{
if (rightOperand._isNegative)
return CPOrderedAscending;
else
return CPOrderedDescending;
}
if ([leftOperand._mantissa count] < [rightOperand._mantissa count])
if (leftOperand._mantissa.length < rightOperand._mantissa.length)
{
if (rightOperand._isNegative)
return CPOrderedDescending;
@@ -420,8 +444,8 @@ function _SimpleAdd(result, leftOperand, rightOperand, roundingMode, longMode)
_CPDecimalSet(result, leftOperand);
var j = [leftOperand._mantissa count] - [rightOperand._mantissa count],
l = [rightOperand._mantissa count],
var j = leftOperand._mantissa.length - rightOperand._mantissa.length,
l = rightOperand._mantissa.length,
i = l - 1,
carry = 0,
error = CPCalculationNoError;
@@ -443,7 +467,7 @@ function _SimpleAdd(result, leftOperand, rightOperand, roundingMode, longMode)
if (carry)
{
for (i = j-1; i >= 0; i--)
for (i = j - 1; i >= 0; i--)
{
if (result._mantissa[i] != 9)
{
@@ -456,13 +480,13 @@ function _SimpleAdd(result, leftOperand, rightOperand, roundingMode, longMode)
if (carry)
{
[result._mantissa insertObject:1 atIndex:0];
Array.prototype.splice.call(result._mantissa, 0, 0, 1);
// The number must be shifted to the right
if ((CPDecimalMaxDigits * factor) == [leftOperand._mantissa count])
if ((CPDecimalMaxDigits * factor) == leftOperand._mantissa.length)
{
var scale = - result._exponent - 1;
CPDecimalRound(result, result,scale,roundingMode);
CPDecimalRound(result, result, scale, roundingMode);
}
if (CPDecimalMaxExponent < result._exponent)
@@ -524,10 +548,10 @@ function CPDecimalAdd(result, leftOperand, rightOperand, roundingMode, longMode)
var normerror = CPDecimalNormalize(n1, n2, roundingMode, longMode);
// below is equiv of simple compare
// below is equiv. of simple compare
var comp = 0,
ll = [n1._mantissa count],
lr = [n2._mantissa count];
ll = n1._mantissa.length,
lr = n2._mantissa.length;
if (ll == lr)
comp = CPOrderedSame;
else if (ll > lr)
@@ -581,8 +605,8 @@ function _SimpleSubtract(result, leftOperand, rightOperand, roundingMode)
{
var error = CPCalculationNoError,
borrow = 0,
l = [rightOperand._mantissa count],
j = [leftOperand._mantissa count] - l,
l = rightOperand._mantissa.length,
j = leftOperand._mantissa.length - l,
i = l - 1;
_CPDecimalSet(result, leftOperand);
@@ -604,7 +628,7 @@ function _SimpleSubtract(result, leftOperand, rightOperand, roundingMode)
if (borrow)
{
for (i = j-1; i >= 0; i--)
for (i = j - 1; i >= 0; i--)
{
if (result._mantissa[i] != 0)
{
@@ -735,10 +759,10 @@ function _SimpleDivide(result, leftOperand, rightOperand, roundingMode)
_CPDecimalSetZero(result);
n1._mantissa = [CPArray array];
n1._mantissa = [];
while ((k < [leftOperand._mantissa count]) || ([n1._mantissa count]
&& !(([n1._mantissa count] == 1) && (n1._mantissa[0] == 0))))
while ((k < leftOperand._mantissa.length) || (n1._mantissa.length
&& !((n1._mantissa.length == 1) && (n1._mantissa[0] == 0))))
{
while (CPOrderedAscending == CPDecimalCompare(n1, rightOperand))
{
@@ -747,19 +771,19 @@ function _SimpleDivide(result, leftOperand, rightOperand, roundingMode)
if (n1._exponent)
{
// Put back zeros removed by compacting
[n1._mantissa addObject:0];
Array.prototype.push.call(n1._mantissa, 0);
n1._exponent--;
n1._isCompact = NO;
}
else
{
if (used < [leftOperand._mantissa count])
if (used < leftOperand._mantissa.length)
{
// Fill up with own digits
if ([n1._mantissa count] || leftOperand._mantissa[used])
if (n1._mantissa.length || leftOperand._mantissa[used])
{
// only add 0 if there is already something
[n1._mantissa addObject:(leftOperand._mantissa[used])];
Array.prototype.push.call(n1._mantissa, (leftOperand._mantissa[used]));
n1._isCompact = NO;
}
used++;
@@ -773,15 +797,15 @@ function _SimpleDivide(result, leftOperand, rightOperand, roundingMode)
break;
}
// Borrow one digit
[n1._mantissa addObject:0];
Array.prototype.push.call(n1._mantissa, 0);
result._exponent--;
}
// Zeros must be added while enough digits are fetched to do the
// subtraction, but first time round this just add zeros at the
// start of the number , increases k, and hence reduces
// the avaialble precision. To solve this only inc k/add zeros if
// this isnt first time round.
// the available precision. To solve this only inc k/add zeros if
// this isn't first time round.
if (!firsttime)
{
k++;
@@ -886,7 +910,7 @@ function CPDecimalDivide(result, leftOperand, rightOperand, roundingMode)
return error;
}
// Simple multiply O(n^2) , replace with something faster, likee divide-n-conquer algo?
// Simple multiply O(n^2) , replace with something faster, like divide-n-conquer algo?
function _SimpleMultiply(result, leftOperand, rightOperand, roundingMode, powerMode)
{
var error = CPCalculationNoError,
@@ -898,11 +922,11 @@ function _SimpleMultiply(result, leftOperand, rightOperand, roundingMode, powerM
// Do every digit of the second number
var i = 0;
for (; i < [rightOperand._mantissa count]; i++)
for (; i < rightOperand._mantissa.length; i++)
{
_CPDecimalSetZero(n);
n._exponent = [rightOperand._mantissa count] - i - 1;
n._exponent = rightOperand._mantissa.length - i - 1;
carry = 0;
d = rightOperand._mantissa[i];
@@ -910,7 +934,7 @@ function _SimpleMultiply(result, leftOperand, rightOperand, roundingMode, powerM
continue;
var j = 0;
for (j = [leftOperand._mantissa count]-1; j >= 0; j--)
for (j = leftOperand._mantissa.length - 1; j >= 0; j--)
{
e = leftOperand._mantissa[j] * d + carry;
if (e >= 10)
@@ -943,11 +967,11 @@ function _SimpleMultiply(result, leftOperand, rightOperand, roundingMode, powerM
result._exponent += exp;
// perform round to CPDecimalMaxDigits
if ([result._mantissa count] > CPDecimalMaxDigits && !powerMode)
if (result._mantissa.length > CPDecimalMaxDigits && !powerMode)
{
result._isCompact = NO;
var scale = CPDecimalMaxDigits - ([result._mantissa count] + result._exponent);
CPDecimalRound(result, result, scale ,roundingMode); // calls compact
var scale = CPDecimalMaxDigits - (result._mantissa.length + result._exponent);
CPDecimalRound(result, result, scale, roundingMode); // calls compact
error = CPCalculationLossOfPrecision;
}
@@ -1001,10 +1025,10 @@ function CPDecimalMultiply(result, leftOperand, rightOperand, roundingMode, powe
n1._isNegative = NO;
n2._isNegative = NO;
// below is equiv of simple compare
// below is equiv. of simple compare
var comp = 0,
ll = [n1._mantissa count],
lr = [n2._mantissa count];
ll = n1._mantissa.length,
lr = n2._mantissa.length;
if (ll == lr)
comp = CPOrderedSame;
else if (ll > lr)
@@ -1133,7 +1157,7 @@ function CPDecimalPower(result, dcm, power, roundingMode)
/*!
@ingroup foundation
Normalises 2 CPDecimals. Normalisation is the process of modifying a
numbers manitssa to ensure that both CPDecimals have the same exponent.
numbers mantissa to ensure that both CPDecimals have the same exponent.
@param dcm1 the first CPDecimal
@param dcm2 the second CPDecimal
@param roundingMode the rounding mode for the operation
@@ -1159,8 +1183,8 @@ function CPDecimalNormalize(dcm1, dcm2, roundingMode, longMode)
e2 = dcm2._exponent;
// Add zeros
var l2 = [dcm2._mantissa count],
l1 = [dcm1._mantissa count],
var l2 = dcm2._mantissa.length,
l1 = dcm1._mantissa.length,
l = 0;
var e = 0;
@@ -1178,16 +1202,16 @@ function CPDecimalNormalize(dcm1, dcm2, roundingMode, longMode)
e = e1 - e2;
if (e2 > e1)
l = MIN((CPDecimalMaxDigits*factor) - l2, e); //(e2 - e1));
l = MIN((CPDecimalMaxDigits * factor) - l2, e); //(e2 - e1));
else
l = MIN((CPDecimalMaxDigits*factor) - l1, e); //(e1 - e2));
l = MIN((CPDecimalMaxDigits * factor) - l1, e); //(e1 - e2));
for (var i = 0; i < l; i++)
{
if (e2 > e1)
[dcm2._mantissa addObject:0]; //dcm2._mantissa[i + l2] = 0;
Array.prototype.push.call(dcm2._mantissa, 0); //dcm2._mantissa[i + l2] = 0;
else
[dcm1._mantissa addObject:0];
Array.prototype.push.call(dcm1._mantissa, 0);
}
if (e2 > e1)
{
@@ -1222,7 +1246,7 @@ function CPDecimalNormalize(dcm1, dcm2, roundingMode, longMode)
// Some zeros where cut of again by compacting
if (e2 > e1)
{
l1 = [dcm1._mantissa count];
l1 = dcm1._mantissa.length;
l = MIN((CPDecimalMaxDigits * factor) - l1, ABS(dcm1._exponent - dcm2._exponent));
for (var i = 0; i < l; i++)
{
@@ -1233,7 +1257,7 @@ function CPDecimalNormalize(dcm1, dcm2, roundingMode, longMode)
}
else
{
l2 = [dcm2._mantissa count];
l2 = dcm2._mantissa.length;
l = MIN((CPDecimalMaxDigits * factor) - l2, ABS(dcm2._exponent - dcm1._exponent));
for (var i = 0; i < l; i++)
{
@@ -1277,7 +1301,7 @@ function CPDecimalRound(result, dcm, scale ,roundingMode)
_CPDecimalSet(result,dcm);
var mc = [result._mantissa count],
var mc = result._mantissa.length,
l = mc + scale + result._exponent;
if (mc <= l)
@@ -1326,7 +1350,7 @@ function CPDecimalRound(result, dcm, scale ,roundingMode)
break;
}
// cut mantissa
result._mantissa = [result._mantissa subarrayWithRange:CPMakeRange(0, l)];
result._mantissa = Array.prototype.slice.call(result._mantissa, 0, l);
if (up)
{
@@ -1349,7 +1373,7 @@ function CPDecimalRound(result, dcm, scale ,roundingMode)
// Overflow in rounding.
// Add one zero add the end. There must be space as
// we just cut off some digits.
[result._mantissa addObject:0];
Array.prototype.push.call(result._mantissa, 0);
}
else
result._exponent++;
@@ -1368,7 +1392,7 @@ function CPDecimalRound(result, dcm, scale ,roundingMode)
function CPDecimalCompact(dcm)
{
// if positive or zero exp leading zeros simply delete, trailing ones u need to increment exponent
if (!dcm || [dcm._mantissa count] == 0 || CPDecimalIsNotANumber(dcm) )
if (!dcm || dcm._mantissa.length == 0 || CPDecimalIsNotANumber(dcm) )
return;
@@ -1379,20 +1403,20 @@ function CPDecimalCompact(dcm)
return;
}
// leading zeros, when exponent is zero these mean we need to move our decimal point to compact
// if exp is zero does it make sense to have them? dont think so so delete them
// if exp is zero does it make sense to have them? don't think so so delete them
while (dcm._mantissa[0] === 0)
{
[dcm._mantissa removeObjectAtIndex:0];
Array.prototype.shift.call(dcm._mantissa);
}
// trailing zeros, strip them
while ([dcm._mantissa lastObject] === 0)
while (dcm._mantissa[dcm._mantissa.length - 1] === 0)
{
[dcm._mantissa removeLastObject];
Array.prototype.pop.call(dcm._mantissa);
dcm._exponent++;
if (dcm._exponent + 1 > CPDecimalMaxExponent)
{
// TODO: test case for this
// overflow if we compact anymore, so dont
// overflow if we compact anymore, so don't
break;
}
}
@@ -1411,13 +1435,18 @@ function CPDecimalString(dcm, locale)
{
// Cocoa seems to just add all the zeros... this maybe controlled by locale,
// will check.
if (dcm._isNaN)
return @"NaN";
var string = @"",
i = 0;
if (dcm._isNegative)
string += "-";
var k = [dcm._mantissa count],
var k = dcm._mantissa.length,
l = ((dcm._exponent < 0) ? dcm._exponent : 0) + k;
if (l < 0)
{
// add leading zeros
File diff suppressed because it is too large Load Diff
+4 -4
View File
@@ -23,9 +23,9 @@
@import "CPArray.j"
@import "CPEnumerator.j"
@import "CPException.j"
@import "CPNull.j"
@import "CPObject.j"
/* @ignore */
@implementation _CPDictionaryValueEnumerator : CPEnumerator
{
@@ -345,7 +345,7 @@
@return A new array containing the keys corresponding to all occurrences of anObject in the receiver. If no object matching anObject is found, returns an empty array.
Each object in the receiver is sent an isEqual: message to determine if it's equal to anObject.
If the check for isEqual fails a check is made to see if the two objects are the same object. This provides compatability for JSObjects.
If the check for isEqual fails a check is made to see if the two objects are the same object. This provides compatibility for JSObjects.
*/
- (CPArray)allKeysForObject:(id)anObject
{
@@ -594,11 +594,11 @@
/*!
@class CPMutableDictionary
@ingroup compatability
@ingroup compatibility
This class is just an empty subclass of CPDictionary.
CPDictionary already implements mutable methods and
this class only exists for source compatability.
this class only exists for source compatibility.
*/
@implementation CPMutableDictionary : CPDictionary
-1
View File
@@ -22,7 +22,6 @@
@import "CPObject.j"
/*!
@class CPEnumerator
@ingroup foundation
+10 -9
View File
@@ -24,11 +24,10 @@
@import "CPObject.j"
@import "CPString.j"
CPInvalidArgumentException = "CPInvalidArgumentException";
CPUnsupportedMethodException = "CPUnsupportedMethodException";
CPRangeException = "CPRangeException";
CPInternalInconsistencyException = "CPInternalInconsistencyException";
CPInvalidArgumentException = @"CPInvalidArgumentException";
CPUnsupportedMethodException = @"CPUnsupportedMethodException";
CPRangeException = @"CPRangeException";
CPInternalInconsistencyException = @"CPInternalInconsistencyException";
/*!
@class CPException
@@ -90,7 +89,9 @@ if (input == nil)
*/
- (id)initWithName:(CPString)aName reason:(CPString)aReason userInfo:(CPDictionary)aUserInfo
{
if (self = [super init])
self = [super init];
if (self)
{
name = aName;
message = aReason;
@@ -162,9 +163,9 @@ if (input == nil)
@end
var CPExceptionNameKey = "CPExceptionNameKey",
CPExceptionReasonKey = "CPExceptionReasonKey",
CPExceptionUserInfoKey = "CPExceptionUserInfoKey";
var CPExceptionNameKey = @"CPExceptionNameKey",
CPExceptionReasonKey = @"CPExceptionReasonKey",
CPExceptionUserInfoKey = @"CPExceptionUserInfoKey";
@implementation CPException (CPCoding)
+4 -9
View File
@@ -36,7 +36,6 @@
@import "CPException.j"
@import "CPObject.j"
@implementation CPFormatter : CPObject
/*!
@@ -57,13 +56,11 @@
return nil;
}
/*- (CPAttributedString)attributedStringForObjectValue:(id)anObject withDefaultAttributes:(CPDictionary)attributes
{
}*/
/*!
The default implementation of this method invokes stringForObjectValue:.
@@ -73,14 +70,13 @@
this method if you want the dollar signs in displayed strings removed for editing.
@param anObject the object for which to return an editing string
@return CPString object that is used for editing the textual represntation of an object
@return CPString object that is used for editing the textual representation of an object
*/
- (CPString)editingStringForObjectValue:(id)anObject
{
return [self stringForObjectValue:anObject];
}
/*!
The default implementation of this method raises an exception.
@@ -93,7 +89,7 @@
@param anObject if conversion is successful, upon return contains the object created from the string
@param aString the string to parse.
@param anError if non-nil, if there is an error durring the conversion, upon return contains an CPString object that describes the problem.
@param anError if non-nil, if there is an error during the conversion, upon return contains an CPString object that describes the problem.
@return BOOL YES if the conversion from the string to a view content object was successful, otherwise NO.
*/
- (BOOL)getObjectValue:(id)anObject forString:(CPString)aString errorDescription:(CPString)anError
@@ -102,7 +98,6 @@
return NO;
}
/*!
Returns a Boolean value that indicates whether a partial string is valid.
@@ -122,7 +117,7 @@
@param aPartialString the text currently in the view.
@param aNewString if aPartialString needs to be modified, upon return contains the replacement string.
@param anError if non-nil, if validation fails contains a CPString object that desibes the problem.
@param anError if non-nil, if validation fails contains a CPString object that describes the problem.
@return YES if aPartialString is an acceptable value, otherwise NO.
*/
- (BOOL)isPartialStringValid:(CPString)aPartialString newEditingString:(CPString)aNewString errorDescription:(CPString)anError
@@ -146,7 +141,7 @@
@param aProposedSelectedRange The selection range that will be used if the string is accepted or replaced.
@param originalString The original string, before the proposed change.
@param originalSelectedRange The selection range over which the change is to take place.
@param error If non-nil, if validation fails contains an CPString object that descibes the problem.
@param error If non-nil, if validation fails contains an CPString object that describes the problem.
@return YES if aPartialString is acceptable, otherwise NO.
*/
+5 -4
View File
@@ -19,10 +19,10 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@import <Foundation/CPObject.j>
@import "CPArray.j"
@import "CPObject.j"
@import "CPOperation.j"
/*!
@class CPFunctionOperation
@brief Represents an operation using a JavaScript function that can be run in an CPOperationQueue
@@ -32,7 +32,6 @@
CPArray _functions;
}
- (void)main
{
if (_functions && [_functions count] > 0)
@@ -50,7 +49,9 @@
- (id)init
{
if (self = [super init])
self = [super init];
if (self)
{
_functions = [];
}
+22 -3
View File
@@ -1,10 +1,29 @@
/*
* CPIndexPath.j
* Foundation
*
* Copyright 2008, 280 North, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@import "CPObject.j"
@import "CPArray.j"
@import "CPException.j"
@import "CPObject.j"
@import "CPRange.j"
@import "CPSortDescriptor.j"
@import "CPException.j"
@implementation CPIndexPath : CPObject
{
+7 -7
View File
@@ -20,10 +20,10 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@import "CPArray.j"
@import "CPObject.j"
@import "CPRange.j"
#define _CPMaxRange(aRange) ((aRange).location + (aRange).length)
#define _CPMakeRange(aLocation, aLength) { location:(aLocation), length:aLength }
#define _CPMakeRangeCopy(aRange) { location:(aRange).location, length:(aRange).length }
@@ -159,7 +159,7 @@
var rangesCount = _ranges.length,
otherRanges = anIndexSet._ranges;
// If we have a discrepency in the number of ranges or the number of indexes,
// If we have a discrepancy in the number of ranges or the number of indexes,
// simply return NO.
if (rangesCount !== otherRanges.length || _count !== anIndexSet._count)
return NO;
@@ -215,7 +215,7 @@
}
/*!
Returns \c YES if the receving index set contains all the indices in the argument.
Returns \c YES if the receiving index set contains all the indices in the argument.
@param anIndexSet the set of indices to check for in the receiving index set
*/
- (BOOL)containsIndexes:(CPIndexSet)anIndexSet
@@ -836,7 +836,7 @@ var CPIndexSetCountKey = @"CPIndexSetCountKey",
/*!
Creates a deep copy of the index set. The returned copy
is mutable. The reason for the two copy methods is for
source compatability with GNUStep code.
source compatibility with GNUStep code.
@return the index set copy
*/
- (id)copy
@@ -847,7 +847,7 @@ var CPIndexSetCountKey = @"CPIndexSetCountKey",
/*!
Creates a deep copy of the index set. The returned copy
is mutable. The reason for the two copy methods is for
source compatability with GNUStep code.
source compatibility with GNUStep code.
@return the index set copy
*/
- (id)mutableCopy
@@ -859,11 +859,11 @@ var CPIndexSetCountKey = @"CPIndexSetCountKey",
/*!
@class CPMutableIndexSet
@ingroup compatability
@ingroup compatibility
This class is an empty of subclass of CPIndexSet.
CPIndexSet already implements mutable methods, and
this class only exists for source compatability.
this class only exists for source compatibility.
*/
@implementation CPMutableIndexSet : CPIndexSet
-2
View File
@@ -20,10 +20,8 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@import "CPException.j"
@import "CPObject.j"
/*!
@class CPInvocation
@ingroup foundation
-1
View File
@@ -23,7 +23,6 @@
@import "CPObject.j"
@import "CPOperation.j"
/*!
@class CPInvocationOperation
@brief Represents an operation using an invocation that can be run in an CPOperationQueue
+12 -8
View File
@@ -20,8 +20,9 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@import "CPException.j"
@import "CPObject.j"
@import "CPRunLoop.j"
CPJSONPConnectionCallbacks = {};
@@ -68,16 +69,19 @@ CPJSONPCallbackReplacementString = @"${JSONP_CALLBACK}";
{
self = [super init];
_request = aRequest;
_delegate = aDelegate;
if (self)
{
_request = aRequest;
_delegate = aDelegate;
_callbackParameter = aString;
_callbackParameter = aString;
if (!_callbackParameter && [[_request URL] absoluteString].indexOf(CPJSONPCallbackReplacementString) < 0)
[CPException raise:CPInvalidArgumentException reason:@"JSONP source specified without callback parameter or CPJSONPCallbackReplacementString in URL."];
if (!_callbackParameter && [[_request URL] absoluteString].indexOf(CPJSONPCallbackReplacementString) < 0)
[CPException raise:CPInvalidArgumentException reason:@"JSONP source specified without callback parameter or CPJSONPCallbackReplacementString in URL."];
if (shouldStartImmediately)
[self start];
if (shouldStartImmediately)
[self start];
}
return self;
}
+2
View File
@@ -22,6 +22,8 @@
@import "CPArray.j"
@import "CPDictionary.j"
@import "CPException.j"
@import "CPIndexSet.j"
@import "CPNull.j"
@import "CPObject.j"
@import "CPSet.j"
+8 -12
View File
@@ -209,20 +209,16 @@ var _changeKindForSetMutationKind = function(mutationKind)
{
switch (mutationKind)
{
case CPKeyValueUnionSetMutation:
return CPKeyValueChangeInsertion;
case CPKeyValueMinusSetMutation:
return CPKeyValueChangeRemoval;
case CPKeyValueIntersectSetMutation:
return CPKeyValueChangeRemoval;
case CPKeyValueSetSetMutation:
return CPKeyValueChangeReplacement;
case CPKeyValueUnionSetMutation: return CPKeyValueChangeInsertion;
case CPKeyValueMinusSetMutation: return CPKeyValueChangeRemoval;
case CPKeyValueIntersectSetMutation: return CPKeyValueChangeRemoval;
case CPKeyValueSetSetMutation: return CPKeyValueChangeReplacement;
}
}
var kvoNewAndOld = CPKeyValueObservingOptionNew | CPKeyValueObservingOptionOld,
DependentKeysKey = "$KVODEPENDENT",
KVOProxyKey = "$KVOPROXY";
var kvoNewAndOld = CPKeyValueObservingOptionNew | CPKeyValueObservingOptionOld,
DependentKeysKey = "$KVODEPENDENT",
KVOProxyKey = "$KVOPROXY";
//rule of thumb: _ methods are called on the real proxy object, others are called on the "fake" proxy object (aka the real object)
@@ -777,7 +773,7 @@ var kvoNewAndOld = CPKeyValueObservingOptionNew | CPKeyValueObservingOptionOld,
if (setMutationKind)
{
//old and new values for unordered to-many relationships can only be calculated before
//set precalculated hidden new value as soon as "didChangeValue..." is called!
//set recalculated hidden new value as soon as "didChangeValue..." is called!
var newValue = changes[_CPKeyValueChangeSetMutationNewValueKey];
[changes setValue:newValue forKey:CPKeyValueChangeNewKey];
+3 -4
View File
@@ -28,7 +28,6 @@
@import "CPString.j"
@import "CPValue.j"
var CPArchiverReplacementClassNames = nil;
var _CPKeyedArchiverDidEncodeObjectSelector = 1,
@@ -84,7 +83,7 @@ var _CPKeyedArchiverStringClass = Nil,
@delegate -(void)archiverDidFinish:(CPKeyedArchiver)archiver;
Called when the archiver finishes encoding.
@param archiver the arhiver that finished encoding
@param archiver the archiver that finished encoding
@delegate -(id)archiver:(CPKeyedArchiver)archiver willEncodeObject:(id)object;
Called when an object is about to be encoded. Allows the delegate to replace
@@ -371,7 +370,7 @@ var _CPKeyedArchiverStringClass = Nil,
}
/*!
Encdoes an object
Encodes an object
@param anObject the object to encode
@param aKey the key to associate with the object
*/
@@ -476,7 +475,7 @@ var _CPKeyedArchiverEncodeObject = function(self, anObject, isConditional)
// We wrap primitive JavaScript objects in a unique subclass of CPValue.
// This way, when we unarchive, we know to unwrap it, since
// _CPKeyedArchiverValue should not be used anywhere else.
if (anObject !== nil && !anObject.isa)
if (anObject !== nil && anObject !== undefined && !anObject.isa)
anObject = [_CPKeyedArchiverValue valueWithJSObject:anObject];
// Get the proper replacement object
+3 -3
View File
@@ -21,15 +21,15 @@
*/
@import "CPArray.j"
@import "CPCoder.j"
@import "CPData.j"
@import "CPDictionary.j"
@import "CPCoder.j"
@import "CPException.j"
@import "CPKeyedArchiver.j"
@import "CPNull.j"
@import "CPNumber.j"
@import "CPString.j"
CPInvalidUnarchiveOperationException = @"CPInvalidUnarchiveOperationException";
var _CPKeyedUnarchiverCannotDecodeObjectOfClassNameOriginalClassesSelector = 1 << 0,
@@ -89,7 +89,7 @@ var CPArrayClass = Ni
@delegate -(id)unarchiver:(CPKeyedUnarchiver)unarchiver didDecodeObject:(id)object;
Called when the unarchiver decodes an object.
@param unarchiver the unarchiver doing the decoding
@param object the decoded objec
@param object the decoded object
@return a substitute to use for the decoded object. This can be the same object argument provide,
another object or \c nil.
-1
View File
@@ -23,7 +23,6 @@
@import "CPException.j"
@import "CPObject.j"
/*!
@class CPNotification
@ingroup foundation
+1 -2
View File
@@ -26,7 +26,6 @@
@import "CPNotification.j"
@import "CPNull.j"
var CPNotificationDefaultCenter = nil;
/*!
@@ -75,7 +74,7 @@ var CPNotificationDefaultCenter = nil;
Adds an object as an observer. The observer will receive notifications with the specified name
and/or containing the specified object (depending on if they are \c nil.
@param anObserver the observing object
@param aSelector the message sent to the observer when a notification occurrs
@param aSelector the message sent to the observer when a notification occurs
@param aNotificationName the name of the notification the observer wants to watch
@param anObject the object in the notification the observer wants to watch
*/

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