Compare commits

...
Author SHA1 Message Date
Alexander LjungbergandStefan Eilers b6e77f4be3 Fixed: menus not closing on left click.
Previously, clicking outside a menu on a control would not close the menu. Also clicking on the menu header again would open a second menu.

This error was caused by the control receiving the click and starting its own tracking, depriving the menu of the mouse up event it was awaiting.

The behaviour to wait for the mouse up was wrong to begin with. Menus should close on mouse down.

This fix closes the menu on left mouse down anywhere but the menu, while still allowing the click to pass through to any control underneath the cursor.

Fixes #1833.
2013-03-14 13:23:22 +01:00
Alexander Ljungberg 81d0812172 Merge branch 'refs/heads/slevenbits-platform-resize-fix' into slevenbits 2013-03-11 17:49:38 +00:00
Alexander Ljungberg 5f086b11b8 Fixed: platform windows resizable.
Without this fix, a platform window could be resized by clicking just under the menu bar and dragging downwards, even that platform windows are supposed to be the size of the browser window by definition.
2013-03-11 17:40:11 +00:00
Alexander Ljungberg 59b766eb93 Fixed: token field autocomplete menu not receiving mouse events in presence of modal window.
Without this fix, the presence of a modal ancestor window to a token field would lock down the autocomplete menu from mouse interaction.

This fix ensures the token field autocomplete menu accepts mouse events even during the presence of modal widows, just like other auxiliary windows such as pop up menus.
2013-03-11 16:41:06 +00:00
Alexander Ljungberg 6327d8c92e Fixed: transient popovers broke modal windows.
Without this fix, opening a transient popover would allow windows other than the modal window (or its children) to be interacted with.

In general, setCallback:forNextEventMatchingMask: did not work right if more than 1 callback was installed.

In the popover case the modal window would install its "any event" callback to control the event loop, but then the popover would add a second callback for mouse down to detect clicks outside of it. This would disrupt the modal event handling and allow mouse clicks (and presumably other events) to escape the modal event catcher.

This fix makes multiple nextEvent callbacks work as one would expect, with later ones taking priority over older ones and reinserted callbacks remaining at a stable priority.

This allows the modal window callback to be at the "bottom" of the handler stack and the popover event handler to be "on top" of that, and to remain that way. In theory more layers of event handling could be layered on top such as 2 simultaneous popovers.

This fix also fixes the dequeue argument in forNextEvent callbacks.
2013-03-11 13:14:18 +00:00
Alexander Ljungberg 969f56911a Test: popovers in attached sheet 2 test.
The popover test now added exposes a bug:

1. Click Modal Window to open a modal window.
2. Click Popover to open a popover.
3. Click on the first window.

It should not be possible to interact with this window since a modal window is open, but a bug in the modal event handling when transient popovers are open will allow the event to incorrectly pass through to the window.

AttachedSheet2 is turning into a complete window/modality/sheets/alerts/popover interaction test.
2013-03-11 12:58:36 +00:00
Alexander Ljungberg 09ea8c3241 Test: manual test for most token field behaviour when in a popover. 2013-03-10 22:49:09 +00:00
Alexander Ljungberg ff15f11927 Fixed: transient popover windows would close on mouse interaction with certain controls.
Without this fix, a transient popover would close if the autocomplete menu of a token field contained in it was clicked.

This happened because the popover considered the click to be on a different window. Although not tested, it's likely the same thing would happen if the menu of a combo pop or a pop up button was clicked.

This fix makes it so that any child window of a popover can be clicked without the popover closing.
2013-03-10 22:48:26 +00:00
Alexander Ljungberg abadc6298d Test: refactor token field test to not rely on ivars.
This will make it easier to extend the test with token fields in windows or popovers.
2013-03-10 22:44:07 +00:00
cacaodev cd96f78228 CPPredicate: use @ref instead of custom function 2013-03-10 19:56:07 +01:00
Alexander Ljungberg 5f2d1b8255 Merge branch 'master' of github.com:cappuccino/cappuccino 2013-03-10 17:41:42 +00:00
Alexander Ljungberg 483bd16a2d Formatting: simplify code slightly. 2013-03-10 17:40:58 +00:00
Alexander Ljungberg b53616ead3 New: @deref(<any idempotent expression>).
This change makes it possible to @deref any expression, such as a conditional expression, as long as the expression doesn't have side effects.

The reason not to allow dereferencing of expressions with side effects is that we might need to evaluate the expression twice in certain uses of deref, which is not obvious when you look at the deref operator in plain code.
2013-03-10 17:32:28 +00:00
Alexander Ljungberg f201ab0721 New: update operators on references, such as @deref(x)++.
This fix implements support for both prefix and postfix update operators on a dereference.
2013-03-10 14:02:37 +00:00
Alexander Ljungberg 767a7a7177 Test: expand CPNumberFormatter test to be more complete.
- Cover the formatting of @"" to nil.
- Check error messages by reference.
- Check output values.
- use @ref() instead of hand coded AT_REF.

Refs #1829.
2013-03-10 13:31:56 +00:00
Alexander Ljungberg 39b49d47f9 Fixed: CPNumberFormatter formatted @"" as any number.
Without this fix, `- CPNumberFormatter getObjectValue:forString:errorDescription:` would return `YES` for string @"", like if it was properly converted to an object value, but then actually leave object value unchanged.

With this fix object value is set to nil like in Cocoa.

Refs #1829.
2013-03-10 13:30:35 +00:00
Alexander Ljungberg c550cd7afb New: optimise CPArray enumerateObjectsWithOptions:usingBlock:. 2013-03-10 13:09:24 +00:00
Alexander Ljungberg f4096b94a7 New: use @ref and @deref instead of Ref.h throughout Cappuccino. 2013-03-10 13:08:34 +00:00
Alexander Ljungberg 9b4c126534 Unit test @ref and @deref. 2013-03-10 12:17:59 +00:00
Alexander Ljungberg 34faf362d1 New: @ref and @deref in Objective-J 2.0. 2013-03-10 12:17:43 +00:00
aparajita 1a24e954f9 Merge pull request #1838 from ahankinson/fix-issue1284
Docs: path to objj mode was wrong in docs

Closes #1284
2013-03-09 19:45:51 -08:00
Aparajita Fishman eb6cdfe97c Typo: fixed spelling in comment 2013-03-09 14:35:16 -05:00
Aparajita Fishman a01de54b65 Fixed: optimize access to object property
Accessing a property via dot notation is faster than indexing via a string.
2013-03-09 14:34:58 -05:00
aparajita 5c7e26c176 Merge pull request #1826 from stewa/non-string-markers
New: use dedicated class instead of CPString for selection markers

Previously, selection markers were strings, which allowed the possibility that user data could be mistaken for a selection marker.

With this commit, selection markers are global instances of a private class, removing the possibility of clashes with user data.
2013-03-09 08:59:37 -08:00
aparajita 4da1c67d18 Merge pull request #1837 from BlairDuncan/keyViewLoopInfinateLoopFix
Fixed: views from other windows cannot be next/previous key views

Previously, a view from another window could be set as the next/previous key view, which would result in unexpected behavior, including an infinite loop.

This commit ensures the proposed next/previous view belongs to the same window as the view to which it will be chained.
2013-03-09 08:17:52 -08:00
aparajita f3d0cdbddc Merge pull request #1836 from kerusan/cpruleeditor_tooltip_localization
Fixed: CPRuleEditor tooltips were not localized

Tooltip text was hardcoded in English. Now they use the localizer.
2013-03-09 07:56:44 -08:00
Andrew Hankinson 5fd241f7d7 Fix #1284: Update Emacs documentation
Small fix to update documentation for emacs. Fixes #1284.
2013-03-08 23:04:23 -05:00
Blair Duncan 7fab8d9782 don't allow views from another window to be next/previouskeyViews 2013-03-08 12:27:19 -05:00
Andrew HankinsonandAparajita Fishman 5fac631f6f New: minimum/maximum support for CPNumberFormatter
Previously, minimum and maximum were not supported in CPNumberFormatter.

This commit adds support for these in IB and via code. Updated unit tests included.

Fixes #1829
2013-03-08 09:30:31 -05:00
cacaodevandAparajita Fishman 72c277d9ee New: CPSegmentedControl segment selection bindings support
This commit adds support for the segment selection bindings: selectedIndex, selectedLabel, and selectedTag.

Sample app included.
2013-03-08 08:54:00 -05:00
Aparajita Fishman 0fdf648e1b Formatting: added missing whitespace 2013-03-08 08:35:16 -05:00
aparajita ba1fc13eed Merge pull request #1827 from stewa/issue1499-simple
Fixed: null placeholder is set correctly when using bindings
2013-03-08 05:32:01 -08:00
Kjell Nilsson 197decc842 Changed tooltip word to lowercase to follow other tooltip formatting 2013-03-08 13:47:46 +01:00
aparajita 9e5aa39781 Merge pull request #1835 from BlairDuncan/undoManagerFix
Fixed: initialize _undoCount to 0 so comparison tests work correctly
2013-03-08 04:19:22 -08:00
Kjell Nilsson c381672aee Added localization of tooltips with the standard localizer 2013-03-08 09:52:55 +01:00
Blair Duncan 62670a4fa4 improved as per aparajita 2013-03-07 22:18:59 -05:00
Aparajita Fishman 4469046b3b Revert "Fix #357: Fix resizeWithOldSuperviewSize to work more like Cocoa"
This reverts commit 4605130a53, which is breaking sheets.
2013-03-07 16:49:25 -05:00
Blair Duncan 7d51a34d11 fix for undoManager isUndoRegistrationEnabled 2013-03-07 16:21:37 -05:00
Stefan Wallström 5cbe94ba66 CPTextField: Optimization: Only restore null placeholder when setting null values through binders. 2013-03-07 20:32:57 +01:00
Antoine Mercadal f690d672a2 Merge pull request #1832 from mrcarlberg/compiler_build_capital_j_extension
Fix #1822: Will compile or issue correct error message when wrong case is used...
2013-03-07 11:20:05 -08:00
Aparajita Fishman cdb9777e96 Fixed: "Remove" button did not move with window resize
In the Manual/TableTest/DataView test app, the remove button did not pin to the right edge of the window when it resized.
2013-03-07 12:16:22 -05:00
aparajita 2bc5efe641 Merge pull request #1815 from cacaodev/CPTableView-issue1814
CPTableView fix for #1814.
2013-03-07 09:13:33 -08:00
Martin Carlberg 5481ce25b2 Fixed: Will compiler or issue correct error message when wrong case is used in filename on @import statements 2013-03-07 17:48:21 +01:00
Stefan Wallström bd269501ac Fixed parameter type for _placeholderForMarker: 2013-03-07 12:49:19 +01:00
Stefan Wallström 455ff57eec Fixed return type for _placeholderForMarker: 2013-03-07 12:39:04 +01:00
Stefan Wallström 51e682335b Use UID instead of hash. 2013-03-07 12:37:35 +01:00
Alexander Ljungberg 2ca20dea23 Merge pull request #1828 from ahankinson/cpdecimal-allow_leading_zeros
Allow CPDecimal to handle decimal numbers with leading zeros
2013-03-07 10:56:21 +00:00
Andrew Hankinson 7bef84e4e9 Allow CPDecimal to handle decimal numbers with leading zeros
Without this fix, CPDecimal will return NaN for numbers that have leading zeros, e.g., 0123.

This fix changes the matching regex to allow leading zeros to pass. This is then converted to a proper number later on, e.g., "0123" => 123. This is in line with Cocoa behaviour.

This commit also includes updated unit tests.
2013-03-07 00:26:02 -05:00
Stefan Wallström 11c6b667fb Fixed: Wrong placeholder string in CPTextField when using bindings 2013-03-06 20:44:09 +01:00
Stefan Wallström 262bd5b7c1 Use dedicated class, _CPStateMarker, instead of CPString for selection markers. 2013-03-06 19:30:17 +01:00
Aparajita Fishman e2580bda05 Fixed: objj_backtrace_print is not available in release frameworks
objj_backtrace_print is only available in debug frameworks. Previously we were not ensuring that objj_backtrace_print was available, which caused an error when running with release frameworks.

Now objj_backtrace_print is checked for availability.
2013-03-06 10:30:54 -05:00
Aparajita Fishman 3364733bd6 Typo 2013-03-06 10:19:26 -05:00
Aparajita Fishman 7461407140 Merge branch 'refs/heads/CPDictionary_deprecate_nil' 2013-03-06 08:53:44 -05:00
Martin CarlbergandAparajita Fishman 0b1805d96f Fixed: Temporary removed test case asserting throw when creating CPDictionary with nil object 2013-03-06 07:57:23 -05:00
Martin CarlbergandAparajita Fishman cfe099bb30 Fixed: Broken test case 2013-03-06 07:57:18 -05:00
Martin CarlbergandAparajita Fishman b98b301089 Fixed: Removed deprecated warning when creating CPDictionary with nil object 2013-03-06 07:56:50 -05:00
Aparajita Fishman 4b0b19aec7 Formatting, refactoring, use separate message for nil key 2013-03-06 07:49:18 -05:00
Aparajita Fishman af142a5ccc Merge branch 'refs/heads/cpdictionary_throw_on_nil' into temp 2013-03-05 15:50:41 -05:00
aparajita e3384d98b7 Merge pull request #1810 from ahankinson/fix-issue1184
Fix #1184: Add missing argument to .apply()
2013-03-05 12:40:27 -08:00
Alexander Ljungberg f4b08a9ce2 New: - CPObject performSelector:withObject:afterDelay:.
Also - CPObject cancelPreviousPerformWithTarget: and other related methods.
2013-03-05 18:52:06 +00:00
aparajita 21595cdebc Merge pull request #1821 from ahankinson/fix-issue357
Fix #357: Fix resizeWithOldSuperviewSize to work more like Cocoa
2013-03-05 05:30:13 -08:00
cacaodev ac3a45aec5 CPTableView: force the mask to CPViewNotSizable for IB made CPTableCellView.
Added documentation for tableView:dataViewForTableColum:row: delegate method. Document other cases, when we expect the data view to have a CPViewNotSizable mask.
ViewBasedCib example: added variable row heights.
2013-03-04 20:03:20 +01:00
Andrew Hankinson 4605130a53 Fix #357: Fix resizeWithOldSuperviewSize to work more like Cocoa
Without this fix, CPView's resizeWithOldSuperviewSize: would simply resize subviews at the rate of 1 pixel for every 2 pixel change.

This change introduces a new method of resizing views to a ratio of the size of the superview.

Patch contributed by @davidkhess
2013-03-02 16:40:00 -05:00
Randy Luecke 89c943f755 Merge pull request #1820 from BlairDuncan/TableViewCursorInfinateLoopFix
fix for issue #1819 tableview infinate loop
2013-03-01 14:20:34 -08:00
Blair Duncan 9730e066b8 fix for issue #1819 tableview infinate loop 2013-03-01 17:00:38 -05:00
Alexander Ljungberg 8668911593 Merge pull request #1817 from gildegoma/travis-ci_use_build_dir_variable
Travis CI: Use new $TRAVIS_BUILD_DIR environment variable
2013-03-01 10:57:02 +00:00
Martin Carlberg 34843a70b9 Merge branch 'master' of https://github.com/cappuccino/cappuccino into cpdictionary_throw_on_nil 2013-03-01 10:50:22 +01:00
Martin Carlberg e686fbc0a8 Fixed: Handle deprecated setObject:forKey: calls with nil object on CPDictionary 2013-03-01 10:50:00 +01:00
Gilles Cornu 95ab1b355a Travis CI: Use new $TRAVIS_BUILD_DIR env-variable
Before this fix: environment variables defined `.travis.yml` were still
dependant of internal configuration of the travis worker virtual
machine. See also previous pull request #1728.

With this fix, `.travis.yml` is even more generic and portable.
2013-03-01 07:58:33 +01:00
Antoine Mercadal 5312524871 Define navigator.userAgent as another ugly Rhino fix 2013-02-28 15:41:14 -08:00
Martin Carlberg 64fb0934a4 Fixed: Do not setObject: forKey: when object or key is nil 2013-02-28 22:59:11 +01:00
Martin Carlberg 6ee3a395fb Fixed: CPDictionary setObject: forKey: will log deprecated warning when passing nil object or key.
This should be replaced by throwing exception after release of next stable version. Code included for this.
2013-02-28 22:58:42 +01:00
Aparajita Fishman 62ced1749f Fixed: invalid menu item validator was not checked properly
Previously, if CPApplication -targetForAction:to:from: returned nil, no check was done to see if that failed because there was no action or no valid target. If the item had no item, no target, and to action binding, it would be left enabled, which was incorrect.

This commit fixes the validation to disable the item if targetForAction:to:from: returns nil and the item has an action or target.
2013-02-27 18:26:34 -05:00
Aparajita Fishman 9ea3b70143 Fixed: table cells were not initialized from xib settings
This is a second attempt to fix the problems addressed by 69bbe627a9.

Because table cell classes needed to use the same initialization code as the NS_initWithCoder methods, it was necessary to refactor the initialization code into separate NS_initWithCell methods and call them separately from NS_initWithCoder.
2013-02-27 18:02:55 -05:00
Aparajita Fishman 07f9b94548 Fixed: initializer did not allow programmers to pass arbitrary types
Originally the initializer had coerced the parameter to a string, even though it is clearly documented that it should be a string. A later commit removed that coercion.

This commit reinstates the type coercion and thus saves the world from those who would pass non-string types in a parameter that says "withString".
2013-02-27 15:17:17 -05:00
Aparajita Fishman c5b3c17ccc Revert "Fixed: table cells were not initialized from xib settings"
This reverts commit 69bbe627a9 until it can be implemented correctly.
2013-02-27 13:54:26 -05:00
Andrew Hankinson 02460f0e9d Change this to _window in apply() 2013-02-27 09:07:21 -05:00
Andrew Hankinson ee20038dce Fix #1184: Add missing argument to .apply()
The Javascript .apply() method takes two arguments: A context argument and an array of values. In CPWebScriptObject callWebScriptMethod:withArguments, only an array of arguments was passed to the .apply() method.

This fix inserts `this` as the first argument, and the array of arguments as the second. This has been converted to a pull request from the original issue (#1184)

The original issue also suggested a fix for handling namespaces, which are not incorporated in this patch.
2013-02-26 21:37:57 -05:00
Aparajita Fishman 226bf5299e Fix: don't touch the item state unless disabling 2013-02-26 21:07:12 -05:00
Aparajita Fishman ae2ed8bf94 Fixed: empty strings and indexes out of range were not handled
Previously CPAttributedString did not provide an -init method,
with the result that an attributed string created with [[CPAttributedString alloc] init]
would not be correctly initialized.

Also, some methods that took indexes into the string were not checking for an invalid index and were not raising exceptions when the documentation said they should.

Finally, some methods that were supposed to return empty dictionaries were returning nil.

This commit fixes all of these problems. Empty strings should no longer cause errors.

Closes #533
2013-02-26 20:15:15 -05:00
aparajita 395d140c76 Merge pull request #1805 from ahankinson/fix-issue1359
Fix #1539: Figure out the best shell config file
2013-02-26 11:47:54 -08:00
Alexander Ljungberg d9354c867b Fixed: token field menu refusing clicks in recent versions.
Not clear why this worked before but not now. This fix makes sense regardless.

Without this fix, clicks would not be sent through to the token field menu because its window wasn't the key window.

This fix makes the autocomplete menu declare it does not need to and does not want to become the key window.

Fixes #1807.
2013-02-26 18:55:22 +00:00
Alexander Ljungberg a6fafcd03b Fixed: inadvertent grid lines in token field menu.
Without this fix, grey lines were showing in the background of token field autocomplete menus in recent versions.

This fix removes the grid lines which were never intended to be there to begin with.

Fixes #1806.
2013-02-26 18:27:41 +00:00
Alexander Ljungberg 0b88f1be14 Docs: incorrect - CPEvent acceptsFirstMouse: documentation. 2013-02-26 18:27:41 +00:00
Aparajita Fishman 69bbe627a9 Fixed: table cells were not initialized from xib settings
Previously, table view cells (non-view-based) were not being decoded with all of the available cell attributes in IB, and many attributes were hard-coded. In addition, there was a bunch of initialization code that has been made redundant by theming.

With this commit, decoding of all control classes has been refactored so that table view cells can use the same code, thus ensuring they decode all available cell attributes. In addition, the redundant code has been eliminated.

It is now possible to apply most table cell attributes such as font, color, alignment, sendsActionOnEndEditing, and so on, directly in IB.

Closes #1803

BREAKING CHANGE:
Changes have been made to table cell decoding in nib2cib. All xibs should be re-converted with `find . -name '*.xib' -exec nib2cib {} \;`.
2013-02-26 13:07:54 -05:00
Alexander Ljungberg 26a9c9e725 New: exclude Sublime specific files more generally. 2013-02-26 17:28:07 +00:00
Alexander Ljungberg 9ce5c1c4d7 Fixed: alignment in CPGrahicsTest.
Refs #1801.
2013-02-26 16:28:15 +00:00
Alexander Ljungberg a0b9efe1fd Fixed: CGPathMoveToPoint problem after a0115962.
Without this fix, CGPathMoveToPoint would not actually move to the point if there had been at least one previous CGPath command (a current path existed) but it was not a move to point command.

This fix ensures move to point is effective in all cases.

Fixes #1801.
2013-02-26 16:27:54 +00:00
Alexander Ljungberg 1aa57ca11b Test: expose errors in CGPathMoveToPoint.
This test highlights the problem described by issue #1801, and exposes that CGPathMoveToPoint is in fact not working correctly after the fix either.
2013-02-26 16:27:54 +00:00
Andrew Hankinson e10ce7a445 Fix #1359: Figure out the best shell config file
This fix adds a little more intelligence to the bootstrap.sh script.

If a user is using ZSH or BASH it will recognize those and append to the appropriate config file, creating .profile if necessary.

If the user's shell cannot be read from the $SHELL variable, it will attempt to find the first suitable configuration file in the user's home directory. If none can be found, it will create .profile.

This was based off the Wikipedia article on Unix shells and the configuration files they will read. The only shells that are not supported by this patch should be csh and tcsh.
2013-02-26 11:13:35 -05:00
aparajita cf9ce6ac60 Merge pull request #1613 from cacaodev/CPTableViewLion
CPTableView : view-based table and new Lion API
2013-02-26 07:29:46 -08:00
cacaodev 10d120ccfd Removed tracing in test apps. Added CPTrace.j in Tests/Manual/, available for any app who wants to import and use it. Added utility function computing moving average. 2013-02-26 16:06:02 +01:00
Aparajita Fishman 2cb3450cf8 Fixed: CGPathEqualToPath did not compare all subpath types
The implementation of CGPathEqualToPath did not compare all of the subpath types now supported by CGPath. In addition, it referred to subpath properties that no longer exist.

The implementation now compares all properties of all supported subpath types.

Closes #1246
2013-02-26 08:41:27 -05:00
Aparajita Fishman 53ce9b6588 Fixed: delegate method collectionViewDidChangeSelection: is deprecated
Previously CPCollectionView supported a delegate method collectionViewDidChangeSelection:, which is not defined in Cocoa. Since CPCollectionView is KVO-compliant for selectionIndexes, this delegate method is no longer necessary and is a needless divergence from Cocoa.

The method is now marked as deprecated, and when used will log a deprecation warning.

Closes #715
2013-02-26 08:11:42 -05:00
aparajita 05012985bb Merge pull request #1801 from mrcarlberg/cgpath_typo
Fixed typo in CGPath.j
2013-02-26 04:34:54 -08:00
Martin Carlberg 93c9a70aa0 Fixed typo 2013-02-26 12:44:37 +01:00
cacaodev 7d03483210 Merge remote-tracking branch 'upstream/master' into CPTableViewLion
Conflicts:
	AppKit/CPView.j
2013-02-26 11:56:18 +01:00
Aparajita Fishman fc9001353f Fixed: CPObjectController -setContent potentially called too early
Previously setContent: was called first, before the rest of the object was initialized. This potentially could have unexpected results because setContent has many side effects.

This commit waits until the object is completely initialized before calling setContent.
2013-02-25 21:22:45 -05:00
aparajita 6a8cba521b Merge pull request #1627 from ggsato/CPArrayControllerFirstSelectionTest
a suggested fix for CPArrayController selection binding failure in retri...
2013-02-25 18:16:04 -08:00
Aparajita Fishman 471641c228 Fixed: subviews in cib did not receive view(Will/Did)MoveToSuperview:
In Cocoa, viewWillMoveToSuperview: and viewDidMoveToSuperview: are called when views are instantiated from code or from a nib.

Previously in Cappuccino, when a view was instantiated from a cib, the _subviews of the view were directly set from the decoded subview array. This short-circuited all of the normal notifications a view receives when added to a superview, including viewWillMoveToSuperview: and viewDidMoveToSuperview:. As a result, some views that override these methods, such as CPSearchField, were not set up correctly when instantiated from a cib.

With this commit, subviews instantiated from a cib are manually added to their superview, thus ensuring they go through the same cycle as views instantiated from code, and ensuring that viewWillMoveToSuperview: and viewDidMoveToSuperview: are called.

Closes #1699
2013-02-25 20:09:18 -05:00
Aparajita Fishman 887421c9fa Fixed: window content view overlapped window frame
Previously, the content view of almost all window types
could overlap the frame of the window.

This is a follow on to b28429f which insets the content view
from the frame for all relevant window types.

Refs #1798
2013-02-25 17:50:12 -05:00
Aparajita Fishman cbe8659cc7 Docs: fixed mistake in comments 2013-02-25 17:27:34 -05:00
Aparajita Fishman b28429f940 Fixed: window content view was not inset from the frame
Previously, _CPStandardWindowView did not inset the content view rect
from the window frame, thus its contents could overlap the window frame.

Now the content view is correctly inset so that content view content
is clipped to the window frame, except for the corners. Because the
corners are round and the window frame is a background color, they
can still be overlapped. this will be fixed in a later commit.

Closes #1798
2013-02-25 17:15:26 -05:00
Alexander Ljungberg 956a4c341c Fix: remove accidentally committed Sublime configuration files. 2013-02-25 20:00:42 +00:00
Alexander Ljungberg 5b05dc92a1 More dictionary literals. 2013-02-25 18:27:44 +00:00
Alexander Ljungberg 8bcbeb0aa9 Improve code readability with dictionary literals. 2013-02-25 17:02:36 +00:00
Alexander Ljungberg 472848da91 New: array literals in Objective-J 2.0.
Array literals look like `@[a, b, c]`.

This syntax is supported for completeness and source compatibility, but are not terribly useful since standard JavaScript arrays are toll-free bridged to CPArray.

Array literals could be handy if you're replacing CPArray with your own implementation.
2013-02-25 14:57:05 +00:00
Alexander Ljungberg 5200f945fe New: dictionary literals in Objective-J 2.0. 2013-02-25 14:24:29 +00:00
Aparajita Fishman a736bb4e93 fix (CPWindow): prevent empty content view when resizing a window
Previously, windows with no minimum size could be resized
by the user such that the content view was completely hidden, and then
resized such that the window was effectively turned inside out.
This obviously needed to be fixed.

Now, when the user resizes a window, each _CPWindowView subclass
is asked for the minimum resize size, with the size being additively
set by each subclass. This minimum size takes into account things
like the title bar, divider line, and close button, and always leaves
at least 2px height for the content view.

The user-requested size is then pinned to the minimum resize size.

In the process of fixing this bug, I discovered in the Cocoa docs
that the CPWindow -setFrame: methods should ignore minSize and maxSize.

Other changes:
- Take the divider height into account in contentRectForFrameRect for titled windows.
- Use _CG macros and fix formatting.

Closes #1753
2013-02-24 22:44:29 -05:00
Alexander Ljungberg 00f60ccaa4 Merge branch 'master' of github.com:cappuccino/cappuccino 2013-02-24 23:54:56 +00:00
Alexander Ljungberg 6d1c4a9570 Fixed: - CPMutableArray removeObjectIdenticalTo did not remove all instances, was documented incorrectly.
Contrary to what the previous documentation said, removeObjectIdenticalTo: should remove all instances of the argument from the receiver, not just the first one.
2013-02-24 23:51:48 +00:00
Aparajita Fishman c6a0e209ad Using a new naming scheme for tests 2013-02-24 18:51:22 -05:00
Alexander Ljungberg be4a168601 Make 30268f9865c compatible with Internet Explorer 8-. 2013-02-24 23:50:09 +00:00
aparajita 2c10671fe4 Merge pull request #1796 from ahankinson/fix-issue1685
Fixes #1685: CPToolbar calls incorrect notification method
2013-02-24 15:45:03 -08:00
Alexander Ljungberg b791289dfe Merge commit 'c4370240f8e31c257f038b661a2e171fe346f28b' 2013-02-24 23:44:00 +00:00
Alexander Ljungberg c4370240f8 Fixed: subclasses of CPMutableArray had broken removeObject:.
The `removeObject:` default provided in CPMutableArray would not work in subclasses because it relied on the class having a .length property.
2013-02-24 23:43:20 +00:00
aparajita fd0bdcba67 Merge pull request #1797 from cacaodev/issue1357
Fix for issue #1357
2013-02-24 15:42:58 -08:00
Alexander Ljungberg f805b6bfa6 Fixes #1409. Improve CPTabView decoding to fix tab selection errors.
This is an improved fix to the corrupted tab view state bug partially addressed by 0f347be.

Without either fix, NSTabView is converted to a CPTabView where tab view item views are subviews of the NSTabView, while in Cappuccino the selected view item is supposed to be a subview of a CPBox.

Without this fix, CPTabView decoding called addSubview: in initWithCoder: which can cause the superview of a view to become set, only to later be overwritten when the superview ivar is decoded.

This fix removes the tab item view as a subview from the tab view before encoding it in nib2cib, and then makes sure not to call addSubview: while still in the initWithCoder stage, but rather later in awakeFromCib.
2013-02-24 23:08:44 +00:00
Alexander Ljungberg 4188b274f7 Move special per class nib2cib processing to the classes themselves in awakeFromNib.
Having class specific code in the class makes more sense, and this will make it easier to add more class specific transformations.
2013-02-24 22:23:12 +00:00
cacaodev bf1e720ebc Merge remote-tracking branch 'upstream/master' into CPTableViewLion 2013-02-24 23:01:43 +01:00
Alexander Ljungberg 599351b56d Crash early in debug mode if addSubview: is called with a not fully decoded view.
If a view to be added is already a subview, but doesn't yet "know it" due to being only partially decoded, a corrupted view hierarchy with duplicate views would be set up, which is very hard to debug.
2013-02-24 21:39:04 +00:00
Alexander Ljungberg 84f42bdd05 Fixed: decoding a CPClipView could result in duplicate subviews.
This bug used to be concealed by the fact that we called [superview removeObject:X] when replacing a subview, which caused all duplicates to be removed.

Without this fix, the call to setDocumentView in CPClipView's decoding would try to add the document view as a subview. But when decoding, the clip view is already in the decoded list of subviews. Normally adding a subview twice would just move it to the end of the list of subviews, but this only works for fully decoded subviews where superview is not nil. Since we're in the middle of decoding there's no guarantee superview is set yet.

This fix avoids calling addSubview:.
2013-02-24 21:26:02 +00:00
Alexander Ljungberg 75b72d601a Fixed: eliminate jake deploy warnings from default apps in 0.9.7. 2013-02-24 18:20:39 +00:00
Alexander Ljungberg a426802b1a Merge branch 'master' into slevenbits 2013-02-24 17:54:41 +00:00
cacaodev d2143844e3 Fix for issue #1357 2013-02-24 18:47:37 +01:00
Alexander Ljungberg ce7e5122e0 Fixes #829. Improve - CPView removeFromSuperview performance.
In the modified test described in #829 performance improves by at least 30% and that's with a significant addSubview: component diluting the test.

This change should improve outline and table view performance.
2013-02-24 17:36:30 +00:00
Alexander Ljungberg 0268f9865c Faster CPMutableArray removeObjectIdenticalTo:.
About 6-8X speedup by skipping all the `indexOfObjectIdenticalTo:` calls and going straight to JS `indexOf`.
2013-02-24 15:19:00 +00:00
aparajita c401e3b55e Merge pull request #1497 from BlairDuncan/afterDocumentLoadFix
fix to enables the startup loader to continue if dynamically loaded
2013-02-23 18:01:28 -08:00
Andrew Hankinson 946b336e92 Added correct notification name. 2013-02-23 17:31:08 -05:00
Andrew Hankinson e40138c2ee Fixes #1685: CPToolbar calls incorrect notification method
This fix corrects the call in CPToolbar _setWindow to `removeObserver:name:object`. Before, this was calling the non-existent `removeObserver:object`, which would raise an exception.

This was fixed by @schipmolder.
2013-02-23 17:20:38 -05:00
Aparajita Fishman 3dad330a59 Font metrics calculations were broken, now fixed.
Updated FontMetricsExplorer application to modernize html files.
2013-02-23 16:02:05 -05:00
cacaodev fb3fe24567 Merge remote-tracking branch 'upstream/master' into CPTableViewLion
Conflicts:
	Tests/Manual/CPOutlineViewCibTest/Resources/MainMenu.cib
2013-02-23 20:55:54 +01:00
Aparajita Fishman a011596231 CGContext fixes/enhancements
- NEW: Retrieve the underlying Image element from a CPImage with -image.
- NEW: You can now render any arbitrary drawing to a pattern context and use that as a fill or stroke pattern. See CGContextCreatePatternContext, CGContextSetFillPattern and CGContextSetStrokePattern. Works in all canvas-enabled browsers, including IE 9+.
- NEW: An example of using a custom rendered pattern is in Tests/Manual/PatternFillTest.
- NEW: Test if a CPImage is a single image (vs. three/nine part) with -isSingleImage.
- FIXED: With canvas, we have to track ourselves whether the context has a path or not.
- FIXED: All shapes except rects may not be added to a path with no context. If you attempt to do so, an error is logged.
- FIXED: CGPath was not setting the start and current point correctly in some cases.
- FIXED: CGContextAddPath was not moving to the path's start point at the beginning.
- FIXED: Removed superfluous CGContextClosePath commands, fixed some drawing sequences.
- FIXED: Misc. formatting.

Sorry, these changes are canvas only (including IE 9+)! I am not going to spend the time to port these fixes to VML (IE 8).
2013-02-23 13:53:20 -05:00
Blair Duncan ac5a4b88d2 updated the testfile 2013-02-23 10:24:29 -05:00
cacaodev 12e743f9dc nib2cibed viewBasedCib example to resurrect scrollers 2013-02-23 14:52:38 +01:00
cacaodev 5355c4935c Merge remote-tracking branch 'upstream/master' into CPTableViewLion 2013-02-23 14:51:46 +01:00
Aparajita Fishman f54f2e7b13 selectNone: is not part of the NSTableView API, not sure why we need it since it is the same as deselectAll: 2013-02-23 08:26:36 -05:00
aparajita 835096c089 Merge pull request #1794 from cacaodev/CPImageView-bindings
CPImageView bindings improvements
2013-02-23 04:33:19 -08:00
cacaodev 16bb194019 Merge remote-tracking branch 'upstream/master' into CPTableViewLion
Conflicts:
	Tests/Manual/TableTest/TableBindings/Resources/MainMenu.cib
	Tests/Manual/TableTest/TableBindings/Resources/MainMenu.xib
2013-02-23 10:55:08 +01:00
Aparajita Fishman a9952a28a4 CPRadioGroup enhancements
- You may now bind radio groups to selectedValue, selectedTag, selectedIndex, enabled, and hidden. enabled and hidden are multiple value bindings.
- Added some API to CPRadioGroup that parallels NSMatrix: selectRadioAtIndex:, selectRadioWithTag:
- Added setEnabled/setHidden, they operate on all of the radios in the group.
- Sample app to demonstrate all new features.
2013-02-23 00:01:19 -05:00
Aparajita Fishman 67624208de XcodeCapp improvements
- Convert to ARC, garbage collection is deprecated.
- Support radio buttons and groups as outlets in IB.
2013-02-22 23:56:21 -05:00
Aparajita Fishman ce0aadfcf7 Optimizations
No need to copy result of [self bounds], it's already a copy
2013-02-22 23:29:17 -05:00
Aparajita Fishman 7c677de10a Fixed bugs in CPColorWithImages and CPImageInBundle 2013-02-22 21:58:12 -05:00
Aparajita Fishman f590d38746 Revert "Fixed a bunch of bugs in CGContextCanvas and CGPath."
This reverts commit 7ab84ca607 until I can figure out why it is breaking other things.
2013-02-22 16:56:19 -05:00
cacaodev 3591ba0f89 CPImageView bindings improvements
Cache image for the CPValue(URL|Path)Binding.
Support for reverse bindings CPValueBinding, CPValue(URL|Path)Binding,
CPDataBinding.
2013-02-22 22:11:42 +01:00
Alexander Ljungberg 80170cfa03 Merge branch 'refs/heads/slevenbits-nsbox-custom-fix' 2013-02-22 19:46:13 +00:00
Alexander Ljungberg 1cb8844470 Fixed: custom NSBoxes placed in Xcode became smaller in Cappuccino.
Without this fix, a regular custom NSBox such as a simple box with a 1px border would become several pixels smaller in Cappuccino.

This fix makes sure we only try to adjust the size for primary and secondary type NSBoxes.
2013-02-22 19:45:56 +00:00
Alexander Ljungberg 9be703e271 Merge branch 'refs/heads/slevenbits-tabview-cib-fix' 2013-02-22 19:10:28 +00:00
Alexander Ljungberg a19ec35a47 Fixes #1409. Fixed: broken tab view decoded from xib in certain situation.
Without this fix, a tab view set up in Xcode where a tab but the first was selected could be instantiated in a corrupted state in Cappuccino, where tab selection would have no effect.

This fix ensures that even if the decoded view of the selected tab view item has a superview different from how we do things in Cappuccino, we make sure to set it right.
2013-02-22 19:08:38 +00:00
Aparajita Fishman 47ade360d5 Formatting 2013-02-22 12:40:43 -05:00
aparajita 0e669417cd Merge pull request #1791 from BlairDuncan/tableViewSelectAll
tableview add support for selectAll: deSelectAll:  selectNone:
2013-02-22 07:59:11 -08:00
Blair Duncan 5c3d3bbc2e updated added a menu to tablebindings test and doxygen comments 2013-02-22 09:45:26 -05:00
Alexander Ljungberg 09b5eef617 Fixed: [CPBox setContentView:nil] crash.
This is allowed in Cocoa so should not crash Cappuccino either.
2013-02-22 14:42:36 +00:00
Blair Duncan 92c2ed970c tableview add support for selectAll: deSelectAll: selectNone: #1594 2013-02-22 00:37:34 -05:00
Aparajita Fishman 7ab84ca607 Fixed a bunch of bugs in CGContextCanvas and CGPath.
- With canvas, we have to track ourselves whether the context has a path or not.
- All shapes except rects may not be added to a path with no context.
- CGPath was not setting the start and current point correctly in some cases.
- CGContextAddPath was not moving to the path's start point at the beginning.

Sorry, I am not going to spend the time to port these fixes to VML!
2013-02-21 21:44:16 -05:00
Alexander Ljungberg 7d37427c96 Fixes #1789. Fixed: bootstrap.sh wget fallback broken by 1789. 2013-02-21 23:41:46 +00:00
Antoine Mercadal 17695ff77c refresh the history menu when user stops listening to a project. close #1784 2013-02-21 14:33:17 -08:00
Alexandre WilhelmandAntoine Mercadal bc2b26132a Fixed bug about font in tableViewHeader closed #1747 2013-02-21 14:05:13 -08:00
Aparajita Fishman 7c033f75ea Eliminated dead code 2013-02-21 17:02:55 -05:00
aparajita 816e3b71a9 Merge pull request #1770 from ahankinson/nib2cib-cpbrowser-compat
Nib2cib cpbrowser compatibility
2013-02-21 12:54:43 -08:00
Andrew Hankinson b0e307bdd0 NSBrowserTest initial commit 2013-02-21 14:07:01 -05:00
Andrew Hankinson ee2d52c40a Merge branch 'refs/heads/master' into nib2cib-cpbrowser-compat 2013-02-21 13:58:48 -05:00
Aparajita Fishman 9007cab02c Removed another alert 2013-02-21 08:58:01 -05:00
Aparajita Fishman d473a82715 Formatting, replaced alert with warning 2013-02-21 08:52:58 -05:00
Aparajita Fishman fb01ceb2a9 Formatting 2013-02-21 07:39:57 -05:00
Aparajita Fishman 109f59ab6c Merge branch 'autosaveTableColumnsFix' 2013-02-21 07:37:09 -05:00
Alexander Ljungberg 169f8eaad1 Merge branch 'master' of github.com:cappuccino/cappuccino 2013-02-20 19:57:24 +00:00
Alexander Ljungberg 854780a22a Fixes #1754. Fixed: CPAlert ignoring keyboard interaction, not movable by background.
Without this fix, a CPAlert window couldn't actually become the key window which meant it couldn't receive keyboard events such as using the escape key to close the alert or hitting enter to activate the default button.

Furthermore the window could not be moved by clicking its background and dragging.

This fix makes CPAlert windows into CPPanels instead, which can become key windows and is more appropriate since panels are meant for auxiliary windows.
2013-02-20 19:56:23 +00:00
Alexander Ljungberg b1883d7204 Refs #1754. Crisp, pixel perfect CPAlert warning triangle. 2013-02-20 18:31:43 +00:00
Alexander Ljungberg 74be583fbb Refs #1754 . Fixed: pixelated corners on Aristo 2 HUD windows. 2013-02-20 18:19:25 +00:00
Alexander Ljungberg 4bc54c45a3 Refs #1754. Fixed: wrong button text shadow direction in Aristo 2 HUD theme. 2013-02-20 16:39:09 +00:00
Alexander Ljungberg 56ec9dbb10 Feature to open the attached sheet test window in HUD mode.
This is not a bad kitchen sink test for HUD widgets and windows.
2013-02-20 16:35:09 +00:00
Alexander Ljungberg 5d08ddadfa CPView _setThemeIncludingDescendants:.
This method makes it possible to e.g. switch a whole window to the HUD theme.

It's internal for now.
2013-02-20 16:33:28 +00:00
cacaodev cd54687f41 CPTableColumnHeaderView: when a column is pressed and is the _editingColumn, make the table view first responder 2013-02-20 17:19:47 +01:00
cacaodev 899cd22999 Fix local hidding global variable in CPOutlineViewCibTest 2013-02-20 17:16:40 +01:00
cacaodev 3aadc958eb Merge remote-tracking branch 'upstream/master' into CPTableViewLion
Conflicts:
	Foundation/CPURLConnection.j
	Tests/Manual/CPOutlineViewCibTest/Resources/MainMenu.cib
	Tests/Manual/TableTest/TableBindings/Resources/MainMenu.cib
2013-02-20 17:15:24 +01:00
Alexander Ljungberg 79dde7bb9b Use HUD style buttons in HUD style test window. 2013-02-20 14:39:50 +00:00
Aparajita Fishman 7d8e9dfc60 Formatting 2013-02-20 03:00:20 -05:00
aparajita e623776f5d Merge pull request #1787 from BlairDuncan/CPDictionaryController
minor optimization so that newObject and includedKeys use the same code
2013-02-19 23:55:11 -08:00
aparajita 230988b90d Merge pull request #1785 from aradabaugh/cgcanvascontext
Fixes #1403 w/formatting and style for missing CGCanvasContext functions. Also...
2013-02-19 18:01:11 -08:00
Alexander Ljungberg 64f85002b1 Merge branch 'master' of github.com:slevenbits/cappuccino into slevenbits 2013-02-19 23:18:01 +00:00
Alexander Ljungberg d4b7fd635d Merge branch 'refs/heads/master' into slevenbits 2013-02-19 23:16:56 +00:00
aparajita a6f4e20078 Merge pull request #1786 from ahankinson/fix-issue1745
Fix #1745: Rename Progress bar images in HUD theme
2013-02-19 14:34:54 -08:00
Aparajita Fishman 02b7198e9b Added action bindings to CPMenuItem
Updated MultipleValueBindings app to use action bindings in About and Help menu items.
2013-02-19 17:25:29 -05:00
Andrew Hankinson 64cb4ddb14 Fix #1745: Rename Progress bar images in HUD theme
This is a partial fix that should resolve #1745.

-- It removes an extra "-bar" from the progress bar images in the HUD theme.
-- It removes an older "-bar-regular" from file names to match the file names in the regular theme
-- It corrects a misspelled "indeterminate" in the progress indicator
2013-02-19 17:15:40 -05:00
Ilya Kulakov cca8dd0056 Fix comment to -[CPCollectionView setItemPrototype:].
Item prototype is a subclass of CPViewController, not CPView.
2013-02-20 04:44:46 +07:00
Aparajita Fishman 238b6c8e57 Modernize index[-debug].html, IE 9+ now run in edge mode 2013-02-19 16:22:58 -05:00
Aparajita Fishman ba372029f9 Update MultipleValueBindings app to use a button that binds to a target with no arguments 2013-02-19 16:22:58 -05:00
Adam Radabaugh a774e52988 Fixes formatting and style for missing CGCanvasContext functions. Adds CGCanvasContext test. 2013-02-19 14:10:39 -07:00
Blair Duncan b6feecae70 minor optimization so that newObject and includedKeys use the same code 2013-02-19 12:06:48 -05:00
aparajita 8c63e32450 Merge pull request #1232 from cncolder/fontinfo-path-fix
Fix fontinfo build path when $CAPP_BUILD not defined.
2013-02-19 07:44:37 -08:00
aparajita 84d8e1ceb7 Merge pull request #1478 from cacaodev/CPTableView-dragging-perf
CPTableView: make dragged views reusable when dragging ends
2013-02-19 07:33:29 -08:00
aparajita 23d3cef52e Merge pull request #1517 from BlairDuncan/FlashViewFix
CPFlashView a few minor fixes, includes Test file
2013-02-19 07:16:28 -08:00
Aparajita Fishman 6a5b6a70b5 I was wrong, a single value binding for CPTextField does have default placeholders. Updated MultipleValueBindings app to display a single value binding as well. 2013-02-19 10:07:21 -05:00
Aparajita Fishman b6f0a29f8f Merge branch 'CPURLConnection-sendSynchronousRequest' of https://github.com/cacaodev/cappuccino 2013-02-19 09:47:40 -05:00
Aparajita Fishman dc366809c8 Merge branch 'CPCollectionView-maxNumberOfRows' of https://github.com/cacaodev/cappuccino 2013-02-19 09:38:10 -05:00
aparajita ceeaab70fc Merge pull request #1679 from mrcarlberg/scroll_before_focus_text_field
Make sure the text field is visible before focus
2013-02-19 06:14:42 -08:00
aparajita 3cfa81bdea Merge pull request #1773 from BlairDuncan/CPPasteboardAvailableTypesFromArrayFix
CPPasteboard availableTypeFromArray fix issue #1683
2013-02-19 06:09:59 -08:00
aparajita 9e99676b66 Merge pull request #1777 from BlairDuncan/CPDictionaryController
CPDictionaryController [+1]
2013-02-19 05:22:29 -08:00
Alexander Ljungberg a63f185ba9 Refs #1778. Store clockwise parameter with right name.
The name has to match what we ultimately use in CGContextCanvas and CGContextVML.
2013-02-19 11:50:47 +00:00
Alexander Ljungberg 4a0dd80c5a Merge pull request #1778 from ahankinson/partial-fix-issue578
This fix adds a missing `isClockwise` property
2013-02-19 11:38:46 +00:00
Alexander Ljungberg d03ae79092 Merge branch 'refs/heads/master' into slevenbits 2013-02-19 10:49:39 +00:00
Alexander Ljungberg 62c62062e0 Formatting, tighten comparisons. 2013-02-19 10:49:25 +00:00
Andrew Hankinson b9a97931c8 Formatting CGPath.j 2013-02-18 23:26:15 -05:00
Andrew Hankinson 4ec3b5e387 This fix adds a missing isClockwise property
Without this fix, the isClockwise property is not stored for use in CGPathAddPath.

C.F. https://github.com/cappuccino/cappuccino/blob/master/AppKit/CoreGraphics/CGPath.j#L195

This is a partial fix for #578.
2013-02-18 23:02:28 -05:00
Blair Duncan 8eb59d97b2 replaced setContest with setContentDictionary in test
enabled "prepairs content" in xib to show key, key1 etc when added
2013-02-18 22:54:42 -05:00
Blair Duncan 35b54117e0 xib 2013-02-18 17:14:32 -05:00
Blair Duncan aa7a915139 add missing file 2013-02-18 17:08:27 -05:00
Blair Duncan 6d54bfe01f removed the wrong one 2013-02-18 16:59:56 -05:00
Blair Duncan 14dff27b97 decode included and excluded keys from xibs
removed default sort descriptors
2013-02-18 16:53:54 -05:00
Aparajita Fishman ff35b4a4b6 It turns out function.displayName is no longer necessary with the latest Safari, Chrome, FireFox, and even IE 9+. All of them correctly identify the function name. 2013-02-18 16:13:13 -05:00
Blair Duncan 9f15a85c86 decode included and excluded keys from xibs
removed default sort descriptors
2013-02-18 13:32:09 -05:00
Alexander Ljungberg e03622be9c + CPBezierPath bezierPathWithRoundedRect:xRadius:yRadius:. 2013-02-18 18:18:28 +00:00
Aparajita Fishman 3239337c1c CPScroller fixes
- Get the scroller orientation from the xib.
- Fix the nonsensical calculation of _isVertical when given bounds.
- Since orientation comes from the xib, had to re-nib2cib everything to be safe.
2013-02-18 11:03:51 -05:00
cacaodev 9a58efaa07 Merge remote-tracking branch 'upstream/master' into CPTableViewLion 2013-02-18 13:09:46 +01:00
cacaodev 3319f578ba _CPCibCustomView : set the identifier property on the replacement view 2013-02-18 13:05:12 +01:00
cacaodev 3e942dbdbd Added CPCib import in CPTableView.j
Fix warning in NSNib.j
2013-02-18 12:59:47 +01:00
Randall Luecke 5427e9a402 Fixed column drag and drop in the tableview. 2013-02-18 04:00:40 -05:00
Aparajita Fishman 4a09feed59 Make sure cursor is reset before calling event handlers, misc. formatting 2013-02-18 03:34:42 -05:00
Blair Duncan 7ff8bda52a CPDictionaryController initial commit 2013-02-18 01:04:59 -05:00
Aparajita Fishman 1c6d2f7fa4 Don't change the platform window's title unless the Cappuccino window is full platform. 2013-02-18 00:43:37 -05:00
Randall Luecke 041f21d117 Small fix to the CPWindow docs so we dont suggest using "window" as a param name. 2013-02-17 15:23:03 -05:00
Randall Luecke f4ba2d68cd Cache the scroller used by the class methods to get the various theme values.
-scrollerOverlay is called in -reflectScrolledClipRect and creating this new
object is VERY expensive, according to my profiling.

This should speed up scrolling across the board!
2013-02-17 02:09:07 -05:00
Blair Duncan 20263e44ba CPPasteboard availableTypeFromArray fix issue #1683 2013-02-16 19:09:41 -05:00
Aparajita Fishman 347270a8b8 Formatting 2013-02-16 18:09:04 -05:00
aparajita 29dd685377 Merge pull request #1772 from BlairDuncan/mainMenuBarFix
main menubar looping cursor navigation
2013-02-16 15:06:05 -08:00
cacaodev fa008c988c Add CPTrace.j and fix import in TableCibTest (a test using the old API) 2013-02-16 23:48:39 +01:00
cacaodev 9a472731d8 Typo, symlinks 2013-02-16 23:41:12 +01:00
Blair Duncan 9c4317783b main menubar looping cursor navigation 2013-02-16 17:26:19 -05:00
Aparajita Fishman fc4d347fa1 Fixed circular import. 2013-02-16 16:57:56 -05:00
Aparajita Fishman 9c408bcf5a Ahem…Javascript object keys are literals, even without quotes! 2013-02-16 16:57:35 -05:00
Aparajita Fishman 30aa6549ec Formatting 2013-02-16 16:56:27 -05:00
cacaodev ba4e3bab5c Theme descriptors: editable textfields on a selected data view should not have a white text color 2013-02-16 19:33:51 +01:00
cacaodev 3fd39ea0c8 Code formatting, cleaned zombie outlets, added outlets to the CPTableCellView owner 2013-02-16 19:00:44 +01:00
Aparajita Fishman b6008b4870 Optimization 2013-02-16 11:20:57 -05:00
Aparajita Fishman dc7e95bbff Don't set default placeholders 2013-02-16 07:45:47 -05:00
Aparajita Fishman f1e4ac4112 Merge branch 'master' of github.com:cappuccino/cappuccino 2013-02-16 07:44:32 -05:00
Aparajita Fishman cf867cf3b6 Add charset to <head> 2013-02-16 07:43:27 -05:00
Antoine Mercadal 6673823a74 Merge pull request #1694 from mrcarlberg/nib2cib_allow_themed_height_on_checkbox_and_radio
nib2cib allows CPCheckBox and CPRadio to have themed height
2013-02-15 22:49:22 -08:00
Antoine Mercadal 46022b0588 Merge branch 'master' of https://github.com/cappuccino/cappuccino 2013-02-15 22:29:20 -08:00
Aparajita Fishman db771960f3 Formatting, factoring code 2013-02-15 23:47:01 -05:00
Aparajita Fishman 2c4f3d7928 Merge branch 'master' of github.com:cappuccino/cappuccino 2013-02-15 21:17:51 -05:00
Aparajita Fishman 9ae851958a IE 9+ supports opacity 2013-02-15 21:17:39 -05:00
aparajita 953bb0e936 Merge pull request #1769 from ahankinson/nib2cib-aristo2-circularslider
Fix theme issue with circular slider
2013-02-15 17:41:32 -08:00
Andrew Hankinson 821938ac9a Decode keys from XIB file 2013-02-15 19:19:53 -05:00
Andrew Hankinson 1fee41d5d0 Merge branch 'nib2cib-cpbrowser-compat' of github.com:ahankinson/cappuccino into nib2cib-cpbrowser-compat 2013-02-15 17:40:14 -05:00
Andrew Hankinson d3a0c57aca Merge branch 'refs/heads/master' into nib2cib-cpbrowser-compat 2013-02-15 17:40:01 -05:00
Andrew Hankinson 1fb33bf7cb Fix theme issue with circular slider
Refer to #1733 for more information
2013-02-15 17:15:49 -05:00
Antoine Mercadal ca339f32d5 Improve menu bar by removing the small arrow 2013-02-15 13:45:22 -08:00
Aparajita Fishman 54cc6a1e0c Be a little less stupid. 2013-02-15 13:35:05 -05:00
Aparajita Fishman 709eaf1a43 Added missing location variable 2013-02-15 13:03:45 -05:00
Aparajita Fishman abaa1e81f2 Support for multiple-value bindings
- CPView and subclasses support multiple-value hidden bindings.
- CPControl and subclasses support multiple-value enabled bindings.
- CPWindow and CPBox support multiple-value title with pattern bindings.
- CPButton supports multiple argument + target bindings.
- CPImageView and CPTextField support multiple-value editable bindings.
- CPMenuItem supports multiple-value enabled bindings.
- Fixed bugs in CPObjectController with simple collection operators.
- CPColorWell uses black as the placeholder color.
- Runtime object attributes from a cib are applied as they are read, not deferred.
- NSNumberFormatter now reads the number style from the xib.
- Normalized some parameter names.
- Formatting.
- Test app for all binding types.
2013-02-15 12:21:13 -05:00
aparajita c3d565c7e5 Merge pull request #1765 from BlairDuncan/pngSystemCursors
pngs of cursors missed in last commit
2013-02-14 22:29:27 -08:00
Blair Duncan 737a8323f2 pngs of cursors missed in last commit 2013-02-14 22:28:51 -05:00
aparajita 9919a30a72 Merge pull request #1764 from BlairDuncan/pngSystemCursors
Custom system cursors to use sprited png's for non IE browsers
2013-02-14 18:23:07 -08:00
Blair Duncan 055d43eb23 Custom system cursors to use sprited png's for non IE browsers 2013-02-14 16:35:30 -05:00
aparajita 2425c8c5d3 Merge pull request #1614 from cacaodev/CPDictionary-initWithObjectsAndKeys
CPDictionary -initWithObjectsAndKeys: do not treat a nil value as a final value
2013-02-14 11:39:21 -08:00
aparajita 3e1a9434db Merge pull request #1717 from daboe01/master
fix for scrollwheel in FF>3 (issue #1244)
2013-02-14 09:12:04 -08:00
cacaodev 4408e480dd Minor test app improvements: copy cursor, 2nd collection view: fix mask & enable selection and dragging. 2013-02-14 16:13:08 +01:00
Alexander Ljungberg 80d5bf4458 Merge branch 'master' of github.com:cappuccino/cappuccino 2013-02-13 23:10:22 +00:00
Alexander Ljungberg 71f6e9ac52 Refs #1757. Improve fix. 2013-02-13 23:09:24 +00:00
cacaodev 4791973b02 If maxNumberOfRows == 0 (the default), ignore maxNumberOfRows 2013-02-13 23:54:02 +01:00
Alexander Ljungberg d82c0a5e0e Merge pull request #1757 from BlairDuncan/textFieldFix
Fix for textfield propogating command N [+1]
2013-02-13 22:45:07 +00:00
Antoine Mercadal 26890ebe44 Merge branch 'master' of https://github.com/cappuccino/cappuccino 2013-02-13 11:39:08 -08:00
Alexander Ljungberg ed73fa12b1 Refs #1757. Add a toggle-able text field to CPDocumentControllerTest to facilitate of testing of text fields effect on Cmd-N accelerator.
In my testing, the presence or enabled state of the text field appeared to have no effect. In Safari cmd-n always worked, in Chrome it never worked.
2013-02-13 19:26:13 +00:00
Alexander Ljungberg 1022029bd9 Merge pull request #1758 from cacaodev/CPCollectionView-issue1755
CPCollectionView Issue 1755:
2013-02-13 18:53:34 +00:00
cacaodev 108042c190 Merge remote-tracking branch 'upstream/master' into CPTableViewLion
Conflicts:
	AppKit/CPTableView.j
	Tests/Manual/TableTest/TableCibTest/AppController.j
2013-02-13 19:27:53 +01:00
daboe01 1f19e028d5 CPWebView scrollwheel fix 2013-02-13 19:07:06 +01:00
cacaodev 21b5eade71 CPCollectionView Issue 1755:
Create the drop indicator in mouseEntered if needed. This is the case where the collection view is a drop destination but not a drag source.
In _updateDragAndDropStateWithDraggingInfo... , handle the special case where the drop destination is 0 (includes item count == 0).
Test app: add an empty collection view acting as a drop destination for the first collectionView.
2013-02-13 17:47:27 +01:00
Alexander Ljungberg 2ddb858647 Refs #1678. Minor tweak. 2013-02-13 15:04:08 +00:00
Alexander Ljungberg 13ede53195 Merge pull request #1678 from mrcarlberg/scroll_rect_to_visible
Fixed scrollRectToVisible in CPView
2013-02-13 14:52:54 +00:00
Blair Duncan 06bd951d71 Fix for textfield propogating command N introduced and discussed on commit 782f47a 2013-02-13 09:38:07 -05:00
Alexander Ljungberg b59440584d Fixed: new file API test caused 'Cannot find function setAttribute in object [object Object]' unit test error. 2013-02-13 13:56:28 +00:00
Alexander Ljungberg 3ba0f58738 Travis no longer has the jdk_switcher so let's try without.
Maybe it'll work with the JDK 7 fix.
2013-02-13 13:01:38 +00:00
Stefan EilersandAlexander Ljungberg 61b19a1df5 Fix "jake release" 2013-02-13 12:24:58 +00:00
Aparajita Fishman 76ff2a4492 Added a totally gnarly example of how to do complex custom data views using Xcode and bindings 2013-02-13 00:08:10 -05:00
Aparajita Fishman 5a558a9d50 Eliminated the "SomethingElse" framework that no one actually removes, declared theWindow as an @outlet to make XcodeCapp happy. 2013-02-13 00:07:04 -05:00
Aparajita Fishman fa83ba816b Fixed missing ivar and updated url 2013-02-13 00:05:42 -05:00
Aparajita Fishman 1b948b584f CPProgressIndicator fixes
- Make height 20px, same as in Xcode, so we can actually lay them out correctly without guessing. And they were just too tall at 25px anyway.

- In case the height does change in the future, calculate the correct height from the theme in NSProgressIndicator.

- Updated the theme descriptor to include the default height.

- Updated Aristo 2 PSD progress indicator artwork.

- Moved init of CPProgressIndicatorSpinningStyleColors out of layoutSubviews, it is file global and only needs to get done once.
2013-02-12 22:35:45 -05:00
Aparajita Fishman 6472ac7701 Formatting, import fixes 2013-02-12 22:29:31 -05:00
Aparajita Fishman 498f494961 Added valueForBinding: 2013-02-12 15:03:33 -05:00
aparajita dc97b638cf Merge pull request #1752 from cacaodev/CPColorWell-binder
Use appropriate subclassing in CPColorWellValueBinder
2013-02-12 11:58:56 -08:00
Aparajita Fishman c0d01ec752 DRY! 2013-02-12 14:44:26 -05:00
Aparajita Fishman 8b17b52575 value and isIndeterminate binding support for CPProgressIndicator 2013-02-12 14:36:10 -05:00
cacaodev b91b85a0b2 Use appropriate subclassing in CPColorWellValueBinder 2013-02-12 20:15:15 +01:00
Alexandre Wilhelm b6a7615d8f Fixed bug about the offset of a pullsdown CPPopUpButton close #1053 2013-02-12 11:06:39 -08:00
Alexander Ljungberg 1e6c7fa6d0 Fixes #1749. Fix CPGradient error introduced by 08ad614. 2013-02-12 16:41:54 +00:00
Aparajita Fishman c67b212538 Changed PLATFORM_FEATURE to an array, we ran out of bits, added CPFileAPIFeature test 2013-02-12 04:01:06 -05:00
Aparajita Fishman 73d685adf5 Remove stray console.log 2013-02-11 23:42:11 -05:00
Aparajita Fishman e4283e2dc2 CPByteCountFormatterUseDefault doesn't need to be transformed, I'm checking for it in the code 2013-02-11 23:32:11 -05:00
Aparajita Fishman a622f5ca9b Formatting 2013-02-11 23:08:08 -05:00
Aparajita Fishman 12b2bd2c52 Wrong filename in header 2013-02-11 19:46:06 -05:00
Aparajita Fishman aeb42ea4f8 CPByteCountFormatter, a complete implementation of NSByteCountFormatter, with test app 2013-02-11 14:08:41 -05:00
Aparajita Fishman 9d99b5f550 Hardly worth using a #define for something called once 2013-02-11 14:06:31 -05:00
Aparajita Fishman 63ae5848f6 Formatting, fixes for CPDecimal/CPDecimalNumber
- CPDecimalRound should return a result in all cases
- Fixed test of CPDecimalRound with CPDecimalNoScale
2013-02-11 14:05:52 -05:00
Andrew Hankinson 6a74832c8b Formatting for NSBrowser.j 2013-02-11 12:13:33 -05:00
Aparajita Fishman 117dda3bb5 Fix unintended globals 2013-02-11 11:17:19 -05:00
Aparajita Fishman 43817779c5 Ignore CPMenu -itemChanged: when unarchiving menu items 2013-02-11 11:07:37 -05:00
Aparajita Fishman 9af2648b22 Replace nil with CPNull 2013-02-11 11:06:34 -05:00
Aparajita Fishman caed991cb1 Reformat to make it actually readable, fixed a wrong value 2013-02-11 11:05:55 -05:00
Alexander Ljungberg 654cf22f3c Refs #1743. Insert button in ArrayController1 test.
Also clean up test a little by initialising the array controller in the xib and connecting the buttons there. This is more natural.

Also make each object created in the table numbered to make it easier to see which one was just added.
2013-02-11 11:36:38 +00:00
Alexander Ljungberg ff7fdaa251 Merge pull request #1743 from ahankinson/fix-issue1723
Fix for #1723: CPArrayController insert
2013-02-11 11:21:43 +00:00
Alexander Ljungberg 5361b787c5 Merge pull request #1744 from stevegeek/master
Fix for issue #1720
2013-02-11 11:08:47 +00:00
Andrew Hankinson 5830269fea Move variable into initialization. Remove unused variable. 2013-02-10 23:57:47 -05:00
Andrew Hankinson 391abe4991 Merge branch 'refs/heads/master' into nib2cib-cpbrowser-compat 2013-02-10 22:45:31 -05:00
Andrew Hankinson 82605f4170 Cause insert: to behave like Cocoa
This fix inserts a new object at the current index, rather then the next. This diverges from the Cocoa documentation, but follows the Cocoa behaviour.
2013-02-10 20:58:58 -05:00
Aparajita Fishman 2221d40f47 Log if there is a formatter attached to a text field 2013-02-10 20:05:14 -05:00
Andrew Hankinson ab49c63840 Fix for #1723: CPArrayController insert
This fix addresses the following problems:

- fixes a bug with add: where it would try to add the sender object, not the represented object
- changes insert: to insert a new represented object after the currently selected object. If no object is currently selected it behaves like add: and adds a new object to the end.

This patch includes tests.
2013-02-10 20:03:41 -05:00
Aparajita Fishman b6a520e350 Typos, formatting 2013-02-10 20:02:55 -05:00
Alexander Ljungberg a5e1ed44f4 Refs #1734. Include pulldown buttons in pop up button manual test.
These pulldowns are bound the same way as their corresponding regular popups.
2013-02-10 23:12:21 +00:00
Alexander Ljungberg a78d69c89e Merge branch 'aristo2-pulldown-themefix' of https://github.com/ahankinson/cappuccino into ahankinson-aristo2-pulldown-themefix 2013-02-10 23:04:11 +00:00
Alexander Ljungberg 9a7996d40d Fixed: CPPopUpButtonTest using non-existent methods.
There's no `selectedTag` getter for CPPopUpButton (although there's such a binding but that's separate). Also don't call private API that no longer exists - use proper public API instead.
2013-02-10 22:57:43 +00:00
Alexander Ljungberg fb577f8b70 Merge pull request #1741 from ahankinson/fix-issue1633
Fix for #1633: setRepresentedFilename
2013-02-10 22:43:15 +00:00
Andrew Hankinson 933a1be8e1 Fix for #1633: setRepresentedFilename
Without this fix, CPWindow setRepresentedFilename is set as a string, not a CPURL (as specified by the variable type). (With tests)
2013-02-10 17:39:24 -05:00
Alexander Ljungberg 5f99ebefb1 Merge pull request #1739 from ahankinson/fix-issue224-mainmenu
Fix for #224: Remove un-necssary default menu items
2013-02-10 13:22:07 +00:00
Alexander Ljungberg 16c463f612 Merge branch 'master' of github.com:cappuccino/cappuccino 2013-02-10 13:14:09 +00:00
Alexander Ljungberg 3406cdfb02 Refs #1663. Whitespace. 2013-02-10 13:13:54 +00:00
Alexander Ljungberg 69915701de Merge pull request #1663 from BlairDuncan/CPBrowserCursorNavigationFix
Fix for left/right cursors in CPBrowser
2013-02-10 13:09:36 +00:00
Alexander Ljungberg 6f4ef18815 Use an icon that exists in manual CPBrowser test. 2013-02-10 13:09:25 +00:00
Antoine Mercadal ef1c5949f1 Merge branch 'master' of github.mv.usa.alcatel.com:amercada/Cappuccino 2013-02-08 10:36:43 -08:00
Alexander Ljungberg 9a646f856b Merge pull request #1673 from mrcarlberg/handle_null_in_cp_description_of_object
Fixed error in CPDescriptionOfObject when JSON property has null value

Conflicts:
	Foundation/CPObject.j
2013-02-08 12:02:05 +00:00
Alexander Ljungberg 21efb90b4c Refs #1700. Fixed: setItemPrototype crash.
Setting the item prototype without first adding the collection view to a view would cause a crash, as would reloadContent.

This fix makes sure the collection view doesn't try to tile itself unless it has a frame.
2013-02-08 11:46:08 +00:00
Alexander Ljungberg 1248b1fb29 Refs #1700. Fix unknown class or global warnings. 2013-02-08 11:26:56 +00:00
Alexander Ljungberg 8ed85ede2c Refs #1700. Use more macros. 2013-02-08 11:17:45 +00:00
Alexander Ljungberg 6181b75d9f Refs #1700. Make reloadContentCachingRemovedItems: a private method. 2013-02-08 11:02:02 +00:00
Alexander Ljungberg 7b1ffb942f Refs #1700. Clean up and use macros. 2013-02-08 11:01:19 +00:00
Alexander Ljungberg 61990e764c Merge pull request #1700 from cacaodev/CPCollectionViewItem-loading
CPCollectionView -maxItemSize support, content binding, collection view item loading ... [+4]
2013-02-08 10:52:00 +00:00
Andrew Hankinson 9c0c87d4c2 Fix for #224
This commit removes some of the more nonsensical main menu items in the capp NibApplication template.
2013-02-07 23:30:54 -05:00
Alexander Ljungberg 535b8e5fc4 Fixed: orphan token field autocomplete menus.
If the parent or grandparent window of a token field which was showing an autocomplete menu was closed, the menu would stick around even that the token field was gone.

This fix makes the token field autocomplete menu a proper child window which should also ensure it moves as needed if the parent window moves.
2013-02-08 00:42:53 +00:00
Alexander Ljungberg baa69ff3bc Fixed: "cannot read property '_tokenScrollView' of null."
This error could occur when interacting with token fields.
2013-02-08 00:34:25 +00:00
Alexander Ljungberg 4991913f45 Fixes #1716. Fixed: blurry popovers in Chrome. 2013-02-08 00:29:38 +00:00
Aparajita Fishman b28ff18918 Adding missing key 2013-02-08 07:48:41 +08:00
Alexandre Wilhelm c38495de88 Fixed bug with the dividerColor of a standardWindow in Aristo1 2013-02-07 10:56:03 -08:00
Antoine Mercadal 563fb657a4 Change some pixel adjustements to reflect what IB is doing in nib2cib 2013-02-06 17:01:27 -08:00
Alexandre Wilhelm b516f14f57 updated slices of aristo2 2013-02-06 11:16:24 -08:00
Alexandre Wilhelm d0ef3c950b Fixed bug about the border of the dividerColor in a window 2013-02-06 11:15:39 -08:00
Alexandre Wilhelm 67b006f385 Fixed the bug about the dividerColor in a standardView 2013-02-06 10:55:49 -08:00
Alexander Ljungberg cd2b2a4d61 Merge branch 'refs/heads/master' into slevenbits 2013-02-06 16:37:49 +00:00
Alexander Ljungberg e12285ecfa Merge branch 'master' of github.com:cappuccino/cappuccino 2013-02-06 16:37:19 +00:00
Alexander Ljungberg 3a92c013eb Formatting. 2013-02-06 16:37:03 +00:00
Alexander Ljungberg e376f97b46 - CPShadow set. 2013-02-06 16:36:49 +00:00
Alexander Ljungberg 08ad614611 CPGradient drawInBezierPath:angle:. 2013-02-06 16:36:33 +00:00
Alexander Ljungberg d1ebf8d697 Make CPShadow mutable.
This commit adds the various `CPShadow` setters such as `setShadowColor:`.
2013-02-06 15:02:03 +00:00
Alexander Ljungberg 4680f0fcc6 CPGradient initWithStartingColor:endingColor:. 2013-02-06 15:00:58 +00:00
Aparajita Fishman 0892ca1a2d Popovers should not overlap the menu bar
Also eliminated redundant code in CPMenu -menuBarHeight
2013-02-06 19:24:09 +08:00
Antoine Mercadal 27f498f40a fix typo 2013-02-05 18:35:59 -08:00
Antoine Mercadal c8029ee081 Merge branch 'master' of github.mv.usa.alcatel.com:amercada/Cappuccino 2013-02-05 18:24:38 -08:00
Antoine Mercadal b5e6f888d7 Support for project history and quick switch in XCC 2013-02-05 18:24:32 -08:00
Alexandre Wilhelm 66dfcd3700 Merge branch 'master' of github.mv.usa.alcatel.com:amercada/Cappuccino 2013-02-04 16:33:06 -08:00
Alexandre Wilhelm 114cd51971 Removed useless code in layoutSubviews 2013-02-04 16:32:51 -08:00
Antoine Mercadal e4e07b90d9 Merge branch 'master' of https://github.com/cappuccino/cappuccino 2013-02-04 13:09:09 -08:00
Alexandre Wilhelm eb6bade2cf Fixed the bug abouth the sheet shrinking 2013-02-04 13:05:53 -08:00
Alexandre Wilhelm d5cf9e34db Fixed bug about the size of a standardView 2013-02-04 13:05:25 -08:00
Alexander Ljungberg c5c381a034 Merge remote-tracking branch 'stewa/truepredicate-fix'
Conflicts:
	Foundation/CPPredicate/CPPredicate.j
2013-02-04 19:02:49 +00:00
Alexander Ljungberg ee5e6d3239 Merge pull request #1736 from cacaodev/_CPJavaScriptArray-objectsAtIndexes
_CPJavaScriptArray -objectsAtIndexes: implementation.
2013-02-04 17:24:48 +00:00
Alexander Ljungberg 0a8214b4cb Merge branch 'refs/heads/master' into slevenbits 2013-02-04 16:51:29 +00:00
Alexander Ljungberg 6b0565e9ab Fixed: CPBox with CPBezelBorder had unexpected inner shadow.
Without this fix, a CPBoxOldStyle box with a CPBezelBorder would draw with the correct border colour and fill, but with an additional inner shadow, unlike Cocoa.

This fix makes it so that only primary and secondary boxes draw with the special "well"-like shadow style.
2013-02-04 16:39:08 +00:00
Alexander Ljungberg 0fa56cb273 Fixed: in recent CPBox versions, corner radius set in IB was ignored.
Without this fix, setting a corner radius of 0 on a CPBoxCustom resulted in there being a corner radius anyhow.

This fix makes sure to preserve the corner radius, border width and margins for non-primary style boxes.
2013-02-04 16:26:26 +00:00
cacaodev 04026c054b _CPJavaScriptArray -objectsAtIndexes: implementation.
Added speed test in CPArrayPerformanceTest (6x faster).
2013-02-04 17:26:18 +01:00
Alexander Ljungberg 3d9b69a860 Fixed: broken corners on primary CPBox in Chrome.
In Chrome, a primary CPBox (showing the new recessed rounded corner look) had distorted and jagged edges in Chrome due to the clipping mask.

This fix places the clipping mask on integer coordinates which seems to resolve the problem.
2013-02-04 15:40:01 +00:00
Alexander Ljungberg d049d067ab Merge branch 'master' of github.com:cappuccino/cappuccino 2013-02-04 13:00:27 +00:00
Alexander Ljungberg 4e3fb88dba Merge branch 'refs/heads/slevenbits-tokenfield-menu' 2013-02-04 13:00:12 +00:00
Alexander Ljungberg c42184951f Make Aristo 2 tokens balanced for hiding button.
In Aristo 2, the token field tokens would always show the close button, and make a big space for it.

This change makes it so that when the delete button, and the new disclosure button, are hidden, which is most of the time, the token doesn't look like it has a big empty hole on the right side.
2013-02-04 11:57:30 +00:00
Alexander Ljungberg 03e4c49091 Improve token field disclosure arrow implementation.
- Tighten up hover state code.
- CPCoding support.
- Make sure to initialise button type to `CPTokenFieldDisclosureButtonType` rather than null.
- Don't try to lay out disclosure/delete button in the token token.
2013-02-04 11:53:18 +00:00
Alexander Ljungberg 0229e1938e Token field disclosure arrow for menu.
Disclosure arrow behaves like in Cocoa: it shows on hover and if clicked displays the token specific menu.

This change also removes the delete button by default. The delete button can be enabled with `[tokenField setButtonType: CPTokenFieldDeleteButtonType]`.
2013-02-04 01:26:16 +00:00
Alexander Ljungberg 0f6461602e Fixed: crash in token field autocomplete.
Without this fix, the autocomplete field would try to select the CPNotFound index from time to time which has always been wrong but is now specifically an error in Cappuccino.

The fix is to select nothing instead.
2013-02-03 22:39:54 +00:00
Andrew Hankinson 951e439eaf Fix pulldown button theming
Without this fix, the pulldown button style displays using the same right-hand side widget as the popup button. This fix creates a new set of bezel images specifically for the popup button.
2013-02-03 17:17:29 -05:00
Andrew Hankinson 5a226464de Add basic compatibility for CPBrowser
Without this fix, nib2cib fails in converting CPBrowser widgets from Interface Builder.

This should probably be made more robust in the future.
2013-02-03 13:45:22 -05:00
Alexander Ljungberg 49c52a00be Fixed: disappearing token delete button.
The token delete button becomes visible on mouse over of the token in the standard theme. It could be made to disappear even that the mouse was still over the token by mousing over the button itself and then out.

This fix delegates all hover management to the token alone.
2013-02-03 18:40:06 +00:00
Aparajita Fishman a339368023 Use CPWindow_Constants.j instead of @globals 2013-02-03 18:02:27 +08:00
aparajita ef1c2b4f03 Update CONTRIBUTING.md 2013-02-03 16:46:13 +08:00
Aparajita Fishman d8e4769972 Misc. tweaks
- Removed stray console.error
- Made border of tooltips darker, they were almost invisible, even over a white background
- Added CGAlignStroke and CGAlignCoordinate, they are of general use
2013-02-03 08:39:30 +08:00
Alexander Ljungberg 2be644d4b1 Merge branch 'refs/heads/master' into slevenbits 2013-02-02 11:15:29 +00:00
Alexander Ljungberg 1dde5a12c4 Merge branch 'master' of github.com:cappuccino/cappuccino 2013-02-02 11:14:56 +00:00
Alexander Ljungberg f9095ceb74 Fix CPError typos. 2013-02-02 11:14:45 +00:00
Alexander Ljungberg 18d77ca9f7 CPTokenField menu per token support.
This change implements support for the CPTokenField delegate method `tokenField:menuForRepresentedObject:` (and the associated `tokenField:hasMenuForRepresentedObject:`).
2013-02-02 01:28:31 +00:00
Aparajita Fishman b2fa60ae08 Based on further testing, it seems .4 seconds is the Cocoa sticky time 2013-02-02 08:29:54 +08:00
Antoine Mercadal cbaf562c44 Revert back the sticky time to 0.5 2013-02-01 16:24:45 -08:00
Antoine Mercadal 250f255253 Merge branch 'master' of https://github.com/cappuccino/cappuccino 2013-02-01 15:20:55 -08:00
Antoine Mercadal 9a4e7fc467 Merge branch 'master' of github.mv.usa.alcatel.com:amercada/Cappuccino 2013-02-01 15:20:48 -08:00
Antoine Mercadal 351ee1a54e Increase the menu sticky interval to 0.2 2013-02-01 15:20:42 -08:00
Alexandre Wilhelm aa40a039f9 Fixed bug with position of buttons in CPAlert 2013-02-01 14:50:46 -08:00
Alexander Ljungberg 55ec70cbd6 CPError class. 2013-02-01 18:36:03 +00:00
Aparajita Fishman 48d711023e Merge branch 'refs/heads/fix-CPWindow-cluster' into cappuccino 2013-02-01 18:42:18 +08:00
Antoine Mercadal 99c1e890b3 Add theme descriptors for popovers in Arsito2 and make the gradient a little bit whiter 2013-01-31 15:26:02 -08:00
Antoine Mercadal 6b17cd4d9e Add theme descriptors for popovers 2013-01-31 15:25:32 -08:00
Antoine Mercadal 8cbfc79034 makes popover's background and stroke color (both minimal and hud style) themable 2013-01-31 15:25:18 -08:00
Antoine Mercadal b3bf190e10 Reduce the menu sticky interval to 0.1 which improve UX and is more like Cocoa behavior 2013-01-31 13:10:44 -08:00
Antoine Mercadal d83d63b3e6 Remove unused global STICKY_TIME_INTERVAL in _CPMenuWindow.j 2013-01-31 13:09:51 -08:00
Aparajita Fishman 64d1465dfe If an event listener is marked to dequeue, dequeue even if the event does not match the mask
* Note that this does not match the Cocoa documentation, but a whole bunch of event handling code relies on this behavior, so I have to keep it the way it was.
* Fixed dequeue flag in CPApplication -runModalSession:
* Added a window title in CPAlertTest
2013-01-31 16:33:33 +08:00
Antoine Mercadal 952fd59c42 Merge branch 'master' of https://github.com/cappuccino/cappuccino 2013-01-30 17:05:52 -08:00
Antoine Mercadal bfb85ccfd2 Various fixes in CPMenu
- No shadow when hightlighted (like Cocoa)
- Themable separator color/text color/shadow color
2013-01-30 17:04:11 -08:00
Antoine Mercadal 42eb4e2da1 Remove unused and commented layout variables 2013-01-30 17:04:05 -08:00
Aparajita Fishman acc240b669 Missing semicolon 2013-01-31 07:42:06 +08:00
Alexander Ljungberg b07f95c362 Fix WithBindings test.
Fix up imports and re-run nib2cib.
2013-01-30 16:24:06 +00:00
Alexander Ljungberg 181c4ad3c6 Support IBOutlet as a synonym to @outlet.
Without this fix the new compiler would treat IBOutlet as the type and expect the next token to be the ivar name.

This fix make the new compiler treat IBOutlet the same as @outlet.
2013-01-30 15:48:30 +00:00
Alexander Ljungberg 50a586f489 Merge branch 'refs/heads/0.9.7' 2013-01-30 15:46:47 +00:00
Alexander Ljungberg 0821794bcc This will be Cappuccino 0.9.7-alpha1. 2013-01-30 14:52:48 +00:00
Aparajita Fishman 347e9cc811 Move CPWindow+CPDraggingAdditions to CPWindow to avoid circular dependency 2013-01-30 22:36:40 +08:00
Aparajita Fishman 1a26fbf6f4 Rework CPWindow cluster so CPWindow's code is in its file 2013-01-30 22:35:21 +08:00
Alexander Ljungberg fc0689fc3c Revert "Fix Travis paths"
This reverts commit 5b28d5f457.
2013-01-30 13:43:30 +00:00
Aparajita Fishman 5b28d5f457 Fix Travis paths 2013-01-30 21:20:50 +08:00
Alexander Ljungberg da47161e1a Fixed: nib2cib error on case sensitive filesystems.
Before this fix, nib2cib compilation would fail with `require error: couldn't find "OS"`.
2013-01-30 11:52:28 +00:00
Alexander Ljungberg 450081ee3e Fixed: 'cannot run program "ulimit"' error.
When running on certain platforms the `ulimit` command is not available, which would crash the build script.

This change simply refrains from using the `ulimit` command if it's not available.
2013-01-30 11:38:39 +00:00
Alexander Ljungberg e30d54723d Since a too low ulimit aborts the build, it's an error. 2013-01-30 11:35:59 +00:00
Alexander Ljungberg c874efaa24 Merge pull request #1728 from gildegoma/pr-forkable-travis-yml
Fixed: 2 integration problems with Travis CI
2013-01-30 11:17:29 +00:00
Alexander Ljungberg 28473a86dc Merge branch 'master' of github.com:cappuccino/cappuccino 2013-01-30 11:15:10 +00:00
Alexander Ljungberg 57b2d73632 Fixed: undefined location of key events.
Without this fix all regular key events such as `CPKeyDown` would have an undefined location.

Since the location can't be retrieved from the browser on key events, this fix now makes it so that the last seen mouse position is included with each key event.
2013-01-30 11:15:01 +00:00
Stephen Ierodiaconou e17253d592 Fixes for #1720: CPDecimalCompare problems when comparing to zero. 2013-01-30 13:03:43 +02:00
Aparajita Fishman eefec02de4 Fixed tracking event listener test to actually look for tracking events, fixed some method documentation 2013-01-30 18:15:42 +08:00
Gilles Cornu c73a96ef7e Fixed: 2 integration problems with Travis CI
Before this fix:
 * Build PATH has recently changed on Travis CI and hard-coded values in `.travis.yml' were no more valid (the `builds` folder has been renamed as `build`)
 * Any contributor that forked the main project repository had to modify the definition of environment variables in order to integrate with http://travis-ci.org

With this fix cappuccino is correctly configured to be built on Travis CI and makes `.travis.yml` more generic (forkable).
2013-01-30 08:40:24 +01:00
Aparajita Fishman 6e424478f1 Warn users if the ulimit is too low and tell them what to do.
Setting ulimit in narwhal.conf isn't necessary, not all targets need a larger limit. In addition, if the hard limit is 512, it can't be set above that once the terminal session starts.
2013-01-30 12:46:27 +08:00
Alexander Ljungberg e4ff2fe476 Merge branch 'refs/heads/0.9.6' 2013-01-29 23:31:32 +00:00
Alexander Ljungberg ad11967893 Fixed: documentation version number lagging behind. 2013-01-29 23:28:35 +00:00
aparajita 120d726b8e Merge pull request #1727 from slevenbits/slevenbits-child-windows
Child window support + popover fixes
2013-01-29 02:42:06 -08:00
Aparajita Fishman b7d1ccf9b6 Child window/popover fixes
- Added CPWindow -_parentWindowDidOrderInChild to notify a window when it is directly ordered in by a parent.
- Fixed observing of target view frame changes to work in all possible cases.
- Fixed typo in code introduced in last commit in CPApplication -sendEvent.
2013-01-28 12:36:59 +08:00
Aparajita Fishman fdbef474f0 Final fixes for popovers as child windows
- Fixed case where a dangling transition function was left when closing a popover.
- Fixed case where closing a popover, moving the target view, then reopening the same popover would not reposition the popover when resizing the target view's window.
- Optimized repositioning of popover on target view change.
- Implemented transitional popovers via trapped mouse down events.
- Implemented dequeue: argument of CPApplication -setTarget:selector:forNextEventMatchingMask:untilDate:inMode:dequeue: and -setCallback:forNextEventMatchingMask:untilDate:inMode:dequeue:.
- Fixed some child window behavior when ordering/closing.
- Eliminated no longer necessary window close notification in CPPopover.
- Fixed window title in theme so it doesn't dim when window is main but not key.
2013-01-28 09:32:37 +08:00
Alexander Ljungberg b34e24d593 Fixed: mutableArrayValue remove repeat values.
mutableArrayValueForKey: … removeObjectsInArray should remove all instances of the found objects. Without this fix, only the first instance was removed.
2013-01-28 00:31:50 +00:00
Aparajita Fishman c29a54e21a More work on child windows
- Popovers are implemented as child windows.
- Renamed _CPAttachedWindow/_CPAttachedWindowView to _CPPopoverWindow/_CPPopoverWindowView, since that is its only use.
- The default for CPView -acceptsFirstMouse is now NO, per Cocoa. Subclasses override this as necessary.
- _CPWindowView -hitTest returns self it the mouse is within a resize region, which may be outside the window's frame.
- Fixed an off by one bug in CPDomWindowLayer -insertWindow:atIndex:, where inserting a visible window behind a window it is already behind would cause it to move up one from its intended position.
- Updated the ChildWindows and CPPopover test apps.
2013-01-27 10:32:23 +08:00
Aparajita Fishman 25633f03c5 Child window support
- Added child window support with test app
- Miscellaneous cleanup
- Reformatted switches
2013-01-27 10:32:23 +08:00
Aparajita Fishman 7e635fb4ea Change setFullBridge to setFullPlatformWindow 2013-01-27 10:31:17 +08:00
Alexander Ljungberg 0b865da3be Merge branch 'master' of github.com:cappuccino/cappuccino 2013-01-26 12:03:52 +00:00
Alexander Ljungberg 30ae887126 Fix unit tests failing due to recent description changes. 2013-01-26 12:03:28 +00:00
Alexander Ljungberg 75d73d3a5e Format object descriptions like object literals.
This change makes CPDictionary descriptions exactly like Objective-C literals. Later when Objective-J adds support for such literals too, it'll be possible to just copy and paste a CPDictionary description into code.

Also updated CPArray to look similar for consistency.
2013-01-26 12:01:20 +00:00
Aparajita Fishman 0f57683e22 Merge branch 'refs/heads/new-PatternColor' into upstream 2013-01-26 15:52:39 +08:00
Aparajita Fishman 6a7e0ff921 Reworked PatternColor to be a lot smarter, supports much more concise expression of images.
- Removed unused images.
- Renamed slices to make more sense.
- Fixed typos in slice names.
2013-01-26 15:50:07 +08:00
Alexander Ljungberg 237143851d Fixed: KVC array removeObjectsInArray:.
Without this fix, KVCArray could try to remove an out of bounds index at CPNotFound from its target array.

This fix makes it so that only found objects are removed.
2013-01-26 01:18:22 +00:00
Alexander Ljungberg 76e9725e26 Error on adding CPNotFound to an index set. 2013-01-26 01:11:33 +00:00
Antoine Mercadal 1080ace4cd Make the ugly fix for rhino a little bit uglier, but makes build on linux works 2013-01-25 10:11:07 -08:00
Aparajita Fishman 95790d55d5 Object description formatting
- Made CPDescriptionOfObject smarter about detecting CG objects
- CPObject, CPArray, CPDictionary do a better (as in perfect) job of indenting nested objects
- CPDictionary is displayed using Cocoa-style key = value; notation
2013-01-25 19:19:01 +08:00
Antoine Mercadal 2d34d458f4 typo 2013-01-25 01:08:51 -08:00
Antoine Mercadal 331a0a87b1 Small UI Update for error data views 2013-01-25 00:32:41 -08:00
Antoine Mercadal 628a4db746 Improve errors reporting
Errors are now displayed in a data view showing:
 - the file
 - the error message
 - A button that allows you to open the errored file in the default system editor
2013-01-24 23:41:25 -08:00
Antoine Mercadal b44a3c191d Update Nib2CibBaselineAlignementTest 2013-01-24 20:35:03 -08:00
Antoine Mercadal 8f4fdeaa8f Improve CPTextField positioniing in nib2cib 2013-01-24 20:34:06 -08:00
Antoine Mercadal cd0f0e3f01 Readd default content-inset for CPTextField 2013-01-24 20:33:22 -08:00
Antoine Mercadal abb4077c95 Greatly improve CPBoxTest 2013-01-24 19:46:27 -08:00
Antoine Mercadal cc45fb58a8 Compensate box frame in nib2cib 2013-01-24 19:46:08 -08:00
Antoine Mercadal b23cadea59 Fix bugs in CPBox and improve the way we draw lines 2013-01-24 19:45:26 -08:00
Antoine Mercadal f27159f63f Merge branch 'master' of github.mv.usa.alcatel.com:amercada/Cappuccino 2013-01-24 18:41:41 -08:00
Alexandre Wilhelm 53c4dce509 Changed images for cancel button in CPSearchField 2013-01-24 17:25:42 -08:00
Alexandre Wilhelm 1aaab57edc Fixed bug about the left disabled part of segmentedControl 2013-01-24 16:57:55 -08:00
Alexandre Wilhelm 1e004fefcc Updated slices 2013-01-24 16:57:34 -08:00
Antoine Mercadal fb2d2c8e05 Merge branch 'master' of github.mv.usa.alcatel.com:amercada/Cappuccino 2013-01-24 16:15:58 -08:00
Antoine Mercadal 836d8d030c Detect multiple actions with same name 2013-01-24 16:15:37 -08:00
Alexandre Wilhelm 38b772c523 Fixed the bug about the moving of the main window in the showcase 2013-01-24 16:13:01 -08:00
Antoine Mercadal d8f1446e76 Merge branch 'master' of github.mv.usa.alcatel.com:amercada/Cappuccino 2013-01-24 16:07:00 -08:00
Antoine Mercadal f30b3afabd XcodeCapp: parser.j is now using Objective-J 2.0 2013-01-24 16:06:54 -08:00
Alexandre Wilhelm 1656c60dee Changed default size of object. Esclude object from the showcase 2013-01-24 15:59:24 -08:00
Alexandre Wilhelm 0f0b315f3b Fixed bug about the cancel button in CPSearchField (changed the type of the button to CPMomentaryChangeButton) 2013-01-24 15:22:45 -08:00
Alexandre Wilhelm f0bb8ce8a7 Merge branch 'master' of github.mv.usa.alcatel.com:amercada/Cappuccino 2013-01-24 13:55:30 -08:00
Alexandre Wilhelm 899f40d5f5 Fixed bug about CPTableView and CPTableViewSelectionHighlightStyleSourceList in Aristo2 2013-01-24 13:55:20 -08:00
Antoine Mercadal 448d3958a2 Fix bug preventing any failure return. 2013-01-24 13:29:38 -08:00
Antoine Mercadal f36b23bdb2 Merge branch 'master' of github.mv.usa.alcatel.com:amercada/Cappuccino 2013-01-24 11:58:04 -08:00
Alexandre Wilhelm f613f68570 Removed TODO comment 2013-01-24 11:55:24 -08:00
Alexandre Wilhelm 58d069ed7d Fixed bug with hud style 2013-01-24 11:51:06 -08:00
Alexandre Wilhelm 3eca24ed58 Fixed bug about CPSearchField in Aristo1 (missing pictures) 2013-01-24 10:45:36 -08:00
Alexander Ljungberg 8aacdc0502 Merge branch 'master' of github.com:cappuccino/cappuccino 2013-01-24 11:42:10 +00:00
Alexander Ljungberg 1f5920f685 Fix merge error in 1f98dbd.
This error caused some failing tests.
2013-01-24 11:41:59 +00:00
Aparajita Fishman 93fb849296 Import fixes 2013-01-24 19:18:39 +08:00
Antoine Mercadal 98cfe2922a Disable artificial inset for labels in nib2cib 2013-01-23 23:39:44 -08:00
Antoine Mercadal e09627775a Merge branch 'master' of github.mv.usa.alcatel.com:amercada/Cappuccino 2013-01-23 17:58:55 -08:00
Antoine Mercadal 90df913def Add missing import in Aristo2 ThemeDescriptor 2013-01-23 17:58:49 -08:00
Alexandre Wilhelm c1dc40c79b Merge branch 'master' of github.mv.usa.alcatel.com:amercada/Cappuccino 2013-01-23 17:22:16 -08:00
Alexandre Wilhelm c5fbeffa9c Fixed bug with position of the buttons in an alert 2013-01-23 17:22:07 -08:00
Aparajita Fishman 1f98dbdf65 Fixed test cases 2013-01-24 09:01:54 +08:00
Antoine Mercadal 2fdf51d12c Merge branch 'master' of https://github.com/cappuccino/cappuccino 2013-01-23 16:39:00 -08:00
Antoine Mercadal fab6466180 Run nib2cib on some tests 2013-01-23 16:38:29 -08:00
Antoine Mercadal fa708272bc fix nib2cib to correctly place normal, small and mini labels 2013-01-23 16:38:16 -08:00
Antoine Mercadal a9b68f7c39 Remove a default inset of 2.0 for labels 2013-01-23 16:37:33 -08:00
Alexander Ljungberg 6281c6469b Fix unit test warnings. 2013-01-24 00:08:47 +00:00
Alexander Ljungberg 65fd33b9cf Fixed: 64a0fb2 broke CPCharacterSet.
The `cs == nil` to `cs === nil` change introduced by 64a0fb2 was incorrect. Since `CPCharacterSet` is used widely through Cappuccino this broke many unit tests and much functionality.

The fix is to again consider both `nil` and `undefined` as cause for initing a new character set.
2013-01-23 23:33:42 +00:00
Alexander Ljungberg 401a5f7ff7 Clean up. 2013-01-23 22:28:01 +00:00
Alexander Ljungberg 1f0ab2ab49 Fixes #1721. Fixed: bad negative numbers from CPNumberFormatter.
Without this fix, CPNumberFormatter didn't format negative values well. E.g. with thousands separators on it could generate, "-,999.00".

This fix generally improves handling of negative numbers by CPNumberFormatter.
2013-01-23 22:23:50 +00:00
Antoine Mercadal fcad7a7fe4 Fix _CPToolTip.j never properly imported 2013-01-23 10:45:42 -08:00
Antoine Mercadal 98daaf858f Add missing import 2013-01-23 10:45:20 -08:00
Antoine Mercadal 348d689243 If the targetView of attachedWindow has no more window, close the popover instead of trying to reposition it 2013-01-23 10:45:09 -08:00
Antoine Mercadal 4acd11d649 Merge branch 'objj_compiler2' into integ 2013-01-23 10:05:11 -08:00
Aparajita Fishman af47857a47 Fixed missing/circular imports in nib2cib 2013-01-23 23:10:10 +08:00
Martin Carlberg 1280b6e13e Fixed new compiler to load frameworks for the environment that it is building and not for the environment that is running 2013-01-23 15:25:13 +01:00
Aparajita Fishman a7587d631c Oops, missed one 2013-01-23 17:16:36 +08:00
Aparajita Fishman 866e1f00f7 Objj2 compiler fixes
- Each file compiles individually with no errors or warnings.
- Added missing imports.
- Fixed imports to remove circularity.
- Removed unnecessary imports.
- Added missing headers.
- Added missing action_button.png.
- Replace CPMakeRect with CGRectMake.
2013-01-23 15:48:56 +07:00
Aparajita Fishman 4f377bcebe Objj2 compiler fixes
Compiled all files individually:

- Added missing imports.
- Added @class/@global declarations to break circular dependencies.
- Misc. code cleanup.

Conflicts:
	AppKit/CPWindow/_CPWindow.j
	AppKit/Platform/DOM/CPPlatformWindow+DOM.j
2013-01-23 15:48:55 +07:00
Aparajita Fishman 64a0fb278b Objj2 compiler fixes
Compiled all files individually:

- Added missing imports.
- Added @class/@global declarations to break circular dependencies.
- Fixed broken code in CPCharacterSet -hasMemberInPlane:
- Misc. code cleanup.
2013-01-23 15:45:08 +07:00
Antoine Mercadal f8c9466d04 Add other missing imports 2013-01-22 15:47:33 -08:00
Antoine Mercadal ef62191e6b Fix missing imports and @global and @class 2013-01-22 15:44:56 -08:00
Antoine Mercadal e25cee0855 Add missing @class 2013-01-22 13:10:55 -08:00
Antoine Mercadal 94439f0d10 Add new found warnings fixes 2013-01-22 12:47:29 -08:00
Antoine Mercadal 2385f48fe4 Add missing imports 2013-01-22 12:27:19 -08:00
Antoine Mercadal ed98acc906 Add missing header + missing @global 2013-01-22 12:26:30 -08:00
Martin Carlberg 201c7637f6 Fixed new compiler to output better formatted error messages 2013-01-22 15:38:02 +01:00
Martin Carlberg 765b10611b Fixed mouse location in key events and copy event 2013-01-22 10:34:04 +01:00
Martin Carlberg 28a135880d Declared some functions when compiling in rhino 2013-01-22 10:33:36 +01:00
Martin Carlberg 2952812a4b Fixed uninitialized warning message in new compiler when using rhino 2013-01-22 10:32:37 +01:00
Martin Carlberg 6c57c4b1e1 Merge branch 'master' of https://github.com/cappuccino/cappuccino into objj_compiler2 2013-01-22 10:28:36 +01:00
Alexandre Wilhelm 706337d8fa Fixed bug with focused textField 2013-01-21 16:07:00 -08:00
Alexandre Wilhelm d13d9228e8 Updated slices 2013-01-21 16:05:19 -08:00
Alexandre Wilhelm c4492fb1a1 updated images for textFields 2013-01-21 13:54:08 -08:00
Alexandre Wilhelm 6e6d4ebc76 Fixed bug about textFields 2013-01-21 13:52:52 -08:00
Alexandre Wilhelm 3b3aa6b2fe Updated slices 2013-01-21 13:52:32 -08:00
Alexandre Wilhelm 11bad2e474 Fixed bug about the color in focused textField 2013-01-21 11:30:26 -08:00
Antoine Mercadal 556f17969c Update CPComboxBox manual test 2013-01-21 09:33:06 -08:00
Antoine Mercadal a2f40be00e Fix small bug in Aristo2 and CPCombobox 2013-01-21 09:32:51 -08:00
Alexander Ljungberg ce9531c80c Merge tag 'v0.9.6' into slevenbits 2013-01-21 12:43:45 +00:00
Aparajita Fishman cc0503c8a4 Fixed missing import, deprecated CP functions, misnamed ivar 2013-01-21 12:07:03 +07:00
Alexander Ljungberg 5ec9cf7faf Fixed: "in" could not be a parameter in a message.
With the new compiler, messages such as `[a in:b]` could not be sent, the "in:" parameter throwing an unexpected token error. This was true both if "in" was the first argument or any of the subsequent parameters (such as in `[a something:X in:Y]`).
2013-01-21 02:11:51 +00:00
Alexander Ljungberg cc05df412e Fixed: objjc didn't print some errors.
Before this fix, certain errors during compilation such as not being able to load a file, would cause the compilation to fail without stating what went wrong.

This fix prints such errors and avoids crashing later when the result of the compilation is undefined.
2013-01-21 01:08:28 +00:00
Alexander Ljungberg 806c7935c5 Lint. 2013-01-20 19:10:41 +00:00
Alexander Ljungberg e7f0400580 Formatting. 2013-01-20 18:24:48 +00:00
Alexander Ljungberg ad109532be It's enough to read flattensSources once. 2013-01-20 18:09:55 +00:00
Alexander Ljungberg 9dbfa99284 Lint. 2013-01-20 17:14:44 +00:00
Alexander Ljungberg 3c684404ed Eliminate mystery CGPointPointer. 2013-01-20 16:44:40 +00:00
Alexander Ljungberg d818615472 Missing import. 2013-01-20 16:35:48 +00:00
Alexander Ljungberg 06694061d2 Fix nib2cib error introduced by c3d8f4f.
This fixes `- [NSWindowTemplate setFullBridge:] unrecognized selector sent to instance` errors when running nib2cib.
2013-01-20 16:05:06 +00:00
Alexander Ljungberg 75c305ae0f Clean up manual CPBox test. 2013-01-20 16:03:56 +00:00
Alexander Ljungberg cb786a0166 Small CPBox optimisation.
No need to call `setNeedsDisplay:` after `setValue:forThemeAttribute:`.
2013-01-20 13:19:29 +00:00
Aparajita Fishman e292bf01d7 Fixed mouse down within the resize slop outside a window not resizing 2013-01-20 09:13:17 +07:00
Aparajita Fishman 17f07ee888 capp_lint will not flag CPRectEdge, more linking 2013-01-20 07:24:00 +07:00
Antoine Mercadal 51c09a1b02 Merge branch 'CPRuleEditor-fixes' of https://github.com/cacaodev/cappuccino into pr-1718 2013-01-19 11:48:18 -08:00
cacaodev fe7befa845 Fix missing @end 2013-01-19 17:11:11 +01:00
cacaodev eca5ef6f84 Fix textfield in rules croped 2013-01-19 17:08:34 +01:00
cacaodev c023a38544 Remove unused code 2013-01-19 17:07:11 +01:00
Aparajita Fishman 7c831fa19d capp_lint flags deprecated CPPoint/Rect/Size types/functions
- Changed to corresponding CG types/functions in all files
- Fixed some demo app bugs
2013-01-19 16:51:56 +07:00
Aparajita Fishman 24c0f2aedc Merge branch 'refs/heads/inactive-window'
Conflicts:
	AppKit/Themes/Aristo/ThemeDescriptors.j
	AppKit/Themes/Aristo2/ThemeDescriptors.j
2013-01-19 15:15:51 +07:00
Antoine Mercadal 6170a274d7 Merge branch 'master' of https://github.com/cappuccino/cappuccino 2013-01-18 23:24:22 -08:00
Antoine Mercadal 155796b0e0 Linting Aristo1 2013-01-18 23:24:00 -08:00
Aparajita Fishman 3b7262681c Added inactive state to window title bar
- When a window is neither key nor main the title bar is clearly different
- capp_lint ThemeDescriptors.j
- Renamed some layers in Aristo2 PSD to be more descriptive
- New artwork files for window close buttons
- Removed stray Aristo2 image
2013-01-19 14:20:51 +07:00
Antoine Mercadal 988ab9722c Linting 2013-01-18 23:20:44 -08:00
Alexander Ljungberg 8eae427591 Merge branch 'master' of github.com:cappuccino/cappuccino 2013-01-19 02:27:55 +00:00
Alexander Ljungberg b4fe13dfb1 Merge branch 'refs/heads/0.9.6' 2013-01-19 02:27:43 +00:00
Alexander Ljungberg c0b5ed6b3f New demos repository. 2013-01-19 02:21:12 +00:00
Alexander Ljungberg dfad18e047 New website location. 2013-01-19 02:11:37 +00:00
Alexander Ljungberg 7f93173b33 This will be the final v0.9.6. 2013-01-19 01:00:05 +00:00
Martin Carlberg f435a15b43 Merge branch 'experimental_class_and_global_implementation' of https://github.com/cappuccino/cappuccino into objj_compiler2
Conflicts:
	Tools/capp/Configuration.j
2013-01-18 23:51:36 +01:00
Martin Carlberg 08d5be5ce3 Fixed imports in Tools/capp 2013-01-18 23:49:22 +01:00
Antoine Mercadal c3d8f4f80b Fix bug in NSWindowTemplate.j where using a non existing ivar 2013-01-18 14:46:49 -08:00
Antoine Mercadal bbb8bdb687 Fix other small bugs 2013-01-18 14:38:37 -08:00
Antoine Mercadal 4138a6d6dc Merge branch 'objj_compiler2' into experimental_class_and_global_implementation 2013-01-18 14:35:03 -08:00
Antoine Mercadal 6b172cd3a6 remove useless usage of self. in NSWindowTemplate.j 2013-01-18 14:34:22 -08:00
Antoine Mercadal 86e0282011 Fix nib2cib warnings 2013-01-18 14:29:25 -08:00
Martin Carlberg f1250ae5eb Merge branch 'experimental_class_and_global_implementation' of https://github.com/cappuccino/cappuccino into objj_compiler2 2013-01-18 22:27:54 +01:00
Martin Carlberg 586c9d3139 Fixed "Can't find superclass 'MyClass' <Context File: Accessors>" problem when
compiling accessors to class with superclass in same file.
2013-01-18 21:23:11 +01:00
cacaodev 00fea3e02f nib2cibed example 2013-01-18 20:24:18 +01:00
cacaodev 6a72855de8 Merge remote-tracking branch 'upstream/master' into CPCollectionViewItem-loading 2013-01-18 20:20:06 +01:00
Antoine Mercadal 6b0edaecc6 Move the editable property to _CPRuleEditorViewSlice.j as it is used in this class 2013-01-18 10:38:35 -08:00
Antoine Mercadal a4bfd2c9f7 Add missing imports 2013-01-18 10:38:03 -08:00
Antoine Mercadal 7a419c262e Add missing @class 2013-01-18 10:37:51 -08:00
Antoine Mercadal 40ac3210c4 Add missing import 2013-01-18 10:37:37 -08:00
Antoine Mercadal 3bb9e234d8 Add missing import 2013-01-18 10:37:27 -08:00
Antoine Mercadal 75a4ef99c9 Add some missing globals in CPTextField 2013-01-18 10:37:16 -08:00
Antoine Mercadal 1e4b6b6c49 Add missing import 2013-01-18 10:30:13 -08:00
Antoine Mercadal c9eeab09a1 Add missing import in _CPWindow.j 2013-01-18 10:17:19 -08:00
Antoine Mercadal 1a61fc832e Fix a bug in wrong code order in _CPMenuManager.j making usage of undeclared variable. Also add some missing imports 2013-01-18 10:16:55 -08:00
Antoine Mercadal 1d232fd263 Add missing import in BKShowcaseController.j 2013-01-18 10:03:11 -08:00
Martin Carlberg 197f3665bc Fixed removed import 2013-01-18 17:33:09 +01:00
cacaodev ce62e32dfa Removed isa in CPTableCellView (Objj2 compat). nib2cibed all examples (Aristo2 compat). 2013-01-18 17:28:36 +01:00
cacaodev 2cc3521989 Merge remote-tracking branch 'upstream/master' into CPTableViewLion
Conflicts:
	Tests/Manual/CPOutlineViewCibTest/Resources/MainMenu.cib
	Tests/Manual/TableTest/TableBindings/Resources/MainMenu.cib
2013-01-18 16:57:46 +01:00
Martin Carlberg 6fbab322cf Fixed warning messages in compiler 2013-01-18 14:25:05 +01:00
Martin Carlberg 458fa9d02e Fixed a lot of small bugs found by new warning message from compiler 2013-01-18 14:24:37 +01:00
daboe01 9f85d2bdb3 fix for scrollwheel in FF>3 (issue #1244) 2013-01-17 20:43:37 +01:00
Martin Carlberg ff20822b47 Merge branch 'master' of https://github.com/cappuccino/cappuccino into objj_compiler2_experiment 2013-01-17 18:20:07 +01:00
Aparajita Fishman eff0621966 Formatting 2013-01-17 15:32:53 +07:00
Antoine Mercadal 6aeb6199f7 Restore line 2013-01-16 18:10:46 -08:00
Alexandre Wilhelm 072fac837c Merge branch 'master' of github.mv.usa.alcatel.com:amercada/Cappuccino 2013-01-16 18:06:59 -08:00
Alexandre Wilhelm f1fa185383 Fixed bug about sheet/titled/window 2013-01-16 18:06:42 -08:00
Antoine Mercadal c471bc0f82 Update CPScrollView manual test to be able to switch scroller mode 2013-01-16 14:21:08 -08:00
Alexandre Wilhelm 37e29949ef Merge branch 'master' of github.mv.usa.alcatel.com:amercada/Cappuccino 2013-01-16 14:12:13 -08:00
Alexandre Wilhelm e840e4a547 Fixed bug about the width of legacy scrollView 2013-01-16 14:12:07 -08:00
Antoine Mercadal 82bb9a6008 Remove useless code in simple line CPBox 2013-01-16 13:42:46 -08:00
Antoine Mercadal 15ed959da7 Merge branch 'master' of github.mv.usa.alcatel.com:amercada/Cappuccino 2013-01-16 13:35:07 -08:00
Antoine Mercadal a0f4c46cb5 Add missing import 2013-01-16 13:35:01 -08:00
Alexandre Wilhelm 71d5655ab2 Increased the content-inset left in textField 2013-01-16 11:57:04 -08:00
Alexandre Wilhelm 29d56b63f7 Fixed bug about border in CPBox lineBorder 2013-01-16 11:48:23 -08:00
Alexandre Wilhelm 35f495ef5b Fixed bug about tableview row height in Aristo1 2013-01-16 11:16:04 -08:00
Antoine Mercadal 1006890b6e Add missing import in nib2cib. 2013-01-16 10:50:33 -08:00
Antoine Mercadal 083d7304fd Fix some adjustment of the tokenfields. Still need to tweak a little the image files for the tokens 2013-01-15 10:45:08 -08:00
Antoine Mercadal 2d8f651674 Merge branch 'objj_compiler2' 2013-01-15 10:20:10 -08:00
Antoine Mercadal e8ee370499 Merge branch 'master' into objj2integration 2013-01-15 09:49:25 -08:00
Alexander Ljungberg 6aa62762d6 Merge branch 'master' of github.com:slevenbits/cappuccino into slevenbits 2013-01-15 16:09:35 +00:00
Alexander Ljungberg 18bf69d2f3 Merge branch 'refs/heads/0.9.6' into slevenbits 2013-01-15 16:09:24 +00:00
Alexander Ljungberg 5c3d71258d Merge branch 'master' of github.com:cappuccino/cappuccino 2013-01-15 16:08:49 +00:00
Alexander Ljungberg 519031a10e Merge branch 'refs/heads/0.9.6' 2013-01-15 16:08:40 +00:00
Alexander Ljungberg 821961fc26 Argument check CPIndexSet indexSetWithIndex:.
Without this check, an index set could be initialised with NaN which would later lead to an infinite loop when enumerating the index set.

This error makes the error early and explicit.
2013-01-15 16:08:17 +00:00
Alexander Ljungberg 4021eae002 Fixed: CPApplicationTest.
A recent commit broke it.
2013-01-15 16:06:44 +00:00
Martin Carlberg 0799ce190d Merge branch 'master' of https://github.com/cappuccino/cappuccino into objj_compiler2 2013-01-15 08:48:30 +01:00
Antoine Mercadal a7c4802446 Merge branch 'master' into objj2integration 2013-01-14 18:22:30 -08:00
Antoine Mercadal 094c6fd273 Update Aristo2 to correctly render CPComboxBoxes 2013-01-14 18:22:12 -08:00
Antoine Mercadal 72a601371e Merge branch 'master' into objj2integration 2013-01-14 17:34:36 -08:00
Antoine Mercadal 2a80ad8344 Fix bezel inset of focused textfields 2013-01-14 17:34:09 -08:00
Alexandre WilhelmandAntoine Mercadal 7e502fffe6 Fixed bug in CPStepper for the automatic size of it when calling a static constructor 2013-01-14 15:54:14 -08:00
Antoine Mercadal e5de031423 Merge branch 'objj_compiler2' into objj2integration
Conflicts:
	AppKit/CPWindow/CPWindow.j
2013-01-14 11:43:24 -08:00
Martin Carlberg d064ecd842 Merge branch 'master' of https://github.com/cappuccino/cappuccino into objj_compiler2
Conflicts:
	AppKit/CPWindow/CPWindow.j
2013-01-14 20:39:08 +01:00
Antoine Mercadal c0d33a1a19 Merge branch 'master' into Aristo2
Conflicts:
	AppKit/CPAlert.j
2013-01-14 10:57:03 -08:00
Martin Carlberg e78f211e8a Added @class and @global declaration and will now make a warning if class or global is not declared. 2013-01-14 18:36:39 +01:00
Martin Carlberg 77d66fa0c9 Fix for: Track spaces will take the spaces after the next token instead of the current. Also do "delete" of property instead of setting it to null for cleaner AST tree. 2013-01-13 22:08:42 +01:00
Martin Carlberg a652fdf8d2 Fix for: Track comments will take the comment after the next token instead of the current. Also do "delete" of property instead of setting it to null for cleaner AST tree. 2013-01-13 22:08:29 +01:00
Aparajita FishmanandMartin Carlberg 85481225a3 Use a better error message for missing semicolons, trailing whitespace elimination 2013-01-13 22:06:18 +01:00
Martin Carlberg 6210bd2e6d Merge branch 'master' of https://github.com/cappuccino/cappuccino into objj_compiler2
Conflicts:
	AppKit/CPWindow/CPWindow.j
2013-01-13 22:01:43 +01:00
Antoine Mercadal 7dd7dca99a Update some HUD art files 2013-01-12 13:37:16 -08:00
Antoine Mercadal 48991e6c3b Update some HUD slices 2013-01-12 13:37:05 -08:00
Antoine Mercadal 825d045143 Remove bg in textfield slices 2013-01-12 11:35:11 -08:00
Antoine Mercadal 86593cc0f4 Update art files for textfields 2013-01-12 11:24:18 -08:00
Antoine Mercadal d987bcf0d0 Add missing slices in PSD 2013-01-12 11:24:04 -08:00
Aparajita Fishman 0e82504daf Formatting 2013-01-12 16:57:59 +07:00
Aparajita Fishman 7fdc3abd30 Missing semicolon 2013-01-12 16:24:26 +07:00
Aparajita Fishman 541c351757 Merge branch 'refs/heads/upstream' 2013-01-12 14:46:34 +07:00
Antoine Mercadal c52a72ec90 small update in art files 2013-01-11 18:38:16 -08:00
Aparajita Fishman e464900f8b Merge branch 'key-view-loop'
Conflicts:
	AppKit/CPWindow/CPWindow.j
2013-01-12 09:38:07 +07:00
Antoine Mercadal b82f7061a0 Small fixes in psd 2013-01-11 18:38:04 -08:00
Antoine Mercadal 55d651ad27 Readd missing art file 2013-01-11 18:14:45 -08:00
Aparajita Fishman 94ee1af33b Merge branch 'refs/heads/upstream' 2013-01-12 09:11:48 +07:00
Antoine Mercadal 5239749580 Optimize all images 2013-01-11 18:01:49 -08:00
Antoine Mercadal fe5b6d40ac Update art files 2013-01-11 17:59:27 -08:00
Antoine Mercadal 5fa42279bd CLeanup PSD 2013-01-11 17:59:13 -08:00
Alexandre Wilhelm b7a2ab57cc Updated Aristo1 and 2 2013-01-11 17:39:11 -08:00
Alexandre Wilhelm 78949f3620 Changed the way to theme the head of a window 2013-01-11 17:38:54 -08:00
Alexandre Wilhelm 924bf07950 Added missing picturs for toolbar in Aristo1 2013-01-11 17:16:02 -08:00
Alexandre Wilhelm 181f7acbb8 Changed the attribute theme background selected menu bar to _CPMenuView 2013-01-11 17:13:58 -08:00
Alexandre Wilhelm d331de6683 Merge branch 'Aristo2' of github.mv.usa.alcatel.com:amercada/Cappuccino into Aristo2 2013-01-11 16:27:57 -08:00
Alexandre Wilhelm 41dbc66d24 Added disabled token field 2013-01-11 16:27:43 -08:00
Antoine Mercadal 6230319f63 Merge branch 'Aristo2' of 172.21.51.218:amercada/Cappuccino into Aristo2 2013-01-11 16:14:03 -08:00
Antoine Mercadal b7e768820f Tweak theme 2013-01-11 16:13:51 -08:00
Antoine Mercadal 5dc2595159 Add missing HUD Slices 2013-01-11 16:13:43 -08:00
Antoine Mercadal 919aa2622d Add some HUD art 2013-01-11 16:13:28 -08:00
Alexandre Wilhelm 025c66db7e Fixed disable stepper 2013-01-11 16:01:55 -08:00
Alexandre Wilhelm b3361100da Updated Aristo2 2013-01-11 15:38:58 -08:00
Alexandre Wilhelm e0ffde1614 Fuxed bug with disabled combobox 2013-01-11 15:38:43 -08:00
Alexandre Wilhelm 4bfe607f64 Fixed bug with disabled popup 2013-01-11 15:38:20 -08:00
Alexandre Wilhelm c0cbe8e0ab Fixed bug with disabled knob 2013-01-11 15:37:42 -08:00
Alexandre Wilhelm 1e6d41e113 Fixed bug with disabled CPSegmentedButton 2013-01-11 15:14:01 -08:00
Alexandre Wilhelm 54f0a49281 Merge branch 'Aristo2' of github.mv.usa.alcatel.com:amercada/Cappuccino into Aristo2 2013-01-11 14:10:25 -08:00
Alexandre Wilhelm 618f5360ae Added disbaled textField for Aristo2 2013-01-11 14:10:15 -08:00
Antoine Mercadal 6f8b5afd56 Merge branch 'Aristo2' of 172.21.51.218:amercada/Cappuccino into Aristo2 2013-01-11 14:05:54 -08:00
Antoine Mercadal 6432528d37 Merge branch 'master' into Aristo2
Conflicts:
	AppKit/CPWindow/CPWindow.j
2013-01-11 14:05:27 -08:00
Alexandre Wilhelm b62e2c0b78 Merge branch 'Aristo2' of github.mv.usa.alcatel.com:amercada/Cappuccino into Aristo2 2013-01-11 13:54:27 -08:00
Alexandre Wilhelm f30e846f09 Added theme value to set the position of the buttons relative to the type of window 2013-01-11 13:54:18 -08:00
Alexandre Wilhelm 0a9b4bdc11 Fixed bug in CPAlert theme 2013-01-11 13:53:51 -08:00
Antoine Mercadal 0102e99d3c Show actual progress bar in indeterminate state 2013-01-11 12:28:42 -08:00
Antoine Mercadal 19548c196e Add some missing slices in Aristo2 HUD 2013-01-11 12:25:56 -08:00
Antoine Mercadal 46ee987742 Merge branch 'Aristo2' of 172.21.51.218:amercada/Cappuccino into Aristo2 2013-01-11 12:25:18 -08:00
Antoine Mercadal 34428d82c7 Add missing art files 2013-01-11 12:25:12 -08:00
Antoine Mercadal bab27b8be1 Update Art for HUD progress bar in Aristo2 2013-01-11 12:24:41 -08:00
Alexandre Wilhelm 6d06970c0f Merge branch 'Aristo2' of github.mv.usa.alcatel.com:amercada/Cappuccino into Aristo2 2013-01-11 12:08:53 -08:00
Alexandre Wilhelm c16a965eb7 Added head window Aristo1 2013-01-11 12:08:33 -08:00
Alexandre Wilhelm 5cb7b82415 Added standard window Aristo1 2013-01-11 11:56:48 -08:00
Alexandre Wilhelm 4d9a4267f4 Removed unused images 2013-01-11 11:56:23 -08:00
Antoine Mercadal fdbc7cc585 Add showcase for HUD progress indicators 2013-01-11 11:49:55 -08:00
Martin Carlberg ed6c35a59f Merge branch 'master' of https://github.com/cappuccino/cappuccino into objj_compiler2
Conflicts:
	AppKit/CPWindow/CPWindow.j
2013-01-11 20:40:35 +01:00
Antoine Mercadal eca14a8868 Add missing art files 2013-01-11 11:39:31 -08:00
Antoine Mercadal fc719cb1c2 Backport art for new themable CPProgressIndicator, CPToolbar, CPMenu, CPMenuBar 2013-01-11 11:39:16 -08:00
Martin Carlberg 3dc6a30c4c Code clean up 2013-01-11 20:36:19 +01:00
Martin Carlberg 3e93e180f1 Turn off test case that don't apply to the new compiler 2013-01-11 20:36:12 +01:00
Alexandre Wilhelm 3446f8f6ae Added modal window for Aristo1 2013-01-11 11:33:06 -08:00
Alexandre Wilhelm 541dd9eac7 Added shadow window 2013-01-11 11:19:04 -08:00
Alexandre Wilhelm 62d866b60f Upadted Aristo1 with HUD window 2013-01-11 11:17:07 -08:00
Antoine Mercadal f8f0444503 Add missing @end 2013-01-11 11:02:35 -08:00
Antoine Mercadal 7eaf84d066 Backport Aristo2 descriptors to Aristo1 2013-01-11 11:00:34 -08:00
Aparajita Fishman 95511b5311 Window resize tweak...
- If a window is fixed width or fixed height, then no resize cursor is shown and no resize area is active on the edges that cannot be resized.
- Optimized CG calls in CPWindow.
- Added fixed height window to test app.
2013-01-11 21:56:04 +07:00
Alexander Ljungberg 23817a04e1 Unit test HTTP response header parsing. 2013-01-11 12:28:14 +00:00
Alexander Ljungberg 2b90d6244f Merge branch 'master' of github.com:cappuccino/cappuccino 2013-01-11 11:02:12 +00:00
Alexander Ljungberg 7485c4eb7a New: -CPHTTPURLResponse allHeaderFields.
When a CPURLConnection response is of the CPHTTPURLResponse type, the raw HTTP headers can now be retrieved through the allHeaderFields message.
2013-01-11 10:53:42 +00:00
Antoine Mercadal 317e9881b8 Make text fields bigger in the showcase 2013-01-10 23:11:36 -08:00
Martin Carlberg c4e06bd2f7 Merge branch 'master' of https://github.com/cappuccino/cappuccino into objj_compiler2 2013-01-11 08:09:12 +01:00
Antoine Mercadal fb1532be1c Re-add the BKLearnMore* keys in Info.plist 2013-01-10 23:08:15 -08:00
Martin Carlberg f076b05e7e More information: Shows that the new compiler is used when doing "objjc --help". New output: "Usage (objjc 2.0):…" 2013-01-11 08:06:51 +01:00
Antoine Mercadal 71f502a8e8 Fix some ivar masking in tests 2013-01-10 23:04:12 -08:00
Antoine Mercadal 5e1ac06375 Merge branch 'master' into Aristo2 2013-01-10 22:42:20 -08:00
Antoine Mercadal 341eb26c62 Merge branch 'master' of https://github.com/cappuccino/cappuccino 2013-01-10 22:41:31 -08:00
Antoine Mercadal 18f8294fa9 Update order of variable to tets in assert 2013-01-10 22:40:15 -08:00
Antoine Mercadal 959a8e7594 Add some widgets in the showcase 2013-01-10 22:33:22 -08:00
Antoine Mercadal 4fde060510 readd modified art files 2013-01-10 20:14:45 -08:00
Antoine Mercadal 6da4c54f9e Add Aristo2 HUD art files 2013-01-10 19:49:30 -08:00
Antoine Mercadal ad0e3441a1 Add missing slices for HUD theme 2013-01-10 19:49:05 -08:00
Antoine Mercadal 56e9e436cf Add theme descriptors for rounded buttons 2013-01-10 19:11:48 -08:00
Antoine Mercadal 6fde1e459d Add rounded button artwork 2013-01-10 19:11:35 -08:00
Antoine Mercadal fa314611bc Merge branch 'Aristo2' of 172.21.51.218:amercada/Cappuccino into Aristo2 2013-01-10 18:23:20 -08:00
Antoine Mercadal c34ebfa2e8 Add rounded button theme descriptors 2013-01-10 18:23:08 -08:00
Alexandre Wilhelm c6f0589ed5 Merge branch 'Aristo2' of github.mv.usa.alcatel.com:amercada/Cappuccino into Aristo2 2013-01-10 18:15:03 -08:00
Alexandre Wilhelm 8ffa8b6657 Fixed bug in _CPMenuView 2013-01-10 18:14:56 -08:00
Antoine Mercadal 0a92b98110 Comment out non-implemented HUD descriptors 2013-01-10 18:13:02 -08:00
Antoine Mercadal b6c31757a7 fix a bug in CPWindow using old AppKit resource 2013-01-10 17:55:06 -08:00
Antoine Mercadal 676efe247f make toolbar art pixel perfect 2013-01-10 17:50:51 -08:00
Antoine Mercadal f6defc091c cleanup 2013-01-10 17:50:25 -08:00
Alexandre Wilhelm 8bb779ea9e Merge branch 'Aristo2' of github.mv.usa.alcatel.com:amercada/Cappuccino into Aristo2 2013-01-10 17:32:55 -08:00
Alexandre Wilhelm 18d0cf51ef Removed unused code 2013-01-10 17:32:47 -08:00
Alexandre Wilhelm 8b7b363440 Changed default color 2013-01-10 17:32:22 -08:00
Antoine Mercadal 6ba77c146b Backport Aristo2 changes to Aristo1 2013-01-10 17:26:12 -08:00
Antoine Mercadal 54ab7ea9ee use _CPMenuItemView to get general open/save/new icons 2013-01-10 17:23:22 -08:00
Antoine Mercadal b9c0e96933 Add theme descriptors for new/open/save icons 2013-01-10 17:23:03 -08:00
Antoine Mercadal 41650d58a2 Add new theme attribute to get general open/save/new icons 2013-01-10 17:22:34 -08:00
Antoine Mercadal 3519f4f9c7 Remove unused AppKit resources 2013-01-10 17:07:05 -08:00
Alexandre Wilhelm 991e40e089 Fixed bug about the color of the colorPanel 2013-01-10 16:59:50 -08:00
Alexander Ljungberg 1a54aadff0 Merge branch 'master' of github.com:cappuccino/cappuccino 2013-01-11 00:48:28 +00:00
Alexander Ljungberg 6e3f82299f Add missing source header. 2013-01-11 00:48:18 +00:00
Alexandre Wilhelm 9e845ec580 Updated psd 2013-01-10 16:31:49 -08:00
Alexandre Wilhelm c95fb32d0a Fixed bug with size of highlighted menuItem 2013-01-10 16:31:38 -08:00
Alexandre Wilhelm bfe64ea153 Merge branch 'Aristo2' of github.mv.usa.alcatel.com:amercada/Cappuccino into Aristo2 2013-01-10 16:14:04 -08:00
Alexandre Wilhelm 146d641f97 Updated Aristo2 2013-01-10 16:13:48 -08:00
Alexandre Wilhelm 6a94ea066d Added support for _CPMenuBarWindow theme 2013-01-10 16:13:36 -08:00
Alexandre Wilhelm 477ec44b75 Added support for _CPMenuWindow 2013-01-10 16:12:12 -08:00
Antoine Mercadal 284b00fa78 Add missing import 2013-01-10 15:31:37 -08:00
Antoine Mercadal 0f94ba3d39 Merge branch 'Aristo2' of 172.21.51.218:amercada/Cappuccino into Aristo2 2013-01-10 14:12:15 -08:00
Antoine Mercadal 2e157dd969 Starting to backport new themeable stuff from Aristo2. Missing art will follow 2013-01-10 14:12:09 -08:00
Antoine Mercadal f945845a77 Style fix 2013-01-10 14:11:35 -08:00
Alexandre Wilhelm 457cf98089 Merge branch 'Aristo2' of github.mv.usa.alcatel.com:amercada/Cappuccino into Aristo2 2013-01-10 13:58:20 -08:00
Alexandre Wilhelm ab65b53201 Updated Aristo2 2013-01-10 13:58:12 -08:00
Alexandre Wilhelm 3da4daeed5 Removed unused code 2013-01-10 13:57:57 -08:00
Alexandre Wilhelm f9c5f89595 Added support for _CPMenuItemStandardView 2013-01-10 13:57:32 -08:00
Antoine Mercadal d71947cb63 Remove unused AppKit Resource 2013-01-10 11:57:49 -08:00
Antoine Mercadal cdf29b6c56 Add missing theme descriptors for CPTableView 2013-01-10 11:57:39 -08:00
Antoine Mercadal 73ddadc0f0 Add missing theme attribute in CPTableView 2013-01-10 11:57:17 -08:00
Antoine Mercadal bd8431504d Merge branch 'Aristo2' of 172.21.51.218:amercada/Cappuccino into Aristo2 2013-01-10 11:49:01 -08:00
Antoine Mercadal efcee75f30 Remove unused AppKit resource 2013-01-10 11:48:56 -08:00
Antoine Mercadal b283e05f9c Fix bug in CPButtonTest 2013-01-10 11:48:45 -08:00
Antoine Mercadal d15757755a use themed minus and plus button image in _CPCibResource 2013-01-10 11:47:20 -08:00
Antoine Mercadal b3259e4b49 Add theme for CPButtonBar plus, minus and action button 2013-01-10 11:42:38 -08:00
Antoine Mercadal cebf8d3579 Make image plus, minus and action themable 2013-01-10 11:42:08 -08:00
Alexandre Wilhelm 9451a6a1ec Merge branch 'Aristo2' of github.mv.usa.alcatel.com:amercada/Cappuccino into Aristo2 2013-01-10 11:42:07 -08:00
Alexandre Wilhelm 5d3321839d Updated Aristo2 2013-01-10 11:41:59 -08:00
Alexandre Wilhelm 594458235b Added support for theme in_CPMenuItemMenuBarView 2013-01-10 11:41:41 -08:00
Antoine Mercadal a3273dedc1 Remove unused art 2013-01-10 11:29:33 -08:00
Antoine Mercadal 42824713e3 Add application's menu default icon in theme 2013-01-10 11:29:24 -08:00
Antoine Mercadal 4ad40ee00d Pull menu default icon from theme instead of AppKit resource 2013-01-10 11:28:43 -08:00
Antoine Mercadal ddf33a13cd Use new CPThemeBlend bundle accessor 2013-01-10 11:28:25 -08:00
Antoine Mercadal 4ce8ea9ce9 make CPThemeBlend's bundle property readonly 2013-01-10 11:27:52 -08:00
Antoine Mercadal 5b84fd6e40 Remove unused AppKit resources 2013-01-10 11:15:41 -08:00
Antoine Mercadal d7af63877e Add system cursors in theme 2013-01-10 11:15:19 -08:00
Antoine Mercadal 844ed59dd8 CPCursor will now look in the theme to get system cursors 2013-01-10 11:14:59 -08:00
Antoine Mercadal 35e29a0615 Fix bug introducing during previous merge 2013-01-10 10:38:10 -08:00
Martin Carlberg 7c71cd1f80 The new compiler takes care of hoisted variables 2013-01-10 19:30:34 +01:00
Martin Carlberg 74ad0faffa Merge branch 'master' of https://github.com/cappuccino/cappuccino into objj_compiler2
Conflicts:
	AppKit/CPWindow/CPWindow.j
2013-01-10 19:28:42 +01:00
Antoine Mercadal e13948957c Merge branch 'master' into Aristo2
Conflicts:
	AppKit/CPWindow/CPWindow.j
	AppKit/CPWindow/_CPWindowView.j
2013-01-10 10:24:33 -08:00
aparajita 64915f18ff Merge pull request #1711 from slevenbits/new-window-resize
This commit provides resizing of windows from all sides. The legacy style, which displays a resize thumb in the lower right, can be restored with [CPWindow setGlobalResizeStyle:CPWindowResizeStyleLegacy].
2013-01-10 09:53:07 -08:00
Aparajita Fishman 1f8306d2b3 Hooked up the edit menu 2013-01-11 00:38:43 +07:00
Aparajita Fishman cdc88dbe18 Key view...
- Factored out blur handler from CPTokenField into CPTextField.
- CPTextField will no longer lose focus unnecessarily.
- Changed switch style in CPWindow -sendEvent.
- Added menu bar to KeyViewLoop test app.
2013-01-11 00:18:38 +07:00
Aparajita Fishman b59f96d238 Key view loop enhancements...
- Nested views are now handled recursively as they are in Cocoa.
- Added a nested view test in the test app.
2013-01-10 21:49:54 +07:00
Alexander Ljungberg 110bd20600 Fix return value type. 2013-01-10 11:48:52 +00:00
Martin Carlberg 0d6a962344 Merge branch 'master' of https://github.com/cappuccino/cappuccino into objj_compiler2 2013-01-10 11:22:41 +01:00
Martin Carlberg c192f3b47b Fix to make the Cappuccino framework compile with rhino 2013-01-10 11:21:45 +01:00
Antoine Mercadal 53fa384608 make nib2cib work either with Aristo1 or Aristo2 for dynamic widget adjustment 2013-01-09 20:25:32 -08:00
Antoine Mercadal 1448791fcd Declare default row height 2013-01-09 20:25:02 -08:00
Antoine Mercadal a66a4210c3 Use theme attribute for default row height 2013-01-09 20:24:42 -08:00
Antoine Mercadal b1ffd8d556 Make default row height a theme attribute 2013-01-09 20:24:27 -08:00
Antoine Mercadal 4548696c73 Remove unused AppKit resources 2013-01-09 19:43:12 -08:00
Antoine Mercadal 0d460dd6b1 Add missing art for toolbar item separator 2013-01-09 19:42:31 -08:00
Antoine Mercadal 4333e3da67 Add theme for CPToolbarItemSeparator 2013-01-09 19:41:56 -08:00
Antoine Mercadal 352ccb21ff Make CPToolbarItemSeparator themable 2013-01-09 19:41:22 -08:00
Antoine Mercadal 2ac57642a4 Remove PSD from ressource folder 2013-01-09 19:01:32 -08:00
Antoine Mercadal af1ddf2fc6 Remove unused AppKit Ressources 2013-01-09 18:59:30 -08:00
Antoine Mercadal e23c519fac Merge branch 'Aristo2' of 172.21.51.218:amercada/Cappuccino into Aristo2 2013-01-09 18:58:05 -08:00
Antoine Mercadal 664a31fc87 Remove unused AppKit Resource 2013-01-09 18:57:58 -08:00
Antoine Mercadal cbcc988625 Add theme for CPBrowser 2013-01-09 18:57:45 -08:00
Antoine Mercadal ce33737a38 Make CPBrowser themable 2013-01-09 18:57:18 -08:00
Alexandre Wilhelm f4e243255a Merge branch 'Aristo2' of github.mv.usa.alcatel.com:amercada/Cappuccino into Aristo2 2013-01-09 18:53:37 -08:00
Alexandre Wilhelm 8df8479716 Updated Aristo2 2013-01-09 18:53:23 -08:00
Alexandre Wilhelm f28ac43446 Added support for _CPBorderlessBridgeWindowView.j theme 2013-01-09 18:53:09 -08:00
Antoine Mercadal 263df059a4 Remove another unused AppKit ressource 2013-01-09 18:30:25 -08:00
Antoine Mercadal 64d1e9ca46 Remove unused AppKit ressource 2013-01-09 18:29:56 -08:00
Antoine Mercadal 286ec29f91 Remove unused AppKit ressource 2013-01-09 18:29:18 -08:00
Antoine Mercadal 66ca5c0d34 Merge branch 'Aristo2' of 172.21.51.218:amercada/Cappuccino into Aristo2 2013-01-09 18:26:50 -08:00
Antoine Mercadal 919335b4f5 Remove unused ressource 2013-01-09 18:25:46 -08:00
Antoine Mercadal c5a4b2605c Add missing theme attributes for CPSearchField 2013-01-09 18:25:11 -08:00
Antoine Mercadal 2da0142387 Make find/search/cancel buttons themable 2013-01-09 18:24:41 -08:00
Alexandre Wilhelm 7ba759b08a Updated Aristo2 for toolBar 2013-01-09 18:24:32 -08:00
Alexandre Wilhelm fdd5aa0a5a Removed unused comments 2013-01-09 18:24:06 -08:00
Alexandre Wilhelm 6ee80f6182 Added support for theme 2013-01-09 18:23:09 -08:00
Aparajita Fishman af2e0348c1 More key view loop madness
- It turns out Cocoa DOES recalculate the loop when calling recalculateKeyViewLoop. It does not wait until selectNext/PreviousKeyView is called.
- Cocoa calculates the key view loop for nibs that do not have one, but does not call recalculateKeyViewLoop.
- If there is no first responder and no initial first responder when a window first becomes key, use the first valid key view, not the first geometric key view.
- Made allViews function a method, not sure why it was a function.
- Unit tests now pass.
2013-01-10 09:11:58 +07:00
Alexandre Wilhelm d4bf45a8b8 Moved psd to Artwork 2013-01-09 17:54:07 -08:00
Alexandre Wilhelm d30425b2bd Merge branch 'Aristo2' of github.mv.usa.alcatel.com:amercada/Cappuccino into Aristo2 2013-01-09 17:51:22 -08:00
Antoine Mercadal cff8fbbd79 Remove unused artwork 2013-01-09 17:49:53 -08:00
Antoine Mercadal 8b52c99604 Improve CPImageViewTest to test heavy shadow view too 2013-01-09 17:49:42 -08:00
Antoine Mercadal 5dee254fca Add theme for CPShadowView 2013-01-09 17:49:22 -08:00
Antoine Mercadal 2ab0f494b4 Make CPShadowView themable 2013-01-09 17:49:11 -08:00
Alexandre Wilhelm b4a58b47b3 Updated Aristo2 2013-01-09 17:35:59 -08:00
Alexandre Wilhelm b19450684b Fixed bug with toolBar 2013-01-09 17:34:32 -08:00
Antoine Mercadal 6451e3b3e3 Remove another Ressources not used anymore 2013-01-09 17:04:48 -08:00
Antoine Mercadal 14e2a169e4 Remove unused AppKit Ressources (moved to theme) 2013-01-09 17:03:54 -08:00
Alexandre Wilhelm f809919561 Update Aristo2 2013-01-09 16:02:37 -08:00
Alexandre Wilhelm 68d4b9d2cd Fixed bug with indicator 2013-01-09 16:02:24 -08:00
Alexandre Wilhelm 5e1c6ae30d Added class method for the title height 2013-01-09 16:01:51 -08:00
Alexandre Wilhelm e1ba234a76 Fixed bug about the position of closable buttons. Fixed bug about theme attribute for sheet window 2013-01-09 16:01:18 -08:00
Alexandre Wilhelm b9b84fe692 Improved code. Removed comments 2013-01-09 16:00:28 -08:00
Alexandre Wilhelm a3f5c461c3 Removed comments 2013-01-09 15:59:50 -08:00
Alexandre Wilhelm 91479543fa Removed unused theme attribute 2013-01-09 15:59:17 -08:00
Alexandre Wilhelm 4dfa724972 Removed comments 2013-01-09 15:58:47 -08:00
Alexandre Wilhelm f8e72504e5 Fixed bug with closable button in CPWindow 2013-01-09 14:43:33 -08:00
Alexandre Wilhelm 51d6ba98d7 Updated aristo2 2013-01-09 14:21:53 -08:00
Alexandre Wilhelm 2309e18eb7 Added themable support for shadow window 2013-01-09 14:21:41 -08:00
Alexandre Wilhelm 6ddb891c29 Fixed import 2013-01-09 14:19:56 -08:00
Alexandre Wilhelm 5100f6cb72 Updated psd with slices 2013-01-09 13:14:15 -08:00
Alexandre Wilhelm 73e56d820b Merge branch 'Aristo2' of github.mv.usa.alcatel.com:amercada/Cappuccino into Aristo2 2013-01-09 13:10:15 -08:00
Alexandre Wilhelm 803cbae1dc Updated Aristo2 2013-01-09 13:09:59 -08:00
Alexandre Wilhelm 9b9f877942 Added themable _CPWindowView 2013-01-09 13:09:43 -08:00
Alexandre Wilhelm 0e6df9d299 Added themable _CPDocModalWindowView 2013-01-09 13:09:20 -08:00
Antoine Mercadal 1cbe1cfaeb Merge branch 'master' into Aristo2 2013-01-09 11:59:01 -08:00
Antoine Mercadal 295eedc0b9 Add missing import in NSMenuItem.j 2013-01-09 11:58:42 -08:00
Antoine Mercadal 97a766517b Set content-margin size to zero for CPBox 2013-01-09 10:54:51 -08:00
Alexandre Wilhelm 42868ecbee Merge branch 'Aristo2' of github.mv.usa.alcatel.com:amercada/Cappuccino into Aristo2 2013-01-09 10:35:02 -08:00
Alexandre Wilhelm 4fd4b145d7 Updated Aristo2 2013-01-09 10:34:44 -08:00
Alexandre Wilhelm d5f7dc851e Themable _CPStandardWindowView 2013-01-09 10:34:10 -08:00
Antoine Mercadal 06fae21c76 Merge branch 'master' into Aristo2 2013-01-09 09:55:20 -08:00
Antoine Mercadal 29fe631ce6 small style fix 2013-01-09 09:54:43 -08:00
Andrew Hankinson 40ab25d2a6 Minor formatting changes 2013-01-09 11:30:20 -05:00
Andrew Hankinson 0f9a2dc9d3 Fixed: XCodeCapp reads the user's shell environment
Before this fix, XCodeCapp always ran under /bin/bash, causing problems when trying to source the files from other shells, like /bin/zsh

This fix reads the shell information directly from the user's environment and XCC to run using that shell.
2013-01-09 11:27:47 -05:00
Martin Carlberg 89da16afec Fixed objjc to output compiled source not the input source 2013-01-09 14:58:22 +01:00
Martin Carlberg 1dfc77a4ba Fixed objjc to use new acorn based compiler 2013-01-09 14:12:58 +01:00
Martin Carlberg 4fb8fa1311 Code clean up 2013-01-09 14:03:38 +01:00
Aparajita Fishman 782f47a30b Key view loop fixes/improvements
- Removed unnecessary code at beginning of CPTextField -becomeFirstResponder that might have been a hack to get around a bug I fixed.
- Fixed race condition in setTimeout closure in CPTextField -becomeFirstResponder.
- CPWindow -setInitialFirstResponder now works reliably and follows Cocoa behavior in that if -makeFirstResponder is called with something other than the window before the window is first shown, it will override the initial first responder.
- Like Cocoa, until the first responder is set during window load, the first responder is the window by default, not the content view.
- Optimized search for any view that has a previous/next key view set.
- Sheets can become key windows again.
- CPWindow -recalculateKeyViewLoop now just marks the loop as dirty, per Cocoa docs.
- CPWindow -autorecalculatesKeyViewLoop now behaves per Cocoa, it only has an effect when views are added or removed.
- If the first responder does not have a valid previous/next key view, it does not resign to nil, per Cocoa behavior.
- Code optimization and cleanup.
- Test app (KeyViewLoopTest) that demonstrates various scenarios.
2013-01-09 18:02:07 +07:00
Martin Carlberg 7eba982278 Merge branch 'master' of https://github.com/cappuccino/cappuccino into objj_compiler2 2013-01-09 11:11:45 +01:00
Martin Carlberg df78df5908 Fixed class method that access isa property 2013-01-09 10:37:33 +01:00
Martin Carlberg 0dd98b56bc "self." is only added to instance variables when compiling an instance method 2013-01-09 10:21:16 +01:00
Martin Carlberg 0a573f9da1 Removed unused 6th parameter 2013-01-09 09:29:43 +01:00
Antoine Mercadal 6d43387c55 Remove actually useless chunck of code in NSSearchField.j 2013-01-08 22:23:08 -08:00
Antoine Mercadal ed4094016b Update nib2cib NSSearchField.j to use correct field height 2013-01-08 22:21:51 -08:00
Antoine Mercadal 56100f150d Merge branch 'master' into Aristo2 2013-01-08 18:43:25 -08:00
Antoine Mercadal 6284f29a96 Fix regexp in XcodeCapp parser. Thanks to Andrew Hankinson 2013-01-08 18:43:09 -08:00
Antoine Mercadal 4e06ed80d1 Merge branch 'Aristo2' of 172.21.51.218:amercada/Cappuccino into Aristo2 2013-01-08 18:09:35 -08:00
Antoine Mercadal a0c294f689 Merge branch 'master' into Aristo2 2013-01-08 18:09:24 -08:00
Antoine Mercadal 19f668f4f6 use the [CPPlatformWindow primaryPlatformWindow] to position the tooltips. 2013-01-08 18:09:07 -08:00
Alexandre Wilhelm 02bd640aab Merge branch 'Aristo2' of github.mv.usa.alcatel.com:amercada/Cappuccino into Aristo2 2013-01-08 17:59:29 -08:00
Alexandre Wilhelm 06b1060a45 Fixed bug in scrollview 2013-01-08 17:59:19 -08:00
Antoine Mercadal 0f0dcb9eae Remove old static theme for CPSplitView 2013-01-08 17:22:19 -08:00
Antoine Mercadal 5ec6d571eb Improve theme for CPSplitView 2013-01-08 17:22:10 -08:00
Antoine Mercadal 347de2cb8b CPSplitView is now fully themable 2013-01-08 17:21:32 -08:00
Antoine Mercadal f6a923ad56 remove old non themable CPProgressIndicator art files 2013-01-08 17:09:38 -08:00
Antoine Mercadal 43455ee661 Remove old CPLevelIndicator ressources 2013-01-08 17:06:13 -08:00
Antoine Mercadal 911df72aeb Add theme for CPLevelIndicator 2013-01-08 17:05:58 -08:00
Antoine Mercadal b82225e279 Make CPLevelIndicator themable 2013-01-08 17:05:33 -08:00
Antoine Mercadal bb3cc58ad0 Merge branch 'Aristo2' of 172.21.51.218:amercada/Cappuccino into Aristo2 2013-01-08 16:30:24 -08:00
Antoine Mercadal 804a345fec Merge branch 'master' into Aristo2 2013-01-08 16:29:52 -08:00
Antoine Mercadal 7816510fdf Merge branch 'master' of https://github.com/cappuccino/cappuccino 2013-01-08 16:29:33 -08:00
Antoine Mercadal 50031dbc89 Remove wrong import string 2013-01-08 16:29:06 -08:00
Alexandre Wilhelm 7f05164a7f Merge branch 'Aristo2' of github.mv.usa.alcatel.com:amercada/Cappuccino into Aristo2 2013-01-08 16:24:24 -08:00
Alexandre Wilhelm 52a6806022 Update Aristo2 2013-01-08 16:23:51 -08:00
Alexandre Wilhelm 1a9d47c554 Fixed bug about scroller-width attribute theme 2013-01-08 16:22:49 -08:00
Antoine Mercadal 2c3b3be3ee Adjust menubar height 2013-01-08 15:51:53 -08:00
Antoine Mercadal cdaed50939 Readd Aristo1 build process
Cappuccino will now continue to support Aristo1
By default Aristo2 will be used, unless you add in your Info.plist

<key>CPDefaultTheme</key>
<string>Aristo</string>

In that case Aristo2 will be use.

If you put

<key>CPDefaultTheme</key>
<string>MyCustomTheme</string>

It will use your custom theme as usual from your app's Resource folder
2013-01-08 15:03:14 -08:00
Antoine Mercadal 5a155020e6 Merge branch 'master' into Aristo2 2013-01-08 15:02:50 -08:00
Martin Carlberg 957b34d169 Added the option trackSpaces to attach spacesBefore and spacesAfter properties to AST nodes. 2013-01-08 22:23:34 +01:00
Martin Carlberg 79d2ac0566 Fixed some comments and removed unwanted spaces 2013-01-08 22:19:55 +01:00
Martin Carlberg 547f9ff61f Merge with latest from Acorn master 2013-01-08 22:18:19 +01:00
Martin Carlberg 9f0da2ec41 Fixed spelling error 2013-01-08 22:13:36 +01:00
Alexander Ljungberg 32eafb7708 Fix import. 2013-01-08 18:21:29 +00:00
Alexander Ljungberg c81b8fb3c3 Formatting. 2013-01-08 18:07:15 +00:00
Antoine Mercadal a9be167146 Add missing import 2013-01-08 10:05:25 -08:00
Martin Carlberg c755dc3ed9 Added some more detailed error messages in parser 2013-01-08 17:00:54 +01:00
Martin Carlberg d20fb2039a Missed some lines in manual merge 2013-01-08 14:34:29 +01:00
Martin Carlberg 1c3411f808 Merge remote-tracking branch 'upstream/master' into objj_compiler2
Conflicts:
	AppKit/CPWindow/CPWindow.j
2013-01-08 09:25:54 +01:00
Antoine Mercadal 7357be3c35 Finish Aristo HUD 2013-01-07 20:03:20 -08:00
Antoine Mercadal 5dd1bed913 Add the HUD version of Aristo2 2013-01-07 18:40:34 -08:00
Antoine Mercadal 18eda8aade Add the HUD version of Aristo2 2013-01-07 17:34:43 -08:00
Antoine Mercadal 8e16e6266e Fix a bug where CPURL was not encoding self._baseURL and self._string 2013-01-07 16:04:08 -08:00
Martin Carlberg 8100cdb17f Fixed "Can't find variable: ObjJCompiler" error 2013-01-07 23:13:54 +01:00
Antoine Mercadal 7fa01fa4f3 Merge branch 'master' into Aristo2
Conflicts:
	Tests/Manual/CPPopover/Resources/MainMenu.cib
2013-01-07 13:23:05 -08:00
Martin Carlberg d49e78c43e Removal of old compiler 2013-01-07 20:29:56 +01:00
Martin Carlberg cf46768ac7 Removal of logs 2013-01-07 20:29:45 +01:00
Martin Carlberg cfe718f4ef Handle preprocessor lines like "#pragma" 2013-01-07 20:29:35 +01:00
Martin Carlberg bf32b90702 Allow signed, unsigned, char, short, int and long to be an identifier 2013-01-07 20:29:13 +01:00
Martin Carlberg 9cb14d6db3 Added new faster compiler based on acorn parser 2013-01-07 09:59:10 +01:00
Martin Carlberg 140cf0debe Code cleanup 2013-01-07 09:55:12 +01:00
Aparajita Fishman 45ad5375a2 Full platform windows and popovers can become main 2013-01-07 07:07:27 +08:00
Alexander Ljungberg 259adda77d Merge pull request #1713 from milestinsley/CPBrowserStyleProperty-fix
Improved support for converting CSS properties to their JS equivalent in CPBrowserStyleProperty
2013-01-06 17:31:08 +00:00
Miles Tinsley 964f3fe06d Improved the reliability of CPBrowserCSSProperty by checking for the browser prefix *before* hyphenating the camel-cased string.
This has the added benefit of ignoring unknown/unsupported prefixes, providing the property itself is camel-cased.

For example:

"LinearBackground" -> "linear-background"
"Linear-Background" -> "linear-background"
"linear-background" -> "linear-background"
"fooLinearBackground" -> "linear-background"

and

"WebkitLinearBackground" -> "-webkit-linear-background"
"MozLinearBackground" -> "-moz-linear-background"
etc..
2013-01-06 17:20:37 +00:00
Miles Tinsley 002c49b32f Updated CPBrowserCSSProperty to support camel cased style property names and convert them into valid browser-aware CSS properties. 2013-01-06 16:57:31 +00:00
Alexander Ljungberg d4313be406 Merge pull request #1713 from milestinsley/CPBrowserStyleProperty-fix
Improved support for converting CSS properties to their JS equivalent in CPBrowserStyleProperty
2013-01-06 15:48:49 +00:00
Miles Tinsley 76a4ded128 Improved support for converting CSS properties to their JS equivalent in CPBrowserStyleProperty
For example, the following CSS property names all resolve to the same correct JS equivalent for the current browser:

 * CPBrowserStyleProperty('TransformOrigin') -> 'WebkitTransformOrigin'
 * CPBrowserStyleProperty('transform-origin') -> 'WebkitTransformOrigin'
2013-01-06 13:26:01 +00:00
Aparajita Fishman 8d68e805f4 Fix CPWindow -canBecomeKeyWindow and -canBecomeMainWindow to match Cocoa behavior (and misleading documentation)
Minor code formatting cleanup as well
2013-01-06 16:21:10 +08:00
Aparajita Fishman 7f8d58d457 Merge branch 'refs/heads/new-window-resize' 2013-01-05 11:17:02 +08:00
Aparajita Fishman f1a171a94c Window resize fixes
- Track mouse exit from window resize rect instead of unconditionally setting arrow cursor.
- Don't show the resize cursors for full platform windows.
- Show the resize down cursor if the top of a window is being resized and it has reached the bottom of the menubar.
- Make windows in CPToolbarTest resizable to test resizing behavior with toolbars.
- Added a full platform window and menubar to the test app.
2013-01-05 11:13:53 +08:00
Antoine Mercadal 7e9b12b475 Update and improve CPBoxTest manual test 2013-01-04 18:46:16 -08:00
Antoine Mercadal 63a3a8a731 Use API to set themable attribute in nib2cib for CPBox 2013-01-04 18:45:53 -08:00
Antoine Mercadal c95421f307 Add theme for CPBox (and it's an improved look) 2013-01-04 18:45:28 -08:00
Antoine Mercadal edc62449f6 Make CPBox themable 2013-01-04 18:45:05 -08:00
Antoine Mercadal a7f1192402 Ignore .XcodeSupport folder 2013-01-04 18:22:08 -08:00
Antoine Mercadal 6bbda8a8e7 Merge branch 'Aristo2' of 172.21.51.218:amercada/Cappuccino into Aristo2 2013-01-04 12:21:07 -08:00
Antoine Mercadal 2431dbc16f rerun nib2cib on CPSegmentedControlTest's MainMenu.xib 2013-01-04 12:20:57 -08:00
Antoine Mercadal d87f86b2a4 Adjust CPSegmentedControl height to match new Aristo2 art 2013-01-04 12:20:36 -08:00
Antoine Mercadal 55a0652c2b Merge branch 'master' into Aristo2 2013-01-04 12:15:51 -08:00
Antoine Mercadal 3e6517849e Add manual test for CPSegmentedControl 2013-01-04 12:15:09 -08:00
Antoine Mercadal deacdde521 Fix bug in CPSegmentedControl not reducing his size when removing segments 2013-01-04 12:14:22 -08:00
Alexandre Wilhelm aa1559b159 Added missing images 2013-01-04 11:57:12 -08:00
Alexandre Wilhelm 88dd2f1495 Fixed bug with tokenfield 2013-01-04 11:52:36 -08:00
Alexandre Wilhelm eb2cd75370 Fixed bug in BKShowcasController with popUpButtons size 2013-01-04 10:32:35 -08:00
Alexander Ljungberg a391e2787b Merge branch 'new-window-resize' into slevenbits 2013-01-04 12:07:03 +00:00
Alexander Ljungberg d072f17896 Optimisation. 2013-01-04 11:28:09 +00:00
Alexander Ljungberg 0d31f79f53 Constrain window resize to usable area of platform window. 2013-01-04 11:28:09 +00:00
Aparajita Fishman d9d9ea9804 Merge branch 'new-window-resize' 2013-01-04 15:22:01 +08:00
Aparajita Fishman b869312e4f Finished full window resize support
- The main run loop resets the cursor if it falls outside of all windows during a mouse move.
- Added cursors supported by CSS that are not in NSCursor.
- Code cleanup in CPCursor.
- Cursors now indicate available resize directions if there is a window min/max size.
- Reduced slop to 3, what it is in Cocoa.
- Added a second non-min/max window to the demo.
2013-01-04 15:19:00 +08:00
Aparajita Fishman deb6224cf8 Support for resizing windows on all sides 2013-01-04 15:17:29 +08:00
Alexandre Wilhelm 4757648349 CPAlert can be moved now 2013-01-03 18:34:22 -08:00
Alexandre Wilhelm a1f166942c Added new modal window 2013-01-03 18:14:13 -08:00
Antoine Mercadal 7dbe0c2899 readd removed art.. 2013-01-03 18:01:36 -08:00
Antoine Mercadal 9bc4873721 Update the menubar art 2013-01-03 17:55:06 -08:00
Antoine Mercadal 15005f5754 Update selection color 2013-01-03 16:59:10 -08:00
Antoine Mercadal c959ca9821 Update static art to match Aristo2 2013-01-03 16:51:10 -08:00
Antoine Mercadal 26687226f4 Merge branch 'Aristo2' of 172.21.51.218:amercada/Cappuccino into Aristo2 2013-01-03 15:04:58 -08:00
Antoine Mercadal 408b5b517b Run ImageOptim on all Aristo2 ressources 2013-01-03 15:04:31 -08:00
Alexandre Wilhelm f403699fb2 Fixed bug with content-inset in textField 2013-01-03 14:51:23 -08:00
Alexandre Wilhelm 193b289e8e CPButtonBar Aristo2 2013-01-03 14:46:05 -08:00
Antoine Mercadal 533fd0574a Merge branch 'master' into Aristo2 2013-01-03 14:25:42 -08:00
Antoine Mercadal 48ffdf419f Restore art for ButtonBar 2013-01-03 14:16:50 -08:00
Antoine Mercadal 93e931e2b6 Fix Aristo2 Build process 2013-01-03 13:47:50 -08:00
Alexandre Wilhelm 6561e4f84e Init of Aristo2 2013-01-03 11:22:46 -08:00
Stefan Wallström 24d6e581a6 Fixed: CPPredicate: TRUEPREDICATE didn't work
CPPredicate_BOOL didn't implement any methods necessary for TRUEPREDICATE to evaluate to true.
2013-01-03 11:04:53 +01:00
Alexander Ljungberg 261c0df2e7 Merge branch 'refs/heads/master' into slevenbits 2012-12-31 17:39:14 +00:00
Alexander Ljungberg 2fd6e7432a Merge branch 'refs/heads/window-resize' into slevenbits 2012-12-31 17:39:07 +00:00
Alexander Ljungberg dcdcd8e41a Fixed: CPPanel could not always become the key window.
Without this fix, `CPPanel` followed the same rules as `CPWindow` with regards to becoming the key window. But `CPPanel` is supposed to always be willing to become the key window, as stated in its documentation.

This change makes `CPPanel` always return `YES` for `canBecomeKeyWindow`.
2012-12-31 14:53:04 +00:00
Alexander Ljungberg 24443221f2 Merge pull request #1708 from imageoptimiser/optimised-images
Optimise images (94 KB reduction)
2012-12-27 16:12:46 +00:00
Aparajita Fishman 0d674c3496 Finished full window resize support
- The main run loop resets the cursor if it falls outside of all windows during a mouse move.
- Added cursors supported by CSS that are not in NSCursor.
- Code cleanup in CPCursor.
- Cursors now indicate available resize directions if there is a window min/max size.
- Reduced slop to 3, what it is in Cocoa.
- Added a second non-min/max window to the demo.
2012-12-26 14:54:27 -08:00
Aparajita Fishman a15b24b9be Support for resizing windows on all sides 2012-12-24 08:53:18 -08:00
imageoptimiserandAdam Howard 787dd10c69 Optimised images 2012-12-24 12:10:02 +00:00
Alexander Ljungberg d0988fa5b0 Merge branch 'refs/heads/slevenbits-tokenfield-close-fix' into slevenbits 2012-12-21 17:07:39 +00:00
Alexander Ljungberg b7031f2f77 Unit test token field autocomplete window close. 2012-12-21 16:53:21 +00:00
Alexander Ljungberg 588da9addb Fixed: token field access of DOM in non-DOM apps.
Without this fix, the internal [tokenField _editorValue] would check the DOM input element even if !PLATFORM(DOM), which could potentially crash unit tests and future non DOM implementations.

The fix returns an empty string for non-DOM platforms.
2012-12-21 16:44:35 +00:00
Alexander Ljungberg 8f8f1a0224 Fixed: token field autocomplete menu remaining after window closed.
Without this change, closing the window containing a token field showing an autocomplete menu would result in a detached autocomplete menu hanging around.

This fix checks for window close notifications and makes sure to dismiss the menu if the window closes.
2012-12-21 15:00:20 +00:00
Alexander Ljungberg 9705f1fe28 Commit message guidelines. 2012-12-21 11:25:13 +00:00
Martin Carlberg d5748474d0 Forgot some more lines 2012-12-20 22:55:58 +01:00
Martin Carlberg 2277fb04b9 Missed to commit some stuff for scope handling 2012-12-20 18:19:39 +01:00
Martin Carlberg 78b2d30905 Added better support for scope 2012-12-20 18:01:47 +01:00
Martin Carlberg ed81d75815 Removes #pragma lines 2012-12-20 17:49:23 +01:00
Martin Carlberg ac3a399df3 Set to use new compiler when compiling with jake 2012-12-20 15:20:38 +01:00
Martin Carlberg 619f90c677 Removed debug stuff 2012-12-20 15:20:12 +01:00
Martin Carlberg 0f3d5f4b10 Added support to choose which compiler should be used when compiling in the browser. Default is old compiler but add "ObjJCompilerSetUsedVersion("objj_compiler2");" in the index.html (and/or index-debug.html) to use new compiler in browser. 2012-12-20 14:26:49 +01:00
Martin Carlberg 26be5bf264 Better error message when importing file that is not found 2012-12-20 14:23:54 +01:00
Martin Carlberg 227c696750 Removed circular imports in CPToolbarItem.j 2012-12-20 14:22:09 +01:00
Martin Carlberg b1cec9480e New test cases to test ivar handling in new compiler 2012-12-20 09:37:52 +01:00
Martin Carlberg 982da962e5 Fixed problems due to the removal of with(self) 2012-12-19 23:51:42 +01:00
Alexander Ljungberg 2a11bdb7ef Fixup: previous fix undid penultimate fix. 2012-12-18 00:34:14 +00:00
Alexander Ljungberg 3775c3fb2e Fixed: CPAlert was a CPView.
Before this fix, CPAlert subclassed CPView, causing an API mismatch with Cocoa and exposing unexpected methods in the public API which made no sense for a CPAlert such as autoresizing masks. It also lead to CPAlert mistakingly shadowing _window from its CPView superclass.

This fix makes CPAlert inherit from CPObject as it should. The theming, which needs to be applied to a view, was moved to an internal view.
2012-12-18 00:22:19 +00:00
Alexander Ljungberg cea120945c Fixed: CPAlert sheet crash.
Without this fix, CPAlert windows would not finish closing before sending the `alertDidEnd:returnCode:` delegate message. This would lead to a crash if the delegate method tried to open a new sheet.

This fix makes sure to fully order out the alert sheet before sending the delegate message.
2012-12-18 00:19:04 +00:00
Martin Carlberg 803c8ce6b5 A little code clean up. 2012-12-17 17:14:33 +01:00
Martin Carlberg ca99114b16 Forgot to add one file 2012-12-17 15:12:02 +01:00
Martin Carlberg 897adf27f0 Fixed import statements in nib2cib, bug in load system and some more fixes to test cases 2012-12-17 14:57:18 +01:00
Martin Carlberg fd59efe41f Bug fixes for failing test cases 2012-12-17 11:15:50 +01:00
Martin Carlberg b52217e8a0 Tried to make the import mess a little better. Fixed a lot of bugs. Changed some class names in the test cases. Looks like all the tests are being run in the same space. Has to look into this….. 2012-12-17 00:40:26 +01:00
Martin Carlberg 0280a10832 More changes now when we don't have with(self) 2012-12-16 19:20:59 +01:00
Martin Carlberg c297e926f9 Compiler now works with jake and can compiler the whole Cappuccino framework. A lot of test cases still fail 2012-12-16 17:38:47 +01:00
Martin Carlberg 59fa5c27b6 Added support for new compiler when loading objj files in the browsers 2012-12-15 23:35:36 +01:00
Alexander Ljungberg a202cfbbe9 Skip check-missing-imports in standard jake test to make the load on travis-ci lighter.
"detect-missing-imports" takes a long, long time to run. Since it only emits warnings it can't affect the result of the continuous integration builds.

Until it can be made a little faster it's probably best to run it by hand with `jake check-missing-imports`.
2012-12-15 12:36:00 +00:00
Alexander Ljungberg 848c893b9e Fixed: CPApplicationTest setArguments.
Without this change, CPApplicationTest's manipulation of window.location.hash was ignored by CPApplication in recent versions, since CPApp in a unit test normally does not have access to the window object.

This change makes it so that CPApp does try to access the window object, even in a unit test scenario (non PLATFORM(DOM)).
2012-12-15 11:50:47 +00:00
Alexander Ljungberg 252b8f5ca5 Fixed: [CPApp windows] contained nil.
Before this fix, CPApp tried to add nil to its internal list of windows, even that nil should not be added to a CPArray. Second, that nil was actually returned by [CPApp windows] rather than an expected list of only CPWindow instances.

This fix makes [CPApp windows] return only actual windows, replaces the internal _windows[0] placeholder with CPNull, and ensures this CPNull is never actually exposed outside of the class.
2012-12-15 11:48:15 +00:00
Alexander Ljungberg d82da5d571 Fix 7070fe9b2e. 2012-12-15 01:36:05 +00:00
Alexander Ljungberg 1ebdd8ed8e Try to make travis output more to the point. 2012-12-15 01:32:06 +00:00
Alexander Ljungberg 7070fe9b2e --quiet and --verbose boostrap.sh options.
Without this change, bootstrap.sh outputs a great deal of often superfluous information, like precisely which files are unzipped.

Also, curl and wget display progress information by default.

With this change, by default unzipping is quiet, unless --verbose is specified. curl and wget still display progress information, but --quiet can be specified to prevent this.
2012-12-15 01:31:28 +00:00
Alexander Ljungberg 7b2464a740 Fix tab view test to work after 2758454.
Now that we use layoutSubviews in CPTabView we have to make sure it's called in a unit test scenario.
2012-12-15 01:12:29 +00:00
Alexander Ljungberg e2f19c30f1 Whitespace. 2012-12-15 01:03:52 +00:00
Alexander Ljungberg 5408df40f5 Merge pull request #1698 from ahankinson/travis-ci
Travis CI Integration
2012-12-15 00:46:49 +00:00
Alexander Ljungberg 79894781b1 Merge pull request #1707 from slevenbits/slevenbits-tokenfield-value-fix
Fixed: if any token field was being edited, the object value of all other token fields contained the partial value.
2012-12-15 00:40:07 +00:00
Alexander Ljungberg e798842dee Merge pull request #1706 from slevenbits/slevenbits-tokenfield-scroll-fix
Fixed: token field autocomplete scrollbars unresponsive to mouse.
2012-12-15 00:40:04 +00:00
Alexander Ljungberg 98ff6c1279 Merge pull request #1705 from slevenbits/slevenbits-popover-firefox-fix
Fixed: popoverDidShow in Firefox. New: popover animation support in Firefox, Opera and IE10.
2012-12-15 00:40:02 +00:00
Alexander Ljungberg 59fb04321d Merge pull request #1704 from slevenbits/slevenbits-key-popover-fix
Fixed: CPPopovers could not become key windows in recent versions.
2012-12-15 00:37:28 +00:00
Alexander Ljungberg 81d537fa24 Merge pull request #1703 from slevenbits/slevenbits-editable-tokenfield-fix
Fixed: tokens could be deleted in an non editable token field.
2012-12-15 00:37:23 +00:00
Alexander Ljungberg 6488ab2375 Merge pull request #1702 from slevenbits/slevenbits-settimeout-fix
Allow setTimeout(f) to support some JS libraries such as PDF.js.
2012-12-15 00:37:20 +00:00
Alexander Ljungberg a10f36e3a2 Merge pull request #1701 from slevenbits/slevenbits-tab-view-resize-fix
Fixed: tab views added in IB didn't resize properly.
2012-12-15 00:37:18 +00:00
Alexander Ljungberg 90640b824c Merge branch 'refs/heads/slevenbits-tokenfield-value-fix' into slevenbits 2012-12-14 15:14:15 +00:00
Alexander Ljungberg eed37a0f81 Fixed: if any token field was being edited, the object value of all other token fields contained the partial value.
Without this fix, token fields generally assumed that if there was anything in the shared editor buffer, it belonged to the current field, even if it wasn't the field that was being edited.

With this fix only the token field actually being edited considers the editor contents.
2012-12-14 15:12:44 +00:00
Alexander Ljungberg 252144950a Merge branch 'refs/heads/slevenbits-popover-firefox-fix' into slevenbits 2012-12-13 14:09:18 +00:00
Alexander Ljungberg 0781a4153e Fixed: popoverDidShow in Firefox. New: popover animation support in Firefox, Opera and IE10.
Before this fix, popoverDidShow: would not be sent to popover delegates when the app ran in Firefox due to Firefox now recognising the -webkit-transition property, but not the webkitTransitionEnd event.

Also, before this fix popover animation was only implemented for Webkit based browsers.

This fix resolves that issue and in addition adds full support for animated popovers in all browsers that support CSS transitions. The fix also improves Cappuccino's general support for CSS3 animations.
2012-12-13 14:04:36 +00:00
Alexander Ljungberg 17e49c458e Merge branch 'refs/heads/slevenbits-key-popover-fix' into slevenbits 2012-12-12 18:17:34 +00:00
Alexander Ljungberg 8ec1325aff Fixed: CPPopovers could not become key windows in recent versions.
This prevented text fields and token fields from accepting input when placed in a pop over.

This fix allows the underlying popover window to become the key window.
2012-12-12 18:17:20 +00:00
Alexander Ljungberg 7fbe571e04 Merge remote-tracking branch 'slevenbits/slevenbits-tokenfield-scroll-fix' into slevenbits 2012-12-12 17:50:41 +00:00
Alexander Ljungberg b0051603da Merge remote-tracking branch 'slevenbits/slevenbits-editable-tokenfield-fix' into slevenbits 2012-12-12 17:50:33 +00:00
Alexander Ljungberg 947b116c06 Manual test for non-editable token fields. 2012-12-12 17:50:05 +00:00
Alexander Ljungberg 095858d3d5 Fixed: token field autocomplete scrollbars unresponsive to mouse.
Without this fix, the scroll handle in the token field autocomplete menu could not be moved using the mouse. Only scroll wheel or keyboard based scrolling was possible.

This fix enables regular mouse interaction with the scrollbar.
2012-12-12 17:47:50 +00:00
Alexander Ljungberg 2b1b1ea33b Fixed: CPScrollView setGlobalScrollerStyle: return value. 2012-12-12 17:45:59 +00:00
Alexander Ljungberg 1bed7e7108 Merge remote-tracking branch 'slevenbits/slevenbits-editable-tokenfield-fix' into slevenbits 2012-12-11 17:28:17 +00:00
Alexander Ljungberg bd1f64bfde Only show token delete button on hover, and only when token field is editable.
Before this change the close button showed at all times, even for token fields which weren't even editable.

This change brings us closer to Cocoa in that there's no token delete button most of the time, and just like in Cocoa there are more controls available on hover. (Although in Cocoa there's a disclosure arrow and we have a close button instead.)
2012-12-11 17:27:13 +00:00
Alexander Ljungberg d27e333941 Fixed: tokens could be deleted in an non editable token field.
Prior to this fix, clicking the (X) button on a token would delete the token even if the field was not actually editable.
2012-12-11 17:19:02 +00:00
Alexander Ljungberg c2bf47eca2 Support CPThemeStateEditable for text fields. 2012-12-11 17:15:24 +00:00
Alexander Ljungberg 9035439f61 Fixed: token field first responder flicker when clicking tokens.
Without this change, clicking a token in a first responder token field would cause it to momentarily lose first responder status and then immediately gain it back.

This fix makes it so that tokens never try to become the first responder, resulting in a more stable token field as tokens are selected and deselected.
2012-12-11 16:43:06 +00:00
Alexander Ljungberg 60fd129bd9 Merge remote-tracking branch 'slevenbits/slevenbits-settimeout-fix' into slevenbits 2012-12-11 13:05:43 +00:00
Alexander Ljungberg 77955f4e2b Allow setTimeout(f) to support some JS libraries such as PDF.js.
Without this change some 3rd party JS libraries such as PDF.js, which rely on the nonstandard setTimeout(f), will not operate correctly.

According to MDN the delay argument is required. However browsers seem to treat setTimeout without delay argument the same as a delay of 0. This fix makes it so that Cappuccino apps do the same.
2012-12-11 00:57:42 +00:00
cacaodev 6b7b63dff4 Drop support with drop indicator.
FIXED: undefined _horizontalMargin
Test app: UI for switching uniformSubviewsResizing.
2012-12-08 23:15:41 +01:00
cacaodev dd5bd17e2b Simplify the "layout computing" method and change its name
There is not need to use that much arguments because the result is stored in ivars.
CPCollectionViewItem -copy: set properties correctly even if the collectionView overrides them.
2012-12-08 17:43:53 +01:00
cacaodev 2ab1493d27 Merge branch 'CPCollectionView-dragged-view' into CPCollectionView-dragAndDrop 2012-12-07 16:51:23 +01:00
cacaodev 9a1e75712d test app: CPSelectionIndexesBinding test 2012-12-07 16:51:11 +01:00
cacaodev 4c1ebfbdd4 -setItemPrototype:
Do not cache removed items in -reloadContent when the item prototype changes.

maxItemSize:
    Interpreted as horiz/vertic expandable when zero size and the proto view has a CPViewWidth|HeightSizable. (per cocoa but not documented).
    maxItemSize height support.

Fixed: incorrect position when num items < numberOfColumns.

Rewrote layout engine. Splitted the computation of size, columns count, rows count from the actual layout where we set the frame.
This will help when/if we support insertion/mutation of  -content or view animations.
We can also be more lazy when the computation results stay the same.

Added shared -init. Whitespace cleaning.

CPCollectionviewCibTest:
    Add ability to set the 2 kinds of prototypes, one loading its view from a cib, the other with a view outlet in the same cib.
    Loaded protoype: the bound textfield can commit its value to the model.
    UI for setting maxNumberOfColumns|Rows min|maxItemSize
2012-12-06 19:42:03 +01:00
Andrew Hankinson f5bb8abfe0 Updating paths for integration into mainline cappuccino 2012-12-03 19:24:14 -05:00
Andrew Hankinson a24f33ad93 Add .travis.yml for Travis-CI support 2012-12-03 19:11:35 -05:00
Alexander Ljungberg ad5f0a7f7d Avoid touching the window object in CPApplication of non-DOM apps. 2012-12-03 22:45:53 +00:00
Alexander Ljungberg 2611e867b3 Fixed: ce9534c too negative with canBecomeKeyWindow.
Due to a typo in ce9534c, even standard titled windows returned NO for `canBecomeKeyWindow`. This triggered errors in `CPApplicationTest`.

The fix returns the correct YES for `canBecomeKeyWindow` of titled windows.
2012-12-03 22:44:12 +00:00
Alexander Ljungberg c9434ec4dc Fixed: CPFontManager attempt to access DOM in non-DOM apps.
The DOM access caused `CPFontManagerTest` when executed with rhino.
2012-12-03 22:22:16 +00:00
Alexander Ljungberg 282e96649a Formatting. 2012-12-03 22:21:01 +00:00
cacaodev 34d6d0695f Freeze autoresizingMask
The mask is 0 and cannot be changed.
Cocoa allows any value but ignores them for layout.
2012-11-30 15:01:44 +01:00
cacaodev 524bd52a56 Partially rewrote layout.
it is not optimal but certainly better than the previous  version. A
collection view was unusable when resized through its scroll view.
2012-11-30 15:01:44 +01:00
cacaodev efc5b8faaa Update min/maxItemSize lazylly instead of subclassing -awakeFromCib
Binders can set values before -awakeFromCib. We were too late
and the bound content was not visible.
2012-11-30 15:00:28 +01:00
cacaodev 112c6bd594 CPCollectionView test. Nib test and bindings test.
Bindings:
collectionView CPContentBinding -> arrayController.selectedObjects
prototypeView CPValueBinding -> owner.representedObject
2012-11-30 14:58:52 +01:00
cacaodev 8b5c0fb715 CPCollectionView : Allow the prototype view to be loaded from a cib
With this commit CPCollectionView can load subviews from an external
cib. Outlets, actions and bindings between the view and the
prototype are restaured when the view is loaded.
2012-11-30 14:56:36 +01:00
Martin Carlberg 82337b8baa Merge branch 'master' into scroll_before_focus_text_field
Conflicts:
	AppKit/CPTokenField.j
2012-11-30 14:43:46 +01:00
Alexander Ljungberg d4f9e7cba4 Merge branch 'master' into slevenbits 2012-11-30 00:07:07 +00:00
Alexander Ljungberg 71b93a2b4c Merge pull request #1696 from slevenbits/slevenbits-tokenfield-autocomplete-position
Fixed: token field autocomplete menu placed incorrectly.
2012-11-29 23:51:52 +00:00
Alexander Ljungberg 86b302491a Merge pull request #1695 from slevenbits/slevenbits-tabbing-fix
Fixed: tabbing to token fields.
2012-11-29 23:50:00 +00:00
Martin Carlberg 744f3d70ed nib2cib allows CPCheckBox and CPRadio to have themed height and adjusts it correctly 2012-11-29 15:37:33 +01:00
Alexander Ljungberg e28a78afd3 Merge pull request #1693 from mrcarlberg/nib2cib_correct_height_for_button_subclasses
nib2cib will now adjust to the correct themed height for subclasses of CPButton
2012-11-29 12:34:29 +00:00
Martin Carlberg 7dd034e56c nib2cib will now adjust to the correct themed height for subclasses of CPButton.
For examples CPPopUpButton can get another height then CPButton.
2012-11-29 13:25:53 +01:00
cacaodev b97a07630d CPStepper : Adds binding support for CPValueBinding, CPMinValueBinding, CPMaxValueBinding. Placehoders defaults are minValue, minValue, maxValue.
CPStepperBindings : Example for these bindings. Shows behavior when input is a marker.
2012-11-27 15:52:38 +01:00
Alexander Ljungberg 990aeca0ba Merge pull request #1681 from mockingbird/master
Make all validations by the framework be autovalidations
2012-11-26 23:44:22 +00:00
Alexander Ljungberg 3c5284f081 Merge pull request #1691 from cacaodev/CPBinder-_updatePlaceholdersWithOptions
CPBinder -_updatePlaceholdersWithOptions:  add a reference to the binding.
2012-11-26 23:36:55 +00:00
Alexander Ljungberg db1bf80cd4 Merge branch 'refs/heads/slevenbits-tabbing-fix' into slevenbits 2012-11-26 23:33:30 +00:00
cacaodev da01d3aaaa do it right 2012-11-26 18:31:08 +01:00
Alexander Ljungberg 9d4e8164b7 Fixed: token field autocomplete selection by mouse.
After recent changes clicking on an autocomplete item in the pop up did nothing. Now this works and in conjunction with the new non-key-window-change update it's likely to work better than before.
2012-11-26 15:39:41 +00:00
Alexander Ljungberg ce9534cdea Fixed: canBecomeKeyWindow response for auxiliary windows.
Without this fix Cappuccino always returned YES for `canBecomeKeyWindow` for every window. But in Cocoa, only "standard" windows with a title bar and/or resizing return YES.

With this fix Cappuccino better matches Cocoa's behaviour.
2012-11-26 14:01:33 +00:00
Alexander Ljungberg 2236e7d2da Unused variable. 2012-11-26 13:48:45 +00:00
Alexander Ljungberg 2ea24ed2dc Merge branch 'slevenbits-tokenfield-autocomplete-position' into slevenbits 2012-11-26 13:41:39 +00:00
Alexander Ljungberg abfb23d931 Merge branch 'refs/heads/slevenbits-tab-view-resize-fix' into slevenbits 2012-11-25 18:00:20 +00:00
Alexander Ljungberg 868480ada5 Merge branch 'refs/heads/master' into slevenbits 2012-11-25 17:59:48 +00:00
Alexander Ljungberg 632e226b51 Manual test to demo/test fixed position text with and without bezel. 2012-11-25 11:12:37 +00:00
cacaodev 6c4d1e5ce1 CPBinder _updatePlaceholdersWithOptions : Added forBinding:(CPString)aBinding argument.
If a binder instance can manage several bindings, you may want to set placeholders depending on the binding name.
2012-11-22 15:33:01 +01:00
Alexander Ljungberg 4ef5dc83bb Fixed: token field autocomplete menu placed incorrectly.
If the token field was in a window not placed in the upper left corner of the screen (like regular platform windows are), the autocomplete menu would show up in the wrong spot.
2012-11-19 15:08:17 +00:00
Alexander Ljungberg 9ebc78773d Put half a vertical spacing above the first row of tokens.
This means there'll be 1 px of spacing both above and below tokens in multi-row configurations. It also places the token much better in the field both in single and multi-row configurations, at least for the Aristo theme.
2012-11-19 12:14:28 +00:00
Alexander Ljungberg e2f8d77f67 Fixed: white line when scrolling between tokens.
Without this fix there'd be a white line visible on top of the token field when scrolling between multiple lines of tokens in a short field.

In addition the scroll view was 1 px short which made it possible to scroll tokens up and down by 1 px even when there was only a single row of tokens which should fit in the field.

This fix expands the clip rect upwards by 1 px to bring it all the way up to the first row of bezel pixels, ensuring sure a single row of tokens fits fully in a 1 row token field.
2012-11-19 11:54:05 +00:00
Alexander Ljungberg 256d36320a Fixed: token fields lost first responder status when switching between windows.
E.g. in a two window application, if a token field was the first responder and another window was made active and then the original window made active again, the token field would no longer be the first responder.
2012-11-19 00:40:26 +00:00
Alexander Ljungberg 6bc8ad0e2c Add a token field to attached sheet test for first responder testing in multi window situations. 2012-11-18 22:34:08 +00:00
Alexander Ljungberg fd3ad76db3 Fixed: after tabbing to a token field it'd immediately lose first responder status.
Without this fix, the tab key press would be propagated to the browser, which would blur the focused input element, even when that input element was the one the new first responder intended to use.
2012-11-18 22:32:41 +00:00
Alexander Ljungberg 8a39561ddb Extend tab view test with different tab view types.
Resizing for all tab view types can now be tested by clicking "Cycle Tab View Type" up to 6 times and resizing the window for each mode. (Some modes are not implemented.)
2012-11-18 19:33:58 +00:00
Alexander Ljungberg 27584544d9 Fixed: tab views added in IB didn't resize properly.
IB sets `autoresizesSubviews` to NO for tab views by default. In Cocoa this doesn't make any difference because `NSTabView` ignores this setting.

This fix makes it so that Cappuccino's tab view also works with `autoresizesSubviews` off.
2012-11-18 19:24:13 +00:00
Alexander Ljungberg 8902acba04 Merge branch 'master' into slevenbits 2012-11-17 11:58:46 +00:00
Alexander Ljungberg 788ee6cd90 Merge branch 'master' of github.com:cappuccino/cappuccino 2012-11-17 11:45:20 +00:00
Alexander Ljungberg 97f3ab23b7 Merge pull request #1689 from slevenbits/slevenbits-content-rect-toolbar-fix
Fixed: incorrect `- CPWindow contentRectForFrameRect:` and  `frameRectForContentRect:` for borderless windows with toolbars.
2012-11-17 11:40:53 +00:00
Alexander Ljungberg 074e9f70a0 Fixed: incorrect - CPWindow contentRectForFrameRect: and frameRectForContentRect: for borderless windows with toolbars.
The window views driving non standard windows (such as borderless or bridge windows) did not take the toolbar into account when calculating the content rect.

Apart from being wrong, this could lead to the content view overlapping the toolbar if the content view was set after the toolbar was prepared.

Perhaps the thought was that the base _CPWindowView shouldn't make assumptions about the placement and sizing of a toolbar and leave that up to subclasses, but the _CPWindowView tile method already did.
2012-11-17 10:06:08 +00:00
Antoine Mercadal 621f1f1d61 Merge branch 'master' of https://github.com/cappuccino/cappuccino 2012-11-15 15:33:49 -08:00
Antoine Mercadal ba338036f9 improve CPPopover's popoverDidShow: management
Before, the popoverDidShow: delegate methods was called during the CSS animation (if any)
Problem is that is we are processing big amount of data, the animation may hang for a bit in the middle, giving an impression of jerkiness.

Now, popoverDidShow: is called at the end of the CSS animation if popover is animated.
2012-11-15 15:31:20 -08:00
Alexander Ljungberg 9b9380c18e Merge branch 'refs/heads/master' into slevenbits 2012-11-15 17:15:18 +00:00
Alexander Ljungberg c896101a30 Fixed: a recent internal method rename broke CPTabViewItem setView:. 2012-11-15 10:05:14 +00:00
cacaodev cd22b29ff1 Adds a binded popup to the ViewBasedCib example. 2012-11-14 16:02:05 +01:00
cacaodev 1d8c46216f Do not enqueue editing data views. No need to clean FR and action if it is not enqueued. Clean up corresponding code. 2012-11-13 21:18:20 +01:00
cacaodev b5d70b90d9 Code style following alexander comments 2012-11-13 19:20:49 +01:00
cacaodev 9b03abaeef ViewBasedCib example now uses a separate table delegate, which is the owner of table cell views.
It shows that the loaded view (intenal or external) has an outlet owned by the table delegate and is available for initial setup in -awakeFromCib
2012-11-13 18:52:45 +01:00
cacaodev 8a3d832b4c NSNib.j : use a UUID to create the temp nib file (for safety). Remove ref to NSTableCellView in info message 2012-11-13 18:37:58 +01:00
Alexander Ljungberg 7fab75216f Fixed: text field responder error when using a formatter.
If the formatter rejected a change and prevented the first responder status from being surrendered, the text field would still stop listening to key window changes and break first responder behaviour when switching between windows.
2012-11-13 16:34:47 +00:00
Alexander Ljungberg 6c265fee30 With the NSMatrix->CPRadioGroup change the selectedRadio is easier to get. 2012-11-13 16:31:52 +00:00
cacaodev d2848fc519 Do not search for custom cibs if we are in a cell-based table view 2012-11-13 12:08:37 +01:00
cacaodev 48092bd7ba makeViewWithIdentifier:owner: search for a custom cib in owner's bundle or main bundle if nil. (was main bundle) 2012-11-13 12:05:03 +01:00
cacaodev 5c15ceedc4 Make the cached list of inexistent custom cibs an ivar 2012-11-13 11:57:18 +01:00
cacaodev f568a2407b Merge remote-tracking branch 'upstream/master' into CPTableViewLion 2012-11-13 11:22:03 +01:00
Alexander Ljungberg f1c6a8bc12 Fixed: Error: Permission denied to access property '_childAppIsStarting' in Firefox.
This error would occur when running an app in an iframe which could not access its parent frame.
2012-11-08 17:30:17 +00:00
Antoine Mercadal 0fa499bd61 Makes CPAlert above popovers 2012-10-30 11:09:38 -07:00
Antoine Mercadal c747a79db9 Merge branch 'master' of https://github.com/cappuccino/cappuccino 2012-10-29 16:10:15 -07:00
Antoine Mercadal a1751cc981 Improve Popover's content view resizing 2012-10-29 16:09:09 -07:00
Martin Carlberg 7bf5f6f5a9 Added scrollRectToVisible when CPTokenField becomeFirstResponder 2012-10-27 15:13:57 +02:00
Alexander Ljungberg 797bfeec98 Implement CPPointInRect.
This improves source code compatibility with Cocoa when replacing NS with CP.
2012-10-24 15:35:42 +01:00
Alexander Ljungberg c3c61e1889 - CPBox titleView.
This method is the Cappuccino analog to `- NSBox titleCell`.
2012-10-24 15:32:45 +01:00
Alexander Ljungberg 0d9973abb9 Fixed: out of place table headers and other text positioning errors.
A line breaking, vertically centred or bottom aligned `_CPImageAndTextView` would not properly recalculate text position when the height of the text changed due to the width of the field changing.

This could cause, for example, table header text to be misaligned if the table was initialised with a zero height.
2012-10-23 16:19:11 +01:00
cacaodev 5b1cf49170 Merge remote-tracking branch 'upstream/master' into CPTableViewLion 2012-10-15 14:23:24 +02:00
Saikat Chakrabarti e46cd1478b Fix syntax of validateVisibleItems 2012-10-07 14:45:23 -04:00
Aparajita Fishman 3992ca71c6 Merge branch 'clickedColumn' 2012-10-02 17:20:53 -04:00
Saikat Chakrabarti d718c292f5 Combine the _autovalidate and validateVisibleItems methods. 2012-10-01 21:21:01 -07:00
Aparajita Fishman 3a04bb2957 Merge branch 'refs/heads/upstream' 2012-09-29 05:28:41 -04:00
Aparajita Fishman 1c3300b066 Merge branch 'tag-fix' 2012-09-28 16:21:27 -04:00
Aparajita Fishman b443cb806a Both cells and controls can have tags in IB, control tag should take precedence 2012-09-28 16:13:24 -04:00
Martin Carlberg 182f4c369a Make sure the text field is visible before focus so the browser
will not scroll without the NSScrollView knowing about it
Issue #1675 and maybe a little of issue #1301
This fix will not work without pull
request #1678 - Fixed scrollRectToVisible in CPView
2012-09-28 12:57:13 +02:00
Martin Carlberg 1d1f2d73ca Fixed scrollRectToVisible in CPView:
Earlier it only worked when the receiver was the document view of the clip view.
Added test case.
2012-09-28 12:27:23 +02:00
Martin Carlberg 23401d37d8 Fixed error in function CPDescriptionOfObject when a JSON object property has a null value.
The function can't handle the following JSON object: {name:null}.
Also added a test case for this.
2012-09-14 10:54:41 +02:00
Alexander Ljungberg adbc420e0f Merge branch 'master' into slevenbits 2012-09-04 16:39:20 +01:00
Alexander Ljungberg e95648ca16 Merge branch 'master' into slevenbits 2012-09-03 20:20:52 +01:00
Alexander Ljungberg d0d66227cb Merge branch 'master' into slevenbits 2012-09-03 11:36:33 +01:00
Alexander Ljungberg 9d57d02eb5 Merge branch 'master' into slevenbits 2012-09-02 23:12:16 +01:00
Alexander Ljungberg bc93b3f6c7 Merge branch 'master' into slevenbits 2012-08-31 22:31:58 +01:00
Alexander Ljungberg 63b57b886e Merge branch 'master' into slevenbits 2012-08-31 22:12:16 +01:00
Blair Duncan ada73a16ce Fix for left/right cursors in CPBrowser 2012-08-24 16:01:31 -04:00
Alexander Ljungberg 10f6c8e8f6 Merge branch 'master' into slevenbits 2012-08-16 19:14:36 +01:00
Alexander Ljungberg 7b3136dae3 Merge branch 'master' into slevenbits 2012-08-15 18:32:36 +01:00
Alexander Ljungberg b7ee0fe44d Merge branch 'master' into slevenbits 2012-08-15 13:39:09 +01:00
Alexander Ljungberg 0150271e67 Merge branch 'master' into slevenbits 2012-08-15 02:09:40 +01:00
Alexander Ljungberg e23ba0852b Merge branch 'master' of github.com:slevenbits/cappuccino into slevenbits 2012-08-11 19:36:01 +01:00
Alexander Ljungberg 7cae90f8f9 Merge branch 'master' into slevenbits 2012-08-11 19:35:39 +01:00
Aparajita Fishman 9e1d09909e Merge branch 'stringValue-fix' 2012-08-09 20:31:37 -07:00
Alexander Ljungberg 306f2c987c Merge branch 'master' of github.com:slevenbits/cappuccino into slevenbits 2012-08-10 03:55:23 +01:00
Alexander Ljungberg 42200ce567 Merge branch 'master' into slevenbits 2012-08-10 03:55:03 +01:00
Aparajita Fishman 79cd71d2ab Merge branch 'fix-xcc-warnings' 2012-08-09 12:17:52 -07:00
Aparajita Fishman 081cf61e68 Merge branch 'refs/heads/upstream' 2012-08-09 11:27:32 -07:00
Alexander Ljungberg ed0fd87646 Merge branch 'master' into slevenbits 2012-08-07 12:32:47 +01:00
Alexander Ljungberg 4136953752 Merge branch 'refs/heads/master' into slevenbits 2012-08-06 14:03:37 +01:00
Alexander Ljungberg e70430057e Merge branch 'master' of github.com:slevenbits/cappuccino into slevenbits 2012-08-05 12:39:19 +01:00
Alexander Ljungberg 8498e28b70 Merge branch 'master' into slevenbits 2012-08-05 12:37:55 +01:00
Eric Wong 7ad24efe4f Merge branch 'cpdecimalnumber-fix' 2012-08-05 10:10:40 +08:00
Alexander Ljungberg a055d6d97e Merge branch 'refs/heads/master' into slevenbits 2012-08-04 14:11:25 +01:00
Alexander Ljungberg 23ed09a84e Merge branch 'refs/heads/master' into slevenbits 2012-08-02 15:54:36 +01:00
cacaodev 7ecf6ece7c Tests for previous commit 2012-07-28 12:50:17 +02:00
cacaodev 1c3d658ca1 CPURLConnection -sendSynchronousRequest: return nil if CPHTTPRequest failed. 2012-07-27 20:11:59 +02:00
cacaodev 9cbb8fd5bc Support for external cibs (a view in an individual cib). Added such view to ViewBasedCib. Also added an example of a view created manually in the delegate 2012-07-27 20:00:00 +02:00
cacaodev f4904b8915 CPCib -initWithContentsOfURL: return nil if the returned data is nil (non existent URL, request failed for some reason ...) 2012-07-27 19:17:45 +02:00
cacaodev 176440eeae CPURLConnection -sendSynchronousRequest: return nil if CPHTTPRequest failed 2012-07-27 19:16:38 +02:00
cacaodev 1a0434fd85 Fix action sent when an edited control is enqueued (see action log in test app).
A non bezeled text field is now bezeled when edited and unbezeled when editing ends - including when you hit enter (but text has to be modified, see comment in code)
2012-07-27 16:32:02 +02:00
cacaodev c6ccf1d487 -rowForView: early return if arg is not a CPView. Was causing an error when you click on table whose window was not frontmost.
Simplify -hitTest:, limit select-row behavior to left mouse events and extend to all data views accepting FR.
2012-07-27 09:48:36 +02:00
Aparajita Fishman 8e6119000d Added CPViewController -isViewLoaded, fixed CPWindowController -setViewController to use that
Before this fix, CPWindowController -setViewController was unconditionally loading the view, which should not happen.
2012-07-26 06:39:31 -07:00
Alexander Ljungberg 1db154ac5b Merge branch 'refs/heads/master' into slevenbits 2012-07-26 13:34:45 +01:00
cacaodev 0faf38a1e1 From within the delegate method, if you ask for an IB view (makeviewWithIdentifier:owner:), the view is now automatically reusable.
Before that, IB views were reusable only if the delegate method was not implemented.
If you create a view in code, you still need to make it reusable by calling -setIdentifier:

Woow ... now viewBasedCib loads the views x3 times faster.
2012-07-23 19:55:06 +02:00
Alexander Ljungberg 7ab833495f Merge branch 'refs/heads/master' into slevenbits 2012-07-23 15:39:03 +02:00
cacaodev 4c4a707624 In CPTableCellView initializers, enforce autoresizingMask to CPViewHeightSizable. Per cocoa except in cocoa it is done when the view is added to superview. 2012-07-23 15:12:06 +02:00
cacaodev e2d4ae4acc viewBasedCib example: fix some labels not sized-to-fit in IB 2012-07-22 21:32:24 +02:00
cacaodev 95b7f78a5a Sorry George. 2012-07-21 20:32:02 +02:00
cacaodev e694f8f173 Preemptive fix (currently disabled) to force drawBackground to YES for edited text fields embedded in a data view. dependency on issue #210. 2012-07-21 20:14:27 +02:00
cacaodev be35ea2704 - Fix behavior when selecting a row in a view-based table (per cocoa). Editable text fields are edited only if the row is selected, otherwise the row is selected. Other controls can be edited directly, without selecting the row first.
- Fixed a bug where data views being FR or containing a FR subview were preserving their FR when reused.
2012-07-21 14:11:24 +02:00
cacaodev 91f2252255 Remove old import in ViewBased, use CPTrace() to log perf. 2012-07-21 09:16:43 +02:00
ggsato 0582033fb7 a suggested fix for CPArrayController selection binding failure in retrieving initial selection values 2012-07-21 14:40:44 +09:00
Alexander Ljungberg 60a33b9592 Merge branch 'master' of github.com:slevenbits/cappuccino into slevenbits 2012-07-19 01:07:29 +01:00
Alexander Ljungberg 7429687932 Merge branch 'master' into slevenbits 2012-07-19 01:06:41 +01:00
Aparajita Fishman fe04cfbe1f Merge branch 'refs/heads/upstream' 2012-07-18 14:48:56 -07:00
Alexander Ljungberg d57f5427fb Merge branch 'master' into slevenbits 2012-07-18 19:23:05 +01:00
Aparajita Fishman 6537a44c02 Merge branch 'refs/heads/upstream' 2012-07-18 09:53:32 -07:00
Aparajita Fishman f8cc2eb670 Merge branch 'refs/heads/upstream' 2012-07-17 15:12:50 -07:00
Alexander Ljungberg c83b4bf3af Merge branch 'master' into slevenbits 2012-07-17 23:02:17 +01:00
Alexander Ljungberg 5c5d2e47a9 Merge branch 'master' into slevenbits 2012-07-17 21:11:45 +01:00
Alexander Ljungberg 9e20f209bf Merge branch 'master' of github.com:slevenbits/cappuccino into slevenbits 2012-07-16 03:17:39 +01:00
Alexander Ljungberg ce5c6d9b96 Merge branch 'master' into slevenbits 2012-07-16 03:17:12 +01:00
cacaodev d01a0e1b2d Set default theme color to black for textfields in a selected row when they are bordered or editing. 2012-07-15 22:39:47 +02:00
cacaodev 2d8681dbd4 CPOutlineViewViewBasedCibTest & TableBindings: cleanup zombie outlets & image in xib.
CPOutlineViewViewBasedCibTest: button expand/collapse item and tracks item state.#
2012-07-15 22:36:07 +02:00
cacaodev 2bd5696d99 Add info message when converting NSTableCellView nib to plist 2012-07-15 22:33:46 +02:00
Aparajita Fishman c166a20b89 Merge branch 'dictionary-key-methods' 2012-07-15 09:28:15 -07:00
Alexander Ljungberg 1cbf927684 Merge branch 'master' of github.com:slevenbits/cappuccino into slevenbits 2012-07-14 14:13:05 +01:00
Alexander Ljungberg 9fdfc4025a Merge branch 'refs/heads/master' into slevenbits 2012-07-14 14:12:53 +01:00
cacaodev 0b1d67116d Merge remote-tracking branch 'upstream/master' into CPTableViewLion 2012-07-14 09:35:26 +02:00
Aparajita Fishman 4958b4c47b Merge branch 'master' of github.com:slevenbits/cappuccino 2012-07-13 21:05:36 -07:00
Aparajita Fishman fedb24c2f3 Merge branch 'text-size-theming' 2012-07-13 21:02:46 -07:00
Aparajita Fishman e61a2a296e Merge branch 'master' of github.com:cappuccino/cappuccino 2012-07-13 21:00:35 -07:00
cacaodev de04c72767 CPDictionary -initWithObjectsAndKeys: skip a nil key instead of breaking 2012-07-13 21:47:39 +02:00
cacaodev da99b7b455 Remove temp merge files from previous commit. Added a view based table example to TableBindings 2012-07-13 16:41:57 +02:00
Alexander Ljungberg 0e87659093 Merge branch 'refs/heads/master' into slevenbits 2012-07-13 15:35:29 +01:00
cacaodev f29f39d427 Merge remote-tracking branch 'upstream/master' into CPTableViewLion
Renamed Test apps.

Conflicts:
	AppKit/CPTableView.j
	Tests/Manual/TableTest/TableBindings/Resources/MainMenu.cib
	Tests/Manual/TableTest/TableBindings/Resources/MainMenu.xib
2012-07-13 13:38:49 +02:00
Alexander Ljungberg eb990b6d4f Merge branch 'refs/heads/master' into slevenbits 2012-07-13 11:38:49 +01:00
Aparajita Fishman 12ea224f21 Merge branch 'master' of github.com:cappuccino/cappuccino 2012-07-12 17:21:40 -07:00
Aparajita Fishman 98260630ac Merge branch 'master' of github.com:cappuccino/cappuccino 2012-07-12 15:17:06 -07:00
Aparajita Fishman ba7fa38924 Merge branch 'master' of github.com:cappuccino/cappuccino 2012-07-12 07:15:19 -07:00
Aparajita Fishman 744bbd15d7 Merge branch 'master' of github.com:cappuccino/cappuccino 2012-07-11 09:24:35 -07:00
Aparajita Fishman 61f683b2e3 Merge branch 'text-clip-fix' 2012-07-11 09:11:04 -07:00
Aparajita Fishman 49521b44fb Merge branch 'system-font' 2012-07-10 18:54:42 -07:00
Aparajita Fishman f76404ef5e Merge branch 'refs/heads/system-font' 2012-07-10 16:41:06 -07:00
Aparajita Fishman 4df0b7c940 Merge branch 'archive-formatter' 2012-07-09 21:31:09 -07:00
Aparajita Fishman 6cd2c96152 Merge branch 'system-font' 2012-07-09 16:50:55 -07:00
Aparajita Fishman 106e21b79c Merge branch 'system-font' 2012-07-09 15:33:34 -07:00
Alexander Ljungberg 970dc912cb Merge branch 'master' into slevenbits 2012-07-09 20:32:07 +01:00
Alexander Ljungberg 6f84440bcd Merge branch 'master' into slevenbits 2012-07-08 21:29:08 +01:00
Alexander Ljungberg 4f69d82a4e Merge branch 'master' into slevenbits 2012-07-08 14:13:37 +01:00
cacaodev 1ee85181e8 Update tracing of views loading for the TableCibTest. 2012-07-07 16:12:03 +02:00
cacaodev c7ef136a7b Replaced CPTableView+Debug by the improved version called CPTrace. Cib test: visual output for view loading perormance (avg/row since tracing start). 2012-07-07 15:43:33 +02:00
cacaodev 5017189440 Merge remote-tracking branch 'upstream/master' into CPTableViewLion
Conflicts:
	AppKit/Themes/Aristo/ThemeDescriptors.j
2012-07-07 11:10:05 +02:00
Aparajita Fishman b85e44098b Merge branch 'CPComboBox' 2012-07-06 08:51:19 -07:00
cacaodev 6281f188f8 Merge branch 'cptextfield-cpthemestateeditable' into CPTableViewLion 2012-06-22 18:27:25 +02:00
cacaodev a444a7de19 Merge remote-tracking branch 'upstream/master' into CPTableViewLion 2012-06-22 18:27:18 +02:00
cacaodev 4369f4b5bb Set CPThemeStateEditable in setEditable: Add to Aristo theme desc. for table view data views 2012-06-22 18:12:35 +02:00
cacaodev 3689a7f17f CPTableView: support -editColumn:row:... for view-based tables even if this is not the prefered way to edit a view. If called, just makes the view first responder. 2012-06-22 17:55:44 +02:00
cacaodev 6b051d77ab Comment 2012-06-17 12:14:36 +02:00
cacaodev 10ae5bfbc0 Merge remote-tracking branch 'upstream/master' into CPTableViewLion 2012-06-17 12:10:37 +02:00
cacaodev 4daef7fc07 Merge remote-tracking branch 'upstream/master' into CPTableViewLion 2012-06-10 08:57:30 +02:00
cacaodev 25a4a00b16 Merge remote-tracking branch 'upstream/master' into CPTableViewLion 2012-06-07 15:08:51 +02:00
cacaodev 36bbab1d84 Merge remote-tracking branch 'upstream/master' into CPTableViewLion 2012-05-27 22:29:39 +02:00
Blair Duncan 59b6ddc29e Merge branch 'autosaveTableColumnsFix' of github.com:BlairDuncan/cappuccino into autosaveTableColumnsFix 2012-05-26 22:23:49 -04:00
Blair Duncan f04032aa97 added updated test file to show bug that this fixes 2012-05-26 22:19:34 -04:00
Blair Duncan 96cba7281a removed unnecessary comment and updated test file 2012-05-26 22:13:22 -04:00
cacaodev 63e8c732cc Merge remote-tracking branch 'upstream/master' into CPTableViewLion 2012-05-26 08:04:10 +02:00
cacaodev dfb2340e83 Merge remote-tracking branch 'upstream/master' into CPTableViewLion 2012-05-16 21:02:03 +02:00
cacaodev 5e3d9df81a In CPTableViewLionCibTest, use valueURL binding for image views; general capp lint. 2012-04-28 10:09:39 +02:00
cacaodev a0d52d415b Merge remote-tracking branch 'upstream/master' into CPTableViewLion 2012-04-28 09:00:53 +02:00
Blair Duncan 9ef9bf9f42 CPFlashView a few minor fixes, includes Test file 2012-04-25 17:07:13 -04:00
Blair Duncan ca381029f1 updated background image for sample test file 2012-04-22 11:57:56 -04:00
cacaodev f42e0d42fd CPCib CPCoding: use new CPData -*base64 methods 2012-04-18 09:01:57 +02:00
cacaodev 99798ffea7 Merge remote-tracking branch 'upstream/master' into CPTableViewLion 2012-04-17 22:13:24 +02:00
Blair Duncan e4d3334313 removed unnecessary comment 2012-04-16 21:04:12 -04:00
Blair Duncan 5384a9e86f Fix for issue 1507 CPTableview autosave tablecolumns 2012-04-16 21:00:33 -04:00
cacaodev a76fbb0073 nib2cibed CPOutlineViewCibTest 2012-04-13 22:27:47 +02:00
cacaodev 299a035b7f Typo 2012-04-13 22:27:21 +02:00
cacaodev a41ff7f2d0 TableView Example: fix row selection after drop
make editable textfield bordered

Finished CPOutlineView view-based. With example
2012-04-13 09:19:36 +02:00
cacaodev b11294d9cf Updated Cib test with the table content binding feature 2012-04-13 09:19:36 +02:00
cacaodev fda6694e0f merge content binding feature 2012-04-13 09:19:35 +02:00
cacaodev 399734fad4 CPTableView -_dragViewForColumn:event:offset:
Set the dragView frame before dataviews are added to it. Otherwise, dataviews will be expanded depending on their autoresize mask and appear cropped on the right.
2012-04-13 09:19:35 +02:00
cacaodev 0b5f0e5e61 CPTableView: Fixed a bug where an error was thrown when trying to edit a view-based cell. View-based cells don't need their editing to be handle by the table (begin or end), instead they are edited directly. Added an editable textfield on the right column view. values are commited via bindings. Focus not shown when you edit because of a bug in CPTextField 2012-04-13 09:19:35 +02:00
cacaodev f87dbec170 Add performance tests for the loadDataViewsInRows:columns: in view-based examples and in cell-based example CPTableCibTest. You need to re-build the fmw if you want to compare before/after view-based API. 2012-04-13 09:19:35 +02:00
cacaodev 67f7649f6c CPTableView with Lion's view-based API
Added : -makeViewWithIdentifier:owner:
	  -rowForView: columnForView: less performant tahn cocoa because we cycle through all visible rows. But these methods are generally used once when editing manually.
  Added identifier property to CPView.

  retro and forward (in IB) compatible with the existing API. You can use IB table view based without the new API. Existing table views / Nib won't break.

  CPTableView view based example. Featuring: IB made data views, different views in the same column, subviews binding in IB

When the view is found automatically in the cib, instantiate with _delegate as the owner (cocoa behavior).
2012-04-13 09:19:23 +02:00
cacaodev c2cad3cca3 nib2cib NSNib support. NSNib are represented as data inside nib files. We need to extract them, write, nib2cib, feed CPCib with the data. 2012-04-13 09:19:23 +02:00
cacaodev 5a99011feb nib2cib support for CPView identifier property. 2012-04-13 09:19:23 +02:00
cacaodev 392702cc18 nib2cib Converter.j : Add a flag to disable ibtool step in case the input is already compiled. Set SharedConverter class var in init (not a singleton, represents the current Converter). 2012-04-13 09:18:54 +02:00
Blair Duncan ed2e637219 Merge branch 'master' of git://github.com/cappuccino/cappuccino into afterDocumentLoadFix 2012-04-11 06:53:53 -04:00
Blair Duncan 3649b0ed9c Added test 2012-04-10 19:28:00 -04:00
Blair Duncan 13fbfb6cac fix to enables the startup loader to continue if dynamically loaded 2012-04-10 16:55:42 -04:00
cacaodev 27cda34f8b CPTableView: When columns or rows dragging ends, enqueue the dragged views so they can be available when you drag again the column if they haven't been unloaded before.
The 2nd time you drag the same column/row, reduces -dragViewFor... duration by 90% according to webkit profiling.
2012-03-17 16:10:54 +01:00
cacaodev 57c8d223ad CPCollectionView dragging: fix a bug where the dragging view was created from content instead of selection 2012-02-29 18:45:11 +01:00
cacaodev 8641738777 Merge remote-tracking branch 'upstream/master' into CPCollectionView-dragged-view 2012-02-29 18:42:25 +01:00
cacaodev bafd62d42d CPCollectionView Implemented - (CPView)draggingViewForItemsAtIndexes:(CPIndexSet)indexes withEvent:(CPEvent)event offset:(CGPoint)dragImageOffset
and the corresponding delegate method from where you can ask for the default dragged view. Multiple selection not implemented yet.
2012-01-25 17:25:23 +01:00
cncolder 1a88651e4e Merge branch 'master' into fontinfo-path-fix 2011-04-28 10:28:04 +08:00
cncolder 229e43f20c Fix build path when $CAPP_BUILD not defined. 2011-04-19 09:14:00 +08:00
1998 changed files with 97915 additions and 17090 deletions
+3
View File
@@ -10,3 +10,6 @@ WebSite
xcuserdata/
!*.xcodeproj/project.pbxproj
*.xCodeSupport/
*.XcodeSupport/
*.sublime-project
*.sublime-workspace
+6
View File
@@ -0,0 +1,6 @@
language: node_js
node_js:
- 0.8
install: ./bootstrap.sh --quiet --noprompt --directory ./narwhal
script: jake test
env: PATH="$TRAVIS_BUILD_DIR/narwhal/bin:$PATH" CAPP_BUILD="$TRAVIS_BUILD_DIR/Build" NARWHAL_ENGINE=rhino
+1 -1
View File
@@ -227,7 +227,7 @@ var secondItem = [[CPAccordionViewItem alloc] initWithIdentifier:@"secondSection
{
var indexSet = [CPIndexSet indexSetWithIndexesInRange:CPMakeRange(0, _items.length)];
[indexSet removeIndexes:_expandedIndexes];
[indexSet removeIndexes:_expandedItemIndexes];
return indexSet;
}
+148 -101
View File
@@ -28,15 +28,19 @@
@import <Foundation/CPObject.j>
@import <Foundation/CPString.j>
@import "CPApplication.j"
@import "CPButton.j"
@import "CPColor.j"
@import "CPFont.j"
@import "CPImage.j"
@import "CPImageView.j"
@import "CPPanel.j"
@import "CPText.j"
@import "CPTextField.j"
@class CPCheckBox
@global CPApp
/*
@global
@group CPAlertStyle
@@ -53,6 +57,8 @@ CPInformationalAlertStyle = 1;
*/
CPCriticalAlertStyle = 2;
var bottomHeight = 71;
/*!
@ingroup appkit
@@ -75,32 +81,33 @@ CPCriticalAlertStyle = 2;
representing the first button added to the alert which appears on the
right, 1 representing the next button to the left and so on)
*/
@implementation CPAlert : CPView
@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;
id _delegate @accessors(property=delegate);
id _modalDelegate;
SEL _didEndSelector;
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
@@ -163,7 +170,8 @@ CPCriticalAlertStyle = 2;
_alertStyle = CPWarningAlertStyle;
_showHelp = NO;
_needsLayout = YES;
_defaultWindowStyle = CPTitledWindowMask;
_defaultWindowStyle = _CPModalWindowMask;
_themeView = [_CPAlertThemeView new];
_messageLabel = [CPTextField labelWithTitle:@"Alert"];
_alertImageView = [[CPImageView alloc] init];
@@ -180,6 +188,11 @@ CPCriticalAlertStyle = 2;
#pragma mark Accessors
- (CPTheme)theme
{
return [_themeView theme];
}
/*!
set the theme to use
@@ -197,9 +210,20 @@ CPCriticalAlertStyle = 2;
_window = nil; // will be regenerated at next layout
_needsLayout = YES;
[super setTheme:aTheme];
[_themeView setTheme:aTheme];
}
- (void)setValue:(id)aValue forThemeAttribute:(CPString)aName
{
[_themeView setValue:aValue forThemeAttribute:aName];
}
- (void)setValue:(id)aValue forThemeAttribute:(CPString)aName inState:(CPThemeState)aState
{
[_themeView setValue:aValue forThemeAttribute:aName inState:aState];
}
/*! @deprecated
*/
- (void)setWindowStyle:(int)aStyle
@@ -334,16 +358,16 @@ CPCriticalAlertStyle = 2;
*/
- (void)_layoutMessageView
{
var inset = [self currentValueForThemeAttribute:@"content-inset"],
var inset = [_themeView currentValueForThemeAttribute:@"content-inset"],
sizeWithFontCorrection = 6.0,
messageLabelWidth,
messageLabelTextSize;
[_messageLabel setTextColor:[self currentValueForThemeAttribute:@"message-text-color"]];
[_messageLabel setFont:[self currentValueForThemeAttribute:@"message-text-font"]];
[_messageLabel setTextShadowColor:[self currentValueForThemeAttribute:@"message-text-shadow-color"]];
[_messageLabel setTextShadowOffset:[self currentValueForThemeAttribute:@"message-text-shadow-offset"]];
[_messageLabel setAlignment:[self currentValueForThemeAttribute:@"message-text-alignment"]];
[_messageLabel setTextColor:[_themeView currentValueForThemeAttribute:@"message-text-color"]];
[_messageLabel setFont:[_themeView currentValueForThemeAttribute:@"message-text-font"]];
[_messageLabel setTextShadowColor:[_themeView currentValueForThemeAttribute:@"message-text-shadow-color"]];
[_messageLabel setTextShadowOffset:[_themeView currentValueForThemeAttribute:@"message-text-shadow-offset"]];
[_messageLabel setAlignment:[_themeView currentValueForThemeAttribute:@"message-text-alignment"]];
[_messageLabel setLineBreakMode:CPLineBreakByWordWrapping];
messageLabelWidth = CGRectGetWidth([[_window contentView] frame]) - inset.left - inset.right;
@@ -357,18 +381,18 @@ CPCriticalAlertStyle = 2;
*/
- (void)_layoutInformativeView
{
var inset = [self currentValueForThemeAttribute:@"content-inset"],
defaultElementsMargin = [self currentValueForThemeAttribute:@"default-elements-margin"],
var inset = [_themeView currentValueForThemeAttribute:@"content-inset"],
defaultElementsMargin = [_themeView currentValueForThemeAttribute:@"default-elements-margin"],
sizeWithFontCorrection = 6.0,
informativeLabelWidth,
informativeLabelOriginY,
informativeLabelTextSize;
[_informativeLabel setTextColor:[self currentValueForThemeAttribute:@"informative-text-color"]];
[_informativeLabel setFont:[self currentValueForThemeAttribute:@"informative-text-font"]];
[_informativeLabel setTextShadowColor:[self currentValueForThemeAttribute:@"informative-text-shadow-color"]];
[_informativeLabel setTextShadowOffset:[self currentValueForThemeAttribute:@"informative-text-shadow-offset"]];
[_informativeLabel setAlignment:[self currentValueForThemeAttribute:@"informative-text-alignment"]];
[_informativeLabel setTextColor:[_themeView currentValueForThemeAttribute:@"informative-text-color"]];
[_informativeLabel setFont:[_themeView currentValueForThemeAttribute:@"informative-text-font"]];
[_informativeLabel setTextShadowColor:[_themeView currentValueForThemeAttribute:@"informative-text-shadow-color"]];
[_informativeLabel setTextShadowOffset:[_themeView currentValueForThemeAttribute:@"informative-text-shadow-offset"]];
[_informativeLabel setAlignment:[_themeView currentValueForThemeAttribute:@"informative-text-alignment"]];
[_informativeLabel setLineBreakMode:CPLineBreakByWordWrapping];
informativeLabelWidth = CGRectGetWidth([[_window contentView] frame]) - inset.left - inset.right;
@@ -386,8 +410,8 @@ CPCriticalAlertStyle = 2;
if (!_accessoryView)
return;
var inset = [self currentValueForThemeAttribute:@"content-inset"],
defaultElementsMargin = [self currentValueForThemeAttribute:@"default-elements-margin"],
var inset = [_themeView currentValueForThemeAttribute:@"content-inset"],
defaultElementsMargin = [_themeView currentValueForThemeAttribute:@"default-elements-margin"],
accessoryViewWidth = CGRectGetWidth([[_window contentView] frame]) - inset.left - inset.right,
accessoryViewOriginY = CGRectGetMaxY([_informativeLabel frame]) + defaultElementsMargin;
@@ -403,16 +427,16 @@ CPCriticalAlertStyle = 2;
if (!_showSuppressionButton)
return;
var inset = [self currentValueForThemeAttribute:@"content-inset"],
suppressionViewXOffset = [self currentValueForThemeAttribute:@"suppression-button-x-offset"],
suppressionViewYOffset = [self currentValueForThemeAttribute:@"suppression-button-y-offset"],
defaultElementsMargin = [self currentValueForThemeAttribute:@"default-elements-margin"],
var inset = [_themeView currentValueForThemeAttribute:@"content-inset"],
suppressionViewXOffset = [_themeView currentValueForThemeAttribute:@"suppression-button-x-offset"],
suppressionViewYOffset = [_themeView currentValueForThemeAttribute:@"suppression-button-y-offset"],
defaultElementsMargin = [_themeView currentValueForThemeAttribute:@"default-elements-margin"],
suppressionButtonViewOriginY = CGRectGetMaxY([(_accessoryView || _informativeLabel) frame]) + defaultElementsMargin + suppressionViewYOffset;
[_suppressionButton setTextColor:[self currentValueForThemeAttribute:@"suppression-button-text-color"]];
[_suppressionButton setFont:[self currentValueForThemeAttribute:@"suppression-button-text-font"]];
[_suppressionButton setTextShadowColor:[self currentValueForThemeAttribute:@"suppression-button-text-shadow-color"]];
[_suppressionButton setTextShadowOffset:[self currentValueForThemeAttribute:@"suppression-button-text-shadow-offset"]];
[_suppressionButton setTextColor:[_themeView currentValueForThemeAttribute:@"suppression-button-text-color"]];
[_suppressionButton setFont:[_themeView currentValueForThemeAttribute:@"suppression-button-text-font"]];
[_suppressionButton setTextShadowColor:[_themeView currentValueForThemeAttribute:@"suppression-button-text-shadow-color"]];
[_suppressionButton setTextShadowOffset:[_themeView currentValueForThemeAttribute:@"suppression-button-text-shadow-offset"]];
[_suppressionButton sizeToFit];
[_suppressionButton setFrameOrigin:CGPointMake(inset.left + suppressionViewXOffset, suppressionButtonViewOriginY)];
@@ -424,14 +448,17 @@ CPCriticalAlertStyle = 2;
*/
- (CGSize)_layoutButtonsFromView:(CPView)lastView
{
var inset = [self currentValueForThemeAttribute:@"content-inset"],
minimumSize = [self currentValueForThemeAttribute:@"size"],
buttonOffset = [self currentValueForThemeAttribute:@"button-offset"],
helpLeftOffset = [self currentValueForThemeAttribute:@"help-image-left-offset"],
var inset = [_themeView currentValueForThemeAttribute:@"content-inset"],
minimumSize = [_themeView currentValueForThemeAttribute:@"size"],
buttonOffset = [_themeView currentValueForThemeAttribute:@"button-offset"],
helpLeftOffset = [_themeView currentValueForThemeAttribute:@"help-image-left-offset"],
aRepresentativeButton = [_buttons objectAtIndex:0],
defaultElementsMargin = [self currentValueForThemeAttribute:@"default-elements-margin"],
defaultElementsMargin = [_themeView currentValueForThemeAttribute:@"default-elements-margin"],
panelSize = [[_window contentView] frame].size,
buttonsOriginY,
buttonMarginY,
buttonMarginX,
theme = [self theme],
offsetX;
[aRepresentativeButton setTheme:[self theme]];
@@ -444,6 +471,19 @@ CPCriticalAlertStyle = 2;
buttonsOriginY = panelSize.height - [aRepresentativeButton frameSize].height + buttonOffset;
offsetX = panelSize.width - inset.right;
switch ([_window styleMask])
{
case _CPModalWindowMask:
buttonMarginY = [_themeView currentValueForThemeAttribute:@"modal-window-button-margin-y"];
buttonMarginX = [_themeView currentValueForThemeAttribute:@"modal-window-button-margin-x"];
break;
default:
buttonMarginY = [_themeView currentValueForThemeAttribute:@"standard-window-button-margin-y"];
buttonMarginX = [_themeView currentValueForThemeAttribute:@"standard-window-button-margin-x"];
break;
}
for (var i = [_buttons count] - 1; i >= 0 ; i--)
{
var button = _buttons[i];
@@ -455,14 +495,14 @@ CPCriticalAlertStyle = 2;
height = CGRectGetHeight(buttonFrame);
offsetX -= width;
[button setFrame:CGRectMake(offsetX, buttonsOriginY, width, height)];
[button setFrame:CGRectMake(offsetX + buttonMarginX, buttonsOriginY + buttonMarginY, width, height)];
offsetX -= 10;
}
if (_showHelp)
{
var helpImage = [self currentValueForThemeAttribute:@"help-image"],
helpImagePressed = [self currentValueForThemeAttribute:@"help-image-pressed"],
var helpImage = [_themeView currentValueForThemeAttribute:@"help-image"],
helpImagePressed = [_themeView currentValueForThemeAttribute:@"help-image-pressed"],
helpImageSize = helpImage ? [helpImage size] : CGSizeMakeZero(),
helpFrame = CGRectMake(helpLeftOffset, buttonsOriginY, helpImageSize.width, helpImageSize.height);
@@ -487,7 +527,7 @@ CPCriticalAlertStyle = 2;
if (!_window)
[self _createWindowWithStyle:nil];
var iconOffset = [self currentValueForThemeAttribute:@"image-offset"],
var iconOffset = [_themeView currentValueForThemeAttribute:@"image-offset"],
theImage = _icon,
finalSize;
@@ -495,13 +535,13 @@ CPCriticalAlertStyle = 2;
switch (_alertStyle)
{
case CPWarningAlertStyle:
theImage = [self currentValueForThemeAttribute:@"warning-image"];
theImage = [_themeView currentValueForThemeAttribute:@"warning-image"];
break;
case CPInformationalAlertStyle:
theImage = [self currentValueForThemeAttribute:@"information-image"];
theImage = [_themeView currentValueForThemeAttribute:@"information-image"];
break;
case CPCriticalAlertStyle:
theImage = [self currentValueForThemeAttribute:@"error-image"];
theImage = [_themeView currentValueForThemeAttribute:@"error-image"];
break;
}
@@ -519,7 +559,7 @@ CPCriticalAlertStyle = 2;
if (_showSuppressionButton)
lastView = _suppressionButton;
else if (_accessoryView)
lastView = _accessoryView
lastView = _accessoryView;
finalSize = [self _layoutButtonsFromView:lastView];
if ([_window styleMask] & CPDocModalWindowMask)
@@ -528,6 +568,12 @@ CPCriticalAlertStyle = 2;
[_window setFrameSize:finalSize];
[_window center];
if ([_window styleMask] & _CPModalWindowMask || [_window styleMask] & CPHUDBackgroundWindowMask)
{
[_window setMovable:YES];
[_window setMovableByWindowBackground:YES];
}
_needsLayout = NO;
}
@@ -592,9 +638,10 @@ CPCriticalAlertStyle = 2;
- (void)_createWindowWithStyle:(int)forceStyle
{
var frame = CGRectMakeZero();
frame.size = [self currentValueForThemeAttribute:@"size"];
frame.size = [_themeView currentValueForThemeAttribute:@"size"];
_window = [[CPWindow alloc] initWithContentRect:frame styleMask:forceStyle || _defaultWindowStyle];
_window = [[CPPanel alloc] initWithContentRect:frame styleMask:forceStyle || _defaultWindowStyle];
[_window setLevel:CPStatusWindowLevel];
if (_title)
[_window setTitle:_title];
@@ -632,8 +679,8 @@ CPCriticalAlertStyle = 2;
{
if ([_window isSheet])
{
[CPApp endSheet:_window returnCode:[aSender tag]];
[_window orderOut:nil];
[CPApp endSheet:_window returnCode:[aSender tag]];
}
else
{
@@ -649,17 +696,19 @@ CPCriticalAlertStyle = 2;
*/
- (void)_alertDidEnd:(CPWindow)aWindow returnCode:(int)returnCode contextInfo:(id)contextInfo
{
if ([_delegate respondsToSelector:@selector(alertDidEnd:returnCode:)])
[_delegate alertDidEnd:self returnCode:returnCode];
if (_didEndSelector)
objj_msgSend(_modalDelegate, _didEndSelector, self, returnCode, contextInfo);
_modalDelegate = nil;
_didEndSelector = nil;
if ([_delegate respondsToSelector:@selector(alertDidEnd:returnCode:)])
[_delegate alertDidEnd:self returnCode:returnCode];
}
#pragma mark Theme Attributes
@end
@implementation _CPAlertThemeView : CPView
+ (CPString)defaultThemeClass
{
@@ -668,42 +717,40 @@ CPCriticalAlertStyle = 2;
+ (id)themeAttributes
{
return [CPDictionary dictionaryWithObjects:[CGSizeMake(400.0, 110.0), CGInsetMake(15, 15, 15, 50), 6, 10,
CPJustifiedTextAlignment, [CPColor blackColor], [CPFont boldSystemFontOfSize:13.0], [CPNull null], CGSizeMakeZero(),
CPJustifiedTextAlignment, [CPColor blackColor], [CPFont systemFontOfSize:12.0], [CPNull null], CGSizeMakeZero(),
CGPointMake(15, 12),
[CPNull null],
[CPNull null],
[CPNull null],
[CPNull null],
[CPNull null],
[CPNull null],
0.0,
0.0,
3.0,
[CPColor blackColor],
[CPFont systemFontOfSize:12.0],
[CPNull null],
0.0
]
forKeys:[@"size", @"content-inset", @"informative-offset", @"button-offset",
@"message-text-alignment", @"message-text-color", @"message-text-font", @"message-text-shadow-color", @"message-text-shadow-offset",
@"informative-text-alignment", @"informative-text-color", @"informative-text-font", @"informative-text-shadow-color", @"informative-text-shadow-offset",
@"image-offset",
@"information-image",
@"warning-image",
@"error-image",
@"help-image",
@"help-image-left-offset",
@"help-image-pressed",
@"suppression-button-y-offset",
@"suppression-button-x-offset",
@"default-elements-margin",
@"suppression-button-text-color",
@"suppression-button-text-font",
@"suppression-button-text-shadow-color",
@"suppression-button-text-shadow-offset"
]];
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
+18 -12
View File
@@ -123,23 +123,29 @@ ACTUAL_FRAME_RATE = 0;
- (void)setAnimationCurve:(CPAnimationCurve)anAnimationCurve
{
var timingFunctionName;
switch (anAnimationCurve)
{
case CPAnimationEaseInOut: timingFunctionName = kCAMediaTimingFunctionEaseInEaseOut;
break;
case CPAnimationEaseInOut:
timingFunctionName = kCAMediaTimingFunctionEaseInEaseOut;
break;
case CPAnimationEaseIn: timingFunctionName = kCAMediaTimingFunctionEaseIn;
break;
case CPAnimationEaseIn:
timingFunctionName = kCAMediaTimingFunctionEaseIn;
break;
case CPAnimationEaseOut: timingFunctionName = kCAMediaTimingFunctionEaseOut;
break;
case CPAnimationEaseOut:
timingFunctionName = kCAMediaTimingFunctionEaseOut;
break;
case CPAnimationLinear: timingFunctionName = kCAMediaTimingFunctionLinear;
break;
case CPAnimationLinear:
timingFunctionName = kCAMediaTimingFunctionLinear;
break;
default: [CPException raise:CPInvalidArgumentException
reason:"Invalid value provided for animation curve"];
break;
default:
[CPException raise:CPInvalidArgumentException
reason:@"Invalid value provided for animation curve"];
break;
}
_animationCurve = anAnimationCurve;
@@ -325,7 +331,7 @@ ACTUAL_FRAME_RATE = 0;
// currently used function to determine time
// 1:1 conversion to js from webkit source files
// UnitBezier.h, WebCore_animation_AnimationBase.cpp
var CubicBezierAtTime = function CubicBezierAtTime(t, p1x, p1y, p2x, p2y, duration)
var CubicBezierAtTime = function(t, p1x, p1y, p2x, p2y, duration)
{
var ax = 0,
bx = 0,
+132 -55
View File
@@ -20,17 +20,22 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#import "../Foundation/CPRange.h"
@import <Foundation/CPBundle.j>
@import "CPCompatibility.j"
@import "CPColorPanel.j"
@import "CPCursor.j"
@import "CPDocumentController.j"
@import "CPEvent.j"
@import "CPMenu.j"
@import "CPResponder.j"
@import "CPDocumentController.j"
@import "CPThemeBlend.j"
@import "CPCibLoading.j"
@import "CPPanel.j"
@import "CPPlatform.j"
@import "CPWindowController.j"
var CPMainCibFile = @"CPMainCibFile",
CPMainCibFileHumanFriendly = @"Main cib file base name",
@@ -82,8 +87,10 @@ CPRunContinuesResponse = -1002;
@implementation CPApplication : CPResponder
{
CPArray _eventListeners;
int _eventListenerInsertionIndex;
CPEvent _currentEvent;
CPWindow _lastMouseMoveWindow;
CPArray _windows;
CPWindow _keyWindow;
@@ -138,10 +145,9 @@ CPRunContinuesResponse = -1002;
if (self)
{
_eventListeners = [];
_eventListenerInsertionIndex = 0;
_windows = [];
[_windows addObject:nil];
_windows = [[CPNull null]];
}
return self;
@@ -250,8 +256,13 @@ CPRunContinuesResponse = -1002;
_documentController = [CPDocumentController sharedDocumentController];
var needsUntitled = !!_documentController,
URLStrings = window.cpOpeningURLStrings && window.cpOpeningURLStrings(),
index = 0,
URLStrings = nil;
#if PLATFORM(DOM)
URLStrings = window.cpOpeningURLStrings && window.cpOpeningURLStrings();
#endif
var index = 0,
count = [URLStrings count];
for (; index < count; ++index)
@@ -401,7 +412,7 @@ CPRunContinuesResponse = -1002;
}
- (void)_documentController:(NSDocumentController *)docController didCloseAll:(BOOL)didCloseAll context:(Object)info
- (void)_documentController:(CPDocumentController)docController didCloseAll:(BOOL)didCloseAll context:(Object)info
{
// callback method for terminate:
if (didCloseAll)
@@ -500,6 +511,8 @@ CPRunContinuesResponse = -1002;
if (_eventListeners[count]._callback === _CPRunModalLoop)
{
_eventListeners.splice(count, 1);
if (count <= _eventListenerInsertionIndex)
_eventListenerInsertionIndex--;
return;
}
@@ -547,7 +560,7 @@ CPRunContinuesResponse = -1002;
// [theWindow._bridge _obscureWindowsBelowModalWindow];
[CPApp setCallback:_CPRunModalLoop forNextEventMatchingMask:CPAnyEventMask untilDate:nil inMode:0 dequeue:NO];
[CPApp setCallback:_CPRunModalLoop forNextEventMatchingMask:CPAnyEventMask untilDate:nil inMode:0 dequeue:YES];
}
/*!
@@ -578,12 +591,14 @@ CPRunContinuesResponse = -1002;
_currentEvent = anEvent;
CPEventModifierFlags = [anEvent modifierFlags];
var theWindow = [anEvent window];
#if PLATFORM(DOM)
var willPropagate = [[[anEvent window] platformWindow] _willPropagateCurrentDOMEvent];
var willPropagate = [[theWindow platformWindow] _willPropagateCurrentDOMEvent];
// temporarily pretend we won't propagate the event. we'll restore the saved value later
// we do this outside the if so that changes user code might make in _handleKeyEquiv. are preserved
[[[anEvent window] platformWindow] _propagateCurrentDOMEvent:NO];
[[theWindow platformWindow] _propagateCurrentDOMEvent:NO];
#endif
// Check if this is a candidate for key equivalent...
@@ -595,7 +610,7 @@ CPRunContinuesResponse = -1002;
// Unconditionally propagate on these keys to solve browser copy paste bugs
if ((characters == "c" || characters == "x" || characters == "v") && (modifierFlags & CPPlatformActionKeyMask))
[[[anEvent window] platformWindow] _propagateCurrentDOMEvent:YES];
[[theWindow platformWindow] _propagateCurrentDOMEvent:YES];
#endif
return;
@@ -603,18 +618,46 @@ CPRunContinuesResponse = -1002;
#if PLATFORM(DOM)
// if we make it this far, then restore the original willPropagate value
[[[anEvent window] platformWindow] _propagateCurrentDOMEvent:willPropagate];
[[theWindow platformWindow] _propagateCurrentDOMEvent:willPropagate];
#endif
if (_eventListeners.length)
if ([anEvent type] == CPMouseMoved)
{
if (_eventListeners[_eventListeners.length - 1]._mask & (1 << [anEvent type]))
_eventListeners.pop()._callback(anEvent);
if (theWindow !== _lastMouseMoveWindow)
[_lastMouseMoveWindow _mouseExitedResizeRect];
return;
_lastMouseMoveWindow = theWindow;
}
[[anEvent window] sendEvent:anEvent];
/*
Event listeners are processed from back to front so that newer event listeners normally take
precedence. If during the execution of a callback a new event listener is added, it should
be inserted after the current callback but before any higher priority callbacks. This makes
repeating event listeners (those that reinsert themselves) stable relative to each other.
*/
for (var i = _eventListeners.length - 1; i >= 0; i--)
{
var listener = _eventListeners[i];
if (listener._mask & (1 << [anEvent type]))
{
_eventListeners.splice(i, 1);
// In case the callback wants to add more listeners.
_eventListenerInsertionIndex = i;
listener._callback(anEvent);
if (listener._dequeue)
{
// Don't process the event normally and don't send it to any other listener.
_eventListenerInsertionIndex = _eventListeners.length;
return;
}
}
}
_eventListenerInsertionIndex = _eventListeners.length;
if (theWindow)
[theWindow sendEvent:anEvent];
}
/*!
@@ -650,6 +693,10 @@ CPRunContinuesResponse = -1002;
*/
- (CPWindow)windowWithWindowNumber:(int)aWindowNumber
{
// Never allow _windows[0] to be returned - it's an internal CPNull placeholder.
if (!aWindowNumber)
return nil;
return _windows[aWindowNumber];
}
@@ -658,7 +705,8 @@ CPRunContinuesResponse = -1002;
*/
- (CPArray)windows
{
return _windows;
// Return all windows, but not the CPNull placeholder in _windows[0].
return [_windows subarrayWithRange:_CPMakeRange(1, [_windows count] - 1)];
}
/*!
@@ -886,31 +934,44 @@ CPRunContinuesResponse = -1002;
/*!
Fires a callback function when an event matching a given mask occurs.
@param aCallback - A js function to be fired.
@prarm aMask - An event mask for the next event.
@param anExpiration - The date for which this callback expires (not implemented).
If multiple callbacks are set which match the same event, later callbacks
take priority over earlier callbacks, unless a new callback is set while
an existing callback is being processed in which case it's given the same
priority as the currently processing callback.
@param aCallback A js function to be fired.
@prarm aMask An event mask for the next event.
@param anExpiration The date for which this callback expires (not implemented).
@param inMode (not implemented).
@param shouldDequeue (not implemented).
@param shouldDequeue YES to remove the event from the queue after calling the callback,
NO to deliver it normally.
*/
- (void)setCallback:(Function)aCallback forNextEventMatchingMask:(unsigned int)aMask untilDate:(CPDate)anExpiration inMode:(CPString)aMode dequeue:(BOOL)shouldDequeue
{
_eventListeners.push(_CPEventListenerMake(aMask, aCallback));
_eventListeners.splice(_eventListenerInsertionIndex++, 0, _CPEventListenerMake(aMask, aCallback, shouldDequeue));
}
/*!
Assigns a target and action for the next event matching a given event mask.
The callback method called will be passed the CPEvent when it fires.
@param aTarget - The target object for the callback.
@param aSelector - The selector which should be called on the target object.
@param aMask - The mask for a given event which should trigger the callback.
@param anExpiration - The date for which the callback expires (not implemented).
If multiple callbacks are set which match the same event, later callbacks
take priority over earlier callbacks, unless a new callback is set while
an existing callback is being processed in which case it's given the same
priority as the currently processing callback.
@param aTarget The target object for the callback.
@param aSelector The selector which should be called on the target object.
@param aMask The mask for a given event which should trigger the callback.
@param anExpiration The date for which the callback expires (not implemented).
@param aMode (not implemented).
@param shouldDequeue (not implemented).
@param shouldDequeue YES to remove the event from the queue after calling the callback,
NO to deliver it normally.
*/
- (void)setTarget:(id)aTarget selector:(SEL)aSelector forNextEventMatchingMask:(unsigned int)aMask untilDate:(CPDate)anExpiration inMode:(CPString)aMode dequeue:(BOOL)shouldDequeue
{
_eventListeners.push(_CPEventListenerMake(aMask, function (anEvent) { objj_msgSend(aTarget, aSelector, anEvent); }));
_eventListeners.splice(_eventListenerInsertionIndex++, 0, _CPEventListenerMake(aMask, function (anEvent) { objj_msgSend(aTarget, aSelector, anEvent); }, shouldDequeue));
}
/*!
@@ -948,6 +1009,7 @@ CPRunContinuesResponse = -1002;
[aWindow orderFront:self];
[aSheet setPlatformWindow:[aWindow platformWindow]];
}
[aWindow _attachSheet:aSheet modalDelegate:aModalDelegate didEndSelector:aDidEndSelector contextInfo:aContextInfo];
}
@@ -1009,7 +1071,8 @@ CPRunContinuesResponse = -1002;
*/
- (CPArray)arguments
{
if (_fullArgsString !== window.location.hash)
// FIXME This should probably not access the window object #if !PLATFORM(DOM), but the unit tests rely on it.
if (window && window.location && _fullArgsString !== window.location.hash)
[self _reloadArguments];
return _args;
@@ -1036,8 +1099,9 @@ CPRunContinuesResponse = -1002;
if (!args || args.length == 0)
{
_args = [];
window.location.hash = @"#";
// Don't use if PLATFORM(DOM) here - the unit test fakes window.location so we should play along.
if (window && window.location)
window.location.hash = @"#";
return;
}
@@ -1052,12 +1116,15 @@ CPRunContinuesResponse = -1002;
var hash = [toEncode componentsJoinedByString:@"/"];
window.location.hash = @"#" + hash;
// Don't use if PLATFORM(DOM) here - the unit test fakes window.location so we should play along.
if (window && window.location)
window.location.hash = @"#" + hash;
}
- (void)_reloadArguments
{
_fullArgsString = window.location.hash;
// FIXME This should probably not access the window object #if !PLATFORM(DOM), but the unit tests rely on it.
_fullArgsString = (window && window.location) ? window.location.hash : "";
if (_fullArgsString.length)
{
@@ -1171,7 +1238,7 @@ CPRunContinuesResponse = -1002;
+ (CPString)defaultThemeName
{
return ([[CPBundle mainBundle] objectForInfoDictionaryKey:"CPDefaultTheme"] || @"Aristo");
return ([[CPBundle mainBundle] objectForInfoDictionaryKey:"CPDefaultTheme"] || @"Aristo2");
}
@end
@@ -1181,28 +1248,29 @@ var _CPModalSessionMake = function(aWindow, aStopCode)
return { _window:aWindow, _state:CPRunContinuesResponse , _previous:nil };
};
var _CPEventListenerMake = function(anEventMask, aCallback)
var _CPEventListenerMake = function(anEventMask, aCallback, shouldDequeue)
{
return { _mask:anEventMask, _callback:aCallback };
return { _mask:anEventMask, _callback:aCallback, _dequeue:shouldDequeue };
};
// Make this a global for use in CPPlatformWindow+DOM.j.
_CPRunModalLoop = function(anEvent)
{
[CPApp setCallback:_CPRunModalLoop forNextEventMatchingMask:CPAnyEventMask untilDate:nil inMode:0 dequeue:NO];
[CPApp setCallback:_CPRunModalLoop forNextEventMatchingMask:CPAnyEventMask untilDate:nil inMode:0 dequeue:YES];
var theWindow = [anEvent window],
modalSession = CPApp._currentSession;
// The special case for popovers here is not clear. In Cocoa the popover window does not respond YES to worksWhenModal,
// yet it works when there is a modal window. Maybe it starts its own modal session, but interaction with the original
// modal window seems to continue working as well. Regardless of correctness, this solution beats popovers not working
// at all from sheets.
/*
The special case for popovers here is not clear. In Cocoa the popover window does not respond YES to worksWhenModal, yet it works when there is a modal window. Maybe it starts its own modal session, but interaction with the original modal window seems to continue working as well. Regardless of correctness, this solution beats popovers not working at all from sheets.
*/
if (theWindow == modalSession._window ||
[theWindow worksWhenModal] ||
[theWindow attachedSheet] == modalSession._window || // -dw- allow modal parent of sheet to be repositioned
([theWindow isKindOfClass:_CPAttachedWindow] && [[theWindow targetView] window] === modalSession._window))
([theWindow isKindOfClass:_CPPopoverWindow] && [[theWindow targetView] window] === modalSession._window))
{
[theWindow sendEvent:anEvent];
}
};
/*!
@@ -1218,7 +1286,17 @@ function CPApplicationMain(args, namedArgs)
#if PLATFORM(DOM)
// hook to allow recorder, etc to manipulate things before starting AppKit
if (window.parent !== window && typeof window.parent._childAppIsStarting === "function")
window.parent._childAppIsStarting(window);
{
try
{
window.parent._childAppIsStarting(window);
}
catch(err)
{
// This could happen if we're in an iframe without access to the parent frame.
CPLog.warn("Failed to call parent frame's _childAppIsStarting().");
}
}
#endif
var mainBundle = [CPBundle mainBundle],
@@ -1275,7 +1353,7 @@ var _CPAppBootstrapperActions = nil;
var defaultThemeName = [CPApplication defaultThemeName],
themeURL = nil;
if (defaultThemeName === @"Aristo")
if (defaultThemeName === @"Aristo" || defaultThemeName === @"Aristo2")
themeURL = [[CPBundle bundleForClass:[CPApplication class]] pathForResource:defaultThemeName + @".blend"];
else
themeURL = [[CPBundle mainBundle] pathForResource:defaultThemeName + @".blend"];
@@ -1302,7 +1380,7 @@ var _CPAppBootstrapperActions = nil;
if (mainCibFile)
{
[mainBundle loadCibFile:mainCibFile
externalNameTable:[CPDictionary dictionaryWithObject:CPApp forKey:CPCibOwner]
externalNameTable:@{ CPCibOwner: CPApp }
loadDelegate:self];
return YES;
@@ -1320,26 +1398,25 @@ var _CPAppBootstrapperActions = nil;
// FIXME: We should implement autoenabling.
[mainMenu setAutoenablesItems:NO];
var bundle = [CPBundle bundleForClass:[CPApplication class]],
newMenuItem = [[CPMenuItem alloc] initWithTitle:@"New" action:@selector(newDocument:) keyEquivalent:@"n"];
var newMenuItem = [[CPMenuItem alloc] initWithTitle:@"New" action:@selector(newDocument:) keyEquivalent:@"n"];
[newMenuItem setImage:[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPApplication/New.png"] size:CGSizeMake(16.0, 16.0)]];
[newMenuItem setAlternateImage:[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPApplication/NewHighlighted.png"] size:CGSizeMake(16.0, 16.0)]];
[newMenuItem setImage:[[CPTheme defaultTheme] valueForAttributeWithName:@"menu-general-icon-new" forClass:_CPMenuView]];
[newMenuItem setAlternateImage:[[CPTheme defaultTheme] valueForAttributeWithName:@"menu-general-icon-new" inState:CPThemeStateHighlighted forClass:_CPMenuView]];
[mainMenu addItem:newMenuItem];
var openMenuItem = [[CPMenuItem alloc] initWithTitle:@"Open" action:@selector(openDocument:) keyEquivalent:@"o"];
[openMenuItem setImage:[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPApplication/Open.png"] size:CGSizeMake(16.0, 16.0)]];
[openMenuItem setAlternateImage:[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPApplication/OpenHighlighted.png"] size:CGSizeMake(16.0, 16.0)]];
[openMenuItem setImage:[[CPTheme defaultTheme] valueForAttributeWithName:@"menu-general-icon-open" forClass:_CPMenuView]];
[openMenuItem setAlternateImage:[[CPTheme defaultTheme] valueForAttributeWithName:@"menu-general-icon-open" inState:CPThemeStateHighlighted forClass:_CPMenuView]];
[mainMenu addItem:openMenuItem];
var saveMenu = [[CPMenu alloc] initWithTitle:@"Save"],
saveMenuItem = [[CPMenuItem alloc] initWithTitle:@"Save" action:@selector(saveDocument:) keyEquivalent:nil];
[saveMenuItem setImage:[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPApplication/Save.png"] size:CGSizeMake(16.0, 16.0)]];
[saveMenuItem setAlternateImage:[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPApplication/SaveHighlighted.png"] size:CGSizeMake(16.0, 16.0)]];
[saveMenuItem setImage:[[CPTheme defaultTheme] valueForAttributeWithName:@"menu-general-icon-save" forClass:_CPMenuView]];
[saveMenuItem setAlternateImage:[[CPTheme defaultTheme] valueForAttributeWithName:@"menu-general-icon-save" inState:CPThemeStateHighlighted forClass:_CPMenuView]];
[saveMenu addItem:[[CPMenuItem alloc] initWithTitle:@"Save" action:@selector(saveDocument:) keyEquivalent:@"s"]];
[saveMenu addItem:[[CPMenuItem alloc] initWithTitle:@"Save As" action:@selector(saveDocumentAs:) keyEquivalent:nil]];
+17 -8
View File
@@ -897,7 +897,9 @@
if (![self canAdd])
return;
[self insert:sender];
var newObject = [self automaticallyPreparesContent] ? [self newObject] : [self _defaultNewObject];
[self addObject:newObject];
}
/*!
@@ -909,9 +911,14 @@
if (![self canInsert])
return;
var newObject = [self automaticallyPreparesContent] ? [self newObject] : [self _defaultNewObject];
var newObject = [self automaticallyPreparesContent] ? [self newObject] : [self _defaultNewObject],
lastSelectedIndex = [_selectionIndexes lastIndex];
if (lastSelectedIndex)
[self insertObject:newObject atArrangedObjectIndex:lastSelectedIndex];
else
[self addObject:newObject];
[self addObject:newObject];
}
/*!
@@ -964,7 +971,7 @@
// be the 'wrong' one - as in not the one the user selected - but the wrong
// one is still just another pointer to the same object, so the user will not
// be able to see any difference.
contentIndex = [_contentObject indexOfObjectIdenticalTo:object];
var contentIndex = [_contentObject indexOfObjectIdenticalTo:object];
[_contentObject removeObjectAtIndex:contentIndex];
}
[arrangedObjects removeObjectAtIndex:anIndex];
@@ -1073,12 +1080,12 @@
@implementation CPArrayController (CPBinder)
+ (Class)_binderClassForBinding:(CPString)theBinding
+ (Class)_binderClassForBinding:(CPString)aBinding
{
if (theBinding == @"contentArray")
if (aBinding == @"contentArray")
return [_CPArrayControllerContentBinder class];
return [super _binderClassForBinding:theBinding];
return [super _binderClassForBinding:aBinding];
}
@end
@@ -1093,7 +1100,8 @@
isCompound = [self handlesContentAsCompoundValue],
dotIndex = keyPath.lastIndexOf("."),
firstPart = dotIndex !== CPNotFound ? keyPath.substring(0, dotIndex) : nil,
isSelectionProxy = firstPart && [[destination valueForKeyPath:firstPart] isKindOfClass:CPControllerSelectionProxy];
isSelectionProxy = firstPart && [[destination valueForKeyPath:firstPart] isKindOfClass:CPControllerSelectionProxy],
newValue;
if (!isCompound && !isSelectionProxy)
{
@@ -1113,6 +1121,7 @@
}
var isPlaceholder = CPIsControllerMarker(newValue);
if (isPlaceholder)
{
if (newValue === CPNotApplicableMarker && [options objectForKey:CPRaisesForNotApplicableKeysBindingOption])
+14 -5
View File
@@ -61,11 +61,11 @@ var DefaultLineWidth = 1.0;
/*!
Create a new CPBezierPath object initialized with an oval path drawn within a rectangular path.
*/
+ (CPBezierPath)bezierPathWithOvalInRect:(CGRect)rect
+ (CPBezierPath)bezierPathWithOvalInRect:(CGRect)aRect
{
var path = [self bezierPath];
[path appendBezierPathWithOvalInRect:rect];
[path appendBezierPathWithOvalInRect:aRect];
return path;
}
@@ -73,11 +73,20 @@ var DefaultLineWidth = 1.0;
/*!
Create a new CPBezierPath object initialized with a rectangular path.
*/
+ (CPBezierPath)bezierPathWithRect:(CGRect)rect
+ (CPBezierPath)bezierPathWithRect:(CGRect)aRect
{
var path = [self bezierPath];
[path appendBezierPathWithRect:rect];
[path appendBezierPathWithRect:aRect];
return path;
}
+ (CPBezierPath)bezierPathWithRoundedRect:(CGRect)aRect xRadius:(float)xRadius yRadius:(float)yRadius
{
var path = [self bezierPath];
[path appendBezierPathWithRoundedRect:aRect xRadius:xRadius yRadius:yRadius];
return path;
}
@@ -168,7 +177,7 @@ var DefaultLineWidth = 1.0;
- (CGRect)bounds
{
// TODO: this should return this. The controlPointBounds is not a tight fit.
// return CGPathGetPathBoundingBox(_path);
// return CGPathGetBoundingBox(_path);
return [self controlPointBounds];
}
+174 -104
View File
@@ -20,6 +20,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@import "CPTextField.j"
@import "CPView.j"
// CPBoxType
@@ -55,14 +56,6 @@ CPBelowBottom = 6;
{
CPBoxType _boxType;
CPBorderType _borderType;
CPColor _borderColor;
CPColor _fillColor;
float _cornerRadius;
float _borderWidth;
CPSize _contentMargin;
CPView _contentView;
CPString _title @accessors(getter=title);
@@ -70,6 +63,33 @@ CPBelowBottom = 6;
CPTextField _titleView;
}
+ (Class)_binderClassForBinding:(CPString)aBinding
{
if ([aBinding hasPrefix:CPDisplayPatternTitleBinding])
return [CPTitleWithPatternBinding class];
return [super _binderClassForBinding:aBinding];
}
+ (CPString)defaultThemeClass
{
return @"box";
}
+ (id)themeAttributes
{
return @{
@"background-color": [CPNull null],
@"border-color": [CPNull null],
@"border-width": 1.0,
@"corner-radius": 3.0,
@"inner-shadow-offset": CGSizeMakeZero(),
@"inner-shadow-size": 6.0,
@"inner-shadow-color": [CPNull null],
@"content-margin": CGSizeMakeZero(),
};
}
+ (id)boxEnclosingView:(CPView)aView
{
var box = [[self alloc] initWithFrame:CGRectMakeZero()],
@@ -85,18 +105,13 @@ CPBelowBottom = 6;
return box;
}
- (id)initWithFrame:(CPRect)frameRect
- (id)initWithFrame:(CGRect)frameRect
{
self = [super initWithFrame:frameRect];
if (self)
{
_borderType = CPBezelBorder;
_fillColor = [CPColor clearColor];
_borderColor = [CPColor blackColor];
_borderWidth = 1.0;
_contentMargin = CGSizeMake(0.0, 0.0);
_titlePosition = CPNoTitle;
_titleView = [CPTextField labelWithTitle:@""];
@@ -118,7 +133,7 @@ CPBelowBottom = 6;
@return the border rectangle of the box
*/
- (CPRect)borderRect
- (CGRect)borderRect
{
return [self bounds];
}
@@ -208,58 +223,54 @@ CPBelowBottom = 6;
- (CPColor)borderColor
{
return _borderColor;
return [self valueForThemeAttribute:@"border-color"];
}
- (void)setBorderColor:(CPColor)color
{
if ([color isEqual:_borderColor])
if ([color isEqual:[self borderColor]])
return;
_borderColor = color;
[self setNeedsDisplay:YES];
[self setValue:color forThemeAttribute:@"border-color"];
}
- (float)borderWidth
{
return _borderWidth;
return [self valueForThemeAttribute:@"border-width"];
}
- (void)setBorderWidth:(float)width
{
if (width === _borderWidth)
if (width === [self borderWidth])
return;
_borderWidth = width;
[self setNeedsDisplay:YES];
[self setValue:width forThemeAttribute:@"border-width"];
}
- (float)cornerRadius
{
return _cornerRadius;
return [self valueForThemeAttribute:@"corner-radius"];
}
- (void)setCornerRadius:(float)radius
{
if (radius === _cornerRadius)
if (radius === [self cornerRadius])
return;
_cornerRadius = radius;
[self setNeedsDisplay:YES];
[self setValue:radius forThemeAttribute:@"corner-radius"];
}
- (CPColor)fillColor
{
return _fillColor;
return [self valueForThemeAttribute:@"background-color"];
}
- (void)setFillColor:(CPColor)color
{
if ([color isEqual:_fillColor])
if ([color isEqual:[self fillColor]])
return;
_fillColor = color;
[self setNeedsDisplay:YES];
[self setValue:color forThemeAttribute:@"background-color"];
}
- (CPView)contentView
@@ -272,34 +283,43 @@ CPBelowBottom = 6;
if (aView === _contentView)
return;
[aView setFrame:CGRectInset([self bounds], _contentMargin.width + _borderWidth, _contentMargin.height + _borderWidth)];
var borderWidth = [self borderWidth],
contentMargin = [self valueForThemeAttribute:@"content-margin"];
[aView setFrame:CGRectInset([self bounds], contentMargin.width + borderWidth, contentMargin.height + borderWidth)];
[aView setAutoresizingMask:CPViewWidthSizable | CPViewHeightSizable];
[self replaceSubview:_contentView with:aView];
// A nil contentView is allowed (tested in Cocoa 2013-02-22).
if (!aView)
[_contentView removeFromSuperview];
else if (_contentView)
[self replaceSubview:_contentView with:aView];
else
[self addSubview:aView];
_contentView = aView;
}
- (CPSize)contentViewMargins
- (CGSize)contentViewMargins
{
return _contentMargin;
return [self valueForThemeAttribute:@"content-margin"];
}
- (void)setContentViewMargins:(CPSize)size
- (void)setContentViewMargins:(CGSize)size
{
if (size.width < 0 || size.height < 0)
[CPException raise:CPGenericException reason:@"Margins must be positive"];
_contentMargin = CGSizeMakeCopy(size);
[self setNeedsDisplay:YES];
[self setValue:CGSizeMakeCopy(size) forThemeAttribute:@"content-margin"];
}
- (void)setFrameFromContentFrame:(CPRect)aRect
- (void)setFrameFromContentFrame:(CGRect)aRect
{
var offset = [self _titleHeightOffset];
var offset = [self _titleHeightOffset],
borderWidth = [self borderWidth],
contentMargin = [self valueForThemeAttribute:@"content-margin"];
[self setFrame:CGRectInset(aRect, -(_contentMargin.width + _borderWidth), -(_contentMargin.height + offset[0] + _borderWidth))];
[self setNeedsDisplay:YES];
[self setFrame:CGRectInset(aRect, -(contentMargin.width + borderWidth), -(contentMargin.height + offset[0] + borderWidth))];
}
- (void)setTitle:(CPString)aTitle
@@ -332,6 +352,16 @@ CPBelowBottom = 6;
[_titleView setFont:aFont];
}
/*!
Return the text field used to display the receiver's title.
This is the Cappuccino equivalent to the `titleCell` method.
*/
- (CPTextField)titleView
{
return _titleView;
}
- (void)_manageTitlePositioning
{
if (_titlePosition == CPNoTitle)
@@ -350,7 +380,7 @@ CPBelowBottom = 6;
case CPAtTop:
case CPAboveTop:
case CPBelowTop:
[_titleView setFrameOrigin:CPPointMake(5.0, 0.0)];
[_titleView setFrameOrigin:CGPointMake(5.0, 0.0)];
[_titleView setAutoresizingMask:CPViewNotSizable];
break;
@@ -358,7 +388,7 @@ CPBelowBottom = 6;
case CPAtBottom:
case CPBelowBottom:
var h = [_titleView frameSize].height;
[_titleView setFrameOrigin:CPPointMake(5.0, [self frameSize].height - h)];
[_titleView setFrameOrigin:CGPointMake(5.0, [self frameSize].height - h)];
[_titleView setAutoresizingMask:CPViewMinYMargin];
break;
}
@@ -370,17 +400,13 @@ CPBelowBottom = 6;
- (void)sizeToFit
{
var contentFrame = [_contentView frame],
offset = [self _titleHeightOffset];
offset = [self _titleHeightOffset],
contentMargin = [self valueForThemeAttribute:@"content-margin"];
if (!contentFrame)
return;
[_contentView setAutoresizingMask:CPViewNotSizable];
[self setFrameSize:CGSizeMake(contentFrame.size.width + _contentMargin.width * 2,
contentFrame.size.height + _contentMargin.height * 2 + offset[0])];
[_contentView setAutoresizingMask:CPViewWidthSizable | CPViewHeightSizable];
[_contentView setFrameOrigin:CGPointMake(_contentMargin.width, _contentMargin.height + offset[1])];
[_contentView setFrameOrigin:CGPointMake(contentMargin.width, contentMargin.height + offset[1])];
}
- (float)_titleHeightOffset
@@ -401,22 +427,27 @@ CPBelowBottom = 6;
}
}
- (void)drawRect:(CPRect)rect
- (void)setValue:(id)aValue forKey:(CPString)aKey
{
if (_borderType === CPNoBorder)
return;
if (aKey === CPDisplayPatternTitleBinding)
[self setTitle:aValue || @""];
else
[super setValue:aValue forKey:aKey];
}
var bounds = CGRectMakeCopy([self bounds]);
- (void)drawRect:(CGRect)rect
{
var bounds = [self bounds];
switch (_boxType)
{
case CPBoxSeparator:
// NSBox does not include a horizontal flag for the separator type. We have to determine
// the type of separator to draw by the width and height of the frame.
if (CGRectGetWidth(bounds) === 5.0)
return [self _drawVerticalSeperatorInRect:bounds];
else if (CGRectGetHeight(bounds) === 5.0)
return [self _drawHorizontalSeperatorInRect:bounds];
if (_CGRectGetWidth(bounds) === 5.0)
return [self _drawVerticalSeparatorInRect:bounds];
else if (_CGRectGetHeight(bounds) === 5.0)
return [self _drawHorizontalSeparatorInRect:bounds];
break;
}
@@ -431,81 +462,137 @@ CPBelowBottom = 6;
bounds.size.height -= [_titleView frameSize].height;
}
// Primary or secondary type boxes always draw the same way, unless they are CPNoBorder.
if ((_boxType === CPBoxPrimary || _boxType === CPBoxSecondary) && _borderType !== CPNoBorder)
{
[self _drawPrimaryBorderInRect:bounds];
return;
}
switch (_borderType)
{
case CPBezelBorder:
[self _drawBezelBorderInRect:bounds];
break;
default:
case CPGrooveBorder:
case CPLineBorder:
[self _drawLineBorderInRect:bounds];
break;
case CPNoBorder:
[self _drawNoBorderInRect:bounds];
break;
}
}
- (void)_drawHorizontalSeperatorInRect:(CGRect)aRect
- (void)_drawHorizontalSeparatorInRect:(CGRect)aRect
{
var context = [[CPGraphicsContext currentContext] graphicsPort];
CGContextSetStrokeColor(context, [self borderColor]);
CGContextSetLineWidth(context, 1.0);
CGContextMoveToPoint(context, CGRectGetMinX(aRect), CGRectGetMinY(aRect) + 0.5);
CGContextAddLineToPoint(context, CGRectGetWidth(aRect), CGRectGetMinY(aRect) + 0.5);
CGContextMoveToPoint(context, _CGRectGetMinX(aRect), _CGRectGetMidY(aRect));
CGContextAddLineToPoint(context, _CGRectGetWidth(aRect), _CGRectGetMidY(aRect));
CGContextStrokePath(context);
}
- (void)_drawVerticalSeperatorInRect:(CGRect)aRect
- (void)_drawVerticalSeparatorInRect:(CGRect)aRect
{
var context = [[CPGraphicsContext currentContext] graphicsPort];
CGContextSetStrokeColor(context, [self borderColor]);
CGContextSetLineWidth(context, 1.0);
CGContextMoveToPoint(context, CGRectGetMinX(aRect) + 0.5, CGRectGetMinY(aRect));
CGContextAddLineToPoint(context, CGRectGetMinX(aRect) + 0.5, CGRectGetHeight(aRect));
CGContextMoveToPoint(context, _CGRectGetMidX(aRect), _CGRectGetMinY(aRect));
CGContextAddLineToPoint(context, _CGRectGetMidX(aRect), _CGRectGetHeight(aRect));
CGContextStrokePath(context);
}
- (void)_drawLineBorderInRect:(CGRect)aRect
{
var context = [[CPGraphicsContext currentContext] graphicsPort],
cornerRadius = [self cornerRadius],
borderWidth = [self borderWidth];
aRect = CGRectInset(aRect, borderWidth / 2.0, borderWidth / 2.0);
CGContextSetFillColor(context, [self fillColor]);
CGContextSetStrokeColor(context, [self borderColor]);
CGContextSetLineWidth(context, borderWidth);
CGContextFillRoundedRectangleInRect(context, aRect, cornerRadius, YES, YES, YES, YES);
CGContextStrokeRoundedRectangleInRect(context, aRect, cornerRadius, YES, YES, YES, YES);
}
- (void)_drawBezelBorderInRect:(CGRect)aRect
{
var context = [[CPGraphicsContext currentContext] graphicsPort],
sides = [CPMinYEdge, CPMaxXEdge, CPMaxYEdge, CPMinXEdge],
sideGray = 190.0 / 255.0,
grays = [142.0 / 255.0, sideGray, sideGray, sideGray],
borderWidth = _borderWidth;
cornerRadius = [self cornerRadius],
borderWidth = [self borderWidth],
shadowOffset = [self valueForThemeAttribute:@"inner-shadow-offset"],
shadowSize = [self valueForThemeAttribute:@"inner-shadow-size"],
shadowColor = [self valueForThemeAttribute:@"inner-shadow-color"];
while (borderWidth--)
aRect = CPDrawTiledRects(aRect, aRect, sides, grays);
var baseRect = aRect;
aRect = CGRectInset(aRect, borderWidth / 2.0, borderWidth / 2.0);
CGContextSaveGState(context);
CGContextSetStrokeColor(context, [self borderColor]);
CGContextSetLineWidth(context, borderWidth);
CGContextSetFillColor(context, [self fillColor]);
CGContextFillRect(context, aRect);
CGContextFillRoundedRectangleInRect(context, aRect, cornerRadius, YES, YES, YES, YES);
CGContextStrokeRoundedRectangleInRect(context, aRect, cornerRadius, YES, YES, YES, YES);
CGContextRestoreGState(context);
}
- (void)_drawLineBorderInRect:(CGRect)aRect
- (void)_drawPrimaryBorderInRect:(CGRect)aRect
{
// Draw the "primary" style CPBox.
var context = [[CPGraphicsContext currentContext] graphicsPort],
cornerRadius = [self cornerRadius],
borderWidth = [self borderWidth],
shadowOffset = [self valueForThemeAttribute:@"inner-shadow-offset"],
shadowSize = [self valueForThemeAttribute:@"inner-shadow-size"],
shadowColor = [self valueForThemeAttribute:@"inner-shadow-color"],
baseRect = aRect;
aRect = CGRectInset(aRect, borderWidth / 2.0, borderWidth / 2.0);
CGContextSaveGState(context);
CGContextSetStrokeColor(context, [self borderColor]);
CGContextSetLineWidth(context, borderWidth);
CGContextSetFillColor(context, [self fillColor]);
CGContextFillRoundedRectangleInRect(context, aRect, cornerRadius, YES, YES, YES, YES);
CGContextBeginPath(context);
// Note we can't use the 0.5 inset rectangle when setting up clipping. The clipping has to be
// on integer coordinates for this to look right in Chrome.
CGContextAddPath(context, CGPathWithRoundedRectangleInRect(baseRect, cornerRadius, cornerRadius, YES, YES, YES, YES));
CGContextClip(context);
CGContextSetShadowWithColor(context, shadowOffset, shadowSize, shadowColor);
CGContextStrokeRoundedRectangleInRect(context, aRect, cornerRadius, YES, YES, YES, YES);
CGContextRestoreGState(context);
}
- (void)_drawNoBorderInRect:(CGRect)aRect
{
var context = [[CPGraphicsContext currentContext] graphicsPort];
aRect = CGRectInset(aRect, _borderWidth / 2.0, _borderWidth / 2.0);
CGContextSetFillColor(context, [self fillColor]);
CGContextSetStrokeColor(context, [self borderColor]);
CGContextSetLineWidth(context, _borderWidth);
CGContextFillRoundedRectangleInRect(context, aRect, _cornerRadius, YES, YES, YES, YES);
CGContextStrokeRoundedRectangleInRect(context, aRect, _cornerRadius, YES, YES, YES, YES);
CGContextFillRect(context, aRect);
}
@end
var CPBoxTypeKey = @"CPBoxTypeKey",
CPBoxBorderTypeKey = @"CPBoxBorderTypeKey",
CPBoxBorderColorKey = @"CPBoxBorderColorKey",
CPBoxFillColorKey = @"CPBoxFillColorKey",
CPBoxCornerRadiusKey = @"CPBoxCornerRadiusKey",
CPBoxBorderWidthKey = @"CPBoxBorderWidthKey",
CPBoxContentMarginKey = @"CPBoxContentMarginKey",
CPBoxTitle = @"CPBoxTitle",
CPBoxTitlePosition = @"CPBoxTitlePosition",
CPBoxTitleView = @"CPBoxTitleView";
@@ -521,14 +608,6 @@ var CPBoxTypeKey = @"CPBoxTypeKey",
_boxType = [aCoder decodeIntForKey:CPBoxTypeKey];
_borderType = [aCoder decodeIntForKey:CPBoxBorderTypeKey];
_borderColor = [aCoder decodeObjectForKey:CPBoxBorderColorKey];
_fillColor = [aCoder decodeObjectForKey:CPBoxFillColorKey];
_cornerRadius = [aCoder decodeFloatForKey:CPBoxCornerRadiusKey];
_borderWidth = [aCoder decodeFloatForKey:CPBoxBorderWidthKey];
_contentMargin = [aCoder decodeSizeForKey:CPBoxContentMarginKey];
_title = [aCoder decodeObjectForKey:CPBoxTitle];
_titlePosition = [aCoder decodeIntForKey:CPBoxTitlePosition];
_titleView = [aCoder decodeObjectForKey:CPBoxTitleView] || [CPTextField labelWithTitle:_title];
@@ -550,18 +629,9 @@ var CPBoxTypeKey = @"CPBoxTypeKey",
[aCoder encodeInt:_boxType forKey:CPBoxTypeKey];
[aCoder encodeInt:_borderType forKey:CPBoxBorderTypeKey];
[aCoder encodeObject:_borderColor forKey:CPBoxBorderColorKey];
[aCoder encodeObject:_fillColor forKey:CPBoxFillColorKey];
[aCoder encodeFloat:_cornerRadius forKey:CPBoxCornerRadiusKey];
[aCoder encodeFloat:_borderWidth forKey:CPBoxBorderWidthKey];
[aCoder encodeObject:_title forKey:CPBoxTitle];
[aCoder encodeInt:_titlePosition forKey:CPBoxTitlePosition];
[aCoder encodeObject:_titleView forKey:CPBoxTitleView];
[aCoder encodeSize:_contentMargin forKey:CPBoxContentMarginKey];
}
@end
+38 -56
View File
@@ -24,15 +24,16 @@
@import "CPControl.j"
@import "CPImage.j"
@import "CPScrollView.j"
@import "CPTableView.j"
@import "CPTextField.j"
@import "CPScrollView.j"
@global CPApp
/*!
@ingroup appkit
@class CPBrowser
*/
@implementation CPBrowser : CPControl
{
id _delegate;
@@ -65,18 +66,18 @@
CPArray _columnWidths;
}
+ (CPImage)branchImage
+ (CPString)defaultThemeClass
{
return [[CPImage alloc] initWithContentsOfFile:[[CPBundle bundleForClass:[CPBrowser class]]
pathForResource:"browser-leaf.png"]
size:CGSizeMake(9,9)];
return "browser";
}
+ (CPImage)highlightedBranchImage
+ (id)themeAttributes
{
return [[CPImage alloc] initWithContentsOfFile:[[CPBundle bundleForClass:[CPBrowser class]]
pathForResource:"browser-leaf-highlighted.png"]
size:CGSizeMake(9,9)];
return @{
@"image-control-resize": [CPNull null],
@"image-control-leaf": [CPNull null],
@"image-control-leaf-pressed": [CPNull null]
};
}
- (id)initWithFrame:(CGRect)aFrame
@@ -276,8 +277,8 @@
var column = [[CPTableColumn alloc] initWithIdentifier:@"Leaf"],
view = [[_CPBrowserLeafView alloc] initWithFrame:CGRectMakeZero()];
[view setBranchImage:[[self class] branchImage]];
[view setHighlightedBranchImage:[[self class] highlightedBranchImage]];
[view setBranchImage:[self valueForThemeAttribute:@"image-control-leaf"]];
[view setHighlightedBranchImage:[self valueForThemeAttribute:@"image-control-leaf-pressed"]];
[column setDataView:view];
[column setResizingMask:CPTableColumnNoResizing];
@@ -425,11 +426,26 @@
- (void)keyDown:(CPEvent)anEvent
{
var column = [self selectedColumn];
if (column === -1)
var key = [anEvent charactersIgnoringModifiers],
column = [self selectedColumn];
if (column === CPNotFound)
return;
[_tableViews[column] keyDown:anEvent];
if (key === CPLeftArrowFunctionKey || key === CPRightArrowFunctionKey)
{
if (key === CPLeftArrowFunctionKey)
{
var previousColumn = column - 1,
selectedRow = [self selectedRowInColumn:previousColumn];
[self selectRow:selectedRow inColumn:previousColumn];
}
else
[self selectRow:0 inColumn:column + 1];
}
else
[_tableViews[column] keyDown:anEvent];
}
// SIZING
@@ -704,8 +720,6 @@
@end
var _CPBrowserResizeControlBackgroundImage = nil;
@implementation _CPBrowserResizeControl : CPView
{
CGPoint _mouseDownX;
@@ -714,22 +728,14 @@ var _CPBrowserResizeControlBackgroundImage = nil;
unsigned _width;
}
+ (CPImage)backgroundImage
{
if (!_CPBrowserResizeControlBackgroundImage)
{
var path = [[CPBundle bundleForClass:[self class]] pathForResource:"browser-resize-control.png"];
_CPBrowserResizeControlBackgroundImage = [[CPImage alloc] initWithContentsOfFile:path
size:CGSizeMake(15, 14)];
}
return _CPBrowserResizeControlBackgroundImage;
}
- (id)initWithFrame:(CGRect)aFrame
{
if (self = [super initWithFrame:aFrame])
[self setBackgroundColor:[CPColor colorWithPatternImage:[[self class] backgroundImage]]];
{
var browser = [[CPBrowser alloc] init];
[self setBackgroundColor:[CPColor colorWithPatternImage:[browser valueForThemeAttribute:@"image-control-resize"]]];
}
return self;
}
@@ -819,13 +825,13 @@ var _CPBrowserResizeControlBackgroundImage = nil;
return [_browser canDragRowsWithIndexes:rowIndexes inColumn:[_browser columnOfTableView:self] withEvent:[CPApp currentEvent]];
}
- (CPImage)dragImageForRowsWithIndexes:(CPIndexSet)dragRows tableColumns:(CPArray)theTableColumns event:(CPEvent)dragEvent offset:(CPPointPointer)dragImageOffset
- (CPImage)dragImageForRowsWithIndexes:(CPIndexSet)dragRows tableColumns:(CPArray)theTableColumns event:(CPEvent)dragEvent offset:(CGPoint)dragImageOffset
{
return [_browser draggingImageForRowsWithIndexes:dragRows inColumn:[_browser columnOfTableView:self] withEvent:dragEvent offset:dragImageOffset] ||
[super dragImageForRowsWithIndexes:dragRows tableColumns:theTableColumns event:dragEvent offset:dragImageOffset];
}
- (CPView)dragViewForRowsWithIndexes:(CPIndexSet)dragRows tableColumns:(CPArray)theTableColumns event:(CPEvent)dragEvent offset:(CPPoint)dragViewOffset
- (CPView)dragViewForRowsWithIndexes:(CPIndexSet)dragRows tableColumns:(CPArray)theTableColumns event:(CPEvent)dragEvent offset:(CGPoint)dragViewOffset
{
var count = theTableColumns.length;
while (count--)
@@ -838,30 +844,6 @@ var _CPBrowserResizeControlBackgroundImage = nil;
[super dragViewForRowsWithIndexes:dragRows tableColumns:theTableColumns event:dragEvent offset:dragViewOffset];
}
- (void)moveUp:(id)sender
{
[super moveUp:sender];
[_browser selectRow:[self selectedRow] inColumn:[_browser selectedColumn]];
}
- (void)moveDown:(id)sender
{
[super moveDown:sender];
[_browser selectRow:[self selectedRow] inColumn:[_browser selectedColumn]];
}
- (void)moveLeft:(id)sender
{
var previousColumn = [_browser selectedColumn] - 1,
selectedRow = [_browser selectedRowInColumn:previousColumn];
[_browser selectRow:selectedRow inColumn:previousColumn];
}
- (void)moveRight:(id)sender
{
[_browser selectRow:0 inColumn:[_browser selectedColumn] + 1];
}
@end
+34 -18
View File
@@ -25,7 +25,8 @@
@import "CPControl.j"
@import "CPStringDrawing.j"
@import "CPText.j"
@import "CPWindow_Constants.j"
/* @group CPBezelStyle */
@@ -59,11 +60,11 @@ CPMomentaryPushInButton = 7;
CPMomentaryPushButton = 0;
CPMomentaryLight = 7;
CPNoButtonMask = 0;
CPContentsButtonMask = 1;
CPPushInButtonMask = 2;
CPGrayButtonMask = 4;
CPBackgroundButtonMask = 8;
CPNoButtonMask = 0;
CPContentsButtonMask = 1;
CPPushInButtonMask = 2;
CPGrayButtonMask = 4;
CPBackgroundButtonMask = 8;
CPNoCellMask = CPNoButtonMask;
CPContentsCellMask = CPContentsButtonMask;
@@ -71,16 +72,19 @@ CPPushInCellMask = CPPushInButtonMask;
CPChangeGrayCellMask = CPGrayButtonMask;
CPChangeBackgroundCellMask = CPBackgroundButtonMask;
CPButtonStateMixed = CPThemeState("mixed");
CPButtonStateBezelStyleRounded = CPThemeState("rounded");
CPButtonStateMixed = CPThemeState("mixed");
CPButtonStateBezelStyleRounded = CPThemeState("rounded");
// add all future correspondance between bezel styles and theme state here.
var CPButtonBezelStyleStateMap = [CPDictionary dictionaryWithObjects:[CPButtonStateBezelStyleRounded, nil]
forKeys:[CPRoundedBezelStyle, CPRoundRectBezelStyle]];
var CPButtonBezelStyleStateMap = @{
CPRoundedBezelStyle: CPButtonStateBezelStyleRounded,
CPRoundRectBezelStyle: [CPNull null],
};
CPButtonDefaultHeight = 24.0;
/// @cond IGNORE
CPButtonDefaultHeight = 25.0;
CPButtonImageOffset = 3.0;
/// @endcond
/*!
@ingroup appkit
@@ -116,6 +120,14 @@ CPButtonImageOffset = 3.0;
BOOL _isTracking;
}
+ (Class)_binderClassForBinding:(CPString)aBinding
{
if (aBinding === CPTargetBinding || [aBinding hasPrefix:CPArgumentBinding])
return [CPActionBinding class];
return [super _binderClassForBinding:aBinding];
}
+ (id)buttonWithTitle:(CPString)aTitle
{
return [self buttonWithTitle:aTitle theme:[CPTheme defaultTheme]];
@@ -139,8 +151,13 @@ CPButtonImageOffset = 3.0;
+ (id)themeAttributes
{
return [CPDictionary dictionaryWithObjects:[[CPNull null], 0.0, _CGInsetMakeZero(), _CGInsetMakeZero(), [CPNull null]]
forKeys:[@"image", @"image-offset", @"bezel-inset", @"content-inset", @"bezel-color"]];
return @{
@"image": [CPNull null],
@"image-offset": 0.0,
@"bezel-inset": _CGInsetMakeZero(),
@"content-inset": _CGInsetMakeZero(),
@"bezel-color": [CPNull null],
};
}
/*!
@@ -221,7 +238,7 @@ CPButtonImageOffset = 3.0;
else if (![anObjectValue isKindOfClass:[CPNumber class]])
anObjectValue = CPOnState;
else if (anObjectValue >= CPOnState)
anObjectValue = CPOnState
anObjectValue = CPOnState;
else if (anObjectValue < CPOffState)
if ([self allowsMixedState])
anObjectValue = CPMixedState;
@@ -522,6 +539,7 @@ CPButtonImageOffset = 3.0;
_isTracking = YES;
var startedTracking = [super startTrackingAt:aPoint];
if (_highlightsBy & (CPPushInCellMask | CPChangeGrayCellMask))
{
if (_showsStateBy & (CPChangeGrayCellMask | CPChangeBackgroundCellMask))
@@ -536,6 +554,7 @@ CPButtonImageOffset = 3.0;
else
[self highlight:NO];
}
return startedTracking;
}
@@ -988,6 +1007,3 @@ var CPButtonImageKey = @"CPButtonImageKey",
}
@end
@import "CPCheckBox.j"
@import "CPRadio.j"
+40 -5
View File
@@ -1,5 +1,31 @@
/*
* CPButtonBar.j
* AppKit
*
* Created by Francisco Tolmasky.
* Copyright 2009, 280 North, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@import "CPView.j"
@import "CPWindow_Constants.j"
@class CPSplitView
@global CPPopUpButtonStatePullsDown
@implementation CPButtonBar : CPView
@@ -12,7 +38,7 @@
+ (id)plusButton
{
var button = [[CPButton alloc] initWithFrame:CGRectMake(0, 0, 35, 25)],
image = [[CPImage alloc] initWithContentsOfFile:[[CPBundle bundleForClass:[CPButtonBar class]] pathForResource:@"plus_button.png"] size:CGSizeMake(11, 12)];
image = [[CPTheme defaultTheme] valueForAttributeWithName:@"button-image-plus" forClass:[CPButtonBar class]];
[button setBordered:NO];
[button setImage:image];
@@ -24,7 +50,7 @@
+ (id)minusButton
{
var button = [[CPButton alloc] initWithFrame:CGRectMake(0, 0, 35, 25)],
image = [[CPImage alloc] initWithContentsOfFile:[[CPBundle bundleForClass:[CPButtonBar class]] pathForResource:@"minus_button.png"] size:CGSizeMake(11, 4)];
image = [[CPTheme defaultTheme] valueForAttributeWithName:@"button-image-minus" forClass:[CPButtonBar class]];
[button setBordered:NO];
[button setImage:image];
@@ -36,7 +62,7 @@
+ (id)actionPopupButton
{
var button = [[CPPopUpButton alloc] initWithFrame:CGRectMake(0, 0, 35, 25)],
image = [[CPImage alloc] initWithContentsOfFile:[[CPBundle bundleForClass:[CPButtonBar class]] pathForResource:@"action_button.png"] size:CGSizeMake(22, 14)];
image = [[CPTheme defaultTheme] valueForAttributeWithName:@"button-image-action" forClass:[CPButtonBar class]];
[button addItemWithTitle:nil];
[[button lastItem] setImage:image];
@@ -55,8 +81,17 @@
+ (id)themeAttributes
{
return [CPDictionary dictionaryWithObjects:[CGInsetMake(0.0, 0.0, 0.0, 0.0), CGSizeMakeZero(), [CPNull null], [CPNull null], [CPNull null], [CPNull null]]
forKeys:[@"resize-control-inset", @"resize-control-size", @"resize-control-color", @"bezel-color", @"button-bezel-color", @"button-text-color"]];
return @{
@"resize-control-inset": CGInsetMake(0.0, 0.0, 0.0, 0.0),
@"resize-control-size": CGSizeMakeZero(),
@"resize-control-color": [CPNull null],
@"bezel-color": [CPNull null],
@"button-bezel-color": [CPNull null],
@"button-text-color": [CPNull null],
@"button-image-plus": [CPNull null],
@"button-image-minus": [CPNull null],
@"button-image-action": [CPNull null],
};
}
- (id)initWithFrame:(CGRect)aFrame
+3 -3
View File
@@ -44,12 +44,12 @@ CPCheckBoxImageOffset = 4.0;
return @"check-box";
}
+ (Class)_binderClassForBinding:(CPString)theBinding
+ (Class)_binderClassForBinding:(CPString)aBinding
{
if (theBinding === CPValueBinding)
if (aBinding === CPValueBinding)
return [_CPCheckBoxValueBinder class];
return [super _binderClassForBinding:theBinding];
return [super _binderClassForBinding:aBinding];
}
- (id)initWithFrame:(CGRect)aFrame
+30 -18
View File
@@ -22,6 +22,7 @@
@import "CPView.j"
@class CPScrollView
/*!
@ingroup appkit
@@ -44,10 +45,10 @@
if (_documentView == aView)
return;
var defaultCenter = [CPNotificationCenter defaultCenter];
if (_documentView)
{
var defaultCenter = [CPNotificationCenter defaultCenter];
[defaultCenter
removeObserver:self
name:CPViewFrameDidChangeNotification
@@ -66,24 +67,30 @@
if (_documentView)
{
[self addSubview:_documentView];
[_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];
[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];
}
/*!
Returns the document view.
*/
@@ -233,7 +240,12 @@ var CPClipViewDocumentViewKey = @"CPScrollViewDocumentView";
- (id)initWithCoder:(CPCoder)aCoder
{
if (self = [super initWithCoder:aCoder])
[self setDocumentView:[aCoder decodeObjectForKey:CPClipViewDocumentViewKey]];
{
// 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;
}
+553 -204
View File
@@ -20,15 +20,22 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#import "../Foundation/CPRange.h"
@import <Foundation/CPArray.j>
@import <Foundation/CPData.j>
@import <Foundation/CPIndexSet.j>
@import <Foundation/CPKeyedArchiver.j>
@import <Foundation/CPKeyedUnarchiver.j>
@import "CPView.j"
@import "CPCollectionViewItem.j"
@import "CPCompatibility.j"
@import "CPDragServer_Constants.j"
@import "CPPasteboard.j"
@import "CPView.j"
@class CPClipView
/*!
@ingroup appkit
@@ -41,7 +48,7 @@
@par Delegate Methods
@delegate - (void)collectionViewDidChangeSelection:(CPCollectionView)collectionView;
Called when the selection in the collection view has changed.
DEPRECATED: Please do not use.
@param collectionView the collection view who's selection changed
@delegate - (void)collectionView:(CPCollectionView)collectionView didDoubleClickOnItemAtIndex:(int)index;
@@ -63,6 +70,8 @@
@return an array of drag types (CPString)
*/
var HORIZONTAL_MARGIN = 2;
@implementation CPCollectionView : CPView
{
CPArray _content;
@@ -99,6 +108,17 @@
id _delegate;
CPEvent _mouseDownEvent;
BOOL _needsMinMaxItemSizeUpdate;
CGSize _storedFrameSize;
BOOL _uniformSubviewsResizing @accessors(property=uniformSubviewsResizing);
BOOL _lockResizing;
CPInteger _currentDropIndex;
CPDragOperation _currentDragOperation;
_CPCollectionViewDropIndicator _dropView;
}
- (id)initWithFrame:(CGRect)aFrame
@@ -107,46 +127,69 @@
if (self)
{
_items = [];
_content = [];
_maxNumberOfRows = 0;
_maxNumberOfColumns = 0;
_cachedItems = [];
_itemSize = CGSizeMakeZero();
_minItemSize = CGSizeMakeZero();
_maxItemSize = CGSizeMakeZero();
_minItemSize = _CGSizeMakeZero();
_maxItemSize = _CGSizeMakeZero();
[self setBackgroundColors:nil];
_verticalMargin = 5.0;
_tileWidth = -1.0;
_selectionIndexes = [CPIndexSet indexSet];
_allowsEmptySelection = YES;
_isSelectable = YES;
_allowsEmptySelection = YES;
[self _init];
}
return self;
}
- (void)_init
{
_content = [];
_items = [];
_cachedItems = [];
_numberOfColumns = CPNotFound;
_numberOfRows = CPNotFound;
_itemSize = _CGSizeMakeZero();
_selectionIndexes = [CPIndexSet indexSet];
_storedFrameSize = _CGSizeMakeZero();
_needsMinMaxItemSizeUpdate = YES;
_uniformSubviewsResizing = NO;
_lockResizing = NO;
_currentDropIndex = -1;
_currentDragOperation = CPDragOperationNone;
_dropView = nil;
[self setAutoresizesSubviews:NO];
[self setAutoresizingMask:0];
}
/*!
Sets the item prototype to \c anItem
The item prototype should implement the CPCoding protocol
because the item is copied by archiving and unarchiving the
prototypal view.
because the item is copied by archiving and unarchiving.
Example:
<pre>
@implement MyCustomView : CPCollectionViewItem
@implement MyCustomViewItem : CPCollectionViewItem
{
CPArray items @accessors;
}
- (id)initWithFrame:(CGRect)aFrame
- (id)initWithCibName:(CPString)aCibNameOrNil bundle:(CPBundle)aCibBundleOrNil
{
self = [super initWithFrame:aFrame];
self = [super initWithCibName:aCibNameOrNil bundle:aCibBundleOrNil];
if (self)
{
items = [];
@@ -183,7 +226,7 @@
_itemForDragging = nil;
_itemPrototype = anItem;
[self reloadContent];
[self _reloadContentCachingRemovedItems:NO];
}
/*!
@@ -206,13 +249,7 @@
item = _cachedItems.pop();
else
{
if (!_itemData)
if (_itemPrototype)
_itemData = [CPKeyedArchiver archivedDataWithRootObject:_itemPrototype];
item = [CPKeyedUnarchiver unarchiveObjectWithData:_itemData];
}
item = [_itemPrototype copy];
[item setRepresentedObject:anObject];
[[item view] setFrameSize:_itemSize];
@@ -367,7 +404,10 @@
[[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];
}
}
/*!
@@ -378,8 +418,13 @@
return [_selectionIndexes copy];
}
/* @ignore */
- (void)reloadContent
{
[self _reloadContentCachingRemovedItems:YES];
}
/* @ignore */
- (void)_reloadContentCachingRemovedItems:(BOOL)shouldCache
{
// Remove current views
var count = _items.length;
@@ -389,7 +434,8 @@
[[_items[count] view] removeFromSuperview];
[_items[count] setSelected:NO];
_cachedItems.push(_items[count]);
if (shouldCache)
_cachedItems.push(_items[count]);
}
_items = [];
@@ -413,91 +459,166 @@
while ((index = [_selectionIndexes indexGreaterThanIndex:index]) != CPNotFound && index < count)
[_items[index] setSelected:YES];
[self tile];
[self tileIfNeeded:NO];
}
/* @ignore */
- (void)tile
- (void)resizeSubviewsWithOldSize:(CPSize)oldBoundsSize
{
var width = CGRectGetWidth([self bounds]);
// Desactivate subviews autoresizing
}
if (width == _tileWidth)
- (void)resizeWithOldSuperviewSize:(CPSize)oldBoundsSize
{
if (_lockResizing)
return;
// We try to fit as many views per row as possible. Any remaining space is then
// either proportioned out to the views (if their minSize != maxSize) or used as
// margin
var itemSize = CGSizeMakeCopy(_minItemSize);
_lockResizing = YES;
_numberOfColumns = MAX(1.0, FLOOR(width / itemSize.width));
[self tile];
if (_maxNumberOfColumns > 0)
_numberOfColumns = MIN(_maxNumberOfColumns, _numberOfColumns);
var remaining = width - _numberOfColumns * itemSize.width,
itemsNeedSizeUpdate = NO;
if (remaining > 0 && itemSize.width < _maxItemSize.width)
itemSize.width = MIN(_maxItemSize.width, itemSize.width + FLOOR(remaining / _numberOfColumns));
// When we ONE column and a non-integral width, the FLOORing above can cause the item width to be smaller than the total width.
if (_maxNumberOfColumns == 1 && itemSize.width < _maxItemSize.width && itemSize.width < width)
itemSize.width = MIN(_maxItemSize.width, width);
if (!CGSizeEqualToSize(_itemSize, itemSize))
{
_itemSize = itemSize;
itemsNeedSizeUpdate = YES;
}
var index = 0,
count = _items.length;
if (_maxNumberOfColumns > 0 && _maxNumberOfRows > 0)
count = MIN(count, _maxNumberOfColumns * _maxNumberOfRows);
_numberOfRows = CEIL(count / _numberOfColumns);
_horizontalMargin = FLOOR((width - _numberOfColumns * itemSize.width) / (_numberOfColumns + 1));
var x = _horizontalMargin,
y = -itemSize.height;
for (; index < count; ++index)
{
if (index % _numberOfColumns == 0)
{
x = _horizontalMargin;
y += _verticalMargin + itemSize.height;
}
var view = [_items[index] view];
[view setFrameOrigin:CGPointMake(x, y)];
if (itemsNeedSizeUpdate)
[view setFrameSize:_itemSize];
x += itemSize.width + _horizontalMargin;
}
var superview = [self superview],
proposedHeight = y + itemSize.height + _verticalMargin;
if ([superview isKindOfClass:[CPClipView class]])
{
var superviewSize = [superview bounds].size;
proposedHeight = MAX(superviewSize.height, proposedHeight);
}
_tileWidth = width;
[self setFrameSize:CGSizeMake(width, proposedHeight)];
_tileWidth = -1.0;
_lockResizing = NO;
}
- (void)resizeSubviewsWithOldSize:(CGSize)aSize
- (void)tile
{
[self tile];
[self tileIfNeeded:!_uniformSubviewsResizing];
}
- (void)tileIfNeeded:(BOOL)lazyFlag
{
var frameSize = [[self superview] frameSize],
count = _items.length,
oldNumberOfColumns = _numberOfColumns,
oldNumberOfRows = _numberOfRows,
oldItemSize = _itemSize,
storedFrameSize = _storedFrameSize;
// No need to tile if we are not yet placed in the view hierarchy.
if (!frameSize)
return;
[self _updateMinMaxItemSizeIfNeeded];
[self _computeGridWithSize:frameSize count:@ref(count)];
//CPLog.debug("frameSize="+CPStringFromSize(frameSize) + "itemSize="+CPStringFromSize(itemSize) + " ncols=" + colsRowsCount[0] +" nrows="+ colsRowsCount[1]+" displayCount="+ colsRowsCount[2]);
[self setFrameSize:_storedFrameSize];
//CPLog.debug("OLD " + oldNumberOfColumns + " NEW " + _numberOfColumns);
if (!lazyFlag ||
_numberOfColumns !== oldNumberOfColumns ||
_numberOfRows !== oldNumberOfRows ||
!_CGSizeEqualToSize(_itemSize, oldItemSize))
[self displayItems:_items frameSize:_storedFrameSize itemSize:_itemSize columns:_numberOfColumns rows:_numberOfRows count:count];
}
- (void)_computeGridWithSize:(CGSize)aSuperviewSize count:(Function)countRef
{
var width = aSuperviewSize.width,
height = aSuperviewSize.height,
itemSize = _CGSizeMakeCopy(_minItemSize),
maxItemSizeWidth = _maxItemSize.width,
maxItemSizeHeight = _maxItemSize.height,
itemsCount = [_items count],
numberOfRows,
numberOfColumns;
numberOfColumns = FLOOR(width / itemSize.width);
if (maxItemSizeWidth == 0)
numberOfColumns = MIN(numberOfColumns, _maxNumberOfColumns);
if (_maxNumberOfColumns > 0)
numberOfColumns = MIN(MIN(_maxNumberOfColumns, itemsCount), numberOfColumns);
numberOfColumns = MAX(1.0, numberOfColumns);
itemSize.width = FLOOR(width / numberOfColumns);
if (maxItemSizeWidth > 0)
{
itemSize.width = MIN(maxItemSizeWidth, itemSize.width);
if (numberOfColumns == 1)
itemSize.width = MIN(maxItemSizeWidth, width);
}
numberOfRows = CEIL(itemsCount / numberOfColumns);
if (_maxNumberOfRows > 0)
numberOfRows = MIN(numberOfRows, _maxNumberOfRows);
height = MAX(height, numberOfRows * (_minItemSize.height + _verticalMargin));
var itemSizeHeight = FLOOR(height / numberOfRows);
if (maxItemSizeHeight > 0)
itemSizeHeight = MIN(itemSizeHeight, maxItemSizeHeight);
_itemSize = _CGSizeMake(MAX(_minItemSize.width, itemSize.width), MAX(_minItemSize.height, itemSizeHeight));
_storedFrameSize = _CGSizeMake(MAX(width, _minItemSize.width), height);
_numberOfColumns = numberOfColumns;
_numberOfRows = numberOfRows;
countRef(MIN(itemsCount, numberOfColumns * numberOfRows));
}
- (void)displayItems:(CPArray)displayItems frameSize:(CGSize)aFrameSize itemSize:(CGSize)anItemSize columns:(CPInteger)numberOfColumns rows:(CPInteger)numberOfRows count:(CPInteger)displayCount
{
// CPLog.debug("DISPLAY ITEMS " + numberOfColumns + " " + numberOfRows);
_horizontalMargin = _uniformSubviewsResizing ? FLOOR((aFrameSize.width - numberOfColumns * anItemSize.width) / (numberOfColumns + 1)) : HORIZONTAL_MARGIN;
var x = _horizontalMargin,
y = -anItemSize.height;
[displayItems enumerateObjectsUsingBlock:function(item, idx, stop)
{
var view = [item view];
if (idx >= displayCount)
{
[view setFrameOrigin:_CGPointMake(-anItemSize.width, -anItemSize.height)];
return;
}
if (idx % numberOfColumns == 0)
{
x = _horizontalMargin;
y += _verticalMargin + anItemSize.height;
}
[view setFrameOrigin:_CGPointMake(x, y)];
[view setFrameSize:anItemSize];
x += anItemSize.width + _horizontalMargin;
}];
}
- (void)_updateMinMaxItemSizeIfNeeded
{
if (!_needsMinMaxItemSizeUpdate)
return;
var prototypeView;
if (_itemPrototype && (prototypeView = [_itemPrototype view]))
{
if (_minItemSize.width == 0)
_minItemSize.width = [prototypeView frameSize].width;
if (_minItemSize.height == 0)
_minItemSize.height = [prototypeView frameSize].height;
if (_maxItemSize.height == 0 && !([prototypeView autoresizingMask] & CPViewHeightSizable))
_maxItemSize.height = [prototypeView frameSize].height;
if (_maxItemSize.width == 0 && !([prototypeView autoresizingMask] & CPViewWidthSizable))
_maxItemSize.width = [prototypeView frameSize].width;
_needsMinMaxItemSizeUpdate = NO;
}
}
// Laying Out the Collection View
@@ -570,10 +691,14 @@
{
if (aSize === nil || aSize === undefined)
[CPException raise:CPInvalidArgumentException reason:"Invalid value provided for minimum size"];
if (CGSizeEqualToSize(_minItemSize, aSize))
if (_CGSizeEqualToSize(_minItemSize, aSize))
return;
_minItemSize = CGSizeMakeCopy(aSize);
_minItemSize = _CGSizeMakeCopy(aSize);
if (_CGSizeEqualToSize(_minItemSize, _CGSizeMakeZero()))
_needsMinMaxItemSizeUpdate = YES;
[self tile];
}
@@ -592,10 +717,13 @@
*/
- (void)setMaxItemSize:(CGSize)aSize
{
if (CGSizeEqualToSize(_maxItemSize, aSize))
if (_CGSizeEqualToSize(_maxItemSize, aSize))
return;
_maxItemSize = CGSizeMakeCopy(aSize);
_maxItemSize = _CGSizeMakeCopy(aSize);
// if (_maxItemSize.width == 0 || _maxItemSize.height == 0)
// _needsMinMaxItemSizeUpdate = YES;
[self tile];
}
@@ -616,7 +744,7 @@
_backgroundColors = backgroundColors;
if (!_backgroundColors)
_backgroundColors = [CPColor whiteColor];
_backgroundColors = [[CPColor whiteColor]];
if ([_backgroundColors count] === 1)
[self setBackgroundColor:_backgroundColors[0]];
@@ -664,9 +792,9 @@
newSelectedRange = nil;
if (index < firstSelectedIndex)
newSelectedRange = CPMakeRange(index, (firstSelectedIndex - index) + 1);
newSelectedRange = _CPMakeRange(index, (firstSelectedIndex - index) + 1);
else
newSelectedRange = CPMakeRange(firstSelectedIndex, (index - firstSelectedIndex) + 1);
newSelectedRange = _CPMakeRange(firstSelectedIndex, (index - firstSelectedIndex) + 1);
indexes = [[self selectionIndexes] copy];
[indexes addIndexesInRange:newSelectedRange];
@@ -688,65 +816,6 @@
[self setSelectionIndexes:[CPIndexSet indexSet]];
}
- (void)mouseDragged:(CPEvent)anEvent
{
// Don't crash if we never registered the intial click.
if (!_mouseDownEvent)
return;
var locationInWindow = [anEvent locationInWindow],
mouseDownLocationInWindow = [_mouseDownEvent locationInWindow];
// FIXME: This is because Safari's drag hysteresis is 3px x 3px
if ((ABS(locationInWindow.x - mouseDownLocationInWindow.x) < 3) &&
(ABS(locationInWindow.y - mouseDownLocationInWindow.y) < 3))
return;
if (![_delegate respondsToSelector:@selector(collectionView:dragTypesForItemsAtIndexes:)])
return;
// 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])
return;
// Set up the pasteboard
var dragTypes = [_delegate collectionView:self dragTypesForItemsAtIndexes:_selectionIndexes];
[[CPPasteboard pasteboardWithName:CPDragPboard] declareTypes:dragTypes owner:self];
if (!_itemForDragging)
_itemForDragging = [self newItemForRepresentedObject:_content[[_selectionIndexes firstIndex]]];
else
[_itemForDragging setRepresentedObject:_content[[_selectionIndexes firstIndex]]];
var view = [_itemForDragging view];
[view setFrameSize:_itemSize];
[view setAlphaValue:0.7];
[self dragView:view
at:[[_items[[_selectionIndexes firstIndex]] view] frame].origin
offset:CGSizeMakeZero()
event:_mouseDownEvent
pasteboard:nil
source:self
slideBack:YES];
}
/*!
Places the selected items on the specified pasteboard. The items are requested from the collection's delegate.
@param aPasteboard the pasteboard to put the items on
@param aType the format the pasteboard data
*/
- (void)pasteboard:(CPPasteboard)aPasteboard provideDataForType:(CPString)aType
{
[aPasteboard setData:[_delegate collectionView:self dataForItemsAtIndexes:_selectionIndexes forType:aType] forType:aType];
}
// Cappuccino Additions
/*!
@@ -764,6 +833,13 @@
[self tile];
}
- (void)setUniformSubviewsResizing:(float)flag
{
_uniformSubviewsResizing = flag;
[self tileIfNeeded:NO];
}
/*!
Gets the collection view's current vertical spacing between elements.
*/
@@ -806,10 +882,17 @@
- (int)_indexAtPoint:(CGPoint)thePoint
{
var row = FLOOR(thePoint.y / (_itemSize.height + _verticalMargin)),
column = FLOOR(thePoint.x / (_itemSize.width + _horizontalMargin));
var column = FLOOR(thePoint.x / (_itemSize.width + _horizontalMargin));
return row * _numberOfColumns + column;
if (column < _numberOfColumns)
{
var row = FLOOR(thePoint.y / (_itemSize.height + _verticalMargin));
if (row < _numberOfRows)
return (row * _numberOfColumns + column);
}
return CPNotFound;
}
- (CPCollectionViewItem)itemAtIndex:(unsigned)anIndex
@@ -840,6 +923,294 @@
@end
@implementation CPCollectionView (DragAndDrop)
/*
TODO: dropOperation is not supported yet. The visible drop operation is like CPCollectionViewDropBefore.
*/
/*!
Places the selected items on the specified pasteboard. The items are requested from the collection's delegate.
@param aPasteboard the pasteboard to put the items on
@param aType the format the pasteboard data
*/
- (void)pasteboard:(CPPasteboard)aPasteboard provideDataForType:(CPString)aType
{
[aPasteboard setData:[_delegate collectionView:self dataForItemsAtIndexes:_selectionIndexes forType:aType] forType:aType];
}
- (void)_createDropIndicatorIfNeeded
{
// Create and position the drop indicator view.
if (!_dropView)
_dropView = [[_CPCollectionViewDropIndicator alloc] initWithFrame:_CGRectMake(-8, -8, 0, 0)];
[_dropView setFrameSize:_CGSizeMake(10, _itemSize.height + _verticalMargin)];
[self addSubview:_dropView];
}
- (void)mouseDragged:(CPEvent)anEvent
{
// Don't crash if we never registered the intial click.
if (!_mouseDownEvent)
return;
[self _createDropIndicatorIfNeeded];
var locationInWindow = [anEvent locationInWindow],
mouseDownLocationInWindow = [_mouseDownEvent locationInWindow];
// FIXME: This is because Safari's drag hysteresis is 3px x 3px
if ((ABS(locationInWindow.x - mouseDownLocationInWindow.x) < 3) &&
(ABS(locationInWindow.y - mouseDownLocationInWindow.y) < 3))
return;
if (![_delegate respondsToSelector:@selector(collectionView:dragTypesForItemsAtIndexes:)])
return;
// 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])
return;
// Set up the pasteboard
var dragTypes = [_delegate collectionView:self dragTypesForItemsAtIndexes:_selectionIndexes];
[[CPPasteboard pasteboardWithName:CPDragPboard] declareTypes:dragTypes owner:self];
var dragImageOffset = _CGSizeMakeZero(),
view = [self _draggingViewForItemsAtIndexes:_selectionIndexes withEvent:_mouseDownEvent offset:dragImageOffset];
[view setFrameSize:_itemSize];
[view setAlphaValue:0.7];
var dragLocation = [self convertPoint:locationInWindow fromView:nil],
dragPoint = _CGPointMake(dragLocation.x - _itemSize.width / 2 , dragLocation.y - _itemSize.height / 2);
[self dragView:view
at:dragPoint
offset:dragImageOffset
event:_mouseDownEvent
pasteboard:nil
source:self
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]];
if (!_itemForDragging)
_itemForDragging = [self newItemForRepresentedObject:idx];
else
[_itemForDragging setRepresentedObject:idx];
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,
dropIndexRef = @ref(dropIndex),
dragOp = [self _validateDragWithInfo:draggingInfo dropIndex:dropIndexRef dropOperation:1];
dropIndex = dropIndexRef();
[self _createDropIndicatorIfNeeded];
[self _updateDragAndDropStateWithDraggingInfo:draggingInfo newDragOperation:dragOp newDropIndex:dropIndex newDropOperation:1];
return _currentDragOperation;
}
- (CPDragOperation)draggingUpdated:(id)draggingInfo
{
if (![self _dropIndexDidChange:draggingInfo])
return _currentDragOperation;
var dropIndex,
dropIndexRef = @ref(dropIndex);
var dragOperation = [self _validateDragWithInfo:draggingInfo dropIndex:dropIndexRef dropOperation:1];
dropIndex = dropIndexRef();
[self _updateDragAndDropStateWithDraggingInfo:draggingInfo newDragOperation:dragOperation newDropIndex:dropIndex newDropOperation:1];
return dragOperation;
}
- (CPDragOperation)_validateDragWithInfo:(id)draggingInfo dropIndex:(Function)dropIndexRef dropOperation:(int)dropOperation
{
var result = CPDragOperationMove,
dropIndex = [self _dropIndexForDraggingInfo:draggingInfo proposedDropOperation:dropOperation];
if ([_delegate respondsToSelector:@selector(collectionView:validateDrop:proposedIndex:dropOperation:)])
{
var dropIndexRef2 = @ref(dropIndex);
result = [_delegate collectionView:self validateDrop:draggingInfo proposedIndex:dropIndexRef2 dropOperation:dropOperation];
if (result !== CPDragOperationNone)
{
dropIndex = dropIndexRef2();
}
}
dropIndexRef(dropIndex);
return result;
}
- (void)draggingExited:(id)draggingInfo
{
[self _updateDragAndDropStateWithDraggingInfo:draggingInfo newDragOperation:0 newDropIndex:-1 newDropOperation:1];
}
- (void)draggingEnded:(id)draggingInfo
{
[self _updateDragAndDropStateWithDraggingInfo:draggingInfo newDragOperation:0 newDropIndex:-1 newDropOperation:1];
}
/*
Not supported. Use -collectionView:dataForItemsAtIndexes:fortype:
- (BOOL)_writeItemsAtIndexes:(CPIndexSet)indexes toPasteboard:(CPPasteboard)pboard
{
if ([self respondsToSelector:@selector(collectionView:writeItemsAtIndexes:toPasteboard:)])
return [_delegate collectionView:self writeItemsAtIndexes:indexes toPasteboard:pboard];
return NO;
}
*/
- (BOOL)performDragOperation:(id)draggingInfo
{
var result = NO;
if (_currentDragOperation && _currentDropIndex !== -1)
result = [_delegate collectionView:self acceptDrop:draggingInfo index:_currentDropIndex dropOperation:1];
[self draggingEnded:draggingInfo]; // Is this correct ?
return result;
}
- (void)_updateDragAndDropStateWithDraggingInfo:(id)draggingInfo newDragOperation:(CPDragOperation)dragOperation newDropIndex:(CPInteger)dropIndex newDropOperation:(CPInteger)dropOperation
{
_currentDropIndex = dropIndex;
_currentDragOperation = dragOperation;
var frameOrigin,
dropviewFrameWidth = _CGRectGetWidth([_dropView frame]);
if (_currentDropIndex == -1 || _currentDragOperation == CPDragOperationNone)
frameOrigin = _CGPointMake(-dropviewFrameWidth, 0);
else if (_currentDropIndex == 0)
frameOrigin = _CGPointMake(0, 0);
else
{
var offset;
if ((_currentDropIndex % _numberOfColumns) !== 0 || _currentDropIndex == [_items count])
{
dropIndex = _currentDropIndex - 1;
offset = (_horizontalMargin - dropviewFrameWidth) / 2;
}
else
{
offset = - _itemSize.width - dropviewFrameWidth - (_horizontalMargin - dropviewFrameWidth) / 2;
}
var rect = [self frameForItemAtIndex:dropIndex];
frameOrigin = _CGPointMake(_CGRectGetMaxX(rect) + offset, rect.origin.y - _verticalMargin);
}
[_dropView setFrameOrigin:frameOrigin];
}
- (BOOL)_dropIndexDidChange:(id)draggingInfo
{
var dropIndex = [self _dropIndexForDraggingInfo:draggingInfo proposedDropOperation:1];
if (dropIndex == CPNotFound)
dropIndex = [[self content] count];
return (_currentDropIndex !== dropIndex)
}
- (CPInteger)_dropIndexForDraggingInfo:(id)draggingInfo proposedDropOperation:(int)dropOperation
{
var location = [self convertPoint:[draggingInfo draggingLocation] fromView:nil],
locationX = location.x + _itemSize.width / 2;
var column = MIN(FLOOR(locationX / (_itemSize.width + _horizontalMargin)), _numberOfColumns),
row = FLOOR(location.y / (_itemSize.height + _verticalMargin));
if (row >= _numberOfRows - 1)
{
if (row >= _numberOfRows)
{
row = _numberOfRows - 1;
column = _numberOfColumns;
}
return MIN((row * _numberOfColumns + column), [_items count]);
}
return (row * _numberOfColumns + column);
}
@end
@implementation _CPCollectionViewDropIndicator : CPView
{
}
- (void)drawRect:(CGRect)aRect
{
var context = [[CPGraphicsContext currentContext] graphicsPort],
width = _CGRectGetWidth(aRect),
circleRect = _CGRectMake(1, 1, width - 2, width - 2);
CGContextSetStrokeColor(context, [CPColor colorWithHexString:@"4886ca"]);
CGContextSetFillColor(context, [CPColor whiteColor]);
CGContextSetLineWidth(context, 3);
//draw white under the circle thing
CGContextFillRect(context, circleRect);
//draw the circle thing
CGContextStrokeEllipseInRect(context, circleRect);
//then draw the line
CGContextBeginPath(context);
CGContextMoveToPoint(context, FLOOR(width / 2), _CGRectGetMinY(aRect) + width);
CGContextAddLineToPoint(context, FLOOR(width / 2), _CGRectGetHeight(aRect));
CGContextStrokePath(context);
}
@end
@implementation CPCollectionView (KeyboardInteraction)
- (void)_modifySelectionWithNewIndex:(int)anIndex direction:(int)aDirection expand:(BOOL)shouldExpand
@@ -854,9 +1225,9 @@
// if the direction is backward (-1) check with the bottom anchor
if (aDirection === -1)
[indexes addIndexesInRange:CPMakeRange(anIndex, bottomAnchor - anIndex + 1)];
[indexes addIndexesInRange:_CPMakeRange(anIndex, bottomAnchor - anIndex + 1)];
else
[indexes addIndexesInRange:CPMakeRange(topAnchor, anIndex - topAnchor + 1)];
[indexes addIndexesInRange:_CPMakeRange(topAnchor, anIndex - topAnchor + 1)];
}
else
indexes = [CPIndexSet indexSetWithIndex:anIndex];
@@ -869,7 +1240,7 @@
{
var frame = [self frameForItemsAtIndexes:[self selectionIndexes]];
if (!CGRectIsNull(frame))
if (!_CGRectIsNull(frame))
[self scrollRectToVisible:frame];
}
@@ -949,6 +1320,11 @@
[self interpretKeyEvents:[anEvent]];
}
- (void)setAutoresizingMask:(int)aMask
{
[super setAutoresizingMask:0];
}
@end
@implementation CPCollectionView (Deprecated)
@@ -983,35 +1359,12 @@ var CPCollectionViewMinItemSizeKey = @"CPCollectionViewMinItemSizeK
@implementation CPCollectionView (CPCoding)
- (void)awakeFromCib
{
[super awakeFromCib];
var prototypeView = [_itemPrototype view];
if (prototypeView && (CGSizeEqualToSize(_minItemSize, CGSizeMakeZero()) || CGSizeEqualToSize(_maxItemSize, CGSizeMakeZero())))
{
var item = _itemPrototype;
if (CGSizeEqualToSize(_minItemSize, CGSizeMakeZero()))
_minItemSize = [prototypeView frameSize];
else if (CGSizeEqualToSize(_maxItemSize, CGSizeMakeZero()))
_maxItemSize = [prototypeView frameSize];
}
}
- (id)initWithCoder:(CPCoder)aCoder
{
self = [super initWithCoder:aCoder];
if (self)
{
_items = [];
_content = [];
_cachedItems = [];
_itemSize = CGSizeMakeZero();
_minItemSize = [aCoder decodeSizeForKey:CPCollectionViewMinItemSizeKey];
_maxItemSize = [aCoder decodeSizeForKey:CPCollectionViewMaxItemSizeKey];
@@ -1025,11 +1378,7 @@ var CPCollectionViewMinItemSizeKey = @"CPCollectionViewMinItemSizeK
[self setBackgroundColors:[aCoder decodeObjectForKey:CPCollectionViewBackgroundColorsKey]];
_tileWidth = -1.0;
_selectionIndexes = [CPIndexSet indexSet];
_allowsEmptySelection = YES;
[self _init];
}
return self;
@@ -1039,10 +1388,10 @@ var CPCollectionViewMinItemSizeKey = @"CPCollectionViewMinItemSizeK
{
[super encodeWithCoder:aCoder];
if (!CGSizeEqualToSize(_minItemSize, CGSizeMakeZero()))
if (!_CGSizeEqualToSize(_minItemSize, _CGSizeMakeZero()))
[aCoder encodeSize:_minItemSize forKey:CPCollectionViewMinItemSizeKey];
if (!CGSizeEqualToSize(_maxItemSize, CGSizeMakeZero()))
if (!_CGSizeEqualToSize(_maxItemSize, _CGSizeMakeZero()))
[aCoder encodeSize:_maxItemSize forKey:CPCollectionViewMaxItemSizeKey];
[aCoder encodeInt:_maxNumberOfRows forKey:CPCollectionViewMaxNumberOfRowsKey];
+26 -1
View File
@@ -22,13 +22,38 @@
@import "CPViewController.j"
/*!
Represents an object inside a CPCollectionView.
*/
@implementation CPCollectionViewItem : CPViewController
{
BOOL _isSelected;
CPData _cachedArchive;
}
- (id)copy
{
var cibName = [self cibName],
copy;
if (cibName)
{
copy = [[[self class] alloc] initWithCibName:cibName bundle:[self cibBundle]];
}
else
{
if (!_cachedArchive)
_cachedArchive = [CPKeyedArchiver archivedDataWithRootObject:self];
copy = [CPKeyedUnarchiver unarchiveObjectWithData:_cachedArchive];
// copy connections
}
[copy setRepresentedObject:[self representedObject]];
[copy setSelected:_isSelected];
return copy;
}
// Setting the Represented Object
+561 -60
View File
@@ -21,12 +21,24 @@
*/
@import <Foundation/CPObject.j>
@import "CPGraphicsContext.j"
@import "CGColor.j"
@import "CPCompatibility.j"
@import "CPImage.j"
/*!
Orientation to use with \c CPColorPattern for vertical patterns.
*/
CPColorPatternIsVertical = YES;
/*!
Orientation to use with \c CPColorPattern for horizontal patterns.
*/
CPColorPatternIsHorizontal = NO;
/// @cond IGNORE
var _redComponent = 0,
@@ -57,64 +69,6 @@ var cachedBlackColor,
/// @endcond
/*!
Orientation to use with \c CPColorPattern for vertical patterns.
*/
CPColorPatternIsVertical = YES;
/*!
Orientation to use with \c CPColorPattern for horizontal patterns.
*/
CPColorPatternIsHorizontal = NO;
/*!
To create a simple color with a pattern image:
<code>CPColorWithImages(name, width, height{, bundle})</code>
To create a color with a three part pattern image:
<code>CPColorWithImages(slices{, orientation})</code>
where slices is an array of three [name, width, height{, bundle}] arrays,
and orientation is \c CPColorPatternIsVertical or \ref CPColorPatternIsHorizontal.
If orientatation is not passed, it defaults to \ref CPColorPatternIsHorizontal.
To create a color with a nine part pattern image:
<code>CPColorWithImages(slices);</code>
where slices is an array of nine [name, width, height{, bundle}] arrays.
*/
function CPColorWithImages()
{
if (arguments.length < 3)
{
var slices = arguments[0],
imageSlices = [];
for (var i = 0; i < slices.length; ++i)
{
var slice = slices[i];
imageSlices.push(slice ? CPImageInBundle(slice[0], CGSizeMake(slice[1], slice[2]), slice[3]) : nil);
}
if (imageSlices.length === 3)
return [CPColor colorWithPatternImage:[[CPThreePartImage alloc] initWithImageSlices:imageSlices isVertical:arguments[1] || CPColorPatternIsHorizontal]];
else
return [CPColor colorWithPatternImage:[[CPNinePartImage alloc] initWithImageSlices:imageSlices]];
}
else if (arguments.length === 3 || arguments.length === 4)
{
return [CPColor colorWithPatternImage:CPImageInBundle(arguments[0], CGSizeMake(arguments[1], arguments[2]), arguments[3])];
}
else
{
return nil;
}
}
/*!
@ingroup appkit
@@ -739,7 +693,7 @@ url("data:image/png;base64,BASE64ENCODEDDATA") // if there is a pattern image
for (var i = 0; i < slices.length; ++i)
{
var imgDescription = [slices[i] description];
var imgDescription = [slices[i] description] || "nil";
description += imgDescription.replace(/^/mg, " ") + ",\n";
}
@@ -747,7 +701,7 @@ url("data:image/png;base64,BASE64ENCODEDDATA") // if there is a pattern image
description = description.substr(0, description.length - 2) + "\n ]\n}";
}
else
description += [patternImage description].replace(/^/mg, " ") + "\n}";
description += ([patternImage description] || "nil").replace(/^/mg, " ") + "\n}";
return description;
}
@@ -872,4 +826,551 @@ var byteToHex = function(n)
hexCharacters.charAt(n % 16);
};
/*!
To create a simple color with a pattern image:
CPColorWithImages(name, width, height{, bundle})
To create a color with a three-part/nine-part image using a pattern string:
CPColorWithImages(pattern, attributes{, bundle})
<pattern> must have one or more placeholders. There are there possible
placeholders available that together can be used to build a filename:
style A top-level style, for example normal (empty) and "default".
state The state of a view, for example "highlighted" and "disabled".
position The position of an image within a 3-part or 9-part image.
This must be provided.
Each placeholder is filled with the values you pass in a the attributes object.
Neither style nor state are necessary, if you omit them the next level of the
hierarchy is the top level.
Attributes
----------
styles: [...]
An array of style names. For example, if you want to generate the filenames
"button-bezel" and "default-button-bezel", you would use ["", "default"]
for the styles.
states: [...]
An array of state names.
positions: <spec>
Specifies the naming convention for the slices of the image. For 3-part images,
<spec> may be one of:
"@" Equivalent to ["left", "center", "right"] for horizontal
images, ["top", "center", "bottom"] for vertical images
"#" Equivalent to ["0", "1", "2"]
[...] An array of any three literal strings
For 9-part images, <spec> may be one of:
"@" | "abbrev" Equivalent to ["top-left", "top", "top-right",
"left", "center", "right",
"bottom-left", "bottom", "bottom-right"]
"full" Equivalent to ["top-left", "top-center", "top-right",
"center-left", "center-center", "center-right",
"bottom-left", "bottom-center", "bottom-right"]
"#" Equivalent to ["0", "1", "2", "3", "4", "5", "6", "7", "8"]
[...] An array of any nine literal strings
width: <number>
The width of the left image for horizontal 3-part images, the top image for
vertical 3-part images, or the top left corner for 9-part images.
height: <number>
The height of the left image for horizontal 3-part images, the top image for
vertical 3-part images, or the top left corner for 9-part images.
centerWidth: <number>
For a horizontal 3-part image that has a center slice width that is not 1.0,
set this for the width of the center slice. If omitted, it defaults
to 1.0. Not used for 9-part images.
rightWidth: <number>
For a horizontal 3-part image that has different left/right slice widths,
or a 9-part image that has different left/right corner slice widths,
set this for the width of the right slice. If omitted, the "width"
value is used for left and right widths.
centerHeight: <number>
For a vertical 3-part image that has a center slice height that is not 1.0,
set this for the height of the center slice. If omitted, it defaults
to 1.0. Not used for 9-part images.
bottomHeight: <number>
For a vertical image that has different top/bottom slice heights,
or a 9-part image that has different top/bottom corner slice heights,
set this for the height of the bottom slice. If omitted, the "height"
value is used for top and bottom heights.
centerIsNil: <BOOL>
For 9-part images, if the center image is nil, set this to YES.
If omitted or set to NO, a center image must be provided.
separator: <string>
The separator to use between components of the pattern.
If it is omitted, it defaults to "-".
orientation: PatternIsHorizontal | PatternIsVertical
The orientation of the image. This must be specified for 3-part images,
it should NOT be specified for 9-part images.
Using a pattern, all of this:
bezelColor = PatternColor(
[
["button-bezel-left.png", 4.0, 24.0],
["button-bezel-center.png", 1.0, 24.0],
["button-bezel-right.png", 4.0, 24.0]
],
PatternIsHorizontal),
highlightedBezelColor = PatternColor(
[
["button-bezel-highlighted-left.png", 4.0, 24.0],
["button-bezel-highlighted-center.png", 1.0, 24.0],
["button-bezel-highlighted-right.png", 4.0, 24.0]
],
PatternIsHorizontal),
disabledBezelColor = PatternColor(
[
["button-bezel-disabled-left.png", 4.0, 24.0],
["button-bezel-disabled-center.png", 1.0, 24.0],
["button-bezel-disabled-right.png", 4.0, 24.0]
],
PatternIsHorizontal),
defaultBezelColor = PatternColor(
[
["default-button-bezel-left.png", 4.0, 24.0],
["default-button-bezel-center.png", 1.0, 24.0],
["default-button-bezel-right.png", 4.0, 24.0]
],
PatternIsHorizontal),
defaultHighlightedBezelColor = PatternColor(
[
["default-button-bezel-highlighted-left.png", 4.0, 24.0],
["default-button-bezel-highlighted-center.png", 1.0, 24.0],
["default-button-bezel-highlighted-right.png", 4.0, 24.0]
],
PatternIsHorizontal),
defaultDisabledBezelColor = PatternColor(
[
["default-button-bezel-disabled-left.png", 4.0, 24.0],
["default-button-bezel-disabled-center.png", 1.0, 24.0],
["default-button-bezel-disabled-right.png", 4.0, 24.0]
],
PatternIsHorizontal)
can be replaced with this:
bezelColors = PatternColor(
"{style}button-bezel{state}{position}.png",
{
styles: ["", "default"],
states: ["", "highlighted", "disabled"],
positions: "@",
width: 4.0,
height: 24.0,
orientation: PatternIsHorizontal
})
Which would effectively create the following object:
{
"@":
{
"@": <ThreePartImage>:
[
["button-bezel-left.png", 4.0, 24.0],
["button-bezel-center.png", 1.0, 24.0],
["button-bezel-right.png", 4.0, 24.0]
],
"highlighted": <ThreePartImage>:
[
["button-bezel-highlighted-left.png", 4.0, 24.0],
["button-bezel-highlighted-center.png", 1.0, 24.0],
["button-bezel-highlighted-right.png", 4.0, 24.0]
],
"disabled": <ThreePartImage>:
[
["button-bezel-disabled-left.png", 4.0, 24.0],
["button-bezel-disabled-center.png", 1.0, 24.0],
["button-bezel-disabled-right.png", 4.0, 24.0]
]
},
"default":
{
"@": <ThreePartImage>:
[
["default-button-bezel-left.png", 4.0, 24.0],
["default-button-bezel-center.png", 1.0, 24.0],
["default-button-bezel-right.png", 4.0, 24.0]
],
"highlighted": <ThreePartImage>:
[
["default-button-bezel-highlighted-left.png", 4.0, 24.0],
["default-button-bezel-highlighted-center.png", 1.0, 24.0],
["default-button-bezel-highlighted-right.png", 4.0, 24.0]
],
"disabled": <ThreePartImage>:
[
["default-button-bezel-disabled-left.png", 4.0, 24.0],
["button-bezel-disabled-center.png", 1.0, 24.0],
["default-button-bezel-disabled-right.png", 4.0, 24.0]
]
}
}
To reference empty names in the pattern color, use the key "@".
So, for example, to reference the "default" style, "disabled" state,
you would use the following expression:
bezelColors["@"]["disabled"]
To create a color with a three-part pattern image explicitly:
CPColorWithImages(slices, orientation)
where slices is an array of three [name, width, height{, bundle}] arrays,
and orientation is CPColorPatternIsVertical or CPColorPatternIsHorizontal.
To create a color with a nine-part pattern image explicitly:
CPColorWithImages(slices);
where slices is an array of nine [name, width, height{, bundle}] arrays.
*/
function CPColorWithImages()
{
var slices = nil,
numParts = 0,
isVertical = false,
imageFactory = CPImageInBundle,
args = Array.prototype.slice.apply(arguments);
if (typeof(args[args.length - 1]) === "function")
imageFactory = args.pop();
switch (args.length)
{
case 1:
return imageFromSlices(args[0], isVertical, imageFactory);
case 2:
// New-style 3-part and 9-part images
if (typeof(args[0]) === "string")
return patternColorsFromPattern.call(this, args[0], args[1], imageFactory);
return imageFromSlices(args[0], args[1], imageFactory);
case 3:
case 4:
return [CPColor colorWithPatternImage:imageFactory(args[0], args[1], args[2], args[3])];
default:
throw("ERROR: Invalid argument count: " + args.length);
}
}
var imageFromSlices = function(slices, isVertical, imageFactory)
{
var imageSlices = [];
for (var i = 0; i < slices.length; ++i)
{
var slice = slices[i];
imageSlices.push(slice ? imageFactory(slice[0], slice[1], slice[2], slice[3]) : nil);
}
switch (slices.length)
{
case 3:
return [CPColor colorWithPatternImage:[[CPThreePartImage alloc] initWithImageSlices:imageSlices isVertical:isVertical]];
case 9:
return [CPColor colorWithPatternImage:[[CPNinePartImage alloc] initWithImageSlices:imageSlices]];
default:
throw("ERROR: Invalid number of image slices: " + slices.length);
}
};
var patternColorsFromPattern = function(pattern, attributes, imageFactory)
{
if (pattern.match(/^.*\{[^}]+\}/))
{
var width = attributes["width"],
height = attributes["height"],
separator = attributes["separator"] || "-",
orientation = attributes["orientation"],
rightWidth,
bottomHeight,
centerWidthHeight,
centerIsNil,
numParts;
// positions are mandatory
if (pattern.indexOf("{position}") < 0)
throw("ERROR: Pattern strings must have a {position} placeholder (\"" + pattern + "\")");
if (orientation === undefined)
{
numParts = 9;
if (attributes["centerIsNil"] !== undefined)
centerIsNil = attributes["centerIsNil"];
}
else
{
numParts = 3;
isVertical = orientation === PatternIsVertical;
if (isVertical)
{
if (attributes["centerHeight"])
centerWidthHeight = attributes["centerHeight"];
}
else
{
if (attributes["centerWidth"])
centerWidthHeight = attributes["centerWidth"];
}
}
if (attributes["rightWidth"])
rightWidth = attributes["rightWidth"];
if (attributes["bottomHeight"])
bottomHeight = attributes["bottomHeight"];
var positions = attributes["positions"] || "@",
states = nil,
styles = nil;
if (numParts === 3)
{
if (positions === "@")
{
if (isVertical)
positions = ["top", "center", "bottom"];
else
positions = ["left", "center", "right"];
}
else if (positions === "#")
positions = ["0", "1", "2"];
else
throw("ERROR: Invalid positions: " + positions)
}
else // numParts === 9
{
if (positions === "@" || positions === "abbrev")
positions = ["top-left", "top", "top-right", "left", "center", "right", "bottom-left", "bottom", "bottom-right"];
else if (positions === "full")
positions = ["top-left", "top-center", "top-right", "center-left", "center-center", "center-right", "bottom-left", "bottom-center", "bottom-right"];
else if (positions === "#")
positions = ["0", "1", "2", "3", "4", "5", "6", "7", "8"];
else
throw("ERROR: Invalid positions: " + positions)
}
// states
if (pattern.indexOf("{state}") >= 0)
{
states = attributes["states"];
if (!states)
throw("ERROR: {state} placeholder in the pattern (\"" + pattern + "\") but no states item in the attributes");
}
// styles
if (pattern.indexOf("{style}") >= 0)
{
styles = attributes["styles"];
if (!styles)
throw("ERROR: {style} placeholder in the pattern (\"" + pattern + "\") but no styles item in the attributes");
}
// Now assemble the hierarchy
var placeholder = "{position}",
pos = pattern.indexOf(placeholder),
i;
for (i = 0; i < positions.length; ++i)
positions[i] = pattern.replace(placeholder, pos === 0 ? positions[i] + separator : separator + positions[i]);
var slices = positions,
object = slices,
key,
sep;
if (states)
{
placeholder = "{state}";
pos = pattern.indexOf(placeholder);
object = {};
for (i = 0; i < states.length; ++i)
{
var state = states[i];
key = state || "@";
sep = state ? separator : "";
object[key] = slices.slice(0);
replacePlaceholderInArray(object[key], placeholder, pos === 0 ? state + sep : sep + state);
}
}
if (styles)
{
placeholder = "{style}";
pos = pattern.indexOf(placeholder);
var styleObject = {};
for (i = 0; i < styles.length; ++i)
{
var style = styles[i];
key = style || "@";
sep = style ? separator : "";
if (states)
{
styleObject[key] = cloneObject(object);
replacePlaceholderInObject(styleObject[key], placeholder, pos === 0 ? style + sep : sep + style);
}
else
{
styleObject[key] = slices.slice(0);
replacePlaceholderInArray(styleObject[key], placeholder, pos === 0 ? style + sep : sep + style);
}
}
object = styleObject;
}
if (styles || states)
{
if (numParts === 3)
makeThreePartSlicesFromObject(object, width, height, centerWidthHeight, rightWidth, bottomHeight, isVertical);
else
makeNinePartSlicesFromObject(object, width, height, rightWidth, bottomHeight, centerIsNil);
makeImagesFromObject(object, isVertical, imageFactory);
return object;
}
else
{
if (numParts === 3)
makeThreePartSlicesFromArray(object, width, height, centerWidthHeight, rightWidth, bottomHeight, isVertical);
else
makeNinePartSlicesFromArray(object, width, height, rightWidth, bottomHeight, centerIsNil);
return imageFromSlices(object, isVertical, imageFactory);
}
}
else
throw("ERROR: No placeholders in slice pattern (\"" + pattern + "\")");
};
var replacePlaceholderInArray = function(array, find, replacement)
{
for (var i = 0; i < array.length; ++i)
array[i] = array[i].replace(find, replacement);
};
var replacePlaceholderInObject = function(object, find, replacement)
{
for (var key in object)
if (object.hasOwnProperty(key))
if (object[key].constructor === Array)
replacePlaceholderInArray(object[key], find, replacement);
else
replacePlaceholderInObject(object[key], find, replacement);
};
var cloneObject = function(object)
{
var clone = {};
for (var key in object)
if (object.hasOwnProperty(key))
if (object[key].constructor === Array)
clone[key] = object[key].slice(0);
else if (typeof(object[key]) === "object")
clone[key] = cloneObject(object[key]);
else
clone[key] = object[key];
return clone;
};
var makeThreePartSlicesFromObject = function(object, width, height, centerWidthHeight, rightWidth, bottomHeight, isVertical)
{
for (var key in object)
if (object.hasOwnProperty(key))
if (object[key].constructor === Array)
makeThreePartSlicesFromArray(object[key], width, height, centerWidthHeight, rightWidth, bottomHeight, isVertical);
else // object
makeThreePartSlicesFromObject(object[key], width, height, centerWidthHeight, rightWidth, bottomHeight, isVertical);
};
var makeThreePartSlicesFromArray = function(array, width, height, centerWidthHeight, rightWidth, bottomHeight, isVertical)
{
array[0] = [array[0], width, height];
if (isVertical)
{
array[1] = [array[1], width, centerWidthHeight ? centerWidthHeight : 1.0];
array[2] = [array[2], width, bottomHeight ? bottomHeight : height];
}
else
{
array[1] = [array[1], centerWidthHeight ? centerWidthHeight : 1.0, height];
array[2] = [array[2], rightWidth ? rightWidth : width, height];
}
};
var makeNinePartSlicesFromObject = function(object, width, height, rightWidth, bottomHeight, centerIsNil)
{
for (var key in object)
if (object.hasOwnProperty(key))
if (object[key].constructor === Array)
makeNinePartSlicesFromArray(object[key], width, height, rightWidth, bottomHeight, centerIsNil);
else // object
makeNinePartSlicesFromObject(object[key], width, height, rightWidth, bottomHeight, centerIsNil);
};
var makeNinePartSlicesFromArray = function(array, width, height, rightWidth, bottomHeight, centerIsNil)
{
rightWidth = rightWidth ? rightWidth : width;
bottomHeight = bottomHeight ? bottomHeight : height;
array[0] = [array[0], width, height]; // top-left
array[1] = [array[1], 1.0, height]; // top
array[2] = [array[2], rightWidth, height]; // top-right
array[3] = [array[3], width, 1.0]; // left
array[4] = centerIsNil ? nil : [array[4], 1.0, 1.0]; // center
array[5] = [array[5], rightWidth, 1.0]; // right
array[6] = [array[6], width, bottomHeight]; // bottom-left
array[7] = [array[7], 1.0, bottomHeight]; // bottom
array[8] = [array[8], rightWidth, bottomHeight]; // bottom-right
};
var makeImagesFromObject = function(object, isVertical, imageFactory)
{
for (var key in object)
if (object.hasOwnProperty(key))
if (object[key].constructor === Array)
object[key] = imageFromSlices(object[key], isVertical, imageFactory);
else // object
makeImagesFromObject(object[key], isVertical, imageFactory);
};
/// @endcond
+30 -26
View File
@@ -20,12 +20,32 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@import "CPApplication.j"
@import "CPButton.j"
@import "CPCookie.j"
@import "CPPanel.j"
@import "CPPasteboard.j"
@import "CPView.j"
@class CPSlider
@global CPApp
/*
A color wheel
@global
@group CPColorPanelMode
*/
CPWheelColorPickerMode = 1;
/*
Slider based picker
@global
@group CPColorPanelMode
*/
CPSliderColorPickerMode = 2;
CPColorPickerViewWidth = 265;
CPColorPickerViewHeight = 370;
CPColorPanelColorDidChangeNotification = @"CPColorPanelColorDidChangeNotification";
@@ -38,22 +58,6 @@ var PREVIEW_HEIGHT = 20.0,
var SharedColorPanel = nil,
ColorPickerClasses = [];
/*
A color wheel
@global
@group CPColorPanelMode
*/
CPWheelColorPickerMode = 1;
/*
Slider based picker
@global
@group CPColorPanelMode
*/
CPSliderColorPickerMode = 2;
CPColorPickerViewWidth = 265;
CPColorPickerViewHeight = 370;
/*!
@ingroup appkit
@class CPColorPanel
@@ -123,7 +127,7 @@ CPColorPickerViewHeight = 370;
if (self)
{
[[self contentView] setBackgroundColor:[CPColor colorWithWhite:0.95 alpha:1.0]];
//[[self contentView] setBackgroundColor:[CPColor colorWithWhite:0.95 alpha:1.0]];
[self setTitle:@"Color Panel"];
[self setLevel:CPFloatingWindowLevel];
@@ -248,8 +252,8 @@ CPColorPickerViewHeight = 370;
var height = (TOOLBAR_HEIGHT + 10 + PREVIEW_HEIGHT + 5 + SWATCH_HEIGHT + 32),
bounds = [[self contentView] bounds];
[view setFrameSize:CPSizeMake(bounds.size.width - 10, bounds.size.height - height)];
[view setFrameOrigin:CPPointMake(5, height)];
[view setFrameSize:CGSizeMake(bounds.size.width - 10, bounds.size.height - height)];
[view setFrameOrigin:CGPointMake(5, height)];
}
[_currentView removeFromSuperview];
@@ -419,7 +423,7 @@ var CPColorPanelSwatchesCookie = "CPColorPanelSwatchesCookie";
CPCookie _swatchCookie;
}
- (id)initWithFrame:(CPRect)aFrame
- (id)initWithFrame:(CGRect)aFrame
{
self = [super initWithFrame:aFrame];
@@ -437,7 +441,7 @@ var CPColorPanelSwatchesCookie = "CPColorPanelSwatchesCookie";
for (var i = 0; i < 50; i++)
{
// FIXME: http://280north.lighthouseapp.com/projects/13294-cappuccino/tickets/25-implement-cpbox
var view = [[CPView alloc] initWithFrame:CPRectMake(13 * i + 1, 1, 12, 12)],
var view = [[CPView alloc] initWithFrame:CGRectMake(13 * i + 1, 1, 12, 12)],
fillView = [[CPView alloc] initWithFrame:CGRectInset([view bounds], 1.0, 1.0)];
[view setBackgroundColor:whiteColor];
@@ -592,7 +596,7 @@ var CPColorPanelSwatchesCookie = "CPColorPanelSwatchesCookie";
CPColorPanel _colorPanel;
}
- (id)initWithFrame:(CPRect)aFrame
- (id)initWithFrame:(CGRect)aFrame
{
self = [super initWithFrame:aFrame];
@@ -633,7 +637,7 @@ var CPColorPanelSwatchesCookie = "CPColorPanelSwatchesCookie";
[[CPPasteboard pasteboardWithName:CPDragPboard] declareTypes:[CPColorDragType] owner:self];
var bounds = CPRectMake(0, 0, 15, 15);
var bounds = CGRectMake(0, 0, 15, 15);
// FIXME: http://280north.lighthouseapp.com/projects/13294-cappuccino/tickets/25-implement-cpbox
var dragView = [[CPView alloc] initWithFrame:bounds],
@@ -645,8 +649,8 @@ var CPColorPanelSwatchesCookie = "CPColorPanelSwatchesCookie";
[dragView addSubview:dragFillView];
[self dragView:dragView
at:CPPointMake(point.x - bounds.size.width / 2.0, point.y - bounds.size.height / 2.0)
offset:CPPointMake(0.0, 0.0)
at:CGPointMake(point.x - bounds.size.width / 2.0, point.y - bounds.size.height / 2.0)
offset:CGPointMake(0.0, 0.0)
event:anEvent
pasteboard:nil
source:self
+10 -4
View File
@@ -24,6 +24,12 @@
@import "CPView.j"
@class CPSlider
@global CPColorPickerViewWidth
@global CPColorPickerViewHeight
@global CPWheelColorPickerMode
/*!
@ingroup appkit
@@ -222,7 +228,7 @@
float _radius;
}
- (id)initWithFrame:(CPRect)aFrame
- (id)initWithFrame:(CGRect)aFrame
{
if (self = [super initWithFrame:aFrame])
{
@@ -269,13 +275,13 @@
#endif
}
- (void)setFrameSize:(CPSize)aSize
- (void)setFrameSize:(CGSize)aSize
{
[super setFrameSize:aSize];
[self setWheelSize:aSize];
}
- (void)setWheelSize:(CPSize)aSize
- (void)setWheelSize:(CGSize)aSize
{
var min = MIN(aSize.width, aSize.height);
@@ -353,7 +359,7 @@
_angle = [self radiansToDegrees:angle];
_distance = (distance / _radius) * 100.0;
[_crosshair setFrameOrigin:CPPointMake(COS(angle) * distance + midX - 2.0, SIN(angle) * distance + midY - 2.0)];
[_crosshair setFrameOrigin:CGPointMake(COS(angle) * distance + midX - 2.0, SIN(angle) * distance + midY - 2.0)];
}
- (void)setPositionToColor:(CPColor)aColor
+2
View File
@@ -20,6 +20,8 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@import <Foundation/CPObject.j>
var sRGBColorSpace = nil;
/*!
+21 -27
View File
@@ -45,12 +45,12 @@ var _CPColorWellDidBecomeExclusiveNotification = @"_CPColorWellDidBecomeExclusiv
CPColor _color;
}
+ (Class)_binderClassForBinding:(CPString)theBinding
+ (Class)_binderClassForBinding:(CPString)aBinding
{
if (theBinding == CPValueBinding)
if (aBinding == CPValueBinding)
return [CPColorWellValueBinder class];
return [super _binderClassForBinding:theBinding];
return [super _binderClassForBinding:aBinding];
}
+ (CPString)defaultThemeClass
@@ -60,8 +60,13 @@ var _CPColorWellDidBecomeExclusiveNotification = @"_CPColorWellDidBecomeExclusiv
+ (id)themeAttributes
{
return [CPDictionary dictionaryWithObjects:[_CGInsetMakeZero(), [CPNull null], _CGInsetMake(3.0, 3.0, 3.0, 3.0), _CGInsetMakeZero(), [CPNull null]]
forKeys:[@"bezel-inset", @"bezel-color", @"content-inset", @"content-border-inset", @"content-border-color"]];
return @{
@"bezel-inset": _CGInsetMakeZero(),
@"bezel-color": [CPNull null],
@"content-inset": _CGInsetMake(3.0, 3.0, 3.0, 3.0),
@"content-border-inset": _CGInsetMakeZero(),
@"content-border-color": [CPNull null],
};
}
- (void)_reverseSetBinding
@@ -315,7 +320,7 @@ var _CPColorWellDidBecomeExclusiveNotification = @"_CPColorWellDidBecomeExclusiv
- (void)_updatePlaceholdersWithOptions:(CPDictionary)options
{
var placeholderColor = [CPColor blueColor];
var placeholderColor = [CPColor blackColor];
[self _setPlaceholder:placeholderColor forMarker:CPMultipleValuesMarker isDefault:YES];
[self _setPlaceholder:placeholderColor forMarker:CPNoSelectionMarker isDefault:YES];
@@ -323,30 +328,19 @@ var _CPColorWellDidBecomeExclusiveNotification = @"_CPColorWellDidBecomeExclusiv
[self _setPlaceholder:placeholderColor forMarker:CPNullMarker isDefault:YES];
}
- (void)setValueFor:(CPString)theBinding
- (id)valueForBinding:(CPString)aBinding
{
var destination = [_info objectForKey:CPObservedObjectKey],
keyPath = [_info objectForKey:CPObservedKeyPathKey],
options = [_info objectForKey:CPOptionsKey],
newValue = [destination valueForKeyPath:keyPath],
isPlaceholder = CPIsControllerMarker(newValue);
return [_source color];
}
if (isPlaceholder)
{
if (newValue === CPNotApplicableMarker && [options objectForKey:CPRaisesForNotApplicableKeysBindingOption])
{
[CPException raise:CPGenericException
reason:@"can't transform non applicable key on: " + _source + " value: " + newValue];
}
- (void)setValue:(id)aValue forBinding:(CPString)theBinding
{
[_source setColor:aValue];
}
newValue = [self _placeholderForMarker:newValue];
}
else
{
newValue = [self transformValue:newValue withOptions:options];
}
[_source setColor:newValue];
- (void)setPlaceholderValue:(id)aValue withMarker:(CPString)aMarker forBinding:(CPString)aBinding
{
[_source setColor:aValue];
}
@end
+17 -11
View File
@@ -20,6 +20,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@import "CPText.j"
@import "CPTextField.j"
@import "_CPPopUpList.j"
@@ -59,15 +60,18 @@ var CPComboBoxTextSubview = @"text",
+ (id)themeAttributes
{
return [CPDictionary dictionaryWithObjectsAndKeys:_CGSizeMake(21.0, 29.0), @"popup-button-size", _CGInsetMake(3.0, 3.0, 3.0, 3.0), @"border-inset"];
return @{
@"popup-button-size": _CGSizeMake(21.0, 29.0),
@"border-inset": _CGInsetMake(3.0, 3.0, 3.0, 3.0),
};
}
+ (Class)_binderClassForBinding:(CPString)theBinding
+ (Class)_binderClassForBinding:(CPString)aBinding
{
if (theBinding === CPContentBinding || theBinding === CPContentValuesBinding)
if (aBinding === CPContentBinding || aBinding === CPContentValuesBinding)
return [_CPComboBoxContentBinder class];
return [super _binderClassForBinding:theBinding];
return [super _binderClassForBinding:aBinding];
}
- (id)initWithFrame:(CGRect)aFrame
@@ -83,7 +87,7 @@ var CPComboBoxTextSubview = @"text",
- (void)_initComboBox
{
_items = [CPArray array];
_listClass = [_CPPopUpList class];
// _listClass = [_CPPopUpList class];
_usesDataSource = NO;
_completes = NO;
_canComplete = NO;
@@ -1110,7 +1114,7 @@ var CPComboBoxCompletionTest = function(object, index, context)
*/
@implementation _CPComboBoxContentBinder : CPBinder
- (void)setValueFor:(CPString)theBinding
- (void)setValueFor:(CPString)aBinding
{
var destination = [_info objectForKey:CPObservedObjectKey],
keyPath = [_info objectForKey:CPObservedKeyPathKey],
@@ -1152,13 +1156,15 @@ var CPComboBoxCompletionTest = function(object, index, context)
else
newValue = [self transformValue:newValue withOptions:options];
switch (theBinding)
switch (aBinding)
{
case CPContentBinding: [_source setContent:newValue];
break;
case CPContentBinding:
[_source setContent:newValue];
break;
case CPContentValuesBinding: [_source setContentValues:newValue];
break;
case CPContentValuesBinding:
[_source setContentValues:newValue];
break;
}
}
+184 -65
View File
@@ -20,7 +20,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@import "CPEvent.j"
@import "CPEvent_Constants.j"
@import "CPPlatform.j"
@@ -38,57 +38,58 @@ CPWindowsOperatingSystem = 1;
CPOtherOperatingSystem = 2;
// Features
CPCSSRGBAFeature = 1 << 5;
CPCSSRGBAFeature = 5;
CPHTMLCanvasFeature = 1 << 6;
CPHTMLContentEditableFeature = 1 << 7;
CPHTMLDragAndDropFeature = 1 << 8;
CPHTMLCanvasFeature = 6;
CPHTMLContentEditableFeature = 7;
CPHTMLDragAndDropFeature = 8;
CPJavaScriptInnerTextFeature = 1 << 9;
CPJavaScriptTextContentFeature = 1 << 10;
CPJavaScriptClipboardEventsFeature = 1 << 11;
CPJavaScriptClipboardAccessFeature = 1 << 12;
CPJavaScriptCanvasDrawFeature = 1 << 13;
CPJavaScriptCanvasTransformFeature = 1 << 14;
CPJavaScriptInnerTextFeature = 9;
CPJavaScriptTextContentFeature = 10;
CPJavaScriptClipboardEventsFeature = 11;
CPJavaScriptClipboardAccessFeature = 12;
CPJavaScriptCanvasDrawFeature = 13;
CPJavaScriptCanvasTransformFeature = 14;
CPVMLFeature = 1 << 15;
CPVMLFeature = 15;
CPJavaScriptRemedialKeySupport = 1 << 16;
CPJavaScriptShadowFeature = 1 << 20;
CPJavaScriptRemedialKeySupport = 16;
CPJavaScriptShadowFeature = 20;
CPJavaScriptNegativeMouseWheelValues = 1 << 22;
CPJavaScriptMouseWheelValues_8_15 = 1 << 23;
CPJavaScriptNegativeMouseWheelValues = 22;
CPJavaScriptMouseWheelValues_8_15 = 23;
CPOpacityRequiresFilterFeature = 1 << 24;
CPOpacityRequiresFilterFeature = 24;
//Internet explorer does not allow dynamically changing the type of an input element
CPInputTypeCanBeChangedFeature = 1 << 25;
CPHTML5DragAndDropSourceYOffBy1 = 1 << 26;
// Internet explorer does not allow dynamically changing the type of an input element
CPInputTypeCanBeChangedFeature = 25;
CPHTML5DragAndDropSourceYOffBy1 = 26;
CPSOPDisabledFromFileURLs = 1 << 27;
CPSOPDisabledFromFileURLs = 27;
// element.style.font can be set for an element not in the DOM.
CPInputSetFontOutsideOfDOM = 1 << 28;
CPInputSetFontOutsideOfDOM = 28;
// Input elements have 1 px of extra padding on the left regardless of padding setting.
CPInput1PxLeftPadding = 1 << 29;
CPInputOnInputEventFeature = 1 << 30;
CPInput1PxLeftPadding = 29;
CPInputOnInputEventFeature = 30;
// When an absolutely positioned div (CPView) with an absolutely positioned canvas in it (CPView with drawRect:) moves things on top of the canvas
// (subviews) don't redraw correctly. E.g. if you have a bunch of text fields in a CPBox in a sheet which animates in, some of the text fields might
// not be visible because the CPBox has a canvas at the bottom and the box moved form offscreen to onscreen.
// This bug is probably very related: https://bugs.webkit.org/show_bug.cgi?id=67203
CPFileAPIFeature = 31;
/*
When an absolutely positioned div (CPView) with an absolutely positioned canvas in it (CPView with drawRect:) moves things on top of the canvas (subviews) don't redraw correctly. E.g. if you have a bunch of text fields in a CPBox in a sheet which animates in, some of the text fields might not be visible because the CPBox has a canvas at the bottom and the box moved form offscreen to onscreen. This bug is probably very related: https://bugs.webkit.org/show_bug.cgi?id=67203
*/
CPCanvasParentDrawErrorsOnMovementBug = 1 << 0;
var USER_AGENT = "",
PLATFORM_ENGINE = CPUnknownBrowserEngine,
PLATFORM_FEATURES = 0,
PLATFORM_BUGS = 0;
PLATFORM_FEATURES = [],
PLATFORM_BUGS = 0,
PLATFORM_STYLE_JS_PROPERTIES = {};
// default these features to true
PLATFORM_FEATURES |= CPInputTypeCanBeChangedFeature;
PLATFORM_FEATURES |= CPInputSetFontOutsideOfDOM;
PLATFORM_FEATURES[CPInputTypeCanBeChangedFeature] = YES;
PLATFORM_FEATURES[CPInputSetFontOutsideOfDOM] = YES;
if (typeof window !== "undefined" && typeof window.navigator !== "undefined")
USER_AGENT = window.navigator.userAgent;
@@ -98,7 +99,7 @@ if (typeof window !== "undefined" && window.opera)
{
PLATFORM_ENGINE = CPOperaBrowserEngine;
PLATFORM_FEATURES |= CPJavaScriptCanvasDrawFeature;
PLATFORM_FEATURES[CPJavaScriptCanvasDrawFeature] = YES;
}
// Internet Explorer
@@ -107,16 +108,16 @@ else if (typeof window !== "undefined" && window.attachEvent) // Must follow Ope
PLATFORM_ENGINE = CPInternetExplorerBrowserEngine;
// Features we can only be sure of with IE (no known independent tests)
PLATFORM_FEATURES |= CPVMLFeature;
PLATFORM_FEATURES |= CPJavaScriptRemedialKeySupport;
PLATFORM_FEATURES |= CPJavaScriptShadowFeature;
PLATFORM_FEATURES[CPVMLFeature] = YES;
PLATFORM_FEATURES[CPJavaScriptRemedialKeySupport] = YES;
PLATFORM_FEATURES[CPJavaScriptShadowFeature] = YES;
PLATFORM_FEATURES |= CPOpacityRequiresFilterFeature;
PLATFORM_FEATURES[CPOpacityRequiresFilterFeature] = YES;
PLATFORM_FEATURES &= ~CPInputTypeCanBeChangedFeature;
PLATFORM_FEATURES[CPInputTypeCanBeChangedFeature] = NO;
// Tested in Internet Explore 8 and 9.
PLATFORM_FEATURES &= ~CPInputSetFontOutsideOfDOM;
PLATFORM_FEATURES[CPInputSetFontOutsideOfDOM] = NO;
}
// WebKit
@@ -125,15 +126,15 @@ else if (USER_AGENT.indexOf("AppleWebKit/") != -1)
PLATFORM_ENGINE = CPWebKitBrowserEngine;
// Features we can only be sure of with WebKit (no known independent tests)
PLATFORM_FEATURES |= CPCSSRGBAFeature;
PLATFORM_FEATURES |= CPHTMLContentEditableFeature;
PLATFORM_FEATURES[CPCSSRGBAFeature] = YES;
PLATFORM_FEATURES[CPHTMLContentEditableFeature] = YES;
if (USER_AGENT.indexOf("Chrome") === -1)
PLATFORM_FEATURES |= CPHTMLDragAndDropFeature;
PLATFORM_FEATURES[CPHTMLDragAndDropFeature] = YES;
PLATFORM_FEATURES |= CPJavaScriptClipboardEventsFeature;
PLATFORM_FEATURES |= CPJavaScriptClipboardAccessFeature;
PLATFORM_FEATURES |= CPJavaScriptShadowFeature;
PLATFORM_FEATURES[CPJavaScriptClipboardEventsFeature] = YES;
PLATFORM_FEATURES[CPJavaScriptClipboardAccessFeature] = YES;
PLATFORM_FEATURES[CPJavaScriptShadowFeature] = YES;
var versionStart = USER_AGENT.indexOf("AppleWebKit/") + "AppleWebKit/".length,
versionEnd = USER_AGENT.indexOf(" ", versionStart),
@@ -143,22 +144,22 @@ else if (USER_AGENT.indexOf("AppleWebKit/") != -1)
minorVersion = parseInt(versionString.substr(versionDivision + 1));
if ((USER_AGENT.indexOf("Safari") !== CPNotFound && (majorVersion > 525 || (majorVersion === 525 && minorVersion > 14))) || USER_AGENT.indexOf("Chrome") !== CPNotFound)
PLATFORM_FEATURES |= CPJavaScriptRemedialKeySupport;
PLATFORM_FEATURES[CPJavaScriptRemedialKeySupport] = YES;
// FIXME this is a terrible hack to get around this bug:
// https://bugs.webkit.org/show_bug.cgi?id=21548
if (![CPPlatform isBrowser])
PLATFORM_FEATURES |= CPJavaScriptRemedialKeySupport;
PLATFORM_FEATURES[CPJavaScriptRemedialKeySupport] = YES;
if (majorVersion < 532 || (majorVersion === 532 && minorVersion < 6))
PLATFORM_FEATURES |= CPHTML5DragAndDropSourceYOffBy1;
PLATFORM_FEATURES[CPHTML5DragAndDropSourceYOffBy1] = YES;
// This is supposedly fixed in webkit r123603. Seems to work in Chrome 21 but not Safari 6.0.
if (majorVersion < 537)
PLATFORM_FEATURES |= CPInput1PxLeftPadding;
PLATFORM_FEATURES[CPInput1PxLeftPadding] = YES;
if (USER_AGENT.indexOf("Chrome") === CPNotFound)
PLATFORM_FEATURES |= CPSOPDisabledFromFileURLs;
PLATFORM_FEATURES[CPSOPDisabledFromFileURLs] = YES;
// Assume this bug was introduced around Safari 5.1/Chrome 16. This could probably be tighter.
if (majorVersion > 533)
@@ -176,59 +177,74 @@ else if (USER_AGENT.indexOf("Gecko") !== -1) // Must follow KHTML check.
{
PLATFORM_ENGINE = CPGeckoBrowserEngine;
PLATFORM_FEATURES |= CPJavaScriptCanvasDrawFeature;
PLATFORM_FEATURES[CPJavaScriptCanvasDrawFeature] = YES;
var index = USER_AGENT.indexOf("Firefox"),
version = (index === -1) ? 2.0 : parseFloat(USER_AGENT.substring(index + "Firefox".length + 1));
if (version >= 3.0)
PLATFORM_FEATURES |= CPCSSRGBAFeature;
PLATFORM_FEATURES[CPCSSRGBAFeature] = YES;
if (version < 3.0)
PLATFORM_FEATURES |= CPJavaScriptMouseWheelValues_8_15;
PLATFORM_FEATURES[CPJavaScriptMouseWheelValues_8_15] = YES;
// Some day this might be fixed and should be version prefixed. No known fixed version yet.
PLATFORM_FEATURES |= CPInput1PxLeftPadding;
PLATFORM_FEATURES[CPInput1PxLeftPadding] = YES;
}
// Feature Specific Checks
// Feature-specific checks
if (typeof document != "undefined")
{
var canvasElement = document.createElement("canvas");
// Detect Canvas Support
// Detect canvas support
if (canvasElement && canvasElement.getContext)
{
PLATFORM_FEATURES |= CPHTMLCanvasFeature;
PLATFORM_FEATURES[CPHTMLCanvasFeature] = YES;
// Detect Canvas setTransform/transform support
// Any browser that supports canvas supports CSS opacity
PLATFORM_FEATURES[CPOpacityRequiresFilterFeature] = NO;
// Detect canvas setTransform/transform support
var context = document.createElement("canvas").getContext("2d");
if (context && context.setTransform && context.transform)
PLATFORM_FEATURES |= CPJavaScriptCanvasTransformFeature;
PLATFORM_FEATURES[CPJavaScriptCanvasTransformFeature] = YES;
}
var DOMElement = document.createElement("div");
// Detect whether we have innerText or textContent (or neither)
if (DOMElement.innerText != undefined)
PLATFORM_FEATURES |= CPJavaScriptInnerTextFeature;
PLATFORM_FEATURES[CPJavaScriptInnerTextFeature] = YES;
else if (DOMElement.textContent != undefined)
PLATFORM_FEATURES |= CPJavaScriptTextContentFeature;
PLATFORM_FEATURES[CPJavaScriptTextContentFeature] = YES;
var DOMInputElement = document.createElement("input");
if ("oninput" in DOMInputElement)
PLATFORM_FEATURES |= CPInputOnInputEventFeature;
PLATFORM_FEATURES[CPInputOnInputEventFeature] = YES;
else if (typeof DOMInputElement.setAttribute === "function")
{
DOMInputElement.setAttribute("oninput", "return;");
if (typeof DOMInputElement.oninput === "function")
PLATFORM_FEATURES |= CPInputOnInputEventFeature;
PLATFORM_FEATURES[CPInputOnInputEventFeature] = YES;
}
// Detect FileAPI support
if (typeof DOMInputElement.setAttribute === "function")
{
DOMInputElement.setAttribute("type", "file");
PLATFORM_FEATURES[CPFileAPIFeature] = !!DOMInputElement["files"];
}
else
PLATFORM_FEATURES[CPFileAPIFeature] = NO;
}
function CPFeatureIsCompatible(aFeature)
{
return PLATFORM_FEATURES & aFeature;
return !!PLATFORM_FEATURES[aFeature];
}
function CPPlatformHasBug(aBug)
@@ -273,3 +289,106 @@ else
CPUndoKeyEquivalentModifierMask = CPControlKeyMask;
CPRedoKeyEquivalentModifierMask = CPControlKeyMask;
}
/*!
Return the properly prefixed JS property for the given name. E.g. in a webkit browser,
CPBrowserStyleProperty('transition') -> WebkitTransition
While technically not a style property, style related event handler names are also supported.
CPBrowserStyleProperty('transitionend') -> 'webkitTransitionEnd'
CSS is only available in platform(dom), so don't rely too heavily on it.
*/
function CPBrowserStyleProperty(aProperty)
{
var lowerProperty = aProperty.toLowerCase();
if (PLATFORM_STYLE_JS_PROPERTIES[lowerProperty] === undefined)
{
var r = nil;
#if PLATFORM(DOM)
var testElement = document.createElement('div');
switch (lowerProperty)
{
case 'transitionend':
var candidates = {
'WebkitTransition' : 'webkitTransitionEnd',
'MozTransition' : 'transitionend',
'OTransition' : 'oTransitionEnd',
'msTransition' : 'MSTransitionEnd',
'transition' : 'transitionend'
};
r = candidates[PLATFORM_STYLE_JS_PROPERTIES['transition']] || nil;
break;
default:
var prefixes = ["Webkit", "Moz", "O", "ms"],
strippedProperty = aProperty.split('-').join(' '),
capProperty = [strippedProperty capitalizedString].split(' ').join('');
for (var i = 0; i < prefixes.length; i++)
{
// First check if the property is already valid without being formatted, otherwise try the capitalized property
if (prefixes[i] + aProperty in testElement.style)
{
r = prefixes[i] + aProperty;
break;
}
else if (prefixes[i] + capProperty in testElement.style)
{
r = prefixes[i] + capProperty;
break;
}
}
if (!r && lowerProperty in testElement.style)
r = lowerProperty;
break;
}
#endif
PLATFORM_STYLE_JS_PROPERTIES[lowerProperty] = r;
}
return PLATFORM_STYLE_JS_PROPERTIES[lowerProperty];
}
function CPBrowserCSSProperty(aProperty)
{
var browserProperty = CPBrowserStyleProperty(aProperty);
if (!browserProperty)
return nil;
var prefixes = {
'Webkit': '-webkit-',
'Moz': '-moz-',
'O': '-o-',
'ms': '-ms-'
};
for (var prefix in prefixes)
{
if (browserProperty.substring(0, prefix.length) == prefix)
{
var browserPropertyWithoutPrefix = browserProperty.substring(prefix.length),
parts = browserPropertyWithoutPrefix.match(/[A-Z][a-z]+/g);
// If there were any capitalized words in the browserProperty, insert a "-" between each one
if (parts && parts.length > 0)
browserPropertyWithoutPrefix = parts.join("-");
return prefixes[prefix] + browserPropertyWithoutPrefix.toLowerCase();
}
}
var parts = browserProperty.match(/[A-Z][a-z]+/g);
if (parts && parts.length > 0)
browserProperty = parts.join("-");
return browserProperty.toLowerCase();
}
+38 -32
View File
@@ -20,14 +20,16 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#import "../Foundation/Ref.h"
@import <Foundation/CPFormatter.j>
@import <Foundation/CPTimer.j>
@import "../Foundation/CPFormatter.j"
@import "CPFont.j"
@import "CPShadow.j"
@import "CPView.j"
@import "CPKeyValueBinding.j"
@global CPApp
CPLeftTextAlignment = 0;
CPRightTextAlignment = 1;
CPCenterTextAlignment = 2;
@@ -108,28 +110,19 @@ var CPControlBlackColor = [CPColor blackColor];
+ (CPDictionary)themeAttributes
{
return [CPDictionary dictionaryWithObjects:[CPLeftTextAlignment,
CPTopVerticalTextAlignment,
CPLineBreakByClipping,
[CPColor blackColor],
[CPFont systemFontOfSize:CPFontCurrentSystemSize],
[CPNull null],
_CGSizeMakeZero(),
CPImageLeft,
CPScaleToFit,
_CGSizeMakeZero(),
_CGSizeMake(-1.0, -1.0)]
forKeys:[@"alignment",
@"vertical-alignment",
@"line-break-mode",
@"text-color",
@"font",
@"text-shadow-color",
@"text-shadow-offset",
@"image-position",
@"image-scaling",
@"min-size",
@"max-size"]];
return @{
@"alignment": CPLeftTextAlignment,
@"vertical-alignment": CPTopVerticalTextAlignment,
@"line-break-mode": CPLineBreakByClipping,
@"text-color": [CPColor blackColor],
@"font": [CPFont systemFontOfSize:CPFontCurrentSystemSize],
@"text-shadow-color": [CPNull null],
@"text-shadow-offset": _CGSizeMakeZero(),
@"image-position": CPImageLeft,
@"image-scaling": CPScaleToFit,
@"min-size": _CGSizeMakeZero(),
@"max-size": _CGSizeMake(-1.0, -1.0),
};
}
+ (void)initialize
@@ -148,12 +141,14 @@ var CPControlBlackColor = [CPColor blackColor];
[self exposeBinding:@"enabled"];
}
+ (Class)_binderClassForBinding:(CPString)theBinding
+ (Class)_binderClassForBinding:(CPString)aBinding
{
if (theBinding === CPValueBinding)
if (aBinding === CPValueBinding)
return [_CPValueBinder class];
else if ([aBinding hasPrefix:CPEnabledBinding])
return [CPMultipleValueAndBinding class];
return [super _binderClassForBinding:theBinding];
return [super _binderClassForBinding:aBinding];
}
/*!
@@ -235,6 +230,9 @@ var CPControlBlackColor = [CPColor blackColor];
{
[self _reverseSetBinding];
var binding = [CPBinder getBinding:CPTargetBinding forObject:self];
[binding invokeAction];
return [CPApp sendAction:anAction to:anObject from:self];
}
@@ -397,6 +395,14 @@ var CPControlBlackColor = [CPColor blackColor];
[self highlight:YES];
}
/*!
Enabled controls accept first mouse by default.
*/
- (BOOL)acceptsFirstMouse:(CPEvent)anEvent
{
return [self isEnabled];
}
- (void)mouseDown:(CPEvent)anEvent
{
if (![self isEnabled])
@@ -545,10 +551,10 @@ var CPControlBlackColor = [CPColor blackColor];
{
value = nil;
if ([_formatter getObjectValue:AT_REF(value) forString:aString errorDescription:nil] === NO)
if ([_formatter getObjectValue:@ref(value) forString:aString errorDescription:nil] === NO)
{
// If the given string is non-empty and doesn't work, Cocoa tries an empty string.
if (!aString || [_formatter getObjectValue:AT_REF(value) forString:@"" errorDescription:nil] === NO)
if (!aString || [_formatter getObjectValue:@ref(value) forString:@"" errorDescription:nil] === NO)
value = undefined; // Means the value is invalid
}
}
@@ -601,7 +607,7 @@ var CPControlBlackColor = [CPColor blackColor];
if ([note object] != self)
return;
[[CPNotificationCenter defaultCenter] postNotificationName:CPControlTextDidBeginEditingNotification object:self userInfo:[CPDictionary dictionaryWithObject:[note object] forKey:"CPFieldEditor"]];
[[CPNotificationCenter defaultCenter] postNotificationName:CPControlTextDidBeginEditingNotification object:self userInfo:@{ "CPFieldEditor": [note object] }];
}
- (void)textDidChange:(CPNotification)note
@@ -610,7 +616,7 @@ var CPControlBlackColor = [CPColor blackColor];
if ([note object] != self)
return;
[[CPNotificationCenter defaultCenter] postNotificationName:CPControlTextDidChangeNotification object:self userInfo:[CPDictionary dictionaryWithObject:[note object] forKey:"CPFieldEditor"]];
[[CPNotificationCenter defaultCenter] postNotificationName:CPControlTextDidChangeNotification object:self userInfo:@{ "CPFieldEditor": [note object] }];
}
- (void)textDidEndEditing:(CPNotification)note
@@ -621,7 +627,7 @@ var CPControlBlackColor = [CPColor blackColor];
[self _reverseSetBinding];
[[CPNotificationCenter defaultCenter] postNotificationName:CPControlTextDidEndEditingNotification object:self userInfo:[CPDictionary dictionaryWithObject:[note object] forKey:"CPFieldEditor"]];
[[CPNotificationCenter defaultCenter] postNotificationName:CPControlTextDidEndEditingNotification object:self userInfo:@{ "CPFieldEditor": [note object] }];
}
/*!
+1 -1
View File
@@ -64,7 +64,7 @@ var CPControllerDeclaredKeysKey = @"CPControllerDeclaredKeysKey";
count = _editors.length;
for (; index < count; ++index)
if (![[_editors objectAtIndex:i] commitEditing])
if (![[_editors objectAtIndex:index] commitEditing])
return NO;
return YES;
+1 -1
View File
@@ -94,7 +94,7 @@
domain = "";
#if PLATFORM(DOM)
document.cookie = _cookieName+"="+value+expires+"; path=/"+domain;
document.cookie = _cookieName + "=" + value + expires + "; path=/" + domain;
#else
_cookieValue = value;
_expires = expires;
+94 -11
View File
@@ -23,9 +23,12 @@ Cursor support by browser:
@import <Foundation/CPObject.j>
@global CPApp
var currentCursor = nil,
cursorStack = [],
cursors = {};
cursors = {},
ieCursorMap = {};
@implementation CPCursor : CPObject
{
@@ -36,6 +39,20 @@ var currentCursor = nil,
BOOL _isSetOnMouseExited @accessors(readwrite, getter=isSetOnMouseExited, setter=setOnMouseExited:);
}
+ (void)initialize
{
if (self !== CPCursor)
return;
// IE < 9 does not support some CSS cursors, we map them to supported ones
ieCursorMap = {
"ew-resize": "e-resize",
"ns-resize": "n-resize",
"nesw-resize": "ne-resize",
"nwse-resize": "nw-resize"
};
}
- (id)initWithCSSString:(CPString)aString
{
if (self = [super init])
@@ -44,23 +61,30 @@ var currentCursor = nil,
return self;
}
// hotspot is supported in CSS3 (but not IE).
- (id)initWithImage:(CPImage)image hotSpot:(CPPoint)hotSpot
/*!
Init a cursor with the given image and hotspot.
hotspot is supported in CSS3 (but not IE).
*/
- (id)initWithImage:(CPImage)image hotSpot:(CGPoint)hotSpot
{
_hotSpot = hotSpot;
_image = image;
return [self initWithCSSString:"url(" + [_image filename] + ")" + hotSpot.x + " " + hotSpot.y + ", auto"];
}
// foregroundColor and backgroundColor are ignored in Cocoa as well. See http://developer.apple.com/library/mac/#documentation/Cocoa/Reference/ApplicationKit/Classes/NSCursor_Class/Reference/Reference.html
- (id)initWithImage:(CPImage)image foregroundColorHint:(CPColor)foregroundColor backgroundColorHint:(CPColor)backgroundColor hotSpot:(CPPoint)aHotSpot
/*!
Init a cursor with the given image and hotspot. This is provided
for compliance with Cocoa. Note that foregroundColor and backgroundColor are ignored
(as they are in Cocoa). See http://developer.apple.com/library/mac/#documentation/Cocoa/Reference/ApplicationKit/Classes/NSCursor_Class/Reference/Reference.html
*/
- (id)initWithImage:(CPImage)image foregroundColorHint:(CPColor)foregroundColor backgroundColorHint:(CPColor)backgroundColor hotSpot:(CGPoint)aHotSpot
{
return [self initWithImage:image hotSpot:hotSpot];
return [self initWithImage:image hotSpot:aHotSpot];
}
+ (void)hide
{
[self _setCursorCSS:"none"]; // Not supported in IE
[self _setCursorCSS:@"none"]; // Not supported in IE < 9
}
+ (void)unhide
@@ -121,6 +145,7 @@ var currentCursor = nil,
{
#if PLATFORM(DOM)
var platformWindows = [[CPPlatformWindow visiblePlatformWindows] allObjects];
for (var i = 0, count = [platformWindows count]; i < count; i++)
platformWindows[i]._DOMBodyElement.style.cursor = aString;
#endif
@@ -130,22 +155,40 @@ var currentCursor = nil,
+ (CPCursor)_systemCursorWithName:(CPString)cursorName cssString:(CPString)aString hasImage:(BOOL)doesHaveImage
{
var cursor = cursors[cursorName];
if (typeof cursor === 'undefined')
if (typeof cursor === "undefined")
{
var cssString;
if (doesHaveImage)
cssString = @"url(" + [[CPBundle bundleForClass:self] resourcePath] + @"/CPCursor/" + cursorName + ".cur), " + aString;
{
var themeResourcePath = [[[CPApp themeBlend] bundle] resourcePath],
extension = CPBrowserIsEngine(CPInternetExplorerBrowserEngine) ? @"cur" : @"png";
cssString = [CPString stringWithFormat:@"url(%@cursors/%@.%@), %@", themeResourcePath, cursorName, extension, aString];
}
else
cssString = aString
{
// IE <= 8 does not support some cursors, map them to supported cursors
var ieLessThan9 = CPBrowserIsEngine(CPInternetExplorerBrowserEngine) && !CPFeatureIsCompatible(CPHTMLCanvasFeature);
if (ieLessThan9)
cssString = ieCursorMap[aString] || aString;
else
cssString = aString;
}
cursor = [[CPCursor alloc] initWithCSSString:cssString];
cursors[cursorName] = cursor;
}
return cursor;
}
+ (CPCursor)arrowCursor
{
return [CPCursor _systemCursorWithName:CPStringFromSelector(_cmd) cssString:"default" hasImage:NO];
return [CPCursor _systemCursorWithName:CPStringFromSelector(_cmd) cssString:@"default" hasImage:NO];
}
+ (CPCursor)crosshairCursor
@@ -163,6 +206,36 @@ var currentCursor = nil,
return [CPCursor _systemCursorWithName:CPStringFromSelector(_cmd) cssString:@"pointer" hasImage:NO];
}
+ (CPCursor)resizeNorthwestCursor
{
return [CPCursor _systemCursorWithName:CPStringFromSelector(_cmd) cssString:@"nw-resize" hasImage:NO];
}
+ (CPCursor)resizeNorthwestSoutheastCursor
{
return [CPCursor _systemCursorWithName:CPStringFromSelector(_cmd) cssString:@"nwse-resize" hasImage:NO];
}
+ (CPCursor)resizeNortheastCursor
{
return [CPCursor _systemCursorWithName:CPStringFromSelector(_cmd) cssString:@"ne-resize" hasImage:NO];
}
+ (CPCursor)resizeNortheastSouthwestCursor
{
return [CPCursor _systemCursorWithName:CPStringFromSelector(_cmd) cssString:@"nesw-resize" hasImage:NO];
}
+ (CPCursor)resizeSouthwestCursor
{
return [CPCursor _systemCursorWithName:CPStringFromSelector(_cmd) cssString:@"sw-resize" hasImage:NO];
}
+ (CPCursor)resizeSoutheastCursor
{
return [CPCursor _systemCursorWithName:CPStringFromSelector(_cmd) cssString:@"se-resize" hasImage:NO];
}
+ (CPCursor)resizeDownCursor
{
return [CPCursor _systemCursorWithName:CPStringFromSelector(_cmd) cssString:@"s-resize" hasImage:NO];
@@ -188,11 +261,21 @@ var currentCursor = nil,
return [CPCursor _systemCursorWithName:CPStringFromSelector(_cmd) cssString:@"col-resize" hasImage:NO];
}
+ (CPCursor)resizeEastWestCursor
{
return [CPCursor _systemCursorWithName:CPStringFromSelector(_cmd) cssString:@"ew-resize" hasImage:NO];
}
+ (CPCursor)resizeUpDownCursor
{
return [CPCursor _systemCursorWithName:CPStringFromSelector(_cmd) cssString:@"row-resize" hasImage:NO];
}
+ (CPCursor)resizeNorthSouthCursor
{
return [CPCursor _systemCursorWithName:CPStringFromSelector(_cmd) cssString:@"ns-resize" hasImage:NO];
}
+ (CPCursor)operationNotAllowedCursor
{
return [CPCursor _systemCursorWithName:CPStringFromSelector(_cmd) cssString:@"not-allowed" hasImage:NO];
+168
View File
@@ -0,0 +1,168 @@
/*
* CPDictionaryController.j
* AppKit
*
* Adapted from Cocotron, by Johannes Fortmann
*
* Created by Blair Duncan
* Copyright 2013, SGL Studio, BBDO Toronto 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 "CPArrayController.j"
@implementation CPDictionaryController : CPArrayController
{
CPDictionary _contentDictionary;
CPArray _includedKeys @accessors(property=includedKeys);
CPArray _excludedKeys @accessors(property=excludedKeys);
CPString _initialKey @accessors(property=initialKey);
id _initialValue @accessors(property=initialValue);
}
- (id)init
{
self = [super init];
if (self)
{
_initialKey = @"key";
_initialValue = @"value";
}
return self;
}
- (id)newObject
{
var keys = [_contentDictionary allKeys],
newKey = _initialKey,
count = 0;
if ([keys containsObject:newKey])
while ([keys containsObject:newKey])
newKey = [CPString stringWithFormat:@"%@%i", _initialKey, ++count];
return [self _newObjectWithKey:newKey value:_initialValue];
}
- (id)_newObjectWithKey:(CPString)aKey value:(id)aValue
{
var aNewObject = [_CPDictionaryControllerKeyValuePair new];
aNewObject._dictionary = _contentDictionary;
aNewObject._controller = self;
aNewObject._key = aKey;
if (aValue !== nil)
[aNewObject setValue:aValue];
return aNewObject;
}
- (CPDictionary)contentDictionary
{
return _contentDictionary;
}
- (void)setContentDictionary:(CPDictionary)aDictionary
{
if (aDictionary == _contentDictionary)
return;
if ([aDictionary isKindOfClass:[CPDictionary class]])
_contentDictionary = aDictionary;
else
_contentDictionary = nil;
var array = [CPArray array],
allKeys = [_contentDictionary allKeys];
[allKeys addObjectsFromArray:_includedKeys];
var iter = [[CPSet setWithArray:allKeys] objectEnumerator],
obj;
while ((obj = [iter nextObject]) !== nil)
if (![_excludedKeys containsObject:obj])
[array addObject:[self _newObjectWithKey:obj value:nil]];
[super setContent:array];
}
@end
var CPIncludedKeys = @"CPIncludedKeys",
CPExcludedKeys = @"CPExcludedKeys";
@implementation CPDictionaryController (CPCoding)
- (id)initWithCoder:(CPCoder)aCoder
{
self = [super initWithCoder:aCoder];
if (self)
{
_includedKeys = [aCoder decodeObjectForKey:CPIncludedKeys];
_excludedKeys = [aCoder decodeObjectForKey:CPExcludedKeys];
_initialKey = @"key";
_initialValue = @"value";
}
return self;
}
- (void)encodeWithCoder:(CPCoder)aCoder
{
[super encodeWithCoder:aCoder];
[aCoder encodeObject:_includedKeys forKey:CPIncludedKeys];
[aCoder encodeObject:_excludedKeys forKey:CPExcludedKeys];
}
@end
@implementation _CPDictionaryControllerKeyValuePair : CPObject
{
CPString _key @accessors(property=key);
CPDictionary _dictionary @accessors(property=dictionary);
CPDictionaryController _controller @accessors(property=controller);
}
- (id)value
{
return [_dictionary objectForKey:_key];
}
- (void)setValue:(id)aValue
{
[_dictionary setObject:aValue forKey:_key];
}
- (BOOL)isExplicitlyIncluded
{
return [[_controller _includedKeys] containsObject:_key];
}
@end
+8 -4
View File
@@ -23,12 +23,16 @@
@import <Foundation/CPString.j>
@import <Foundation/CPArray.j>
@import "CPApplication.j"
@import "CPAlert.j"
@import "CPResponder.j"
@import "CPSavePanel.j"
@import "CPViewController.j"
@import "CPWindowController.j"
@class CPDocumentController
@global CPApp
/*
@global
@@ -125,7 +129,7 @@ var CPDocumentUntitledCount = 0;
if (self)
{
_windowControllers = [];
_viewControllersForWindowControllers = [CPDictionary dictionary];
_viewControllersForWindowControllers = @{};
_hasUndoManager = YES;
_changeCount = 0;
@@ -142,7 +146,7 @@ var CPDocumentUntitledCount = 0;
@param anError not used
@return the initialized document
*/
- (id)initWithType:(CPString)aType error:({CPError})anError
- (id)initWithType:(CPString)aType error:(/*{*/CPError/*}*/)anError
{
self = [self init];
@@ -211,7 +215,7 @@ var CPDocumentUntitledCount = 0;
@throws CPUnsupportedMethodException if this method hasn't been overridden by the subclass
@return the document data
*/
- (CPData)dataOfType:(CPString)aType error:({CPError})anError
- (CPData)dataOfType:(CPString)aType error:(/*{*/CPError/*}*/)anError
{
[CPException raise:CPUnsupportedMethodException
reason:"dataOfType:error: must be overridden by the document subclass."];
+10 -6
View File
@@ -25,6 +25,10 @@
@import "CPDocument.j"
@import "CPOpenPanel.j"
@import "CPMenuItem.j"
@import "CPWindowController.j"
@global CPApp
var CPSharedDocumentController = nil;
@@ -124,7 +128,7 @@ var CPSharedDocumentController = nil;
@param anError not used
@return the created document
*/
- (CPDocument)makeUntitledDocumentOfType:(CPString)aType error:({CPError})anError
- (CPDocument)makeUntitledDocumentOfType:(CPString)aType error:(/*{*/CPError/*}*/)anError
{
return [[[self documentClassForType:aType] alloc] initWithType:aType error:anError];
}
@@ -144,7 +148,7 @@ var CPSharedDocumentController = nil;
{
var type = [self typeForContentsOfURL:anAbsoluteURL error:anError];
result = [self makeDocumentWithContentsOfURL:anAbsoluteURL ofType:type delegate:self didReadSelector:@selector(document:didRead:contextInfo:) contextInfo:[CPDictionary dictionaryWithObject:shouldDisplay forKey:@"shouldDisplay"]];
result = [self makeDocumentWithContentsOfURL:anAbsoluteURL ofType:type delegate:self didReadSelector:@selector(document:didRead:contextInfo:) contextInfo:@{ @"shouldDisplay": shouldDisplay }];
[self addDocument:result];
@@ -339,10 +343,10 @@ var CPSharedDocumentController = nil;
- (void)closeAllDocumentsWithDelegate:(id)aDelegate didCloseAllSelector:(SEL)didCloseSelector contextInfo:(Object)info
{
var context = {
delegate: aDelegate,
selector: didCloseSelector,
context: info
};
delegate: aDelegate,
selector: didCloseSelector,
context: info
};
[self _closeDocumentsStartingWith:nil shouldClose:YES context:context];
}
+9 -45
View File
@@ -20,22 +20,17 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@import "CPApplication.j"
@import "CPDragServer_Constants.j"
@import "CPEvent.j"
@import "CPImageView.j"
@import "CPPasteboard.j"
@import "CPView.j"
@import "CPWindow.j"
@import "CPWindow_Constants.j"
@class CPWindow // This file is imported by CPWindow.j
@class _CPDOMDataTransferPasteboard
CPDragOperationNone = 0;
CPDragOperationCopy = 1 << 1;
CPDragOperationLink = 1 << 1;
CPDragOperationGeneric = 1 << 2;
CPDragOperationPrivate = 1 << 3;
CPDragOperationMove = 1 << 4;
CPDragOperationDelete = 1 << 5;
CPDragOperationEvery = -1;
@global CPApp
#define DRAGGING_WINDOW(anObject) ([anObject isKindOfClass:[CPWindow class]] ? anObject : [anObject window])
@@ -72,7 +67,7 @@ var CPDragServerSource = nil,
- (unsigned)draggingSourceOperationMask
*/
- (CPPoint)draggingLocation
- (CGPoint)draggingLocation
{
return [[CPDragServer sharedDragServer] draggingLocation];
}
@@ -253,7 +248,7 @@ var CPDraggingSource_draggedImage_movedTo_ = 1 << 0,
_draggingUpdateTimer = [CPTimer scheduledTimerWithTimeInterval:CPDragServerPeriodicUpdateInterval
target:self
selector:@selector(_sendPeriodicDraggingUpdate:)
userInfo:[CPDictionary dictionaryWithJSObject:{platformWindow:aPlatformWindow, location:aLocation}]
userInfo:@{ "platformWindow":aPlatformWindow, "location":aLocation }
repeats:NO];
var scrollView = [_draggingDestination isKindOfClass:[CPView class]] ? [_draggingDestination enclosingScrollView] : nil;
@@ -461,6 +456,7 @@ var CPDraggingSource_draggedImage_movedTo_ = 1 << 0,
else if (type === CPKeyDown)
{
var characters = [anEvent characters];
if (characters === CPEscapeFunctionKey)
{
_dragOperation = CPDragOperationNone;
@@ -477,39 +473,7 @@ var CPDraggingSource_draggedImage_movedTo_ = 1 << 0,
// If we're not a mouse up, then we're going to want to grab the next event.
[CPApp setTarget:self selector:@selector(trackDragging:)
forNextEventMatchingMask:CPMouseMovedMask | CPLeftMouseDraggedMask | CPLeftMouseUpMask | CPKeyDownMask
untilDate:nil inMode:0 dequeue:NO];
}
@end
@implementation CPWindow (CPDraggingAdditions)
/* @ignore */
- (id)_dragHitTest:(CGPoint)aPoint pasteboard:(CPPasteboard)aPasteboard
{
// If none of our views or ourselves has registered for drag events...
if (!_inclusiveRegisteredDraggedTypes)
return nil;
// We don't need to do this because the only place this gets called
// -_dragHitTest: in CPPlatformWindow does this already. Perhaps to
// be safe?
// if (![self containsPoint:aPoint])
// return nil;
var adjustedPoint = [self convertPlatformWindowToBase:aPoint],
hitView = [_windowView hitTest:adjustedPoint];
while (hitView && ![aPasteboard availableTypeFromArray:[hitView registeredDraggedTypes]])
hitView = [hitView superview];
if (hitView)
return hitView;
if ([aPasteboard availableTypeFromArray:[self registeredDraggedTypes]])
return self;
return nil;
untilDate:nil inMode:0 dequeue:YES];
}
@end
+30
View File
@@ -0,0 +1,30 @@
/*
* CPDragServer_Constants.j
* AppKit
*
* Created by Francisco Tolmasky.
* Copyright 2008, 280 North, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
CPDragOperationNone = 0;
CPDragOperationCopy = 1 << 1;
CPDragOperationLink = 1 << 1;
CPDragOperationGeneric = 1 << 2;
CPDragOperationPrivate = 1 << 3;
CPDragOperationMove = 1 << 4;
CPDragOperationDelete = 1 << 5;
CPDragOperationEvery = -1;
+19 -161
View File
@@ -20,162 +20,19 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@import "CPEvent_Constants.j"
@import <Foundation/CPObject.j>
@import <Foundation/CPObjJRuntime.j>
@import <Foundation/CPString.j>
@import "CPCompatibility.j"
@import "CGGeometry.j"
@import "CPText.j"
@class CPTextField
CPLeftMouseDown = 1;
CPLeftMouseUp = 2;
CPRightMouseDown = 3;
CPRightMouseUp = 4;
CPMouseMoved = 5;
CPLeftMouseDragged = 6;
CPRightMouseDragged = 7;
CPMouseEntered = 8;
CPMouseExited = 9;
CPKeyDown = 10;
CPKeyUp = 11;
CPFlagsChanged = 12;
CPAppKitDefined = 13;
CPSystemDefined = 14;
CPApplicationDefined = 15;
CPPeriodic = 16;
CPCursorUpdate = 17;
CPScrollWheel = 22;
CPOtherMouseDown = 25;
CPOtherMouseUp = 26;
CPOtherMouseDragged = 27;
// iPhone Event Types
CPTouchStart = 28;
CPTouchMove = 29;
CPTouchEnd = 30;
CPTouchCancel = 31;
CPAlphaShiftKeyMask = 1 << 16;
CPShiftKeyMask = 1 << 17;
CPControlKeyMask = 1 << 18;
CPAlternateKeyMask = 1 << 19;
CPCommandKeyMask = 1 << 20;
CPNumericPadKeyMask = 1 << 21;
CPHelpKeyMask = 1 << 22;
CPFunctionKeyMask = 1 << 23;
CPDeviceIndependentModifierFlagsMask = 0xffff0000;
CPLeftMouseDownMask = 1 << CPLeftMouseDown;
CPLeftMouseUpMask = 1 << CPLeftMouseUp;
CPRightMouseDownMask = 1 << CPRightMouseDown;
CPRightMouseUpMask = 1 << CPRightMouseUp;
CPOtherMouseDownMask = 1 << CPOtherMouseDown;
CPOtherMouseUpMask = 1 << CPOtherMouseUp;
CPMouseMovedMask = 1 << CPMouseMoved;
CPLeftMouseDraggedMask = 1 << CPLeftMouseDragged;
CPRightMouseDraggedMask = 1 << CPRightMouseDragged;
CPOtherMouseDragged = 1 << CPOtherMouseDragged;
CPMouseEnteredMask = 1 << CPMouseEntered;
CPMouseExitedMask = 1 << CPMouseExited;
CPCursorUpdateMask = 1 << CPCursorUpdate;
CPKeyDownMask = 1 << CPKeyDown;
CPKeyUpMask = 1 << CPKeyUp;
CPFlagsChangedMask = 1 << CPFlagsChanged;
CPAppKitDefinedMask = 1 << CPAppKitDefined;
CPSystemDefinedMask = 1 << CPSystemDefined;
CPApplicationDefinedMask = 1 << CPApplicationDefined;
CPPeriodicMask = 1 << CPPeriodic;
CPScrollWheelMask = 1 << CPScrollWheel;
CPAnyEventMask = 0xffffffff;
CPUpArrowFunctionKey = "\uF700";
CPDownArrowFunctionKey = "\uF701";
CPLeftArrowFunctionKey = "\uF702";
CPRightArrowFunctionKey = "\uF703";
CPF1FunctionKey = "\uF704";
CPF2FunctionKey = "\uF705";
CPF3FunctionKey = "\uF706";
CPF4FunctionKey = "\uF707";
CPF5FunctionKey = "\uF708";
CPF6FunctionKey = "\uF709";
CPF7FunctionKey = "\uF70A";
CPF8FunctionKey = "\uF70B";
CPF9FunctionKey = "\uF70C";
CPF10FunctionKey = "\uF70D";
CPF11FunctionKey = "\uF70E";
CPF12FunctionKey = "\uF70F";
CPF13FunctionKey = "\uF710";
CPF14FunctionKey = "\uF711";
CPF15FunctionKey = "\uF712";
CPF16FunctionKey = "\uF713";
CPF17FunctionKey = "\uF714";
CPF18FunctionKey = "\uF715";
CPF19FunctionKey = "\uF716";
CPF20FunctionKey = "\uF717";
CPF21FunctionKey = "\uF718";
CPF22FunctionKey = "\uF719";
CPF23FunctionKey = "\uF71A";
CPF24FunctionKey = "\uF71B";
CPF25FunctionKey = "\uF71C";
CPF26FunctionKey = "\uF71D";
CPF27FunctionKey = "\uF71E";
CPF28FunctionKey = "\uF71F";
CPF29FunctionKey = "\uF720";
CPF30FunctionKey = "\uF721";
CPF31FunctionKey = "\uF722";
CPF32FunctionKey = "\uF723";
CPF33FunctionKey = "\uF724";
CPF34FunctionKey = "\uF725";
CPF35FunctionKey = "\uF726";
CPInsertFunctionKey = "\uF727";
CPDeleteFunctionKey = "\uF728";
CPHomeFunctionKey = "\uF729";
CPBeginFunctionKey = "\uF72A";
CPEndFunctionKey = "\uF72B";
CPPageUpFunctionKey = "\uF72C";
CPPageDownFunctionKey = "\uF72D";
CPPrintScreenFunctionKey = "\uF72E";
CPScrollLockFunctionKey = "\uF72F";
CPPauseFunctionKey = "\uF730";
CPSysReqFunctionKey = "\uF731";
CPBreakFunctionKey = "\uF732";
CPResetFunctionKey = "\uF733";
CPStopFunctionKey = "\uF734";
CPMenuFunctionKey = "\uF735";
CPUserFunctionKey = "\uF736";
CPSystemFunctionKey = "\uF737";
CPPrintFunctionKey = "\uF738";
CPClearLineFunctionKey = "\uF739";
CPClearDisplayFunctionKey = "\uF73A";
CPInsertLineFunctionKey = "\uF73B";
CPDeleteLineFunctionKey = "\uF73C";
CPInsertCharFunctionKey = "\uF73D";
CPDeleteCharFunctionKey = "\uF73E";
CPPrevFunctionKey = "\uF73F";
CPNextFunctionKey = "\uF740";
CPSelectFunctionKey = "\uF741";
CPExecuteFunctionKey = "\uF742";
CPUndoFunctionKey = "\uF743";
CPRedoFunctionKey = "\uF744";
CPFindFunctionKey = "\uF745";
CPHelpFunctionKey = "\uF746";
CPModeSwitchFunctionKey = "\uF747";
CPEscapeFunctionKey = "\u001B";
CPSpaceFunctionKey = "\u0020";
CPDOMEventDoubleClick = "dblclick";
CPDOMEventMouseDown = "mousedown";
CPDOMEventMouseUp = "mouseup";
CPDOMEventMouseMoved = "mousemove";
CPDOMEventMouseDragged = "mousedrag";
CPDOMEventKeyUp = "keyup";
CPDOMEventKeyDown = "keydown";
CPDOMEventKeyPress = "keypress";
CPDOMEventCopy = "copy";
CPDOMEventPaste = "paste";
CPDOMEventScrollWheel = "mousewheel";
CPDOMEventTouchStart = "touchstart";
CPDOMEventTouchMove = "touchmove";
CPDOMEventTouchEnd = "touchend";
CPDOMEventTouchCancel = "touchcancel";
@global CPApp
var _CPEventPeriodicEventPeriod = 0,
_CPEventPeriodicEventTimer = nil,
@@ -190,7 +47,7 @@ var _CPEventPeriodicEventPeriod = 0,
@implementation CPEvent : CPObject
{
CPEventType _type;
CPPoint _location;
CGPoint _location;
unsigned _modifierFlags;
CPTimeInterval _timestamp;
CPGraphicsContext _context;
@@ -206,6 +63,7 @@ var _CPEventPeriodicEventPeriod = 0,
DOMEvent _DOMEvent;
int _data1;
int _data2;
short _subtype;
float _deltaX;
float _deltaY;
@@ -308,13 +166,13 @@ var _CPEventPeriodicEventPeriod = 0,
}
/* @ignore */
- (id)_initMouseEventWithType:(CPEventType)anEventType location:(CPPoint)aPoint modifierFlags:(unsigned)modifierFlags
- (id)_initMouseEventWithType:(CPEventType)anEventType location:(CGPoint)aPoint modifierFlags:(unsigned)modifierFlags
timestamp:(CPTimeInterval)aTimestamp windowNumber:(int)aWindowNumber context:(CPGraphicsContext)aGraphicsContext
eventNumber:(int)anEventNumber clickCount:(int)aClickCount pressure:(float)aPressure
{
if (self = [self _initWithType:anEventType])
{
_location = CPPointCreateCopy(aPoint);
_location = CGPointCreateCopy(aPoint);
_modifierFlags = modifierFlags;
_timestamp = aTimestamp;
_context = aGraphicsContext;
@@ -328,13 +186,13 @@ var _CPEventPeriodicEventPeriod = 0,
}
/* @ignore */
- (id)_initKeyEventWithType:(CPEventType)anEventType location:(CPPoint)aPoint modifierFlags:(unsigned int)modifierFlags
- (id)_initKeyEventWithType:(CPEventType)anEventType location:(CGPoint)aPoint modifierFlags:(unsigned int)modifierFlags
timestamp:(CPTimeInterval)aTimestamp windowNumber:(int)aWindowNumber context:(CPGraphicsContext)aGraphicsContext
characters:(CPString)characters charactersIgnoringModifiers:(CPString)unmodCharacters isARepeat:(BOOL)isARepeat keyCode:(unsigned short)code
{
if (self = [self _initWithType:anEventType])
{
_location = CPPointCreateCopy(aPoint);
_location = CGPointCreateCopy(aPoint);
_modifierFlags = modifierFlags;
_timestamp = aTimestamp;
_context = aGraphicsContext;
@@ -355,7 +213,7 @@ var _CPEventPeriodicEventPeriod = 0,
{
if (self = [self _initWithType:anEventType])
{
_location = CPPointCreateCopy(aPoint);
_location = CGPointCreateCopy(aPoint);
_modifierFlags = modifierFlags;
_timestamp = aTimestamp;
_context = aGraphicsContext;
@@ -649,7 +507,7 @@ var _CPEventPeriodicEventPeriod = 0,
case CPKeyDown:
case CPKeyUp:
case CPFlagsChanged:
return [CPString stringWithFormat:@"CPEvent: type=%d loc=%@ time=%.1f flags=0x%X win=%@ winNum=%d ctxt=%@ chars=\"%@\" unmodchars=\"%@\" repeat=%d keyCode=%d", _type, CPStringFromPoint(_location), _timestamp, _modifierFlags, _window, _windowNumber, _context, _characters, _charactersIgnoringModifiers, _isARepeat, _keyCode];
return [CPString stringWithFormat:@"CPEvent: type=%d loc=%@ time=%.1f flags=0x%X win=%@ winNum=%d ctxt=%@ chars=\"%@\" unmodchars=\"%@\" repeat=%d keyCode=%d", _type, CGStringFromPoint(_location), _timestamp, _modifierFlags, _window, _windowNumber, _context, _characters, _charactersIgnoringModifiers, _isARepeat, _keyCode];
case CPLeftMouseDown:
case CPLeftMouseUp:
case CPRightMouseDown:
@@ -659,9 +517,9 @@ var _CPEventPeriodicEventPeriod = 0,
case CPRightMouseDragged:
case CPMouseEntered:
case CPMouseExited:
return [CPString stringWithFormat:@"CPEvent: type=%d loc=%@ time=%.1f flags=0x%X win=%@ winNum=%d ctxt=%@ evNum=%d click=%d buttonNumber=%d pressure=%f", _type, CPStringFromPoint(_location), _timestamp, _modifierFlags, _window, _windowNumber, _context, _eventNumber, _clickCount, [self buttonNumber], _pressure];
return [CPString stringWithFormat:@"CPEvent: type=%d loc=%@ time=%.1f flags=0x%X win=%@ winNum=%d ctxt=%@ evNum=%d click=%d buttonNumber=%d pressure=%f", _type, CGStringFromPoint(_location), _timestamp, _modifierFlags, _window, _windowNumber, _context, _eventNumber, _clickCount, [self buttonNumber], _pressure];
default:
return [CPString stringWithFormat:@"CPEvent: type=%d loc=%@ time=%.1f flags=0x%X win=%@ winNum=%d ctxt=%@ subtype=%d data1=%d data2=%d", _type, CPStringFromPoint(_location), _timestamp, _modifierFlags, _window, _windowNumber, _context, _subtype, _data1, _data2];
return [CPString stringWithFormat:@"CPEvent: type=%d loc=%@ time=%.1f flags=0x%X win=%@ winNum=%d ctxt=%@ subtype=%d data1=%d data2=%d", _type, CGStringFromPoint(_location), _timestamp, _modifierFlags, _window, _windowNumber, _context, _subtype, _data1, _data2];
}
}
+174
View File
@@ -0,0 +1,174 @@
/*
* CPEvent_Constants.j
* AppKit
*
* Created by Francisco Tolmasky.
* Copyright 2008, 280 North, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
CPLeftMouseDown = 1;
CPLeftMouseUp = 2;
CPRightMouseDown = 3;
CPRightMouseUp = 4;
CPMouseMoved = 5;
CPLeftMouseDragged = 6;
CPRightMouseDragged = 7;
CPMouseEntered = 8;
CPMouseExited = 9;
CPKeyDown = 10;
CPKeyUp = 11;
CPFlagsChanged = 12;
CPAppKitDefined = 13;
CPSystemDefined = 14;
CPApplicationDefined = 15;
CPPeriodic = 16;
CPCursorUpdate = 17;
CPScrollWheel = 22;
CPOtherMouseDown = 25;
CPOtherMouseUp = 26;
CPOtherMouseDragged = 27;
// iPhone Event Types
CPTouchStart = 28;
CPTouchMove = 29;
CPTouchEnd = 30;
CPTouchCancel = 31;
CPAlphaShiftKeyMask = 1 << 16;
CPShiftKeyMask = 1 << 17;
CPControlKeyMask = 1 << 18;
CPAlternateKeyMask = 1 << 19;
CPCommandKeyMask = 1 << 20;
CPNumericPadKeyMask = 1 << 21;
CPHelpKeyMask = 1 << 22;
CPFunctionKeyMask = 1 << 23;
CPDeviceIndependentModifierFlagsMask = 0xffff0000;
CPLeftMouseDownMask = 1 << CPLeftMouseDown;
CPLeftMouseUpMask = 1 << CPLeftMouseUp;
CPRightMouseDownMask = 1 << CPRightMouseDown;
CPRightMouseUpMask = 1 << CPRightMouseUp;
CPOtherMouseDownMask = 1 << CPOtherMouseDown;
CPOtherMouseUpMask = 1 << CPOtherMouseUp;
CPMouseMovedMask = 1 << CPMouseMoved;
CPLeftMouseDraggedMask = 1 << CPLeftMouseDragged;
CPRightMouseDraggedMask = 1 << CPRightMouseDragged;
CPOtherMouseDragged = 1 << CPOtherMouseDragged;
CPMouseEnteredMask = 1 << CPMouseEntered;
CPMouseExitedMask = 1 << CPMouseExited;
CPCursorUpdateMask = 1 << CPCursorUpdate;
CPKeyDownMask = 1 << CPKeyDown;
CPKeyUpMask = 1 << CPKeyUp;
CPFlagsChangedMask = 1 << CPFlagsChanged;
CPAppKitDefinedMask = 1 << CPAppKitDefined;
CPSystemDefinedMask = 1 << CPSystemDefined;
CPApplicationDefinedMask = 1 << CPApplicationDefined;
CPPeriodicMask = 1 << CPPeriodic;
CPScrollWheelMask = 1 << CPScrollWheel;
CPAnyEventMask = 0xffffffff;
CPUpArrowFunctionKey = "\uF700";
CPDownArrowFunctionKey = "\uF701";
CPLeftArrowFunctionKey = "\uF702";
CPRightArrowFunctionKey = "\uF703";
CPF1FunctionKey = "\uF704";
CPF2FunctionKey = "\uF705";
CPF3FunctionKey = "\uF706";
CPF4FunctionKey = "\uF707";
CPF5FunctionKey = "\uF708";
CPF6FunctionKey = "\uF709";
CPF7FunctionKey = "\uF70A";
CPF8FunctionKey = "\uF70B";
CPF9FunctionKey = "\uF70C";
CPF10FunctionKey = "\uF70D";
CPF11FunctionKey = "\uF70E";
CPF12FunctionKey = "\uF70F";
CPF13FunctionKey = "\uF710";
CPF14FunctionKey = "\uF711";
CPF15FunctionKey = "\uF712";
CPF16FunctionKey = "\uF713";
CPF17FunctionKey = "\uF714";
CPF18FunctionKey = "\uF715";
CPF19FunctionKey = "\uF716";
CPF20FunctionKey = "\uF717";
CPF21FunctionKey = "\uF718";
CPF22FunctionKey = "\uF719";
CPF23FunctionKey = "\uF71A";
CPF24FunctionKey = "\uF71B";
CPF25FunctionKey = "\uF71C";
CPF26FunctionKey = "\uF71D";
CPF27FunctionKey = "\uF71E";
CPF28FunctionKey = "\uF71F";
CPF29FunctionKey = "\uF720";
CPF30FunctionKey = "\uF721";
CPF31FunctionKey = "\uF722";
CPF32FunctionKey = "\uF723";
CPF33FunctionKey = "\uF724";
CPF34FunctionKey = "\uF725";
CPF35FunctionKey = "\uF726";
CPInsertFunctionKey = "\uF727";
CPDeleteFunctionKey = "\uF728";
CPHomeFunctionKey = "\uF729";
CPBeginFunctionKey = "\uF72A";
CPEndFunctionKey = "\uF72B";
CPPageUpFunctionKey = "\uF72C";
CPPageDownFunctionKey = "\uF72D";
CPPrintScreenFunctionKey = "\uF72E";
CPScrollLockFunctionKey = "\uF72F";
CPPauseFunctionKey = "\uF730";
CPSysReqFunctionKey = "\uF731";
CPBreakFunctionKey = "\uF732";
CPResetFunctionKey = "\uF733";
CPStopFunctionKey = "\uF734";
CPMenuFunctionKey = "\uF735";
CPUserFunctionKey = "\uF736";
CPSystemFunctionKey = "\uF737";
CPPrintFunctionKey = "\uF738";
CPClearLineFunctionKey = "\uF739";
CPClearDisplayFunctionKey = "\uF73A";
CPInsertLineFunctionKey = "\uF73B";
CPDeleteLineFunctionKey = "\uF73C";
CPInsertCharFunctionKey = "\uF73D";
CPDeleteCharFunctionKey = "\uF73E";
CPPrevFunctionKey = "\uF73F";
CPNextFunctionKey = "\uF740";
CPSelectFunctionKey = "\uF741";
CPExecuteFunctionKey = "\uF742";
CPUndoFunctionKey = "\uF743";
CPRedoFunctionKey = "\uF744";
CPFindFunctionKey = "\uF745";
CPHelpFunctionKey = "\uF746";
CPModeSwitchFunctionKey = "\uF747";
CPEscapeFunctionKey = "\u001B";
CPSpaceFunctionKey = "\u0020";
CPDOMEventDoubleClick = "dblclick";
CPDOMEventMouseDown = "mousedown";
CPDOMEventMouseUp = "mouseup";
CPDOMEventMouseMoved = "mousemove";
CPDOMEventMouseDragged = "mousedrag";
CPDOMEventKeyUp = "keyup";
CPDOMEventKeyDown = "keydown";
CPDOMEventKeyPress = "keypress";
CPDOMEventCopy = "copy";
CPDOMEventPaste = "paste";
CPDOMEventScrollWheel = "mousewheel";
CPDOMEventTouchStart = "touchstart";
CPDOMEventTouchMove = "touchmove";
CPDOMEventTouchEnd = "touchend";
CPDOMEventTouchCancel = "touchcancel";
+19 -13
View File
@@ -38,7 +38,6 @@ var IEFlashCLSID = "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000";
#if PLATFORM(DOM)
DOMElement _DOMParamElement;
DOMElement _DOMObjectElement;
DOMElement _DOMInnerObjectElement;
#endif
}
@@ -52,22 +51,16 @@ var IEFlashCLSID = "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000";
if (!CPBrowserIsEngine(CPInternetExplorerBrowserEngine))
{
_DOMObjectElement = document.createElement(@"object");
_DOMObjectElement.id = [self elementID];
_DOMObjectElement.width = @"100%";
_DOMObjectElement.height = @"100%";
_DOMObjectElement.style.top = @"0px";
_DOMObjectElement.style.left = @"0px";
_DOMObjectElement.type = @"application/x-shockwave-flash";
_DOMObjectElement.setAttribute(@"classid", IEFlashCLSID);
_DOMParamElement = document.createElement(@"param");
_DOMParamElement.name = @"movie";
_DOMInnerObjectElement = document.createElement(@"object");
_DOMInnerObjectElement.width = @"100%";
_DOMInnerObjectElement.height = @"100%";
_DOMObjectElement.appendChild(_DOMParamElement);
_DOMObjectElement.appendChild(_DOMInnerObjectElement);
_DOMElement.appendChild(_DOMObjectElement);
}
@@ -89,7 +82,7 @@ var IEFlashCLSID = "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000";
if (!CPBrowserIsEngine(CPInternetExplorerBrowserEngine))
{
_DOMParamElement.value = [aFlashMovie filename];
_DOMInnerObjectElement.data = [aFlashMovie filename];
_DOMObjectElement.data = [aFlashMovie filename];
}
else
[self _rebuildIEObjects];
@@ -107,11 +100,14 @@ var IEFlashCLSID = "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000";
enumerator = [aDictionary keyEnumerator],
key;
while ((key = [enumerator nextObject]) !== nil)
if (key = [enumerator nextObject])
varString = [varString stringByAppendingFormat:@"%@=%@", key, [aDictionary objectForKey:key]];
while (key = [enumerator nextObject])
varString = [varString stringByAppendingFormat:@"&%@=%@", key, [aDictionary objectForKey:key]];
if (!_params)
_params = [CPDictionary dictionary];
_params = @{};
[_params setObject:varString forKey:@"flashvars"];
[self setParameters:_params];
@@ -141,7 +137,7 @@ var IEFlashCLSID = "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000";
#if PLATFORM(DOM)
if (!CPBrowserIsEngine(CPInternetExplorerBrowserEngine))
{
_paramElements = [CPDictionary dictionary];
_paramElements = @{};
var enumerator = [_params keyEnumerator],
key;
@@ -184,10 +180,20 @@ var IEFlashCLSID = "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000";
_DOMObjectElement = document.createElement(@"object");
_DOMElement.appendChild(_DOMObjectElement);
_DOMObjectElement.outerHTML = [CPString stringWithFormat:@"<object classid=%@ width=%@ height=%@>%@</object>", IEFlashCLSID, CGRectGetWidth([self bounds]), CGRectGetHeight([self bounds]), paramString];
_DOMObjectElement.outerHTML = [CPString stringWithFormat:@"<object id=%@ classid=%@ width=%@ height=%@>%@</object>", [self elementID], IEFlashCLSID, CGRectGetWidth([self bounds]), CGRectGetHeight([self bounds]), paramString];
}
#endif
- (CPString)elementID
{
return @"CPFV_" + [self UID];
}
- (void)mouseMoved:(id)sommit
{
[[[self window] platformWindow] _propagateCurrentDOMEvent:YES];
}
- (void)mouseDragged:(CPEvent)anEvent
{
[[[self window] platformWindow] _propagateCurrentDOMEvent:YES];
+2 -2
View File
@@ -281,7 +281,7 @@ following:
that dynamically tracks the current system font size.
@return the requested system font
*/
+ (CPFont)systemFontOfSize:(CPSize)aSize
+ (CPFont)systemFontOfSize:(CGSize)aSize
{
return _CPSystemFont(aSize === 0 ? _CPFontSystemFontSize : aSize, NO);
}
@@ -293,7 +293,7 @@ following:
that dynamically tracks the current system font size.
@return the requested bold system font
*/
+ (CPFont)boldSystemFontOfSize:(CPSize)aSize
+ (CPFont)boldSystemFontOfSize:(CGSize)aSize
{
return _CPSystemFont(aSize === 0 ? _CPFontSystemFontSize : aSize, YES);
}
+13 -9
View File
@@ -24,6 +24,8 @@
@import "CPFont.j"
@global CPApp
CPItalicFontMask = 1 << 0;
CPBoldFontMask = 1 << 1;
CPUnboldFontMask = 1 << 2;
@@ -54,7 +56,7 @@ var CPSharedFontManager = nil,
id _delegate @accessors(property=delegate);
CPFont _selectedFont;
BOOL _multiple @accessors;
BOOL _multiple @accessors(getter=isMultiple, setter=setMultiple:);
CPDictionary _activeChange;
}
@@ -99,6 +101,9 @@ var CPSharedFontManager = nil,
{
if (!_availableFonts)
{
_availableFonts = [];
#if PLATFORM(DOM)
_CPFontDetectSpan = document.createElement("span");
_CPFontDetectSpan.fontSize = "24px";
_CPFontDetectSpan.appendChild(document.createTextNode("mmmmmmmmmml"));
@@ -110,13 +115,16 @@ var CPSharedFontManager = nil,
_CPFontDetectReferenceFonts = _CPFontDetectPickTwoDifferentFonts(["monospace", "serif", "sans-serif", "cursive"]);
_availableFonts = [];
for (var i = 0; i < _CPFontDetectAllFonts.length; i++)
{
var available = _CPFontDetectFontAvailable(_CPFontDetectAllFonts[i]);
if (available)
_availableFonts.push(_CPFontDetectAllFonts[i]);
}
#else
// If there's no font detection, just assume all fonts are available.
_availableFonts = _CPFontDetectAllFonts;
#endif
}
return _availableFonts;
}
@@ -133,7 +141,7 @@ var CPSharedFontManager = nil,
- (void)setSelectedFont:(CPFont)aFont isMultiple:(BOOL)aFlag
{
_selectedFont = aFont;
_isMultiple = aFlag;
_multiple = aFlag;
// TODO Notify CPFontPanel when it exists.
}
@@ -143,11 +151,6 @@ var CPSharedFontManager = nil,
return _selectedFont;
}
- (BOOL)isMultiple
{
return _isMultiple;
}
- (int)weightOfFont:(CPFont)aFont
{
// TODO Weight 5 is a normal of book weight and 9 and above is bold, but it would be nice to be more
@@ -205,7 +208,8 @@ var CPSharedFontManager = nil,
- (@action)addFontTrait:(id)sender
{
_activeChange = [CPDictionary dictionaryWithObject:[sender tag] forKey:@"addTraits"];
var tag = [sender tag];
_activeChange = tag === nil ? @{} : @{ @"addTraits": tag };
[self sendAction];
}
+47 -2
View File
@@ -20,6 +20,16 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@import <Foundation/CPObject.j>
@import <Foundation/CPException.j>
@import <Foundation/CPMutableArray.j>
@import "CGColor.j"
@import "CGColorSpace.j"
@import "CGGradient.j"
@import "CPBezierPath.j"
@import "CPGraphicsContext.j"
CPGradientDrawsBeforeStartingLocation = kCGGradientDrawsBeforeStartLocation;
CPGradientDrawsAfterEndingLocation = kCGGradientDrawsAfterEndLocation;
@@ -31,6 +41,11 @@ CPGradientDrawsAfterEndingLocation = kCGGradientDrawsAfterEndLocation;
CGGradient _gradient;
}
- (id)initWithStartingColor:(CPColor)startingColor endingColor:(CPColor)endingColor
{
return [self initWithColors:[startingColor, endingColor]];
}
- (id)initWithColors:(CPArray)someColors
{
var count = [someColors count];
@@ -74,7 +89,19 @@ CPGradientDrawsAfterEndingLocation = kCGGradientDrawsAfterEndLocation;
CGContextClipToRect(ctx, rect);
CGContextAddRect(ctx, rect);
var startPoint,
[self _drawInRect:rect atAngle:angle];
CGContextRestoreGState(ctx);
}
/*!
@ignore like draw in rect but apply no clipping.
*/
- (void)_drawInRect:(CGRect)rect atAngle:(float)angle
{
var ctx = [[CPGraphicsContext currentContext] graphicsPort],
startPoint,
endPoint;
// Modulo of negative values doesn't work as expected in JS.
@@ -108,7 +135,25 @@ CPGradientDrawsAfterEndingLocation = kCGGradientDrawsAfterEndLocation;
startPoint.y + length * SIN(radians));
[self drawFromPoint:startPoint toPoint:endPoint options:CPGradientDrawsBeforeStartingLocation | CPGradientDrawsAfterEndingLocation];
CGContextRestoreGState(ctx);
}
- (void)drawInBezierPath:(CPBezierPath)aPath angle:(float)anAngle
{
[CPGraphicsContext saveGraphicsState];
var ctx = [[CPGraphicsContext currentContext] graphicsPort];
// Nail down the path which CGContextDrawLinearGradient will cause to be filled.
// Note we don't do this by clipping to the path and then calling drawInRect:atAngle:
// as this would cut off any antialias of the drawing, plus any active context shadow.
CGContextBeginPath(ctx);
CGContextAddPath(ctx, aPath._path);
CGContextSetLineWidth(ctx, [aPath lineWidth]);
CGContextClosePath(ctx);
[self _drawInRect:[aPath bounds] atAngle:anAngle];
[CPGraphicsContext restoreGraphicsState];
}
- (void)drawFromPoint:(NSPoint)startingPoint toPoint:(NSPoint)endingPoint options:(NSGradientDrawingOptions)options
+1
View File
@@ -68,6 +68,7 @@ var CPGraphicsContextCurrent = nil,
+ (void)restoreGraphicsState
{
var lastContext = [CPGraphicsContextThreadStack lastObject];
if (lastContext)
{
[lastContext restoreGraphicsState];
+68 -14
View File
@@ -21,12 +21,14 @@
*/
@import <Foundation/CPBundle.j>
@import <Foundation/CPGeometry.j>
@import <Foundation/CPNotificationCenter.j>
@import <Foundation/CPObject.j>
@import <Foundation/CPRunLoop.j>
@import <Foundation/CPString.j>
@import <Foundation/CPData.j>
@import "CGGeometry.j"
@import "CPCompatibility.j"
CPImageLoadStatusInitialized = 0;
CPImageLoadStatusLoading = 1;
@@ -46,18 +48,47 @@ var imagesForNames = { },
AppKitImageForNames = { },
ImageDescriptionFormat = "%s {\n filename: \"%s\",\n size: { width:%f, height:%f }\n}";
AppKitImageForNames[CPImageNameColorPanel] = CGSizeMake(26.0, 29.0);
AppKitImageForNames[CPImageNameColorPanelHighlighted] = CGSizeMake(26.0, 29.0);
AppKitImageForNames[CPImageNameColorPanel] = _CGSizeMake(26.0, 29.0);
AppKitImageForNames[CPImageNameColorPanelHighlighted] = _CGSizeMake(26.0, 29.0);
function CPImageInBundle(aFilename, aSize, aBundle)
/*!
Returns a resource image with a relative path and size
in a bundle.
@param filename A filename or relative path to a resource image.
@param width Width of the image. May be omitted.
@param height Height of the image. May be omitted if width is omitted.
@param size Instead of passing width/height, a CGSize may be passed.
@param bundle Bundle in which the image resource can be found.
If omitted, defaults to the main bundle.
@return CPImage
*/
function CPImageInBundle()
{
if (!aBundle)
aBundle = [CPBundle mainBundle];
var filename = arguments[0],
size = nil,
bundle = nil;
if (aSize)
return [[CPImage alloc] initWithContentsOfFile:[aBundle pathForResource:aFilename] size:aSize];
if (typeof(arguments[1]) === "number")
{
if (arguments[1] !== nil && arguments[1] !== undefined)
size = _CGSizeMake(arguments[1], arguments[2]);
return [[CPImage alloc] initWithContentsOfFile:[aBundle pathForResource:aFilename]];
bundle = arguments[3];
}
else if (typeof(arguments[1]) === "object")
{
size = arguments[1];
bundle = arguments[2];
}
if (!bundle)
bundle = [CPBundle mainBundle];
if (size)
return [[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:filename] size:size];
return [[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:filename]];
}
function CPAppKitImage(aFilename, aSize)
@@ -100,7 +131,7 @@ function CPAppKitImage(aFilename, aSize)
- (id)init
{
return [self initByReferencingFile:@"" size:CGSizeMake(-1, -1)];
return [self initByReferencingFile:@"" size:_CGSizeMake(-1, -1)];
}
/*!
@@ -117,7 +148,7 @@ function CPAppKitImage(aFilename, aSize)
if (self)
{
_size = CPSizeCreateCopy(aSize);
_size = _CGSizeMakeCopy(aSize);
_filename = aFilename;
_loadStatus = CPImageLoadStatusInitialized;
}
@@ -149,7 +180,7 @@ function CPAppKitImage(aFilename, aSize)
*/
- (id)initWithContentsOfFile:(CPString)aFilename
{
self = [self initByReferencingFile:aFilename size:CGSizeMake(-1, -1)];
self = [self initByReferencingFile:aFilename size:_CGSizeMake(-1, -1)];
if (self)
[self load];
@@ -216,7 +247,7 @@ function CPAppKitImage(aFilename, aSize)
*/
- (void)setSize:(CGSize)aSize
{
_size = CGSizeMakeCopy(aSize);
_size = _CGSizeMakeCopy(aSize);
}
/*!
@@ -271,6 +302,14 @@ function CPAppKitImage(aFilename, aSize)
return _name;
}
/*!
Returns the underlying Image element for a single image.
*/
- (Image)image
{
return _image;
}
/*!
Sets the receiver's delegate.
@param the delegate
@@ -359,6 +398,11 @@ function CPAppKitImage(aFilename, aSize)
#endif
}
- (BOOL)isSingleImage
{
return YES;
}
- (BOOL)isThreePartImage
{
return NO;
@@ -402,7 +446,7 @@ function CPAppKitImage(aFilename, aSize)
// FIXME: IE is wrong on image sizes????
if (!_size || (_size.width == -1 && _size.height == -1))
_size = CGSizeMake(_image.width, _image.height);
_size = _CGSizeMake(_image.width, _image.height);
[[CPNotificationCenter defaultCenter]
postNotificationName:CPImageDidLoadNotification
@@ -490,6 +534,11 @@ function CPAppKitImage(aFilename, aSize)
return _isVertical;
}
- (BOOL)isSingleImage
{
return NO;
}
- (BOOL)isThreePartImage
{
return YES;
@@ -554,6 +603,11 @@ var CPThreePartImageImageSlicesKey = @"CPThreePartImageImageSlicesKey",
return _imageSlices;
}
- (BOOL)isSingleImage
{
return NO;
}
- (BOOL)isThreePartImage
{
return NO;
+42 -5
View File
@@ -26,6 +26,9 @@
@import "CPImage.j"
@import "CPShadowView.j"
@global CPImagesPboardType
@global appkit_tag_dom_elements
CPImageAlignCenter = 0;
CPImageAlignTop = 1;
CPImageAlignTopLeft = 2;
@@ -67,12 +70,14 @@ var CPImageViewEmptyPlaceholderImage = nil;
CPImageViewEmptyPlaceholderImage = [[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"empty.png"]];
}
+ (Class)_binderClassForBinding:(CPString)theBinding
+ (Class)_binderClassForBinding:(CPString)aBinding
{
if (theBinding === CPValueBinding || theBinding === CPValueURLBinding || theBinding === CPValuePathBinding || theBinding === CPDataBinding)
if (aBinding === CPValueBinding || aBinding === CPValueURLBinding || aBinding === CPValuePathBinding || aBinding === CPDataBinding)
return [CPImageViewValueBinder class];
else if ([aBinding hasPrefix:CPEditableBinding])
return [CPMultipleValueAndBinding class];
return [super _binderClassForBinding:theBinding];
return [super _binderClassForBinding:aBinding];
}
- (id)initWithFrame:(CGRect)aFrame
@@ -471,16 +476,30 @@ var CPImageViewEmptyPlaceholderImage = nil;
{
var image;
if (aBinding === CPDataBinding)
if (aValue == nil)
image = nil;
else if (aBinding === CPDataBinding)
image = [[CPImage alloc] initWithData:aValue];
else if (aBinding === CPValueURLBinding || aBinding === CPValuePathBinding)
image = [[CPImage alloc] initWithContentsOfFile:aValue];
image = [CPImage cachedImageWithContentsOfFile:aValue];
else if (aBinding === CPValueBinding)
image = aValue;
[_source setImage:image];
}
- (void)valueForBinding:(CPString)aBinding
{
var image = [_source image];
if (aBinding === CPDataBinding)
return [image data];
else if (aBinding === CPValueURLBinding || aBinding === CPValuePathBinding)
return [image filename];
else if (aBinding === CPValueBinding)
return image;
}
@end
var CPImageViewImageKey = @"CPImageViewImageKey",
@@ -565,3 +584,21 @@ var CPImageViewImageKey = @"CPImageViewImageKey",
}
@end
@implementation CPImage (CahedImage)
+ (CPImage)cachedImageWithContentsOfFile:(CPString)aFile
{
var cached_name = [CPString stringWithFormat:@"%@_%d", [self class], [aFile hash]],
image = [CPImage imageNamed:cached_name];
if (!image)
{
image = [[CPImage alloc] initWithContentsOfFile:aFile];
[image setName:cached_name];
}
return image;
}
@end
+3 -2
View File
@@ -21,9 +21,10 @@
*/
@import <Foundation/CPObject.j>
@import <Foundation/CPArray.j>
@import "CPEvent.j"
@import "CPEvent_Constants.j"
@import "CPText.j"
CPStandardKeyBindings = {
@"@.": @"cancelOperation:",
+387 -93
View File
@@ -26,11 +26,14 @@
@import <Foundation/CPObject.j>
@import <Foundation/CPArray.j>
@import <Foundation/CPDictionary.j>
@import <Foundation/CPInvocation.j>
@import <Foundation/CPValueTransformer.j>
@import <Foundation/CPKeyValueObserving.j>
@class CPButton
var exposedBindingsMap = [CPDictionary new],
bindingsMap = [CPDictionary new];
var exposedBindingsMap = @{},
bindingsMap = @{};
var CPBindingOperationAnd = 0,
CPBindingOperationOr = 1;
@@ -38,7 +41,7 @@ var CPBindingOperationAnd = 0,
@implementation CPBinder : CPObject
{
CPDictionary _info;
id _source;
id _source @accessors(getter=source);
JSObject _suppressedNotifications;
JSObject _placeholderForMarker;
@@ -94,9 +97,9 @@ var CPBindingOperationAnd = 0,
if (!theBinding)
return;
var infoDictionary = theBinding._info,
observedObject = [infoDictionary objectForKey:CPObservedObjectKey],
keyPath = [infoDictionary objectForKey:CPObservedKeyPathKey];
var info = theBinding._info,
observedObject = [info objectForKey:CPObservedObjectKey],
keyPath = [info objectForKey:CPObservedKeyPathKey];
[observedObject removeObserver:theBinding forKeyPath:keyPath];
[bindings removeObjectForKey:aBinding];
@@ -105,6 +108,7 @@ var CPBindingOperationAnd = 0,
+ (void)unbindAllForObject:(id)anObject
{
var bindings = [bindingsMap objectForKey:[anObject UID]];
if (!bindings)
return;
@@ -119,26 +123,32 @@ var CPBindingOperationAnd = 0,
- (id)initWithBinding:(CPString)aBinding name:(CPString)aName to:(id)aDestination keyPath:(CPString)aKeyPath options:(CPDictionary)options from:(id)aSource
{
self = [super init];
// We use [self init] here because subclasses override init. We can't override this method
// because their initialization has to occur before this method in this class is executed.
self = [self init];
if (self)
{
_source = aSource;
_info = [CPDictionary dictionaryWithObjects:[aDestination, aKeyPath] forKeys:[CPObservedObjectKey, CPObservedKeyPathKey]];
_info = @{
CPObservedObjectKey: aDestination,
CPObservedKeyPathKey: aKeyPath,
};
_suppressedNotifications = {};
_placeholderForMarker = {};
if (options)
[_info setObject:options forKey:CPOptionsKey];
[self _updatePlaceholdersWithOptions:options];
[self _updatePlaceholdersWithOptions:options forBinding:aName];
[aDestination addObserver:self forKeyPath:aKeyPath options:CPKeyValueObservingOptionNew context:aBinding];
var bindings = [bindingsMap objectForKey:[_source UID]];
if (!bindings)
{
bindings = [CPDictionary new];
bindings = @{};
[bindingsMap setObject:bindings forKey:[_source UID]];
}
@@ -149,21 +159,25 @@ var CPBindingOperationAnd = 0,
return self;
}
- (void)raiseIfNotApplicable:(id)aValue forKeyPath:(CPString)keyPath options:(CPDictionary)options
{
if (aValue === CPNotApplicableMarker && [options objectForKey:CPRaisesForNotApplicableKeysBindingOption])
{
[CPException raise:CPGenericException
reason:@"Cannot transform non-applicable key on: " + _source + " key path: " + keyPath + " value: " + aValue];
}
}
- (void)setValueFor:(CPString)theBinding
{
var destination = [_info objectForKey:CPObservedObjectKey],
keyPath = [_info objectForKey:CPObservedKeyPathKey],
options = [_info objectForKey:CPOptionsKey],
newValue = [destination valueForKeyPath:keyPath],
isPlaceholder = CPIsControllerMarker(newValue);
newValue = [destination valueForKeyPath:keyPath];
if (isPlaceholder)
if (CPIsControllerMarker(newValue))
{
if (newValue === CPNotApplicableMarker && [options objectForKey:CPRaisesForNotApplicableKeysBindingOption])
{
[CPException raise:CPGenericException
reason:@"Cannot transform non-applicable key on: " + _source + " key path: " + keyPath + " value: " + newValue];
}
[self raiseIfNotApplicable:newValue forKeyPath:keyPath options:options];
var value = [self _placeholderForMarker:newValue];
[self setPlaceholderValue:value withMarker:newValue forBinding:theBinding];
@@ -210,6 +224,7 @@ var CPBindingOperationAnd = 0,
return;
var objectSuppressions = _suppressedNotifications[[anObject UID]];
if (objectSuppressions && objectSuppressions[aKeyPath])
return;
@@ -228,6 +243,7 @@ var CPBindingOperationAnd = 0,
if (!valueTransformer)
{
var valueTransformerClass = CPClassFromString(valueTransformerName);
if (valueTransformerClass)
{
valueTransformer = [[valueTransformerClass alloc] init];
@@ -285,6 +301,7 @@ var CPBindingOperationAnd = 0,
var uid = [anObject UID],
objectSuppressions = _suppressedNotifications[uid];
if (!objectSuppressions)
_suppressedNotifications[uid] = objectSuppressions = {};
@@ -301,6 +318,7 @@ var CPBindingOperationAnd = 0,
var uid = [anObject UID],
objectSuppressions = _suppressedNotifications[uid];
if (!objectSuppressions)
return;
@@ -317,15 +335,23 @@ var CPBindingOperationAnd = 0,
optionName = CPBinderPlaceholderOptions[count],
isExplicit = [options containsKey:optionName],
placeholder = isExplicit ? [options objectForKey:optionName] : nil;
[self _setPlaceholder:placeholder forMarker:marker isDefault:!isExplicit];
}
}
- (void)_placeholderForMarker:aMarker
- (void)_updatePlaceholdersWithOptions:(CPDictionary)options forBinding:(CPString)aBinding
{
var placeholder = _placeholderForMarker[aMarker];
[self _updatePlaceholdersWithOptions:options];
}
- (JSObject)_placeholderForMarker:(id)aMarker
{
var placeholder = _placeholderForMarker[[aMarker UID]];
if (placeholder)
return placeholder['value'];
return placeholder.value;
return nil;
}
@@ -333,14 +359,14 @@ var CPBindingOperationAnd = 0,
{
if (isDefault)
{
var existingPlaceholder = _placeholderForMarker[aMarker];
var existingPlaceholder = _placeholderForMarker[[aMarker UID]];
// Don't overwrite an explicitly set placeholder with a default.
if (existingPlaceholder && !existingPlaceholder['isDefault'])
if (existingPlaceholder && !existingPlaceholder.isDefault)
return;
}
_placeholderForMarker[aMarker] = { 'isDefault': isDefault, 'value': aPlaceholder };
_placeholderForMarker[[aMarker UID]] = { 'isDefault': isDefault, 'value': aPlaceholder };
}
@end
@@ -352,7 +378,7 @@ var CPBindingOperationAnd = 0,
[CPBinder exposeBinding:aBinding forClass:[self class]];
}
+ (Class)_binderClassForBinding:(CPString)theBinding
+ (Class)_binderClassForBinding:(CPString)aBinding
{
return [CPBinder class];
}
@@ -405,7 +431,7 @@ var CPBindingOperationAnd = 0,
[binderClass unbind:aBinding forObject:self];
}
- (id)_replacementKeyPathForBinding:(CPString)binding
- (CPString)_replacementKeyPathForBinding:(CPString)binding
{
return binding;
}
@@ -414,13 +440,13 @@ var CPBindingOperationAnd = 0,
/*!
@ignore
Provides stub implementations that simply call super for the "objectValue" binding
This class should not be necessary but assures backwards compliance with our old way of doing bindings
Every class with a value binding should implement a subclass to handle it's specific value binding logic
Provides stub implementations that simply calls super for the "objectValue" binding.
This class should not be necessary but assures backwards compliance with our old way of doing bindings.
IMPORTANT!
Every class with a value binding should implement a subclass to handle its specific value binding logic.
*/
@implementation _CPValueBinder : CPBinder
{
}
- (void)setValueFor:(CPString)theBinding
{
@@ -434,8 +460,9 @@ var CPBindingOperationAnd = 0,
@end
@implementation _CPKeyValueOrBinding : CPBinder
@implementation _CPMultipleValueBooleanBinding : CPBinder
{
CPBindingOperationKind _operation;
}
- (void)setValueFor:(CPString)aBinding
@@ -445,7 +472,14 @@ var CPBindingOperationAnd = 0,
if (!bindings)
return;
[_source setValue:resolveMultipleValues(aBinding, bindings, CPBindingOperationOr) forKey:aBinding];
var baseBinding = aBinding.replace(/\d$/, "");
[_source setValue:[self resolveMultipleValuesForBinding:baseBinding bindings:bindings booleanOperation:_operation] forKey:baseBinding];
}
- (void)reverseSetValueFor:(CPString)theBinding
{
// read-only
}
- (void)observeValueForKeyPath:(CPString)aKeyPath ofObject:(id)anObject change:(CPDictionary)changes context:(id)context
@@ -453,61 +487,146 @@ var CPBindingOperationAnd = 0,
[self setValueFor:context];
}
@end
@implementation _CPKeyValueAndBinding : CPBinder
- (BOOL)resolveMultipleValuesForBinding:(CPString)aBinding bindings:(CPDictionary)bindings booleanOperation:(CPBindingOperationKind)operation
{
}
- (void)setValueFor:(CPString)aBinding
{
var bindings = [bindingsMap objectForKey:[_source UID]];
if (!bindings)
return;
[_source setValue:resolveMultipleValues(aBinding, bindings, CPBindingOperationAnd) forKey:aBinding];
}
- (void)observeValueForKeyPath:(CPString)aKeyPath ofObject:(id)anObejct change:(CPDictionary)changes context:(id)context
{
[self setValueFor:context];
}
@end
var resolveMultipleValues = function(/*CPString*/key, /*CPDictionary*/bindings, /*GSBindingOperationKind*/operation)
{
var bindingName = key,
var bindingName = aBinding,
theBinding,
count = 1;
count = 2;
while (theBinding = [bindings objectForKey:bindingName])
{
var infoDictionary = theBinding._info,
object = [infoDictionary objectForKey:CPObservedObjectKey],
keyPath = [infoDictionary objectForKey:CPObservedKeyPathKey],
options = [infoDictionary objectForKey:CPOptionsKey];
var info = theBinding._info,
object = [info objectForKey:CPObservedObjectKey],
keyPath = [info objectForKey:CPObservedKeyPathKey],
options = [info objectForKey:CPOptionsKey],
value = [object valueForKeyPath:keyPath];
var value = [theBinding transformValue:[object valueForKeyPath:keyPath] withOptions:options];
if (CPIsControllerMarker(value))
{
[self raiseIfNotApplicable:value forKeyPath:keyPath options:options];
value = [theBinding _placeholderForMarker:value];
}
else
value = [theBinding transformValue:value withOptions:options];
if (value == operation)
return operation;
if (operation === CPBindingOperationOr)
{
// Any true condition means true for OR
if (value)
return YES;
}
bindingName = [CPString stringWithFormat:@"%@%i", key, ++count];
// Any false condition means false for AND
else if (!value)
return NO;
bindingName = aBinding + (count++);
}
return !operation;
};
// If we get here, all OR conditions were false or all AND conditions were true
return operation === CPBindingOperationOr ? NO : YES;
}
var invokeAction = function(/*CPString*/targetKey, /*CPString*/argumentKey, /*CPDictionary*/bindings)
@end
@implementation CPMultipleValueAndBinding : _CPMultipleValueBooleanBinding
- (id)init
{
var theBinding = [bindings objectForKey:targetKey],
infoDictionary = theBinding._info,
if (self = [super init])
_operation = CPBindingOperationAnd;
object = [infoDictionary objectForKey:CPObservedObjectKey],
keyPath = [infoDictionary objectForKey:CPObservedKeyPathKey],
options = [infoDictionary objectForKey:CPOptionsKey],
return self;
}
@end
@implementation CPMultipleValueOrBinding : _CPMultipleValueBooleanBinding
- (id)init
{
if (self = [super init])
_operation = CPBindingOperationOr;
return self;
}
@end
@implementation _CPMultipleValueActionBinding : CPBinder
{
CPString _argumentBinding;
CPString _targetBinding;
}
- (void)setValueFor:(CPString)theBinding
{
// Called when the binding is first created
[self checkForNullBinding:theBinding initializing:YES];
}
- (void)reverseSetValueFor:(CPString)theBinding
{
// no-op
}
- (void)observeValueForKeyPath:(CPString)aKeyPath ofObject:(id)anObject change:(CPDictionary)changes context:(id)context
{
// context is the binding name
[self checkForNullBinding:context initializing:NO];
}
/*!
@ignore
When the value of a multiple-value argument binding changes,
if the binding is marked not to allow null arguments, we have to check
if the binding's value is nil and disable the button if it is.
Otherwise the button is enabled.
*/
- (void)checkForNullBinding:(CPString)theBinding initializing:(BOOL)isInitializing
{
// Only done for buttons
if (![_source isKindOfClass:CPButton])
return;
// We start with the button enabled for the first argument during init,
// and subsequent checks can disable it.
if (isInitializing && theBinding === CPArgumentBinding)
[_source setEnabled:YES];
var bindings = [bindingsMap valueForKey:[_source UID]],
binding = [bindings objectForKey:theBinding],
info = binding._info,
options = [info objectForKey:CPOptionsKey];
if (![options valueForKey:CPAllowsNullArgumentBindingOption])
{
var object = [info objectForKey:CPObservedObjectKey],
keyPath = [info objectForKey:CPObservedKeyPathKey],
value = [object valueForKeyPath:keyPath];
if (value === nil || value === undefined)
{
[_source setEnabled:NO];
return;
}
}
// If a binding value changed and did not fail the null test, enable the button
if (!isInitializing)
[_source setEnabled:YES];
}
- (void)invokeAction
{
var bindings = [bindingsMap valueForKey:[_source UID]],
theBinding = [bindings objectForKey:CPTargetBinding],
info = theBinding._info,
object = [info objectForKey:CPObservedObjectKey],
keyPath = [info objectForKey:CPObservedKeyPathKey],
options = [info objectForKey:CPOptionsKey],
target = [object valueForKeyPath:keyPath],
selector = [options objectForKey:CPSelectorNameBindingOption];
@@ -515,27 +634,194 @@ var invokeAction = function(/*CPString*/targetKey, /*CPString*/argumentKey, /*CP
if (!target || !selector)
return;
var invocation = [CPInvocation invocationWithMethodSignature:[target methodSignatureForSelector:selector]];
[invocation setSelector:selector];
var bindingName = argumentKey,
var invocation = [CPInvocation invocationWithMethodSignature:[target methodSignatureForSelector:selector]],
bindingName = CPArgumentBinding,
count = 1;
while (theBinding = [bindings objectForKey:bindingName])
{
infoDictionary = theBinding._info;
info = theBinding._info;
object = [info objectForKey:CPObservedObjectKey];
keyPath = [info objectForKey:CPObservedKeyPathKey];
keyPath = [infoDictionary objectForKey:CPObserverKeyPathKey];
object = [[infoDictionary objectForKey:CPObservedObjectKey] valueForKeyPath:keyPath];
[invocation setArgument:[object valueForKeyPath:keyPath] atIndex:++count];
if (object)
[invocation setArgument:object atIndex:++count];
bindingName = [CPString stringWithFormat:@"%@%i", argumentKey, count];
bindingName = CPArgumentBinding + count;
}
[invocation invoke];
};
[invocation setSelector:selector];
[invocation invokeWithTarget:target];
}
@end
@implementation CPActionBinding : _CPMultipleValueActionBinding
- (id)init
{
if (self = [super init])
{
_argumentBinding = CPArgumentBinding;
_targetBinding = CPTargetBinding;
}
return self;
}
@end
@implementation CPDoubleClickActionBinding : _CPMultipleValueActionBinding
- (id)init
{
if (self = [super init])
{
_argumentBinding = CPArgumentBinding;
_targetBinding = CPTargetBinding;
}
return self;
}
@end
/*!
Abstract superclass for CPValueWithPatternBinding and CPTitleWithPatternBinding.
*/
@implementation _CPPatternBinding : CPBinder
{
CPString _bindingKey;
CPString _patternPlaceholder;
}
- (void)setValueFor:(CPString)aBinding
{
var bindings = [bindingsMap valueForKey:[_source UID]];
if (!bindings)
return;
// Strip off any trailing number from the binding name
var baseBinding = aBinding.replace(/\d$/, ""),
result = [self resolveMultipleValuesForBindings:bindings];
if (result.isPlaceholder)
[self setPlaceholderValue:result.value withMarker:result.marker forBinding:baseBinding];
else
[self setValue:result.value forBinding:baseBinding];
}
- (void)reverseSetValueFor:(CPString)theBinding
{
// read-only
}
- (void)observeValueForKeyPath:(CPString)aKeyPath ofObject:(id)anObject change:(CPDictionary)changes context:(id)context
{
[self setValueFor:context];
}
- (JSObject)resolveMultipleValuesForBindings:(CPDictionary)bindings
{
var theBinding,
result = { value:@"", isPlaceholder:NO, marker:nil };
for (var count = 1; theBinding = [bindings objectForKey:_bindingKey + count]; ++count)
{
var info = theBinding._info,
object = [info objectForKey:CPObservedObjectKey],
keyPath = [info objectForKey:CPObservedKeyPathKey],
options = [info objectForKey:CPOptionsKey],
value = [object valueForKeyPath:keyPath];
if (count === 1)
result.value = [options objectForKey:CPDisplayPatternBindingOption];
if (CPIsControllerMarker(value))
{
[self raiseIfNotApplicable:value forKeyPath:keyPath options:options];
result.isPlaceholder = YES;
result.marker = value;
value = [theBinding _placeholderForMarker:value];
}
else
value = [theBinding transformValue:value withOptions:options];
if (value === nil || value === undefined)
value = @"";
result.value = result.value.replace("%{" + _patternPlaceholder + count + "}@", [value description]);
}
return result;
}
@end
/*!
Users of this class must override setValue:forKey: and if the
key is CPDisplayPatternValueBinding, set the appropriate value
for the control class. For example, CPTextField uses setObjectValue.
*/
@implementation CPValueWithPatternBinding : _CPPatternBinding
- (id)init
{
if (self = [super init])
{
_bindingKey = CPDisplayPatternValueBinding;
_patternPlaceholder = @"value";
}
return self;
}
@end
/*!
Users of this class must override setValue:forKey: and if the
key is CPDisplayPatternTitleBinding, set the appropriate value
for the control class. For example, CPBox uses setTitle.
*/
@implementation CPTitleWithPatternBinding : _CPPatternBinding
- (id)init
{
if (self = [super init])
{
_bindingKey = CPDisplayPatternTitleBinding;
_patternPlaceholder = @"title";
}
return self;
}
@end
@implementation _CPStateMarker : CPObject
{
CPString _name;
}
- (id)initWithName:(CPString)aName
{
if (self = [super init])
_name = aName
return self;
}
- (CPString)description
{
return "<" + _name + ">";
}
@end
// Keys in options dictionary
@@ -545,18 +831,23 @@ CPObservedKeyPathKey = @"CPObservedKeyPathKey";
CPOptionsKey = @"CPOptionsKey";
// special markers
CPMultipleValuesMarker = @"CPMultipleValuesMarker";
CPNoSelectionMarker = @"CPNoSelectionMarker";
CPNotApplicableMarker = @"CPNotApplicableMarker";
CPNullMarker = @"CPNullMarker";
CPNoSelectionMarker = [[_CPStateMarker alloc] initWithName:@"NO SELECTION MARKER"];
CPMultipleValuesMarker = [[_CPStateMarker alloc] initWithName:@"MULTIPLE VALUES MARKER"];
CPNotApplicableMarker = [[_CPStateMarker alloc] initWithName:@"NOT APPLICABLE MARKER"];
CPNullMarker = [[_CPStateMarker alloc] initWithName:@"NULL MARKER"];
// Binding name constants
CPAlignmentBinding = @"alignment";
CPArgumentBinding = @"argument";
CPContentArrayBinding = @"contentArray";
CPContentBinding = @"content";
CPContentObjectBinding = @"contentObject";
CPContentObjectsBinding = @"contentObjects";
CPContentValuesBinding = @"contentValues";
CPDisplayPatternTitleBinding = @"displayPatternTitle";
CPDisplayPatternValueBinding = @"displayPatternValue";
CPDoubleClickArgumentBinding = @"doubleClickArgument";
CPDoubleClickTargetBinding = @"doubleClickTarget";
CPEditableBinding = @"editable";
CPEnabledBinding = @"enabled";
CPFontBinding = @"font";
@@ -564,6 +855,8 @@ CPFontNameBinding = @"fontName";
CPFontBoldBinding = @"fontBold";
CPHiddenBinding = @"hidden";
CPFilterPredicateBinding = @"filterPredicate";
CPMaxValueBinding = @"maxValue";
CPMinValueBinding = @"minValue";
CPPredicateBinding = @"predicate";
CPSelectedIndexBinding = @"selectedIndex";
CPSelectedLabelBinding = @"selectedLabel";
@@ -573,6 +866,7 @@ CPSelectedTagBinding = @"selectedTag";
CPSelectedValueBinding = @"selectedValue";
CPSelectedValuesBinding = @"selectedValues";
CPSelectionIndexesBinding = @"selectionIndexes";
CPTargetBinding = @"target";
CPTextColorBinding = @"textColor";
CPTitleBinding = @"title";
CPToolTipBinding = @"toolTip";
@@ -581,7 +875,7 @@ CPValueURLBinding = @"valueURL";
CPValuePathBinding = @"valuePath";
CPDataBinding = @"data";
//Binding options constants
// Binding options constants
CPAllowsEditingMultipleValuesSelectionBindingOption = @"CPAllowsEditingMultipleValuesSelection";
CPAllowsNullArgumentBindingOption = @"CPAllowsNullArgument";
CPConditionallySetsEditableBindingOption = @"CPConditionallySetsEditable";
+25 -73
View File
@@ -21,6 +21,9 @@
*/
@import "CPControl.j"
@import "CPWindow_Constants.j"
@global CPApp
CPTickMarkBelow = 0;
CPTickMarkAbove = 1;
@@ -32,14 +35,6 @@ CPContinuousCapacityLevelIndicatorStyle = 1;
CPDiscreteCapacityLevelIndicatorStyle = 2;
CPRatingLevelIndicatorStyle = 3;
var _CPLevelIndicatorBezelColor = nil,
_CPLevelIndicatorSegmentEmptyColor = nil,
_CPLevelIndicatorSegmentNormalColor = nil,
_CPLevelIndicatorSegmentWarningColor = nil,
_CPLevelIndicatorSegmentCriticalColor = nil,
_CPLevelIndicatorSpacing = 1;
/*!
@ingroup appkit
@class CPLevelIndicator
@@ -62,57 +57,21 @@ var _CPLevelIndicatorBezelColor = nil,
BOOL _isTracking;
}
+ (void)initialize
+ (CPString)defaultThemeClass
{
if (self !== [CPLevelIndicator class])
return;
return "level-indicator";
}
var bundle = [CPBundle bundleForClass:CPLevelIndicator];
_CPLevelIndicatorBezelColor = [CPColor colorWithPatternImage:[[CPThreePartImage alloc] initWithImageSlices:
[
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPLevelIndicator/level-indicator-bezel-left.png"] size:CGSizeMake(3.0, 18.0)],
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPLevelIndicator/level-indicator-bezel-center.png"] size:CGSizeMake(1.0, 18.0)],
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPLevelIndicator/level-indicator-bezel-right.png"] size:CGSizeMake(3.0, 18.0)]
]
isVertical:NO
]];
_CPLevelIndicatorSegmentEmptyColor = [CPColor colorWithPatternImage:[[CPThreePartImage alloc] initWithImageSlices:
[
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPLevelIndicator/level-indicator-segment-empty-left.png"] size:CGSizeMake(3.0, 17.0)],
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPLevelIndicator/level-indicator-segment-empty-center.png"] size:CGSizeMake(1.0, 17.0)],
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPLevelIndicator/level-indicator-segment-empty-right.png"] size:CGSizeMake(3.0, 17.0)]
]
isVertical:NO
]];
_CPLevelIndicatorSegmentNormalColor = [CPColor colorWithPatternImage:[[CPThreePartImage alloc] initWithImageSlices:
[
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPLevelIndicator/level-indicator-segment-normal-left.png"] size:CGSizeMake(3.0, 17.0)],
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPLevelIndicator/level-indicator-segment-normal-center.png"] size:CGSizeMake(1.0, 17.0)],
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPLevelIndicator/level-indicator-segment-normal-right.png"] size:CGSizeMake(3.0, 17.0)]
]
isVertical:NO
]];
_CPLevelIndicatorSegmentWarningColor = [CPColor colorWithPatternImage:[[CPThreePartImage alloc] initWithImageSlices:
[
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPLevelIndicator/level-indicator-segment-warning-left.png"] size:CGSizeMake(3.0, 17.0)],
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPLevelIndicator/level-indicator-segment-warning-center.png"] size:CGSizeMake(1.0, 17.0)],
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPLevelIndicator/level-indicator-segment-warning-right.png"] size:CGSizeMake(3.0, 17.0)]
]
isVertical:NO
]];
_CPLevelIndicatorSegmentCriticalColor = [CPColor colorWithPatternImage:[[CPThreePartImage alloc] initWithImageSlices:
[
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPLevelIndicator/level-indicator-segment-critical-left.png"] size:CGSizeMake(3.0, 17.0)],
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPLevelIndicator/level-indicator-segment-critical-center.png"] size:CGSizeMake(1.0, 17.0)],
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPLevelIndicator/level-indicator-segment-critical-right.png"] size:CGSizeMake(3.0, 17.0)]
]
isVertical:NO
]];
+ (id)themeAttributes
{
return @{
@"bezel-color": [CPNull null],
@"color-empty": [CPNull null],
@"color-normal": [CPNull null],
@"color-warning": [CPNull null],
@"color-critical": [CPNull null],
@"spacing": 1.0,
};
}
- (id)initWithFrame:(CGRect)aFrame
@@ -125,37 +84,31 @@ var _CPLevelIndicatorBezelColor = nil,
_maxValue = 2;
_warningValue = 2;
_criticalValue = 2;
[self _init];
}
return self;
}
- (void)_init
{
}
- (void)layoutSubviews
{
var bezelView = [self layoutEphemeralSubviewNamed:"bezel"
positioned:CPWindowBelow
relativeToEphemeralSubviewNamed:nil];
// TODO Make themable.
[bezelView setBackgroundColor:_CPLevelIndicatorBezelColor];
[bezelView setBackgroundColor:[self valueForThemeAttribute:@"bezel-color"]];
var segmentCount = _maxValue - _minValue;
if (segmentCount <= 0)
return;
var filledColor = _CPLevelIndicatorSegmentNormalColor,
var filledColor = [self valueForThemeAttribute:@"color-normal"],
value = [self doubleValue];
if (value <= _criticalValue)
filledColor = _CPLevelIndicatorSegmentCriticalColor;
filledColor = [self valueForThemeAttribute:@"color-critical"];
else if (value <= _warningValue)
filledColor = _CPLevelIndicatorSegmentWarningColor;
filledColor = [self valueForThemeAttribute:@"color-warning"];
for (var i = 0; i < segmentCount; i++)
{
@@ -163,7 +116,7 @@ var _CPLevelIndicatorBezelColor = nil,
positioned:CPWindowAbove
relativeToEphemeralSubviewNamed:bezelView];
[segmentView setBackgroundColor:(_minValue + i) < value ? filledColor : _CPLevelIndicatorSegmentEmptyColor];
[segmentView setBackgroundColor:(_minValue + i) < value ? filledColor : [self valueForThemeAttribute:@"color-empty"]];
}
}
@@ -194,11 +147,12 @@ var _CPLevelIndicatorBezelColor = nil,
return _CGRectMakeZero();
var basicSegmentWidth = bounds.size.width / segmentCount,
segmentFrame = CGRectCreateCopy([self bounds]);
segmentFrame = CGRectCreateCopy([self bounds]),
spacing = [self valueForThemeAttribute:@"spacing"];
segmentFrame.origin.y = (_CGRectGetHeight(bounds) - bezelHeight) / 2.0;
segmentFrame.origin.x = FLOOR(segment * basicSegmentWidth);
segmentFrame.size.width = (segment == segmentCount - 1) ? bounds.size.width - segmentFrame.origin.x : FLOOR(((segment + 1) * basicSegmentWidth)) - FLOOR((segment * basicSegmentWidth)) - _CPLevelIndicatorSpacing;
segmentFrame.size.width = (segment == segmentCount - 1) ? bounds.size.width - segmentFrame.origin.x : FLOOR(((segment + 1) * basicSegmentWidth)) - FLOOR((segment * basicSegmentWidth)) - spacing;
segmentFrame.size.height = segmentHeight;
return segmentFrame;
@@ -226,7 +180,7 @@ var _CPLevelIndicatorBezelColor = nil,
return _isEditable;
}
- (CPView)hitTest:(CPPoint)aPoint
- (CPView)hitTest:(CGPoint)aPoint
{
// Don't swallow clicks when displayed in a table.
if (![self isEditable])
@@ -388,8 +342,6 @@ var CPLevelIndicatorStyleKey = "CPLevelIndicatorStyleKey",
_isEditable = [aCoder decodeBoolForKey:CPLevelIndicatorIsEditableKey];
[self _init];
[self setNeedsLayout];
[self setNeedsDisplay:YES];
}
+65 -27
View File
@@ -25,12 +25,10 @@
@import <Foundation/CPNotificationCenter.j>
@import <Foundation/CPString.j>
@import "_CPMenuManager.j"
@import "CPApplication.j"
@import "CPClipView.j"
@import "CPKeyValueBinding.j"
@import "CPMenuItem.j"
@import "CPPanel.j"
@global CPApp
CPMenuDidAddItemNotification = @"CPMenuDidAddItemNotification";
CPMenuDidChangeItemNotification = @"CPMenuDidChangeItemNotification";
@@ -38,12 +36,8 @@ CPMenuDidRemoveItemNotification = @"CPMenuDidRemoveItemNotification";
CPMenuDidEndTrackingNotification = @"CPMenuDidEndTrackingNotification";
var MENUBAR_HEIGHT = 28.0;
var _CPMenuBarVisible = NO,
_CPMenuBarTitle = @"",
_CPMenuBarIconImage = nil,
_CPMenuBarIconImageAlphaValue = 1.0,
_CPMenuBarAttributes = nil,
_CPMenuBarSharedWindow = nil;
@@ -83,7 +77,7 @@ var _CPMenuBarVisible = NO,
if (self !== [CPMenu class])
return;
[[self class] setMenuBarAttributes:[CPDictionary dictionary]];
[[self class] setMenuBarAttributes:@{}];
}
+ (BOOL)menuBarVisible
@@ -109,8 +103,8 @@ var _CPMenuBarVisible = NO,
[_CPMenuBarSharedWindow setMenu:[CPApp mainMenu]];
[_CPMenuBarSharedWindow setTitle:_CPMenuBarTitle];
[_CPMenuBarSharedWindow setIconImage:_CPMenuBarIconImage];
[_CPMenuBarSharedWindow setIconImageAlphaValue:_CPMenuBarIconImageAlphaValue];
[_CPMenuBarSharedWindow setIconImage:[[CPTheme defaultTheme] valueForAttributeWithName:@"menu-bar-icon-image" forClass:_CPMenuView]];
[_CPMenuBarSharedWindow setIconImageAlphaValue:[[CPTheme defaultTheme] valueForAttributeWithName:@"menu-bar-icon-image-alpha-value" forClass:_CPMenuView]];
[_CPMenuBarSharedWindow setColor:[_CPMenuBarAttributes objectForKey:@"CPMenuBarBackgroundColor"]];
[_CPMenuBarSharedWindow setTextColor:[_CPMenuBarAttributes objectForKey:@"CPMenuBarTextColor"]];
@@ -154,6 +148,13 @@ var _CPMenuBarVisible = NO,
return _CPMenuBarImage;
}
+ (void)_setOrRemoveMenuBarAttribute:(id)aValue forKey:(id)aKey
{
if (aValue === nil)
[_CPMenuBarAttributes removeObjectForKey:aKey];
else
[_CPMenuBarAttributes setObject:aValue forKey:aKey];
}
+ (void)setMenuBarAttributes:(CPDictionary)attributes
{
@@ -178,8 +179,8 @@ var _CPMenuBarVisible = NO,
else if (!textColor && !titleColor)
{
[_CPMenuBarAttributes setObject:[CPColor colorWithRed:0.051 green:0.2 blue:0.275 alpha:1.0] forKey:@"CPMenuBarTextColor"];
[_CPMenuBarAttributes setObject:[CPColor colorWithRed:0.051 green:0.2 blue:0.275 alpha:1.0] forKey:@"CPMenuBarTitleColor"];
[self _setOrRemoveMenuBarAttribute:[[CPTheme defaultTheme] valueForAttributeWithName:@"menu-bar-text-color" forClass:_CPMenuView] forKey:@"CPMenuBarTextColor"];
[self _setOrRemoveMenuBarAttribute:[[CPTheme defaultTheme] valueForAttributeWithName:@"menu-bar-title-color" forClass:_CPMenuView] forKey:@"CPMenuBarTitleColor"];
}
if (!textShadowColor && titleShadowColor)
@@ -190,18 +191,18 @@ var _CPMenuBarVisible = NO,
else if (!textShadowColor && !titleShadowColor)
{
[_CPMenuBarAttributes setObject:[CPColor whiteColor] forKey:@"CPMenuBarTextShadowColor"];
[_CPMenuBarAttributes setObject:[CPColor whiteColor] forKey:@"CPMenuBarTitleShadowColor"];
[self _setOrRemoveMenuBarAttribute:[[CPTheme defaultTheme] valueForAttributeWithName:@"menu-bar-text-shadow-color" forClass:_CPMenuView] forKey:@"CPMenuBarTextShadowColor"];
[self _setOrRemoveMenuBarAttribute:[[CPTheme defaultTheme] valueForAttributeWithName:@"menu-bar-title-shadow-color" forClass:_CPMenuView] forKey:@"CPMenuBarTitleShadowColor"];
}
if (!highlightColor)
[_CPMenuBarAttributes setObject:[CPColor colorWithCalibratedRed:94.0 / 255.0 green:130.0 / 255.0 blue:186.0 / 255.0 alpha:1.0] forKey:@"CPMenuBarHighlightColor"];
[self _setOrRemoveMenuBarAttribute:[[CPTheme defaultTheme] valueForAttributeWithName:@"menu-bar-highlight-color" forClass:_CPMenuView] forKey:@"CPMenuBarHighlightColor"];
if (!highlightTextColor)
[_CPMenuBarAttributes setObject:[CPColor whiteColor] forKey:@"CPMenuBarHighlightTextColor"];
[self _setOrRemoveMenuBarAttribute:[[CPTheme defaultTheme] valueForAttributeWithName:@"menu-bar-highlight-text-color" forClass:_CPMenuView] forKey:@"CPMenuBarHighlightTextColor"];
if (!highlightTextShadowColor)
[_CPMenuBarAttributes setObject:[CPColor blackColor] forKey:@"CPMenuBarHighlightTextShadowColor"];
[self _setOrRemoveMenuBarAttribute:[[CPTheme defaultTheme] valueForAttributeWithName:@"menu-bar-highlight-text-shadow-color" forClass:_CPMenuView] forKey:@"CPMenuBarHighlightTextShadowColor"];
if (_CPMenuBarSharedWindow)
{
@@ -230,14 +231,14 @@ var _CPMenuBarVisible = NO,
- (float)menuBarHeight
{
if (self === [CPApp mainMenu])
return MENUBAR_HEIGHT;
return [CPMenu menuBarHeight];
return 0.0;
}
+ (float)menuBarHeight
{
return MENUBAR_HEIGHT;
return [[CPTheme defaultTheme] valueForAttributeWithName:@"menu-bar-height" forClass:_CPMenuView];
}
// Creating a CPMenu Object
@@ -366,7 +367,12 @@ var _CPMenuBarVisible = NO,
*/
- (void)itemChanged:(CPMenuItem)aMenuItem
{
if ([aMenuItem menu] !== self)
/*
During cib unarchiving, menu items will have a reference to their menu,
but of course the items are still being unarchived and the menu's _items
have not yet been instantiated. In that case we will not do anything here.
*/
if ([aMenuItem menu] !== self || !_items)
return;
[aMenuItem setValue:[aMenuItem valueForKey:@"changeCount"] + 1 forKey:@"changeCount"];
@@ -374,7 +380,7 @@ var _CPMenuBarVisible = NO,
[[CPNotificationCenter defaultCenter]
postNotificationName:CPMenuDidChangeItemNotification
object:self
userInfo:[CPDictionary dictionaryWithObject:[_items indexOfObjectIdenticalTo:aMenuItem] forKey:@"CPMenuItemIndex"]];
userInfo:@{ @"CPMenuItemIndex": [_items indexOfObjectIdenticalTo:aMenuItem] }];
}
// Finding Menu Items
@@ -607,8 +613,9 @@ var _CPMenuBarVisible = NO,
/*!
Enables or disables the receivers menu items.
If the target does not implement the menu item's action method the item is disabled.
If the target responsds to selector validateMenuItem: or validateUserInterfaceItem: (in that order) the return value is used.
If the item has no target, an action binding is checked. If the target does not implement
the menu item's action method or the binding's selector, the item is disabled.
If the target responds to selector validateMenuItem: or validateUserInterfaceItem: (in that order) the return value is used.
*/
- (void)update
{
@@ -616,6 +623,7 @@ var _CPMenuBarVisible = NO,
return;
var items = [self itemArray];
for (var i = 0; i < [items count]; i++)
{
var item = [items objectAtIndex:i];
@@ -625,7 +633,31 @@ var _CPMenuBarVisible = NO,
var validator = [CPApp targetForAction:[item action] to:[item target] from:item];
if (!validator || ![validator respondsToSelector:[item action]])
if (!validator)
{
// If targetForAction: returns nil, it could be that there is no action.
// If there is an action and nil is returned, no valid target could be found.
if ([item action] || [item target])
[item setEnabled:NO];
else
{
// Check to see if there is a target binding with an invalid selector
var info = [CPBinder infoForBinding:CPTargetBinding forObject:item];
if (info)
{
var object = [info objectForKey:CPObservedObjectKey],
keyPath = [info objectForKey:CPObservedKeyPathKey],
options = [info objectForKey:CPOptionsKey],
target = [object valueForKeyPath:keyPath],
selector = [options valueForKey:CPSelectorNameBindingOption];
if (target && selector && ![target respondsToSelector:CPSelectorFromString(selector)])
[item setEnabled:NO];
}
}
}
else if (![validator respondsToSelector:[item action]])
[item setEnabled:NO];
else if ([validator respondsToSelector:@selector(validateMenuItem:)])
[item setEnabled:[validator validateMenuItem:item]];
@@ -675,7 +707,13 @@ var _CPMenuBarVisible = NO,
// highlightedItem is always enabled. Do there exist edge cases: disabling on closing a menu,
// etc.? Requires further investigation and tests.
if (highlightedItem && [highlightedItem isEnabled])
{
// Perform any action binding
var binding = [CPBinder getBinding:CPTargetBinding forObject:highlightedItem];
[binding invokeAction];
[CPApp sendAction:[highlightedItem action] to:[highlightedItem target] from:highlightedItem];
}
}
//
@@ -1110,7 +1148,7 @@ var _CPMenuBarVisible = NO,
[[CPNotificationCenter defaultCenter]
postNotificationName:CPMenuDidAddItemNotification
object:self
userInfo:[CPDictionary dictionaryWithObject:anIndex forKey:@"CPMenuItemIndex"]];
userInfo:@{ @"CPMenuItemIndex": anIndex }];
}
- (void)removeObjectFromItemsAtIndex:(CPUInteger)anIndex
@@ -1124,7 +1162,7 @@ var _CPMenuBarVisible = NO,
[[CPNotificationCenter defaultCenter]
postNotificationName:CPMenuDidRemoveItemNotification
object:self
userInfo:[CPDictionary dictionaryWithObject:anIndex forKey:@"CPMenuItemIndex"]];
userInfo:@{ @"CPMenuItemIndex": anIndex }];
}
@end
+39 -129
View File
@@ -1,14 +1,33 @@
/*
* _CPMenuBarWindow.j
* AppKit
*
* Created by Francisco Tolmasky.
* Copyright 2009, 280 North, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@import "CPPanel.j"
@import "_CPMenuWindow.j"
@import "_CPMenuManager.j"
@class _CPMenuView
var MENUBAR_HEIGHT = 28.0,
MENUBAR_MARGIN = 10.0,
MENUBAR_LEFT_MARGIN = 10.0,
MENUBAR_RIGHT_MARGIN = 10.0;
var _CPMenuBarWindowBackgroundColor = nil,
_CPMenuBarWindowFont = nil;
@global CPMenuDidAddItemNotification
@global CPMenuDidChangeItemNotification
@global CPMenuDidRemoveItemNotification
@implementation _CPMenuBarWindow : CPPanel
{
@@ -32,19 +51,9 @@ var _CPMenuBarWindowBackgroundColor = nil,
CPColor _highlightTextShadowColor;
}
+ (void)initialize
{
if (self !== [_CPMenuBarWindow class])
return;
var bundle = [CPBundle bundleForClass:self];
_CPMenuBarWindowFont = [CPFont boldSystemFontOfSize:[CPFont systemFontSize]];
}
+ (CPFont)font
{
return _CPMenuBarWindowFont;
return [[CPTheme defaultTheme] valueForAttributeWithName:@"menu-bar-window-font" forClass:_CPMenuView];
}
- (id)init
@@ -52,7 +61,7 @@ var _CPMenuBarWindowBackgroundColor = nil,
// This only shows up in browser land, so don't bother calculating metrics in desktop.
var contentRect = [[CPPlatformWindow primaryPlatformWindow] contentBounds];
contentRect.size.height = MENUBAR_HEIGHT;
contentRect.size.height = [[CPTheme defaultTheme] valueForAttributeWithName:@"menu-bar-window-height" forClass:_CPMenuView];
self = [super initWithContentRect:contentRect styleMask:CPBorderlessWindowMask];
@@ -119,12 +128,7 @@ var _CPMenuBarWindowBackgroundColor = nil,
- (void)setColor:(CPColor)aColor
{
if (!aColor)
{
if (!_CPMenuBarWindowBackgroundColor)
_CPMenuBarWindowBackgroundColor = [CPColor colorWithPatternImage:[[CPImage alloc] initWithContentsOfFile:[[CPBundle bundleForClass:[_CPMenuBarWindow class]] pathForResource:@"_CPMenuBarWindow/_CPMenuBarWindowBackground.png"] size:CGSizeMake(1.0, 28.0)]];
[[self contentView] setBackgroundColor:_CPMenuBarWindowBackgroundColor];
}
[[self contentView] setBackgroundColor:[[CPTheme defaultTheme] valueForAttributeWithName:@"menu-bar-window-background-color" forClass:_CPMenuView]];
else
[[self contentView] setBackgroundColor:aColor];
}
@@ -316,6 +320,11 @@ var _CPMenuBarWindowBackgroundColor = nil,
[self tile];
}
- (BOOL)acceptsFirstMouse:(CPEvent)anEvent
{
return YES;
}
- (void)mouseDown:(CPEvent)anEvent
{
var constraintRect = CGRectInset([[self platformWindow] visibleFrame], 5.0, 0.0);
@@ -344,7 +353,7 @@ var _CPMenuBarWindowBackgroundColor = nil,
index = 0,
count = items.length,
x = MENUBAR_LEFT_MARGIN,
x = [[CPTheme defaultTheme] valueForAttributeWithName:@"menu-bar-window-left-margin" forClass:_CPMenuView],
y = 0.0,
isLeftAligned = YES;
@@ -354,7 +363,7 @@ var _CPMenuBarWindowBackgroundColor = nil,
if ([item isSeparatorItem])
{
x = CGRectGetWidth([self frame]) - MENUBAR_RIGHT_MARGIN;
x = CGRectGetWidth([self frame]) - [[CPTheme defaultTheme] valueForAttributeWithName:@"menu-bar-window-right-margin" forClass:_CPMenuView];
isLeftAligned = NO;
continue;
@@ -368,13 +377,13 @@ var _CPMenuBarWindowBackgroundColor = nil,
if (isLeftAligned)
{
[menuItemView setFrame:CGRectMake(x, 0.0, CGRectGetWidth(frame), MENUBAR_HEIGHT)];
[menuItemView setFrame:CGRectMake(x, 0.0, CGRectGetWidth(frame), [[CPTheme defaultTheme] valueForAttributeWithName:@"menu-bar-window-height" forClass:_CPMenuView])];
x += CGRectGetWidth([menuItemView frame]);
}
else
{
[menuItemView setFrame:CGRectMake(x - CGRectGetWidth(frame), 0.0, CGRectGetWidth(frame), MENUBAR_HEIGHT)];
[menuItemView setFrame:CGRectMake(x - CGRectGetWidth(frame), 0.0, CGRectGetWidth(frame), [[CPTheme defaultTheme] valueForAttributeWithName:@"menu-bar-window-height" forClass:_CPMenuView])];
x = CGRectGetMinX([menuItemView frame]);
}
@@ -452,102 +461,3 @@ var _CPMenuBarWindowBackgroundColor = nil,
}
@end
@implementation _CPMenuBarView : _CPMenuView
{
}
- (CGRect)rectForItemAtIndex:(int)anIndex
{
return [_menuItemViews[anIndex === CPNotFound ? 0 : anIndex] frame];
}
- (int)itemIndexAtPoint:(CGPoint)aPoint
{
var bounds = [self bounds];
if (!CGRectContainsPoint(bounds, aPoint))
return CPNotFound;
var x = aPoint.x,
low = 0,
high = _visibleMenuItemInfos.length - 1;
while (low <= high)
{
var middle = FLOOR(low + (high - low) / 2),
info = _visibleMenuItemInfos[middle],
frame = [info.view frame];
if (x < CGRectGetMinX(frame))
high = middle - 1;
else if (x > CGRectGetMaxX(frame))
low = middle + 1;
else
return info.index;
}
return CPNotFound;
}
- (void)tile
{
var items = [_menu itemArray],
index = 0,
count = items.length,
x = MENUBAR_LEFT_MARGIN,
y = 0.0,
isLeftAligned = YES;
for (; index < count; ++index)
{
var item = items[index];
if ([item isSeparatorItem])
{
x = CGRectGetWidth([self frame]) - MENUBAR_RIGHT_MARGIN;
isLeftAligned = NO;
continue;
}
if ([item isHidden])
continue;
var menuItemView = [item _menuItemView],
frame = [menuItemView frame];
if (isLeftAligned)
{
[menuItemView setFrameOrigin:CGPointMake(x, (MENUBAR_HEIGHT - 1.0 - CGRectGetHeight(frame)) / 2.0)];
x += CGRectGetWidth([menuItemView frame]) + MENUBAR_MARGIN;
}
else
{
[menuItemView setFrameOrigin:CGPointMake(x - CGRectGetWidth(frame), (MENUBAR_HEIGHT - 1.0 - CGRectGetHeight(frame)) / 2.0)];
x = CGRectGetMinX([menuItemView frame]) - MENUBAR_MARGIN;
}
}
var bounds = [[self contentView] bounds],
titleFrame = [_titleField frame];
if ([_iconImageView isHidden])
[_titleField setFrameOrigin:CGPointMake((CGRectGetWidth(bounds) - CGRectGetWidth(titleFrame)) / 2.0, (CGRectGetHeight(bounds) - CGRectGetHeight(titleFrame)) / 2.0)];
else
{
var iconFrame = [_iconImageView frame],
iconWidth = CGRectGetWidth(iconFrame),
totalWidth = iconWidth + CGRectGetWidth(titleFrame);
[_iconImageView setFrameOrigin:CGPointMake((CGRectGetWidth(bounds) - totalWidth) / 2.0, (CGRectGetHeight(bounds) - CGRectGetHeight(iconFrame)) / 2.0)];
[_titleField setFrameOrigin:CGPointMake((CGRectGetWidth(bounds) - totalWidth) / 2.0 + iconWidth, (CGRectGetHeight(bounds) - CGRectGetHeight(titleFrame)) / 2.0)];
}
}
@end
+87 -18
View File
@@ -1,11 +1,45 @@
@import <Foundation/CPObject.j>
/*
* _CPMenuManager.j
* AppKit
*
* Created by Francisco Tolmasky.
* Copyright 2009, 280 North, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@import <Foundation/CPObject.j>
@import <Foundation/CPNotificationCenter.j>
@import "CPEvent.j"
@import "CPKeyBinding.j"
@class CPWindow
@class _CPMenuWindow
@global CPApp
@global CPMenuDidEndTrackingNotification
@global _CPMenuWindowMenuBarBackgroundStyle
@global _CPMenuWindowPopUpBackgroundStyle
_CPMenuManagerScrollingStateUp = -1;
_CPMenuManagerScrollingStateDown = 1;
_CPMenuManagerScrollingStateNone = 0;
var STICKY_TIME_INTERVAL = 0.5,
var STICKY_TIME_INTERVAL = 0.4,
SharedMenuManager = nil;
@implementation _CPMenuManager: CPObject
@@ -26,6 +60,8 @@ var STICKY_TIME_INTERVAL = 0.5,
CPMenuItem _previousActiveItem;
int _showTimerID;
int _menuBarButtonItemIndex;
}
+ (_CPMenuManager)sharedMenuManager
@@ -85,7 +121,7 @@ var STICKY_TIME_INTERVAL = 0.5,
activeItem = activeItemIndex !== CPNotFound ? [menu itemAtIndex:activeItemIndex] : nil;
_menuBarButtonItemIndex = activeItemIndex;
_menuBarButtonMenuContainer = aMenuContainer;
// _menuBarButtonMenuContainer = aMenuContainer;
if ([activeItem _isMenuBarButton])
return [self trackMenuBarButtonEvent:anEvent];
@@ -96,6 +132,11 @@ var STICKY_TIME_INTERVAL = 0.5,
[self trackEvent:anEvent];
}
- (void)_trackAgain
{
[CPApp setTarget:self selector:@selector(trackEvent:) forNextEventMatchingMask:CPKeyDownMask | CPPeriodicMask | CPMouseMovedMask | CPLeftMouseDraggedMask | CPLeftMouseDownMask | CPLeftMouseUpMask | CPRightMouseUpMask | CPAppKitDefinedMask | CPScrollWheelMask untilDate:nil inMode:nil dequeue:YES];
}
- (void)trackEvent:(CPEvent)anEvent
{
var type = [anEvent type],
@@ -105,8 +146,6 @@ var STICKY_TIME_INTERVAL = 0.5,
if (type === CPAppKitDefined)
return [self completeTracking];
[CPApp setTarget:self selector:@selector(trackEvent:) forNextEventMatchingMask:CPKeyDownMask | CPPeriodicMask | CPMouseMovedMask | CPLeftMouseDraggedMask | CPLeftMouseUpMask | CPRightMouseUpMask | CPAppKitDefinedMask | CPScrollWheelMask untilDate:nil inMode:nil dequeue:YES];
if (type === CPKeyDown)
{
var menu = trackingMenu,
@@ -122,23 +161,18 @@ var STICKY_TIME_INTERVAL = 0.5,
if ([menu numberOfItems])
[self interpretKeyEvent:anEvent forMenu:menu];
[self _trackAgain];
return;
}
if (_keyBuffer)
{
if (([anEvent timestamp] - _startTime) > (STICKY_TIME_INTERVAL + [activeMenu numberOfItems] / 2))
[self selectNextItemBeginningWith:_keyBuffer inMenu:menu clearBuffer:YES];
if (type === CPPeriodic)
return;
}
// Periodic events don't have a valid location.
var globalLocation = type === CPPeriodic ? _lastGlobalLocation : [anEvent globalLocation];
if (!globalLocation)
{
[self _trackAgain];
return;
}
// Find which menu window the mouse is currently on top of
var activeMenuContainer = [self menuContainerForPoint:globalLocation],
@@ -149,6 +183,37 @@ var STICKY_TIME_INTERVAL = 0.5,
activeItemIndex = activeMenuContainer ? [activeMenuContainer itemIndexAtPoint:menuLocation] : CPNotFound,
activeItem = activeItemIndex !== CPNotFound ? [activeMenu itemAtIndex:activeItemIndex] : nil;
// Click outside the menu structure?
if (type === CPLeftMouseDown && (!activeMenuContainer || !CGRectContainsPoint([activeMenuContainer globalFrame], globalLocation)))
{
[self completeTracking];
/*
You can close and interact with a control in a single click. E.g. you can have a menu open,
click on a button outside of it and have the menu immediately close and the button activate,
without having to click once to close the menu and once to activate the button.
Since we normally dequeue the event after tracking it, we'll have to put it back on the stack
in this special case. Note that it's important the event is executed /right now/, since certain
controls such as HTML upload buttons need a native click event at the top of the stack trace
to activate - it's not something we can fake later.
*/
[CPApp sendEvent:anEvent];
return;
}
[self _trackAgain];
if (_keyBuffer)
{
if (([anEvent timestamp] - _startTime) > (STICKY_TIME_INTERVAL + [activeMenu numberOfItems] / 2))
[self selectNextItemBeginningWith:_keyBuffer inMenu:menu clearBuffer:YES];
if (type === CPPeriodic)
return;
}
// unhighlight when mouse is moved off the menu
if (_lastGlobalLocation && CGRectContainsPoint([activeMenuContainer globalFrame], _lastGlobalLocation)
&& !CGRectContainsPoint([activeMenuContainer globalFrame], globalLocation))
@@ -216,7 +281,7 @@ var STICKY_TIME_INTERVAL = 0.5,
_lastMouseOverMenuView = nil;
}
if (activeItemIndex != CPNotFound)
if (activeItemIndex !== CPNotFound)
[activeMenu _highlightItemAtIndex:activeItemIndex];
if (type === CPMouseMoved || type === CPLeftMouseDragged || type === CPLeftMouseDown || type === CPPeriodic)
@@ -556,7 +621,7 @@ var STICKY_TIME_INTERVAL = 0.5,
return;
}
next = current + (last - first);
var next = current + (last - first);
if (next < [menu numberOfItems])
[menu _highlightItemAtIndex:next];
@@ -584,7 +649,7 @@ var STICKY_TIME_INTERVAL = 0.5,
return;
}
next = current - (last - first);
var next = current - (last - first);
if (next < 0)
[menu _highlightItemAtIndex:0];
@@ -665,6 +730,8 @@ var STICKY_TIME_INTERVAL = 0.5,
if ([item isSeparatorItem] || [item isHidden] || ![item isEnabled])
[self moveDown:menu];
}
else if (menu == [CPApp mainMenu])
[menu _highlightItemAtIndex:0];
}
- (void)moveUp:(CPMenu)menu
@@ -673,10 +740,12 @@ var STICKY_TIME_INTERVAL = 0.5,
if (index < 0)
{
if (index != CPNotFound)
if (index != CPNotFound || menu == [CPApp mainMenu])
[menu _highlightItemAtIndex:[menu numberOfItems] - 1];
return;
}
[menu _highlightItemAtIndex:index];
var item = [menu highlightedItem];
+93 -74
View File
@@ -1,5 +1,29 @@
@import "CPWindow.j"
/*
* _CPMenuWindow.j
* AppKit
*
* Created by Francisco Tolmasky.
* Copyright 2009, 280 North, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@import "CPClipView.j"
@import "CPImageView.j"
@import "CPWindow.j"
@import "_CPMenuManager.j"
var _CPMenuWindowPool = [],
_CPMenuWindowPoolCapacity = 5,
@@ -10,15 +34,6 @@ _CPMenuWindowMenuBarBackgroundStyle = 0;
_CPMenuWindowPopUpBackgroundStyle = 1;
_CPMenuWindowAttachedMenuBackgroundStyle = 2;
var STICKY_TIME_INTERVAL = 500,
TOP_MARGIN = 5.0,
LEFT_MARGIN = 1.0,
RIGHT_MARGIN = 1.0,
BOTTOM_MARGIN = 5.0,
SCROLL_INDICATOR_HEIGHT = 16.0;
/*
@ignore
*/
@@ -63,17 +78,6 @@ var STICKY_TIME_INTERVAL = 500,
_CPMenuWindowPool.push(aMenuWindow);
}
+ (void)initialize
{
if (self !== [_CPMenuWindow class])
return;
var bundle = [CPBundle bundleForClass:self];
_CPMenuWindowMoreAboveImage = [[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"_CPMenuWindow/_CPMenuWindowMoreAbove.png"] size:CGSizeMake(38.0, 18.0)];
_CPMenuWindowMoreBelowImage = [[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"_CPMenuWindow/_CPMenuWindowMoreBelow.png"] size:CGSizeMake(38.0, 18.0)];
}
- (id)initWithContentRect:(CGRect)aRect styleMask:(unsigned)aStyleMask
{
_constraintRect = _CGRectMakeZero();
@@ -92,22 +96,22 @@ var STICKY_TIME_INTERVAL = 500,
_menuView = [[_CPMenuView alloc] initWithFrame:CGRectMakeZero()];
_menuClipView = [[CPClipView alloc] initWithFrame:CGRectMake(LEFT_MARGIN, TOP_MARGIN, 0.0, 0.0)];
_menuClipView = [[CPClipView alloc] initWithFrame:CGRectMake([_menuView valueForThemeAttribute:@"menu-window-margin-inset"].left, [_menuView valueForThemeAttribute:@"menu-window-margin-inset"].top, 0.0, 0.0)];
[_menuClipView setDocumentView:_menuView];
[contentView addSubview:_menuClipView];
_moreAboveView = [[CPImageView alloc] initWithFrame:CGRectMakeZero()];
[_moreAboveView setImage:_CPMenuWindowMoreAboveImage];
[_moreAboveView setFrameSize:[_CPMenuWindowMoreAboveImage size]];
[_moreAboveView setImage:[_menuView valueForThemeAttribute:@"menu-window-more-above-image"]];
[_moreAboveView setFrameSize:[[_menuView valueForThemeAttribute:@"menu-window-more-above-image"] size]];
[contentView addSubview:_moreAboveView];
_moreBelowView = [[CPImageView alloc] initWithFrame:CGRectMakeZero()];
[_moreBelowView setImage:_CPMenuWindowMoreBelowImage];
[_moreBelowView setFrameSize:[_CPMenuWindowMoreBelowImage size]];
[_moreBelowView setImage:[_menuView valueForThemeAttribute:@"menu-window-more-below-image"]];
[_moreBelowView setFrameSize:[[_menuView valueForThemeAttribute:@"menu-window-more-below-image"] size]];
[contentView addSubview:_moreBelowView];
}
@@ -117,7 +121,7 @@ var STICKY_TIME_INTERVAL = 500,
+ (float)_standardLeftMargin
{
return LEFT_MARGIN;
return [[CPTheme defaultTheme] valueForAttributeWithName:@"menu-window-margin-inset" forClass:_CPMenuView].left;
}
- (void)setFont:(CPFont)aFont
@@ -139,36 +143,10 @@ var STICKY_TIME_INTERVAL = 500,
var bundle = [CPBundle bundleForClass:[self class]];
if (aBackgroundStyle == _CPMenuWindowPopUpBackgroundStyle)
color = [CPColor colorWithPatternImage:[[CPNinePartImage alloc] initWithImageSlices:
[
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"_CPMenuWindow/_CPMenuWindowRounded0.png"] size:CGSizeMake(4.0, 4.0)],
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"_CPMenuWindow/_CPMenuWindow1.png"] size:CGSizeMake(1.0, 4.0)],
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"_CPMenuWindow/_CPMenuWindowRounded2.png"] size:CGSizeMake(4.0, 4.0)],
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"_CPMenuWindow/_CPMenuWindow3.png"] size:CGSizeMake(4.0, 1.0)],
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"_CPMenuWindow/_CPMenuWindow4.png"] size:CGSizeMake(1.0, 1.0)],
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"_CPMenuWindow/_CPMenuWindow5.png"] size:CGSizeMake(4.0, 1.0)],
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"_CPMenuWindow/_CPMenuWindowRounded6.png"] size:CGSizeMake(4.0, 4.0)],
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"_CPMenuWindow/_CPMenuWindow7.png"] size:CGSizeMake(1.0, 4.0)],
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"_CPMenuWindow/_CPMenuWindowRounded8.png"] size:CGSizeMake(4.0, 4.0)]
]]];
color = [[CPTheme defaultTheme] valueForAttributeWithName:@"menu-window-pop-up-background-style-color" forClass:_CPMenuView];
else if (aBackgroundStyle == _CPMenuWindowMenuBarBackgroundStyle)
color = [CPColor colorWithPatternImage:[[CPNinePartImage alloc] initWithImageSlices:
[
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"_CPMenuWindow/_CPMenuWindow3.png"] size:CGSizeMake(4.0, 0.0)],
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"_CPMenuWindow/_CPMenuWindow4.png"] size:CGSizeMake(1.0, 0.0)],
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"_CPMenuWindow/_CPMenuWindow5.png"] size:CGSizeMake(4.0, 0.0)],
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"_CPMenuWindow/_CPMenuWindow3.png"] size:CGSizeMake(4.0, 1.0)],
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"_CPMenuWindow/_CPMenuWindow4.png"] size:CGSizeMake(1.0, 1.0)],
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"_CPMenuWindow/_CPMenuWindow5.png"] size:CGSizeMake(4.0, 1.0)],
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"_CPMenuWindow/_CPMenuWindowRounded6.png"] size:CGSizeMake(4.0, 4.0)],
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"_CPMenuWindow/_CPMenuWindow7.png"] size:CGSizeMake(1.0, 4.0)],
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"_CPMenuWindow/_CPMenuWindowRounded8.png"] size:CGSizeMake(4.0, 4.0)]
]]];
color = [[CPTheme defaultTheme] valueForAttributeWithName:@"menu-window-menu-bar-background-style-color" forClass:_CPMenuView];
_CPMenuWindowBackgroundColors[aBackgroundStyle] = color;
}
@@ -186,12 +164,13 @@ var STICKY_TIME_INTERVAL = 500,
[aMenu _setMenuWindow:self];
[_menuView setMenu:aMenu];
var menuViewSize = [_menuView frame].size;
var menuViewSize = [_menuView frame].size,
marginInset = [_menuView valueForThemeAttribute:@"menu-window-margin-inset"];
[self setFrameSize:CGSizeMake(LEFT_MARGIN + menuViewSize.width + RIGHT_MARGIN, TOP_MARGIN + menuViewSize.height + BOTTOM_MARGIN)];
[self setFrameSize:CGSizeMake(marginInset.left + menuViewSize.width + marginInset.right, marginInset.top + menuViewSize.height + marginInset.bottom)];
[_menuView scrollPoint:CGPointMake(0.0, 0.0)];
[_menuClipView setFrame:CGRectMake(LEFT_MARGIN, TOP_MARGIN, menuViewSize.width, menuViewSize.height)];
[_menuClipView setFrame:CGRectMake(marginInset.left, marginInset.top, menuViewSize.width, menuViewSize.height)];
}
- (void)setMinWidth:(float)aWidth
@@ -249,7 +228,9 @@ var STICKY_TIME_INTERVAL = 500,
// FIXME: This gets called far too often.
_unconstrainedFrame = _CGRectMakeCopy(aFrame);
var constrainedFrame = CGRectIntersection(_unconstrainedFrame, _constraintRect);
var constrainedFrame = CGRectIntersection(_unconstrainedFrame, _constraintRect),
marginInset = [_menuView valueForThemeAttribute:@"menu-window-margin-inset"],
scrollIndicatorHeight = [_menuView valueForThemeAttribute:@"menu-window-scroll-indicator-height"];
// We don't want to simply intersect the visible frame and the unconstrained frame.
// We should be allowing as much of the width to fit as possible (pushing back and forward).
@@ -268,41 +249,41 @@ var STICKY_TIME_INTERVAL = 500,
[super setFrame:constrainedFrame display:shouldDisplay animate:shouldAnimate];
// This needs to happen before changing the frame.
var menuViewOrigin = CGPointMake(CGRectGetMinX(aFrame) + LEFT_MARGIN, CGRectGetMinY(aFrame) + TOP_MARGIN),
moreAbove = menuViewOrigin.y < CGRectGetMinY(constrainedFrame) + TOP_MARGIN,
moreBelow = menuViewOrigin.y + CGRectGetHeight([_menuView frame]) > CGRectGetMaxY(constrainedFrame) - BOTTOM_MARGIN,
var menuViewOrigin = CGPointMake(CGRectGetMinX(aFrame) + marginInset.left, CGRectGetMinY(aFrame) + marginInset.top),
moreAbove = menuViewOrigin.y < CGRectGetMinY(constrainedFrame) + marginInset.top,
moreBelow = menuViewOrigin.y + CGRectGetHeight([_menuView frame]) > CGRectGetMaxY(constrainedFrame) - marginInset.bottom,
topMargin = TOP_MARGIN,
bottomMargin = BOTTOM_MARGIN,
topMargin = marginInset.top,
bottomMargin = marginInset.bottom,
contentView = [self contentView],
bounds = [contentView bounds];
if (moreAbove)
{
topMargin += SCROLL_INDICATOR_HEIGHT;
topMargin += scrollIndicatorHeight;
var frame = [_moreAboveView frame];
[_moreAboveView setFrameOrigin:CGPointMake((CGRectGetWidth(bounds) - CGRectGetWidth(frame)) / 2.0, (TOP_MARGIN + SCROLL_INDICATOR_HEIGHT - CGRectGetHeight(frame)) / 2.0)];
[_moreAboveView setFrameOrigin:CGPointMake((CGRectGetWidth(bounds) - CGRectGetWidth(frame)) / 2.0, (marginInset.top + scrollIndicatorHeight - CGRectGetHeight(frame)) / 2.0)];
}
[_moreAboveView setHidden:!moreAbove];
if (moreBelow)
{
bottomMargin += SCROLL_INDICATOR_HEIGHT;
bottomMargin += scrollIndicatorHeight;
[_moreBelowView setFrameOrigin:CGPointMake((CGRectGetWidth(bounds) - CGRectGetWidth([_moreBelowView frame])) / 2.0, CGRectGetHeight(bounds) - SCROLL_INDICATOR_HEIGHT - BOTTOM_MARGIN)];
[_moreBelowView setFrameOrigin:CGPointMake((CGRectGetWidth(bounds) - CGRectGetWidth([_moreBelowView frame])) / 2.0, CGRectGetHeight(bounds) - scrollIndicatorHeight - marginInset.bottom)];
}
[_moreBelowView setHidden:!moreBelow];
var clipFrame = CGRectMakeZero();
clipFrame.origin.x = LEFT_MARGIN;
clipFrame.origin.x = marginInset.left;
clipFrame.origin.y = topMargin;
clipFrame.size.width = CGRectGetWidth(constrainedFrame) - LEFT_MARGIN - RIGHT_MARGIN;
clipFrame.size.width = CGRectGetWidth(constrainedFrame) - marginInset.left - marginInset.right;
clipFrame.size.height = CGRectGetHeight(constrainedFrame) - topMargin - bottomMargin;
[_menuClipView setFrame:clipFrame];
@@ -398,15 +379,15 @@ var STICKY_TIME_INTERVAL = 500,
- (_CPManagerScrollingState)scrollingStateForPoint:(CGPoint)aGlobalLocation
{
var frame = [self frame];
if (!CPRectContainsPoint(frame,aGlobalLocation) || ![self canScroll])
if (!CGRectContainsPoint(frame,aGlobalLocation) || ![self canScroll])
return _CPMenuManagerScrollingStateNone;
// If we're at or above of the top scroll indicator...
if (aGlobalLocation.y < CGRectGetMinY(frame) + TOP_MARGIN + SCROLL_INDICATOR_HEIGHT && ![_moreAboveView isHidden])
if (aGlobalLocation.y < CGRectGetMinY(frame) + [_menuView valueForThemeAttribute:@"menu-window-margin-inset"].top + [_menuView valueForThemeAttribute:@"menu-window-scroll-indicator-height"] && ![_moreAboveView isHidden])
return _CPMenuManagerScrollingStateUp;
// If we're at or below the bottom scroll indicator...
if (aGlobalLocation.y > CGRectGetMaxY(frame) - BOTTOM_MARGIN - SCROLL_INDICATOR_HEIGHT && ![_moreBelowView isHidden])
if (aGlobalLocation.y > CGRectGetMaxY(frame) - [_menuView valueForThemeAttribute:@"menu-window-margin-inset"].bottom - [_menuView valueForThemeAttribute:@"menu-window-scroll-indicator-height"] && ![_moreBelowView isHidden])
return _CPMenuManagerScrollingStateDown;
return _CPMenuManagerScrollingStateNone;
@@ -414,7 +395,7 @@ var STICKY_TIME_INTERVAL = 500,
- (float)deltaYForItemAtIndex:(int)anIndex
{
return TOP_MARGIN + CGRectGetMinY([_menuView rectForItemAtIndex:anIndex]);
return [_menuView valueForThemeAttribute:@"menu-window-margin-inset"].top + CGRectGetMinY([_menuView rectForItemAtIndex:anIndex]);
}
- (CGPoint)rectForItemAtIndex:(int)anIndex
@@ -445,6 +426,44 @@ var STICKY_TIME_INTERVAL = 500,
CPFont _font @accessors(property=font);
}
+ (CPString)defaultThemeClass
{
return "menu-view";
}
+ (id)themeAttributes
{
return @{
@"menu-window-more-above-image": [CPNull null],
@"menu-window-more-below-image": [CPNull null],
@"menu-window-pop-up-background-style-color": [CPNull null],
@"menu-window-menu-bar-background-style-color": [CPNull null],
@"menu-window-margin-inset": CGInsetMake(5.0, 1.0, 1.0, 5.0),
@"menu-window-scroll-indicator-height": 16.0,
@"menu-bar-window-background-color": [CPNull null],
@"menu-bar-window-background-selected-color": [CPNull null],
@"menu-bar-window-font": [CPNull null],
@"menu-bar-window-height": 30.0,
@"menu-bar-window-margin": 10.0,
@"menu-bar-window-left-margin": 10.0,
@"menu-bar-window-right-margin": 10.0,
@"menu-bar-text-color": [CPNull null],
@"menu-bar-title-color": [CPNull null],
@"menu-bar-text-shadow-color": [CPNull null],
@"menu-bar-title-shadow-color": [CPNull null],
@"menu-bar-highlight-color": [CPNull null],
@"menu-bar-highlight-text-color": [CPNull null],
@"menu-bar-highlight-text-shadow-color": [CPNull null],
@"menu-bar-height": 28.0,
@"menu-bar-icon-image": [CPNull null],
@"menu-bar-icon-image-alpha-value": 1.0,
@"menu-general-icon-new": [CPNull null],
@"menu-general-icon-save": [CPNull null],
@"menu-general-icon-open": [CPNull null],
};
}
- (unsigned)numberOfUnhiddenItems
{
return _visibleMenuItemInfos.length;
+33 -19
View File
@@ -25,29 +25,33 @@
@import <Foundation/CPString.j>
@import "CPImage.j"
@import "CPMenu.j"
@import "CPText.j"
@import "CPView.j"
@import "_CPMenuItemView.j"
@class CPMenu
var CPMenuItemStringRepresentationDictionary = [CPDictionary dictionary];
[CPMenuItemStringRepresentationDictionary setObject:"\u238B" forKey:CPEscapeFunctionKey];
[CPMenuItemStringRepresentationDictionary setObject:"\u21E5" forKey:CPTabCharacter];
[CPMenuItemStringRepresentationDictionary setObject:"\u21E4" forKey:CPBackTabCharacter];
[CPMenuItemStringRepresentationDictionary setObject:"\u2423" forKey:CPSpaceFunctionKey];
[CPMenuItemStringRepresentationDictionary setObject:"\u23CE" forKey:CPCarriageReturnCharacter];
[CPMenuItemStringRepresentationDictionary setObject:"\u232B" forKey:CPBackspaceCharacter];
[CPMenuItemStringRepresentationDictionary setObject:"\u232B" forKey:CPDeleteFunctionKey];
[CPMenuItemStringRepresentationDictionary setObject:"\u2326" forKey:CPDeleteCharacter];
[CPMenuItemStringRepresentationDictionary setObject:"\u21F1" forKey:CPHomeFunctionKey];
[CPMenuItemStringRepresentationDictionary setObject:"\u21F2" forKey:CPEndFunctionKey];
[CPMenuItemStringRepresentationDictionary setObject:"\u21DE" forKey:CPPageUpFunctionKey];
[CPMenuItemStringRepresentationDictionary setObject:"\u21DF" forKey:CPPageDownFunctionKey];
[CPMenuItemStringRepresentationDictionary setObject:"\u2191" forKey:CPUpArrowFunctionKey];
[CPMenuItemStringRepresentationDictionary setObject:"\u2193" forKey:CPDownArrowFunctionKey];
[CPMenuItemStringRepresentationDictionary setObject:"\u2190" forKey:CPLeftArrowFunctionKey];
[CPMenuItemStringRepresentationDictionary setObject:"\u2192" forKey:CPRightArrowFunctionKey];
[CPMenuItemStringRepresentationDictionary setObject:"\u2327" forKey:CPClearDisplayFunctionKey];
@global CPApp
var CPMenuItemStringRepresentationDictionary = @{
CPEscapeFunctionKey: "\u238B",
CPTabCharacter: "\u21E5",
CPBackTabCharacter: "\u21E4",
CPSpaceFunctionKey: "\u2423",
CPCarriageReturnCharacter: "\u23CE",
CPBackspaceCharacter: "\u232B",
CPDeleteFunctionKey: "\u232B",
CPDeleteCharacter: "\u2326",
CPHomeFunctionKey: "\u21F1",
CPEndFunctionKey: "\u21F2",
CPPageUpFunctionKey: "\u21DE",
CPPageDownFunctionKey: "\u21DF",
CPUpArrowFunctionKey: "\u2191",
CPDownArrowFunctionKey: "\u2193",
CPLeftArrowFunctionKey: "\u2190",
CPRightArrowFunctionKey: "\u2192",
CPClearDisplayFunctionKey: "\u2327",
};
/*!
@ingroup appkit
@@ -101,6 +105,16 @@ var CPMenuItemStringRepresentationDictionary = [CPDictionary dictionary];
_CPMenuItemView _menuItemView;
}
+ (Class)_binderClassForBinding:(CPString)aBinding
{
if ([aBinding hasPrefix:CPEnabledBinding])
return [CPMultipleValueAndBinding class];
else if (aBinding === CPTargetBinding || [aBinding hasPrefix:CPArgumentBinding])
return [CPActionBinding class];
return [super _binderClassForBinding:aBinding];
}
- (id)init
{
return [self initWithTitle:@"" action:nil keyEquivalent:nil];
+44 -128
View File
@@ -1,17 +1,30 @@
@import "CPView.j"
/*
* _CPMenuItemMenuBarView.j
* AppKit
*
* Created by Francisco Tolmasky.
* Copyright 2009, 280 North, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@import "CPControl.j"
@import "_CPImageAndTextView.j"
var HORIZONTAL_MARGIN = 8.0,
SUBMENU_INDICATOR_MARGIN = 3.0,
VERTICAL_MARGIN = 4.0;
var SelectionColor = nil,
SUBMENU_INDICATOR_COLOR = nil,
_CPMenuItemSelectionColor = nil,
_CPMenuItemTextShadowColor = nil,
_CPMenuItemDefaultStateImages = [],
_CPMenuItemDefaultStateHighlightedImages = [];
@class _CPMenuBarWindow
@class _CPMenuView
@implementation _CPMenuItemMenuBarView : CPView
{
@@ -24,31 +37,22 @@ var SelectionColor = nil,
BOOL _isDirty;
_CPImageAndTextView _imageAndTextView;
CPView _submenuIndicatorView;
}
+ (void)initialize
+ (CPString)defaultThemeClass
{
if (self !== [_CPMenuItemMenuBarView class])
return;
return "menu-item-bar-view";
}
var bundle = [CPBundle bundleForClass:self];
SelectionColor = [CPColor colorWithPatternImage:[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"_CPMenuBarWindow/_CPMenuBarWindowBackgroundSelected.png"] size:CGSizeMake(1.0, 28.0)]];
SUBMENU_INDICATOR_COLOR = [CPColor grayColor];
_CPMenuItemSelectionColor = [CPColor colorWithCalibratedRed:95.0 / 255.0 green:131.0 / 255.0 blue:185.0 / 255.0 alpha:1.0];
_CPMenuItemTextShadowColor = [CPColor colorWithCalibratedRed:26.0 / 255.0 green: 73.0 / 255.0 blue:109.0 / 255.0 alpha:1.0];
_CPMenuItemDefaultStateImages[CPOffState] = nil;
_CPMenuItemDefaultStateHighlightedImages[CPOffState] = nil;
_CPMenuItemDefaultStateImages[CPOnState] = [[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPMenuItem/CPMenuItemOnState.png"] size:CGSizeMake(14.0, 14.0)];
_CPMenuItemDefaultStateHighlightedImages[CPOnState] = [[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPMenuItem/CPMenuItemOnStateHighlighted.png"] size:CGSizeMake(14.0, 14.0)];
_CPMenuItemDefaultStateImages[CPMixedState] = nil;
_CPMenuItemDefaultStateHighlightedImages[CPMixedState] = nil;
+ (id)themeAttributes
{
return @{
@"menu-item-selection-color": [CPNull null],
@"menu-item-text-shadow-color": [CPNull null],
@"horizontal-margin": 12.0,
@"submenu-indicator-margin": 3.0,
@"vertical-margin": 4.0,
};
}
+ (id)view
@@ -62,7 +66,7 @@ var SelectionColor = nil,
if (self)
{
_imageAndTextView = [[_CPImageAndTextView alloc] initWithFrame:CGRectMake(HORIZONTAL_MARGIN, 0.0, 0.0, 0.0)];
_imageAndTextView = [[_CPImageAndTextView alloc] initWithFrame:CGRectMake([self valueForThemeAttribute:@"horizontal-margin"], 0.0, 0.0, 0.0)];
[_imageAndTextView setImagePosition:CPImageLeft];
[_imageAndTextView setImageOffset:3.0];
@@ -71,12 +75,6 @@ var SelectionColor = nil,
[self addSubview:_imageAndTextView];
_submenuIndicatorView = [[_CPMenuItemMenuBarSubmenuIndicatorView alloc] initWithFrame:CGRectMake(0.0, 0.0, 9.0, 6.0)];
[_submenuIndicatorView setAutoresizingMask:CPViewMinYMargin | CPViewMaxYMargin];
[self addSubview:_submenuIndicatorView];
[self setAutoresizingMask:CPViewWidthSizable | CPViewHeightSizable];
}
@@ -94,14 +92,14 @@ var SelectionColor = nil,
- (CPColor)textShadowColor
{
if (![_menuItem isEnabled])
return [CPColor colorWithWhite:0.8 alpha:0.8];
return [CPColor clearColor];
return _textShadowColor || [CPColor colorWithWhite:1.0 alpha:0.8];
}
- (void)update
{
var x = HORIZONTAL_MARGIN,
var x = [self valueForThemeAttribute:@"horizontal-margin"],
height = 0.0;
[_imageAndTextView setFont:[_menuItem font] || [_CPMenuBarWindow font]];
@@ -117,39 +115,13 @@ var SelectionColor = nil,
imageAndTextViewFrame.origin.x = x;
x += CGRectGetWidth(imageAndTextViewFrame);
height = MAX(height, CGRectGetHeight(imageAndTextViewFrame));
var hasSubmenuIndicator = [_menuItem hasSubmenu] && [_menuItem action];
if (hasSubmenuIndicator)
{
[_submenuIndicatorView setHidden:NO];
[_submenuIndicatorView setColor:[self textColor]];
[_submenuIndicatorView setShadowColor:[self textShadowColor]];
var submenuViewFrame = [_submenuIndicatorView frame];
submenuViewFrame.origin.x = x + SUBMENU_INDICATOR_MARGIN;
x = CGRectGetMaxX(submenuViewFrame);
height = MAX(height, CGRectGetHeight(submenuViewFrame));
}
else
[_submenuIndicatorView setHidden:YES];
height += 2.0 * VERTICAL_MARGIN;
height = MAX(height, CGRectGetHeight(imageAndTextViewFrame)) + 2.0 * [self valueForThemeAttribute:@"vertical-margin"];
imageAndTextViewFrame.origin.y = FLOOR((height - CGRectGetHeight(imageAndTextViewFrame)) / 2.0);
[_imageAndTextView setFrame:imageAndTextViewFrame];
if (hasSubmenuIndicator)
{
submenuViewFrame.origin.y = FLOOR((height - CGRectGetHeight(submenuViewFrame)) / 2.0) + 1.0;
[_submenuIndicatorView setFrame:submenuViewFrame];
}
[self setAutoresizesSubviews:NO];
[self setFrameSize:CGSizeMake(x + HORIZONTAL_MARGIN, height)];
[self setFrameSize:CGSizeMake(x + [self valueForThemeAttribute:@"horizontal-margin"], height)];
[self setAutoresizesSubviews:YES];
}
@@ -162,14 +134,11 @@ var SelectionColor = nil,
if (shouldHighlight)
{
if (![_menuItem _isMenuBarButton])
[self setBackgroundColor:SelectionColor];
[self setBackgroundColor:[[CPTheme defaultTheme] valueForAttributeWithName:@"menu-bar-window-background-selected-color" forClass:_CPMenuView]];
[_imageAndTextView setImage:[_menuItem alternateImage] || [_menuItem image]];
[_imageAndTextView setTextColor:[CPColor whiteColor]];
[_imageAndTextView setTextShadowColor:_CPMenuItemTextShadowColor];
[_submenuIndicatorView setColor:[CPColor whiteColor]];
[_submenuIndicatorView setShadowColor:[CPColor colorWithWhite:0.1 alpha:0.7]];
[_imageAndTextView setTextShadowColor:[self valueForThemeAttribute:@"menu-item-text-shadow-color"]];
}
else
{
@@ -178,60 +147,7 @@ var SelectionColor = nil,
[_imageAndTextView setImage:[_menuItem image]];
[_imageAndTextView setTextColor:[self textColor]];
[_imageAndTextView setTextShadowColor:[self textShadowColor]];
[_submenuIndicatorView setColor:[self textColor]];
[_submenuIndicatorView setShadowColor:[self textShadowColor]];
}
}
@end
@implementation _CPMenuItemMenuBarSubmenuIndicatorView : CPView
{
CPColor _color;
CPColor _shadowColor;
}
- (void)setColor:(CPColor)aColor
{
if (_color === aColor)
return;
_color = aColor;
[self setNeedsDisplay:YES];
}
- (void)setShadowColor:(CPColor)aColor
{
if (_shadowColor === aColor)
return;
_shadowColor = aColor;
[self setNeedsDisplay:YES];
}
- (void)drawRect:(CGRect)aRect
{
var context = [[CPGraphicsContext currentContext] graphicsPort],
bounds = [self bounds];
bounds.size.height -= 1.0;
bounds.size.width -= 2.0;
bounds.origin.x += 1.0;
CGContextBeginPath(context);
CGContextMoveToPoint(context, CGRectGetMinX(bounds), CGRectGetMinY(bounds));
CGContextAddLineToPoint(context, CGRectGetMaxX(bounds), CGRectGetMinY(bounds));
CGContextAddLineToPoint(context, CGRectGetMidX(bounds), CGRectGetMaxY(bounds));
CGContextClosePath(context);
CGContextSetShadowWithColor(context, CGSizeMake(0.0, 1.0), 1.1, _shadowColor || [CPColor whiteColor]);
CGContextSetFillColor(context, _color || [CPColor blackColor]);
CGContextFillPath(context);
}
@end
+25 -2
View File
@@ -1,6 +1,29 @@
/*
* _CPMenuItemSeparatorView.j
* AppKit
*
* Created by Francisco Tolmasky.
* Copyright 2009, 280 North, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@import "CPView.j"
@class _CPMenuItemStandardView
@implementation _CPMenuItemSeparatorView : CPView
{
@@ -31,8 +54,8 @@
CGContextMoveToPoint(context, CGRectGetMinX(bounds), FLOOR(CGRectGetMidY(bounds)) - 0.5);
CGContextAddLineToPoint(context, CGRectGetMaxX(bounds), FLOOR(CGRectGetMidY(bounds)) - 0.5);
CGContextSetStrokeColor(context, [CPColor lightGrayColor]);
CGContextSetStrokeColor(context, [[CPTheme defaultTheme] valueForAttributeWithName:@"menu-item-separator-color" forClass:_CPMenuItemStandardView]);
CGContextStrokePath(context);
}
@end
@end
+134 -67
View File
@@ -1,32 +1,38 @@
/*
* _CPMenuItemStandardView.j
* AppKit
*
* Created by Francisco Tolmasky.
* Copyright 2009, 280 North, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@import "CPControl.j"
var LEFT_MARGIN = 3.0,
RIGHT_MARGIN = 14.0 + 3.0,
STATE_COLUMN_WIDTH = 14.0,
INDENTATION_WIDTH = 17.0,
VERTICAL_MARGIN = 4.0,
RIGHT_COLUMNS_MARGIN = 30.0,
KEY_EQUIVALENT_MARGIN = 10.0;
var SUBMENU_INDICATOR_COLOR = nil,
_CPMenuItemSelectionColor = nil,
_CPMenuItemTextShadowColor = nil,
_CPMenuItemDefaultStateImages = [],
_CPMenuItemDefaultStateHighlightedImages = [];
@import "CPImageView.j"
@import "_CPImageAndTextView.j"
@implementation _CPMenuItemStandardView : CPView
{
CPMenuItem _menuItem @accessors(property=menuItem);
CPFont _font;
CPColor _textColor;
CPColor _textShadowColor;
CGSize _minSize @accessors(readonly, property=minSize);
BOOL _isDirty;
BOOL _highlighted;
CPImageView _stateView;
_CPImageAndTextView _imageAndTextView;
@@ -34,26 +40,32 @@ var SUBMENU_INDICATOR_COLOR = nil,
CPView _submenuIndicatorView;
}
+ (void)initialize
+ (CPString)defaultThemeClass
{
if (self !== [_CPMenuItemStandardView class])
return;
return "menu-item-standard-view";
}
SUBMENU_INDICATOR_COLOR = [CPColor grayColor];
_CPMenuItemSelectionColor = [CPColor colorWithCalibratedRed:95.0 / 255.0 green:131.0 / 255.0 blue:185.0 / 255.0 alpha:1.0];
_CPMenuItemTextShadowColor = [CPColor colorWithCalibratedRed:26.0 / 255.0 green: 73.0 / 255.0 blue:109.0 / 255.0 alpha:1.0];
var bundle = [CPBundle bundleForClass:self];
_CPMenuItemDefaultStateImages[CPOffState] = nil;
_CPMenuItemDefaultStateHighlightedImages[CPOffState] = nil;
_CPMenuItemDefaultStateImages[CPOnState] = [[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPMenuItem/CPMenuItemOnState.png"] size:CGSizeMake(14.0, 14.0)];
_CPMenuItemDefaultStateHighlightedImages[CPOnState] = [[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPMenuItem/CPMenuItemOnStateHighlighted.png"] size:CGSizeMake(14.0, 14.0)];
_CPMenuItemDefaultStateImages[CPMixedState] = nil;
_CPMenuItemDefaultStateHighlightedImages[CPMixedState] = nil;
+ (id)themeAttributes
{
return @{
@"submenu-indicator-color": [CPNull null],
@"menu-item-selection-color": [CPNull null],
@"menu-item-text-shadow-color": [CPNull null],
@"menu-item-text-color": [CPNull null],
@"menu-item-default-off-state-image": [CPNull null],
@"menu-item-default-off-state-highlighted-image": [CPNull null],
@"menu-item-default-on-state-image": [CPNull null],
@"menu-item-default-on-state-highlighted-image": [CPNull null],
@"menu-item-default-mixed-state-image": [CPNull null],
@"menu-item-default-mixed-state-highlighted-image": [CPNull null],
@"menu-item-separator-color": [CPNull null],
@"left-margin": 3.0,
@"right-margin": 17.0,
@"state-column-width": 14.0,
@"indentation-width": 17.0,
@"vertical-margin": 4.0,
@"right-columns-margin": 30.0,
};
}
+ (id)view
@@ -63,7 +75,7 @@ var SUBMENU_INDICATOR_COLOR = nil,
+ (float)_standardLeftMargin
{
return LEFT_MARGIN + STATE_COLUMN_WIDTH;
return [[CPTheme defaultTheme] valueForAttributeWithName:@"left-margin" forClass:[self class]] + [[CPTheme defaultTheme] valueForAttributeWithName:@"state-column-width" forClass:[self class]];
}
- (id)initWithFrame:(CGRect)aFrame
@@ -95,7 +107,7 @@ var SUBMENU_INDICATOR_COLOR = nil,
_submenuIndicatorView = [[_CPMenuItemSubmenuIndicatorView alloc] initWithFrame:CGRectMake(0.0, 0.0, 8.0, 10.0)];
[_submenuIndicatorView setColor:SUBMENU_INDICATOR_COLOR];
[_submenuIndicatorView setColor:[self valueForThemeAttribute:@"submenu-indicator-color"]];
[_submenuIndicatorView setAutoresizingMask:CPViewMinXMargin];
[self addSubview:_submenuIndicatorView];
@@ -111,7 +123,10 @@ var SUBMENU_INDICATOR_COLOR = nil,
if (![_menuItem isEnabled])
return [CPColor lightGrayColor];
return _textColor || [CPColor colorWithCalibratedRed:70.0 / 255.0 green:69.0 / 255.0 blue:69.0 / 255.0 alpha:1.0];
if (_highlighted)
return [CPColor whiteColor];
return [self valueForThemeAttribute:@"menu-item-text-color"];
}
- (CPColor)textShadowColor
@@ -119,7 +134,10 @@ var SUBMENU_INDICATOR_COLOR = nil,
if (![_menuItem isEnabled])
return nil;
return _textShadowColor || [CPColor colorWithWhite:1.0 alpha:0.8];
if (_highlighted)
return nil;
return [self valueForThemeAttribute:@"menu-item-text-shadow-color"];
}
- (void)setFont:(CPFont)aFont
@@ -129,16 +147,34 @@ var SUBMENU_INDICATOR_COLOR = nil,
- (void)update
{
var x = LEFT_MARGIN + [_menuItem indentationLevel] * INDENTATION_WIDTH,
var x = [self valueForThemeAttribute:@"left-margin"] + [_menuItem indentationLevel] * [self valueForThemeAttribute:@"indentation-width"],
height = 0.0,
hasStateColumn = [[_menuItem menu] showsStateColumn];
if (hasStateColumn)
{
[_stateView setHidden:NO];
[_stateView setImage:_CPMenuItemDefaultStateImages[[_menuItem state]] || nil];
//[_stateView setImage:_CPMenuItemDefaultStateImages[[_menuItem state]] || nil];
x += STATE_COLUMN_WIDTH;
switch ([_menuItem state])
{
case CPOnState:
[_stateView setImage:[self valueForThemeAttribute:@"menu-item-default-on-state-image"]];
break;
case CPOffState:
[_stateView setImage:[self valueForThemeAttribute:@"menu-item-default-off-state-image"]];
break;
case CPMixedState:
[_stateView setImage:[self valueForThemeAttribute:@"menu-item-default-mixed-state-image"]];
break;
default:
break;
}
x += [self valueForThemeAttribute:@"state-column-width"];
}
else
[_stateView setHidden:YES];
@@ -162,7 +198,7 @@ var SUBMENU_INDICATOR_COLOR = nil,
hasSubmenu = [_menuItem hasSubmenu];
if (hasKeyEquivalent || hasSubmenu)
x += RIGHT_COLUMNS_MARGIN;
x += [self valueForThemeAttribute:@"right-columns-margin"];
if (hasKeyEquivalent)
{
@@ -173,7 +209,7 @@ var SUBMENU_INDICATOR_COLOR = nil,
[_keyEquivalentView setTextColor:[self textColor]];
[_keyEquivalentView setTextShadowColor:[self textShadowColor]];
[_keyEquivalentView setTextShadowOffset:CGSizeMake(0, 1)];
[_keyEquivalentView setFrameOrigin:CGPointMake(x, VERTICAL_MARGIN)];
[_keyEquivalentView setFrameOrigin:CGPointMake(x, [self valueForThemeAttribute:@"vertical-margin"])];
[_keyEquivalentView sizeToFit];
var keyEquivalentViewFrame = [_keyEquivalentView frame];
@@ -183,7 +219,7 @@ var SUBMENU_INDICATOR_COLOR = nil,
height = MAX(height, CGRectGetHeight(keyEquivalentViewFrame));
if (hasSubmenu)
x += RIGHT_COLUMNS_MARGIN;
x += [self valueForThemeAttribute:@"right-columns-margin"];
}
else
[_keyEquivalentView setHidden:YES];
@@ -202,13 +238,13 @@ var SUBMENU_INDICATOR_COLOR = nil,
else
[_submenuIndicatorView setHidden:YES];
height += 2.0 * VERTICAL_MARGIN;
height += 2.0 * [self valueForThemeAttribute:@"vertical-margin"];
imageAndTextViewFrame.origin.y = FLOOR((height - CGRectGetHeight(imageAndTextViewFrame)) / 2.0);
[_imageAndTextView setFrame:imageAndTextViewFrame];
if (hasStateColumn)
[_stateView setFrameSize:CGSizeMake(STATE_COLUMN_WIDTH, height)];
[_stateView setFrameSize:CGSizeMake([self valueForThemeAttribute:@"state-column-width"], height)];
if (hasKeyEquivalent)
{
@@ -222,7 +258,7 @@ var SUBMENU_INDICATOR_COLOR = nil,
[_submenuIndicatorView setFrame:submenuViewFrame];
}
_minSize = CGSizeMake(x + RIGHT_MARGIN, height);
_minSize = CGSizeMake(x + [self valueForThemeAttribute:@"right-margin"], height);
[self setAutoresizesSubviews:NO];
[self setFrameSize:_minSize];
@@ -235,37 +271,68 @@ var SUBMENU_INDICATOR_COLOR = nil,
if (![_menuItem isEnabled])
return;
_highlighted = shouldHighlight;
[_imageAndTextView setTextColor:[self textColor]];
[_keyEquivalentView setTextColor:[self textColor]];
[_imageAndTextView setTextShadowColor:[self textShadowColor]];
[_keyEquivalentView setTextShadowColor:[self textShadowColor]];
if (shouldHighlight)
{
[self setBackgroundColor:_CPMenuItemSelectionColor];
[self setBackgroundColor:[self valueForThemeAttribute:@"menu-item-selection-color"]];
[_imageAndTextView setImage:[_menuItem alternateImage] || [_menuItem image]];
[_imageAndTextView setTextColor:[CPColor whiteColor]];
[_keyEquivalentView setTextColor:[CPColor whiteColor]];
[_submenuIndicatorView setColor:[CPColor whiteColor]];
[_imageAndTextView setTextShadowColor:_CPMenuItemTextShadowColor];
[_keyEquivalentView setTextShadowColor:_CPMenuItemTextShadowColor];
[_submenuIndicatorView setColor:[self textColor]];
}
else
{
[self setBackgroundColor:nil];
[_imageAndTextView setImage:[_menuItem image]];
[_imageAndTextView setTextColor:[self textColor]];
[_keyEquivalentView setTextColor:[self textColor]];
[_submenuIndicatorView setColor:SUBMENU_INDICATOR_COLOR];
[_imageAndTextView setTextShadowColor:[self textShadowColor]];
[_keyEquivalentView setTextShadowColor:[self textShadowColor]];
[_submenuIndicatorView setColor:[self valueForThemeAttribute:@"submenu-indicator-color"]];
}
if ([[_menuItem menu] showsStateColumn])
{
if (shouldHighlight)
[_stateView setImage:_CPMenuItemDefaultStateHighlightedImages[[_menuItem state]] || nil];
{
switch ([_menuItem state])
{
case CPOnState:
[_stateView setImage:[self valueForThemeAttribute:@"menu-item-default-on-state-highlighted-image"]];
break;
case CPOffState:
[_stateView setImage:[self valueForThemeAttribute:@"menu-item-default-off-state-highlighted-image"]];
break;
case CPMixedState:
[_stateView setImage:[self valueForThemeAttribute:@"menu-item-default-mixed-state-highlighted-image"]];
break;
default:
break;
}
}
else
[_stateView setImage:_CPMenuItemDefaultStateImages[[_menuItem state]] || nil];
{
switch ([_menuItem state])
{
case CPOnState:
[_stateView setImage:[self valueForThemeAttribute:@"menu-item-default-on-state-image"]];
break;
case CPOffState:
[_stateView setImage:[self valueForThemeAttribute:@"menu-item-default-off-state-image"]];
break;
case CPMixedState:
[_stateView setImage:[self valueForThemeAttribute:@"menu-item-default-mixed-state-image"]];
break;
default:
break;
}
}
}
}
+33 -34
View File
@@ -1,22 +1,32 @@
/*
* _CPMenuItemView.j
* AppKit
*
* Created by Francisco Tolmasky.
* Copyright 2009, 280 North, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@import <AppKit/CPControl.j>
@import "CPControl.j"
@import "_CPMenuItemSeparatorView.j"
@import "_CPMenuItemStandardView.j"
@import "_CPMenuItemMenuBarView.j"
var LEFT_MARGIN = 3.0,
RIGHT_MARGIN = 16.0,
STATE_COLUMN_WIDTH = 14.0,
INDENTATION_WIDTH = 17.0,
VERTICAL_MARGIN = 4.0;
var _CPMenuItemSelectionColor = nil,
_CPMenuItemTextShadowColor = nil,
_CPMenuItemDefaultStateImages = [],
_CPMenuItemDefaultStateHighlightedImages = [];
@global CPApp
/*
@ignore
@@ -38,31 +48,22 @@ var _CPMenuItemSelectionColor = nil,
CPView _submenuView;
}
+ (void)initialize
+ (CPString)defaultThemeClass
{
if (self !== [_CPMenuItemView class])
return;
_CPMenuItemSelectionColor = [CPColor colorWithCalibratedRed:95.0 / 255.0 green:131.0 / 255.0 blue:185.0 / 255.0 alpha:1.0];
_CPMenuItemTextShadowColor = [CPColor colorWithCalibratedRed:26.0 / 255.0 green: 73.0 / 255.0 blue:109.0 / 255.0 alpha:1.0];
var bundle = [CPBundle bundleForClass:self];
_CPMenuItemDefaultStateImages[CPOffState] = nil;
_CPMenuItemDefaultStateHighlightedImages[CPOffState] = nil;
_CPMenuItemDefaultStateImages[CPOnState] = [[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPMenuItem/CPMenuItemOnState.png"] size:CGSizeMake(14.0, 14.0)];
_CPMenuItemDefaultStateHighlightedImages[CPOnState] = [[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPMenuItem/CPMenuItemOnStateHighlighted.png"] size:CGSizeMake(14.0, 14.0)];
_CPMenuItemDefaultStateImages[CPMixedState] = nil;
_CPMenuItemDefaultStateHighlightedImages[CPMixedState] = nil;
return "menu-item-view";
}
+ (float)leftMargin
+ (id)themeAttributes
{
return LEFT_MARGIN + STATE_COLUMN_WIDTH;
return @{};
}
// Not used in the Appkit
// + (float)leftMargin
// {
// return LEFT_MARGIN + STATE_COLUMN_WIDTH;
// }
- (id)initWithFrame:(CGRect)aFrame forMenuItem:(CPMenuItem)aMenuItem
{
self = [super initWithFrame:aFrame];
@@ -245,8 +246,6 @@ var _CPMenuItemSelectionColor = nil,
CGContextMoveToPoint(context, 1.0, 4.0);
CGContextAddLineToPoint(context, 9.0, 4.0);
CGContextAddLineToPoint(context, 5.0, 8.0);
CGContextAddLineToPoint(context, 1.0, 4.0);
CGContextClosePath(context);
CGContextSetFillColor(context, _color);
+30 -12
View File
@@ -22,8 +22,10 @@
@import <Foundation/CPDictionary.j>
@import <Foundation/CPCountedSet.j>
@import <Foundation/_CPCollectionKVCOperators.j>
@import "CPController.j"
@import "CPKeyValueBinding.j"
/*!
@class
@@ -104,11 +106,13 @@
{
if (self = [super init])
{
[self setContent:aContent];
[self setEditable:YES];
[self setObjectClass:[CPMutableDictionary class]];
_observedKeys = [[CPCountedSet alloc] init];
_selection = [[CPControllerSelectionProxy alloc] initWithController:self];
[self setContent:aContent];
}
return self;
@@ -516,8 +520,12 @@ var CPObjectControllerContentKey = @"CPObjectControllerCo
- (void)addObserver:(id)anObserver forKeyPath:(CPString)aKeyPath options:(CPKeyValueObservingOptions)options context:(id)context
{
if (aKeyPath.indexOf("@") === 0)
if (aKeyPath.charAt(0) === "@")
{
// Simple collection operators are scalar and can't be proxied
if ([_CPCollectionKVCOperator isSimpleCollectionOperator:aKeyPath])
return;
var proxy = [[_CPObservationProxy alloc] initWithKeyPath:aKeyPath observer:anObserver object:self];
proxy._options = options;
@@ -540,8 +548,12 @@ var CPObjectControllerContentKey = @"CPObjectControllerCo
- (void)removeObserver:(id)anObserver forKeyPath:(CPString)aKeyPath
{
if (aKeyPath.indexOf("@") === 0)
if (aKeyPath.charAt(0) === "@")
{
// Simple collection operators are scalar and can't be proxied
if ([_CPCollectionKVCOperator isSimpleCollectionOperator:aKeyPath])
return;
var proxy = [[_CPObservationProxy alloc] initWithKeyPath:aKeyPath observer:anObserver object:self],
index = [_observationProxies indexOfObject:proxy];
@@ -566,7 +578,7 @@ var CPObjectControllerContentKey = @"CPObjectControllerCo
{
var proxy = [_observationProxies objectAtIndex:i],
keyPath = [proxy keyPath],
operator = keyPath.indexOf(".") === 0;
operator = keyPath.charAt(0) === ".";
if (operator)
[self willChangeValueForKey:keyPath];
@@ -588,7 +600,7 @@ var CPObjectControllerContentKey = @"CPObjectControllerCo
{
var proxy = [_observationProxies objectAtIndex:i],
keyPath = [proxy keyPath],
operator = keyPath.indexOf(".") === 0;
operator = keyPath.charAt(0) === ".";
if (operator)
[self willChangeValueForKey:keyPath];
@@ -625,7 +637,7 @@ var CPObjectControllerContentKey = @"CPObjectControllerCo
{
var proxy = [_observationProxies objectAtIndex:i],
keyPath = [proxy keyPath],
operator = keyPath.indexOf(".") === 0;
operator = keyPath.charAt(0) === ".";
if (operator)
[self willChangeValueForKey:keyPath];
@@ -657,7 +669,7 @@ var CPObjectControllerContentKey = @"CPObjectControllerCo
{
if (self = [super init])
{
_cachedValues = [CPDictionary dictionary];
_cachedValues = @{};
_observationProxies = [CPArray array];
_controller = aController;
_observedObjectsByKeyPath = {};
@@ -699,12 +711,18 @@ var CPObjectControllerContentKey = @"CPObjectControllerCo
- (id)valueForKeyPath:(CPString)theKeyPath
{
var values = [[_controller selectedObjects] valueForKeyPath:theKeyPath],
value = [self _controllerMarkerForValues:values];
var values = [[_controller selectedObjects] valueForKeyPath:theKeyPath];
[_cachedValues setObject:value forKey:theKeyPath];
// Simple collection operators like @count return a scalar value, not an array or set
if ([values isKindOfClass:CPArray] || [values isKindOfClass:CPSet])
{
var value = [self _controllerMarkerForValues:values];
[_cachedValues setObject:value forKey:theKeyPath];
return value;
return value;
}
else
return values;
}
- (id)valueForKey:(CPString)theKeyPath
@@ -798,7 +816,7 @@ var CPObjectControllerContentKey = @"CPObjectControllerCo
[_observationProxies removeObjectAtIndex:index];
_observedObjects = nil;
_observedObjectsByKeyPath[aKeyPath] = nil;
}
@end
+2 -2
View File
@@ -47,9 +47,9 @@
var options = { directoryURL: [self directoryURL],
canChooseFiles: [self canChooseFiles],
canChooseDirectories: [self canChooseDirectories],
allowsMultipleSelection: [self allowsMultipleSelection] };
allowsMultipleSelection: [self allowsMultipleSelection] },
var result = window.cpOpenPanel(options);
result = window.cpOpenPanel(options);
_URLs = result.URLs;
+51 -42
View File
@@ -20,9 +20,11 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@import "CPButton.j"
@import "CPTableColumn.j"
@import "CPTableView.j"
@global CPApp
CPOutlineViewColumnDidMoveNotification = @"CPOutlineViewColumnDidMoveNotification";
CPOutlineViewColumnDidResizeNotification = @"CPOutlineViewColumnDidResizeNotification";
@@ -33,20 +35,21 @@ CPOutlineViewItemWillExpandNotification = @"CPOutlineViewItemWillExpandN
CPOutlineViewSelectionDidChangeNotification = @"CPOutlineViewSelectionDidChangeNotification";
CPOutlineViewSelectionIsChangingNotification = @"CPOutlineViewSelectionIsChangingNotification";
var CPOutlineViewDataSource_outlineView_setObjectValue_forTableColumn_byItem_ = 1 << 1,
CPOutlineViewDataSource_outlineView_shouldDeferDisplayingChildrenOfItem_ = 1 << 2,
var CPOutlineViewDataSource_outlineView_objectValue_forTableColumn_byItem_ = 1 << 1,
CPOutlineViewDataSource_outlineView_setObjectValue_forTableColumn_byItem_ = 1 << 2,
CPOutlineViewDataSource_outlineView_shouldDeferDisplayingChildrenOfItem_ = 1 << 3,
CPOutlineViewDataSource_outlineView_acceptDrop_item_childIndex_ = 1 << 3,
CPOutlineViewDataSource_outlineView_validateDrop_proposedItem_proposedChildIndex_ = 1 << 4,
CPOutlineViewDataSource_outlineView_validateDrop_proposedRow_proposedDropOperation_ = 1 << 5,
CPOutlineViewDataSource_outlineView_namesOfPromisedFilesDroppedAtDestination_forDraggedItems_ = 1 << 6,
CPOutlineViewDataSource_outlineView_acceptDrop_item_childIndex_ = 1 << 4,
CPOutlineViewDataSource_outlineView_validateDrop_proposedItem_proposedChildIndex_ = 1 << 5,
CPOutlineViewDataSource_outlineView_validateDrop_proposedRow_proposedDropOperation_ = 1 << 6,
CPOutlineViewDataSource_outlineView_namesOfPromisedFilesDroppedAtDestination_forDraggedItems_ = 1 << 7,
CPOutlineViewDataSource_outlineView_itemForPersistentObject_ = 1 << 7,
CPOutlineViewDataSource_outlineView_persistentObjectForItem_ = 1 << 8,
CPOutlineViewDataSource_outlineView_itemForPersistentObject_ = 1 << 8,
CPOutlineViewDataSource_outlineView_persistentObjectForItem_ = 1 << 9,
CPOutlineViewDataSource_outlineView_writeItems_toPasteboard_ = 1 << 9,
CPOutlineViewDataSource_outlineView_writeItems_toPasteboard_ = 1 << 10,
CPOutlineViewDataSource_outlineView_sortDescriptorsDidChange_ = 1 << 10;
CPOutlineViewDataSource_outlineView_sortDescriptorsDidChange_ = 1 << 11;
var CPOutlineViewDelegate_outlineView_dataViewForTableColumn_item_ = 1 << 1,
CPOutlineViewDelegate_outlineView_didClickTableColumn_ = 1 << 2,
@@ -228,12 +231,12 @@ var CPOutlineViewCoalesceSelectionNotificationStateOff = 0,
if (![aDataSource respondsToSelector:@selector(outlineView:numberOfChildrenOfItem:)])
[CPException raise:CPInternalInconsistencyException reason:"Data source must implement 'outlineView:numberOfChildrenOfItem:'"];
if (![aDataSource respondsToSelector:@selector(outlineView:objectValueForTableColumn:byItem:)])
[CPException raise:CPInternalInconsistencyException reason:"Data source must implement 'outlineView:objectValueForTableColumn:byItem:'"];
_outlineViewDataSource = aDataSource;
_implementedOutlineViewDataSourceMethods = 0;
if ([_outlineViewDataSource respondsToSelector:@selector(outlineView:objectValueForTableColumn:byItem:)])
_implementedOutlineViewDataSourceMethods |= CPOutlineViewDataSource_outlineView_objectValue_forTableColumn_byItem_;
if ([_outlineViewDataSource respondsToSelector:@selector(outlineView:setObjectValue:forTableColumn:byItem:)])
_implementedOutlineViewDataSourceMethods |= CPOutlineViewDataSource_outlineView_setObjectValue_forTableColumn_byItem_;
@@ -1052,11 +1055,12 @@ var CPOutlineViewCoalesceSelectionNotificationStateOff = 0,
@ignore
We need to offset the dataview and add the disclosure triangle.
*/
- (CPView)_dragViewForColumn:(int)theColumnIndex event:(CPEvent)theDragEvent offset:(CPPointPointer)theDragViewOffset
- (CPView)_dragViewForColumn:(int)theColumnIndex event:(CPEvent)theDragEvent offset:(CGPoint)theDragViewOffset
{
var dragView = [[_CPColumnDragView alloc] initWithLineColor:[self gridColor]],
tableColumn = [[self tableColumns] objectAtIndex:theColumnIndex],
bounds = _CGRectMake(0.0, 0.0, [tableColumn width], _CGRectGetHeight([self exposedRect]) + 23.0),
defaultRowHeight = [self valueForThemeAttribute:@"default-row-height"],
bounds = _CGRectMake(0.0, 0.0, [tableColumn width], _CGRectGetHeight([self exposedRect]) + defaultRowHeight),
columnRect = [self rectOfColumn:theColumnIndex],
headerView = [tableColumn headerView],
row = [_exposedRows firstIndex];
@@ -1070,7 +1074,7 @@ var CPOutlineViewCoalesceSelectionNotificationStateOff = 0,
dataViewFrame.origin.x = 0.0;
// Offset by table header height - scroll position
dataViewFrame.origin.y = ( _CGRectGetMinY(dataViewFrame) - _CGRectGetMinY([self exposedRect]) ) + 23.0;
dataViewFrame.origin.y = ( _CGRectGetMinY(dataViewFrame) - _CGRectGetMinY([self exposedRect]) ) + defaultRowHeight;
[dataView setFrame:dataViewFrame];
[dataView setObjectValue:[self _objectValueForTableColumn:tableColumn row:row]];
@@ -1184,7 +1188,7 @@ var CPOutlineViewCoalesceSelectionNotificationStateOff = 0,
/*!
@ignore
*/
- (id)_parentItemForUpperRow:(int)theUpperRowIndex andLowerRow:(int)theLowerRowIndex atMouseOffset:(CPPoint)theOffset
- (id)_parentItemForUpperRow:(int)theUpperRowIndex andLowerRow:(int)theLowerRowIndex atMouseOffset:(CGPoint)theOffset
{
if (_shouldRetargetItem)
return _retargetedItem;
@@ -1214,7 +1218,7 @@ var CPOutlineViewCoalesceSelectionNotificationStateOff = 0,
/*!
@ignore
*/
- (CPRect)_rectForDropHighlightViewBetweenUpperRow:(int)theUpperRowIndex andLowerRow:(int)theLowerRowIndex offset:(CPPoint)theOffset
- (CGRect)_rectForDropHighlightViewBetweenUpperRow:(int)theUpperRowIndex andLowerRow:(int)theLowerRowIndex offset:(CGPoint)theOffset
{
// Call super and the update x to reflect the current indentation level
var rect = [super _rectForDropHighlightViewBetweenUpperRow:theUpperRowIndex andLowerRow:theLowerRowIndex offset:theOffset],
@@ -1438,7 +1442,7 @@ var CPOutlineViewCoalesceSelectionNotificationStateOff = 0,
[[CPNotificationCenter defaultCenter]
postNotificationName:CPOutlineViewItemWillExpandNotification
object:self
userInfo:[CPDictionary dictionaryWithObject:item forKey:"CPObject"]];
userInfo:@{ "CPObject": item }];
}
/*!
@@ -1449,7 +1453,7 @@ var CPOutlineViewCoalesceSelectionNotificationStateOff = 0,
[[CPNotificationCenter defaultCenter]
postNotificationName:CPOutlineViewItemDidExpandNotification
object:self
userInfo:[CPDictionary dictionaryWithObject:item forKey:"CPObject"]];
userInfo:@{ "CPObject": item }];
}
/*!
@@ -1460,7 +1464,7 @@ var CPOutlineViewCoalesceSelectionNotificationStateOff = 0,
[[CPNotificationCenter defaultCenter]
postNotificationName:CPOutlineViewItemWillCollapseNotification
object:self
userInfo:[CPDictionary dictionaryWithObject:item forKey:"CPObject"]];
userInfo:@{ "CPObject": item }];
}
/*!
@@ -1471,7 +1475,7 @@ var CPOutlineViewCoalesceSelectionNotificationStateOff = 0,
[[CPNotificationCenter defaultCenter]
postNotificationName:CPOutlineViewItemDidCollapseNotification
object:self
userInfo:[CPDictionary dictionaryWithObject:item forKey:"CPObject"]];
userInfo:@{ "CPObject": item }];
}
- (void)keyDown:(CPEvent)anEvent
@@ -1530,6 +1534,16 @@ var CPOutlineViewCoalesceSelectionNotificationStateOff = 0,
[super keyDown:anEvent];
}
- (BOOL)_dataSourceRespondsToObjectValueForTableColumn
{
return _implementedOutlineViewDataSourceMethods & CPOutlineViewDataSource_outlineView_objectValue_forTableColumn_byItem_;
}
- (BOOL)_delegateRespondsToDataViewForTableColumn
{
return _implementedOutlineViewDelegateMethods & CPOutlineViewDelegate_outlineView_dataViewForTableColumn_item_;
}
@end
// FIX ME: We're using with() here because Safari fails if we use anOutlineView._itemInfosForItems or whatever...
@@ -1727,7 +1741,7 @@ var _loadItemInfoForItem = function(/*CPOutlineView*/ anOutlineView, /*id*/ anIt
return [_outlineView._outlineViewDataSource outlineView:_outlineView writeItems:items toPasteboard:thePasteboard];
}
- (int)_childIndexForDropOperation:(CPTableViewDropOperation)theDropOperation row:(int)theRow offset:(CPPoint)theOffset
- (int)_childIndexForDropOperation:(CPTableViewDropOperation)theDropOperation row:(int)theRow offset:(CGPoint)theOffset
{
if (_outlineView._shouldRetargetChildIndex)
return _outlineView._retargedChildIndex;
@@ -1751,7 +1765,7 @@ var _loadItemInfoForItem = function(/*CPOutlineView*/ anOutlineView, /*id*/ anIt
return childIndex;
}
- (void)_parentItemForDropOperation:(CPTableViewDropOperation)theDropOperation row:(int)theRow offset:(CPPoint)theOffset
- (void)_parentItemForDropOperation:(CPTableViewDropOperation)theDropOperation row:(int)theRow offset:(CGPoint)theOffset
{
if (theDropOperation === CPTableViewDropAbove)
return [_outlineView _parentItemForUpperRow:theRow - 1 andLowerRow:theRow atMouseOffset:theOffset]
@@ -1823,21 +1837,6 @@ var _loadItemInfoForItem = function(/*CPOutlineView*/ anOutlineView, /*id*/ anIt
return self;
}
- (CPView)tableView:(CPTableView)theTableView dataViewForTableColumn:(CPTableColumn)theTableColumn row:(int)theRow
{
var dataView = nil;
if ((_outlineView._implementedOutlineViewDelegateMethods & CPOutlineViewDelegate_outlineView_dataViewForTableColumn_item_))
dataView = [_outlineView._outlineViewDelegate outlineView:_outlineView
dataViewForTableColumn:theTableColumn
item:[_outlineView itemAtRow:theRow]];
if (!dataView)
dataView = [theTableColumn dataViewForRow:theRow];
return dataView;
}
- (BOOL)tableView:(CPTableView)theTableView shouldSelectRow:(int)theRow
{
return SHOULD_SELECT_ITEM(_outlineView, [_outlineView itemAtRow:theRow]);
@@ -1894,6 +1893,17 @@ var _loadItemInfoForItem = function(/*CPOutlineView*/ anOutlineView, /*id*/ anIt
return [_outlineView menu] || [[_outlineView class] defaultMenu];
}
- (CPView)tableView:(CPTableView)aTableView dataViewForTableColumn:(CPTableColumn)aTableColumn row:(int)aRow
{
if ((_outlineView._implementedOutlineViewDelegateMethods & CPOutlineViewDelegate_outlineView_dataViewForTableColumn_item_))
{
var item = [_outlineView itemAtRow:aRow];
return [_outlineView._outlineViewDelegate outlineView:_outlineView dataViewForTableColumn:aTableColumn item:item]
}
return nil;
}
@end
@implementation CPDisclosureButton : CPButton
@@ -1945,9 +1955,8 @@ var _loadItemInfoForItem = function(/*CPOutlineView*/ anOutlineView, /*id*/ anIt
CGContextMoveToPoint(context, 0.0, 0.0);
CGContextAddLineToPoint(context, 9.0, 0.0);
CGContextAddLineToPoint(context, 4.5, 8.0);
CGContextAddLineToPoint(context, 0.0, 0.0);
CGContextClosePath(context);
CGContextSetFillColor(context,
colorForDisclosureTriangle([self hasThemeState:CPThemeStateSelected],
[self hasThemeState:CPThemeStateHighlighted]));
@@ -1955,8 +1964,8 @@ var _loadItemInfoForItem = function(/*CPOutlineView*/ anOutlineView, /*id*/ anIt
CGContextBeginPath(context);
CGContextMoveToPoint(context, 0.0, 0.0);
CGContextAddLineToPoint(context, 4.5, 8.0);
if (_angle === 0.0)
CGContextAddLineToPoint(context, 9.0, 0.0);
+5
View File
@@ -114,4 +114,9 @@ CPDocModalWindowMask = 1 << 6;
return NO;
}
- (BOOL)canBecomeKeyWindow
{
return YES;
}
@end
+9 -8
View File
@@ -22,6 +22,7 @@
@import <Foundation/CPObject.j>
@import <Foundation/CPArray.j>
@import <Foundation/CPData.j>
@import <Foundation/CPDictionary.j>
@import <Foundation/CPPropertyListSerialization.j>
@@ -78,7 +79,7 @@ var CPPasteboards = nil,
[self setVersion:1.0];
CPPasteboards = [CPDictionary dictionary];
CPPasteboards = @{};
if (typeof window.cpPasteboardWithName !== "undefined")
supportsNativePasteboard = YES;
@@ -117,11 +118,11 @@ var CPPasteboards = nil,
if (self)
{
_name = aName;
// _name = aName;
_types = [];
_owners = [CPDictionary dictionary];
_provided = [CPDictionary dictionary];
_owners = @{};
_provided = @{};
_changeCount = 0;
@@ -187,8 +188,8 @@ var CPPasteboards = nil,
{
[_types setArray:types];
_owners = [CPDictionary dictionary];
_provided = [CPDictionary dictionary];
_owners = @{};
_provided = @{};
var count = _types.length;
@@ -247,14 +248,14 @@ var CPPasteboards = nil,
// Determining Types
/*!
Checks the pasteboard's types for a match with the types listen in the specified array. The array should
Checks the pasteboard's types for a match with the types listed in the specified array. The array should
be ordered by the requestor's most preferred data type first.
@param anArray an array of requested types ordered by preference
@return the highest match with the pasteboard's supported types or \c nil if no match was found
*/
- (CPString)availableTypeFromArray:(CPArray)anArray
{
return [[self types] firstObjectCommonWithArray:anArray];
return [anArray firstObjectCommonWithArray:[self types]];
}
/*!
+2 -3
View File
@@ -20,8 +20,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@import <Foundation/CPGeometry.j>
@import "CGGeometry.j"
@import "CPButton.j"
@import "CPKeyValueBinding.j"
@import "CPMenu.j"
@@ -680,7 +679,7 @@ CPPopUpButtonStatePullsDown = CPThemeState("pulls-down");
if ([self pullsDown])
{
var positionedItem = nil,
location = CGPointMake(0.0, CGRectGetMaxY(bounds));
location = CGPointMake(0.0, CGRectGetMaxY(bounds) - 1);
}
else
{
+38 -49
View File
@@ -28,7 +28,7 @@
@import "CPImageView.j"
@import "CPResponder.j"
@import "CPView.j"
@import "_CPAttachedWindow.j"
@import "_CPPopoverWindow.j"
CPPopoverBehaviorApplicationDefined = 0;
@@ -45,7 +45,7 @@ var CPPopoverDelegate_popover_willShow_ = 1 << 0,
/*! @ingroup appkit
@class CPPopover
This class represent a widget that displays a attached
This class represent a widget that displays a popover
view relative to another one.
Delegate can implement:
@@ -67,7 +67,7 @@ var CPPopoverDelegate_popover_willShow_ = 1 << 0,
int _appearance @accessors(property=appearance);
int _behavior @accessors(getter=behavior);
_CPAttachedWindow _attachedWindow;
_CPPopoverWindow _popoverWindow;
int _implementedDelegateMethods;
}
@@ -103,9 +103,10 @@ var CPPopoverDelegate_popover_willShow_ = 1 << 0,
*/
- (CGRect)positioningRect
{
if (![_attachedWindow isVisible])
if (![_popoverWindow isVisible])
return CGRectMakeZero();
return [_attachedWindow frame];
return [_popoverWindow frame];
}
/*! Sets the frame of the popover
@@ -113,9 +114,10 @@ var CPPopoverDelegate_popover_willShow_ = 1 << 0,
*/
- (void)setPositioningRect:(CGRect)aRect
{
if (![_attachedWindow isVisible])
if (![_popoverWindow isVisible])
return;
[_attachedWindow setFrame:aRect];
[_popoverWindow setFrame:aRect];
}
/*!
@@ -125,8 +127,9 @@ var CPPopoverDelegate_popover_willShow_ = 1 << 0,
*/
- (CGSize)contentSize
{
if (![_attachedWindow isVisible])
if (![_popoverWindow isVisible])
return CGRectMakeZero();
return [[_contentViewController view] frameSize];
}
@@ -135,7 +138,7 @@ var CPPopoverDelegate_popover_willShow_ = 1 << 0,
@param aSize the desired size
*/
- (void)setContentSize:(CPSize)aSize
- (void)setContentSize:(CGSize)aSize
{
[[_contentViewController view] setFrameSize:aSize];
}
@@ -147,7 +150,7 @@ var CPPopoverDelegate_popover_willShow_ = 1 << 0,
*/
- (BOOL)isShown
{
return [_attachedWindow isVisible];
return [_popoverWindow isVisible];
}
/*!
@@ -164,7 +167,7 @@ Set the behavior of the CPPopover. It can be:
return;
_behavior = aBehavior;
[_attachedWindow setStyleMask:[self styleMaskForBehavior]];
[_popoverWindow setStyleMask:[self styleMaskForBehavior]];
}
- (void)setDelegate:(id)aDelegate
@@ -210,31 +213,26 @@ Set the behavior of the CPPopover. It can be:
[CPException raise:CPInternalInconsistencyException reason:@"contentViewController must not be nil"];
// If the popover is currently closing, do nothing. That is what Cocoa does.
if ([_attachedWindow isClosing])
if ([_popoverWindow isClosing])
return;
if (_implementedDelegateMethods & CPPopoverDelegate_popover_willShow_)
[_delegate popoverWillShow:self];
if (!_attachedWindow)
if (!_popoverWindow)
{
_attachedWindow = [[_CPAttachedWindow alloc] initWithContentRect:CGRectMakeZero() styleMask:[self styleMaskForBehavior]];
var parentWindow = [positioningView window];
if (![parentWindow isKindOfClass:_CPAttachedWindow])
[[CPNotificationCenter defaultCenter] addObserver:self selector:@selector(parentWindowWillClose:) name:CPWindowWillCloseNotification object:parentWindow];
_popoverWindow = [[_CPPopoverWindow alloc] initWithContentRect:CGRectMakeZero() styleMask:[self styleMaskForBehavior]];
}
[_attachedWindow setAppearance:_appearance];
[_attachedWindow setAnimates:_animates];
[_attachedWindow setDelegate:self];
[_attachedWindow setMovableByWindowBackground:NO];
[_attachedWindow setFrame:[_attachedWindow frameRectForContentRect:[[_contentViewController view] frame]]];
[_attachedWindow setContentView:[_contentViewController view]];
[_attachedWindow positionRelativeToRect:positioningRect ofView:positioningView preferredEdge:preferredEdge];
[_popoverWindow setAppearance:_appearance];
[_popoverWindow setAnimates:_animates];
[_popoverWindow setDelegate:self];
[_popoverWindow setMovableByWindowBackground:NO];
[_popoverWindow setFrame:[_popoverWindow frameRectForContentRect:[[_contentViewController view] frame]]];
[_popoverWindow setContentView:[_contentViewController view]];
[_popoverWindow positionRelativeToRect:positioningRect ofView:positioningView preferredEdge:preferredEdge];
if (_implementedDelegateMethods & CPPopoverDelegate_popover_didShow_)
if (!_animates && _implementedDelegateMethods & CPPopoverDelegate_popover_didShow_)
[_delegate popoverDidShow:self];
}
@@ -256,16 +254,16 @@ Set the behavior of the CPPopover. It can be:
*/
- (void)_close
{
if ([_attachedWindow isClosing] || ![self isShown])
if ([_popoverWindow isClosing] || ![self isShown])
return;
if (_implementedDelegateMethods & CPPopoverDelegate_popover_willClose_)
[_delegate popoverWillClose:self];
[_attachedWindow close];
[_popoverWindow close];
// popoverDidClose will be sent from attachedWindowDidClose, since
// the attached window will close asynchronously when animating.
// popoverDidClose will be sent from popoverWindowDidClose, since
// the popover window will close asynchronously when animating.
}
@@ -279,7 +277,7 @@ Set the behavior of the CPPopover. It can be:
*/
- (IBAction)performClose:(id)sender
{
if ([_attachedWindow isClosing])
if ([_popoverWindow isClosing])
return;
if (_implementedDelegateMethods & CPPopoverDelegate_popover_shouldClose_)
@@ -294,37 +292,28 @@ Set the behavior of the CPPopover. It can be:
#pragma mark Delegates
/*! @ignore */
- (BOOL)attachedWindowShouldClose:(_CPAttachedWindow)anAttachedWindow
- (BOOL)popoverWindowShouldClose:(_CPPopoverWindow)aPopoverWindow
{
[self performClose:self];
// We return NO, because we want the CPPopover to determine
// if the attached window can be closed and to give us a chance
// if the popover window can be closed and to give us a chance
// to send delegate messages.
return NO;
}
/*! @ignore */
- (void)attachedWindowDidClose:(_CPAttachedWindow)anAttachedWindow
- (void)popoverWindowDidClose:(_CPPopoverWindow)aPopoverWindow
{
if (_implementedDelegateMethods & CPPopoverDelegate_popover_didClose_)
[_delegate popoverDidClose:self];
}
#pragma mark -
#pragma mark Notifications
/*!
@ignore
This method is called only when a non-popover parent window
is closing. In that case popovers should order out.
*/
- (void)parentWindowWillClose:(CPNotification)aNotification
/*! @ignore */
- (void)popoverWindowDidShow:(_CPPopoverWindow)aPopoverWindow
{
[_attachedWindow orderOut:nil];
[self performClose:nil];
if (_implementedDelegateMethods & CPPopoverDelegate_popover_didShow_)
[_delegate popoverDidShow:self];
}
@end
@@ -340,7 +329,7 @@ Set the behavior of the CPPopover. It can be:
@end
var CPPopoverNeedsNewAttachedWindowKey = @"CPPopoverNeedsNewAttachedWindowKey",
var CPPopoverNeedsNewPopoverWindowKey = @"CPPopoverNeedsNewPopoverWindowKey",
CPPopoverAppearanceKey = @"CPPopoverAppearanceKey",
CPPopoverAnimatesKey = @"CPPopoverAnimatesKey",
CPPopoverContentViewControllerKey = @"CPPopoverContentViewControllerKey",
+113 -100
View File
@@ -23,29 +23,26 @@
@import "CGGeometry.j"
@import "CPImageView.j"
@import "CPView.j"
@import "CPWindow_Constants.j"
/*
@global
@group CPProgressIndicatorStyle
*/
CPProgressIndicatorBarStyle = 0;
CPProgressIndicatorBarStyle = 0;
/*
@global
@group CPProgressIndicatorStyle
*/
CPProgressIndicatorSpinningStyle = 1;
CPProgressIndicatorSpinningStyle = 1;
/*
@global
@group CPProgressIndicatorStyle
*/
CPProgressIndicatorHUDBarStyle = 2;
CPProgressIndicatorHUDBarStyle = 2;
var CPProgressIndicatorSpinningStyleColors = nil,
CPProgressIndicatorClassName = nil,
CPProgressIndicatorStyleIdentifiers = nil,
CPProgressIndicatorStyleSizes = nil;
var CPProgressIndicatorSpinningStyleColors = [];
/*!
@ingroup appkit
@@ -64,7 +61,7 @@ var CPProgressIndicatorSpinningStyleColors = nil,
CPControlSize _controlSize;
BOOL _isIndeterminate;
BOOL _indeterminate;
CPProgressIndicatorStyle _style;
BOOL _isAnimating;
@@ -73,66 +70,30 @@ var CPProgressIndicatorSpinningStyleColors = nil,
BOOL _isDisplayedWhenStopped;
}
/*
@ignore
*/
+ (void)initialize
+ (CPString)defaultThemeClass
{
if (self !== [CPProgressIndicator class])
return;
return @"progress-indicator";
}
var bundle = [CPBundle bundleForClass:self];
+ (CPDictionary)themeAttributes
{
return @{
@"indeterminate-bar-color": [CPNull null],
@"bar-color": [CPNull null],
@"default-height": 20,
@"bezel-color": [CPNull null],
@"spinning-mini-gif": [CPNull null],
@"spinning-small-gif": [CPNull null],
@"spinning-regular-gif": [CPNull null],
};
}
CPProgressIndicatorSpinningStyleColors = [];
+ (Class)_binderClassForBinding:(CPString)aBinding
{
if (aBinding === CPValueBinding || aBinding === @"isIndeterminate")
return [_CPProgressIndicatorBinder class];
CPProgressIndicatorSpinningStyleColors[CPMiniControlSize] = [CPColor colorWithPatternImage:[[CPImage alloc] initWithContentsOfFile:
[bundle pathForResource:@"CPProgressIndicator/CPProgressIndicatorSpinningStyleMini.gif"] size:CGSizeMake(16.0, 16.0)]];
CPProgressIndicatorSpinningStyleColors[CPSmallControlSize] = [CPColor colorWithPatternImage:[[CPImage alloc] initWithContentsOfFile:
[bundle pathForResource:@"CPProgressIndicator/CPProgressIndicatorSpinningStyleSmall.gif"] size:CGSizeMake(32.0, 32.0)]];
CPProgressIndicatorSpinningStyleColors[CPRegularControlSize] = [CPColor colorWithPatternImage:[[CPImage alloc] initWithContentsOfFile:
[bundle pathForResource:@"CPProgressIndicator/CPProgressIndicatorSpinningStyleRegular.gif"] size:CGSizeMake(64.0, 64.0)]];
CPProgressIndicatorBezelBorderViewPool = [];
var start = CPProgressIndicatorBarStyle,
end = CPProgressIndicatorHUDBarStyle;
for (; start <= end; ++start)
{
CPProgressIndicatorBezelBorderViewPool[start] = [];
CPProgressIndicatorBezelBorderViewPool[start][CPMiniControlSize] = [];
CPProgressIndicatorBezelBorderViewPool[start][CPSmallControlSize] = [];
CPProgressIndicatorBezelBorderViewPool[start][CPRegularControlSize] = [];
}
CPProgressIndicatorClassName = [self className];
CPProgressIndicatorStyleIdentifiers = [];
CPProgressIndicatorStyleIdentifiers[CPProgressIndicatorBarStyle] = @"Bar";
CPProgressIndicatorStyleIdentifiers[CPProgressIndicatorSpinningStyle] = @"Spinny";
CPProgressIndicatorStyleIdentifiers[CPProgressIndicatorHUDBarStyle] = @"HUDBar";
var regularIdentifier = _CPControlIdentifierForControlSize(CPRegularControlSize),
smallIdentifier = _CPControlIdentifierForControlSize(CPSmallControlSize),
miniIdentifier = _CPControlIdentifierForControlSize(CPMiniControlSize);
CPProgressIndicatorStyleSizes = [];
// Bar Style
var prefixes = [
CPProgressIndicatorClassName + @"BezelBorder" + CPProgressIndicatorStyleIdentifiers[CPProgressIndicatorBarStyle],
CPProgressIndicatorClassName + @"Bar" + CPProgressIndicatorStyleIdentifiers[CPProgressIndicatorBarStyle],
CPProgressIndicatorClassName + @"BezelBorder" + CPProgressIndicatorStyleIdentifiers[CPProgressIndicatorHUDBarStyle],
CPProgressIndicatorClassName + @"Bar" + CPProgressIndicatorStyleIdentifiers[CPProgressIndicatorHUDBarStyle]
];
for (var i = 0, count = prefixes.length; i < count; i++)
{
var prefix = prefixes[i];
CPProgressIndicatorStyleSizes[prefix + regularIdentifier] = [_CGSizeMake(3.0, 16.0), _CGSizeMake(1.0, 16.0), _CGSizeMake(3.0, 16.0)];
CPProgressIndicatorStyleSizes[prefix + smallIdentifier] = [_CGSizeMake(3.0, 16.0), _CGSizeMake(1.0, 16.0), _CGSizeMake(3.0, 16.0)];
CPProgressIndicatorStyleSizes[prefix + miniIdentifier] = [_CGSizeMake(3.0, 16.0), _CGSizeMake(1.0, 16.0), _CGSizeMake(3.0, 16.0)];
}
return [super _binderClassForBinding:aBinding];
}
- (id)initWithFrame:(CGRect)aFrame
@@ -151,8 +112,7 @@ var CPProgressIndicatorSpinningStyleColors = nil,
_controlSize = CPRegularControlSize;
[self updateBackgroundColor];
[self drawBar];
[self setNeedsLayout];
}
return self;
@@ -314,12 +274,12 @@ var CPProgressIndicatorSpinningStyleColors = nil,
Specifies whether this progress indicator should be indeterminate or display progress based on it's max and min.
@param isDeterminate \c YES makes the indicator indeterminate
*/
- (void)setIndeterminate:(BOOL)isIndeterminate
- (void)setIndeterminate:(BOOL)indeterminate
{
if (_isIndeterminate == isIndeterminate)
if (_indeterminate == indeterminate)
return;
_isIndeterminate = isIndeterminate;
_indeterminate = indeterminate;
[self updateBackgroundColor];
}
@@ -329,7 +289,7 @@ var CPProgressIndicatorSpinningStyleColors = nil,
*/
- (BOOL)isIndeterminate
{
return _isIndeterminate;
return _indeterminate;
}
/*!
@@ -343,6 +303,8 @@ var CPProgressIndicatorSpinningStyleColors = nil,
_style = aStyle;
[self setTheme:(_style === CPProgressIndicatorHUDBarStyle) ? [CPTheme defaultHudTheme] : [CPTheme defaultTheme]];
[self updateBackgroundColor];
}
@@ -354,8 +316,7 @@ var CPProgressIndicatorSpinningStyleColors = nil,
if (_style == CPProgressIndicatorSpinningStyle)
[self setFrameSize:[[CPProgressIndicatorSpinningStyleColors[_controlSize] patternImage] size]];
else
[self setFrameSize:CGSizeMake(CGRectGetWidth([self frame]), CPProgressIndicatorStyleSizes[
CPProgressIndicatorClassName + @"BezelBorder" + CPProgressIndicatorStyleIdentifiers[CPProgressIndicatorBarStyle] + _CPControlIdentifierForControlSize(_controlSize)][0].height)];
[self setFrameSize:CGSizeMake(CGRectGetWidth([self frame]), [self valueForThemeAttribute:@"default-height"])];
}
/*!
@@ -405,20 +366,7 @@ var CPProgressIndicatorSpinningStyleColors = nil,
/* @ignore */
- (void)drawBar
{
if (_style == CPProgressIndicatorSpinningStyle)
return;
var barView = [self layoutEphemeralSubviewNamed:"bar-view"
positioned:CPWindowBelow
relativeToEphemeralSubviewNamed:nil];
[barView setBackgroundColor:_CPControlThreePartImagePattern(
NO,
CPProgressIndicatorStyleSizes,
CPProgressIndicatorClassName,
@"Bar",
CPProgressIndicatorStyleIdentifiers[_style],
_CPControlIdentifierForControlSize(_controlSize))];
[self setNeedsLayout];
}
- (CPView)createEphemeralSubviewNamed:(CPString)aName
@@ -436,7 +384,10 @@ var CPProgressIndicatorSpinningStyleColors = nil,
if (barWidth > 0.0 && barWidth < 4.0)
barWidth = 4.0;
return _CGRectMake(0, 0, barWidth, 16.0);
if (_indeterminate)
barWidth = width;
return _CGRectMake(0, 0, barWidth, [self valueForThemeAttribute:@"default-height"]);
}
return nil;
@@ -444,6 +395,18 @@ var CPProgressIndicatorSpinningStyleColors = nil,
/* @ignore */
- (void)updateBackgroundColor
{
if ([CPProgressIndicatorSpinningStyleColors count] === 0)
{
CPProgressIndicatorSpinningStyleColors[CPMiniControlSize] = [self valueForThemeAttribute:@"spinning-mini-gif"];
CPProgressIndicatorSpinningStyleColors[CPSmallControlSize] = [self valueForThemeAttribute:@"spinning-small-gif"];
CPProgressIndicatorSpinningStyleColors[CPRegularControlSize] = [self valueForThemeAttribute:@"spinning-regular-gif"];
}
[self setNeedsLayout];
}
- (void)layoutSubviews
{
if (YES)//_isBezeled)
{
@@ -458,15 +421,16 @@ var CPProgressIndicatorSpinningStyleColors = nil,
}
else
{
[self setBackgroundColor:_CPControlThreePartImagePattern(
NO,
CPProgressIndicatorStyleSizes,
CPProgressIndicatorClassName,
@"BezelBorder",
CPProgressIndicatorStyleIdentifiers[_style],
_CPControlIdentifierForControlSize(_controlSize))];
[self setBackgroundColor:[self currentValueForThemeAttribute:@"bezel-color"]];
[self drawBar];
var barView = [self layoutEphemeralSubviewNamed:"bar-view"
positioned:CPWindowBelow
relativeToEphemeralSubviewNamed:nil];
if (_indeterminate)
[barView setBackgroundColor:[self currentValueForThemeAttribute:@"indeterminate-bar-color"]];
else
[barView setBackgroundColor:[self currentValueForThemeAttribute:@"bar-color"]];
}
}
else
@@ -486,7 +450,7 @@ var CPProgressIndicatorSpinningStyleColors = nil,
_maxValue = [aCoder decodeObjectForKey:@"_maxValue"];
_doubleValue = [aCoder decodeObjectForKey:@"_doubleValue"];
_controlSize = [aCoder decodeObjectForKey:@"_controlSize"];
_isIndeterminate = [aCoder decodeObjectForKey:@"_isIndeterminate"];
_indeterminate = [aCoder decodeObjectForKey:@"_indeterminate"];
_style = [aCoder decodeIntForKey:@"_style"];
_isAnimating = [aCoder decodeObjectForKey:@"_isAnimating"];
_isDisplayedWhenStoppedSet = [aCoder decodeObjectForKey:@"_isDisplayedWhenStoppedSet"];
@@ -500,8 +464,8 @@ var CPProgressIndicatorSpinningStyleColors = nil,
- (void)encodeWithCoder:(CPCoder)aCoder
{
// Don't encode the background colour. It can be recreated based on the flags and if encoded causes hardcoded
// image paths in the cib while just wasting space.
// Don't encode the background colour. It can be recreated based on the flags
// and if encoded causes hardcoded image paths in the cib while just wasting space.
var backgroundColor = [self backgroundColor];
[self setBackgroundColor:nil];
[super encodeWithCoder:aCoder];
@@ -511,7 +475,7 @@ var CPProgressIndicatorSpinningStyleColors = nil,
[aCoder encodeObject:_maxValue forKey:@"_maxValue"];
[aCoder encodeObject:_doubleValue forKey:@"_doubleValue"];
[aCoder encodeObject:_controlSize forKey:@"_controlSize"];
[aCoder encodeObject:_isIndeterminate forKey:@"_isIndeterminate"];
[aCoder encodeObject:_indeterminate forKey:@"_indeterminate"];
[aCoder encodeInt:_style forKey:@"_style"];
[aCoder encodeObject:_isAnimating forKey:@"_isAnimating"];
[aCoder encodeObject:_isDisplayedWhenStoppedSet forKey:@"_isDisplayedWhenStoppedSet"];
@@ -519,3 +483,52 @@ var CPProgressIndicatorSpinningStyleColors = nil,
}
@end
@implementation _CPProgressIndicatorBinder : CPBinder
- (void)_updatePlaceholdersWithOptions:(CPDictionary)options forBinding:(CPString)aBinding
{
var value = aBinding === CPValueBinding ? 0.0 : YES;
[self _setPlaceholder:value forMarker:CPMultipleValuesMarker isDefault:YES];
[self _setPlaceholder:value forMarker:CPNoSelectionMarker isDefault:YES];
[self _setPlaceholder:value forMarker:CPNotApplicableMarker isDefault:YES];
[self _setPlaceholder:value forMarker:CPNullMarker isDefault:YES];
}
- (id)valueForBinding:(CPString)aBinding
{
if (aBinding === CPValueBinding)
return [_source doubleValue];
else if (aBinding === @"isIndeterminate")
[_source isIndeterminate];
else
return [super valueForBinding:aBinding];
}
- (BOOL)_setValue:(id)aValue forBinding:(CPString)aBinding
{
if (aBinding === CPValueBinding)
[_source setDoubleValue:aValue];
else if (aBinding === @"isIndeterminate")
[_source setIndeterminate:aValue];
else
return NO;
return YES;
}
- (void)setValue:(id)aValue forBinding:(CPString)aBinding
{
if (![self _setValue:aValue forBinding:aBinding])
[super setValue:aValue forBinding:aBinding];
}
- (void)setPlaceholderValue:(id)aValue withMarker:(CPString)aMarker forBinding:(CPString)aBinding
{
if (![self _setValue:aValue forBinding:aBinding])
[super setPlaceholderValue:aValue withMarker:aMarker forBinding:aBinding];
}
@end
+212 -13
View File
@@ -25,6 +25,8 @@
@import "CPButton.j"
@global CPApp
/*!
@ingroup appkit
@@ -202,29 +204,122 @@ var CPRadioRadioGroupKey = @"CPRadioRadioGroupKey";
@implementation CPRadioGroup : CPObject
{
CPSet _radios;
CPArray _radios;
CPRadio _selectedRadio;
BOOL _enabled @accessors(getter=enabled);
BOOL _hidden @accessors(getter=hidden);
id _target @accessors(property=target);
SEL _action @accessors(property=action);
}
+ (void)initialize
{
if (self !== [CPRadioGroup class])
return;
[self exposeBinding:CPSelectedValueBinding];
[self exposeBinding:CPSelectedTagBinding];
[self exposeBinding:CPSelectedIndexBinding];
[self exposeBinding:CPEnabledBinding];
[self exposeBinding:CPHiddenBinding];
}
- (id)init
{
self = [super init];
if (self)
{
_radios = [CPSet set];
_radios = [];
_selectedRadio = nil;
_enabled = YES;
_hidden = NO;
}
return self;
}
/*!
Selects the radio button at the given index within the group.
If index is -1, all of the radio buttons are turned off.
*/
- (void)selectRadioAtIndex:(int)index
{
if (index === -1)
[self _setSelectedRadio:nil];
else
{
var radio = [_radios objectAtIndex:index];
[self _setSelectedRadio:radio];
[radio setState:CPOnState];
}
}
/*!
Selects the first radio button within the group with the given tag.
If a radio button with the given tag is found, selects it
and returns YES. Otherwise returns NO.
*/
- (BOOL)selectRadioWithTag:(int)tag
{
var index = [_radios indexOfObjectPassingTest:function(radio)
{
return [radio tag] === tag;
}];
if (index !== CPNotFound)
{
[self selectRadioAtIndex:index];
return YES;
}
else
return NO;
}
/*!
Returns the CPRadio that is currently selected within the group,
or nil if none are selected.
*/
- (CPRadio)selectedRadio
{
return _selectedRadio;
}
/*!
Returns the index of the selected radio within the array of radio buttons.
Buttons are numbered going left to right and top to bottom. Returns -1
if no radio within the group is selected.
*/
- (int)selectedRadioIndex
{
return [_radios indexOfObject:_selectedRadio];
}
- (CPArray)radios
{
return _radios;
}
- (void)setEnabled:(BOOL)enabled
{
[_radios makeObjectsPerformSelector:@selector(setEnabled:) withObject:enabled];
}
- (void)setHidden:(BOOL)hidden
{
[_radios makeObjectsPerformSelector:@selector(setHidden:) withObject:hidden];
}
#pragma mark Private
- (void)_addRadio:(CPRadio)aRadio
{
[_radios addObject:aRadio];
if ([_radios indexOfObject:aRadio] === CPNotFound)
[_radios addObject:aRadio];
if ([aRadio state] === CPOnState)
[self _setSelectedRadio:aRadio];
@@ -238,23 +333,30 @@ var CPRadioRadioGroupKey = @"CPRadioRadioGroupKey";
[_radios removeObject:aRadio];
}
/*!
Selects the first radio button within the group with the given tag.
If a radio button with the given tag is found, selects it
and returns YES. Otherwise returns NO.
*/
- (void)_selectRadioWithTitle:(CPString)aTitle
{
var index = [_radios indexOfObjectPassingTest:function(radio)
{
return [radio title] === aTitle;
}];
[self selectRadioAtIndex:index];
}
- (void)_setSelectedRadio:(CPRadio)aRadio
{
if (_selectedRadio === aRadio)
return;
[_selectedRadio setState:CPOffState];
_selectedRadio = aRadio;
}
- (CPRadio)selectedRadio
{
return _selectedRadio;
}
- (CPArray)radios
{
return [_radios allObjects];
[_CPRadioGroupSelectionBinder reverseSetValueForObject:self];
}
@end
@@ -284,3 +386,100 @@ var CPRadioGroupRadiosKey = @"CPRadioGroupRadiosKey",
}
@end
@implementation CPRadioGroup (BindingSupport)
+ (Class)_binderClassForBinding:(CPString)aBinding
{
if (aBinding === CPSelectedValueBinding ||
aBinding === CPSelectedTagBinding ||
aBinding === CPSelectedIndexBinding)
{
var capitalizedBinding = aBinding.charAt(0).toUpperCase() + aBinding.substr(1);
return [CPClassFromString(@"_CPRadioGroup" + capitalizedBinding + "Binder") class];
}
else if ([aBinding hasPrefix:CPEnabledBinding])
return [CPMultipleValueAndBinding class];
else if ([aBinding hasPrefix:CPHiddenBinding])
return [CPMultipleValueOrBinding class];
return [super _binderClassForBinding:aBinding];
}
@end
var binderForObject = {};
@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
{
[self setValue:aValue forBinding:aBinding];
}
@end
@implementation _CPRadioGroupSelectedIndexBinder : _CPRadioGroupSelectionBinder
- (void)setValue:(id)aValue forBinding:(CPString)aBinding
{
[_source selectRadioAtIndex:aValue];
}
- (id)valueForBinding:(CPString)aBinding
{
return [_source selectedRadioIndex];
}
@end
@implementation _CPRadioGroupSelectedTagBinder : _CPRadioGroupSelectionBinder
- (void)setValue:(id)aValue forBinding:(CPString)aBinding
{
[_source selectRadioWithTag:aValue];
}
- (id)valueForBinding:(CPString)aBinding
{
return [[_source selectedRadio] tag];
}
@end
@implementation _CPRadioGroupSelectedValueBinder : _CPRadioGroupSelectionBinder
- (void)setValue:(id)aValue forBinding:(CPString)aBinding
{
[_source _selectRadioWithTitle:aValue];
}
- (id)valueForBinding:(CPString)aBinding
{
return [[_source selectedRadio] title];
}
@end
+4
View File
@@ -21,7 +21,11 @@
*/
@import <Foundation/CPObject.j>
@import <Foundation/CPObjJRuntime.j>
@import "CPEvent.j"
@class CPKeyBinding
CPDeleteKeyCode = 8;
CPTabKeyCode = 9;
+10 -6
View File
@@ -82,15 +82,15 @@
}
/*! @cond */
+ (Class)_binderClassForBinding:(CPString)theBinding
+ (Class)_binderClassForBinding:(CPString)aBinding
{
if (theBinding == CPValueBinding)
if (aBinding == CPValueBinding)
return [CPPredicateEditorValueBinder class];
return [super _binderClassForBinding:theBinding];
return [super _binderClassForBinding:aBinding];
}
- (id)_replacementKeyPathForBinding:(CPString)aBinding
- (CPString)_replacementKeyPathForBinding:(CPString)aBinding
{
if (aBinding == CPValueBinding)
return @"predicate";
@@ -220,7 +220,7 @@
var children = [CPArray array],
itemsCount = 0,
menuIndex = -1,
itemsArray,
itemArray,
templateView = [templateViews objectAtIndex:count],
isPopup = [templateView isKindOfClass:[CPPopUpButton class]];
@@ -360,7 +360,11 @@
rootItems = [treeChild children];
}
var row = [CPDictionary dictionaryWithObjectsAndKeys:criteria, @"criteria", values, @"displayValues", rowType, @"rowType"];
var row = @{
@"criteria": criteria,
@"displayValues": values,
@"rowType": rowType,
};
return row;
}
@@ -20,6 +20,17 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@import <Foundation/CPPredicate.j>
@import "CPCheckBox.j"
@import "CPPopUpButton.j"
@import "CPMenuItem.j"
@import "CPTextField.j"
// NOTE: CPDatePicker is not implemented yet
@class CPDatePicker
CPUndefinedAttributeType = 0;
CPInteger16AttributeType = 100;
CPInteger32AttributeType = 200;
@@ -583,7 +594,7 @@ CPTransformableAttributeType = 1800;
- (CPPopUpButton)_viewFromExpressions:(CPArray)expressions
{
var popup = [[CPPopUpButton alloc] initWithFrame:CPMakeRect(0, 0, 100, 18)],
var popup = [[CPPopUpButton alloc] initWithFrame:CGRectMake(0, 0, 100, 18)],
count = [expressions count];
for (var i = 0; i < count; i++)
+38 -49
View File
@@ -20,35 +20,26 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@import <AppKit/CPTextField.j>
@import <AppKit/CPViewAnimation.j>
@import <AppKit/CPView.j>
@import <Foundation/CPPredicate.j>
@import <Foundation/CPArray.j>
@import <Foundation/CPDictionary.j>
@import <Foundation/CPIndexSet.j>
@import "CPPasteboard.j"
@import "CPRuleEditor_Constants.j"
@import "CPTextField.j"
@import "CPViewAnimation.j"
@import "CPView.j"
@import "_CPRuleEditorViewSliceRow.j"
@import "_CPRuleEditorLocalizer.j"
CPRuleEditorPredicateLeftExpression = "CPRuleEditorPredicateLeftExpression";
CPRuleEditorPredicateRightExpression = "CPRuleEditorPredicateRightExpression";
CPRuleEditorPredicateComparisonModifier = "CPRuleEditorPredicateComparisonModifier";
CPRuleEditorPredicateOptions = "CPRuleEditorPredicateOptions";
CPRuleEditorPredicateOperatorType = "CPRuleEditorPredicateOperatorType";
CPRuleEditorPredicateCustomSelector = "CPRuleEditorPredicateCustomSelector";
CPRuleEditorPredicateCompoundType = "CPRuleEditorPredicateCompoundType";
@class CPCompoundPredicate
@class CPComparisonPredicate
CPRuleEditorRowsDidChangeNotification = "CPRuleEditorRowsDidChangeNotification";
CPRuleEditorRulesDidChangeNotification = "CPRuleEditorRulesDidChangeNotification";
CPRuleEditorNestingModeSingle = 0; // Only a single row is allowed. Plus/minus buttons will not be shown
CPRuleEditorNestingModeList = 1; // Allows a single list, with no nesting and no compound rows
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
CPRuleEditorRowTypeSimple = 0;
CPRuleEditorRowTypeCompound = 1;
@global CPDirectPredicateModifier
@global CPCaseInsensitivePredicateOption
@global CPOrPredicateType
var CPRuleEditorItemPBoardType = @"CPRuleEditorItemPBoardType",
itemsContext = "items",
@@ -133,8 +124,16 @@ var CPRuleEditorItemPBoardType = @"CPRuleEditorItemPBoardType",
+ (id)themeAttributes
{
return [CPDictionary dictionaryWithObjects:[[CPNull null], [CPNull null], [CPNull null], [CPNull null], [CPNull null], [CPNull null], [CPNull null], [CPNull null]]
forKeys:[@"alternating-row-colors", @"selected-color", @"slice-top-border-color", @"slice-bottom-border-color", @"slice-last-bottom-border-color", @"font", @"add-image", @"remove-image"]];
return @{
@"alternating-row-colors": [CPNull null],
@"selected-color": [CPNull null],
@"slice-top-border-color": [CPNull null],
@"slice-bottom-border-color": [CPNull null],
@"slice-last-bottom-border-color": [CPNull null],
@"font": [CPNull null],
@"add-image": [CPNull null],
@"remove-image": [CPNull null],
};
}
- (id)initWithFrame:(CGRect)frame
@@ -800,7 +799,7 @@ TODO: implement
*/
- (CPPredicate)predicateForRow:(CPInteger)aRow
{
var predicateParts = [CPDictionary dictionary],
var predicateParts = @{},
items = [self criteriaForRow:aRow],
count = [items count],
predicate,
@@ -1396,7 +1395,10 @@ TODO: implement
{
var item = [items objectAtIndex:i],
value = [values objectAtIndex:i],
itemAndValue = [CPDictionary dictionaryWithObjects:[item, value] forKeys:["item", "value"]];
itemAndValue = @{
"item": item,
"value": value,
};
[itemsAndValues addObject:itemAndValue];
}
@@ -1512,23 +1514,10 @@ TODO: implement
oldRows = [CPArray arrayWithArray:newRows];
[oldRows removeObjectsInArray:changeNewValue];
}
else if (changeKind === CPKeyValueChangeRemoval)
{
newRows = [self _subrowObjectsOfObject:object];
oldRows = [CPArray arrayWithArray:newRows];
var delIndexes = [change objectForKey:CPKeyValueChangeIndexesKey];
[oldRows insertObjects:delObjects atIndexes:changeOldValue]; // Pas sur que ce soit bon
}
[self _changedRowArray:newRows withOldRowArray:oldRows forParent:object];
[self _reconfigureSubviewsAnimate:[self _wantsRowAnimations]];
}
else if (context === itemsContext)
{
}
else if (context === valuesContext)
{
}
}
- (void)_changedItem:(id)fromItem toItem:(id)toItem inRow:(int)aRow atCriteriaIndex:(int)fromItemIndex
@@ -1703,8 +1692,8 @@ TODO: implement
- (void)_setBoundDataSource:(id)datasource withKeyPath:(CPString)keyPath options:(CPDictionary)options
{
if ([observableController respondsToSelector:@selector(objectClass)])
_rowClass = [observableController objectClass];
if ([datasource respondsToSelector:@selector(objectClass)])
_rowClass = [datasource objectClass];
_boundArrayKeyPath = keyPath;
_boundArrayOwner = datasource;
@@ -1793,7 +1782,7 @@ TODO: implement
if (animate)
{
var animation = [CPDictionary dictionary];
var animation = @{};
[animation setObject:aslice forKey:CPViewAnimationTargetKey];
[animation setObject:startRect forKey:CPViewAnimationStartFrameKey];
[animation setObject:targetRect forKey:CPViewAnimationEndFrameKey];
@@ -1888,17 +1877,17 @@ TODO: implement
- (CPString)_toolTipForAddCompoundRowButton
{
return @"Add Compound row";
return [_standardLocalizer localizedStringForString:@"Add compound row"];
}
- (CPString)_toolTipForAddSimpleRowButton
{
return @"Add row";
return [_standardLocalizer localizedStringForString:@"Add row"];
}
- (CPString)_toolTipForDeleteRowButton
{
return @"Delete row";
return [_standardLocalizer localizedStringForString:@"Delete row"];
}
- (void)_updateSliceIndentations
@@ -2058,7 +2047,7 @@ TODO: implement
[super setNeedsDisplay:flag];
}
- (void)setFrameSize:(CPSize)size
- (void)setFrameSize:(CGSize)size
{
[self setNeedsDisplay:YES];
@@ -2126,7 +2115,7 @@ TODO: implement
[dragview setBackgroundColor:[firstSlice backgroundColor]];
[dragview setAlphaValue:0.7];
dragPoint = CPMakePoint(0, firstIndex * _sliceHeight);
dragPoint = CGPointMake(0, firstIndex * _sliceHeight);
[self dragView:dragview
at:dragPoint
@@ -2188,7 +2177,7 @@ TODO: implement
if (_subviewIndexOfDropLine !== CPNotFound && _subviewIndexOfDropLine < numberOfRows)
{
var previousBelowSlice = [_slices objectAtIndex:_subviewIndexOfDropLine];
[previousBelowSlice setFrameOrigin:CPMakePoint(0, [previousBelowSlice rowIndex] * _sliceHeight)];
[previousBelowSlice setFrameOrigin:CGPointMake(0, [previousBelowSlice rowIndex] * _sliceHeight)];
}
if (indexOfDropLine <= _lastRow && indexOfDropLine < numberOfRows)
@@ -2254,7 +2243,7 @@ TODO: implement
return [CPIndexSet indexSetWithIndex:CPDragOperationMove];
}
- (void)draggedView:(CPView)dragView endedAt:(CPPoint)aPoint operation:(CPDragOperation)operation
- (void)draggedView:(CPView)dragView endedAt:(CGPoint)aPoint operation:(CPDragOperation)operation
{
_draggingRows = nil;
@@ -2290,7 +2279,7 @@ TODO: implement
- (void)_postRowCountChangedNotificationOfType:(CPString)notificationName indexes:indexes
{
var userInfo = [CPDictionary dictionaryWithObject:indexes forKey:"indexes"];
var userInfo = @{ "indexes": indexes };
[[CPNotificationCenter defaultCenter] postNotificationName:notificationName object:self userInfo:userInfo];
}
@@ -2578,7 +2567,7 @@ var dropSeparatorColor = [CPColor colorWithHexString:@"4886ca"];
{
}
- (void)drawRect:(CPRect)rect
- (void)drawRect:(CGRect)rect
{
var context = [[CPGraphicsContext currentContext] graphicsPort];
CGContextSetFillColor(context, dropSeparatorColor);
@@ -0,0 +1,40 @@
/*
* CPRuleEditor_Constants.j
* AppKit
*
* Created by cacaodev.
* Copyright 2011, cacaodev.
*
* 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
*/
CPRuleEditorPredicateLeftExpression = "CPRuleEditorPredicateLeftExpression";
CPRuleEditorPredicateRightExpression = "CPRuleEditorPredicateRightExpression";
CPRuleEditorPredicateComparisonModifier = "CPRuleEditorPredicateComparisonModifier";
CPRuleEditorPredicateOptions = "CPRuleEditorPredicateOptions";
CPRuleEditorPredicateOperatorType = "CPRuleEditorPredicateOperatorType";
CPRuleEditorPredicateCustomSelector = "CPRuleEditorPredicateCustomSelector";
CPRuleEditorPredicateCompoundType = "CPRuleEditorPredicateCompoundType";
CPRuleEditorRowsDidChangeNotification = "CPRuleEditorRowsDidChangeNotification";
CPRuleEditorRulesDidChangeNotification = "CPRuleEditorRulesDidChangeNotification";
CPRuleEditorNestingModeSingle = 0; // Only a single row is allowed. Plus/minus buttons will not be shown
CPRuleEditorNestingModeList = 1; // Allows a single list, with no nesting and no compound rows
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
CPRuleEditorRowTypeSimple = 0;
CPRuleEditorRowTypeCompound = 1;
@@ -1,9 +1,25 @@
/*
* Created by cacaodev@gmail.com.
* Copyright (c) 2011 Pear, Inc. All rights reserved.
* 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
*/
@class _CPPredicateEditorTree;
@import <Foundation/CPObject.j>
@import <Foundation/CPString.j>
@implementation _CPPredicateEditorRowNode : CPObject
{
_CPPredicateEditorTree tree @accessors;
+19 -2
View File
@@ -1,8 +1,25 @@
/*
* Created by cacaodev@gmail.com.
* Copyright (c) 2011 Pear, Inc. All rights reserved.
* 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 <Foundation/CPObject.j>
@import <Foundation/CPString.j>
@implementation _CPPredicateEditorTree : CPObject
{
CPPredicateEditorRowTemplate template @accessors;
+22 -4
View File
@@ -1,11 +1,27 @@
/*
* Created by cacaodev@gmail.com.
* Copyright (c) 2011 Pear, Inc. All rights reserved.
* 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 <Foundation/CPObject.j>
@import <Foundation/CPDictionary.j>
@import <Foundation/CPString.j>
@import <Foundation/CPURLConnection.j>
@import <Foundation/CPURLRequest.j>
var LocalizerStringsRegex = new RegExp("\"(.+)\"\\s*=\\s*\"(.+)\"\\s*;\\s*(//.+)?");
@@ -13,7 +29,7 @@ var LocalizerStringsRegex = new RegExp("\"(.+)\"\\s*=\\s*\"(.+)\"\\s*;\\s*(//.+)
{
CPDictionary _dictionary @accessors(property=dictionary);
CPURLConnection connection;
CPURLRequest resquest;
CPURLRequest request;
}
- (void)loadContentOfURL:(CPURL)aURL
@@ -43,7 +59,7 @@ var LocalizerStringsRegex = new RegExp("\"(.+)\"\\s*=\\s*\"(.+)\"\\s*;\\s*(//.+)
- (void)loadContent:(CPString)aContent
{
var dict = [CPDictionary dictionary],
var dict = @{},
lines = [aContent componentsSeparatedByString:"\n"],
count = [lines count];
@@ -77,3 +93,5 @@ var LocalizerStringsRegex = new RegExp("\"(.+)\"\\s*=\\s*\"(.+)\"\\s*;\\s*(//.+)
return aString;
}
@end
+31 -4
View File
@@ -1,8 +1,27 @@
/*
* Created by cacaodev@gmail.com.
* Copyright (c) 2011 Pear, Inc. All rights reserved.
* 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";
@@ -44,9 +63,11 @@ else if (CPBrowserIsEngine(CPInternetExplorerBrowserEngine))
{
[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
@@ -65,9 +86,9 @@ else if (CPBrowserIsEngine(CPInternetExplorerBrowserEngine))
return self;
}
- (id)hitTest:(CPPoint)point
- (id)hitTest:(CGPoint)point
{
if (!CPRectContainsPoint([self frame], point) || ![self sliceIsEditable])
if (!CGRectContainsPoint([self frame], point) || ![self sliceIsEditable])
return nil;
return self;
@@ -98,11 +119,13 @@ else if (CPBrowserIsEngine(CPInternetExplorerBrowserEngine))
- (void)layoutSubviews
{
#if PLATFORM(DOM)
radius = FLOOR(CGRectGetHeight([self bounds]) / 2);
var style = _DOMElement.style,
radiusCSS = radius + "px";
style.borderRadius = radiusCSS;
#endif
[super layoutSubviews];
}
@@ -139,9 +162,11 @@ else if (CPBrowserIsEngine(CPInternetExplorerBrowserEngine))
{
[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
@@ -162,6 +187,7 @@ else if (CPBrowserIsEngine(CPInternetExplorerBrowserEngine))
- (void)layoutSubviews
{
#if PLATFORM(DOM)
radius = FLOOR(CGRectGetHeight([self bounds]) / 2);
var style = _DOMElement.style,
@@ -169,6 +195,7 @@ else if (CPBrowserIsEngine(CPInternetExplorerBrowserEngine))
style.borderRadius = radiusCSS;
style[GRADIENT_PROPERTY] = ([self isHighlighted]) ? GRADIENT_HIGHLIGHTED : GRADIENT_NORMAL;
#endif
[super layoutSubviews];
}
+28 -11
View File
@@ -1,17 +1,34 @@
/*
* Created by cacaodev@gmail.com.
* Copyright (c) 2011 Pear, Inc. All rights reserved.
* 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 "CPView.j"
@implementation _CPRuleEditorViewSlice : CPView
{
CPRuleEditor _ruleEditor;
int _indentation @accessors(property=indentation);
int _rowIndex @accessors(property=rowIndex);
CPRect _animationTargetRect @accessors(property=_animationTargetRect);
CGRect _animationTargetRect @accessors(property=_animationTargetRect);
BOOL _selected @accessors(getter=_isSelected, setter=_setSelected:);
BOOL _lastSelected @accessors(getter=_isLastSelected, setter=_setLastSelected:);
CPColor _backgroundColor @accessors(property=backgroundColor);
BOOL _editable @accessors(getter=isEditable, setter=setEditable:);
}
- (void)removeFromSuperview
@@ -41,14 +58,14 @@
_selected = select;
}
- (void)drawRect:(CPRect)rect
- (void)drawRect:(CGRect)rect
{
var context = [[CPGraphicsContext currentContext] graphicsPort],
bounds = [self bounds],
maxX = CGRectGetWidth(bounds),
maxY = CGRectGetHeight(bounds);
// Draw background
// Draw background
if ([self _isSelected])
_backgroundColor = [_ruleEditor _selectedRowColor];
else
@@ -61,33 +78,33 @@
CGContextSetFillColor(context, _backgroundColor);
CGContextFillRect(context, rect);
// Draw Top Border
// Draw Top Border
CGContextBeginPath(context);
CGContextMoveToPoint(context, 0, 0);
CGContextAddLineToPoint(context, maxX, 0);
CGContextClosePath(context);
CGContextSetStrokeColor(context, [_ruleEditor _sliceTopBorderColor]);
CGContextStrokePath(context);
// Draw Bottom Border
// Draw Bottom Border
CGContextBeginPath(context);
CGContextMoveToPoint(context, 0, maxY);
CGContextAddLineToPoint(context, maxX, maxY);
CGContextClosePath(context);
var bottomColor = (_rowIndex == [_ruleEditor _lastRow]) ? [_ruleEditor _sliceLastBottomBorderColor] : [_ruleEditor _sliceBottomBorderColor];
CGContextSetStrokeColor(context, bottomColor);
CGContextStrokePath(context);
}
- (void)mouseDown:(CPEvent)theEvent
{
if (editable)
if (_editable)
[_ruleEditor _mouseDownOnSlice:self withEvent:theEvent];
}
- (void)mouseUp:(CPEvent)theEvent
{
if (editable)
if (_editable)
[_ruleEditor _mouseUpOnSlice:self withEvent:theEvent];
}
+40 -41
View File
@@ -1,11 +1,27 @@
/*
* Created by cacaodev@gmail.com.
* Copyright (c) 2011 Pear, Inc. All rights reserved.
* 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 "CPRuleEditor_Constants.j"
@import "_CPRuleEditorViewSlice.j"
@import "_CPRuleEditorPopUpButton.j"
@import "CPRuleEditor.j"
@global CPApp
var CONTROL_HEIGHT = 16.,
BUTTON_HEIGHT = 16.;
@@ -18,7 +34,7 @@ var CONTROL_HEIGHT = 16.,
CPMutableArray _ruleOptionInitialViewFrames;
CPButton _addButton;
CPButton _subtractButton;
BOOL editable;
CPRuleEditorRowType _rowType @accessors;
CPRuleEditorRowType _plusButtonRowType;
}
@@ -37,14 +53,14 @@ var CONTROL_HEIGHT = 16.,
_ruleOptionFrames = [[CPMutableArray alloc] init];
_ruleOptionInitialViewFrames = [[CPMutableArray alloc] init];
_ruleOptionViews = [[CPMutableArray alloc] init];
editable = [_ruleEditor isEditable];
_editable = [_ruleEditor isEditable];
_addButton = [self _createAddRowButton];
_subtractButton = [self _createDeleteRowButton];
[_addButton setToolTip:[_ruleEditor _toolTipForAddSimpleRowButton]];
[_subtractButton setToolTip:[_ruleEditor _toolTipForDeleteRowButton]];
[_addButton setHidden:!editable];
[_subtractButton setHidden:!editable];
[_addButton setHidden:!_editable];
[_subtractButton setHidden:!_editable];
[self addSubview:_addButton];
[self addSubview:_subtractButton];
@@ -123,15 +139,16 @@ var CONTROL_HEIGHT = 16.,
- (_CPRuleEditorTextField)_createStaticTextFieldWithStringValue:(CPString)text
{
var textField = [[_CPRuleEditorTextField alloc] initWithFrame:CPMakeRect(0, 0, 200, CONTROL_HEIGHT)],
refont = [_ruleEditor font],
font = [CPFont fontWithName:[refont familyName] size:[refont size] + 2],
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];
localizedText = [[_ruleEditor standardLocalizer] localizedStringForString:text];
[textField setFrameSize:CGSizeMake(size.width + 4, CONTROL_HEIGHT + 2)];
[textField setValue:font forThemeAttribute:@"font"];
[textField setStringValue:localizedText];
[textField sizeToFit];
return textField;
}
@@ -254,7 +271,11 @@ var CONTROL_HEIGHT = 16.,
}
}
repObject = [CPDictionary dictionaryWithObjectsAndKeys:childItem, @"item", childValue, @"value", i, @"indexInCriteria"];
repObject = @{
@"item": childItem,
@"value": childValue,
@"indexInCriteria": i
};
[menuItem setRepresentedObject:repObject];
[menuItems addObject:menuItem];
}
@@ -300,7 +321,7 @@ var CONTROL_HEIGHT = 16.,
[_correspondingRuleItems setArray:ruleItems];
if (!editable)
if (!_editable)
[self _updateEnabledStateForSubviews];
[self _relayoutSubviewsWidthChanged:YES];
@@ -353,14 +374,6 @@ var CONTROL_HEIGHT = 16.,
optionFrame.origin.y = (rowHeight - CGRectGetHeight(optionFrame)) / 2 - 2;
// small positioning fix
if ([ruleOptionView isKindOfClass:CPTextField])
{
optionFrame.origin.y += 2;
[_ruleOptionViews[i] setValue:CGInsetMake(7, 7, 7, 8) forThemeAttribute:@"content-inset"];
}
if (widthChanged)
{
optionFrame.origin.x = optionViewOriginX;
@@ -390,14 +403,9 @@ var CONTROL_HEIGHT = 16.,
[self _setRowTypeToAddFromPlusButton:type];
}
- (BOOL)isEditable
{
return editable;
}
- (void)setEditable:(BOOL)value
{
editable = value;
[super setEditable:value]
// [self _updateEnabledStateForSubviews];
[self _updateButtonVisibilities];
}
@@ -473,7 +481,7 @@ var CONTROL_HEIGHT = 16.,
[self layoutSubviews];
}
- (void)drawRect:(CPRect)rect
- (void)drawRect:(CGRect)rect
{
[super drawRect:rect];
}
@@ -485,13 +493,6 @@ var CONTROL_HEIGHT = 16.,
return NO;
}
- (BOOL)_isRuleStaticTextField:(CPView)view
{
if ([view isKindOfClass:[_CPRuleEditorTextField class]])
return YES;
return NO;
}
- (void)_sendRuleAction:(id)sender
{
[_ruleEditor _updatePredicate];
@@ -513,19 +514,17 @@ var CONTROL_HEIGHT = 16.,
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self != nil)
if (self)
{
[self setBordered:NO];
[self setEditable:NO];
[self setDrawsBackground:NO];
}
return self;
}
- (id)hitTest:(CPPoint)point
- (id)hitTest:(CGPoint)point
{
if (!CPRectContainsPoint([self frame], point))
if (!CGRectContainsPoint([self frame], point))
return nil;
return [self superview];
+8 -8
View File
@@ -143,10 +143,10 @@ var CPScrollerStyleGlobal = CPScrollerStyleOverlay,
+ (CPDictionary)themeAttributes
{
return [CPDictionary dictionaryWithJSObject:{
@"bottom-corner-color": [CPColor whiteColor],
@"border-color": [CPColor blackColor]
}];
return @{
@"bottom-corner-color": [CPColor whiteColor],
@"border-color": [CPColor blackColor]
};
}
+ (CGSize)contentSizeForFrameSize:(CGSize)frameSize hasHorizontalScroller:(BOOL)hFlag hasVerticalScroller:(BOOL)vFlag borderType:(CPBorderType)borderType
@@ -213,7 +213,7 @@ var CPScrollerStyleGlobal = CPScrollerStyleOverlay,
@param aStyle the scroller style to set all scroller views to use (CPScrollerStyleLegacy or CPScrollerStyleOverlay)
*/
+ (int)setGlobalScrollerStyle:(int)aStyle
+ (void)setGlobalScrollerStyle:(int)aStyle
{
CPScrollerStyleGlobal = aStyle;
[[CPNotificationCenter defaultCenter] postNotificationName:CPScrollerStyleGlobalChangeNotification object:nil];
@@ -1112,8 +1112,8 @@ Notifies the delegate when the scroll view has finished scrolling.
contentFrame.size.height -= headerClipViewHeight;
var difference = _CGSizeMake(_CGRectGetWidth(documentFrame) - _CGRectGetWidth(contentFrame), _CGRectGetHeight(documentFrame) - _CGRectGetHeight(contentFrame)),
verticalScrollerWidth = _CGRectGetWidth([_verticalScroller frame]),
horizontalScrollerHeight = _CGRectGetHeight([_horizontalScroller frame]),
verticalScrollerWidth = [CPScroller scrollerWidthInStyle:[_verticalScroller style]],
horizontalScrollerHeight = [CPScroller scrollerWidthInStyle:[_horizontalScroller style]],
hasVerticalScroll = difference.height > 0.0,
hasHorizontalScroll = difference.width > 0.0,
shouldShowVerticalScroller = _hasVerticalScroller && (!_autohidesScrollers || hasVerticalScroll),
@@ -1256,7 +1256,7 @@ Notifies the delegate when the scroll view has finished scrolling.
#pragma mark -
#pragma mark Overrides
- (void)drawRect:(CPRect)aRect
- (void)drawRect:(CGRect)aRect
{
[super drawRect:aRect];
+62 -44
View File
@@ -25,7 +25,12 @@
#include "../Foundation/Foundation.h"
@import "CPAnimation.j"
@import "CPControl.j"
@import "CPWindow_Constants.j"
@import "CPViewAnimation.j"
@global CPApp
// CPScroller Constants
CPScrollerNoPart = 0;
@@ -52,6 +57,8 @@ var PARTS_ARRANGEMENT = [CPScrollerKnobSlot, CPScrollerDecrementLine, CPScroll
NAMES_FOR_PARTS = {},
PARTS_FOR_NAMES = {};
var _CACHED_THEME_SCROLLER = nil; // This is used by the class methods to pull the theme attributes.
NAMES_FOR_PARTS[CPScrollerDecrementLine] = @"decrement-line";
NAMES_FOR_PARTS[CPScrollerIncrementLine] = @"increment-line";
NAMES_FOR_PARTS[CPScrollerKnobSlot] = @"knob-slot";
@@ -103,19 +110,19 @@ CPThemeStateScrollerKnobDark = CPThemeState("scroller-knob-dark");
+ (id)themeAttributes
{
return [CPDictionary dictionaryWithJSObject:{
@"scroller-width": 7.0,
@"knob-slot-color": [CPNull null],
@"decrement-line-color": [CPNull null],
@"increment-line-color": [CPNull null],
@"knob-color": [CPNull null],
@"decrement-line-size":_CGSizeMakeZero(),
@"increment-line-size":_CGSizeMakeZero(),
@"track-inset":_CGInsetMakeZero(),
@"knob-inset": _CGInsetMakeZero(),
@"minimum-knob-length":21.0,
@"track-border-overlay": 9.0
}];
return @{
@"scroller-width": 7.0,
@"knob-slot-color": [CPNull null],
@"decrement-line-color": [CPNull null],
@"increment-line-color": [CPNull null],
@"knob-color": [CPNull null],
@"decrement-line-size":_CGSizeMakeZero(),
@"increment-line-size":_CGSizeMakeZero(),
@"track-inset":_CGInsetMakeZero(),
@"knob-inset": _CGInsetMakeZero(),
@"minimum-knob-length":21.0,
@"track-border-overlay": 9.0
};
}
+ (float)scrollerWidth
@@ -128,11 +135,13 @@ CPThemeStateScrollerKnobDark = CPThemeState("scroller-knob-dark");
*/
+ (float)scrollerWidthInStyle:(int)aStyle
{
var scroller = [[self alloc] init];
if (!_CACHED_THEME_SCROLLER)
_CACHED_THEME_SCROLLER = [[self alloc] init];
if (aStyle == CPScrollerStyleLegacy)
return [scroller valueForThemeAttribute:@"scroller-width" inState:CPThemeStateScrollViewLegacy];
return [scroller currentValueForThemeAttribute:@"scroller-width"];
return [_CACHED_THEME_SCROLLER valueForThemeAttribute:@"scroller-width" inState:CPThemeStateScrollViewLegacy];
return [_CACHED_THEME_SCROLLER currentValueForThemeAttribute:@"scroller-width"];
}
/*!
@@ -140,7 +149,10 @@ CPThemeStateScrollerKnobDark = CPThemeState("scroller-knob-dark");
*/
+ (float)scrollerOverlay
{
return [[[self alloc] init] currentValueForThemeAttribute:@"track-border-overlay"];
if (!_CACHED_THEME_SCROLLER)
_CACHED_THEME_SCROLLER = [[self alloc] init];
return [_CACHED_THEME_SCROLLER currentValueForThemeAttribute:@"track-border-overlay"];
}
/*!
@@ -170,14 +182,19 @@ CPThemeStateScrollerKnobDark = CPThemeState("scroller-knob-dark");
_allowFadingOut = YES;
_isMouseOver = NO;
_style = CPScrollerStyleOverlay;
var paramAnimFadeOut = [CPDictionary dictionaryWithObjects:[self, CPViewAnimationFadeOutEffect]
forKeys:[CPViewAnimationTargetKey, CPViewAnimationEffectKey]];
var paramAnimFadeOut = @{
CPViewAnimationTargetKey: self,
CPViewAnimationEffectKey: CPViewAnimationFadeOutEffect,
};
_animationScroller = [[CPViewAnimation alloc] initWithDuration:0.2 animationCurve:CPAnimationEaseInOut];
[_animationScroller setViewAnimations:[paramAnimFadeOut]];
[_animationScroller setDelegate:self];
[self setAlphaValue:0.0];
[self _calculateIsVertical];
// We have to choose an orientation. If for some bizarre reason width === height,
// punt and choose vertical.
[self _setIsVertical:_CGRectGetHeight(aFrame) >= _CGRectGetWidth(aFrame)];
}
return self;
@@ -217,7 +234,7 @@ CPThemeStateScrollerKnobDark = CPThemeState("scroller-knob-dark");
[self unsetThemeState:CPThemeStateScrollViewLegacy];
}
[self _adjustScrollerSize];
//[self _adjustScrollerSize];
}
- (void)setObjectValue:(id)aValue
@@ -523,6 +540,7 @@ CPThemeStateScrollerKnobDark = CPThemeState("scroller-knob-dark");
- (void)layoutSubviews
{
[self _adjustScrollerSize];
[self checkSpaceForParts];
var index = 0,
@@ -633,13 +651,13 @@ CPThemeStateScrollerKnobDark = CPThemeState("scroller-knob-dark");
if ([anEvent modifierFlags] & CPAlternateKeyMask)
{
if (_trackingPart == CPScrollerDecrementLine)
if (_trackingPart === CPScrollerDecrementLine)
_hitPart = CPScrollerDecrementPage;
else if (_trackingPart == CPScrollerIncrementLine)
else if (_trackingPart === CPScrollerIncrementLine)
_hitPart = CPScrollerIncrementPage;
else if (_trackingPart == CPScrollerDecrementPage || _trackingPart == CPScrollerIncrementPage)
else if (_trackingPart === CPScrollerDecrementPage || _trackingPart === CPScrollerIncrementPage)
{
var knobRect = [self rectForPart:CPScrollerKnob],
knobWidth = ![self isVertical] ? _CGRectGetWidth(knobRect) : _CGRectGetHeight(knobRect),
@@ -667,11 +685,11 @@ CPThemeStateScrollerKnobDark = CPThemeState("scroller-knob-dark");
{
_trackingStartPoint = [self convertPoint:[anEvent locationInWindow] fromView:nil];
if (_trackingPart == CPScrollerDecrementPage || _trackingPart == CPScrollerIncrementPage)
if (_trackingPart === CPScrollerDecrementPage || _trackingPart === CPScrollerIncrementPage)
{
var hitPart = [self testPart:[anEvent locationInWindow]];
if (hitPart == CPScrollerDecrementPage || hitPart == CPScrollerIncrementPage)
if (hitPart === CPScrollerDecrementPage || hitPart === CPScrollerIncrementPage)
{
_trackingPart = hitPart;
_hitPart = hitPart;
@@ -687,18 +705,13 @@ CPThemeStateScrollerKnobDark = CPThemeState("scroller-knob-dark");
}
- (void)_calculateIsVertical
- (void)_setIsVertical:(BOOL)isVertical
{
// Recalculate isVertical.
var bounds = [self bounds],
width = _CGRectGetWidth(bounds),
height = _CGRectGetHeight(bounds);
_isVertical = isVertical;
_isVertical = width < height ? 1 : (width > height ? 0 : -1);
if (_isVertical === 1)
if (_isVertical)
[self setThemeState:CPThemeStateVertical];
else if (_isVertical === 0)
else
[self unsetThemeState:CPThemeStateVertical];
}
@@ -733,12 +746,14 @@ CPThemeStateScrollerKnobDark = CPThemeState("scroller-knob-dark");
switch (_hitPart)
{
case CPScrollerKnob: return [self trackKnob:anEvent];
case CPScrollerKnob:
return [self trackKnob:anEvent];
case CPScrollerDecrementLine:
case CPScrollerIncrementLine:
case CPScrollerDecrementPage:
case CPScrollerIncrementPage: return [self trackScrollButtons:anEvent];
case CPScrollerIncrementPage:
return [self trackScrollButtons:anEvent];
}
}
@@ -786,9 +801,10 @@ CPThemeStateScrollerKnobDark = CPThemeState("scroller-knob-dark");
@end
var CPScrollerControlSizeKey = @"CPScrollerControlSize",
var CPScrollerControlSizeKey = @"CPScrollerControlSize",
CPScrollerIsVerticalKey = @"CPScrollerIsVerticalKey",
CPScrollerKnobProportionKey = @"CPScrollerKnobProportion",
CPScrollerStyleKey = @"CPScrollerStyleKey";
CPScrollerStyleKey = @"CPScrollerStyleKey";
@implementation CPScroller (CPCoding)
@@ -797,7 +813,6 @@ var CPScrollerControlSizeKey = @"CPScrollerControlSize",
if (self = [super initWithCoder:aCoder])
{
_controlSize = CPRegularControlSize;
if ([aCoder containsValueForKey:CPScrollerControlSizeKey])
_controlSize = [aCoder decodeIntForKey:CPScrollerControlSizeKey];
@@ -813,17 +828,19 @@ var CPScrollerControlSizeKey = @"CPScrollerControlSize",
_allowFadingOut = YES;
_isMouseOver = NO;
var paramAnimFadeOut = [CPDictionary dictionaryWithObjects:[self, CPViewAnimationFadeOutEffect]
forKeys:[CPViewAnimationTargetKey, CPViewAnimationEffectKey]];
var paramAnimFadeOut = @{
CPViewAnimationTargetKey: self,
CPViewAnimationEffectKey: CPViewAnimationFadeOutEffect,
};
_animationScroller = [[CPViewAnimation alloc] initWithDuration:0.2 animationCurve:CPAnimationEaseInOut];
[_animationScroller setViewAnimations:[paramAnimFadeOut]];
[_animationScroller setDelegate:self];
[self setAlphaValue:0.0];
[self _calculateIsVertical];
[self setStyle:[aCoder decodeIntForKey:CPScrollerStyleKey]];
[self _setIsVertical:[aCoder decodeBoolForKey:CPScrollerIsVerticalKey]];
}
return self;
@@ -834,6 +851,7 @@ 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];
}
+24 -24
View File
@@ -21,22 +21,19 @@
*/
@import "CPButton.j"
@import "CPMenu.j"
@import "CPMenuItem.j"
@import "CPTextField.j"
@class CPUserDefaults
@global CPApp
CPSearchFieldRecentsTitleMenuItemTag = 1000;
CPSearchFieldRecentsMenuItemTag = 1001;
CPSearchFieldClearRecentsMenuItemTag = 1002;
CPSearchFieldNoRecentsMenuItemTag = 1003;
var CPSearchFieldSearchImage = nil,
CPSearchFieldFindImage = nil,
CPSearchFieldCancelImage = nil,
CPSearchFieldCancelPressedImage = nil;
var SEARCH_BUTTON_DEFAULT_WIDTH = 25.0,
CANCEL_BUTTON_DEFAULT_WIDTH = 22.0,
BUTTON_DEFAULT_HEIGHT = 22.0;
var CPAutosavedRecentsChangedNotification = @"CPAutosavedRecentsChangedNotification";
var RECENT_SEARCH_PREFIX = @" ";
@@ -70,16 +67,14 @@ var RECENT_SEARCH_PREFIX = @" ";
return @"searchfield"
}
+ (void)initialize
+ (CPDictionary)themeAttributes
{
if (self !== [CPSearchField class])
return;
var bundle = [CPBundle bundleForClass:self];
CPSearchFieldSearchImage = [[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPSearchField/CPSearchFieldSearch.png"] size:_CGSizeMake(SEARCH_BUTTON_DEFAULT_WIDTH, BUTTON_DEFAULT_HEIGHT)];
CPSearchFieldFindImage = [[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPSearchField/CPSearchFieldFind.png"] size:_CGSizeMake(SEARCH_BUTTON_DEFAULT_WIDTH, BUTTON_DEFAULT_HEIGHT)];
CPSearchFieldCancelImage = [[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPSearchField/CPSearchFieldCancel.png"] size:_CGSizeMake(CANCEL_BUTTON_DEFAULT_WIDTH, BUTTON_DEFAULT_HEIGHT)];
CPSearchFieldCancelPressedImage = [[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPSearchField/CPSearchFieldCancelPressed.png"] size:_CGSizeMake(CANCEL_BUTTON_DEFAULT_WIDTH, BUTTON_DEFAULT_HEIGHT)];
return @{
@"image-search": [CPNull null],
@"image-find": [CPNull null],
@"image-cancel": [CPNull null],
@"image-cancel-pressed": [CPNull null]
};
}
- (id)initWithFrame:(CGRect)frame
@@ -170,7 +165,7 @@ var RECENT_SEARCH_PREFIX = @" ";
- (void)resetSearchButton
{
var button = [self searchButton],
searchButtonImage = (_searchMenuTemplate === nil) ? CPSearchFieldSearchImage : CPSearchFieldFindImage;
searchButtonImage = (_searchMenuTemplate === nil) ? [self valueForThemeAttribute:@"image-search"] : [self valueForThemeAttribute:@"image-find"];
[button setBordered:NO];
[button setImageScaling:CPImageScaleAxesIndependently];
@@ -193,6 +188,7 @@ var RECENT_SEARCH_PREFIX = @" ";
[_cancelButton setAutoresizingMask:CPViewMinXMargin];
[_cancelButton setTarget:self];
[_cancelButton setAction:@selector(cancelOperation:)];
[_cancelButton setButtonType:CPMomentaryChangeButton];
[self _updateCancelButtonVisibility];
[self addSubview:_cancelButton];
}
@@ -216,8 +212,8 @@ var RECENT_SEARCH_PREFIX = @" ";
var button = [self cancelButton];
[button setBordered:NO];
[button setImageScaling:CPImageScaleAxesIndependently];
[button setImage:CPSearchFieldCancelImage];
[button setAlternateImage:CPSearchFieldCancelPressedImage];
[button setImage:[self valueForThemeAttribute:@"image-cancel"]];
[button setAlternateImage:[self valueForThemeAttribute:@"image-cancel-pressed"]];
[button setAutoresizingMask:CPViewMinXMargin];
[button setTarget:self];
[button setAction:@selector(cancelOperation:)];
@@ -258,7 +254,9 @@ var RECENT_SEARCH_PREFIX = @" ";
*/
- (CGRect)searchButtonRectForBounds:(CGRect)rect
{
return _CGRectMake(5, (_CGRectGetHeight(rect) - BUTTON_DEFAULT_HEIGHT) / 2, SEARCH_BUTTON_DEFAULT_WIDTH, BUTTON_DEFAULT_HEIGHT);
var size = [[self valueForThemeAttribute:@"image-search"] size] || CGSizeMakeZero();
return _CGRectMake(5, (_CGRectGetHeight(rect) - size.height) / 2, size.width, size.height);
}
/*!
@@ -268,7 +266,9 @@ var RECENT_SEARCH_PREFIX = @" ";
*/
- (CGRect)cancelButtonRectForBounds:(CGRect)rect
{
return _CGRectMake(_CGRectGetWidth(rect) - CANCEL_BUTTON_DEFAULT_WIDTH - 5, (_CGRectGetHeight(rect) - CANCEL_BUTTON_DEFAULT_WIDTH) / 2, BUTTON_DEFAULT_HEIGHT, BUTTON_DEFAULT_HEIGHT);
var size = [[self valueForThemeAttribute:@"image-cancel"] size] || CGSizeMakeZero();
return _CGRectMake(_CGRectGetWidth(rect) - size.width - 5, (_CGRectGetHeight(rect) - size.width) / 2, size.height, size.height);
}
// Managing Menu Templates
@@ -679,7 +679,7 @@ var RECENT_SEARCH_PREFIX = @" ";
return;
var aFrame = [[self superview] convertRect:[self frame] toView:nil],
location = CPMakePoint(aFrame.origin.x + 10, aFrame.origin.y + aFrame.size.height - 4);
location = CGPointMake(aFrame.origin.x + 10, aFrame.origin.y + aFrame.size.height - 4);
var anEvent = [CPEvent mouseEventWithType:CPRightMouseDown location:location modifierFlags:0 timestamp:[[CPApp currentEvent] timestamp] windowNumber:[[self window] windowNumber] context:nil eventNumber:1 clickCount:1 pressure:0];
+135 -8
View File
@@ -23,7 +23,10 @@
@import <Foundation/CPArray.j>
@import "CPControl.j"
@import "CPWindow_Constants.j"
@import "_CPImageAndTextView.j"
@global CPApp
CPSegmentSwitchTrackingSelectOne = 0;
CPSegmentSwitchTrackingSelectAny = 1;
@@ -55,8 +58,33 @@ CPSegmentSwitchTrackingMomentary = 2;
+ (id)themeAttributes
{
return [CPDictionary dictionaryWithObjects:[CPCenterTextAlignment, CPCenterVerticalTextAlignment, CPImageLeft, CPImageScaleNone, _CGInsetMakeZero(), _CGInsetMakeZero(), [CPNull null], [CPNull null], [CPNull null], [CPNull null], 1.0, 24.0]
forKeys:[@"alignment", @"vertical-alignment", @"image-position", @"image-scaling", @"bezel-inset", @"content-inset", @"left-segment-bezel-color", @"right-segment-bezel-color", @"center-segment-bezel-color", @"divider-bezel-color", @"divider-thickness", @"default-height"]];
return @{
@"alignment": CPCenterTextAlignment,
@"vertical-alignment": CPCenterVerticalTextAlignment,
@"image-position": CPImageLeft,
@"image-scaling": CPImageScaleNone,
@"bezel-inset": _CGInsetMakeZero(),
@"content-inset": _CGInsetMakeZero(),
@"left-segment-bezel-color": [CPNull null],
@"right-segment-bezel-color": [CPNull null],
@"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
@@ -76,6 +104,19 @@ CPSegmentSwitchTrackingMomentary = 2;
return self;
}
- (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");
else
[super bind:aBinding toObject:anObject withKeyPath:aKeyPath options:options];
}
- (void)_reverseSetBinding
{
[_CPSegmentedControlBinder reverseSetValueForObject:self];
}
/*!
Returns the tag of the selected segment.
*/
@@ -115,13 +156,15 @@ CPSegmentSwitchTrackingMomentary = 2;
if (_selectedSegment >= _segments.length)
_selectedSegment = -1;
// Make space for/remove space used by dividers.
var thickness = [self currentValueForThemeAttribute:@"divider-thickness"],
delta = thickness * (dividersAfter - dividersBefore),
frame = [self frame];
frame = [self frame],
widthOfAllSegments = 0,
dividerExtraSpace = ([_segments count] - 1) * thickness;
if (delta)
[self setFrameSize:CGSizeMake(frame.size.width + delta, frame.size.height)];
for (var i = 0; i < [_segments count]; i++)
widthOfAllSegments += [_segments[i] width];
[self setFrameSize:CGSizeMake(widthOfAllSegments + dividerExtraSpace, frame.size.height)];
[self tileWithChangedSegment:0];
}
@@ -172,6 +215,21 @@ CPSegmentSwitchTrackingMomentary = 2;
return NO;
}
- (BOOL)_selectSegmentWithLabel:(CPString)aLabel
{
var index = 0;
for (; index < _segments.length; ++index)
if (_segments[index].label == aLabel)
{
[self setSelectedSegment:index];
return YES;
}
return NO;
}
// Specifying Tracking Mode
- (BOOL)isTracking
@@ -463,7 +521,7 @@ CPSegmentSwitchTrackingMomentary = 2;
}
else if (aName === "right-segment-bezel")
{
return CPRectMake(CGRectGetWidth([self bounds]) - contentInset.right,
return CGRectMake(CGRectGetWidth([self bounds]) - contentInset.right,
bezelInset.top,
contentInset.right,
height);
@@ -799,6 +857,7 @@ CPSegmentSwitchTrackingMomentary = 2;
return;
var highlighted = [self testSegment:location] === _trackingSegment;
if (highlighted != _trackingHighlighted)
{
_trackingHighlighted = highlighted;
@@ -885,6 +944,74 @@ var CPSegmentedControlSegmentsKey = "CPSegmentedControlSegmentsKey",
@end
var CPSegmentedControlBindersMap = {},
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
{
[super _updatePlaceholdersWithOptions:options];
[self _setPlaceholder:CPSegmentedControlNoSelectionPlaceholder forMarker:CPMultipleValuesMarker isDefault:YES];
[self _setPlaceholder:CPSegmentedControlNoSelectionPlaceholder forMarker:CPNoSelectionMarker isDefault:YES];
[self _setPlaceholder:CPSegmentedControlNoSelectionPlaceholder forMarker:CPNotApplicableMarker isDefault:YES];
[self _setPlaceholder:CPSegmentedControlNoSelectionPlaceholder forMarker:CPNullMarker isDefault:YES];
}
- (void)setPlaceholderValue:(id)aValue withMarker:(CPString)aMarker forBinding:(CPString)aBinding
{
if (aValue == CPSegmentedControlNoSelectionPlaceholder)
[_source setSelected:NO forSegment:[_source selectedSegment]];
else
[self setValue:aValue forBinding:aBinding];
}
- (void)setValue:(id)aValue forBinding:(CPString)aBinding
{
if (aBinding == CPSelectedIndexBinding)
[_source setSelectedSegment:aValue];
else if (aBinding == CPSelectedTagBinding)
[_source selectSegmentWithTag:aValue];
else if (aBinding == CPSelectedLabelBinding)
[_source _selectSegmentWithLabel:aValue];
}
- (id)valueForBinding:(CPString)aBinding
{
var selectedIndex = [_source selectedSegment];
if (aBinding == CPSelectedIndexBinding)
return selectedIndex;
else if (aBinding == CPSelectedTagBinding)
return [_source tagForSegment:selectedIndex];
else if (aBinding == CPSelectedLabelBinding)
return [_source labelForSegment:selectedIndex];
}
@end
@implementation _CPSegmentItem : CPObject
{
+9 -30
View File
@@ -31,11 +31,9 @@
*/
@implementation CPShadow : CPObject
{
CPSize _offset;
float _blurRadius;
CPColor _color;
CPString _cssString;
CGSize _offset @accessors(property=shadowOffset);
float _blurRadius @accessors(property=shadowBlurRadius);
CPColor _color @accessors(property=shadowColor);
}
/*!
@@ -51,7 +49,7 @@
}
/* @ignore */
- (id)_initWithOffset:(CPSize)anOffset blurRadius:(float)aBlurRadius color:(CPColor)aColor
- (id)_initWithOffset:(CGSize)anOffset blurRadius:(float)aBlurRadius color:(CPColor)aColor
{
self = [super init];
@@ -60,35 +58,16 @@
_offset = anOffset;
_blurRadius = aBlurRadius;
_color = aColor;
_cssString = [_color cssString] + " " + ROUND(anOffset.width) + @"px " + ROUND(anOffset.height) + @"px " + ROUND(_blurRadius) + @"px";
}
return self;
}
/*!
Returns the shadow's offset.
*/
- (CGSize)shadowOffset
- (void)set
{
return _offset;
}
var context = [[CPGraphicsContext currentContext] graphicsPort];
/*!
Returns the shadow's blur radius
*/
- (float)shadowBlurRadius
{
return _blurRadius;
}
/*!
Returns the shadow's color.
*/
- (CPColor)shadowColor
{
return _color;
CGContextSetShadowWithColor(context, _offset, _blurRadius, _color);
}
/*!
@@ -96,7 +75,7 @@
*/
- (CPString)cssString
{
return _cssString;
return [_color cssString] + " " + ROUND(_offset.width) + @"px " + ROUND(_offset.height) + @"px " + ROUND(_blurRadius) + @"px";
}
@end
@end
+41 -69
View File
@@ -24,25 +24,15 @@
@import "CGGeometry.j"
@import "CPImage.j"
@import "CPImageView.j"
@import "CPView.j"
CPLightShadow = 0;
CPHeavyShadow = 1;
var CPShadowViewLightBackgroundColor = nil,
CPShadowViewHeavyBackgroundColor = nil;
CPThemeStateShadowViewLight = CPThemeState("shadowview-style-light");
CPThemeStateShadowViewHeavy = CPThemeState("shadowview-style-heavy");
var LIGHT_LEFT_INSET = 3.0,
LIGHT_RIGHT_INSET = 3.0,
LIGHT_TOP_INSET = 3.0,
LIGHT_BOTTOM_INSET = 5.0,
HEAVY_LEFT_INSET = 7.0,
HEAVY_RIGHT_INSET = 7.0,
HEAVY_TOP_INSET = 5.0,
HEAVY_BOTTOM_INSET = 5.0;
/*!
@ingroup appkit
@@ -52,40 +42,25 @@ var LIGHT_LEFT_INSET = 3.0,
CPShadowWeight _weight;
}
+ (void)initialize
+ (CPString)defaultThemeClass
{
if (self !== [CPShadowView class])
return;
return "shadow-view";
}
var bundle = [CPBundle bundleForClass:[self class]];
+ (id)themeAttributes
{
return @{
@"bezel-color": [CPNull null],
@"content-inset": CGInsetMakeZero()
};
}
CPShadowViewLightBackgroundColor = CPColorWithImages([
[@"CPShadowView/CPShadowViewLightTopLeft.png", 9.0, 9.0, bundle],
[@"CPShadowView/CPShadowViewLightTop.png", 1.0, 9.0, bundle],
[@"CPShadowView/CPShadowViewLightTopRight.png", 9.0, 9.0, bundle],
+ (CGRect)frameForContentFrame:(CGRect)aFrame withWeight:(CPShadowWeight)aWeight
{
var shadowView = [CPShadowView new],
inset = [shadowView valueForThemeAttribute:@"content-inset" inState:(aWeight == CPLightShadow) ? CPThemeStateShadowViewLight : CPThemeStateShadowViewHeavy];
[@"CPShadowView/CPShadowViewLightLeft.png", 9.0, 1.0, bundle],
nil,
[@"CPShadowView/CPShadowViewLightRight.png", 9.0, 1.0, bundle],
[@"CPShadowView/CPShadowViewLightBottomLeft.png", 9.0, 9.0, bundle],
[@"CPShadowView/CPShadowViewLightBottom.png", 1.0, 9.0, bundle],
[@"CPShadowView/CPShadowViewLightBottomRight.png", 9.0, 9.0, bundle]
]);
CPShadowViewHeavyBackgroundColor = CPColorWithImages([
[@"CPShadowView/CPShadowViewHeavyTopLeft.png", 17.0, 17.0, bundle],
[@"CPShadowView/CPShadowViewHeavyTop.png", 1.0, 17.0, bundle],
[@"CPShadowView/CPShadowViewHeavyTopRight.png", 17.0, 17.0, bundle],
[@"CPShadowView/CPShadowViewHeavyLeft.png", 17.0, 1.0, bundle],
nil,
[@"CPShadowView/CPShadowViewHeavyRight.png", 17.0, 1.0, bundle],
[@"CPShadowView/CPShadowViewHeavyBottomLeft.png", 17.0, 17.0, bundle],
[@"CPShadowView/CPShadowViewHeavyBottom.png", 1.0, 17.0, bundle],
[@"CPShadowView/CPShadowViewHeavyBottomRight.png", 17.0, 17.0, bundle]
]);
return CGRectMake(_CGRectGetMinX(aFrame) - inset.left, _CGRectGetMinY(aFrame) - inset.top, _CGRectGetWidth(aFrame) + inset.left + inset.right, _CGRectGetHeight(aFrame) + inset.top + inset.bottom);
}
+ (id)shadowViewEnclosingView:(CPView)aView
@@ -102,15 +77,16 @@ var LIGHT_LEFT_INSET = 3.0,
[shadowView setWeight:aWeight];
var size = [shadowView frame].size,
width = size.width - [shadowView leftInset] - [shadowView rightInset],
height = size.height - [shadowView topInset] - [shadowView bottomInset],
inset = [shadowView currentValueForThemeAttribute:@"content-inset"],
width = size.width - inset.left - inset.right,
height = size.height - inset.top - inset.bottom,
enclosingView = [aView superview];
[shadowView setHitTests:[aView hitTests]];
[shadowView setAutoresizingMask:[aView autoresizingMask]];
[aView removeFromSuperview];
[shadowView addSubview:aView];
[aView setFrame:CGRectMake([shadowView leftInset], [shadowView topInset], width, height)]
[aView setFrame:CGRectMake(inset.left, inset.top, width, height)];
[enclosingView addSubview:shadowView];
}
@@ -123,9 +99,7 @@ var LIGHT_LEFT_INSET = 3.0,
if (self)
{
_weight = CPLightShadow;
[self setBackgroundColor:CPShadowViewLightBackgroundColor];
[self setWeight:CPLightShadow];
[self setHitTests:NO];
}
@@ -141,54 +115,45 @@ var LIGHT_LEFT_INSET = 3.0,
_weight = aWeight;
if (_weight == CPLightShadow)
[self setBackgroundColor:CPShadowViewLightBackgroundColor];
[self setThemeState:CPThemeStateShadowViewLight];
else
[self setBackgroundColor:CPShadowViewHeavyBackgroundColor];
[self setThemeState:CPThemeStateShadowViewHeavy];
[self setNeedsLayout];
}
- (float)leftInset
{
return _weight == CPLightShadow ? LIGHT_LEFT_INSET : HEAVY_LEFT_INSET;
return [self currentValueForThemeAttribute:@"content-inset"].left;
}
- (float)rightInset
{
return _weight == CPLightShadow ? LIGHT_RIGHT_INSET : HEAVY_RIGHT_INSET;
return [self currentValueForThemeAttribute:@"content-inset"].right;
}
- (float)topInset
{
return _weight == CPLightShadow ? LIGHT_TOP_INSET : HEAVY_TOP_INSET;
return [self currentValueForThemeAttribute:@"content-inset"].top;
}
- (float)bottomInset
{
return _weight == CPLightShadow ? LIGHT_BOTTOM_INSET : HEAVY_BOTTOM_INSET;
return [self currentValueForThemeAttribute:@"content-inset"].bottom;
}
- (float)horizontalInset
{
if (_weight == CPLightShadow)
return LIGHT_LEFT_INSET + LIGHT_RIGHT_INSET;
var currentContentInset = [self currentValueForThemeAttribute:@"content-inset"];
return HEAVY_LEFT_INSET + HEAVY_RIGHT_INSET;
return currentContentInset.left + currentContentInset.right;
}
- (float)verticalInset
{
if (_weight == CPLightShadow)
return LIGHT_TOP_INSET + LIGHT_BOTTOM_INSET;
var currentContentInset = [self currentValueForThemeAttribute:@"content-inset"];
return HEAVY_TOP_INSET + HEAVY_BOTTOM_INSET;
}
+ (CGRect)frameForContentFrame:(CGRect)aFrame withWeight:(CPShadowWeight)aWeight
{
if (aWeight == CPLightShadow)
return CGRectMake(_CGRectGetMinX(aFrame) - LIGHT_LEFT_INSET, _CGRectGetMinY(aFrame) - LIGHT_TOP_INSET, _CGRectGetWidth(aFrame) + LIGHT_LEFT_INSET + LIGHT_RIGHT_INSET, _CGRectGetHeight(aFrame) + LIGHT_TOP_INSET + LIGHT_BOTTOM_INSET);
else
return CGRectMake(_CGRectGetMinX(aFrame) - HEAVY_LEFT_INSET, _CGRectGetMinY(aFrame) - HEAVY_TOP_INSET, _CGRectGetWidth(aFrame) + HEAVY_LEFT_INSET + HEAVY_RIGHT_INSET, _CGRectGetHeight(aFrame) + HEAVY_TOP_INSET + HEAVY_BOTTOM_INSET);
return currentContentInset.top + currentContentInset.bottom;
}
- (CGRect)frameForContentFrame:(CGRect)aFrame
@@ -201,4 +166,11 @@ var LIGHT_LEFT_INSET = 3.0,
[self setFrame:[self frameForContentFrame:aFrame]];
}
- (void)layoutSubviews
{
[super layoutSubviews];
[self setBackgroundColor:[self currentValueForThemeAttribute:@"bezel-color"]];
}
@end
+9 -2
View File
@@ -21,6 +21,7 @@
*/
@import "CPControl.j"
@import "CPWindow_Constants.j"
/*! SLIDER STATES */
@@ -39,6 +40,8 @@ CPCircularSlider = 1;
double _altIncrementValue;
BOOL _isVertical;
CGSize _dragOffset;
}
+ (CPString)defaultThemeClass
@@ -48,8 +51,12 @@ CPCircularSlider = 1;
+ (id)themeAttributes
{
return [CPDictionary dictionaryWithObjects:[[CPNull null], _CGSizeMakeZero(), 0.0, [CPNull null]]
forKeys:[@"knob-color", @"knob-size", @"track-width", @"track-color"]];
return @{
@"knob-color": [CPNull null],
@"knob-size": _CGSizeMakeZero(),
@"track-width": 0.0,
@"track-color": [CPNull null],
};
}
- (id)initWithFrame:(CGRect)aFrame
+8 -2
View File
@@ -20,8 +20,14 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@import "CPView.j"
@import "CPColorPicker.j"
@import "CPSlider.j"
@import "CPTextField.j"
@import "CPView.j"
@global CPColorPickerViewWidth
@global CPColorPickerViewHeight
@global CPSliderColorPickerMode
/*
@@ -65,7 +71,7 @@
- (id)initView
{
aFrame = CGRectMake(0, 0, CPColorPickerViewWidth, CPColorPickerViewHeight);
var aFrame = CGRectMake(0, 0, CPColorPickerViewWidth, CPColorPickerViewHeight);
_contentView = [[CPView alloc] initWithFrame:aFrame];
[_contentView setAutoresizingMask:CPViewWidthSizable | CPViewHeightSizable];
+2 -1
View File
@@ -21,6 +21,7 @@
*/
@import <Foundation/CPObject.j>
@import <Foundation/CPRunLoop.j>
CPSoundLoadStateEmpty = 0;
CPSoundLoadStateLoading = 1;
@@ -59,7 +60,7 @@ CPSoundPlayBackStatePause = 2;
if (self = [super init])
{
_loadStatus = CPSoundLoadStateEmpty;
_loops = NO;
// _loops = NO;
_audioTag = document.createElement("audio");
_audioTag.preload = YES;
_playRequestBeforeLoad = NO;
+26 -27
View File
@@ -25,6 +25,10 @@
@import "CPButtonBar.j"
@import "CPImage.j"
@import "CPView.j"
@import "CPCursor.j"
@class CPUserDefaults
@global CPApp
#define SPLIT_VIEW_MAYBE_POST_WILL_RESIZE() \
if ((_suppressResizeNotificationsMask & DidPostWillResizeNotification) === 0) \
@@ -51,10 +55,7 @@
CPSplitViewDidResizeSubviewsNotification = @"CPSplitViewDidResizeSubviewsNotification";
CPSplitViewWillResizeSubviewsNotification = @"CPSplitViewWillResizeSubviewsNotification";
var CPSplitViewHorizontalImage = nil,
CPSplitViewVerticalImage = nil,
ShouldSuppressResizeNotifications = 1,
var ShouldSuppressResizeNotifications = 1,
DidPostWillResizeNotification = 1 << 1,
DidSuppressResizeNotification = 1 << 2;
@@ -104,22 +105,13 @@ var CPSplitViewHorizontalImage = nil,
+ (id)themeAttributes
{
return [CPDictionary dictionaryWithObjects:[1.0, 10.0, [CPColor grayColor]]
forKeys:[@"divider-thickness", @"pane-divider-thickness", @"pane-divider-color"]];
}
/*
@ignore
*/
+ (void)initialize
{
if (self !== [CPSplitView class])
return;
var bundle = [CPBundle bundleForClass:self];
CPSplitViewHorizontalImage = CPImageInBundle("CPSplitView/CPSplitViewHorizontal.png", CGSizeMake(5.0, 10.0), bundle);
CPSplitViewVerticalImage = CPImageInBundle("CPSplitView/CPSplitViewVertical.png", CGSizeMake(10.0, 5.0), bundle);
return @{
@"divider-thickness": 1.0,
@"pane-divider-thickness": 10.0,
@"pane-divider-color": [CPColor grayColor],
@"horizontal-divider-color": [CPNull null],
@"vertical-divider-color": [CPNull null],
};
}
- (id)initWithFrame:(CGRect)aFrame
@@ -202,7 +194,7 @@ var CPSplitViewHorizontalImage = nil,
_originComponent = [self isVertical] ? "x" : "y";
_sizeComponent = [self isVertical] ? "width" : "height";
_dividerImagePath = [self isVertical] ? [CPSplitViewVerticalImage filename] : [CPSplitViewHorizontalImage filename];
_dividerImagePath = [self isVertical] ? [[self valueForThemeAttribute:@"vertical-divider-color"] filename] : [[self valueForThemeAttribute:@"horizontal-divider-color"] filename];
return changed;
}
@@ -793,7 +785,7 @@ var CPSplitViewHorizontalImage = nil,
[self setNeedsDisplay:YES];
}
- (void)resizeSubviewsWithOldSize:(CPSize)oldSize
- (void)resizeSubviewsWithOldSize:(CGSize)oldSize
{
if ([_delegate respondsToSelector:@selector(splitView:resizeSubviewsWithOldSize:)])
{
@@ -1037,7 +1029,7 @@ The sum of the views and the sum of the dividers should be equal to the size of
var userInfo = nil;
if (_currentDivider !== CPNotFound)
userInfo = [CPDictionary dictionaryWithObject:_currentDivider forKey:@"CPSplitViewDividerIndex"];
userInfo = @{ @"CPSplitViewDividerIndex": _currentDivider };
[[CPNotificationCenter defaultCenter] postNotificationName:CPSplitViewWillResizeSubviewsNotification
object:self
@@ -1049,7 +1041,7 @@ The sum of the views and the sum of the dividers should be equal to the size of
var userInfo = nil;
if (_currentDivider !== CPNotFound)
userInfo = [CPDictionary dictionaryWithObject:_currentDivider forKey:@"CPSplitViewDividerIndex"];
userInfo = @{ @"CPSplitViewDividerIndex": _currentDivider };
[[CPNotificationCenter defaultCenter] postNotificationName:CPSplitViewDidResizeSubviewsNotification
object:self
@@ -1102,7 +1094,7 @@ The sum of the views and the sum of the dividers should be equal to the size of
for (var i = 0; i < count; i++)
{
var frame = [_subviews[i] frame];
[positions addObject:CPStringFromRect(frame)];
[positions addObject:CGStringFromRect(frame)];
[preCollapseArray addObject:[_preCollapsePositions objectForKey:"" + i]];
}
@@ -1149,7 +1141,7 @@ The sum of the views and the sum of the dividers should be equal to the size of
for (var i = 0, count = [frames count] - 1; i < count; i++)
{
var frame = CPRectFromString(frames[i]);
var frame = CGRectFromString(frames[i]);
position += frame.size[_sizeComponent];
[self setPosition:position ofDividerAtIndex:i];
@@ -1165,7 +1157,14 @@ The sum of the views and the sum of the dividers should be equal to the size of
_preCollapsePositions = [CPMutableDictionary new];
for (var i = 0, count = [preCollapseArray count]; i < count; i++)
[_preCollapsePositions setObject:preCollapseArray[i] forKey:i + ""];
{
var item = preCollapseArray[i];
if (item === nil)
[_preCollapsePositions removeObjectForKey:String(i)];
else
[_preCollapsePositions setObject:item forKey:String(i)];
}
}
}
+55 -8
View File
@@ -20,9 +20,9 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@import <AppKit/CPControl.j>
@import <AppKit/CPButton.j>
@import <AppKit/CPTextField.j>
@import "CPControl.j"
@import "CPButton.j"
@import "CPTextField.j"
@@ -55,11 +55,15 @@
*/
+ (CPStepper)stepperWithInitialValue:(float)aValue minValue:(float)aMinValue maxValue:(float)aMaxValue
{
var stepper = [[CPStepper alloc] initWithFrame:_CGRectMake(0, 0, 19, 25)];
var stepper = [[CPStepper alloc] initWithFrame:_CGRectMakeZero()];
[stepper setDoubleValue:aValue];
[stepper setMinValue:aMinValue];
[stepper setMaxValue:aMaxValue];
// _sizeToFit will put the good size for the stepper depending of the current theme
[stepper _sizeToFit];
return stepper;
}
@@ -76,6 +80,22 @@
return [CPStepper stepperWithInitialValue:0.0 minValue:0.0 maxValue:59.0];
}
+ (Class)_binderClassForBinding:(CPString)aBinding
{
if (aBinding == CPValueBinding || aBinding == CPMinValueBinding || aBinding == CPMaxValueBinding)
return [_CPStepperValueBinder class];
return [super _binderClassForBinding:aBinding];
}
- (CPString)_replacementKeyPathForBinding:(CPString)aBinding
{
if (aBinding == CPValueBinding)
return @"doubleValue";
return [super _replacementKeyPathForBinding:aBinding];
}
/*!
Initializes a CPStepper.
@param aFrame the frame of the control
@@ -157,6 +177,7 @@
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);
[_buttonUp setFrame:upFrame];
[_buttonDown setFrame:downFrame];
@@ -168,6 +189,11 @@
[_buttonDown setValue:[self valueForThemeAttribute:@"bezel-color-down-button" inState:CPThemeStateBordered | CPThemeStateHighlighted] forThemeAttribute:@"bezel-color" inState:CPThemeStateBordered | CPThemeStateHighlighted];
}
- (void)_sizeToFit
{
[self setFrame:CGRectMake([self frameOrigin].x, [self frameOrigin].y, 0, 0)];
}
/*!
Set if CPStepper should autorepeat.
@param shouldAutoRepeat if YES, the first mouse down does one increment (decrement) and, after each delay of 0.5 seconds
@@ -211,8 +237,7 @@
else
[self setDoubleValue:([self doubleValue] - _increment)];
if (_target && _action && [_target respondsToSelector:_action])
[self sendAction:_action to:_target];
[self sendAction:[self action] to:[self target]];
}
/*!
@@ -244,8 +269,30 @@
+ (id)themeAttributes
{
return [CPDictionary dictionaryWithObjects:[[CPNull null], [CPNull null], _CGSizeMakeZero(), _CGSizeMakeZero()]
forKeys:[@"bezel-color-up-button", @"bezel-color-down-button", @"up-button-size", @"down-button-size"]];
return @{
@"bezel-color-up-button": [CPNull null],
@"bezel-color-down-button": [CPNull null],
@"up-button-size": _CGSizeMakeZero(),
@"down-button-size": _CGSizeMakeZero(),
};
}
@end
@implementation _CPStepperValueBinder : CPBinder
{
}
- (void)_updatePlaceholdersWithOptions:(CPDictionary)options forBinding:(CPString)aBinding
{
var placeholder = (aBinding == CPMaxValueBinding) ? [_source maxValue] : [_source minValue];
[super _updatePlaceholdersWithOptions:options];
[self _setPlaceholder:placeholder forMarker:CPMultipleValuesMarker isDefault:YES];
[self _setPlaceholder:placeholder forMarker:CPNoSelectionMarker isDefault:YES];
[self _setPlaceholder:placeholder forMarker:CPNotApplicableMarker isDefault:YES];
[self _setPlaceholder:placeholder forMarker:CPNullMarker isDefault:YES];
}
@end
+1
View File
@@ -22,6 +22,7 @@
@import <Foundation/CPString.j>
@import "CGGeometry.j"
@import "CPPlatformString.j"
+40 -21
View File
@@ -88,9 +88,6 @@ var CPTabViewDidSelectTabViewItemSelector = 1,
_box = [[CPBox alloc] initWithFrame:[self bounds]];
[self setBackgroundColor:[CPColor colorWithCalibratedWhite:0.95 alpha:1.0]];
[_box setAutoresizingMask:CPViewWidthSizable | CPViewHeightSizable];
[_tabs setAutoresizingMask:CPViewMinXMargin | CPViewMaxXMargin];
[self addSubview:_box];
[self addSubview:_tabs];
}
@@ -343,21 +340,9 @@ var CPTabViewDidSelectTabViewItemSelector = 1,
_type = aTabViewType;
if (_type !== CPTopTabsBezelBorder && _type !== CPBottomTabsBezelBorder)
{
[_box setFrame:[self bounds]];
[_tabs removeFromSuperview];
}
else
{
var aFrame = [self frame],
segmentedHeight = _CGRectGetHeight([_tabs frame]),
origin = _type === CPTopTabsBezelBorder ? segmentedHeight / 2 : 0;
[_box setFrame:_CGRectMake(0, origin, _CGRectGetWidth(aFrame),
_CGRectGetHeight(aFrame) - segmentedHeight / 2)];
[self addSubview:_tabs];
}
switch (_type)
{
@@ -373,6 +358,29 @@ var CPTabViewDidSelectTabViewItemSelector = 1,
[_box setBorderType:CPNoBorder];
break;
}
[self setNeedsLayout];
}
- (void)layoutSubviews
{
// Even if CPTabView's autoresizesSubviews is NO, _tabs and _box has to be laid out.
// This means we can't rely on autoresize masks.
if (_type !== CPTopTabsBezelBorder && _type !== CPBottomTabsBezelBorder)
{
[_box setFrame:[self bounds]];
}
else
{
var aFrame = [self frame],
segmentedHeight = _CGRectGetHeight([_tabs frame]),
origin = _type === CPTopTabsBezelBorder ? segmentedHeight / 2 : 0;
[_box setFrame:_CGRectMake(0, origin, _CGRectGetWidth(aFrame),
_CGRectGetHeight(aFrame) - segmentedHeight / 2)];
[self _repositionTabs];
}
}
/*!
@@ -497,20 +505,31 @@ var CPTabViewItemsKey = "CPTabViewItemsKey",
[_items makeObjectsPerformSelector:@selector(_setTabView:) withObject:self];
[self _updateItems];
[self _repositionTabs];
[self setDelegate:[aCoder decodeObjectForKey:CPTabViewDelegateKey]];
var selected = [aCoder decodeObjectForKey:CPTabViewSelectedItemKey];
if (selected)
[self selectTabViewItem:selected];
[self setTabViewType:[aCoder decodeIntForKey:CPTabViewTypeKey]];
self.selectOnAwake = [aCoder decodeObjectForKey:CPTabViewSelectedItemKey];
_type = [aCoder decodeIntForKey:CPTabViewTypeKey];
}
return self;
}
- (void)awakeFromCib
{
if (self.selectOnAwake)
{
[self selectTabViewItem:self.selectOnAwake];
delete self.selectOnAwake;
}
var type = _type;
_type = nil;
[self setTabViewType:type];
[self setNeedsLayout];
}
- (void)encodeWithCoder:(CPCoder)aCoder
{
[super encodeWithCoder:aCoder];
+2 -1
View File
@@ -60,6 +60,7 @@ CPPressedTab = 2;
CPView _auxiliaryView;
CPTabView _tabView;
unsigned _tabState; // Looks like it is not yet implemented
}
- (id)init
@@ -138,7 +139,7 @@ CPPressedTab = 2;
_view = aView;
if ([_tabView selectedTabViewItem] == self)
[_tabView _setContentViewForItem:self];
[_tabView _setContentViewFromItem:self];
}
/*!
+14 -23
View File
@@ -26,8 +26,11 @@
@import <Foundation/CPSortDescriptor.j>
@import <Foundation/CPString.j>
@import "CPTableHeaderView.j"
@import "CPTextField.j"
@global CPTableViewColumnDidResizeNotification
@class _CPTableColumnHeaderView
CPTableColumnNoResizing = 0;
CPTableColumnAutoresizingMask = 1 << 0;
@@ -49,7 +52,7 @@ CPTableColumnUserResizingMask = 1 << 1;
CPTableView _tableView;
CPView _headerView;
CPView _dataView;
Object _dataViewData;
CPData _dataViewData;
float _width;
float _minWidth;
@@ -83,7 +86,7 @@ CPTableColumnUserResizingMask = 1 << 1;
if (self)
{
_dataViewData = { };
_dataViewData = nil;
_width = 100.0;
_minWidth = 10.0;
@@ -392,12 +395,12 @@ CPTableColumnUserResizingMask = 1 << 1;
- (void)setDataView:(CPView)aView
{
if (_dataView)
_dataViewData[[_dataView UID]] = nil;
_dataViewData = nil;
[aView setThemeState:CPThemeStateTableDataView];
_dataView = aView;
_dataViewData[[aView UID]] = [CPKeyedArchiver archivedDataWithRootObject:aView];
_dataViewData = [CPKeyedArchiver archivedDataWithRootObject:aView];
}
- (CPView)dataView
@@ -421,24 +424,12 @@ CPTableColumnUserResizingMask = 1 << 1;
/*!
@ignore
*/
- (id)_newDataViewForRow:(int)aRowIndex
- (id)_newDataView
{
var dataView = [self dataViewForRow:aRowIndex],
dataViewUID = [dataView UID];
if (!_dataViewData)
return nil;
var x = [self tableView]._cachedDataViews[dataViewUID];
if (x && x.length)
return x.pop();
// if we haven't cached an archive of the data view, do it now
if (!_dataViewData[dataViewUID])
_dataViewData[dataViewUID] = [CPKeyedArchiver archivedDataWithRootObject:dataView];
// unarchive the data view cache
var newDataView = [CPKeyedUnarchiver unarchiveObjectWithData:_dataViewData[dataViewUID]];
newDataView.identifier = dataViewUID;
// make sure only we have control over the size and placement
var newDataView = [CPKeyedUnarchiver unarchiveObjectWithData:_dataViewData];
[newDataView setAutoresizingMask:CPViewNotSizable];
return newDataView;
@@ -557,7 +548,7 @@ CPTableColumnUserResizingMask = 1 << 1;
[[CPNotificationCenter defaultCenter]
postNotificationName:CPTableViewColumnDidResizeNotification
object:[self tableView]
userInfo:[CPDictionary dictionaryWithObjects:[self, oldWidth] forKeys:[@"CPTableColumn", "CPOldWidth"]]];
userInfo:@{ @"CPTableColumn": self, @"CPOldWidth": oldWidth }];
}
@end
@@ -754,7 +745,7 @@ var CPTableColumnIdentifierKey = @"CPTableColumnIdentifierKey",
if (self)
{
_dataViewData = { };
_dataViewData = nil;
_width = [aCoder decodeFloatForKey:CPTableColumnWidthKey];
_minWidth = [aCoder decodeFloatForKey:CPTableColumnMinWidthKey];
+29 -5
View File
@@ -22,9 +22,15 @@
@import <Foundation/CPIndexSet.j>
@import "CPCursor.j"
@import "CPPasteboard.j"
@import "CPTableColumn.j"
@import "CPTableView.j"
@import "CPView.j"
@import "_CPImageAndTextView.j"
@class CPTableView
@global CPApp
@implementation _CPTableColumnHeaderView : CPView
@@ -39,13 +45,22 @@
+ (id)themeAttributes
{
return [CPDictionary dictionaryWithObjects:[[CPNull null], CPLeftTextAlignment, CPLineBreakByTruncatingTail, CGInsetMakeZero(), [CPNull null], [CPNull null], [CPNull null], CGSizeMakeZero()]
forKeys:[@"background-color", @"text-alignment", @"line-break-mode", @"text-inset", @"text-color", @"font", @"text-shadow-color", @"text-shadow-offset"]];
return @{
@"background-color": [CPNull null],
@"text-alignment": CPLeftTextAlignment,
@"line-break-mode": CPLineBreakByTruncatingTail,
@"text-inset": CGInsetMakeZero(),
@"text-color": [CPNull null],
@"font": [CPNull null],
@"text-shadow-color": [CPNull null],
@"text-shadow-offset": CGSizeMakeZero(),
};
}
- (void)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self)
[self _init];
@@ -232,8 +247,10 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal
+ (id)themeAttributes
{
return [CPDictionary dictionaryWithObjects:[[CPNull null], [CPColor grayColor]]
forKeys:[@"background-color", @"divider-color"]];
return @{
@"background-color": [CPNull null],
@"divider-color": [CPColor grayColor],
};
}
- (void)_init
@@ -314,6 +331,9 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal
{
var headerView = [_tableView._tableColumns[column] headerView];
[headerView setThemeState:CPThemeStateHighlighted];
if (_tableView._editingColumn == column)
[[self window] makeFirstResponder:_tableView];
}
_pressedColumn = column;
@@ -544,6 +564,8 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal
[self stopTrackingTableColumn:_activeColumn at:aLocation];
[self setNeedsDisplay:YES];
[_tableView _enqueueDraggingViews];
}
- (BOOL)shouldResizeTableColumn:(int)aColumnIndex at:(CGPoint)aPoint
@@ -692,6 +714,7 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal
columnMaxX;
CGContextBeginPath(context);
for (; columnArrayIndex < columnArrayCount; columnArrayIndex++)
{
// grab each column rect and add vertical lines
@@ -703,6 +726,7 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal
CGContextMoveToPoint(context, FLOOR(columnMaxX) - 0.5, ROUND(_CGRectGetMinY(columnToStroke)));
CGContextAddLineToPoint(context, FLOOR(columnMaxX) - 0.5, ROUND(_CGRectGetMaxY(columnToStroke)) - 1.0);
}
CGContextClosePath(context);
CGContextStrokePath(context);
+522 -68
View File
File diff suppressed because it is too large Load Diff
+173 -84
View File
@@ -20,13 +20,17 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#import "../Foundation/Ref.h"
@import "CPControl.j"
@import "CPStringDrawing.j"
@import "CPCompatibility.j"
@import "CPText.j"
@import "CPWindow_Constants.j"
@import "_CPImageAndTextView.j"
@class CPPasteboard
@global CPApp
@global CPStringPboardType
CPTextFieldSquareBezel = 0; /*! A textfield bezel with squared corners. */
CPTextFieldRoundedBezel = 1; /*! A textfield bezel with rounded corners. */
@@ -34,8 +38,6 @@ CPTextFieldRoundedBezel = 1; /*! A textfield bezel with rounded corne
CPTextFieldDidFocusNotification = @"CPTextFieldDidFocusNotification";
CPTextFieldDidBlurNotification = @"CPTextFieldDidBlurNotification";
#if PLATFORM(DOM)
var CPTextFieldDOMInputElement = nil,
CPTextFieldDOMPasswordInputElement = nil,
CPTextFieldDOMStandardInputElement = nil,
@@ -46,13 +48,42 @@ var CPTextFieldDOMInputElement = nil,
CPTextFieldInputIsActive = NO,
CPTextFieldCachedSelectStartFunction = nil,
CPTextFieldCachedDragFunction = nil,
CPTextFieldBlurFunction = nil,
CPTextFieldBlurHandler = nil,
CPTextFieldInputFunction = nil;
#endif
var CPSecureTextFieldCharacter = "\u2022";
function CPTextFieldBlurFunction(anEvent, owner, domElement, inputElement, resigning, didBlurRef)
{
if (owner && domElement != inputElement.parentNode)
return;
if (!resigning && [[owner window] isKeyWindow])
{
/*
Browsers blur text fields when a click occurs anywhere outside the text field. That is normal for browsers, but in Cocoa the key view retains focus unless the click target accepts first responder. So if we lost focus but were not told to resign and our window is still key, restore focus.
*/
window.setTimeout(function()
{
inputElement.focus();
}, 0.0);
}
CPTextFieldHandleBlur(anEvent, @ref(owner));
@deref(didBlurRef) = YES;
return true;
}
function CPTextFieldHandleBlur(anEvent, ownerRef)
{
@deref(ownerRef) = nil;
[[CPRunLoop currentRunLoop] limitDateForMode:CPDefaultRunLoopMode];
}
@implementation CPString (CPTextFieldAdditions)
/*!
@@ -96,6 +127,18 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
CPControlSize _controlSize;
}
+ (Class)_binderClassForBinding:(CPString)aBinding
{
if (aBinding === CPValueBinding)
return [_CPTextFieldValueBinder class];
else if ([aBinding hasPrefix:CPDisplayPatternValueBinding])
return [_CPTextFieldPatternValueBinder class];
else if ([aBinding hasPrefix:CPEditableBinding])
return [CPMultipleValueAndBinding class];
return [super _binderClassForBinding:aBinding];
}
+ (CPTextField)textFieldWithStringValue:(CPString)aStringValue placeholder:(CPString)aPlaceholder width:(float)aWidth
{
return [self textFieldWithStringValue:aStringValue placeholder:aPlaceholder width:aWidth theme:[CPTheme defaultTheme]];
@@ -159,18 +202,13 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
return "textfield";
}
+ (Class)_binderClassForBinding:(CPString)theBinding
{
if (theBinding === CPValueBinding)
return [_CPTextFieldValueBinder class];
return [super _binderClassForBinding:theBinding];
}
+ (id)themeAttributes
{
return [CPDictionary dictionaryWithObjects:[_CGInsetMakeZero(), _CGInsetMake(2.0, 2.0, 2.0, 2.0), [CPNull null]]
forKeys:[@"bezel-inset", @"content-inset", @"bezel-color"]];
return @{
@"bezel-inset": _CGInsetMakeZero(),
@"content-inset": _CGInsetMake(1.0, 0.0, 0.0, 0.0),
@"bezel-color": [CPNull null],
};
}
/* @ignore */
@@ -188,28 +226,15 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
CPTextFieldDOMInputElement.style.background = "transparent";
CPTextFieldDOMInputElement.style.outline = "none";
CPTextFieldBlurFunction = function(anEvent)
CPTextFieldBlurHandler = function(anEvent)
{
if (CPTextFieldInputOwner && CPTextFieldInputOwner._DOMElement != CPTextFieldDOMInputElement.parentNode)
return;
if (!CPTextFieldInputResigning)
{
[[CPTextFieldInputOwner window] makeFirstResponder:nil];
return;
}
CPTextFieldHandleBlur(anEvent, CPTextFieldDOMInputElement);
CPTextFieldInputDidBlur = YES;
return true;
};
CPTextFieldHandleBlur = function(anEvent)
{
CPTextFieldInputOwner = nil;
[[CPRunLoop currentRunLoop] limitDateForMode:CPDefaultRunLoopMode];
return CPTextFieldBlurFunction(
anEvent,
CPTextFieldInputOwner,
CPTextFieldInputOwner._DOMElement,
CPTextFieldDOMInputElement,
CPTextFieldInputResigning,
@ref(CPTextFieldInputDidBlur));
};
if (CPFeatureIsCompatible(CPInputOnInputEventFeature))
@@ -219,9 +244,16 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
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];
@@ -231,8 +263,8 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
CPTextFieldDOMInputElement.oninput = CPTextFieldInputFunction;
}
//FIXME make this not onblur
CPTextFieldDOMInputElement.onblur = CPTextFieldBlurFunction;
// FIXME make this not onblur
CPTextFieldDOMInputElement.onblur = CPTextFieldBlurHandler;
CPTextFieldDOMStandardInputElement = CPTextFieldDOMInputElement;
}
@@ -261,7 +293,7 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
CPTextFieldDOMPasswordInputElement.style.outline = "none";
CPTextFieldDOMPasswordInputElement.type = "password";
CPTextFieldDOMPasswordInputElement.onblur = CPTextFieldBlurFunction;
CPTextFieldDOMPasswordInputElement.onblur = CPTextFieldBlurHandler;
}
CPTextFieldDOMInputElement = CPTextFieldDOMPasswordInputElement;
@@ -308,9 +340,19 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
if (shouldBeEditable)
_isSelectable = YES;
if (_isEditable)
[self setThemeState:CPThemeStateEditable];
else
[self unsetThemeState:CPThemeStateEditable];
// We only allow first responder status if the field is editable and enabled.
if (!shouldBeEditable && [[self window] firstResponder] === self)
[[self window] makeFirstResponder:nil];
if (shouldBeEditable)
[self setThemeState:CPThemeStateEditable];
else
[self unsetThemeState:CPThemeStateEditable];
}
/*!
@@ -489,14 +531,8 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
/* @ignore */
- (BOOL)becomeFirstResponder
{
#if PLATFORM(DOM)
if (CPTextFieldInputOwner && [CPTextFieldInputOwner window] !== [self window])
[[CPTextFieldInputOwner window] makeFirstResponder:nil];
#endif
// As long as we are the first responder we need to monitor the key status of our window.
[[CPNotificationCenter defaultCenter] addObserver:self selector:@selector(_windowDidResignKey:) name:CPWindowDidResignKeyNotification object:[self window]];
[[CPNotificationCenter defaultCenter] addObserver:self selector:@selector(_windowDidBecomeKey:) name:CPWindowDidBecomeKeyNotification object:[self window]];
[self _setObserveWindowKeyNotifications:YES];
_isEditing = NO;
@@ -507,12 +543,15 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
}
/*!
A text field can be the first responder without necessarily being the focus of keyboard input. For example, it might be the first responder of window A but window B is the main and key window. It's important we don't put a focused input field into a text field in a non key window, even if that field is the first responder, because the key window might also have a first responder text field which the user will expect to receive keyboard input.
A text field can be the first responder without necessarily being the focus of keyboard input. For example, it might be the first responder of window A but window B is the main and key window. It's important we don't put a focused input field into a text field in a non-key window, even if that field is the first responder, because the key window might also have a first responder text field which the user will expect to receive keyboard input.
Since a first responder but non-key window text field can't receive input it should not even look like an active text field (Cocoa has a "slightly active" text field look it uses when another window is the key window, but Cappuccino doesn't today.)
*/
- (void)_becomeFirstKeyResponder
{
// Make sure the text field is visible so the browser will not scroll without the NSScrollView knowing about it.
[self scrollRectToVisible:[self bounds]];
[self setThemeState:CPThemeStateEditing];
[self _updatePlaceholderState];
@@ -529,8 +568,10 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
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])
@@ -566,37 +607,24 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
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.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.
// 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];
window.setTimeout(function()
{
element.focus();
// Select the text if the textfield became first responder through keyboard interaction
if (!_willBecomeFirstResponderByClick)
[self _selectText:self immediately:YES];
_willBecomeFirstResponderByClick = NO;
[self textDidFocus:[CPNotification notificationWithName:CPTextFieldDidFocusNotification object:self userInfo:nil]];
CPTextFieldInputOwner = self;
}, 0.0);
[[[self window] platformWindow] _propagateCurrentDOMEvent:YES];
CPTextFieldInputIsActive = YES;
if (document.attachEvent)
@@ -607,16 +635,34 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
[[self window] platformWindow]._DOMBodyElement.ondrag = function () {};
[[self window] platformWindow]._DOMBodyElement.onselectstart = function () {};
}
CPTextFieldInputOwner = self;
window.setTimeout(function()
{
/*
setTimeout handlers are not guaranteed to fire in the order they were initiated. This can cause a race condition when several windows with text fields are opened quickly, resulting in several instances of this timeout function being fired, perhaps out of order. So we have to check that by the time this function is fired, CPTextFieldInputOwner has not been changed to another text field in the meantime.
*/
if (CPTextFieldInputOwner !== self)
return;
element.focus();
// Select the text if the textfield became first responder through keyboard interaction
if (!_willBecomeFirstResponderByClick)
[self _selectText:self immediately:YES];
_willBecomeFirstResponderByClick = NO;
[self textDidFocus:[CPNotification notificationWithName:CPTextFieldDidFocusNotification object:self userInfo:nil]];
}, 0.0);
#endif
}
/* @ignore */
- (BOOL)resignFirstResponder
{
// When we are no longer the first responder we don't worry about the key status of our window anymore.
[[CPNotificationCenter defaultCenter] removeObserver:self name:CPWindowDidResignKeyNotification object:[self window]];
[[CPNotificationCenter defaultCenter] removeObserver:self name:CPWindowDidBecomeKeyNotification object:[self window]];
#if PLATFORM(DOM)
var element = [self _inputElement],
@@ -638,6 +684,9 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
#endif
// When we are no longer the first responder we don't worry about the key status of our window anymore.
[self _setObserveWindowKeyNotifications:NO];
[self _resignFirstKeyResponder];
_isEditing = NO;
@@ -661,7 +710,6 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
_willBecomeFirstResponderByClick = NO;
[self _updatePlaceholderState];
[self setNeedsLayout];
#if PLATFORM(DOM)
@@ -674,7 +722,7 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
element.blur();
if (!CPTextFieldInputDidBlur)
CPTextFieldBlurFunction();
CPTextFieldBlurHandler();
CPTextFieldInputDidBlur = NO;
CPTextFieldInputResigning = NO;
@@ -696,6 +744,20 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
#endif
}
- (void)_setObserveWindowKeyNotifications:(BOOL)shouldObserve
{
if (shouldObserve)
{
[[CPNotificationCenter defaultCenter] addObserver:self selector:@selector(_windowDidResignKey:) name:CPWindowDidResignKeyNotification object:[self window]];
[[CPNotificationCenter defaultCenter] addObserver:self selector:@selector(_windowDidBecomeKey:) name:CPWindowDidBecomeKeyNotification object:[self window]];
}
else
{
[[CPNotificationCenter defaultCenter] removeObserver:self name:CPWindowDidResignKeyNotification object:[self window]];
[[CPNotificationCenter defaultCenter] removeObserver:self name:CPWindowDidBecomeKeyNotification object:[self window]];
}
}
- (void)_windowDidResignKey:(CPNotification)aNotification
{
if (![[self window] isKeyWindow])
@@ -714,7 +776,7 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
var error = @"";
if ([self _setStringValue:aValue isNewValue:NO errorDescription:AT_REF(error)] === NO)
if ([self _setStringValue:aValue isNewValue:NO errorDescription:@ref(error)] === NO)
{
var acceptInvalidValue = NO;
@@ -731,11 +793,20 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
}
/*!
Text fields require panels to become key window, so this returns \c YES.
Text fields require panels to become key window, so this returns \c YES
if the text field is ready to become the first responder as well.
*/
- (BOOL)needsPanelToBecomeKey
{
return YES;
return [self acceptsFirstResponder];
}
/*!
Only text fields that can become first responder accepts first mouse.
*/
- (BOOL)acceptsFirstMouse:(CPEvent)anEvent
{
return [self acceptsFirstResponder];
}
- (void)mouseDown:(CPEvent)anEvent
@@ -972,7 +1043,7 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
{
var object = nil;
if ([formatter getObjectValue:AT_REF(object) forString:aValue errorDescription:anError])
if ([formatter getObjectValue:@ref(object) forString:aValue errorDescription:anError])
objectValue = object;
else
{
@@ -1011,7 +1082,7 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
// Formatting failed, get an "empty" object by formatting an empty string.
// If that fails, the value is undefined.
if ([formatter getObjectValue:AT_REF(value) forString:@"" errorDescription:nil] === NO)
if ([formatter getObjectValue:@ref(value) forString:@"" errorDescription:nil] === NO)
value = undefined;
[super setObjectValue:value];
@@ -1568,10 +1639,8 @@ var CPTextFieldIsEditableKey = "CPTextFieldIsEditableKey",
@end
@implementation _CPTextFieldValueBinder : CPBinder
{
}
- (void)_updatePlaceholdersWithOptions:(CPDictionary)options
- (void)_updatePlaceholdersWithOptions:(CPDictionary)options forBinding:(CPBinder)aBinding
{
[super _updatePlaceholdersWithOptions:options];
@@ -1589,8 +1658,28 @@ var CPTextFieldIsEditableKey = "CPTextFieldIsEditableKey",
- (void)setValue:(id)aValue forBinding:(CPString)aBinding
{
if (!aValue || (aValue.isa && [aValue isMemberOfClass:CPNull]))
[_source setPlaceholderString:[self _placeholderForMarker:CPNullMarker]];
[_source setObjectValue:aValue];
}
@end
@implementation _CPTextFieldPatternValueBinder : CPValueWithPatternBinding
- (void)setPlaceholderValue:(id)aValue withMarker:(CPString)aMarker forBinding:(CPString)aBinding
{
[_source setPlaceholderString:aValue];
[_source setObjectValue:nil];
}
- (void)setValue:(id)aValue forBinding:(CPString)aBinding
{
if (!aValue || (aValue.isa && [aValue isMemberOfClass:CPNull]))
[_source setPlaceholderString:[self _placeholderForMarker:CPNullMarker]];
[_source setObjectValue:aValue];
}
@end
+10 -8
View File
@@ -21,9 +21,11 @@
*/
@import <Foundation/CPObject.j>
@import <Foundation/CPMutableArray.j>
@import <Foundation/CPString.j>
@import <Foundation/CPKeyedUnarchiver.j>
@class CPView
var CPThemesByName = { },
CPThemeDefaultTheme = nil,
@@ -83,7 +85,7 @@ var CPThemesByName = { },
if (self)
{
_name = aName;
_attributes = [CPDictionary dictionary];
_attributes = @{};
CPThemesByName[_name] = self;
}
@@ -145,7 +147,7 @@ var CPThemesByName = { },
className = [aClass defaultThemeClass];
else if ([aClass respondsToSelector:@selector(themeClass)])
{
CPLog.warn(@"%@ themeClass is deprecated in favor of defaultThemeClass",CPStringFromClass([anObject class]));
CPLog.warn(@"%@ themeClass is deprecated in favor of defaultThemeClass", CPStringFromClass(aClass));
className = [aClass themeClass];
}
else
@@ -268,7 +270,7 @@ var CPThemesByName = { },
if (!attributes)
{
attributes = [CPDictionary dictionary];
attributes = @{};
[_attributes setObject:attributes forKey:aClass];
}
@@ -441,7 +443,7 @@ CPThemeStateKeyWindow = CPThemeState("keyWindow");
_cache = { };
_name = aName;
_defaultValue = aDefaultValue;
_values = [CPDictionary dictionary];
_values = @{};
}
return self;
@@ -472,9 +474,9 @@ CPThemeStateKeyWindow = CPThemeState("keyWindow");
_cache = {};
if (aValue === undefined || aValue === nil)
_values = [CPDictionary dictionary];
_values = @{};
else
_values = [CPDictionary dictionaryWithObject:aValue forKey:String(CPThemeStateNormal)];
_values = @{ String(CPThemeStateNormal): aValue };
}
- (void)setValue:(id)aValue forState:(CPThemeState)aState
@@ -583,7 +585,7 @@ CPThemeStateKeyWindow = CPThemeState("keyWindow");
_name = [aCoder decodeObjectForKey:@"name"];
_defaultValue = [aCoder decodeObjectForKey:@"defaultValue"];
_values = [CPDictionary dictionary];
_values = @{};
if ([aCoder containsValueForKey:@"value"])
{
@@ -631,7 +633,7 @@ CPThemeStateKeyWindow = CPThemeState("keyWindow");
}
else
{
var encodedValues = [CPDictionary dictionary];
var encodedValues = @{};
while (count--)
{
+1 -1
View File
@@ -33,7 +33,7 @@
@implementation CPThemeBlend : CPObject
{
CPBundle _bundle;
CPBundle _bundle @accessors(getter=bundle);
CPArray _themes;
id _loadDelegate;
}
+349 -105
View File
@@ -26,12 +26,16 @@
@import <Foundation/CPIndexSet.j>
@import <Foundation/CPTimer.j>
@import "CPButton.j"
@import "CPScrollView.j"
@import "CPTextField.j"
@import "CPTableView.j"
@import "CPWindow.j"
@import "_CPAutocompleteMenu.j"
@import "CPButton.j"
@import "CPPopUpButton.j"
@import "CPScrollView.j"
@import "CPTableView.j"
@import "CPText.j"
@import "CPTextField.j"
@import "CPWindow_Constants.j"
@global CPApp
#if PLATFORM(DOM)
@@ -47,7 +51,7 @@ var CPTokenFieldDOMInputElement = nil,
CPTokenFieldCachedDragFunction = nil,
CPTokenFieldFocusInput = NO,
CPTokenFieldBlurFunction = nil;
CPTokenFieldBlurHandler = nil;
#endif
@@ -55,6 +59,9 @@ var CPScrollDestinationNone = 0,
CPScrollDestinationLeft = 1,
CPScrollDestinationRight = 2;
CPTokenFieldDisclosureButtonType = 0;
CPTokenFieldDeleteButtonType = 1;
@implementation CPTokenField : CPTextField
{
CPScrollView _tokenScrollView;
@@ -71,8 +78,9 @@ var CPScrollDestinationNone = 0,
CPEvent _mouseDownEvent;
BOOL _preventResign;
BOOL _shouldNotifyTarget;
int _buttonType @accessors(property=buttonType);
}
+ (CPCharacterSet)defaultTokenizingCharacterSet
@@ -92,15 +100,16 @@ var CPScrollDestinationNone = 0,
+ (id)themeAttributes
{
return [CPDictionary dictionaryWithObject:_CGInsetMakeZero() forKey:@"editor-inset"];
return @{ @"editor-inset": _CGInsetMakeZero() };
}
- (id)initWithFrame:(CPRect)frame
- (id)initWithFrame:(CGRect)frame
{
if (self = [super initWithFrame:frame])
{
_completionDelay = [[self class] defaultCompletionDelay];
_tokenizingCharacterSet = [[self class] defaultTokenizingCharacterSet];
_buttonType = CPTokenFieldDisclosureButtonType;
[self setBezeled:YES];
[self _init];
@@ -138,18 +147,23 @@ var CPScrollDestinationNone = 0,
return _autocompleteMenu;
}
- (void)_complete:(_CPAutocompleteMenu)anAutocompleteMenu
{
[self _autocompleteWithEvent:nil];
}
- (void)_autocompleteWithEvent:(CPEvent)anEvent
{
if (![self _inputElement].value && (![_autocompleteMenu contentArray] || ![self hasThemeState:CPThemeStateAutocompleting]))
if (![self _editorValue] && (![_autocompleteMenu contentArray] || ![self hasThemeState:CPThemeStateAutocompleting]))
return;
[self _hideCompletions];
var token = [_autocompleteMenu selectedItem],
shouldRemoveLastObject = token !== @"" && [self _inputElement].value !== @"";
shouldRemoveLastObject = token !== @"" && [self _editorValue] !== @"";
if (!token)
token = [self _inputElement].value;
token = [self _editorValue];
// Make sure the user typed an actual token to prevent the previous token from being emptied
// If the input area is empty, we want to fall back to the normal behavior, resigning first
@@ -307,9 +321,24 @@ var CPScrollDestinationNone = 0,
- (BOOL)becomeFirstResponder
{
#if PLATFORM(DOM)
if (CPTokenFieldInputOwner && [CPTokenFieldInputOwner window] !== [self window])
[[CPTokenFieldInputOwner window] makeFirstResponder:nil];
#endif
// As long as we are the first responder we need to monitor the key status of our window.
[self _setObserveWindowKeyNotifications:YES];
[self scrollRectToVisible:[self bounds]];
if ([[self window] isKeyWindow])
[self _becomeFirstKeyResponder];
return YES;
}
- (void)_becomeFirstKeyResponder
{
[self setThemeState:CPThemeStateEditing];
[self _updatePlaceholderState];
@@ -343,16 +372,19 @@ var CPScrollDestinationNone = 0,
element.style.width = CGRectGetWidth(contentRect) + "px";
element.style.height = [font defaultLineHeightForFont] + "px";
[_tokenScrollView documentView]._DOMElement.appendChild(element);
window.setTimeout(function()
{
element.focus();
CPTokenFieldInputOwner = self;
}, 0.0);
[_tokenScrollView documentView]._DOMElement.appendChild(element);
//post CPControlTextDidBeginEditingNotification
[self textDidBeginEditing:[CPNotification notificationWithName:CPControlTextDidBeginEditingNotification object:self userInfo:nil]];
//post CPControlTextDidBeginEditingNotification
[self textDidBeginEditing:[CPNotification notificationWithName:CPControlTextDidBeginEditingNotification object:self userInfo:nil]];
window.setTimeout(function()
{
element.focus();
CPTokenFieldInputOwner = self;
}, 0.0);
}, 0.0);
[[[self window] platformWindow] _propagateCurrentDOMEvent:YES];
@@ -368,18 +400,35 @@ var CPScrollDestinationNone = 0,
}
#endif
return YES;
}
- (BOOL)resignFirstResponder
{
if (_preventResign)
return NO;
[self _autocomplete];
// From CPTextField superclass.
[self _setObserveWindowKeyNotifications:NO];
[self _resignFirstKeyResponder];
if (_shouldNotifyTarget)
{
_shouldNotifyTarget = NO;
[self textDidEndEditing:[CPNotification notificationWithName:CPControlTextDidEndEditingNotification object:self userInfo:nil]];
if ([self sendsActionOnEndEditing])
[self sendAction:[self action] to:[self target]];
}
return YES;
}
- (void)_resignFirstKeyResponder
{
[self unsetThemeState:CPThemeStateEditing];
[self _autocomplete];
[self _updatePlaceholderState];
[self setNeedsLayout];
#if PLATFORM(DOM)
@@ -389,7 +438,7 @@ var CPScrollDestinationNone = 0,
element.blur();
if (!CPTokenFieldInputDidBlur)
CPTokenFieldBlurFunction();
CPTokenFieldBlurHandler();
CPTokenFieldInputDidBlur = NO;
CPTokenFieldInputResigning = NO;
@@ -409,26 +458,10 @@ var CPScrollDestinationNone = 0,
}
#endif
[self _updatePlaceholderState];
[self setNeedsLayout];
if (_shouldNotifyTarget)
{
_shouldNotifyTarget = NO;
[self textDidEndEditing:[CPNotification notificationWithName:CPControlTextDidEndEditingNotification object:self userInfo:nil]];
if ([self sendsActionOnEndEditing])
[self sendAction:[self action] to:[self target]];
}
return YES;
}
- (void)mouseDown:(CPEvent)anEvent
{
_preventResign = YES;
_mouseDownEvent = anEvent;
[self _selectToken:nil byExtendingSelection:NO];
@@ -438,13 +471,11 @@ var CPScrollDestinationNone = 0,
- (void)mouseUp:(CPEvent)anEvent
{
_preventResign = NO;
_mouseDownEvent = nil;
}
- (void)_mouseDownOnToken:(_CPTokenFieldToken)aToken withEvent:(CPEvent)anEvent
{
_preventResign = YES;
_mouseDownEvent = anEvent;
}
@@ -457,8 +488,6 @@ var CPScrollDestinationNone = 0,
// Snap to the token if it's only half visible due to mouse wheel scrolling.
_shouldScrollTo = aToken;
}
_preventResign = NO;
}
// ===========
@@ -492,9 +521,9 @@ var CPScrollDestinationNone = 0,
#if PLATFORM(DOM)
if ([self _inputElement].value != @"")
if ([self _editorValue])
{
var token = [self _representedObjectForEditingString:[self _inputElement].value];
var token = [self _representedObjectForEditingString:[self _editorValue]];
[objectValue insertObject:token atIndex:_selectedRange.location];
}
@@ -543,10 +572,11 @@ var CPScrollDestinationNone = 0,
if (newToken === nil)
{
newToken = [[_CPTokenFieldToken alloc] init];
newToken = [_CPTokenFieldToken new];
[newToken setTokenField:self];
[newToken setRepresentedObject:tokenObject];
[newToken setStringValue:tokenValue];
[newToken setEditable:[self isEditable]];
[contentView addSubview:newToken];
}
@@ -592,6 +622,13 @@ var CPScrollDestinationNone = 0,
}
}
- (void)setEditable:(BOOL)shouldBeEditable
{
[super setEditable:shouldBeEditable];
[[self _tokens] makeObjectsPerformSelector:@selector(setEditable:) withObject:shouldBeEditable];
}
- (void)sendAction:(SEL)anAction to:(id)anObject
{
_shouldNotifyTarget = NO;
@@ -621,35 +658,19 @@ var CPScrollDestinationNone = 0,
CPTokenFieldDOMInputElement.style.background = "transparent";
CPTokenFieldDOMInputElement.style.outline = "none";
CPTokenFieldBlurFunction = function(anEvent)
CPTokenFieldBlurHandler = function(anEvent)
{
if (CPTokenFieldInputOwner && [CPTokenFieldInputOwner._tokenScrollView documentView]._DOMElement != CPTokenFieldDOMInputElement.parentNode)
return;
if (CPTokenFieldInputOwner && CPTokenFieldInputOwner._preventResign)
return false;
if (!CPTokenFieldInputResigning && !CPTokenFieldFocusInput)
{
[[CPTokenFieldInputOwner window] makeFirstResponder:nil];
return;
}
CPTokenFieldHandleBlur(anEvent, CPTokenFieldDOMInputElement);
CPTokenFieldInputDidBlur = YES;
return true;
return CPTextFieldBlurFunction(
anEvent,
CPTokenFieldInputOwner,
CPTokenFieldInputOwner ? [CPTokenFieldInputOwner._tokenScrollView documentView]._DOMElement : nil,
CPTokenFieldDOMInputElement,
CPTokenFieldInputResigning,
@ref(CPTokenFieldInputDidBlur));
};
CPTokenFieldHandleBlur = function(anEvent)
{
CPTokenFieldInputOwner = nil;
[[CPRunLoop currentRunLoop] limitDateForMode:CPDefaultRunLoopMode];
};
//FIXME make this not onblur
CPTokenFieldDOMInputElement.onblur = CPTokenFieldBlurFunction;
// FIXME make this not onblur
CPTokenFieldDOMInputElement.onblur = CPTokenFieldBlurHandler;
CPTokenFieldDOMStandardInputElement = CPTokenFieldDOMInputElement;
}
@@ -668,6 +689,17 @@ var CPScrollDestinationNone = 0,
}
#endif
- (CPString)_editorValue
{
if (![self hasThemeState:CPThemeStateEditing])
return @"";
#if PLATFORM(DOM)
return [self _inputElement].value;
#else
return @"";
#endif
}
- (void)moveUp:(id)sender
{
[[self _autocompleteMenu] selectPrevious];
@@ -747,7 +779,7 @@ var CPScrollDestinationNone = 0,
- (void)moveLeft:(id)sender
{
// Left arrow
if ((_selectedRange.location > 0 || _selectedRange.length) && CPTokenFieldDOMInputElement.value == "")
if ((_selectedRange.location > 0 || _selectedRange.length) && [self _editorValue] == "")
{
if (_selectedRange.length)
// Simply collapse the range.
@@ -766,7 +798,7 @@ var CPScrollDestinationNone = 0,
- (void)moveLeftAndModifySelection:(id)sender
{
if (_selectedRange.location > 0 && CPTokenFieldDOMInputElement.value == "")
if (_selectedRange.location > 0 && [self _editorValue] == "")
{
_selectedRange.location--;
// When shift is depressed, select the next token backwards.
@@ -784,7 +816,7 @@ var CPScrollDestinationNone = 0,
- (void)moveRight:(id)sender
{
// Right arrow
if ((_selectedRange.location < [[self _tokens] count] || _selectedRange.length) && CPTokenFieldDOMInputElement.value == "")
if ((_selectedRange.location < [[self _tokens] count] || _selectedRange.length) && [self _editorValue] == "")
{
if (_selectedRange.length)
{
@@ -810,7 +842,7 @@ var CPScrollDestinationNone = 0,
- (void)moveRightAndModifySelection:(id)sender
{
if (_CPMaxRange(_selectedRange) < [[self _tokens] count] && CPTokenFieldDOMInputElement.value == "")
if (_CPMaxRange(_selectedRange) < [[self _tokens] count] && [self _editorValue] == "")
{
// Leave the selection location in place but include the next token to the right.
_selectedRange.length++;
@@ -828,7 +860,7 @@ var CPScrollDestinationNone = 0,
{
// TODO Even if the editor isn't empty you should be able to delete the previous token by placing the cursor
// at the beginning of the editor.
if (CPTokenFieldDOMInputElement.value == @"")
if ([self _editorValue] == @"")
{
[self _hideCompletions];
@@ -854,7 +886,7 @@ var CPScrollDestinationNone = 0,
{
// TODO Even if the editor isn't empty you should be able to delete the next token by placing the cursor
// at the end of the editor.
if (CPTokenFieldDOMInputElement.value == @"")
if ([self _editorValue] == @"")
{
// Delete forward if nothing is selected, else delete all selected.
[self _hideCompletions];
@@ -897,7 +929,9 @@ var CPScrollDestinationNone = 0,
- (void)keyDown:(CPEvent)anEvent
{
#if PLATFORM(DOM)
CPTokenFieldTextDidChangeValue = [self stringValue];
#endif
// Leave the default _propagateCurrentDOMEvent setting in place. This might be YES or NO depending
// on if something that could be a browser shortcut was pressed or not, such as Cmd-R to reload.
@@ -907,14 +941,16 @@ var CPScrollDestinationNone = 0,
[self interpretKeyEvents:[anEvent]];
[[CPRunLoop currentRunLoop] limitDateForMode:CPDefaultRunLoopMode];
}}
}
- (void)keyUp:(CPEvent)anEvent
{
#if PLATFORM(DOM)
if ([self stringValue] !== CPTokenFieldTextDidChangeValue)
{
[self textDidChange:[CPNotification notificationWithName:CPControlTextDidChangeNotification object:self userInfo:nil]];
}
#endif
[[[self window] platformWindow] _propagateCurrentDOMEvent:YES];
}
@@ -970,8 +1006,7 @@ var CPScrollDestinationNone = 0,
var frame = [self frame],
contentView = [_tokenScrollView documentView],
tokens = [self _tokens],
shouldShowAutoComplete = [self hasThemeState:CPThemeStateAutocompleting];
tokens = [self _tokens];
// Hack to make sure we are handling an array
if (![tokens isKindOfClass:[CPArray class]])
@@ -981,14 +1016,17 @@ var CPScrollDestinationNone = 0,
var contentRect = _CGRectMakeCopy([contentView bounds]),
contentOrigin = contentRect.origin,
contentSize = contentRect.size,
offset = CPPointMake(contentOrigin.x, contentOrigin.y),
spaceBetweenTokens = CPSizeMake(2.0, 2.0),
offset = CGPointMake(contentOrigin.x, contentOrigin.y),
spaceBetweenTokens = CGSizeMake(2.0, 2.0),
isEditing = [[self window] firstResponder] == self,
tokenToken = [_CPTokenFieldToken new],
font = [self currentValueForThemeAttribute:@"font"],
lineHeight = [font defaultLineHeightForFont],
editorInset = [self currentValueForThemeAttribute:@"editor-inset"];
// Put half a spacing above the tokens.
offset.y += CEIL(spaceBetweenTokens.height / 2.0);
// Get the height of a typical token, or a token token if you will.
[tokenToken sizeToFit];
@@ -1066,6 +1104,8 @@ var CPScrollDestinationNone = 0,
tokenFrame = fitAndFrame(tokenViewSize.width, tokenViewSize.height);
[tokenView setFrame:tokenFrame];
[tokenView setButtonType:_buttonType];
}
if (isEditing && !_selectedRange.length && _CPMaxRange(_selectedRange) >= [tokens count])
@@ -1088,7 +1128,7 @@ var CPScrollDestinationNone = 0,
}
// Trim off any excess height downwards (in case we shrank).
var scrollHeight = offset.y + tokenHeight + CEIL(spaceBetweenTokens.height / 2.0);
var scrollHeight = offset.y + tokenHeight;
if (_CGRectGetHeight([contentView bounds]) > scrollHeight)
[contentView setFrameSize:_CGSizeMake(_CGRectGetWidth([_tokenScrollView bounds]), scrollHeight)];
@@ -1218,6 +1258,30 @@ var CPScrollDestinationNone = 0,
return aString;
}
- (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];
return NO;
}
- (CPMenu)_menuForRepresentedObject:(id)aRepresentedObject
{
var delegate = [self delegate];
if ([delegate respondsToSelector:@selector(tokenField:hasMenuForRepresentedObject:)] &&
[delegate respondsToSelector:@selector(tokenField:menuForRepresentedObject:)])
{
var hasMenu = [delegate tokenField:self hasMenuForRepresentedObject:aRepresentedObject];
if (hasMenu)
return [delegate tokenField:self menuForRepresentedObject:aRepresentedObject] || nil;
}
return nil;
}
// We put the string on the pasteboard before calling this delegate method.
// By default, we write the NSStringPboardType as well as an array of NSStrings.
// - (BOOL)tokenField:(NSTokenField *)tokenField writeRepresentedObjects:(NSArray *)objects toPasteboard:(NSPasteboard *)pboard;
@@ -1242,13 +1306,25 @@ var CPScrollDestinationNone = 0,
[_autocompleteMenu _hideCompletions];
}
- (void)setButtonType:(int)aButtonType
{
if (_buttonType === aButtonType)
return;
_buttonType = aButtonType;
[self setNeedsLayout];
}
@end
@implementation _CPTokenFieldToken : CPTextField
{
_CPTokenFieldTokenCloseButton _deleteButton;
CPTokenField _tokenField;
id _representedObject;
_CPTokenFieldTokenCloseButton _deleteButton;
_CPTokenFieldTokenDisclosureButton _disclosureButton;
CPTokenField _tokenField;
id _representedObject;
int _buttonType;
}
+ (CPString)defaultThemeClass
@@ -1256,16 +1332,19 @@ var CPScrollDestinationNone = 0,
return "tokenfield-token";
}
- (id)initWithFrame:(CPRect)frame
- (BOOL)acceptsFirstResponder
{
return NO;
}
- (id)initWithFrame:(CGRect)frame
{
if (self = [super initWithFrame:frame])
{
_deleteButton = [[_CPTokenFieldTokenCloseButton alloc] initWithFrame:CPRectMakeZero()];
[self addSubview:_deleteButton];
[self setEditable:NO];
[self setHighlighted:NO];
[self setBezeled:YES];
[self setButtonType:CPTokenFieldDisclosureButtonType];
}
return self;
@@ -1289,6 +1368,41 @@ var CPScrollDestinationNone = 0,
- (void)setRepresentedObject:(id)representedObject
{
_representedObject = representedObject;
[self setNeedsLayout];
}
- (void)setEditable:(BOOL)shouldBeEditable
{
[super setEditable:shouldBeEditable];
[self setNeedsLayout];
}
- (BOOL)setThemeState:(CPThemeState)aState
{
var r = [super setThemeState:aState];
// Share hover state with the disclosure and delete buttons.
if (aState & CPThemeStateHovered)
{
[_disclosureButton setThemeState:CPThemeStateHovered];
[_deleteButton setThemeState:CPThemeStateHovered];
}
return r;
}
- (BOOL)unsetThemeState:(CPThemeState)aState
{
var r = [super unsetThemeState:aState];
// Share hover state with the disclosure and delete button.
if (aState & CPThemeStateHovered)
{
[_disclosureButton unsetThemeState:CPThemeStateHovered];
[_deleteButton unsetThemeState:CPThemeStateHovered];
}
return r;
}
- (CGSize)_minimumFrameSize
@@ -1304,6 +1418,47 @@ var CPScrollDestinationNone = 0,
return size;
}
- (void)setButtonType:(int)aButtonType
{
if (_buttonType === aButtonType)
return;
_buttonType = aButtonType;
if (_buttonType === CPTokenFieldDisclosureButtonType)
{
if (_deleteButton)
{
[_deleteButton removeFromSuperview];
_deleteButton = nil;
}
if (!_disclosureButton)
{
_disclosureButton = [[_CPTokenFieldTokenDisclosureButton alloc] initWithFrame:CGRectMakeZero()];
[self addSubview:_disclosureButton];
}
}
else
{
if (_disclosureButton)
{
[_disclosureButton removeFromSuperview];
_disclosureButton = nil;
}
if (!_deleteButton)
{
_deleteButton = [[_CPTokenFieldTokenCloseButton alloc] initWithFrame:CGRectMakeZero()];
[self addSubview:_deleteButton];
[_deleteButton setTarget:self];
[_deleteButton setAction:@selector(_delete:)];
}
}
[self setNeedsLayout];
}
- (void)layoutSubviews
{
[super layoutSubviews];
@@ -1312,16 +1467,33 @@ var CPScrollDestinationNone = 0,
positioned:CPWindowBelow
relativeToEphemeralSubviewNamed:@"content-view"];
if (bezelView)
if (bezelView && _tokenField)
{
[_deleteButton setTarget:self];
[_deleteButton setAction:@selector(_delete:)];
switch (_buttonType)
{
case CPTokenFieldDisclosureButtonType:
var shouldBeEnabled = [self hasMenu];
[_disclosureButton setHidden:!shouldBeEnabled];
var frame = [bezelView frame],
buttonOffset = [_deleteButton currentValueForThemeAttribute:@"offset"],
buttonSize = [_deleteButton currentValueForThemeAttribute:@"min-size"];
if (shouldBeEnabled)
[_disclosureButton setMenu:[self menu]];
[_deleteButton setFrame:_CGRectMake(CPRectGetMaxX(frame) - buttonOffset.x, CPRectGetMinY(frame) + buttonOffset.y, buttonSize.width, buttonSize.height)];
var frame = [bezelView frame],
buttonOffset = [_disclosureButton currentValueForThemeAttribute:@"offset"],
buttonSize = [_disclosureButton currentValueForThemeAttribute:@"min-size"];
[_disclosureButton setFrame:_CGRectMake(CGRectGetMaxX(frame) - buttonOffset.x, CGRectGetMinY(frame) + buttonOffset.y, buttonSize.width, buttonSize.height)];
break;
case CPTokenFieldDeleteButtonType:
[_deleteButton setEnabled:[self isEditable] && [self isEnabled]];
var frame = [bezelView frame],
buttonOffset = [_deleteButton currentValueForThemeAttribute:@"offset"],
buttonSize = [_deleteButton currentValueForThemeAttribute:@"min-size"];
[_deleteButton setFrame:_CGRectMake(CGRectGetMaxX(frame) - buttonOffset.x, CGRectGetMinY(frame) + buttonOffset.y, buttonSize.width, buttonSize.height)];
break;
}
}
}
@@ -1337,14 +1509,22 @@ var CPScrollDestinationNone = 0,
- (void)_delete:(id)sender
{
[_tokenField _deleteToken:self];
if ([self isEditable])
[_tokenField _deleteToken:self];
}
- (BOOL)hasMenu
{
return [_tokenField _hasMenuForRepresentedObject:_representedObject];
}
- (CPMenu)menu
{
return [_tokenField _menuForRepresentedObject:_representedObject];
}
@end
/*
Theming hook.
*/
@implementation _CPTokenFieldTokenCloseButton : CPButton
{
}
@@ -1363,11 +1543,73 @@ var CPScrollDestinationNone = 0,
return "tokenfield-token-close-button";
}
- (void)mouseEntered:(CPEvent)anEvent
{
// Don't toggle hover state from within the button - we use the hover state of the token field as a whole.
}
- (void)mouseExited:(CPEvent)anEvent
{
// Don't toggle hover state from within the button - we use the hover state of the token field as a whole.
}
@end
@implementation _CPTokenFieldTokenDisclosureButton : CPPopUpButton
{
}
+ (id)themeAttributes
{
var attributes = [CPButton themeAttributes];
[attributes setObject:_CGPointMake(15, 5) forKey:@"offset"];
return attributes;
}
+ (CPString)defaultThemeClass
{
return "tokenfield-token-disclosure-button";
}
- (id)initWithFrame:(CGRect)aFrame
{
if (self = [self initWithFrame:aFrame pullsDown:YES])
{
[self setBordered:YES];
[super setTitle:@""];
}
return self;
}
- (void)setTitle:(CPString)aTitle
{
// skip
}
- (void)synchronizeTitleAndSelectedItem
{
// skip
}
- (void)mouseEntered:(CPEvent)anEvent
{
// Don't toggle hover state from within the button - we use the hover state of the token field as a whole.
}
- (void)mouseExited:(CPEvent)anEvent
{
// Don't toggle hover state from within the button - we use the hover state of the token field as a whole.
}
@end
var CPTokenFieldTokenizingCharacterSetKey = "CPTokenFieldTokenizingCharacterSetKey",
CPTokenFieldCompletionDelayKey = "CPTokenFieldCompletionDelay";
CPTokenFieldCompletionDelayKey = "CPTokenFieldCompletionDelay",
CPTokenFieldButtonTypeKey = "CPTokenFieldButtonTypeKey";
@implementation CPTokenField (CPCoding)
@@ -1379,6 +1621,7 @@ var CPTokenFieldTokenizingCharacterSetKey = "CPTokenFieldTokenizingCharacterSe
{
_tokenizingCharacterSet = [aCoder decodeObjectForKey:CPTokenFieldTokenizingCharacterSetKey] || [[self class] defaultTokenizingCharacterSet];
_completionDelay = [aCoder decodeDoubleForKey:CPTokenFieldCompletionDelayKey] || [[self class] defaultCompletionDelay];
_buttonType = [aCoder decodeIntForKey:CPTokenFieldButtonTypeKey] || CPTokenFieldDisclosureButtonType;
[self _init];
@@ -1395,6 +1638,7 @@ var CPTokenFieldTokenizingCharacterSetKey = "CPTokenFieldTokenizingCharacterSe
[aCoder encodeInt:_tokenizingCharacterSet forKey:CPTokenFieldTokenizingCharacterSetKey];
[aCoder encodeDouble:_completionDelay forKey:CPTokenFieldCompletionDelayKey];
[aCoder encodeInt:_buttonType forKey:CPTokenFieldButtonTypeKey];
}
@end
+54 -65
View File
@@ -28,6 +28,7 @@
@import "CPPopUpButton.j"
@import "CPToolbarItem.j"
@global CPApp
/*
@global
@@ -117,8 +118,8 @@ var CPToolbarsByIdentifier = nil,
if (self !== [CPToolbar class])
return;
CPToolbarsByIdentifier = [CPDictionary dictionary];
CPToolbarConfigurationsByIdentifier = [CPDictionary dictionary];
CPToolbarsByIdentifier = @{};
CPToolbarConfigurationsByIdentifier = @{};
}
/* @ignore */
@@ -135,19 +136,6 @@ var CPToolbarsByIdentifier = nil,
[toolbarsSharingIdentifier addObject:toolbar];
}
/*
Temporary theme attributes until we've figured out which CPView these theme attributes should
belong to.
@ignore
*/
+ (id)_themeAttributes
{
// "regular-size-height" is used if no item has a non-zero min size and sizeMode == CPToolbarSizeModeRegular.
// "small-size-height" is used if no item has a non-zero min size and sizeMode == CPToolbarSizeModeSmall.
return [CPDictionary dictionaryWithObjects:[_CGInsetMake(4.0, 4.0, 4.0, TOOLBAR_ITEM_MARGIN), 59.0, 46.0]
forKeys:[@"content-inset", @"regular-size-height", @"small-size-height"]];
}
- (id)init
{
return [self initWithIdentifier:@""];
@@ -242,12 +230,12 @@ var CPToolbarsByIdentifier = nil,
- (void)_setWindow:(CPWindow)aWindow
{
if (_window)
[[CPNotificationCenter defaultCenter] removeObserver:self object:_window];
[[CPNotificationCenter defaultCenter] removeObserver:self name:_CPWindowDidChangeFirstResponderNotification object:_window];
_window = aWindow;
if (_window)
[[CPNotificationCenter defaultCenter] addObserver:self selector:@selector(_autovalidate) name:_CPWindowDidChangeFirstResponderNotification object:aWindow];
[[CPNotificationCenter defaultCenter] addObserver:self selector:@selector(_autoValidateVisibleItems) name:_CPWindowDidChangeFirstResponderNotification object:aWindow];
}
/*!
@@ -281,18 +269,8 @@ var CPToolbarsByIdentifier = nil,
- (CGRect)_toolbarViewFrame
{
var height = _desiredHeight || (_sizeMode != CPToolbarSizeModeSmall ? [self _valueForThemeAttribute:@"regular-size-height"] : [self _valueForThemeAttribute:@"small-size-height"]);
return CPRectMake(0.0, 0.0, 1200.0, height);
}
/*
Temporary theme attributes until we've figured out which CPView these theme attributes should
belong to.
@ignore
*/
- (id)_valueForThemeAttribute:(CPString)attributeName
{
return [[[self class] _themeAttributes] valueForKey:attributeName];
var height = _desiredHeight || (_sizeMode != CPToolbarSizeModeSmall ? [_toolbarView valueForThemeAttribute:@"regular-size-height"] : [_toolbarView valueForThemeAttribute:@"small-size-height"]);
return CGRectMake(0.0, 0.0, 1200.0, height);
}
/* @ignore */
@@ -400,14 +378,15 @@ var CPToolbarsByIdentifier = nil,
*/
- (void)validateVisibleItems
{
var toolbarItems = [self visibleItems],
count = [toolbarItems count];
while (count--)
[toolbarItems[count] validate];
[self _validateVisibleItems:NO]
}
- (void)_autovalidate
- (void)_autoValidateVisibleItems
{
[self _validateVisibleItems:YES]
}
- (void)_validateVisibleItems:(BOOL)isAutovalidation
{
var toolbarItems = [self visibleItems],
count = [toolbarItems count];
@@ -415,7 +394,7 @@ var CPToolbarsByIdentifier = nil,
while (count--)
{
var item = [toolbarItems objectAtIndex:count];
if ([item autovalidates])
if (!isAutovalidation || [item autovalidates])
[item validate];
}
}
@@ -591,9 +570,6 @@ var _CPToolbarViewBackgroundColor = nil,
_CPToolbarViewExtraItemsImage = nil,
_CPToolbarViewExtraItemsAlternateImage = nil;
var TOOLBAR_ITEM_MARGIN = 10.0,
TOOLBAR_EXTRA_ITEMS_WIDTH = 20.0;
var _CPToolbarItemInfoMake = function(anIndex, aView, aLabel, aMinWidth)
{
return { index:anIndex, view:aView, label:aLabel, minWidth:aMinWidth };
@@ -622,16 +598,24 @@ var _CPToolbarItemInfoMake = function(anIndex, aView, aLabel, aMinWidth)
BOOL _FIXME_isHUD;
}
+ (void)initialize
+ (CPString)defaultThemeClass
{
if (self !== [_CPToolbarView class])
return;
return @"toolbar-view";
}
var bundle = [CPBundle bundleForClass:self];
_CPToolbarViewExtraItemsImage = [[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:"_CPToolbarView/_CPToolbarViewExtraItemsImage.png"] size:CPSizeMake(10.0, 15.0)];
_CPToolbarViewExtraItemsAlternateImage = [[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:"_CPToolbarView/_CPToolbarViewExtraItemsAlternateImage.png"] size:_CGSizeMake(10.0, 15.0)];
+ (id)themeAttributes
{
return @{
@"item-margin": 10.0,
@"extra-item-width": 20.0,
@"extra-item-extra-image": [CPNull null],
@"extra-item-extra-alternate-image": [CPNull null],
@"content-inset": _CGInsetMake(4.0, 4.0, 4.0, 10),
@"regular-size-height": 59.0,
@"small-size-height": 46.0,
@"image-item-separator-color": [CPNull null],
@"image-item-separator-size": CGRectMake(0.0, 0.0, 2.0, 32.0),
};
}
- (id)initWithFrame:(CGRect)aFrame
@@ -651,8 +635,6 @@ var _CPToolbarItemInfoMake = function(anIndex, aView, aLabel, aMinWidth)
[_additionalItemsButton setImagePosition:CPImageOnly];
[[_additionalItemsButton menu] setShowsStateColumn:NO];
[[_additionalItemsButton menu] setAutoenablesItems:NO];
[_additionalItemsButton setAlternateImage:_CPToolbarViewExtraItemsAlternateImage];
}
return self;
@@ -708,7 +690,7 @@ var _CPToolbarItemInfoMake = function(anIndex, aView, aLabel, aMinWidth)
// minimum width for hiding items.
if (itemsWidth < minWidth)
{
itemsWidth -= TOOLBAR_EXTRA_ITEMS_WIDTH;
itemsWidth -= [self valueForThemeAttribute:@"extra-item-width"];
_visibleItems = [_visibleItems copy];
@@ -724,7 +706,7 @@ var _CPToolbarItemInfoMake = function(anIndex, aView, aLabel, aMinWidth)
var item = itemsSortedByVisibilityPriority[--count],
view = [self viewForItem:item];
minWidth -= [view minSize].width + TOOLBAR_ITEM_MARGIN;
minWidth -= [view minSize].width + [self valueForThemeAttribute:@"item-margin"];
[_visibleItems removeObjectIdenticalTo:item];
[invisibleItemsSortedByPriority addObject:item];
@@ -750,7 +732,7 @@ var _CPToolbarItemInfoMake = function(anIndex, aView, aLabel, aMinWidth)
// We'll figure out the proper height for the toolbar depending on its items.
// If nothing has a minimum size we'll use the standard toolbar size for the
// sizeMode, indicated by a 0 _desiredHeight.
var contentInset = [_toolbar _valueForThemeAttribute:@"content-inset"],
var contentInset = [self valueForThemeAttribute:@"content-inset"],
newDesiredHeight = height ? height + contentInset.top + contentInset.bottom : 0;
if (newDesiredHeight != _toolbar._desiredHeight)
@@ -827,7 +809,7 @@ var _CPToolbarItemInfoMake = function(anIndex, aView, aLabel, aMinWidth)
var index = 0,
count = _visibleItems.length,
x = contentInset.left,
contentInset = [_toolbar _valueForThemeAttribute:@"content-inset"],
contentInset = [self valueForThemeAttribute:@"content-inset"],
y = contentInset.top;
for (; index < count; ++index)
@@ -837,7 +819,7 @@ var _CPToolbarItemInfoMake = function(anIndex, aView, aLabel, aMinWidth)
[view setFrame:_CGRectMake(x, y, viewWidth, height)];
x += viewWidth + TOOLBAR_ITEM_MARGIN;
x += viewWidth + [self valueForThemeAttribute:@"item-margin"];
}
var needsAdditionalItemsButton = NO;
@@ -876,7 +858,7 @@ var _CPToolbarItemInfoMake = function(anIndex, aView, aLabel, aMinWidth)
[_additionalItemsButton removeAllItems];
[_additionalItemsButton addItemWithTitle:@"Additional Items"];
[[_additionalItemsButton itemArray][0] setImage:_CPToolbarViewExtraItemsImage];
[[_additionalItemsButton itemArray][0] setImage:[self valueForThemeAttribute:@"extra-item-extra-image"]];
var index = 0,
count = [_invisibleItems count],
@@ -942,7 +924,7 @@ var _CPToolbarItemInfoMake = function(anIndex, aView, aLabel, aMinWidth)
count = items.length;
_minWidth = TOOLBAR_ITEM_MARGIN;
_minWidth = [self valueForThemeAttribute:@"item-margin"];
_viewsForToolbarItems = { };
for (; index < count; ++index)
@@ -957,12 +939,17 @@ var _CPToolbarItemInfoMake = function(anIndex, aView, aLabel, aMinWidth)
[self addSubview:view];
_minWidth += [view minSize].width + TOOLBAR_ITEM_MARGIN;
_minWidth += [view minSize].width + [self valueForThemeAttribute:@"item-margin"];
}
[self tile];
}
- (void)layoutSubviews
{
[_additionalItemsButton setAlternateImage:[self valueForThemeAttribute:@"extra-item-extra-alternate-image"]];
}
@end
/* @ignore */
@@ -1059,13 +1046,7 @@ var LABEL_MARGIN = 2.0;
if (identifier === CPToolbarSeparatorItemIdentifier)
{
_view = [[CPView alloc] initWithFrame:_CGRectMake(0.0, 0.0, 2.0, 32.0)];
// FIXME: Get rid of this old API!!!
sizes = {};
sizes[@"CPToolbarItemSeparator"] = [_CGSizeMake(2.0, 26.0), _CGSizeMake(2.0, 1.0), _CGSizeMake(2.0, 26.0)];
[_view setBackgroundColor:_CPControlThreePartImagePattern(YES, sizes, @"CPToolbarItem", @"Separator")];
_view = [[CPView alloc] initWithFrame:CGRectMakeZero()];
[self addSubview:_view];
}
@@ -1138,7 +1119,15 @@ var LABEL_MARGIN = 2.0;
width = _CGRectGetWidth(bounds);
if (identifier === CPToolbarSeparatorItemIdentifier)
return [_view setFrame:_CGRectMake(ROUND((width - 2.0) / 2.0), 0.0, 2.0, _CGRectGetHeight(bounds))];
{
var itemSeparatorColor = [_toolbar valueForThemeAttribute:@"image-item-separator-color"],
itemSeparatorSize = [_toolbar valueForThemeAttribute:@"image-item-separator-size"];
[_view setFrame:_CGRectMake(ROUND((width - itemSeparatorSize.size.width) / 2.0), 0.0, itemSeparatorSize.size.width, _CGRectGetHeight(bounds))];
[_view setBackgroundColor:itemSeparatorColor];
return;
}
// The view is centred in the available space above the label.
var view = _view || _imageView,
+1 -634
View File
@@ -20,641 +20,8 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@import <Foundation/CPObject.j>
@import <Foundation/CPString.j>
@import "CPImage.j"
@import "CPView.j"
CPToolbarItemVisibilityPriorityStandard = 0;
CPToolbarItemVisibilityPriorityLow = -1000;
CPToolbarItemVisibilityPriorityHigh = 1000;
CPToolbarItemVisibilityPriorityUser = 2000;
CPToolbarSeparatorItemIdentifier = @"CPToolbarSeparatorItem";
CPToolbarSpaceItemIdentifier = @"CPToolbarSpaceItem";
CPToolbarFlexibleSpaceItemIdentifier = @"CPToolbarFlexibleSpaceItem";
CPToolbarShowColorsItemIdentifier = @"CPToolbarShowColorsItem";
CPToolbarShowFontsItemIdentifier = @"CPToolbarShowFontsItem";
CPToolbarCustomizeToolbarItemIdentifier = @"CPToolbarCustomizeToolbarItem";
CPToolbarPrintItemIdentifier = @"CPToolbarPrintItem";
/*!
@ingroup appkit
@class CPToolbarItem
A representation of an item in a CPToolbar.
*/
@implementation CPToolbarItem : CPObject
{
CPString _itemIdentifier;
CPToolbar _toolbar;
CPString _label;
CPString _paletteLabel;
CPString _toolTip;
int _tag;
id _target;
SEL _action;
BOOL _isEnabled;
CPImage _image;
CPImage _alternateImage;
CPView _view;
CGSize _minSize;
CGSize _maxSize;
int _visibilityPriority;
BOOL _autovalidates;
}
- (id)init
{
return [self initWithItemIdentifier:@""];
}
// Creating a Toolbar Item
/*!
Initializes the toolbar item with a specified identifier.
@param anItemIdentifier the item's identifier
@return the initialized toolbar item
*/
- (id)initWithItemIdentifier:(CPString)anItemIdentifier
{
self = [super init];
if (self)
{
_itemIdentifier = anItemIdentifier;
_tag = 0;
_isEnabled = YES;
_minSize = CGSizeMakeZero();
_maxSize = CGSizeMakeZero();
_visibilityPriority = CPToolbarItemVisibilityPriorityStandard;
_autovalidates = YES;
}
return self;
}
// Managing Attributes
/*!
Returns the item's identifier.
*/
- (CPString)itemIdentifier
{
return _itemIdentifier;
}
/*!
Returns the toolbar of which this item is a part.
*/
- (CPToolbar)toolbar
{
return _toolbar;
}
/* @ignore */
- (void)_setToolbar:(CPToolbar)aToolbar
{
_toolbar = aToolbar;
}
/*!
Returns the item's label
*/
- (CPString)label
{
return _label;
}
/*!
Sets the item's label.
@param aLabel the new label for the item
*/
- (void)setLabel:(CPString)aLabel
{
_label = aLabel;
}
/*!
Returns the palette label.
*/
- (CPString)paletteLabel
{
return _paletteLabel;
}
/*!
Sets the palette label
@param aPaletteLabel the new palette label
*/
- (void)setPaletteLabel:(CPString)aPaletteLabel
{
_paletteLabel = aPaletteLabel;
}
/*!
Returns the item's tooltip. A tooltip pops up
next to the cursor when the user hovers over
the item with the mouse.
*/
- (CPString)toolTip
{
if ([_view respondsToSelector:@selector(toolTip)])
return [_view toolTip];
return _toolTip;
}
/*!
Sets the item's tooltip. A tooltip pops up next to the cursor when the user hovers over the item with the mouse.
@param aToolTip the new item tool tip
*/
- (void)setToolTip:(CPString)aToolTip
{
if ([_view respondsToSelector:@selector(setToolTip:)])
[_view setToolTip:aToolTip];
_toolTip = aToolTip;
}
/*!
Returns the item's tag.
*/
- (int)tag
{
if ([_view respondsToSelector:@selector(tag)])
return [_view tag];
return _tag;
}
/*!
Sets the item's tag.
@param aTag the new tag for the item
*/
- (void)setTag:(int)aTag
{
if ([_view respondsToSelector:@selector(setTag:)])
[_view setTag:aTag];
_tag = aTag;
}
/*!
Returns the item's action target.
*/
- (id)target
{
if (_view)
return [_view respondsToSelector:@selector(target)] ? [_view target] : nil;
return _target;
}
/*!
Sets the target of the action that is triggered when the user clicks this item. \c nil will cause
the action to be passed on to the first responder.
@param aTarget the new target
*/
- (void)setTarget:(id)aTarget
{
if (!_view)
_target = aTarget;
else if ([_view respondsToSelector:@selector(setTarget:)])
[_view setTarget:aTarget];
}
/*!
Returns the action that is triggered when the user clicks this item.
*/
- (SEL)action
{
if (_view)
return [_view respondsToSelector:@selector(action)] ? [_view action] : nil;
return _action;
}
/*!
Sets the action that is triggered when the user clicks this item.
@param anAction the new action
*/
- (void)setAction:(SEL)anAction
{
if (!_view)
_action = anAction;
else if ([_view respondsToSelector:@selector(setAction:)])
[_view setAction:anAction];
}
/*!
Returns \c YES if the item is enabled.
*/
- (BOOL)isEnabled
{
if ([_view respondsToSelector:@selector(isEnabled)])
return [_view isEnabled];
return _isEnabled;
}
/*!
Sets whether the item is enabled.
@param aFlag \c YES enables the item
*/
- (void)setEnabled:(BOOL)shouldBeEnabled
{
if (_isEnabled === shouldBeEnabled)
return;
if ([_view respondsToSelector:@selector(setEnabled:)])
[_view setEnabled:shouldBeEnabled];
_isEnabled = shouldBeEnabled;
}
/*!
Returns the item's image
*/
- (CPImage)image
{
if ([_view respondsToSelector:@selector(image)])
return [_view image];
return _image;
}
/*!
Sets the item's image.
@param anImage the new item image
*/
- (void)setImage:(CPImage)anImage
{
if ([_view respondsToSelector:@selector(setImage:)])
[_view setImage:anImage];
_image = anImage;
if (!_image)
return;
if (_minSize.width === 0 && _minSize.height === 0 &&
_maxSize.width === 0 && _maxSize.height === 0)
{
var imageSize = [_image size];
if (imageSize.width > 0 || imageSize.height > 0)
{
[self setMinSize:imageSize];
[self setMaxSize:imageSize];
}
}
}
/*!
Sets the alternate image. This image is displayed on the item when the user is clicking it.
@param anImage the new alternate image
*/
- (void)setAlternateImage:(CPImage)anImage
{
if ([_view respondsToSelector:@selector(setAlternateImage:)])
[_view setAlternateImage:anImage];
_alternateImage = anImage;
}
/*!
Returns the alternate image. This image is displayed on the item when the user is clicking it.
*/
- (CPImage)alternateImage
{
if ([_view respondsToSelector:@selector(alternateIamge)])
return [_view alternateImage];
return _alternateImage;
}
/*!
Returns the item's view.
*/
- (CPView)view
{
return _view;
}
/*!
Sets the item's view
@param aView the item's new view
*/
- (void)setView:(CPView)aView
{
if (_view == aView)
return;
_view = aView;
if (_view)
{
// Tags get forwarded.
if (_tag !== 0 && [_view respondsToSelector:@selector(setTag:)])
[_view setTag:_tag];
_target = nil;
_action = nil;
}
}
/*!
Returns the item's minimum size.
*/
- (CGSize)minSize
{
return _minSize;
}
/*!
Sets the item's minimum size.
@param aMinSize the new minimum size
*/
- (void)setMinSize:(CGSize)aMinSize
{
if (!aMinSize.height || !aMinSize.width)
return;
_minSize = CGSizeMakeCopy(aMinSize);
// Try to provide some sanity: Make maxSize >= minSize
_maxSize = CGSizeMake(MAX(_minSize.width, _maxSize.width), MAX(_minSize.height, _maxSize.height));
}
/*!
Returns the item's maximum size.
*/
- (CGSize)maxSize
{
return _maxSize;
}
/*!
Sets the item's new maximum size.
@param aMaxSize the new maximum size
*/
- (void)setMaxSize:(CGSize)aMaxSize
{
if (!aMaxSize.height || !aMaxSize.width)
return;
_maxSize = CGSizeMakeCopy(aMaxSize);
// Try to provide some sanity: Make minSize <= maxSize
_minSize = CGSizeMake(MIN(_minSize.width, _maxSize.width), MIN(_minSize.height, _maxSize.height));
}
// Visibility Priority
/*!
Returns the item's visibility priority. The value will be one of:
<pre>
CPToolbarItemVisibilityPriorityStandard
CPToolbarItemVisibilityPriorityLow
CPToolbarItemVisibilityPriorityHigh
CPToolbarItemVisibilityPriorityUser
</pre>
*/
- (int)visibilityPriority
{
return _visibilityPriority;
}
/*!
Sets the item's visibility priority. The value must be one of:
<pre>
CPToolbarItemVisibilityPriorityStandard
CPToolbarItemVisibilityPriorityLow
CPToolbarItemVisibilityPriorityHigh
CPToolbarItemVisibilityPriorityUser
</pre>
@param aVisiblityPriority the priority
*/
- (void)setVisibilityPriority:(int)aVisibilityPriority
{
_visibilityPriority = aVisibilityPriority;
}
- (void)validate
{
var action = [self action],
target = [self target];
// View items do not do any target-action analysis.
if (_view)
{
if ([target respondsToSelector:@selector(validateToolbarItem:)])
{
var shouldBeEnabled = [target validateToolbarItem:self];
if (_isEnabled !== shouldBeEnabled)
[self setEnabled:shouldBeEnabled];
}
return;
}
if (!action)
{
if (_isEnabled)
return [self setEnabled:NO];
return;
}
if (target && ![target respondsToSelector:action])
{
if (_isEnabled)
return [self setEnabled:NO];
return;
}
target = [CPApp targetForAction:action to:target from:self];
if (!target)
{
if (_isEnabled)
return [self setEnabled:NO];
return;
}
if ([target respondsToSelector:@selector(validateToolbarItem:)])
{
var shouldBeEnabled = [target validateToolbarItem:self];
if (_isEnabled !== shouldBeEnabled)
[self setEnabled:shouldBeEnabled];
}
else
{
if (!_isEnabled)
[self setEnabled:YES];
}
}
- (BOOL)autovalidates
{
return _autovalidates;
}
- (void)setAutovalidates:(BOOL)shouldAutovalidate
{
_autovalidates = !!shouldAutovalidate;
}
@end
var CPToolbarItemItemIdentifierKey = @"CPToolbarItemItemIdentifierKey",
CPToolbarItemLabelKey = @"CPToolbarItemLabelKey",
CPToolbarItemPaletteLabelKey = @"CPToolbarItemPaletteLabelKey",
CPToolbarItemToolTipKey = @"CPToolbarItemToolTipKey",
CPToolbarItemTagKey = @"CPToolbarItemTagKey",
CPToolbarItemTargetKey = @"CPToolbarItemTargetKey",
CPToolbarItemActionKey = @"CPToolbarItemActionKey",
CPToolbarItemEnabledKey = @"CPToolbarItemEnabledKey",
CPToolbarItemImageKey = @"CPToolbarItemImageKey",
CPToolbarItemAlternateImageKey = @"CPToolbarItemAlternateImageKey",
CPToolbarItemViewKey = @"CPToolbarItemViewKey",
CPToolbarItemMinSizeKey = @"CPToolbarItemMinSizeKey",
CPToolbarItemMaxSizeKey = @"CPToolbarItemMaxSizeKey",
CPToolbarItemVisibilityPriorityKey = @"CPToolbarItemVisibilityPriorityKey",
CPToolbarItemAutovalidatesKey = @"CPToolbarItemAutovalidatesKey";
@implementation CPToolbarItem (CPCoding)
- (id)initWithCoder:(CPCoder)aCoder
{
self = [super init];
if (self)
{
_itemIdentifier = [aCoder decodeObjectForKey:CPToolbarItemItemIdentifierKey];
_minSize = [aCoder decodeSizeForKey:CPToolbarItemMinSizeKey];
_maxSize = [aCoder decodeSizeForKey:CPToolbarItemMaxSizeKey];
[self setLabel:[aCoder decodeObjectForKey:CPToolbarItemLabelKey]];
[self setPaletteLabel:[aCoder decodeObjectForKey:CPToolbarItemPaletteLabelKey]];
[self setToolTip:[aCoder decodeObjectForKey:CPToolbarItemToolTipKey]];
[self setTag:[aCoder decodeObjectForKey:CPToolbarItemTagKey]];
[self setTarget:[aCoder decodeObjectForKey:CPToolbarItemTargetKey]];
[self setAction:CPSelectorFromString([aCoder decodeObjectForKey:CPToolbarItemActionKey])];
[self setEnabled:[aCoder decodeBoolForKey:CPToolbarItemEnabledKey]];
[self setImage:[aCoder decodeObjectForKey:CPToolbarItemImageKey]];
[self setAlternateImage:[aCoder decodeObjectForKey:CPToolbarItemAlternateImageKey]];
[self setView:[aCoder decodeObjectForKey:CPToolbarItemViewKey]];
[self setVisibilityPriority:[aCoder decodeIntForKey:CPToolbarItemVisibilityPriorityKey]];
[self setAutovalidates:[aCoder decodeBoolForKey:CPToolbarItemAutovalidatesKey]];
}
return self;
}
- (void)encodeWithCoder:(CPCoder)aCoder
{
[aCoder encodeObject:_itemIdentifier forKey:CPToolbarItemItemIdentifierKey];
[aCoder encodeObject:[self label] forKey:CPToolbarItemLabelKey];
[aCoder encodeObject:[self paletteLabel] forKey:CPToolbarItemPaletteLabelKey];
[aCoder encodeObject:[self toolTip] forKey:CPToolbarItemToolTipKey];
[aCoder encodeObject:[self tag] forKey:CPToolbarItemTagKey];
[aCoder encodeObject:[self target] forKey:CPToolbarItemTargetKey];
[aCoder encodeObject:[self action] forKey:CPToolbarItemActionKey];
[aCoder encodeObject:[self isEnabled] forKey:CPToolbarItemEnabledKey];
[aCoder encodeObject:[self image] forKey:CPToolbarItemImageKey];
[aCoder encodeObject:[self alternateImage] forKey:CPToolbarItemAlternateImageKey];
[aCoder encodeObject:[self view] forKey:CPToolbarItemViewKey];
[aCoder encodeSize:[self minSize] forKey:CPToolbarItemMinSizeKey];
[aCoder encodeSize:[self maxSize] forKey:CPToolbarItemMaxSizeKey];
[aCoder encodeObject:[self visibilityPriority] forKey:CPToolbarItemVisibilityPriorityKey];
[aCoder encodeBool:[self autovalidates] forKey:CPToolbarItemAutovalidatesKey];
}
@end
@implementation CPToolbarItem (CPCopying)
- (id)copy
{
var copy = [[[self class] alloc] initWithItemIdentifier:_itemIdentifier];
if (_view)
[copy setView:[CPKeyedUnarchiver unarchiveObjectWithData:[CPKeyedArchiver archivedDataWithRootObject:_view]]];
[copy _setToolbar:_toolbar];
[copy setLabel:_label];
[copy setPaletteLabel:_paletteLabel];
[copy setToolTip:[self toolTip]];
[copy setTag:[self tag]];
[copy setTarget:[self target]];
[copy setAction:[self action]];
[copy setEnabled:[self isEnabled]];
[copy setImage:[self image]];
[copy setAlternateImage:[self alternateImage]];
[copy setMinSize:_minSize];
[copy setMaxSize:_maxSize];
[copy setVisibilityPriority:[self visibilityPriority]];
[copy setAutovalidates:[self autovalidates]];
return copy;
}
@end
// Standard toolbar identifiers
@implementation CPToolbarItem (Standard)
/* @ignore */
+ (CPToolbarItem)_standardItemWithItemIdentifier:(CPString)anItemIdentifier
{
switch (anItemIdentifier)
{
case CPToolbarSeparatorItemIdentifier: return [_CPToolbarSeparatorItem new];
case CPToolbarSpaceItemIdentifier: return [_CPToolbarSpaceItem new];
case CPToolbarFlexibleSpaceItemIdentifier: return [_CPToolbarFlexibleSpaceItem new];
case CPToolbarShowColorsItemIdentifier: return [_CPToolbarShowColorsItem new];
case CPToolbarShowFontsItemIdentifier: return nil;
case CPToolbarCustomizeToolbarItemIdentifier: return nil;
case CPToolbarPrintItemIdentifier: return nil;
}
return nil;
}
@end
@import "_CPToolbarItem.j"
@import "_CPToolbarFlexibleSpaceItem.j"
@import "_CPToolbarShowColorsItem.j"
@import "_CPToolbarSeparatorItem.j"
+21
View File
@@ -1,3 +1,24 @@
/*
* CPTreeNode.j
* AppKit
*
* Created by Francisco Tolmasky.
* Copyright 2009, 280 North, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@import <Foundation/CPObject.j>
@import <Foundation/CPIndexPath.j>
+9 -2
View File
@@ -23,9 +23,15 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@import <Foundation/CPDictionary.j>
@import <Foundation/CPNotificationCenter.j>
@import <Foundation/CPString.j>
@import <AppKit/CPController.j>
@import <Foundation/CPUserDefaults.j>
@import "CPController.j"
@global CPUserDefaultsDidChangeNotification
var SharedUserDefaultsController = nil;
@@ -34,6 +40,7 @@ var SharedUserDefaultsController = nil;
CPUserDefaults _defaults @accessors(readonly, property=defaults);
CPDictionary _initialValues @accessors(property=initialValues);
BOOL _appliesImmediately @accessors(property=appliesImmediately);
id _valueProxy;
}
+ (id)sharedUserDefaultsController
+97 -35
View File
@@ -21,19 +21,27 @@
*/
@import <Foundation/CPArray.j>
@import <Foundation/CPGeometry.j>
@import <Foundation/CPObjJRuntime.j>
@import <Foundation/CPSet.j>
@import "CGAffineTransform.j"
@import "CGGeometry.j"
@import "CPColor.j"
@import "CPGraphicsContext.j"
@import "CPResponder.j"
@import "CPTheme.j"
@import "CPWindow_Constants.j"
@import "_CPDisplayServer.j"
@class _CPToolTip
@class CPWindow
@class _CPMenuItemView
@class CPPlatformWindow
@class CPMenu
@class CPClipView
@class CPScrollView
@global appkit_tag_dom_elements
/*
@global
@@ -126,6 +134,7 @@ var CPViewFlags = { },
CPGraphicsContext _graphicsContext;
int _tag;
CPString _identifier @accessors(property=identifier);
CGRect _frame;
CGRect _bounds;
@@ -219,6 +228,14 @@ var CPViewFlags = { },
CachedNotificationCenter = [CPNotificationCenter defaultCenter];
}
+ (Class)_binderClassForBinding:(CPString)aBinding
{
if ([aBinding hasPrefix:CPHiddenBinding])
return [CPMultipleValueOrBinding class];
return [super _binderClassForBinding:aBinding];
}
- (void)_setupViewFlags
{
var theClass = [self class],
@@ -459,11 +476,15 @@ var CPViewFlags = { },
{
if (aSubview === self)
[CPException raise:CPInvalidArgumentException reason:"can't add a view as a subview of itself"];
#if DEBUG
if (!aSubview._superview && _subviews.indexOf(aSubview) !== CPNotFound)
[CPException raise:CPInvalidArgumentException reason:"can't insert a subview in duplicate (probably partially decoded)"];
#endif
// We will have to adjust the z-index of all views starting at this index.
var count = _subviews.length;
// dirty the key view loop, in case the window wants to auto recalculate it
// Dirty the key view loop, in case the window wants to auto recalculate it
[[self window] _dirtyKeyViewLoop];
// If this is already one of our subviews, remove it.
@@ -544,15 +565,15 @@ var CPViewFlags = { },
if (!_superview)
return;
// dirty the key view loop, in case the window wants to auto recalculate it
// Dirty the key view loop, in case the window wants to auto recalculate it
[[self window] _dirtyKeyViewLoop];
[_superview willRemoveSubview:self];
[_superview._subviews removeObject:self];
[_superview._subviews removeObjectIdenticalTo:self];
#if PLATFORM(DOM)
CPDOMDisplayServerRemoveChild(_superview._DOMElement, _DOMElement);
CPDOMDisplayServerRemoveChild(_superview._DOMElement, _DOMElement);
#endif
_superview = nil;
@@ -651,6 +672,9 @@ var CPViewFlags = { },
if (_window === aWindow)
return;
// Unlike in Cocoa you can observe the window of a view.
[self willChangeValueForKey:@"window"];
[[self window] _dirtyKeyViewLoop];
// Clear out first responder if we're the first responder and leaving.
@@ -678,6 +702,8 @@ var CPViewFlags = { },
[self viewDidMoveToWindow];
[[self window] _dirtyKeyViewLoop];
[self didChangeValueForKey:@"window"];
}
/*!
@@ -1349,6 +1375,7 @@ var CPViewFlags = { },
}
else
{
[self setNeedsDisplay:YES];
[self _notifyViewDidUnhide];
}
}
@@ -1484,13 +1511,12 @@ var CPViewFlags = { },
/*!
Returns whether the receiver should be sent a \c -mouseDown: message for \c anEvent.<br/>
Returns \c YES by default.
Returns \c NO by default.
@return \c YES, if the view object accepts first mouse-down event. \c NO, otherwise.
*/
//FIXME: should be NO by default?
- (BOOL)acceptsFirstMouse:(CPEvent)anEvent
{
return YES;
return NO;
}
/*!
@@ -1516,7 +1542,7 @@ var CPViewFlags = { },
@param aPoint the point to test
@return returns the containing view, or nil if the point is not contained
*/
- (CPView)hitTest:(CPPoint)aPoint
- (CPView)hitTest:(CGPoint)aPoint
{
if (_isHidden || !_hitTests || !_CGRectContainsPoint(_frame, aPoint))
return nil;
@@ -1561,6 +1587,7 @@ var CPViewFlags = { },
- (void)rightMouseDown:(CPEvent)anEvent
{
var menu = [self menuForEvent:anEvent];
if (menu)
[CPMenu popUpContextMenu:menu withEvent:anEvent forView:self];
else if ([[self nextResponder] isKindOfClass:CPView])
@@ -2037,7 +2064,7 @@ setBoundsOrigin:
@param aSourceObject the drag operation controller
@param slideBack Whether the view should 'slide back' if the drag is rejected
*/
- (void)dragView:(CPView)aView at:(CPPoint)aLocation offset:(CPSize)mouseOffset event:(CPEvent)anEvent pasteboard:(CPPasteboard)aPasteboard source:(id)aSourceObject slideBack:(BOOL)slideBack
- (void)dragView:(CPView)aView at:(CGPoint)aLocation offset:(CGSize)mouseOffset event:(CPEvent)anEvent pasteboard:(CPPasteboard)aPasteboard source:(id)aSourceObject slideBack:(BOOL)slideBack
{
[_window dragView:aView at:[self convertPoint:aLocation toView:nil] offset:mouseOffset event:anEvent pasteboard:aPasteboard source:aSourceObject slideBack:slideBack];
}
@@ -2087,7 +2114,7 @@ setBoundsOrigin:
Draws the receiver into \c aRect. This method should be overridden by subclasses.
@param aRect the area that should be drawn into
*/
- (void)drawRect:(CPRect)aRect
- (void)drawRect:(CGRect)aRect
{
}
@@ -2107,7 +2134,7 @@ setBoundsOrigin:
Marks the area denoted by \c aRect as dirty, and initiates a redraw on it.
@param aRect the area that needs to be redrawn
*/
- (void)setNeedsDisplayInRect:(CPRect)aRect
- (void)setNeedsDisplayInRect:(CGRect)aRect
{
if (!(_viewClassFlags & CPViewHasCustomDrawRect))
return;
@@ -2155,7 +2182,7 @@ setBoundsOrigin:
Draws the receiver into the area defined by \c aRect.
@param aRect the area to be drawn
*/
- (void)displayRect:(CPRect)aRect
- (void)displayRect:(CGRect)aRect
{
[self viewWillDraw];
@@ -2192,6 +2219,7 @@ setBoundsOrigin:
{
var graphicsPort = CGBitmapGraphicsContextCreate();
#if PLATFORM(DOM)
_DOMContentsElement = graphicsPort.DOMElement;
_DOMContentsElement.style.zIndex = -100;
@@ -2208,7 +2236,6 @@ setBoundsOrigin:
_DOMContentsElement.style.width = ROUND(_CGRectGetWidth(_frame)) + "px";
_DOMContentsElement.style.height = ROUND(_CGRectGetHeight(_frame)) + "px";
#if PLATFORM(DOM)
// The performance implications of this aren't clear, but without this subviews might not be redrawn when this
// view moves.
if (CPPlatformHasBug(CPCanvasParentDrawErrorsOnMovementBug))
@@ -2311,13 +2338,11 @@ setBoundsOrigin:
*/
- (BOOL)scrollRectToVisible:(CGRect)aRect
{
var visibleRect = [self visibleRect];
// Make sure we have a rect that exists.
aRect = CGRectIntersection(aRect, _bounds);
// If aRect is empty or is already visible then no scrolling required.
if (_CGRectIsEmpty(aRect) || CGRectContainsRect(visibleRect, aRect))
// If aRect is empty no scrolling required.
if (_CGRectIsEmpty(aRect))
return NO;
var enclosingClipView = [self _enclosingClipView];
@@ -2326,20 +2351,34 @@ setBoundsOrigin:
if (!enclosingClipView)
return NO;
var scrollPoint = _CGPointMakeCopy(visibleRect.origin);
var documentView = [enclosingClipView documentView];
// If the clip view doesn't have a document view, then there isn't much we can do.
if (!documentView)
return NO;
// Get the document view visible rect and convert aRect to the document view's coordinate system
var documentViewVisibleRect = [documentView visibleRect],
rectInDocumentView = [self convertRect:aRect toView:documentView];
// If already visible then no scrolling required.
if (CGRectContainsRect(documentViewVisibleRect, rectInDocumentView))
return NO;
var scrollPoint = _CGPointMakeCopy(documentViewVisibleRect.origin);
// One of the following has to be true since our current visible rect didn't contain aRect.
if (_CGRectGetMinX(aRect) <= _CGRectGetMinX(visibleRect))
scrollPoint.x = _CGRectGetMinX(aRect);
else if (_CGRectGetMaxX(aRect) > _CGRectGetMaxX(visibleRect))
scrollPoint.x += _CGRectGetMaxX(aRect) - _CGRectGetMaxX(visibleRect);
if (_CGRectGetMinX(rectInDocumentView) < _CGRectGetMinX(documentViewVisibleRect))
scrollPoint.x = _CGRectGetMinX(rectInDocumentView);
else if (_CGRectGetMaxX(rectInDocumentView) > _CGRectGetMaxX(documentViewVisibleRect))
scrollPoint.x += _CGRectGetMaxX(rectInDocumentView) - _CGRectGetMaxX(documentViewVisibleRect);
if (_CGRectGetMinY(aRect) <= _CGRectGetMinY(visibleRect))
scrollPoint.y = CGRectGetMinY(aRect);
else if (_CGRectGetMaxY(aRect) > _CGRectGetMaxY(visibleRect))
scrollPoint.y += _CGRectGetMaxY(aRect) - _CGRectGetMaxY(visibleRect);
if (_CGRectGetMinY(rectInDocumentView) < _CGRectGetMinY(documentViewVisibleRect))
scrollPoint.y = _CGRectGetMinY(rectInDocumentView);
else if (_CGRectGetMaxY(rectInDocumentView) > _CGRectGetMaxY(documentViewVisibleRect))
scrollPoint.y += _CGRectGetMaxY(rectInDocumentView) - _CGRectGetMaxY(documentViewVisibleRect);
[enclosingClipView scrollToPoint:CGPointMake(scrollPoint.x, scrollPoint.y)];
[enclosingClipView scrollToPoint:scrollPoint];
return YES;
}
@@ -2523,7 +2562,7 @@ setBoundsOrigin:
- (void)_setPreviousKeyView:(CPView)previous
{
if ([previous isEqual:self])
if ([previous isEqual:self] || ![[previous window] isEqual:[self window]])
_previousKeyView = nil;
else
_previousKeyView = previous;
@@ -2531,7 +2570,7 @@ setBoundsOrigin:
- (void)setNextKeyView:(CPView)next
{
if ([next isEqual:self])
if ([next isEqual:self] || ![[next window] isEqual:[self window]])
_nextKeyView = nil;
else
{
@@ -2759,6 +2798,12 @@ setBoundsOrigin:
[self viewDidChangeTheme];
}
- (void)_setThemeIncludingDescendants:(CPTheme)aTheme
{
[self setTheme:aTheme];
[[self subviews] makeObjectsPerformSelector:@selector(_setThemeIncludingDescendants:) withObject:aTheme];
}
- (CPTheme)theme
{
return _theme;
@@ -2782,7 +2827,7 @@ setBoundsOrigin:
- (CPDictionary)_themeAttributeDictionary
{
var dictionary = [CPDictionary dictionary];
var dictionary = @{};
if (_themeAttributes)
{
@@ -2975,7 +3020,8 @@ var CPViewAutoresizingMaskKey = @"CPViewAutoresizingMask",
CPViewThemeStateKey = @"CPViewThemeStateKey",
CPViewWindowKey = @"CPViewWindowKey",
CPViewNextKeyViewKey = @"CPViewNextKeyViewKey",
CPViewPreviousKeyViewKey = @"CPViewPreviousKeyViewKey";
CPViewPreviousKeyViewKey = @"CPViewPreviousKeyViewKey",
CPReuseIdentifierKey = @"CPReuseIdentifierKey";
@implementation CPView (CPCoding)
@@ -3004,11 +3050,24 @@ var CPViewAutoresizingMaskKey = @"CPViewAutoresizingMask",
{
// We have to manually check because it may be 0, so we can't use ||
_tag = [aCoder containsValueForKey:CPViewTagKey] ? [aCoder decodeIntForKey:CPViewTagKey] : -1;
_identifier = [aCoder decodeObjectForKey:CPReuseIdentifierKey];
_window = [aCoder decodeObjectForKey:CPViewWindowKey];
_subviews = [aCoder decodeObjectForKey:CPViewSubviewsKey] || [];
_superview = [aCoder decodeObjectForKey:CPViewSuperviewKey];
// We have to manually add the subviews so that they will receive
// viewWillMoveToSuperview: and viewDidMoveToSuperview:
_subviews = [];
var subviews = [aCoder decodeObjectForKey:CPViewSubviewsKey] || [];
for (var i = 0, count = [subviews count]; i < count; ++i)
{
// addSubview won't do anything if the superview is already self, so clear it
subviews[i]._superview = nil;
[self addSubview:subviews[i]];
}
// FIXME: Should we encode/decode this?
_registeredDraggedTypes = [CPSet set];
_registeredDraggedTypesArray = [];
@@ -3154,6 +3213,9 @@ var CPViewAutoresizingMaskKey = @"CPViewAutoresizingMask",
for (var attributeName in _themeAttributes)
if (_themeAttributes.hasOwnProperty(attributeName))
CPThemeAttributeEncode(aCoder, _themeAttributes[attributeName]);
if (_identifier)
[aCoder encodeObject:_identifier forKey:CPReuseIdentifierKey];
}
@end
+7 -2
View File
@@ -22,6 +22,7 @@
@import "CPAnimation.j"
@class CPWindow
CPViewAnimationTargetKey = @"CPViewAnimationTargetKey";
CPViewAnimationStartFrameKey = @"CPViewAnimationStartFrameKey";
@@ -58,8 +59,12 @@ CPViewAnimationFadeOutEffect = @"CPViewAnimationFadeOutEffect";
For example:
<pre>
var animation = [CPDictionary dictionaryWithObjects:[myViewToAnimate, aStartFrame, anEndFrame, CPViewAnimationFadeInEffect]
forKeys:[CPViewAnimationTargetKey, CPViewAnimationStartFrameKey, CPViewAnimationEndFrameKey, CPViewAnimationEffectKey]];
var animation = @{
CPViewAnimationTargetKey: myViewToAnimate,
CPViewAnimationStartFrameKey: aStartFrame,
CPViewAnimationEndFrameKey: anEndFrame,
CPViewAnimationEffectKey: CPViewAnimationFadeInEffect,
};
</pre>
If you pass nil instead of an array of dictionaries you should later call setViewAnimations:.

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