Compare commits

...
745 Commits
Author SHA1 Message Date
Alexander Ljungberg d39bcfb7bd Tests: new nil exception test for CPDictionary. 2015-03-29 13:16:51 +01:00
Alexander Ljungberg c7770c37d0 New: throw an exception on nil CPDictionary keys and values.
Previously only a deprecation warning was issued. This warning was scheduled to be removed in Cappuccino 0.9.8, this release.
2015-03-29 13:02:55 +01:00
Alexander Ljungberg ca2fb81247 This will be Cappuccino 0.9.8. 2015-03-29 12:45:10 +01:00
Alexandre Wilhelm 6a1543cb82 Fixed: Duplicate unit-tests
Previously, some unit-tests had the same name in a test file. Now they have unique name.
2015-02-03 16:46:49 -08:00
Antoine Mercadal a2c0b47908 Merge pull request #2297 from daboe01/datepicker-date-constraint
Fixed: CPDatePicker does not grey out dates outside of minDate and maxDate
2015-01-15 13:44:23 -08:00
Antoine Mercadal f2528b5e9a Merge pull request #2296 from ahankinson/fixed-inconsistent-DOM-method
Fixed: Inconsistent naming of CPDOMDisplayServerSetStyleBackgroundSize
2015-01-15 11:38:32 -08:00
Antoine Mercadal 02f301dae0 Merge pull request #2294 from ahankinson/fix-issue-2293
Fixed: CPStepper class method returns `id` instead of CPStepper type
2015-01-15 11:37:38 -08:00
daboe01 6c47fc9023 disable forbidden dates 2015-01-15 20:28:46 +01:00
Andrew Hankinson f03adf727b Fixed: Inconsistent naming of CPDOMDisplayServerSetStyleBackgroundSize
Previously the method `CPDOMDisplayServerSetStyleBackgroundSize` was named `CPDomDisplayServerSetStyleBackgroundSize`, which was inconsistent with the names of all other similar methods in the CPDOMDisplayServer.h file. This commit fixes this and updates all instances of its use in CPView.j.
2015-01-15 13:59:19 -05:00
Andrew Hankinson 77684dfe31 Merge branch 'refs/heads/master' into fix-issue-2293 2015-01-15 12:00:09 -05:00
Antoine Mercadal ee688d9ae4 Merge pull request #2295 from Dogild/showCase-theme-collectionView
Fixed: showcase of themes are broken
2015-01-15 08:50:25 -08:00
Alexandre Wilhelm 9b16d3624e Fixed: showcase of themes are broken
Previously the showcase of the themes were broken. This was due to a change of the CPCollectionView, previously we used to use the delegate collectionViewDidChange. This delegate method has been removed. We now use an observer on the selectionIndexes.
2015-01-14 17:15:37 -08:00
Andrew Hankinson 2fc75be3dd Fixed: CPStepper class method returns id instead of CPStepper type
Previously the CPStepper class returned the `CPStepper` type instead of the `id` type. This caused warnings to be raised when initializing subclasses of CPStepper.

This commit fixes this issue by specifying the `id` type in the return values.

Fixes #2293
2015-01-14 17:12:16 -05:00
Antoine Mercadal eb883bc51e Merge pull request #2272 from ahankinson/new-fixed-with-credentials-cpurl
Rework of withCredentials, CPURLRequest, and CPURLConnection
2015-01-14 11:51:14 -08:00
Antoine Mercadal fdc5ed93fc Merge pull request #2252 from ahankinson/fix-doxygen-config
Fixed: Doxygen configuration
2015-01-13 18:48:12 -08:00
Antoine Mercadal 148960eecd Merge pull request #2292 from Dogild/xcodecapp-panel-top
New: option to active or not xCodeCapp when opening the errors & warnings panel
2015-01-13 18:45:16 -08:00
Antoine Mercadal 0265fc36fa Merge pull request #2289 from Dogild/CheckBoxSize
Fixed: wrong default size of CPCheckBox when using constructor checkBoxWithTitle
2015-01-13 18:44:45 -08:00
Antoine Mercadal f4c2a0a7f8 Merge pull request #2290 from Dogild/rule-editor-button-jolie
Fixed: Predicate button were blurred for Aristo2
2015-01-13 18:43:46 -08:00
Antoine Mercadal de3eb861ed Merge pull request #2291 from Dogild/WarningTravis
Fixed: warnings when compiling cappuccino
2015-01-13 18:43:03 -08:00
Alexandre Wilhelm f5b64b4958 Fixed: compiling issue for the class CPShadow 2015-01-13 14:11:16 -08:00
Alexandre Wilhelm 20eb59d9b6 Fixed: compiling warning for the class CPInvocation 2015-01-13 13:57:22 -08:00
Alexandre Wilhelm ca1bb8e634 Fixed: compiling warning for the function CGContextDrawImage 2015-01-13 13:24:43 -08:00
Alexandre Wilhelm 6213c098ce New: option to active or not xCodeCapp when opening the errors & warnings panel
Previously, when xCodeCapp opened the errors & warnings panel, xcc was always the new active application of the system.
Now an option is available in the preferences of xcc to disable this possibility. If disable the errors & warnings panel will open itself, but your favorite text editor will still be the active application of your system (you will keep the focus).
2015-01-13 13:11:35 -08:00
Alexandre Wilhelm 31023a1a71 Fixed: warnings when compiling cappuccino
Previously, some warnings were raised when compiling Cappuccino.
2015-01-13 11:46:53 -08:00
Alexandre Wilhelm b963b9547b Fixed: Predicate button were blurred for Aristo2
Previously, the button + and - of a CPPredicateEditor were blurred for Aristo2. Now they are nice and not blurred anymore.
This PR also add a second state for the button, the button will be darker when clicking on it.

Fixes #2183
2015-01-12 18:26:53 -08:00
Alexandre Wilhelm fa4c0af78d Fixed: wrong default size of CPCheckBox when using constructor checkBoxWithTitle
Previously, the default size of a CPCheckBox created with the constructor method checkBoxWithTitle did not take in account the size of the checkBox view.
Now when calculating the size of the control, it will firstly calculate the size of the title and then add the size of the checkBox view and the offset.

Fixes #2281
2015-01-12 16:56:43 -08:00
Andrew Hankinson ef0e0432a7 Fixed: Generate Treeview and activate search engine. 2015-01-09 17:05:03 -05:00
Andrew Hankinson d16f2b54fe Merge branch 'refs/heads/master' into fix-doxygen-config 2015-01-09 16:56:49 -05:00
Antoine Mercadal a3a3da309c Merge branch 'DateException' of https://github.com/Dogild/cappuccino into Dogild-DateException 2015-01-09 10:41:52 -08:00
Alexandre Wilhelm fa7b71cabe Fixed: cappuccino raised an exception when the param of constructor method of a CPDate are not a string. It now raises an warning 2015-01-09 08:37:29 -08:00
Antoine Mercadal d3490f6a2e Merge pull request #2243 from ahankinson/new-CFError-CPError
New: CFError and Updated CPError
2015-01-08 17:33:31 -08:00
Antoine Mercadal 82dc126952 Merge pull request #2264 from Dogild/MemoryLeakTableView
Fixed: Memory leak in CPTableView, CPScrollView [+1]
2015-01-08 17:25:20 -08:00
Antoine Mercadal 6f90e765d4 Merge pull request #2269 from mrcarlberg/self_ref
Fixed: @ref did not generate self.x for an ivar x
2015-01-08 17:25:02 -08:00
Antoine Mercadal b1382e8e89 Merge pull request #2287 from cacaodev/CPOperationQueue-cancelOperation
FIXED : a CPOperation marked as cancelled was never started
2015-01-08 17:24:11 -08:00
Antoine Mercadal 0fb739935f Merge pull request #2288 from daboe01/fixed-sheet-positioning-
Fixed: -showRelativeToRect:ofView:preferredEdge is ignoring the positioning rectangle
2015-01-08 17:23:47 -08:00
Alexandre Wilhelm e49a9f1f06 Fixed: targetRect was assigned too late when displaying a popoverWindow. This var can be used before ordering the popoverWindow 2015-01-06 15:28:14 -08:00
Alexandre Wilhelm 0f5dd99167 Fixed: the method setContentSize: of the CPPopover did not take care about the rect given when displaying the popover 2015-01-06 15:20:02 -08:00
daboe01 2f9f3db198 remove accidental code duplication 2015-01-03 10:21:28 +01:00
daboe01 00ebc265d8 make _targetRect an ivar 2015-01-02 19:35:09 +01:00
daboe01 5995b42872 fixed: popover positioning 2014-12-25 17:37:18 +01:00
Andrew Hankinson 9edb0abda0 Fixed: Styling is removed from build docset; Existing docset is removed before moving a new one. 2014-12-19 15:14:08 -05:00
Andrew Hankinson eaa966e72b Fixed: docset will generate docs before running 2014-12-19 15:13:16 -05:00
Andrew Hankinson a48df23252 New: Jake command for building a Docset
This commit adds the `docset` command to jake, to create a Docset from a doxygen build. It adds a shell script to the "support" directory that manages the build, and includes an Info.plist file that gets copied to the Docset when built.
2014-12-19 13:16:05 -05:00
Antoine Mercadal 3aa8eb9533 Merge pull request #2267 from ahankinson/fix-zindex-on-body
Fixed: z-index of -1000 caused a blank screen in some browsers [+1]
2014-12-19 08:19:47 -08:00
cacaodev e407eeea40 FIXED : travis build 2014-12-16 21:43:19 +01:00
cacaodev 873232d560 FIXED : a CPOperation marked as cancelled was never started (CPOperation -start) when managed in a queue.
FIXED : After an operation started, either from a queue or explicitely, its finished property was never set to true.

This was causing dependant operation to never be executed.
After this commit, cancelled operations are started (but not executed) and correctly marked as finished.

Tests: CPOperationQueueTest and CPOperationTest for an operation managed by a queue or run explicitely.
2014-12-16 18:43:08 +01:00
Alexandre Wilhelm 47cced540e Style: added missing semi-colon in CPComboBox 2014-12-10 10:31:38 -08:00
Alexandre Wilhelm 5b4bddc2e0 Fixed: removed stupid console.error(coucou).... 2014-12-10 10:29:46 -08:00
Alexandre Wilhelm cd511da678 Fixed: used _implementedDelegateMethods in CPComboBox at the same time in CPTextField. This occured some issues with the delegate of the comboBoxDelegate when using textField delegate. This commit fix a issue about the row height of a an element in the list of the comboBox 2014-12-10 10:25:10 -08:00
Antoine Mercadal c4fbef2dd3 Merge pull request #2280 from Dogild/RuleEditorDragging
Fixed: crash when dragging the first line of a RuleEditor above the field Any
2014-12-09 19:37:29 -08:00
Alexandre Wilhelm 92b997fb78 Fixed: crash when dragging the first line of a RuleEditor above the field Any
Previously, cappuccino crashed when dragging the first line of a CPRuleEditor above the field any.
Now we make sure, we can not drag over this limit.
2014-12-09 19:04:12 -08:00
Antoine Mercadal 05d602c313 Merge pull request #2279 from Dogild/CPDatePickerEnter
Fixed: CPDatePicker takes key code CPReturnKeyCode all the time
2014-12-09 18:11:38 -08:00
Antoine Mercadal e1d92bd630 Merge pull request #2265 from Dogild/FocusRingDatePicker
Fixed: CPDatePicker doesn't have a focusRing when editing
2014-12-09 17:42:59 -08:00
Antoine Mercadal 373951a75e Merge pull request #2275 from Dogild/ButtonBarRemove
Fixed: button are always removed from the superview in layoutSubviews
2014-12-09 17:40:27 -08:00
Antoine Mercadal f17898d43d Merge pull request #2276 from Dogild/PopoverWindowObserver
Fixed: wrong option for the observer in _CPPopoverWindow
2014-12-09 17:39:52 -08:00
Antoine Mercadal 129eef79a3 Merge pull request #2274 from kevin-xu/vim-typedef-supported
New: Highlighted "@typedef" in VIM.
2014-12-09 17:39:11 -08:00
Antoine Mercadal e3988e7b84 Merge pull request #2277 from t00f/cppredicate_editor
Fix controls' heights that are displayed in CPPredicateEditor
2014-12-09 17:38:53 -08:00
Alexandre Wilhelm 9174338140 Fixed: CPDatePicker takes key code CPReturnKeyCode all the time
Previously, the CPDatePicker took the key code CPReturnKeyCode all the time. It means, the key event wasn't redistributed to the other component, for example a defaultButton in a window.

Now instead of returning YES, it returns [super performKeyEquivalent:anEvent]
2014-12-09 17:26:02 -08:00
Andrew Hankinson 642dc36c41 Test: Cross Origin Manual Test
This commit adds a manual testing application for checking Cross-origin behaviour in different browsers. A README file included in this application provides details on how to run the tests.
2014-12-09 16:07:43 -05:00
Christophe Serafin 1016c3e22f Fix controls' heights that are displayed in CPPredicateEditor
Lastly, we removed the usage of max-size to enable some controls like CPTextField to have
a specific height. This may caused a CPTextField to have a wrong height.
As all controls in a CPPredicateEditor have a CPControlSize to small, we now force their height to the minimum size.
2014-12-08 18:54:35 -08:00
Alexandre Wilhelm b74d49b0bf Fixed: changed option for observer in _CPPopoverWindow.j 2014-12-08 15:54:25 -08:00
Alexandre Wilhelm 8b29369b7e Fixed: wrong option for the observer in _CPPopoverWindow
Previously the option of the observer in _CPPopoverWindow were set to 0, now it's set to CPKeyValueObservingOptionNew.

This PR fix also another issue, the popoverWindow registered the observer in the wrong order. It firstly observed the frame of the sender and then removed it directly. Now it register when ordering front the popover and remove it when closing the popover
2014-12-08 15:36:31 -08:00
Alexandre Wilhelm cb5fe06e58 Fixed: button are always removed from the superview in layoutSubviews
Previously, the button of a CPButtonBar were always removed and readded in the method layoutSubviews.
Now we only remove the hidden button.
2014-12-08 15:29:28 -08:00
kevin-xu 4ebb2baf06 New: Highlighted "@typedef" in VIM.
"@typedef" should be highlighted since #2254.
2014-12-08 22:00:02 +08:00
Alexandre Wilhelm 0f4a938dfc Fixed: attributes of the listDelegate of a CPComboBox could crash cappuccino 2014-12-05 09:50:49 -08:00
Andrew Hankinson 2a16fb5e09 Fixed: Properly initialize the _withCredentials variable in CPURLRequest 2014-12-04 18:11:38 -05:00
Andrew Hankinson c22cf71099 New: Added CPCopying protocol to CPURLRequest
Previously it was not possible to deep-copy a CPURLRequest, which meant that a CPURLConnection could not keep track of both the original and modified versions of a request.

This commit adds the copy method to CPURLRequest.
2014-12-04 18:11:10 -05:00
Andrew Hankinson c739718710 New: CPURLConnection now has the originalRequest and currentRequest methods
Previously, CPURLConnection did not implement the originalRequest and currentRequest methods (added to Cocoa in 10.8).

This commit adds this functionality.

NB: this is dependent on CPURLRequest having deep-copy capabilities to make a copy of the original request, which has been added in another commit on this pull request.
2014-12-04 18:08:54 -05:00
Andrew Hankinson 2db9fd9657 Test: Expand Unit tests for CPURLConnection
These tests cover new methods added to CPURLConnection
2014-12-04 18:06:02 -05:00
Andrew Hankinson 56b613ff8a Tests: Unit tests for CPURLRequest 2014-12-04 18:05:38 -05:00
Andrew Hankinson cd2e9e29d4 Tests: Fixed tests for withCredentials 2014-12-04 16:37:34 -05:00
Andrew Hankinson d1917db47e Fixed: Reworked withCredentials for XMLHTTPRequests
Previously, the withCredentials parameter was accessed primarily through the CPURLConnection, which gave limited access to changing the request before it was sent off.

This commit removes withCredentials from CPURLConnection and places it on CPURLRequest so that it may be more easily modified prior to sending the request. This also simplifies the logic in CPURLConnection for creating and establishing connections with credentials.

In this commit, all CFHTTPRequests are assumed to not use withCredentials unless they are explicitly set. Setting [aURLRequest withCredentials] will set the withCredentials property on the underlying XMLHTTPRequest prior to the connection being opened.
2014-12-04 15:29:52 -05:00
Andrew Hankinson 8024f6a804 Fixed: Move CPURLRequest methods to @accessors
This commit changes the simple getters/setters from CPURLRequest to use @accessors.
2014-12-04 15:12:11 -05:00
Alexandre Wilhelm 46a0ce8e98 Fixed: wrong condition when setting the frame in CPWindow when ordering a view 2014-12-04 11:06:50 -08:00
Alexandre Wilhelm c7ccff914f Test: added basic test for ordering window 2014-12-02 16:48:44 -08:00
Alexandre Wilhelm 8efb6f8808 Test: added unit test for registered notification for the tableView 2014-12-02 16:39:07 -08:00
Alexandre Wilhelm 006bf72c17 Test: added unit test for registered notification for the scrollView 2014-12-02 16:38:55 -08:00
Alexandre Wilhelm ec3af04f29 Test: added tests for CPComboBox 2014-12-02 16:38:17 -08:00
Alexandre Wilhelm b45399a045 Test: added class notificationHelper with the method registeredNotificationsForObserver 2014-12-02 16:37:57 -08:00
Alexandre Wilhelm 12ed70fec2 Fixed: notifications CPWindowDidResignKeyNotification and CPWindowDidBecomeKeyNotification were not registered for a firstresponder textField when ordered again a window 2014-12-02 16:37:02 -08:00
Alexandre Wilhelm c3ce0a61b6 Fixed: type with the method _windowWillBeAddedToTheDOM in CPWindow 2014-12-02 10:03:13 -08:00
Andrew Hankinson 526e0725d8 Merge branch 'new-CFError-CPError' of github.com:ahankinson/cappuccino into new-CFError-CPError 2014-12-02 12:51:25 -05:00
Andrew Hankinson 7e4e0567ef Merge branch 'refs/heads/master' into new-CFError-CPError 2014-12-02 12:51:14 -05:00
Martin Carlberg ee13978115 Fixed: @ref did not generate self.x for an ivar x 2014-12-02 13:54:02 +01:00
Alexandre Wilhelm f5d847f320 Style: style in CPWindow 2014-12-01 16:08:49 -08:00
Alexandre Wilhelm 1df0da7509 Fixed: method addObservers and removeObservers were not call all the time when ordering or not a window 2014-12-01 16:07:48 -08:00
Alexandre Wilhelm e4bfd0ef5e Fixed: issue when opening a popUpList of a CPComboBox. We now firstly open the panel and then we modify the content of the panel, this occured an issue with the rendering of the view 2014-12-01 16:07:13 -08:00
Alexandre Wilhelm 2e66601c19 Fixed: memory leak in CPComboBox
Previously, when assigning a listDelegate to a CPComboBox, we never deleted the observers added by this method. Now we add and delete these observers in the method addObservers and removeObservers.

This PR fix another issue. Previously, the behavior of the panel of the comboBox wasn't the same as the one in Cocoa. Now, when closing the panel, the hit view won't be the first responder as it was. Cocoa works like this as well.
2014-12-01 14:22:39 -08:00
Alexandre Wilhelm 2484fb85e9 Fixed: warning raised by the compiler due to unknown type in var declarations 2014-12-01 14:22:06 -08:00
Alexander Ljungberg b2557c38dd Merge pull request #2266 from zittix/patch-2
Docs: fixed bootstrap.sh URL due to github URL change
2014-11-28 23:20:59 +00:00
Alexandre Wilhelm 56acbfc85c Fixed: change == to === on CPTextField when assigning a delegateo 2014-11-28 10:00:27 -08:00
Alexandre Wilhelm 77f962eed4 Style: removed comment in CPDatePicker 2014-11-28 09:58:44 -08:00
Andrew Hankinson 18a6ecc79a Fixed: z-index of -1000 caused a blank screen in some browsers
Previously, a z-index value of -1000 caused some browsers to not display certain UI elements correctly. Setting this value to 0 instead seems to fix this.

This commit changes the default value in the templates generated by `capp gen`.

Fixes #2232, Refs #2194
2014-11-27 11:22:40 -05:00
Mathieu Monney c3fc6a087a Fixed URL, wasn't the tagged released one. 2014-11-27 13:30:31 +01:00
Mathieu Monney 02a47dc7b9 FIXED bootstrap URL due to github URL change. 2014-11-27 13:25:29 +01:00
Alexandre Wilhelm 30413e6f8f Merged conflict in CPComboBox 2014-11-26 16:00:03 -08:00
Alexandre Wilhelm 6ed7354884 Merge branch 'master' of https://github.com/cappuccino/cappuccino 2014-11-26 15:57:40 -08:00
Alexandre Wilhelm 94f89acc84 Fixed: memory leaks when using a delegate with a CPTextField 2014-11-26 15:56:10 -08:00
Alexandre Wilhelm 392a6cfbca Fixed: memory leak when using a delegate with a CPComboBox 2014-11-26 15:55:50 -08:00
Alexandre Wilhelm e03b6b3824 Fixed: _postDidResizeNotificationWithOldWidth does not exists anymore, replace by _didResizeTableColumn:tableColumn:oldWidht: 2014-11-26 15:18:39 -08:00
Alexandre Wilhelm 51940cea3d Fixed: leak memory with CPTableViews delegate 2014-11-26 15:05:22 -08:00
Antoine Mercadal 5ab346e5d1 Merge pull request #2254 from primalmotion/objj-typedef-and-ivar-checks
Objj typedef and ivar checks
2014-11-26 13:40:56 -08:00
Antoine Mercadal 243024e232 Fix broken tests due to new objj type checks 2014-11-26 13:12:39 -08:00
Alexandre Wilhelm e62fd4dc00 Merged of CPCLipView 2014-11-26 13:09:51 -08:00
Alexandre Wilhelm 547522a0a4 Fixed: Memory leak in CPClipView
Previously, the CPClipView registered the documentView to the notificationCenter as an observer to be notified when the frame/bounds of the  documentView change.

Now, we don't use the notificationCenter anymore. The class CPView send a message to its superview (when it's a clipView) when the frame or bounds change. This fix the memory leak of the CPClipView

Fixed #2264
2014-11-26 13:06:03 -08:00
Alexandre Wilhelm 4fd3ce606a Merge branch 'FocusRingDatePicker' of https://github.com/Dogild/cappuccino into FocusRingDatePicker 2014-11-26 12:04:39 -08:00
Alexandre Wilhelm ad364b6184 Fixed: CPDatePicker doesn't have a focusRing when editing
Previously, the CPDatePicker didn't have a focus ring when an user was editing it.
Now it does. It works for Aristo1 and Aristo2.

Test App in Tests/Manual/CPDatePickerTest

Fixed #2263
2014-11-26 12:04:00 -08:00
Alexandre Wilhelm 3269ba10ec Fixed: CPDatePicker doesn't have a focusRing when editing
Previously, the CPDatePicker didn't have a focus ring when an user was editing it.
Now it does. It works for Aristo1 and Aristo2.

Test App in Tests/Manual/CPDatePickerTest
2014-11-26 12:01:40 -08:00
Antoine Mercadal b0a7fe4079 Merge branch 'master' into objj-typedef-and-ivar-checks
+ fixed new warnings from master

Conflicts:
	Foundation/CPNotificationCenter.j
2014-11-26 12:00:34 -08:00
Antoine Mercadal 31afae71d1 Typos 2014-11-26 11:52:25 -08:00
Antoine Mercadal e7ae969c8e Merge pull request #2261 from Dogild/CPNotificationBlock
New: added method addObserverForName:object::usingBlock: in CPNotificationCenter
2014-11-26 11:51:17 -08:00
Alexandre Wilhelm fc5bb7417f Fixed: removed useless comment in CPClipView.j 2014-11-26 10:20:07 -08:00
Alexander Ljungberg 81e6c5c2fa Merge branch 'master' of github.com:cappuccino/cappuccino 2014-11-26 11:07:57 +00:00
Alexander Ljungberg e9f73cbb45 Minor formatting. 2014-11-26 11:07:48 +00:00
Alexandre Wilhelm b36cc8f1e9 Fixed: Memory leak in CPTableView, CPScrollView
Prevously, when removing a CPTableView or a CPScrollView, the CPNotificationCenter kept a reference of these observers in the notification center.

Now, the CPNotificationCenter does only have a observer when necessary.
2014-11-25 17:33:17 -08:00
Andrew Hankinson 6f6938deb7 Fixed: Updated Comment 2014-11-25 17:58:17 -05:00
Andrew Hankinson b63bddacb0 Merge branch 'new-CFError-CPError' of github.com:ahankinson/cappuccino into new-CFError-CPError 2014-11-25 17:56:34 -05:00
Andrew Hankinson b1d56924e6 Fixed: Formatting 2014-11-25 17:56:04 -05:00
Andrew Hankinson 85d80e7ca0 Merge branch 'refs/heads/master' into new-CFError-CPError 2014-11-25 17:51:41 -05:00
Alexandre Wilhelm d481d9cca5 Fixed: added queue to the method addObserverForName:(CPString)aNotificationName object:(id)anObject queue:(id)queue usingBlock:(Function)block 2014-11-20 23:38:53 -08:00
Alexandre Wilhelm fe25dbd872 New: added method addObserverForName:object::usingBlock: in CPNotificationCenter
Previously, the method addObserverForName:object::usingBlock: didn't exist in Cappuccino.
Now it does.

To observe, you need to use the method - (id <CPObject>)addObserverForName:(CPString)aNotificationName object:(id)anObject usingBlock:(Function)block

To unregister observations, you pass the object returned by this method to removeObserver:. You must invoke removeObserver: or removeObserver:name:object:.

Test /Tests/Foundation/CPNotificationCenterTest.j

Fixed #2259
2014-11-20 15:24:23 -08:00
Antoine Mercadal 0dcc645f22 Fix a missing @class declaration 2014-11-20 11:50:18 -08:00
Antoine Mercadal f3090e7827 Update test cases 2014-11-20 11:44:51 -08:00
Antoine Mercadal 37b9895878 Add check to ensure a @class declaration is not already defined as a type 2014-11-20 11:44:32 -08:00
Antoine Mercadal d5b4d66272 Merge pull request #2260 from Dogild/MenuCrash
Fixed: CPMenu crash when opening a menu with items and then opening the menu without items
2014-11-19 16:29:45 -08:00
Antoine Mercadal 653f706f1b Update README 2014-11-19 16:29:05 -08:00
Antoine Mercadal d106e6485b Add some manual test cases for objj output 2014-11-19 16:23:56 -08:00
Antoine Mercadal 460a60440a Correctly set the type of datasource in CPComboBox 2014-11-19 14:53:38 -08:00
Antoine Mercadal 9e66c699e1 FIXED: prevent to declare a type that is already declared as a class and vice-versa 2014-11-19 14:35:33 -08:00
Antoine Mercadal 86d2431925 CPWebScriptObject is a class, not a typedef 2014-11-19 14:34:52 -08:00
Alexandre Wilhelm d30659c37c Fixed: CPMenu crash when opening a menu with items and then opening the menu without items
Previously, when opening a menu with items and then opening another menu without items, Cappuccino simply crashed. Now it works !
2014-11-19 14:27:19 -08:00
Antoine Mercadal 1402133c32 Merge pull request #2164 from daboe01/fixed--CPTextField-&-Bindings--data-updates-even-though-no-editing-has-taken-place
Fixed: textField bindings delete data in case of multiple selection after tabbing out with no editing
2014-11-17 12:49:15 -08:00
Antoine Mercadal 5a99e18d7c Merge pull request #2238 from Dogild/ChainSheetWindow
Fixed: unable to chain sheet in a window
2014-11-17 12:42:15 -08:00
Antoine Mercadal afe326c1c1 Merge pull request #2258 from t00f/fix_controlSize_height
Fixed: Enable CPTextField to have a specific height
2014-11-17 12:40:37 -08:00
Antoine Mercadal e40612a032 Merge pull request #2255 from ahankinson/fix-default-jakefile
Fixed: Environment configuration in Jakefile templates
2014-11-17 12:39:43 -08:00
Antoine Mercadal 9c6cca7db6 Merge pull request #2257 from primalmotion/textfield-multiline-support
NEW: Support for multiline mode in CPTextField
2014-11-17 12:39:00 -08:00
Christophe Serafin a5283a26ab Fixed: Enable CPTextField to have a specific height
When setting controlSize, CPTextfield height was forced to min-size height.
Now we check that the frame size is between the min and the max size. It allows to constrain
a CPControl to have a fixed height by specifying a min-size equivalent to the maxsize.
In CPTextField case, we only have a min-size which enable us to have a specific size.

Changes has been made in Aristo2 only.
2014-11-14 13:49:33 -08:00
Antoine Mercadal e2020fa7f2 Add CPAltEnterTextAreaFeature checking. FF doesn't add a cariage return on textarea when doing alt+enter 2014-11-13 00:17:29 -08:00
Antoine Mercadal de3f6d3e82 Add manual test 2014-11-13 00:10:37 -08:00
Antoine Mercadal e7cde2ca5f Add support for usesMultilineMode and fix wraps and scrolls in nib2cib 2014-11-13 00:10:22 -08:00
Antoine Mercadal 0c7b2ae702 NEW: Support for multiline mode in CPTextField
This patch adds support for CPTextField with multiline content. It uses
a DOM textarea when needed, instead of DOM input.

It also disable the spellchecking, fixes a bug where the input element was not
correctly resized when the frame changed, and refactor some code
2014-11-12 23:59:46 -08:00
Andrew Hankinson 1c822901e2 Merge branch 'master' of git://github.com/cappuccino/cappuccino into new-CFError-CPError 2014-11-12 16:41:10 -05:00
Antoine Mercadal 0cafb3fac5 FIXED: CPViewController coming from a XIB could call viewDidLoad two times
This patch ensure that CPViewController is never calling viewDidLoad more than one time.
2014-11-10 17:03:34 -08:00
Antoine Mercadal d8718cc20f Merge pull request #2256 from Dogild/PlatformWindowKey
Fixed: CPWindow doesn't take the event when moving from another platformWindow
2014-11-07 16:26:15 -08:00
Antoine Mercadal c484e4afe5 Merge pull request #2244 from ahankinson/fix-deprecate-nativehost
Fixed: NativeHost is no longer built by default
2014-11-07 15:48:50 -08:00
Antoine Mercadal e155cca65e Merge pull request #2245 from ahankinson/fix-cleanup-tools-folder
Fixed: Removed old CI scripts from the Tools directory
2014-11-07 15:48:25 -08:00
Antoine Mercadal 5cad5b095a Merge pull request #2250 from Dogild/CursorContentInset
Fixed: text cursor for CPTextField class doesn't take content-inset in account
2014-11-07 15:46:39 -08:00
Antoine Mercadal 2dff805d40 Merge pull request #2251 from Dogild/ThemeComboBox
Fixed: wrong content-inset for CPComboBox
2014-11-07 15:45:46 -08:00
Antoine Mercadal 0afd65539f Merge pull request #2253 from Dogild/XcodeCappNotificationXib
Fixed: notification xib converted wasn't displayed anymore
2014-11-07 15:43:26 -08:00
Alexandre Wilhelm 664d5777fd Fixed: CPWindow doesn't take the event when moving from another platformWindow
Previously, when moving from platformWindow to another platformWindow, the targeted window didn't get the new event because the keyWindow of the application was still set to the other platformWindow.

This PR fixes another issue about opening panel in a platformWindow. When opening a panel in a platformWindow, cappuccino set the new key window to the wrong platformWindow.
2014-11-07 15:43:18 -08:00
Antoine Mercadal 9a307269ca FIXED: CPButtonBar was not removing old button set from the view
This patch ensure that when we are using setButtons: old buttons are actually removed from the superview
2014-11-07 14:25:35 -08:00
Alexandre Wilhelm ab2657b795 Fixed compilation warning in nib2cib 2014-11-06 15:11:58 -08:00
Antoine Mercadal 57d435b6db NEW: .gitignore ignores .tm_properties 2014-11-06 14:59:40 -08:00
Andrew Hankinson de2e77cc86 Adding userInfo error keys and documenting CPURLError.j 2014-11-06 17:23:27 -05:00
Alexandre Wilhelm ee5e22c574 Merged 2014-11-06 13:30:26 -08:00
Alexandre Wilhelm 1ce6a630d2 Fixed: warnings from objj were displayed several times 2014-11-06 13:29:16 -08:00
Antoine Mercadal aee89b1f63 NEW: option to define if the reporting window should stay on top 2014-11-06 12:21:23 -08:00
Antoine Mercadal 0f791be195 FIXED: config warning issues 2014-11-06 12:20:56 -08:00
Antoine Mercadal 45248bcb65 FIXED: ivars warning fixes 2014-11-06 12:17:58 -08:00
Andrew Hankinson 3c092f36cb Merge branch 'refs/heads/master' into new-CFError-CPError 2014-11-06 14:34:30 -05:00
Andrew Hankinson 9a5afb70b5 Fixed: Environment configuration in Jakefile templates
Previously the Jakefile template for the capp utility would emit a template where the "configuration" build environment parameter could have multiple values. At the head of the file, the configuration parameter could be an environment variable composed of ENV['CONFIG'], ENV['CONFIGURATION'] or ENV['c']. It would default to "Debug".

However, other locations in this file did not use the detected configuration, and only looked at ENV['CONFIGURATION'] for the environment variable.

This commit fixes this by using the detected configuration environment variable as the build environment.
2014-11-06 13:40:47 -05:00
Antoine Mercadal f9275a70af FIXED: New warnings reveleaded by ivar type checking
This patch fixes all new warnings
2014-11-06 10:17:05 -08:00
Antoine Mercadal 8ee443a43c NEW: @typedef and ivar type warning
Previously, ObjJ was ignoring unknow ivar type. This patch adds some check to ensure the type is either a known class, the current class
itself, a global, a basic JS type or a declared custom type.

In order to declare custom types, this patch introduces the @typedef keyword.

For instance, this will throw a warning:

```objj
@import <Foundation/Foundation.j>

@implementation MyClass: CPObject
{
    NUSuppaType mode;
}
@end
```

This will not:

```objj
@import <Foundation/Foundation.j>

@typedef NUSuppaType

@implementation NUMyClass: CPObject
{
     NUSuppaType mode;
}
@end
```

Declared types are shared accross all application, one type can only be declared once.
2014-11-06 10:10:05 -08:00
Alexandre Wilhelm 26223bb383 Fixed: include path doesn't take the absolute path 2014-11-06 09:52:40 -08:00
Alexandre Wilhelm ea0c5e291f Fixed: notification xib converted wasn't displayed anymore
Previously, the notification xib converted didn't show up. Now it does again.

This PR fixes another issue. Now when checking the the compilation issues, we only pass objj file to the command objj.
2014-11-06 09:38:30 -08:00
Andrew Hankinson 8ef7cacdda Fixed: Doxygen configuration
The Doxygen configuration file caused warnings to appear about obsolete tags. (The version of doxygen that the file was created for was 1.7.1, which was released in 2010.)

This commit uses the automatic doxygen updater (doxygen -u) to update it to a more recent version (1.8.7).

Additionally, this commit changes the .doxygen file to build a docset by default. The effect of this is to simply emit a `Makefile` in the output directory that can be further used to compile a docset. Parameters for the project publisher and name were added for this docset.
2014-11-06 12:34:18 -05:00
Antoine Mercadal 6d956c6138 Merge branch 'xCodeCapp3.2' of https://github.com/Dogild/cappuccino
Conflicts:
	Tools/XcodeCapp/XcodeCapp/ProcessSourceOperation.m
2014-11-05 19:06:06 -08:00
Antoine Mercadal b028e62731 Merge pull request #2248 from Dogild/OBJJEnhancement
New: new options for the command objj
2014-11-05 19:03:36 -08:00
Alexandre Wilhelm fc43ec8185 Fixed: wrong content-inset for CPComboBox
Previously, the content-inset of a CPComboBox was wrong, the text of the controller was over the popUPButton.
2014-11-05 14:26:34 -08:00
Alexandre Wilhelm 491b5dcd6f Fixed: text cursor for CPTextField class doesn't take content-inset in account
Previously, the text cursor of the CPTextField didn't take in account the content-inset. This raised issue with class as the CPComboBox, when the mouse was over the popUpButton, there was still the text cursor instead of the default one.

Now it works as in Cocoa.
2014-11-05 14:13:08 -08:00
Alexandre Wilhelm 02bbe0e6f5 Fixed: removed unused constant 2014-11-05 13:07:25 -08:00
Alexandre Wilhelm b827b7ffce New: xCodeCapp 3.2, command objj on each processing files or on the entire project
This pull requests adds a nice feature to xCodeCapp, now each time a fill is processing, xCodeCapp will launch the command objj to check the compilation issues. If it finds something, it will show them up on the classic error panel. This basically show import warnings, warnings you don't catch with your browser but only during the build of the application.
Objj is only launched if no errors was found after the first parsing (the parser which translate a file to objective-c).

This feature can be disabled on the preferences panel.

The menu has a new menu item "Check Compilation Issues". This action will launch objj on each files of the project and shows warnings and errors found.

The command objj will take automatically the OBJJ_INCLUDE_PATH in the index.html or index-debug.html. This options can be disabled in the preferences panel as well.

This PR only works with the PR #2248
2014-11-05 12:57:03 -08:00
Antoine Mercadal 459374db1c FIXED: Open the popup list as a child window in CPComboBox 2014-11-05 11:35:14 -08:00
Alexandre Wilhelm 97a65059e5 Fixed: when using the option -m, objj doesn't process every files in a error is raised, now it does 2014-11-05 11:12:17 -08:00
Antoine Mercadal d629f4b501 STYLE: Make previous patch cleaner 2014-11-05 11:11:03 -08:00
Antoine Mercadal f486c02b5e FIXED: Some APIs in CPComboBox were broken
Previously, when setting font, alignement, intercellSpacing or itemHeight, CPComboBox was assuming the listDelegate was already created.
This patch stores the values in CPComboBox if the listDelegate is not ready, and apply them once it is.
2014-11-05 10:55:19 -08:00
Antoine Mercadal d63669ac22 Merge pull request #2242 from primalmotion/disable-flag-for-commonjs-environement
NEW: Environment variable to disable CommonJS environement building
2014-11-04 18:08:22 -08:00
Alexandre Wilhelm ad82b0064a Fixed: added options -m for objj. This option allows you to make objj on several files 2014-11-04 13:23:54 -08:00
Alexandre Wilhelm 58f2d7117a Test: removed test for capp_lint 2014-11-03 21:22:31 -08:00
Alexandre Wilhelm 735b0f8593 Revert "Test: removed test for capp_lint"
This reverts commit 2bf012100a.
2014-11-03 21:22:01 -08:00
Alexandre Wilhelm 2bf012100a Test: removed test for capp_lint 2014-11-03 21:02:15 -08:00
Alexandre Wilhelm 7abcc42a42 Test: updated test ToolTest.j. Added tests for capp_lint and objj 2014-11-03 19:55:02 -08:00
Alexandre Wilhelm 4d77e7dd6b Fixed: fixed issue with press, capp and nib2cib with the new command objj 2014-11-03 19:54:35 -08:00
Alexandre Wilhelm 5678fe3b83 Fixed: change option -p in objj by bash concept -- 2014-11-03 18:12:47 -08:00
Alexandre Wilhelm f74888419c Fixed: part of the code missing after the previous commit refs #f21dcb8265d78683f984aa70014e1fb91a191ae7 2014-11-03 15:33:37 -08:00
Alexandre Wilhelm f21dcb8265 New: Added option --parser/-p to the command objj
Previously it wasn't possible to specify a custom parser for the command objj. This is needed for xCodeCapp
2014-11-03 15:25:47 -08:00
Alexandre Wilhelm 5bd07716eb New: new options for the command objj
This pull requests adds the following feature for the command objj:

- Option -h or --help to get the help of the command
- Option -I or --objj-include-paths to specify the frameworks to be used
- Possibility to pass several files to the command, for example objj AppController.j Test.j
2014-11-03 14:49:25 -08:00
Andrew Hankinson c37f0cfaa9 Fixed: Removed old CI scripts from the Tools directory
The Tools directory contained some old scripts for a previous continuous integration system. Since we're using Travis now, these are no longer needed.
2014-11-01 12:20:03 -04:00
Andrew Hankinson 9621d76faa Fixed: NativeHost is no longer built by default
This commit removes NativeHost from the 'Tools' Jakefile, ensuring that it does not get built by default.

Fixes #2239
2014-11-01 12:10:23 -04:00
Andrew Hankinson 32c252393a Fixed: Broken unit test 2014-11-01 10:01:56 -04:00
Andrew Hankinson ef5d1d6e58 Fixed: Wrong method included on CPError 2014-11-01 09:27:12 -04:00
Andrew Hankinson 660d36e001 Updating CPError tests 2014-11-01 09:26:37 -04:00
Andrew Hankinson 2cc67f23ab New: CPError unit test 2014-11-01 09:12:35 -04:00
Andrew Hankinson 6fe3054738 New: Unit tests for CFError methods 2014-11-01 09:04:57 -04:00
Andrew Hankinson 7811521c08 New: CPURLError definitions
This commit adds support for the CPURLError codes, with underlying support provided by Foundation's CFURL Errors.
2014-11-01 09:03:08 -04:00
Andrew Hankinson 96135c9875 New: Toll-free bridged CPError with CFError
This commit changes CPError to use a toll-free bridge with CFError, matching Cocoa's implementation of this class.
2014-11-01 09:01:42 -04:00
Andrew Hankinson 0038eab6ab Add CFError and CFNetworkErrors to the Includes list 2014-11-01 08:59:35 -04:00
Andrew Hankinson a34e8fbc9a Fixed method calls for global CFError methods 2014-11-01 08:59:10 -04:00
Andrew Hankinson 0399b3daed Fixed: Renamed CPCoder method to match language
Previously CPCoder had a method named "encodeValueOfObjCType" which is a misnomer.

This commit renames the method to "encodeValueOfObjJType."
2014-11-01 07:41:51 -04:00
Antoine Mercadal 64a15db791 NEW: Environment variable to disable CommonJS environement building
This patch allows user to disable the commonJS build phase by setting the system environement variable IGNORE_ENV_COMMONJS.

For instance `export IGNORE_ENV_COMMONJS=1`
2014-10-31 18:39:55 -07:00
Andrew Hankinson 49cb446f8b New: Initial commit of CFNetworkErrors file
This commit adds constants for CFURL Errors to enable cross-compatibility with the Cocoa CF and CPURL error reporting functions
2014-10-31 17:15:52 -04:00
Andrew Hankinson 82c32d7dee New: Implementation of the CoreFoundation CFError
This commit adds an implementation of the CoreFoundation CFError classes and functions.
2014-10-31 17:14:55 -04:00
Alexandre Wilhelm bfd0ceac53 Typo: becauwe instead of because 2014-10-29 21:50:46 -07:00
Alexandre Wilhelm ba20936c17 Fixed: unable to chain sheet in a window
Previously when chaining sheet on the same window, Cappuccino crashed.
Now chaining a sheet in the delegate method of the method endSheet: will open the next sheet.

Now when opening a sheet, we check if another sheet is currently closing. If yes, we wait till we get the notification of the closing of the previous sheet. And then we open the next sheet.

Fixed #2159

Test app in Tests/Manual/AttachedSheet2/SheetWindowController.j
2014-10-29 15:04:55 -07:00
Antoine Mercadal 4b058a8c56 Merge pull request #2150 from daboe01/fix-cpcollectionview-height
FIXED: CPCollectionView height is too low [+1]
2014-10-28 16:23:50 -07:00
Antoine Mercadal 49ba0cab27 Merge pull request #2236 from Dogild/CPDatePickerTextDragged
New: possibility to drag in a textual CPDatePicker
2014-10-28 16:23:08 -07:00
Antoine Mercadal b9c4f888b9 Merge pull request #2235 from Dogild/CPTextFieldResetCursor
Fixed: cursor of CPTextField is not updated to default
2014-10-28 16:22:34 -07:00
Alexandre Wilhelm 09e3c5ecfc New: possibility to drag in a textual CPDatePicker
Previously it wasn't possible to update the selected element of a textual CPDatePicker when dragging.
Now we can as in Cocoa.
2014-10-28 13:31:27 -07:00
Alexandre Wilhelm b180f06c2a Fixed: cursor of CPTextField is not updated to default
Previously, when changing the mode of the CPTextField from editable to non-editable, the cursor wasn't set to default. Now it does.
2014-10-28 11:19:49 -07:00
Antoine Mercadal 90345addce Merge pull request #2234 from ahankinson/fix-nib2cib-secure-field-size
Fixed: CPSecureTextField size was not calculated correctly in nib2cib.
2014-10-27 13:51:53 -07:00
Antoine Mercadal 328172cfeb Merge pull request #2230 from Dogild/TableViewBezeledTextField
Fixed: bezeled is set to yes when making a right click on a non-selectable CPTextField in a cell of a CPTableView
2014-10-27 13:51:00 -07:00
Antoine Mercadal a75e5d914c Merge pull request #2233 from Dogild/cursorTextField
Fixed: arrow cursor when the cursor is hover a CPTextField
2014-10-27 13:50:38 -07:00
Andrew Hankinson a783479306 Fixed: CPSecureTextField size was not calculated correctly in nib2cib.
Previously, the Secure Text Field size was slightly smaller when placed using Interface Builder.

This commit adjusts the size in nib2cib by ensuring CPTextField _adjustNib2CibSize is called on CPSecureTextField.
2014-10-27 14:47:12 -04:00
Alexandre Wilhelm ecb557daa5 Fixed: optimization about setting the good cursor for a CPTextField 2014-10-27 10:09:33 -07:00
Alexandre Wilhelm d5e811f9f1 Fixed: exception descriptions in CPDate did not countain all of the needed informations 2014-10-26 21:27:10 -07:00
Alexandre Wilhelm 3e5a6986f9 Fixed: arrow cursor when the cursor is hover a CPTextField
Previously, when the cursor was hover a CPTextField the cursor was an arrow till we selected the textField.
Now when the cursor is hover a CPTextField, and if this textField is enabled and editable or selectable we show the selecting cursor. This is the default behavior in Cocoa as well.

Updated manual test Tests/Manual/CPTextField/
2014-10-24 23:26:48 -07:00
Antoine Mercadal 8e346f18bf Merge pull request #2231 from Dogild/TableViewFirstResponderNoneStyle
Fixed: hitTest method returns the wrong view in the CPTableView when the  selectionStyle is set to CPTableViewSelectionHighlightStyleNone
2014-10-24 14:47:41 -07:00
Alexandre Wilhelm 34c7dededf Fixed: hitTest method returns the wrong view in the CPTableView when the selectionStyle is set to CPTableViewSelectionHighlightStyleNone
Previously, when having a CPTableView with a selectionStyle set to CPTableViewSelectionHighlightStyleNone, we needed two clicks to be able to select or click on a control of the cell. Now we only need one click as in Cocoa.

This is fixed by changing the method hitTest and returning the good view which can become the firstResponder.
2014-10-24 14:06:42 -07:00
Alexandre Wilhelm e56cc85e96 Fixed: bezeled is set to yes when making a right click on a non-selectable CPTextField in a cell of a CPTableView
Previously, when making a right click on a non-selectable CPTextField which is contained in a dataView of a CPTableView set the bezel attribute to yes.

Now, when making this things, Cappuccino will check if the CPTextField if editable or not.
2014-10-23 16:24:04 -07:00
Antoine Mercadal 8d660ff386 Merge pull request #2226 from Dogild/SegementedControlFixed
Fixed: CPSegmentedControl doesn't support small and mini control
2014-10-23 13:50:40 -07:00
Antoine Mercadal 2e3c658bc8 Merge pull request #2229 from Dogild/WindowCloseFirstResponder
Fixed: CPWindow keeps a reference of its firstResponder when closing a window
2014-10-23 12:55:08 -07:00
Alexandre Wilhelm 7af50c3951 Fixed: style in CPSegmentedControl 2014-10-23 12:53:10 -07:00
Antoine Mercadal 0bbada27f3 Merge pull request #2228 from Dogild/unfocusedSelectionGradientColorsProto
Fixed: prototype of method unfocusedSelectionGradientColors is void
2014-10-23 12:01:27 -07:00
Alexandre Wilhelm fcd2b778ea Fixed: CPWindow keeps a reference of its firstResponder when closing a window
Previously, when closing a CPWindow, the window kept a reference of the firstResponder. This things raised an issue when opening a window again and asking the window to make the first responder to the same element as the one we had.

Now when closing a window, the window will update its firstResponder to nil.
2014-10-23 11:53:46 -07:00
Alexandre Wilhelm cbef08eeff Fixed: prototype of method unfocusedSelectionGradientColors is void
Previously the prototype method of unfocusedSelectionGradientColors as void, now it's CPColor
2014-10-23 10:59:54 -07:00
Alexandre Wilhelm 6d3f430b24 Fixed: constructor of CPDate can take string param
Previously, when making a CPDate with some constructors, we could pass a string or nil to create a date. For example it was allowed to do var date = [CPDate dateWithTimeIntervalSince1970:"10"];

Now this is not possible anymore and it works like in Cocoa, only number are authorized.
2014-10-22 17:27:46 -07:00
Alexandre Wilhelm e4516c19d3 Fixed: CPSegmentedControl doesn't support small and mini control
Previously, when changing the controlSize of a CPSegmentedControl, Cappuccino didn't have the theme to do that.
Now, Cappuccino supports the controlSize small and mini. Aristo and Aristo2 have new attributes for that.
The attribute theme "default-height" has been replaced by "min-size" and "max-size" (used everywhere else in Cappuccino).
The CPSegmentedControl has now the theme attribute "nib2cib-adjustment-frame".

This pull request fixed alignment issue when adding a CPSegmentedControl from xCode. In the method initWithCode, we didn't care about the divider thickness, now we do. This same method will also add leftovers pixel to have exactly the same size as in xCode. Leftovers pixels are here because FLOOR operation and size of the font.

Manual test in Tests/Manual/CPSegmentedControlTest
Manual test in Tests/Manual/Nib2CibAlignment
2014-10-22 15:29:40 -07:00
Antoine Mercadal 8eb52f9a88 FIXED: Previous commit about explicitely define the observing options broke the abolity to hide buttons in CPButtonBar
This patch ensure to correctly set the options
2014-10-20 19:36:48 -07:00
Antoine Mercadal f2956670cd Merge pull request #2224 from mrcarlberg/kvo_honor_options_when_creating_change_dictionary
KVO now honor options when creating change dictionary
2014-10-20 18:42:09 -07:00
Martin Carlberg 5b7afd72e3 Fixed: Test cases now use correct options for KVO change dictionaries 2014-10-09 19:30:05 +02:00
Martin Carlberg 643566bbfd Honor options when creating KVO change dictionary 2014-10-09 19:27:57 +02:00
Martin Carlberg 5e0e61b7e5 Don’t create old or new values in KVO change dictionary when doing bindings 2014-10-09 19:25:56 +02:00
Antoine Mercadal 608480c1d2 FIXED: popover window was not trapping next mouse event if delegate responds no to popoverShouldClose:
This patch fixes that by automatically trapping next mouse event if after a performClose, the popover is still visible
2014-10-01 14:48:47 -07:00
Antoine Mercadal 5979baa874 FIXED: - (BOOL)popoverShouldClose: was not called in transient and semi-transient mode
Previously, handlers of events that could make the popover to close were not calling CPPopover's performClose:. This patch ensure performClose: is called, and so delegates are consulted if the popover can be closed or not
2014-10-01 14:17:39 -07:00
Antoine Mercadal 73a2823d0b Merge pull request #2213 from mrcarlberg/error_cannot_find_protocol_declaration
Fixed: When the compiler can't find a protocol in a class declaration
2014-09-30 16:56:36 -07:00
Antoine Mercadal 804ffb826d Merge pull request #2219 from kevin-xu/narwhal.local.conf-fixed
Fixed: It cannot execute the "jake" commands correctly in the Cappuccino...
2014-09-30 16:55:57 -07:00
Antoine Mercadal 4bcbe577c6 Merge pull request #2172 from daboe01/Fixed--activateIgnoringOtherApps
Fixed: activateIgnoringOtherApps:shouldIgnoreOthe... missed call to _didBecomeActive
2014-09-30 16:55:27 -07:00
Antoine Mercadal 2b1b858776 Merge pull request #2221 from mrcarlberg/no_line_information_for_errors_on_line_zero
Fixed: No line information for compiler errors on the first line of a file
2014-09-30 16:52:25 -07:00
Antoine Mercadal 8089f52744 Merge pull request #2214 from kevin-xu/kevin-xu-branch
Fixed: objj.vim is too old and has some bugs.
2014-09-30 16:51:36 -07:00
Antoine Mercadal 3aaa887d68 Merge pull request #2223 from Dogild/InstanceCPTableDrawView
Fixed: Several views of _CPTableDrawView created when encoding and decoding a CPTableView
2014-09-30 16:50:21 -07:00
Alexandre Wilhelm b617d60b60 Fixed: Several views of _CPTableDrawView created when encoding and decoding a CPTableView
Previously, when encoding and decoding a CPTableView, the tableView had several _CPTableDrawView (in the subviews).
Now when encoding, we make sure to remove _CPTableDrawView from its superview.
2014-09-30 15:28:26 -07:00
Antoine Mercadal 321a5533df Merge pull request #2222 from Dogild/FirstResponderWindow
Fixed: firstResponder is lost when adding a firstResponder view to the same window
2014-09-30 10:42:46 -07:00
Alexandre Wilhelm 921fcbdcd0 Fixed: firstResponder is lost when adding a firstResponder view to the same window
Previously, when adding a view (which is the firstResponder of the window) to the same window, the firstResponder was set to nil.
Now it keeps the same firstResponder.
2014-09-29 19:19:17 -07:00
kevin-xu 06d0357f74 Fixed: objj.vim is too old and has some bugs.
objj.vim cannot highlight much syntax correctly, and it should be updated. I've modified objc.vim to objj.vim which reads javascript.vim in the beginning, and now it looks good. Because javascript.vim & c.vim must be loaded into objj.vim, so they should also be committed.

Fixes #2211
2014-09-28 21:17:44 -07:00
Martin Carlberg 2f7681f881 Fixed: No line information was provided for compiler errors on the first line of a file 2014-09-26 13:28:44 +02:00
kevin-xu a822ec729a Fixed: It cannot execute the "jake" commands correctly in the Cappuccino repository directory when it's not the Apple OS.
When running the "jake" commands in the repository directory, it would print:

$ jake --help
narwhal/packages/narwhal-jsc/bin/narwhal-jsc: line 33: narwhal/packages/narwhal-jsc/bin/narwhal-jscore: No such file or directory

Now, it will print:

$ pwd
/home/kevin/workspace/Cappuccino
$ jake --help
Usage: jake [OPTIONS] targets...
-f --jakefile FILE: Use FILE as the jakefile.
-T --tasks: Display the tasks with descriptions, then exit.
-D --describe: Describe the tasks then exit.
-P --prereqs: Display the tasks and dependencies, then exit.
	-v --verbose: Log message to standard output.
-h --help: displays usage information (final option)

Fixes #2181
2014-09-24 21:33:31 -07:00
Antoine Mercadal 38370c7f2e Merge pull request #2203 from sbalay/dev
Add support to diacritic insensitive search in CPString rangeOfString:options:range: method
2014-09-24 12:37:57 -07:00
Antoine Mercadal 37f65eb3dd Merge pull request #2194 from daboe01/div-1-fix
Fixed: divs with negative z-indices are causing display issues in some versions of chrome.
2014-09-24 12:34:13 -07:00
Antoine Mercadal 9347ce2ede Merge pull request #2202 from RoosterDragon/master
Fixed: CPBinder unbindAllForObject did not work.
2014-09-24 12:33:11 -07:00
Antoine Mercadal c4a839f47a Merge pull request #2218 from RoosterDragon/ImageView-leak
Fixed: CPImageView no longer leaks due to image load notification.
2014-09-24 12:30:43 -07:00
Antoine Mercadal 43f7dcd08f Merge pull request #2204 from Dogild/CPDatePicker-CPTableView
Fixed: CPDatePicker in a CPTableView wrong behavior
2014-09-24 12:27:04 -07:00
Antoine Mercadal 71bfe4dd44 Merge pull request #2176 from Dogild/CPView-addSubview
Fixed: Methods viewDidMoveToSuperview viewDidMoveToWindow viewWillMoveToSuperview viewWillMoveToWindow not called as in Cocoa
2014-09-24 12:22:07 -07:00
Antoine Mercadal 5bc44e7190 Merge pull request #2210 from Dogild/CPDatePicker-action
Fixed: CPDatePicker send an action with the methods setObjectValue: and setDateValue: [+1]
2014-09-24 12:04:13 -07:00
Antoine Mercadal 84c1b92fdf Merge pull request #2207 from cacaodev/bindings-issue#2199
Fix bindings memory leak, avoid incompatible bindings
2014-09-24 11:57:26 -07:00
Alexandre Wilhelm be6e222d8d Fixed: memory leak in CPColorWell 2014-09-24 10:14:38 -07:00
RoosterDragon 7db488cdfb Fixed: CPImageView no longer leaks due to image load notification.
Previously, CPImageView would sometimes attach a notification to CPImageDidLoadNotification when the image was set, but would never remove this notification. The view could then leak memory as the notification center would be keeping a reference even if the view was no longer being used.

This commit fixes that issue by removing the observation once the image has loaded.

Fixes #2198.
2014-09-24 13:45:49 +01:00
Antoine Mercadal ca8a70a1ee Merge pull request #2217 from Dogild/SelectedThemeStateTableView
Fixed: CPThemeStateSelectedDataView still set when removing a view
2014-09-19 13:10:31 -07:00
Alexandre Wilhelm 903cc8ee83 Fixed: CPThemeStateSelectedDataView still set when removing a view
Previously, when removing a view from a CPTableView, the themeState CPThemeStateSelectedDataView wasn't unset. Now it does.
2014-09-19 09:59:56 -07:00
Martin Carlberg 13fe318110 Fixed: When the compiler can't find a protocol in a class declaration it now gives an understandable error.
This fixes #2212
2014-09-16 20:13:42 +02:00
Antoine Mercadal b9b396a279 FIXED: using setHidden: for a button in buttonbar was not working
Previously, CPButtonBar was not updating its layout after changing the visibility of its buttons.
This patch adds makes CPButtonBar observersing the buttons and relayout if the visibility of one button is updated.
2014-09-12 14:42:27 -07:00
cacaodev a2755221d0 The cocoa behavior is:
Exclusive bindings are impossible in IB
Possible in code (tested with segmented control and selectedIndex & selectedTag) but then you get unexpected behavior. A segment can be selected after a click and then
changes to another segment.
After this commit, extra exclusive bindings are just ignored and we warn about it.
2014-09-12 22:33:50 +02:00
Alexandre Wilhelm 83ec89fa20 Fixed: CPDatePicker send an action with the methods setObjectValue: and setDateValue:
Previously, the CPDatePicker sent an action to the target when the method setObjectValue: and setDateValue were called.
Now it sends the action only when the user makes an action.

Fixed #2206
2014-09-10 12:54:16 -07:00
cacaodev 68b193a782 NEW: bind:toObject: ... now checks if another binding mutually exclusive is already binded. Throws an exception if this is the case.
Controls can implement -isExlusiveBinding: to determine if bindings are exclusive. Defaults to NO.
Exclusive bindings are mainly CPSelectedIndexBinding | CPSelectedTagBinding | CPSelectedValueBinding
2014-09-09 20:31:15 +02:00
Sebastian Balay fa5fd1e71c Add support to diacritic insensitive search in CPString rangeOfString:options:range: method
When searching by range, the option of diacritic insensitive search was not being contemplated

Also add support to strip variants of 'E' 'I' 'O' 'U' that were not implemented.
Source: http://www.ascii-code.com/
2014-09-08 10:01:12 -03:00
cacaodev e051d02ad3 FIXED : CPBinder subclasses were keeping references to the source object in a class var.
This could cause memory leaks and was unnecessarily verbose.
CPPopUpButton , CPRadio and CPSegmentedControl now use a generic CPBinder method for searching the binder involved when the control is asked to reverse set the binding, typically after a user interaction.
Fixes #2199
TODO: prevent user to bind multiple selection bindings when these bindings are exclusive.
2014-09-06 20:35:41 +02:00
cacaodev a3796fe128 Added private method to CPBinder: + (void)_reverseSetValueFromExclusiveBinderForObject:(id)anObject
Usage: when a control is known to have exclusive bindings (like selected index/tag/value), use this method when
you don't know the binding name and want to send values to the binded object (via reverseSetValueFor:).
In CPBinder binderMap, picks the first binder matching the receiver class or subclass.
2014-09-06 20:22:51 +02:00
Alexandre Wilhelm c1e89bd1c3 Fixed: CPDatePicker in a CPTableView wrong behavior
Previously, when clicking on a CPDatePicker in a CPTableView, cappuccino didn't select the tableView row firstly.
Now it does as in cocoa.
The stepper still have the same behavior as a CPButton in a CPTableView.

refs #2201
2014-09-05 16:16:46 -07:00
Alexandre Wilhelm aded1dd4da Merged: manual merged 2014-09-05 13:00:48 -07:00
RoosterDragon 1e39281423 Fixed: CPBinder unbindAllForObject did not work.
Previously, calling CPBinder unbindObjectForKey would not actually unbind each of the bindings because it was passing the wrong object to the unbind method which would silently ignore the issue. The commit passes the correct parameter to allow unbinding to actually take place.

Fixes #2197.
2014-09-05 14:46:20 +01:00
Antoine Mercadal d92cc0f365 Merge branch 'master' of https://github.com/cappuccino/cappuccino 2014-09-04 18:18:29 -07:00
Antoine Mercadal a5e39d1db3 Revert "Merge pull request #2158 from mrbannon/master"
This reverts commit 228a95f776, reversing
changes made to cf93b72edd.
2014-09-04 18:17:15 -07:00
Antoine Mercadal 7052ce9e63 Merge pull request #2196 from Dogild/BackSpaceTextField
Fixed: backspace on a none editable/enable field trigger the browser's page back button
2014-09-04 18:06:14 -07:00
Alexandre Wilhelm 8d036ab1d4 Fixed: backspace on a none editable/enable field trigger the browser's page back button
Previously, when hitting the backspace key on a none editable/enable field, this triggered the browser's back button.
Now it does not anymore.

All credits for @apajarita

Fixed #2189
2014-09-04 17:44:29 -07:00
Antoine Mercadal 48276f989f Fixed: - (CGSize)sizeWithFont:(CPFont)aFont inWidth:(float)aWidth adjust +1 to the computed size
The width computing of a string is always a little random, and that led to truncated labels. This patch adds
a pixel in width in order to fix any rounding errors.
2014-09-04 17:35:03 -07:00
Antoine Mercadal 57f2d3e26a Revert "Merge pull request #2152 from daboe01/Fix-for-missing-backgroundcolor-support-textfield"
This reverts commit 5c193f49df, reversing
changes made to 5b2ef77c2c.
2014-09-04 14:34:09 -07:00
Alexandre Wilhelm c4924e4005 Fixed: typo 2014-09-04 14:30:40 -07:00
Antoine Mercadal 5c193f49df Merge pull request #2152 from daboe01/Fix-for-missing-backgroundcolor-support-textfield
FIXED: CPTextField's setTextFieldBackgroundColor: has not effect
2014-09-04 14:05:21 -07:00
Antoine Mercadal 5b2ef77c2c Merge pull request #2195 from Dogild/BackgroundSizeFrameSize
Fixed: CSS style background-size doesn't change its value when changing a frameSize
2014-09-04 14:04:42 -07:00
Antoine Mercadal 371b660b33 Merge pull request #2072 from mrcarlberg/fix_accessors_in_categories_fails
Fixed: Ivars with accessors in a Category failed with duplicate ivar error
2014-09-04 14:02:53 -07:00
Antoine Mercadal 228a95f776 Merge pull request #2158 from mrbannon/master
Fixed: #2157 - fixed issue with InvalidStateError when using CPURLConnection in IE11
2014-09-04 13:59:13 -07:00
Antoine Mercadal cf93b72edd Merge pull request #2173 from daboe01/Fixed--collectionViewDidChangeSelection
Fixed: support for outdated collectionViewDidChangeSelection delegate method
2014-09-04 13:57:39 -07:00
Antoine Mercadal 90c60cc5e4 Merge pull request #2184 from daboe01/patch-1
Fixed: typo in scrollRectToVisible: documentation
2014-09-04 13:56:26 -07:00
Antoine Mercadal e79ab4f47a Merge pull request #2190 from Dogild/text-ColorDatePicker
Fixed: wrong text-color for CPDatePicker
2014-09-04 13:55:32 -07:00
Antoine Mercadal 4e946cbb27 Merge pull request #2185 from daboe01/backport-closebutton-aristo
Fixed: Aristo1 close button of inactive windows looks like as in active windows
2014-09-04 13:55:11 -07:00
Antoine Mercadal d5c5070e59 Merge pull request #2191 from t00f/fix#2182
Fixed truncated CPRadio / CPRadioGroup. #2182
2014-09-04 13:54:47 -07:00
Antoine Mercadal 50b3aabb76 Merge pull request #2192 from ratijas/master
-setFloat:forKey: @selector(aValue) -> @selector(floatValue)
2014-09-04 13:54:14 -07:00
Antoine Mercadal b2fd84192b Merge pull request #2193 from Dogild/DatePickerTableView
Fixed: CPDatePicker textual and graphical doesn't work in a CPTableView
2014-09-04 13:53:52 -07:00
Alexandre Wilhelm 1a7f7cb197 Fixed: CSS style background-size doesn't change its value when changing frameSize
Previously, when changing the frameSize of a CPView, the style background-size wasn't changed with.
This raised issue with threePartImage.

Fixed #2187
2014-09-04 13:42:25 -07:00
daboe01 ecab61929e formatting 2014-09-04 18:00:13 +02:00
daboe01 ab4f0f87ca bump zIndex by 1 to avoid -1 2014-09-04 17:51:59 +02:00
Alexandre Wilhelm ae5b3c4c2d Fixed: CPDatePicker textual and graphical doesn't work in a CPTableView
Previously, when using a textual or graphical CPDatePicker in a CPTableView Cappuccino crashed.
This PR fix this issue by adding the subviews of a CPDatePicker in the method layoutSubviews instead of in the initialization.

This PR add another feature on the graphical CPDatePicker, the button next and previous month are now in the mode continuous as in Cocoa.
2014-09-03 16:09:58 -07:00
ratijas 06240d1183 -setFloat:forKey: @selector(aValue) -> @selector(floatValue) 2014-09-03 16:08:21 +00:00
Christophe Serafin f3b3d8d759 Test: Update CPControlSize and Nib2CibAlignment tests to show CPRadioGroup truncated fix.
It removes unuseful grid image and adds CPRadio and CPRadioGroup into CPControlSize and Nib2CibAlignment tests.
2014-09-02 17:45:14 -07:00
Christophe Serafin 8420f6ccfe Fixed: CPRadioGroup were truncated
Since PR #2170, CPRadioGroup were truncated because they are specific components translated into a NSMatrix (CPView) object.
This fix sets CPRadio controlSize according to xCode value and uses its frame adjustment to adjust CPRadio inside a CPRadioGroup.
2014-09-02 17:39:33 -07:00
Alexandre Wilhelm f007ecf6c5 Fixed: wrong text-color for CPDatePicker
Previously the color of a CPDatePicker wasn't black as a CPTextField

Fixed #2188
2014-09-02 13:17:07 -07:00
daboe01 758a023267 style 2014-08-31 21:21:42 +02:00
daboe01 fe6a576d84 add special close button for inactive windows 2014-08-31 21:16:36 +02:00
daboe01 d4f2d99a6b Fixed: typo in scrollRectToVisible: documentation 2014-08-31 13:48:34 +02:00
Antoine Mercadal cb390325a6 Merge pull request #2170 from t00f/themeable-rule-editor
ControlSize management and CPRuleEditor/CPPredicateEditor alignments
2014-08-29 10:11:05 -07:00
Antoine Mercadal 1922ef974b Merge pull request #2180 from kevin-xu/kevin-xu-branch
Fixed: bootstrap.sh cannot filter the OpenRDK version key out correctly.
2014-08-28 22:42:01 -07:00
Alexandre Wilhelm de495aa1c5 Fixed: _removeObservers called in orderFront, we don't need this as addObservers and removeObservers work with boolean to check if the observers are set or not 2014-08-28 22:28:41 -07:00
Alexandre Wilhelm cf0b4c8f03 Fixed: added CPView test for the method addSubview 2014-08-28 22:23:20 -07:00
Alexandre Wilhelm aa4a4b07d8 Fixed: method viewWillMoveToWindow and viewDidMoveToWindow not called when when adding a view to a view without a window where the previous superview had a window 2014-08-28 22:22:50 -07:00
kevin-xu 75a4d8a2b9 Fixed: bootstrap.sh cannot filter the OpenRDK version key out correctly.
When running ./bootstrap.sh, it will print the error message:
"./bootstrap.sh: line 138: [: too many arguments"

This fix correct it by filtering out the OpenRDK Runtime Environment line.

Fixes #2179
2014-08-28 20:14:35 -07:00
Antoine Mercadal b92214461e FIXED: Some tooltips was truncated
This patch adds a small size adjustment when we compute the size of the
tooltip. It seems to fix all truncated tooltips problem.
2014-08-28 19:02:22 -07:00
Antoine Mercadal 3f4ba87079 FIXED: Tooltip content alignement was mistakely set to be justified
This patch ensure the tooltip content is left aligned correctly
2014-08-28 18:30:55 -07:00
Antoine Mercadal f1cfa14750 FIXED: buttons in CPButtonBar were never removed from the CPButtonBar
Previsouly, layoutSubview was layouting the visible buttons, but it was not removing them from
the buttonbar
2014-08-28 17:26:22 -07:00
daboe01 b24f5b6ad6 fixed unit test 2014-08-24 14:12:44 +02:00
Christophe Serafin 3dbce0e800 move DOMElement.style.backgroundSize to CPDomDisplayServerSetStyleBackgroundSize equivalent method 2014-08-22 10:09:09 -07:00
Christophe Serafin 872fd126f4 fix style 2014-08-22 10:07:56 -07:00
Christophe Serafin efca50c6ac fix style 2014-08-22 10:07:29 -07:00
Antoine Mercadal 3cf013b25b Merge pull request #2178 from Dogild/CPOUtlineView-fix-reuseItem
Fixed: crash of the CPOutlineView when reloading and changing an item to another parent
2014-08-21 10:42:58 -07:00
Alexandre Wilhelm 92a5fa19fb Fixed: crash of the CPOutlineView when reloading and changing an item to another parent
Previously, when reloading the CPOutlineView and changing an item to another parentItem, the CPOutlineView deleted the reference of the item.

Now, when removing old data to avoid memory leaks, the CPOutlineView checks if the pending item to delete doesn't have another parent item.
2014-08-20 18:32:20 -07:00
Alexandre Wilhelm 1fcf13d149 Fixed: added optimization for releasing observers 2014-08-20 16:13:59 -07:00
Alexandre Wilhelm bd20050db8 Fixed: added a boolean to avoid to addObservers seveal times 2014-08-20 15:23:10 -07:00
Alexandre Wilhelm ce0233d0a2 Fixed: revert commit abdf1156d4 for CPComboBox 2014-08-20 15:11:21 -07:00
Alexandre Wilhelm 0479e9b3f3 Fixed: make sure to remove observers when opening a CPWindow 2014-08-19 17:52:24 -07:00
Alexandre Wilhelm abdf1156d4 Fixed: memory leaks with CPNotifications
Previously, when removing a view, Cappuccino didn't clean the notification center. The notification center kept in reference old views.

This PR fix this issue. When a CPView is added to a view, the methods _removeObservers and _addObservers are called. In these both methods we remove and add the observer to the notification center if needed. _removeObservers and _addObservers are called for the view and its subviews. These both methods are called through the method viewWillMoveToSuperview.

When a CPView is removed, we only call the method _removeObservers.
When a CPWindow is closed, we call the method _removeObservers on its contentView.
When a CPWindow is about to be opened, we call the method _removeObservers and _addObservers on its contentView.

Refs #1880
Refs #2024

Test app in Tests/Manual/AttachedSheet2/SheetWindowController.j
2014-08-19 17:45:01 -07:00
Alexandre Wilhelm 9ed30f563a Fixed: Methods viewDidMoveToSuperview viewDidMoveToWindow viewWillMoveToSuperview viewWillMoveToWindow not called as in Cocoa
Previously, when adding, removing, replacing a CPView, the framework didn't call the methods viewDidMoveToSuperview, viewDidMoveToWindow, viewWillMoveToSuperview and viewWillMoveToWindow as in Cocoa. Now it does.

The main change is that these methods will be called when removing a CPView.

Added unit-test in Tests/AppKit/CPViewTest.j
2014-08-19 14:26:26 -07:00
Christophe Serafin d1985bad3b update Nib2CibAlignment test 2014-08-18 13:09:51 -07:00
Christophe Serafin c83a4dc8e4 fix _adjustNib2CibSize calls 2014-08-18 13:09:15 -07:00
Christophe Serafin 5484bbf8bf fix Aristo and Aristo2 alignments 2014-08-18 13:08:47 -07:00
Christophe Serafin 62e8d70d74 fix _adjustNib2CibSize calls 2014-08-18 13:08:09 -07:00
Alexandre Wilhelm b2f1477b45 Fixed: wrong condition in CPApplication 2014-08-15 16:37:03 -07:00
Christophe Serafin 7323a5e393 fix disappearing buttons 2014-08-15 09:04:26 -07:00
Christophe Serafin f8205cc376 realign Aristo2 buttons for fix 6f9210 2014-08-15 08:20:46 -07:00
Antoine Mercadal 1b639ab978 Improve test XIB 2014-08-15 01:01:47 -07:00
Antoine Mercadal 4828f7478e Merge branch 'master' into themeable-rule-editor 2014-08-14 21:05:58 -07:00
Antoine Mercadal 9646f7039a Update XIB 2014-08-14 21:05:16 -07:00
Antoine Mercadal 6f921028de do not call again _adjustNib2CibSize 2014-08-14 21:04:57 -07:00
Antoine Mercadal 2508db0550 Remove usless computation 2014-08-14 21:04:32 -07:00
Antoine Mercadal 775141b7f7 Merge branch 'themeable-rule-editor' of https://github.com/t00f/cappuccino into themeable-rule-editor 2014-08-14 21:03:45 -07:00
Antoine Mercadal a2d9c1aa72 Merge pull request #2174 from Dogild/PopoverDelegate
Fixed: delegate popover did show not called with a none animate CPPopover
2014-08-14 20:59:29 -07:00
Christophe Serafin 4b639843ec fixed buttons positions and extended Nib2CibAlignment test 2014-08-14 18:18:08 -07:00
Christophe Serafin 464389a862 update nib2cib-adjustment-frame to match Nib2CibAlignment Test. Except for button in small and mini sizes 2014-08-14 14:17:57 -07:00
Alexandre Wilhelm 48b3eb259d Fixed: delegate popover did show not called with a none animate CPPopover
Previously, the delegate popoverDidShow wasn't called with an none animated CPPopover.
2014-08-14 14:10:37 -07:00
daboe01 4cebfbcd13 removed collectionViewDidChangeSelection 2014-08-14 22:57:05 +02:00
daboe01 1767cf8ad4 formatting+nil equality 2014-08-14 22:41:59 +02:00
daboe01 b1981bb70c fix activateIgnoringOtherApps:shouldIgnoreOthe... 2014-08-14 22:27:46 +02:00
Christophe Serafin 3dc581efbb introduce nib2cib-adjustment-frame as theme attribute to enbable proper control alignment 2014-08-14 10:54:38 -07:00
Christophe Serafin 655cc3256c remove arbitrary CONTROL_HEIGHT 2014-08-14 10:45:12 -07:00
Christophe Serafin bf5b660cb5 fix background size with 1-part image 2014-08-12 17:26:43 -07:00
Christophe Serafin 712dc493ca remove CPDateFormater dependancy and CPString convertion 2014-08-12 15:42:03 -07:00
Christophe Serafin f4fba64ffb remove test on sendAction 2014-08-12 14:06:37 -07:00
Christophe Serafin 02430916cb add CPDatePicker without CPStepper in CPControlSize test demo 2014-08-12 13:58:05 -07:00
Christophe Serafin e3ad115698 correction based on primalmotion comments 2014-08-12 13:56:25 -07:00
Christophe Serafin c078bb04b2 Correction and optimizations based on Alex comments. Fix for CPDatePickerTest 2014-08-12 13:31:22 -07:00
Antoine Mercadal d95e133792 Merge pull request #2171 from Dogild/CPTextField-Platform
Fixed: Checking if a CPTextField is usable in a CPPlatformWindow
2014-08-12 12:11:50 -07:00
Alexandre Wilhelm a04f1045bc Fixed: Checking if a CPTextField is usable in a CPPlatformWindow
Previously, when a CPTextField was in a CPPlatformWindow, the checking of if the CPTextField was usable or not (depending on its position) in a CPPlatformWindow didn't take in account the content-inset of the CPTextField. Now it does.
2014-08-12 11:27:25 -07:00
Christophe Serafin db6975e07a force size only for bordered buttons and bezeled textfields 2014-08-11 18:08:15 -07:00
Christophe Serafin 93127489e7 stop forcing font on CPButton and CPTextField. If the developper wants to set a bigger font it is possible in Cocoa 2014-08-11 17:25:31 -07:00
Christophe Serafin 83064294ac remove useless images and declaration 2014-08-11 15:04:35 -07:00
Christophe Serafin 0b64758360 adjust CPPopUpButton alignment 2014-08-11 15:04:06 -07:00
Christophe Serafin 4e1a2c04a5 create a CPControlSize Manual test to verify control sizes with a certain theme 2014-08-11 14:27:01 -07:00
Christophe Serafin 8412c1db21 enable autoresize theme images instead of creating small and mini images. Remove all existing small and mini images 2014-08-11 14:25:02 -07:00
Antoine Mercadal 18a7a9fdce Merge pull request #2168 from Dogild/CPOutlineView-fixed
Fixed: Memory leaks in CPOutlineView + corrupted itemInfos dictionary
2014-08-11 14:15:59 -07:00
Antoine Mercadal fc90d00354 Merge branch 'master' of https://github.com/cappuccino/cappuccino 2014-08-11 12:47:12 -07:00
Antoine Mercadal 55861a8f44 FIXED: transient popovers were not close with right click
This patch ensure that is a popover is transient and the user right clicks outside, it closes properly.
2014-08-11 12:46:09 -07:00
Alexandre Wilhelm 4fbd307163 Fixed: refactoring of the class CPOutlineView 2014-08-09 15:10:25 -07:00
Alexandre Wilhelm 3e4c03852d Fixed: Memory leaks in CPOutlineView + corrupted itemInfos dictionary
Previously, when reloading a CPOutlineView with different datas than before, the CPOutlineView kept a reference of the previous datas.
Now, when reloading, the CPOutlineView will delete these references when we don't need it anymore. For that, the CPOutlineView will only try to delete the previous reference when we have reloaded the children of a node, otherwise it will keep the other references.

This PR fix some issue with the following methods :

- (BOOL)isExpandable:(id)anItem;
- (BOOL)isItemExpanded:(id)anItem;
- (CPInteger)rowForItem:(id)anItem;
- (CPInteger)levelForItem:(id)anItem;
- (id)itemAtRow:(CPInteger)aRow;
- (CPInteger)levelForItem:(id)anItem;
- (CPInteger)levelForRow:(CPInteger)aRow;

Previously these methods took care about not displayed items. Now they just work with displayed items.

Added unit-tests in Test/AppKit/CPOutlineViewTest.j

Test app in Test/Manual/CPOutlineViewTestCib
2014-08-08 15:05:24 -07:00
Christophe Serafin c8a04b998b update origin Y according to control Size 2014-08-07 18:27:01 -07:00
Christophe Serafin 568a652fb4 added default CPButton images 2014-08-07 18:26:32 -07:00
Christophe Serafin a2c9b5c042 added choices in list to test CPPredicateEditor with CPPopupButton 2014-08-07 16:51:36 -07:00
Christophe Serafin fd3a4b069d removes CPRuleEditorPopUpButton and use CPPopUpButton directly 2014-08-07 16:50:52 -07:00
Christophe Serafin 4aaafa6de7 fix CPDatePicker alignment in CPPredicateEditor. fixes #2162 2014-08-07 16:50:23 -07:00
Christophe Serafin 97475fb27b enable CPButton to use ControlSize management 2014-08-07 16:47:09 -07:00
Christophe Serafin 26e29df657 update CPRuleEditor to use small control size for each control. 2014-08-07 09:44:06 -07:00
Christophe Serafin 269ab3884a enable testing with boolean type 2014-08-07 09:43:07 -07:00
Christophe Serafin d15a853bf7 enable control size management on CPButton, CPPopUpButton, CPCheckbox, CPDatePicker, CPTexteField, CPStepper 2014-08-07 09:41:43 -07:00
Aparajita Fishman b3f7f440c8 Set user event flag based on presence of DOMEvent. 2014-08-06 08:08:53 -04:00
Christophe Serafin c298c968f5 ignore xcodeproj directory 2014-08-05 17:35:25 -07:00
Christophe Serafin 5feac3a7ff allow using regular, small and mini sizes from xCode and from code using setControlSize method. Available on CPTextField, CPStepper, CPDatePicker only for the moment 2014-08-05 17:34:58 -07:00
Antoine Mercadal 215c1c53f5 Merge pull request #2166 from Dogild/PopoverAnimation
Fixed: CPPopover animation issue
2014-08-04 12:54:26 -07:00
Alexandre Wilhelm 7890085c6c Fixed: CPPopover animation issue
Previously, when opening a popover after another one, the CPPopover was blurred.
This occurred due to some CSS Transitions specification :

"Since this specification does not define when a style change event occurs, and thus what changes to computed values are considered simultaneous, authors should be aware that changing any of the transition properties a small amount of time after making a change that might transition can result in behavior that varies between implementations, since the changes might be considered simultaneous in some implementations but not others."

The fix consists to access to a transform value of the style of the _DOMElement to force it to recalculate the values.

More information here : https://code.google.com/p/chromium/issues/detail?id=388082

Fixed #2143
Test app in Test/Manual/CPPopover
2014-08-04 10:55:29 -07:00
Christophe Serafin 12c427a9cf enable CPControl to use setControlSize. Created an example with CPStepper 2014-08-01 16:57:02 -07:00
daboe01 d686a0dadf reverseSetValuesFor: handle multiple selection 2014-07-30 21:09:41 +02:00
Antoine Mercadal eb186f550c Merge branch 'master' of https://github.com/cappuccino/cappuccino 2014-07-30 11:32:59 -07:00
Antoine Mercadal 01b631aea6 FIXED: Popover not showing in correct platform window.
This was fixed a month ago, but additional later commits added a dumb test preventing this to work correctly
2014-07-30 11:31:54 -07:00
Aparajita Fishman 293114f1a0 Fixed: delete methods erased entire field
Previously, the deleteForward:, deleteBackward: and delete: methods in CPTextField called setStringValue, which would consult a formatter, and if the formatter failed all of the text would be deleted.

Now the code has been refactored such that when one of the delete methods is invoked via a key event, the formatter is not used and the DOM event is used, which results in the expected behavior.

A bug in checking the selected range was also fixed in deleteForward:.

The CPFormatter test was updated with buttons to call the delete methods directly to ensure they work correctly when not invoked from a key event.

Closes #1997
2014-07-29 23:32:14 +04:00
Antoine Mercadal 20b92c03cb Merge pull request #2161 from Dogild/CPComboBoxDataSource
New: added protocol CPComboBoxDataSource
2014-07-29 11:22:37 -07:00
Antoine Mercadal b6d76eb84e Merge pull request #2163 from t00f/predicate_editor_with_date
set CPDatePicker elements to days, months, year when used within a CPPre...
2014-07-28 17:29:25 -07:00
Alexandre Wilhelm 25bb51f4a3 New: added protocol CPComboBoxDataSource
Added protocol CPComboBoxDataSource
2014-07-28 13:38:11 -07:00
Christophe Serafin 4a3f51e550 set CPDatePicker elements to days, months, year when used within a CPPredicateRowTemplate 2014-07-28 12:51:32 -07:00
Ryan Bannon d629a13499 Fix: https://github.com/cappuccino/cappuccino/issues/2157
Possible bug in XMLHTTPRequest.  Thanks to hmsimmonds for locating the following:

http://connect.microsoft.com/IE/feedback/details/795580/ie11-xmlhttprequest-incorrectly-throws-invalidstateerror-when-setting-responsetype

https://github.com/enyo/dropzone/issues/179

In short, setting the "withCredentials" flag must be done after open().
2014-07-23 16:58:02 -04:00
Alexander Ljungberg 07c0de71ec New: support line-by-line scrolling with old scroll wheel devices in Firefox.
Without this change, using a traditional scroll wheel mouse with discrete steps would result in very slow scrolling in Firefox.

With this fix we handle these events like in Cocoa: as "[im]preciseScrollingDeltas", which `CPScrollView` in turn knows to apply the configurable line scroll amount for. For backwards compatibility, [event deltaX] and [event deltaY] are premultiplied with a suitable constant, while [event scrollingDeltaX] and [event scrollingDeltaY] show the true values needed.

Browsers other than Firefox seem to always send pixel scrolling information even for old style scrolling devices, at least on the Mac, so are not affected by this change.

Fixes #2013.
2014-07-23 15:04:07 +01:00
Alexander Ljungberg 7470f4ffcf New: CPEvent scrollingDeltaX, scrollingDeltaY and hasPreciseScrollingDeltas.
Refs #2013.
2014-07-23 15:00:30 +01:00
Alexander Ljungberg 81f9748313 Merge pull request #2013 from daboe01/fix-scrollwheel-speed-on-firefox
Fixed: scroll wheel speed is way to low in firefox [+1]
2014-07-23 13:49:19 +01:00
Alexander Ljungberg 58928a5000 Formatting: CPDateFormatter changes and tests.
Refs #2155.
2014-07-22 12:49:35 +01:00
Alexander Ljungberg 4c44ede945 Merge pull request #2155 from krodelin/CPDateFormatter-emptyLanguages
Fixed: CPDateFormatter now works for non-"en" locales [+1]
2014-07-22 12:41:03 +01:00
Alexander Ljungberg d3c4105429 Formatting recent changes. 2014-07-22 12:09:06 +01:00
Antoine Mercadal ed307adb22 Merge pull request #2135 from Dogild/TokenFieldDelegate
Fixed: unsigned delegate methods of CPTokenField erased by CPTextField
2014-07-18 18:42:49 -07:00
Antoine Mercadal 8001688daf Merge pull request #2076 from cacaodev/issue2039
FIXED: Error when binding several objects to the same objectController [+1]
2014-07-18 18:42:18 -07:00
Antoine Mercadal 4c0687b9a5 Merge branch 'fix-menu-enabled-bindings' of https://github.com/daboe01/cappuccino into daboe01-fix-menu-enabled-bindings 2014-07-15 10:22:46 -07:00
Alexandre Wilhelm 33043dd8af Fixed: removed unsued code in CPTokenFieldTest 2014-07-13 21:25:35 -07:00
Antoine Mercadal 1848f96efa FIXED: style 2014-07-10 11:39:43 -07:00
Antoine Mercadal 51440cc7f7 Merge branch 'FIXED--insertAttributedString-did-not-coalsece' of https://github.com/daboe01/cappuccino into daboe01-FIXED--insertAttributedString-did-not-coalsece 2014-07-10 11:38:37 -07:00
Antoine Mercadal 09f100c0c2 Merge branch 'fix-cfhttp-cpurl-2141-2138' of https://github.com/ahankinson/cappuccino into ahankinson-fix-cfhttp-cpurl-2141-2138 2014-07-09 15:45:28 -07:00
Antoine Mercadal a8b66abe15 Merge pull request #2151 from Dogild/EscapePanelRefac
Fixed: escape on a panel or popover breaks the key chain event
2014-07-09 14:12:50 -07:00
Antoine Mercadal 03c45a78a9 Merge branch 'popoverOpen' of https://github.com/Dogild/cappuccino into Dogild-popoverOpen 2014-07-09 14:06:12 -07:00
Alexandre Wilhelm 6574d4450f Fixed: style in _CPPopoverWindow 2014-07-07 20:55:48 -07:00
Alexandre Wilhelm d7f0ff84d6 Fixed: code style in CPPopover 2014-07-07 19:21:00 -07:00
Andrew Hankinson 5ef4c8e83e Fix: Remove _backgroundColor
This parameter exists on CPView, so it has been removed here. A note was added on the setter to identify that the parameter was defined in the superclass.
2014-07-02 08:34:40 +01:00
Andrew Hankinson 5ab48c6015 Fixed: Updated backgroundColor internal variable handling
Previously, _textFieldBackgroundColor was used as the internal variable, and getter/setter methods were explicitly declared to handle getting/setting this value.

This commit changes the name of the internal variable to match the Cocoa compliant method (backgroundColor/setBackgroundColor). It also declares an @accessor option to auto-generate the getter. The setter is explicitly declared because it needs to mark the object as needing display.

Additionally, the logic for the setting is moved from the older method, setTextFieldBackgroundColor, to the new one, setBackgroundColor, and a comment was made to clarify that the older one was deprecated with a link to this issue.
2014-07-01 16:48:21 +01:00
Udo Schneider 9119e08342 Fixed: CPDateFormatter now works for non-"en" locales
CPDateFormatter previously only defined symbols for "en"-locale. Using another locale simple yielded nil-results for most keys. This fix addresses this behavior by always returning the english symbols as default unless other symbols have been explicitly provided or set.
2014-07-01 00:26:51 +02:00
Udo Schneider ce82ce1444 Test: Added Tests for non-english locales
CPDateFormatter only supports the "en" locale by default. All other locales yield empty results for most symbols. The tests added ensure, that the english "default" values are returned if no specific data is available (which is currently the case for every locale except "en").
2014-07-01 00:23:44 +02:00
daboe01 bbffd3d113 correction of typos 2014-06-30 07:07:26 +02:00
daboe01 85cff2c0f3 changed test to use cocoa api 2014-06-30 05:57:10 +02:00
daboe01 9a0c621ad6 introduced cocoa methods for background color 2014-06-30 05:55:22 +02:00
Alexandre Wilhelm 5c66104d25 Fixed: methodsare public instead of private in CPPopover 2014-06-29 19:35:47 -07:00
Alexandre Wilhelm c642d76e91 Fixed: CPPopover doesn't handle semi-transient behavior 2014-06-29 19:17:56 -07:00
Alexandre Wilhelm 6d78ed3462 Fixed: CPPopover test doesn't handle semi-transient state 2014-06-29 19:17:17 -07:00
daboe01 437142ed7b manual test 2014-06-28 17:03:00 +02:00
daboe01 634c6dd455 apply to contentView instead of bezelView 2014-06-28 16:55:43 +02:00
daboe01 3652931be8 fix for missing textFieldBackgroundColor support 2014-06-28 15:20:27 +02:00
Alexandre Wilhelm 7de3022a4a Fixed: animation doesn't work as in cocoa 2014-06-27 13:50:16 -07:00
daboe01 f82e52b7a2 correction of height calculation 2014-06-26 18:06:50 +02:00
Alexandre Wilhelm c274f27810 Fixed: escape on a panel or popover breaks the key chain event
Previously when hitting escape on a CPPanel, the key chain event was broken.
Now when the user hit escape, cappuccino do the following process

- Check if the firstResponder or the chain of the nextResponder implement cancelOperation:
- If not, performKeyEquivalent on the firstResponder and so on
- If not, call the method cancel: on the firstResponder and the chain (not in the case of the CPPopover)

Previously, a complete: method was called if the user hit escape on a void window. This is not a feature of Cocoa, @apajarita or @aljunberg can you confirm that ?

This commit is related to the commit #2139
2014-06-25 18:08:26 -07:00
daboe01 88954b9bf6 fix cpcollectionview height issue 2014-06-25 20:54:18 +02:00
Antoine Mercadal f418f9de4c Merge pull request #2139 from Dogild/EscapePanel
Fixed: CPPanel and popover doesn't close when hitting escape
2014-06-24 17:45:27 -07:00
Antoine Mercadal 57f6ee7f78 Merge pull request #2140 from Dogild/DatePickerStepperValue
Fixed: CPDatePicker value is wrong when making a click on the stepper
2014-06-24 17:29:26 -07:00
Alexandre Wilhelm f8457bd918 Fixed: _closeOnBlur in CPPopover doesn't need accessors 2014-06-24 17:22:09 -07:00
Alexandre Wilhelm 71c1369365 Fixed: removed uelsee import in CPWindow 2014-06-24 17:20:31 -07:00
Alexandre Wilhelm b015a6ea6c Fixed: refactoring of the escape feature of the panel and popover 2014-06-24 17:18:13 -07:00
Alexandre Wilhelm 34072f3947 Fixed: stringValue is used instead of intValue 2014-06-24 16:53:31 -07:00
Antoine Mercadal 036b82afd9 Merge pull request #2134 from Dogild/CPTextFieldEditingStyle
Fixed: CPTextField doesn't update its style when editing [+1]
2014-06-24 16:44:05 -07:00
Antoine Mercadal 52b5b3f741 Merge pull request #2116 from Dogild/xCodeCappUpdatingCapp
New: updating Cappuccino from xCodeCapp
2014-06-24 16:43:05 -07:00
Aparajita Fishman c2f7f2ad27 Merge pull request #2148 from zittix/patch-2
Fixed: Crash of press tool due to theme attribute not set
2014-06-24 13:15:29 -04:00
Alexandre Wilhelm bc9c78acfe Fixed: wrong comment 2014-06-24 10:03:26 -07:00
Mathieu Monney 7bd27ebd52 Fixed: Crash of press tool due to theme attribute not set
When using the press tool, it can happen that one of the theme attribute is not set as not everything is instantiated. 

This fix makes sure that the attribute is set before accessing it to avoid any crash of the press tool.
2014-06-24 15:37:59 +02:00
Alexandre Wilhelm 43ed8be114 Fixed: popoverWillShow called when the popover is opened
Previously, the delegate popoverWillShow was called even if the popover was already shown. This PR fix this issue.
Also, it was possible to launch several times the method orderFront of the _CPPopoverWindow from the CPPopover.
For example with a double click on a button. Now the _CPPopoverWindow has a var isOpening and nothing else is possible during the opening of the popover (not possible to close or to click somewhere else etc etc). This work as in Cocoa.

Test app in Tests/Manual/CPPopover/
2014-06-23 17:29:18 -07:00
Andrew Hankinson a896fe7425 Test: New CFHTTPRequest test
This commit adds a new test for CFHTTPRequest, which at present only contains the test for withCredentials
2014-06-23 16:15:24 -04:00
Andrew Hankinson 6c52e4936f Tests: Updating test for CPURLConnection
This test checks to make sure the CPURLConnection withCredentials functionality works.
2014-06-23 16:14:21 -04:00
Andrew Hankinson 32657793c8 Formatting: CPURLConnection 2014-06-23 16:13:36 -04:00
Andrew Hankinson 63eb88c6ae Merge branch 'fix-cfhttp-cpurl-2141-2138' of github.com:ahankinson/cappuccino into fix-cfhttp-cpurl-2141-2138 2014-06-23 15:51:31 -04:00
Andrew Hankinson 28520cc493 Formatting: Cleaning up CPURLConnection
Removed some extra whitespace and added a newline at the end of the file.
2014-06-23 15:51:13 -04:00
Ryan Bannon 8be05b404c Fixed: change variable name
Changed "returnValue" to "connection" - more descriptive.

Ref: https://github.com/cappuccino/cappuccino/pull/2144#commitcomment-6769088
2014-06-23 15:47:40 -04:00
Alexandre Wilhelm 96b791b5f9 Fixed: fixed gangster's comment 2014-06-23 10:28:10 -07:00
Ryan Bannon ba9eac3ea4 Working #2144: Reintegrated changes from #2138 and fixed test fail.
Now using instance variables for withCredentials.  Also fixed test failure.
2014-06-23 13:08:36 -04:00
Alexandre Wilhelm 717841877f Fixed: typo in _CPDatePickerTextField.j 2014-06-22 13:18:03 -07:00
Aparajita Fishman cf06686d67 Merge pull request #2101 from mockingbird/fix-cpwindow-setcontentview-check
Have CPWindow setContentView check that the new view is not the same as the existing content view
2014-06-22 14:29:36 -04:00
Alexander Ljungberg 8d7594c96a Formatting and clean up.
Refs #2103.
2014-06-22 16:07:17 +01:00
Alexander Ljungberg ed36869f1d Test: complex message receiver.
Refs #2103.
2014-06-22 16:02:37 +01:00
Alexander Ljungberg ea3adc44fd Fixed: objj_msgSend_reset not resetting with fast objj_msgSend.
Refs #2103.
2014-06-22 14:29:40 +01:00
Alexander Ljungberg 5fafc97bc0 Merge branch 'master' into fastobjj 2014-06-22 13:05:32 +01:00
Alexander Ljungberg fba900707a Test: formatting, fix name of previous test.
Refs #2103.
2014-06-22 12:58:24 +01:00
Alexander Ljungberg 175a455d75 Test: add CPAutosizePerformance test to validate objj_msgSend speed improvements.
This test was written by cacaodev.

Refs #2103.
2014-06-22 12:57:11 +01:00
Andrew Hankinson ffcef907b3 Fixed: CPURLConnection now accepts withCredentials
From the original PR:

CPURLConnection was modified to reduce the withCredentials flag to a file-scope member. This has been done to facilitate use of withCredentials when a developer cannot modify the CPURLConnection manually (e.g. https://github.com/wireload/Ratatosk/blob/master/WLRemoteLink.j, line 466).

Refs #1296, #2138
2014-06-21 20:36:12 -04:00
Andrew Hankinson 33317782ea Fixed: CFHTTPRequest now accepts the withCredentials property
From the original PR:

Currently, CPURLConnection has no way to access the withCredential
property of an XMLHTTPRequest, meaning we can't utilize cross-domain
calls using CORS in our applications.

This commit adds the withCredentials property to CFHTTPRequest.

Refs #1296
2014-06-21 20:32:28 -04:00
Alexandre Wilhelm 3b9a0124fa Fixed: setTextColor of CPTextField changed the color of the placeholder
Previously, the method setTextColor changed the color of the placeholder as well.
Now it doesn't as in cocoa

Test app in Test/Manual/CPTextFieldEditingStyleTest
2014-06-19 21:05:17 -07:00
Alexandre Wilhelm 5d5d03fd4c Fixed: textField in CPTextFieldTest doens't have a placeholder 2014-06-19 21:05:06 -07:00
Alexandre Wilhelm 148f3172e6 Fixed: When closing a panel with escape, the delegates are not called
Previously, when closing a panel or popover with escape, the different delegates weren't called.
Now it does.
2014-06-18 18:58:08 -07:00
Alexandre Wilhelm 972c14225b Fixed: CPDatePicker value is wrong when making a click on the stepper
Previously, when making a click on the stepper of a textual CPDatePicker, the intern value of the stepper wasn't updated with the correct value of the CPDatePicker. This occurred when the user changed the dateValue in the delegate methods of the textField.
2014-06-18 18:30:29 -07:00
Alexandre Wilhelm ce86c757cd Fixed: missing bracket... 2014-06-18 16:39:26 -07:00
Alexandre Wilhelm cd6ffba9ac Fixed: CPPanel and popover doesn't close when hitting escape
Previously, a panel or a popover didn't close when the user hit the key escape.
Now it does. The panel or the popover will close on the keyDown event as in cocoa.

Test app in Tests/Manual/CPPanelTest/ and Tests/Manual/CPPopoverTests

Fixed #1767
2014-06-18 16:29:13 -07:00
Aparajita Fishman ab7209ceba Merge pull request #2137 from Asriwi/fix-popover-close-exception
Fixed: CPPopover not closing in some browsers
2014-06-15 16:05:01 -04:00
Aparajita Fishman 63cca6190f Merge pull request #2136 from daboe01/NEW--documentVisibleRect
NEW: support for documentVisibleRect
2014-06-14 22:04:07 -04:00
daboe01 0f2ec90064 documentVisibleRect support 2014-06-14 08:14:38 +02:00
Alexandre Wilhelm 4568dfabb9 Added: added unit test for CPTokenField 2014-06-12 10:58:11 -07:00
Alexander Ljungberg 2a78da6d07 Formatting and comment on table view first responder change.
Refs #2133.
2014-06-10 11:03:08 +02:00
Alexander Ljungberg c3505f865e Merge pull request #2133 from Dogild/TableViewTheme
Fixed: font cell of a CPTableView comes black when editing another cell
2014-06-10 10:53:37 +02:00
Alexandre Wilhelm 3364e6c63b Fixed: unsigned delegate methods of CPTokenField erased by CPTextField
Previously, the unsigned delegate methods _implementedDelegateMethods was erased by the CPTextField, so some delegate methods didn't work any more.
This PR just renames the unsigned delegate methods to _implementedTokenFieldDelegateMethods.
2014-06-09 14:34:08 -07:00
Alexandre Wilhelm a129f2c5c5 Fixed: CPTextField doesn't update its style when editing
Previously, the update of the style of an editing textField didn't work.
Now when editing, we can update the font, color, alignment and vertical-alignment of the textField

Test app in Tests/Manual/CPTextFieldEditingStyleTest/

Fixed #2057
2014-06-09 12:16:15 -07:00
cacaodev 770b0c7022 Here is an ojtest for this issue. 2014-06-07 18:34:59 +02:00
Antoine Mercadal 15a7a0459a Merge pull request #1927 from Alos/layoutSubview-fix
Fixed: CPTabView will now update its tab's labels when the layoutSubview...
2014-06-06 15:54:44 -07:00
Antoine Mercadal 6490858f43 Merge pull request #2131 from Dogild/datePickerShiftClick
New: Added feature to select a set of dates with a shift click in CPDatePicker
2014-06-06 15:42:40 -07:00
Antoine Mercadal aac6f75025 Merge pull request #2129 from Dogild/TyopDatePicker
Fixed: typo in CPDatePicker
2014-06-06 14:37:29 -07:00
Antoine Mercadal 86945218de Merge pull request #2132 from Dogild/ComboBoxModal
Fixed: CPComboBox doesn't work in modal.
2014-06-06 14:36:57 -07:00
daboe01 4632ba3ae5 double var fix 2014-06-04 20:38:51 +02:00
daboe01 38d63c3dc9 formatting 2014-06-04 20:33:30 +02:00
Alexandre Wilhelm c64e5a5799 Fixed: font cell of a CPTableView comes black when editing another cell
Previously, when editing a cell, the other cells of the tableView lost the themeState of the firstResponder.
Now the other cells, as the tableView, keep this state when a cell is editing.

Fixed #2133
2014-06-04 11:19:32 -07:00
Alexander Ljungberg 7c6ef51cb2 New: CPDate dateByAddingTimeInterval:.
Refs #2126.
2014-06-03 17:41:35 +01:00
Alexandre Wilhelm 1e1297378c Fixed: font cell of a CPTableView comes black when editing another cell
The font of a default dataView came black when editing another cell of the tableView.
Now it stays black.

Fixed #2130
2014-06-02 17:31:32 -07:00
Alexandre Wilhelm ac53b30f25 Fixed: CPComboBox doesn't work in modal.
Previously a CPComboBox didn't work when its parent window was in modal. Now it works.

Fixed #2122
2014-06-01 21:18:14 -07:00
Alexandre Wilhelm a5448549b1 New: Added feature to select a set of dates with a shift click in CPDatePicker
Previously it wasn't possible to select a set of dates with a shift click, now we can.
This works only when the mode CPRangeDateMode is set.
It has the same behavior as in Cocoa.
2014-05-31 21:33:59 -07:00
Alexandre Wilhelm a83b9109bf Fixed: typo in CPDatePicker 2014-05-29 15:13:17 -07:00
Alexander Ljungberg fdb079548e Merge pull request #2103 from mrcarlberg/fast_msg_send
Fixed: Faster objj_msgSend
2014-05-29 21:51:57 +01:00
Antoine Mercadal effd837cd0 Merge pull request #2126 from Dogild/DatePickerTabIssue
Fixed: CPDatePicker firstResponder issue
2014-05-27 11:15:00 -07:00
Alexandre Wilhelm 089d564934 Fixed: CPDatePicker firstResponder issue
Previously, the textual datePicker didn't work because it couldn't become the firstResponder.
This PR fixed another issue as well. Previously it wasn't possible to modify a date when moving only with tab and when the datePicker came firstResponder with tabulation.
2014-05-27 10:12:02 -07:00
Alexander Ljungberg 90c65c2927 Merge pull request #2125 from Dogild/bootstrapRegex
Fixed: bootstrap doesn't handle specific OpenJDK Runtime Environment version
2014-05-23 11:55:14 -07:00
Alexandre Wilhelm 7958775c6a Fixed: bootstrap doesn't handle specific OpenJDK Runtime Environment version
Previously, bootstrap didn't handle some OpenJDK Runtime Environment version as: rhel-2.4.7.1.el6_5-x86_64 u55-b13.
Now it did, the regular expression to catch the version of the jdk was wrong.

Fixes #2113
2014-05-23 10:38:56 -07:00
Antoine Mercadal ff99812c4d Merge pull request #2124 from Dogild/fakePaste
Fixed: Issue when making a paste with a right click
2014-05-22 16:45:16 -07:00
Alexandre Wilhelm 741ac31ba6 Fixed: Issue when making a paste with a right click
Previously when making a paste with a right click caused a crash because the location of the fake event was set to null.
This crash occurs only if the user didn't hit the keyboard yet.
Now, the location of the fake event takes the location of the last event of the app, who is the right click.
2014-05-22 15:17:40 -07:00
Antoine Mercadal f953b4dc0f FIXED: Warning when closing a popover for the first time
Previously, the _CPPopoverWindow was trying to remove itself as observer while it wasn't defined
as an observer. This would cause a warning. This patch encapsulates addObserver and removeObserver into methods
that actually check if it's already observing/not observing when trying to observe/not observe
2014-05-20 13:37:53 -07:00
daboe01 76ce921778 added manual test 2014-05-20 06:00:36 +02:00
daboe01 4819f3ca15 whitespace formatting 2014-05-13 21:07:41 +02:00
daboe01 48dd722db9 unit test for coalesce on insert 2014-05-13 20:51:53 +02:00
Alexandre Wilhelm 57c2613d37 Fixed: kDefaultXCCAutoShowNotificationOnCappLint is set to NO 2014-05-12 16:11:07 -07:00
Alexandre Wilhelm 804927f893 Fixed: Removed value bindings for Capp Lint in XCodeCapp .xib file. Reference to PR #2119 2014-05-12 16:09:43 -07:00
Alexander Ljungberg f151920404 Fixed: table view selection text colour in Aristo 1.
This is the same fix as in a4702d48b4 but applied to Aristo 1.

Refs #2009, refs #2001.
2014-05-12 16:04:00 +01:00
Alexander Ljungberg 02f36a1abe New: theme kitchen sink manual test to exercise many themable controls in many states at once.
This test makes it easier to verify themes and theme tweaks.
2014-05-12 15:22:39 +01:00
Alexander Ljungberg c04041f110 New: ensure new first responder and key window states work well with all widgets. 2014-05-12 15:21:35 +01:00
Alexander Ljungberg a4702d48b4 Fixed: illegible white on grey text in table view.
If a table view row is selected its text will turn white to offset against the blue selection colour. However, when the table is not the first responder, or the window is in is not the key window, the light grey highlight colour is used instead, but the text remains white.

This fix ensures the text becomes black in this case by utilising the new first responder and key window theme states.

Fixes #2009, fixes #2001.
2014-05-12 15:21:08 +01:00
Alexander Ljungberg ba27a4cc4a Fixed: new first responder and key window theme states not always applied. 2014-05-12 15:17:49 +01:00
Alexander Ljungberg c28da78294 Fixed: nib2cib of segmented control would not convert enabled state. 2014-05-11 22:17:32 +01:00
Alexander Ljungberg 61f6ef4c19 Fixed: crash in CALayer when running non-DOM platform. 2014-05-11 22:11:43 +01:00
Alexander Ljungberg d46b9b5aad Fixed: text date picker stepper incorrectly enabled after decode.
Without this fix the textual date picker would properly disable the text field bit but not its stepper when unarchived.
2014-05-11 22:11:08 +01:00
Alexander Ljungberg 7fc014f5d9 Fixed: contentInset theme value read 2x in tool bar. 2014-05-11 22:09:23 +01:00
Alexander Ljungberg b28e0d15d8 Fixed: nib2cib of date picker would not convert enabled state.
Without this fix, if a disabled date picker was converted with nib2cib it would come out enabled.
2014-05-11 21:34:26 +01:00
Alexander Ljungberg 0cc1679f64 New: nib2cib support for the standard color panel toolbar item. 2014-05-11 16:39:53 +01:00
Alexander Ljungberg e7a0e9ac70 Fixed: nib2cib "The built in image NSRadioButton is not supported" error.
The nib2cib change which introduced support for the plus and minus template images in nib2cib also broke support for converting radio groups.

This fix restores that support.
2014-05-11 16:39:08 +01:00
Alexander Ljungberg 025a43ea4e New: CPThemeStateKeyWindow for CPView.
Every view in the key window now takes on the 'key window' theme state. This makes it easy to theme everything in inactive windows in more muted colours. Also, combined with the first responder theme state of the previous commit we can have visuals like "first responder but in an inactive window" for text views and such things.
2014-05-11 15:51:17 +01:00
Alexander Ljungberg 050fcf2ab8 New: CPThemeStateFirstResponder for CPView.
When a CPView becomes the first responder it now takes on the 'first responder' theme state, as does all its subviews. This allows it to naturally change appearance when it has the keyboard focus, such as with focus rings and brighter colour schemes.
2014-05-11 15:48:37 +01:00
Alexander Ljungberg c9642fcf35 Test: CPLevelIndicatorTest.
Refs #2071.
2014-05-09 23:24:50 +01:00
Alexander Ljungberg 79c257642c New: visual test for warning/critical state in CPLevelIndicator.
This change makes sure there is both a level indicator which goes into warning and critical display mode for low levels and one which goes into the same for high levels in the manual test for level indicator.

Refs #2071.
2014-05-09 23:04:02 +01:00
Alexander Ljungberg 4f9d9d7a1d Merge pull request #2071 from krodelin/feature-CPLevelIndicator
New: Added bidirectional CPLevelIndicator behaviour
2014-05-09 22:55:12 +01:00
Alexander Ljungberg f14ac355f0 Merge branch 'refs/heads/0.9.7' 2014-05-09 21:34:14 +01:00
Alexander Ljungberg e0217477ce Merge pull request #2118 from ahankinson/fix-issue2117
Fixed: Variable scope in CPSegmentedControl.j
2014-05-09 19:10:54 +01:00
Alexander Ljungberg 5e3bad2a36 Merge branch 'master' of github.com:cappuccino/cappuccino 2014-05-09 19:07:34 +01:00
Andrew Hankinson 26d6450f0a Fixed: Variable scope in CPSegmentedControl.j
Previously, an errant semicolon resulted in improperly scoped variables in CPSegmentedControl.

This fix removes the semicolon in favour of a comma.

Fixes #2117
2014-05-09 13:15:47 -04:00
Aparajita Fishman 5923f7d859 Fixed: oops, it should have been single backslashes. 2014-05-08 17:40:51 -04:00
Aparajita Fishman 57f6a5ca8c Tweak: use continuation lines so the tmLanguage symbol parser works correctly. 2014-05-08 17:08:27 -04:00
Alexandre Wilhelm dd30ffa7ce Fixed: udpate file help.pages 2014-05-08 10:26:22 -07:00
Alexandre Wilhelm 8f5aa0ea16 Fixed: xCodeCapp documentation is outdated
Fixes #2114
2014-05-08 10:04:51 -07:00
Alexandre Wilhelm 1ddf21a256 Fixed: type in preferences for the update of cappuccino 2014-05-08 09:56:06 -07:00
Antoine Mercadal 9d8796c703 Merge branch 'master' of https://github.com/cappuccino/cappuccino 2014-05-07 10:54:56 -07:00
Antoine Mercadal 59a97272bb FIXED: Crash due to tooltip trying to be attached to a window that is gone
Previously, _CPToolTip was not testing if the view and so parentWindow was still here. During the timer, it might be gone, which would cause crash. This patch ensure the window is still there before showing the tooltip
2014-05-07 10:52:57 -07:00
Alexandre Wilhelm e9d328a309 Merge remote-tracking branch 'origin' into xCodeCappUpdatingCapp 2014-05-06 23:49:49 -07:00
Alexandre Wilhelm 448f2913eb Fixed: Jake clean in xCodeCapp
Previously we used jake clean instead of jake clobber
2014-05-06 23:48:23 -07:00
Aparajita Fishman d92b630069 Merge pull request #1958 from GlennAustin/gla/NoOSX10.5
Fixed: Remove explicit use of Mac OS X 10.5 SDK, replace with "latest OS X"
2014-05-05 17:02:09 -04:00
Antoine Mercadal 584955caa8 FIXED: updateFrameWithSize: was always assuming the popver was open 2014-05-05 13:23:44 -07:00
Antoine Mercadal 951e81158c FIXED: popverWillShow was called to early and contentSize was returning 0,0 if popover was hidden 2014-05-05 13:22:55 -07:00
Antoine Mercadal 2a88e598ff FIXED: Crash when using setContentSize: on a popover that is not shown. 2014-05-05 12:52:58 -07:00
Alexandre Wilhelm 3e5e88b369 Fixed: fixed type in XcodeCapp 2014-05-05 09:50:16 -07:00
Alexandre Wilhelm 4806c52ba6 New: updating Cappuccino from xCodeCapp
This PR add the possibility to update cappuccino from xCodeCapp. How does it work :

- Create a temporary file for cappuccino
- Download Cappuccino. The downloaded Cappuccino will be either the last release or the last version of the master branch (option in the preference)
- Make a jake clean
- Make a jake install

There is a small window to follow the progress of the install (3 steps ; download - clean - install).
If there is a issue with the install, the developer will be notify with which step failed (xCodeCapp internally log everything).
The environment var CAPP_NOSUDO is set to 1. It means, if a developer did a bootstrap or a previous jake install in sudo, the update of cappuccino will fail.

Changed the credit of xCodeCapp and pass it to the version 3.1
2014-05-01 18:52:28 -07:00
Antoine Mercadal 86d186e279 Merge pull request #2112 from Dogild/PopoverContentSize
Fixed: CPPopover doesn't change his frame when changing the contentSize
2014-04-30 17:36:29 -07:00
Antoine Mercadal 5bf5388552 FIXED: setContentSize: to work when no window is initialized yet 2014-04-30 17:05:51 -07:00
Antoine Mercadal c19ed471ca Merge branch 'PopoverContentSize' of https://github.com/Dogild/cappuccino into Dogild-PopoverContentSize 2014-04-30 17:03:50 -07:00
Alexandre Wilhelm 9d694a1589 Fixed: setContentSize doesn't work when called several times
Previously when calling setContentSize several times, the final frame of the view was wrong.
I removed the animation as well. This doesn't work, and need a lot more of implementation.
2014-04-30 16:23:00 -07:00
Alexandre Wilhelm 4dadf0cb95 Fixed: CPPopover doesn't change his frame when with setContentSize
Previously when we changed the contentSize of an open popover, nothing happens.
Now, we the frame change and it's animated if needed
2014-04-30 15:38:13 -07:00
Alexandre Wilhelm de4bc67159 Fixed: the way to add the tooltip's window is wrong
Previously when adding a tooltip, we added it to the platformWindow.
Now we add id to the window of the targeted view.

Fixed #2110
2014-04-30 13:24:18 -07:00
Alexandre Wilhelm af37616e48 Fixed: CPToolTip still shown when closing window asynchronous …
When closing a windows asynchronous, the tooltip of views of the window could stay shown.
Fixed #2110
2014-04-29 16:43:32 -07:00
Antoine Mercadal 07f7ad0a05 FIXED: Crash when hit CMD+Z on a control in a CPPopover
Previously, there were collision in addition delegate bitmask identifiers between CPWindow and _CPPopoverWindow.
This patch fixes this collision
2014-04-23 11:28:41 -07:00
Antoine Mercadal fd355636d0 Merge pull request #2108 from Dogild/xCodeCappOptionsNotification
New: Added option in xCodeCapp for displaying error in notification
2014-04-22 18:29:46 -07:00
Alexandre Wilhelm e8528271ee Fixed: tableView doens't update its content with capp_lint 2014-04-22 11:42:19 -07:00
Alexandre Wilhelm 41ed80e0c4 Fixed: capp_lint in xCodeCapp doesn't care about xcodecapp-ignore 2014-04-21 19:11:48 -07:00
Alexandre Wilhelm e8fef8104d Fixed: check the entire project with capp_lint doesn't open the reporting window or a notification 2014-04-21 17:44:13 -07:00
Alexandre Wilhelm 30c48df1f0 Fixed: delegate of the notificationCenter is in AppController 2014-04-21 17:34:39 -07:00
Alexandre Wilhelm f14add2791 New: open reporting window when clickin on a notification in xCodeCapp 2014-04-21 17:30:12 -07:00
Antoine Mercadal 14cb6d21a9 FIXED: XCC Preferences Coherency
This patch fixes various UX weirdness with preferences and makes everything aligned.
2014-04-21 16:59:06 -07:00
Alexandre Wilhelm eaa607b48d New: Added option in xCodeCapp for displaying error in notification
Previously it wasn't possible to configure xCodeCapp to show or not errors/warnings and capp_lint with notifications
2014-04-21 15:34:12 -07:00
Antoine Mercadal 0bd2a032bb FIXED: Give basedir option to capp_lint from XCC or it won't work once completely built 2014-04-21 14:03:45 -07:00
Antoine Mercadal d6961889fb FIXED: Do not invoke sudo in install.sh for capp_lint 2014-04-21 11:14:57 -07:00
Antoine Mercadal 51ffd0d64a Revert "Revert "Fixed: path is wrong with local copy""
This reverts commit 6825e3f7ce.
2014-04-21 11:06:30 -07:00
Antoine Mercadal 120ac31394 Merge pull request #2106 from Dogild/CappLintxCode
New: Integration of capp_lint in xCodeCapp
2014-04-21 10:52:18 -07:00
Antoine Mercadal 4284b97b43 Merge pull request #2105 from Dogild/capp_lintInstall
New: capp_lint is installed with jake install
2014-04-21 10:41:36 -07:00
Alexandre Wilhelm d1615567e2 Fixed: xib of xCodeCapp is in format 5.1 2014-04-21 10:30:00 -07:00
daboe01 9ad3e50511 fixed: .insertAttributedString.. does not coalesce 2014-04-19 14:32:54 +02:00
Alexandre Wilhelm 372372a0aa Fixed: capp_lint doesn't handle protocol
Previously capp_lint didn't handle protocol. Now it does

Fixed #2060
2014-04-18 18:41:27 -07:00
Alexandre Wilhelm 7f35ff5fe5 Fixed: capp_lint for the entire project is not launch from a thread 2014-04-18 11:18:53 -07:00
Alexandre Wilhelm c28cd8a270 Fixed: capp_lint on the entire project doesn't remove the content of the error tableview 2014-04-18 10:47:00 -07:00
Alexandre Wilhelm 973940fcb2 New: Integration of capp_lint in xCodeCapp
Now capp_lint is fully integrated in xCodeCapp.
You can check the entire project with the menuitem of the app.
There is an option in the preference to make a capp_lint (on the file who was just processed) each time a file is processed by xCodeCapp.
Error of capp_lint are reported in the error tableView. The messages displayed the following informations : path of the file, line and error.
2014-04-17 18:26:25 -07:00
Martin Carlberg a740f60734 Fixed: Added test case 2014-04-17 16:18:21 +02:00
Alexander Ljungberg 2b557a0f8d Merge pull request #2105 from Dogild/capp_lintInstall
New: capp_lint is installed with jake install
2014-04-17 09:40:07 +01:00
Alexandre Wilhelm cd19fc7c81 New: capp_lint is installed with jake install
Previously we had to install capp_lint separately from Cappuccino.
Now capp_lint will be installed with Cappuccino.
Before capp_lint was installed in /urs/local/bin/, now it is in /usr/local/narwhal/bin/.
2014-04-16 16:49:40 -07:00
Alexander Ljungberg b5f9501001 Test: CPObject isSubclassOfClass. 2014-04-16 23:01:17 +01:00
Alexander Ljungberg 8c0cd28f64 Merge branch 'master' of github.com:cappuccino/cappuccino 2014-04-16 22:06:16 +01:00
Martin Carlberg e8e10d4224 Fixed: If receiver in the function objj_msgSend is a class we don't need to check if it is nil as a class can never be nil without the load has already failed. 2014-04-15 13:52:41 +02:00
Antoine Mercadal 3e187df75b FIXED: CPPopover transitionend not correctly called in random cases with Chrome 34
There are some weird race conditions happening in Chrome 34 regarding the transitionend event. Setting the timeout to 10ms is not noticealble for the user, and seems to fix the issue.
2014-04-14 15:19:49 -07:00
Martin Carlberg 88d2ed9e93 Fixed: Forgot to commit the files for the new test case 2014-04-14 18:39:34 +02:00
Martin Carlberg ab5674aa4e Fixed: Send message test cases now work. Also added a test case for send message with 'self' as receiver 2014-04-14 16:38:34 +02:00
Martin Carlberg 81e4b6b37b Fixed: If the function 'eval' is called it might have altered 'self' and from here on we check if 'self' is null before 'objj_msgSend' is called with 'self' as receiver 2014-04-14 16:37:21 +02:00
Martin Carlberg b1507952df Fixed: Checks if 'self' is nil only if self has a chance to be changed when sending messages 2014-04-11 15:41:32 +02:00
Martin Carlberg c4ac7cf375 Fixed: Remove use of hard coded call of objj_msgSend function 2014-04-11 10:47:28 +02:00
Martin Carlberg c23292db8a Fixed: Optimized msgSend code when receiver is an identifier.
If the receiver is an identifier and not an ivar that needs 'self.' infront there is no need to assign it to a temporary variable. Also if the identifier is 'self' there we assume it is not nil.
2014-04-10 18:27:19 +02:00
Alexander Ljungberg a350ffeaa1 Merge pull request #2103 from mrcarlberg/fast_msg_send
Fixed: Faster objj_msgSend
2014-04-10 11:23:59 +01:00
Martin Carlberg 0efb7e67c9 Fixed: Use new fast msgSend function for some foundation classes 2014-04-10 11:03:49 +02:00
Alexander Ljungberg a61e0f6cec Merge pull request #2103 from mrcarlberg/fast_msg_send
Fixed: Faster objj_msgSend
2014-04-10 09:45:55 +01:00
Martin Carlberg 0f5b36e9c5 Fixed: Code generated in test cases is corrected for the fast msgSend function 2014-04-09 17:02:28 +02:00
Martin Carlberg 93e7133076 Fixed: Got decorators working with the fast msgSend 2014-04-09 16:52:14 +02:00
Martin Carlberg 2411edd461 Fixed: Faster objj_msgSend
Conflicts:
	Objective-J/Runtime.js
2014-04-08 20:51:18 +02:00
Antoine Mercadal af83065df5 FIXED: Warning due to use of aDOMEvent.returnValue
This patch fixes a warning thrown by recent versions of Chrome about IE ways of doing. It simply uses aDOMEvent.returnValue if aDOMEvent.preventDefault() and aDOMEvent.cancelBubble if aDOMEvent.stopPropagation are not avavailable
2014-04-08 11:41:45 -07:00
Antoine Mercadal 1557c567d4 FIXED: crash due to wrong delegate bitmask 2014-04-03 15:56:04 -07:00
Antoine Mercadal 8bdaeab998 FIXED: Selection behavior when implementing selectionIndexesForProposedSelection
Previously, when delegates implemented tableView:selectionIndexesForProposedSelection:, the selection with arrow were broken. This patch ensure to try to select next/previous row if the current row cannot be selected.
It also cleans up the selection indexes when sending selectAll: as Cocoa does.
2014-04-03 14:10:00 -07:00
Antoine Mercadal 6825e3f7ce Revert "Fixed: path is wrong with local copy"
This reverts commit de2397fa05.
2014-04-03 12:35:44 -07:00
Antoine Mercadal 4602549ec8 STYLE: fix coding style issue 2014-04-03 11:34:33 -07:00
Antoine Mercadal a7b2df2450 Merge pull request #2082 from zittix/patch-2
FIXED: CPSegementedControl with nib2cib crashes
2014-04-03 11:33:27 -07:00
daboe01 3c0f6d3631 fix for menu enabled state not beeing visually updated upon change 2014-04-03 20:00:28 +02:00
Antoine Mercadal 7ac37b75f3 Merge pull request #2097 from Asriwi/fix-textfield-placeholder
Fixed: show placeholder string while editing empty CPTextField
2014-04-03 10:50:05 -07:00
Antoine Mercadal b1e6d57bf1 Merge pull request #2096 from daboe01/fix-text-clobbering-multiple-windows
Fixed: editing textFields on different windows can clobber each others contents
2014-04-03 10:45:12 -07:00
Antoine Mercadal f19c6a0a5b Merge pull request #2100 from Dogild/TableViewWillRemoveView
New: Added delegate tableView:willRemoveView:forTableColumn:row
2014-04-03 10:44:35 -07:00
Antoine Mercadal 789279fe76 Merge pull request #2098 from Dogild/CPBrowserDelegate
New: Added CPBrowserDelegate protocol
2014-04-03 10:43:37 -07:00
Antoine Mercadal 39a8d8803a Merge pull request #2095 from Dogild/CPControlDelegate
New: Added CPControlTextEditingDelegate and CPTextFieldDelegate protocol
2014-04-03 10:43:13 -07:00
Antoine Mercadal f4ce73fc0d Merge pull request #2094 from Dogild/CPWindowDelegateProtocol
New: Added CPWindowDelegate protocol
2014-04-03 10:42:44 -07:00
Antoine Mercadal cac9d9266c Merge pull request #2093 from Dogild/CPTokenFieldDelegate
New: Added CPTokenFieldDelegate protocol.
2014-04-03 10:42:27 -07:00
Antoine Mercadal 7e94d02fb7 Merge pull request #2092 from Dogild/CPRuleEditorDelegate
New: Added CPRuleEditorDelegate protocol
2014-04-03 10:42:10 -07:00
Antoine Mercadal f3913b1dd2 Merge pull request #2091 from Dogild/CPComboBoxDelegate
New: Added CPComboDelegate protocol
2014-04-03 10:41:40 -07:00
Antoine Mercadal 50fc716c15 Merge pull request #2090 from Dogild/CPMenuDelegateProtocol
New: Added protocol CPMenuDelegate
2014-04-03 10:41:21 -07:00
Antoine Mercadal 50412392f8 Merge pull request #2089 from Dogild/CPImageDelegateProtocol
New: Added protocol CPImageDelegate
2014-04-03 10:40:59 -07:00
Antoine Mercadal 1b80859022 Merge pull request #2088 from Dogild/CPSoundDelegateProtocole
New: Added protocol CPSoundDelegate
2014-04-03 10:40:42 -07:00
Antoine Mercadal c6bd758793 Merge pull request #2087 from Dogild/CPAnimationDelegateProtocol
New: Added protocol CPAnimationDelegate
2014-04-03 10:40:07 -07:00
Antoine Mercadal cd4d657815 Merge pull request #2086 from Dogild/SplitViewDelegateProtocol
New: Added CPSplitViewDelegate protocol
2014-04-03 10:39:28 -07:00
Antoine Mercadal a4852b7a21 Merge pull request #2085 from Dogild/CPPopoverDelegateProtocole
New: Added CPPopoverDelegate protocole
2014-04-03 10:39:07 -07:00
Antoine Mercadal 0b3c06abc0 Merge pull request #2083 from Dogild/CPDatePickerAltCommandButton
New: Graphical CPDatePicker clicking on the arrows with key mask Command/Control/Alternate
2014-04-03 10:38:35 -07:00
Alexander Ljungberg 1b351ad5bb New: + CPColor checkerBoardColor for debug use.
This color has a standard 'transparency' checkerboard pattern which is especially useful for our scrolling tests where it makes scrolling easy to visualise.

Refs #2078, #2079.
2014-04-03 11:38:11 +01:00
Alexander Ljungberg 1a1fc3ef21 Merge pull request #2079 from mockingbird/fix-osx-scrolling
Fix OS X scrolling issue.  Closes #2078.
2014-04-03 10:52:24 +01:00
Saikat Chakrabarti fa3f18c88b Have CPWindow setContentView check that the new view is not the same as the existing content view. 2014-04-02 22:56:22 -07:00
Alexandre Wilhelm 904454d737 New: added delegate outlineView:willRemoveView:forTableColumn:item: in CPOUtlineView 2014-04-02 19:27:40 -07:00
Alexandre Wilhelm c1fb54ecad New: Added delegate tableView:willRemoveView:forTableColumn:row
Added delegate tableView:willRemoveView:forTableColumn:row in CPTableView
2014-04-02 13:55:39 -07:00
Antoine Mercadal bd88b28310 Merge pull request #2099 from Dogild/bootstrap
Fixed: path is wrong with local copy
2014-04-01 18:26:30 -07:00
Alexandre Wilhelm de2397fa05 Fixed: path is wrong with local copy
Previously when using a local copy to install Cappuccino, we used to copy the local capp-base at /usr/local/narwhal and then we tried to move /usr/local/narwhal/cappuccino-cappuccino-base*/* to /usr/local/narwhal/. .
Now we move /usr/local/narwhal/cappuccino-base*/* to /usr/local/narwhal/. .
2014-04-01 18:09:14 -07:00
Alexandre Wilhelm 2513cf0969 New: Added CPBrowserDelegate protocol
Added CPBrowserDelegate protocol
Also, now, delegate methods are called as we are used to do it in Cappuccino
2014-03-30 18:27:12 -07:00
daboe01 15e16d86e4 fix for text clobbering when switching windows 2014-03-29 20:19:16 +01:00
Alexandre Wilhelm 26118ee881 New: Added CPControlTextEditingDelegate and CPTextFieldDelegate protocol
Added CPControlTextEditingDelegate and CPTextFieldDelegate protocol
2014-03-28 11:49:18 -07:00
Alexandre Wilhelm 232cf69006 Fixed: wonrd params for the method _sendDelegateWindowWillReturnUndoManager 2014-03-27 19:54:15 -07:00
Alexandre Wilhelm 9d2fba308d New: Added CPWindowDelegate protocol
Added CPWindowDelegate protocol
Also, now, delegate methods are called as we are used to do it in Cappuccino
2014-03-27 19:52:06 -07:00
Alexandre Wilhelm 1171c9a0b2 New: Added CPTokenFieldDelegate protocol.
Added CPTokenFieldDelegate protocol.
Also, now, delegate methods are called as we are used to do it in Cappuccino
2014-03-27 17:43:07 -07:00
Alexandre Wilhelm 9b397245f8 New: Added CPRuleEditorDelegate protocol
Added CPRuleEditorDelegate protocol.
Also, now, delegate methods are called as we are used to do it in Cappuccino
2014-03-27 15:25:38 -07:00
Alexandre Wilhelm 59b80ab8f6 New: Added CPComboDelegate protocol 2014-03-27 14:50:25 -07:00
Alexandre Wilhelm 18258877a8 New: Added protocol CPMenuDelegate
Added protocol CPMenuDelegate.
Also, now, delegate methods are called as we are used to do it in Cappuccino
2014-03-27 14:17:34 -07:00
Alexandre Wilhelm e2b12c730e Fixed: param of setDelegate: does not conform to protocol CPImageDelegate 2014-03-27 13:55:42 -07:00
Alexandre Wilhelm 0a85b4b383 New: Added protocol CPImageDelegate.
Added protocol CPImageDelegate.
Also, now, delegate methods are called as we are used to do it in Cappuccino
2014-03-27 13:52:59 -07:00
Alexandre Wilhelm d5af9806ea New: Added protocol CPSoundDelegate
Added protocol CPSoundDelegate.
Also, now, delegate methods are called as we are used to do it in Cappuccino
2014-03-27 13:33:32 -07:00
Alexandre Wilhelm 104761d064 Fixed: AppController of CPAnimationTest does not implement protocol CPAnimationDelegate 2014-03-27 12:21:38 -07:00
Alexandre Wilhelm 59065418ac Fixed: CPAnimationDelegate protocol methods are required 2014-03-27 12:19:51 -07:00
Alexandre Wilhelm 7ccdc50637 New: Added protocol CPAnimationDelegate
Added protocol CPAnimationDelegate.
Also, now, delegate methods are called as we are used to do it in Cappuccino

Test app in Tests/Manual/CPAnimationTest.
2014-03-27 12:11:22 -07:00
Alexandre Wilhelm f8ae61058e New: Added CPSplitViewDelegate protocol
Added the CPSplitViewDelegate protocol.
Also, now, delegate methods are called as we are used to do it in Cappuccino
2014-03-26 17:14:27 -07:00
Alexandre Wilhelm cc9d896cf8 New: Added CPPopoverDelegate protocole
Added CPPopopverDelegate protocole
2014-03-25 21:03:00 -07:00
Ashley Williams c5637ea29b Formatting: Fixed formatting in _CPPopoverWindow
Refs #2137
2014-03-24 05:08:36 -07:00
Ashley Williams be3c4abbce Fixed: CPPopover not closing in some browsers
In browsers without support for _DOMElement.removeEventListener CPPopover
throws an exception when closing, and the popover is not removed. This fix
checks for support implicitly using the _browserAnimates variable.
2014-03-23 21:05:56 -07:00
Ashley Williams d5c48567b3 Test: added manual test case to check for placeholder.
Refs #2049
2014-03-23 17:05:57 -07:00
Ashley Williams 5b4e7df856 Fixed: show placeholder string while editing empty CPTextField
Previously, selecting an empty text field hid the contentView, causing the placeholder string to dissapear. This fix leaves the contentView of the text field visible when the internal _stringValue is nil or empty.

Fixes #2049
2014-03-23 16:07:54 -07:00
Antoine Mercadal 23f04b3d09 Merge pull request #2080 from Dogild/CPButtonStateBezelStyleRoundRect-Theme
Fixed: CPRoundRectBezelStyle gives a CPNull ThemeState
2014-03-20 16:45:09 -07:00
Antoine Mercadal 050e3e86e3 Merge branch 'master' of https://github.com/cappuccino/cappuccino 2014-03-20 16:35:12 -07:00
Antoine Mercadal c21d0c64a0 FIXED: dependency to tusk
Previously, jake install was calling tusk to ensure installed packages are up to date, and was used to install the new build. As tusk and all that narwhal suite is deprecated and causes more and more problems, this patch:

 - removes the up-to-date check: it's very likely that no package will never be updated anymore
 - uses a local function to install the freshly build
2014-03-20 16:28:57 -07:00
Alexandre Wilhelm 970b176fbf New: Graphical CPDatePicker clicking on the arrows with key mask Command/Control/Alternate
Now when clicking on the arrows with the key mask Command/Control or Alternate change the date to 1 year or 10 years as in Cocoa.
2014-03-20 15:57:25 -07:00
Antoine Mercadal 9e918cc717 NEW: Ability to perform offline bootstraping
Previously, bootstrap.sh was always trying to fetch cappuccino-base from github. This patch provides a new option "--copy-local [PATH]" that will let the user give a path of a local copy of the cappuccino-base zip. This can be pretty useful in an automated build system that cannot always access the internet.
2014-03-20 15:23:47 -07:00
Mathieu Monney 4a31467afb FIXED: CPSegementedControl with nib2cib crashes
When having a CPSegmentedControl within a a XIB files, nib2cib crashes with the following error:

```
'undefined' is not an object (evaluating 'self._themeStates[aSegment].without')
```

This pull request fixes the problem by making sure that the drawBezel method is called with a valid segment index when accessing the themeState.

Reduction: https://dl.dropboxusercontent.com/u/14629300/BugCPSegmentedControl.zip
2014-03-17 10:46:39 +01:00
Alexandre Wilhelm 86f07245d4 Fixed: CPRoundRectBezelStyle gives a CPNull ThemeState
Previously with the CPRoundRectBezelStyle we got a CPNull themeState. Now we get an instance of ThemeState with the theme CPButtonStateBezelStyleRoundRect. CPButtonStateBezelStyleRoundRect is equal to CPThemeState("roundRect").
2014-03-11 13:18:26 -07:00
Alexander Ljungberg d51f179c2d Fixed: error when running some XML tests with rhino.
This problem causes error in Travis that are not errors with JSC.
2014-03-10 22:44:00 +00:00
Saikat Chakrabarti 974942a736 Fix OS X scrolling issue. Closes #2078. 2014-03-10 14:37:49 -07:00
Alexander Ljungberg 31d17cada7 Merge pull request #2077 from mockingbird/fix-cpcheckbutton-theme-bug
Fix bug with unsetThemeState + more tests.
2014-03-10 19:27:04 +00:00
Saikat Chakrabarti 647686e68e Fix CPViewTest 2014-03-10 12:17:23 -07:00
Alexander Ljungberg 959212a95f Merge pull request #2077 from mockingbird/fix-cpcheckbutton-theme-bug
Fix bug with unsetThemeState + more tests.
2014-03-10 17:55:03 +00:00
Saikat Chakrabarti 45df8c0f74 Fix bug with unsetThemeState + more tests. 2014-03-09 15:15:11 -07:00
Alexander Ljungberg 1dbd41a746 Fixed: error in Internet Explorer if Info.plist was served with wrong content type.
Without this fix, in Internet Explorer the plist parser would only receive an empty XML document for the main Info.plist (and any other such loaded documents) if the server did not provide the content type "text/xml".

This fix parses the XML correctly even if there is no such content type.

Fixes #2051.
2014-03-06 14:16:00 +00:00
Alexander Ljungberg 8c43f4f628 Fixed: theoretical error while skipping whitespace in XML plists.
This fix ensures the PLIST_FIRST_CHILD() code gets to run both statements in the XML parsing while loop.

There's no obvious way to trigger an error due to this bug, but better correct than wrong.

Refs #2051.
2014-03-06 14:13:22 +00:00
Alexander Ljungberg 633445883e Test: CFPropertyList.propertyListFromXML.
These tests validate some basic edge cases with the parsing of XML plists.

Refs #2051.
2014-03-06 14:09:18 +00:00
Alexander Ljungberg e6acc3c336 Fixed: missing var, minor tweaks.
Refs #2073.
2014-03-06 14:03:46 +00:00
Alexander Ljungberg 90b947a7da Merge pull request #2073 from mockingbird/set-backed-cptheme
Change CPThemes to use sets instead of bitmasks. Closes #2015.
2014-03-06 12:25:47 +00:00
Saikat Chakrabarti b6b4015a82 Introduce .and and .without syntax for ThemeStates. 2014-03-01 23:26:20 -08:00
Saikat Chakrabarti 2fd8940c02 Allow array arguments to various methods that take ThemeStates 2014-03-01 23:11:24 -08:00
Saikat Chakrabarti 7408710761 Move placement of CPThemeStates cache to above the cache method for clarity. 2014-02-28 11:14:46 -08:00
Alexander Ljungberg e4a4dd3219 Merge pull request #2073 from mockingbird/set-backed-cptheme
Change CPThemes to use sets instead of bitmasks. Closes #2015.
2014-02-28 16:56:20 +00:00
Saikat Chakrabarti 745ad7cc34 Clean up the interface a bit to consolidate ThemeState methods onto one object. Keep CPThemeState as just a helper function. 2014-02-26 13:11:43 -08:00
cacaodev 821f8fea6f FIXED: Error when binding several objects to the same objectController.selection.keyPath and objectController selection changes. Fixes issue #2039 2014-02-26 15:07:44 +01:00
Saikat Chakrabarti b0d90bb612 ThemeState is a string now instead of an int on a CPView 2014-02-23 16:03:56 -08:00
daboe01 b439e0cfa0 symbolic constant 2014-02-22 20:33:17 +01:00
Saikat Chakrabarti 68952b273b Add a bunch of unit tests for CPTheme.j 2014-02-21 14:30:09 -08:00
Saikat Chakrabarti df148e4946 Fix a small typo in CPTheme.j themestate caching 2014-02-21 14:29:31 -08:00
Saikat Chakrabarti 8b2f2fe24d Add new unit tests for CPView 2014-02-21 13:11:08 -08:00
Martin Carlberg ee668df440 Fixed: Ivars with accessors in a Category failed with duplicate ivar error 2014-02-21 12:27:52 +01:00
Udo Schneider 6cae917058 New: Added bidirectional CPLevelIndicator behaviour
Depending on whether min < max or max > min CPLevelIndicator changes the order of the normal/warning/critical color. This commit enables this behavior for both cases.
2014-02-21 08:43:00 +01:00
Saikat Chakrabarti cf99a7bf18 Fix bug that was turning dictionary keys into objects 2014-02-20 18:14:01 -08:00
Saikat Chakrabarti 727b519750 Remove unused method in CPTheme 2014-02-20 18:09:47 -08:00
Saikat Chakrabarti 861d093d80 All ThemeStates always have at least one state - the normal state 2014-02-20 17:52:16 -08:00
Saikat Chakrabarti c3d2decdec Fix bugs with CPThemeAttribute encoding and decoding 2014-02-20 17:30:28 -08:00
Saikat Chakrabarti d862d701f3 Add note to ThemeState object about it being private 2014-02-20 17:30:28 -08:00
Saikat Chakrabarti 883c4a185d Some cleanup of CPSegmentedControl.j 2014-02-20 17:30:28 -08:00
Saikat Chakrabarti 7eb35ef33d Clarify documentation for CPThemeState() 2014-02-20 17:30:28 -08:00
Saikat Chakrabarti 1563b0bf55 Get all tests to pass 2014-02-20 17:30:28 -08:00
Saikat Chakrabarti bad731c86f Fix subtracting theme states 2014-02-20 17:30:28 -08:00
Saikat Chakrabarti 5309cc5916 Change CPTheme implementation to fix how searching for a matching theme works 2014-02-20 17:30:28 -08:00
Saikat Chakrabarti f8ef6ab397 Fix accidental semicolon 2014-02-20 17:30:27 -08:00
Saikat Chakrabarti 9e61991ad2 Fix bug when setting themeStates in a themeAttribute 2014-02-20 17:30:27 -08:00
Saikat Chakrabarti c644e8a30f Change CPTheme to be hash-backed to make it a bit faster 2014-02-20 17:30:27 -08:00
Saikat Chakrabarti 45a237af16 Handle null inputs for subtracting CPThemes. 2014-02-20 17:30:27 -08:00
Saikat Chakrabarti 0450fdb542 Get jaking working 2014-02-20 17:30:27 -08:00
Saikat Chakrabarti 7d304fbd51 First round of changes to change theming system to use arrays and not bitmasks as their underlying datatype 2014-02-20 17:30:27 -08:00
Antoine Mercadal 33df895709 Merge pull request #2070 from primalmotion/doxygen-theme-refresh
NEW: Doxygen theme refresh [+3]
2014-02-20 12:25:20 -08:00
Antoine Mercadal 22ef6ca56a Merge pull request #2067 from Dogild/DatePickerOneDigit
Fixed: Textual CPDatePicker issue with number of digit
2014-02-17 15:34:26 -08:00
Antoine Mercadal 2e015c9816 NEW: Doxygen theme refresh
See screenshots attached to the PR for example.
2014-02-17 15:15:57 -08:00
Alos 1d40b5010e Merge branch 'layoutSubview-fix' of github.com:Alos/cappuccino into layoutSubview-fix
Conflicts:
	AppKit/CPTabView.j
2014-02-16 23:28:57 -06:00
Alos 9d25f1c073 Fixed layoutSubviews
Added missing setNeedsLayout
2014-02-16 23:25:22 -06:00
Alos 2a8de9cb28 Merge branch 'layoutSubview-fix' of github.com:Alos/cappuccino into layoutSubview-fix 2014-02-16 23:18:24 -06:00
Alos 67767ede17 Fixed layoutSubviews
Added missing setNeedsLayout
2014-02-16 23:16:38 -06:00
Alos 03db4d73ad Merge branch 'layoutSubview-fix' of github.com:Alos/cappuccino into layoutSubview-fix
Conflicts:
	AppKit/CPTabView.j
2014-02-16 23:07:36 -06:00
Alos fcb1f4665f Fixed an ugly merge 2014-02-16 22:38:41 -06:00
Alexander Ljungberg 77ea0d3ea6 Merge pull request #2069 from Dogild/PreprocessBrew
Fixed: Wrong link to install homebrew
2014-02-13 22:34:32 +00:00
Alexandre Wilhelm 23ff035eb3 Fixed: Wrong link to install homebrew
Previously the link to install homebrew was wrong.
2014-02-13 13:38:36 -08:00
Alexander Ljungberg 9906173a3f Merge pull request #2066 from CarlRosell/master
Fixed: Broken Documentation.
2014-02-13 12:48:21 +00:00
Alexander Ljungberg c6dd18ce40 Fixed: typo. 2014-02-13 12:41:20 +00:00
Alexander Ljungberg a31ad2c367 Fixed: CPAttributedString isEqual: despite attribute differences.
As soon as a range reached the end of the string the equality test would end with a YES, without even comparing the final attribute dict.
2014-02-13 12:41:14 +00:00
Alexander Ljungberg 7e20422e20 Test: CPAttributedString coding. 2014-02-13 12:17:55 +00:00
Alexander Ljungberg bd2f63c232 Improve CPAttributedString coding.
Refs #2050.
2014-02-13 12:17:37 +00:00
Alexander Ljungberg 532a874ba6 Merge pull request #2050 from daboe01/NEW--archiving-for-CPAttributedString
NEW: CPCoding for CPAttributedString
2014-02-12 22:02:18 +00:00
Alexander Ljungberg 48fa46e0d5 Formatting: CPAttributedString.
Refs #2045.
2014-02-12 21:57:44 +00:00
Alexander Ljungberg f72119f1b6 Formatting: CPAttributedStringTest.
Refs #2045.
2014-02-12 21:57:44 +00:00
daboe01andAlexander Ljungberg 3063d53a2b more formatting 2014-02-12 21:57:44 +00:00
daboe01andAlexander Ljungberg e4163c5da4 formatting 2014-02-12 21:57:44 +00:00
daboe01andAlexander Ljungberg a34ae45b05 formatting 2014-02-12 21:57:44 +00:00
daboe01andAlexander Ljungberg d8e4f1150e more protection against edge cases 2014-02-12 21:57:44 +00:00
daboe01andAlexander Ljungberg c2534ae6da unit-tests + simplification 2014-02-12 21:57:44 +00:00
daboe01andAlexander Ljungberg 342ea97406 yet another minor fix 2014-02-12 21:57:43 +00:00
daboe01andAlexander Ljungberg 6f66c06111 fixed one last minor glitch 2014-02-12 21:57:43 +00:00
daboe01andAlexander Ljungberg aaeffe61a6 editing fix 2014-02-12 21:57:43 +00:00
daboe01andAlexander Ljungberg f5daa96c8e minor fix 2014-02-12 21:57:43 +00:00
daboe01andAlexander Ljungberg 67fed5f3d7 fixing editing semantics 2014-02-12 21:57:43 +00:00
Antoine Mercadal 4531b017b3 Merge pull request #2054 from cacaodev/CPPredicateEditor-dates
Fixed: support for dates (CPDatePicker) in CPPredicateEditor
2014-02-11 10:53:15 -08:00
Antoine Mercadal 101a03c38d Merge pull request #2044 from krodelin/fix-CPNumber-numberWithBool
Fixed: CPNumber>>numberWithBool: breaks CPComparisonPredicate
2014-02-11 10:51:43 -08:00
Alexandre Wilhelm 8147f648a1 Fixed: Textual CPDatePicker issue with number of digit
Previously, the day/month/hour of the textual datePicker had always two digits, even when the number was under 10. For instance the day 8 was displayed 08.
Now it's like in cocoa, 8 is displayed 8.

Fixes #2059
2014-02-07 16:36:05 -08:00
Carl Rosell 30b1fa9c5b Docs: Added @class to make_headers documentation, 2014-02-05 10:05:58 +01:00
Carl Rosell fa66c2692f Fixed: Broken Documentation. 2014-02-05 09:29:25 +01:00
Antoine Mercadal 1814f6b545 FIXED: Crash when clicking on an empty CPTableView with variable row height.
Previously, clicking anywhere in an empty CPTableView with variable row height was causing a crash due to the code trying to find the latest cached row height. This patch adds a check to ensure the last cached row height is not nil.
2014-01-23 12:56:39 -08:00
Udo Schneider 9d04ad5097 Merge branch 'refactor-locale' into fix-CPNumber-numberWithBool 2014-01-23 21:46:09 +01:00
cacaodev 93b48ba973 Fixed: support for dates (CPDatePicker) in CPPredicateEditor
Before this commit, row templates and views belo,ging to them were copied via archiving/unarchiving.
This was causing problems when the view was not completely CPCoding compliant, like for CPDatePicker.

With this commit, template views use CPCopying (-copy method) when available.
Also added CPCopying for CPDatePicker as a category in CPPredicateEditor.

Test: in CPPredicateEditorTest, on the right panel, choose a keypath, operator, and select 'Dates' in the popup for the right expression.

Fixes #2041
2014-01-17 10:49:52 +01:00
Antoine Mercadal 047983d7bf Merge pull request #2052 from Dogild/CPDatePickerRefactor
Fixed : CPDatePicker textual issues
2014-01-14 16:04:17 -08:00
Alexandre Wilhelm ebccbf28a7 Fixed: issues with timeZone
This PR fixes several issues with the timeZone.
It also changes the way to "calculate" the date of the textual datePicker.
2014-01-14 15:12:10 -08:00
Alexandre Wilhelm 1dc84f9b58 Fixed: issue with _dateWithTimeZone when timeZone is null
Fixed the private method _dateWithTimeZone when aTimeZone is null
2014-01-14 15:10:55 -08:00
Antoine Mercadal 35f3987803 Merge pull request #2048 from mrcarlberg/cpdateformatter_relative_dont_work_in_jan
Fixed: RelativeDateFormating didn't work in January
2014-01-14 15:01:28 -08:00
Antoine Mercadal b6bd132066 Merge pull request #2037 from Dogild/protocolToolbar
New : Added protocol CPToolbarDelegate
2014-01-14 14:49:26 -08:00
Antoine Mercadal 3ce2f28303 Merge pull request #2036 from Dogild/protocolTabView
New : Added CPTabViewDelegate protocol
2014-01-14 14:48:59 -08:00
Antoine Mercadal 0d9cda8a85 Merge pull request #2035 from Dogild/protocolOutlineView
New : Added protocols CPOutlineViewDelegate and CPOutlineViewDataSource
2014-01-14 14:48:44 -08:00
Antoine Mercadal f2decc09a5 Merge pull request #2034 from Dogild/protocolApplication
New : Added CPApplicationDelegate protocol
2014-01-14 14:48:31 -08:00
Antoine Mercadal b1c55b23ee Merge pull request #2033 from Dogild/protocolCollectionView
New: Added CPCollectionViewDelegate protocol
2014-01-14 14:48:14 -08:00
Antoine Mercadal 4622600ab0 Merge pull request #2031 from Dogild/protocolTableView
New : Added protocols CPTableViewDelegate and CPTableViewDataSource
2014-01-14 14:47:39 -08:00
Antoine Mercadal 396358d4e5 Merge pull request #2032 from Dogild/protocolAlert
New : Added protocol CPAlertDelegate
2014-01-14 14:47:19 -08:00
Alexandre Wilhelm 8b975f50dd Fixed : CPDatePicker textual issues
This PR fixes several issues about the textual CPDatePicker :
- Fixed the issue about keyView loop when not assigning the nextKeyView
- Changed the behavior of the component when editing or deleting the date. It works as in cocoa now.
- Fixed bug about frameSize of each component when editing
- Fixed bug about NaN or null values
- Added optimization
- Refactoring the code
2014-01-10 08:52:25 -08:00
daboe01 a1ea371c73 NEW: CPCoding for CPAttributedString 2014-01-10 12:26:52 +01:00
Martin Carlberg acd5442246 Fixed: RelativeDateFormating didn't work in January and was inaccurate for some time intervals around when daylight saving time changed. 2014-01-09 17:16:05 +01:00
Udo Schneider d176dd0623 Fixed: CPNumber>>numberWithBool: breaks CPComparisonPredicate
Commit df2be92 breaks CPComparisonPredicate if one side of the comparison is a property which returns a BOOL.

CPPredicateParser parses literal BOOLs (YES/NO) into 0/1 using CPNumber>>numberWithBool:. CPComparisonPredicate however does not cast a BOOL from a property using numberWithBool:. E.g.

[[YES,NO] filteredArrayUsingPredicate:[CPPredicate predicateWithFormat:'self = YES']]
used to return [true], now it returns [].

This fix addresses the issue by "typecasting" the lhs/rhs values to numbers using CPNumber>>numberWithBool: if they are of type boolean.

Fixes #2028
2013-12-27 18:30:15 +01:00
Alexandre Wilhelm 68310bb479 Fixed: objectValueForTableColumn and numberOfRowsInTableView are required methods 2013-12-10 11:01:49 -08:00
Alexandre Wilhelm e822966464 Fixed: removed unused test case 2013-12-10 11:00:47 -08:00
Alexander Ljungberg febce68bc8 Test: don't run Travis setup quietly to make it easier to track setup errors. 2013-12-09 17:13:43 +00:00
Alexander Ljungberg fadffeedca New: make bootstrap.sh use Github with SSL.
This is the default for Github now and accessing the old bare http URL just causes a redirect to https.
2013-12-09 17:12:52 +00:00
Alexander Ljungberg 2fc501fe59 Fixed: CPDateFormatter stringFromDate:"" did not return a default date.
In Cocoa formatting an empty string actually results in a particular date. For consistency we should handle an empty string the same way.

Refs #2030.
2013-12-09 16:58:55 +00:00
Alexander Ljungberg 21aac76ba2 Fixed: CPDateFormatter getObjectValue: with nil errorDescription crash.
Like for all formatters, a nil errorDescription just means we don't care about the error description if there is an error.

Fixes #2030.
2013-12-09 16:39:53 +00:00
Alexandre Wilhelm fa3ebf2ca7 Fixed: CPAlertDelegate protocol does not implement CPObject protocol 2013-12-09 01:24:51 -08:00
Alexandre Wilhelm d2bf2539b5 Fixed: CPApplicationDelegate protocol does not implement CPObject protocol 2013-12-09 01:24:03 -08:00
Alexandre Wilhelm 8a0acedc94 Fixed: CPCollectionViewDelegate protocol does not implement CPObject protocol 2013-12-09 01:23:14 -08:00
Alexandre Wilhelm 11e5cd4f84 Fixed: CPOutlineViewDelegate and CPOutlineViewDataSource protocol do not implement CPObject protocol 2013-12-09 01:22:05 -08:00
Alexandre Wilhelm 27fdb3116c Fixed: CPTabViewDelegate protocol does not implement CPObject protocol 2013-12-09 01:21:01 -08:00
Alexandre Wilhelm b9c0c89a24 Fixed: CPTableViewDelegate and CPTableViewDataSource protocol do not implement CPObject protocol 2013-12-09 01:20:11 -08:00
Alexandre Wilhelm 8078889a09 Fixed: CPToolbarDelegate protocol do not implement CPObject protocol 2013-12-09 01:19:04 -08:00
Alexandre Wilhelm 5dd4266ccc New : Added protocol CPToolbarDelegate
This pr adds the protocol CPToolbarDelegate
Also, now, delegate methods are called as we are used to do it in Cappuccino.
2013-12-08 19:14:30 -08:00
Alexandre Wilhelm 7d14676bce New : Added CPTabViewDelegate protocol
This PR adds the CPTabViewDelegate protocol
2013-12-08 19:01:50 -08:00
Alexandre Wilhelm db113da121 New : Added protocols CPOutlineViewDelegate and CPOutlineViewDataSource
This PR add protocols CPOutlineViewDelegate and CPOutlineViewDataSource
2013-12-08 18:52:26 -08:00
Alexandre Wilhelm 5b2bfcef7d New : Added CPApplicationDelegate protocol
This PR add the protocol CPApplicationDelegate
2013-12-08 18:42:50 -08:00
Alexandre Wilhelm 4d266f4ad2 New: Added CPCollectionViewDelegate protocol
This PR adds the protocol CPCollectionViewDelegate.
Also, now the delegate methods are called like we are used to do it in Cappuccino.
2013-12-08 18:35:52 -08:00
Alexandre Wilhelm b81a325b28 Fixed : Remove unused method 2013-12-08 18:06:43 -08:00
Alexandre Wilhelm 09eca10eb6 New : Added protocol CPAlertDelegate
This PR adds the protocol CPAlertDelegate.
The delegate methods are called as we are used to in Cappuccino.
2013-12-08 18:01:06 -08:00
Alexandre Wilhelm 7b86465d7b New : Added protocols CPTableViewDelegate and CPTableViewDataSource
This PR adds protocols CPTableViewDelegate and CPTableViewDataSource

Unit test in Tests/AppKit/CPTableViewTest.j
2013-12-08 17:48:41 -08:00
daboe01 40da5a849d formatting 2013-11-19 20:14:35 +01:00
daboe01 ad170ed854 Fixed: scroll wheel speed is way to low in firefox
I increased scroll wheel speed to a sensible value
2013-10-29 17:33:12 +01:00
Glenn L. Austin 8d7c47a5e4 Fixed: Remove explicit use of Mac OS X 10.5 SDK, replace with "latest OS X"
The fontinfo and imagesize Xcode projects still explicitly refer to using the Mac OS X 10.5 SDK, while all other Xcode projects simply refer to the latest Mac OS X SDK, with no explicit OS version. This change modifies these two projects to mirror other Xcode projects in the project.

Fixes #1957
2013-06-28 10:26:44 -07:00
Sergio Felix d7b5382c32 Fixed: CPTabView will now update its tabs labels when the layoutSubviews method is called. Fixes 1926 2013-05-13 01:08:32 -05:00
387 changed files with 35611 additions and 22240 deletions
+2
View File
@@ -5,6 +5,7 @@ Demos
./Aristo
WebSite
.push-package
*.xcodeproj*
*.xcodeproj/*.pbxuser
*.xcodeproj/*.perspectivev3
xcuserdata/
@@ -15,3 +16,4 @@ xcuserdata/
Tests/Manual/**/*.xcodeproj
*.sublime-project
*.sublime-workspace
*.tm_properties
+1 -1
View File
@@ -1,6 +1,6 @@
language: node_js
node_js:
- 0.8
install: ./bootstrap.sh --quiet --noprompt --directory ./narwhal
install: ./bootstrap.sh --noprompt --directory ./narwhal
script: jake test
env: PATH="$TRAVIS_BUILD_DIR/narwhal/bin:$PATH" CAPP_BUILD="$TRAVIS_BUILD_DIR/Build" NARWHAL_ENGINE=rhino
+129 -63
View File
@@ -41,6 +41,10 @@
@global CPApp
var CPAlertDelegate_alertShowHelp_ = 1 << 0,
CPAlertDelegate_alertDidEnd_returnCode_ = 1 << 1;
@typedef CPAlertStyle
/*
@global
@group CPAlertStyle
@@ -59,6 +63,62 @@ CPCriticalAlertStyle = 2;
var bottomHeight = 71;
@protocol CPAlertDelegate <CPObject>
@optional
- (BOOL)alertShowHelp:(CPAlert)alert;
- (void)alertDidEnd:(CPAlert)theAlert returnCode:(int)returnCode;
@end
@implementation _CPAlertThemeView : CPView
+ (CPString)defaultThemeClass
{
return @"alert";
}
+ (CPDictionary)themeAttributes
{
return @{
@"size": CGSizeMake(400.0, 110.0),
@"content-inset": CGInsetMake(15, 15, 15, 50),
@"informative-offset": 6,
@"button-offset": 10,
@"message-text-alignment": CPJustifiedTextAlignment,
@"message-text-color": [CPColor blackColor],
@"message-text-font": [CPFont boldSystemFontOfSize:13.0],
@"message-text-shadow-color": [CPNull null],
@"message-text-shadow-offset": CGSizeMakeZero(),
@"informative-text-alignment": CPJustifiedTextAlignment,
@"informative-text-color": [CPColor blackColor],
@"informative-text-font": [CPFont systemFontOfSize:12.0],
@"informative-text-shadow-color": [CPNull null],
@"informative-text-shadow-offset": CGSizeMakeZero(),
@"image-offset": CGPointMake(15, 12),
@"information-image": [CPNull null],
@"warning-image": [CPNull null],
@"error-image": [CPNull null],
@"help-image": [CPNull null],
@"help-image-left-offset": 15,
@"help-image-pressed": [CPNull null],
@"suppression-button-y-offset": 0.0,
@"suppression-button-x-offset": 0.0,
@"default-elements-margin": 3.0,
@"suppression-button-text-color": [CPColor blackColor],
@"suppression-button-text-font": [CPFont systemFontOfSize:12.0],
@"suppression-button-text-shadow-color": [CPNull null],
@"suppression-button-text-shadow-offset": 0.0,
@"modal-window-button-margin-y": 0.0,
@"modal-window-button-margin-x": 0.0,
@"standard-window-button-margin-y": 0.0,
@"standard-window-button-margin-x": 0.0,
};
}
@end
/*!
@ingroup appkit
@@ -83,32 +143,33 @@ var bottomHeight = 71;
*/
@implementation CPAlert : CPObject
{
BOOL _showHelp @accessors(property=showsHelp);
BOOL _showSuppressionButton @accessors(property=showsSuppressionButton);
BOOL _showHelp @accessors(property=showsHelp);
BOOL _showSuppressionButton @accessors(property=showsSuppressionButton);
CPAlertStyle _alertStyle @accessors(property=alertStyle);
CPString _title @accessors(property=title);
CPView _accessoryView @accessors(property=accessoryView);
CPImage _icon @accessors(property=icon);
CPAlertStyle _alertStyle @accessors(property=alertStyle);
CPString _title @accessors(property=title);
CPView _accessoryView @accessors(property=accessoryView);
CPImage _icon @accessors(property=icon);
CPArray _buttons @accessors(property=buttons, readonly);
CPCheckBox _suppressionButton @accessors(property=suppressionButton, readonly);
CPArray _buttons @accessors(property=buttons, readonly);
CPCheckBox _suppressionButton @accessors(property=suppressionButton, readonly);
id _delegate @accessors(property=delegate);
id _modalDelegate;
SEL _didEndSelector @accessors(property=didEndSelector);
Function _didEndBlock;
id <CPAlertDelegate> _delegate @accessors(property=delegate);
id _modalDelegate;
SEL _didEndSelector @accessors(property=didEndSelector);
Function _didEndBlock;
unsigned _implementedDelegateMethods;
_CPAlertThemeView _themeView @accessors(property=themeView, readonly);
CPWindow _window @accessors(property=window, readonly);
int _defaultWindowStyle;
_CPAlertThemeView _themeView @accessors(property=themeView, readonly);
CPWindow _window @accessors(property=window, readonly);
int _defaultWindowStyle;
CPImageView _alertImageView;
CPTextField _informativeLabel;
CPTextField _messageLabel;
CPButton _alertHelpButton;
CPImageView _alertImageView;
CPTextField _informativeLabel;
CPTextField _messageLabel;
CPButton _alertHelpButton;
BOOL _needsLayout;
BOOL _needsLayout;
}
#pragma mark Creating Alerts
@@ -187,6 +248,30 @@ var bottomHeight = 71;
return self;
}
#pragma mark -
#pragma mark Delegate
/*!
Set the delegate of the receiver
@param aDelegate the delegate object for the alert.
*/
- (void)setDelegate:(id <CPAlertDelegate>)aDelegate
{
if (_delegate === aDelegate)
return;
_delegate = aDelegate;
_implementedDelegateMethods = 0;
if ([_delegate respondsToSelector:@selector(alertShowHelp:)])
_implementedDelegateMethods |= CPAlertDelegate_alertShowHelp_;
if ([_delegate respondsToSelector:@selector(alertDidEnd:returnCode:)])
_implementedDelegateMethods |= CPAlertDelegate_alertDidEnd_returnCode_;
}
#pragma mark Accessors
- (CPTheme)theme
@@ -219,7 +304,7 @@ var bottomHeight = 71;
[_themeView setValue:aValue forThemeAttribute:aName];
}
- (void)setValue:(id)aValue forThemeAttribute:(CPString)aName inState:(CPThemeState)aState
- (void)setValue:(id)aValue forThemeAttribute:(CPString)aName inState:(ThemeState)aState
{
[_themeView setValue:aValue forThemeAttribute:aName inState:aState];
}
@@ -696,8 +781,7 @@ var bottomHeight = 71;
*/
- (@action)_showHelp:(id)aSender
{
if ([_delegate respondsToSelector:@selector(alertShowHelp:)])
[_delegate alertShowHelp:self];
[self _sendDelegateAlertShowHelp];
}
/*
@@ -743,56 +827,38 @@ var bottomHeight = 71;
{
if (_didEndSelector)
objj_msgSend(_delegate, _didEndSelector, self, returnCode);
else if ([_delegate respondsToSelector:@selector(alertDidEnd:returnCode:)])
[_delegate alertDidEnd:self returnCode:returnCode];
else
[self _sendDelegateAlertDidEndReturnCode:returnCode];
}
}
@end
@implementation _CPAlertThemeView : CPView
+ (CPString)defaultThemeClass
@implementation CPAlert (CPAlertDelegate)
/*!
@ignore
Call the delegate alertDidEnd:returnCode
*/
- (void)_sendDelegateAlertDidEndReturnCode:(int)returnCode
{
return @"alert";
if (!(_implementedDelegateMethods & CPAlertDelegate_alertDidEnd_returnCode_))
return;
[_delegate alertDidEnd:self returnCode:returnCode];
}
+ (CPDictionary)themeAttributes
/*!
@ignore
Call the delegate alertShowHelp:
*/
- (BOOL)_sendDelegateAlertShowHelp
{
return @{
@"size": CGSizeMake(400.0, 110.0),
@"content-inset": CGInsetMake(15, 15, 15, 50),
@"informative-offset": 6,
@"button-offset": 10,
@"message-text-alignment": CPJustifiedTextAlignment,
@"message-text-color": [CPColor blackColor],
@"message-text-font": [CPFont boldSystemFontOfSize:13.0],
@"message-text-shadow-color": [CPNull null],
@"message-text-shadow-offset": CGSizeMakeZero(),
@"informative-text-alignment": CPJustifiedTextAlignment,
@"informative-text-color": [CPColor blackColor],
@"informative-text-font": [CPFont systemFontOfSize:12.0],
@"informative-text-shadow-color": [CPNull null],
@"informative-text-shadow-offset": CGSizeMakeZero(),
@"image-offset": CGPointMake(15, 12),
@"information-image": [CPNull null],
@"warning-image": [CPNull null],
@"error-image": [CPNull null],
@"help-image": [CPNull null],
@"help-image-left-offset": 15,
@"help-image-pressed": [CPNull null],
@"suppression-button-y-offset": 0.0,
@"suppression-button-x-offset": 0.0,
@"default-elements-margin": 3.0,
@"suppression-button-text-color": [CPColor blackColor],
@"suppression-button-text-font": [CPFont systemFontOfSize:12.0],
@"suppression-button-text-shadow-color": [CPNull null],
@"suppression-button-text-shadow-offset": 0.0,
@"modal-window-button-margin-y": 0.0,
@"modal-window-button-margin-x": 0.0,
@"standard-window-button-margin-y": 0.0,
@"standard-window-button-margin-x": 0.0,
};
if (!(_implementedDelegateMethods & CPAlertDelegate_alertShowHelp_))
return YES;
return [_delegate alertShowHelp:self];
}
@end
+111 -33
View File
@@ -26,25 +26,26 @@
@import "CAMediaTimingFunction.j"
/*
@global
@group CPAnimationCurve
*/
@protocol CPAnimationDelegate <CPObject>
@optional
- (BOOL)animationShouldStart:(CPAnimation)animation;
- (float)animation:(CPAnimation)animation valueForProgress:(float)progress;
- (void)animationDidEnd:(CPAnimation)animation;
- (void)animationDidStop:(CPAnimation)animation;
@end
var CPAnimationDelegate_animationShouldStart_ = 1 << 1,
CPAnimationDelegate_animation_valueForProgress_ = 1 << 2,
CPAnimationDelegate_animationDidEnd_ = 1 << 3,
CPAnimationDelegate_animationDidStop_ = 1 << 4;
@typedef CPAnimationCurve
CPAnimationEaseInOut = 0;
/*
@global
@group CPAnimationCurve
*/
CPAnimationEaseIn = 1;
/*
@global
@group CPAnimationCurve
*/
CPAnimationEaseOut = 2;
/*
@global
@group CPAnimationCurve
*/
CPAnimationLinear = 3;
ACTUAL_FRAME_RATE = 0;
@@ -80,17 +81,18 @@ ACTUAL_FRAME_RATE = 0;
*/
@implementation CPAnimation : CPObject
{
CPTimeInterval _lastTime;
CPTimeInterval _duration;
CPTimeInterval _lastTime;
CPTimeInterval _duration;
CPAnimationCurve _animationCurve;
CAMediaTimingFunction _timingFunction;
CPAnimationCurve _animationCurve;
CAMediaTimingFunction _timingFunction;
float _frameRate;
float _progress;
float _frameRate;
float _progress;
id _delegate;
CPTimer _timer;
id <CPAnimationDelegate> _delegate;
CPTimer _timer;
unsigned _implementedDelegateMethods;
}
/*!
@@ -214,9 +216,25 @@ ACTUAL_FRAME_RATE = 0;
Sets the animation's delegate.
@param aDelegate the new delegate
*/
- (void)setDelegate:(id)aDelegate
- (void)setDelegate:(id <CPAnimationDelegate>)aDelegate
{
if (_delegate === aDelegate)
return;
_delegate = aDelegate;
_implementedDelegateMethods = 0;
if ([_delegate respondsToSelector:@selector(animationShouldStart:)])
_implementedDelegateMethods |= CPAnimationDelegate_animationShouldStart_;
if ([_delegate respondsToSelector:@selector(animationDidEnd:)])
_implementedDelegateMethods |= CPAnimationDelegate_animationDidEnd_;
if ([_delegate respondsToSelector:@selector(animationDidStop:)])
_implementedDelegateMethods |= CPAnimationDelegate_animationDidStop_;
if ([_delegate respondsToSelector:@selector(animation:valueForProgress:)])
_implementedDelegateMethods |= CPAnimationDelegate_animation_valueForProgress_;
}
/*!
@@ -227,7 +245,7 @@ ACTUAL_FRAME_RATE = 0;
- (void)startAnimation
{
// If we're already animating, or our delegate stops us, animate.
if (_timer || _delegate && [_delegate respondsToSelector:@selector(animationShouldStart:)] && ![_delegate animationShouldStart:self])
if (_timer || ![self _sendDelegateAnimationShouldStart])
return;
if (_progress === 1.0)
@@ -236,7 +254,7 @@ ACTUAL_FRAME_RATE = 0;
ACTUAL_FRAME_RATE = 0;
_lastTime = new Date();
var timerInterval = _frameRate <= 0.0 ? 0.0001 : 1.0/_frameRate;
var timerInterval = _frameRate <= 0.0 ? 0.0001 : 1.0 / _frameRate;
_timer = [CPTimer scheduledTimerWithTimeInterval:timerInterval target:self selector:@selector(animationTimerDidFire:) userInfo:nil repeats:YES];
}
@@ -260,8 +278,7 @@ ACTUAL_FRAME_RATE = 0;
[_timer invalidate];
_timer = nil;
if ([_delegate respondsToSelector:@selector(animationDidEnd:)])
[_delegate animationDidEnd:self];
[self _sendDelegateAnimationDidEnd];
}
}
@@ -276,8 +293,7 @@ ACTUAL_FRAME_RATE = 0;
[_timer invalidate];
_timer = nil;
if ([_delegate respondsToSelector:@selector(animationDidStop:)])
[_delegate animationDidStop:self];
[self _sendDelegateAnimationDidStop];
}
/*!
@@ -313,8 +329,8 @@ ACTUAL_FRAME_RATE = 0;
{
var t = [self currentProgress];
if ([_delegate respondsToSelector:@selector(animation:valueForProgress:)])
return [_delegate animation:self valueForProgress:t];
if ([self _delegateRespondsToAnimationValueForProgress])
return [self _sendDelegateAnimationValueForProgress:t];
if (_animationCurve == CPAnimationLinear)
return t;
@@ -330,6 +346,68 @@ ACTUAL_FRAME_RATE = 0;
@end
@implementation CPAnimation (CPAnimationDelegate)
/*!
@ignore
Check if the delegate responds to animation:valueForProgress:
*/
- (BOOL)_delegateRespondsToAnimationValueForProgress
{
return _implementedDelegateMethods & CPAnimationDelegate_animation_valueForProgress_;
}
/*!
@ignore
Call delegate animationShouldStart:
*/
- (BOOL)_sendDelegateAnimationShouldStart
{
if (!(_implementedDelegateMethods & CPAnimationDelegate_animationShouldStart_))
return YES;
return [_delegate animationShouldStart:self];
}
/*!
@ignore
Call delegate animation:valueForProgress:
*/
- (float)_sendDelegateAnimationValueForProgress:(float)aProgress
{
if (!(_implementedDelegateMethods & CPAnimationDelegate_animation_valueForProgress_))
return aProgress;
return [_delegate animation:self valueForProgress:aProgress];
}
/*!
@ignore
Call delegate animationDidEnd:
*/
- (void)_sendDelegateAnimationDidEnd
{
if (!(_implementedDelegateMethods & CPAnimationDelegate_animationDidEnd_))
return;
[_delegate animationDidEnd:self];
}
/*!
@ignore
Call delegate animationDidStop:
*/
- (void)_sendDelegateAnimationDidStop
{
if (!(_implementedDelegateMethods & CPAnimationDelegate_animationDidStop_))
return;
[_delegate animationDidStop:self];
}
@end
// currently used function to determine time
// 1:1 conversion to js from webkit source files
// UnitBezier.h, WebCore_animation_AnimationBase.cpp
+43 -24
View File
@@ -37,10 +37,27 @@
@import "CPWindowController.j"
@import "_CPPopoverWindow.j"
@typedef CPModalSession
var CPMainCibFile = @"CPMainCibFile",
CPMainCibFileHumanFriendly = @"Main cib file base name",
CPEventModifierFlags = 0;
@protocol CPApplicationDelegate <CPObject>
@optional
- (void)applicationDidBecomeActive:(CPNotification)aNotification;
- (void)applicationDidChangeScreenParameters:(CPNotification)aNotification;
- (void)applicationDidFinishLaunching:(CPNotification)aNotification;
- (void)applicationDidResignActive:(CPNotification)aNotification;
- (void)applicationWillBecomeActive:(CPNotification)aNotification;
- (void)applicationWillFinishLaunching:(CPNotification)aNotification;
- (void)applicationWillResignActive:(CPNotification)aNotification;
- (void)applicationWillTerminate:(CPNotification)aNotification;
@end
/*!
@ingroup appkit
@class CPApplication
@@ -68,36 +85,36 @@ var CPMainCibFile = @"CPMainCibFile",
*/
@implementation CPApplication : CPResponder
{
CPArray _eventListeners;
int _eventListenerInsertionIndex;
CPArray _eventListeners;
int _eventListenerInsertionIndex;
CPEvent _currentEvent;
CPWindow _lastMouseMoveWindow;
CPEvent _currentEvent;
CPWindow _lastMouseMoveWindow;
CPArray _windows;
CPWindow _keyWindow;
CPWindow _mainWindow;
CPWindow _previousKeyWindow;
CPWindow _previousMainWindow;
CPArray _windows;
CPWindow _keyWindow;
CPWindow _mainWindow;
CPWindow _previousKeyWindow;
CPWindow _previousMainWindow;
CPDocumentController _documentController;
CPDocumentController _documentController;
CPModalSession _currentSession;
CPModalSession _currentSession;
//
id _delegate;
BOOL _finishedLaunching;
BOOL _isActive;
id <CPApplicationDelegate> _delegate;
BOOL _finishedLaunching;
BOOL _isActive;
CPDictionary _namedArgs;
CPArray _args;
CPString _fullArgsString;
CPDictionary _namedArgs;
CPArray _args;
CPString _fullArgsString;
CPImage _applicationIconImage;
CPImage _applicationIconImage;
CPPanel _aboutPanel;
CPPanel _aboutPanel;
CPThemeBlend _themeBlend @accessors(property=themeBlend);
CPThemeBlend _themeBlend @accessors(property=themeBlend);
}
/*!
@@ -143,7 +160,7 @@ var CPMainCibFile = @"CPMainCibFile",
react to these events.
@param aDelegate the delegate object
*/
- (void)setDelegate:(id)aDelegate
- (void)setDelegate:(id <CPApplicationDelegate>)aDelegate
{
if (_delegate == aDelegate)
return;
@@ -433,7 +450,7 @@ var CPMainCibFile = @"CPMainCibFile",
[CPPlatform activateIgnoringOtherApps:shouldIgnoreOtherApps];
_isActive = YES;
[self _willResignActive];
[self _didBecomeActive];
}
- (void)deactivate
@@ -971,7 +988,9 @@ var CPMainCibFile = @"CPMainCibFile",
return;
}
[aSheet._windowView _enableSheet:YES inWindow:aWindow];
if (![aWindow attachedSheet])
[aSheet._windowView _enableSheet:YES inWindow:aWindow];
[aWindow _attachSheet:aSheet modalDelegate:aModalDelegate didEndSelector:didEndSelector contextInfo:contextInfo];
}
@@ -1158,7 +1177,7 @@ var CPMainCibFile = @"CPMainCibFile",
[[self keyWindow] orderFront:self];
else if ([self mainWindow])
[[self mainWindow] makeKeyAndOrderFront:self];
else
else if ([self mainMenu])
[[self mainMenu]._menuWindow makeKeyWindow]; //FIXME this may not actually work
_previousKeyWindow = nil;
+1 -1
View File
@@ -23,7 +23,7 @@
*/
@import <Foundation/CPIndexSet.j>
@import <Foundation/CPPredicate.j>
@import "CPObjectController.j"
@import "CPKeyValueBinding.j"
+3
View File
@@ -24,6 +24,7 @@
@import "CPView.j"
// CPBoxType
@typedef CPBoxType
CPBoxPrimary = 0;
CPBoxSecondary = 1;
CPBoxSeparator = 2;
@@ -31,12 +32,14 @@ CPBoxOldStyle = 3;
CPBoxCustom = 4;
// CPBorderType
@typedef CPBorderType
CPNoBorder = 0;
CPLineBorder = 1;
CPBezelBorder = 2;
CPGrooveBorder = 3;
// CPTitlePosition
@typedef CPTitlePosition
CPNoTitle = 0;
CPAboveTop = 1;
CPAtTop = 2;
+256 -69
View File
@@ -20,6 +20,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@import <Foundation/CPObject.j>
@import <Foundation/CPIndexSet.j>
@import "CPControl.j"
@@ -30,40 +31,86 @@
@global CPApp
@protocol CPBrowserDelegate <CPObject>
@optional
- (BOOL)browser:(CPBrowser)browser acceptDrop:(id)info atRow:(CPInteger)row column:(CPInteger)column dropOperation:(CPTableViewDropOperation)dropOperation;
- (BOOL)browser:(CPBrowser)browser canDragRowsWithIndexes:(CPIndexSet)rowIndexes inColumn:(CPInteger)column withEvent:(CPEvent )event;
- (BOOL)browser:(CPBrowser)browser isLeafItem:(id)item;
- (BOOL)browser:(CPBrowser)browser shouldSelectRowIndexes:(CPIndexSet)anIndexSet inColumn:(CPInteger)column;
- (BOOL)browser:(CPBrowser)browser writeRowsWithIndexes:(CPIndexSet)rowIndexes inColumn:(CPInteger)column toPasteboard:(CPPasteboard)pasteboard;
- (CPDragOperation)browser:(CPBrowser)browser validateDrop:(id)info proposedRow:(CPInteger)row column:(CPInteger)column dropOperation:(CPTableViewDropOperation)dropOperation;
- (CPImage)browser:(CPBrowser)browser imageValueForItem:(id)anItem;
- (CPImage)browser:(CPBrowser)browser draggingImageForRowsWithIndexes:(CPIndexSet)rowIndexes inColumn:(CPInteger)column withEvent:(CPEvent)event offset:(CGPoint)dragImageOffset;
- (CPImage)browser:(CPBrowser)browser imageValueForItem:(id)item;
- (CPIndexSet)browser:(CPBrowser)browser selectionIndexesForProposedSelection:(CPIndexSet)proposedSelectionIndexes inColumn:(CPInteger)column;
- (CPInteger)browser:(CPBrowser)browser numberOfChildrenOfItem:(id)item;
- (CPView)browser:(CPBrowser)browser draggingViewForRowsWithIndexes:(CPIndexSet)rowIndexes inColumn:(CPInteger)column withEvent:(CPEvent)event offset:(CGPoint)dragImageOffset;
- (id)browser:(CPBrowser)browser child:(CPInteger)index ofItem:(id)item;
- (id)browser:(CPBrowser)browser objectValueForItem:(id)item;
- (id)rootItemForBrowser:(CPBrowser)browser;
- (void)browser:(CPBrowser)browser didChangeLastColumn:(CPInteger)oldLastColumn toColumn:(CPInteger)column;
- (void)browser:(CPBrowser)browser didResizeColumn:(CPInteger)column;
- (void)browserSelectionIsChanging:(CPBrowser)browser;
- (void)browserSelectionDidChange:(CPBrowser)browser;
@end
var CPBrowserDelegate_browser_acceptDrop_atRow_column_dropOperation_ = 1 << 1,
CPBrowserDelegate_browser_canDragRowsWithIndexes_inColumn_withEvent_ = 1 << 2,
CPBrowserDelegate_browser_isLeafItem_ = 1 << 3,
CPBrowserDelegate_browser_shouldSelectRowIndexes_inColumn_ = 1 << 4,
CPBrowserDelegate_browser_writeRowsWithIndexes_inColumn_toPasteboard_ = 1 << 5,
CPBrowserDelegate_browser_validateDrop_proposedRow_column_dropOperation_ = 1 << 6,
CPBrowserDelegate_browser_imageValueForItem_ = 1 << 7,
CPBrowserDelegate_browser_draggingImageForRowsWithIndexes_inColumn_withEvent_offset_ = 1 << 8,
CPBrowserDelegate_browser_imageValueForItem_ = 1 << 9,
CPBrowserDelegate_browser_selectionIndexesForProposedSelection_inColumn_ = 1 << 10,
CPBrowserDelegate_browser_numberOfChildrenOfItem_ = 1 << 11,
CPBrowserDelegate_browser_draggingViewForRowsWithIndexes_inColumn_withEvent_offset_ = 1 << 12,
CPBrowserDelegate_browser_child_ofItem_ = 1 << 13,
CPBrowserDelegate_browser_objectValueForItem_ = 1 << 14,
CPBrowserDelegate_rootItemForBrowser_ = 1 << 15,
CPBrowserDelegate_browser_didChangeLastColumn_toColumn_ = 1 << 16,
CPBrowserDelegate_browser_didResizeColumn_ = 1 << 17,
CPBrowserDelegate_browserSelectionIsChanging_ = 1 << 18,
CPBrowserDelegate_browserSelectionDidChange_ = 1 << 19;
/*!
@ingroup appkit
@class CPBrowser
*/
@implementation CPBrowser : CPControl
{
id _delegate;
CPString _pathSeparator;
id <CPBrowserDelegate> _delegate;
CPString _pathSeparator;
unsigned _implementedDelegateMethods;
CPView _contentView;
CPScrollView _horizontalScrollView;
CPView _prototypeView;
CPView _contentView;
CPScrollView _horizontalScrollView;
CPView _prototypeView;
CPArray _tableViews;
CPArray _tableDelegates;
CPArray _tableViews;
CPArray _tableDelegates;
id _rootItem;
id _rootItem;
BOOL _delegateSupportsImages;
BOOL _delegateSupportsImages;
SEL _doubleAction @accessors(property=doubleAction);
SEL _doubleAction @accessors(property=doubleAction);
BOOL _allowsMultipleSelection;
BOOL _allowsEmptySelection;
BOOL _allowsMultipleSelection;
BOOL _allowsEmptySelection;
Class _tableViewClass @accessors(property=tableViewClass);
Class _tableViewClass @accessors(property=tableViewClass);
float _rowHeight;
float _imageWidth;
float _leafWidth;
float _minColumnWidth;
float _defaultColumnWidth @accessors(property=defaultColumnWidth);
float _rowHeight;
float _imageWidth;
float _leafWidth;
float _minColumnWidth;
float _defaultColumnWidth @accessors(property=defaultColumnWidth);
CPArray _columnWidths;
CPArray _columnWidths;
}
+ (CPString)defaultThemeClass
@@ -137,10 +184,74 @@
[CPKeyedArchiver archivedDataWithRootObject:_prototypeView]];
}
- (void)setDelegate:(id)anObject
- (void)setDelegate:(id <CPBrowserDelegate>)anObject
{
if (_delegate === anObject)
return;
_delegate = anObject;
_delegateSupportsImages = [_delegate respondsToSelector:@selector(browser:imageValueForItem:)];
_implementedDelegateMethods = 0;
_delegateSupportsImages = NO;
if ([_delegate respondsToSelector:@selector(browser:acceptDrop:atRow:column:dropOperation:)])
_implementedDelegateMethods |= CPBrowserDelegate_browser_acceptDrop_atRow_column_dropOperation_;
if ([_delegate respondsToSelector:@selector(browser:canDragRowsWithIndexes:inColumn:withEvent:)])
_implementedDelegateMethods |= CPBrowserDelegate_browser_canDragRowsWithIndexes_inColumn_withEvent_;
if ([_delegate respondsToSelector:@selector(browser:isLeafItem:)])
_implementedDelegateMethods |= CPBrowserDelegate_browser_isLeafItem_;
if ([_delegate respondsToSelector:@selector(browser:shouldSelectRowIndexes:inColumn:)])
_implementedDelegateMethods |= CPBrowserDelegate_browser_shouldSelectRowIndexes_inColumn_;
if ([_delegate respondsToSelector:@selector(browser:writeRowsWithIndexes:inColumn:toPasteboard:)])
_implementedDelegateMethods |= CPBrowserDelegate_browser_writeRowsWithIndexes_inColumn_toPasteboard_;
if ([_delegate respondsToSelector:@selector(browser:validateDrop:proposedRow:column:dropOperation:)])
_implementedDelegateMethods |= CPBrowserDelegate_browser_validateDrop_proposedRow_column_dropOperation_;
if ([_delegate respondsToSelector:@selector(browser:imageValueForItem:)])
_implementedDelegateMethods |= CPBrowserDelegate_browser_imageValueForItem_;
if ([_delegate respondsToSelector:@selector(browser:draggingImageForRowsWithIndexes:inColumn:withEvent:offset:)])
_implementedDelegateMethods |= CPBrowserDelegate_browser_draggingImageForRowsWithIndexes_inColumn_withEvent_offset_;
if ([_delegate respondsToSelector:@selector(browser:imageValueForItem:)])
{
_delegateSupportsImages = YES;
_implementedDelegateMethods |= CPBrowserDelegate_browser_imageValueForItem_;
}
if ([_delegate respondsToSelector:@selector(browser:selectionIndexesForProposedSelection:inColumn:)])
_implementedDelegateMethods |= CPBrowserDelegate_browser_selectionIndexesForProposedSelection_inColumn_;
if ([_delegate respondsToSelector:@selector(browser:numberOfChildrenOfItem:)])
_implementedDelegateMethods |= CPBrowserDelegate_browser_numberOfChildrenOfItem_;
if ([_delegate respondsToSelector:@selector(browser:draggingViewForRowsWithIndexes:inColumn:withEvent:offset:)])
_implementedDelegateMethods |= CPBrowserDelegate_browser_draggingViewForRowsWithIndexes_inColumn_withEvent_offset_;
if ([_delegate respondsToSelector:@selector(browser:child:ofItem:)])
_implementedDelegateMethods |= CPBrowserDelegate_browser_child_ofItem_;
if ([_delegate respondsToSelector:@selector(browser:objectValueForItem:)])
_implementedDelegateMethods |= CPBrowserDelegate_browser_objectValueForItem_;
if ([_delegate respondsToSelector:@selector(rootItemForBrowser:)])
_implementedDelegateMethods |= CPBrowserDelegate_rootItemForBrowser_;
if ([_delegate respondsToSelector:@selector(browser:didChangeLastColumn:toColumn:)])
_implementedDelegateMethods |= CPBrowserDelegate_browser_didChangeLastColumn_toColumn_;
if ([_delegate respondsToSelector:@selector(browser:didChangeLastColumn:)])
_implementedDelegateMethods |= CPBrowserDelegate_browser_didResizeColumn_;
if ([_delegate respondsToSelector:@selector(browserSelectionIsChanging:)])
_implementedDelegateMethods |= CPBrowserDelegate_browserSelectionIsChanging_;
if ([_delegate respondsToSelector:@selector(browserSelectionDidChange:)])
_implementedDelegateMethods |= CPBrowserDelegate_browserSelectionDidChange_;
[self loadColumnZero];
}
@@ -162,10 +273,7 @@
- (void)loadColumnZero
{
if ([_delegate respondsToSelector:@selector(rootItemForBrowser:)])
_rootItem = [_delegate rootItemForBrowser:self];
else
_rootItem = nil;
_rootItem = [self _sendDelegateRootItemForBrowser];
[self setLastColumn:-1];
[self addColumn];
@@ -190,8 +298,7 @@
_tableViews = _tableViews.slice(0, indexPlusOne);
_tableDelegates = _tableDelegates.slice(0, indexPlusOne);
if ([_delegate respondsToSelector:@selector(browser:didChangeLastColumn:toColumn:)])
[_delegate browser:self didChangeLastColumn:oldValue toColumn:columnIndex];
[self _sendDelegateBrowserDidChangeLastColumn:oldValue toColumn:columnIndex];
[self tile];
}
@@ -366,7 +473,7 @@
- (BOOL)isLeafItem:(id)item
{
return [_delegate respondsToSelector:@selector(browser:isLeafItem:)] && [_delegate browser:self isLeafItem:item];
return (_implementedDelegateMethods & CPBrowserDelegate_browser_isLeafItem_) && [_delegate browser:self isLeafItem:item];
}
- (id)parentForItemsInColumn:(CPInteger)column
@@ -493,9 +600,7 @@
{
_columnWidths[column] = aWidth;
if ([_delegate respondsToSelector:@selector(browser:didResizeColumn:)])
[_delegate browser:self didResizeColumn:column];
[self _sendDelegateBrowserDidResizeColumn:column];
[self tile];
}
@@ -610,15 +715,12 @@
if (column < 0 || column > [self lastColumn] + 1)
return;
if ([_delegate respondsToSelector:@selector(browser:selectionIndexesForProposedSelection:inColumn:)])
indexSet = [_delegate browser:self selectionIndexesForProposedSelection:indexSet inColumn:column];
indexSet = [self _sendDelegateBrowserSelectionIndexesForProposedSelection:indexSet inColumn:column];
if ([_delegate respondsToSelector:@selector(browser:shouldSelectRowIndexes:inColumn:)] &&
![_delegate browser:self shouldSelectRowIndexes:indexSet inColumn:column])
if (![self _sendDelegateBrowserShouldSelectRowIndexes:indexSet inColumn:column])
return;
if ([_delegate respondsToSelector:@selector(browserSelectionIsChanging:)])
[_delegate browserSelectionIsChanging:self];
[self _sendDelegateBrowserSelectionIsChanging];
if (column > [self lastColumn])
[self addColumn];
@@ -629,8 +731,7 @@
[self scrollColumnToVisible:column];
if ([_delegate respondsToSelector:@selector(browserSelectionDidChange:)])
[_delegate browserSelectionDidChange:self];
[self _sendDelegateBrowserSelectionDidChange];
}
- (void)setBackgroundColor:(CPColor)aColor
@@ -652,30 +753,6 @@
[_tableViews makeObjectsPerformSelector:@selector(registerForDraggedTypes:) withObject:types];
}
- (BOOL)canDragRowsWithIndexes:(CPIndexSet)rowIndexes inColumn:(CPInteger)columnIndex withEvent:(CPEvent)dragEvent
{
if ([_delegate respondsToSelector:@selector(browser:canDragRowsWithIndexes:inColumn:withEvent:)])
return [_delegate browser:self canDragRowsWithIndexes:rowIndexes inColumn:columnIndex withEvent:dragEvent];
return YES;
}
- (CPImage)draggingImageForRowsWithIndexes:(CPIndexSet)rowIndexes inColumn:(CPInteger)columnIndex withEvent:(CPEvent)dragEvent offset:(CGPoint)dragImageOffset
{
if ([_delegate respondsToSelector:@selector(browser:draggingImageForRowsWithIndexes:inColumn:withEvent:offset:)])
return [_delegate browser:self draggingImageForRowsWithIndexes:rowIndexes inColumn:columnIndex withEvent:dragEvent offset:dragImageOffset];
return nil;
}
- (CPView)draggingViewForRowsWithIndexes:(CPIndexSet)rowIndexes inColumn:(CPInteger)columnIndex withEvent:(CPEvent)dragEvent offset:(CGPoint)dragImageOffset
{
if ([_delegate respondsToSelector:@selector(browser:draggingViewForRowsWithIndexes:inColumn:withEvent:offset:)])
return [_delegate browser:self draggingViewForRowsWithIndexes:rowIndexes inColumn:columnIndex withEvent:dragEvent offset:dragImageOffset];
return nil;
}
@end
@implementation CPBrowser (CPCoding)
@@ -860,8 +937,6 @@
@end
@import <Foundation/CPObject.j>
@implementation _CPBrowserTableDelegate : CPObject
{
CPBrowser _browser @accessors;
@@ -909,7 +984,7 @@
- (BOOL)tableView:(CPTableView)aTableView acceptDrop:(id)info row:(CPInteger)row dropOperation:(CPTableViewDropOperation)operation
{
if ([_delegate respondsToSelector:@selector(browser:acceptDrop:atRow:column:dropOperation:)])
if (_browser._implementedDelegateMethods & CPBrowserDelegate_browser_acceptDrop_atRow_column_dropOperation_)
return [_delegate browser:_browser acceptDrop:info atRow:row column:_index dropOperation:operation];
else
return NO;
@@ -917,7 +992,7 @@
- (CPDragOperation)tableView:(CPTableView)aTableView validateDrop:(id)info proposedRow:(CPInteger)row proposedDropOperation:(CPTableViewDropOperation)operation
{
if ([_delegate respondsToSelector:@selector(browser:validateDrop:proposedRow:column:dropOperation:)])
if (_browser._implementedDelegateMethods & CPBrowserDelegate_browser_validateDrop_proposedRow_column_dropOperation_)
return [_delegate browser:_browser validateDrop:info proposedRow:row column:_index dropOperation:operation];
else
return CPDragOperationNone;
@@ -925,7 +1000,7 @@
- (BOOL)tableView:(CPTableView)aTableView writeRowsWithIndexes:(CPIndexSet)rowIndexes toPasteboard:(CPPasteboard)pboard
{
if ([_delegate respondsToSelector:@selector(browser:writeRowsWithIndexes:inColumn:toPasteboard:)])
if (_browser._implementedDelegateMethods & CPBrowserDelegate_browser_writeRowsWithIndexes_inColumn_toPasteboard_)
return [_delegate browser:_browser writeRowsWithIndexes:rowIndexes inColumn:_index toPasteboard:pboard];
else
return NO;
@@ -980,7 +1055,7 @@
var imageView = [self layoutEphemeralSubviewNamed:@"image-view"
positioned:CPWindowAbove
relativeToEphemeralSubviewNamed:nil],
isHighlighted = [self themeState] & CPThemeStateSelectedDataView;
isHighlighted = [self hasThemeState:CPThemeStateSelectedDataView];
[imageView setImage: _isLeaf ? (isHighlighted ? _highlightedBranchImage : _branchImage) : nil];
[imageView setImageScaling:CPImageScaleNone];
@@ -1008,3 +1083,115 @@
}
@end
@implementation CPBrowser (CPBrowserDelegate)
/*!
@ignore
Call delegate rootItemForBrowser:
*/
- (id)_sendDelegateRootItemForBrowser
{
if (!(_implementedDelegateMethods & CPBrowserDelegate_rootItemForBrowser_))
return nil;
return [_delegate rootItemForBrowser:self];
}
/*!
@ignore
Call delegate browser:didChangeLastColumn:toColumn:
*/
- (void)_sendDelegateBrowserDidChangeLastColumn:(CPInteger)lastColumn toColumn:(CPInteger)newColumn
{
if (!(_implementedDelegateMethods & CPBrowserDelegate_browser_didChangeLastColumn_toColumn_))
return;
[_delegate browser:self didChangeLastColumn:lastColumn toColumn:newColumn];
}
/*!
@ignore
Call delegate browser:didResizeColumn:
*/
- (void)_sendDelegateBrowserDidResizeColumn:(CPInteger)column
{
if (!(_implementedDelegateMethods & CPBrowserDelegate_browser_didResizeColumn_))
return;
[_delegate browser:self didResizeColumn:column];
}
/*!
@ignore
Call delegate browserSelectionIsChanging:
*/
- (void)_sendDelegateBrowserSelectionIsChanging
{
if (!(_implementedDelegateMethods & CPBrowserDelegate_browserSelectionIsChanging_))
return;
[_delegate browserSelectionIsChanging:self];
}
/*!
@ignore
Call delegate browser:shouldSelectRowIndexes:inColumn:
*/
- (BOOL)_sendDelegateBrowserShouldSelectRowIndexes:(CPIndexSet)anIndexSet inColumn:(CPInteger)aColumn
{
if (!(_implementedDelegateMethods & CPBrowserDelegate_browser_shouldSelectRowIndexes_inColumn_))
return YES;
return [_delegate browser:self shouldSelectRowIndexes:anIndexSet inColumn:aColumn];
}
/*!
@ignore
Call delegate browser:selectionIndexesForProposedSelection:inColumn:
*/
- (CPIndexSet)_sendDelegateBrowserSelectionIndexesForProposedSelection:(CPIndexSet)anIndexSet inColumn:(CPInteger)aColumn
{
if (!(_implementedDelegateMethods & CPBrowserDelegate_browser_selectionIndexesForProposedSelection_inColumn_))
return anIndexSet;
return [_delegate browser:self selectionIndexesForProposedSelection:anIndexSet inColumn:aColumn];
}
/*!
@ignore
Call delegate browserSelectionDidChange
*/
- (void)_sendDelegateBrowserSelectionDidChange
{
if (!(_implementedDelegateMethods & CPBrowserDelegate_browserSelectionDidChange_))
return;
[_delegate browserSelectionDidChange:self];
}
- (BOOL)canDragRowsWithIndexes:(CPIndexSet)rowIndexes inColumn:(CPInteger)columnIndex withEvent:(CPEvent)dragEvent
{
if (_implementedDelegateMethods & CPBrowserDelegate_browser_canDragRowsWithIndexes_inColumn_withEvent_)
return [_delegate browser:self canDragRowsWithIndexes:rowIndexes inColumn:columnIndex withEvent:dragEvent];
return YES;
}
- (CPImage)draggingImageForRowsWithIndexes:(CPIndexSet)rowIndexes inColumn:(CPInteger)columnIndex withEvent:(CPEvent)dragEvent offset:(CGPoint)dragImageOffset
{
if (_implementedDelegateMethods & CPBrowserDelegate_browser_draggingImageForRowsWithIndexes_inColumn_withEvent_offset_)
return [_delegate browser:self draggingImageForRowsWithIndexes:rowIndexes inColumn:columnIndex withEvent:dragEvent offset:dragImageOffset];
return nil;
}
- (CPView)draggingViewForRowsWithIndexes:(CPIndexSet)rowIndexes inColumn:(CPInteger)columnIndex withEvent:(CPEvent)dragEvent offset:(CGPoint)dragImageOffset
{
if (_implementedDelegateMethods & CPBrowserDelegate_browser_draggingViewForRowsWithIndexes_inColumn_withEvent_offset_)
return [_delegate browser:self draggingViewForRowsWithIndexes:rowIndexes inColumn:columnIndex withEvent:dragEvent offset:dragImageOffset];
return nil;
}
@end
+23 -11
View File
@@ -29,8 +29,7 @@
@import "CPWindow_Constants.j"
/* @group CPBezelStyle */
// IB style
@typedef CPBezelStyle
CPRoundedBezelStyle = 1; // Push
CPRegularSquareBezelStyle = 2; // Bevel
CPThickSquareBezelStyle = 3;
@@ -49,6 +48,7 @@ CPHUDBezelStyle = -1;
/* @group CPButtonType */
@typedef CPButtonType
CPMomentaryLightButton = 0;
CPPushOnPushOffButton = 1;
CPToggleButton = 2;
@@ -72,13 +72,14 @@ CPPushInCellMask = CPPushInButtonMask;
CPChangeGrayCellMask = CPGrayButtonMask;
CPChangeBackgroundCellMask = CPBackgroundButtonMask;
CPButtonStateMixed = CPThemeState("mixed");
CPButtonStateBezelStyleRounded = CPThemeState("rounded");
CPButtonStateMixed = CPThemeState("mixed");
CPButtonStateBezelStyleRounded = CPThemeState("rounded");
CPButtonStateBezelStyleRoundRect = CPThemeState("roundRect");
// add all future correspondance between bezel styles and theme state here.
var CPButtonBezelStyleStateMap = @{
CPRoundedBezelStyle: CPButtonStateBezelStyleRounded,
CPRoundRectBezelStyle: [CPNull null],
CPRoundRectBezelStyle: CPButtonStateBezelStyleRoundRect,
};
/// @cond IGNORE
@@ -107,7 +108,6 @@ CPButtonImageOffset = 3.0;
// NS-style Display Properties
CPBezelStyle _bezelStyle;
CPControlSize _controlSize;
CPString _keyEquivalent;
unsigned _keyEquivalentModifierMask;
@@ -188,8 +188,6 @@ CPButtonImageOffset = 3.0;
- (void)_init
{
_controlSize = CPRegularControlSize;
_keyEquivalent = @"";
_keyEquivalentModifierMask = 0;
@@ -200,6 +198,20 @@ CPButtonImageOffset = 3.0;
[self setButtonType:CPMomentaryPushInButton];
}
#pragma mark -
#pragma mark Control Size
- (void)setControlSize:(CPControlSize)aControlSize
{
[super setControlSize:aControlSize];
if ([self isBordered])
[self _sizeToControlSize];
}
#pragma mark -
// Setting the state
/*!
Returns a Boolean value indicating whether the button allows a mixed state.
@@ -268,7 +280,7 @@ CPButtonImageOffset = 3.0;
break;
case CPOffState:
[self unsetThemeState:CPThemeStateSelected | CPButtonStateMixed | CPThemeStateHighlighted];
[self unsetThemeState:[CPThemeStateSelected, CPButtonStateMixed, CPThemeStateHighlighted]];
}
}
@@ -653,10 +665,10 @@ CPButtonImageOffset = 3.0;
*/
- (void)sizeToFit
{
[self layoutSubviews];
[self setFrameSize:[self _minimumFrameSize]];
[self layoutSubviews];
if ([self ephemeralSubviewNamed:@"content-view"])
[self layoutSubviews];
}
+38 -10
View File
@@ -26,7 +26,10 @@
@class CPSplitView
@global CPPopUpButtonStatePullsDown
@global CPKeyValueChangeOldKey
@global CPKeyValueChangeNewKey
@global CPKeyValueObservingOptionNew
@global CPKeyValueObservingOptionOld
@implementation CPButtonBar : CPView
{
@@ -129,10 +132,20 @@
- (void)setButtons:(CPArray)buttons
{
for (var i = [_buttons count] - 1; i >= 0; i--)
{
[_buttons[i] removeFromSuperview];
[_buttons[i] removeObserver:self forKeyPath:@"hidden"];
}
_buttons = [CPArray arrayWithArray:buttons];
for (var i = 0, count = [_buttons count]; i < count; i++)
for (var i = [_buttons count] - 1; i >= 0; i--)
{
[_buttons[i] addObserver:self forKeyPath:@"hidden" options:CPKeyValueObservingOptionNew | CPKeyValueObservingOptionOld context:nil];
[_buttons[i] setBordered:YES];
}
[self setNeedsLayout];
}
@@ -218,8 +231,15 @@
count = [buttonsNotHidden count];
while (count--)
if ([buttonsNotHidden[count] isHidden])
[buttonsNotHidden removeObject:buttonsNotHidden[count]];
{
var button = buttonsNotHidden[count];
if ([button isHidden])
{
[button removeFromSuperview];
[buttonsNotHidden removeObject:button];
}
}
var currentButtonOffset = _resizeControlIsLeftAligned ? CGRectGetMaxX([self bounds]) + 1 : -1,
bounds = [self bounds],
@@ -250,15 +270,15 @@
currentButtonOffset += width - 1;
}
[button setValue:normalColor forThemeAttribute:@"bezel-color" inState:CPThemeStateNormal | CPThemeStateBordered];
[button setValue:highlightedColor forThemeAttribute:@"bezel-color" inState:CPThemeStateHighlighted | CPThemeStateBordered];
[button setValue:disabledColor forThemeAttribute:@"bezel-color" inState:CPThemeStateDisabled | CPThemeStateBordered];
[button setValue:normalColor forThemeAttribute:@"bezel-color" inState:[CPThemeStateNormal, CPThemeStateBordered]];
[button setValue:highlightedColor forThemeAttribute:@"bezel-color" inState:[CPThemeStateHighlighted, CPThemeStateBordered, ]];
[button setValue:disabledColor forThemeAttribute:@"bezel-color" inState:[CPThemeStateDisabled, CPThemeStateBordered]];
[button setValue:textColor forThemeAttribute:@"text-color" inState:CPThemeStateBordered];
// FIXME shouldn't need this
[button setValue:normalColor forThemeAttribute:@"bezel-color" inState:CPThemeStateNormal | CPThemeStateBordered | CPPopUpButtonStatePullsDown];
[button setValue:highlightedColor forThemeAttribute:@"bezel-color" inState:CPThemeStateHighlighted | CPThemeStateBordered | CPPopUpButtonStatePullsDown];
[button setValue:disabledColor forThemeAttribute:@"bezel-color" inState:CPThemeStateDisabled | CPThemeStateBordered | CPPopUpButtonStatePullsDown];
[button setValue:normalColor forThemeAttribute:@"bezel-color" inState:[CPThemeStateNormal, CPThemeStateBordered, CPPopUpButtonStatePullsDown]];
[button setValue:highlightedColor forThemeAttribute:@"bezel-color" inState:[CPThemeStateHighlighted, CPThemeStateBordered, CPPopUpButtonStatePullsDown]];
[button setValue:disabledColor forThemeAttribute:@"bezel-color" inState:[CPThemeStateDisabled, CPThemeStateBordered, CPPopUpButtonStatePullsDown]];
[self addSubview:button];
}
@@ -274,6 +294,14 @@
}
}
- (void)observeValueForKeyPath:(CPString)keyPath ofObject:(id)object change:(CPDictionary)change context:(id)context
{
if ([change objectForKey:CPKeyValueChangeOldKey] == [change objectForKey:CPKeyValueChangeNewKey])
return;
[self setNeedsLayout];
}
- (void)setFrameSize:(CGSize)aSize
{
[super setFrameSize:aSize];
+24
View File
@@ -111,6 +111,30 @@ CPCheckBoxImageOffset = 4.0;
return startedTracking;
}
#pragma mark -
#pragma mark Override methods from CPButton
- (CGSize)_minimumFrameSize
{
var size = [super _minimumFrameSize],
contentView = [self ephemeralSubviewNamed:@"content-view"];
if (!contentView && [[self title] length])
{
var minSize = [self currentValueForThemeAttribute:@"min-size"],
maxSize = [self currentValueForThemeAttribute:@"max-size"];
// Here we always add the min size to the control which is the size of the view of the checkBox
size.width += minSize.width + CPCheckBoxImageOffset;
if (maxSize.width >= 0.0)
size.width = MIN(size.width, maxSize.width);
}
return size;
}
@end
@implementation _CPCheckBoxValueBinder : CPBinder
+5 -38
View File
@@ -46,49 +46,12 @@
return;
if (_documentView)
{
var defaultCenter = [CPNotificationCenter defaultCenter];
[defaultCenter
removeObserver:self
name:CPViewFrameDidChangeNotification
object:_documentView];
[defaultCenter
removeObserver:self
name:CPViewBoundsDidChangeNotification
object:_documentView];
[_documentView removeFromSuperview];
}
_documentView = aView;
if (_documentView)
{
[self addSubview:_documentView];
[self _observeDocumentView];
}
}
- (void)_observeDocumentView
{
var defaultCenter = [CPNotificationCenter defaultCenter];
[_documentView setPostsFrameChangedNotifications:YES];
[_documentView setPostsBoundsChangedNotifications:YES];
[defaultCenter
addObserver:self
selector:@selector(viewFrameChanged:)
name:CPViewFrameDidChangeNotification
object:_documentView];
[defaultCenter
addObserver:self
selector:@selector(viewBoundsChanged:)
name:CPViewBoundsDidChangeNotification
object:_documentView];
}
/*!
@@ -230,6 +193,11 @@
return [self scrollToPoint:CGPointMake(bounds.origin.x - deltaX, bounds.origin.y - deltaY)];
}
- (CGRect)documentVisibleRect
{
return [self convertRect:[self bounds] fromView:_documentView];
}
@end
@@ -244,7 +212,6 @@ var CPClipViewDocumentViewKey = @"CPScrollViewDocumentView";
// Don't call setDocumentView: here. It calls addSubview:, but it's A) not necessary since the
// view hierarchy is fully encoded and B) dangerous if the subview is not fully decoded.
_documentView = [aCoder decodeObjectForKey:CPClipViewDocumentViewKey];
[self _observeDocumentView];
}
return self;
+260 -81
View File
@@ -32,6 +32,34 @@
@import "CPPasteboard.j"
@import "CPView.j"
@class _CPCollectionViewDropIndicator
var CPCollectionViewDelegate_collectionView_acceptDrop_index_dropOperation_ = 1 << 0,
CPCollectionViewDelegate_collectionView_canDragItemsAtIndexes_withEvent_ = 1 << 1,
CPCollectionViewDelegate_collectionView_writeItemsAtIndexes_toPasteboard_ = 1 << 2,
CPCollectionViewDelegate_collectionView_dragTypesForItemsAtIndexes_ = 1 << 3,
CPCollectionViewDelegate_collectionView_dataForItemsAtIndexes_forType_ = 1 << 4,
CPCollectionViewDelegate_collectionView_validateDrop_proposedIndex_dropOperation_ = 1 << 5,
CPCollectionViewDelegate_collectionView_didDoubleClickOnItemAtIndex_ = 1 << 6,
CPCollectionViewDelegate_collectionView_menuForItemAtIndex_ = 1 << 7,
CPCollectionViewDelegate_collectionView_draggingViewForItemsAtIndexes_withEvent_offset = 1 << 8;
@protocol CPCollectionViewDelegate <CPObject>
@optional
- (BOOL)collectionView:(CPCollectionView)collectionView acceptDrop:(id)draggingInfo index:(CPInteger)index dropOperation:(CPCollectionViewDropOperation)dropOperation;
- (BOOL)collectionView:(CPCollectionView)collectionView canDragItemsAtIndexes:(CPIndexSet)indexes withEvent:(CPEvent)event;
- (BOOL)collectionView:(CPCollectionView)collectionView writeItemsAtIndexes:(CPIndexSet)indexes toPasteboard:(CPPasteboard)pasteboard;
- (CPArray)collectionView:(CPCollectionView)collectionView dragTypesForItemsAtIndexes:(CPIndexSet)indexes;
- (CPData)collectionView:(CPCollectionView)collectionView dataForItemsAtIndexes:(CPIndexSet)indices forType:(CPString)aType;
- (CPDragOperation)collectionView:(CPCollectionView)collectionView validateDrop:(id)draggingInfo proposedIndex:(CPInteger)proposedDropIndex dropOperation:(CPCollectionViewDropOperation)proposedDropOperation;
- (CPMenu)collectionView:(CPCollectionView)collectionView menuForItemAtIndex:(CPInteger)anIndex;
- (CPView)collectionView:(CPCollectionView)collectionView dragginViewForItemsAtIndexes:(CPIndexSet)indexes withEvent:(CPEvent)event offset:(CGPoint)dragImageOffset;
- (void)collectionView:(CPCollectionView)collectionView didDoubleClickOnItemAtIndex:(int)index;
@end
/*!
@ingroup appkit
@class CPCollectionView
@@ -42,10 +70,6 @@
@par Delegate Methods
@delegate - (void)collectionViewDidChangeSelection:(CPCollectionView)collectionView;
DEPRECATED: Please do not use.
@param collectionView the collection view who's selection changed
@delegate - (void)collectionView:(CPCollectionView)collectionView didDoubleClickOnItemAtIndex:(int)index;
Called when the user double-clicks on an item in the collection view.
@param collectionView the collection view that received the double-click
@@ -69,51 +93,52 @@ var HORIZONTAL_MARGIN = 2;
@implementation CPCollectionView : CPView
{
CPArray _content;
CPArray _items;
CPArray _content;
CPArray _items;
CPData _itemData;
CPCollectionViewItem _itemPrototype;
CPCollectionViewItem _itemForDragging;
CPMutableArray _cachedItems;
CPData _itemData;
CPCollectionViewItem _itemPrototype;
CPCollectionViewItem _itemForDragging;
CPMutableArray _cachedItems;
unsigned _maxNumberOfRows;
unsigned _maxNumberOfColumns;
unsigned _maxNumberOfRows;
unsigned _maxNumberOfColumns;
CGSize _minItemSize;
CGSize _maxItemSize;
CGSize _minItemSize;
CGSize _maxItemSize;
CPArray _backgroundColors;
CPArray _backgroundColors;
float _tileWidth;
float _tileWidth;
BOOL _isSelectable;
BOOL _allowsMultipleSelection;
BOOL _allowsEmptySelection;
CPIndexSet _selectionIndexes;
BOOL _isSelectable;
BOOL _allowsMultipleSelection;
BOOL _allowsEmptySelection;
CPIndexSet _selectionIndexes;
CGSize _itemSize;
CGSize _itemSize;
float _horizontalMargin;
float _verticalMargin;
float _horizontalMargin;
float _verticalMargin;
unsigned _numberOfRows;
unsigned _numberOfColumns;
unsigned _numberOfRows;
unsigned _numberOfColumns;
id _delegate;
id <CPCollectionViewDelegate> _delegate;
unsigned _implementedDelegateMethods;
CPEvent _mouseDownEvent;
CPEvent _mouseDownEvent;
BOOL _needsMinMaxItemSizeUpdate;
CGSize _storedFrameSize;
BOOL _needsMinMaxItemSizeUpdate;
CGSize _storedFrameSize;
BOOL _uniformSubviewsResizing @accessors(property=uniformSubviewsResizing);
BOOL _lockResizing;
BOOL _uniformSubviewsResizing @accessors(property=uniformSubviewsResizing);
BOOL _lockResizing;
CPInteger _currentDropIndex;
CPDragOperation _currentDragOperation;
CPInteger _currentDropIndex;
CPDragOperation _currentDragOperation;
_CPCollectionViewDropIndicator _dropView;
_CPCollectionViewDropIndicator _dropView;
}
- (id)initWithFrame:(CGRect)aFrame
@@ -168,6 +193,51 @@ var HORIZONTAL_MARGIN = 2;
[self setAutoresizingMask:0];
}
#pragma mark -
#pragma mark Delegate
/*!
Set the delegate of the receiver
@param aDelegate the delegate object for the collectionView.
*/
- (void)setDelegate:(id <CPCollectionViewDelegate>)aDelegate
{
if (_delegate === aDelegate)
return;
_delegate = aDelegate;
_implementedDelegateMethods = 0;
if ([_delegate respondsToSelector:@selector(collectionView:acceptDrop:index:dropOperation:)])
_implementedDelegateMethods |= CPCollectionViewDelegate_collectionView_acceptDrop_index_dropOperation_;
if ([_delegate respondsToSelector:@selector(collectionView:canDragItemsAtIndexes:withEvent:)])
_implementedDelegateMethods |= CPCollectionViewDelegate_collectionView_canDragItemsAtIndexes_withEvent_;
if ([_delegate respondsToSelector:@selector(collectionView:writeItemsAtIndexes:toPasteboard:)])
_implementedDelegateMethods |= CPCollectionViewDelegate_collectionView_writeItemsAtIndexes_toPasteboard_;
if ([_delegate respondsToSelector:@selector(collectionView:dragTypesForItemsAtIndexes:)])
_implementedDelegateMethods |= CPCollectionViewDelegate_collectionView_dragTypesForItemsAtIndexes_;
if ([_delegate respondsToSelector:@selector(collectionView:dataForItemsAtIndexes:forType:)])
_implementedDelegateMethods |= CPCollectionViewDelegate_collectionView_dataForItemsAtIndexes_forType_;
if ([_delegate respondsToSelector:@selector(collectionView:validateDrop:proposedIndex:dropOperation:)])
_implementedDelegateMethods |= CPCollectionViewDelegate_collectionView_validateDrop_proposedIndex_dropOperation_;
if ([_delegate respondsToSelector:@selector(collectionView:didDoubleClickOnItemAtIndex:)])
_implementedDelegateMethods |= CPCollectionViewDelegate_collectionView_didDoubleClickOnItemAtIndex_;
if ([_delegate respondsToSelector:@selector(collectionView:menuForItemAtIndex:)])
_implementedDelegateMethods |= CPCollectionViewDelegate_collectionView_menuForItemAtIndex_;
if ([_delegate respondsToSelector:@selector(collectionView:draggingViewForItemsAtIndexes:withEvent:offset:)])
_implementedDelegateMethods |= CPCollectionViewDelegate_collectionView_draggingViewForItemsAtIndexes_withEvent_offset;
}
/*!
Sets the item prototype to \c anItem
@param anItem the new item prototype.
@@ -395,12 +465,6 @@ var HORIZONTAL_MARGIN = 2;
var binderClass = [[self class] _binderClassForBinding:@"selectionIndexes"];
[[binderClass getBinding:@"selectionIndexes" forObject:self] reverseSetValueFor:@"selectionIndexes"];
if ([_delegate respondsToSelector:@selector(collectionViewDidChangeSelection:)])
{
CPLog.warn("The delegate method collectionViewDidChangeSelection: is deprecated and will be removed in a future version, please bind to selectionIndexes instead.");
[_delegate collectionViewDidChangeSelection:self];
}
}
/*!
@@ -545,7 +609,7 @@ var HORIZONTAL_MARGIN = 2;
height = MAX(height, numberOfRows * (_minItemSize.height + _verticalMargin));
var itemSizeHeight = FLOOR(height / numberOfRows);
var itemSizeHeight = FLOOR(height / numberOfRows) - _verticalMargin;
if (maxItemSizeHeight > 0)
itemSizeHeight = MIN(itemSizeHeight, maxItemSizeHeight);
@@ -755,8 +819,8 @@ var HORIZONTAL_MARGIN = 2;
- (void)mouseUp:(CPEvent)anEvent
{
if ([_selectionIndexes count] && [anEvent clickCount] == 2 && [_delegate respondsToSelector:@selector(collectionView:didDoubleClickOnItemAtIndex:)])
[_delegate collectionView:self didDoubleClickOnItemAtIndex:[_selectionIndexes firstIndex]];
if ([_selectionIndexes count] && [anEvent clickCount] == 2)
[self _sendDelegateDidDoubleClickOnItemAtIndex:[_selectionIndexes firstIndex]];
}
- (void)mouseDown:(CPEvent)anEvent
@@ -846,15 +910,6 @@ var HORIZONTAL_MARGIN = 2;
return _verticalMargin;
}
/*!
Sets the collection view's delegate
@param aDelegate the new delegate
*/
- (void)setDelegate:(id)aDelegate
{
_delegate = aDelegate;
}
/*!
Returns the collection view's delegate
*/
@@ -868,13 +923,13 @@ var HORIZONTAL_MARGIN = 2;
*/
- (CPMenu)menuForEvent:(CPEvent)theEvent
{
if (![[self delegate] respondsToSelector:@selector(collectionView:menuForItemAtIndex:)])
if (![self _delegateRespondsToCollectionViewMenuForItemAtIndex])
return [super menuForEvent:theEvent];
var location = [self convertPoint:[theEvent locationInWindow] fromView:nil],
index = [self _indexAtPoint:location];
return [_delegate collectionView:self menuForItemAtIndex:index];
return [self _sendDelegateMenuForItemAtIndex:index];
}
- (int)_indexAtPoint:(CGPoint)thePoint
@@ -932,7 +987,7 @@ var HORIZONTAL_MARGIN = 2;
*/
- (void)pasteboard:(CPPasteboard)aPasteboard provideDataForType:(CPString)aType
{
[aPasteboard setData:[_delegate collectionView:self dataForItemsAtIndexes:_selectionIndexes forType:aType] forType:aType];
[aPasteboard setData:[self _sendDelegateDataForItemsAtIndexes:_selectionIndexes forType:aType] forType:aType];
}
- (void)_createDropIndicatorIfNeeded
@@ -962,24 +1017,23 @@ var HORIZONTAL_MARGIN = 2;
(ABS(locationInWindow.y - mouseDownLocationInWindow.y) < 3))
return;
if (![_delegate respondsToSelector:@selector(collectionView:dragTypesForItemsAtIndexes:)])
if (![self _delegateRespondsToCollectionViewDragTypesForItemsAtIndexes])
return;
// If we don't have any selected items, we've clicked away, and thus the drag is meaningless.
if (![_selectionIndexes count])
return;
if ([_delegate respondsToSelector:@selector(collectionView:canDragItemsAtIndexes:withEvent:)] &&
![_delegate collectionView:self canDragItemsAtIndexes:_selectionIndexes withEvent:_mouseDownEvent])
if (![self _sendDelegateCanDragItemsAtIndexes:_selectionIndexes withEvent:_mouseDownEvent])
return;
// Set up the pasteboard
var dragTypes = [_delegate collectionView:self dragTypesForItemsAtIndexes:_selectionIndexes];
var dragTypes = [self _sendDelegateDragTypesForItemsAtIndexes:_selectionIndexes];
[[CPPasteboard pasteboardWithName:CPDragPboard] declareTypes:dragTypes owner:self];
var dragImageOffset = CGSizeMakeZero(),
view = [self _draggingViewForItemsAtIndexes:_selectionIndexes withEvent:_mouseDownEvent offset:dragImageOffset];
view = [self _sendDelegateDraggingViewForItemsAtIndexes:_selectionIndexes withEvent:_mouseDownEvent offset:dragImageOffset];
[view setFrameSize:_itemSize];
[view setAlphaValue:0.7];
@@ -996,14 +1050,6 @@ var HORIZONTAL_MARGIN = 2;
slideBack:YES];
}
- (CPView)_draggingViewForItemsAtIndexes:(CPIndexSet)indexes withEvent:(CPEvent)anEvent offset:(CGPoint)offset
{
if ([_delegate respondsToSelector:@selector(collectionView:draggingViewForItemsAtIndexes:withEvent:offset:)])
return [_delegate collectionView:self draggingViewForItemsAtIndexes:indexes withEvent:anEvent offset:offset];
return [self draggingViewForItemsAtIndexes:indexes withEvent:anEvent offset:offset];
}
- (CPView)draggingViewForItemsAtIndexes:(CPIndexSet)indexes withEvent:(CPEvent)event offset:(CGPoint)dragImageOffset
{
var idx = _content[[indexes firstIndex]];
@@ -1016,14 +1062,6 @@ var HORIZONTAL_MARGIN = 2;
return [_itemForDragging view];
}
- (BOOL)_canDragItemsAtIndexes:(CPIndexSet)indexes withEvent:(CPEvent)anEvent
{
if ([self respondsToSelector:@selector(collectionView:canDragItemsAtIndexes:withEvent:)])
return [_delegate collectionView:self canDragItemsAtIndexes:indexes withEvent:anEvent];
return YES;
}
- (CPDragOperation)draggingEntered:(id)draggingInfo
{
var dropIndex = -1,
@@ -1061,16 +1099,14 @@ var HORIZONTAL_MARGIN = 2;
var result = CPDragOperationMove,
dropIndex = [self _dropIndexForDraggingInfo:draggingInfo proposedDropOperation:dropOperation];
if ([_delegate respondsToSelector:@selector(collectionView:validateDrop:proposedIndex:dropOperation:)])
if ([self _delegateRespondsToCollectionViewValidateDropProposedIndexDropOperation])
{
var dropIndexRef2 = @ref(dropIndex);
result = [_delegate collectionView:self validateDrop:draggingInfo proposedIndex:dropIndexRef2 dropOperation:dropOperation];
result = [self _sendDelegateValidateDrop:draggingInfo proposedIndex:dropIndexRef2 dropOperation:dropOperation];
if (result !== CPDragOperationNone)
{
dropIndex = dropIndexRef2();
}
}
dropIndexRef(dropIndex);
@@ -1104,7 +1140,7 @@ Not supported. Use -collectionView:dataForItemsAtIndexes:fortype:
var result = NO;
if (_currentDragOperation && _currentDropIndex !== -1)
result = [_delegate collectionView:self acceptDrop:draggingInfo index:_currentDropIndex dropOperation:1];
result = [self _sendDelegateAcceptDrop:draggingInfo index:_currentDropIndex dropOperation:1];
[self draggingEnded:draggingInfo]; // Is this correct ?
@@ -1329,6 +1365,7 @@ Not supported. Use -collectionView:dataForItemsAtIndexes:fortype:
@end
@implementation CPCollectionView (Deprecated)
- (CGRect)rectForItemAtIndex:(int)anIndex
@@ -1349,6 +1386,148 @@ Not supported. Use -collectionView:dataForItemsAtIndexes:fortype:
@end
@implementation CPCollectionView (CPCollectionViewDelegate)
/*
@ignore
Return YES if the delegate implements collectionView:validateDrop:proposedIndex:dropOperation:
*/
- (BOOL)_delegateRespondsToCollectionViewValidateDropProposedIndexDropOperation
{
return _implementedDelegateMethods & CPCollectionViewDelegate_collectionView_validateDrop_proposedIndex_dropOperation_;
}
/*
@ignore
Return YES if the delegate implements collectionView:menuForItemAtIndex:
*/
- (BOOL)_delegateRespondsToCollectionViewMenuForItemAtIndex
{
return _implementedDelegateMethods & CPCollectionViewDelegate_collectionView_menuForItemAtIndex_;
}
/*
@ignore
Return YES if the delegate implements collectionView:dragTypesForItemsAtIndexes:
*/
- (BOOL)_delegateRespondsToCollectionViewDragTypesForItemsAtIndexes
{
return _implementedDelegateMethods & CPCollectionViewDelegate_collectionView_dragTypesForItemsAtIndexes_;
}
/*!
@ignore
Call delegate collectionView:acceptDrop:index:dropOperation:
*/
- (BOOL)_sendDelegateAcceptDrop:(id)draggingInfo index:(CPInteger)index dropOperation:(CPCollectionViewDropOperation)dropOperation
{
if (!(_implementedDelegateMethods & CPCollectionViewDelegate_collectionView_acceptDrop_index_dropOperation_))
return NO;
return [_delegate collectionView:self acceptDrop:draggingInfo index:index dropOperation:dropOperation];
}
/*!
@ignore
Call delegate collectionView:canDragItemsAtIndexes:withEvent:
*/
- (BOOL)_sendDelegateCanDragItemsAtIndexes:(CPIndexSet)indexes withEvent:(CPEvent)anEvent
{
if (!(_implementedDelegateMethods & CPCollectionViewDelegate_collectionView_canDragItemsAtIndexes_withEvent_))
return YES;
return [_delegate collectionView:self canDragItemsAtIndexes:indexes withEvent:anEvent];
}
/*!
@ignore
Call delegate collectionView:writeItemsAtIndexes:toPasteboard:
*/
- (BOOL)_sendDelegateWriteItemsAtIndexes:(CPIndexSet)indexes toPasteboard:(CPPasteboard)pasteboard
{
if (!(_implementedDelegateMethods & CPCollectionViewDelegate_collectionView_writeItemsAtIndexes_toPasteboard_))
return NO;
return [_delegate collectionView:self writeItemsAtIndexes:indexes toPasteboard:pasteboard];
}
/*!
@ignore
Call delegate collectionView:dragTypesForItemsAtIndexes:
*/
- (CPArray)_sendDelegateDragTypesForItemsAtIndexes:(CPIndexSet)indexes
{
if (!(_implementedDelegateMethods & CPCollectionViewDelegate_collectionView_dragTypesForItemsAtIndexes_))
return [];
return [_delegate collectionView:self dragTypesForItemsAtIndexes:indexes];
}
/*!
@ignore
Call delegate collectionView:dataForItemsAtIndexes:forType:
*/
- (CPData)_sendDelegateDataForItemsAtIndexes:(CPIndexSet)indexes forType:(CPString)aType
{
if (!(_implementedDelegateMethods & CPCollectionViewDelegate_collectionView_dataForItemsAtIndexes_forType_))
return nil;
return [_delegate collectionView:self dataForItemsAtIndexes:indexes forType:aType];
}
/*!
@ignore
Call delegate collectionView:validateDrop:proposedIndex:dropOperation:
*/
- (CPDragOperation)_sendDelegateValidateDrop:(id)draggingInfo proposedIndex:(CPInteger)proposedDropIndex dropOperation:(CPCollectionViewDropOperation)proposedDropOperation
{
if (!(_implementedDelegateMethods & CPCollectionViewDelegate_collectionView_validateDrop_proposedIndex_dropOperation_))
return CPDragOperationNone;
return [_delegate collectionView:self validateDrop:draggingInfo proposedIndex:proposedDropIndex dropOperation:proposedDropOperation];
}
/*!
@ignore
Call delegate collectionView:didDoubleClickOnItemAtIndex:
*/
- (void)_sendDelegateDidDoubleClickOnItemAtIndex:(int)index
{
if (!(_implementedDelegateMethods & CPCollectionViewDelegate_collectionView_didDoubleClickOnItemAtIndex_))
return;
return [_delegate collectionView:self didDoubleClickOnItemAtIndex:index];
}
/*!
@ignore
Call delegate collectionView:menuForItemAtIndex:
*/
- (void)_sendDelegateMenuForItemAtIndex:(CPInteger)anIndex
{
if (!(_implementedDelegateMethods & CPCollectionViewDelegate_collectionView_menuForItemAtIndex_))
return nil;
return [_delegate collectionView:self menuForItemAtIndex:anIndex];
}
/*!
@ignore
Call delegate draggingViewForItemsAtIndexes:withEvent:offset:
*/
- (CPView)_sendDelegateDraggingViewForItemsAtIndexes:(CPIndexSet)indexes withEvent:(CPEvent)anEvent offset:(CGPoint)dragImageOffset
{
if (!(_implementedDelegateMethods & CPCollectionViewDelegate_collectionView_draggingViewForItemsAtIndexes_withEvent_offset))
return [self draggingViewForItemsAtIndexes:indexes withEvent:anEvent offset:dragImageOffset];
return [_delegate collectionView:self draggingViewForItemsAtIndexes:indexes withEvent:anEvent offset:dragImageOffset];
}
@end
var CPCollectionViewMinItemSizeKey = @"CPCollectionViewMinItemSizeKey",
CPCollectionViewMaxItemSizeKey = @"CPCollectionViewMaxItemSizeKey",
CPCollectionViewVerticalMarginKey = @"CPCollectionViewVerticalMarginKey",
+6
View File
@@ -813,6 +813,12 @@ url("data:image/png;base64,BASE64ENCODEDDATA") // if there is a pattern image
return [CPColor colorWithRed:RAND() green:RAND() blue:RAND() alpha:1.0];
}
+ (CPColor)checkerBoardColor
{
// Thanks to cocco http://stackoverflow.com/a/18368212/76900.
return [CPColor colorWithPatternImage:[[CPImage alloc] initWithContentsOfFile:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAABlBMVEX////MzMw46qqDAAAAEElEQVQImWNg+M+AFeEQBgB+vw/xfUUZkgAAAABJRU5ErkJggg=="]];
}
@end
/// @cond IGNORE
+3
View File
@@ -27,6 +27,9 @@
@import "CPView.j"
@class CPSlider
@class _CPColorPanelToolbar
@class _CPColorPanelSwatches
@class _CPColorPanelPreview
@global CPApp
+2
View File
@@ -25,6 +25,8 @@
@import "CPView.j"
@class CPSlider
@class CPColorPanel
@class __CPColorWheel
@global CPColorPickerViewWidth
@global CPColorPickerViewHeight
+39 -5
View File
@@ -86,14 +86,12 @@ var _CPColorWellDidBecomeExclusiveNotification = @"_CPColorWellDidBecomeExclusiv
_active = NO;
_color = [CPColor whiteColor];
[self setBordered:YES];
[self _registerForNotifications];
}
return self;
}
- (void)_registerForNotifications
- (void)_registerNotifications
{
var defaultCenter = [CPNotificationCenter defaultCenter];
@@ -110,6 +108,22 @@ var _CPColorWellDidBecomeExclusiveNotification = @"_CPColorWellDidBecomeExclusiv
object:[CPColorPanel sharedColorPanel]];
}
- (void)_removeNotifications
{
var defaultCenter = [CPNotificationCenter defaultCenter];
[defaultCenter
removeObserver:self
name:_CPColorWellDidBecomeExclusiveNotification
object:nil];
[defaultCenter
removeObserver:self
name:CPWindowWillCloseNotification
object:[CPColorPanel sharedColorPanel]];
}
/*!
Sets whether the color well is bordered.
*/
@@ -312,6 +326,28 @@ var _CPColorWellDidBecomeExclusiveNotification = @"_CPColorWellDidBecomeExclusiv
[contentBorderView setBackgroundColor:[self currentValueForThemeAttribute:@"content-border-color"]];
}
#pragma mark -
#pragma mark Observers method
- (void)_addObservers
{
if (_isObserving)
return;
[super _addObservers];
[self _registerNotifications];
}
- (void)_removeObservers
{
if (!_isObserving)
return;
[super _removeObservers];
[self _removeNotifications];
}
@end
@implementation CPColorWellValueBinder : CPBinder
@@ -363,8 +399,6 @@ var CPColorWellColorKey = "CPColorWellColorKey",
_active = NO;
_color = [aCoder decodeObjectForKey:CPColorWellColorKey];
[self setBordered:[aCoder decodeBoolForKey:CPColorWellBorderedKey]];
[self _registerForNotifications];
}
return self;
+168 -75
View File
@@ -25,6 +25,27 @@
@import "_CPPopUpList.j"
// TODO : should conform to protocol CPTextFieldDelegate
@protocol CPComboBoxDelegate <CPObject>
@optional
- (void)comboBoxSelectionIsChanging:(CPNotification)aNotification;
- (void)comboBoxSelectionDidChange:(CPNotification)aNotification;
- (void)comboBoxWillPopUp:(CPNotification)aNotification;
- (void)comboBoxWillDismiss:(CPNotification)aNotification;
@end
@protocol CPComboBoxDataSource <CPObject>
@optional
- (CPString)comboBox:(CPComboBox)aComboBox completedString:(CPString)uncompletedString;
- (id)comboBox:(CPComboBox)aComboBox objectValueForItemAtIndex:(int)index;
- (int)comboBox:(CPComboBox)aComboBox indexOfItemWithStringValue:(CPString)stringValue;
- (int)numberOfItemsInComboBox:(CPComboBox)aComboBox;
@end
CPComboBoxSelectionDidChangeNotification = @"CPComboBoxSelectionDidChangeNotification";
CPComboBoxSelectionIsChangingNotification = @"CPComboBoxSelectionIsChangingNotification";
CPComboBoxWillDismissNotification = @"CPComboBoxWillDismissNotification";
@@ -32,6 +53,11 @@ CPComboBoxWillPopUpNotification = @"CPComboBoxWillPopUpNotification";
CPComboBoxStateButtonBordered = CPThemeState("button-bordered");
var CPComboBoxDelegate_comboBoxSelectionIsChanging_ = 1 << 0,
CPComboBoxDelegate_comboBoxSelectionDidChange_ = 1 << 1,
CPComboBoxDelegate_comboBoxWillPopUp_ = 1 << 2,
CPComboBoxDelegate_comboBoxWillDismiss_ = 1 << 3;
var CPComboBoxTextSubview = @"text",
CPComboBoxButtonSubview = @"button",
CPComboBoxDefaultNumberOfVisibleItems = 5,
@@ -40,17 +66,20 @@ var CPComboBoxTextSubview = @"text",
@implementation CPComboBox : CPTextField
{
CPArray _items;
_CPPopUpList _listDelegate;
CPComboBoxDataSource _dataSource;
BOOL _usesDataSource;
BOOL _completes;
BOOL _canComplete;
int _numberOfVisibleItems;
BOOL _forceSelection;
BOOL _hasVerticalScroller;
CPString _selectedStringValue;
BOOL _popUpButtonCausedResign;
BOOL _canComplete;
BOOL _completes;
BOOL _forceSelection;
BOOL _hasVerticalScroller;
BOOL _popUpButtonCausedResign;
BOOL _usesDataSource;
CGSize _intercellSpacing;
CPArray _items;
id<CPComboBoxDataSource> _dataSource;
CPInteger _implementedDelegateComboBoxMethods;
CPString _selectedStringValue;
float _itemHeight;
int _numberOfVisibleItems;
_CPPopUpList _listDelegate;
}
+ (CPString)defaultThemeClass
@@ -119,7 +148,9 @@ var CPComboBoxTextSubview = @"text",
return;
_hasVerticalScroller = flag;
[[_listDelegate scrollView] setHasVerticalScroller:flag];
if (_listDelegate)
[[_listDelegate scrollView] setHasVerticalScroller:_hasVerticalScroller];
}
- (CGSize)intercellSpacing
@@ -129,7 +160,13 @@ var CPComboBoxTextSubview = @"text",
- (void)setIntercellSpacing:(CGSize)aSize
{
[[_listDelegate tableView] setIntercellSpacing:aSize];
if (_intercellSpacing && CGSizeEqualToSize(aSize, _intercellSpacing))
return;
_intercellSpacing = aSize;
if (_listDelegate)
[[_listDelegate tableView] setIntercellSpacing:_intercellSpacing];
}
- (BOOL)isButtonBordered
@@ -152,10 +189,18 @@ var CPComboBoxTextSubview = @"text",
- (void)setItemHeight:(float)itemHeight
{
[[_listDelegate tableView] setRowHeight:itemHeight];
if (itemHeight === _itemHeight)
return;
// FIXME: This shouldn't be necessary, but CPTableView does not tile after setRowHeight
[[_listDelegate tableView] reloadData];
_itemHeight = itemHeight;
if (_listDelegate)
{
[[_listDelegate tableView] setRowHeight:_itemHeight];
// FIXME: This shouldn't be necessary, but CPTableView does not tile after setRowHeight
[[_listDelegate tableView] reloadData];
}
}
- (int)numberOfVisibleItems
@@ -171,7 +216,7 @@ var CPComboBoxTextSubview = @"text",
#pragma mark Setting a Delegate
- (id /*< CPComboBoxDelegate >*/)delegate
- (id <CPComboBoxDelegate>)delegate
{
return [super delegate];
}
@@ -182,48 +227,28 @@ var CPComboBoxTextSubview = @"text",
protocol, in actual fact it doesn't. Also note that the same
delegate may conform to the NSTextFieldDelegate protocol.
*/
- (void)setDelegate:(id /*< CPComboBoxDelegate >*/)aDelegate
- (void)setDelegate:(id <CPComboBoxDelegate>)aDelegate
{
var delegate = [self delegate];
if (aDelegate === delegate)
return;
var defaultCenter = [CPNotificationCenter defaultCenter];
if (delegate)
{
[defaultCenter removeObserver:delegate name:CPComboBoxSelectionIsChangingNotification object:self];
[defaultCenter removeObserver:delegate name:CPComboBoxSelectionDidChangeNotification object:self];
[defaultCenter removeObserver:delegate name:CPComboBoxWillDismissNotification object:self];
[defaultCenter removeObserver:delegate name:CPComboBoxWillPopUpNotification object:self];
}
_implementedDelegateComboBoxMethods = 0;
if (aDelegate)
{
if ([aDelegate respondsToSelector:@selector(comboBoxSelectionIsChanging:)])
[defaultCenter addObserver:delegate
selector:@selector(comboBoxSelectionIsChanging:)
name:CPComboBoxSelectionIsChangingNotification
object:self];
_implementedDelegateComboBoxMethods |= CPComboBoxDelegate_comboBoxSelectionIsChanging_;
if ([aDelegate respondsToSelector:@selector(comboBoxSelectionDidChange:)])
[defaultCenter addObserver:delegate
selector:@selector(comboBoxSelectionDidChange:)
name:CPComboBoxSelectionDidChangeNotification
object:self];
_implementedDelegateComboBoxMethods |= CPComboBoxDelegate_comboBoxSelectionDidChange_;
if ([aDelegate respondsToSelector:@selector(comboBoxWillPopUp:)])
[defaultCenter addObserver:delegate
selector:@selector(comboBoxWillPopUp:)
name:CPComboBoxWillPopUpNotification
object:self];
_implementedDelegateComboBoxMethods |= CPComboBoxDelegate_comboBoxWillPopUp_;
if ([aDelegate respondsToSelector:@selector(comboBoxWillDismiss:)])
[defaultCenter addObserver:delegate
selector:@selector(comboBoxWillDissmis:)
name:CPComboBoxWillDismissNotification
object:self];
_implementedDelegateComboBoxMethods |= CPComboBoxDelegate_comboBoxWillDismiss_;
}
[super setDelegate:aDelegate];
@@ -231,7 +256,7 @@ var CPComboBoxTextSubview = @"text",
#pragma mark Setting a Data Source
- (id /*< CPComboBoxDataSource >*/)dataSource
- (id <CPComboBoxDataSource>)dataSource
{
if (!_usesDataSource)
[self _dataSourceWarningForMethod:_cmd condition:NO];
@@ -239,10 +264,12 @@ var CPComboBoxTextSubview = @"text",
return _dataSource;
}
- (void)setDataSource:(id /*< CPComboBoxDataSource >*/)aSource
- (void)setDataSource:(id <CPComboBoxDataSource>)aSource
{
if (!_usesDataSource)
{
[self _dataSourceWarningForMethod:_cmd condition:NO];
}
else if (_dataSource !== aSource)
{
if (![aSource respondsToSelector:@selector(numberOfItemsInComboBox:)] ||
@@ -251,7 +278,9 @@ var CPComboBoxTextSubview = @"text",
CPLog.warn("Illegal %s data source (%s). Must implement numberOfItemsInComboBox: and comboBox:objectValueForItemAtIndex:", [self className], [aSource description]);
}
else
{
_dataSource = aSource;
}
}
}
@@ -369,49 +398,57 @@ var CPComboBoxTextSubview = @"text",
if (_listDelegate === aDelegate)
return;
var defaultCenter = [CPNotificationCenter defaultCenter];
if (_listDelegate)
{
[defaultCenter removeObserver:self name:_CPPopUpListWillPopUpNotification object:_listDelegate];
[defaultCenter removeObserver:self name:_CPPopUpListWillDismissNotification object:_listDelegate];
[defaultCenter removeObserver:self name:_CPPopUpListDidDismissNotification object:_listDelegate];
[defaultCenter removeObserver:self name:_CPPopUpListItemWasClickedNotification object:_listDelegate];
var oldTableView = [_listDelegate tableView];
if (oldTableView)
{
[defaultCenter removeObserver:self name:CPTableViewSelectionIsChangingNotification object:oldTableView];
[defaultCenter removeObserver:self name:CPTableViewSelectionDidChangeNotification object:oldTableView];
}
}
[self _removeObserversForListDelegate:_listDelegate];
_listDelegate = aDelegate;
// We only add the observers if the CPComboBox is displayed
if ([self window])
[self _addObserversForListDelegate:_listDelegate]
// Apply our text style to the list
[_listDelegate setFont:[self font]];
[_listDelegate setAlignment:[self alignment]];
[[_listDelegate scrollView] setHasVerticalScroller:_hasVerticalScroller];
if (_intercellSpacing)
[[_listDelegate tableView] setIntercellSpacing:_intercellSpacing];
if (_itemHeight)
[[_listDelegate tableView] setRowHeight:_itemHeight];
}
- (void)_addObserversForListDelegate:(_CPPopUpList)aDelegate
{
if (!aDelegate)
return;
var defaultCenter = [CPNotificationCenter defaultCenter];
[defaultCenter addObserver:self
selector:@selector(comboBoxWillPopUp:)
name:_CPPopUpListWillPopUpNotification
object:_listDelegate];
object:aDelegate];
[defaultCenter addObserver:self
selector:@selector(comboBoxWillDismiss:)
name:_CPPopUpListWillDismissNotification
object:_listDelegate];
object:aDelegate];
[defaultCenter addObserver:self
selector:@selector(listDidDismiss:)
name:_CPPopUpListDidDismissNotification
object:_listDelegate];
object:aDelegate];
[defaultCenter addObserver:self
selector:@selector(itemWasClicked:)
name:_CPPopUpListItemWasClickedNotification
object:_listDelegate];
object:aDelegate];
[[_listDelegate scrollView] setHasVerticalScroller:_hasVerticalScroller];
[[aDelegate scrollView] setHasVerticalScroller:_hasVerticalScroller];
var tableView = [_listDelegate tableView];
var tableView = [aDelegate tableView];
[defaultCenter addObserver:self
selector:@selector(comboBoxSelectionIsChanging:)
@@ -422,10 +459,27 @@ var CPComboBoxTextSubview = @"text",
selector:@selector(comboBoxSelectionDidChange:)
name:CPTableViewSelectionDidChangeNotification
object:tableView];
}
// Apply our text style to the list
[_listDelegate setFont:[self font]];
[_listDelegate setAlignment:[self alignment]];
- (void)_removeObserversForListDelegate:(_CPPopUpList)aDelegate
{
if (!aDelegate)
return;
var defaultCenter = [CPNotificationCenter defaultCenter];
[defaultCenter removeObserver:self name:_CPPopUpListWillPopUpNotification object:aDelegate];
[defaultCenter removeObserver:self name:_CPPopUpListWillDismissNotification object:aDelegate];
[defaultCenter removeObserver:self name:_CPPopUpListDidDismissNotification object:aDelegate];
[defaultCenter removeObserver:self name:_CPPopUpListItemWasClickedNotification object:aDelegate];
var oldTableView = [aDelegate tableView];
if (oldTableView)
{
[defaultCenter removeObserver:self name:CPTableViewSelectionIsChangingNotification object:oldTableView];
[defaultCenter removeObserver:self name:CPTableViewSelectionDidChangeNotification object:oldTableView];
}
}
- (int)indexOfItemWithObjectValue:(id)anObject
@@ -470,8 +524,6 @@ var CPComboBoxTextSubview = @"text",
if (!_listDelegate)
[self setListDelegate:[[_CPPopUpList alloc] initWithDataSource:self]];
[self _selectMatchingItem];
// Note the offset here is 1 less than the focus ring width because the outer edge
// of the focus ring is very transparent and it looks better if the list is closer.
if (CPComboBoxFocusRingWidth < 0)
@@ -482,6 +534,7 @@ var CPComboBoxTextSubview = @"text",
}
[_listDelegate popUpRelativeToRect:[self _borderFrame] view:self offset:CPComboBoxFocusRingWidth - 1];
[self _selectMatchingItem];
}
/*! @ignore */
@@ -817,13 +870,17 @@ var CPComboBoxTextSubview = @"text",
- (void)setFont:(CPFont)aFont
{
[super setFont:aFont];
[_listDelegate setFont:aFont];
if (_listDelegate)
[_listDelegate setFont:aFont];
}
- (void)setAlignment:(CPTextAlignment)alignment
{
[super setAlignment:alignment];
[_listDelegate setAlignment:alignment];
if (_listDelegate)
[_listDelegate setAlignment:alignment];
}
#pragma mark Pop Up Button Layout
@@ -894,7 +951,9 @@ var CPComboBoxTextSubview = @"text",
index = [_dataSource comboBox:self indexOfItemWithStringValue:stringValue]
}
else
{
index = [self indexOfItemWithObjectValue:stringValue];
}
[_listDelegate selectRow:index];
@@ -946,6 +1005,28 @@ var CPComboBoxTextSubview = @"text",
}
}
#pragma mark -
#pragma mark Observers method
- (void)_addObservers
{
if (_isObserving)
return;
[super _addObservers];
[self _addObserversForListDelegate:_listDelegate];
}
- (void)_removeObservers
{
if (!_isObserving)
return;
[super _removeObservers];
[self _removeObserversForListDelegate:_listDelegate];
}
@end
@implementation CPComboBox (CPComboBoxDelegate)
@@ -953,24 +1034,36 @@ var CPComboBoxTextSubview = @"text",
/*! @ignore */
- (void)comboBoxSelectionIsChanging:(CPNotification)aNotification
{
if (_implementedDelegateComboBoxMethods & CPComboBoxDelegate_comboBoxSelectionIsChanging_)
[_delegate comboBoxSelectionIsChanging:[[CPNotification alloc] initWithName:CPComboBoxSelectionIsChangingNotification object:self userInfo:nil]];
[[CPNotificationCenter defaultCenter] postNotificationName:CPComboBoxSelectionIsChangingNotification object:self];
}
/*! @ignore */
- (void)comboBoxSelectionDidChange:(CPNotification)aNotification
{
if (_implementedDelegateComboBoxMethods & CPComboBoxDelegate_comboBoxSelectionDidChange_)
[_delegate comboBoxSelectionDidChange:[[CPNotification alloc] initWithName:CPComboBoxSelectionDidChangeNotification object:self userInfo:nil]];
[[CPNotificationCenter defaultCenter] postNotificationName:CPComboBoxSelectionDidChangeNotification object:self];
}
/*! @ignore */
- (void)comboBoxWillPopUp:(CPNotification)aNotification
{
if (_implementedDelegateComboBoxMethods & CPComboBoxDelegate_comboBoxWillPopUp_)
[_delegate comboBoxWillPopUp:[[CPNotification alloc] initWithName:CPComboBoxWillPopUpNotification object:self userInfo:nil]];
[[CPNotificationCenter defaultCenter] postNotificationName:CPComboBoxWillPopUpNotification object:self];
}
/*! @ignore */
- (void)comboBoxWillDismiss:(CPNotification)aNotification
{
if (_implementedDelegateComboBoxMethods & CPComboBoxDelegate_comboBoxWillDismiss_)
[_delegate comboBoxWillDismiss:[[CPNotification alloc] initWithName:CPComboBoxWillDismissNotification object:self userInfo:nil]];
[[CPNotificationCenter defaultCenter] postNotificationName:CPComboBoxWillDismissNotification object:self];
}
+4
View File
@@ -78,6 +78,8 @@ CPInputOnInputEventFeature = 30;
CPFileAPIFeature = 31;
CPAltEnterTextAreaFeature = 32;
/*
@@ -100,6 +102,7 @@ var USER_AGENT = "",
// default these features to true
PLATFORM_FEATURES[CPInputTypeCanBeChangedFeature] = YES;
PLATFORM_FEATURES[CPInputSetFontOutsideOfDOM] = YES;
PLATFORM_FEATURES[CPAltEnterTextAreaFeature] = YES;
if (typeof window !== "undefined" && typeof window.navigator !== "undefined")
USER_AGENT = window.navigator.userAgent;
@@ -208,6 +211,7 @@ else if (USER_AGENT.indexOf("Gecko") !== -1) // Must follow KHTML check.
// Some day this might be fixed and should be version prefixed. No known fixed version yet.
PLATFORM_FEATURES[CPInput1PxLeftPadding] = YES;
PLATFORM_FEATURES[CPAltEnterTextAreaFeature] = NO;
// This was supposed to be added in Firefox 22, but when testing with the latest beta as of 2013-06-14
// it does not seem to work. It seems to exhibit the CPJavaScriptPasteRequiresEditableTarget problem,
// and in addition doesn't seem to work with our native copy code either.
+114 -6
View File
@@ -30,16 +30,31 @@
@global CPApp
@protocol CPControlTextEditingDelegate <CPObject>
@optional
- (void)controlTextDidBeginEditing:(CPNotification)aNotification;
- (void)controlTextDidChange:(CPNotification)aNotification;
- (void)controlTextDidEndEditing:(CPNotification)aNotification;
- (void)controlTextDidFocus:(CPNotification)aNotification;
- (void)controlTextDidBlur:(CPNotification)aNotification;
- (BOOL)control:(CPControl)control didFailToFormatString:(CPString)string errorDescription:(CPString)error;
@end
@typedef CPTextAlignment
CPLeftTextAlignment = 0;
CPRightTextAlignment = 1;
CPCenterTextAlignment = 2;
CPJustifiedTextAlignment = 3;
CPNaturalTextAlignment = 4;
@typedef CPControlSize
CPRegularControlSize = 0;
CPSmallControlSize = 1;
CPMiniControlSize = 2;
@typedef CPLineBreakMode
CPLineBreakByWordWrapping = 0;
CPLineBreakByCharWrapping = 1;
CPLineBreakByClipping = 2;
@@ -47,11 +62,13 @@ CPLineBreakByTruncatingHead = 3;
CPLineBreakByTruncatingTail = 4;
CPLineBreakByTruncatingMiddle = 5;
@typedef CPVerticalTextAlignment
CPTopVerticalTextAlignment = 1;
CPCenterVerticalTextAlignment = 2;
CPBottomVerticalTextAlignment = 3;
// Deprecated for use with images, use the CPImageScale constants
@typedef CPImageScaling
CPScaleProportionally = 0;
CPScaleToFit = 1;
CPScaleNone = 2;
@@ -61,6 +78,7 @@ CPImageScaleAxesIndependently = 1;
CPImageScaleNone = 2;
CPImageScaleProportionallyUpOrDown = 3;
@typedef CPCellImagePosition
CPNoImage = 0;
CPImageOnly = 1;
CPImageLeft = 2;
@@ -106,6 +124,8 @@ var CPControlBlackColor = [CPColor blackColor];
BOOL _trackingWasWithinFrame;
unsigned _trackingMouseDownFlags;
CGPoint _previousTrackingLocation;
CPControlSize _controlSize;
}
+ (CPDictionary)themeAttributes
@@ -122,6 +142,7 @@ var CPControlBlackColor = [CPColor blackColor];
@"image-scaling": CPScaleToFit,
@"min-size": CGSizeMakeZero(),
@"max-size": CGSizeMake(-1.0, -1.0),
@"nib2cib-adjustment-frame": CGRectMakeZero()
};
}
@@ -177,13 +198,95 @@ var CPControlBlackColor = [CPColor blackColor];
if (self)
{
_sendActionOn = CPLeftMouseUpMask;
_sendActionOn = CPLeftMouseUpMask;
_trackingMouseDownFlags = 0;
}
return self;
}
#pragma mark -
#pragma mark Control Size
/*!
Returns the control's control size
*/
- (CPControlSize)controlSize
{
return _controlSize;
}
/*!
Sets the control's size.
@param aControlSize the control's size
*/
- (void)setControlSize:(CPControlSize)aControlSize
{
if (_controlSize === aControlSize)
return;
[self unsetThemeState:[self _controlSizeThemeState]];
_controlSize = aControlSize;
[self setThemeState:[self _controlSizeThemeState]];
[self setNeedsLayout];
[self setNeedsDisplay:YES];
}
/*!
Gets the current theme state according to the current controlSize.
@return a CPThemeState
*/
- (ThemeState)_controlSizeThemeState
{
switch(_controlSize)
{
case CPSmallControlSize:
return CPThemeStateControlSizeSmall;
case CPMiniControlSize:
return CPThemeStateControlSizeMini;
case CPRegularControlSize:
default:
return CPThemeStateControlSizeRegular;
}
}
/*!
@ignore
Change frame size according to the theme control size theme constraints
Basically for height to min-size.
*/
- (void)_sizeToControlSize
{
var frameSize = [self frameSize],
minSize = [self currentValueForThemeAttribute:@"min-size"],
maxSize = [self currentValueForThemeAttribute:@"max-size"];
if (minSize.width > 0)
{
frameSize.width = MAX(minSize.width, frameSize.width);
if (maxSize.width > 0)
frameSize.width = MIN(maxSize.width, frameSize.width);
}
if (minSize.height > 0)
{
frameSize.height = MAX(minSize.height, frameSize.height);
if (maxSize.height > 0)
frameSize.height = MIN(maxSize.height, frameSize.height);
}
[self setFrameSize:frameSize];
}
#pragma mark -
/*!
Sets the receiver's target action.
@@ -915,14 +1018,15 @@ var CPControlBlackColor = [CPColor blackColor];
@end
var CPControlValueKey = @"CPControlValueKey",
var CPControlActionKey = @"CPControlActionKey",
CPControlControlSizeKey = @"CPControlControlSizeKey",
CPControlControlStateKey = @"CPControlControlStateKey",
CPControlIsEnabledKey = @"CPControlIsEnabledKey",
CPControlTargetKey = @"CPControlTargetKey",
CPControlActionKey = @"CPControlActionKey",
CPControlSendActionOnKey = @"CPControlSendActionOnKey",
CPControlFormatterKey = @"CPControlFormatterKey",
CPControlIsEnabledKey = @"CPControlIsEnabledKey",
CPControlSendActionOnKey = @"CPControlSendActionOnKey",
CPControlSendsActionOnEndEditingKey = @"CPControlSendsActionOnEndEditingKey",
CPControlTargetKey = @"CPControlTargetKey",
CPControlValueKey = @"CPControlValueKey",
__Deprecated__CPImageViewImageKey = @"CPImageViewImageKey";
@@ -949,6 +1053,8 @@ var CPControlValueKey = @"CPControlValueKey",
[self setSendsActionOnEndEditing:[aCoder decodeBoolForKey:CPControlSendsActionOnEndEditingKey]];
[self setFormatter:[aCoder decodeObjectForKey:CPControlFormatterKey]];
[self setControlSize:[aCoder decodeIntForKey:CPControlControlSizeKey]];
}
return self;
@@ -981,6 +1087,8 @@ var CPControlValueKey = @"CPControlValueKey",
if (_formatter !== nil)
[aCoder encodeObject:_formatter forKey:CPControlFormatterKey];
[aCoder encodeInt:_controlSize forKey:CPControlControlSizeKey];
}
@end
+1
View File
@@ -22,6 +22,7 @@ Cursor support by browser:
*/
@import <Foundation/CPObject.j>
@import "CPImage.j"
@global CPApp
+66 -19
View File
@@ -28,7 +28,6 @@
@import <Foundation/CPArray.j>
@import <Foundation/CPObject.j>
@import <Foundation/CPDate.j>
@import <Foundation/CPDateFormatter.j>
@import <Foundation/CPLocale.j>
@import <Foundation/CPTimeZone.j>
@@ -76,6 +75,7 @@ CPEraDatePickerElementFlag = 0x0100;
CPInteger _datePickerStyle @accessors(property=datePickerStyle);
CPInteger _timeInterval @accessors(property=timeInterval);
BOOL _invokedByUserEvent;
_CPDatePickerTextField _datePickerTextfield;
_CPDatePickerCalendar _datePickerCalendar;
unsigned _implementedCDatePickerDelegateMethods;
@@ -206,24 +206,32 @@ CPEraDatePickerElementFlag = 0x0100;
if (!_locale)
_locale = [CPLocale currentLocale];
if (!_timeZone)
_timeZone = [CPTimeZone systemTimeZone];
_datePickerTextfield = [[_CPDatePickerTextField alloc] initWithFrame:[self bounds] withDatePicker:self];
[_datePickerTextfield setDateValue:_dateValue];
[self addSubview:_datePickerTextfield];
_datePickerCalendar = [[_CPDatePickerCalendar alloc] initWithFrame:[self bounds] withDatePicker:self];
[_datePickerCalendar setDateValue:_dateValue];
[_datePickerCalendar setHidden:YES];
[self addSubview:_datePickerCalendar];
// We might have been unarchived in a disabled state.
[_datePickerTextfield setEnabled:[self isEnabled]];
[self setNeedsDisplay:YES];
[self setNeedsLayout];
}
#pragma mark -
#pragma mark Control Size
- (void)setControlSize:(CPControlSize)aControlSize
{
[super setControlSize:aControlSize];
if ([self datePickerStyle] == CPTextFieldAndStepperDatePickerStyle || [self datePickerStyle] == CPTextFieldDatePickerStyle)
[self _sizeToControlSize];
}
#pragma mark -
#pragma mark Delegate methods
@@ -252,15 +260,26 @@ CPEraDatePickerElementFlag = 0x0100;
if (_datePickerStyle == CPTextFieldAndStepperDatePickerStyle || _datePickerStyle == CPTextFieldDatePickerStyle)
{
[_datePickerTextfield setHidden:NO];
[_datePickerCalendar setHidden:YES];
if (![_datePickerTextfield superview])
[self addSubview:_datePickerTextfield];
if ([_datePickerCalendar superview])
[_datePickerCalendar removeFromSuperview];
[_datePickerTextfield setControlSize:[self controlSize]];
[_datePickerTextfield setNeedsLayout];
[_datePickerTextfield setNeedsDisplay:YES];
}
else
{
[_datePickerCalendar setHidden:NO];
[_datePickerTextfield setHidden:YES];
if (![_datePickerCalendar superview])
[self addSubview:_datePickerCalendar];
if ([_datePickerTextfield superview])
[_datePickerTextfield removeFromSuperview];
[_datePickerCalendar setNeedsLayout];
[_datePickerCalendar setNeedsDisplay:YES];
}
}
@@ -275,11 +294,14 @@ CPEraDatePickerElementFlag = 0x0100;
return _dateValue
}
/*! Set the objectValue ofhe datePier. It has to be a CPDate
/*! Set the objectValue of the datePicker. It has to be a CPDate
@param aDateValue the dateValue
*/
- (void)setObjectValue:(CPDate)aValue
{
if (![aValue isKindOfClass:[CPDate class]])
return;
[self setDateValue:aValue];
}
@@ -291,6 +313,7 @@ CPEraDatePickerElementFlag = 0x0100;
if (aDateValue == nil)
return;
_invokedByUserEvent = NO;
[self _setDateValue:aDateValue timeInterval:_timeInterval];
}
@@ -309,7 +332,14 @@ CPEraDatePickerElementFlag = 0x0100;
aTimeInterval = MAX(MIN(aTimeInterval, [_maxDate timeIntervalSinceDate:aDateValue]), [_minDate timeIntervalSinceDate:aDateValue]);
if ([aDateValue isEqualToDate:_dateValue] && aTimeInterval == _timeInterval)
{
if (_datePickerStyle == CPTextFieldAndStepperDatePickerStyle || _datePickerStyle == CPTextFieldDatePickerStyle)
[_datePickerTextfield setDateValue:_dateValue];
else
[_datePickerCalendar setDateValue:_dateValue];
return;
}
if (_implementedCDatePickerDelegateMethods & CPDatePicker_validateProposedDateValue_timeInterval)
{
@@ -331,7 +361,8 @@ CPEraDatePickerElementFlag = 0x0100;
_timeInterval = (_datePickerMode == CPSingleDateMode)? 0 : aTimeInterval;
[self didChangeValueForKey:@"timeInterval"];
[self sendAction:[self action] to:[self target]];
if (_invokedByUserEvent)
[self sendAction:[self action] to:[self target]];
if (_datePickerStyle == CPTextFieldAndStepperDatePickerStyle || _datePickerStyle == CPTextFieldDatePickerStyle)
[_datePickerTextfield setDateValue:_dateValue];
@@ -370,6 +401,8 @@ CPEraDatePickerElementFlag = 0x0100;
{
_datePickerStyle = aDatePickerStyle;
[self setControlSize:[self controlSize]];
[self setNeedsDisplay:YES];
[self setNeedsLayout];
}
@@ -509,6 +542,11 @@ CPEraDatePickerElementFlag = 0x0100;
[self didChangeValueForKey:@"timeZone"];
[self setNeedsLayout];
if (_datePickerStyle == CPTextFieldAndStepperDatePickerStyle || _datePickerStyle == CPTextFieldDatePickerStyle)
[_datePickerTextfield setDateValue:_dateValue];
else
[_datePickerCalendar setDateValue:_dateValue];
}
@@ -520,11 +558,16 @@ CPEraDatePickerElementFlag = 0x0100;
- (BOOL)becomeFirstResponder
{
if (_datePickerStyle == CPTextFieldAndStepperDatePickerStyle || _datePickerStyle == CPTextFieldDatePickerStyle)
[_datePickerTextfield _selecteTextFieldWithFlags:[[CPApp currentEvent] modifierFlags]];
else
return NO;
{
if (![super becomeFirstResponder])
return NO;
return YES;
[_datePickerTextfield _selectTextFieldWithFlags:[[CPApp currentEvent] modifierFlags]];
return YES;
}
return NO;
}
/*! Return YES
@@ -628,12 +671,13 @@ var CPDatePickerModeKey = @"CPDatePickerModeKey",
_timeInterval = [aCoder decodeDoubleForKey:CPIntervalKey];
_datePickerMode = [aCoder decodeIntForKey:CPDatePickerModeKey];
_datePickerElements = [aCoder decodeIntForKey:CPDatePickerElementsKey];
_datePickerStyle = [aCoder decodeIntForKey:CPDatePickerStyleKey];
[self setDatePickerStyle:[aCoder decodeIntForKey:CPDatePickerStyleKey]];
_locale = [aCoder decodeObjectForKey:CPLocaleKey];
_dateValue = [aCoder decodeObjectForKey:CPDateValueKey];
_backgroundColor = [aCoder decodeObjectForKey:CPBackgroundColorKey];
_drawsBackground = [aCoder decodeBoolForKey:CPDrawsBackgroundKey];
_isBordered = [aCoder decodeBoolForKey:CPBorderedKey];
[self _init];
}
@@ -642,7 +686,9 @@ var CPDatePickerModeKey = @"CPDatePickerModeKey",
- (void)encodeWithCoder:(CPCoder)aCoder
{
// FIXME Do we need to encode _datePickerTextfield and _datePickerCalendar? As subviews they'll be encoded, but when we decode we recreate them anyhow.
[super encodeWithCoder:aCoder];
[aCoder encodeDouble:_timeInterval forKey:CPIntervalKey];
[aCoder encodeInt:_datePickerMode forKey:CPDatePickerModeKey];
[aCoder encodeInt:_datePickerStyle forKey:CPDatePickerStyleKey];
@@ -655,6 +701,7 @@ var CPDatePickerModeKey = @"CPDatePickerModeKey",
[aCoder encodeObject:_backgroundColor forKey:CPBackgroundColorKey];
[aCoder encodeObject:_drawsBackground forKey:CPDrawsBackgroundKey];
[aCoder encodeObject:_isBordered forKey:CPBorderedKey];
}
@end
+144 -59
View File
@@ -29,7 +29,11 @@
@import <Foundation/Foundation.j>
@class CPDatePicker
@class _CPDatePickerMonthView
@class _CPDatePickerHeaderView
@class _CPDatePickerBox
@global CPApp
@global CPSingleDateMode
@global CPRangeDateMode
@@ -43,6 +47,10 @@
@global CPYearMonthDayDatePickerElementFlag
@global CPEraDatePickerElementFlag
@global CPAlternateKeyMask
@global CPCommandKeyMask
@global CPControlKeyMask
var CPShortWeekDayNameArrayEn = [@"Mo", @"Tu", @"We", @"Th", @"Fr", @"Sa", @"Su"],
CPShortWeekDayNameArrayUS = [@"Su", @"Mo", @"Tu", @"We", @"Th", @"Fr", @"Sa"],
CPShortWeekDayNameArrayFr = [@"L", @"M", @"M", @"J", @"V", @"S", @"D"],
@@ -58,7 +66,7 @@ var CPShortWeekDayNameArrayEn = [@"Mo", @"Tu", @"We", @"Th", @"Fr", @"Sa", @"Su"
_CPDatePickerMonthView _monthView;
_CPDatePickerHeaderView _headerView;
_CPDatePickerClock _datePickerClock;
CPBox _box;
_CPDatePickerBox _box;
CPDatePicker _datePicker;
CPInteger _startSelectionIndex;
CPInteger _currentSelectionIndex;
@@ -80,6 +88,7 @@ var CPShortWeekDayNameArrayEn = [@"Mo", @"Tu", @"We", @"Th", @"Fr", @"Sa", @"Su"
_datePicker = aDatePicker
[self _init];
}
return self;
}
@@ -91,7 +100,7 @@ var CPShortWeekDayNameArrayEn = [@"Mo", @"Tu", @"We", @"Th", @"Fr", @"Sa", @"Su"
sizeCalendar = [_datePicker valueForThemeAttribute:@"size-calendar"],
sizeClock = [_datePicker valueForThemeAttribute:@"size-clock"];
_box = [[_DatePickerBox alloc] initWithFrame:CGRectMake(0, 0, sizeCalendar.width, sizeHeader.height + sizeCalendar.height)];
_box = [[_CPDatePickerBox alloc] initWithFrame:CGRectMake(0, 0, sizeCalendar.width, sizeHeader.height + sizeCalendar.height)];
[_box setDatePicker:_datePicker];
_headerView = [[_CPDatePickerHeaderView alloc] initWithFrame:CGRectMake(0, 0, sizeHeader.width, sizeHeader.height) datePicker:_datePicker delegate:self];
@@ -113,11 +122,6 @@ var CPShortWeekDayNameArrayEn = [@"Mo", @"Tu", @"We", @"Th", @"Fr", @"Sa", @"Su"
#pragma mark -
#pragma mark Responder methods
- (BOOL)becomeFirstResponder
{
return YES;
}
- (BOOL)acceptsFirstResponder
{
return YES;
@@ -215,6 +219,8 @@ var CPShortWeekDayNameArrayEn = [@"Mo", @"Tu", @"We", @"Th", @"Fr", @"Sa", @"Su"
[_headerView setHidden:YES];
[_monthView setHidden:YES];
}
[self setFrameSize:[_datePicker frameSize]];
}
@@ -223,16 +229,62 @@ var CPShortWeekDayNameArrayEn = [@"Mo", @"Tu", @"We", @"Th", @"Fr", @"Sa", @"Su"
/*! Move to the nextMonth without changing the dateValue of the datePicker
*/
- (void)_nextMonth:(id)sender
- (void)_clickArrowNext:(id)sender
{
[self setDateValue:[_monthView nextMonth]];
var currentEvent = [CPApp currentEvent],
modifierFlags = [currentEvent modifierFlags];
if (modifierFlags & (CPCommandKeyMask | CPControlKeyMask | CPAlternateKeyMask))
{
var date = [[_monthView monthDate] copy];
date.setDate(1);
if (modifierFlags & CPAlternateKeyMask)
date.setUTCFullYear(date.getUTCFullYear() + 10);
else
date.setUTCFullYear(date.getUTCFullYear() + 1);
[self setDateValue:date];
}
else
{
[self _displayNextMonth];
}
}
- (void)_displayNextMonth
{
[self setDateValue:[_monthView nextMonth]];
}
- (void)_displayPreviousMonth
{
[self setDateValue:[_monthView previousMonth]];
}
/*! Move to the previous month without changing the dateValue of the datePicker
*/
- (void)_previousMonth:(id)sender
- (void)_clickArrowPrevious:(id)sender
{
[self setDateValue:[_monthView previousMonth]];
var currentEvent = [CPApp currentEvent],
modifierFlags = [currentEvent modifierFlags];
if (modifierFlags & (CPCommandKeyMask | CPControlKeyMask | CPAlternateKeyMask))
{
var date = [[_monthView monthDate] copy];
date.setDate(1);
if (modifierFlags & CPAlternateKeyMask)
date.setUTCFullYear(date.getUTCFullYear() - 10);
else
date.setUTCFullYear(date.getUTCFullYear() - 1);
[self setDateValue:date];
}
else
{
[self _displayPreviousMonth];
}
}
/*! Move to the current selected day
@@ -334,10 +386,12 @@ var CPShortWeekDayNameArrayEn = [@"Mo", @"Tu", @"We", @"Th", @"Fr", @"Sa", @"Su"
[self addSubview:_currentButton];
[_previousButton setTarget:aDelegate];
[_previousButton setAction:@selector(_previousMonth:)];
[_previousButton setAction:@selector(_clickArrowPrevious:)];
[_previousButton setContinuous:YES];
[_nextButton setTarget:aDelegate];
[_nextButton setAction:@selector(_nextMonth:)];
[_nextButton setAction:@selector(_clickArrowNext:)];
[_nextButton setContinuous:YES];
[_currentButton setTarget:aDelegate];
[_currentButton setAction:@selector(_currentMonth:)];
@@ -683,7 +737,7 @@ var CPShortWeekDayNameArrayEn = [@"Mo", @"Tu", @"We", @"Th", @"Fr", @"Sa", @"Su"
[dayTile setDate:[currentDate copy]];
[dayTile setStringValue:currentDate.getDate()];
[dayTile setDisabled:![self isEnabled] || currentDate.getMonth() !== currentMonth.getMonth()];
[dayTile setDisabled:![self isEnabled] || currentDate.getMonth() !== currentMonth.getMonth() || currentDate < [_datePicker minDate] || currentDate > [_datePicker maxDate]];
[dayTile setHighlighted:isPresentMonth && currentDate.getDate() == now.getDate()];
}
@@ -845,26 +899,62 @@ var CPShortWeekDayNameArrayEn = [@"Mo", @"Tu", @"We", @"Th", @"Fr", @"Sa", @"Su"
_indexDayTile = -1;
_eventDragged = nil
_datePicker._invokedByUserEvent = YES;
// Check if we have to change or not the month of the component
if ([dayTile date].getMonth() == _date.getMonth())
{
var minDate = [[_datePicker minDate] copy],
maxDate = [[_datePicker maxDate] copy];
if ([_datePicker datePickerMode] == CPRangeDateMode && [anEvent modifierFlags] & CPShiftKeyMask)
{
var dateValueAtMidnight = [[_datePicker dateValue] copy];
[minDate _resetToMidnight];
[maxDate _resetToLastSeconds];
[dateValueAtMidnight _resetToMidnight];
if (dateTile >= minDate && dateTile <= maxDate)
[_datePicker _setDateValue:[self _hoursMinutesSecondsFromDatePickerForDate:dateTile] timeInterval:0];
if (dateTile < dateValueAtMidnight)
{
var interval;
if (dateTile == dateValueAtMidnight)
interval = [_datePicker timeInterval];
else
interval = ([dateValueAtMidnight timeIntervalSinceDate:dateTile] + [_datePicker timeInterval]);
[_datePicker _setDateValue:[self _hoursMinutesSecondsFromDatePickerForDate:dateTile] timeInterval:interval];
}
else if ([[dayTile date] isEqualToDate:dateValueAtMidnight])
{
[_datePicker _setDateValue:[self _hoursMinutesSecondsFromDatePickerForDate:dateTile] timeInterval:0];
}
else
{
[_datePicker _setDateValue:[self _hoursMinutesSecondsFromDatePickerForDate:[dateValueAtMidnight copy]] timeInterval:([dateTile timeIntervalSinceDate:dateValueAtMidnight])];
}
// Be sure to display the good month
[_delegate setDateValue:dateTile];
}
else
{
var minDate = [[_datePicker minDate] copy],
maxDate = [[_datePicker maxDate] copy];
[minDate _resetToMidnight];
[maxDate _resetToLastSeconds];
if (dateTile >= minDate && dateTile <= maxDate)
[_datePicker _setDateValue:[self _hoursMinutesSecondsFromDatePickerForDate:dateTile] timeInterval:0];
}
}
else
{
// Check the year and the month. The year is usefull when changing from Jan to Dec.
if (_date.getMonth() - [dayTile date].getMonth() == 1 || _date.getFullYear() - [dayTile date].getFullYear() == 1)
[_delegate _previousMonth:self];
[_delegate _displayPreviousMonth];
else
[_delegate _nextMonth:self];
[_delegate _displayNextMonth];
}
_datePicker._invokedByUserEvent = NO;
}
/*! Mouse dragged event
@@ -882,6 +972,8 @@ var CPShortWeekDayNameArrayEn = [@"Mo", @"Tu", @"We", @"Th", @"Fr", @"Sa", @"Su"
_indexDayTile = [self indexOfTileForEvent:anEvent];
_eventDragged = anEvent;
_datePicker._invokedByUserEvent = YES;
if ([_datePicker datePickerMode] == CPSingleDateMode)
{
// Check if we have to change or not the month of the component
@@ -899,9 +991,9 @@ var CPShortWeekDayNameArrayEn = [@"Mo", @"Tu", @"We", @"Th", @"Fr", @"Sa", @"Su"
// Check the year and the month. The year is usefull when changing from Jan to Dec.
if (_date.getMonth() - [dayTile date].getMonth() == 1 || _date.getFullYear() - [dayTile date].getFullYear() == 1)
[_delegate _previousMonth:self];
[_delegate _displayPreviousMonth];
else
[_delegate _nextMonth:self];
[_delegate _displayNextMonth];
}
}
else
@@ -923,6 +1015,8 @@ var CPShortWeekDayNameArrayEn = [@"Mo", @"Tu", @"We", @"Th", @"Fr", @"Sa", @"Su"
[_datePicker _setDateValue:[self _hoursMinutesSecondsFromDatePickerForDate:_clickDate] timeInterval:[dateTile timeIntervalSinceDate:dateValueAtMidnight]];
}
}
_datePicker._invokedByUserEvent = NO;
}
- (void)mouseUp:(CPEvent)anEvent
@@ -944,7 +1038,7 @@ var CPShortWeekDayNameArrayEn = [@"Mo", @"Tu", @"We", @"Th", @"Fr", @"Sa", @"Su"
if (_isMonthJustChanged)
{
_dragDate.setMonth(_date.getMonth() + 1);
[_delegate _nextMonth:self];
[_delegate _displayNextMonth];
}
}
@@ -953,7 +1047,7 @@ var CPShortWeekDayNameArrayEn = [@"Mo", @"Tu", @"We", @"Th", @"Fr", @"Sa", @"Su"
if (_isMonthJustChanged)
{
_dragDate.setMonth(_date.getMonth() - 1);
[_delegate _previousMonth:self];
[_delegate _displayPreviousMonth];
}
}
@@ -1020,30 +1114,30 @@ var CPShortWeekDayNameArrayEn = [@"Mo", @"Tu", @"We", @"Th", @"Fr", @"Sa", @"Su"
[_textField setValue:[_datePicker valueForThemeAttribute:@"tile-text-shadow-color" inState:CPThemeStateDisabled] forThemeAttribute:@"text-shadow-color" inState:CPThemeStateDisabled];
[_textField setValue:[_datePicker valueForThemeAttribute:@"tile-text-shadow-offset" inState:CPThemeStateDisabled] forThemeAttribute:@"text-shadow-offset" inState:CPThemeStateDisabled];
[_textField setValue:[_datePicker valueForThemeAttribute:@"tile-font" inState:CPThemeStateDisabled | CPThemeStateSelected] forThemeAttribute:@"font" inState:CPThemeStateDisabled | CPThemeStateSelected];
[_textField setValue:[_datePicker valueForThemeAttribute:@"tile-text-color" inState:CPThemeStateDisabled | CPThemeStateSelected] forThemeAttribute:@"text-color" inState:CPThemeStateDisabled | CPThemeStateSelected];
[_textField setValue:[_datePicker valueForThemeAttribute:@"tile-text-shadow-color" inState:CPThemeStateDisabled | CPThemeStateSelected] forThemeAttribute:@"text-shadow-color" inState:CPThemeStateDisabled | CPThemeStateSelected];
[_textField setValue:[_datePicker valueForThemeAttribute:@"tile-text-shadow-offset" inState:CPThemeStateDisabled | CPThemeStateSelected] forThemeAttribute:@"text-shadow-offset" inState:CPThemeStateDisabled | CPThemeStateSelected];
[_textField setValue:[_datePicker valueForThemeAttribute:@"tile-font" inState:[CPThemeStateDisabled, CPThemeStateSelected]] forThemeAttribute:@"font" inState:[CPThemeStateDisabled, CPThemeStateSelected]];
[_textField setValue:[_datePicker valueForThemeAttribute:@"tile-text-color" inState:[CPThemeStateDisabled, CPThemeStateSelected]]forThemeAttribute:@"text-color" inState:[CPThemeStateDisabled, CPThemeStateSelected]];
[_textField setValue:[_datePicker valueForThemeAttribute:@"tile-text-shadow-color" inState:[CPThemeStateDisabled, CPThemeStateSelected]] forThemeAttribute:@"text-shadow-color" inState:[CPThemeStateDisabled, CPThemeStateSelected]];
[_textField setValue:[_datePicker valueForThemeAttribute:@"tile-text-shadow-offset" inState:[CPThemeStateDisabled, CPThemeStateSelected]] forThemeAttribute:@"text-shadow-offset" inState:[CPThemeStateDisabled, CPThemeStateSelected]];
[_textField setValue:[_datePicker valueForThemeAttribute:@"tile-font" inState:CPThemeStateHighlighted] forThemeAttribute:@"font" inState:CPThemeStateHighlighted];
[_textField setValue:[_datePicker valueForThemeAttribute:@"tile-text-color" inState:CPThemeStateHighlighted] forThemeAttribute:@"text-color" inState:CPThemeStateHighlighted];
[_textField setValue:[_datePicker valueForThemeAttribute:@"tile-text-shadow-color" inState:CPThemeStateHighlighted] forThemeAttribute:@"text-shadow-color" inState:CPThemeStateHighlighted];
[_textField setValue:[_datePicker valueForThemeAttribute:@"tile-text-shadow-offset" inState:CPThemeStateHighlighted] forThemeAttribute:@"text-shadow-offset" inState:CPThemeStateHighlighted];
[_textField setValue:[_datePicker valueForThemeAttribute:@"tile-font" inState:CPThemeStateHighlighted | CPThemeStateSelected] forThemeAttribute:@"font" inState:CPThemeStateHighlighted | CPThemeStateSelected];
[_textField setValue:[_datePicker valueForThemeAttribute:@"tile-text-color" inState:CPThemeStateHighlighted | CPThemeStateSelected] forThemeAttribute:@"text-color" inState:CPThemeStateHighlighted | CPThemeStateSelected];
[_textField setValue:[_datePicker valueForThemeAttribute:@"tile-text-shadow-color" inState:CPThemeStateHighlighted | CPThemeStateSelected] forThemeAttribute:@"text-shadow-color" inState:CPThemeStateHighlighted | CPThemeStateSelected];
[_textField setValue:[_datePicker valueForThemeAttribute:@"tile-text-shadow-offset" inState:CPThemeStateHighlighted | CPThemeStateSelected] forThemeAttribute:@"text-shadow-offset" inState:CPThemeStateHighlighted | CPThemeStateSelected];
[_textField setValue:[_datePicker valueForThemeAttribute:@"tile-font" inState:[CPThemeStateHighlighted, CPThemeStateSelected]] forThemeAttribute:@"font" inState:[CPThemeStateHighlighted, CPThemeStateSelected]];
[_textField setValue:[_datePicker valueForThemeAttribute:@"tile-text-color" inState:[CPThemeStateHighlighted, CPThemeStateSelected]] forThemeAttribute:@"text-color" inState:[CPThemeStateHighlighted, CPThemeStateSelected]];
[_textField setValue:[_datePicker valueForThemeAttribute:@"tile-text-shadow-color" inState:[CPThemeStateHighlighted, CPThemeStateSelected]] forThemeAttribute:@"text-shadow-color" inState:[CPThemeStateHighlighted, CPThemeStateSelected]];
[_textField setValue:[_datePicker valueForThemeAttribute:@"tile-text-shadow-offset" inState:[CPThemeStateHighlighted, CPThemeStateSelected]] forThemeAttribute:@"text-shadow-offset" inState:[CPThemeStateHighlighted, CPThemeStateSelected]];
[_textField setValue:[_datePicker valueForThemeAttribute:@"tile-font" inState: CPThemeStateDisabled | CPThemeStateHighlighted | CPThemeStateSelected] forThemeAttribute:@"font" inState: CPThemeStateDisabled | CPThemeStateHighlighted | CPThemeStateSelected];
[_textField setValue:[_datePicker valueForThemeAttribute:@"tile-text-color" inState: CPThemeStateDisabled | CPThemeStateHighlighted | CPThemeStateSelected] forThemeAttribute:@"text-color" inState: CPThemeStateDisabled | CPThemeStateHighlighted | CPThemeStateSelected];
[_textField setValue:[_datePicker valueForThemeAttribute:@"tile-text-shadow-color" inState: CPThemeStateDisabled | CPThemeStateHighlighted | CPThemeStateSelected] forThemeAttribute:@"text-shadow-color" inState: CPThemeStateDisabled | CPThemeStateHighlighted | CPThemeStateSelected];
[_textField setValue:[_datePicker valueForThemeAttribute:@"tile-text-shadow-offset" inState: CPThemeStateDisabled | CPThemeStateHighlighted | CPThemeStateSelected] forThemeAttribute:@"text-shadow-offset" inState: CPThemeStateDisabled | CPThemeStateHighlighted | CPThemeStateSelected];
[_textField setValue:[_datePicker valueForThemeAttribute:@"tile-font" inState:[CPThemeStateDisabled, CPThemeStateHighlighted, CPThemeStateSelected]] forThemeAttribute:@"font" inState:[CPThemeStateDisabled, CPThemeStateHighlighted, CPThemeStateSelected]];
[_textField setValue:[_datePicker valueForThemeAttribute:@"tile-text-color" inState:[CPThemeStateDisabled, CPThemeStateHighlighted, CPThemeStateSelected]] forThemeAttribute:@"text-color" inState:[CPThemeStateDisabled, CPThemeStateHighlighted, CPThemeStateSelected]];
[_textField setValue:[_datePicker valueForThemeAttribute:@"tile-text-shadow-color" inState:[CPThemeStateDisabled, CPThemeStateHighlighted, CPThemeStateSelected]] forThemeAttribute:@"text-shadow-color" inState:[CPThemeStateDisabled, CPThemeStateHighlighted, CPThemeStateSelected]];
[_textField setValue:[_datePicker valueForThemeAttribute:@"tile-text-shadow-offset" inState:[CPThemeStateDisabled, CPThemeStateHighlighted, CPThemeStateSelected]] forThemeAttribute:@"text-shadow-offset" inState:[CPThemeStateDisabled, CPThemeStateHighlighted, CPThemeStateSelected]];
[_textField setValue:[_datePicker valueForThemeAttribute:@"tile-font" inState: CPThemeStateDisabled | CPThemeStateHighlighted ] forThemeAttribute:@"font" inState: CPThemeStateDisabled | CPThemeStateHighlighted ];
[_textField setValue:[_datePicker valueForThemeAttribute:@"tile-text-color" inState: CPThemeStateDisabled | CPThemeStateHighlighted ] forThemeAttribute:@"text-color" inState: CPThemeStateDisabled | CPThemeStateHighlighted ];
[_textField setValue:[_datePicker valueForThemeAttribute:@"tile-text-shadow-color" inState: CPThemeStateDisabled | CPThemeStateHighlighted ] forThemeAttribute:@"text-shadow-color" inState: CPThemeStateDisabled | CPThemeStateHighlighted ];
[_textField setValue:[_datePicker valueForThemeAttribute:@"tile-text-shadow-offset" inState: CPThemeStateDisabled | CPThemeStateHighlighted ] forThemeAttribute:@"text-shadow-offset" inState: CPThemeStateDisabled | CPThemeStateHighlighted];
[_textField setValue:[_datePicker valueForThemeAttribute:@"tile-font" inState:[CPThemeStateDisabled, CPThemeStateHighlighted]] forThemeAttribute:@"font" inState:[CPThemeStateDisabled, CPThemeStateHighlighted]];
[_textField setValue:[_datePicker valueForThemeAttribute:@"tile-text-color" inState:[CPThemeStateDisabled, CPThemeStateHighlighted]] forThemeAttribute:@"text-color" inState:[CPThemeStateDisabled, CPThemeStateHighlighted]];
[_textField setValue:[_datePicker valueForThemeAttribute:@"tile-text-shadow-color" inState:[CPThemeStateDisabled, CPThemeStateHighlighted]] forThemeAttribute:@"text-shadow-color" inState:[CPThemeStateDisabled, CPThemeStateHighlighted]];
[_textField setValue:[_datePicker valueForThemeAttribute:@"tile-text-shadow-offset" inState:[CPThemeStateDisabled, CPThemeStateHighlighted]] forThemeAttribute:@"text-shadow-offset" inState:[CPThemeStateDisabled, CPThemeStateHighlighted]];
[self addSubview:_textField];
@@ -1059,7 +1153,7 @@ var CPShortWeekDayNameArrayEn = [@"Mo", @"Tu", @"We", @"Th", @"Fr", @"Sa", @"Su"
/*! Set a theme
*/
- (BOOL)setThemeState:(CPThemeState)aState
- (BOOL)setThemeState:(ThemeState)aState
{
[_textField setThemeState:aState];
[super setThemeState:aState];
@@ -1067,7 +1161,7 @@ var CPShortWeekDayNameArrayEn = [@"Mo", @"Tu", @"We", @"Th", @"Fr", @"Sa", @"Su"
/*! Unset a theme
*/
- (BOOL)unsetThemeState:(CPThemeState)aState
- (BOOL)unsetThemeState:(ThemeState)aState
{
[_textField unsetThemeState:aState];
[super unsetThemeState:aState];
@@ -1156,7 +1250,7 @@ var CPShortWeekDayNameArrayEn = [@"Mo", @"Tu", @"We", @"Th", @"Fr", @"Sa", @"Su"
var themeState = [self themeState],
context = [[CPGraphicsContext currentContext] graphicsPort];
if (themeState & CPThemeStateSelected)
if (themeState.hasThemeState(CPThemeStateSelected))
{
[self setBackgroundColor:[_datePicker valueForThemeAttribute:@"bezel-color-calendar" inState:themeState]];
CGContextSetLineWidth(context, [_datePicker valueForThemeAttribute:@"border-width"]);
@@ -1175,19 +1269,11 @@ var CPShortWeekDayNameArrayEn = [@"Mo", @"Tu", @"We", @"Th", @"Fr", @"Sa", @"Su"
@end
@implementation _DatePickerBox : CPView
@implementation _CPDatePickerBox : CPView
{
CPDatePicker _datePicker @accessors(property=datePicker);
}
- (id)init
{
if (self = [super init])
{
}
return self;
}
- (void)drawRect:(CGRect)aRect
{
[super drawRect:aRect];
@@ -1201,10 +1287,10 @@ var CPShortWeekDayNameArrayEn = [@"Mo", @"Tu", @"We", @"Th", @"Fr", @"Sa", @"Su"
CGContextSetStrokeColor(context, [_datePicker valueForThemeAttribute:@"border-color" inState:[_datePicker themeState]]);
CGContextSetLineWidth(context, [_datePicker valueForThemeAttribute:@"border-width"]);
CGContextMoveToPoint(context, borderWidth,borderWidth);
CGContextAddLineToPoint(context, aRect.size.width - borderWidth,borderWidth);
CGContextAddLineToPoint(context, aRect.size.width - borderWidth,aRect.size.height - borderWidth);
CGContextAddLineToPoint(context, borderWidth,aRect.size.height - borderWidth);
CGContextMoveToPoint(context, borderWidth, borderWidth);
CGContextAddLineToPoint(context, aRect.size.width - borderWidth, borderWidth);
CGContextAddLineToPoint(context, aRect.size.width - borderWidth, aRect.size.height - borderWidth);
CGContextAddLineToPoint(context, borderWidth, aRect.size.height - borderWidth);
CGContextAddLineToPoint(context, borderWidth,borderWidth);
CGContextStrokePath(context);
@@ -1223,5 +1309,4 @@ var CPShortWeekDayNameArrayEn = [@"Mo", @"Tu", @"We", @"Th", @"Fr", @"Sa", @"Su"
[self setBackgroundColor:[CPColor clearColor]];
}
@end
-1
View File
@@ -25,7 +25,6 @@
@import "CPImageView.j"
@import "CALayer.j"
@class _CPCibCustomResource
@class CPDatePicker
File diff suppressed because it is too large Load Diff
+1
View File
@@ -20,6 +20,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@typedef CPDragOperation
CPDragOperationNone = 0;
CPDragOperationCopy = 1 << 1;
CPDragOperationLink = 1 << 1;
+36
View File
@@ -31,9 +31,15 @@
@import "CPText.j"
@class CPTextField
@class CPWindow
@class CPGraphicsContext
@global CPApp
@typedef DOMEvent
@typedef CPEventType
var _CPEventPeriodicEventPeriod = 0,
_CPEventPeriodicEventTimer = nil,
_CPEventUpperCaseRegex = new RegExp("[A-Z]"),
@@ -68,6 +74,9 @@ var _CPEventPeriodicEventPeriod = 0,
float _deltaX;
float _deltaY;
float _deltaZ;
float _scrollingDeltaX;
float _scrollingDeltaY;
BOOL _hasPreciseScrollingDeltas;
#if PLATFORM(DOM)
BOOL _suppressCappuccinoCut;
@@ -163,7 +172,9 @@ var _CPEventPeriodicEventPeriod = 0,
// Make sure these are 0 rather than nil.
_deltaX = 0;
_scrollingDeltaX = 0;
_deltaY = 0;
_scrollingDeltaY = 0;
_deltaZ = 0;
}
@@ -417,6 +428,31 @@ var _CPEventPeriodicEventPeriod = 0,
return _deltaZ;
}
- (BOOL)hasPreciseScrollingDeltas
{
return !!_hasPreciseScrollingDeltas;
}
/*!
Returns the change in points on the x-axis for a mouse movement, unless hasPreciseScrollingDeltas is NO,
in which case the change is measured in number of "lines" or "rows" and needs to be multiplied as appropriate
to get change in pixels.
*/
- (float)scrollingDeltaX
{
return _scrollingDeltaX;
}
/*!
Returns the change in points on the y-axis for a mouse movement, unless hasPreciseScrollingDeltas is NO,
in which case the change is measured in number of "lines" or "columns" and needs to be multiplied as appropriate
to get change in pixels.
*/
- (float)scrollingDeltaY
{
return _scrollingDeltaY;
}
- (BOOL)_triggersKeyEquivalent:(CPString)aKeyEquivalent withModifierMask:aKeyEquivalentModifierMask
{
if (!aKeyEquivalent)
+4 -4
View File
@@ -174,20 +174,20 @@ following:
return _CPFontSystemFontSize;
}
+ (float)systemFontSizeForControlSize:(CPControlSize)aSize
+ (CPFont)systemFontForControlSize:(CPControlSize)aSize
{
// TODO These sizes should be themable or made less arbitrary in some other way.
switch (aSize)
{
case CPSmallControlSize:
return _CPFontSystemFontSize - 1;
return [self systemFontOfSize:_CPFontSystemFontSize - 1];
case CPMiniControlSize:
return _CPFontSystemFontSize - 2;
return [self systemFontOfSize:_CPFontSystemFontSize - 2];
case CPRegularControlSize:
default:
return _CPFontSystemFontSize;
return [self systemFontOfSize:_CPFontSystemFontSize];
}
}
+38 -10
View File
@@ -30,6 +30,20 @@
@import "CGGeometry.j"
@import "CPCompatibility.j"
@protocol CPImageDelegate <CPObject>
@optional
- (void)imageDidLoad:(CPImage)anImage;
- (void)imageDidError:(CPImage)anImage;
- (void)imageDidAbort:(CPImage)anImage;
@end
var CPImageDelegate_imageDidLoad_ = 1 << 1,
CPImageDelegate_imageDidError_ = 1 << 2,
CPImageDelegate_imageDidAbort_ = 1 << 3;
CPImageLoadStatusInitialized = 0;
CPImageLoadStatusLoading = 1;
CPImageLoadStatusCompleted = 2;
@@ -119,14 +133,15 @@ function CPAppKitImage(aFilename, aSize)
*/
@implementation CPImage : CPObject
{
CGSize _size;
CPString _filename;
CPString _name;
CGSize _size;
CPString _filename;
CPString _name;
id _delegate;
unsigned _loadStatus;
id <CPImageDelegate> _delegate;
unsigned _loadStatus;
unsigned _implementedDelegateMethods;
Image _image;
Image _image;
}
- (id)init
@@ -319,9 +334,22 @@ function CPAppKitImage(aFilename, aSize)
Sets the receiver's delegate.
@param the delegate
*/
- (void)setDelegate:(id)aDelegate
- (void)setDelegate:(id <CPImageDelegate>)aDelegate
{
if (_delegate === aDelegate)
return;
_delegate = aDelegate;
_implementedDelegateMethods = 0;
if ([_delegate respondsToSelector:@selector(imageDidLoad:)])
_implementedDelegateMethods |= CPImageDelegate_imageDidLoad_;
if ([_delegate respondsToSelector:@selector(imageDidError:)])
_implementedDelegateMethods |= CPImageDelegate_imageDidError_;
if ([_delegate respondsToSelector:@selector(imageDidAbort:)])
_implementedDelegateMethods |= CPImageDelegate_imageDidAbort_;
}
/*!
@@ -457,7 +485,7 @@ function CPAppKitImage(aFilename, aSize)
postNotificationName:CPImageDidLoadNotification
object:self];
if ([_delegate respondsToSelector:@selector(imageDidLoad:)])
if (_implementedDelegateMethods & CPImageDelegate_imageDidLoad_)
[_delegate imageDidLoad:self];
}
@@ -466,7 +494,7 @@ function CPAppKitImage(aFilename, aSize)
{
_loadStatus = CPImageLoadStatusReadError;
if ([_delegate respondsToSelector:@selector(imageDidError:)])
if (_implementedDelegateMethods & CPImageDelegate_imageDidError_)
[_delegate imageDidError:self];
}
@@ -475,7 +503,7 @@ function CPAppKitImage(aFilename, aSize)
{
_loadStatus = CPImageLoadStatusCancelled;
if ([_delegate respondsToSelector:@selector(imageDidAbort:)])
if (_implementedDelegateMethods & CPImageDelegate_imageDidAbort_)
[_delegate imageDidAbort:self];
}
+2
View File
@@ -29,6 +29,7 @@
@global CPImagesPboardType
@global appkit_tag_dom_elements
@typedef CPImageAlignment
CPImageAlignCenter = 0;
CPImageAlignTop = 1;
CPImageAlignTopLeft = 2;
@@ -178,6 +179,7 @@ var CPImageViewEmptyPlaceholderImage = nil;
- (void)imageDidLoad:(CPNotification)aNotification
{
[[CPNotificationCenter defaultCenter] removeObserver:self name:CPImageDidLoadNotification object:[self objectValue]];
[self hideOrDisplayContents];
[self setNeedsLayout];
+45 -2
View File
@@ -35,6 +35,7 @@
var exposedBindingsMap = @{},
bindingsMap = @{};
@typedef CPBindingOperationKind
var CPBindingOperationAnd = 0,
CPBindingOperationOr = 1;
@@ -70,6 +71,20 @@ var CPBindingOperationAnd = 0,
return [[bindingsMap objectForKey:[anObject UID]] objectForKey:aBinding];
}
+ (void)_reverseSetValueFromExclusiveBinderForObject:(id)anObject
{
var bindersByBindingName = [bindingsMap objectForKey:[anObject UID]];
[bindersByBindingName enumerateKeysAndObjectsUsingBlock:function(binding, binder, stop)
{
if ([binder isKindOfClass:[self class]])
{
[binder reverseSetValueFor:binding];
stop(YES);
}
}];
}
+ (CPDictionary)infoForBinding:(CPString)aBinding forObject:(id)anObject
{
var theBinding = [self getBinding:aBinding forObject:anObject];
@@ -116,7 +131,7 @@ var CPBindingOperationAnd = 0,
count = allKeys.length;
while (count--)
[anObject unbind:[bindings objectForKey:allKeys[count]]];
[anObject unbind:allKeys[count]];
[bindingsMap removeObjectForKey:[anObject UID]];
}
@@ -142,7 +157,7 @@ var CPBindingOperationAnd = 0,
[self _updatePlaceholdersWithOptions:options forBinding:aName];
[aDestination addObserver:self forKeyPath:aKeyPath options:CPKeyValueObservingOptionNew context:aBinding];
[aDestination addObserver:self forKeyPath:aKeyPath options:0 context:aBinding];
var bindings = [bindingsMap objectForKey:[_source UID]];
@@ -159,6 +174,24 @@ var CPBindingOperationAnd = 0,
return self;
}
+ (BOOL)isBindingAllowed:(CPString)aBinding forObject:(id)anObject
{
if ([[anObject class] isBindingExclusive:aBinding])
{
var bindingsForObject = [bindingsMap objectForKey:[anObject UID]],
allBindings = [bindingsForObject allKeys],
count = [allBindings count];
while(count--)
{
if ([[anObject class] isBindingExclusive:allBindings[count]])
return NO;
}
}
return YES;
}
- (void)raiseIfNotApplicable:(id)aValue forKeyPath:(CPString)keyPath options:(CPDictionary)options
{
if (aValue === CPNotApplicableMarker && [options objectForKey:CPRaisesForNotApplicableKeysBindingOption])
@@ -387,6 +420,11 @@ var CPBindingOperationAnd = 0,
return [CPBinder class];
}
+ (BOOL)isBindingExclusive:(CPString)aBinding
{
return NO;
}
- (CPArray)exposedBindings
{
var exposedBindings = [],
@@ -415,6 +453,11 @@ var CPBindingOperationAnd = 0,
if (!anObject || !aKeyPath)
return CPLog.error("Invalid object or path on " + self + " for " + aBinding);
if (![CPBinder isBindingAllowed:aBinding forObject:self])
{
CPLog.warn([self description] + " : cannot bind " + aBinding + " because another binding with the same functionality is already in use.");
return;
}
//if (![[self exposedBindings] containsObject:aBinding])
// CPLog.warn("No binding exposed on " + self + " for " + aBinding);
+17 -4
View File
@@ -25,11 +25,13 @@
@global CPApp
@typedef CPTickMarkPosition
CPTickMarkBelow = 0;
CPTickMarkAbove = 1;
CPTickMarkLeft = CPTickMarkAbove;
CPTickMarkRight = CPTickMarkBelow;
@typedef CPLevelIndicatorStyle
CPRelevancyLevelIndicatorStyle = 0;
CPContinuousCapacityLevelIndicatorStyle = 1;
CPDiscreteCapacityLevelIndicatorStyle = 2;
@@ -105,10 +107,21 @@ CPRatingLevelIndicatorStyle = 3;
var filledColor = [self valueForThemeAttribute:@"color-normal"],
value = [self doubleValue];
if (value <= _criticalValue)
filledColor = [self valueForThemeAttribute:@"color-critical"];
else if (value <= _warningValue)
filledColor = [self valueForThemeAttribute:@"color-warning"];
if (_warningValue < _criticalValue)
{
if (value >= _criticalValue)
filledColor = [self valueForThemeAttribute:@"color-critical"];
else if (value >= _warningValue)
filledColor = [self valueForThemeAttribute:@"color-warning"];
}
else
{
if (value <= _criticalValue)
filledColor = [self valueForThemeAttribute:@"color-critical"];
else if (value <= _warningValue)
filledColor = [self valueForThemeAttribute:@"color-warning"];
}
for (var i = 0; i < segmentCount; i++)
{
+68 -21
View File
@@ -30,6 +30,17 @@
@global CPApp
@protocol CPMenuDelegate <CPObject>
@optional
- (void)menuWillOpen:(CPMenu)aMenu;
- (void)menuDidClose:(CPMenu)aMenu;
@end
var CPMenuDelegate_menuWillOpen_ = 1 << 1,
CPMenuDelegate_menuDidClose_ = 1 << 2;
CPMenuDidAddItemNotification = @"CPMenuDidAddItemNotification";
CPMenuDidChangeItemNotification = @"CPMenuDidChangeItemNotification";
CPMenuDidRemoveItemNotification = @"CPMenuDidRemoveItemNotification";
@@ -50,26 +61,27 @@ var _CPMenuBarVisible = NO,
*/
@implementation CPMenu : CPObject
{
CPMenu _supermenu;
CPMenu _supermenu;
CPString _title;
CPString _name;
CPString _title;
CPString _name;
CPFont _font;
CPFont _font;
float _minimumWidth;
float _minimumWidth;
CPMutableArray _items;
CPMutableArray _items;
BOOL _autoenablesItems;
BOOL _showsStateColumn;
BOOL _autoenablesItems;
BOOL _showsStateColumn;
id _delegate;
id <CPMenuDelegate> _delegate;
unsigned _implementedDelegateMethods;
int _highlightedIndex;
_CPMenuWindow _menuWindow;
int _highlightedIndex;
_CPMenuWindow _menuWindow;
CPEvent _lastCloseEvent;
CPEvent _lastCloseEvent;
}
// Managing the Menu Bar
@@ -639,6 +651,7 @@ var _CPMenuBarVisible = NO,
if (binder)
{
[binder setValueFor:CPEnabledBinding];
[[_menuWindow _menuView] tile];
return;
}
@@ -941,9 +954,19 @@ var _CPMenuBarVisible = NO,
// Managing the Delegate
- (void)setDelegate:(id)aDelegate
- (void)setDelegate:(id <CPMenuDelegate>)aDelegate
{
if (_delegate === aDelegate)
return;
_delegate = aDelegate;
_implementedDelegateMethods = 0;
if ([_delegate respondsToSelector:@selector(menuWillOpen:)])
_implementedDelegateMethods |= CPMenuDelegate_menuWillOpen_;
if ([_delegate respondsToSelector:@selector(menuDidClose:)])
_implementedDelegateMethods |= CPMenuDelegate_menuDidClose_;
}
- (id)delegate
@@ -953,10 +976,7 @@ var _CPMenuBarVisible = NO,
- (void)_menuWillOpen
{
var delegate = [self delegate];
if ([delegate respondsToSelector:@selector(menuWillOpen:)])
[delegate menuWillOpen:self];
[self _sendDelegateMenuWillOpen];
}
- (void)_menuDidClose
@@ -965,10 +985,7 @@ var _CPMenuBarVisible = NO,
// when a click on the button itself caused the menu to close.
_lastCloseEvent = [CPApp currentEvent];
var delegate = [self delegate];
if ([delegate respondsToSelector:@selector(menuDidClose:)])
[delegate menuDidClose:self];
[self _sendDelegateMenuDidClose];
}
// Handling Tracking
@@ -1132,6 +1149,36 @@ var _CPMenuBarVisible = NO,
@end
@implementation CPMenu (CPMenuDelegate)
/*!
@ignore
Call delegate menuWillOpen
*/
- (void)_sendDelegateMenuWillOpen
{
if (!(_implementedDelegateMethods & CPMenuDelegate_menuWillOpen_))
return;
[_delegate menuWillOpen:self];
}
/*!
@ignore
Call delegate menuDidClose
*/
- (void)_sendDelegateMenuDidClose
{
if (!(_implementedDelegateMethods & CPMenuDelegate_menuDidClose_))
return;
[_delegate menuDidClose:self];
}
@end
@implementation CPMenu (CPKeyValueCoding)
- (CPUInteger)countOfItems
+1
View File
@@ -24,6 +24,7 @@
@import "_CPMenuManager.j"
@class _CPMenuView
@class CPMenu
@global CPMenuDidAddItemNotification
@global CPMenuDidChangeItemNotification
+3 -1
View File
@@ -25,6 +25,8 @@
@import "CPWindow.j"
@import "_CPMenuManager.j"
@class _CPMenuView
var _CPMenuWindowPool = [],
_CPMenuWindowPoolCapacity = 5,
@@ -410,7 +412,7 @@ _CPMenuWindowAttachedMenuBackgroundStyle = 2;
{
// Don't return indexes of items that aren't visible.
if (!CGRectContainsPoint([_menuClipView bounds], [_menuClipView convertPoint:aPoint fromView:nil]))
return NO;
return CPNotFound;
return [_menuView itemIndexAtPoint:[_menuView convertPoint:aPoint fromView:nil]];
}
@@ -25,6 +25,7 @@
@class _CPMenuBarWindow
@class _CPMenuView
@class CPMenuItem
@implementation _CPMenuItemMenuBarView : CPView
{
@@ -24,6 +24,9 @@
@import "CPImageView.j"
@import "_CPImageAndTextView.j"
@class CPMenuItem
@implementation _CPMenuItemStandardView : CPView
{
CPMenuItem _menuItem @accessors(property=menuItem);
+1
View File
@@ -26,6 +26,7 @@
@import "_CPMenuItemStandardView.j"
@import "_CPMenuItemMenuBarView.j"
@class CPMenuItem
@global CPApp
/*
+17 -12
View File
@@ -459,13 +459,13 @@ var CPObjectControllerContentKey = @"CPObjectControllerCo
- (BOOL)isEqual:(id)anObject
{
if ([anObject class] === [self class])
{
if (anObject._observer === _observer && [anObject._keyPath isEqual:_keyPath] && [anObject._object isEqual:_object])
return YES;
}
if (self === anObject)
return YES;
return NO;
if (!anObject || [anObject class] !== [self class] || anObject._observer !== _observer || anObject._keyPath !== _keyPath || anObject._object !== _object)
return NO;
return YES;
}
- (void)observeValueForKeyPath:(CPString)aKeyPath ofObject:(id)anObject change:(CPDictionary)change context:(id)context
@@ -808,15 +808,20 @@ var CPObjectControllerContentKey = @"CPObjectControllerCo
- (void)removeObserver:(id)anObject forKeyPath:(CPString)aKeyPath
{
var proxy = [[_CPObservationProxy alloc] initWithKeyPath:aKeyPath observer:anObject object:self],
index = [_observationProxies indexOfObject:proxy];
[_observationProxies enumerateObjectsUsingBlock:function(aProxy, idx, stop)
{
if (aProxy._object === self && aProxy._keyPath == aKeyPath && aProxy._observer === anObject)
{
var observedObjects = _observedObjectsByKeyPath[aKeyPath];
var observedObjects = _observedObjectsByKeyPath[aKeyPath];
[observedObjects removeObserver:[_observationProxies objectAtIndex:index] forKeyPath:aKeyPath];
[observedObjects removeObserver:aProxy forKeyPath:aKeyPath];
[_observationProxies removeObjectAtIndex:idx];
[_observationProxies removeObjectAtIndex:index];
_observedObjectsByKeyPath[aKeyPath] = nil;
_observedObjectsByKeyPath[aKeyPath] = nil;
stop(YES);
}
}];
}
@end
+412 -241
View File
@@ -52,7 +52,6 @@ var CPOutlineViewDataSource_outlineView_objectValue_forTableColumn_byItem_
CPOutlineViewDataSource_outlineView_sortDescriptorsDidChange_ = 1 << 11;
var CPOutlineViewDelegate_outlineView_dataViewForTableColumn_item_ = 1 << 1,
CPOutlineViewDelegate_outlineView_viewForTableColumn_item_ = 1 << 26,
CPOutlineViewDelegate_outlineView_didClickTableColumn_ = 1 << 2,
CPOutlineViewDelegate_outlineView_didDragTableColumn_ = 1 << 3,
CPOutlineViewDelegate_outlineView_heightOfRowByItem_ = 1 << 4,
@@ -75,8 +74,10 @@ var CPOutlineViewDelegate_outlineView_dataViewForTableColumn_item_
CPOutlineViewDelegate_outlineView_typeSelectStringForTableColumn_item_ = 1 << 21,
CPOutlineViewDelegate_outlineView_willDisplayOutlineView_forTableColumn_item_ = 1 << 22,
CPOutlineViewDelegate_outlineView_willDisplayView_forTableColumn_item_ = 1 << 23,
CPOutlineViewDelegate_selectionShouldChangeInOutlineView_ = 1 << 24,
CPOutlineViewDelegate_outlineView_menuForTableColumn_item_ = 1 << 25;
CPOutlineViewDelegate_outlineView_willRemoveView_forTableColumn_item_ = 1 << 24,
CPOutlineViewDelegate_selectionShouldChangeInOutlineView_ = 1 << 25,
CPOutlineViewDelegate_outlineView_menuForTableColumn_item_ = 1 << 26,
CPOutlineViewDelegate_outlineView_viewForTableColumn_item_ = 1 << 27;
CPOutlineViewDropOnItemIndex = -1;
@@ -88,6 +89,58 @@ var CPOutlineViewCoalesceSelectionNotificationStateOff = 0,
#define SHOULD_SELECT_ITEM(anOutlineView, anItem) (!((anOutlineView)._implementedOutlineViewDelegateMethods & CPOutlineViewDelegate_outlineView_shouldSelectItem_) || [(anOutlineView)._outlineViewDelegate outlineView:(anOutlineView) shouldSelectItem:(anItem)])
@protocol CPOutlineViewDelegate <CPObject>
@optional
- (BOOL)outlineView:(CPOutlineView)anOutlineView isGroupItem:(id)anItem;
- (BOOL)outlineView:(CPOutlineView)anOutlineView shouldCollapseItem:(id)anItem;
- (BOOL)outlineView:(CPOutlineView)anOutlineView shouldEditTableColumn:(CPTableColumn)aTableColumn item:(id)anItem;
- (BOOL)outlineView:(CPOutlineView)anOutlineView shouldExpandItem:(id)anItem;
- (BOOL)outlineView:(CPOutlineView)anOutlineView shouldReorderColumn:(CPInteger)columnIndex toColumn:(CPInteger)newColumnIndex;
- (BOOL)outlineView:(CPOutlineView)anOutlineView shouldSelectItem:(id)anItem;
- (BOOL)outlineView:(CPOutlineView)anOutlineView shouldSelectTableColumn:(CPTableColumn)aTableColumn;
- (BOOL)outlineView:(CPOutlineView)anOutlineView shouldShowOutlineDisclosureControlForItem:(id)anItem;
- (BOOL)outlineView:(CPOutlineView)anOutlineView shouldShowViewExpansionForTableColumn:(CPTableColumn)aTableColumn item:(id)anItem;
- (BOOL)outlineView:(CPOutlineView)anOutlineView shouldTrackView:(CPView)aView forTableColumn:(CPTableColumn)aTableColumn item:(id)anItem;
- (BOOL)outlineView:(CPOutlineView)anOutlineView shouldTypeSelectForEvent:(CPEvent)anEvent withCurrentSearchString:(CPString)searchString;
- (BOOL)selectionShouldChangeInOutlineView:(CPOutlineView)anOutlineView;
- (CPIndexSet)outlineView:(CPOutlineView)anOutlineView selectionIndexesForProposedSelection:(CPIndexSet)proposedSelectionIndexes;
- (CPMenu)outlineView:(CPOutlineView)anOutlineView menuForTableColumn:(CPTableColumn)aTableColumn item:(id)anItem;
- (CPString)outlineView:(CPOutlineView)anOutlineView toolTipForView:(CPView)aView rect:(CGRect)aRect tableColumn:(CPTableColumn)aTableColumn item:(id)anItem mouseLocation:(CGPoint)mouseLocation;
- (CPString)outlineView:(CPOutlineView)anOutlineView typeSelectStringForTableColumn:(CPTableColumn)aTableColumn item:(id)anItem;
- (CPView)outlineView:(CPOutlineView)anOutlineView dataViewForTableColumn:(CPTableColumn)aTableColumn item:(id)anItem;
- (CPView)outlineView:(CPOutlineView)anOutlineView viewForTableColumn:(CPTableColumn)aTableColumn item:(id)anItem;
- (float)outlineView:(CPOutlineView)anOutlineView heightOfRowByItem:(id)anItem;
- (float)outlineView:(CPOutlineView)anOutlineView sizeToFitWidthOfColumn:(CPTableColumn)aTableColumn;
- (id)outlineView:(CPOutlineView)anOutlineView nextTypeSelectMatchFromItem:(id)startItem toItem:(id)endItem forString:(CPString)searchString;
- (void)outlineView:(CPOutlineView)anOutlineView didClickTableColumn:(CPTableColumn)aTableColumn;
- (void)outlineView:(CPOutlineView)anOutlineView didDragTableColumn:(CPTableColumn)aTableColumn;
- (void)outlineView:(CPOutlineView)anOutlineView mouseDownInHeaderOfTableColumn:(CPTableColumn)aTableColumn;
- (void)outlineView:(CPOutlineView)anOutlineView willDisplayOutlineView:(CPView)aView forTableColumn:(CPTableColumn)aTableColumn item:(id)anItem;
- (void)outlineView:(CPOutlineView)anOutlineView willDisplayView:(CPView)aView forTableColumn:(CPTableColumn)aTableColumn item:(id)anItem;
- (void)outlineView:(CPOutlineView)anOutlineView willRemoveView:(CPView)aView forTableColumn:(CPTableColumn)aTableColumn item:(id)anItem;
@end
@protocol CPOutlineViewDataSource <CPObject>
@optional
- (BOOL)outlineView:(CPOutlineView)anOutlineView acceptDrop:(id /*<CPDraggingInfo>*/)info item:(id)anItem childIndex:(CPInteger)anIndex;
- (BOOL)outlineView:(CPOutlineView)anOutlineView shouldDeferDisplayingChildrenOfItem:(id)anItem;
- (BOOL)outlineView:(CPOutlineView)anOutlineView writeItems:(CPArray)items toPasteboard:(CPPasteboard)pboard;
- (CPArray)outlineView:(CPOutlineView)anOutlineView namesOfPromisedFilesDroppedAtDestination:(CPURL)dropDestination forDraggedItems:(CPArray)items;
- (CPDragOperation)outlineView:(CPOutlineView)anOutlineView validateDrop:(id /*<CPDraggingInfo>*/)info proposedItem:(id)anItem proposedChildIndex:(CPInteger)anIndex;
- (CPDragOperation)outlineView:(CPOutlineView)anOutlineView validateDrop:(id /*<CPDraggingInfo>*/)info proposedRow:(int)theRow proposedDropOperation:(CPTableViewDropOperation)theOperation;
- (id)outlineView:(CPOutlineView)anOutlineView itemForPersistentObject:(id)anObject;
- (id)outlineView:(CPOutlineView)anOutlineView objectValueforTableColumn:(CPTableColumn)aTableColumn byItem:(id)anItem;
- (id)outlineView:(CPOutlineView)anOutlineView persistentObjectForItem:(id)anItem;
- (void)outlineView:(CPOutlineView)anOutlineView setObjectValue:(id)anObject forTableColumn:(CPTableColumn)aTableColumn byItem:(id)anItem;
- (void)outlineView:(CPOutlineView)anOutlineView sortDescriptorsDidChange:(CPArray)oldDescriptors;
@end
/*!
@ingroup appkit
@class CPOutlineView
@@ -105,34 +158,37 @@ var CPOutlineViewCoalesceSelectionNotificationStateOff = 0,
*/
@implementation CPOutlineView : CPTableView
{
id _outlineViewDataSource;
id _outlineViewDelegate;
CPTableColumn _outlineTableColumn;
id <CPOutlineViewDataSource> _outlineViewDataSource;
id <CPOutlineViewDelegate> _outlineViewDelegate;
CPTableColumn _outlineTableColumn;
float _indentationPerLevel;
BOOL _indentationMarkerFollowsDataView;
float _indentationPerLevel;
BOOL _indentationMarkerFollowsDataView;
CPInteger _implementedOutlineViewDataSourceMethods;
CPInteger _implementedOutlineViewDelegateMethods;
CPInteger _implementedOutlineViewDataSourceMethods;
CPInteger _implementedOutlineViewDelegateMethods;
Object _rootItemInfo;
CPMutableArray _itemsForRows;
Object _itemInfosForItems;
Object _rootItemInfo;
CPMutableArray _itemsForRows;
Object _itemInfosForItems;
CPControl _disclosureControlPrototype;
CPArray _disclosureControlsForRows;
CPData _disclosureControlData;
CPArray _disclosureControlQueue;
CPControl _disclosureControlPrototype;
CPArray _disclosureControlsForRows;
CPData _disclosureControlData;
CPArray _disclosureControlQueue;
BOOL _shouldRetargetItem;
id _retargetedItem;
BOOL _shouldRetargetItem;
id _retargetedItem;
BOOL _shouldRetargetChildIndex;
CPInteger _retargedChildIndex;
CPTimer _dragHoverTimer;
id _dropItem;
BOOL _shouldRetargetChildIndex;
CPInteger _retargedChildIndex;
CPTimer _dragHoverTimer;
id _dropItem;
BOOL _coalesceSelectionNotificationState;
BOOL _coalesceSelectionNotificationState;
CPArray _pendingItemToClean;
CPArray _itemAddedDuringLastLoading;
}
- (id)initWithFrame:(CGRect)aFrame
@@ -218,7 +274,7 @@ var CPOutlineViewCoalesceSelectionNotificationStateOff = 0,
If you want the drag to begin you should return YES and place the drag data on the pboard.
@code - (BOOL)outlineView:(CPOutlineView)outlineView writeItems:(CPArray)items toPasteboard:(CPPasteboard)pboard; @endcode
*/
- (void)setDataSource:(id)aDataSource
- (void)setDataSource:(id <CPOutlineViewDataSource>)aDataSource
{
if (_outlineViewDataSource === aDataSource)
return;
@@ -293,7 +349,7 @@ var CPOutlineViewCoalesceSelectionNotificationStateOff = 0,
if (!anItem)
return YES;
var itemInfo = _itemInfosForItems[[anItem UID]];
var itemInfo = [self _itemInfosForItem:anItem];
if (!itemInfo)
return NO;
@@ -326,7 +382,7 @@ var CPOutlineViewCoalesceSelectionNotificationStateOff = 0,
if (!anItem)
return YES;
var itemInfo = _itemInfosForItems[[anItem UID]];
var itemInfo = [self _itemInfosForItem:anItem];
if (!itemInfo)
return NO;
@@ -334,6 +390,107 @@ var CPOutlineViewCoalesceSelectionNotificationStateOff = 0,
return itemInfo.isExpanded;
}
/*!
Returns the item at a given row index. If no item exists nil is returned.
@param aRow - The row index you want to find the item at.
@return id - The item at a given index.
*/
- (id)itemAtRow:(CPInteger)aRow
{
return _itemsForRows[aRow] || nil;
}
/*!
Returns the row of a given item
@param anItem - The item you want to find the row of.
@return int - The row index of a given item.
*/
- (CPInteger)rowForItem:(id)anItem
{
if (!anItem)
return _rootItemInfo.row;
var itemInfo = [self _itemInfosForItem:anItem];
if (!itemInfo)
return CPNotFound;
return itemInfo.row;
}
/*!
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.
*/
- (CPInteger)levelForItem:(id)anItem
{
if (!anItem)
return _rootItemInfo.level;
var itemInfo = [self _itemInfosForItem:anItem];
if (!itemInfo)
return CPNotFound;
return itemInfo.level;
}
/*!
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 receiver
@return int - the indentation level of aRow.
*/
- (CPInteger)levelForRow:(CPInteger)aRow
{
var item = [self itemAtRow:aRow];
if (!item && aRow >= 0)
item = [CPObject new];
return [self levelForItem:item];
}
/*!
@ignore
Return the itemInfos for the given item.
The method returns only itemInfo for displayed items
*/
- (Object)_itemInfosForItem:(id)anItem
{
var itemInfo = _itemInfosForItems[[anItem UID]];
if (!itemInfo || [self _parentIsCollapsed:[self parentForItem:anItem]])
return nil;
return itemInfo;
}
/*!
@ignore
Return a boolean to know if one parent of the given item is collapsed or not
*/
- (BOOL)_parentIsCollapsed:(id)anItem
{
var parentItem = [self parentForItem:anItem],
itemInfo = _itemInfosForItems[[anItem UID]];
if (!itemInfo)
return NO;
if (!itemInfo.isExpanded)
return YES;
return [self _parentIsCollapsed:parentItem];
}
/*!
Expands a given item.
@@ -370,6 +527,7 @@ var CPOutlineViewCoalesceSelectionNotificationStateOff = 0,
// 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;
@@ -389,6 +547,7 @@ var CPOutlineViewCoalesceSelectionNotificationStateOff = 0,
// Shift selection indexes below so that the same items remain selected.
var rowCountDelta = [self numberOfRows] - previousRowCount;
if (rowCountDelta)
{
var selection = [self selectedRowIndexes],
@@ -478,6 +637,7 @@ var CPOutlineViewCoalesceSelectionNotificationStateOff = 0,
[self _setSelectedRowIndexes:selection]; // _noteSelectionDidChange will be suppressed.
}
}
itemInfo.isExpanded = NO;
[self reloadItem:anItem reloadChildren:YES];
@@ -509,42 +669,205 @@ var CPOutlineViewCoalesceSelectionNotificationStateOff = 0,
*/
- (void)reloadItem:(id)anItem reloadChildren:(BOOL)shouldReloadChildren
{
_pendingItemToClean = [];
_itemAddedDuringLastLoading = [];
if (!!shouldReloadChildren || !anItem)
_loadItemInfoForItem(self, anItem);
[self _loadItemInfoForItem:anItem intermediate:NO];
else
_reloadItem(self, anItem);
[self _reloadItem:anItem];
[self _cleanPendingItem];
[super reloadData];
}
/*!
Returns the item at a given row index. If no item exists nil is returned.
@param aRow - The row index you want to find the item at.
@return id - The item at a given index.
*/
- (id)itemAtRow:(CPInteger)aRow
{
return _itemsForRows[aRow] || nil;
}
/*!
Returns the row of a given item
@param anItem - The item you want to find the row of.
@return int - The row index of a given item.
*/
- (CPInteger)rowForItem:(id)anItem
- (void)_reloadItem:(id)anItem
{
if (!anItem)
return _rootItemInfo.row;
return;
// Get the existing info if it exists.
var itemUID = [anItem UID],
itemInfo = _itemInfosForItems[itemUID];
// If we're not in the tree, then just bail.
if (!itemInfo)
return [];
// See if the item itself can be swapped out.
var parent = itemInfo.parent,
parentItemInfo = parent ? _itemInfosForItems[[parent UID]] : _rootItemInfo,
parentChildren = parentItemInfo.children,
index = [parentChildren indexOfObjectIdenticalTo:anItem],
newItem = [_outlineViewDataSource outlineView:self child:index ofItem:parent];
if (anItem !== newItem)
{
_itemInfosForItems[[anItem UID]] = nil;
_itemInfosForItems[[newItem UID]] = itemInfo;
parentChildren[index] = newItem;
_itemsForRows[itemInfo.row] = newItem;
}
itemInfo.isExpandable = [_outlineViewDataSource outlineView:self isItemExpandable:newItem];
itemInfo.isExpanded = itemInfo.isExpandable && itemInfo.isExpanded;
itemInfo.shouldShowOutlineDisclosureControl = [self _sendDelegateShouldShowOutlineDisclosureControlForItem:newItem];
}
- (void)_addPendingItemsFromPreviousItems:(CPArray)previousItems forItemInfo:(Object)itemInfo
{
if (!itemInfo)
return;
var children = itemInfo.children;
for (var i = [previousItems count] - 1; i >= 0; i--)
{
var item = previousItems[i];
if (![children containsObject:item])
[self _addPendingItem:item];
}
}
- (void)_addPendingItem:(id)anItem
{
var itemInfo = _itemInfosForItems[[anItem UID]];
if (!itemInfo)
return CPNotFound;
return;
return itemInfo.row;
var children = itemInfo.children;
for (var i = [children count]; i >= 0; i--)
{
var child = children[i];
[self _addPendingItem:child];
}
[_pendingItemToClean addObject:anItem];
}
- (void)_cleanPendingItem
{
for (var i = [_pendingItemToClean count]; i >= 0; i--)
{
var item = _pendingItemToClean[i];
if (![_itemAddedDuringLastLoading containsObject:item])
delete _itemInfosForItems[[item UID]];
}
_pendingItemToClean = [];
_itemAddedDuringLastLoading = [];
}
- (CPArray)_loadItemInfoForItem:(id)anItem intermediate:(BOOL)isIntermediate
{
if (!anItem)
{
var itemInfo = _rootItemInfo;
}
else
{
// Get the existing info if it exists.
var itemUID = [anItem UID],
itemInfo = _itemInfosForItems[itemUID];
// If we're not in the tree, then just bail.
if (!itemInfo)
return [];
itemInfo.isExpandable = [_outlineViewDataSource outlineView:self isItemExpandable:anItem];
itemInfo.shouldShowOutlineDisclosureControl = [self _sendDelegateShouldShowOutlineDisclosureControlForItem:anItem];
// If we were previously expanded, but now no longer expandable, "de-expand".
// NOTE: we are *not* collapsing, thus no notification is posted.
if (!itemInfo.isExpandable && itemInfo.isExpanded)
{
itemInfo.isExpanded = NO;
itemInfo.children = [];
}
}
// The root item does not count as a descendant.
var weight = itemInfo.weight,
descendants = anItem ? [anItem] : [];
[_itemAddedDuringLastLoading addObject:anItem];
if (itemInfo.isExpanded && [self _sendDataSourceShouldDeferDisplayingChildrenOfItem:anItem])
{
var index = 0,
count = [_outlineViewDataSource outlineView:self numberOfChildrenOfItem:anItem],
level = itemInfo.level + 1,
previousChildren = itemInfo.children;
itemInfo.children = [];
for (; index < count; ++index)
{
var childItem = [_outlineViewDataSource outlineView:self child:index ofItem:anItem],
childItemInfo = _itemInfosForItems[[childItem UID]];
if (!childItemInfo)
{
childItemInfo = { isExpanded:NO, isExpandable:NO, shouldShowOutlineDisclosureControl:YES, children:[], weight:1 };
_itemInfosForItems[[childItem UID]] = childItemInfo;
}
itemInfo.children[index] = childItem;
var childDescendants = [self _loadItemInfoForItem:childItem intermediate:YES];
childItemInfo.parent = anItem;
childItemInfo.level = level;
descendants = descendants.concat(childDescendants);
}
// Here we clean the itemInfos dictionary
// Some items could have been removed at this point, we don't need to keep a ref of them anymore
[self _addPendingItemsFromPreviousItems:previousChildren forItemInfo:itemInfo];
}
itemInfo.weight = descendants.length;
if (!isIntermediate)
{
// row = -1 is the root item, so just go to row 0 since it is ignored.
var index = MAX(itemInfo.row, 0);
descendants.unshift(index, weight);
_itemsForRows.splice.apply(_itemsForRows, descendants);
var count = _itemsForRows.length;
for (; index < count; ++index)
_itemInfosForItems[[_itemsForRows[index] UID]].row = index;
var deltaWeight = itemInfo.weight - weight;
if (deltaWeight !== 0)
{
var parent = itemInfo.parent;
while (parent)
{
var parentItemInfo = _itemInfosForItems[[parent UID]];
parentItemInfo.weight += deltaWeight;
parent = parentItemInfo.parent;
}
if (anItem)
_rootItemInfo.weight += deltaWeight;
}
}
return descendants;
}
/*!
@@ -574,39 +897,6 @@ var CPOutlineViewCoalesceSelectionNotificationStateOff = 0,
return _outlineTableColumn;
}
/*!
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.
*/
- (CPInteger)levelForItem:(id)anItem
{
if (!anItem)
return _rootItemInfo.level;
var itemInfo = _itemInfosForItems[[anItem UID]];
if (!itemInfo)
return CPNotFound;
return itemInfo.level;
}
/*!
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 receiver
@return int - the indentation level of aRow.
*/
- (CPInteger)levelForRow:(CPInteger)aRow
{
return [self levelForItem:[self itemAtRow:aRow]];
}
/*!
Sets the number of pixels to indent an item at each indentation level.
@@ -717,6 +1007,7 @@ var CPOutlineViewCoalesceSelectionNotificationStateOff = 0,
- (CGRect)frameOfOutlineDisclosureControlAtRow:(CPInteger)aRow
{
var theItem = [self itemAtRow:aRow];
if (![self isExpandable:theItem] || ![self _shouldShowOutlineDisclosureControlForItem:theItem])
return CGRectMakeZero();
@@ -826,7 +1117,7 @@ var CPOutlineViewCoalesceSelectionNotificationStateOff = 0,
@code - (int)outlineView:(CPOutlineView)outlineView heightOfRowByItem:(id)anItem; @endcode
*/
- (void)setDelegate:(id)aDelegate
- (void)setDelegate:(id <CPOutlineViewDelegate>)aDelegate
{
if (_outlineViewDelegate === aDelegate)
return;
@@ -912,6 +1203,7 @@ var CPOutlineViewCoalesceSelectionNotificationStateOff = 0,
CPOutlineViewDelegate_outlineView_typeSelectStringForTableColumn_item_ , @selector(outlineView:typeSelectStringForTableColumn:item:),
CPOutlineViewDelegate_outlineView_willDisplayOutlineView_forTableColumn_item_ , @selector(outlineView:willDisplayOutlineView:forTableColumn:item:),
CPOutlineViewDelegate_outlineView_willDisplayView_forTableColumn_item_ , @selector(outlineView:willDisplayView:forTableColumn:item:),
CPOutlineViewDelegate_outlineView_willRemoveView_forTableColumn_item_ , @selector(outlineView:willRemoveView:forTableColumn:item:),
CPOutlineViewDelegate_selectionShouldChangeInOutlineView_ , @selector(selectionShouldChangeInOutlineView:),
CPOutlineViewDelegate_outlineView_menuForTableColumn_item_ , @selector(outlineView:menuForTableColumn:item:)
],
@@ -988,17 +1280,6 @@ var CPOutlineViewCoalesceSelectionNotificationStateOff = 0,
CPLog.warn("outlineView:dataViewForTableColumn:item: is deprecated. You should use -outlineView:viewForTableColumn:item: where you can request the view with -makeViewWithIdentifier:owner:");
}
- (BOOL)_sendDelegateDeleteKeyPressed
{
if ([[self delegate] respondsToSelector: @selector(outlineViewDeleteKeyPressed:)])
{
[[self delegate] outlineViewDeleteKeyPressed:self];
return YES;
}
return NO;
}
/*!
Returns the delegate object for the outlineview.
*/
@@ -1557,6 +1838,33 @@ var CPOutlineViewCoalesceSelectionNotificationStateOff = 0,
[super keyDown:anEvent];
}
- (BOOL)_sendDelegateDeleteKeyPressed
{
if ([[self delegate] respondsToSelector: @selector(outlineViewDeleteKeyPressed:)])
{
[[self delegate] outlineViewDeleteKeyPressed:self];
return YES;
}
return NO;
}
- (BOOL)_sendDelegateShouldShowOutlineDisclosureControlForItem:(id)anItem
{
if (!(_implementedOutlineViewDelegateMethods & CPOutlineViewDelegate_outlineView_shouldShowOutlineDisclosureControlForItem_))
return YES;
return [_outlineViewDelegate outlineView:self shouldShowOutlineDisclosureControlForItem:anItem];
}
- (BOOL)_sendDataSourceShouldDeferDisplayingChildrenOfItem:(id)anItem
{
if (!(_implementedOutlineViewDataSourceMethods & CPOutlineViewDataSource_outlineView_shouldDeferDisplayingChildrenOfItem_))
return YES;
return [_outlineViewDataSource outlineView:self shouldDeferDisplayingChildrenOfItem:anItem];
}
- (CPView)_sendDelegateViewForTableColumn:(CPTableColumn)aTableColumn row:(CPInteger)aRow
{
return [_outlineViewDelegate outlineView:self viewForTableColumn:aTableColumn item:[self itemAtRow:aRow]];
@@ -1612,152 +1920,6 @@ var CPOutlineViewCoalesceSelectionNotificationStateOff = 0,
@end
// FIX ME: We're using with() here because Safari fails if we use anOutlineView._itemInfosForItems or whatever...
var _reloadItem = function(/*CPOutlineView*/ anOutlineView, /*id*/ anItem)
{
if (!anItem)
return;
with (anOutlineView)
{
// Get the existing info if it exists.
var itemInfosForItems = _itemInfosForItems,
dataSource = _outlineViewDataSource,
itemUID = [anItem UID],
itemInfo = itemInfosForItems[itemUID];
// If we're not in the tree, then just bail.
if (!itemInfo)
return [];
// See if the item itself can be swapped out.
var parent = itemInfo.parent,
parentItemInfo = parent ? itemInfosForItems[[parent UID]] : _rootItemInfo,
parentChildren = parentItemInfo.children,
index = [parentChildren indexOfObjectIdenticalTo:anItem],
newItem = [dataSource outlineView:anOutlineView child:index ofItem:parent];
if (anItem !== newItem)
{
itemInfosForItems[[anItem UID]] = nil;
itemInfosForItems[[newItem UID]] = itemInfo;
parentChildren[index] = newItem;
_itemsForRows[itemInfo.row] = newItem;
}
itemInfo.isExpandable = [dataSource outlineView:anOutlineView isItemExpandable:newItem];
itemInfo.isExpanded = itemInfo.isExpandable && itemInfo.isExpanded;
itemInfo.shouldShowOutlineDisclosureControl = !(_implementedOutlineViewDelegateMethods & CPOutlineViewDelegate_outlineView_shouldShowOutlineDisclosureControlForItem_) || [_outlineViewDelegate outlineView:self shouldShowOutlineDisclosureControlForItem:newItem];
}
};
// FIX ME: We're using with() here because Safari fails if we use anOutlineView._itemInfosForItems or whatever...
var _loadItemInfoForItem = function(/*CPOutlineView*/ anOutlineView, /*id*/ anItem, /*BOOL*/ isIntermediate)
{
with (anOutlineView)
{
var itemInfosForItems = _itemInfosForItems,
dataSource = _outlineViewDataSource;
if (!anItem)
var itemInfo = _rootItemInfo;
else
{
// Get the existing info if it exists.
var itemUID = [anItem UID],
itemInfo = itemInfosForItems[itemUID];
// If we're not in the tree, then just bail.
if (!itemInfo)
return [];
itemInfo.isExpandable = [dataSource outlineView:anOutlineView isItemExpandable:anItem];
itemInfo.shouldShowOutlineDisclosureControl = !(_implementedOutlineViewDelegateMethods & CPOutlineViewDelegate_outlineView_shouldShowOutlineDisclosureControlForItem_) || [_outlineViewDelegate outlineView:self shouldShowOutlineDisclosureControlForItem:anItem];
// If we were previously expanded, but now no longer expandable, "de-expand".
// NOTE: we are *not* collapsing, thus no notification is posted.
if (!itemInfo.isExpandable && itemInfo.isExpanded)
{
itemInfo.isExpanded = NO;
itemInfo.children = [];
}
}
// The root item does not count as a descendant.
var weight = itemInfo.weight,
descendants = anItem ? [anItem] : [];
if (itemInfo.isExpanded && (!(_implementedOutlineViewDataSourceMethods & CPOutlineViewDataSource_outlineView_shouldDeferDisplayingChildrenOfItem_) ||
![dataSource outlineView:anOutlineView shouldDeferDisplayingChildrenOfItem:anItem]))
{
var index = 0,
count = [dataSource outlineView:anOutlineView numberOfChildrenOfItem:anItem],
level = itemInfo.level + 1;
itemInfo.children = [];
for (; index < count; ++index)
{
var childItem = [dataSource outlineView:anOutlineView child:index ofItem:anItem],
childItemInfo = itemInfosForItems[[childItem UID]];
if (!childItemInfo)
{
childItemInfo = { isExpanded:NO, isExpandable:NO, shouldShowOutlineDisclosureControl:YES, children:[], weight:1 };
itemInfosForItems[[childItem UID]] = childItemInfo;
}
itemInfo.children[index] = childItem;
var childDescendants = _loadItemInfoForItem(anOutlineView, childItem, YES);
childItemInfo.parent = anItem;
childItemInfo.level = level;
descendants = descendants.concat(childDescendants);
}
}
itemInfo.weight = descendants.length;
if (!isIntermediate)
{
// row = -1 is the root item, so just go to row 0 since it is ignored.
var index = MAX(itemInfo.row, 0),
itemsForRows = _itemsForRows;
descendants.unshift(index, weight);
itemsForRows.splice.apply(itemsForRows, descendants);
var count = itemsForRows.length;
for (; index < count; ++index)
itemInfosForItems[[itemsForRows[index] UID]].row = index;
var deltaWeight = itemInfo.weight - weight;
if (deltaWeight !== 0)
{
var parent = itemInfo.parent;
while (parent)
{
var parentItemInfo = itemInfosForItems[[parent UID]];
parentItemInfo.weight += deltaWeight;
parent = parentItemInfo.parent;
}
if (anItem)
_rootItemInfo.weight += deltaWeight;
}
}
}//end of with
return descendants;
};
@implementation _CPOutlineViewTableViewDataSource : CPObject
{
CPObject _outlineView;
@@ -1938,6 +2100,15 @@ var _loadItemInfoForItem = function(/*CPOutlineView*/ anOutlineView, /*id*/ anIt
}
}
- (void)tableView:(CPTableView)aTableView willRemoveView:(id)aView forTableColumn:(CPTableColumn)aTableColumn row:(CPInteger)aRowIndex
{
if ((_outlineView._implementedOutlineViewDelegateMethods & CPOutlineViewDelegate_outlineView_willRemoveView_forTableColumn_item_))
{
var item = [_outlineView itemAtRow:aRowIndex];
[_outlineView._outlineViewDelegate outlineView:_outlineView willRemoveView:aView forTableColumn:aTableColumn item:item];
}
}
- (BOOL)tableView:(CPTableView)aTableView isGroupRow:(CPInteger)aRow
{
if ((_outlineView._implementedOutlineViewDelegateMethods & CPOutlineViewDelegate_outlineView_isGroupItem_))
+20
View File
@@ -119,4 +119,24 @@ CPDocModalWindowMask = 1 << 6;
return YES;
}
#pragma mark -
#pragma mark Overrides
/*!
@ignore
*/
- (void)cancelOperation:(id)sender
{
if ([[CPApp currentEvent] _couldBeKeyEquivalent] && [self performKeyEquivalent:[CPApp currentEvent]])
return;
[[self firstResponder] tryToPerform:@selector(cancel:) with:self];
}
- (void)cancel:(id)sender
{
[self performClose:sender];
}
@end
+4 -1
View File
@@ -26,6 +26,9 @@
@import <Foundation/CPDictionary.j>
@import <Foundation/CPPropertyListSerialization.j>
@class CPWebScriptObject
@typedef DataTransfer
CPGeneralPboard = @"CPGeneralPboard";
CPFontPboard = @"CPFontPboard";
@@ -66,7 +69,7 @@ var CPPasteboards = nil,
unsigned _changeCount;
CPString _stateUID;
WebScriptObject _nativePasteboard;
CPWebScriptObject _nativePasteboard;
}
/*
+14 -31
View File
@@ -26,8 +26,6 @@
@import "CPMenu.j"
@import "CPMenuItem.j"
var VISIBLE_MARGIN = 7.0;
CPPopUpButtonStatePullsDown = CPThemeState("pulls-down");
/*!
@@ -773,13 +771,6 @@ CPPopUpButtonStatePullsDown = CPThemeState("pulls-down");
[[self selectedItem] setState:CPOffState];
}
- (void)_reverseSetBinding
{
[_CPPopUpButtonSelectionBinder reverseSetValueForObject:self];
[super _reverseSetBinding];
}
@end
@implementation CPPopUpButton (BindingSupport)
@@ -802,6 +793,20 @@ CPPopUpButtonStatePullsDown = CPThemeState("pulls-down");
return [super _binderClassForBinding:aBinding];
}
+ (BOOL)isBindingExclusive:(CPString)aBinding
{
return (aBinding == CPSelectedIndexBinding ||
aBinding == CPSelectedTagBinding ||
aBinding == CPSelectedValueBinding);
}
- (void)_reverseSetBinding
{
[_CPPopUpButtonSelectionBinder _reverseSetValueFromExclusiveBinderForObject:self];
[super _reverseSetBinding];
}
@end
@implementation _CPPopUpButtonContentBinder : CPBinder
@@ -931,30 +936,8 @@ CPPopUpButtonStatePullsDown = CPThemeState("pulls-down");
@end
var binderForObject = {};
@implementation _CPPopUpButtonSelectionBinder : CPBinder
{
CPString _selectionBinding @accessors;
}
- (id)initWithBinding:(CPString)aBinding name:(CPString)aName to:(id)aDestination keyPath:(CPString)aKeyPath options:(CPDictionary)options from:(id)aSource
{
self = [super initWithBinding:aBinding name:aName to:aDestination keyPath:aKeyPath options:options from:aSource];
if (self)
{
binderForObject[[aSource UID]] = self;
_selectionBinding = aName;
}
return self;
}
+ (void)reverseSetValueForObject:(id)aSource
{
var binder = binderForObject[[aSource UID]];
[binder reverseSetValueFor:[binder _selectionBinding]];
}
- (void)setPlaceholderValue:(id)aValue withMarker:(CPString)aMarker forBinding:(CPString)aBinding
+70 -32
View File
@@ -28,8 +28,19 @@
@import "CPImageView.j"
@import "CPResponder.j"
@import "CPView.j"
@import "CPViewController.j"
@import "_CPPopoverWindow.j"
@protocol CPPopoverDelegate <CPObject>
@optional
- (BOOL)popoverShouldClose:(CPPopover)aPopover;
- (void)popoverWillClose:(CPPopover)aPopover;
- (void)popoverDidClose:(CPPopover)aPopover;
- (void)popoverWillShow:(CPPopover)aPopover;
- (void)popoverDidShow:(CPPopover)aPopover;
@end
CPPopoverBehaviorApplicationDefined = 0;
CPPopoverBehaviorTransient = 1;
@@ -60,15 +71,16 @@ var CPPopoverDelegate_popover_willShow_ = 1 << 0,
*/
@implementation CPPopover : CPResponder
{
@outlet CPViewController _contentViewController @accessors(property=contentViewController);
@outlet id _delegate @accessors(getter=delegate);
@outlet CPViewController _contentViewController @accessors(property=contentViewController);
@outlet id <CPPopoverDelegate> _delegate @accessors(getter=delegate);
BOOL _animates @accessors(getter=animates);
int _appearance @accessors(property=appearance);
int _behavior @accessors(getter=behavior);
BOOL _animates @accessors(getter=animates);
int _appearance @accessors(property=appearance);
int _behavior @accessors(getter=behavior);
_CPPopoverWindow _popoverWindow;
int _implementedDelegateMethods;
_CPPopoverWindow _popoverWindow;
CPView _positioningView;
int _implementedDelegateMethods;
}
@@ -127,9 +139,6 @@ var CPPopoverDelegate_popover_willShow_ = 1 << 0,
*/
- (CGSize)contentSize
{
if (![_popoverWindow isVisible])
return CGRectMakeZero();
return [[_contentViewController view] frameSize];
}
@@ -140,7 +149,10 @@ var CPPopoverDelegate_popover_willShow_ = 1 << 0,
*/
- (void)setContentSize:(CGSize)aSize
{
[[_contentViewController view] setFrameSize:aSize];
if (!_popoverWindow)
[[_contentViewController view] setFrameSize:aSize];
else
[_popoverWindow updateFrameWithSize:aSize];
}
/*!
@@ -181,10 +193,10 @@ Set the behavior of the CPPopover. It can be:
return;
_behavior = aBehavior;
[_popoverWindow setStyleMask:[self styleMaskForBehavior]];
[_popoverWindow setStyleMask:[self _styleMaskForBehavior]];
}
- (void)setDelegate:(id)aDelegate
- (void)setDelegate:(id <CPPopoverDelegate>)aDelegate
{
if (_delegate === aDelegate)
return;
@@ -226,17 +238,14 @@ Set the behavior of the CPPopover. It can be:
if (!_contentViewController)
[CPException raise:CPInternalInconsistencyException reason:@"contentViewController must not be nil"];
// If the popover is currently closing, do nothing. That is what Cocoa does.
if ([_popoverWindow isClosing])
// If the popover is currently closing or opening, do nothing. That is what Cocoa does.
if ([_popoverWindow isClosing] || [_popoverWindow isOpening])
return;
if (_implementedDelegateMethods & CPPopoverDelegate_popover_willShow_)
[_delegate popoverWillShow:self];
_positioningView = positioningView;
if (!_popoverWindow)
{
_popoverWindow = [[_CPPopoverWindow alloc] initWithContentRect:CGRectMakeZero() styleMask:[self styleMaskForBehavior]];
}
_popoverWindow = [[_CPPopoverWindow alloc] initWithContentRect:CGRectMakeZero() styleMask:[self _styleMaskForBehavior]];
[_popoverWindow setPlatformWindow:[[positioningView window] platformWindow]];
[_popoverWindow setAppearance:_appearance];
@@ -245,15 +254,22 @@ Set the behavior of the CPPopover. It can be:
[_popoverWindow setMovableByWindowBackground:NO];
[_popoverWindow setFrame:[_popoverWindow frameRectForContentRect:[[_contentViewController view] frame]]];
[_popoverWindow setContentView:[_contentViewController view]];
if (![self isShown])
[self _popoverWillShow];
[_popoverWindow positionRelativeToRect:positioningRect ofView:positioningView preferredEdge:preferredEdge];
if (!_animates && _implementedDelegateMethods & CPPopoverDelegate_popover_didShow_)
[_delegate popoverDidShow:self];
if (![self isShown])
[self _popoverWindowDidShow];
}
- (unsigned)styleMaskForBehavior
- (unsigned)_styleMaskForBehavior
{
return (_behavior == CPPopoverBehaviorTransient) ? CPClosableOnBlurWindowMask : 0;
if (_behavior == CPPopoverBehaviorApplicationDefined)
return 0;
return CPClosableOnBlurWindowMask
}
/*!
@@ -272,9 +288,9 @@ Set the behavior of the CPPopover. It can be:
if ([_popoverWindow isClosing] || ![self isShown])
return;
if (_implementedDelegateMethods & CPPopoverDelegate_popover_willClose_)
[_delegate popoverWillClose:self];
[self _popoverWillClose];
_positioningView = nil;
[_popoverWindow close];
// popoverDidClose will be sent from popoverWindowDidClose, since
@@ -295,9 +311,8 @@ Set the behavior of the CPPopover. It can be:
if ([_popoverWindow isClosing])
return;
if (_implementedDelegateMethods & CPPopoverDelegate_popover_shouldClose_)
if (![_delegate popoverShouldClose:self])
return;
if (![self _popoverShouldClose])
return;
[self _close];
}
@@ -307,7 +322,7 @@ Set the behavior of the CPPopover. It can be:
#pragma mark Delegates
/*! @ignore */
- (BOOL)popoverWindowShouldClose:(_CPPopoverWindow)aPopoverWindow
- (BOOL)_popoverWindowShouldClose
{
[self performClose:self];
@@ -318,19 +333,42 @@ Set the behavior of the CPPopover. It can be:
}
/*! @ignore */
- (void)popoverWindowDidClose:(_CPPopoverWindow)aPopoverWindow
- (void)_popoverWindowDidClose
{
if (_implementedDelegateMethods & CPPopoverDelegate_popover_didClose_)
[_delegate popoverDidClose:self];
}
/*! @ignore */
- (void)popoverWindowDidShow:(_CPPopoverWindow)aPopoverWindow
- (void)_popoverWindowDidShow
{
if (_implementedDelegateMethods & CPPopoverDelegate_popover_didShow_)
[_delegate popoverDidShow:self];
}
/*! @ignore */
- (BOOL)_popoverShouldClose
{
if (_implementedDelegateMethods & CPPopoverDelegate_popover_shouldClose_)
return [_delegate popoverShouldClose:self];
return YES;
}
/*! @ignore */
- (void)_popoverWillClose
{
if (_implementedDelegateMethods & CPPopoverDelegate_popover_willClose_)
[_delegate popoverWillClose:self];
}
/*! @ignore */
- (void)_popoverWillShow
{
if (_implementedDelegateMethods & CPPopoverDelegate_popover_willShow_)
[_delegate popoverWillShow:self];
}
@end
@implementation CPPopover (Deprecated)
+1
View File
@@ -26,6 +26,7 @@
@import "CPWindow_Constants.j"
@typedef CPProgressIndicatorStyle
/*
@global
@group CPProgressIndicatorStyle
+10 -23
View File
@@ -25,6 +25,8 @@
@import "CPButton.j"
@class CPRadioGroup
@global CPApp
@@ -356,7 +358,7 @@ var CPRadioRadioGroupKey = @"CPRadioRadioGroupKey";
[_selectedRadio setState:CPOffState];
_selectedRadio = aRadio;
[_CPRadioGroupSelectionBinder reverseSetValueForObject:self];
[_CPRadioGroupSelectionBinder _reverseSetValueFromExclusiveBinderForObject:self];
}
@end
@@ -407,32 +409,17 @@ var CPRadioGroupRadiosKey = @"CPRadioGroupRadiosKey",
return [super _binderClassForBinding:aBinding];
}
@end
+ (BOOL)isBindingExclusive:(CPString)aBinding
{
return (aBinding == CPSelectedIndexBinding ||
aBinding == CPSelectedTagBinding ||
aBinding == CPSelectedValueBinding);
}
var binderForObject = {};
@end
@implementation _CPRadioGroupSelectionBinder : CPBinder
{
CPString _selectionBinding @accessors;
}
- (id)initWithBinding:(CPString)aBinding name:(CPString)aName to:(id)aDestination keyPath:(CPString)aKeyPath options:(CPDictionary)options from:(id)aSource
{
self = [super initWithBinding:aBinding name:aName to:aDestination keyPath:aKeyPath options:options from:aSource];
if (self)
{
binderForObject[[aSource UID]] = self;
_selectionBinding = aName;
}
return self;
}
+ (void)reverseSetValueForObject:(id)aSource
{
var binder = binderForObject[[aSource UID]];
[binder reverseSetValueFor:[binder _selectionBinding]];
}
- (void)setPlaceholderValue:(id)aValue withMarker:(CPString)aMarker forBinding:(CPString)aBinding
+1
View File
@@ -26,6 +26,7 @@
@import "CPEvent.j"
@class CPKeyBinding
@class CPMenu
CPDeleteKeyCode = 8;
CPTabKeyCode = 9;
@@ -27,8 +27,7 @@
@import "CPMenuItem.j"
@import "CPTextField.j"
// NOTE: CPDatePicker is not implemented yet
@class CPDatePicker
@import "CPDatePicker.j"
CPUndefinedAttributeType = 0;
@@ -488,7 +487,36 @@ CPTransformableAttributeType = 1800;
- (id)copy
{
return [CPKeyedUnarchiver unarchiveObjectWithData:[CPKeyedArchiver archivedDataWithRootObject:self]];
var views = [CPArray array];
var copy = [[[self class] alloc] init];
[copy _setTemplateType:_templateType];
[copy _setOptions:_predicateOptions];
[copy _setModifier:_predicateModifier];
[copy _setLeftAttributeType:_leftAttributeType];
[copy _setRightAttributeType:_rightAttributeType];
[copy setLeftIsWildcard:_leftIsWildcard];
[copy setRightIsWildcard:_rightIsWildcard];
[_views enumerateObjectsUsingBlock:function(aView, idx, stop)
{
var vcopy;
if ([aView implementsSelector:@selector(copy)])
{
vcopy = [aView copy];
}
else
{
vcopy = [CPKeyedUnarchiver unarchiveObjectWithData:[CPKeyedArchiver archivedDataWithRootObject:aView]];
}
[views addObject:vcopy];
}];
[copy setTemplateViews:views];
return copy;
}
+ (id)_operatorsForAttributeType:(CPAttributeType)attributeType
@@ -680,7 +708,10 @@ CPTransformableAttributeType = 1800;
view = [[CPCheckBox alloc] initWithFrame:CGRectMake(0, 0, 50, 26)];
}
else if (attributeType == CPDateAttributeType)
view = [[CPDatePicker alloc] initWithFrame:CGRectMake(0, 0, 150, 26)];
{
view = [[CPDatePicker alloc] initWithFrame:CGRectMake(0, 0, 180, 26)];
[view setDatePickerElements:CPYearMonthDayDatePickerElementFlag];
}
else
return nil;
@@ -797,5 +828,31 @@ var CPPredicateTemplateTypeKey = @"CPPredicateTemplateType",
[coder encodeObject:_views forKey:CPPredicateTemplateViewsKey];
}
@end
// Copy support for built-in types
@implementation CPDatePicker (CPCopying)
- (id)copy
{
var ret = [[[self class] alloc] initWithFrame:[self frame]];
[ret setTextFont:[self textFont]];
[ret setMinDate:[self minDate]];
[ret setMaxDate:[self maxDate]];
[ret setTimeInterval:[self timeInterval]];
[ret setDatePickerMode:[self datePickerMode]];
[ret setDatePickerElements:[self datePickerElements]];
[ret setDatePickerStyle:[self datePickerStyle]];
[ret setLocale:[self locale]];
[ret setDateValue:[self dateValue]];
[ret setBackgroundColor:[self backgroundColor]];
[ret setDrawsBackground:[self drawsBackground]];
[ret setBordered:[self isBordered]];
[ret _init];
return ret;
}
@end
/*! @endcond */
+111 -42
View File
@@ -41,6 +41,21 @@
@global CPCaseInsensitivePredicateOption
@global CPOrPredicateType
@protocol CPRuleEditorDelegate <CPObject>
@required
- (id)ruleEditor:(CPRuleEditor)editor child:(CPInteger)index forCriterion:(id)criterion withRowType:(CPRuleEditorRowType)rowType;
- (id)ruleEditor:(CPRuleEditor)editor displayValueForCriterion:(id)criterion inRow:(CPInteger)row;
- (CPInteger)ruleEditor:(CPRuleEditor)editor numberOfChildrenForCriterion:(id)criterion withRowType:(CPRuleEditorRowType)rowType;
@optional
- (CPDictionary)ruleEditor:(CPRuleEditor)editor predicatePartsForCriterion:(id)criterion withDisplayValue:(id)value inRow:(CPInteger)row;
- (void)ruleEditorRowsDidChange:(CPNotification)notification;
@end
var CPRuleEditorDelegate_ruleEditor_predicatePartsForCriterion_withDisplayValue_inRow_ = 1 << 1;
var CPRuleEditorItemPBoardType = @"CPRuleEditorItemPBoardType",
itemsContext = "items",
valuesContext = "values",
@@ -69,50 +84,51 @@ var CPRuleEditorItemPBoardType = @"CPRuleEditorItemPBoardType",
@implementation CPRuleEditor : CPControl
{
BOOL _suppressKeyDownHandling;
BOOL _allowsEmptyCompoundRows;
BOOL _disallowEmpty;
BOOL _delegateWantsValidation;
BOOL _editable;
BOOL _sendAction;
BOOL _suppressKeyDownHandling;
BOOL _allowsEmptyCompoundRows;
BOOL _disallowEmpty;
BOOL _delegateWantsValidation;
BOOL _editable;
BOOL _sendAction;
Class _rowClass;
Class _rowClass;
CPIndexSet _draggingRows;
CPInteger _subviewIndexOfDropLine;
CPView _dropLineView;
CPIndexSet _draggingRows;
CPInteger _subviewIndexOfDropLine;
CPView _dropLineView;
CPMutableArray _rowCache;
CPMutableArray _slices;
CPMutableArray _rowCache;
CPMutableArray _slices;
CPPredicate _predicate;
CPPredicate _predicate;
CPString _itemsKeyPath;
CPString _subrowsArrayKeyPath;
CPString _typeKeyPath;
CPString _valuesKeyPath;
CPString _boundArrayKeyPath @accessors(property=boundArrayKeyPath);
CPString _itemsKeyPath;
CPString _subrowsArrayKeyPath;
CPString _typeKeyPath;
CPString _valuesKeyPath;
CPString _boundArrayKeyPath @accessors(property=boundArrayKeyPath);
CPView _slicesHolder;
CPViewAnimation _currentAnimation;
CPView _slicesHolder;
CPViewAnimation _currentAnimation;
CPInteger _lastRow;
CPInteger _nestingMode;
CPInteger _lastRow;
CPInteger _nestingMode;
float _alignmentGridWidth;
float _sliceHeight;
float _alignmentGridWidth;
float _sliceHeight;
id _ruleDataSource;
id _ruleDelegate;
id _boundArrayOwner;
id _ruleDataSource;
id <CPRuleEditorDelegate> _ruleDelegate;
id _boundArrayOwner;
unsigned _implementedDelegateMethods;
CPString _stringsFilename;
CPString _stringsFilename;
BOOL _isKeyDown;
BOOL _nestingModeDidChange;
BOOL _isKeyDown;
BOOL _nestingModeDidChange;
_CPRuleEditorLocalizer _standardLocalizer @accessors(property=standardLocalizer);
CPDictionary _itemsAndValuesToAddForRowType;
_CPRuleEditorLocalizer _standardLocalizer @accessors(property=standardLocalizer);
CPDictionary _itemsAndValuesToAddForRowType;
}
/*! @cond */
@@ -131,8 +147,10 @@ var CPRuleEditorItemPBoardType = @"CPRuleEditorItemPBoardType",
@"slice-bottom-border-color": [CPNull null],
@"slice-last-bottom-border-color": [CPNull null],
@"font": [CPNull null],
@"font-color": [CPNull null],
@"add-image": [CPNull null],
@"remove-image": [CPNull null],
@"vertical-alignment": [CPNull null]
};
}
@@ -143,7 +161,7 @@ var CPRuleEditorItemPBoardType = @"CPRuleEditorItemPBoardType",
{
_slices = [[CPMutableArray alloc] init];
_sliceHeight = 26.;
_sliceHeight = 26.0;
_nestingMode = CPRuleEditorNestingModeSimple; // 10.5 default is CPRuleEditorNestingModeCompound
_editable = YES;
_allowsEmptyCompoundRows = NO;
@@ -213,19 +231,24 @@ var CPRuleEditorItemPBoardType = @"CPRuleEditorItemPBoardType",
@discussion CPRuleEditor requires a delegate that implements the required delegate methods to function.
@see delegate
*/
- (void)setDelegate:(id)aDelegate
- (void)setDelegate:(id <CPRuleEditorDelegate>)aDelegate
{
if (_ruleDelegate === aDelegate)
return;
var nc = [CPNotificationCenter defaultCenter];
if (_ruleDelegate)
[nc removeObserver:_ruleDelegate name:nil object:self];
_ruleDelegate = aDelegate;
_implementedDelegateMethods = 0;
if ([_ruleDelegate respondsToSelector:@selector(ruleEditorRowsDidChange:)])
[nc addObserver:_ruleDelegate selector:@selector(ruleEditorRowsDidChange:) name:CPRuleEditorRowsDidChangeNotification object:nil];
if ([_ruleDelegate respondsToSelector:@selector(ruleEditor:predicatePartsForCriterion:withDisplayValue:inRow:)])
_implementedDelegateMethods |= CPRuleEditorDelegate_ruleEditor_predicatePartsForCriterion_withDisplayValue_inRow_;
}
/*!
@brief Returns a Boolean value that indicates whether the receiver is editable.
@@ -810,7 +833,7 @@ TODO: implement
var item = [items objectAtIndex:i],
//var displayValue = [self _queryValueForItem:item inRow:aRow]; Ask the delegate or get cached value ?.
displayValue = [[self displayValuesForRow:aRow] objectAtIndex:i],
predpart = [_ruleDelegate ruleEditor:self predicatePartsForCriterion:item withDisplayValue:displayValue inRow:aRow];
predpart = [self _sendDelegateRuleEditorPredicatePartsForCriterion:item withDisplayValue:displayValue inRow:aRow];
if (predpart)
[predicateParts addEntriesFromDictionary:predpart];
@@ -1716,8 +1739,7 @@ TODO: implement
{
if (_delegateWantsValidation)
{
var selector = @selector(ruleEditor:predicatePartsForCriterion:withDisplayValue:inRow:);
if (![_ruleDelegate respondsToSelector:selector])
if (![self _delegateRespondsToRuleEditorPredicatePartsForCriterionWithDisplayValueInRow])
return;
_delegateWantsValidation = NO;
@@ -1865,14 +1887,34 @@ TODO: implement
return [self valueForThemeAttribute:@"font"];
}
- (CPImage)_addImage
- (CPColor)_fontColor
{
return [self valueForThemeAttribute:@"add-image"];
return [self valueForThemeAttribute:@"font-color"];
}
- (CPImage)_removeImage
- (CPImage)_imageAdd
{
return [self valueForThemeAttribute:@"remove-image"];
return [self valueForThemeAttribute:@"add-image" inState:CPThemeStateNormal];
}
- (CPImage)_imageAddHighlighted
{
return [self valueForThemeAttribute:@"add-image" inState:CPThemeStateHighlighted];
}
- (CPImage)_imageRemove
{
return [self valueForThemeAttribute:@"remove-image" inState:CPThemeStateNormal];
}
- (CPImage)_imageRemoveHighlighted
{
return [self valueForThemeAttribute:@"remove-image" inState:CPThemeStateHighlighted];
}
- (CPVerticalTextAlignment)_verticalAlignment
{
return [self valueForThemeAttribute:@"vertical-alignment"];
}
- (CPString)_toolTipForAddCompoundRowButton
@@ -2165,7 +2207,7 @@ TODO: implement
indexOfDropLine = FLOOR(y / _sliceHeight),
numberOfRows = [self numberOfRows];
if (indexOfDropLine < 0 || indexOfDropLine > numberOfRows || (indexOfDropLine >= [_draggingRows firstIndex] && indexOfDropLine <= [_draggingRows lastIndex] + 1))
if (indexOfDropLine <= 0 || indexOfDropLine > numberOfRows || (indexOfDropLine >= [_draggingRows firstIndex] && indexOfDropLine <= [_draggingRows lastIndex] + 1))
{
if (_subviewIndexOfDropLine !== CPNotFound && indexOfDropLine !== _subviewIndexOfDropLine)
[self _clearDropLine];
@@ -2377,6 +2419,33 @@ TODO: implement
@end
@implementation CPRuleEditor (CPRuleEditorDelegate)
/*!
@ignore
Check if the delegate responds to ruleEditor:predicatePartsForCriterion:withDisplayValue:inRow:
*/
- (BOOL)_delegateRespondsToRuleEditorPredicatePartsForCriterionWithDisplayValueInRow
{
return _implementedDelegateMethods & CPRuleEditorDelegate_ruleEditor_predicatePartsForCriterion_withDisplayValue_inRow_;
}
/*!
@ignore
Call delegate ruleEditor:predicatePartsForCriterion:withDisplayValue:inRow:
*/
- (CPDictionary)_sendDelegateRuleEditorPredicatePartsForCriterion:(id)criterion withDisplayValue:(id)value inRow:(CPInteger)row
{
if (!(_implementedDelegateMethods & CPRuleEditorDelegate_ruleEditor_predicatePartsForCriterion_withDisplayValue_inRow_))
return @{};
return [_ruleDelegate ruleEditor:self predicatePartsForCriterion:criterion withDisplayValue:value inRow:row];
}
@end
var CPRuleEditorAlignmentGridWidthKey = @"CPRuleEditorAlignmentGridWidth",
CPRuleEditorSliceHeightKey = @"CPRuleEditorSliceHeight",
CPRuleEditorStringsFilenameKey = @"CPRuleEditorStringsFilename",
@@ -20,6 +20,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
CPRuleEditorPredicateLeftExpression = "CPRuleEditorPredicateLeftExpression";
CPRuleEditorPredicateRightExpression = "CPRuleEditorPredicateRightExpression";
CPRuleEditorPredicateComparisonModifier = "CPRuleEditorPredicateComparisonModifier";
@@ -36,5 +37,6 @@ CPRuleEditorNestingModeList = 1; // Allows a single list, with no nes
CPRuleEditorNestingModeCompound = 2; // Unlimited nesting and compound rows; this is the default
CPRuleEditorNestingModeSimple = 3; // One compound row at the top with subrows beneath it, and no further nesting allowed
@typedef CPRuleEditorRowType
CPRuleEditorRowTypeSimple = 0;
CPRuleEditorRowTypeCompound = 1;
@@ -20,6 +20,8 @@
@import <Foundation/CPObject.j>
@import <Foundation/CPString.j>
@class CPPredicateEditorRowTemplate
@implementation _CPPredicateEditorTree : CPObject
{
CPPredicateEditorRowTemplate template @accessors;
@@ -1,203 +0,0 @@
/*
* Created by cacaodev@gmail.com.
* Copyright (c) 2011 Pear, Inc. All rights reserved.
*
* 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 "CPBezierPath.j"
@import "CPPopUpButton.j"
@class _CPRuleEditorViewSlice
var GRADIENT_START_COLOR = "#fcfcfc",
GRADIENT_END_COLOR = "#dfdfdf",
BORDER_COLOR = "#BDBDBD";
var GRADIENT_NORMAL,
GRADIENT_HIGHLIGHTED,
GRADIENT_PROPERTY;
if (CPBrowserIsEngine(CPWebKitBrowserEngine))
{
GRADIENT_NORMAL = "-webkit-gradient(linear, left top, left bottom, from(" + GRADIENT_START_COLOR + "), to(" + GRADIENT_END_COLOR + "))",
GRADIENT_HIGHLIGHTED = "-webkit-gradient(linear, left top, left bottom, from(" + GRADIENT_END_COLOR + "), to(" + GRADIENT_START_COLOR + "))";
GRADIENT_PROPERTY = "background";
}
else if (CPBrowserIsEngine(CPGeckoBrowserEngine))
{
GRADIENT_NORMAL = "-moz-linear-gradient(top, " + GRADIENT_START_COLOR + ", " + GRADIENT_END_COLOR + ")",
GRADIENT_HIGHLIGHTED = "-moz-linear-gradient(top, " + GRADIENT_END_COLOR + ", " + GRADIENT_START_COLOR + ")";
GRADIENT_PROPERTY = "background";
}
else if (CPBrowserIsEngine(CPInternetExplorerBrowserEngine))
{
GRADIENT_NORMAL = "progid:DXImageTransform.Microsoft.gradient(startColorstr='" + GRADIENT_START_COLOR + "', endColorstr='" + GRADIENT_END_COLOR + "')";
GRADIENT_HIGHLIGHTED = "progid:DXImageTransform.Microsoft.gradient(startColorstr='" + GRADIENT_END_COLOR + "', endColorstr='" + GRADIENT_START_COLOR + "')";
GRADIENT_PROPERTY = "filter";
}else
{
GRADIENT_NORMAL = GRADIENT_START_COLOR;
GRADIENT_HIGHLIGHTED = GRADIENT_END_COLOR;
GRADIENT_PROPERTY = "background";
}
@implementation _CPRuleEditorPopUpButton : CPPopUpButton
{
CPInteger radius;
}
- (void)_sharedInit
{
[self setBordered:NO];
#if PLATFORM(DOM)
var style = _DOMElement.style;
style.border = "1px solid " + BORDER_COLOR;
style[GRADIENT_PROPERTY] = GRADIENT_NORMAL;
#endif
}
- (id)initWithFrame:(CGRect)aFrame
{
if (self = [super initWithFrame:aFrame])
[self _sharedInit];
return self;
}
- (id)initWithCoder:(CPCoder)aCoder
{
self = [super initWithCoder:aCoder];
[self _sharedInit];
return self;
}
- (CPView)hitTest:(CGPoint)point
{
if (!CGRectContainsPoint([self frame], point) || ![self sliceIsEditable])
return nil;
return self;
}
- (BOOL)sliceIsEditable
{
var superview = [self superview];
return ![superview isKindOfClass:[_CPRuleEditorViewSlice]] || [superview isEditable];
}
- (void)trackMouse:(CPEvent)theEvent
{
if (![self sliceIsEditable])
return;
[super trackMouse:theEvent];
}
- (CGRect)contentRectForBounds:(CGRect)bounds
{
var contentRect = [super contentRectForBounds:bounds];
contentRect.origin.x += radius;
contentRect.size.width -= 2 * radius;
return contentRect;
}
- (void)layoutSubviews
{
#if PLATFORM(DOM)
radius = FLOOR(CGRectGetHeight([self bounds]) / 2);
var style = _DOMElement.style,
radiusCSS = radius + "px";
style.borderRadius = radiusCSS;
#endif
[super layoutSubviews];
}
- (void)drawRect:(CGRect)aRect
{
var context = [[CPGraphicsContext currentContext] graphicsPort],
bounds = [self bounds],
arrow_width = FLOOR(CGRectGetHeight(bounds) / 3.5);
CGContextTranslateCTM(context, CGRectGetWidth(bounds) - radius - arrow_width, CGRectGetHeight(bounds) / 2);
var arrowsPath = [CPBezierPath bezierPath];
[arrowsPath moveToPoint:CGPointMake(0, 1)];
[arrowsPath lineToPoint:CGPointMake(arrow_width, 1)];
[arrowsPath lineToPoint:CGPointMake(arrow_width / 2, arrow_width + 1)];
[arrowsPath closePath];
CGContextSetFillColor(context, [CPColor colorWithWhite:101 / 255 alpha:1]);
[arrowsPath fill];
CGContextScaleCTM(context, 1 , -1);
[arrowsPath fill];
}
@end
@implementation _CPRuleEditorButton : CPButton
{
CPInteger radius;
}
- (void)_sharedInit
{
[self setBordered:NO];
#if PLATFORM(DOM)
var style = _DOMElement.style;
style.border = "1px solid " + BORDER_COLOR;
style[GRADIENT_PROPERTY] = GRADIENT_NORMAL;
#endif
}
- (id)initWithFrame:(CGRect)aFrame
{
if (self = [super initWithFrame:aFrame])
[self _sharedInit];
return self;
}
- (id)initWithCoder:(CPCoder)aCoder
{
self = [super initWithCoder:aCoder];
[self _sharedInit];
return self;
}
- (void)layoutSubviews
{
#if PLATFORM(DOM)
radius = FLOOR(CGRectGetHeight([self bounds]) / 2);
var style = _DOMElement.style,
radiusCSS = radius + "px";
style.borderRadius = radiusCSS;
style[GRADIENT_PROPERTY] = ([self isHighlighted]) ? GRADIENT_HIGHLIGHTED : GRADIENT_NORMAL;
#endif
[super layoutSubviews];
}
@end
+5 -3
View File
@@ -19,6 +19,8 @@
@import "CPView.j"
@class CPRuleEditor
@implementation _CPRuleEditorViewSlice : CPView
{
CPRuleEditor _ruleEditor;
@@ -61,9 +63,9 @@
- (void)drawRect:(CGRect)rect
{
var context = [[CPGraphicsContext currentContext] graphicsPort],
bounds = [self bounds],
maxX = CGRectGetWidth(bounds),
maxY = CGRectGetHeight(bounds);
bounds = [self bounds],
maxX = CGRectGetWidth(bounds),
maxY = CGRectGetHeight(bounds);
// Draw background
if ([self _isSelected])
+97 -87
View File
@@ -19,24 +19,27 @@
@import "CPRuleEditor_Constants.j"
@import "_CPRuleEditorViewSlice.j"
@import "_CPRuleEditorPopUpButton.j"
@import "CPButton.j"
@import "CPDatePicker.j"
@import "CPPopUpButton.j"
@global CPApp
var CONTROL_HEIGHT = 16.,
BUTTON_HEIGHT = 16.;
@global CPMiniControlSize
@global CPSmallControlSize
@implementation _CPRuleEditorViewSliceRow : _CPRuleEditorViewSlice
{
CPMutableArray _ruleOptionViews;
CPMutableArray _ruleOptionFrames;
CPMutableArray _correspondingRuleItems;
CPMutableArray _ruleOptionInitialViewFrames;
CPButton _addButton;
CPButton _subtractButton;
CPButton _addButton;
CPButton _subtractButton;
CPMutableArray _correspondingRuleItems;
CPMutableArray _ruleOptionFrames;
CPMutableArray _ruleOptionInitialViewFrames;
CPMutableArray _ruleOptionViews;
CPRuleEditorRowType _rowType @accessors;
CPRuleEditorRowType _plusButtonRowType;
CPRuleEditorRowType _rowType @accessors;
CPRuleEditorRowType _plusButtonRowType;
}
- (id)initWithFrame:(CGRect)frame ruleEditorView:(id)editor
@@ -49,34 +52,33 @@ var CONTROL_HEIGHT = 16.,
- (void)_initShared
{
_correspondingRuleItems = [[CPMutableArray alloc] init];
_ruleOptionFrames = [[CPMutableArray alloc] init];
_ruleOptionInitialViewFrames = [[CPMutableArray alloc] init];
_ruleOptionViews = [[CPMutableArray alloc] init];
_editable = [_ruleEditor isEditable];
_correspondingRuleItems = [[CPMutableArray alloc] init];
_ruleOptionFrames = [[CPMutableArray alloc] init];
_ruleOptionInitialViewFrames = [[CPMutableArray alloc] init];
_ruleOptionViews = [[CPMutableArray alloc] init];
_editable = [_ruleEditor isEditable];
_addButton = [self _createAddRowButton];
_subtractButton = [self _createDeleteRowButton];
_addButton = [self _createAddRowButton];
_subtractButton = [self _createDeleteRowButton];
[_addButton setToolTip:[_ruleEditor _toolTipForAddSimpleRowButton]];
[_subtractButton setToolTip:[_ruleEditor _toolTipForDeleteRowButton]];
[_addButton setHidden:!_editable];
[_subtractButton setHidden:!_editable];
[self addSubview:_addButton];
[self addSubview:_subtractButton];
[self setAutoresizingMask:CPViewWidthSizable];
var center = [CPNotificationCenter defaultCenter];
[center addObserver:self selector:@selector(_textDidChange:) name:CPControlTextDidChangeNotification object:nil];
}
- (CPButton)_createRowButton
{
var button = [[_CPRuleEditorButton alloc] initWithFrame:CGRectMakeZero()];
[button setFont:[CPFont boldFontWithName:@"Apple Symbol" size:12.0]];
[button setTextColor:[CPColor colorWithWhite:150 / 255 alpha:1]];
var button = [[CPButton alloc] initWithFrame:CGRectMakeZero()];
[button setFont:[_ruleEditor font]];
[button setTextColor:[_ruleEditor _fontColor]];
[button setAlignment:CPCenterTextAlignment];
[button setAutoresizingMask:CPViewMinXMargin];
[button setButtonType:CPMomentaryChangeButton];
[button setBordered:NO];
[button setHidden:!_editable];
[button setImagePosition:CPImageOnly];
return button;
@@ -86,7 +88,10 @@ var CONTROL_HEIGHT = 16.,
{
var button = [self _createRowButton];
[button setImage:[_ruleEditor _addImage]];
[button setToolTip:[_ruleEditor _toolTipForAddSimpleRowButton]];
[button setValue:[_ruleEditor _imageAdd] forThemeAttribute:@"image" inState:CPThemeStateNormal];
[button setValue:[_ruleEditor _imageAddHighlighted] forThemeAttribute:@"image" inState:CPThemeStateHighlighted];
[button setAction:@selector(_addOption:)];
[button setTarget:self];
@@ -97,7 +102,10 @@ var CONTROL_HEIGHT = 16.,
{
var button = [self _createRowButton];
[button setImage:[_ruleEditor _removeImage]];
[button setToolTip:[_ruleEditor _toolTipForDeleteRowButton]];
[button setValue:[_ruleEditor _imageRemove] forThemeAttribute:@"image" inState:CPThemeStateNormal];
[button setValue:[_ruleEditor _imageRemoveHighlighted] forThemeAttribute:@"image" inState:CPThemeStateHighlighted];
[button setAction:@selector(_deleteOption:)];
[button setTarget:self];
@@ -107,20 +115,17 @@ var CONTROL_HEIGHT = 16.,
- (CPMenuItem)_createMenuItemWithTitle:(CPString )title
{
title = [[_ruleEditor standardLocalizer] localizedStringForString:title];
var mItem = [[CPMenuItem alloc] initWithTitle:title action:nil keyEquivalent:@""];
return mItem;
return [[CPMenuItem alloc] initWithTitle:title action:nil keyEquivalent:@""];
}
- (CPPopUpButton)_createPopUpButtonWithItems:(CPArray)itemsArray selectedItemIndex:(int)index
{
var title = [[itemsArray objectAtIndex:index] title],
font = [_ruleEditor font],
width = [title sizeWithFont:font].width + 20,
rect = CGRectMake(0, 0, (width - width % 40) + 80, CONTROL_HEIGHT),
var title = [[itemsArray objectAtIndex:index] title],
font = [_ruleEditor font],
width = [title sizeWithFont:font].width + 35, // 35 for right arrows + margins
rect = CGRectMake(0, 0, width, [_ruleEditor rowHeight]),
popup = [[CPPopUpButton alloc] initWithFrame:rect];
popup = [[_CPRuleEditorPopUpButton alloc] initWithFrame:rect];
[popup setTextColor:[CPColor colorWithWhite:101 / 255 alpha:1]];
[popup setValue:font forThemeAttribute:@"font"];
var count = [itemsArray count];
@@ -137,17 +142,17 @@ var CONTROL_HEIGHT = 16.,
return [CPMenuItem separatorItem];
}
- (_CPRuleEditorTextField)_createStaticTextFieldWithStringValue:(CPString)text
- (CPTextField)_createStaticTextFieldWithStringValue:(CPString)text
{
var textField = [[_CPRuleEditorTextField alloc] initWithFrame:CGRectMakeZero()],
ruleEditorFont = [_ruleEditor font],
font = [CPFont fontWithName:[ruleEditorFont familyName] size:[ruleEditorFont size] + 2],
localizedText = [[_ruleEditor standardLocalizer] localizedStringForString:text],
size = [localizedText sizeWithFont:font];
[textField setFrameSize:CGSizeMake(size.width + 4, CONTROL_HEIGHT + 2)];
var textField = [[CPTextField alloc] initWithFrame:CGRectMakeZero()],
ruleEditorFont = [_ruleEditor font],
font = [CPFont fontWithName:[ruleEditorFont familyName] size:[ruleEditorFont size] + 2],
localizedText = [[_ruleEditor standardLocalizer] localizedStringForString:text],
size = [localizedText sizeWithFont:font];
[textField setFrameSize:CGSizeMake(size.width + 4, [_ruleEditor rowHeight])];
[textField setValue:font forThemeAttribute:@"font"];
[textField setValue:[_ruleEditor _verticalAlignment] forThemeAttribute:@"vertical-alignment"];
[textField setStringValue:localizedText];
return textField;
@@ -159,6 +164,7 @@ var CONTROL_HEIGHT = 16.,
[self setNeedsDisplay:YES];
var type = _plusButtonRowType;
if ([_ruleEditor nestingMode] == CPRuleEditorNestingModeCompound && ([[CPApp currentEvent] modifierFlags] & CPAlternateKeyMask))
type = CPRuleEditorRowTypeCompound;
@@ -170,12 +176,12 @@ var CONTROL_HEIGHT = 16.,
[_ruleEditor _deleteSlice:self];
}
- (void)_ruleOptionPopupChangedAction:(CPMenuItem )sender
- (void)_ruleOptionPopupChangedAction:(CPMenuItem)sender
{
var layoutdict = [sender representedObject],
newItem = [layoutdict objectForKey:@"item"],
var layoutdict = [sender representedObject],
newItem = [layoutdict objectForKey:@"item"],
indexInCriteria = [layoutdict objectForKey:@"indexInCriteria"],
oldItem = [_correspondingRuleItems objectAtIndex:indexInCriteria];
oldItem = [_correspondingRuleItems objectAtIndex:indexInCriteria];
if (![newItem isEqual:oldItem])
{
@@ -307,8 +313,16 @@ var CONTROL_HEIGHT = 16.,
if (ruleView != nil)
{
[ruleView setControlSize:CPSmallControlSize];
var minSize = [ruleView currentValueForThemeAttribute:@"min-size"],
frame = [ruleView frame];
// Force controls to their minimum size
frame.size.height = minSize.height;
[ruleView setFrame:frame];
[_ruleOptionViews addObject:ruleView];
var frame = [ruleView frame];
[_ruleOptionInitialViewFrames addObject:frame];
[_ruleOptionFrames addObject:frame];
@@ -331,8 +345,6 @@ var CONTROL_HEIGHT = 16.,
var aView = [_ruleOptionViews objectAtIndex:firstResponderIndex];
[[self window] makeFirstResponder:aView]; // This is not working. bug in CPPopUpButton firstResponder ?
}
//[self setNeedsDisplay:YES];
}
- (void)_updateEnabledStateForSubviews
@@ -350,14 +362,15 @@ var CONTROL_HEIGHT = 16.,
var optionViewOriginX,
leftHorizontalPadding,
leftButtonMinX,
rowHeight = [_ruleEditor rowHeight],
count = [_ruleOptionViews count],
sliceFrame = [self frame],
rowHeight = [_ruleEditor rowHeight],
count = [_ruleOptionViews count],
sliceFrame = [self frame],
image = [_ruleEditor _imageAdd],
buttonFrame = CGRectMake(CGRectGetWidth(sliceFrame) - BUTTON_HEIGHT - [self _rowButtonsRightHorizontalPadding], ([_ruleEditor rowHeight] - BUTTON_HEIGHT) / 2 - 2, BUTTON_HEIGHT, BUTTON_HEIGHT);
buttonFrame = CGRectMake(CGRectGetWidth(sliceFrame) - [image size].width - [self _rowButtonsRightHorizontalPadding], ([_ruleEditor rowHeight] - [image size].height) / 2 - 1, [image size].width, [image size].height);
[_addButton setFrame:buttonFrame];
buttonFrame.origin.x -= BUTTON_HEIGHT + [self _rowButtonsInterviewHorizontalPadding];
buttonFrame.origin.x -= [image size].width + [self _rowButtonsInterviewHorizontalPadding];
[_subtractButton setFrame:buttonFrame];
if (widthChanged)
@@ -372,7 +385,8 @@ var CONTROL_HEIGHT = 16.,
var ruleOptionView = _ruleOptionViews[i],
optionFrame = _ruleOptionFrames[i];
optionFrame.origin.y = (rowHeight - CGRectGetHeight(optionFrame)) / 2 - 2;
// Use a pixel correction to align controls
optionFrame.origin.y = (rowHeight - CGRectGetHeight(optionFrame)) / 2;
if (widthChanged)
{
@@ -481,6 +495,26 @@ var CONTROL_HEIGHT = 16.,
[self layoutSubviews];
}
- (void)_addObservers
{
if (_isObserving)
return;
[super _addObservers];
[[CPNotificationCenter defaultCenter] addObserver:self selector:@selector(_textDidChange:) name:CPControlTextDidChangeNotification object:nil];
}
- (void)_removeObservers
{
if (!_isObserving)
return;
[super _removeObservers];
[[CPNotificationCenter defaultCenter] removeObserver:self name:CPControlTextDidChangeNotification object:nil];
}
- (void)drawRect:(CGRect)rect
{
[super drawRect:rect];
@@ -488,8 +522,9 @@ var CONTROL_HEIGHT = 16.,
- (BOOL)_isRulePopup:(CPView)view
{
if ([view isKindOfClass:[_CPRuleEditorPopUpButton class]])
if ([view isKindOfClass:[CPPopUpButton class]])
return YES;
return NO;
}
@@ -506,28 +541,3 @@ var CONTROL_HEIGHT = 16.,
}
@end
@implementation _CPRuleEditorTextField : CPTextField
{
}
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self)
{
[self setDrawsBackground:NO];
}
return self;
}
- (CPView)hitTest:(CGPoint)point
{
if (!CGRectContainsPoint([self frame], point))
return nil;
return [self superview];
}
@end
+45 -6
View File
@@ -264,11 +264,6 @@ var CPScrollerStyleGlobal = CPScrollerStyleOverlay,
_delegate = nil;
_scrollTimer = nil;
_implementedDelegateMethods = 0;
[[CPNotificationCenter defaultCenter] addObserver:self
selector:@selector(_didReceiveDefaultStyleChange:)
name:CPScrollerStyleGlobalChangeNotification
object:nil];
}
return self;
@@ -1262,10 +1257,45 @@ Notifies the delegate when the scroll view has finished scrolling.
[self reflectScrolledClipView:_contentView];
}
- (CGRect)documentVisibleRect
{
return [_contentView documentVisibleRect];
}
#pragma mark -
#pragma mark Overrides
- (void)_removeObservers
{
if (!_isObserving)
return;
[[CPNotificationCenter defaultCenter] removeObserver:self
name:CPScrollerStyleGlobalChangeNotification
object:nil];
[super _removeObservers];
}
- (void)_addObservers
{
if (_isObserving)
return;
//Make sure to have the last global style for the scroller
[self _didReceiveDefaultStyleChange:nil];
[[CPNotificationCenter defaultCenter] addObserver:self
selector:@selector(_didReceiveDefaultStyleChange:)
name:CPScrollerStyleGlobalChangeNotification
object:nil];
[super _addObservers];
}
- (void)drawRect:(CGRect)aRect
{
[super drawRect:aRect];
@@ -1399,7 +1429,16 @@ Notifies the delegate when the scroll view has finished scrolling.
if (![_horizontalScroller isHidden] || ![_verticalScroller isHidden])
_timerScrollersHide = [CPTimer scheduledTimerWithTimeInterval:CPScrollViewFadeOutTime target:self selector:@selector(_hideScrollers:) userInfo:nil repeats:NO];
[self _respondToScrollWheelEventWithDeltaX:[anEvent deltaX] deltaY:[anEvent deltaY]];
var deltaX = [anEvent scrollingDeltaX],
deltaY = [anEvent scrollingDeltaY];
if (![anEvent hasPreciseScrollingDeltas])
{
deltaX *= (_horizontalLineScroll || 1.0);
deltaY *= (_verticalLineScroll || 1.0);
}
[self _respondToScrollWheelEventWithDeltaX:deltaX deltaY:deltaY];
}
- (void)scrollPageUp:(id)sender
+4 -33
View File
@@ -33,6 +33,7 @@
@global CPApp
// CPScroller Constants
@typedef CPScrollerPart
CPScrollerNoPart = 0;
CPScrollerDecrementPage = 1;
CPScrollerKnob = 2;
@@ -44,6 +45,7 @@ CPScrollerKnobSlot = 6;
CPScrollerIncrementArrow = 0;
CPScrollerDecrementArrow = 1;
@typedef CPUsableScrollerParts
CPNoScrollerParts = 0;
CPOnlyScrollerArrows = 1;
CPAllScrollerParts = 2;
@@ -78,7 +80,6 @@ CPThemeStateScrollerKnobDark = CPThemeState("scroller-knob-dark");
@implementation CPScroller : CPControl
{
CPControlSize _controlSize;
CPUsableScrollerParts _usableParts;
CPArray _partRects;
@@ -172,7 +173,6 @@ CPThemeStateScrollerKnobDark = CPThemeState("scroller-knob-dark");
{
if (self = [super initWithFrame:aFrame])
{
_controlSize = CPRegularControlSize;
_partRects = [];
[self setFloatValue:0.0];
@@ -243,29 +243,6 @@ CPThemeStateScrollerKnobDark = CPThemeState("scroller-knob-dark");
[super setObjectValue:MIN(1.0, MAX(0.0, +aValue))];
}
/*!
Returns the scroller's control size
*/
- (CPControlSize)controlSize
{
return _controlSize;
}
/*!
Sets the scroller's size.
@param aControlSize the scroller's size
*/
- (void)setControlSize:(CPControlSize)aControlSize
{
if (_controlSize == aControlSize)
return;
_controlSize = aControlSize;
[self setNeedsLayout];
[self setNeedsDisplay:YES];
}
/*!
Return's the knob's proportion
*/
@@ -733,7 +710,7 @@ CPThemeStateScrollerKnobDark = CPThemeState("scroller-knob-dark");
var themeState = _themeState;
if (NAMES_FOR_PARTS[_hitPart] + "-color" !== anAttributeName)
themeState &= ~CPThemeStateHighlighted;
themeState = themeState.without(CPThemeStateHighlighted);
return [self valueForThemeAttribute:anAttributeName inState:themeState];
}
@@ -802,8 +779,7 @@ CPThemeStateScrollerKnobDark = CPThemeState("scroller-knob-dark");
@end
var CPScrollerControlSizeKey = @"CPScrollerControlSize",
CPScrollerIsVerticalKey = @"CPScrollerIsVerticalKey",
var CPScrollerIsVerticalKey = @"CPScrollerIsVerticalKey",
CPScrollerKnobProportionKey = @"CPScrollerKnobProportion",
CPScrollerStyleKey = @"CPScrollerStyleKey";
@@ -813,10 +789,6 @@ var CPScrollerControlSizeKey = @"CPScrollerControlSize",
{
if (self = [super initWithCoder:aCoder])
{
_controlSize = CPRegularControlSize;
if ([aCoder containsValueForKey:CPScrollerControlSizeKey])
_controlSize = [aCoder decodeIntForKey:CPScrollerControlSizeKey];
_knobProportion = 1.0;
if ([aCoder containsValueForKey:CPScrollerKnobProportionKey])
@@ -851,7 +823,6 @@ var CPScrollerControlSizeKey = @"CPScrollerControlSize",
{
[super encodeWithCoder:aCoder];
[aCoder encodeInt:_controlSize forKey:CPScrollerControlSizeKey];
[aCoder encodeInt:_isVertical forKey:CPScrollerIsVerticalKey];
[aCoder encodeFloat:_knobProportion forKey:CPScrollerKnobProportionKey];
[aCoder encodeInt:_style forKey:CPScrollerStyleKey];
+18 -6
View File
@@ -119,16 +119,28 @@ var RECENT_SEARCH_PREFIX = @" ";
_canResignFirstResponder = YES;
}
- (void)viewWillMoveToSuperview:(CPView)aView
#pragma mark -
#pragma mark Override observers
- (void)_removeObservers
{
[super viewWillMoveToSuperview:aView];
if (!_isObserving)
return;
[super _removeObservers];
// First we remove any observer that may have been in place to avoid memory leakage.
[[CPNotificationCenter defaultCenter] removeObserver:self name:CPControlTextDidChangeNotification object:self];
}
// Register the observe here if we need to.
if (aView)
[[CPNotificationCenter defaultCenter] addObserver:self selector:@selector(_searchFieldTextDidChange:) name:CPControlTextDidChangeNotification object:self];
- (void)_addObservers
{
if (_isObserving)
return;
[super _addObservers];
[[CPNotificationCenter defaultCenter] addObserver:self selector:@selector(_searchFieldTextDidChange:) name:CPControlTextDidChangeNotification object:self];
}
// Managing Buttons
+118 -73
View File
@@ -25,9 +25,11 @@
@import "CPControl.j"
@import "CPWindow_Constants.j"
@import "_CPImageAndTextView.j"
@import "CPMenu.j"
@global CPApp
@typedef CPSegmentSwitchTracking
CPSegmentSwitchTrackingSelectOne = 0;
CPSegmentSwitchTrackingSelectAny = 1;
CPSegmentSwitchTrackingMomentary = 2;
@@ -70,23 +72,9 @@ CPSegmentSwitchTrackingMomentary = 2;
@"center-segment-bezel-color": [CPNull null],
@"divider-bezel-color": [CPNull null],
@"divider-thickness": 1.0,
@"default-height": 24.0,
};
}
+ (Class)_binderClassForBinding:(CPString)aBinding
{
if ([self _isSelectionBinding:aBinding])
return [_CPSegmentedControlBinder class];
return [super _binderClassForBinding:aBinding];
}
+ (BOOL)_isSelectionBinding:(CPString)aBinding
{
return (aBinding === CPSelectedIndexBinding || aBinding === CPSelectedLabelBinding || aBinding === CPSelectedTagBinding);
}
- (id)initWithFrame:(CGRect)aRect
{
_segments = [];
@@ -104,17 +92,14 @@ CPSegmentSwitchTrackingMomentary = 2;
return self;
}
- (void)bind:(CPString)aBinding toObject:(id)anObject withKeyPath:(CPString)aKeyPath options:(CPDictionary)options
/*!
Sets the control's size.
@param aControlSize the control's size
*/
- (void)setControlSize:(CPControlSize)aControlSize
{
if ([[self class] _isSelectionBinding:aBinding] && _trackingMode !== CPSegmentSwitchTrackingSelectOne)
CPLog.warn("Binding " + aBinding + " needs CPSegmentSwitchTrackingSelectOne tracking mode");
else
[super bind:aBinding toObject:anObject withKeyPath:aKeyPath options:options];
}
- (void)_reverseSetBinding
{
[_CPSegmentedControlBinder reverseSetValueForObject:self];
[super setControlSize:aControlSize];
[self _sizeToControlSize];
}
/*!
@@ -285,7 +270,6 @@ CPSegmentSwitchTrackingMomentary = 2;
- (void)setWidth:(float)aWidth forSegment:(unsigned)aSegment
{
[_segments[aSegment] setWidth:aWidth];
[self tileWithChangedSegment:aSegment];
}
@@ -432,9 +416,9 @@ CPSegmentSwitchTrackingMomentary = 2;
[_segments[aSegment] setEnabled:shouldBeEnabled];
if (shouldBeEnabled)
_themeStates[aSegment] &= ~CPThemeStateDisabled;
_themeStates[aSegment] = _themeStates[aSegment].without(CPThemeStateDisabled);
else
_themeStates[aSegment] |= CPThemeStateDisabled;
_themeStates[aSegment] = _themeStates[aSegment].and(CPThemeStateDisabled);
[self setNeedsLayout];
[self setNeedsDisplay:YES];
@@ -477,10 +461,13 @@ CPSegmentSwitchTrackingMomentary = 2;
*/
- (void)drawSegmentBezel:(int)aSegment highlight:(BOOL)shouldHighlight
{
if (shouldHighlight)
_themeStates[aSegment] |= CPThemeStateHighlighted;
else
_themeStates[aSegment] &= ~CPThemeStateHighlighted;
if(aSegment < _themeStates.length)
{
if (shouldHighlight)
_themeStates[aSegment] = _themeStates[aSegment].and(CPThemeStateHighlighted);
else
_themeStates[aSegment] = _themeStates[aSegment].without(CPThemeStateHighlighted);
}
[self setNeedsLayout];
[self setNeedsDisplay:YES];
@@ -510,7 +497,7 @@ CPSegmentSwitchTrackingMomentary = 2;
- (CGRect)rectForEphemeralSubviewNamed:(CPString)aName
{
var height = [self currentValueForThemeAttribute:@"default-height"],
var height = [self currentValueForThemeAttribute:@"min-size"].height,
contentInset = [self currentValueForThemeAttribute:@"content-inset"],
bezelInset = [self currentValueForThemeAttribute:@"bezel-inset"],
bounds = [self bounds];
@@ -574,9 +561,17 @@ CPSegmentSwitchTrackingMomentary = 2;
if (_segments.length <= 0)
return;
var themeState = _themeStates[0];
var themeState = _themeStates[0],
isDisabled = [self hasThemeState:CPThemeStateDisabled],
isControlSizeSmall = [self hasThemeState:CPThemeStateControlSizeSmall],
isControlSizeMini = [self hasThemeState:CPThemeStateControlSizeMini];
themeState |= _themeState & CPThemeStateDisabled;
themeState = isDisabled ? themeState.and(CPThemeStateDisabled) : themeState;
if (isControlSizeSmall)
themeState = themeState.and(CPThemeStateControlSizeSmall);
else if (isControlSizeMini)
themeState = themeState.and(CPThemeStateControlSizeMini);
var leftCapColor = [self valueForThemeAttribute:@"left-segment-bezel-color"
inState:themeState],
@@ -589,7 +584,12 @@ CPSegmentSwitchTrackingMomentary = 2;
var themeState = _themeStates[_themeStates.length - 1];
themeState |= _themeState & CPThemeStateDisabled;
themeState = isDisabled ? themeState.and(CPThemeStateDisabled) : themeState;
if (isControlSizeSmall)
themeState = themeState.and(CPThemeStateControlSizeSmall);
else if (isControlSizeMini)
themeState = themeState.and(CPThemeStateControlSizeMini);
var rightCapColor = [self valueForThemeAttribute:@"right-segment-bezel-color"
inState:themeState],
@@ -604,7 +604,12 @@ CPSegmentSwitchTrackingMomentary = 2;
{
var themeState = _themeStates[i];
themeState |= _themeState & CPThemeStateDisabled;
themeState = isDisabled ? themeState.and(CPThemeStateDisabled) : themeState;
if (isControlSizeSmall)
themeState = themeState.and(CPThemeStateControlSizeSmall);
else if (isControlSizeMini)
themeState = themeState.and(CPThemeStateControlSizeMini);
var bezelColor = [self valueForThemeAttribute:@"center-segment-bezel-color"
inState:themeState],
@@ -615,7 +620,6 @@ CPSegmentSwitchTrackingMomentary = 2;
[bezelView setBackgroundColor:bezelColor];
// layout image/title views
var segment = _segments[i],
contentView = [self layoutEphemeralSubviewNamed:@"segment-content-" + i
@@ -642,11 +646,16 @@ CPSegmentSwitchTrackingMomentary = 2;
if (i == count - 1)
continue;
var borderState = _themeStates[i] | _themeStates[i + 1];
var borderState = _themeStates[i].and(_themeStates[i + 1]);
borderState = (borderState & CPThemeStateSelected & ~CPThemeStateHighlighted) ? CPThemeStateSelected : CPThemeStateNormal;
borderState = (borderState.hasThemeState(CPThemeStateSelected) && !borderState.hasThemeState(CPThemeStateHighlighted)) ? CPThemeStateSelected : CPThemeStateNormal;
borderState |= _themeState & CPThemeStateDisabled;
borderState = isDisabled ? borderState.and(CPThemeStateDisabled) : borderState;
if (isControlSizeSmall)
borderState = borderState.and(CPThemeStateControlSizeSmall);
else if (isControlSizeMini)
borderState = borderState.and(CPThemeStateControlSizeMini);
var borderColor = [self valueForThemeAttribute:@"divider-bezel-color"
inState:borderState],
@@ -676,7 +685,7 @@ CPSegmentSwitchTrackingMomentary = 2;
var segment = _segments[aSegment],
segmentWidth = [segment width],
themeState = _themeStates[aSegment] | (_themeState & CPThemeStateDisabled),
themeState = _themeState.hasThemeState(CPThemeStateDisabled) ? _themeStates[aSegment].and(CPThemeStateDisabled) : _themeStates[aSegment],
contentInset = [self valueForThemeAttribute:@"content-inset" inState:themeState],
font = [self font];
@@ -704,7 +713,6 @@ CPSegmentSwitchTrackingMomentary = 2;
// Update control size
var frame = [self frame];
[self setFrameSize:CGSizeMake(CGRectGetWidth(frame) + delta, CGRectGetHeight(frame))];
// Update segment width
@@ -740,7 +748,7 @@ CPSegmentSwitchTrackingMomentary = 2;
- (CGRect)bezelFrameForSegment:(unsigned)aSegment
{
var height = [self currentValueForThemeAttribute:@"default-height"],
var height = [self currentValueForThemeAttribute:@"min-size"].height,
bezelInset = [self currentValueForThemeAttribute:@"bezel-inset"],
width = [self widthForSegment:aSegment],
left = [self _leftOffsetForSegment:aSegment];
@@ -750,7 +758,7 @@ CPSegmentSwitchTrackingMomentary = 2;
- (CGRect)contentFrameForSegment:(unsigned)aSegment
{
var height = [self currentValueForThemeAttribute:@"default-height"],
var height = [self currentValueForThemeAttribute:@"min-size"].height,
contentInset = [self currentValueForThemeAttribute:@"content-inset"],
width = [self widthForSegment:aSegment],
left = [self _leftOffsetForSegment:aSegment];
@@ -912,20 +920,40 @@ var CPSegmentedControlSegmentsKey = "CPSegmentedControlSegmentsKey",
else
_trackingMode = CPSegmentSwitchTrackingSelectOne;
// HACK
// Here we update the themeStates array for each segments to know if there are selected or not
for (var i = 0; i < _segments.length; i++)
_themeStates[i] = [_segments[i] selected] ? CPThemeStateSelected : CPThemeStateNormal;
// We do this in a second loop because it relies on all the themeStates being set first
for (var i = 0; i < _segments.length; i++)
[self tileWithChangedSegment:i];
var thickness = [self currentValueForThemeAttribute:@"divider-thickness"],
dividerExtraSpace = ([_segments count] - 1) * thickness,
difference = MAX(originalWidth - [self frame].size.width - dividerExtraSpace, 0.0),
remainingWidth = FLOOR(difference / _segments.length),
widthOfAllSegments = 0;
for (var i = 0; i < _segments.length; i++)
{
_themeStates[i] = [_segments[i] selected] ? CPThemeStateSelected : CPThemeStateNormal;
[self tileWithChangedSegment:i];
[self setWidth:[_segments[i] width] + remainingWidth forSegment:i];
widthOfAllSegments += [_segments[i] width];
}
var difference = MAX(originalWidth - [self frame].size.width, 0.0),
remainingWidth = FLOOR(difference / _segments.length);
// Here we handle the leftovers pixel, and we will add one pixel to each segment cell till we have the same size as the originalSize.
// This is needed to have a perfect/same alignment between our application and xCode.
var leftOversPixel = originalWidth - (widthOfAllSegments + dividerExtraSpace);
for (var i = 0; i < _segments.length; i++)
[self setWidth:[_segments[i] width] + remainingWidth forSegment:i];
// Make sure we don't make an out of range
if (leftOversPixel < _segments.length - 1)
{
for (var i = 0; i < leftOversPixel; i++)
{
[self setWidth:[_segments[i] width] + 1 forSegment:i];
}
}
[self setFrameSize:CGSizeMake(originalWidth, [self frame].size.height)];
[self tileWithChangedSegment:0];
}
@@ -944,31 +972,48 @@ var CPSegmentedControlSegmentsKey = "CPSegmentedControlSegmentsKey",
@end
var CPSegmentedControlBindersMap = {},
CPSegmentedControlNoSelectionPlaceholder = "CPSegmentedControlNoSelectionPlaceholder";
@implementation CPSegmentedControl (BindingSupport)
+ (Class)_binderClassForBinding:(CPString)aBinding
{
if ([self _isSelectionBinding:aBinding])
return [_CPSegmentedControlBinder class];
return [super _binderClassForBinding:aBinding];
}
+ (BOOL)_isSelectionBinding:(CPString)aBinding
{
return (aBinding === CPSelectedIndexBinding || aBinding === CPSelectedLabelBinding || aBinding === CPSelectedTagBinding);
}
+ (BOOL)isBindingExclusive:(CPString)aBinding
{
return [self _isSelectionBinding:aBinding];
}
- (void)bind:(CPString)aBinding toObject:(id)anObject withKeyPath:(CPString)aKeyPath options:(CPDictionary)options
{
if ([[self class] _isSelectionBinding:aBinding] && _trackingMode !== CPSegmentSwitchTrackingSelectOne)
{
CPLog.warn("Binding " + aBinding + " needs CPSegmentSwitchTrackingSelectOne tracking mode");
return;
}
[super bind:aBinding toObject:anObject withKeyPath:aKeyPath options:options];
}
- (void)_reverseSetBinding
{
[_CPSegmentedControlBinder _reverseSetValueFromExclusiveBinderForObject:self];
}
@end
var CPSegmentedControlNoSelectionPlaceholder = "CPSegmentedControlNoSelectionPlaceholder";
@implementation _CPSegmentedControlBinder : CPBinder
{
CPString _selectionBinding @accessors(readonly, getter=selectionBinding);
}
+ (void)reverseSetValueForObject:(id)aSource
{
var binder = CPSegmentedControlBindersMap[[aSource UID]];
[binder reverseSetValueFor:[binder selectionBinding]];
}
- (id)initWithBinding:(CPString)aBinding name:(CPString)aName to:(id)aDestination keyPath:(CPString)aKeyPath options:(CPDictionary)options from:(id)aSource
{
self = [super initWithBinding:aBinding name:aName to:aDestination keyPath:aKeyPath options:options from:aSource];
if (self)
{
CPSegmentedControlBindersMap[[aSource UID]] = self;
_selectionBinding = aName;
}
return self;
}
- (void)_updatePlaceholdersWithOptions:(CPDictionary)options
+5 -2
View File
@@ -22,6 +22,9 @@
@import <Foundation/CPObject.j>
@import "CGGeometry.j"
@import "CPColor.j"
@import "CPGraphicsContext.j"
/*!
@deprecated
@@ -31,9 +34,9 @@
*/
@implementation CPShadow : CPObject
{
CGSize _offset @accessors(property=shadowOffset);
CGSize _offset @accessors(property=shadowOffset);
float _blurRadius @accessors(property=shadowBlurRadius);
CPColor _color @accessors(property=shadowColor);
CPColor _color @accessors(property=shadowColor);
}
/*!
+1 -1
View File
@@ -26,7 +26,7 @@
@import "CPImage.j"
@import "CPView.j"
@typedef CPShadowWeight
CPLightShadow = 0;
CPHeavyShadow = 1;
+50 -2
View File
@@ -23,6 +23,18 @@
@import <Foundation/CPObject.j>
@import <Foundation/CPRunLoop.j>
@typedef HTMLAudioElement
@protocol CPSoundDelegate <CPObject>
@optional
- (void)sound:(CPSound)aSound didFinishPlaying:(BOOL)finishedLoading;
@end
var CPSoundDelegate_sound_didFinishPlaying_ = 1 << 1;
CPSoundLoadStateEmpty = 0;
CPSoundLoadStateLoading = 1;
CPSoundLoadStateCanBePlayed = 2;
@@ -50,6 +62,7 @@ CPSoundPlayBackStatePause = 2;
HTMLAudioElement _audioTag;
int _loadStatus;
int _playBackStatus;
unsigned _implementedDelegateMethods;
}
#pragma mark -
@@ -133,6 +146,25 @@ CPSoundPlayBackStatePause = 2;
}
#pragma mark -
#pragma mark Delegate methods
/*!
Sets the sound's delegate.
@param aDelegate the new delegate
*/
- (void)setDelegate:(id)aDelegate
{
if (_delegate === aDelegate)
return;
_delegate = aDelegate;
_implementedDelegateMethods = 0;
if ([_delegate respondsToSelector:@selector(sound:didFinishPlaying:)])
_implementedDelegateMethods |= CPSoundDelegate_sound_didFinishPlaying_;
}
#pragma mark -
#pragma mark Events listener
@@ -207,8 +239,7 @@ CPSoundPlayBackStatePause = 2;
_audioTag.currentTime = 0.0;
_playBackStatus = CPSoundPlayBackStateStop;
if (_delegate && [_delegate respondsToSelector:@selector(sound:didFinishPlaying:)])
[_delegate sound:self didFinishPlaying:YES];
[self _sendDelegateSoundDidFinishPlaying:YES];
return YES;
}
@@ -316,3 +347,20 @@ CPSoundPlayBackStatePause = 2;
}
@end
@implementation CPSound (CPSoundDelegate)
/*!
@ignore
Call delegate sound:didFinishPlaying:
*/
- (void)_sendDelegateSoundDidFinishPlaying:(BOOL)finishedPlaying
{
if (!(_implementedDelegateMethods & CPSoundDelegate_sound_didFinishPlaying_))
return;
[_delegate sound:self didFinishPlaying:finishedPlaying];
}
@end
+253 -73
View File
@@ -30,6 +30,33 @@
@class CPUserDefaults
@global CPApp
@protocol CPSplitViewDelegate <CPObject>
@optional
- (BOOL)splitView:(CPSplitView)splitView canCollapseSubview:(CPView)subview;
- (BOOL)splitView:(CPSplitView)splitView shouldAdjustSizeOfSubview:(CPView)subview;
- (BOOL)splitView:(CPSplitView)splitView shouldCollapseSubview:(CPView)subview forDoubleClickOnDividerAtIndex:(CPInteger)dividerIndex;
- (CGRect)splitView:(CPSplitView)splitView additionalEffectiveRectOfDividerAtIndex:(CPInteger)dividerIndex;
- (CGRect)splitView:(CPSplitView)splitView effectiveRect:(CGRect)proposedEffectiveRect forDrawnRect:(CGRect)drawnRect ofDividerAtIndex:(CPInteger)dividerIndex;
- (float)splitView:(CPSplitView)splitView constrainMaxCoordinate:(float)proposedMax ofSubviewAt:(CPInteger)dividerIndex;
- (float)splitView:(CPSplitView)splitView constrainMinCoordinate:(float)proposedMin ofSubviewAt:(CPInteger)dividerIndex;
- (float)splitView:(CPSplitView)splitView constrainSplitPosition:(float)proposedPosition ofSubviewAt:(CPInteger)dividerIndex;
- (void)splitView:(CPSplitView)splitView resizeSubviewsWithOldSize:(CGSize)oldSize;
- (void)splitViewDidResizeSubviews:(CPNotification)aNotification;
- (void)splitViewWillResizeSubviews:(CPNotification)aNotification;
@end
var CPSplitViewDelegate_splitView_canCollapseSubview_ = 1 << 0,
CPSplitViewDelegate_splitView_shouldAdjustSizeOfSubview_ = 1 << 1,
CPSplitViewDelegate_splitView_shouldCollapseSubview_forDoubleClickOnDividerAtIndex_ = 1 << 2,
CPSplitViewDelegate_splitView_additionalEffectiveRectOfDividerAtIndex_ = 1 << 3,
CPSplitViewDelegate_splitView_effectiveRect_forDrawnRect_ofDividerAtIndex_ = 1 << 4,
CPSplitViewDelegate_splitView_constrainMaxCoordinate_ofSubviewAt_ = 1 << 5,
CPSplitViewDelegate_splitView_constrainMinCoordinate_ofSubviewAt_ = 1 << 6,
CPSplitViewDelegate_splitView_constrainSplitPosition_ofSubviewAt_ = 1 << 7,
CPSplitViewDelegate_splitView_resizeSubviewsWithOldSize_ = 1 << 8;
#define SPLIT_VIEW_MAYBE_POST_WILL_RESIZE() \
if ((_suppressResizeNotificationsMask & DidPostWillResizeNotification) === 0) \
{ \
@@ -73,29 +100,31 @@ var ShouldSuppressResizeNotifications = 1,
@implementation CPSplitView : CPView
{
id _delegate;
BOOL _isVertical;
BOOL _isPaneSplitter;
id <CPSplitViewDelegate> _delegate;
BOOL _isVertical;
BOOL _isPaneSplitter;
int _currentDivider;
float _initialOffset;
CPDictionary _preCollapsePositions;
int _currentDivider;
float _initialOffset;
CPDictionary _preCollapsePositions;
CPString _originComponent;
CPString _sizeComponent;
CPString _originComponent;
CPString _sizeComponent;
CPArray _DOMDividerElements;
CPString _dividerImagePath;
int _drawingDivider;
CPArray _DOMDividerElements;
CPString _dividerImagePath;
int _drawingDivider;
CPString _autosaveName;
BOOL _shouldAutosave;
CGSize _shouldRestoreFromAutosaveUnlessFrameSize;
CPString _autosaveName;
BOOL _shouldAutosave;
CGSize _shouldRestoreFromAutosaveUnlessFrameSize;
BOOL _needsResizeSubviews;
int _suppressResizeNotificationsMask;
BOOL _needsResizeSubviews;
int _suppressResizeNotificationsMask;
CPArray _buttonBars;
CPArray _buttonBars;
unsigned _implementedDelegateMethods;
}
+ (CPString)defaultThemeClass
@@ -406,11 +435,8 @@ var ShouldSuppressResizeNotifications = 1,
buttonBarRect.origin = [self convertPoint:buttonBarRect.origin fromView:buttonBar];
}
if ([_delegate respondsToSelector:@selector(splitView:effectiveRect:forDrawnRect:ofDividerAtIndex:)])
effectiveRect = [_delegate splitView:self effectiveRect:effectiveRect forDrawnRect:effectiveRect ofDividerAtIndex:anIndex];
if ([_delegate respondsToSelector:@selector(splitView:additionalEffectiveRectOfDividerAtIndex:)])
additionalRect = [_delegate splitView:self additionalEffectiveRectOfDividerAtIndex:anIndex];
effectiveRect = [self _sendDelegateSplitViewEffectiveRect:effectiveRect forDrawnRect:effectiveRect ofDividerAtIndex:anIndex];
additionalRect = [self _sendDelegateSplitViewAdditionalEffectiveRectOfDividerAtIndex:anIndex];
return CGRectContainsPoint(effectiveRect, aPoint) ||
(additionalRect && CGRectContainsPoint(additionalRect, aPoint)) ||
@@ -472,21 +498,21 @@ var ShouldSuppressResizeNotifications = 1,
if ([self cursorAtPoint:point hitDividerAtIndex:i])
{
if ([anEvent clickCount] == 2 &&
[_delegate respondsToSelector:@selector(splitView:canCollapseSubview:)] &&
[_delegate respondsToSelector:@selector(splitView:shouldCollapseSubview:forDoubleClickOnDividerAtIndex:)])
[self _delegateRespondsToSplitViewCanCollapseSubview] &&
[self _delegateRespondsToSplitViewshouldCollapseSubviewForDoubleClickOnDividerAtIndex])
{
var minPosition = [self minPossiblePositionOfDividerAtIndex:i],
maxPosition = [self maxPossiblePositionOfDividerAtIndex:i],
preCollapsePosition = [_preCollapsePositions objectForKey:"" + i] || 0;
if ([_delegate splitView:self canCollapseSubview:_subviews[i]] && [_delegate splitView:self shouldCollapseSubview:_subviews[i] forDoubleClickOnDividerAtIndex:i])
if ([self _sendDelegateSplitViewCanCollapseSubview:_subviews[i]] && [self _sendDelegateSplitViewShouldCollapseSubview:_subviews[i] forDoubleClickOnDividerAtIndex:i])
{
if ([self isSubviewCollapsed:_subviews[i]])
[self setPosition:preCollapsePosition ? preCollapsePosition : (minPosition + (maxPosition - minPosition) / 2) ofDividerAtIndex:i];
else
[self setPosition:minPosition ofDividerAtIndex:i];
}
else if ([_delegate splitView:self canCollapseSubview:_subviews[i + 1]] && [_delegate splitView:self shouldCollapseSubview:_subviews[i + 1] forDoubleClickOnDividerAtIndex:i])
else if ([self _sendDelegateSplitViewCanCollapseSubview:_subviews[i + 1]] && [self _sendDelegateSplitViewShouldCollapseSubview:_subviews[i + 1] forDoubleClickOnDividerAtIndex:i])
{
if ([self isSubviewCollapsed:_subviews[i + 1]])
[self setPosition:preCollapsePosition ? preCollapsePosition : (minPosition + (maxPosition - minPosition) / 2) ofDividerAtIndex:i];
@@ -580,12 +606,8 @@ var ShouldSuppressResizeNotifications = 1,
if (sizeA === 0)
canGrow = YES; // Subview is collapsed.
else if (!canShrink &&
[_delegate respondsToSelector:@selector(splitView:canCollapseSubview:)] &&
[_delegate splitView:self canCollapseSubview:_subviews[i]])
{
else if (!canShrink && [self _sendDelegateSplitViewCanCollapseSubview:_subviews[i]])
canShrink = YES; // Subview is collapsible.
}
if (sizeB === 0)
{
@@ -594,9 +616,7 @@ var ShouldSuppressResizeNotifications = 1,
// It's safe to assume it can always be uncollapsed.
canShrink = YES;
}
else if (!canGrow &&
[_delegate respondsToSelector:@selector(splitView:canCollapseSubview:)] &&
[_delegate splitView:self canCollapseSubview:_subviews[i + 1]])
else if (!canGrow && [self _sendDelegateSplitViewCanCollapseSubview:_subviews[i + 1]])
{
canGrow = YES; // Right/lower subview is collapsible.
}
@@ -657,53 +677,38 @@ var ShouldSuppressResizeNotifications = 1,
- (int)_realPositionForPosition:(float)position ofDividerAtIndex:(int)dividerIndex
{
// not sure where this should override other positions?
if ([_delegate respondsToSelector:@selector(splitView:constrainSplitPosition:ofSubviewAt:)])
{
var proposedPosition = [_delegate splitView:self constrainSplitPosition:position ofSubviewAt:dividerIndex];
var proposedPosition = [self _sendDelegateSplitViewConstrainSplitPosition:position ofSubviewAt:dividerIndex];
// Silently ignore bad positions which could result from odd delegate responses. We don't want these
// bad results to go into the system and cause havoc with frame sizes as the split view tries to resize
// its subviews.
if (_IS_NUMERIC(proposedPosition))
position = proposedPosition;
}
// Silently ignore bad positions which could result from odd delegate responses. We don't want these
// bad results to go into the system and cause havoc with frame sizes as the split view tries to resize
// its subviews.
if (_IS_NUMERIC(proposedPosition))
position = proposedPosition;
var proposedMax = [self maxPossiblePositionOfDividerAtIndex:dividerIndex],
proposedMin = [self minPossiblePositionOfDividerAtIndex:dividerIndex],
actualMax = proposedMax,
actualMin = proposedMin;
actualMin = proposedMin,
proposedActualMin = [self _sendDelegateSplitViewConstrainMinCoordinate:proposedMin ofSubviewAt:dividerIndex],
proposedActualMax = [self _sendDelegateSplitViewConstrainMaxCoordinate:proposedMax ofSubviewAt:dividerIndex];
if ([_delegate respondsToSelector:@selector(splitView:constrainMinCoordinate:ofSubviewAt:)])
{
var proposedActualMin = [_delegate splitView:self constrainMinCoordinate:proposedMin ofSubviewAt:dividerIndex];
if (_IS_NUMERIC(proposedActualMin))
actualMin = proposedActualMin;
if (_IS_NUMERIC(proposedActualMin))
actualMin = proposedActualMin;
}
if ([_delegate respondsToSelector:@selector(splitView:constrainMaxCoordinate:ofSubviewAt:)])
{
var proposedActualMax = [_delegate splitView:self constrainMaxCoordinate:proposedMax ofSubviewAt:dividerIndex];
if (_IS_NUMERIC(proposedActualMax))
actualMax = proposedActualMax;
}
if (_IS_NUMERIC(proposedActualMax))
actualMax = proposedActualMax;
var viewA = _subviews[dividerIndex],
viewB = _subviews[dividerIndex + 1],
realPosition = MAX(MIN(position, actualMax), actualMin);
// Is this position past the halfway point to collapse?
if (position < proposedMin + (actualMin - proposedMin) / 2)
if ([_delegate respondsToSelector:@selector(splitView:canCollapseSubview:)])
if ([_delegate splitView:self canCollapseSubview:viewA])
realPosition = proposedMin;
if ((position < proposedMin + (actualMin - proposedMin) / 2) && [self _sendDelegateSplitViewCanCollapseSubview:viewA])
realPosition = proposedMin;
// We can also collapse to the right.
if (position > proposedMax - (proposedMax - actualMax) / 2)
if ([_delegate respondsToSelector:@selector(splitView:canCollapseSubview:)])
if ([_delegate splitView:self canCollapseSubview:viewB])
realPosition = proposedMax;
if ((position > proposedMax - (proposedMax - actualMax) / 2) && [self _sendDelegateSplitViewCanCollapseSubview:viewB])
realPosition = proposedMax;
return realPosition;
}
@@ -787,9 +792,9 @@ var ShouldSuppressResizeNotifications = 1,
- (void)resizeSubviewsWithOldSize:(CGSize)oldSize
{
if ([_delegate respondsToSelector:@selector(splitView:resizeSubviewsWithOldSize:)])
if ([self _delegateRespondsToSplitViewResizeSubviewsWithOldSize])
{
[_delegate splitView:self resizeSubviewsWithOldSize:oldSize];
[self _sendDelegateSplitViewResizeSubviewsWithOldSize:oldSize];
return;
}
@@ -815,8 +820,7 @@ var ShouldSuppressResizeNotifications = 1,
oldFlexibleSpace = 0,
totalSizablePanes = 0,
isSizableMap = {},
viewSizes = [],
delegateRespondsToShouldAdjust = [_delegate respondsToSelector:@selector(splitView:shouldAdjustSizeOfSubview:)];
viewSizes = [];
// What we want to do is to preserve non resizable sizes first, and then to preserve the ratio of size to available
// non fixed space for every other subview. E.g. assume fixed space was 20 pixels initially, view 1 was 20 and
@@ -832,7 +836,7 @@ var ShouldSuppressResizeNotifications = 1,
for (index = 0; index < count; ++index)
{
var view = _subviews[index],
isSizable = !delegateRespondsToShouldAdjust || [_delegate splitView:self shouldAdjustSizeOfSubview:view],
isSizable = [self _sendDelegateSplitViewShouldAdjustSizeOfSubview:view],
size = [view frame].size[_sizeComponent];
isSizableMap[index] = isSizable;
@@ -958,25 +962,59 @@ The sum of the views and the sum of the dividers should be equal to the size of
@param delegate - The delegate of the splitview.
*/
- (void)setDelegate:(id)delegate
- (void)setDelegate:(id <CPSplitViewDelegate>)aDelegate
{
if (_delegate === aDelegate)
return;
if ([_delegate respondsToSelector:@selector(splitViewDidResizeSubviews:)])
[[CPNotificationCenter defaultCenter] removeObserver:_delegate name:CPSplitViewDidResizeSubviewsNotification object:self];
if ([_delegate respondsToSelector:@selector(splitViewWillResizeSubviews:)])
[[CPNotificationCenter defaultCenter] removeObserver:_delegate name:CPSplitViewWillResizeSubviewsNotification object:self];
_delegate = delegate;
_delegate = aDelegate;
_implementedDelegateMethods = 0;
if ([_delegate respondsToSelector:@selector(splitViewDidResizeSubviews:)])
[[CPNotificationCenter defaultCenter] addObserver:_delegate
selector:@selector(splitViewDidResizeSubviews:)
name:CPSplitViewDidResizeSubviewsNotification
object:self];
if ([_delegate respondsToSelector:@selector(splitViewWillResizeSubviews:)])
[[CPNotificationCenter defaultCenter] addObserver:_delegate
selector:@selector(splitViewWillResizeSubviews:)
name:CPSplitViewWillResizeSubviewsNotification
object:self];
if ([_delegate respondsToSelector:@selector(splitView:canCollapseSubview:)])
_implementedDelegateMethods |= CPSplitViewDelegate_splitView_canCollapseSubview_;
if ([_delegate respondsToSelector:@selector(splitView:shouldAdjustSizeOfSubview:)])
_implementedDelegateMethods |= CPSplitViewDelegate_splitView_shouldAdjustSizeOfSubview_;
if ([_delegate respondsToSelector:@selector(splitView:shouldCollapseSubview:forDoubleClickOnDividerAtIndex:)])
_implementedDelegateMethods |= CPSplitViewDelegate_splitView_shouldCollapseSubview_forDoubleClickOnDividerAtIndex_;
if ([_delegate respondsToSelector:@selector(splitView:additionalEffectiveRectOfDividerAtIndex:)])
_implementedDelegateMethods |= CPSplitViewDelegate_splitView_additionalEffectiveRectOfDividerAtIndex_;
if ([_delegate respondsToSelector:@selector(splitView:effectiveRect:forDrawnRect:ofDividerAtIndex:)])
_implementedDelegateMethods |= CPSplitViewDelegate_splitView_effectiveRect_forDrawnRect_ofDividerAtIndex_;
if ([_delegate respondsToSelector:@selector(splitView:constrainMaxCoordinate:ofSubviewAt:)])
_implementedDelegateMethods |= CPSplitViewDelegate_splitView_constrainMaxCoordinate_ofSubviewAt_;
if ([_delegate respondsToSelector:@selector(splitView:constrainMinCoordinate:ofSubviewAt:)])
_implementedDelegateMethods |= CPSplitViewDelegate_splitView_constrainMinCoordinate_ofSubviewAt_;
if ([_delegate respondsToSelector:@selector(splitView:constrainSplitPosition:ofSubviewAt:)])
_implementedDelegateMethods |= CPSplitViewDelegate_splitView_constrainSplitPosition_ofSubviewAt_;
if ([_delegate respondsToSelector:@selector(splitView:resizeSubviewsWithOldSize:)])
_implementedDelegateMethods |= CPSplitViewDelegate_splitView_resizeSubviewsWithOldSize_;
}
/*!
@@ -1192,6 +1230,148 @@ The sum of the views and the sum of the dividers should be equal to the size of
@end
@implementation CPSplitView (CPSplitViewDelegate)
/*!
@ignore
Return YES if the delegate implements splitView:resizeSubviewsWithOldSize:
*/
- (BOOL)_delegateRespondsToSplitViewResizeSubviewsWithOldSize
{
return _implementedDelegateMethods & CPSplitViewDelegate_splitView_resizeSubviewsWithOldSize_;
}
/*!
@ignore
Return YES if the delegate implements splitView:canCollapseSubview:
*/
- (BOOL)_delegateRespondsToSplitViewCanCollapseSubview
{
return _implementedDelegateMethods & CPSplitViewDelegate_splitView_canCollapseSubview_;
}
/*!
@ignore
Return YES if the delegate implements splitView:shouldCollapseSubview:forDoubleClickOnDividerAtIndex
*/
- (BOOL)_delegateRespondsToSplitViewshouldCollapseSubviewForDoubleClickOnDividerAtIndex
{
return _implementedDelegateMethods & CPSplitViewDelegate_splitView_shouldCollapseSubview_forDoubleClickOnDividerAtIndex_;
}
/*!
@ignore
Call the delegate splitView:canCollapseSubview:
*/
- (BOOL)_sendDelegateSplitViewCanCollapseSubview:(CPView)aView
{
if (!(_implementedDelegateMethods & CPSplitViewDelegate_splitView_canCollapseSubview_))
return NO;
return [_delegate splitView:self canCollapseSubview:aView];
}
/*!
@ignore
Call the delegate splitView:shouldAdjustSizeOfSubview:
*/
- (BOOL)_sendDelegateSplitViewShouldAdjustSizeOfSubview:(CPView)aView
{
if (!(_implementedDelegateMethods & CPSplitViewDelegate_splitView_shouldAdjustSizeOfSubview_))
return YES;
return [_delegate splitView:self shouldAdjustSizeOfSubview:aView];
}
/*!
@ignore
Call the delegate splitView:shouldCollapseSubview:forDoubleClickOnDividerAtIndex:
*/
- (BOOL)_sendDelegateSplitViewShouldCollapseSubview:(CPView)aView forDoubleClickOnDividerAtIndex:(int)anIndex
{
if (!(_implementedDelegateMethods & CPSplitViewDelegate_splitView_shouldCollapseSubview_forDoubleClickOnDividerAtIndex_))
return NO;
return [_delegate splitView:self shouldCollapseSubview:aView forDoubleClickOnDividerAtIndex:anIndex];
}
/*!
@ignore
Call the delegate splitView:additionalEffectiveRectOfDividerAtIndex:
*/
- (CGRect)_sendDelegateSplitViewAdditionalEffectiveRectOfDividerAtIndex:(int)anIndex
{
if (!(_implementedDelegateMethods & CPSplitViewDelegate_splitView_additionalEffectiveRectOfDividerAtIndex_))
return nil;
return [_delegate splitView:self additionalEffectiveRectOfDividerAtIndex:anIndex];
}
/*!
@ignore
Call the delegate splitView:effectiveRect:forDrawnRect:ofDividerAtIndex:
*/
- (CGRect)_sendDelegateSplitViewEffectiveRect:(CGRect)proposedEffectiveRect forDrawnRect:(CGRect)drawnRect ofDividerAtIndex:(CPInteger)dividerIndex
{
if (!(_implementedDelegateMethods & CPSplitViewDelegate_splitView_effectiveRect_forDrawnRect_ofDividerAtIndex_))
return proposedEffectiveRect;
return [_delegate splitView:self effectiveRect:proposedEffectiveRect forDrawnRect:drawnRect ofDividerAtIndex:dividerIndex];
}
/*!
@ignore
Call the delegate splitView:constrainMaxCoordinate:ofSubviewAt:
*/
- (float)_sendDelegateSplitViewConstrainMaxCoordinate:(float)proposedMax ofSubviewAt:(CPInteger)dividerIndex
{
if (!(_implementedDelegateMethods & CPSplitViewDelegate_splitView_constrainMaxCoordinate_ofSubviewAt_))
return nil;
return [_delegate splitView:self constrainMaxCoordinate:proposedMax ofSubviewAt:dividerIndex];
}
/*!
@ignore
Call the delegate splitView:constrainMinCoordinate:ofSubviewAt:
*/
- (float)_sendDelegateSplitViewConstrainMinCoordinate:(float)proposedMin ofSubviewAt:(CPInteger)dividerIndex
{
if (!(_implementedDelegateMethods & CPSplitViewDelegate_splitView_constrainMinCoordinate_ofSubviewAt_))
return nil;
return [_delegate splitView:self constrainMinCoordinate:proposedMin ofSubviewAt:dividerIndex];
}
/*!
@ignore
Call the delegate splitView:constrainSplitPosition:ofSubviewAt:
*/
- (float)_sendDelegateSplitViewConstrainSplitPosition:(float)proposedMax ofSubviewAt:(CPInteger)dividerIndex
{
if (!(_implementedDelegateMethods & CPSplitViewDelegate_splitView_constrainSplitPosition_ofSubviewAt_))
return nil;
return [_delegate splitView:self constrainSplitPosition:proposedMax ofSubviewAt:dividerIndex];
}
/*!
@ignore
Call the delegate splitView:resizeSubviewsWithOldSize:
*/
- (void)_sendDelegateSplitViewResizeSubviewsWithOldSize:(CGSize)oldSize
{
if (!(_implementedDelegateMethods & CPSplitViewDelegate_splitView_resizeSubviewsWithOldSize_))
return;
[_delegate splitView:self resizeSubviewsWithOldSize:oldSize];
}
@end
var CPSplitViewDelegateKey = "CPSplitViewDelegateKey",
CPSplitViewIsVerticalKey = "CPSplitViewIsVerticalKey",
CPSplitViewIsPaneSplitterKey = "CPSplitViewIsPaneSplitterKey",
+28 -21
View File
@@ -25,7 +25,6 @@
@import "CPTextField.j"
/*!
CPStepper is an implementation of Cocoa NSStepper.
@@ -53,9 +52,9 @@
@param maxValue the maximal acceptable value of the stepper
@return Initialized CPStepper
*/
+ (CPStepper)stepperWithInitialValue:(float)aValue minValue:(float)aMinValue maxValue:(float)aMaxValue
+ (id)stepperWithInitialValue:(float)aValue minValue:(float)aMinValue maxValue:(float)aMaxValue
{
var stepper = [[CPStepper alloc] initWithFrame:CGRectMakeZero()];
var stepper = [[self alloc] initWithFrame:CGRectMakeZero()];
[stepper setDoubleValue:aValue];
[stepper setMinValue:aMinValue];
@@ -75,14 +74,14 @@
@return Initialized CPStepper
*/
+ (CPStepper)stepper
+ (id)stepper
{
return [CPStepper stepperWithInitialValue:0.0 minValue:0.0 maxValue:59.0];
}
+ (Class)_binderClassForBinding:(CPString)aBinding
{
if (aBinding == CPValueBinding || aBinding == CPMinValueBinding || aBinding == CPMaxValueBinding)
if (aBinding === CPValueBinding || aBinding === CPMinValueBinding || aBinding === CPMaxValueBinding)
return [_CPStepperValueBinder class];
return [super _binderClassForBinding:aBinding];
@@ -90,7 +89,7 @@
- (CPString)_replacementKeyPathForBinding:(CPString)aBinding
{
if (aBinding == CPValueBinding)
if (aBinding === CPValueBinding)
return @"doubleValue";
return [super _replacementKeyPathForBinding:aBinding];
@@ -138,9 +137,16 @@
[self setContinuous:_autorepeat];
[self addSubview:_buttonDown];
[self _sizeToFit];
[self setNeedsLayout];
}
- (void)setControlSize:(CPControlSize)aControlSize
{
[super setControlSize:aControlSize];
[self _sizeToFit];
}
#pragma mark -
#pragma mark Superclass overrides
@@ -159,8 +165,8 @@
- (void)setFrame:(CGRect)aFrame
{
var upSize = [self valueForThemeAttribute:@"up-button-size"],
downSize = [self valueForThemeAttribute:@"down-button-size"],
var upSize = [self currentValueForThemeAttribute:@"up-button-size"],
downSize = [self currentValueForThemeAttribute:@"down-button-size"],
minSize = CGSizeMake(upSize.width, upSize.height + downSize.height),
frame = CGRectMakeCopy(aFrame);
@@ -172,21 +178,22 @@
/*! @ignore */
- (void)layoutSubviews
{
var aFrame = [self frame],
upSize = [self valueForThemeAttribute:@"up-button-size"],
downSize = [self valueForThemeAttribute:@"down-button-size"],
upFrame = CGRectMake(aFrame.size.width - upSize.width, 0, upSize.width, upSize.height),
downFrame = CGRectMake(aFrame.size.width - downSize.width, upSize.height, downSize.width, downSize.height);
var controlSizeThemeState = [self _controlSizeThemeState],
aFrame = [self frame],
upSize = [self valueForThemeAttribute:@"up-button-size" inState:controlSizeThemeState],
downSize = [self valueForThemeAttribute:@"down-button-size" inState:controlSizeThemeState],
upFrame = CGRectMake(0, 0, upSize.width, upSize.height),
downFrame = CGRectMake(0, upSize.height, downSize.width, downSize.height);
[_buttonUp setFrame:upFrame];
[_buttonDown setFrame:downFrame];
[_buttonUp setValue:[self valueForThemeAttribute:@"bezel-color-up-button" inState:CPThemeStateBordered] forThemeAttribute:@"bezel-color" inState:CPThemeStateBordered];
[_buttonUp setValue:[self valueForThemeAttribute:@"bezel-color-up-button" inState:CPThemeStateBordered | CPThemeStateDisabled] forThemeAttribute:@"bezel-color" inState:CPThemeStateBordered | CPThemeStateDisabled];
[_buttonUp setValue:[self valueForThemeAttribute:@"bezel-color-up-button" inState:CPThemeStateBordered | CPThemeStateHighlighted] forThemeAttribute:@"bezel-color" inState:CPThemeStateBordered | CPThemeStateHighlighted];
[_buttonDown setValue:[self valueForThemeAttribute:@"bezel-color-down-button" inState:CPThemeStateBordered] forThemeAttribute:@"bezel-color" inState:CPThemeStateBordered];
[_buttonDown setValue:[self valueForThemeAttribute:@"bezel-color-down-button" inState:CPThemeStateBordered | CPThemeStateDisabled] forThemeAttribute:@"bezel-color" inState:CPThemeStateBordered | CPThemeStateDisabled];
[_buttonDown setValue:[self valueForThemeAttribute:@"bezel-color-down-button" inState:CPThemeStateBordered | CPThemeStateHighlighted] forThemeAttribute:@"bezel-color" inState:CPThemeStateBordered | CPThemeStateHighlighted];
[_buttonUp setValue:[self valueForThemeAttribute:@"bezel-color-up-button" inState:[controlSizeThemeState, CPThemeStateBordered]] forThemeAttribute:@"bezel-color" inState:CPThemeStateBordered];
[_buttonUp setValue:[self valueForThemeAttribute:@"bezel-color-up-button" inState:[controlSizeThemeState, CPThemeStateBordered, CPThemeStateDisabled]] forThemeAttribute:@"bezel-color" inState:[CPThemeStateBordered, CPThemeStateDisabled]];
[_buttonUp setValue:[self valueForThemeAttribute:@"bezel-color-up-button" inState:[controlSizeThemeState, CPThemeStateBordered, CPThemeStateHighlighted]] forThemeAttribute:@"bezel-color" inState:[CPThemeStateBordered, CPThemeStateHighlighted]];
[_buttonDown setValue:[self valueForThemeAttribute:@"bezel-color-down-button" inState:[controlSizeThemeState, CPThemeStateBordered]] forThemeAttribute:@"bezel-color" inState:CPThemeStateBordered];
[_buttonDown setValue:[self valueForThemeAttribute:@"bezel-color-down-button" inState:[controlSizeThemeState, CPThemeStateBordered, CPThemeStateDisabled]] forThemeAttribute:@"bezel-color" inState:[CPThemeStateBordered, CPThemeStateDisabled]];
[_buttonDown setValue:[self valueForThemeAttribute:@"bezel-color-down-button" inState:[controlSizeThemeState, CPThemeStateBordered, CPThemeStateHighlighted]] forThemeAttribute:@"bezel-color" inState:[CPThemeStateBordered, CPThemeStateHighlighted]];
}
- (void)_sizeToFit
@@ -232,7 +239,7 @@
if (![self isEnabled])
return;
if (aSender == _buttonUp)
if (aSender === _buttonUp)
[self setDoubleValue:([self doubleValue] + _increment)];
else
[self setDoubleValue:([self doubleValue] - _increment)];
@@ -285,7 +292,7 @@
- (void)_updatePlaceholdersWithOptions:(CPDictionary)options forBinding:(CPString)aBinding
{
var placeholder = (aBinding == CPMaxValueBinding) ? [_source maxValue] : [_source minValue];
var placeholder = (aBinding === CPMaxValueBinding) ? [_source maxValue] : [_source minValue];
[super _updatePlaceholdersWithOptions:options];
+28 -14
View File
@@ -25,6 +25,7 @@
@import "CPTabViewItem.j"
@import "CPView.j"
@typedef CPTabViewType
CPTopTabsBezelBorder = 0;
//CPLeftTabsBezelBorder = 1;
CPBottomTabsBezelBorder = 2;
@@ -33,10 +34,22 @@ CPNoTabsBezelBorder = 4; //Displays no tabs and has a bezeled border.
CPNoTabsLineBorder = 5; //Has no tabs and displays a line border.
CPNoTabsNoBorder = 6; //Displays no tabs and no border.
var CPTabViewDidSelectTabViewItemSelector = 1,
CPTabViewShouldSelectTabViewItemSelector = 2,
CPTabViewWillSelectTabViewItemSelector = 4,
CPTabViewDidChangeNumberOfTabViewItemsSelector = 8;
var CPTabViewDidSelectTabViewItemSelector = 1 << 1,
CPTabViewShouldSelectTabViewItemSelector = 1 << 2,
CPTabViewWillSelectTabViewItemSelector = 1 << 3,
CPTabViewDidChangeNumberOfTabViewItemsSelector = 1 << 4;
@protocol CPTabViewDelegate <CPObject>
@optional
- (BOOL)tabView:(CPTabView)tabView shouldSelectTabViewItem:(CPTabViewItem)tabViewItem;
- (void)tabView:(CPTabView)tabView didSelectTabViewItem:(CPTabViewItem)tabViewItem;
- (void)tabView:(CPTabView)tabView willSelectTabViewItem:(CPTabViewItem)tabViewItem;
- (void)tabViewDidChangeNumberOfTabViewItems:(CPTabView)tabView;
@end
/*!
@ingroup appkit
@@ -48,18 +61,18 @@ var CPTabViewDidSelectTabViewItemSelector = 1,
*/
@implementation CPTabView : CPView
{
CPArray _items;
CPArray _items;
CPSegmentedControl _tabs;
CPBox _box;
CPSegmentedControl _tabs;
CPBox _box;
CPNumber _selectedIndex;
CPNumber _selectedIndex;
CPTabViewType _type;
CPFont _font;
CPTabViewType _type;
CPFont _font;
id _delegate;
unsigned _delegateSelectors;
id <CPTabViewDelegate> _delegate;
unsigned _delegateSelectors;
}
- (id)initWithFrame:(CGRect)aFrame
@@ -82,7 +95,7 @@ var CPTabViewDidSelectTabViewItemSelector = 1,
_tabs = [[CPSegmentedControl alloc] initWithFrame:CGRectMake(0, 0, 0, 0)];
[_tabs setHitTests:NO];
var height = [_tabs valueForThemeAttribute:@"default-height"];
var height = [_tabs valueForThemeAttribute:@"min-size"].height;
[_tabs setFrameSize:CGSizeMake(0, height)];
_box = [[CPBox alloc] initWithFrame:[self bounds]];
@@ -379,6 +392,7 @@ var CPTabViewDidSelectTabViewItemSelector = 1,
[_box setFrame:CGRectMake(0, origin, CGRectGetWidth(aFrame),
CGRectGetHeight(aFrame) - segmentedHeight / 2)];
[self _updateItems];
[self _repositionTabs];
}
}
@@ -405,7 +419,7 @@ var CPTabViewDidSelectTabViewItemSelector = 1,
Sets the delegate for this tab view.
@param aDelegate the tab view's delegate
*/
- (void)setDelegate:(id)aDelegate
- (void)setDelegate:(id <CPTabViewDelegate>)aDelegate
{
if (_delegate == aDelegate)
return;
+2 -1
View File
@@ -23,7 +23,7 @@
@import <Foundation/CPObject.j>
@import "CPView.j"
@class CPTabView
/*
The tab is currently selected.
@@ -90,6 +90,7 @@ CPPressedTab = 2;
- (void)setLabel:(CPString)aLabel
{
_label = aLabel;
[_tabView setNeedsLayout];
}
/*!
+2 -16
View File
@@ -28,9 +28,8 @@
@import "CPTextField.j"
@global CPTableViewColumnDidResizeNotification
@class _CPTableColumnHeaderView
@class CPTableView
CPTableColumnNoResizing = 0;
CPTableColumnAutoresizingMask = 1 << 0;
@@ -185,7 +184,7 @@ CPTableColumnUserResizingMask = 1 << 1;
[tableView tile];
if (!_disableResizingPosting)
[self _postDidResizeNotificationWithOldWidth:oldWidth];
[[self tableView] _didResizeTableColumn:self oldWidth:oldWidth];
}
}
@@ -538,19 +537,6 @@ CPTableColumnUserResizingMask = 1 << 1;
return _headerToolTip;
}
/*!
@ignore
*/
- (void)_postDidResizeNotificationWithOldWidth:(float)oldWidth
{
[[self tableView] _didResizeTableColumn:self];
[[CPNotificationCenter defaultCenter]
postNotificationName:CPTableViewColumnDidResizeNotification
object:[self tableView]
userInfo:@{ @"CPTableColumn": self, @"CPOldWidth": oldWidth }];
}
@end
@implementation CPTableColumnValueBinder : CPBinder
+1 -1
View File
@@ -625,7 +625,7 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal
- (void)stopResizingTableColumn:(CPInteger)aColumnIndex at:(CGPoint)aPoint
{
var tableColumn = [[_tableView tableColumns] objectAtIndex:aColumnIndex];
[tableColumn _postDidResizeNotificationWithOldWidth:_columnOldWidth];
[_tableView _didResizeTableColumn:tableColumn oldWidth:_columnOldWidth];
[tableColumn setDisableResizingPosting:NO];
[_tableView setDisableAutomaticResizing:NO];
+321 -194
View File
@@ -42,6 +42,7 @@
@class CPTableHeaderView
@class CPClipView
@class CPButton
@class _CPDropOperationDrawingView
@global CPApp
@@ -58,7 +59,6 @@ var CPTableViewDataSource_numberOfRowsInTableView_
CPTableViewDataSource_tableView_namesOfPromisedFilesDroppedAtDestination_forDraggedRowsWithIndexes_ = 1 << 4,
CPTableViewDataSource_tableView_validateDrop_proposedRow_proposedDropOperation_ = 1 << 5,
CPTableViewDataSource_tableView_writeRowsWithIndexes_toPasteboard_ = 1 << 6,
CPTableViewDataSource_tableView_sortDescriptorsDidChange_ = 1 << 7;
var CPTableViewDelegate_selectionShouldChangeInTableView_ = 1 << 0,
@@ -80,10 +80,13 @@ var CPTableViewDelegate_selectionShouldChangeInTableView_
CPTableViewDelegate_tableView_toolTipForView_rect_tableColumn_row_mouseLocation_ = 1 << 16,
CPTableViewDelegate_tableView_typeSelectStringForTableColumn_row_ = 1 << 17,
CPTableViewDelegate_tableView_willDisplayView_forTableColumn_row_ = 1 << 18,
CPTableViewDelegate_tableViewSelectionDidChange_ = 1 << 19,
CPTableViewDelegate_tableViewSelectionIsChanging_ = 1 << 20,
CPTableViewDelegate_tableViewMenuForTableColumn_row_ = 1 << 21,
CPTableViewDelegate_tableView_shouldReorderColumn_toColumn_ = 1 << 22;
CPTableViewDelegate_tableView_willRemoveView_forTableColumn_row_ = 1 << 19,
CPTableViewDelegate_tableViewColumnDidMove_ = 1 << 20,
CPTableViewDelegate_tableViewColumnDidResize_ = 1 << 21,
CPTableViewDelegate_tableViewSelectionDidChange_ = 1 << 22,
CPTableViewDelegate_tableViewSelectionIsChanging_ = 1 << 23,
CPTableViewDelegate_tableViewMenuForTableColumn_row_ = 1 << 24,
CPTableViewDelegate_tableView_shouldReorderColumn_toColumn_ = 1 << 25;
//CPTableViewDraggingDestinationFeedbackStyles
CPTableViewDraggingDestinationFeedbackStyleNone = -1;
@@ -116,14 +119,61 @@ CPTableViewLastColumnOnlyAutoresizingStyle = 4;
CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
#define NUMBER_OF_COLUMNS() (_tableColumns.length)
#define UPDATE_COLUMN_RANGES_IF_NECESSARY() if (_dirtyTableColumnRangeIndex !== CPNotFound) [self _recalculateTableColumnRanges];
#define UPDATE_COLUMN_RANGES_IF_NECESSARY() \
if (_dirtyTableColumnRangeIndex !== CPNotFound) \
[self _recalculateTableColumnRanges];
#define FULL_ROW_HEIGHT() (_rowHeight + _intercellSpacing.height)
#define ROW_BOTTOM(__heightInfo) (__heightInfo.y + __heightInfo.height + _intercellSpacing.height)
#define HAS_VARIABLE_ROW_HEIGHTS() (_implementedDelegateMethods & CPTableViewDelegate_tableView_heightOfRow_)
@protocol CPTableViewDataSource <CPObject>
@optional
- (BOOL)tableView:(CPTableView)aTableView acceptDrop:(id <CPDraggingInfo>)info row:(CPInteger)aRowIndex dropOperation:(CPTableViewDropOperation)operation;
- (BOOL)tableView:(CPTableView)aTableView writeRowsWithIndexes:(CPIndexSet)rowIndexes toPasteboard:(CPPasteboard)pboard;
- (CPArray)tableView:(CPTableView)aTableView namesOfPromisedFilesDroppedAtDestination:(CPURL)dropDestination forDraggedRowsWithIndexes:(CPIndexSet)anIndexSet;
- (CPDragOperation)tableView:(CPTableView)aTableView validateDrop:(id <CPDraggingInfo>)info proposedRow:(CPInteger)aRowIndex proposedDropOperation:(CPTableViewDropOperation)anOperation;
- (CPInteger)numberOfRowsInTableView:(CPTableView)aTableView;
- (id)tableView:(CPTableView)aTableView objectValueForTableColumn:(CPTableColumn)aTableColumn row:(CPInteger)aRowIndex;
- (void)tableView:(CPTableView)aTableView setObjectValue:(id)anObjectValue forTableColumn:(CPTableColumn)aTableColumn row:(CPInteger)aRowIndex;
- (void)tableView:(CPTableView)aTableView sortDescriptorsDidChange:(CPArray)oldDescriptors;
@end
@protocol CPTableViewDelegate <CPObject>
@optional
- (BOOL)selectionShouldChangeInTableView:(CPTableView)aTableView;
- (BOOL)tableView:(CPTableView)aTableView isGroupRow:(CPInteger)aRowIndex;
- (BOOL)tableView:(CPTableView)aTableView shouldEditTableColumn:(CPTableColumn)aTableView row:(CPInteger)aRowIndex;
- (BOOL)tableView:(CPTableView)aTableView shouldReorderColumn:(CPInteger)columnIndex toColumn:(NSInteger)newColumnIndex;
- (BOOL)tableView:(CPTableView)aTableView shouldSelectRow:(CPInteger)aRowIndex;
- (BOOL)tableView:(CPTableView)aTableView shouldSelectTableColumn:(CPTableColumn)aTableColumn;
- (BOOL)tableView:(CPTableView)aTableView shouldShowViewExpansionForTableColumn:(CPTableColumn)aTableColumn row:(CPInteger)aRowIndex;
- (BOOL)tableView:(CPTableView)aTableView shouldTrackView:(CPView)aView forTableColumn:(CPTableColumn)aTableColumn row:(CPInteger)aRowIndex;
- (BOOL)tableView:(CPTableView)aTableView shouldTypeSelectForEvent:(CPEvent)anEvent withCurrentSearchString:(CPString)searchString;
- (CPIndexSet)tableView:(CPTableView)aTableView selectionIndexesForProposedSelection:(CPIndexSet)proposedSelectionIndexes;
- (CPInteger)tableView:(CPTableView)aTableView nextTypeSelectMatchFromRow:(CPInteger)startRow toRow:(CPInteger)endRow forString:(CPString)searchString;
- (CPMenu)tableViewMenuForTableColumn:(CPTableColumn)aTableColumn row:(CPInteger)aRowIndex;
- (CPString)tableView:(CPTableView)aTableView toolTipForView:(CPView)aView rect:(CGRect)aRect tableColumn:(CPTableColumn)aTableColumn row:(CPInteger)aRowIndex mouseLocation:(CGPoint)mouseLocation;
- (CPString)tableView:(CPTableView)aTableView typeSelectStringForTableColumn:(CPTableColumn)aTableColumn row:(CPInteger)aRowIndex;
- (CPView)tableView:(CPTableView)aTableView dataViewForTableColumn:(CPTableColumn)aTableColumn row:(CPInteger)aRowIndex;
- (CPView)tableView:(CPTableView)aTableView viewForTableColumn:(CPTableColumn)aTableColumn row:(CPInteger)aRowIndex;
- (float)tableView:(CPTableView)aTableView heightOfRow:(CPInteger)aRowIndex;
- (void)tableView:(CPTableView)aTableView didClickTableColumn:(CPTableColumn)aTableColumn;
- (void)tableView:(CPTableView)aTableView didDragTableColumn:(CPTableColumn)aTableColumn;
- (void)tableView:(CPTableView)aTableView mouseDownInHeaderOfTableColumn:(CPTableColumn)aTableColumn;
- (void)tableView:(CPTableView)aTableView willDisplayView:(CPView)aView forTableColumn:(CPTableColumn)aTableColumn row:(CPInteger)aRowIndex;
- (void)tableView:(CPTableView)aTableView willRemoveView:(CPView)aView forTableColumn:(CPTableColumn)aTableColumn row:(CPInteger)aRowIndex;
- (void)tableViewSelectionDidChange:(CPNotification)aNotification;
- (void)tableViewSelectionIsChanging:(CPNotification)aNotification;
@end
@implementation _CPTableDrawView : CPView
{
CPTableView _tableView;
id _tableView;
}
- (id)initWithTableView:(CPTableView)aTableView
@@ -173,106 +223,108 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
*/
@implementation CPTableView : CPControl
{
id _dataSource;
CPInteger _implementedDataSourceMethods;
id <CPTableViewDataSource> _dataSource;
CPInteger _implementedDataSourceMethods;
id _delegate;
CPInteger _implementedDelegateMethods;
id <CPTableViewDelegate> _delegate;
CPInteger _implementedDelegateMethods;
CPArray _tableColumns;
CPArray _tableColumnRanges;
CPInteger _dirtyTableColumnRangeIndex;
CPInteger _numberOfHiddenColumns;
CPArray _tableColumns;
CPArray _tableColumnRanges;
CPInteger _dirtyTableColumnRangeIndex;
CPInteger _numberOfHiddenColumns;
BOOL _reloadAllRows;
Object _objectValues;
BOOL _reloadAllRows;
Object _objectValues;
CGRect _exposedRect;
CPIndexSet _exposedRows;
CPIndexSet _exposedColumns;
CGRect _exposedRect;
CPIndexSet _exposedRows;
CPIndexSet _exposedColumns;
Object _dataViewsForTableColumns;
Object _cachedDataViews;
CPDictionary _archivedDataViews;
Object _unavailable_custom_cibs;
Object _dataViewsForTableColumns;
Object _cachedDataViews;
CPDictionary _archivedDataViews;
Object _unavailable_custom_cibs;
//Configuring Behavior
BOOL _allowsColumnReordering;
BOOL _allowsColumnResizing;
BOOL _allowsColumnSelection;
BOOL _allowsMultipleSelection;
BOOL _allowsEmptySelection;
BOOL _allowsColumnReordering;
BOOL _allowsColumnResizing;
BOOL _allowsColumnSelection;
BOOL _allowsMultipleSelection;
BOOL _allowsEmptySelection;
CPArray _sortDescriptors;
CPArray _sortDescriptors;
//Setting Display Attributes
CGSize _intercellSpacing;
float _rowHeight;
CGSize _intercellSpacing;
float _rowHeight;
BOOL _usesAlternatingRowBackgroundColors;
CPArray _alternatingRowBackgroundColors;
BOOL _usesAlternatingRowBackgroundColors;
CPArray _alternatingRowBackgroundColors;
unsigned _selectionHighlightStyle;
CPColor _unfocusedSelectionHighlightColor;
CPDictionary _unfocusedSourceListSelectionColor;
CPTableColumn _currentHighlightedTableColumn;
unsigned _gridStyleMask;
unsigned _selectionHighlightStyle;
CPColor _unfocusedSelectionHighlightColor;
CPDictionary _unfocusedSourceListSelectionColor;
CPTableColumn _currentHighlightedTableColumn;
unsigned _gridStyleMask;
unsigned _numberOfRows;
CPIndexSet _groupRows;
unsigned _numberOfRows;
CPIndexSet _groupRows;
CPArray _cachedRowHeights;
CPArray _cachedRowHeights;
// Persistence
CPString _autosaveName;
BOOL _autosaveTableColumns;
CPString _autosaveName;
BOOL _autosaveTableColumns;
CPTableHeaderView _headerView;
_CPCornerView _cornerView;
CPTableHeaderView _headerView;
_CPCornerView _cornerView;
CPIndexSet _selectedColumnIndexes;
CPIndexSet _selectedRowIndexes;
CPInteger _selectionAnchorRow;
CPInteger _lastSelectedRow;
CPIndexSet _previouslySelectedRowIndexes;
CGPoint _startTrackingPoint;
CPDate _startTrackingTimestamp;
BOOL _trackingPointMovedOutOfClickSlop;
CGPoint _editingCellIndex;
CPInteger _editingRow;
CPInteger _editingColumn;
CPIndexSet _selectedColumnIndexes;
CPIndexSet _selectedRowIndexes;
CPInteger _selectionAnchorRow;
CPInteger _lastSelectedRow;
CPIndexSet _previouslySelectedRowIndexes;
CGPoint _startTrackingPoint;
CPDate _startTrackingTimestamp;
BOOL _trackingPointMovedOutOfClickSlop;
CGPoint _editingCellIndex;
CPInteger _editingRow;
CPInteger _editingColumn;
_CPTableDrawView _tableDrawView;
_CPTableDrawView _tableDrawView;
SEL _doubleAction;
CPInteger _clickedRow;
CPInteger _clickedColumn;
unsigned _columnAutoResizingStyle;
SEL _doubleAction;
CPInteger _clickedRow;
CPInteger _clickedColumn;
unsigned _columnAutoResizingStyle;
int _lastTrackedRowIndex;
CGPoint _originalMouseDownPoint;
BOOL _verticalMotionCanDrag;
unsigned _destinationDragStyle;
BOOL _isSelectingSession;
CPIndexSet _draggedRowIndexes;
BOOL _wasSelectionBroken;
int _lastTrackedRowIndex;
CGPoint _originalMouseDownPoint;
BOOL _verticalMotionCanDrag;
unsigned _destinationDragStyle;
BOOL _isSelectingSession;
CPIndexSet _draggedRowIndexes;
BOOL _wasSelectionBroken;
_CPDropOperationDrawingView _dropOperationFeedbackView;
CPDragOperation _dragOperationDefaultMask;
int _retargetedDropRow;
CPDragOperation _retargetedDropOperation;
CPArray _draggingViews;
CPDragOperation _dragOperationDefaultMask;
int _retargetedDropRow;
CPDragOperation _retargetedDropOperation;
CPArray _draggingViews;
BOOL _disableAutomaticResizing @accessors(property=disableAutomaticResizing);
BOOL _lastColumnShouldSnap;
BOOL _implementsCustomDrawRow;
BOOL _isViewBased;
BOOL _contentBindingExplicitlySet;
BOOL _disableAutomaticResizing @accessors(property=disableAutomaticResizing);
BOOL _lastColumnShouldSnap;
BOOL _implementsCustomDrawRow;
BOOL _isViewBased;
BOOL _contentBindingExplicitlySet;
SEL _viewForTableColumnRowSelector;
SEL _viewForTableColumnRowSelector;
CPTableColumn _draggedColumn;
CPArray _differedColumnDataToRemove;
CPTableColumn _draggedColumn;
CPArray _differedColumnDataToRemove;
CPView _observedClipView;
}
/*!
@@ -426,8 +478,6 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
if (!_sortDescriptors)
_sortDescriptors = [];
[self _startObservingFirstResponder];
}
/*!
@@ -495,7 +545,7 @@ NOT YET IMPLEMENTED
- (CPArray)tableView:(CPTableView)aTableView namesOfPromisedFilesDroppedAtDestination:(CPURL)dropDestination forDraggedRowsWithIndexes:(CPIndexSet)indexSet;
@endcode
*/
- (void)setDataSource:(id)aDataSource
- (void)setDataSource:(id <CPTableViewDataSource>)aDataSource
{
if (_dataSource === aDataSource)
return;
@@ -917,7 +967,7 @@ NOT YET IMPLEMENTED
</pre>
*/
- (void)unfocusedSelectionGradientColors
- (CPColor)unfocusedSelectionGradientColors
{
if (!_unfocusedSourceListSelectionColor)
{
@@ -1121,6 +1171,9 @@ NOT YET IMPLEMENTED
[[CPNotificationCenter defaultCenter] postNotificationName:CPTableViewColumnDidMoveNotification
object:self
userInfo:@{ @"CPOldColumn": fromIndex, @"CPNewColumn": toIndex }];
if (_implementedDelegateMethods & CPTableViewDelegate_tableViewColumnDidMove_)
[_delegate tableViewColumnDidMove:[[CPNotification alloc] initWithName:CPTableViewColumnDidMoveNotification object:self userInfo:@{ @"CPOldColumn": fromIndex, @"CPNewColumn": toIndex }]];
}
/*!
@@ -1199,9 +1252,17 @@ NOT YET IMPLEMENTED
/*!
@ignore
*/
- (void)_didResizeTableColumn:(CPTableColumn)theColumn
- (void)_didResizeTableColumn:(CPTableColumn)theColumn oldWidth:(int)oldWidth
{
[self _autosave];
[[CPNotificationCenter defaultCenter]
postNotificationName:CPTableViewColumnDidResizeNotification
object:self
userInfo:@{ @"CPTableColumn": theColumn, @"CPOldWidth": oldWidth }];
if (_implementedDelegateMethods & CPTableViewDelegate_tableViewColumnDidResize_)
[_delegate tableViewColumnDidResize:[[CPNotification alloc] initWithName:CPTableViewColumnDidResizeNotification object:self userInfo:@{ @"CPTableColumn": theColumn, @"CPOldWidth": oldWidth }]];
}
//Selecting Columns and Rows
@@ -1298,6 +1359,38 @@ NOT YET IMPLEMENTED
[self _setSelectedRowIndexes:newSelectedIndexes];
}
/*!
@ignore
cleanup a an indexset from the indexes that cannot be selected
according to the table view delegate.
*/
- (CPIndexSet)_cleanUpSelectionRowIndexes:(CPIndexSet)anIndexSet
{
if ([self _delegateRespondsToSelectionIndexesForProposedSelection])
{
return [self _sendDelegateSelectionIndexesForProposedSelection:anIndexSet];
}
else if ([self _delegateRespondsToShouldSelectRow])
{
var indexesToRemove = [CPIndexSet new],
currentIndex = [anIndexSet firstIndex];
while (currentIndex != CPNotFound)
{
if (![self _sendDelegateShouldSelectRow:currentIndex])
[indexesToRemove addIndex:currentIndex];
currentIndex = [anIndexSet indexGreaterThanIndex:currentIndex];
}
[anIndexSet removeIndexes:indexesToRemove];
return anIndexSet;
}
else
return anIndexSet;
}
/*!
@ignore
*/
@@ -1522,7 +1615,10 @@ NOT YET IMPLEMENTED
if ([[self selectedColumnIndexes] count])
[self selectColumnIndexes:[CPIndexSet indexSetWithIndexesInRange:CPMakeRange(0, [self numberOfColumns])] byExtendingSelection:NO];
else
[self selectRowIndexes:[CPIndexSet indexSetWithIndexesInRange:CPMakeRange(0, [self numberOfRows])] byExtendingSelection:NO];
{
var range = [self _cleanUpSelectionRowIndexes:[CPIndexSet indexSetWithIndexesInRange:CPMakeRange(0, [self numberOfRows])]];
[self selectRowIndexes:range byExtendingSelection:NO];
}
}
}
@@ -2014,7 +2110,7 @@ NOT YET IMPLEMENTED
// search the (potentially large number of) rows for nothing.
var heightInfo = [_cachedRowHeights lastObject];
if (aPoint.y >= ROW_BOTTOM(heightInfo))
if (!heightInfo || aPoint.y >= ROW_BOTTOM(heightInfo))
return -1;
return [_cachedRowHeights indexOfObject:aPoint
@@ -2774,40 +2870,11 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
- (void)tableViewDeleteKeyPressed:(CPTableView)aTableView;
@endcode
*/
- (void)setDelegate:(id)aDelegate
- (void)setDelegate:(id <CPTableViewDelegate>)aDelegate
{
if (_delegate === aDelegate)
return;
var defaultCenter = [CPNotificationCenter defaultCenter];
if (_delegate)
{
if ([_delegate respondsToSelector:@selector(tableViewColumnDidMove:)])
[defaultCenter
removeObserver:_delegate
name:CPTableViewColumnDidMoveNotification
object:self];
if ([_delegate respondsToSelector:@selector(tableViewColumnDidResize:)])
[defaultCenter
removeObserver:_delegate
name:CPTableViewColumnDidResizeNotification
object:self];
if ([_delegate respondsToSelector:@selector(tableViewSelectionDidChange:)])
[defaultCenter
removeObserver:_delegate
name:CPTableViewSelectionDidChangeNotification
object:self];
if ([_delegate respondsToSelector:@selector(tableViewSelectionIsChanging:)])
[defaultCenter
removeObserver:_delegate
name:CPTableViewSelectionIsChangingNotification
object:self];
}
_delegate = aDelegate;
_implementedDelegateMethods = 0;
@@ -2872,6 +2939,9 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
if ([_delegate respondsToSelector:@selector(tableView:willDisplayView:forTableColumn:row:)])
_implementedDelegateMethods |= CPTableViewDelegate_tableView_willDisplayView_forTableColumn_row_;
if ([_delegate respondsToSelector:@selector(tableView:willRemoveView:forTableColumn:row:)])
_implementedDelegateMethods |= CPTableViewDelegate_tableView_willRemoveView_forTableColumn_row_;
if ([_delegate respondsToSelector:@selector(tableView:menuForTableColumn:row:)])
_implementedDelegateMethods |= CPTableViewDelegate_tableViewMenuForTableColumn_row_;
@@ -2879,32 +2949,16 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
_implementedDelegateMethods |= CPTableViewDelegate_tableView_shouldReorderColumn_toColumn_;
if ([_delegate respondsToSelector:@selector(tableViewColumnDidMove:)])
[defaultCenter
addObserver:_delegate
selector:@selector(tableViewColumnDidMove:)
name:CPTableViewColumnDidMoveNotification
object:self];
_implementedDelegateMethods |= CPTableViewDelegate_tableViewColumnDidMove_;
if ([_delegate respondsToSelector:@selector(tableViewColumnDidResize:)])
[defaultCenter
addObserver:_delegate
selector:@selector(tableViewColumnDidResize:)
name:CPTableViewColumnDidResizeNotification
object:self];
_implementedDelegateMethods |= CPTableViewDelegate_tableViewColumnDidResize_;
if ([_delegate respondsToSelector:@selector(tableViewSelectionDidChange:)])
[defaultCenter
addObserver:_delegate
selector:@selector(tableViewSelectionDidChange:)
name:CPTableViewSelectionDidChangeNotification
object:self];
_implementedDelegateMethods |= CPTableViewDelegate_tableViewSelectionDidChange_;
if ([_delegate respondsToSelector:@selector(tableViewSelectionIsChanging:)])
[defaultCenter
addObserver:_delegate
selector:@selector(tableViewSelectionIsChanging:)
name:CPTableViewSelectionIsChangingNotification
object:self];
_implementedDelegateMethods |= CPTableViewDelegate_tableViewSelectionIsChanging_;
}
/*!
@@ -3507,6 +3561,8 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
var dataView = [dataViews objectAtIndex:row];
[self _sendDelegateWillRemoveView:dataView forTableColumn:tableColumn row:row];
[dataViews replaceObjectAtIndex:row withObject:nil];
[self _enqueueReusableDataView:dataView];
@@ -3863,6 +3919,9 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
// FIXME: yuck!
var identifier = [aDataView identifier];
if ([aDataView hasThemeState:CPThemeStateSelectedDataView])
[aDataView unsetThemeState:CPThemeStateSelectedDataView];
if (!_cachedDataViews[identifier])
_cachedDataViews[identifier] = [aDataView];
else
@@ -4366,39 +4425,15 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
*/
- (void)viewWillMoveToSuperview:(CPView)aView
{
var superview = [self superview],
defaultCenter = [CPNotificationCenter defaultCenter];
if (superview)
{
[defaultCenter
removeObserver:self
name:CPViewFrameDidChangeNotification
object:superview];
[defaultCenter
removeObserver:self
name:CPViewBoundsDidChangeNotification
object:superview];
}
if ([aView isKindOfClass:[CPClipView class]])
_observedClipView = aView;
else
{
[aView setPostsFrameChangedNotifications:YES];
[aView setPostsBoundsChangedNotifications:YES];
[defaultCenter
addObserver:self
selector:@selector(superviewFrameChanged:)
name:CPViewFrameDidChangeNotification
object:aView];
[defaultCenter
addObserver:self
selector:@selector(superviewBoundsChanged:)
name:CPViewBoundsDidChangeNotification
object:aView];
[self _stopObservingClipView];
_observedClipView = nil;
}
[super viewWillMoveToSuperview:aView];
}
/*!
@@ -4980,6 +5015,9 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
postNotificationName:CPTableViewSelectionIsChangingNotification
object:self
userInfo:nil];
if (_implementedDelegateMethods & CPTableViewDelegate_tableViewSelectionIsChanging_)
[_delegate tableViewSelectionIsChanging:[[CPNotification alloc] initWithName:CPTableViewSelectionIsChangingNotification object:self userInfo:nil]];
}
/*!
@@ -4991,6 +5029,9 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
postNotificationName:CPTableViewSelectionDidChangeNotification
object:self
userInfo:nil];
if (_implementedDelegateMethods & CPTableViewDelegate_tableViewSelectionDidChange_)
[_delegate tableViewSelectionDidChange:[[CPNotification alloc] initWithName:CPTableViewSelectionDidChangeNotification object:self userInfo:nil]];
}
/*!
@@ -5009,24 +5050,6 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
[self setNeedsDisplay:YES];
}
/*!
@ignore
*/
- (BOOL)becomeFirstResponder
{
[self setNeedsDisplay:YES];
return YES;
}
/*!
@ignore
*/
- (BOOL)resignFirstResponder
{
[self setNeedsDisplay:YES];
return YES;
}
/*!
@ignore
*/
@@ -5051,14 +5074,88 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
var hit = [super hitTest:aPoint];
if ([[CPApp currentEvent] type] == CPLeftMouseDown && [hit acceptsFirstResponder] && ![self isRowSelected:[self rowForView:hit]])
{
if (_selectionHighlightStyle == CPTableViewSelectionHighlightStyleNone)
return hit;
return self;
}
return hit;
}
- (void)_startObservingFirstResponder
- (void)_removeObservers
{
[[CPNotificationCenter defaultCenter] addObserver:self selector:@selector(_firstResponderDidChange:) name:_CPWindowDidChangeFirstResponderNotification object:[self window]];
if (!_isObserving)
return;
[self _stopObservingClipView];
[super _removeObservers];
}
- (void)_addObservers
{
if (_isObserving)
return;
[self _startObservingClipView];
[super _addObservers];
}
/*!
Called when the receiver is about to be moved to a new window.
@param aWindow the window to which the receiver will be moved.
*/
- (void)viewWillMoveToWindow:(CPWindow)aWindow
{
[super viewWillMoveToWindow:aWindow];
[self _stopObservingFirstResponder];
if (aWindow)
[self _startObservingFirstResponderForWindow:aWindow];
}
- (void)_startObservingClipView
{
if (!_observedClipView)
return;
var defaultCenter = [CPNotificationCenter defaultCenter];
[_observedClipView setPostsFrameChangedNotifications:YES];
[_observedClipView setPostsBoundsChangedNotifications:YES];
[defaultCenter addObserver:self
selector:@selector(superviewFrameChanged:)
name:CPViewFrameDidChangeNotification
object:_observedClipView];
[defaultCenter addObserver:self
selector:@selector(superviewBoundsChanged:)
name:CPViewBoundsDidChangeNotification
object:_observedClipView];
}
- (void)_stopObservingClipView
{
if (!_observedClipView)
return;
var defaultCenter = [CPNotificationCenter defaultCenter];
[defaultCenter removeObserver:self
name:CPViewFrameDidChangeNotification
object:_observedClipView];
[defaultCenter removeObserver:self
name:CPViewBoundsDidChangeNotification
object:_observedClipView];
}
- (void)_startObservingFirstResponderForWindow:(CPWindow)aWindow
{
[[CPNotificationCenter defaultCenter] addObserver:self selector:@selector(_firstResponderDidChange:) name:_CPWindowDidChangeFirstResponderNotification object:aWindow];
}
- (void)_stopObservingFirstResponder
@@ -5074,13 +5171,20 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
{
_editingRow = CPNotFound;
_editingColumn = CPNotFound;
// This is needed to unset the themeState firstResponder of the tableView
[self _notifyViewDidResignFirstResponder];
return;
}
_editingRow = [self rowForView:responder];
_editingColumn = [self columnForView:responder];
if (_editingRow !== CPNotFound && [responder isKindOfClass:[CPTextField class]] && ![responder isBezeled])
// We want to keep the 'First Responder' theme state for the table view as a whole, even when a subview is being edited.
// This makes sure the theming effects of a focused table remain in effect even as cells are being edited in it.
[self _notifyViewDidBecomeFirstResponder];
if (_editingRow !== CPNotFound && [responder isKindOfClass:[CPTextField class]] && ![responder isBezeled] && [responder isEditable])
{
[responder setBezeled:YES];
[self _registerForEndEditingNote:responder];
@@ -5210,9 +5314,9 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
if (i >= [self numberOfRows] || i < 0)
return;
if (![self _delegateRespondsToSelectionIndexesForProposedSelection] && [self _delegateRespondsToShouldSelectRow])
if ([self _delegateRespondsToSelectionIndexesForProposedSelection] || [self _delegateRespondsToShouldSelectRow])
{
var shouldSelect = [self _sendDelegateShouldSelectRow:i];
var shouldSelect = !![[self _cleanUpSelectionRowIndexes:[CPIndexSet indexSetWithIndex:i]] count];
/* If shouldSelect returns NO it means this row cannot be selected.
The proper behaviour is to then try to see if the next/previous
@@ -5221,7 +5325,7 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
while (!shouldSelect && (i < [self numberOfRows] && i > 0))
{
shouldGoUpward ? --i : ++i; //check to see if the row can be selected. If it can't be then see if the next row can be selected.
shouldSelect = [self _sendDelegateShouldSelectRow:i];
shouldSelect = !![[self _cleanUpSelectionRowIndexes:[CPIndexSet indexSetWithIndex:i]] count];
}
if (!shouldSelect)
@@ -5583,6 +5687,18 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
[_delegate tableView:self willDisplayView:aCell forTableColumn:aTableColumn row:aRowIndex];
}
/*!
@ignore
Call the delegate tableView:willRemoveView:forTableColumn:row:
*/
- (void)_sendDelegateWillRemoveView:(id)aCell forTableColumn:(CPTableColumn)aTableColumn row:(CPInteger)aRowIndex
{
if (!(_implementedDelegateMethods & CPTableViewDelegate_tableView_willRemoveView_forTableColumn_row_))
return;
[_delegate tableView:self willRemoveView:aCell forTableColumn:aTableColumn row:aRowIndex];
}
/*!
@ignore
Return a CPMenu for the given tableColumn and row. By default return the menu of super.
@@ -5916,6 +6032,11 @@ var CPTableViewDataSourceKey = @"CPTableViewDataSourceKey",
{
[super encodeWithCoder:aCoder];
// We do this in order to avoid encoding the _tableDrawView, which
// should just automatically be created programmatically as needed.
if (_tableDrawView)
[_tableDrawView removeFromSuperview];
[aCoder encodeObject:_dataSource forKey:CPTableViewDataSourceKey];
[aCoder encodeObject:_delegate forKey:CPTableViewDelegateKey];
@@ -6143,14 +6264,20 @@ var CPTableViewDataSourceKey = @"CPTableViewDataSourceKey",
[self setThemeState:CPThemeStateTableDataView];
}
- (BOOL)setThemeState:(CPThemeState)aState
- (BOOL)setThemeState:(ThemeState)aState
{
if (aState.isa && [aState isKindOfClass:CPArray])
aState = CPThemeState.apply(null, aState);
[super setThemeState:aState];
[self recursivelyPerformSelector:@selector(setThemeState:) withObject:aState startingFrom:self];
}
- (BOOL)unsetThemeState:(CPThemeState)aState
- (BOOL)unsetThemeState:(ThemeState)aState
{
if (aState.isa && [aState isKindOfClass:CPArray])
aState = CPThemeState.apply(null, aState);
[super unsetThemeState:aState];
[self recursivelyPerformSelector:@selector(unsetThemeState:) withObject:aState startingFrom:self];
}
+408 -224
View File
@@ -31,16 +31,32 @@
@global CPApp
@global CPStringPboardType
@global CPCursor
@protocol CPTextFieldDelegate <CPControlTextEditingDelegate>
@end
var CPTextFieldDelegate_control_didFailToFormatString_errorDescription_ = 1 << 1,
CPTextFieldDelegate_controlTextDidBeginEditing_ = 1 << 2,
CPTextFieldDelegate_controlTextDidChange_ = 1 << 3,
CPTextFieldDelegate_controlTextDidEndEditing_ = 1 << 4,
CPTextFieldDelegate_controlTextDidFocus_ = 1 << 5,
CPTextFieldDelegate_controlTextDidBlur_ = 1 << 6;
@typedef CPTextFieldBezelStyle
CPTextFieldSquareBezel = 0; /*! A textfield bezel with squared corners. */
CPTextFieldRoundedBezel = 1; /*! A textfield bezel with rounded corners. */
CPTextFieldDidFocusNotification = @"CPTextFieldDidFocusNotification";
CPTextFieldDidBlurNotification = @"CPTextFieldDidBlurNotification";
var CPTextFieldDOMInputElement = nil,
CPTextFieldDOMPasswordInputElement = nil,
var CPTextFieldDOMCurrentElement = nil,
CPTextFieldDOMTextAreaElement = nil,
CPTextFieldDOMStandardInputElement = nil,
CPTextFieldDOMPasswordInputElement = nil,
CPTextFieldInputOwner = nil,
CPTextFieldTextDidChangeValue = nil,
CPTextFieldInputResigning = NO,
@@ -112,26 +128,30 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
*/
@implementation CPTextField : CPControl
{
BOOL _isEditing;
BOOL _isEditing;
BOOL _isEditable;
BOOL _isSelectable;
BOOL _isSecure;
BOOL _willBecomeFirstResponderByClick;
BOOL _isEditable;
BOOL _isSelectable;
BOOL _isSecure;
BOOL _willBecomeFirstResponderByClick;
BOOL _invokedByUserEvent;
BOOL _drawsBackground;
BOOL _drawsBackground;
CPColor _textFieldBackgroundColor;
CPColor _textFieldBackgroundColor;
CPString _placeholderString;
CPString _stringValue;
CPString _placeholderString;
CPString _stringValue;
id _delegate;
id <CPTextFieldDelegate> _delegate;
unsigned _implementedDelegateMethods;
// NS-style Display Properties
CPTextFieldBezelStyle _bezelStyle;
BOOL _isBordered;
CPControlSize _controlSize;
CPTextFieldBezelStyle _bezelStyle;
BOOL _isBordered;
BOOL _usesSingleLineMode;
BOOL _wraps;
BOOL _scrolls;
}
+ (Class)_binderClassForBinding:(CPString)aBinding
@@ -218,98 +238,124 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
};
}
#pragma mark -
#pragma mark Control Size
- (void)setControlSize:(CPControlSize)aControlSize
{
[super setControlSize:aControlSize];
if ([self isBezeled])
[self _sizeToControlSize];
}
#pragma mark -
#if PLATFORM(DOM)
- (DOMElement)_inputElement
{
if (!CPTextFieldDOMInputElement)
if (!CPTextFieldDOMTextAreaElement)
{
CPTextFieldDOMInputElement = document.createElement("input");
CPTextFieldDOMInputElement.style.position = "absolute";
CPTextFieldDOMInputElement.style.border = "0px";
CPTextFieldDOMInputElement.style.padding = "0px";
CPTextFieldDOMInputElement.style.margin = "0px";
CPTextFieldDOMInputElement.style.whiteSpace = "pre";
CPTextFieldDOMInputElement.style.background = "transparent";
CPTextFieldDOMInputElement.style.outline = "none";
CPTextFieldDOMTextAreaElement = document.createElement("textarea");
CPTextFieldDOMTextAreaElement.style.position = "absolute";
CPTextFieldDOMTextAreaElement.style.border = "0px";
CPTextFieldDOMTextAreaElement.style.padding = "0px";
CPTextFieldDOMTextAreaElement.style.margin = "0px";
CPTextFieldDOMTextAreaElement.style.background = "transparent";
CPTextFieldDOMTextAreaElement.style.outline = "none";
CPTextFieldDOMTextAreaElement.style.resize = "none";
CPTextFieldDOMTextAreaElement.style.overflow = "hidden";
CPTextFieldDOMTextAreaElement.spellcheck = NO;
}
if (!CPTextFieldDOMStandardInputElement)
{
CPTextFieldDOMStandardInputElement = document.createElement("input");
CPTextFieldDOMStandardInputElement.style.position = "absolute";
CPTextFieldDOMStandardInputElement.style.border = "0px";
CPTextFieldDOMStandardInputElement.style.padding = "0px";
CPTextFieldDOMStandardInputElement.style.margin = "0px";
CPTextFieldDOMStandardInputElement.style.whiteSpace = "pre";
CPTextFieldDOMStandardInputElement.style.background = "transparent";
CPTextFieldDOMStandardInputElement.style.outline = "none";
CPTextFieldDOMStandardInputElement.spellcheck = NO;
}
if (!CPTextFieldDOMPasswordInputElement)
{
CPTextFieldDOMPasswordInputElement = document.createElement("input");
CPTextFieldDOMPasswordInputElement.style.position = "absolute";
CPTextFieldDOMPasswordInputElement.style.border = "0px";
CPTextFieldDOMPasswordInputElement.style.padding = "0px";
CPTextFieldDOMPasswordInputElement.style.margin = "0px";
CPTextFieldDOMPasswordInputElement.style.whiteSpace = "pre";
CPTextFieldDOMPasswordInputElement.style.background = "transparent";
CPTextFieldDOMPasswordInputElement.style.outline = "none";
CPTextFieldDOMPasswordInputElement.type = "password";
CPTextFieldDOMPasswordInputElement.spellcheck = NO;
}
if (!CPTextFieldBlurHandler)
{
CPTextFieldBlurHandler = function(anEvent)
{
return CPTextFieldBlurFunction(
anEvent,
CPTextFieldInputOwner,
CPTextFieldInputOwner ? CPTextFieldInputOwner._DOMElement : nil,
CPTextFieldDOMInputElement,
CPTextFieldDOMCurrentElement,
CPTextFieldInputResigning,
@ref(CPTextFieldInputDidBlur));
};
}
if (CPFeatureIsCompatible(CPInputOnInputEventFeature))
if (!CPTextFieldInputFunction)
{
if (!CPFeatureIsCompatible(CPInputOnInputEventFeature))
return;
CPTextFieldInputFunction = function(anEvent)
{
CPTextFieldInputFunction = function(anEvent)
{
if (!CPTextFieldInputOwner)
return;
if (!CPTextFieldInputOwner)
return;
var cappEvent = [CPEvent keyEventWithType:CPKeyUp
location:CGPointMakeZero()
modifierFlags:0
timestamp:[CPEvent currentTimestamp]
windowNumber:[[CPApp keyWindow] windowNumber]
context:nil
characters:nil
charactersIgnoringModifiers:nil
isARepeat:NO
keyCode:nil];
var cappEvent = [CPEvent keyEventWithType:CPKeyUp
location:CGPointMakeZero()
modifierFlags:0
timestamp:[CPEvent currentTimestamp]
windowNumber:[[CPApp keyWindow] windowNumber]
context:nil
characters:nil
charactersIgnoringModifiers:nil
isARepeat:NO
keyCode:nil];
[CPTextFieldInputOwner keyUp:cappEvent];
[CPTextFieldInputOwner keyUp:cappEvent];
[[CPRunLoop currentRunLoop] limitDateForMode:CPDefaultRunLoopMode];
}
CPTextFieldDOMInputElement.oninput = CPTextFieldInputFunction;
[[CPRunLoop currentRunLoop] limitDateForMode:CPDefaultRunLoopMode];
}
// FIXME make this not onblur
CPTextFieldDOMInputElement.onblur = CPTextFieldBlurHandler;
CPTextFieldDOMPasswordInputElement.oninput = CPTextFieldInputFunction;
CPTextFieldDOMPasswordInputElement.onblur = CPTextFieldBlurHandler;
CPTextFieldDOMStandardInputElement = CPTextFieldDOMInputElement;
CPTextFieldDOMStandardInputElement.oninput = CPTextFieldInputFunction;
CPTextFieldDOMPasswordInputElement.onblur = CPTextFieldBlurHandler;
CPTextFieldDOMTextAreaElement.oninput = CPTextFieldInputFunction;
CPTextFieldDOMTextAreaElement.onblur = CPTextFieldBlurHandler;
}
if (CPFeatureIsCompatible(CPInputTypeCanBeChangedFeature))
{
if ([self isSecure])
CPTextFieldDOMInputElement.type = "password";
else
CPTextFieldDOMInputElement.type = "text";
return CPTextFieldDOMInputElement;
}
if ([self isSecure])
{
if (!CPTextFieldDOMPasswordInputElement)
{
CPTextFieldDOMPasswordInputElement = document.createElement("input");
CPTextFieldDOMPasswordInputElement.style.position = "absolute";
CPTextFieldDOMPasswordInputElement.style.border = "0px";
CPTextFieldDOMPasswordInputElement.style.padding = "0px";
CPTextFieldDOMPasswordInputElement.style.margin = "0px";
CPTextFieldDOMPasswordInputElement.style.whiteSpace = "pre";
CPTextFieldDOMPasswordInputElement.style.background = "transparent";
CPTextFieldDOMPasswordInputElement.style.outline = "none";
CPTextFieldDOMPasswordInputElement.type = "password";
CPTextFieldDOMPasswordInputElement.onblur = CPTextFieldBlurHandler;
}
CPTextFieldDOMInputElement = CPTextFieldDOMPasswordInputElement;
}
CPTextFieldDOMCurrentElement = CPTextFieldDOMPasswordInputElement;
else if (_usesSingleLineMode)
CPTextFieldDOMCurrentElement = CPTextFieldDOMStandardInputElement;
else
{
CPTextFieldDOMInputElement = CPTextFieldDOMStandardInputElement;
}
CPTextFieldDOMCurrentElement = CPTextFieldDOMTextAreaElement;
return CPTextFieldDOMInputElement;
return CPTextFieldDOMCurrentElement;
}
#endif
@@ -528,6 +574,24 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
return _textFieldBackgroundColor;
}
/*! @ignore */
- (void)_setUsesSingleLineMode:(BOOL)aFlag
{
_usesSingleLineMode = aFlag;
}
/*! @ignore */
- (void)_setWraps:(BOOL)aFlag
{
_wraps = aFlag;
}
/*! @ignore */
- (void)_setScrolls:(BOOL)aFlag
{
_scrolls = aFlag;
}
/*! @ignore */
- (BOOL)acceptsFirstResponder
{
@@ -537,7 +601,7 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
/*! @ignore */
- (BOOL)becomeFirstResponder
{
if (![self isEnabled])
if (![self isEnabled] || ![super becomeFirstResponder])
return NO;
// As long as we are the first responder we need to monitor the key status of our window.
@@ -581,75 +645,12 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
#if PLATFORM(DOM)
var element = [self _inputElement],
font = [self currentValueForThemeAttribute:@"font"],
lineHeight = [font defaultLineHeightForFont];
[self _setCSSStyleForInputElement];
var element = [self _inputElement];
element.value = _stringValue;
element.style.color = [[self currentValueForThemeAttribute:@"text-color"] cssString];
if (CPFeatureIsCompatible(CPInputSetFontOutsideOfDOM))
element.style.font = [font cssString];
element.style.zIndex = 1000;
switch ([self alignment])
{
case CPCenterTextAlignment:
element.style.textAlign = "center";
break;
case CPRightTextAlignment:
element.style.textAlign = "right";
break;
default:
element.style.textAlign = "left";
}
var contentRect = [self contentRectForBounds:[self bounds]],
verticalAlign = [self currentValueForThemeAttribute:"vertical-alignment"];
switch (verticalAlign)
{
case CPTopVerticalTextAlignment:
var topPoint = CGRectGetMinY(contentRect) + "px";
break;
case CPCenterVerticalTextAlignment:
var topPoint = (CGRectGetMidY(contentRect) - (lineHeight / 2)) + "px";
break;
case CPBottomVerticalTextAlignment:
var topPoint = (CGRectGetMaxY(contentRect) - lineHeight) + "px";
break;
default:
var topPoint = CGRectGetMinY(contentRect) + "px";
break;
}
element.style.top = topPoint;
var left = CGRectGetMinX(contentRect);
// If the browser has a built in left padding, compensate for it. We need the input text to be exactly on top of the original text.
if (CPFeatureIsCompatible(CPInput1PxLeftPadding))
left -= 1;
element.style.left = left + "px";
element.style.width = CGRectGetWidth(contentRect) + "px";
element.style.height = ROUND(lineHeight) + "px";
element.style.lineHeight = ROUND(lineHeight) + "px";
element.style.verticalAlign = "top";
element.style.cursor = "auto";
_DOMElement.appendChild(element);
// The font change above doesn't work for some browsers if the element isn't already appendChild'ed.
if (!CPFeatureIsCompatible(CPInputSetFontOutsideOfDOM))
element.style.font = [font cssString];
CPTextFieldInputIsActive = YES;
if (document.attachEvent)
@@ -687,6 +688,81 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
return YES;
}
/*!
Set the css style for the input element of the textField
@ignore
*/
- (void)_setCSSStyleForInputElement
{
#if PLATFORM(DOM)
var element = [self _inputElement],
font = [self currentValueForThemeAttribute:@"font"],
lineHeight = [font defaultLineHeightForFont],
contentRect = [self contentRectForBounds:[self bounds]],
verticalAlign = [self currentValueForThemeAttribute:"vertical-alignment"],
left = CGRectGetMinX(contentRect);
// If the browser has a built in left padding, compensate for it. We need the input text to be exactly on top of the original text.
if (CPFeatureIsCompatible(CPInput1PxLeftPadding))
left -= 1;
switch (verticalAlign)
{
case CPTopVerticalTextAlignment:
var topPoint = CGRectGetMinY(contentRect) + "px";
break;
case CPCenterVerticalTextAlignment:
var topPoint = (CGRectGetMidY(contentRect) - (lineHeight / 2)) + "px";
break;
case CPBottomVerticalTextAlignment:
var topPoint = (CGRectGetMaxY(contentRect) - lineHeight) + "px";
break;
default:
var topPoint = CGRectGetMinY(contentRect) + "px";
break;
}
if ([self hasThemeState:CPTextFieldStatePlaceholder])
element.style.color = [[self valueForThemeAttribute:@"text-color" inState:CPTextFieldStatePlaceholder] cssString];
else
element.style.color = [[self valueForThemeAttribute:@"text-color" inState:CPThemeStateEditing] cssString];
switch ([self alignment])
{
case CPCenterTextAlignment:
element.style.textAlign = "center";
break;
case CPRightTextAlignment:
element.style.textAlign = "right";
break;
default:
element.style.textAlign = "left";
}
var isTextArea = element.nodeName.toUpperCase() == "TEXTAREA";
element.style.zIndex = 1000;
element.style.top = topPoint;
element.style.lineHeight = ROUND(lineHeight) + "px";
element.style.height = isTextArea ? CGRectGetHeight(contentRect) + "px" : ROUND(lineHeight) + "px";;
element.style.width = CGRectGetWidth(contentRect) + "px";
element.style.left = left + "px";
element.style.verticalAlign = "top";
element.style.cursor = "auto";
element.style.font = [font cssString];
if (isTextArea)
element.style.whiteSpace = _wraps ? "pre" : "nowrap";
#endif
}
/*! @ignore */
- (BOOL)resignFirstResponder
{
@@ -790,6 +866,26 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
}
}
- (void)_removeObservers
{
if (!_isObserving)
return;
[super _removeObservers];
[self _setObserveWindowKeyNotifications:NO];
}
- (void)_addObservers
{
if (_isObserving)
return;
[super _addObservers];
if ([[self window] firstResponder] === self)
[self _setObserveWindowKeyNotifications:YES];
}
- (void)_windowDidResignKey:(CPNotification)aNotification
{
if (![[self window] isKeyWindow])
@@ -818,7 +914,7 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
{
var acceptInvalidValue = NO;
if ([_delegate respondsToSelector:@selector(control:didFailToFormatString:errorDescription:)])
if (_implementedDelegateMethods & CPTextFieldDelegate_control_didFailToFormatString_errorDescription_)
acceptInvalidValue = [_delegate control:self didFailToFormatString:aValue errorDescription:error];
if (acceptInvalidValue === NO)
@@ -858,6 +954,12 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
[self textDidChange:[CPNotification notificationWithName:CPControlTextDidChangeNotification object:self userInfo:nil]];
}
- (void)mouseMoved:(CPEvent)anEvent
{
[super mouseMoved:anEvent];
[self _updateCursorForEvent:anEvent];
}
- (void)mouseDown:(CPEvent)anEvent
{
// Don't track! (ever?)
@@ -928,7 +1030,6 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
if (newValue !== _stringValue)
{
[self _setStringValue:newValue];
[self _didEdit];
}
@@ -938,13 +1039,20 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
- (void)keyDown:(CPEvent)anEvent
{
if (!([self isEnabled] && [self isEditable]))
return;
// 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];
// Set a flag so that key handling methods (such as deleteBackward:)
// know they were invoked from a user event.
_invokedByUserEvent = !!anEvent._DOMEvent;
[self interpretKeyEvents:[anEvent]];
_invokedByUserEvent = NO;
[[CPRunLoop currentRunLoop] limitDateForMode:CPDefaultRunLoopMode];
}
@@ -1022,7 +1130,11 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
range = [self selectedRange],
element = [self _inputElement];
element.value = [element.value stringByReplacingCharactersInRange:[self selectedRange] withString:aCharacter];
// we don't need to do this in case of textarea
// or we will end up with 2 carriage returns
if (aCharacter != CPNewlineCharacter || element.nodeName.toUpperCase() != "TEXTAREA" || !CPFeatureIsCompatible(CPAltEnterTextAreaFeature))
element.value = [element.value stringByReplacingCharactersInRange:[self selectedRange] withString:aCharacter];
[self _setStringValue:element.value];
// NOTE: _stringValue is now the current input element value
@@ -1040,6 +1152,9 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
if ([note object] != self)
return;
if (_implementedDelegateMethods & CPTextFieldDelegate_controlTextDidBlur_)
[_delegate controlTextDidBlur:note];
[[CPNotificationCenter defaultCenter] postNotification:note];
}
@@ -1049,6 +1164,9 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
if ([note object] != self)
return;
if (_implementedDelegateMethods & CPTextFieldDelegate_controlTextDidFocus_)
[_delegate controlTextDidFocus:note];
[[CPNotificationCenter defaultCenter] postNotification:note];
}
@@ -1059,9 +1177,57 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
[self _continuouslyReverseSetBinding];
if (_implementedDelegateMethods & CPTextFieldDelegate_controlTextDidChange_)
[_delegate controlTextDidChange:note];
[super textDidChange:note];
}
- (void)textDidBeginEditing:(CPNotification)note
{
//this looks to prevent false propagation of notifications for other objects
if ([note object] != self)
return;
if (_implementedDelegateMethods & CPTextFieldDelegate_controlTextDidBeginEditing_)
[_delegate controlTextDidBeginEditing:[[CPNotification alloc] initWithName:CPControlTextDidBeginEditingNotification object:self userInfo:@{"CPFieldEditor": [note object]}]]
[super textDidBeginEditing:note];
}
- (void)textDidEndEditing:(CPNotification)note
{
//this looks to prevent false propagation of notifications for other objects
if ([note object] != self)
return;
[super textDidEndEditing:note];
if (_implementedDelegateMethods & CPTextFieldDelegate_controlTextDidEndEditing_)
[_delegate controlTextDidEndEditing:note];
}
- (void)_updateCursorForEvent:(CPEvent)anEvent
{
var frame = CGRectMakeCopy([self frame]),
contentInset = [self currentValueForThemeAttribute:@"content-inset"];
frame = [[self superview] convertRectToBase:CGRectInsetByInset(frame, contentInset)];
if ([self isEnabled] && ([self isSelectable] || [self isEditable]) && CGRectContainsPoint(frame, [anEvent locationInWindow]))
{
#if PLATFORM(DOM)
self._DOMElement.style.cursor = "text";
#endif
}
else
{
#if PLATFORM(DOM)
self._DOMElement.style.cursor = "default";
#endif
}
}
/*!
Returns the string in the text field.
*/
@@ -1118,12 +1284,17 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
}
- (void)setObjectValue:(id)aValue
{
[self _setObjectValue:aValue useFormatter:YES];
}
- (void)_setObjectValue:(id)aValue useFormatter:(BOOL)useFormatter
{
[super setObjectValue:aValue];
var formatter = [self formatter];
if (formatter)
if (useFormatter && formatter)
{
// If there is a formatter, make sure the object value can be formatted successfully
var formattedString = [self hasThemeState:CPThemeStateEditing] ? [formatter editingStringForObjectValue:aValue] : [formatter stringForObjectValue:aValue];
@@ -1148,7 +1319,7 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
#if PLATFORM(DOM)
if (CPTextFieldInputOwner === self || [[self window] firstResponder] === self)
if ((CPTextFieldInputOwner === self || [[self window] firstResponder] === self) && [[self window] isKeyWindow])
[self _inputElement].value = _stringValue;
#endif
@@ -1158,7 +1329,7 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
- (void)_updatePlaceholderState
{
if ((!_stringValue || _stringValue.length === 0) && ![self hasThemeState:CPThemeStateEditing])
if (!_stringValue || _stringValue.length === 0)
[self setThemeState:CPTextFieldStatePlaceholder];
else
[self unsetThemeState:CPTextFieldStatePlaceholder];
@@ -1508,7 +1679,7 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
var selectedRange = [self selectedRange];
if (selectedRange.length < 1)
if (selectedRange.length === 0)
{
if (selectedRange.location < 1)
return;
@@ -1518,19 +1689,7 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
selectedRange.length += 1;
}
var newValue = [_stringValue stringByReplacingCharactersInRange:selectedRange withString:""];
[self setStringValue:newValue];
[self setSelectedRange:CPMakeRange(selectedRange.location, 0)];
[self _didEdit];
#if PLATFORM(DOM)
// Since we just performed the deletion manually, we don't need the browser to do anything else.
// (Previously we would allow the event to propagate for the browser to delete 1 character only,
// and we'd delete the rest manually. But this meant that if deleteBackward: was called without
// it being a browser backspace event, 1 character would be left behind.)
[[[self window] platformWindow] _propagateCurrentDOMEvent:NO];
#endif
[self _replaceCharactersInRange:selectedRange withCharacters:@""];
}
- (void)delete:(id)sender
@@ -1544,16 +1703,7 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
if (selectedRange.length < 1)
return;
var newValue = [_stringValue stringByReplacingCharactersInRange:selectedRange withString:""];
[self setStringValue:newValue];
[self setSelectedRange:CPMakeRange(selectedRange.location, 0)];
[self _didEdit];
#if PLATFORM(DOM)
// Since we just performed the deletion manually, we don't need the browser to do anything else.
[[[self window] platformWindow] _propagateCurrentDOMEvent:NO];
#endif
[self _replaceCharactersInRange:selectedRange withCharacters:@""];
}
- (void)deleteForward:(id)sender
@@ -1563,79 +1713,67 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
var selectedRange = [self selectedRange];
if (selectedRange.length < 1)
if (selectedRange.length === 0)
{
if (selectedRange.location + 1 >= _stringValue.length)
if (selectedRange.location >= _stringValue.length)
return;
// Delete a single element forward from the insertion point if there's no selection.
selectedRange.length += 1;
}
var newValue = [_stringValue stringByReplacingCharactersInRange:selectedRange withString:""];
[self _replaceCharactersInRange:selectedRange withCharacters:@""];
}
[self setStringValue:newValue];
[self setSelectedRange:CPMakeRange(selectedRange.location, 0)];
[self _didEdit];
- (void)_replaceCharactersInRange:(CPRange)range withCharacters:(CPString)characters
{
var newValue = [_stringValue stringByReplacingCharactersInRange:range withString:characters];
if (_invokedByUserEvent)
{
[self _setStringValue:newValue];
}
else
{
[self _setObjectValue:newValue useFormatter:NO];
[self setSelectedRange:CPMakeRange(range.location, 0)];
#if PLATFORM(DOM)
// Since we just performed the deletion manually, we don't need the browser to do anything else.
[[[self window] platformWindow] _propagateCurrentDOMEvent:NO];
// Since we just performed the deletion manually, we don't need the browser to do anything else.
[[[self window] platformWindow] _propagateCurrentDOMEvent:NO];
#endif
}
[self _didEdit];
}
#pragma mark Setting the Delegate
- (void)setDelegate:(id)aDelegate
- (void)setDelegate:(id <CPTextFieldDelegate>)aDelegate
{
var defaultCenter = [CPNotificationCenter defaultCenter];
//unsubscribe the existing delegate if it exists
if (_delegate)
{
[defaultCenter removeObserver:_delegate name:CPControlTextDidBeginEditingNotification object:self];
[defaultCenter removeObserver:_delegate name:CPControlTextDidChangeNotification object:self];
[defaultCenter removeObserver:_delegate name:CPControlTextDidEndEditingNotification object:self];
[defaultCenter removeObserver:_delegate name:CPTextFieldDidFocusNotification object:self];
[defaultCenter removeObserver:_delegate name:CPTextFieldDidBlurNotification object:self];
}
if (_delegate === aDelegate)
return;
_delegate = aDelegate;
_implementedDelegateMethods = 0;
if ([_delegate respondsToSelector:@selector(control:didFailToFormatString:errorDescription:)])
_implementedDelegateMethods |= CPTextFieldDelegate_control_didFailToFormatString_errorDescription_
if ([_delegate respondsToSelector:@selector(controlTextDidBeginEditing:)])
[defaultCenter
addObserver:_delegate
selector:@selector(controlTextDidBeginEditing:)
name:CPControlTextDidBeginEditingNotification
object:self];
_implementedDelegateMethods |= CPTextFieldDelegate_controlTextDidBeginEditing_;
if ([_delegate respondsToSelector:@selector(controlTextDidChange:)])
[defaultCenter
addObserver:_delegate
selector:@selector(controlTextDidChange:)
name:CPControlTextDidChangeNotification
object:self];
_implementedDelegateMethods |= CPTextFieldDelegate_controlTextDidChange_;
if ([_delegate respondsToSelector:@selector(controlTextDidEndEditing:)])
[defaultCenter
addObserver:_delegate
selector:@selector(controlTextDidEndEditing:)
name:CPControlTextDidEndEditingNotification
object:self];
_implementedDelegateMethods |= CPTextFieldDelegate_controlTextDidEndEditing_;
if ([_delegate respondsToSelector:@selector(controlTextDidFocus:)])
[defaultCenter
addObserver:_delegate
selector:@selector(controlTextDidFocus:)
name:CPTextFieldDidFocusNotification
object:self];
_implementedDelegateMethods |= CPTextFieldDelegate_controlTextDidFocus_;
if ([_delegate respondsToSelector:@selector(controlTextDidBlur:)])
[defaultCenter
addObserver:_delegate
selector:@selector(controlTextDidBlur:)
name:CPTextFieldDidBlurNotification
object:self];
_implementedDelegateMethods |= CPTextFieldDelegate_controlTextDidBlur_;
}
- (id)delegate
@@ -1705,7 +1843,7 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
if (contentView)
{
[contentView setHidden:[self hasThemeState:CPThemeStateEditing]];
[contentView setHidden:(_stringValue && _stringValue.length > 0) && [self hasThemeState:CPThemeStateEditing]];
var string = "";
@@ -1729,6 +1867,9 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
[contentView setTextShadowColor:[self currentValueForThemeAttribute:@"text-shadow-color"]];
[contentView setTextShadowOffset:[self currentValueForThemeAttribute:@"text-shadow-offset"]];
}
if (_isEditing)
[self _setCSSStyleForInputElement];
}
- (void)takeValueFromKeyPath:(CPString)aKeyPath ofObjects:(CPArray)objects
@@ -1749,6 +1890,20 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
#pragma mark Overrides
/*!
Sets the text color of the receiver.
@param aColor - A CPColor object.
*/
- (void)setTextColor:(CPColor)aColor
{
// We don't want to change the text-color of the placeHolder of the textField
var placeholderColor = [self valueForThemeAttribute:@"text-color" inState:CPTextFieldStatePlaceholder];
[super setTextColor:aColor];
[self setValue:placeholderColor forThemeAttribute:@"text-color" inState:CPTextFieldStatePlaceholder];
}
- (void)viewDidHide
{
[super viewDidHide];
@@ -1795,7 +1950,7 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
if (!wind)
return NO;
var frame = [self convertRectToBase:[self bounds]],
var frame = [self convertRectToBase:[self contentRectForBounds:[self bounds]]],
usableRect = [[wind platformWindow] usableContentFrame];
frame.origin = [wind convertBaseToGlobal:frame.origin];
@@ -1827,7 +1982,11 @@ var CPTextFieldIsEditableKey = "CPTextFieldIsEditableKey",
CPTextFieldLineBreakModeKey = "CPTextFieldLineBreakModeKey",
CPTextFieldAlignmentKey = "CPTextFieldAlignmentKey",
CPTextFieldBackgroundColorKey = "CPTextFieldBackgroundColorKey",
CPTextFieldPlaceholderStringKey = "CPTextFieldPlaceholderStringKey";
CPTextFieldPlaceholderStringKey = "CPTextFieldPlaceholderStringKey",
CPTextFieldUsesSingleLineMode = "CPTextFieldUsesSingleLineMode",
CPTextFieldWraps = "CPTextFieldWraps",
CPTextFieldScrolls = "CPTextFieldScrolls";
@implementation CPTextField (CPCoding)
@@ -1853,6 +2012,10 @@ var CPTextFieldIsEditableKey = "CPTextFieldIsEditableKey",
[self setAlignment:[aCoder decodeIntForKey:CPTextFieldAlignmentKey]];
[self setPlaceholderString:[aCoder decodeObjectForKey:CPTextFieldPlaceholderStringKey]];
[self _setUsesSingleLineMode:[aCoder decodeBoolForKey:CPTextFieldUsesSingleLineMode]];
[self _setWraps:[aCoder decodeBoolForKey:CPTextFieldWraps]];
[self _setScrolls:[aCoder decodeBoolForKey:CPTextFieldScrolls]];
}
return self;
@@ -1877,6 +2040,10 @@ var CPTextFieldIsEditableKey = "CPTextFieldIsEditableKey",
[aCoder encodeInt:[self alignment] forKey:CPTextFieldAlignmentKey];
[aCoder encodeObject:_placeholderString forKey:CPTextFieldPlaceholderStringKey];
[aCoder encodeBool:_usesSingleLineMode forKey:CPTextFieldUsesSingleLineMode];
[aCoder encodeBool:_wraps forKey:CPTextFieldWraps];
[aCoder encodeBool:_scrolls forKey:CPTextFieldScrolls];
}
@end
@@ -1907,6 +2074,23 @@ var CPTextFieldIsEditableKey = "CPTextFieldIsEditableKey",
[_source setObjectValue:aValue];
}
- (void)reverseSetValueFor:(CPString)aBinding
{
var destination = [_info objectForKey:CPObservedObjectKey],
keyPath = [_info objectForKey:CPObservedKeyPathKey],
options = [_info objectForKey:CPOptionsKey],
newValue = [self valueForBinding:aBinding],
value = [destination valueForKeyPath:keyPath];
if (CPIsControllerMarker(value) && newValue === nil) return;
newValue = [self reverseTransformValue:newValue withOptions:options];
[self suppressSpecificNotificationFromObject:destination keyPath:keyPath];
[destination setValue:newValue forKeyPath:keyPath];
[self unsuppressSpecificNotificationFromObject:destination keyPath:keyPath];
}
@end
@implementation _CPTextFieldPatternValueBinder : CPValueWithPatternBinding
+206 -151
View File
@@ -26,6 +26,7 @@
@import <Foundation/CPKeyedUnarchiver.j>
@class CPView
@class _CPThemeAttribute
var CPThemesByName = { },
CPThemeDefaultTheme = nil,
@@ -240,7 +241,7 @@ var CPThemesByName = { },
@param aClass The themed class in which to look for the attribute
@return A value or nil
*/
- (id)valueForAttributeWithName:(CPString)aName inState:(CPThemeState)aState forClass:(id)aClass
- (id)valueForAttributeWithName:(CPString)aName inState:(ThemeState)aState forClass:(id)aClass
{
var attribute = [self attributeWithName:aName forClass:aClass];
@@ -314,6 +315,164 @@ var CPThemeNameKey = @"CPThemeNameKey",
@end
/*!
* ThemeStates are immutable objects representing a particular ThemeState. Applications should never be creating
* ThemeStates directly but should instead use the CPThemeState function.
*/
function ThemeState(stateNames)
{
var stateNameKeys = [];
this._stateNames = {};
for (key in stateNames)
{
if (!stateNames.hasOwnProperty(key))
continue;
if (key !== 'normal')
{
this._stateNames[key] = true;
stateNameKeys.push(key);
}
}
if (stateNameKeys.length === 0)
{
stateNameKeys.push('normal');
this._stateNames['normal'] = true;
}
stateNameKeys.sort();
this._stateNameString = stateNameKeys[0];
var stateNameLength = stateNameKeys.length;
for (var stateIndex = 1; stateIndex < stateNameLength; stateIndex++)
this._stateNameString = this._stateNameString + "+" + stateNameKeys[stateIndex];
this._stateNameCount = stateNameLength;
}
ThemeState.prototype.toString = function()
{
return this._stateNameString;
}
ThemeState.prototype.hasThemeState = function(aState)
{
if (!aState || !aState._stateNames)
return false;
// We can do this in O(n) because both states have their stateNames already sorted.
for (var stateName in aState._stateNames)
{
if (!aState._stateNames.hasOwnProperty(stateName))
continue;
if (!this._stateNames[stateName])
return false;
}
return true;
}
ThemeState.prototype.isSubsetOf = function(aState)
{
if (aState._stateNameCount < this._stateNameCount)
return false;
for (var key in this._stateNames)
{
if (!this._stateNames.hasOwnProperty(key))
continue;
if (!aState._stateNames[key])
return false;
}
return true;
}
ThemeState.prototype.without = function(aState)
{
if (!aState || aState === [CPNull null])
return this;
var newStates = {};
for (var stateName in this._stateNames)
{
if (!this._stateNames.hasOwnProperty(stateName))
continue;
if (!aState._stateNames[stateName])
newStates[stateName] = true;
}
return ThemeState._cacheThemeState(new ThemeState(newStates));
}
ThemeState.prototype.and = function(aState)
{
return CPThemeState(this, aState);
}
var CPThemeStates = {};
ThemeState._cacheThemeState = function(aState)
{
// We do this caching so themeState equality works. Basically, doing CPThemeState('foo+bar') === CPThemeState('bar', 'foo') will return true.
var themeState = CPThemeStates[String(aState)];
if (themeState === undefined)
{
themeState = aState;
CPThemeStates[String(themeState)] = themeState;
}
return themeState;
}
/*!
* This method can be called in multiple ways:
* CPThemeState('state1') - creates a new CPThemeState that corresponds to the string 'state1'
* CPThemeState('state1', 'state2') - creates a new composite CPThemeState made up of both 'state1' or 'state2'
* CPThemeState('state1+state2') - The same as CPThemeState('state1', 'state2')
* CPThemeState(state1, state2) - creates a new composite CPThemeState made up of state1 and state2
* where state1 and state2 are not strings but are themselves CPThemeStates.
*/
function CPThemeState()
{
if (arguments.length < 1)
throw "CPThemeState() must be called with at least one string argument";
var themeState;
if (arguments.length === 1 && typeof arguments[0] === 'string')
{
themeState = CPThemeStates[arguments[0]];
if (themeState !== undefined)
return themeState;
}
var stateNames = {};
for (var argIndex = 0; argIndex < arguments.length; argIndex++)
{
if (arguments[argIndex] === [CPNull null] || !arguments[argIndex])
continue;
if (typeof arguments[argIndex] === 'object')
{
for (var stateName in arguments[argIndex]._stateNames)
{
if (!arguments[argIndex]._stateNames.hasOwnProperty(stateName))
continue;
stateNames[stateName] = true;
}
}
else
{
var allNames = arguments[argIndex].split('+');
for (var nameIndex = 0; nameIndex < allNames.length; nameIndex++)
stateNames[allNames[nameIndex]] = true;
}
}
themeState = ThemeState._cacheThemeState(new ThemeState(stateNames));
return themeState;
}
@implementation _CPThemeKeyedUnarchiver : CPKeyedUnarchiver
{
CPBundle _bundle;
@@ -341,88 +500,28 @@ var CPThemeNameKey = @"CPThemeNameKey",
@end
var CPThemeStates = {},
CPThemeStateNames = {},
CPThemeStateCount = 0;
function CPThemeState(aStateName)
{
var state = CPThemeStates[aStateName];
if (state === undefined)
{
if (aStateName.indexOf('+') === -1)
state = 1 << CPThemeStateCount++;
else
{
var state = 0,
states = aStateName.split('+'),
count = states.length;
while (count--)
{
var stateName = states[count],
individualState = CPThemeStates[stateName];
if (individualState === undefined)
{
individualState = 1 << CPThemeStateCount++;
CPThemeStates[stateName] = individualState;
CPThemeStateNames[individualState] = stateName;
}
state |= individualState;
}
}
CPThemeStates[aStateName] = state;
CPThemeStateNames[state] = aStateName;
}
return state;
}
function CPThemeStateName(aState)
{
var name = CPThemeStateNames[aState];
if (name !== undefined)
return name;
if (!(aState & (aState - 1)))
return "";
var state = 1,
name = "";
for (; state < aState; state <<= 1)
if (aState & state)
name += (name.length === 0 ? '' : '+') + CPThemeStateNames[state];
CPThemeStateNames[aState] = name;
return name;
}
CPThemeStateNames[0] = "normal";
CPThemeStateNormal = CPThemeStates["normal"] = 0;
CPThemeStateDisabled = CPThemeState("disabled");
CPThemeStateHovered = CPThemeState("hovered");
CPThemeStateHighlighted = CPThemeState("highlighted");
CPThemeStateSelected = CPThemeState("selected");
CPThemeStateTableDataView = CPThemeState("tableDataView");
CPThemeStateSelectedDataView = CPThemeState("selectedTableDataView");
CPThemeStateGroupRow = CPThemeState("CPThemeStateGroupRow");
CPThemeStateBezeled = CPThemeState("bezeled");
CPThemeStateBordered = CPThemeState("bordered");
CPThemeStateEditable = CPThemeState("editable");
CPThemeStateEditing = CPThemeState("editing");
CPThemeStateVertical = CPThemeState("vertical");
CPThemeStateDefault = CPThemeState("default");
CPThemeStateCircular = CPThemeState("circular");
CPThemeStateAutocompleting = CPThemeState("autocompleting");
CPThemeStateMainWindow = CPThemeState("mainWindow");
CPThemeStateKeyWindow = CPThemeState("keyWindow");
CPThemeStateNormal = CPThemeState("normal");
CPThemeStateDisabled = CPThemeState("disabled");
CPThemeStateHovered = CPThemeState("hovered");
CPThemeStateHighlighted = CPThemeState("highlighted");
CPThemeStateSelected = CPThemeState("selected");
CPThemeStateTableDataView = CPThemeState("tableDataView");
CPThemeStateSelectedDataView = CPThemeState("selectedTableDataView");
CPThemeStateGroupRow = CPThemeState("CPThemeStateGroupRow");
CPThemeStateBezeled = CPThemeState("bezeled");
CPThemeStateBordered = CPThemeState("bordered");
CPThemeStateEditable = CPThemeState("editable");
CPThemeStateEditing = CPThemeState("editing");
CPThemeStateVertical = CPThemeState("vertical");
CPThemeStateDefault = CPThemeState("default");
CPThemeStateCircular = CPThemeState("circular");
CPThemeStateAutocompleting = CPThemeState("autocompleting");
CPThemeStateFirstResponder = CPThemeState("firstResponder");
CPThemeStateMainWindow = CPThemeState("mainWindow");
CPThemeStateKeyWindow = CPThemeState("keyWindow");
CPThemeStateControlSizeRegular = CPThemeState("controlSizeRegular");
CPThemeStateControlSizeSmall = CPThemeState("controlSizeSmall");
CPThemeStateControlSizeMini = CPThemeState("controlSizeMini");
@implementation _CPThemeAttribute : CPObject
{
@@ -464,11 +563,6 @@ CPThemeStateKeyWindow = CPThemeState("keyWindow");
return [_values count] > 0;
}
- (BOOL)isTrivial
{
return ([_values count] === 1) && (Number([_values allKeys][0]) === CPThemeStateNormal);
}
- (void)setValue:(id)aValue
{
_cache = {};
@@ -479,7 +573,7 @@ CPThemeStateKeyWindow = CPThemeState("keyWindow");
_values = @{ String(CPThemeStateNormal): aValue };
}
- (void)setValue:(id)aValue forState:(CPThemeState)aState
- (void)setValue:(id)aValue forState:(ThemeState)aState
{
_cache = { };
@@ -494,44 +588,34 @@ CPThemeStateKeyWindow = CPThemeState("keyWindow");
return [self valueForState:CPThemeStateNormal];
}
- (id)valueForState:(CPThemeState)aState
- (id)valueForState:(ThemeState)aState
{
var value = _cache[aState];
var stateName = String(aState),
value = _cache[stateName];
// This can be nil.
if (value !== undefined)
return value;
value = [_values objectForKey:String(aState)];
value = [_values objectForKey:stateName];
// If we don't have a value, and we have a non-normal state...
if ((value === undefined || value === nil) && aState !== CPThemeStateNormal)
if (value === undefined || value === nil)
{
// If this is a composite state (not a power of 2), find the closest partial subset match.
if (aState & (aState - 1))
// If this is a composite state, find the closest partial subset match.
if (aState._stateNameCount > 1)
{
var highestOneCount = 0,
states = [_values allKeys],
count = states.length;
var states = [_values allKeys],
count = states.length,
largestThemeState = 0;
while (count--)
{
// states[count] is a string!
var state = Number(states[count]);
var stateObject = CPThemeState(states[count]);
// A & B = A iff A < B
if ((state & aState) === state)
if (stateObject.isSubsetOf(aState) && stateObject._stateNameCount > largestThemeState)
{
var oneCount = cachedNumberOfOnes[state];
if (oneCount === undefined)
oneCount = numberOfOnes(state);
if (oneCount > highestOneCount)
{
highestOneCount = oneCount;
value = [_values objectForKey:String(state)];
}
value = [_values objectForKey:states[count]];
largestThemeState = stateObject._stateNameCount;
}
}
}
@@ -554,7 +638,7 @@ CPThemeStateKeyWindow = CPThemeState("keyWindow");
value = nil;
}
_cache[aState] = value;
_cache[stateName] = value;
return value;
}
@@ -596,10 +680,10 @@ CPThemeStateKeyWindow = CPThemeState("keyWindow");
if ([aCoder containsValueForKey:@"value"])
{
var state = CPThemeStateNormal;
var state = String(CPThemeStateNormal);
if ([aCoder containsValueForKey:@"state"])
state = CPThemeState([aCoder decodeObjectForKey:@"state"]);
state = [aCoder decodeObjectForKey:@"state"];
[_values setObject:[aCoder decodeObjectForKey:"value"] forKey:state];
}
@@ -613,7 +697,7 @@ CPThemeStateKeyWindow = CPThemeState("keyWindow");
{
var key = keys[count];
[_values setObject:[encodedValues objectForKey:key] forKey:CPThemeState(key)];
[_values setObject:[encodedValues objectForKey:key] forKey:key];
}
}
}
@@ -633,8 +717,8 @@ CPThemeStateKeyWindow = CPThemeState("keyWindow");
{
var onlyKey = keys[0];
if (Number(onlyKey) !== CPThemeStateNormal)
[aCoder encodeObject:CPThemeStateName(Number(onlyKey)) forKey:@"state"];
if (onlyKey !== String(CPThemeStateNormal))
[aCoder encodeObject:onlyKey forKey:@"state"];
[aCoder encodeObject:[_values objectForKey:onlyKey] forKey:@"value"];
}
@@ -646,7 +730,7 @@ CPThemeStateKeyWindow = CPThemeState("keyWindow");
{
var key = keys[count];
[encodedValues setObject:[_values objectForKey:key] forKey:CPThemeStateName(Number(key))];
[encodedValues setObject:[_values objectForKey:key] forKey:key];
}
[aCoder encodeObject:encodedValues forKey:@"values"];
@@ -655,35 +739,6 @@ CPThemeStateKeyWindow = CPThemeState("keyWindow");
@end
var cachedNumberOfOnes = [ 0 /*000000*/, 1 /*000001*/, 1 /*000010*/, 2 /*000011*/, 1 /*000100*/, 2 /*000101*/, 2 /*000110*/,
3 /*000111*/, 1 /*001000*/, 2 /*001001*/, 2 /*001010*/, 3 /*001011*/, 2 /*001100*/, 3 /*001101*/,
3 /*001110*/, 4 /*001111*/, 1 /*010000*/, 2 /*010001*/, 2 /*010010*/, 3 /*010011*/, 2 /*010100*/,
3 /*010101*/, 3 /*010110*/, 4 /*010111*/, 2 /*011000*/, 3 /*011001*/, 3 /*011010*/, 4 /*011011*/,
3 /*011100*/, 4 /*011101*/, 4 /*011110*/, 5 /*011111*/, 1 /*100000*/, 2 /*100001*/, 2 /*100010*/,
3 /*100011*/, 2 /*100100*/, 3 /*100101*/, 3 /*100110*/, 4 /*100111*/, 2 /*101000*/, 3 /*101001*/,
3 /*101010*/, 4 /*101011*/, 3 /*101100*/, 4 /*101101*/, 4 /*101110*/, 5 /*101111*/, 2 /*110000*/,
3 /*110001*/, 3 /*110010*/, 4 /*110011*/, 3 /*110100*/, 4 /*110101*/, 4 /*110110*/, 5 /*110111*/,
3 /*111000*/, 4 /*111001*/, 4 /*111010*/, 5 /*111011*/, 4 /*111100*/, 5 /*111101*/, 5 /*111110*/,
6 /*111111*/ ];
var numberOfOnes = function(aNumber)
{
var count = 0,
slot = aNumber;
while (aNumber)
{
++count;
aNumber &= (aNumber - 1);
}
cachedNumberOfOnes[slot] = count;
return count;
};
numberOfOnes.displayName = "numberOfOnes";
function CPThemeAttributeEncode(aCoder, aThemeAttribute)
{
var values = aThemeAttribute._values,
@@ -694,7 +749,7 @@ function CPThemeAttributeEncode(aCoder, aThemeAttribute)
{
var state = [values allKeys][0];
if (Number(state) === 0)
if (state === String(CPThemeStateNormal))
{
[aCoder encodeObject:[values objectForKey:state] forKey:key];
@@ -723,7 +778,7 @@ function CPThemeAttributeDecode(aCoder, anAttributeName, aDefaultValue, aTheme,
{
var attribute = [aCoder decodeObjectForKey:key];
if (!attribute.isa || ![attribute isKindOfClass:[_CPThemeAttribute class]])
if (!attribute || !attribute.isa || ![attribute isKindOfClass:[_CPThemeAttribute class]])
{
var themeAttribute = [[_CPThemeAttribute alloc] initWithName:anAttributeName defaultValue:aDefaultValue];
+107 -38
View File
@@ -33,10 +33,35 @@
@import "CPTextField.j"
@import "CPWindow_Constants.j"
@class _CPTokenFieldTokenCloseButton
@class _CPTokenFieldTokenDisclosureButton
@global CPApp
@global CPTextFieldDidFocusNotification
@global CPTextFieldDidBlurNotification
// TODO: should be conform to protocol CPTextFieldDelegate
@protocol CPTokenFieldDelegate <CPObject>
@optional
- (BOOL)tokenField:(CPTokenField)tokenField hasMenuForRepresentedObject:(id)representedObject;
- (CPArray)tokenField:(CPTokenField)tokenField completionsForSubstring:(CPString)substring indexOfToken:(CPInteger)tokenIndex indexOfSelectedItem:(CPInteger)selectedIndex;
- (CPArray)tokenField:(CPTokenField)tokenField shouldAddObjects:(CPArray)tokens atIndex:(CPUInteger)index;
- (CPMenu)tokenField:(CPTokenField)tokenField menuForRepresentedObject:(id)representedObject;
- (CPString )tokenField:(CPTokenField)tokenField displayStringForRepresentedObject:(id)representedObject;
- (id)tokenField:(CPTokenField)tokenField representedObjectForEditingString:(CPString)editingString;
@end
var CPTokenFieldDelegate_tokenField_hasMenuForRepresentedObject_ = 1 << 1,
CPTokenFieldDelegate_tokenField_completionsForSubstring_indexOfToken_indexOfSelectedItem_ = 1 << 2,
CPTokenFieldDelegate_tokenField_shouldAddObjects_atIndex_ = 1 << 3,
CPTokenFieldDelegate_tokenField_menuForRepresentedObject_ = 1 << 4,
CPTokenFieldDelegate_tokenField_displayStringForRepresentedObject_ = 1 << 5,
CPTokenFieldDelegate_tokenField_representedObjectForEditingString_ = 1 << 6;
#if PLATFORM(DOM)
var CPTokenFieldDOMInputElement = nil,
@@ -64,23 +89,26 @@ CPTokenFieldDeleteButtonType = 1;
@implementation CPTokenField : CPTextField
{
CPScrollView _tokenScrollView;
int _shouldScrollTo;
CPScrollView _tokenScrollView;
int _shouldScrollTo;
CPRange _selectedRange;
CPRange _selectedRange;
_CPAutocompleteMenu _autocompleteMenu;
CGRect _inputFrame;
_CPAutocompleteMenu _autocompleteMenu;
CGRect _inputFrame;
CPTimeInterval _completionDelay;
CPTimeInterval _completionDelay;
CPCharacterSet _tokenizingCharacterSet @accessors(property=tokenizingCharacterSet);
CPCharacterSet _tokenizingCharacterSet @accessors(property=tokenizingCharacterSet);
CPEvent _mouseDownEvent;
CPEvent _mouseDownEvent;
BOOL _shouldNotifyTarget;
BOOL _shouldNotifyTarget;
int _buttonType @accessors(property=buttonType);
int _buttonType @accessors(property=buttonType);
id <CPTokenFieldDelegate> _tokenFieldDelegate;
unsigned _implementedTokenFieldDelegateMethods;
}
+ (CPCharacterSet)defaultTokenizingCharacterSet
@@ -140,6 +168,41 @@ CPTokenFieldDeleteButtonType = 1;
[self addSubview:_tokenScrollView];
}
#pragma mark -
#pragma mark Delegate methods
/*!
Set the delegate of the receiver
*/
- (void)setDelegate:(id <CPTokenFieldDelegate>)aDelegate
{
if (_tokenFieldDelegate === aDelegate)
return;
_tokenFieldDelegate = aDelegate;
_implementedTokenFieldDelegateMethods = 0;
if ([_tokenFieldDelegate respondsToSelector:@selector(tokenField:hasMenuForRepresentedObject:)])
_implementedTokenFieldDelegateMethods |= CPTokenFieldDelegate_tokenField_hasMenuForRepresentedObject_;
if ([_tokenFieldDelegate respondsToSelector:@selector(tokenField:completionsForSubstring:indexOfToken:indexOfSelectedItem:)])
_implementedTokenFieldDelegateMethods |= CPTokenFieldDelegate_tokenField_completionsForSubstring_indexOfToken_indexOfSelectedItem_;
if ([_tokenFieldDelegate respondsToSelector:@selector(tokenField:shouldAddObjects:atIndex:)])
_implementedTokenFieldDelegateMethods |= CPTokenFieldDelegate_tokenField_shouldAddObjects_atIndex_;
if ([_tokenFieldDelegate respondsToSelector:@selector(tokenField:menuForRepresentedObject:)])
_implementedTokenFieldDelegateMethods |= CPTokenFieldDelegate_tokenField_menuForRepresentedObject_;
if ([_tokenFieldDelegate respondsToSelector:@selector(tokenField:displayStringForRepresentedObject:)])
_implementedTokenFieldDelegateMethods |= CPTokenFieldDelegate_tokenField_displayStringForRepresentedObject_;
if ([_tokenFieldDelegate respondsToSelector:@selector(tokenField:representedObjectForEditingString:)])
_implementedTokenFieldDelegateMethods |= CPTokenFieldDelegate_tokenField_representedObjectForEditingString_;
[super setDelegate:_tokenFieldDelegate];
}
- (_CPAutocompleteMenu)_autocompleteMenu
{
if (!_autocompleteMenu)
@@ -321,6 +384,9 @@ CPTokenFieldDeleteButtonType = 1;
- (BOOL)becomeFirstResponder
{
if (![super becomeFirstResponder])
return NO;
#if PLATFORM(DOM)
if (CPTokenFieldInputOwner && [CPTokenFieldInputOwner window] !== [self window])
[[CPTokenFieldInputOwner window] makeFirstResponder:nil];
@@ -1185,12 +1251,10 @@ CPTokenFieldDeleteButtonType = 1;
*/
- (CPArray)_completionsForSubstring:(CPString)substring indexOfToken:(int)tokenIndex indexOfSelectedItem:(int)selectedIndex
{
if ([[self delegate] respondsToSelector:@selector(tokenField:completionsForSubstring:indexOfToken:indexOfSelectedItem:)])
{
return [[self delegate] tokenField:self completionsForSubstring:substring indexOfToken:tokenIndex indexOfSelectedItem:selectedIndex];
}
if (!(_implementedTokenFieldDelegateMethods & CPTokenFieldDelegate_tokenField_completionsForSubstring_indexOfToken_indexOfSelectedItem_))
return [];
return [];
return [_tokenFieldDelegate tokenField:self completionsForSubstring:substring indexOfToken:tokenIndex indexOfSelectedItem:selectedIndex];
}
/*!
@@ -1199,6 +1263,7 @@ CPTokenFieldDeleteButtonType = 1;
- (CGPoint)_completionOrigin:(_CPAutocompleteMenu)anAutocompleteMenu
{
var relativeFrame = _inputFrame ? [[_tokenScrollView documentView] convertRect:_inputFrame toView:self ] : [self bounds];
return CGPointMake(CGRectGetMinX(relativeFrame), CGRectGetMaxY(relativeFrame));
}
@@ -1212,13 +1277,12 @@ CPTokenFieldDeleteButtonType = 1;
*/
- (CPString)_displayStringForRepresentedObject:(id)representedObject
{
if ([[self delegate] respondsToSelector:@selector(tokenField:displayStringForRepresentedObject:)])
if (_implementedTokenFieldDelegateMethods & CPTokenFieldDelegate_tokenField_displayStringForRepresentedObject_)
{
var stringForRepresentedObject = [[self delegate] tokenField:self displayStringForRepresentedObject:representedObject];
var stringForRepresentedObject = [_tokenFieldDelegate tokenField:self displayStringForRepresentedObject:representedObject];
if (stringForRepresentedObject !== nil)
{
return stringForRepresentedObject;
}
}
return representedObject;
@@ -1235,10 +1299,10 @@ CPTokenFieldDeleteButtonType = 1;
*/
- (CPArray)_shouldAddObjects:(CPArray)tokens atIndex:(int)index
{
var delegate = [self delegate];
if ([delegate respondsToSelector:@selector(tokenField:shouldAddObjects:atIndex:)])
if (_implementedTokenFieldDelegateMethods & CPTokenFieldDelegate_tokenField_shouldAddObjects_atIndex_)
{
var approvedObjects = [delegate tokenField:self shouldAddObjects:tokens atIndex:index];
var approvedObjects = [_tokenFieldDelegate tokenField:self shouldAddObjects:tokens atIndex:index];
if (approvedObjects !== nil)
return approvedObjects;
}
@@ -1257,10 +1321,10 @@ CPTokenFieldDeleteButtonType = 1;
*/
- (id)_representedObjectForEditingString:(CPString)aString
{
var delegate = [self delegate];
if ([delegate respondsToSelector:@selector(tokenField:representedObjectForEditingString:)])
if (_implementedTokenFieldDelegateMethods & CPTokenFieldDelegate_tokenField_representedObjectForEditingString_)
{
var token = [delegate tokenField:self representedObjectForEditingString:aString];
var token = [_tokenFieldDelegate tokenField:self representedObjectForEditingString:aString];
if (token !== nil && token !== undefined)
return token;
// If nil was returned, assume the string is the represented object. The alternative would have been
@@ -1272,23 +1336,22 @@ CPTokenFieldDeleteButtonType = 1;
- (BOOL)_hasMenuForRepresentedObject:(id)aRepresentedObject
{
var delegate = [self delegate];
if ([delegate respondsToSelector:@selector(tokenField:hasMenuForRepresentedObject:)] &&
[delegate respondsToSelector:@selector(tokenField:menuForRepresentedObject:)])
return [delegate tokenField:self hasMenuForRepresentedObject:aRepresentedObject];
if ((_implementedTokenFieldDelegateMethods & CPTokenFieldDelegate_tokenField_hasMenuForRepresentedObject_) &&
(_implementedTokenFieldDelegateMethods & CPTokenFieldDelegate_tokenField_menuForRepresentedObject_))
return [_tokenFieldDelegate tokenField:self hasMenuForRepresentedObject:aRepresentedObject];
return NO;
}
- (CPMenu)_menuForRepresentedObject:(id)aRepresentedObject
{
var delegate = [self delegate];
if ([delegate respondsToSelector:@selector(tokenField:hasMenuForRepresentedObject:)] &&
[delegate respondsToSelector:@selector(tokenField:menuForRepresentedObject:)])
if ((_implementedTokenFieldDelegateMethods & CPTokenFieldDelegate_tokenField_hasMenuForRepresentedObject_) &&
(_implementedTokenFieldDelegateMethods & CPTokenFieldDelegate_tokenField_menuForRepresentedObject_))
{
var hasMenu = [delegate tokenField:self hasMenuForRepresentedObject:aRepresentedObject];
var hasMenu = [_tokenFieldDelegate tokenField:self hasMenuForRepresentedObject:aRepresentedObject];
if (hasMenu)
return [delegate tokenField:self menuForRepresentedObject:aRepresentedObject] || nil;
return [_tokenFieldDelegate tokenField:self menuForRepresentedObject:aRepresentedObject] || nil;
}
return nil;
@@ -1389,12 +1452,15 @@ CPTokenFieldDeleteButtonType = 1;
[self setNeedsLayout];
}
- (BOOL)setThemeState:(CPThemeState)aState
- (BOOL)setThemeState:(ThemeState)aState
{
if (aState.isa && [aState isKindOfClass:CPArray])
aState = CPThemeState.apply(null, aState);
var r = [super setThemeState:aState];
// Share hover state with the disclosure and delete buttons.
if (aState & CPThemeStateHovered)
if (aState.hasThemeState(CPThemeStateHovered))
{
[_disclosureButton setThemeState:CPThemeStateHovered];
[_deleteButton setThemeState:CPThemeStateHovered];
@@ -1403,12 +1469,15 @@ CPTokenFieldDeleteButtonType = 1;
return r;
}
- (BOOL)unsetThemeState:(CPThemeState)aState
- (BOOL)unsetThemeState:(ThemeState)aState
{
if (aState.isa && [aState isKindOfClass:CPArray])
aState = CPThemeState.apply(null, aState);
var r = [super unsetThemeState:aState];
// Share hover state with the disclosure and delete button.
if (aState & CPThemeStateHovered)
if (aState.hasThemeState(CPThemeStateHovered))
{
[_disclosureButton unsetThemeState:CPThemeStateHovered];
[_deleteButton unsetThemeState:CPThemeStateHovered];
+141 -11
View File
@@ -30,6 +30,15 @@
@global CPApp
var CPToolbarDelegate_toolbar_itemForItemIdentifier_willBeInsertedIntoToolbar_ = 1 << 0,
CPToolbarDelegate_toolbarAllowedItemIdentifiers_ = 1 << 1,
CPToolbarDelegate_toolbarDefaultItemIdentifiers_ = 1 << 2,
CPToolbarDelegate_toolbarDidRemoveItem_ = 1 << 3,
CPToolbarDelegate_toolbarSelectableItemIdentifiers_ = 1 << 4,
CPToolbarDelegate_toolbarWillAddItem_ = 1 << 5;
@typedef CPToolbarDisplayMode
/*
@global
@group CPToolbarDisplayMode
@@ -51,7 +60,7 @@ CPToolbarDisplayModeIconOnly = 2;
*/
CPToolbarDisplayModeLabelOnly = 3;
@typedef CPToolbarSizeMode
CPToolbarSizeModeDefault = 0;
CPToolbarSizeModeRegular = 1;
CPToolbarSizeModeSmall = 2;
@@ -59,6 +68,20 @@ CPToolbarSizeModeSmall = 2;
var CPToolbarsByIdentifier = nil,
CPToolbarConfigurationsByIdentifier = nil;
@protocol CPToolbarDelegate <CPObject>
@optional
- (CPToolbarItem)toolbar:(CPToolbar)toolbar itemForItemIdentifier:(CPString)itemIdentifier willBeInsertedIntoToolbar:(BOOL)flag;
- (CPArray)toolbarAllowedItemIdentifiers:(CPToolbar)toolbar;
- (CPArray)toolbarDefaultItemIdentifiers:(CPToolbar)toolbar;
- (void)toolbarDidRemoveItem:(CPNotification)notification;
- (CPArray)toolbarSelectableItemIdentifiers:(CPToolbar)toolbar;
- (void)toolbarWillAddItem:(CPNotification)notification;
@end
/*!
@ingroup appkit
@class CPToolbar
@@ -89,14 +112,15 @@ var CPToolbarsByIdentifier = nil,
@implementation CPToolbar : CPObject
{
CPString _identifier;
CPToolbarDisplayMode _displayMode @accessors(property=displayMode);
CPToolbarDisplayMode _displayMode @accessors(property=displayMode);
BOOL _showsBaselineSeparator;
BOOL _allowsUserCustomization;
BOOL _isVisible;
CPToolbarSizeMode _sizeMode @accessors(property=sizeMode);
CPToolbarSizeMode _sizeMode @accessors(property=sizeMode);
int _desiredHeight;
id _delegate;
id <CPToolbarDelegate> _delegate;
unsigned _implementedDelegateMethods;
CPArray _itemIdentifiers;
@@ -239,6 +263,25 @@ var CPToolbarsByIdentifier = nil,
return;
_delegate = aDelegate;
_implementedDelegateMethods = 0;
if ([_delegate respondsToSelector:@selector(toolbar:itemForItemIdentifier:willBeInsertedIntoToolbar:)])
_implementedDelegateMethods |= CPToolbarDelegate_toolbar_itemForItemIdentifier_willBeInsertedIntoToolbar_;
if ([_delegate respondsToSelector:@selector(toolbarAllowedItemIdentifiers:)])
_implementedDelegateMethods |= CPToolbarDelegate_toolbarAllowedItemIdentifiers_;
if ([_delegate respondsToSelector:@selector(toolbarDefaultItemIdentifiers:)])
_implementedDelegateMethods |= CPToolbarDelegate_toolbarDefaultItemIdentifiers_;
if ([_delegate respondsToSelector:@selector(toolbarDidRemoveItem:)])
_implementedDelegateMethods |= CPToolbarDelegate_toolbarDidRemoveItem_;
if ([_delegate respondsToSelector:@selector(toolbarSelectableItemIdentifiers:)])
_implementedDelegateMethods |= CPToolbarDelegate_toolbarSelectableItemIdentifiers_;
if ([_delegate respondsToSelector:@selector(toolbarWillAddItem:)])
_implementedDelegateMethods |= CPToolbarDelegate_toolbarWillAddItem_;
[self _reloadToolbarItems];
}
@@ -289,9 +332,9 @@ var CPToolbarsByIdentifier = nil,
// _defaultItems may have been loaded from Cib
_itemIdentifiers = [_defaultItems valueForKey:@"itemIdentifier"] || [];
if ([_delegate respondsToSelector:@selector(toolbarDefaultItemIdentifiers:)])
if ([self _delegateRespondsToToolbarDefaultItemIdentifiers])
{
var itemIdentifiersFromDelegate = [_delegate toolbarDefaultItemIdentifiers:self];
var itemIdentifiersFromDelegate = [self _sendDelegateToolbarDefaultItemIdentifiers];
// If we get items both from the Cib and from the delegate method, put the delegate items before the
// Cib ones.
@@ -316,7 +359,7 @@ var CPToolbarsByIdentifier = nil,
item = [_identifiedItems objectForKey:identifier];
if (!item && _delegate)
item = [_delegate toolbar:self itemForItemIdentifier:identifier willBeInsertedIntoToolbar:YES];
item = [self _sendDelegateItemForItemIdentifier:identifier willBeInsertedIntoToolbar:YES];
item = [item copy];
@@ -394,12 +437,14 @@ var CPToolbarsByIdentifier = nil,
- (id)_itemForItemIdentifier:(CPString)identifier willBeInsertedIntoToolbar:(BOOL)toolbar
{
var item = [_identifiedItems objectForKey:identifier];
if (!item)
{
item = [CPToolbarItem _standardItemWithItemIdentifier:identifier];
if (_delegate && !item)
{
item = [[_delegate toolbar:self itemForItemIdentifier:identifier willBeInsertedIntoToolbar:toolbar] copy];
item = [[self _sendDelegateItemForItemIdentifier:identifier willBeInsertedIntoToolbar:toolbar] copy];
if (!item)
[CPException raise:CPInvalidArgumentException
reason:@"Toolbar delegate " + _delegate + " returned nil toolbar item for identifier " + identifier];
@@ -424,11 +469,11 @@ var CPToolbarsByIdentifier = nil,
/* @ignore */
- (id)_defaultToolbarItems
{
if (!_defaultItems && [_delegate respondsToSelector:@selector(toolbarDefaultItemIdentifiers:)])
if (!_defaultItems && [self _delegateRespondsToToolbarDefaultItemIdentifiers])
{
_defaultItems = [];
var identifiers = [_delegate toolbarDefaultItemIdentifiers:self],
var identifiers = [self _sendDelegateToolbarDefaultItemIdentifiers],
index = 0,
count = [identifiers count];
@@ -800,7 +845,6 @@ var _CPToolbarItemInfoMake = function(anIndex, aView, aLabel, aMinWidth)
var index = 0,
count = _visibleItems.length,
x = contentInset.left,
contentInset = [self valueForThemeAttribute:@"content-inset"],
y = contentInset.top;
for (; index < count; ++index)
@@ -1240,3 +1284,89 @@ var LABEL_MARGIN = 2.0;
}
@end
@implementation CPToolbar (CPToolbarDelegate)
/*
@ignore
Return YES if the delegate implements toolbarDefaultItemIdentifiers:
*/
- (BOOL)_delegateRespondsToToolbarDefaultItemIdentifiers
{
return _implementedDelegateMethods & CPToolbarDelegate_toolbarDefaultItemIdentifiers_;
}
/*!
@ignore
Call the delegate toolbar:itemForItemIdentifier:willBeInsertedIntoToolbar:
*/
- (CPToolbarItem)_sendDelegateItemForItemIdentifier:(CPString)itemIdentifier willBeInsertedIntoToolbar:(BOOL)flag
{
if (!(_implementedDelegateMethods & CPToolbarDelegate_toolbar_itemForItemIdentifier_willBeInsertedIntoToolbar_))
return nil;
return [_delegate toolbar:self itemForItemIdentifier:itemIdentifier willBeInsertedIntoToolbar:flag];
}
/*!
@ignore
Call the delegate toolbarAllowedItemIdentifiers:
*/
- (CPArray)_sendDelegateToolbarAllowedItemIdentifiers
{
if (!(_implementedDelegateMethods & CPToolbarDelegate_toolbarAllowedItemIdentifiers_))
return [];
return [_delegate toolbarAllowedItemIdentifiers:self];
}
/*!
@ignore
Call the delegate toolbarDefaultItemIdentifiers:
*/
- (CPArray)_sendDelegateToolbarDefaultItemIdentifiers
{
if (!(_implementedDelegateMethods & CPToolbarDelegate_toolbarDefaultItemIdentifiers_))
return [];
return [_delegate toolbarDefaultItemIdentifiers:self];
}
/*!
@ignore
Call the delegate toolbarDidRemoveItem:
*/
- (void)_sendDelegateToolbarDidRemoveItem:(CPNotification)notification
{
if (!(_delegate & CPToolbarDelegate_toolbarDidRemoveItem_))
return;
[_delegate toolbarDidRemoveItem:notification];
}
/*!
@ignore
Call the delegate toolbarSelectableItemIdentifiers:
*/
- (CPArray)_sendDelegateToolbarSelectableItemIdentifiers
{
if (!(_implementedDelegateMethods & CPToolbarDelegate_toolbarSelectableItemIdentifiers_))
return [];
return [_delegate toolbarSelectableItemIdentifiers:self];
}
/*!
@ignore
Call the delegate toolbarWillAddItem:
*/
- (void)_sendDelegateToolbarWillAddItem:(CPNotification)notification
{
if (!(_delegate & CPToolbarDelegate_toolbarWillAddItem_))
return;
[_delegate toolbarWillAddItem:notification];
}
@end
+225 -42
View File
@@ -40,9 +40,12 @@
@class CPMenu
@class CPClipView
@class CPScrollView
@class CALayer
@global appkit_tag_dom_elements
@typedef _CPViewFullScreenModeState
#if PLATFORM(DOM)
if (typeof(appkit_tag_dom_elements) !== "undefined" && appkit_tag_dom_elements)
@@ -172,6 +175,7 @@ var CPViewFlags = { },
BOOL _postsBoundsChangedNotifications;
BOOL _inhibitFrameAndBoundsChangedNotifications;
BOOL _inLiveResize;
BOOL _isSuperviewAClipView;
#if PLATFORM(DOM)
DOMElement _DOMElement;
@@ -228,6 +232,8 @@ var CPViewFlags = { },
Function _toolTipFunctionIn;
Function _toolTipFunctionOut;
BOOL _toolTipInstalled;
BOOL _isObserving;
}
/*
@@ -343,6 +349,9 @@ var CPViewFlags = { },
_scaleSize = CGSizeMake(1.0, 1.0);
_isScaled = NO;
_theme = [CPTheme defaultTheme];
_themeState = CPThemeStateNormal;
#if PLATFORM(DOM)
_DOMElement = DOMElementPrototype.cloneNode(false);
AppKitTagDOMElement(self, _DOMElement);
@@ -354,9 +363,6 @@ var CPViewFlags = { },
_DOMImageSizes = [];
#endif
_theme = [CPTheme defaultTheme];
_themeState = CPThemeStateNormal;
[self _setupToolTipHandlers];
[self _setupViewFlags];
@@ -508,8 +514,12 @@ var CPViewFlags = { },
[CPException raise:CPInvalidArgumentException reason:"can't insert a subview in duplicate (probably partially decoded)"];
#endif
// Notify the subview that it will be moving.
[aSubview viewWillMoveToSuperview:self];
// We will have to adjust the z-index of all views starting at this index.
var count = _subviews.length;
var count = _subviews.length,
lastWindow;
// Dirty the key view loop, in case the window wants to auto recalculate it
[[self window] _dirtyKeyViewLoop];
@@ -537,14 +547,12 @@ var CPViewFlags = { },
}
else
{
var superview = aSubview._superview;
lastWindow = [superview window];
// Remove the view from its previous superview.
[aSubview removeFromSuperview];
// Set the subview's window to our own.
[aSubview _setWindow:_window];
// Notify the subview that it will be moving.
[aSubview viewWillMoveToSuperview:self];
[aSubview _removeFromSuperview];
// Set ourselves as the superview.
aSubview._superview = self;
@@ -579,6 +587,28 @@ var CPViewFlags = { },
[aSubview viewDidMoveToSuperview];
// Set the subview's window to our own.
if (_window)
[aSubview _setWindow:_window];
if (!_window && lastWindow)
[aSubview _setWindow:nil];
// This method might be called before we are fully unarchived, in which case the theme state isn't set up yet
// and none of the below matters anyhow.
if (_themeState)
{
if ([self hasThemeState:CPThemeStateFirstResponder])
[aSubview _notifyViewDidBecomeFirstResponder];
else
[aSubview _notifyViewDidResignFirstResponder];
if ([self hasThemeState:CPThemeStateKeyWindow])
[aSubview _notifyWindowDidBecomeKey];
else
[aSubview _notifyWindowDidResignKey];
}
[self didAddSubview:aSubview];
}
@@ -595,6 +625,18 @@ var CPViewFlags = { },
Does nothing if there's no container view.
*/
- (void)removeFromSuperview
{
var superview = _superview;
[self viewWillMoveToSuperview:nil];
[self _removeFromSuperview];
[self viewDidMoveToSuperview];
if (superview)
[self _setWindow:nil];
}
- (void)_removeFromSuperview
{
if (!_superview)
return;
@@ -615,9 +657,10 @@ var CPViewFlags = { },
if (!_isHidden && [_superview isHiddenOrHasHiddenAncestor])
[self _notifyViewDidUnhide];
_superview = nil;
[self _notifyWindowDidResignKey];
[self _notifyViewDidResignFirstResponder];
[self _setWindow:nil];
_superview = nil;
}
/*!
@@ -627,14 +670,14 @@ var CPViewFlags = { },
*/
- (void)replaceSubview:(CPView)aSubview with:(CPView)aView
{
if (aSubview._superview !== self)
if (aSubview._superview !== self || aSubview === aView)
return;
var index = [_subviews indexOfObjectIdenticalTo:aSubview];
[aSubview removeFromSuperview];
[self _insertSubview:aView atIndex:index];
[aSubview removeFromSuperview];
}
- (void)setSubviews:(CPArray)newSubviews
@@ -709,13 +752,10 @@ var CPViewFlags = { },
/* @ignore */
- (void)_setWindow:(CPWindow)aWindow
{
if (_window === aWindow)
return;
[[self window] _dirtyKeyViewLoop];
// Clear out first responder if we're the first responder and leaving.
if ([_window firstResponder] === self)
if ([_window firstResponder] === self && _window != aWindow)
[_window makeFirstResponder:nil];
// Notify the view and its subviews
@@ -736,6 +776,11 @@ var CPViewFlags = { },
while (count--)
[_subviews[count] _setWindow:aWindow];
if ([_window isKeyWindow])
[self setThemeState:CPThemeStateKeyWindow];
else
[self unsetThemeState:CPThemeStateKeyWindow];
[self viewDidMoveToWindow];
[[self window] _dirtyKeyViewLoop];
@@ -780,6 +825,12 @@ var CPViewFlags = { },
*/
- (void)viewWillMoveToSuperview:(CPView)aView
{
_isSuperviewAClipView = [aView isKindOfClass:[CPClipView class]];
[self _removeObservers];
if (aView)
[self _addObservers];
}
/*!
@@ -798,6 +849,32 @@ var CPViewFlags = { },
{
}
- (void)_removeObservers
{
if (!_isObserving)
return;
var count = [_subviews count];
while (count--)
[_subviews[count] _removeObservers];
_isObserving = NO;
}
- (void)_addObservers
{
if (_isObserving)
return;
var count = [_subviews count];
while (count--)
[_subviews[count] _addObservers];
_isObserving = YES;
}
/*!
Returns the menu item containing the receiver or one of its ancestor views.
@return a menu item, or \c nil if the view or one of its ancestors wasn't found
@@ -881,6 +958,9 @@ var CPViewFlags = { },
if (_postsFrameChangedNotifications)
[CachedNotificationCenter postNotificationName:CPViewFrameDidChangeNotification object:self];
if (_isSuperviewAClipView)
[[self superview] viewFrameChanged:[[CPNotification alloc] initWithName:CPViewFrameDidChangeNotification object:self userInfo:nil]];
}
/*!
@@ -943,6 +1023,9 @@ var CPViewFlags = { },
if (_postsFrameChangedNotifications && !_inhibitFrameAndBoundsChangedNotifications)
[CachedNotificationCenter postNotificationName:CPViewFrameDidChangeNotification object:self];
if (_isSuperviewAClipView && !_inhibitFrameAndBoundsChangedNotifications)
[[self superview] viewFrameChanged:[[CPNotification alloc] initWithName:CPViewFrameDidChangeNotification object:self userInfo:nil]];
#if PLATFORM(DOM)
var transform = _superview ? _superview._boundsTransform : NULL;
@@ -1001,7 +1084,8 @@ var CPViewFlags = { },
else
{
var images = [[_backgroundColor patternImage] imageSlices],
partIndex = 0;
partIndex = 0,
frameSize = aSize;
if (_backgroundType === BackgroundVerticalThreePartImage)
{
@@ -1011,16 +1095,21 @@ var CPViewFlags = { },
// Make sure to repeat the top and bottom pieces horizontally if they're not the exact width needed.
if (top)
{
CPDOMDisplayServerSetStyleBackgroundSize(_DOMImageParts[partIndex], frameSize.width + "px", top + "px");
CPDOMDisplayServerSetStyleSize(_DOMImageParts[partIndex], size.width, top);
partIndex++;
}
if (_DOMImageSizes[1])
{
var height = frameSize.height - top - bottom;
CPDOMDisplayServerSetStyleBackgroundSize(_DOMImageParts[partIndex], frameSize.width + "px", height + "px");
CPDOMDisplayServerSetStyleSize(_DOMImageParts[partIndex], size.width, size.height - top - bottom);
partIndex++;
}
if (bottom)
{
CPDOMDisplayServerSetStyleBackgroundSize(_DOMImageParts[partIndex], frameSize.width + "px", bottom + "px");
CPDOMDisplayServerSetStyleSize(_DOMImageParts[partIndex], size.width, bottom);
}
}
@@ -1032,16 +1121,21 @@ var CPViewFlags = { },
// Make sure to repeat the left and right pieces vertically if they're not the exact height needed.
if (left)
{
CPDOMDisplayServerSetStyleBackgroundSize(_DOMImageParts[partIndex], left + "px", frameSize.height + "px");
CPDOMDisplayServerSetStyleSize(_DOMImageParts[partIndex], left, size.height);
partIndex++;
}
if (_DOMImageSizes[1])
{
var width = (frameSize.width - left - right);
CPDOMDisplayServerSetStyleBackgroundSize(_DOMImageParts[partIndex], width + "px", frameSize.height + "px");
CPDOMDisplayServerSetStyleSize(_DOMImageParts[partIndex], size.width - left - right, size.height);
partIndex++;
}
if (right)
{
CPDOMDisplayServerSetStyleBackgroundSize(_DOMImageParts[partIndex], right + "px", frameSize.height + "px");
CPDOMDisplayServerSetStyleSize(_DOMImageParts[partIndex], right, size.height);
}
}
@@ -1091,6 +1185,9 @@ var CPViewFlags = { },
if (_postsFrameChangedNotifications && !_inhibitFrameAndBoundsChangedNotifications)
[CachedNotificationCenter postNotificationName:CPViewFrameDidChangeNotification object:self];
if (_isSuperviewAClipView && !_inhibitFrameAndBoundsChangedNotifications)
[[self superview] viewFrameChanged:[[CPNotification alloc] initWithName:CPViewFrameDidChangeNotification object:self userInfo:nil]];
}
/*!
@@ -1125,6 +1222,9 @@ var CPViewFlags = { },
if (_postsBoundsChangedNotifications)
[CachedNotificationCenter postNotificationName:CPViewBoundsDidChangeNotification object:self];
if (_isSuperviewAClipView)
[[self superview] viewBoundsChanged:[[CPNotification alloc] initWithName:CPViewBoundsDidChangeNotification object:self userInfo:nil]];
}
/*!
@@ -1187,6 +1287,9 @@ var CPViewFlags = { },
if (_postsBoundsChangedNotifications && !_inhibitFrameAndBoundsChangedNotifications)
[CachedNotificationCenter postNotificationName:CPViewBoundsDidChangeNotification object:self];
if (_isSuperviewAClipView && !_inhibitFrameAndBoundsChangedNotifications)
[[self superview] viewBoundsChanged:[[CPNotification alloc] initWithName:CPViewBoundsDidChangeNotification object:self userInfo:nil]];
}
/*!
@@ -1225,6 +1328,9 @@ var CPViewFlags = { },
if (_postsBoundsChangedNotifications && !_inhibitFrameAndBoundsChangedNotifications)
[CachedNotificationCenter postNotificationName:CPViewBoundsDidChangeNotification object:self];
if (_isSuperviewAClipView && !_inhibitFrameAndBoundsChangedNotifications)
[[self superview] viewBoundsChanged:[[CPNotification alloc] initWithName:CPViewBoundsDidChangeNotification object:self userInfo:nil]];
}
@@ -1782,6 +1888,9 @@ var CPViewFlags = { },
_DOMElement.style.background = "";
_DOMImageParts[0].style.background = [_backgroundColor cssString];
if (patternImage)
CPDOMDisplayServerSetStyleBackgroundSize(_DOMImageParts[0], [patternImage size].width + "px", [patternImage size].height + "px");
if (CPFeatureIsCompatible(CPOpacityRequiresFilterFeature))
_DOMImageParts[0].style.filter = "alpha(opacity=" + [_backgroundColor alphaComponent] * 100 + ")";
else
@@ -1792,6 +1901,9 @@ var CPViewFlags = { },
}
else
_DOMElement.style.background = colorCSS;
if (patternImage)
CPDOMDisplayServerSetStyleBackgroundSize(_DOMElement, [patternImage size].width + "px", [patternImage size].height + "px");
}
else
{
@@ -1896,18 +2008,24 @@ var CPViewFlags = { },
// Make sure to repeat the top and bottom pieces horizontally if they're not the exact width needed.
if (top)
{
CPDOMDisplayServerSetStyleBackgroundSize(_DOMImageParts[partIndex], frameSize.width + "px", top + "px");
CPDOMDisplayServerSetStyleLeftTop(_DOMImageParts[partIndex], NULL, 0.0, 0.0);
CPDOMDisplayServerSetStyleSize(_DOMImageParts[partIndex], frameSize.width, top);
partIndex++;
}
if (_DOMImageSizes[1])
{
var height = frameSize.height - top - bottom;
//_DOMImageParts[partIndex].style.backgroundSize = frameSize.width + "px " + height + "px";
CPDOMDisplayServerSetStyleBackgroundSize(_DOMImageParts[partIndex], frameSize.width + "px", height + "px");
CPDOMDisplayServerSetStyleLeftTop(_DOMImageParts[partIndex], NULL, 0.0, top);
CPDOMDisplayServerSetStyleSize(_DOMImageParts[partIndex], frameSize.width, frameSize.height - top - bottom);
CPDOMDisplayServerSetStyleSize(_DOMImageParts[partIndex], frameSize.width, height);
partIndex++;
}
if (bottom)
{
CPDOMDisplayServerSetStyleBackgroundSize(_DOMImageParts[partIndex], frameSize.width + "px", bottom + "px");
CPDOMDisplayServerSetStyleLeftBottom(_DOMImageParts[partIndex], NULL, 0.0, 0.0);
CPDOMDisplayServerSetStyleSize(_DOMImageParts[partIndex], frameSize.width, bottom);
}
@@ -1922,18 +2040,23 @@ var CPViewFlags = { },
// Make sure to repeat the left and right pieces vertically if they're not the exact height needed.
if (left)
{
CPDOMDisplayServerSetStyleBackgroundSize(_DOMImageParts[partIndex], left + "px", frameSize.height + "px");
CPDOMDisplayServerSetStyleLeftTop(_DOMImageParts[partIndex], NULL, 0.0, 0.0);
CPDOMDisplayServerSetStyleSize(_DOMImageParts[partIndex], left, frameSize.height);
partIndex++;
}
if (_DOMImageSizes[1])
{
var width = (frameSize.width - left - right);
CPDOMDisplayServerSetStyleBackgroundSize(_DOMImageParts[partIndex], width + "px", frameSize.height + "px");
CPDOMDisplayServerSetStyleLeftTop(_DOMImageParts[partIndex], NULL, left, 0.0);
CPDOMDisplayServerSetStyleSize(_DOMImageParts[partIndex], frameSize.width - left - right, frameSize.height);
CPDOMDisplayServerSetStyleSize(_DOMImageParts[partIndex], width, frameSize.height);
partIndex++;
}
if (right)
{
CPDOMDisplayServerSetStyleBackgroundSize(_DOMImageParts[partIndex], right + "px", frameSize.height + "px");
CPDOMDisplayServerSetStyleRightTop(_DOMImageParts[partIndex], NULL, 0.0, 0.0);
CPDOMDisplayServerSetStyleSize(_DOMImageParts[partIndex], right, frameSize.height);
}
@@ -2518,7 +2641,7 @@ setBoundsOrigin:
/*!
Scrolls the nearest ancestor CPClipView a minimum amount so \c aRect can become visible.
@param aRect the area to become visible
@return <codeYES if any scrolling occurred, \c NO otherwise.
@return \c YES if any scrolling occurred, \c NO otherwise.
*/
- (BOOL)scrollRectToVisible:(CGRect)aRect
{
@@ -2887,23 +3010,23 @@ setBoundsOrigin:
return _themeState;
}
- (BOOL)hasThemeState:(CPThemeState)aState
- (BOOL)hasThemeState:(ThemeState)aState
{
// Because CPThemeStateNormal is defined as 0 we need to check for it explicitly here
if (aState === CPThemeStateNormal && _themeState === CPThemeStateNormal)
return YES;
if (aState.isa && [aState isKindOfClass:CPArray])
return _themeState.hasThemeState.apply(_themeState, aState);
return !!(_themeState & ((typeof aState === "string") ? CPThemeState(aState) : aState));
return _themeState.hasThemeState(aState);
}
- (BOOL)setThemeState:(CPThemeState)aState
- (BOOL)setThemeState:(ThemeState)aState
{
var newState = (typeof aState === "string") ? CPThemeState(aState) : aState;
if (aState && aState.isa && [aState isKindOfClass:CPArray])
aState = CPThemeState.apply(null, aState);
if (_themeState & newState)
if (_themeState.hasThemeState(aState))
return NO;
_themeState |= newState;
_themeState = CPThemeState(_themeState, aState);
[self setNeedsLayout];
[self setNeedsDisplay:YES];
@@ -2911,21 +3034,75 @@ setBoundsOrigin:
return YES;
}
- (BOOL)unsetThemeState:(CPThemeState)aState
- (BOOL)unsetThemeState:(ThemeState)aState
{
var newState = ((typeof aState === "string") ? CPThemeState(aState) : aState);
if (aState && aState.isa && [aState isKindOfClass:CPArray])
aState = CPThemeState.apply(null, aState);
if (!(_themeState & newState))
var oldThemeState = _themeState;
_themeState = _themeState.without(aState);
if (oldThemeState === _themeState)
return NO;
_themeState &= ~newState;
[self setNeedsLayout];
[self setNeedsDisplay:YES];
return YES;
}
- (BOOL)becomeFirstResponder
{
var r = [super becomeFirstResponder];
if (r)
[self _notifyViewDidBecomeFirstResponder];
return r;
}
- (void)_notifyViewDidBecomeFirstResponder
{
[self setThemeState:CPThemeStateFirstResponder];
var count = [_subviews count];
while (count--)
[_subviews[count] _notifyViewDidBecomeFirstResponder];
}
- (BOOL)resignFirstResponder
{
var r = [super resignFirstResponder];
if (r)
[self _notifyViewDidResignFirstResponder];
return r;
}
- (void)_notifyViewDidResignFirstResponder
{
[self unsetThemeState:CPThemeStateFirstResponder];
var count = [_subviews count];
while (count--)
[_subviews[count] _notifyViewDidResignFirstResponder];
}
- (void)_notifyWindowDidBecomeKey
{
[self setThemeState:CPThemeStateKeyWindow];
var count = [_subviews count];
while (count--)
[_subviews[count] _notifyWindowDidBecomeKey];
}
- (void)_notifyWindowDidResignKey
{
[self unsetThemeState:CPThemeStateKeyWindow];
var count = [_subviews count];
while (count--)
[_subviews[count] _notifyWindowDidResignKey];
}
#pragma mark Theme Attributes
+ (CPString)defaultThemeClass
@@ -3077,8 +3254,11 @@ setBoundsOrigin:
return dictionary;
}
- (void)setValue:(id)aValue forThemeAttribute:(CPString)aName inState:(CPThemeState)aState
- (void)setValue:(id)aValue forThemeAttribute:(CPString)aName inState:(ThemeState)aState
{
if (aState.isa && [aState isKindOfClass:CPArray])
aState = CPThemeState.apply(null, aState);
if (!_themeAttributes || !_themeAttributes[aName])
[CPException raise:CPInvalidArgumentException reason:[self className] + " does not contain theme attribute '" + aName + "'"];
@@ -3109,8 +3289,11 @@ setBoundsOrigin:
[self setNeedsLayout];
}
- (id)valueForThemeAttribute:(CPString)aName inState:(CPThemeState)aState
- (id)valueForThemeAttribute:(CPString)aName inState:(ThemeState)aState
{
if (aState.isa && [aState isKindOfClass:CPArray])
aState = CPThemeState.apply(null, aState);
if (!_themeAttributes || !_themeAttributes[aName])
[CPException raise:CPInvalidArgumentException reason:[self className] + " does not contain theme attribute '" + aName + "'"];
@@ -3361,7 +3544,7 @@ var CPViewAutoresizingMaskKey = @"CPViewAutoresizingMask",
_theme = [CPTheme defaultTheme];
_themeClass = [aCoder decodeObjectForKey:CPViewThemeClassKey];
_themeState = CPThemeState([aCoder decodeIntForKey:CPViewThemeStateKey]);
_themeState = CPThemeState([aCoder decodeObjectForKey:CPViewThemeStateKey]);
_themeAttributes = {};
var theClass = [self class],
@@ -3452,7 +3635,7 @@ var CPViewAutoresizingMaskKey = @"CPViewAutoresizingMask",
[aCoder encodeConditionalObject:previousKeyView forKey:CPViewPreviousKeyViewKey];
[aCoder encodeObject:[self themeClass] forKey:CPViewThemeClassKey];
[aCoder encodeInt:CPThemeStateName(_themeState) forKey:CPViewThemeStateKey];
[aCoder encodeObject:String(_themeState) forKey:CPViewThemeStateKey];
for (var attributeName in _themeAttributes)
if (_themeAttributes.hasOwnProperty(attributeName))
+1
View File
@@ -210,6 +210,7 @@ var CPViewControllerCachedCibs;
[cibOwner viewControllerDidLoadCib:self];
_isLoading = NO;
_isLazy = NO;
[self _viewDidLoad];
}
else if (_isLazy)
+4 -1
View File
@@ -23,6 +23,9 @@
@import "CPView.j"
@import "CPScrollView.j"
@class CPWebScriptObject
@typedef Window
// FIXME: implement these where possible:
/*
@@ -93,7 +96,7 @@ CPWebViewAppKitScrollMaxPollCount = 3;
CPScrollView _scrollView;
CPView _frameView;
IFrame _iframe;
DOMElement _iframe;
CPString _mainFrameURL;
CPArray _backwardStack;
CPArray _forwardStack;
+190 -38
View File
@@ -50,9 +50,36 @@
@class CPMenu
@class CPProgressIndicator
@class CPToolbar
@class CPWindowController
@class _CPWindowFrameAnimation
@global CPApp
@typedef _CPWindowFullPlatformWindowSession
@protocol CPWindowDelegate <CPObject>
@optional
- (BOOL)windowShouldClose:(CPWindow)aWindow;
- (CPUndoManager)windowWillReturnUndoManager:(CPWindow)window;
- (void)windowDidBecomeKey:(CPNotification)aNotification;
- (void)windowDidBecomeMain:(CPNotification)aNotification;
- (void)windowDidEndSheet:(CPNotification)aNotification;
- (void)windowDidMove:(CPNotification)aNotification;
- (void)windowDidResignKey:(CPNotification)aNotification;
- (void)windowDidResignMain:(CPNotification)aNotification;
- (void)windowDidResize:(CPNotification)aNotification;
- (void)windowWillBeginSheet:(CPNotification)aNotification;
- (void)windowWillClose:(CPWindow)aWindow;
@end
var CPWindowDelegate_windowShouldClose_ = 1 << 1
CPWindowDelegate_windowWillReturnUndoManager_ = 1 << 2,
CPWindowDelegate_windowWillClose_ = 1 << 3;
var CPWindowSaveImage = nil,
CPWindowResizeTime = 0.2,
@@ -171,7 +198,8 @@ var CPWindowActionMessageKeys = [
CPResponder _firstResponder;
CPResponder _initialFirstResponder;
BOOL _hasBecomeKeyWindow;
id _delegate;
id <CPWindowDelegate> _delegate;
unsigned _implementedDelegateMethods;
CPString _title;
@@ -205,8 +233,6 @@ var CPWindowActionMessageKeys = [
unsigned _autoresizingMask;
BOOL _delegateRespondsToWindowWillReturnUndoManagerSelector;
BOOL _isFullPlatformWindow;
_CPWindowFullPlatformWindowSession _fullPlatformWindowSession;
@@ -881,16 +907,21 @@ CPTexturedBackgroundWindowMask
- (void)_orderFront
{
#if PLATFORM(DOM)
// -dw- if a sheet is clicked, the parent window should come up too
if (_isSheet)
[_parentView orderFront:self];
if (!_isVisible)
[self _setFrame:_frame display:YES animate:NO constrainWidth:YES constrainHeight:YES];
// Save the boolean since it will be updated in the method order:window:relativeTo:
var wasVisible = _isVisible;
[_platformWindow orderFront:self];
[_platformWindow order:CPWindowAbove window:self relativeTo:nil];
// setFrame is set after ordering the window as this method can send some notifications
if (!wasVisible)
[self _setFrame:_frame display:YES animate:NO constrainWidth:YES constrainHeight:YES];
#endif
if (!CPApp._keyWindow)
@@ -911,6 +942,23 @@ CPTexturedBackgroundWindowMask
{
}
/*
Called when the window is displayed in the DOM
*/
- (void)_windowWillBeAddedToTheDOM
{
[[self contentView] _addObservers];
}
/*
Called when the window is removed in the DOM
*/
- (void)_windowWillBeRemovedFromTheDOM
{
[[self contentView] _removeObservers];
}
/*
Makes the receiver the last window in the screen ordering.
@param aSender the object that requested this
@@ -957,6 +1005,7 @@ CPTexturedBackgroundWindowMask
[_platformWindow order:CPWindowOut window:self relativeTo:nil];
#endif
[self makeFirstResponder:nil];
[self _updateMainAndKeyWindows];
}
@@ -1110,7 +1159,7 @@ CPTexturedBackgroundWindowMask
*/
- (void)setContentView:(CPView)aView
{
if (_contentView)
if (_contentView && _contentView !== aView)
[_contentView removeFromSuperview];
var bounds = CGRectMake(0.0, 0.0, CGRectGetWidth(_frame), CGRectGetHeight(_frame));
@@ -1343,8 +1392,11 @@ CPTexturedBackgroundWindowMask
Sets the delegate for the window. Passing \c nil will just remove the window's current delegate.
@param aDelegate an object to respond to the various delegate methods of CPWindow
*/
- (void)setDelegate:(id)aDelegate
- (void)setDelegate:(id <CPWindowDelegate>)aDelegate
{
if (_delegate === aDelegate)
return;
var defaultCenter = [CPNotificationCenter defaultCenter];
[defaultCenter removeObserver:_delegate name:CPWindowDidResignKeyNotification object:self];
@@ -1357,7 +1409,16 @@ CPTexturedBackgroundWindowMask
[defaultCenter removeObserver:_delegate name:CPWindowDidEndSheetNotification object:self];
_delegate = aDelegate;
_delegateRespondsToWindowWillReturnUndoManagerSelector = [_delegate respondsToSelector:@selector(windowWillReturnUndoManager:)];
_implementedDelegateMethods = 0;
if ([_delegate respondsToSelector:@selector(windowShouldClose:)])
_implementedDelegateMethods |= CPWindowDelegate_windowShouldClose_;
if ([_delegate respondsToSelector:@selector(windowWillReturnUndoManager:)])
_implementedDelegateMethods |= CPWindowDelegate_windowWillReturnUndoManager_;
if ([_delegate respondsToSelector:@selector(windowWillClose:)])
_implementedDelegateMethods |= CPWindowDelegate_windowWillClose_;
if ([_delegate respondsToSelector:@selector(windowDidResignKey:)])
[defaultCenter
@@ -1759,10 +1820,14 @@ CPTexturedBackgroundWindowMask
// even that we just moved it to a new first responder.
[[[anEvent window] platformWindow] _propagateCurrentDOMEvent:NO]
#endif
}
}
return didTabBack;
}
else if ([anEvent charactersIgnoringModifiers] == CPEscapeFunctionKey && [self _processKeyboardUIKey:anEvent])
{
return;
}
[[self firstResponder] keyDown:anEvent];
@@ -1805,6 +1870,12 @@ CPTexturedBackgroundWindowMask
if (_leftMouseDownView !== _firstResponder && [_leftMouseDownView acceptsFirstResponder])
[self makeFirstResponder:_leftMouseDownView];
var keyWindow = [CPApp keyWindow];
// This is only when we move from a platform to another one
if ([keyWindow platformWindow] != [self platformWindow])
[self makeKeyAndOrderFront:self];
[CPApp activateIgnoringOtherApps:YES];
var theWindow = [anEvent window],
@@ -1932,6 +2003,7 @@ CPTexturedBackgroundWindowMask
_hasBecomeKeyWindow = YES;
[_windowView noteKeyWindowStateChanged];
[_contentView _notifyWindowDidBecomeKey];
[[CPNotificationCenter defaultCenter]
postNotificationName:CPWindowDidBecomeKeyNotification
@@ -2000,6 +2072,7 @@ CPTexturedBackgroundWindowMask
CPApp._keyWindow = nil;
[_windowView noteKeyWindowStateChanged];
[_contentView _notifyWindowDidResignKey];
[[CPNotificationCenter defaultCenter]
postNotificationName:CPWindowDidResignKeyNotification
@@ -2243,9 +2316,9 @@ CPTexturedBackgroundWindowMask
// The Cocoa docs say that if both the delegate and the window implement
// windowShouldClose:, only the delegate receives the message.
if ([_delegate respondsToSelector:@selector(windowShouldClose:)])
if ([self _delegateRespondsToWindowShouldClose])
{
if (![_delegate windowShouldClose:self])
if (![self _sendDelegateWindowShouldClose])
return;
}
else if ([self respondsToSelector:@selector(windowShouldClose:)])
@@ -2301,8 +2374,7 @@ CPTexturedBackgroundWindowMask
*/
- (void)close
{
if ([_delegate respondsToSelector:@selector(windowWillClose:)])
[_delegate windowWillClose:self];
[self _sendDelegateWindowWillClose];
[[CPNotificationCenter defaultCenter] postNotificationName:CPWindowWillCloseNotification object:self];
@@ -2435,7 +2507,7 @@ CPTexturedBackgroundWindowMask
if (currentWindow === self || currentWindow === menuWindow)
continue;
if ([currentWindow isVisible] && [currentWindow canBecomeKeyWindow])
if ([currentWindow isVisible] && [currentWindow canBecomeKeyWindow] && [currentWindow platformWindow] == [keyWindow platformWindow])
{
[currentWindow makeKeyWindow];
break;
@@ -2637,6 +2709,23 @@ CPTexturedBackgroundWindowMask
[attachedSheet setFrame:sheetFrame display:YES animate:NO];
}
- (void)_previousSheetIsClosedNotification:(CPNotification)aNotification
{
[[CPNotificationCenter defaultCenter] removeObserver:self name:CPWindowDidEndSheetNotification object:self];
var sheet = _sheetContext[@"nextSheet"],
modalDelegate =_sheetContext[@"nextModalDelegate"],
endSelector = _sheetContext[@"nextEndSelector"],
contextInfo = _sheetContext[@"nextContextInfo"];
// Needed, because when the notification CPWindowDidEndSheetNotification is sent, the sheetContext is not up to date...
setTimeout(function()
{
[sheet._windowView _enableSheet:YES inWindow:self];
[self _attachSheet:sheet modalDelegate:modalDelegate didEndSelector:endSelector contextInfo:contextInfo];
}, 0)
}
/*
Starting point for sheet session, called from CPApplication beginSheet:
*/
@@ -2645,9 +2734,24 @@ CPTexturedBackgroundWindowMask
{
if (_sheetContext)
{
[CPException raise:CPInternalInconsistencyException
reason:@"The target window of beginSheet: already has a sheet, did you forget orderOut: ?"];
return;
// Here we wait till the current sheet is closed
if (_sheetContext[@"isClosing"])
{
// Here we save the next sheet to open
_sheetContext[@"nextSheet"] = aSheet;
_sheetContext[@"nextModalDelegate"] = aModalDelegate;
_sheetContext[@"nextEndSelector"] = didEndSelector;
_sheetContext[@"nextContextInfo"] = contextInfo;
[[CPNotificationCenter defaultCenter] addObserver:self selector:@selector(_previousSheetIsClosedNotification:) name:CPWindowDidEndSheetNotification object:self];
return;
}
else
{
[CPException raise:CPInternalInconsistencyException
reason:@"The target window of beginSheet: already has a sheet, did you forget orderOut: ?"];
return;
}
}
_sheetContext = {
@@ -2699,7 +2803,12 @@ CPTexturedBackgroundWindowMask
*/
- (void)_detachSheetWindow
{
if (_sheetContext["isClosing"])
return;
_sheetContext["isAttached"] = NO;
_sheetContext["isClosing"] = YES;
_sheetContext["opened"] = NO;
// A timer seems to be necessary for the animation to work correctly.
// It would be ideal to block here and spin the event loop, until attach is complete.
@@ -2832,12 +2941,6 @@ CPTexturedBackgroundWindowMask
return;
}
if (_sheetContext["isClosing"])
return;
_sheetContext["opened"] = NO;
_sheetContext["isClosing"] = YES;
// The parent window can be orderedOut to disable the sheet animate out, as in Cocoa
if ([self isVisible])
{
@@ -2984,20 +3087,9 @@ CPTexturedBackgroundWindowMask
if ([selectors count] <= 0)
return NO;
if (character !== CPEscapeFunctionKey)
{
var selector = [selectors objectAtIndex:0];
return [[self firstResponder] tryToPerform:selector with:self];
}
else
{
/*
Cocoa sends complete: for the escape key (instead of the default cancelOperation:). This is also the only action that is not sent directly to the first responder, but through doCommandBySelector. The difference is that doCommandBySelector: will also send the action to the window and application delegates.
*/
[[self firstResponder] doCommandBySelector:@selector(complete:)];
}
var selector = [selectors objectAtIndex:0];
return NO;
return [[self firstResponder] tryToPerform:selector with:self];
}
- (void)_dirtyKeyViewLoop
@@ -3294,6 +3386,66 @@ var keyViewComparator = function(lhs, rhs, context)
return CPOrderedDescending;
};
@implementation CPWindow (CPWindowDelegate)
/*!
@ignore
Check if the delegate implements windowWillReturnUndoManager:
*/
- (BOOL)_delegateRespondsToWindowWillUndoManager
{
return _implementedDelegateMethods & CPWindowDelegate_windowWillReturnUndoManager_;
}
/*!
@ignore
Check if the delegate implements windowShouldClose
*/
- (BOOL)_delegateRespondsToWindowShouldClose
{
return _implementedDelegateMethods & CPWindowDelegate_windowShouldClose_
}
/*!
@ignore
Call delegate windowShouldClose:
*/
- (BOOL)_sendDelegateWindowShouldClose
{
if (!(_implementedDelegateMethods & CPWindowDelegate_windowShouldClose_))
return YES;
return [_delegate windowShouldClose:self];
}
/*!
@ignore
Call delegate windowWillReturnUndoManager:
*/
- (BOOL)_sendDelegateWindowWillReturnUndoManager
{
if (!(_implementedDelegateMethods & CPWindowDelegate_windowWillReturnUndoManager_))
return nil;
return [_delegate windowWillReturnUndoManager:self];
}
/*!
@ignore
Call delegate windowWillClose:
*/
- (void)_sendDelegateWindowWillClose
{
if (!(_implementedDelegateMethods & CPWindowDelegate_windowWillClose_))
return;
[_delegate windowWillClose:self];
}
@end
@implementation CPWindow (BridgeSupport)
/*
@@ -3431,8 +3583,8 @@ var keyViewComparator = function(lhs, rhs, context)
return documentUndoManager;
// If not, check to see if the delegate has one.
if (_delegateRespondsToWindowWillReturnUndoManagerSelector)
return [_delegate windowWillReturnUndoManager:self];
if ([self _delegateRespondsToWindowWillUndoManager])
return [self _sendDelegateWindowWillReturnUndoManager];
// If not, create one.
if (!_undoManager)
+2
View File
@@ -81,6 +81,7 @@ CPWindowMinYMargin = 8;
CPWindowHeightSizable = 16;
CPWindowMaxYMargin = 32;
@typedef CPWindowLevel
CPBackgroundWindowLevel = -1;
/*
Default level for windows
@@ -143,6 +144,7 @@ CPDraggingWindowLevel = 500;
*/
CPScreenSaverWindowLevel = 1000;
@typedef CPWindowOrderingMode
/*
The receiver is placed directly in front of the window specified.
@global
+1
View File
@@ -25,6 +25,7 @@
@import "CPCib.j"
@import "CPResponder.j"
@import "CPViewController.j"
@import "CPWindow.j"
@class CPDocument
+2 -2
View File
@@ -51,7 +51,7 @@
// Not being able to set the action is a fatal error.
if ([_source respondsToSelector:@selector(setAction:)])
objj_msgSend(_source, @selector(setAction:), selector);
[_source setAction:selector];
else
[CPException
@@ -60,7 +60,7 @@
// Not being able to set the target is a fatal error.
if ([_source respondsToSelector:@selector(setTarget:)])
objj_msgSend(_source, @selector(setTarget:), _destination);
[_source setTarget:_destination];
else
[CPException
+4
View File
@@ -498,6 +498,7 @@ var CALayerRegisteredRunLoopUpdates = nil;
{
_context = CGBitmapGraphicsContextCreate();
#if PLATFORM(DOM)
_DOMContentsElement = _context.DOMElement;
_DOMContentsElement.style.zIndex = -100;
@@ -515,6 +516,7 @@ var CALayerRegisteredRunLoopUpdates = nil;
_DOMContentsElement.style.height = ROUND(CGRectGetHeight(_backingStoreFrame)) + "px";
_DOMElement.appendChild(_DOMContentsElement);
#endif
}
if (USE_BUFFER)
@@ -1036,6 +1038,7 @@ function _CALayerUpdateSublayerTransformForSublayers(aLayer)
function _CALayerUpdateDOM(aLayer, aMask)
{
#if PLATFORM(DOM)
var DOMElementStyle = aLayer._DOMElement.style;
if (aMask & CALayerZPositionUpdateMask)
@@ -1066,6 +1069,7 @@ function _CALayerUpdateDOM(aLayer, aMask)
DOMContentsElement.style.height = height + "px";
}
}
#endif
}
function _CALayerRecalculateGeometry(aLayer, aGeometryChange)
+2
View File
@@ -22,6 +22,8 @@
@import "CGGeometry.j"
@typedef CGAffineTransform
function CGAffineTransformMake(a, b, c, d, tx, ty)
{
+2
View File
@@ -20,6 +20,8 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@typedef CGColorSpace
kCGColorSpaceModelUnknown = -1;
kCGColorSpaceModelMonochrome = 0;
kCGColorSpaceModelRGB = 1;
+2 -1
View File
@@ -25,6 +25,7 @@
@import "CGGeometry.j"
@import "CGPath.j"
@typedef CGContext
kCGLineCapButt = 0;
kCGLineCapRound = 1;
@@ -737,7 +738,7 @@ else if (CPFeatureIsCompatible(CPVMLFeature))
else
{
// I have declared these functions here to make it compile without warnings with the new compiler under rhino.
CGContextClearRect = CGContextDrawLinearGradient = CGContextClip = CGContextClipToRect = function() {throw new Error("function is not declared in this environment")}
CGContextClearRect = CGContextDrawLinearGradient = CGContextClip = CGContextClipToRect = CGContextDrawImage = function() {throw new Error("function is not declared in this environment")}
}
/*!
@endcond
+1
View File
@@ -23,6 +23,7 @@
@import "CGColor.j"
@import "CGColorSpace.j"
@typedef CGGradient
kCGGradientDrawsBeforeStartLocation = 1 << 0;
kCGGradientDrawsAfterEndLocation = 1 << 1;
+2 -1
View File
@@ -23,6 +23,7 @@
@import "CGAffineTransform.j"
@import "CGGeometry.j"
@typedef CGPath
kCGPathElementMoveToPoint = 0;
kCGPathElementAddLineToPoint = 1;
@@ -629,4 +630,4 @@ function CGPathContainsPoint(aPath, aTransform, point, eoFill)
/*!
@}
*/
*/
+3
View File
@@ -27,9 +27,12 @@
@class CPMenu
@class CPPlatformPasteboard
@class CPWindow
@global CPApp
@typedef DOMWindow
var PrimaryPlatformWindow = NULL;
@implementation CPPlatformWindow : CPObject
+6
View File
@@ -80,6 +80,9 @@ aDOMElement.style.bottom = ROUND(____p.y) + "px";
aDOMElement.width = MAX(0.0, ROUND(aWidth));\
aDOMElement.height = MAX(0.0, ROUND(aHeight));
#define CPDOMDisplayServerSetStyleBackgroundSize(aDOMElement, aWidth, aHeight)\
aDOMElement.style.backgroundSize = aWidth + ' ' + aHeight;
#define CPDOMDisplayServerAppendChild(aParentElement, aChildElement) aParentElement.appendChild(aChildElement)
#define CPDOMDisplayServerInsertBefore(aParentElement, aChildElement, aBeforeElement) aParentElement.insertBefore(aChildElement, aBeforeElement)
@@ -126,6 +129,9 @@ aDOMElement.style.bottom = ROUND(____p.y) + "px";
CPDOMDisplayServerInstructions[__index + 2] = aWidth;\
CPDOMDisplayServerInstructions[__index + 3] = aHeight;
#define CPDOMDisplayServerSetStyleBackgroundSize(aDOMElement, aWidth, aHeight)\
aDOMElement.style.backgroundSize = aWidth + ' ' + aHeight;
#define CPDOMDisplayServerAppendChild(aParentElement, aChildElement)\
if (aChildElement.CPDOMDisplayContext) aChildElement.CPDOMDisplayContext[SetStyleOrigin] = -1;\
CPDOMDisplayServerInstructions[CPDOMDisplayServerInstructionCount++] = AppendChild;\
+1 -4
View File
@@ -71,7 +71,6 @@ var hasEditableTarget = function(aDOMEvent)
BOOL hasBugWhichPreventsNonEditablePaste;
BOOL hasBugWhichPreventsNonEditablePasteRedirect;
CPEvent _lastKeyDownEvent;
BOOL currentEventIsNativePasteEvent;
BOOL currentEventIsNativeCopyOrCutEvent;
BOOL currentEventShouldBeSuppressed;
@@ -208,8 +207,6 @@ var hasEditableTarget = function(aDOMEvent)
if (!(modifierFlags & (CPControlKeyMask | CPCommandKeyMask)))
return;
_lastKeyDownEvent = anEvent;
var aDOMEvent = anEvent._DOMEvent,
characters = [anEvent characters],
mayRequireDOMPasteboardElement = [self _mayRequireDOMPasteboardElementHack:aDOMEvent flags:modifierFlags];
@@ -302,7 +299,7 @@ var hasEditableTarget = function(aDOMEvent)
timestamp = [CPEvent currentTimestamp], // fake event, might as well use current timestamp
windowNumber = [[CPApp keyWindow] windowNumber],
modifierFlags = CPPlatformActionKeyMask,
location = [_lastKeyDownEvent locationInWindow],
location = [[CPApp currentEvent] locationInWindow],
anEvent = [CPEvent keyEventWithType:CPKeyDown location:location modifierFlags:modifierFlags
timestamp:timestamp windowNumber:windowNumber context:nil
characters:characters charactersIgnoringModifiers:characters isARepeat:NO keyCode:keyCode];
+1 -1
View File
@@ -151,7 +151,7 @@ var DOMFixedWidthSpanElement = nil,
else if (CPFeatureIsCompatible(CPJavaScriptTextContentFeature))
span.textContent = aString;
return CGSizeMake(span.clientWidth, span.clientHeight);
return CGSizeMake(span.clientWidth + 1, span.clientHeight);
}
+ (CPDictionary)metricsOfFont:(CPFont)aFont
+49 -23
View File
@@ -201,6 +201,11 @@ var ModifierKeyCodes = [
supportsNativeDragAndDrop = [CPPlatform supportsDragAndDrop];
var resizeTimer = nil;
var PreventScroll = true;
// When scrolling with an old-style scroll wheel with discete steps ('clicks'), the scroll amount can indicate how many "lines" to
// scroll.
#define SCROLLWHEEL_LINE_PIXELS 6.0
#if PLATFORM(DOM)
@@ -325,8 +330,8 @@ var resizeTimer = nil;
_DOMScrollingElement.style.position = "absolute";
_DOMScrollingElement.style.visibility = "hidden";
_DOMScrollingElement.style.zIndex = @"999";
_DOMScrollingElement.style.height = "60px";
_DOMScrollingElement.style.width = "60px";
_DOMScrollingElement.style.height = "500px";
_DOMScrollingElement.style.width = "500px";
_DOMScrollingElement.style.overflow = "scroll";
//_DOMScrollingElement.style.backgroundColor = "rgba(0,0,0,1.0)"; // debug help.
_DOMScrollingElement.style.opacity = "0";
@@ -335,8 +340,8 @@ var resizeTimer = nil;
_DOMBodyElement.appendChild(_DOMScrollingElement);
var _DOMInnerScrollingElement = theDocument.createElement("div");
_DOMInnerScrollingElement.style.width = "400px";
_DOMInnerScrollingElement.style.height = "400px";
_DOMInnerScrollingElement.style.width = "5000px";
_DOMInnerScrollingElement.style.height = "5000px";
_DOMScrollingElement.appendChild(_DOMInnerScrollingElement);
// Set an initial scroll offset
@@ -842,6 +847,12 @@ var resizeTimer = nil;
- (void)scrollEvent:(DOMEvent)aDOMEvent
{
if (PreventScroll)
{
PreventScroll = false;
aDOMEvent.preventDefault();
}
if (_hideDOMScrollingElementTimeout)
{
clearTimeout(_hideDOMScrollingElementTimeout);
@@ -852,7 +863,6 @@ var resizeTimer = nil;
aDOMEvent = window.event;
var location = nil;
if (CPFeatureIsCompatible(CPJavaScriptMouseWheelValues_8_15))
{
var x = aDOMEvent._offsetX || 0.0,
@@ -911,9 +921,22 @@ var resizeTimer = nil;
// We lag 1 event behind without this timeout.
setTimeout(function()
{
// Find the scroll delta
var deltaX = _DOMScrollingElement.scrollLeft - 150,
deltaY = (_DOMScrollingElement.scrollTop - 150) || (aDOMEvent.deltaY === undefined ? 0 : aDOMEvent.deltaY);
if (aDOMEvent.deltaMode !== undefined && aDOMEvent.deltaMode !== 0)
{
event._hasPreciseScrollingDeltas = NO;
event._scrollingDeltaX = aDOMEvent.deltaX;
event._scrollingDeltaY = aDOMEvent.deltaY;
event._deltaX = aDOMEvent.deltaX * SCROLLWHEEL_LINE_PIXELS;
event._deltaY = aDOMEvent.deltaY * SCROLLWHEEL_LINE_PIXELS;
}
else
{
event._hasPreciseScrollingDeltas = YES;
event._scrollingDeltaX = (_DOMScrollingElement.scrollLeft - 150) || aDOMEvent.deltaX || 0;
event._scrollingDeltaY = (_DOMScrollingElement.scrollTop - 150) || aDOMEvent.deltaY || 0;
event._deltaX = event._scrollingDeltaX;
event._deltaY = event._scrollingDeltaY;
}
// If we scroll super with momentum,
// there are so many events going off that
@@ -924,13 +947,8 @@ var resizeTimer = nil;
//
// We get free performance boost if we skip sending these events,
// as sending a scroll event with no deltas doesn't do anything.
if (deltaX || deltaY)
{
event._deltaX = deltaX;
event._deltaY = deltaY;
if (event._deltaX || event._deltaY)
[CPApp sendEvent:event];
}
// We set StopDOMEventPropagation = NO on line 1008
//if (StopDOMEventPropagation)
@@ -950,6 +968,7 @@ var resizeTimer = nil;
// can receive events.
_hideDOMScrollingElementTimeout = setTimeout(function()
{
PreventScroll = true;
_DOMScrollingElement.style.visibility = "hidden";
}, 300);
}
@@ -1124,7 +1143,7 @@ var resizeTimer = nil;
_mouseDownIsRightClick = button == 2 || (CPBrowserIsOperatingSystem(CPMacOperatingSystem) && button == 0 && modifierFlags & CPControlKeyMask);
if (sourceElement.tagName === "INPUT" && sourceElement != _DOMFocusElement)
if ((sourceElement.tagName === "INPUT" || sourceElement.tagName === "TEXTAREA") && sourceElement != _DOMFocusElement)
{
if ([CPPlatform supportsDragAndDrop])
{
@@ -1261,7 +1280,7 @@ var resizeTimer = nil;
insertionIndex = _windowLevels[middle] > aLevel ? middle : middle + 1
[_windowLevels insertObject:aLevel atIndex:insertionIndex];
layer._DOMElement.style.zIndex = aLevel;
layer._DOMElement.style.zIndex = aLevel + 1; // adding one avoids negative zIndices. These have been causing issues in Chrome
_DOMBodyElement.appendChild(layer._DOMElement);
}
@@ -1280,7 +1299,10 @@ var resizeTimer = nil;
// When ordering out, ignore otherWindow, simply remove aWindow from its level.
// If layer is nil, this will be a no-op.
if (orderingMode === CPWindowOut)
{
[aWindow _windowWillBeRemovedFromTheDOM];
return [layer removeWindow:aWindow];
}
/*
If aWindow is a child of otherWindow and is not yet visible,
@@ -1326,6 +1348,8 @@ var resizeTimer = nil;
if (otherWindow)
insertionIndex = orderingMode === CPWindowAbove ? otherWindow._index + 1 : otherWindow._index;
[aWindow _windowWillBeAddedToTheDOM];
// Place the window at the appropriate index.
[layer insertWindow:aWindow atIndex:insertionIndex];
@@ -1376,6 +1400,9 @@ var resizeTimer = nil;
var index = ordering === CPWindowAbove ? parent._index + 1 : parent._index;
if (!childWasVisible)
[child _windowWillBeAddedToTheDOM];
[aLayer insertWindow:child atIndex:index];
if (!childWasVisible)
@@ -1654,16 +1681,15 @@ var CPDOMEventGetClickCount = function(aComparisonEvent, aTimestamp, aLocation)
// Global.
_CPDOMEventStop = function(aDOMEvent, aPlatformWindow)
{
// IE Model
aDOMEvent.cancelBubble = true;
aDOMEvent.returnValue = false;
// W3C Model
if (aDOMEvent.preventDefault)
if (aDOMEvent.preventDefault) // W3C Model
aDOMEvent.preventDefault();
else // IE Model
aDOMEvent.returnValue = false;
if (aDOMEvent.stopPropagation)
if (aDOMEvent.stopPropagation) // W3C Model
aDOMEvent.stopPropagation();
else // IE Model
aDOMEvent.cancelBubble = true;
};
function CPWindowObjectList()
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

File diff suppressed because it is too large Load Diff
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 88 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 79 B

File diff suppressed because it is too large Load Diff

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